diff options
author | Keith Short <keithshort@chromium.org> | 2020-02-19 17:56:12 -0700 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2020-02-29 01:19:14 +0000 |
commit | 0eb3e2a0c7e71e461b2ee0375652bb61b28c1cb7 (patch) | |
tree | d62b83b28f7e7f7cb66c6e353a51527bfba37ca0 /power | |
parent | bb9998acdffc3176a119f5c8620345b832cf17f0 (diff) | |
download | chrome-ec-0eb3e2a0c7e71e461b2ee0375652bb61b28c1cb7.tar.gz |
volteer: Prevent glitch on SLP_S3_L during power on
Reconfigure the SLP_S3_L power interrupt as an output and drive this
signal low while the PP3300_A rail comes up. This prevents a glitch on
the SLP_S3_L signal that can affect the power sequencing.
BUG=b:143346794
BRANCH=none
TEST=make buildall
TEST=Verify Volteer boots. With debug code enabled, verify SLP_S3_L
drives low while PP3300 turns on.
Change-Id: Ic8204874cb9e68a1af27fafcf5274d50ce5cb38f
Signed-off-by: Keith Short <keithshort@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2068535
Reviewed-by: Abe Levkoy <alevkoy@chromium.org>
Diffstat (limited to 'power')
-rw-r--r-- | power/icelake.c | 51 |
1 files changed, 36 insertions, 15 deletions
diff --git a/power/icelake.c b/power/icelake.c index 62e3ccbc8e..fadfb8d3a6 100644 --- a/power/icelake.c +++ b/power/icelake.c @@ -174,18 +174,25 @@ static void assert_ec_ap_vccst_pwrgd_pch_pwrok(void) DECLARE_DEFERRED(assert_ec_ap_vccst_pwrgd_pch_pwrok); #endif /* CONFIG_CHIPSET_JASPERLAKE */ -enum power_state power_handle_state(enum power_state state) +static void dsw_pwrok_pass_thru(void) { int dswpwrok_in = intel_x86_get_pg_ec_dsw_pwrok(); static int dswpwrok_out = -1; - int all_sys_pwrgd_in = intel_x86_get_pg_ec_all_sys_pwrgd(); - int all_sys_pwrgd_out; -#ifdef CONFIG_CHIPSET_JASPERLAKE - int timeout_ms = 10; -#endif /* CONFIG_CHIPSET_JASPERLAKE */ /* Pass-through DSW_PWROK to ICL. */ if (dswpwrok_in != dswpwrok_out) { + if (IS_ENABLED(CONFIG_CHIPSET_SLP_S3_L_OVERRIDE) + && dswpwrok_in) { + /* + * Once DSW_PWROK is high, reconfigure SLP_S3_L back to + * an input after a short delay. + */ + msleep(1); + CPRINTS("Release SLP_S3_L"); + gpio_reset(SLP_S3_SIGNAL_L); + power_signal_enable_interrupt(SLP_S3_SIGNAL_L); + } + CPRINTS("Pass thru GPIO_DSW_PWROK: %d", dswpwrok_in); /* * A minimum 10 msec delay is required between PP3300_A being @@ -195,6 +202,17 @@ enum power_state power_handle_state(enum power_state state) GPIO_SET_LEVEL(GPIO_PCH_DSW_PWROK, dswpwrok_in); dswpwrok_out = dswpwrok_in; } +} + +enum power_state power_handle_state(enum power_state state) +{ + int all_sys_pwrgd_in = intel_x86_get_pg_ec_all_sys_pwrgd(); + int all_sys_pwrgd_out; +#ifdef CONFIG_CHIPSET_JASPERLAKE + int timeout_ms = 10; +#endif /* CONFIG_CHIPSET_JASPERLAKE */ + + dsw_pwrok_pass_thru(); #ifdef CONFIG_CHIPSET_JASPERLAKE /* @@ -219,6 +237,17 @@ enum power_state power_handle_state(enum power_state state) switch (state) { case POWER_G3S5: + if (IS_ENABLED(CONFIG_CHIPSET_SLP_S3_L_OVERRIDE)) { + /* + * Prevent glitches on the SLP_S3_L and PCH_PWROK + * signals while when the PP3300_A rail is turned on. + * Drive SLP_S3_L from the EC until DSW_PWROK is high. + */ + CPRINTS("Drive SLP_S3_L low during PP3300_A rampup"); + power_signal_disable_interrupt(SLP_S3_SIGNAL_L); + gpio_set_flags(SLP_S3_SIGNAL_L, GPIO_ODR_LOW); + } + /* Default behavior - turn on PP5000 rail first */ if (!IS_ENABLED(CONFIG_CHIPSET_PP3300_RAIL_FIRST)) enable_pp5000_rail(); @@ -235,15 +264,7 @@ enum power_state power_handle_state(enum power_state state) break; /* Pass thru DSWPWROK again since we changed it. */ - dswpwrok_in = intel_x86_get_pg_ec_dsw_pwrok(); - /* - * A minimum 10 msec delay is required between PP3300_A being - * stable and the DSW_PWROK signal being passed to the PCH. - */ - msleep(10); - GPIO_SET_LEVEL(GPIO_PCH_DSW_PWROK, dswpwrok_in); - CPRINTS("Pass thru GPIO_DSW_PWROK: %d", dswpwrok_in); - dswpwrok_out = dswpwrok_in; + dsw_pwrok_pass_thru(); /* Turn on PP5000 after PP3300 and DSW PWROK when enabled */ if (IS_ENABLED(CONFIG_CHIPSET_PP3300_RAIL_FIRST)) |