| // Copyright lowRISC contributors. |
| // Licensed under the Apache License, Version 2.0, see LICENSE for details. |
| // SPDX-License-Identifier: Apache-2.0 |
| |
| #include "sw/device/lib/dif/dif_sensor_ctrl.h" |
| |
| #include <assert.h> |
| |
| #include "sw/device/lib/base/bitfield.h" |
| #include "sw/device/lib/base/mmio.h" |
| #include "sw/device/lib/base/multibits.h" |
| #include "sw/device/lib/dif/dif_base.h" |
| |
| #include "sensor_ctrl_regs.h" // Generated |
| |
| /** |
| * Helper function to determine if a higher than supported event was supplied |
| * as an argument. This check is used in multiple places so use a helper |
| * function. |
| */ |
| static inline bool is_ast_event_invalid(dif_sensor_ctrl_event_idx_t event_idx) { |
| return event_idx > SENSOR_CTRL_PARAM_NUM_ALERT_EVENTS; |
| } |
| |
| /** |
| * Helper function to get CFG_REGWEN |
| */ |
| static bool is_locked(const dif_sensor_ctrl_t *sensor_ctrl) { |
| return (mmio_region_read32(sensor_ctrl->base_addr, |
| SENSOR_CTRL_CFG_REGWEN_REG_OFFSET) == 0); |
| } |
| |
| OT_WARN_UNUSED_RESULT |
| dif_result_t dif_sensor_ctrl_lock_cfg(const dif_sensor_ctrl_t *sensor_ctrl) { |
| if (sensor_ctrl == NULL) { |
| return kDifBadArg; |
| } |
| |
| mmio_region_write32(sensor_ctrl->base_addr, SENSOR_CTRL_CFG_REGWEN_REG_OFFSET, |
| 0); |
| |
| return kDifOk; |
| } |
| |
| OT_WARN_UNUSED_RESULT |
| dif_result_t dif_sensor_ctrl_set_ast_event_trigger( |
| const dif_sensor_ctrl_t *sensor_ctrl, dif_sensor_ctrl_event_idx_t event_idx, |
| dif_toggle_t enable) { |
| if (sensor_ctrl == NULL || is_ast_event_invalid(event_idx)) { |
| return kDifBadArg; |
| }; |
| |
| uint32_t reg = mmio_region_read32(sensor_ctrl->base_addr, |
| SENSOR_CTRL_ALERT_TRIG_REG_OFFSET); |
| reg = bitfield_bit32_write(reg, event_idx, dif_toggle_to_bool(enable)); |
| mmio_region_write32(sensor_ctrl->base_addr, SENSOR_CTRL_ALERT_TRIG_REG_OFFSET, |
| reg); |
| |
| return kDifOk; |
| } |
| |
| OT_WARN_UNUSED_RESULT |
| dif_result_t dif_sensor_ctrl_set_alert_fatal( |
| const dif_sensor_ctrl_t *sensor_ctrl, dif_sensor_ctrl_event_idx_t event_idx, |
| dif_toggle_t en_fatal) { |
| if (sensor_ctrl == NULL || is_ast_event_invalid(event_idx)) { |
| return kDifBadArg; |
| }; |
| |
| if (is_locked(sensor_ctrl)) { |
| return kDifLocked; |
| } |
| |
| uint32_t reg = mmio_region_read32(sensor_ctrl->base_addr, |
| SENSOR_CTRL_FATAL_ALERT_EN_REG_OFFSET); |
| reg = bitfield_bit32_write(reg, event_idx, dif_toggle_to_bool(en_fatal)); |
| mmio_region_write32(sensor_ctrl->base_addr, |
| SENSOR_CTRL_FATAL_ALERT_EN_REG_OFFSET, reg); |
| |
| return kDifOk; |
| } |
| |
| OT_WARN_UNUSED_RESULT |
| dif_result_t dif_sensor_ctrl_get_recov_events( |
| const dif_sensor_ctrl_t *sensor_ctrl, dif_sensor_ctrl_events_t *events) { |
| if (sensor_ctrl == NULL || events == NULL) { |
| return kDifBadArg; |
| }; |
| |
| *events = mmio_region_read32(sensor_ctrl->base_addr, |
| SENSOR_CTRL_RECOV_ALERT_REG_OFFSET); |
| |
| return kDifOk; |
| }; |
| |
| OT_WARN_UNUSED_RESULT |
| dif_result_t dif_sensor_ctrl_clear_recov_event( |
| const dif_sensor_ctrl_t *sensor_ctrl, |
| dif_sensor_ctrl_event_idx_t event_idx) { |
| if (sensor_ctrl == NULL || is_ast_event_invalid(event_idx)) { |
| return kDifBadArg; |
| }; |
| |
| uint32_t reg = bitfield_bit32_write(0, event_idx, 1); |
| mmio_region_write32(sensor_ctrl->base_addr, |
| SENSOR_CTRL_RECOV_ALERT_REG_OFFSET, reg); |
| |
| return kDifOk; |
| } |
| |
| OT_WARN_UNUSED_RESULT |
| dif_result_t dif_sensor_ctrl_get_fatal_events( |
| const dif_sensor_ctrl_t *sensor_ctrl, dif_sensor_ctrl_events_t *events) { |
| if (sensor_ctrl == NULL || events == NULL) { |
| return kDifBadArg; |
| }; |
| |
| *events = mmio_region_read32(sensor_ctrl->base_addr, |
| SENSOR_CTRL_FATAL_ALERT_REG_OFFSET); |
| |
| return kDifOk; |
| }; |
| |
| OT_WARN_UNUSED_RESULT |
| dif_result_t dif_sensor_ctrl_get_ast_init_done_status( |
| const dif_sensor_ctrl_t *sensor_ctrl, dif_toggle_t *done) { |
| if (sensor_ctrl == NULL || done == NULL) { |
| return kDifBadArg; |
| }; |
| |
| uint32_t reg = |
| mmio_region_read32(sensor_ctrl->base_addr, SENSOR_CTRL_STATUS_REG_OFFSET); |
| *done = dif_bool_to_toggle( |
| bitfield_bit32_read(reg, SENSOR_CTRL_STATUS_AST_INIT_DONE_BIT)); |
| |
| return kDifOk; |
| } |
| |
| OT_WARN_UNUSED_RESULT |
| dif_result_t dif_sensor_ctrl_get_io_power_status( |
| const dif_sensor_ctrl_t *sensor_ctrl, |
| dif_sensor_ctrl_io_power_status_t *io_power_status) { |
| if (sensor_ctrl == NULL || io_power_status == NULL) { |
| return kDifBadArg; |
| }; |
| |
| uint32_t reg = |
| mmio_region_read32(sensor_ctrl->base_addr, SENSOR_CTRL_STATUS_REG_OFFSET); |
| *io_power_status = |
| bitfield_field32_read(reg, SENSOR_CTRL_STATUS_IO_POK_FIELD); |
| |
| return kDifOk; |
| } |