From 8ee76987c8e91d379b4e580a2b895b454c31da45 Mon Sep 17 00:00:00 2001 From: Aaron Durbin Date: Fri, 23 Aug 2013 10:49:01 -0500 Subject: [PATCH] bolt: workaround board sequencing deficiencies The bolt board has the PP1050 regulator's pgood output connected to VCCST_PWRGD on the chipset. However, that is inappropriate because VCCST_PWRGD is the signal used when the 1.05V rail is good when transitioning to S0. The PP1050 regulator needs to be up while in S5 to supply the 1.05V suspend rail. To work around this mismatch, the PP1050_PGOOD signal which is routed to the EC needs to be changed to an open-drain output. It's driven low until the transition to S0 in order to properly sequence the chip. BUG=chrome-os-partner:20372 BRANCH=None TEST=Built and booted on handful of boards. Change-Id: Ic85eab8f295f6e76d9b33f440e68c82096976683 Signed-off-by: Aaron Durbin Reviewed-on: https://gerrit.chromium.org/gerrit/66821 Reviewed-by: Bill Richardson Reviewed-by: Randall Spangler --- board/bolt/board.c | 5 ++-- board/bolt/board.h | 1 - board/bolt/power_sequence.c | 46 ++++++++++++++++++++++++++----------- 3 files changed, 34 insertions(+), 18 deletions(-) diff --git a/board/bolt/board.c b/board/bolt/board.c index b3e622af20..55c22f2f7b 100644 --- a/board/bolt/board.c +++ b/board/bolt/board.c @@ -51,8 +51,8 @@ const struct gpio_info gpio_list[] = { x86_interrupt}, {"PCH_SUSWARN_L", LM4_GPIO_G, (1<<2), GPIO_INT_BOTH, x86_interrupt}, - {"PP1050_PGOOD", LM4_GPIO_H, (1<<4), GPIO_INT_BOTH, - x86_interrupt}, + /* EC needs to control PP1050_PGOOD as it goes to VCCST_PGOOD. */ + {"PP1050_PGOOD", LM4_GPIO_H, (1<<4), GPIO_ODR_LOW, NULL }, {"PP1350_PGOOD", LM4_GPIO_H, (1<<6), GPIO_INT_BOTH, x86_interrupt}, {"PP5000_PGOOD", LM4_GPIO_N, (1<<0), GPIO_INT_BOTH, @@ -151,7 +151,6 @@ const int gpio_alt_funcs_count = ARRAY_SIZE(gpio_alt_funcs); const struct x86_signal_info x86_signal_list[] = { {GPIO_PP5000_PGOOD, 1, "PGOOD_PP5000"}, {GPIO_PP1350_PGOOD, 1, "PGOOD_PP1350"}, - {GPIO_PP1050_PGOOD, 1, "PGOOD_PP1050"}, {GPIO_VCORE_PGOOD, 1, "PGOOD_VCORE"}, {GPIO_PCH_SLP_S0_L, 1, "SLP_S0#_DEASSERTED"}, {GPIO_PCH_SLP_S3_L, 1, "SLP_S3#_DEASSERTED"}, diff --git a/board/bolt/board.h b/board/bolt/board.h index af60583e44..2133701812 100644 --- a/board/bolt/board.h +++ b/board/bolt/board.h @@ -168,7 +168,6 @@ enum gpio_signal { enum x86_signal { X86_PGOOD_PP5000 = 0, X86_PGOOD_PP1350, - X86_PGOOD_PP1050, X86_PGOOD_VCORE, X86_PCH_SLP_S0n_DEASSERTED, X86_PCH_SLP_S3n_DEASSERTED, diff --git a/board/bolt/power_sequence.c b/board/bolt/power_sequence.c index ba5e70589c..606e5434cb 100644 --- a/board/bolt/power_sequence.c +++ b/board/bolt/power_sequence.c @@ -25,7 +25,6 @@ /* Input state flags */ #define IN_PGOOD_PP5000 X86_SIGNAL_MASK(X86_PGOOD_PP5000) #define IN_PGOOD_PP1350 X86_SIGNAL_MASK(X86_PGOOD_PP1350) -#define IN_PGOOD_PP1050 X86_SIGNAL_MASK(X86_PGOOD_PP1050) #define IN_PGOOD_VCORE X86_SIGNAL_MASK(X86_PGOOD_VCORE) #define IN_PCH_SLP_S0n_DEASSERTED X86_SIGNAL_MASK(X86_PCH_SLP_S0n_DEASSERTED) #define IN_PCH_SLP_S3n_DEASSERTED X86_SIGNAL_MASK(X86_PCH_SLP_S3n_DEASSERTED) @@ -35,7 +34,7 @@ /* All always-on supplies */ #define IN_PGOOD_ALWAYS_ON (IN_PGOOD_PP5000) /* All non-core power rails */ -#define IN_PGOOD_ALL_NONCORE (IN_PGOOD_PP1350 | IN_PGOOD_PP1050) +#define IN_PGOOD_ALL_NONCORE (IN_PGOOD_PP1350) /* All core power rails */ #define IN_PGOOD_ALL_CORE (IN_PGOOD_VCORE) /* Rails required for S3 */ @@ -131,6 +130,7 @@ enum x86_state x86_chipset_init(void) gpio_set_level(GPIO_VCORE_EN, 0); gpio_set_level(GPIO_PP1050_EN, 0); gpio_set_level(GPIO_PP1350_EN, 0); + gpio_set_level(GPIO_PP1050_PGOOD, 0); gpio_set_level(GPIO_EC_EDP_VDD_EN, 0); gpio_set_level(GPIO_PP3300_DX_EN, 0); gpio_set_level(GPIO_PP3300_DSW_GATED_EN, 0); @@ -195,23 +195,33 @@ enum x86_state x86_handle_state(enum x86_state state) */ msleep(10); - /* Assert DPWROK */ - gpio_set_level(GPIO_PCH_DPWROK, 1); - if (x86_wait_signals(IN_PCH_SLP_SUSn_DEASSERTED)) { - chipset_force_shutdown(); - return X86_G3; - } - - /* Enable PP5000 (5V) rail as 1.05V and 1.35V rails are - * derived from 5V. */ + /* Enable PP5000 (5V) rail as 1.05V and 1.35V rails need 5V + * rail to regulate properly. */ gpio_set_level(GPIO_PP5000_EN, 1); if (x86_wait_signals(IN_PGOOD_PP5000)) { chipset_force_shutdown(); return X86_G3; } + /* Assert DPWROK */ + gpio_set_level(GPIO_PCH_DPWROK, 1); + + /* Enable PP1050 rail. Bring up the PP1050_PCH_SUS rail to + * provide 1.05V suspend as early as possible as the RSMSRT# + * signal deasserting indicates both the PP3300_PCH_SUS + * and PP1050_PCH_SUS rails are good. Since PP1050_PGGOOD is + * driven as output to work around VCCST_PWRGD timing problems + * there is no way to know when PP1050_PCH_SUS rail is good. + * Similarly the PP3300_PCH_SUS rail is enabled by SLP_SUS# + * being deasserted without a power good signal. The RSMRST# + * is driven by an RC circuit feeding into schmitt trigger. + * Therefore, the PP1050_PCH_SUS rail is brought up as early + * as possible after DPWROK is asserted so that it will be + * ready by the time RSMRST# is deasserted. */ gpio_set_level(GPIO_PP1050_EN, 1); - if (x86_wait_signals(IN_PGOOD_PP1050)) { + + /* Wait for SLP_SUS# to deassert before enabling PP1050. */ + if (x86_wait_signals(IN_PCH_SLP_SUSn_DEASSERTED)) { chipset_force_shutdown(); return X86_G3; } @@ -252,12 +262,17 @@ enum x86_state x86_handle_state(enum x86_state state) return X86_S3; case X86_S3S0: + /* Wait 20ms before allowing VCCST_PGOOD to rise. */ + msleep(20); + /* Assert VCCST_PGOOD using PP1050_PGOOD. */ + gpio_set_level(GPIO_PP1050_PGOOD, 1); + /* Turn on power rails */ gpio_set_level(GPIO_PP3300_DX_EN, 1); gpio_set_level(GPIO_PP3300_DSW_GATED_EN, 1); - /* Enable wireless -- FIXME: not really*/ - wireless_enable(0 /* EC_WIRELESS_SWITCH_ALL */); + /* Enable wireless */ + wireless_enable(EC_WIRELESS_SWITCH_ALL); /* * Make sure touchscreen is out if reset (even if the @@ -273,6 +288,7 @@ enum x86_state x86_handle_state(enum x86_state state) gpio_set_level(GPIO_EC_EDP_VDD_EN, 0); gpio_set_level(GPIO_PP3300_DX_EN, 0); gpio_set_level(GPIO_PP3300_DSW_GATED_EN, 0); + gpio_set_level(GPIO_PP1050_PGOOD, 0); return X86_S3; } @@ -303,6 +319,8 @@ enum x86_state x86_handle_state(enum x86_state state) /* Call hooks before we remove power rails */ hook_notify(HOOK_CHIPSET_SUSPEND); + /* Drop VCCST_PGOOD */ + gpio_set_level(GPIO_PP1050_PGOOD, 0); /* Clear PCH_PWROK */ gpio_set_level(GPIO_SYS_PWROK, 0); gpio_set_level(GPIO_PCH_PWROK, 0);