diff options
author | Duncan Laurie <dlaurie@chromium.org> | 2015-10-22 08:55:17 -0700 |
---|---|---|
committer | ChromeOS bot <3su6n15k.default@developer.gserviceaccount.com> | 2015-11-05 01:28:31 +0000 |
commit | 28322ab75f72e01b13de0ce63b0ac3bf7aeaf8f0 (patch) | |
tree | 2fe8353ffd7d6c0fc7be64583706bc2f5b00b977 | |
parent | 94b4be7f303dd454f6d054042697fe90242d78b3 (diff) | |
download | chrome-ec-28322ab75f72e01b13de0ce63b0ac3bf7aeaf8f0.tar.gz |
buddy: Enable RTCRST pulse if SLP_S5 does not deassert
Enable the workaround for power sequencing failures by pulsing
RTCRST to the PCH if it fails to sequence out of S5 state.
BUG=chrome-os-partner:47175
BRANCH=none
TEST=Confirm RTCRST asserts if SLP_S5 does not deassert and then system can
power on normally.
Change-Id: I6be081dfaa1f73ff02feaad595dc285391962221
Signed-off-by: Grover Yen <Grover_Yen@wistron.com>
Reviewed-on: https://chromium-review.googlesource.com/310588
Reviewed-by: Duncan Laurie <dlaurie@chromium.org>
-rw-r--r-- | board/buddy/board.h | 3 | ||||
-rw-r--r-- | board/buddy/gpio.inc | 2 | ||||
-rw-r--r-- | power/haswell.c | 29 |
3 files changed, 31 insertions, 3 deletions
diff --git a/board/buddy/board.h b/board/buddy/board.h index a56d7066ae..e953904d12 100644 --- a/board/buddy/board.h +++ b/board/buddy/board.h @@ -40,6 +40,9 @@ #define CONFIG_VBOOT_HASH #define CONFIG_WIRELESS +/* This board has RTCRST connection from EC GPIO to the PCH */ +#define BOARD_HAS_RTCRST + #ifndef __ASSEMBLER__ /* I2C ports */ diff --git a/board/buddy/gpio.inc b/board/buddy/gpio.inc index 6ee268cc58..de171c1f03 100644 --- a/board/buddy/gpio.inc +++ b/board/buddy/gpio.inc @@ -83,7 +83,7 @@ GPIO(USB1_ENABLE, E, 4, GPIO_OUT_LOW, NULL) /* USB port 1 output power GPIO(USB2_ENABLE, D, 5, GPIO_OUT_LOW, NULL) /* USB port 2 output power enable */ GPIO(PCH_SUSACK_L, F, 3, GPIO_OUT_HIGH, NULL) /* Acknowledge PCH SUSWARN# signal */ -GPIO(PCH_RTCRST_L, F, 6, GPIO_ODR_HIGH, NULL) /* Not supposed to be here */ +GPIO(PCH_RTCRST_L, F, 6, GPIO_ODR_HIGH, NULL) /* Reset PCH RTC well */ GPIO(PCH_SRTCRST_L, F, 7, GPIO_ODR_HIGH, NULL) /* Not supposed to be here */ GPIO(PWR_LED0_L, N, 6, GPIO_ODR_HIGH, NULL) /* Power LED - blue */ diff --git a/power/haswell.c b/power/haswell.c index c5443b1fb6..27eb9d0724 100644 --- a/power/haswell.c +++ b/power/haswell.c @@ -15,6 +15,7 @@ #include "lid_switch.h" #include "power.h" #include "system.h" +#include "task.h" #include "timer.h" #include "util.h" #include "wireless.h" @@ -66,6 +67,21 @@ void chipset_force_shutdown(void) gpio_set_level(GPIO_PCH_RSMRST_L, 0); } +static void chipset_reset_rtc(void) +{ +#ifdef BOARD_HAS_RTCRST + /* + * Assert RTCRST# to the PCH long enough for it to latch the + * assertion and reset the internal RTC backed state. + */ + CPRINTS("Asserting RTCRST# to PCH"); + gpio_set_level(GPIO_PCH_RTCRST_L, 0); + udelay(3 * SECOND); + gpio_set_level(GPIO_PCH_RTCRST_L, 1); + udelay(10 * MSEC); +#endif +} + void chipset_reset(int cold_reset) { CPRINTS("%s(%d)", __func__, cold_reset); @@ -159,8 +175,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_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_shutdown(); + 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: |