summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Yilun Lin <yllin@chromium.org>2021-06-25 11:02:20 +0800
committerCommit Bot <commit-bot@chromium.org>2021-06-30 09:27:37 +0000
commitb67388a0c2e861aa3aede4c92c538c71e0d700b2 (patch)
treee6e9a736b3f38ca112f1e39a9c5ae492e0cf6561
parentb5920dc038c24311dda0522c879fcff6a2d93e85 (diff)
downloadchrome-ec-b67388a0c2e861aa3aede4c92c538c71e0d700b2.tar.gz
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 <yllin@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2987232 Tested-by: Sue Chen <sue.chen@quanta.corp-partner.google.com> Reviewed-by: Eric Yilun Lin <yllin@google.com> Commit-Queue: Eric Yilun Lin <yllin@google.com>
-rw-r--r--baseboard/kukui/baseboard.h5
-rw-r--r--power/mt8183.c71
2 files changed, 76 insertions, 0 deletions
diff --git a/baseboard/kukui/baseboard.h b/baseboard/kukui/baseboard.h
index 34a73e24ef..16ad2c4bca 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()) {