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"
23 /*
24  PWRMGR BACK TO BACK DEEP SLEEP, RESET / WAKEUP TEST
25 
26  This test introduces reset or wakeup event close to (before or after)
27  entering low power state.
28 
29  'kNumRound' is set to 10 by sv sequence (chip_sw_repeat_reset_wkup_vseq.sv)
30 
31  For the reset event, the sequence assert power on resets by driving POR_N
32  PAD. For the wake up event, the sequence assert power button in by driving
33  IOR13 PAD.
34 
35  */
36 OTTF_DEFINE_TEST_CONFIG();
37 
38 static const dt_rstmgr_t kRstmgrDt = 0;
39 static_assert(kDtRstmgrCount == 1, "this test expects a rstmgr");
40 static const dt_pwrmgr_t kPwrmgrDt = 0;
41 static_assert(kDtPwrmgrCount == 1, "this test expects a pwrmgr");
42 static const dt_pinmux_t kPinmuxDt = 0;
43 static_assert(kDtPinmuxCount == 1, "this test expects exactly one pinmux");
44 static const dt_flash_ctrl_t kFlashCtrlDt = 0;
45 static_assert(kDtFlashCtrlCount >= 1,
46  "this library expects at least one flash_ctrl");
47 static_assert(kDtSysrstCtrlCount >= 1,
48  "this test expects at least one sysrst_ctrl");
49 static const dt_sysrst_ctrl_t kSysrstCtrlDt = 0;
50 static_assert(kDtAonTimerCount == 1, "this test expects an aon_timer");
51 static const dt_aon_timer_t kAonTimerDt = 0;
52 
53 static volatile const uint8_t kNumRound;
54 
55 static dif_flash_ctrl_state_t flash_ctrl;
56 static dif_sysrst_ctrl_t sysrst_ctrl;
57 static dif_pinmux_t pinmux;
58 
59 /**
60  * sysrst_ctrl config for test #1
61  * . set sysrst_ctrl.KEY_INTR_CTL.pwrb_in_H2L to 1
62  * . use IOR13 as pwrb_in
63  */
64 static void prgm_push_button_wakeup(void) {
67  .debounce_time_threshold = 1, // 5us
68  };
69  CHECK_DIF_OK(
70  dif_sysrst_ctrl_input_change_detect_configure(&sysrst_ctrl, config));
71  CHECK_DIF_OK(dif_pinmux_mio_select_input(
72  &pinmux,
73  dt_sysrst_ctrl_periph_io(kSysrstCtrlDt, kDtSysrstCtrlPeriphIoPwrbIn),
74  kDtPadIor13));
75 }
76 
77 bool test_main(void) {
78  // Issue a wakeup signal in ~1.5 ms through the AON timer.
79  // This timer is needed when reset or wakeup fail to
80  // bring state machine back to active state.
81  // This can happen when wake up event comes before low power
82  // entry event.
83  uint64_t wakeup_threshold = kDeviceType == kDeviceSimVerilator ? 3000 : 300;
84 
85  // Initialize pwrmgr
86  dif_pwrmgr_t pwrmgr;
87  CHECK_DIF_OK(dif_pwrmgr_init_from_dt(kPwrmgrDt, &pwrmgr));
88 
89  // Initialize rstmgr since this will check some registers.
90  dif_rstmgr_t rstmgr;
91  CHECK_DIF_OK(dif_rstmgr_init_from_dt(kRstmgrDt, &rstmgr));
92 
93  // Initialize flash_ctrl
94  CHECK_DIF_OK(dif_flash_ctrl_init_state_from_dt(&flash_ctrl, kFlashCtrlDt));
95 
96  // Initialize sysrst_ctrl
97  CHECK_DIF_OK(dif_sysrst_ctrl_init_from_dt(kSysrstCtrlDt, &sysrst_ctrl));
98 
99  // Initialize pinmux
100  CHECK_DIF_OK(dif_pinmux_init_from_dt(kPinmuxDt, &pinmux));
101 
102  // First check the flash stored value
103  uint32_t event_idx = 0;
104  CHECK_STATUS_OK(flash_ctrl_testutils_counter_get(0, &event_idx));
105  // Enable flash access
106  CHECK_STATUS_OK(
107  flash_ctrl_testutils_default_region_access(&flash_ctrl,
108  /*rd_en*/ true,
109  /*prog_en*/ true,
110  /*erase_en*/ true,
111  /*scramble_en*/ false,
112  /*ecc_en*/ false,
113  /*he_en*/ false));
114 
115  // Increment flash counter to know where we are
116  CHECK_STATUS_OK(flash_ctrl_testutils_counter_increment(&flash_ctrl, 0));
117 
118  // Read wakeup reason before check
119  dif_pwrmgr_wakeup_reason_t wakeup_reason;
120  CHECK_DIF_OK(dif_pwrmgr_wakeup_reason_get(&pwrmgr, &wakeup_reason));
121  LOG_INFO("wakeup type:%d wakeup reason: 0x%02X", wakeup_reason.types,
122  wakeup_reason.request_sources);
123 
124  dif_pwrmgr_request_sources_t pwrmgr_aon_timer_wakeups;
125  CHECK_DIF_OK(dif_pwrmgr_find_request_source(
126  &pwrmgr, kDifPwrmgrReqTypeWakeup, dt_aon_timer_instance_id(kAonTimerDt),
127  kDtAonTimerWakeupWkupReq, &pwrmgr_aon_timer_wakeups));
128  dif_pwrmgr_request_sources_t pwrmgr_sysrst_ctrl_wakeups;
129  CHECK_DIF_OK(dif_pwrmgr_find_request_source(
130  &pwrmgr, kDifPwrmgrReqTypeWakeup,
131  dt_sysrst_ctrl_instance_id(kSysrstCtrlDt), kDtSysrstCtrlWakeupWkupReq,
132  &pwrmgr_sysrst_ctrl_wakeups));
133  dif_pwrmgr_request_sources_t pwrmgr_all_wakeups;
135  &pwrmgr, kDifPwrmgrReqTypeWakeup, &pwrmgr_all_wakeups));
136 
137  if (wakeup_reason.types == 0) {
138  // POR reset
139  CHECK(wakeup_reason.request_sources == 0);
140  } else if (wakeup_reason.types == kDifPwrmgrWakeupTypeRequest) {
141  // sysrst_ctrl or aon_timer
142  CHECK(wakeup_reason.request_sources ==
143  (pwrmgr_sysrst_ctrl_wakeups | pwrmgr_aon_timer_wakeups));
144  } else {
145  LOG_ERROR("unexpected wakeup_type: 0x%x", wakeup_reason.types);
146  }
147 
148  // Read reset info before check
150  rst_info = rstmgr_testutils_reason_get();
151  rstmgr_testutils_reason_clear();
152  LOG_INFO("reset info = 0x%02X", rst_info);
153 
154  if (rst_info != kDifRstmgrResetInfoPor &&
155  rst_info != kDifRstmgrResetInfoLowPowerExit) {
156  LOG_ERROR("unexpected reset info: 0x%x", rst_info);
157  }
158 
159  dif_aon_timer_t aon_timer;
160  CHECK_DIF_OK(dif_aon_timer_init_from_dt(kAonTimerDt, &aon_timer));
161 
162  // Status clean up
163  if (event_idx > 0) {
164  // aon timer clean up
165  CHECK_DIF_OK(dif_aon_timer_wakeup_stop(&aon_timer));
166  // mmio_region_write32(
167  // mmio_region_from_addr(TOP_EARLGREY_AON_TIMER_AON_BASE_ADDR),
168  // AON_TIMER_WKUP_CAUSE_REG_OFFSET, 0);
169  CHECK_DIF_OK(dif_aon_timer_clear_wakeup_cause(&aon_timer));
170  // sysrst ctrl status clean up
171  CHECK_DIF_OK(dif_sysrst_ctrl_ulp_wakeup_clear_status(&sysrst_ctrl));
172  }
173 
174  if (event_idx < kNumRound) {
175  LOG_INFO("Test round %d", event_idx);
176  } else {
177  LOG_INFO("Test finish");
178  return true;
179  }
180 
181  // pin mux / sysrst ctrl set up for push button wakeup
182  prgm_push_button_wakeup();
183 
184  // Prepare rstmgr for a reset.
185  CHECK_STATUS_OK(rstmgr_testutils_pre_reset(&rstmgr));
186 
187  // This is mark for sv sequence to prepare to asserting parallel event.
188  LOG_INFO("ready for power down");
189  busy_spin_micros(10);
190  // timer setup in case wake up comes before entering low power mode
191  CHECK_STATUS_OK(
192  aon_timer_testutils_wakeup_config(&aon_timer, wakeup_threshold));
193 
194  // Deep sleep.
195  CHECK_STATUS_OK(
196  pwrmgr_testutils_enable_low_power(&pwrmgr, pwrmgr_all_wakeups, 0));
197 
198  // Enter low power mode.
200 
201  return false;
202 }