diff options
Diffstat (limited to 'board/samus/power_sequence.c')
-rw-r--r-- | board/samus/power_sequence.c | 32 |
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); |