summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDuncan Laurie <dlaurie@chromium.org>2015-10-22 08:55:17 -0700
committerChromeOS bot <3su6n15k.default@developer.gserviceaccount.com>2015-10-30 15:52:46 +0000
commit9cecbd36503bbf6d0e6d888c9fb4762e381cbaf7 (patch)
tree7d5ac33ebd1182c64a4f24963c98f41619ef420c
parentd07d1870fa2e10c25b0062afa3036566f1304fc2 (diff)
downloadchrome-ec-9cecbd36503bbf6d0e6d888c9fb4762e381cbaf7.tar.gz
lulu: 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:46520 BRANCH=lulu TEST=Confirm RTCRST asserts if SLP_S5 does not deassert and then system can power on normally. Change-Id: I29a7e9b120882f6b2303bf285a9ee6b63a9a628c Signed-off-by: Duncan Laurie <dlaurie@chromium.org> Signed-off-by: Grover Yen <Grover_Yen@wistron.com> Reviewed-on: https://chromium-review.googlesource.com/309927 Tested-by: Sean Chiang <sean_fs_chiang@wistron.com> Commit-Queue: Sean Chiang <sean_fs_chiang@wistron.com>
-rw-r--r--board/lulu/board.h3
-rw-r--r--board/lulu/gpio.inc2
-rw-r--r--power/haswell.c29
3 files changed, 31 insertions, 3 deletions
diff --git a/board/lulu/board.h b/board/lulu/board.h
index ffeeb5eddb..7423a66abe 100644
--- a/board/lulu/board.h
+++ b/board/lulu/board.h
@@ -45,6 +45,9 @@
#define CONFIG_WIRELESS_SUSPEND \
(EC_WIRELESS_SWITCH_WLAN | EC_WIRELESS_SWITCH_WLAN_POWER)
+/* This board has RTCRST connection from EC GPIO to the PCH */
+#define BOARD_HAS_RTCRST
+
#ifndef __ASSEMBLER__
/* I2C ports */
diff --git a/board/lulu/gpio.inc b/board/lulu/gpio.inc
index 8b2e61c36d..395f7b470f 100644
--- a/board/lulu/gpio.inc
+++ b/board/lulu/gpio.inc
@@ -80,7 +80,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(BAT_LED0_L, D, 0, GPIO_ODR_HIGH, NULL) /* Battery charging LED - white */
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: