summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Yilun Lin <yllin@chromium.org>2021-06-11 15:42:19 +0800
committerCommit Bot <commit-bot@chromium.org>2021-06-15 03:18:00 +0000
commita14b96c8c6a045bdd80dfb690cd8026fb5bb8fcd (patch)
treeb09d00372b549fc86492bdf57bfe28d16e6f4528
parent2c58e541897163dcb879a3755884d193fb0011a9 (diff)
downloadchrome-ec-a14b96c8c6a045bdd80dfb690cd8026fb5bb8fcd.tar.gz
asurada: enable HOST_SLEEP_STATE to smooth suspend trasnsition
MT8192 previously didn't enable the command due to it already has AP_IN_SLEEP_L, but we found that if we don't have the command, EC might have rare chance to interrupt AP with hostevent when AP in transition to S3, and cause the suspend failure. This CL enables CONFIG_POWER_TRACK_HOST_SLEEP_STATE so the EC is able to handle the AP's hint to disable non-wakeup hostevent when it's transisting to S3. BUG=b:186709406 TEST=ensure EC received the AP's note BRANCH=asurada Change-Id: I7a2a7eefc7620817ca446fd24370375130daf6be Signed-off-by: Eric Yilun Lin <yllin@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2954984 Tested-by: Eric Yilun Lin <yllin@google.com> Auto-Submit: Eric Yilun Lin <yllin@google.com> Reviewed-by: Ting Shen <phoenixshen@chromium.org> Commit-Queue: Ting Shen <phoenixshen@chromium.org>
-rw-r--r--baseboard/asurada/baseboard.h3
-rw-r--r--power/mt8192.c70
2 files changed, 73 insertions, 0 deletions
diff --git a/baseboard/asurada/baseboard.h b/baseboard/asurada/baseboard.h
index 7a485c0005..d166b80f93 100644
--- a/baseboard/asurada/baseboard.h
+++ b/baseboard/asurada/baseboard.h
@@ -26,6 +26,8 @@
#define CONFIG_CHIPSET_MT8192
#define CONFIG_EXTPOWER_GPIO
#define CONFIG_HIBERNATE_WAKE_PINS_DYNAMIC
+#define CONFIG_POWER_SLEEP_FAILURE_DETECTION
+#define CONFIG_POWER_TRACK_HOST_SLEEP_STATE
/* Chipset */
#define CONFIG_CMD_AP_RESET_LOG
@@ -169,6 +171,7 @@
(EC_HOST_EVENT_MASK(EC_HOST_EVENT_AC_CONNECTED) | \
EC_HOST_EVENT_MASK(EC_HOST_EVENT_AC_DISCONNECTED) | \
EC_HOST_EVENT_MASK(EC_HOST_EVENT_LID_OPEN) | \
+ EC_HOST_EVENT_MASK(EC_HOST_EVENT_HANG_DETECT) | \
EC_HOST_EVENT_MASK(EC_HOST_EVENT_MODE_CHANGE) | \
EC_HOST_EVENT_MASK(EC_HOST_EVENT_POWER_BUTTON))
diff --git a/power/mt8192.c b/power/mt8192.c
index b1ff717100..4c0a5ec166 100644
--- a/power/mt8192.c
+++ b/power/mt8192.c
@@ -170,6 +170,26 @@ void chipset_reset(enum chipset_reset_reason reason)
GPIO_SET_LEVEL(GPIO_SYS_RST_ODL, 1);
}
+#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 */
+
enum power_state power_chipset_init(void)
{
int exit_hard_off = 1;
@@ -350,6 +370,13 @@ 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;
@@ -362,6 +389,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.
@@ -375,6 +406,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 */
+
/*
* Enable idle task deep sleep. Allow the low power idle task
* to go into deep sleep in S3 or lower.
@@ -453,6 +488,41 @@ static void power_button_changed(void)
}
DECLARE_HOOK(HOOK_POWER_BUTTON_CHANGE, power_button_changed, HOOK_PRIO_DEFAULT);
+#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 */
+
#ifdef CONFIG_LID_SWITCH
static void lid_changed(void)
{