diff options
author | Daisuke Nojiri <dnojiri@chromium.org> | 2020-05-22 13:54:49 -0700 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2020-06-09 00:53:20 +0000 |
commit | a46980b1865aeaed3d685e5ff2b14f790159894a (patch) | |
tree | d1478be414fd9032694243e7d514b99e64c83384 /power/intel_x86.c | |
parent | e938e49b2d7319158d46f596fbee38a066f11a99 (diff) | |
download | chrome-ec-a46980b1865aeaed3d685e5ff2b14f790159894a.tar.gz |
x86 power: Initialize chipset state to S5 after sysjump
Currently, RW initializes the chipset state to G3 and forces the
chipset to shut down unless the AP is already powered on. This
behavior is based on the assumption that sysjump happens only upon
a request from the AP.
With EFS2, it's no longer the case because EC jumps while the AP
is off. AP may be off, resetting (i.e. s0->s5->s0), or shutting
down (s0->s5).
This patch makes RW set the chipset state to S5 if the corresponding
power signals are on.
BUG=b:154778457
BRANCH=none
TEST=Verify test_that suite:faft_bios passes.
Signed-off-by: Daisuke Nojiri <dnojiri@chromium.org>
Change-Id: I65cbb6c6e7f8a01e80d83a74e376ceb9628b9789
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2213733
Reviewed-by: Aseda Aboagye <aaboagye@chromium.org>
Reviewed-by: Aaron Durbin <adurbin@google.com>
Diffstat (limited to 'power/intel_x86.c')
-rw-r--r-- | power/intel_x86.c | 40 |
1 files changed, 26 insertions, 14 deletions
diff --git a/power/intel_x86.c b/power/intel_x86.c index a4de71ff5f..8457c3bb0a 100644 --- a/power/intel_x86.c +++ b/power/intel_x86.c @@ -340,23 +340,35 @@ void chipset_throttle_cpu(int throttle) enum power_state power_chipset_init(void) { + CPRINTS("%s: power_signal=0x%x", __func__, power_get_signals()); + + if (!system_jumped_to_this_image()) + return POWER_G3; /* - * If we're switching between images without rebooting, see if the x86 - * is already powered on; if so, leave it there instead of cycling - * through G3. + * We are here as RW. We need to handle the following cases: + * + * 1. Late sysjump by software sync. AP is in S0. + * 2. Shutting down in recovery mode then sysjump by EFS2. AP is in S5 + * and expected to sequence down. + * 3. Rebooting from recovery mode then sysjump by EFS2. AP is in S5 + * and expected to sequence up. + * 4. RO jumps to RW from main() by EFS2. (a.k.a. power on reset, cold + * reset). AP is in G3. */ - if (system_jumped_to_this_image()) { - if ((power_get_signals() & IN_ALL_S0) == IN_ALL_S0) { - /* Disable idle task deep sleep when in S0. */ - disable_sleep(SLEEP_MASK_AP_RUN); - CPRINTS("already in S0"); - return POWER_S0; - } - - /* Force all signals to their G3 states */ - chipset_force_g3(); + if ((power_get_signals() & IN_ALL_S0) == IN_ALL_S0) { + /* case #1. Disable idle task deep sleep when in S0. */ + disable_sleep(SLEEP_MASK_AP_RUN); + CPRINTS("already in S0"); + return POWER_S0; } - + if ((power_get_signals() & CHIPSET_G3S5_POWERUP_SIGNAL) + == CHIPSET_G3S5_POWERUP_SIGNAL) { + /* case #2 & #3 */ + CPRINTS("already in S5"); + return POWER_S5; + } + /* case #4 */ + chipset_force_g3(); return POWER_G3; } |