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 
15 static_assert(SYSRST_CTRL_PARAM_NUM_COMBO == 4,
16  "Number of key combinations has changed. Update the "
17  "dif_sysrst_ctrl_key_combo_t enum.");
18 static_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 
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 
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,
122  config.debounce_time_threshold);
123 
124  return kDifOk;
125 }
126 
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 
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 
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 
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 
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 
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 
319 static 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 
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 
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 
415 static 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 
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 
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 
489 static 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 
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 
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 
563 static 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 
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 
616  const dif_sysrst_ctrl_t *sysrst_ctrl,
618  if (sysrst_ctrl == NULL || !dif_is_valid_toggle(config.override_key_0) ||
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,
637  config.debounce_time_threshold);
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,
646  auto_block_ctl_reg = bitfield_bit32_write(
647  auto_block_ctl_reg, SYSRST_CTRL_AUTO_BLOCK_OUT_CTL_KEY0_OUT_VALUE_BIT,
649  auto_block_ctl_reg = bitfield_bit32_write(
650  auto_block_ctl_reg, SYSRST_CTRL_AUTO_BLOCK_OUT_CTL_KEY1_OUT_SEL_BIT,
652  auto_block_ctl_reg = bitfield_bit32_write(
653  auto_block_ctl_reg, SYSRST_CTRL_AUTO_BLOCK_OUT_CTL_KEY1_OUT_VALUE_BIT,
655  auto_block_ctl_reg = bitfield_bit32_write(
656  auto_block_ctl_reg, SYSRST_CTRL_AUTO_BLOCK_OUT_CTL_KEY2_OUT_SEL_BIT,
658  auto_block_ctl_reg = bitfield_bit32_write(
659  auto_block_ctl_reg, SYSRST_CTRL_AUTO_BLOCK_OUT_CTL_KEY2_OUT_VALUE_BIT,
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 
668 static bool get_key_auto_override_en_bit_index(dif_sysrst_ctrl_key_t key,
669  uint32_t *en_bit_index) {
670  switch (key) {
671  case kDifSysrstCtrlKey0:
672  *en_bit_index = SYSRST_CTRL_AUTO_BLOCK_OUT_CTL_KEY0_OUT_SEL_BIT;
673  break;
674  case kDifSysrstCtrlKey1:
675  *en_bit_index = SYSRST_CTRL_AUTO_BLOCK_OUT_CTL_KEY1_OUT_SEL_BIT;
676  break;
677  case kDifSysrstCtrlKey2:
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 }