From 005a9d3e4043eda517bb83215d0c1d4a18d663c3 Mon Sep 17 00:00:00 2001 From: Eric Yilun Lin Date: Fri, 25 Jun 2021 11:02:20 +0800 Subject: kukui: enable HOST_SLEEP_STATE to smooth suspend trasnsition To smooth the suspend transition to prevent from EC waking up AP during S0->S3. BUG=none TEST=ensure AP notify EC before suspending BRANCH=kukui,icarus Change-Id: I6d4d79be2688c53e0057f5e60a394cfa8974e501 Signed-off-by: Eric Yilun Lin Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2987228 Tested-by: Eric Yilun Lin Auto-Submit: Eric Yilun Lin Reviewed-by: Ting Shen Commit-Queue: Ting Shen --- baseboard/kukui/baseboard.h | 5 ++++ power/mt8183.c | 71 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+) diff --git a/baseboard/kukui/baseboard.h b/baseboard/kukui/baseboard.h index 1f30d1e858..c8d67f9c91 100644 --- a/baseboard/kukui/baseboard.h +++ b/baseboard/kukui/baseboard.h @@ -128,6 +128,11 @@ #endif /* VARIANT_KUKUI_JACUZZI */ +#if defined(SECTION_IS_RW) || defined(VARIANT_KUKUI_EC_IT81202) +#define CONFIG_POWER_SLEEP_FAILURE_DETECTION +#define CONFIG_POWER_TRACK_HOST_SLEEP_STATE +#endif + /* * Define this flag if board controls dp mux via gpio pins USB_C0_DP_OE_L and * USB_C0_DP_POLARITY. diff --git a/power/mt8183.c b/power/mt8183.c index 0acd2bc217..bdbd319601 100644 --- a/power/mt8183.c +++ b/power/mt8183.c @@ -165,6 +165,26 @@ void chipset_exit_hard_off_button(void) } DECLARE_DEFERRED(chipset_exit_hard_off_button); +#ifdef CONFIG_POWER_TRACK_HOST_SLEEP_STATE +static void power_reset_host_sleep_state(void) +{ + power_set_host_sleep_state(HOST_SLEEP_EVENT_DEFAULT_RESET); + sleep_reset_tracking(); + power_chipset_handle_host_sleep_event(HOST_SLEEP_EVENT_DEFAULT_RESET, + NULL); +} + +static void handle_chipset_reset(void) +{ + if (chipset_in_state(CHIPSET_STATE_SUSPEND)) { + CPRINTS("Chipset reset: exit s3"); + power_reset_host_sleep_state(); + task_wake(TASK_ID_CHIPSET); + } +} +DECLARE_HOOK(HOOK_CHIPSET_RESET, handle_chipset_reset, HOOK_PRIO_FIRST); +#endif /* CONFIG_POWER_TRACK_HOST_SLEEP_STATE */ + /* If chipset needs to be reset, EC also reboots to RO. */ void chipset_reset(enum chipset_reset_reason reason) { @@ -442,6 +462,14 @@ enum power_state power_handle_state(enum power_state state) /* Call hooks now that rails are up */ hook_notify(HOOK_CHIPSET_STARTUP); + /* + * Clearing the sleep failure detection tracking on the path + * to S0 to handle any reset conditions. + */ +#ifdef CONFIG_POWER_SLEEP_FAILURE_DETECTION + power_reset_host_sleep_state(); +#endif /* CONFIG_POWER_SLEEP_FAILURE_DETECTION */ + /* Power up to next state */ return POWER_S3; @@ -456,6 +484,10 @@ enum power_state power_handle_state(enum power_state state) /* Call hooks now that rails are up */ hook_notify(HOOK_CHIPSET_RESUME); +#ifdef CONFIG_POWER_SLEEP_FAILURE_DETECTION + sleep_resume_transition(); +#endif /* CONFIG_POWER_SLEEP_FAILURE_DETECTION */ + /* * Disable idle task deep sleep. This means that the low * power idle task will not go into deep sleep while in S0. @@ -469,6 +501,10 @@ enum power_state power_handle_state(enum power_state state) /* Call hooks before we remove power rails */ hook_notify(HOOK_CHIPSET_SUSPEND); +#ifdef CONFIG_POWER_SLEEP_FAILURE_DETECTION + sleep_suspend_transition(); +#endif /* CONFIG_POWER_SLEEP_FAILURE_DETECTION */ + /* * TODO(b:109850749): Check if we need some delay here to * "debounce" entering suspend (rk3399 uses 20ms delay). @@ -539,6 +575,41 @@ enum power_state power_handle_state(enum power_state state) return state; } +#ifdef CONFIG_POWER_TRACK_HOST_SLEEP_STATE +static void suspend_hang_detected(void) +{ + CPRINTS("Warning: Detected sleep hang! Waking host up!"); + host_set_single_event(EC_HOST_EVENT_HANG_DETECT); +} + +__override void power_chipset_handle_host_sleep_event( + enum host_sleep_event state, + struct host_sleep_event_context *ctx) +{ + CPRINTS("Handle sleep: %d", state); + + if (state == HOST_SLEEP_EVENT_S3_SUSPEND) { + /* + * Indicate to power state machine that a new host event for + * S3 suspend has been received and so chipset suspend + * notification needs to be sent to listeners. + */ + sleep_set_notify(SLEEP_NOTIFY_SUSPEND); + sleep_start_suspend(ctx, suspend_hang_detected); + + } else if (state == HOST_SLEEP_EVENT_S3_RESUME) { + /* + * Wake up chipset task and indicate to power state machine that + * listeners need to be notified of chipset resume. + */ + sleep_set_notify(SLEEP_NOTIFY_RESUME); + task_wake(TASK_ID_CHIPSET); + sleep_complete_resume(ctx); + + } +} +#endif /* CONFIG_POWER_TRACK_HOST_SLEEP_STATE */ + static void power_button_changed(void) { if (power_button_is_pressed()) { -- cgit v1.2.1