Software APIs
pwrmgr_b2b_sleep_reset_test.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 
14 #include "sw/device/lib/testing/aon_timer_testutils.h"
15 #include "sw/device/lib/testing/flash_ctrl_testutils.h"
16 #include "sw/device/lib/testing/nv_counter_testutils.h"
17 #include "sw/device/lib/testing/pwrmgr_testutils.h"
18 #include "sw/device/lib/testing/rstmgr_testutils.h"
19 #include "sw/device/lib/testing/test_framework/check.h"
21 
22 #include "aon_timer_regs.h"
24 /*
25  PWRMGR BACK TO BACK DEEP SLEEP, RESET / WAKEUP TEST
26 
27  This test introduces reset or wakeup event close to (before or after)
28  entering low power state.
29 
30  'kNumRound' is set to 10 by sv sequence (chip_sw_repeat_reset_wkup_vseq.sv)
31 
32  For the reset event, the sequence assert power on resets by driving POR_N
33  PAD. For the wake up event, the sequence assert power button in by driving
34  IOR13 PAD.
35 
36  */
37 OTTF_DEFINE_TEST_CONFIG();
38 
39 static volatile const uint8_t kNumRound;
40 
41 static dif_flash_ctrl_state_t flash_ctrl;
42 static dif_sysrst_ctrl_t sysrst_ctrl;
43 static dif_pinmux_t pinmux;
44 
45 /**
46  * sysrst_ctrl config for test #1
47  * . set sysrst_ctrl.KEY_INTR_CTL.pwrb_in_H2L to 1
48  * . use IOR13 as pwrb_in
49  */
50 static void prgm_push_button_wakeup(void) {
53  .debounce_time_threshold = 1, // 5us
54  };
55  CHECK_DIF_OK(
56  dif_sysrst_ctrl_input_change_detect_configure(&sysrst_ctrl, config));
57  CHECK_DIF_OK(dif_pinmux_input_select(
60 }
61 
62 bool test_main(void) {
63  // Issue a wakeup signal in ~1.5 ms through the AON timer.
64  // This timer is needed when reset or wakeup fail to
65  // bring state machine back to active state.
66  // This can happen when wake up event comes before low power
67  // entry event.
68  uint64_t wakeup_threshold = kDeviceType == kDeviceSimVerilator ? 3000 : 300;
69 
70  // Initialize pwrmgr
71  dif_pwrmgr_t pwrmgr;
72  CHECK_DIF_OK(dif_pwrmgr_init(
74 
75  // Initialize rstmgr since this will check some registers.
76  dif_rstmgr_t rstmgr;
77  CHECK_DIF_OK(dif_rstmgr_init(
79 
80  // Initialize flash_ctrl
81  CHECK_DIF_OK(dif_flash_ctrl_init_state(
82  &flash_ctrl,
84 
85  // Initialize sysrst_ctrl
86  CHECK_DIF_OK(dif_sysrst_ctrl_init(
88  &sysrst_ctrl));
89 
90  // Initialize pinmux
91  CHECK_DIF_OK(dif_pinmux_init(
93 
94  // First check the flash stored value
95  uint32_t event_idx = 0;
96  CHECK_STATUS_OK(flash_ctrl_testutils_counter_get(0, &event_idx));
97  // Enable flash access
98  CHECK_STATUS_OK(
99  flash_ctrl_testutils_default_region_access(&flash_ctrl,
100  /*rd_en*/ true,
101  /*prog_en*/ true,
102  /*erase_en*/ true,
103  /*scramble_en*/ false,
104  /*ecc_en*/ false,
105  /*he_en*/ false));
106 
107  // Increment flash counter to know where we are
108  CHECK_STATUS_OK(flash_ctrl_testutils_counter_increment(&flash_ctrl, 0));
109 
110  // Read wakeup reason before check
111  dif_pwrmgr_wakeup_reason_t wakeup_reason;
112  CHECK_DIF_OK(dif_pwrmgr_wakeup_reason_get(&pwrmgr, &wakeup_reason));
113  LOG_INFO("wakeup type:%d wakeup reason: 0x%02X", wakeup_reason.types,
114  wakeup_reason.request_sources);
115 
116  if (wakeup_reason.types == 0) {
117  // POR reset
118  CHECK(wakeup_reason.request_sources == 0);
119  } else if (wakeup_reason.types == kDifPwrmgrWakeupTypeRequest) {
120  // sysrst_ctrl or aon_timer
121  CHECK(wakeup_reason.request_sources == (kDifPwrmgrWakeupRequestSourceOne |
122  kDifPwrmgrWakeupRequestSourceFive));
123  } else {
124  LOG_ERROR("unexpected wakeup_type: 0x%x", wakeup_reason.types);
125  }
126 
127  // Read reset info before check
129  rst_info = rstmgr_testutils_reason_get();
130  rstmgr_testutils_reason_clear();
131  LOG_INFO("reset info = 0x%02X", rst_info);
132 
133  if (rst_info != kDifRstmgrResetInfoPor &&
134  rst_info != kDifRstmgrResetInfoLowPowerExit) {
135  LOG_ERROR("unexpected reset info: 0x%x", rst_info);
136  }
137 
138  dif_aon_timer_t aon_timer;
139  CHECK_DIF_OK(dif_aon_timer_init(
141 
142  // Status clean up
143  if (event_idx > 0) {
144  // aon timer clean up
145  CHECK_DIF_OK(dif_aon_timer_wakeup_stop(&aon_timer));
146  // mmio_region_write32(
147  // mmio_region_from_addr(TOP_EARLGREY_AON_TIMER_AON_BASE_ADDR),
148  // AON_TIMER_WKUP_CAUSE_REG_OFFSET, 0);
149  CHECK_DIF_OK(dif_aon_timer_clear_wakeup_cause(&aon_timer));
150  // sysrst ctrl status clean up
151  CHECK_DIF_OK(dif_sysrst_ctrl_ulp_wakeup_clear_status(&sysrst_ctrl));
152  }
153 
154  if (event_idx < kNumRound) {
155  LOG_INFO("Test round %d", event_idx);
156  } else {
157  LOG_INFO("Test finish");
158  return true;
159  }
160 
161  // pin mux / sysrst ctrl set up for push button wakeup
162  prgm_push_button_wakeup();
163 
164  // Prepare rstmgr for a reset.
165  CHECK_STATUS_OK(rstmgr_testutils_pre_reset(&rstmgr));
166 
167  // This is mark for sv sequence to prepare to asserting parallel event.
168  LOG_INFO("ready for power down");
169  busy_spin_micros(10);
170  // timer setup in case wake up comes before entering low power mode
171  CHECK_STATUS_OK(
172  aon_timer_testutils_wakeup_config(&aon_timer, wakeup_threshold));
173 
174  // Deep sleep.
175  CHECK_STATUS_OK(pwrmgr_testutils_enable_low_power(
176  &pwrmgr,
177  (kDifPwrmgrWakeupRequestSourceOne | kDifPwrmgrWakeupRequestSourceTwo |
178  kDifPwrmgrWakeupRequestSourceThree | kDifPwrmgrWakeupRequestSourceFour |
179  kDifPwrmgrWakeupRequestSourceFive | kDifPwrmgrWakeupRequestSourceSix),
180  0));
181 
182  // Enter low power mode.
184 
185  return false;
186 }