diff options
Diffstat (limited to 'power')
-rw-r--r-- | power/stoney.c | 81 |
1 files changed, 48 insertions, 33 deletions
diff --git a/power/stoney.c b/power/stoney.c index 911ebe3b09..7c1c8261c3 100644 --- a/power/stoney.c +++ b/power/stoney.c @@ -41,16 +41,32 @@ void chipset_force_shutdown(void) } } +static void chipset_force_g3(void) +{ +#ifdef BOARD_KAHLEE + /* Power off in G3 not supported on kahlee so shutdown instead. */ + chipset_force_shutdown(); +#else + /* Disable system power ("*_A" rails) in G3. */ + gpio_set_level(GPIO_EN_PWR_A, 0); +#endif +} + void chipset_reset(int cold_reset) { CPRINTS("%s(%d)", __func__, cold_reset); + + if (chipset_in_state(CHIPSET_STATE_ANY_OFF)) { + CPRINTS("Can't reset: SOC is off"); + return; + } + if (cold_reset) { /* * Perform chipset_force_shutdown and mark forcing_coldreset. * Once in S5G3 state, check forcing_coldreset to power up. */ forcing_coldreset = 1; - chipset_force_shutdown(); } else { /* @@ -89,13 +105,12 @@ enum power_state power_chipset_init(void) } CPRINTS("forcing G3"); - chipset_force_shutdown(); + chipset_force_g3(); } return POWER_G3; } -static void handle_pass_through(enum power_state state, - enum gpio_signal pin_in, +static void handle_pass_through(enum gpio_signal pin_in, enum gpio_signal pin_out) { /* @@ -105,6 +120,13 @@ static void handle_pass_through(enum power_state state, int in_level = gpio_get_level(pin_in); int out_level = gpio_get_level(pin_out); + /* + * Only pass through high VGATE (S0 power) when SPOK (system power, S5) + * is also high (VGATE is pulled high in G3 when SPOK is low). + */ + if ((pin_in == GPIO_VGATE) && !gpio_get_level(GPIO_SPOK)) + in_level = 0; + /* Nothing to do. */ if (in_level == out_level) return; @@ -121,8 +143,12 @@ static void handle_pass_through(enum power_state state, CPRINTS("Pass through %s: %d", gpio_get_name(pin_in), in_level); } -enum power_state _power_handle_state(enum power_state state) +enum power_state power_handle_state(enum power_state state) { + handle_pass_through(GPIO_SPOK, GPIO_PCH_RSMRST_L); + + handle_pass_through(GPIO_VGATE, GPIO_PCH_SYS_PWROK); + if (state == POWER_S5 && forcing_shutdown) { power_button_pch_release(); forcing_shutdown = 0; @@ -136,22 +162,27 @@ enum power_state _power_handle_state(enum power_state state) /* Exit SOC G3 */ /* Platform is powering up, clear forcing_coldreset */ forcing_coldreset = 0; -#ifdef CONFIG_PMIC + +#ifndef BOARD_KAHLEE + /* Enable system power ("*_A" rails) in S5. */ + gpio_set_level(GPIO_EN_PWR_A, 1); +#endif + /* Call hooks to initialize PMIC */ hook_notify(HOOK_CHIPSET_PRE_INIT); -#endif - CPRINTS("Exit SOC G3"); if (power_wait_signals(IN_SPOK)) { - chipset_force_shutdown(); + chipset_force_g3(); return POWER_G3; } + + CPRINTS("Exit SOC G3"); + return POWER_S5; case POWER_S5: if (!power_has_signals(IN_SPOK)) { /* Required rail went away */ - chipset_force_shutdown(); return POWER_S5G3; } else if (gpio_get_level(GPIO_PCH_SLP_S5_L) == 1) { /* Power up to next state */ @@ -162,7 +193,6 @@ enum power_state _power_handle_state(enum power_state state) case POWER_S5S3: if (!power_has_signals(IN_SPOK)) { /* Required rail went away */ - chipset_force_shutdown(); return POWER_S5G3; } @@ -174,8 +204,7 @@ enum power_state _power_handle_state(enum power_state state) case POWER_S3: if (!power_has_signals(IN_SPOK)) { /* Required rail went away */ - chipset_force_shutdown(); - return POWER_S3S5; + return POWER_S5G3; } else if (gpio_get_level(GPIO_PCH_SLP_S3_L) == 1) { /* Power up to next state */ return POWER_S3S0; @@ -188,8 +217,7 @@ enum power_state _power_handle_state(enum power_state state) case POWER_S3S0: if (!power_has_signals(IN_SPOK)) { /* Required rail went away */ - chipset_force_shutdown(); - return POWER_S3S5; + return POWER_S5G3; } /* Enable wireless */ @@ -208,14 +236,14 @@ enum power_state _power_handle_state(enum power_state state) case POWER_S0: if (!power_has_signals(IN_SPOK)) { - chipset_force_shutdown(); - return POWER_S0S3; + /* Required rail went away */ + return POWER_S5G3; } else if (gpio_get_level(GPIO_PCH_SLP_S3_L) == 0) { /* Power down to next state */ return POWER_S0S3; } - break; + case POWER_S0S3: /* Call hooks before we remove power rails */ hook_notify(HOOK_CHIPSET_SUSPEND); @@ -241,7 +269,6 @@ enum power_state _power_handle_state(enum power_state state) return POWER_S5; case POWER_S5G3: - chipset_force_shutdown(); /* Power up the platform again for forced cold reset */ if (forcing_coldreset) { @@ -249,6 +276,8 @@ enum power_state _power_handle_state(enum power_state state) return POWER_G3S5; } + chipset_force_g3(); + return POWER_G3; default: @@ -256,17 +285,3 @@ enum power_state _power_handle_state(enum power_state state) } return state; } - -enum power_state power_handle_state(enum power_state state) -{ - enum power_state new_state; - - handle_pass_through(state, GPIO_SPOK, GPIO_PCH_RSMRST_L); - - handle_pass_through(state, GPIO_VGATE, GPIO_PCH_SYS_PWROK); - - new_state = _power_handle_state(state); - - return new_state; -} - |