Software APIs
dif_sysrst_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
12
13#include "sysrst_ctrl_regs.h" // Generated.
14
15static_assert(SYSRST_CTRL_PARAM_NUM_COMBO == 4,
16 "Number of key combinations has changed. Update the "
17 "dif_sysrst_ctrl_key_combo_t enum.");
18static_assert(SYSRST_CTRL_KEY_INTR_STATUS_FLASH_WP_L_L2H_BIT == 13,
19 "Flash write-protect key interrupt bit has changed. Update the "
20 "dif_sysrst_ctrl_input_change_irq_get_causes() DIF.");
21
22dif_result_t dif_sysrst_ctrl_key_combo_detect_configure(
23 const dif_sysrst_ctrl_t *sysrst_ctrl, dif_sysrst_ctrl_key_combo_t key_combo,
25 if (sysrst_ctrl == NULL || config.pre_condition_keys > kDifSysrstCtrlKeyAll ||
26 config.keys > kDifSysrstCtrlKeyAll ||
28 return kDifBadArg;
29 }
30
31 ptrdiff_t pre_cond_combo_select_ctl_reg_offset;
32 ptrdiff_t pre_cond_combo_detect_ctl_reg_offset;
33 ptrdiff_t combo_select_ctl_reg_offset;
34 ptrdiff_t combo_detect_ctl_reg_offset;
35 ptrdiff_t combo_action_ctl_reg_offset;
36
37 switch (key_combo) {
39 pre_cond_combo_select_ctl_reg_offset =
40 SYSRST_CTRL_COM_PRE_SEL_CTL_0_REG_OFFSET;
41 pre_cond_combo_detect_ctl_reg_offset =
42 SYSRST_CTRL_COM_PRE_DET_CTL_0_REG_OFFSET;
43 combo_select_ctl_reg_offset = SYSRST_CTRL_COM_SEL_CTL_0_REG_OFFSET;
44 combo_detect_ctl_reg_offset = SYSRST_CTRL_COM_DET_CTL_0_REG_OFFSET;
45 combo_action_ctl_reg_offset = SYSRST_CTRL_COM_OUT_CTL_0_REG_OFFSET;
46 break;
48 pre_cond_combo_select_ctl_reg_offset =
49 SYSRST_CTRL_COM_PRE_SEL_CTL_1_REG_OFFSET;
50 pre_cond_combo_detect_ctl_reg_offset =
51 SYSRST_CTRL_COM_PRE_DET_CTL_1_REG_OFFSET;
52 combo_select_ctl_reg_offset = SYSRST_CTRL_COM_SEL_CTL_1_REG_OFFSET;
53 combo_detect_ctl_reg_offset = SYSRST_CTRL_COM_DET_CTL_1_REG_OFFSET;
54 combo_action_ctl_reg_offset = SYSRST_CTRL_COM_OUT_CTL_1_REG_OFFSET;
55 break;
57 pre_cond_combo_select_ctl_reg_offset =
58 SYSRST_CTRL_COM_PRE_SEL_CTL_2_REG_OFFSET;
59 pre_cond_combo_detect_ctl_reg_offset =
60 SYSRST_CTRL_COM_PRE_DET_CTL_2_REG_OFFSET;
61 combo_select_ctl_reg_offset = SYSRST_CTRL_COM_SEL_CTL_2_REG_OFFSET;
62 combo_detect_ctl_reg_offset = SYSRST_CTRL_COM_DET_CTL_2_REG_OFFSET;
63 combo_action_ctl_reg_offset = SYSRST_CTRL_COM_OUT_CTL_2_REG_OFFSET;
64 break;
66 pre_cond_combo_select_ctl_reg_offset =
67 SYSRST_CTRL_COM_PRE_SEL_CTL_3_REG_OFFSET;
68 pre_cond_combo_detect_ctl_reg_offset =
69 SYSRST_CTRL_COM_PRE_DET_CTL_3_REG_OFFSET;
70 combo_select_ctl_reg_offset = SYSRST_CTRL_COM_SEL_CTL_3_REG_OFFSET;
71 combo_detect_ctl_reg_offset = SYSRST_CTRL_COM_DET_CTL_3_REG_OFFSET;
72 combo_action_ctl_reg_offset = SYSRST_CTRL_COM_OUT_CTL_3_REG_OFFSET;
73 break;
74 default:
75 return kDifBadArg;
76 }
77
78 if (!mmio_region_read32(sysrst_ctrl->base_addr,
79 SYSRST_CTRL_REGWEN_REG_OFFSET)) {
80 return kDifLocked;
81 }
82
83 mmio_region_write32(sysrst_ctrl->base_addr,
84 pre_cond_combo_select_ctl_reg_offset,
85 config.pre_condition_keys);
86 mmio_region_write32(sysrst_ctrl->base_addr,
87 pre_cond_combo_detect_ctl_reg_offset,
89 mmio_region_write32(sysrst_ctrl->base_addr, combo_select_ctl_reg_offset,
90 config.keys);
91 mmio_region_write32(sysrst_ctrl->base_addr, combo_detect_ctl_reg_offset,
93 mmio_region_write32(sysrst_ctrl->base_addr, combo_action_ctl_reg_offset,
94 config.actions);
95
97 mmio_region_write32(sysrst_ctrl->base_addr,
98 SYSRST_CTRL_EC_RST_CTL_REG_OFFSET,
100 }
101
102 return kDifOk;
103}
104
105dif_result_t dif_sysrst_ctrl_input_change_detect_configure(
106 const dif_sysrst_ctrl_t *sysrst_ctrl,
108 if (sysrst_ctrl == NULL || config.input_changes > kDifSysrstCtrlInputAll) {
109 return kDifBadArg;
110 }
111
112 if (!mmio_region_read32(sysrst_ctrl->base_addr,
113 SYSRST_CTRL_REGWEN_REG_OFFSET)) {
114 return kDifLocked;
115 }
116
117 mmio_region_write32(sysrst_ctrl->base_addr,
118 SYSRST_CTRL_KEY_INTR_CTL_REG_OFFSET,
119 config.input_changes);
120 mmio_region_write32(sysrst_ctrl->base_addr,
121 SYSRST_CTRL_KEY_INTR_DEBOUNCE_CTL_REG_OFFSET,
123
124 return kDifOk;
125}
126
127dif_result_t dif_sysrst_ctrl_output_pin_override_configure(
128 const dif_sysrst_ctrl_t *sysrst_ctrl, dif_sysrst_ctrl_pin_t output_pin,
130 if (sysrst_ctrl == NULL ||
131 (config.override_value == true && config.allow_one == false) ||
132 (config.override_value == false && config.allow_zero == false) ||
133 !dif_is_valid_toggle(config.enabled)) {
134 return kDifBadArg;
135 }
136
137 uint32_t pin_out_ctl_bit_index;
138 uint32_t pin_out_value_bit_index;
139 uint32_t pin_out_allow_0_bit_index;
140 uint32_t pin_out_allow_1_bit_index;
141
142 switch (output_pin) {
144 pin_out_ctl_bit_index = SYSRST_CTRL_PIN_OUT_CTL_KEY0_OUT_BIT;
145 pin_out_value_bit_index = SYSRST_CTRL_PIN_OUT_VALUE_KEY0_OUT_BIT;
146 pin_out_allow_0_bit_index = SYSRST_CTRL_PIN_ALLOWED_CTL_KEY0_OUT_0_BIT;
147 pin_out_allow_1_bit_index = SYSRST_CTRL_PIN_ALLOWED_CTL_KEY0_OUT_1_BIT;
148 break;
150 pin_out_ctl_bit_index = SYSRST_CTRL_PIN_OUT_CTL_KEY1_OUT_BIT;
151 pin_out_value_bit_index = SYSRST_CTRL_PIN_OUT_VALUE_KEY1_OUT_BIT;
152 pin_out_allow_0_bit_index = SYSRST_CTRL_PIN_ALLOWED_CTL_KEY1_OUT_0_BIT;
153 pin_out_allow_1_bit_index = SYSRST_CTRL_PIN_ALLOWED_CTL_KEY1_OUT_1_BIT;
154 break;
156 pin_out_ctl_bit_index = SYSRST_CTRL_PIN_OUT_CTL_KEY2_OUT_BIT;
157 pin_out_value_bit_index = SYSRST_CTRL_PIN_OUT_VALUE_KEY2_OUT_BIT;
158 pin_out_allow_0_bit_index = SYSRST_CTRL_PIN_ALLOWED_CTL_KEY2_OUT_0_BIT;
159 pin_out_allow_1_bit_index = SYSRST_CTRL_PIN_ALLOWED_CTL_KEY2_OUT_1_BIT;
160 break;
162 pin_out_ctl_bit_index = SYSRST_CTRL_PIN_OUT_CTL_PWRB_OUT_BIT;
163 pin_out_value_bit_index = SYSRST_CTRL_PIN_OUT_VALUE_PWRB_OUT_BIT;
164 pin_out_allow_0_bit_index = SYSRST_CTRL_PIN_ALLOWED_CTL_PWRB_OUT_0_BIT;
165 pin_out_allow_1_bit_index = SYSRST_CTRL_PIN_ALLOWED_CTL_PWRB_OUT_1_BIT;
166 break;
168 pin_out_ctl_bit_index = SYSRST_CTRL_PIN_OUT_CTL_BAT_DISABLE_BIT;
169 pin_out_value_bit_index = SYSRST_CTRL_PIN_OUT_VALUE_BAT_DISABLE_BIT;
170 pin_out_allow_0_bit_index = SYSRST_CTRL_PIN_ALLOWED_CTL_BAT_DISABLE_0_BIT;
171 pin_out_allow_1_bit_index = SYSRST_CTRL_PIN_ALLOWED_CTL_BAT_DISABLE_1_BIT;
172 break;
174 pin_out_ctl_bit_index = SYSRST_CTRL_PIN_OUT_CTL_Z3_WAKEUP_BIT;
175 pin_out_value_bit_index = SYSRST_CTRL_PIN_OUT_VALUE_Z3_WAKEUP_BIT;
176 pin_out_allow_0_bit_index = SYSRST_CTRL_PIN_ALLOWED_CTL_Z3_WAKEUP_0_BIT;
177 pin_out_allow_1_bit_index = SYSRST_CTRL_PIN_ALLOWED_CTL_Z3_WAKEUP_1_BIT;
178 break;
180 pin_out_ctl_bit_index = SYSRST_CTRL_PIN_OUT_CTL_EC_RST_L_BIT;
181 pin_out_value_bit_index = SYSRST_CTRL_PIN_OUT_VALUE_EC_RST_L_BIT;
182 pin_out_allow_0_bit_index = SYSRST_CTRL_PIN_ALLOWED_CTL_EC_RST_L_0_BIT;
183 pin_out_allow_1_bit_index = SYSRST_CTRL_PIN_ALLOWED_CTL_EC_RST_L_1_BIT;
184 break;
186 pin_out_ctl_bit_index = SYSRST_CTRL_PIN_OUT_CTL_FLASH_WP_L_BIT;
187 pin_out_value_bit_index = SYSRST_CTRL_PIN_OUT_VALUE_FLASH_WP_L_BIT;
188 pin_out_allow_0_bit_index = SYSRST_CTRL_PIN_ALLOWED_CTL_FLASH_WP_L_0_BIT;
189 pin_out_allow_1_bit_index = SYSRST_CTRL_PIN_ALLOWED_CTL_FLASH_WP_L_1_BIT;
190 break;
191 default:
192 return kDifBadArg;
193 }
194
195 if (!mmio_region_read32(sysrst_ctrl->base_addr,
196 SYSRST_CTRL_REGWEN_REG_OFFSET)) {
197 return kDifLocked;
198 }
199
200 // Configure output pin control register.
201 uint32_t pin_out_ctl_reg = mmio_region_read32(
202 sysrst_ctrl->base_addr, SYSRST_CTRL_PIN_OUT_CTL_REG_OFFSET);
203 pin_out_ctl_reg = bitfield_bit32_write(pin_out_ctl_reg, pin_out_ctl_bit_index,
204 dif_toggle_to_bool(config.enabled));
205 mmio_region_write32(sysrst_ctrl->base_addr,
206 SYSRST_CTRL_PIN_OUT_CTL_REG_OFFSET, pin_out_ctl_reg);
207
208 // Configure output pin override value register.
209 uint32_t pin_out_value_reg = mmio_region_read32(
210 sysrst_ctrl->base_addr, SYSRST_CTRL_PIN_OUT_VALUE_REG_OFFSET);
211 pin_out_value_reg = bitfield_bit32_write(
212 pin_out_value_reg, pin_out_value_bit_index, config.override_value);
213 mmio_region_write32(sysrst_ctrl->base_addr,
214 SYSRST_CTRL_PIN_OUT_VALUE_REG_OFFSET, pin_out_value_reg);
215
216 // Configure output pin allowed values register.
217 uint32_t pin_out_allowed_values_reg = mmio_region_read32(
218 sysrst_ctrl->base_addr, SYSRST_CTRL_PIN_ALLOWED_CTL_REG_OFFSET);
219 pin_out_allowed_values_reg = bitfield_bit32_write(
220 pin_out_allowed_values_reg, pin_out_allow_0_bit_index, config.allow_zero);
221 pin_out_allowed_values_reg = bitfield_bit32_write(
222 pin_out_allowed_values_reg, pin_out_allow_1_bit_index, config.allow_one);
223 mmio_region_write32(sysrst_ctrl->base_addr,
224 SYSRST_CTRL_PIN_ALLOWED_CTL_REG_OFFSET,
225 pin_out_allowed_values_reg);
226
227 return kDifOk;
228}
229
230dif_result_t dif_sysrst_ctrl_ulp_wakeup_configure(
231 const dif_sysrst_ctrl_t *sysrst_ctrl,
233 if (sysrst_ctrl == NULL || !dif_is_valid_toggle(config.enabled)) {
234 return kDifBadArg;
235 }
236
237 if (!mmio_region_read32(sysrst_ctrl->base_addr,
238 SYSRST_CTRL_REGWEN_REG_OFFSET)) {
239 return kDifLocked;
240 }
241
242 mmio_region_write32(sysrst_ctrl->base_addr, SYSRST_CTRL_ULP_CTL_REG_OFFSET,
243 dif_toggle_to_bool(config.enabled));
244 mmio_region_write32(sysrst_ctrl->base_addr,
245 SYSRST_CTRL_ULP_AC_DEBOUNCE_CTL_REG_OFFSET,
247 mmio_region_write32(sysrst_ctrl->base_addr,
248 SYSRST_CTRL_ULP_LID_DEBOUNCE_CTL_REG_OFFSET,
250 mmio_region_write32(sysrst_ctrl->base_addr,
251 SYSRST_CTRL_ULP_PWRB_DEBOUNCE_CTL_REG_OFFSET,
253
254 return kDifOk;
255}
256
257dif_result_t dif_sysrst_ctrl_ulp_wakeup_set_enabled(
258 const dif_sysrst_ctrl_t *sysrst_ctrl, dif_toggle_t enabled) {
259 if (sysrst_ctrl == NULL || !dif_is_valid_toggle(enabled)) {
260 return kDifBadArg;
261 }
262
263 mmio_region_write32(sysrst_ctrl->base_addr, SYSRST_CTRL_ULP_CTL_REG_OFFSET,
264 dif_toggle_to_bool(enabled));
265
266 return kDifOk;
267}
268
269dif_result_t dif_sysrst_ctrl_ulp_wakeup_get_enabled(
270 const dif_sysrst_ctrl_t *sysrst_ctrl, dif_toggle_t *is_enabled) {
271 if (sysrst_ctrl == NULL || is_enabled == NULL) {
272 return kDifBadArg;
273 }
274
275 *is_enabled = dif_bool_to_toggle(mmio_region_read32(
276 sysrst_ctrl->base_addr, SYSRST_CTRL_ULP_CTL_REG_OFFSET));
277
278 return kDifOk;
279}
280
281dif_result_t dif_sysrst_ctrl_pins_set_inverted(
282 const dif_sysrst_ctrl_t *sysrst_ctrl, uint32_t pins, bool inverted) {
283 if (sysrst_ctrl == NULL || pins > kDifSysrstCtrlPinAllNonOpenDrain) {
284 return kDifBadArg;
285 }
286
287 if (!mmio_region_read32(sysrst_ctrl->base_addr,
288 SYSRST_CTRL_REGWEN_REG_OFFSET)) {
289 return kDifLocked;
290 }
291
292 uint32_t inverted_pins = mmio_region_read32(
293 sysrst_ctrl->base_addr, SYSRST_CTRL_KEY_INVERT_CTL_REG_OFFSET);
294
295 if (inverted) {
296 inverted_pins |= pins;
297 } else {
298 inverted_pins &= ~pins;
299 }
300
301 mmio_region_write32(sysrst_ctrl->base_addr,
302 SYSRST_CTRL_KEY_INVERT_CTL_REG_OFFSET, inverted_pins);
303
304 return kDifOk;
305}
306
307dif_result_t dif_sysrst_ctrl_pins_get_inverted(
308 const dif_sysrst_ctrl_t *sysrst_ctrl, uint32_t *inverted_pins) {
309 if (sysrst_ctrl == NULL || inverted_pins == NULL) {
310 return kDifBadArg;
311 }
312
313 *inverted_pins = mmio_region_read32(sysrst_ctrl->base_addr,
314 SYSRST_CTRL_KEY_INVERT_CTL_REG_OFFSET);
315
316 return kDifOk;
317}
318
319static bool get_output_pin_allowed_bit_indices(dif_sysrst_ctrl_pin_t pin,
320 uint32_t *allow_0_bit_index,
321 uint32_t *allow_1_bit_index) {
322 switch (pin) {
324 *allow_0_bit_index = SYSRST_CTRL_PIN_ALLOWED_CTL_KEY0_OUT_0_BIT;
325 *allow_1_bit_index = SYSRST_CTRL_PIN_ALLOWED_CTL_KEY0_OUT_1_BIT;
326 break;
328 *allow_0_bit_index = SYSRST_CTRL_PIN_ALLOWED_CTL_KEY1_OUT_0_BIT;
329 *allow_1_bit_index = SYSRST_CTRL_PIN_ALLOWED_CTL_KEY1_OUT_1_BIT;
330 break;
332 *allow_0_bit_index = SYSRST_CTRL_PIN_ALLOWED_CTL_KEY2_OUT_0_BIT;
333 *allow_1_bit_index = SYSRST_CTRL_PIN_ALLOWED_CTL_KEY2_OUT_1_BIT;
334 break;
336 *allow_0_bit_index = SYSRST_CTRL_PIN_ALLOWED_CTL_PWRB_OUT_0_BIT;
337 *allow_1_bit_index = SYSRST_CTRL_PIN_ALLOWED_CTL_PWRB_OUT_1_BIT;
338 break;
340 *allow_0_bit_index = SYSRST_CTRL_PIN_ALLOWED_CTL_BAT_DISABLE_0_BIT;
341 *allow_1_bit_index = SYSRST_CTRL_PIN_ALLOWED_CTL_BAT_DISABLE_1_BIT;
342 break;
344 *allow_0_bit_index = SYSRST_CTRL_PIN_ALLOWED_CTL_Z3_WAKEUP_0_BIT;
345 *allow_1_bit_index = SYSRST_CTRL_PIN_ALLOWED_CTL_Z3_WAKEUP_1_BIT;
346 break;
348 *allow_0_bit_index = SYSRST_CTRL_PIN_ALLOWED_CTL_EC_RST_L_0_BIT;
349 *allow_1_bit_index = SYSRST_CTRL_PIN_ALLOWED_CTL_EC_RST_L_1_BIT;
350 break;
352 *allow_0_bit_index = SYSRST_CTRL_PIN_ALLOWED_CTL_FLASH_WP_L_0_BIT;
353 *allow_1_bit_index = SYSRST_CTRL_PIN_ALLOWED_CTL_FLASH_WP_L_1_BIT;
354 break;
355 default:
356 return false;
357 }
358 return true;
359}
360
361dif_result_t dif_sysrst_ctrl_output_pin_override_set_allowed(
362 const dif_sysrst_ctrl_t *sysrst_ctrl, dif_sysrst_ctrl_pin_t pin,
363 bool allow_zero, bool allow_one) {
364 if (sysrst_ctrl == NULL) {
365 return kDifBadArg;
366 }
367
368 uint32_t allow_0_bit_index;
369 uint32_t allow_1_bit_index;
370 if (!get_output_pin_allowed_bit_indices(pin, &allow_0_bit_index,
371 &allow_1_bit_index)) {
372 return kDifBadArg;
373 }
374
375 if (!mmio_region_read32(sysrst_ctrl->base_addr,
376 SYSRST_CTRL_REGWEN_REG_OFFSET)) {
377 return kDifLocked;
378 }
379
380 uint32_t allowed_values_reg = mmio_region_read32(
381 sysrst_ctrl->base_addr, SYSRST_CTRL_PIN_ALLOWED_CTL_REG_OFFSET);
382 allowed_values_reg =
383 bitfield_bit32_write(allowed_values_reg, allow_0_bit_index, allow_zero);
384 allowed_values_reg =
385 bitfield_bit32_write(allowed_values_reg, allow_1_bit_index, allow_one);
386 mmio_region_write32(sysrst_ctrl->base_addr,
387 SYSRST_CTRL_PIN_ALLOWED_CTL_REG_OFFSET,
388 allowed_values_reg);
389
390 return kDifOk;
391}
392
393dif_result_t dif_sysrst_ctrl_output_pin_override_get_allowed(
394 const dif_sysrst_ctrl_t *sysrst_ctrl, dif_sysrst_ctrl_pin_t pin,
395 bool *allow_zero, bool *allow_one) {
396 if (sysrst_ctrl == NULL || allow_zero == NULL || allow_one == NULL) {
397 return kDifBadArg;
398 }
399
400 uint32_t allow_0_bit_index;
401 uint32_t allow_1_bit_index;
402 if (!get_output_pin_allowed_bit_indices(pin, &allow_0_bit_index,
403 &allow_1_bit_index)) {
404 return kDifBadArg;
405 }
406
407 uint32_t allowed_values_reg = mmio_region_read32(
408 sysrst_ctrl->base_addr, SYSRST_CTRL_PIN_ALLOWED_CTL_REG_OFFSET);
409 *allow_zero = bitfield_bit32_read(allowed_values_reg, allow_0_bit_index);
410 *allow_one = bitfield_bit32_read(allowed_values_reg, allow_1_bit_index);
411
412 return kDifOk;
413}
414
415static bool get_output_pin_ctl_bit_index(dif_sysrst_ctrl_pin_t pin,
416 uint32_t *pin_out_ctl_bit_index) {
417 switch (pin) {
419 *pin_out_ctl_bit_index = SYSRST_CTRL_PIN_OUT_CTL_KEY0_OUT_BIT;
420 break;
422 *pin_out_ctl_bit_index = SYSRST_CTRL_PIN_OUT_CTL_KEY1_OUT_BIT;
423 break;
425 *pin_out_ctl_bit_index = SYSRST_CTRL_PIN_OUT_CTL_KEY2_OUT_BIT;
426 break;
428 *pin_out_ctl_bit_index = SYSRST_CTRL_PIN_OUT_CTL_PWRB_OUT_BIT;
429 break;
431 *pin_out_ctl_bit_index = SYSRST_CTRL_PIN_OUT_CTL_BAT_DISABLE_BIT;
432 break;
434 *pin_out_ctl_bit_index = SYSRST_CTRL_PIN_OUT_CTL_Z3_WAKEUP_BIT;
435 break;
437 *pin_out_ctl_bit_index = SYSRST_CTRL_PIN_OUT_CTL_EC_RST_L_BIT;
438 break;
440 *pin_out_ctl_bit_index = SYSRST_CTRL_PIN_OUT_CTL_FLASH_WP_L_BIT;
441 break;
442 default:
443 return false;
444 }
445 return true;
446}
447
448dif_result_t dif_sysrst_ctrl_output_pin_override_set_enabled(
449 const dif_sysrst_ctrl_t *sysrst_ctrl, dif_sysrst_ctrl_pin_t pin,
450 dif_toggle_t enabled) {
451 if (sysrst_ctrl == NULL || !dif_is_valid_toggle(enabled)) {
452 return kDifBadArg;
453 }
454
455 uint32_t pin_out_ctl_bit_index;
456 if (!get_output_pin_ctl_bit_index(pin, &pin_out_ctl_bit_index)) {
457 return kDifBadArg;
458 }
459
460 uint32_t pin_out_ctl_reg = mmio_region_read32(
461 sysrst_ctrl->base_addr, SYSRST_CTRL_PIN_OUT_CTL_REG_OFFSET);
462 pin_out_ctl_reg = bitfield_bit32_write(pin_out_ctl_reg, pin_out_ctl_bit_index,
463 dif_toggle_to_bool(enabled));
464 mmio_region_write32(sysrst_ctrl->base_addr,
465 SYSRST_CTRL_PIN_OUT_CTL_REG_OFFSET, pin_out_ctl_reg);
466
467 return kDifOk;
468}
469
470dif_result_t dif_sysrst_ctrl_output_pin_override_get_enabled(
471 const dif_sysrst_ctrl_t *sysrst_ctrl, dif_sysrst_ctrl_pin_t pin,
472 dif_toggle_t *is_enabled) {
473 if (sysrst_ctrl == NULL || is_enabled == NULL) {
474 return kDifBadArg;
475 }
476
477 uint32_t pin_out_ctl_bit_index;
478 if (!get_output_pin_ctl_bit_index(pin, &pin_out_ctl_bit_index)) {
479 return kDifBadArg;
480 }
481
482 uint32_t pin_out_ctl_reg = mmio_region_read32(
483 sysrst_ctrl->base_addr, SYSRST_CTRL_PIN_OUT_CTL_REG_OFFSET);
484 *is_enabled = bitfield_bit32_read(pin_out_ctl_reg, pin_out_ctl_bit_index);
485
486 return kDifOk;
487}
488
489static bool get_output_pin_value_bit_index(dif_sysrst_ctrl_pin_t pin,
490 uint32_t *pin_out_value_bit_index) {
491 switch (pin) {
493 *pin_out_value_bit_index = SYSRST_CTRL_PIN_OUT_VALUE_KEY0_OUT_BIT;
494 break;
496 *pin_out_value_bit_index = SYSRST_CTRL_PIN_OUT_VALUE_KEY1_OUT_BIT;
497 break;
499 *pin_out_value_bit_index = SYSRST_CTRL_PIN_OUT_VALUE_KEY2_OUT_BIT;
500 break;
502 *pin_out_value_bit_index = SYSRST_CTRL_PIN_OUT_VALUE_PWRB_OUT_BIT;
503 break;
505 *pin_out_value_bit_index = SYSRST_CTRL_PIN_OUT_VALUE_BAT_DISABLE_BIT;
506 break;
508 *pin_out_value_bit_index = SYSRST_CTRL_PIN_OUT_VALUE_Z3_WAKEUP_BIT;
509 break;
511 *pin_out_value_bit_index = SYSRST_CTRL_PIN_OUT_VALUE_EC_RST_L_BIT;
512 break;
514 *pin_out_value_bit_index = SYSRST_CTRL_PIN_OUT_VALUE_FLASH_WP_L_BIT;
515 break;
516 default:
517 return false;
518 }
519 return true;
520}
521
522dif_result_t dif_sysrst_ctrl_output_pin_set_override(
523 const dif_sysrst_ctrl_t *sysrst_ctrl, dif_sysrst_ctrl_pin_t pin,
524 bool value) {
525 if (sysrst_ctrl == NULL) {
526 return kDifBadArg;
527 }
528
529 uint32_t pin_out_value_bit_index;
530 if (!get_output_pin_value_bit_index(pin, &pin_out_value_bit_index)) {
531 return kDifBadArg;
532 }
533
534 uint32_t pin_out_value_reg = mmio_region_read32(
535 sysrst_ctrl->base_addr, SYSRST_CTRL_PIN_OUT_VALUE_REG_OFFSET);
536 pin_out_value_reg =
537 bitfield_bit32_write(pin_out_value_reg, pin_out_value_bit_index, value);
538 mmio_region_write32(sysrst_ctrl->base_addr,
539 SYSRST_CTRL_PIN_OUT_VALUE_REG_OFFSET, pin_out_value_reg);
540
541 return kDifOk;
542}
543
544dif_result_t dif_sysrst_ctrl_output_pin_get_override(
545 const dif_sysrst_ctrl_t *sysrst_ctrl, dif_sysrst_ctrl_pin_t pin,
546 bool *value) {
547 if (sysrst_ctrl == NULL || value == NULL) {
548 return kDifBadArg;
549 }
550
551 uint32_t pin_out_value_bit_index;
552 if (!get_output_pin_value_bit_index(pin, &pin_out_value_bit_index)) {
553 return kDifBadArg;
554 }
555
556 uint32_t pin_out_value_reg = mmio_region_read32(
557 sysrst_ctrl->base_addr, SYSRST_CTRL_PIN_OUT_VALUE_REG_OFFSET);
558 *value = bitfield_bit32_read(pin_out_value_reg, pin_out_value_bit_index);
559
560 return kDifOk;
561}
562
563static bool get_input_pin_value_bit_index(dif_sysrst_ctrl_pin_t pin,
564 uint32_t *pin_in_value_bit_index) {
565 switch (pin) {
567 *pin_in_value_bit_index = SYSRST_CTRL_PIN_IN_VALUE_KEY0_IN_BIT;
568 break;
570 *pin_in_value_bit_index = SYSRST_CTRL_PIN_IN_VALUE_KEY1_IN_BIT;
571 break;
573 *pin_in_value_bit_index = SYSRST_CTRL_PIN_IN_VALUE_KEY2_IN_BIT;
574 break;
576 *pin_in_value_bit_index = SYSRST_CTRL_PIN_IN_VALUE_PWRB_IN_BIT;
577 break;
579 *pin_in_value_bit_index = SYSRST_CTRL_PIN_IN_VALUE_AC_PRESENT_BIT;
580 break;
582 *pin_in_value_bit_index = SYSRST_CTRL_PIN_IN_VALUE_LID_OPEN_BIT;
583 break;
585 *pin_in_value_bit_index = SYSRST_CTRL_PIN_IN_VALUE_EC_RST_L_BIT;
586 break;
588 *pin_in_value_bit_index = SYSRST_CTRL_PIN_IN_VALUE_FLASH_WP_L_BIT;
589 break;
590 default:
591 return false;
592 }
593 return true;
594}
595
596dif_result_t dif_sysrst_ctrl_input_pin_read(
597 const dif_sysrst_ctrl_t *sysrst_ctrl, dif_sysrst_ctrl_pin_t pin,
598 bool *value) {
599 if (sysrst_ctrl == NULL || value == NULL) {
600 return kDifBadArg;
601 }
602
603 uint32_t pin_in_value_bit_index;
604 if (!get_input_pin_value_bit_index(pin, &pin_in_value_bit_index)) {
605 return kDifBadArg;
606 }
607
608 uint32_t pin_in_value_reg = mmio_region_read32(
609 sysrst_ctrl->base_addr, SYSRST_CTRL_PIN_IN_VALUE_REG_OFFSET);
610 *value = bitfield_bit32_read(pin_in_value_reg, pin_in_value_bit_index);
611
612 return kDifOk;
613}
614
615dif_result_t dif_sysrst_ctrl_auto_override_configure(
616 const dif_sysrst_ctrl_t *sysrst_ctrl,
618 if (sysrst_ctrl == NULL || !dif_is_valid_toggle(config.override_key_0) ||
619 !dif_is_valid_toggle(config.override_key_1) ||
620 !dif_is_valid_toggle(config.override_key_2) ||
621 !dif_is_valid_toggle(enabled)) {
622 return kDifBadArg;
623 }
624
625 if (!mmio_region_read32(sysrst_ctrl->base_addr,
626 SYSRST_CTRL_REGWEN_REG_OFFSET)) {
627 return kDifLocked;
628 }
629
630 // Configure Auto Block Debounce Control register.
631 uint32_t auto_block_ctl_reg = bitfield_bit32_write(
632 0, SYSRST_CTRL_AUTO_BLOCK_DEBOUNCE_CTL_AUTO_BLOCK_ENABLE_BIT,
633 dif_toggle_to_bool(enabled));
634 auto_block_ctl_reg = bitfield_field32_write(
635 auto_block_ctl_reg,
636 SYSRST_CTRL_AUTO_BLOCK_DEBOUNCE_CTL_DEBOUNCE_TIMER_FIELD,
638 mmio_region_write32(sysrst_ctrl->base_addr,
639 SYSRST_CTRL_AUTO_BLOCK_DEBOUNCE_CTL_REG_OFFSET,
640 auto_block_ctl_reg);
641
642 // Configure Auto Block Output Control register.
643 auto_block_ctl_reg =
644 bitfield_bit32_write(0, SYSRST_CTRL_AUTO_BLOCK_OUT_CTL_KEY0_OUT_SEL_BIT,
645 dif_toggle_to_bool(config.override_key_0));
646 auto_block_ctl_reg = bitfield_bit32_write(
647 auto_block_ctl_reg, SYSRST_CTRL_AUTO_BLOCK_OUT_CTL_KEY0_OUT_VALUE_BIT,
648 dif_toggle_to_bool(config.key_0_override_value));
649 auto_block_ctl_reg = bitfield_bit32_write(
650 auto_block_ctl_reg, SYSRST_CTRL_AUTO_BLOCK_OUT_CTL_KEY1_OUT_SEL_BIT,
651 dif_toggle_to_bool(config.override_key_1));
652 auto_block_ctl_reg = bitfield_bit32_write(
653 auto_block_ctl_reg, SYSRST_CTRL_AUTO_BLOCK_OUT_CTL_KEY1_OUT_VALUE_BIT,
654 dif_toggle_to_bool(config.key_1_override_value));
655 auto_block_ctl_reg = bitfield_bit32_write(
656 auto_block_ctl_reg, SYSRST_CTRL_AUTO_BLOCK_OUT_CTL_KEY2_OUT_SEL_BIT,
657 dif_toggle_to_bool(config.override_key_2));
658 auto_block_ctl_reg = bitfield_bit32_write(
659 auto_block_ctl_reg, SYSRST_CTRL_AUTO_BLOCK_OUT_CTL_KEY2_OUT_VALUE_BIT,
660 dif_toggle_to_bool(config.key_2_override_value));
661 mmio_region_write32(sysrst_ctrl->base_addr,
662 SYSRST_CTRL_AUTO_BLOCK_OUT_CTL_REG_OFFSET,
663 auto_block_ctl_reg);
664
665 return kDifOk;
666}
667
668static bool get_key_auto_override_en_bit_index(dif_sysrst_ctrl_key_t key,
669 uint32_t *en_bit_index) {
670 switch (key) {
672 *en_bit_index = SYSRST_CTRL_AUTO_BLOCK_OUT_CTL_KEY0_OUT_SEL_BIT;
673 break;
675 *en_bit_index = SYSRST_CTRL_AUTO_BLOCK_OUT_CTL_KEY1_OUT_SEL_BIT;
676 break;
678 *en_bit_index = SYSRST_CTRL_AUTO_BLOCK_OUT_CTL_KEY2_OUT_SEL_BIT;
679 break;
680 default:
681 return false;
682 }
683 return true;
684}
685
686dif_result_t dif_sysrst_ctrl_auto_override_set_enabled(
687 const dif_sysrst_ctrl_t *sysrst_ctrl, dif_sysrst_ctrl_key_t key,
688 dif_toggle_t enabled) {
689 if (sysrst_ctrl == NULL || !dif_is_valid_toggle(enabled)) {
690 return kDifBadArg;
691 }
692
693 uint32_t en_bit_index;
694 if (!get_key_auto_override_en_bit_index(key, &en_bit_index)) {
695 return kDifBadArg;
696 }
697
698 if (!mmio_region_read32(sysrst_ctrl->base_addr,
699 SYSRST_CTRL_REGWEN_REG_OFFSET)) {
700 return kDifLocked;
701 }
702
703 uint32_t auto_block_ctl_reg = mmio_region_read32(
704 sysrst_ctrl->base_addr, SYSRST_CTRL_AUTO_BLOCK_OUT_CTL_REG_OFFSET);
705 auto_block_ctl_reg = bitfield_bit32_write(auto_block_ctl_reg, en_bit_index,
706 dif_toggle_to_bool(enabled));
707 mmio_region_write32(sysrst_ctrl->base_addr,
708 SYSRST_CTRL_AUTO_BLOCK_OUT_CTL_REG_OFFSET,
709 auto_block_ctl_reg);
710
711 return kDifOk;
712}
713
714dif_result_t dif_sysrst_ctrl_auto_override_get_enabled(
715 const dif_sysrst_ctrl_t *sysrst_ctrl, dif_sysrst_ctrl_key_t key,
716 dif_toggle_t *is_enabled) {
717 if (sysrst_ctrl == NULL || is_enabled == NULL) {
718 return kDifBadArg;
719 }
720
721 uint32_t en_bit_index;
722 if (!get_key_auto_override_en_bit_index(key, &en_bit_index)) {
723 return kDifBadArg;
724 }
725
726 uint32_t auto_block_ctl_reg = mmio_region_read32(
727 sysrst_ctrl->base_addr, SYSRST_CTRL_AUTO_BLOCK_OUT_CTL_REG_OFFSET);
728 *is_enabled =
729 dif_bool_to_toggle(bitfield_bit32_read(auto_block_ctl_reg, en_bit_index));
730
731 return kDifOk;
732}
733
734dif_result_t dif_sysrst_ctrl_key_combo_irq_get_causes(
735 const dif_sysrst_ctrl_t *sysrst_ctrl, uint32_t *causes) {
736 if (sysrst_ctrl == NULL || causes == NULL) {
737 return kDifBadArg;
738 }
739
740 *causes = mmio_region_read32(sysrst_ctrl->base_addr,
741 SYSRST_CTRL_COMBO_INTR_STATUS_REG_OFFSET);
742
743 return kDifOk;
744}
745
746dif_result_t dif_sysrst_ctrl_key_combo_irq_clear_causes(
747 const dif_sysrst_ctrl_t *sysrst_ctrl, uint32_t causes) {
748 if (sysrst_ctrl == NULL || causes >= (1U << SYSRST_CTRL_PARAM_NUM_COMBO)) {
749 return kDifBadArg;
750 }
751
752 mmio_region_write32(sysrst_ctrl->base_addr,
753 SYSRST_CTRL_COMBO_INTR_STATUS_REG_OFFSET, causes);
754
755 return kDifOk;
756}
757
758dif_result_t dif_sysrst_ctrl_input_change_irq_get_causes(
759 const dif_sysrst_ctrl_t *sysrst_ctrl, uint32_t *causes) {
760 if (sysrst_ctrl == NULL || causes == NULL) {
761 return kDifBadArg;
762 }
763
764 *causes = mmio_region_read32(sysrst_ctrl->base_addr,
765 SYSRST_CTRL_KEY_INTR_STATUS_REG_OFFSET);
766
767 return kDifOk;
768}
769
770dif_result_t dif_sysrst_ctrl_input_change_irq_clear_causes(
771 const dif_sysrst_ctrl_t *sysrst_ctrl, uint32_t causes) {
772 if (sysrst_ctrl == NULL ||
773 causes >= (1U << (SYSRST_CTRL_KEY_INTR_STATUS_FLASH_WP_L_L2H_BIT + 1))) {
774 return kDifBadArg;
775 }
776
777 mmio_region_write32(sysrst_ctrl->base_addr,
778 SYSRST_CTRL_KEY_INTR_STATUS_REG_OFFSET, causes);
779 return kDifOk;
780}
781
782dif_result_t dif_sysrst_ctrl_ulp_wakeup_get_status(
783 const dif_sysrst_ctrl_t *sysrst_ctrl, bool *wakeup_detected) {
784 if (sysrst_ctrl == NULL || wakeup_detected == NULL) {
785 return kDifBadArg;
786 }
787
788 *wakeup_detected = mmio_region_read32(sysrst_ctrl->base_addr,
789 SYSRST_CTRL_WKUP_STATUS_REG_OFFSET);
790
791 return kDifOk;
792}
793
794dif_result_t dif_sysrst_ctrl_ulp_wakeup_clear_status(
795 const dif_sysrst_ctrl_t *sysrst_ctrl) {
796 if (sysrst_ctrl == NULL) {
797 return kDifBadArg;
798 }
799
800 mmio_region_write32(sysrst_ctrl->base_addr,
801 SYSRST_CTRL_WKUP_STATUS_REG_OFFSET, 1);
802
803 return kDifOk;
804}
805
806dif_result_t dif_sysrst_ctrl_lock(const dif_sysrst_ctrl_t *sysrst_ctrl) {
807 if (sysrst_ctrl == NULL) {
808 return kDifBadArg;
809 }
810
811 mmio_region_write32(sysrst_ctrl->base_addr, SYSRST_CTRL_REGWEN_REG_OFFSET, 0);
812
813 return kDifOk;
814}
815
816dif_result_t dif_sysrst_ctrl_is_locked(const dif_sysrst_ctrl_t *sysrst_ctrl,
817 bool *is_locked) {
818 if (sysrst_ctrl == NULL || is_locked == NULL) {
819 return kDifBadArg;
820 }
821
822 *is_locked = !mmio_region_read32(sysrst_ctrl->base_addr,
823 SYSRST_CTRL_REGWEN_REG_OFFSET);
824
825 return kDifOk;
826}