summaryrefslogtreecommitdiff
path: root/board/samus/power_sequence.c
diff options
context:
space:
mode:
Diffstat (limited to 'board/samus/power_sequence.c')
-rw-r--r--board/samus/power_sequence.c32
1 files changed, 29 insertions, 3 deletions
diff --git a/board/samus/power_sequence.c b/board/samus/power_sequence.c
index 9c166093e8..95c017dbf3 100644
--- a/board/samus/power_sequence.c
+++ b/board/samus/power_sequence.c
@@ -91,6 +91,20 @@ static void chipset_force_g3(void)
wireless_set_state(WIRELESS_OFF);
}
+static void chipset_reset_rtc(void)
+{
+ /*
+ * Assert RTCRST# to the PCH long enough for it to latch the
+ * assertion and reset the internal RTC backed state.
+ */
+ if (system_get_board_version() >= BOARD_VERSION_EVT) {
+ CPRINTS("Asserting RTCRST# to PCH");
+ gpio_set_level(GPIO_PCH_RTCRST_L, 0);
+ udelay(100);
+ gpio_set_level(GPIO_PCH_RTCRST_L, 1);
+ }
+}
+
void chipset_reset(int cold_reset)
{
CPRINTS("%s(%d)", __func__, cold_reset);
@@ -175,9 +189,17 @@ enum power_state power_handle_state(enum power_state state)
break;
case POWER_S5:
- if (gpio_get_level(GPIO_PCH_SLP_S5_L) == 1)
- return POWER_S5S3; /* Power up to next state */
-
+ while ((power_get_signals() & IN_PCH_SLP_S5_DEASSERTED) == 0) {
+ if (task_wait_event(SECOND*4) == TASK_EVENT_TIMER) {
+ CPRINTS("timeout waiting for S5 exit");
+ /* Put system in G3 and assert RTCRST# */
+ chipset_force_g3();
+ chipset_reset_rtc();
+ /* Try to power back up after RTC reset */
+ return POWER_G3S5;
+ }
+ }
+ return POWER_S5S3; /* Power up to next state */
break;
case POWER_S3:
@@ -207,6 +229,10 @@ enum power_state power_handle_state(enum power_state state)
break;
case POWER_G3S5:
+ /* Assert RTCRST# while in G3 if keyboard initiated reset */
+ if (system_get_reset_flags() & RESET_FLAG_RESET_PIN)
+ chipset_reset_rtc();
+
/* Enable 3.3V DSW */
gpio_set_level(GPIO_PP3300_DSW_EN, 1);