8 #include "sw/device/tests/pwrmgr_sleep_all_wake_ups_impl.h"
10 #include "dt/dt_aon_timer.h"
16 #include "sw/device/lib/testing/aon_timer_testutils.h"
17 #include "sw/device/lib/testing/pwrmgr_testutils.h"
18 #include "sw/device/lib/testing/rv_plic_testutils.h"
21 #include "dt/dt_adc_ctrl.h"
24 #ifdef HAS_SENSOR_CTRL
25 #include "dt/dt_sensor_ctrl.h"
28 #include "sensor_ctrl_regs.h"
30 #ifdef HAS_SYSRST_CTRL
31 #include "dt/dt_sysrst_ctrl.h"
35 #include "dt/dt_usbdev.h"
39 static const uint32_t kPinmuxWkupDetector5 = 5;
40 static const uint32_t kSensorCtrlEventIdx = 0;
46 static const dt_pwrmgr_t kPwrmgrDt = 0;
47 static_assert(kDtPwrmgrCount == 1,
"this library expects exactly one pwrmgr");
48 static const dt_pinmux_t kPinmuxDt = 0;
49 static_assert(kDtPinmuxCount == 1,
"this library expects exactly one pinmux");
50 static const dt_rv_plic_t kRvPlicDt = 0;
51 static_assert(kDtRvPlicCount == 1,
"this library expects exactly one rv_plic");
54 dif_rv_plic_t rv_plic;
56 #define INIT_DIF_DT(__mod_name, __src, __difname) \
57 dt_##__mod_name##_t __dt = dt_##__mod_name##_from_instance_id(src.inst_id); \
58 dif_##__mod_name##_t __difname; \
59 CHECK_DIF_OK(dif_##__mod_name##_init_from_dt(__dt, &__difname));
61 #ifdef HAS_SYSRST_CTRL
67 static void sysrst_ctrl_wakeup_config(dt_pwrmgr_wakeup_src_t src) {
68 INIT_DIF_DT(sysrst_ctrl, src, sysrst_ctrl)
71 .debounce_time_threshold = 1,
76 CHECK_DIF_OK(dif_pinmux_init_from_dt(kPinmuxDt, &pinmux));
83 static void sysrst_ctrl_wakeup_check(dt_pwrmgr_wakeup_src_t src) {
84 INIT_DIF_DT(sysrst_ctrl, src, sysrst_ctrl)
85 bool has_wakeup =
false;
88 CHECK(has_wakeup,
"Expected sysrst_ctrl wakeup to be set");
91 static void sysrst_ctrl_wakeup_clear(dt_pwrmgr_wakeup_src_t src) {
92 INIT_DIF_DT(sysrst_ctrl, src, sysrst_ctrl)
97 .debounce_time_threshold = 0,
106 static bool adc_ctrl_skip(dt_pwrmgr_wakeup_src_t src) {
114 static void adc_ctrl_wakeup_config(dt_pwrmgr_wakeup_src_t src) {
115 INIT_DIF_DT(adc_ctrl, src, adc_ctrl)
118 .power_up_time_aon_cycles = 7,
119 .wake_up_time_aon_cycles = 100,
120 .num_low_power_samples = 2,
121 .num_normal_power_samples = 8,
126 .
filter = kDifAdcCtrlFilter5,
130 .generate_wakeup_on_match =
true,
131 .generate_irq_on_match =
false,
143 static void adc_ctrl_wakeup_check(dt_pwrmgr_wakeup_src_t src) {
144 INIT_DIF_DT(adc_ctrl, src, adc_ctrl)
145 uint32_t filter_status = 0;
149 CHECK(filter_status == ((1 << kDifAdcCtrlFilter5) | (1 << kDifAdcCtrlTrans)),
150 "Expected bits %d and %d set in filter status, got status 0x%x",
151 kDifAdcCtrlFilter5, kDifAdcCtrlTrans, filter_status);
154 static void adc_ctrl_wakeup_clear(dt_pwrmgr_wakeup_src_t src) {
155 INIT_DIF_DT(adc_ctrl, src, adc_ctrl)
166 static void pinmux_wakeup_config(dt_pwrmgr_wakeup_src_t src) {
167 INIT_DIF_DT(pinmux, src, pinmux)
168 #ifdef OPENTITAN_IS_EARLGREY
175 #error Unsupported top, please provide a pin configuration
180 .pad_select = wakeup_pin,
182 .counter_threshold = 0 ,
190 ? kDifPinmuxPadAttrPullResistorEnable
199 static void pinmux_wakeup_check(dt_pwrmgr_wakeup_src_t src) {
200 INIT_DIF_DT(pinmux, src, pinmux)
201 uint32_t wakeup_cause;
203 CHECK(wakeup_cause == 1 << kPinmuxWkupDetector5,
204 "Expected pinmux wakeup cause 5");
207 static void pinmux_wakeup_clear(dt_pwrmgr_wakeup_src_t src) {
208 INIT_DIF_DT(pinmux, src, pinmux)
220 static void usb_wakeup_config(dt_pwrmgr_wakeup_src_t src) {
223 static const dt_usbdev_t dt = 0;
224 static_assert(kDtUsbdevCount == 1,
"expect exactly one usbdev");
225 CHECK_DIF_OK(dif_usbdev_init_from_dt(dt, &usbdev));
229 .dn_pullup_en =
false,
234 LOG_INFO(
"usb_wakeup_config: wait 20us (usb)");
239 static void usb_wakeup_check(dt_pwrmgr_wakeup_src_t src) {
243 static void usb_wakeup_clear(dt_pwrmgr_wakeup_src_t src) {
244 INIT_DIF_DT(pinmux, src, pinmux)
246 static const dt_usbdev_t dt_usbdev = 0;
247 static_assert(kDtUsbdevCount == 1,
"expect exactly one usbdev");
248 CHECK_DIF_OK(dif_usbdev_init_from_dt(dt_usbdev, &usbdev));
261 static void aontimer_wakeup_config(dt_pwrmgr_wakeup_src_t src) {
262 INIT_DIF_DT(aon_timer, src, aon_timer)
263 CHECK_STATUS_OK(aon_timer_testutils_wakeup_config(&aon_timer, 10));
266 static void aontimer_wakeup_check(dt_pwrmgr_wakeup_src_t src) {
267 INIT_DIF_DT(aon_timer, src, aon_timer)
270 CHECK(cause,
"Expected aontimer wakeup cause to be enabled");
273 static void aontimer_wakeup_clear(dt_pwrmgr_wakeup_src_t src) {
274 INIT_DIF_DT(aon_timer, src, aon_timer)
281 #ifdef HAS_SENSOR_CTRL
286 static void sensor_ctrl_wakeup_config(dt_pwrmgr_wakeup_src_t src) {
287 INIT_DIF_DT(sensor_ctrl, src, sensor_ctrl)
289 for (uint32_t k = 0; k < SENSOR_CTRL_PARAM_NUM_ALERT_EVENTS; k++) {
297 static void sensor_ctrl_wakeup_check(dt_pwrmgr_wakeup_src_t src) {
298 INIT_DIF_DT(sensor_ctrl, src, sensor_ctrl)
302 &sensor_ctrl, kSensorCtrlEventIdx, &enable));
305 CHECK(events & (1 << kSensorCtrlEventIdx),
"Expected bit %d to be set",
306 kSensorCtrlEventIdx);
309 static void sensor_ctrl_wakeup_clear(dt_pwrmgr_wakeup_src_t src) {
310 INIT_DIF_DT(sensor_ctrl, src, sensor_ctrl)
318 &sensor_ctrl, kSensorCtrlEventIdx, &enable));
322 CHECK(events == 0,
"Expected recoverable events to be clear, got 0x%x",
328 #ifdef HAS_SYSRST_CTRL
330 .
name =
"SYSRST_CTRL",
331 .dev_type = kDtDeviceTypeSysrstCtrl,
332 .wakeup = kDtSysrstCtrlWakeupWkupReq,
334 .config = sysrst_ctrl_wakeup_config,
335 .check = sysrst_ctrl_wakeup_check,
336 .clear = sysrst_ctrl_wakeup_clear,
342 .dev_type = kDtDeviceTypeAdcCtrl,
343 .wakeup = kDtAdcCtrlWakeupWkupReq,
344 .skip = adc_ctrl_skip,
345 .config = adc_ctrl_wakeup_config,
346 .check = adc_ctrl_wakeup_check,
347 .clear = adc_ctrl_wakeup_clear,
352 .dev_type = kDtDeviceTypePinmux,
353 .wakeup = kDtPinmuxWakeupPinWkupReq,
355 .config = pinmux_wakeup_config,
356 .check = pinmux_wakeup_check,
357 .clear = pinmux_wakeup_clear,
362 .dev_type = kDtDeviceTypePinmux,
363 .wakeup = kDtPinmuxWakeupUsbWkupReq,
365 .config = usb_wakeup_config,
366 .check = usb_wakeup_check,
367 .clear = usb_wakeup_clear,
372 .dev_type = kDtDeviceTypeAonTimer,
373 .wakeup = kDtAonTimerWakeupWkupReq,
375 .config = aontimer_wakeup_config,
376 .check = aontimer_wakeup_check,
377 .clear = aontimer_wakeup_clear,
379 #ifdef HAS_SENSOR_CTRL
381 .name =
"SENSOR_CTRL",
382 .dev_type = kDtDeviceTypeSensorCtrl,
383 .wakeup = kDtSensorCtrlWakeupWkupReq,
385 .config = sensor_ctrl_wakeup_config,
386 .check = sensor_ctrl_wakeup_check,
387 .clear = sensor_ctrl_wakeup_clear,
393 size_t wakeup_unit, dt_pwrmgr_wakeup_src_t *out_src) {
394 dt_pwrmgr_wakeup_src_t src = dt_pwrmgr_wakeup_src(kPwrmgrDt, wakeup_unit);
398 for (
size_t idx = 0; idx <
ARRAYSIZE(kTestWakeupSources); idx++) {
399 if (dt_device_type(src.inst_id) == kTestWakeupSources[idx].dev_type &&
400 src.wakeup == kTestWakeupSources[idx].wakeup) {
401 return &kTestWakeupSources[idx];
404 LOG_ERROR(
"unable to test wakeup source %d (inst_id=%d, wkup=%d)",
405 wakeup_unit, src.inst_id, src.wakeup);
409 void init_units(
void) {
410 CHECK_DIF_OK(dif_pwrmgr_init_from_dt(kPwrmgrDt, &pwrmgr));
411 CHECK_DIF_OK(dif_rv_plic_init_from_dt(kRvPlicDt, &rv_plic));
414 dt_pwrmgr_irq_to_plic_id(kPwrmgrDt, kDtPwrmgrIrqWakeup);
415 rv_plic_testutils_irq_range_enable(&rv_plic, kPlicTarget, irq_id, irq_id);
420 size_t get_wakeup_count(
void) {
return dt_pwrmgr_wakeup_src_count(kPwrmgrDt); }
422 bool execute_test(
size_t wakeup_unit,
bool deep_sleep) {
423 dt_pwrmgr_wakeup_src_t wakeup;
425 CHECK(src,
"cannot execute test");
427 if (src->
skip && src->
skip(wakeup)) {
440 cfg &= ~kDifPwrmgrDomainOptionMainPowerInLowPower;
442 cfg |= kDifPwrmgrDomainOptionMainPowerInLowPower;
445 pwrmgr_testutils_enable_low_power(&pwrmgr, 1 << wakeup_unit, cfg));
446 LOG_INFO(
"Issue WFI to enter sleep %d", wakeup_unit);
451 void check_wakeup_reason(
size_t wakeup_unit) {
452 dt_pwrmgr_wakeup_src_t wakeup;
454 CHECK(src,
"cannot execute test");
458 CHECK(UNWRAP(pwrmgr_testutils_is_wakeup_reason(&pwrmgr, 1 << wakeup_unit)),
459 "wakeup reason wrong exp:%x obs:%x", wakeup_unit, wakeup_reason);
464 static bool get_wakeup_status(
void) {
468 return (wake_req > 0);
471 void clear_wakeup(
size_t wakeup_unit) {
472 dt_pwrmgr_wakeup_src_t wakeup;
474 CHECK(src,
"cannot execute test");
486 bool ottf_handle_irq(uint32_t *exc_info, dt_instance_id_t devid,
488 if (devid == dt_pwrmgr_instance_id(kPwrmgrDt) &&
489 irq_id == dt_pwrmgr_irq_to_plic_id(kPwrmgrDt, kDtPwrmgrIrqWakeup)) {
490 CHECK_DIF_OK(dif_pwrmgr_irq_acknowledge(&pwrmgr, kDtPwrmgrIrqWakeup));