From 28322ab75f72e01b13de0ce63b0ac3bf7aeaf8f0 Mon Sep 17 00:00:00 2001 From: Duncan Laurie Date: Thu, 22 Oct 2015 08:55:17 -0700 Subject: 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 Reviewed-on: https://chromium-review.googlesource.com/310588 Reviewed-by: Duncan Laurie --- board/buddy/board.h | 3 +++ board/buddy/gpio.inc | 2 +- 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: -- cgit v1.2.1