Skip to content

Commit

Permalink
[dv,pwrmgr] Fix chip_sw_pwrmgr_sensor_ctrl_deep_sleep_wake_up
Browse files Browse the repository at this point in the history
Hold the ast_alert until sensor_ctrl acks the alert, otherwise the
pwrmgr WAKE_INFO csr is not properly updated.
Check that the sensor_ctrl recoverable errors are as expected.

Signed-off-by: Guillermo Maturana <[email protected]>
  • Loading branch information
matutem committed Jan 18, 2024
1 parent 3b4e36e commit c73a560
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 22 deletions.
12 changes: 9 additions & 3 deletions hw/top_earlgrey/dv/env/chip_if.sv
Original file line number Diff line number Diff line change
Expand Up @@ -706,11 +706,17 @@ interface chip_if;
release `AST_HIER.adc_d_o;
endtask

// This task triggers a wakeup by forcing an incoming alert from AST to sensor_ctrl.
// It should be used when the device is in sleep mode, and the alert will be cleared by
// sensor_ctrl alert ack output.
task static trigger_sensor_ctrl_wkup();
`uvm_info(MsgId, "forcing sensor_ctrl ast_alert_i to 1", UVM_MEDIUM)
`uvm_info(MsgId, "forcing sensor_ctrl ast_alert_i[0] to 1", UVM_MEDIUM)
force `SENSOR_CTRL_HIER.ast_alert_i.alerts[0].p = 1'b1;
#100us;
`uvm_info(MsgId, "releasing sensor_ctrl ast_alert_i", UVM_MEDIUM)
// Release the alert when an ack cycle is done, so wait for ack to rise
// and release when it falls, with a timeout of 20 micro seconds.
`DV_WAIT(`SENSOR_CTRL_HIER.ast_alert_o.alerts_ack[0].p == 1'b1, , 20_000_000, "chip_if")
`uvm_info(MsgId, "releasing sensor_ctrl ast_alert_i[0]", UVM_MEDIUM)
@(posedge `SENSOR_CTRL_HIER.clk_i);
release `SENSOR_CTRL_HIER.ast_alert_i.alerts[0].p;
endtask

Expand Down
52 changes: 33 additions & 19 deletions sw/device/tests/pwrmgr_sensor_ctrl_deep_sleep_wake_up.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,16 @@ OTTF_DEFINE_TEST_CONFIG();
/**
* Clean up pwrmgr wakeup reason register for the next round.
*/
static void delay_n_clear(uint32_t delay_in_us) {
busy_spin_micros(delay_in_us);
CHECK_DIF_OK(dif_pwrmgr_wakeup_reason_clear(&pwrmgr));
static bool pwrmgr_wake_status_is_clear(void) {
dif_pwrmgr_request_sources_t sources;
CHECK_DIF_OK(dif_pwrmgr_get_current_request_sources(
&pwrmgr, kDifPwrmgrReqTypeWakeup, &sources));
return sources == 0;
}

static status_t wait_for_pwrmgr_wake_status_is_clear(void) {
IBEX_TRY_SPIN_FOR(pwrmgr_wake_status_is_clear(), 20);
return OK_STATUS();
}

bool test_main(void) {
Expand All @@ -54,27 +61,34 @@ bool test_main(void) {
if (wakeup_reason.request_sources == 0) {
// This is a POR. Prepare to start the test.
CHECK_DIF_OK(dif_pwrmgr_wakeup_reason_clear(&pwrmgr));
CHECK_DIF_OK(dif_pwrmgr_wakeup_request_recording_set_enabled(
&pwrmgr, kDifToggleEnabled));

CHECK_DIF_OK(dif_pwrmgr_get_domain_config(&pwrmgr, &cfg));
cfg &= (kDifPwrmgrDomainOptionIoClockInLowPower |
kDifPwrmgrDomainOptionUsbClockInLowPower |
kDifPwrmgrDomainOptionUsbClockInActivePower);
CHECK_STATUS_OK(pwrmgr_testutils_enable_low_power(
&pwrmgr, kDifPwrmgrWakeupRequestSourceSix, cfg));
LOG_INFO("Issue WFI to enter sensor_ctrl sleep");
wait_for_interrupt();

// This is not reachable.
return false;
} else if (wakeup_reason.types != kDifPwrmgrWakeupTypeRequest) {
LOG_ERROR("Unexpected wakeup_reason.types 0x%x", wakeup_reason.types);
return false;
} else {
// This is a reset from deep_sleep wakeup. Run checks.
check_wakeup_reason(5);
// This is a reset from deep_sleep due to sensor_ctrl wakeup.
LOG_INFO("Woke up by sensor_ctrl");
clear_wakeup(PWRMGR_PARAM_SENSOR_CTRL_AON_WKUP_REQ_IDX);
dif_sensor_ctrl_events_t events;
CHECK(!pwrmgr_wake_status_is_clear(), "Expected wake_status to be set");
CHECK_DIF_OK(dif_sensor_ctrl_get_recov_events(&sensor_ctrl, &events));
CHECK(events == 1, "Expected bit 0 to be set");
CHECK_DIF_OK(dif_sensor_ctrl_clear_recov_event(&sensor_ctrl, 0));
CHECK_DIF_OK(dif_sensor_ctrl_get_recov_events(&sensor_ctrl, &events));
CHECK(events == 0, "Expected recoverable events to clear");
CHECK_STATUS_OK(wait_for_pwrmgr_wake_status_is_clear(), 20);
return true;
}

delay_n_clear(4);
CHECK_DIF_OK(dif_pwrmgr_get_domain_config(&pwrmgr, &cfg));
cfg &= (kDifPwrmgrDomainOptionIoClockInLowPower |
kDifPwrmgrDomainOptionUsbClockInLowPower |
kDifPwrmgrDomainOptionUsbClockInActivePower);
CHECK_STATUS_OK(pwrmgr_testutils_enable_low_power(
&pwrmgr, kDifPwrmgrWakeupRequestSourceSix, cfg));
LOG_INFO("Issue WFI to enter sensor_ctrl sleep");
wait_for_interrupt();

// This is not reachable.
return false;
}

0 comments on commit c73a560

Please sign in to comment.