diff options
author | Mary Ruthven <mruthven@chromium.org> | 2022-03-01 13:27:38 -0600 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2022-03-01 21:38:12 +0000 |
commit | 9fdde5f20035c3776802a9d4de281ad9b1c1733e (patch) | |
tree | fb8b39abd1cf1f53350f96369ac0684ac6b66391 | |
parent | 6c4038cf114eb47232ca6c13ae54e0d597110fb8 (diff) | |
download | chrome-ec-9fdde5f20035c3776802a9d4de281ad9b1c1733e.tar.gz |
ds_disable: clear ds_disable if the AP doesn't turn off in 10S
The disable deep sleep variable is supposed to be temporary and only
apply to the next TPM_RST_L pulse. If TPM_RST_L doesn't get asserted
within 10 seconds of the disable deep sleep vendor command, it probably
means something went wrong with suspend and it was aborted. Clear
disable deep sleep after 10 seconds, so it doesn't get applied to some
other suspend.
BUG=b:222124677
TEST=manual
# Send command to disable deep sleep
trunks_send --raw 80010000000c20000000003b
> [50.252944 dis DS]
ccdstate
DS Dis: on
# Wait 10 seconds and make sure cr50 clears it
> [60.252941 DDS: clear]
# Send command to disable deep sleep
trunks_send --raw 80010000000c20000000003b
# Shutdown the device immediately.
shudown -P now
# Verify cr50 disables deep sleep
1 [24.650581 dis DS]
1/[27.364002 tpm_rst_asserted]
[28.364776 AP off]
[28.365516 Block DS]
# Wait 20 seconds. Check that cr50 doesn't clear it
> ccdstate
DS Dis: on
AP: off
..
> idle
idle action: sleep
# boot the device
10| 1 inicom2.8Minicom2.8[85.437511 deferred_tpm_rst_isr]
[85.438472 AP on]
[85.439010 set TPM wake]
[85.439594 tpm_reset_request(0, 0)]
[85.440494 tpm_reset_now(0)]
[85.443954 tpm_init]
tpm_manufactured: manufactured
[85.446109 tpm_reset_now: done]
[85.446891 DDS: clear]
# shutdown the device
# check cr50 enters deep sleep
Change-Id: I2140dbb01e8d9b21c5f5309e43efc21b636361e5
Signed-off-by: Mary Ruthven <mruthven@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3498704
Reviewed-by: Vadim Sukhomlinov <sukhomlinov@chromium.org>
-rw-r--r-- | board/cr50/ap_state.c | 21 |
1 files changed, 20 insertions, 1 deletions
diff --git a/board/cr50/ap_state.c b/board/cr50/ap_state.c index 79506b2a2e..88385b639d 100644 --- a/board/cr50/ap_state.c +++ b/board/cr50/ap_state.c @@ -11,6 +11,7 @@ #include "hooks.h" #include "registers.h" #include "system.h" +#include "timer.h" #include "tpm_registers.h" #define CPRINTS(format, args...) cprints(CC_SYSTEM, format, ## args) @@ -44,6 +45,15 @@ void pmu_check_tpm_rst(void) } } +void clear_ds_disable(void) +{ + if (!disable_ds_temp) + return; + CPRINTS("DDS: clear"); + disable_ds_temp = false; +} +DECLARE_DEFERRED(clear_ds_disable); + /* * Disable deep sleep during the next TPM_RST_L pulse * @@ -62,6 +72,11 @@ static enum vendor_cmd_rc vc_ds_disable_temp(enum vendor_cmd_cc code, if (input_size) return VENDOR_RC_BOGUS_ARGS; + /* + * Clear this if the AP doesn't turn off in 10 seconds, since + * that probably means suspend was aborted. + */ + hook_call_deferred(&clear_ds_disable_data, 10 * SECOND); disable_ds_temp = true; CPRINTS("dis DS"); @@ -119,6 +134,9 @@ static void deferred_set_ap_off(void) * support. It happens to be correlated with ARM vs x86 at present. */ if (disable_ds_temp) { + /* Cancel the clear ds disable call since the AP turned off. */ + hook_call_deferred(&clear_ds_disable_data, -1); + CPRINTS("Block DS"); disable_deep_sleep(); /* @@ -163,11 +181,12 @@ void set_ap_on(void) CPRINTS("set TPM wake"); gpio_set_wakepin(GPIO_TPM_RST_L, GPIO_HIB_WAKE_LOW); } + /* * disable_ds_temp only survives one TPM_RST_L pulse. Clear it when * the AP turns back on. */ - disable_ds_temp = false; + hook_call_deferred(&clear_ds_disable_data, 0); } static uint8_t waiting_for_ap_reset; |