Software APIs
dif_sensor_ctrl.c
1// Copyright lowRISC contributors (OpenTitan project).
2// Licensed under the Apache License, Version 2.0, see LICENSE for details.
3// SPDX-License-Identifier: Apache-2.0
4
6
7#include <assert.h>
8
11#include "sw/device/lib/base/multibits.h"
13
14#include "sensor_ctrl_regs.h" // Generated
15
16/**
17 * Helper function to determine if a higher than supported event was supplied
18 * as an argument. This check is used in multiple places so use a helper
19 * function.
20 */
21static inline bool is_ast_event_valid(dif_sensor_ctrl_event_idx_t event_idx) {
22 return event_idx < SENSOR_CTRL_PARAM_NUM_ALERT_EVENTS;
23}
24
25/**
26 * Helper function to get CFG_REGWEN
27 */
28static bool is_locked(const dif_sensor_ctrl_t *sensor_ctrl) {
29 return (mmio_region_read32(sensor_ctrl->base_addr,
30 SENSOR_CTRL_CFG_REGWEN_REG_OFFSET) == 0);
31}
32
34dif_result_t dif_sensor_ctrl_lock_cfg(const dif_sensor_ctrl_t *sensor_ctrl) {
35 if (sensor_ctrl == NULL) {
36 return kDifBadArg;
37 }
38
39 mmio_region_write32(sensor_ctrl->base_addr, SENSOR_CTRL_CFG_REGWEN_REG_OFFSET,
40 0);
41
42 return kDifOk;
43}
44
46dif_result_t dif_sensor_ctrl_get_ast_event_trigger(
47 const dif_sensor_ctrl_t *sensor_ctrl, dif_sensor_ctrl_event_idx_t event_idx,
48 dif_toggle_t *enable) {
49 if (sensor_ctrl == NULL || !is_ast_event_valid(event_idx) || enable == NULL) {
50 return kDifBadArg;
51 };
52
53 uint32_t reg = mmio_region_read32(sensor_ctrl->base_addr,
54 SENSOR_CTRL_ALERT_TRIG_REG_OFFSET);
55 *enable = dif_bool_to_toggle(bitfield_bit32_read(reg, event_idx));
56
57 return kDifOk;
58}
59
61dif_result_t dif_sensor_ctrl_set_ast_event_trigger(
62 const dif_sensor_ctrl_t *sensor_ctrl, dif_sensor_ctrl_event_idx_t event_idx,
63 dif_toggle_t enable) {
64 if (sensor_ctrl == NULL || !is_ast_event_valid(event_idx)) {
65 return kDifBadArg;
66 };
67
68 uint32_t reg = mmio_region_read32(sensor_ctrl->base_addr,
69 SENSOR_CTRL_ALERT_TRIG_REG_OFFSET);
70 reg = bitfield_bit32_write(reg, event_idx, dif_toggle_to_bool(enable));
71 mmio_region_write32(sensor_ctrl->base_addr, SENSOR_CTRL_ALERT_TRIG_REG_OFFSET,
72 reg);
73
74 return kDifOk;
75}
76
78dif_result_t dif_sensor_ctrl_set_alert_en(const dif_sensor_ctrl_t *sensor_ctrl,
80 dif_toggle_t en) {
81 if (sensor_ctrl == NULL || !is_ast_event_valid(event_idx)) {
82 return kDifBadArg;
83 };
84
85 if (is_locked(sensor_ctrl)) {
86 return kDifLocked;
87 }
88
89 mmio_region_write32(
90 sensor_ctrl->base_addr,
91 SENSOR_CTRL_ALERT_EN_0_REG_OFFSET + ((ptrdiff_t)event_idx << 2),
92 dif_toggle_to_multi_bit_bool4(en));
93
94 return kDifOk;
95}
96
98dif_result_t dif_sensor_ctrl_set_alert_fatal(
99 const dif_sensor_ctrl_t *sensor_ctrl, dif_sensor_ctrl_event_idx_t event_idx,
100 dif_toggle_t en_fatal) {
101 if (sensor_ctrl == NULL || !is_ast_event_valid(event_idx)) {
102 return kDifBadArg;
103 };
104
105 if (is_locked(sensor_ctrl)) {
106 return kDifLocked;
107 }
108
109 uint32_t reg = mmio_region_read32(sensor_ctrl->base_addr,
110 SENSOR_CTRL_FATAL_ALERT_EN_REG_OFFSET);
111 reg = bitfield_bit32_write(reg, event_idx, dif_toggle_to_bool(en_fatal));
112 mmio_region_write32(sensor_ctrl->base_addr,
113 SENSOR_CTRL_FATAL_ALERT_EN_REG_OFFSET, reg);
114
115 return kDifOk;
116}
117
119dif_result_t dif_sensor_ctrl_get_recov_events(
120 const dif_sensor_ctrl_t *sensor_ctrl, dif_sensor_ctrl_events_t *events) {
121 if (sensor_ctrl == NULL || events == NULL) {
122 return kDifBadArg;
123 };
124
125 *events = mmio_region_read32(sensor_ctrl->base_addr,
126 SENSOR_CTRL_RECOV_ALERT_REG_OFFSET);
127
128 return kDifOk;
129};
130
132dif_result_t dif_sensor_ctrl_clear_recov_event(
133 const dif_sensor_ctrl_t *sensor_ctrl,
134 dif_sensor_ctrl_event_idx_t event_idx) {
135 if (sensor_ctrl == NULL || !is_ast_event_valid(event_idx)) {
136 return kDifBadArg;
137 };
138
139 uint32_t reg = bitfield_bit32_write(0, event_idx, 1);
140 mmio_region_write32(sensor_ctrl->base_addr,
141 SENSOR_CTRL_RECOV_ALERT_REG_OFFSET, reg);
142
143 return kDifOk;
144}
145
147dif_result_t dif_sensor_ctrl_get_fatal_events(
148 const dif_sensor_ctrl_t *sensor_ctrl, dif_sensor_ctrl_events_t *events) {
149 if (sensor_ctrl == NULL || events == NULL) {
150 return kDifBadArg;
151 };
152
153 *events = mmio_region_read32(sensor_ctrl->base_addr,
154 SENSOR_CTRL_FATAL_ALERT_REG_OFFSET);
155
156 return kDifOk;
157};
158
160dif_result_t dif_sensor_ctrl_get_ast_init_done_status(
161 const dif_sensor_ctrl_t *sensor_ctrl, dif_toggle_t *done) {
162 if (sensor_ctrl == NULL || done == NULL) {
163 return kDifBadArg;
164 };
165
166 uint32_t reg =
167 mmio_region_read32(sensor_ctrl->base_addr, SENSOR_CTRL_STATUS_REG_OFFSET);
168 *done = dif_bool_to_toggle(
169 bitfield_bit32_read(reg, SENSOR_CTRL_STATUS_AST_INIT_DONE_BIT));
170
171 return kDifOk;
172}
173
175dif_result_t dif_sensor_ctrl_get_io_power_status(
176 const dif_sensor_ctrl_t *sensor_ctrl,
177 dif_sensor_ctrl_io_power_status_t *io_power_status) {
178 if (sensor_ctrl == NULL || io_power_status == NULL) {
179 return kDifBadArg;
180 };
181
182 uint32_t reg =
183 mmio_region_read32(sensor_ctrl->base_addr, SENSOR_CTRL_STATUS_REG_OFFSET);
184 *io_power_status =
185 bitfield_field32_read(reg, SENSOR_CTRL_STATUS_IO_POK_FIELD);
186
187 return kDifOk;
188}