stoney: 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:156694627, b:157077589
BRANCH=none
TEST=test_that suite:faft_bios

Signed-off-by: Daisuke Nojiri <dnojiri@chromium.org>
Change-Id: Id8fdd10f411f403cb42bd8429fef737e88421ae9
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2220547
Reviewed-by: Aseda Aboagye <aaboagye@chromium.org>
Reviewed-by: Denis Brockus <dbrockus@chromium.org>
This commit is contained in:
Daisuke Nojiri 2020-05-28 12:33:16 -07:00 committed by Commit Bot
parent a46980b186
commit 84b959ca35
1 changed files with 25 additions and 14 deletions

View File

@ -94,26 +94,37 @@ void chipset_handle_espi_reset_assert(void)
enum power_state power_chipset_init(void)
{
CPRINTS("%s: power_signal=0x%x", __func__, power_get_signals());
/* Pause in S5 when shutting down. */
power_set_pause_in_s5(1);
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 (gpio_get_level(GPIO_S0_PGOOD)) {
/* Disable idle task deep sleep when in S0. */
disable_sleep(SLEEP_MASK_AP_RUN);
CPRINTS("already in S0");
return POWER_S0;
}
CPRINTS("forcing G3");
chipset_force_g3();
if (gpio_get_level(GPIO_S0_PGOOD)) {
/* 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() & IN_S5_PGOOD) {
/* case #2 & #3 */
CPRINTS("already in S5");
return POWER_S5;
}
/* case #4 */
chipset_force_g3();
return POWER_G3;
}