8 #include "sw/device/lib/runtime/irq.h"
10 #include "sw/device/lib/testing/pwrmgr_testutils.h"
11 #include "sw/device/lib/testing/rand_testutils.h"
12 #include "sw/device/lib/testing/rv_plic_testutils.h"
13 #include "sw/device/lib/testing/test_framework/check.h"
16 OTTF_DEFINE_TEST_CONFIG();
37 #if defined(OPENTITAN_IS_EARLGREY)
38 static const dt_pad_t kOptOut[] = {
42 #elif defined(OPENTITAN_IS_DARJEELING)
43 static const dt_pad_t kOptOut[] = {};
45 #error Unsupported top
48 static uint8_t kPads[kDtPadCount] = {0};
51 static dif_pwrmgr_t pwrmgr;
52 static dif_pinmux_t pinmux;
53 static dif_rv_plic_t plic;
58 bool ottf_handle_irq(uint32_t *exc_info, dt_instance_id_t devid,
60 if (devid != dt_pwrmgr_instance_id(kDtPwrmgrAon)) {
64 dt_pwrmgr_irq_t irq = dt_pwrmgr_irq_from_plic_id(kDtPwrmgrAon, irq_id);
65 CHECK(irq == kDtPwrmgrIrqWakeup,
"IRQ ID: %d is incorrect", irq);
66 CHECK_DIF_OK(dif_pwrmgr_irq_acknowledge(&pwrmgr, irq));
75 void draw_pinmux_ret(uint32_t num_pins, uint8_t *arr,
const dt_pad_t *optout,
77 for (uint32_t i = 0; i < num_pins; i += 16) {
78 uint32_t val = rand_testutils_gen32();
79 uint32_t min_idx = (i + 16 < num_pins) ? i + 16 : num_pins;
81 for (uint32_t j = i; j < min_idx; j++) {
83 arr[j] = (val >> ((j & 0xF) * 2)) & 0x3;
85 arr[j] = (uint8_t)rand_testutils_gen32_range(0, 2);
91 for (
int i = 0; i < num_optout; i++) {
103 void print_chosen_values(
void) {
104 LOG_INFO(
"BEGIN Chosen Retention Types");
106 for (dt_pad_t pad = 0; pad < kDtPadCount; ++pad) {
111 LOG_INFO(
"DIO [%d]: %x", index, kPads[pad]);
113 LOG_INFO(
"MIO [%d]: %x", index, kPads[pad]);
117 LOG_INFO(
"END Chosen Retention Types");
125 void configure_pad_retention_types(dif_pinmux_t *pinmux) {
126 LOG_INFO(
"Configuring PADs retention types in PINMUX...");
128 for (dt_pad_t pad = 0; pad < kDtPadCount; pad++) {
135 LOG_INFO(
"PADs retention modes are configured.");
138 bool lowpower_prep(dif_pwrmgr_t *pwrmgr, dif_pinmux_t *pinmux,
bool deepsleep) {
142 LOG_INFO(
"Selecting PADs retention modes...");
144 draw_pinmux_ret(kDtPadCount, kPads, kOptOut,
ARRAYSIZE(kOptOut));
146 print_chosen_values();
149 configure_pad_retention_types(pinmux);
153 pwrmgr_domain_cfg &= ~kDifPwrmgrDomainOptionMainPowerInLowPower;
155 pwrmgr_domain_cfg |= kDifPwrmgrDomainOptionMainPowerInLowPower;
172 irq_global_ctrl(
true);
173 irq_external_ctrl(
true);
175 CHECK_DIF_OK(dif_pwrmgr_init_from_dt(kDtPwrmgrAon, &pwrmgr));
176 CHECK_DIF_OK(dif_pinmux_init_from_dt(kDtPinmuxAon, &pinmux));
177 CHECK_DIF_OK(dif_rv_plic_init_from_dt(kDtRvPlic, &plic));
179 if (UNWRAP(pwrmgr_testutils_is_wakeup_reason(&pwrmgr, 0)) ==
true) {
180 uint32_t deep_powerdown_en = rand_testutils_gen32_range(0, 1);
181 bool deepsleep = (deep_powerdown_en) ?
true :
false;
183 #if defined(OPENTITAN_IS_EARLGREY)
190 #elif defined(OPENTITAN_IS_DARJEELING)
193 #error Unsupported top
198 static const uint32_t kPlicTarget = 0;
199 rv_plic_testutils_irq_range_enable(
201 dt_pwrmgr_irq_to_plic_id(kDtPwrmgrAon, kDtPwrmgrIrqWakeup),
202 dt_pwrmgr_irq_to_plic_id(kDtPwrmgrAon, kDtPwrmgrIrqWakeup));
207 result = lowpower_prep(&pwrmgr, &pinmux, deepsleep);
210 if (UNWRAP(pwrmgr_testutils_is_wakeup_reason(
211 &pwrmgr, kDifPwrmgrWakeupRequestSourceThree)) ==
true) {
221 LOG_ERROR(
"Unexpected wakeup detected: type = %d, request_source = %d",