| /* | |
| * Copyright 2023 Google LLC | |
| * Copyright lowRISC contributors | |
| * | |
| * Licensed under the Apache License, Version 2.0 (the "License"); | |
| * you may not use this file except in compliance with the License. | |
| * You may obtain a copy of the License at | |
| * | |
| * http://www.apache.org/licenses/LICENSE-2.0 | |
| * | |
| * Unless required by applicable law or agreed to in writing, software | |
| * distributed under the License is distributed on an "AS IS" BASIS, | |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| * See the License for the specific language governing permissions and | |
| * limitations under the License. | |
| */ | |
| #include "hw/top_matcha/sw/autogen/top_matcha.h" | |
| #include "sw/device/lib/base/mmio.h" | |
| #include "sw/device/lib/dif/dif_pinmux.h" | |
| #include "sw/device/lib/dif/dif_pwrmgr.h" | |
| #include "sw/device/lib/dif/dif_rstmgr.h" | |
| #include "sw/device/lib/dif/dif_sysrst_ctrl.h" | |
| #include "sw/device/lib/runtime/log.h" | |
| #include "sw/device/lib/testing/pwrmgr_testutils.h" | |
| #include "sw/device/lib/testing/rstmgr_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_rstmgr_t rstmgr; | |
| static dif_sysrst_ctrl_t sysrst_ctrl; | |
| enum { | |
| kTestPhaseCheckComboReset = 0, | |
| kTestPhaseCheckDeepSleepWakeup = 1, | |
| kTestPhaseCheckDeepSleepReset = 2, | |
| kTestPhaseFinalCheck = 3, | |
| }; | |
| // Threshold/Duration values are not specific to a real-world debounce | |
| // scenario so are kept short to avoid excessive simulation time. | |
| // Assuming a 5us aon clock period. | |
| enum { | |
| kDetectionTimeThreshold = 1024, // ~5ms | |
| kEcResetDuration = 512, // ~2.5ms | |
| kDebounceTimeThreshold = 128, // ~0.6ms | |
| }; | |
| static volatile const uint8_t kTestPhase = 0; | |
| static void check_combo_reset(void) { | |
| CHECK_DIF_OK(dif_sysrst_ctrl_key_combo_detect_configure( | |
| &sysrst_ctrl, kDifSysrstCtrlKeyCombo0, | |
| (dif_sysrst_ctrl_key_combo_config_t){ | |
| .actions = kDifSysrstCtrlKeyComboActionEcReset | | |
| kDifSysrstCtrlKeyComboActionSelfReset, | |
| .detection_time_threshold = kDetectionTimeThreshold, | |
| .embedded_controller_reset_duration = kEcResetDuration, | |
| .keys = kDifSysrstCtrlKey0 | kDifSysrstCtrlKey1})); | |
| CHECK_DIF_OK(dif_sysrst_ctrl_input_change_detect_configure( | |
| &sysrst_ctrl, (dif_sysrst_ctrl_input_change_config_t){ | |
| .debounce_time_threshold = kDebounceTimeThreshold, | |
| .input_changes = kDifSysrstCtrlInputKey0H2L | | |
| kDifSysrstCtrlInputKey1H2L})); | |
| CHECK_DIF_OK(dif_sysrst_ctrl_output_pin_override_configure( | |
| &sysrst_ctrl, kDifSysrstCtrlPinFlashWriteProtectInOut, | |
| (dif_sysrst_ctrl_pin_config_t){.allow_one = true, | |
| .allow_zero = true, | |
| .enabled = kDifToggleEnabled, | |
| .override_value = true})); | |
| // Prepare rstmgr for a reset with sysrst_ctrl (source one). | |
| rstmgr_testutils_pre_reset(&rstmgr); | |
| CHECK_DIF_OK(dif_pwrmgr_set_request_sources(&pwrmgr, kDifPwrmgrReqTypeReset, | |
| kDifPwrmgrResetRequestSourceOne, | |
| kDifToggleEnabled)); | |
| // Issue WFI and wait for reset condition. | |
| test_status_set(kTestStatusInWfi); | |
| wait_for_interrupt(); | |
| } | |
| static void check_deep_sleep_wakeup(void) { | |
| CHECK_DIF_OK(dif_sysrst_ctrl_ulp_wakeup_configure( | |
| &sysrst_ctrl, (dif_sysrst_ctrl_ulp_wakeup_config_t){ | |
| .ac_power_debounce_time_threshold = 0, | |
| .lid_open_debounce_time_threshold = 0, | |
| .power_button_debounce_time_threshold = 0, | |
| .enabled = kDifToggleEnabled})); | |
| // Setup low power. | |
| // Wakeup source is from sysrst_ctrl (source one). | |
| rstmgr_testutils_pre_reset(&rstmgr); | |
| pwrmgr_testutils_enable_low_power(&pwrmgr, kDifPwrmgrWakeupRequestSourceOne, | |
| 0); | |
| // Issue WFI and wait for reset condition. | |
| test_status_set(kTestStatusInWfi); | |
| wait_for_interrupt(); | |
| } | |
| static void check_deep_sleep_reset(void) { | |
| CHECK_DIF_OK(dif_sysrst_ctrl_key_combo_detect_configure( | |
| &sysrst_ctrl, kDifSysrstCtrlKeyCombo1, | |
| (dif_sysrst_ctrl_key_combo_config_t){ | |
| .actions = kDifSysrstCtrlKeyComboActionEcReset | | |
| kDifSysrstCtrlKeyComboActionSelfReset, | |
| .detection_time_threshold = kDetectionTimeThreshold, | |
| .embedded_controller_reset_duration = kEcResetDuration, | |
| .keys = kDifSysrstCtrlKey2 | kDifSysrstCtrlKeyPowerButton})); | |
| CHECK_DIF_OK(dif_sysrst_ctrl_output_pin_override_configure( | |
| &sysrst_ctrl, kDifSysrstCtrlPinFlashWriteProtectInOut, | |
| (dif_sysrst_ctrl_pin_config_t){.allow_one = true, | |
| .allow_zero = true, | |
| .enabled = kDifToggleEnabled, | |
| .override_value = true})); | |
| CHECK_DIF_OK(dif_sysrst_ctrl_input_change_detect_configure( | |
| &sysrst_ctrl, (dif_sysrst_ctrl_input_change_config_t){ | |
| .debounce_time_threshold = kDebounceTimeThreshold, | |
| .input_changes = kDifSysrstCtrlInputKey2H2L | | |
| kDifSysrstCtrlInputPowerButtonH2L})); | |
| // Setup low power. | |
| // Reset source is from sysrst_ctrl (source one). | |
| rstmgr_testutils_pre_reset(&rstmgr); | |
| CHECK_DIF_OK(dif_pwrmgr_set_request_sources(&pwrmgr, kDifPwrmgrReqTypeReset, | |
| kDifPwrmgrResetRequestSourceOne, | |
| kDifToggleEnabled)); | |
| // Enable low power with wakeup source other than | |
| // sysrst_ctrl (e.g. source two) as we don't want | |
| // a wakeup request but instead a reset. | |
| pwrmgr_testutils_enable_low_power(&pwrmgr, kDifPwrmgrWakeupRequestSourceTwo, | |
| 0); | |
| // Issue WFI and wait for reset condition. | |
| test_status_set(kTestStatusInWfi); | |
| wait_for_interrupt(); | |
| } | |
| bool test_main(void) { | |
| CHECK_DIF_OK(dif_pwrmgr_init( | |
| mmio_region_from_addr(TOP_MATCHA_PWRMGR_AON_BASE_ADDR), &pwrmgr)); | |
| CHECK_DIF_OK(dif_rstmgr_init( | |
| mmio_region_from_addr(TOP_MATCHA_RSTMGR_AON_BASE_ADDR), &rstmgr)); | |
| CHECK_DIF_OK(dif_sysrst_ctrl_init( | |
| mmio_region_from_addr(TOP_MATCHA_SYSRST_CTRL_AON_BASE_ADDR), | |
| &sysrst_ctrl)); | |
| dif_rstmgr_reset_info_bitfield_t rstmgr_reset_info; | |
| rstmgr_reset_info = rstmgr_testutils_reason_get(); | |
| dif_pinmux_t pinmux; | |
| CHECK_DIF_OK(dif_pinmux_init( | |
| mmio_region_from_addr(TOP_MATCHA_PINMUX_AON_BASE_ADDR), &pinmux)); | |
| CHECK_DIF_OK(dif_pinmux_input_select( | |
| &pinmux, kTopMatchaPinmuxPeripheralInSysrstCtrlAonKey0In, | |
| kTopMatchaPinmuxInselIob3)); | |
| CHECK_DIF_OK(dif_pinmux_input_select( | |
| &pinmux, kTopMatchaPinmuxPeripheralInSysrstCtrlAonKey1In, | |
| kTopMatchaPinmuxInselIob6)); | |
| CHECK_DIF_OK(dif_pinmux_input_select( | |
| &pinmux, kTopMatchaPinmuxPeripheralInSysrstCtrlAonKey2In, | |
| kTopMatchaPinmuxInselIob8)); | |
| CHECK_DIF_OK(dif_pinmux_input_select( | |
| &pinmux, kTopMatchaPinmuxPeripheralInSysrstCtrlAonPwrbIn, | |
| kTopMatchaPinmuxInselIob9)); | |
| CHECK_DIF_OK(dif_pinmux_input_select( | |
| &pinmux, kTopMatchaPinmuxPeripheralInSysrstCtrlAonAcPresent, | |
| kTopMatchaPinmuxInselIoc7)); | |
| CHECK_DIF_OK(dif_pinmux_input_select( | |
| &pinmux, kTopMatchaPinmuxPeripheralInSysrstCtrlAonLidOpen, | |
| kTopMatchaPinmuxInselIoc9)); | |
| CHECK_DIF_OK(dif_sysrst_ctrl_output_pin_override_set_enabled( | |
| &sysrst_ctrl, kDifSysrstCtrlPinEcResetInOut, kDifToggleDisabled)); | |
| switch (kTestPhase) { | |
| case kTestPhaseCheckComboReset: | |
| CHECK(rstmgr_reset_info == kDifRstmgrResetInfoPor); | |
| check_combo_reset(); | |
| break; | |
| case kTestPhaseCheckDeepSleepWakeup: | |
| CHECK(rstmgr_reset_info == kDifRstmgrResetInfoSysRstCtrl); | |
| check_deep_sleep_wakeup(); | |
| break; | |
| case kTestPhaseCheckDeepSleepReset: | |
| CHECK(rstmgr_reset_info == kDifRstmgrResetInfoLowPowerExit); | |
| check_deep_sleep_reset(); | |
| break; | |
| case kTestPhaseFinalCheck: | |
| CHECK(rstmgr_reset_info == | |
| (kDifRstmgrResetInfoSysRstCtrl | kDifRstmgrResetInfoLowPowerExit)); | |
| return true; | |
| break; | |
| default: | |
| LOG_ERROR("Unexpected test phase : %d", kTestPhase); | |
| break; | |
| } | |
| return false; | |
| } |