Update chip_sw_pwrmgr_sleep_sensor_ctrl_alert_wakeup to fix time out problem Change-Id: Ia99e8c40c4293daa14fafb69a103d984417e0766
diff --git a/hw/top_matcha/dv/chip_sim_cfg.hjson b/hw/top_matcha/dv/chip_sim_cfg.hjson index 5c178f4..9057076 100644 --- a/hw/top_matcha/dv/chip_sim_cfg.hjson +++ b/hw/top_matcha/dv/chip_sim_cfg.hjson
@@ -2085,6 +2085,7 @@ "chip_sw_otp_ctrl_smoketest", "chip_sw_pwrmgr_deep_sleep_power_glitch_reset", "chip_sw_pwrmgr_sleep_power_glitch_reset", + "chip_sw_pwrmgr_sleep_sensor_ctrl_alert_wakeup", "chip_sw_rom_ctrl_integrity_check", "chip_sw_rstmgr_smoketest", "chip_sw_rstmgr_sw_req",
diff --git a/sw/device/tests/BUILD b/sw/device/tests/BUILD index 0bee4f2..48a45e5 100644 --- a/sw/device/tests/BUILD +++ b/sw/device/tests/BUILD
@@ -852,15 +852,13 @@ matcha_dv_test( name = "sensor_ctrl_wakeup_test", - srcs = ["@lowrisc_opentitan//sw/device/tests:sensor_ctrl_wakeup.c"], + srcs = ["sensor_ctrl_wakeup.c"], deps = [ - ":test_dv_lib_opentitan", - "//hw/top_matcha/ip/sensor_ctrl/data:sensor_ctrl_regs", + ":test_dv_lib", "//sw/device/lib/dif:rv_plic_sec", - "@lowrisc_opentitan//sw/device/lib/arch:device", + "//sw/device/lib/testing:isr_testutils", "@lowrisc_opentitan//sw/device/lib/dif:pwrmgr", "@lowrisc_opentitan//sw/device/lib/dif:sensor_ctrl", - "@lowrisc_opentitan//sw/device/lib/testing:isr_testutils", "@lowrisc_opentitan//sw/device/lib/testing:pwrmgr_testutils", "@lowrisc_opentitan//sw/device/lib/testing:rv_plic_testutils", ],
diff --git a/sw/device/tests/sensor_ctrl_wakeup.c b/sw/device/tests/sensor_ctrl_wakeup.c new file mode 100644 index 0000000..d1529b0 --- /dev/null +++ b/sw/device/tests/sensor_ctrl_wakeup.c
@@ -0,0 +1,133 @@ +// Copyright 2023 Google LLC. +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +#include "hw/top_matcha/sw/autogen/top_matcha.h" +#include "sensor_ctrl_regs.h" // Generated. +#include "sw/device/lib/base/mmio.h" +#include "sw/device/lib/dif/dif_pwrmgr.h" +#include "sw/device/lib/dif/dif_rv_plic.h" +#include "sw/device/lib/dif/dif_sensor_ctrl.h" +#include "sw/device/lib/runtime/ibex.h" +#include "sw/device/lib/runtime/irq.h" +#include "sw/device/lib/runtime/log.h" +#include "sw/device/lib/testing/autogen/isr_testutils.h" +#include "sw/device/lib/testing/pwrmgr_testutils.h" +#include "sw/device/lib/testing/rv_plic_testutils.h" +#include "sw/device/lib/testing/test_framework/check.h" +#include "sw/device/lib/testing/test_framework/ottf_main.h" + +OTTF_DEFINE_TEST_CONFIG(); + +static dif_pwrmgr_t pwrmgr; +static dif_rv_plic_t plic; +static plic_isr_ctx_t plic_ctx = {.rv_plic = &plic, + .hart_id = kTopMatchaPlicTargetIbex0}; + +static pwrmgr_isr_ctx_t pwrmgr_isr_ctx = { + .pwrmgr = &pwrmgr, + .plic_pwrmgr_start_irq_id = kTopMatchaPlicIrqIdPwrmgrAonWakeup, + .expected_irq = kDifPwrmgrIrqWakeup, + .is_only_irq = true}; + +static bool get_wakeup_status(void) { + dif_pwrmgr_request_sources_t wake_req = -1; + CHECK_DIF_OK(dif_pwrmgr_get_current_request_sources( + &pwrmgr, kDifPwrmgrReqTypeWakeup, &wake_req)); + return (wake_req > 0); +} + +/** + * External interrupt handler. + */ +void ottf_external_isr(void) { + dif_pwrmgr_irq_t irq_id; + top_matcha_plic_peripheral_t peripheral; + + isr_testutils_pwrmgr_isr(plic_ctx, pwrmgr_isr_ctx, &peripheral, &irq_id); + + // Check that both the peripheral and the irq id is correct + CHECK(peripheral == kTopMatchaPlicPeripheralPwrmgrAon, + "IRQ peripheral: %d is incorrect", peripheral); + CHECK(irq_id == kDifPwrmgrIrqWakeup, "IRQ ID: %d is incorrect", irq_id); +} + +bool test_main(void) { + dif_sensor_ctrl_t sensor_ctrl; + + // Enable global and external IRQ at Ibex. + irq_global_ctrl(true); + irq_external_ctrl(true); + + // Initialize the PLIC. + mmio_region_t plic_base_addr = + mmio_region_from_addr(TOP_MATCHA_RV_PLIC_BASE_ADDR); + CHECK_DIF_OK(dif_rv_plic_init(plic_base_addr, &plic)); + + // Initialize pwrmgr + CHECK_DIF_OK(dif_pwrmgr_init( + mmio_region_from_addr(TOP_MATCHA_PWRMGR_AON_BASE_ADDR), &pwrmgr)); + + // Initialize sensor_ctrl + CHECK_DIF_OK(dif_sensor_ctrl_init( + mmio_region_from_addr(TOP_MATCHA_SENSOR_CTRL_BASE_ADDR), &sensor_ctrl)); + + // Enable all the AON interrupts used in this test. + rv_plic_testutils_irq_range_enable(&plic, kTopMatchaPlicTargetIbex0, + kTopMatchaPlicIrqIdPwrmgrAonWakeup, + kTopMatchaPlicIrqIdPwrmgrAonWakeup); + + // Enable pwrmgr interrupt + CHECK_DIF_OK(dif_pwrmgr_irq_set_enabled(&pwrmgr, 0, kDifToggleEnabled)); + + // Capture the number of events to test + uint32_t sensor_ctrl_events = SENSOR_CTRL_PARAM_NUM_ALERT_EVENTS; + + dif_pwrmgr_domain_config_t sleep_config = + kDifPwrmgrDomainOptionMainPowerInLowPower; + + for (size_t i = 0; i < sensor_ctrl_events; ++i) { + LOG_INFO("Testing sensor_ctrl event %d", i); + + // Setup event trigger + CHECK_DIF_OK(dif_sensor_ctrl_set_ast_event_trigger(&sensor_ctrl, i, + kDifToggleEnabled)); + + // Normal sleep. + pwrmgr_testutils_enable_low_power(&pwrmgr, kDifPwrmgrWakeupRequestSourceSix, + sleep_config); + + // Enter low power mode. + LOG_INFO("Issue WFI to enter sleep"); + wait_for_interrupt(); + + // Wakeup from sleep. + LOG_INFO("Wake from sleep"); + + dif_sensor_ctrl_events_t events; + CHECK_DIF_OK(dif_sensor_ctrl_get_recov_events(&sensor_ctrl, &events)); + + if (events != (1 << i)) { + LOG_ERROR("Recoverable event 0x%x does not match expectation %d", events, + i); + } + + // clear event trigger + CHECK_DIF_OK(dif_sensor_ctrl_set_ast_event_trigger(&sensor_ctrl, i, + kDifToggleDisabled)); + + // since there is synchronization delay to trigger clearing and actual event + // de-assertion, clear and poll until it is finished before moving on + while (events) { + CHECK_DIF_OK(dif_sensor_ctrl_clear_recov_event(&sensor_ctrl, i)); + CHECK_DIF_OK(dif_sensor_ctrl_get_recov_events(&sensor_ctrl, &events)); + } + + // ensure the de-asserted events have cleared from the wakeup pipeline + // within 30us + IBEX_SPIN_FOR(!get_wakeup_status(), 30); + } + + return true; +}