diff options
-rw-r--r-- | include/config.h | 6 | ||||
-rw-r--r-- | include/power.h | 4 | ||||
-rw-r--r-- | power/braswell.c | 39 | ||||
-rw-r--r-- | power/common.c | 4 |
4 files changed, 49 insertions, 4 deletions
diff --git a/include/config.h b/include/config.h index a913009aeb..e43fd25253 100644 --- a/include/config.h +++ b/include/config.h @@ -1102,6 +1102,12 @@ #undef CONFIG_LOW_POWER_USE_LFIOSC /* + * Enable Pseudo G3 (power removed from EC) + * This requires board specific implementation. + */ +#undef CONFIG_LOW_POWER_PSEUDO_G3 + +/* * Enable deep sleep during S0 (ignores SLEEP_MASK_AP_RUN). */ #undef CONFIG_LOW_POWER_S0 diff --git a/include/power.h b/include/power.h index 9ba4213ad1..6a108c8690 100644 --- a/include/power.h +++ b/include/power.h @@ -117,4 +117,8 @@ inline int power_get_pause_in_s5(void); */ inline void power_set_pause_in_s5(int pause); +#ifdef CONFIG_LOW_POWER_PSEUDO_G3 +void enter_pseudo_g3(void); +#endif + #endif /* __CROS_EC_POWER_H */ diff --git a/power/braswell.c b/power/braswell.c index aa9301f5d8..7ca596a3cf 100644 --- a/power/braswell.c +++ b/power/braswell.c @@ -141,6 +141,10 @@ enum power_state power_handle_state(enum power_state state) break; case POWER_G3S5: + /* Exit SOC G3 */ + gpio_set_level(GPIO_SUSPWRDNACK_SOC_EC, 0); + CPRINTS("Exit SOC G3"); + if (power_wait_signals(IN_PGOOD_S5)) { chipset_force_shutdown(); return POWER_G3; @@ -296,10 +300,37 @@ enum power_state power_handle_state(enum power_state state) return power_get_pause_in_s5() ? POWER_S5 : POWER_S5G3; case POWER_S5G3: - /* Assert RSMRST# */ - gpio_set_level(GPIO_PCH_RSMRST_L, 0); - return POWER_G3; - } + if (gpio_get_level(GPIO_PCH_SUSPWRDNACK) == 1) { + /* Assert RSMRST# */ + gpio_set_level(GPIO_PCH_RSMRST_L, 0); + + /* Config pins for SOC G3 */ + gpio_config_module(MODULE_GPIO, 1); + /* Enter SOC G3 */ + gpio_set_level(GPIO_SUSPWRDNACK_SOC_EC, 1); + CPRINTS("Enter SOC G3"); + + return POWER_G3; + } else { + CPRINTS("waiting for PMC_SUSPWRDNACK to assert!"); + return POWER_S5; + } + } return state; } + +#ifdef CONFIG_LOW_POWER_PSEUDO_G3 +void enter_pseudo_g3(void) +{ + CPRINTS("Enter Psuedo G3"); + cflush(); + + gpio_set_level(GPIO_EC_HIB_L, 1); + gpio_set_level(GPIO_SMC_SHUTDOWN, 1); + + /* Power to EC should shut down now */ + while (1) + ; +} +#endif diff --git a/power/common.c b/power/common.c index f59fe45273..2520d06010 100644 --- a/power/common.c +++ b/power/common.c @@ -167,8 +167,12 @@ static enum power_state power_common_state(enum power_state state) * Time's up. Hibernate until wake pin * asserted. */ +#ifdef CONFIG_LOW_POWER_PSEUDO_G3 + enter_pseudo_g3(); +#else CPRINTS("hibernating"); system_hibernate(0, 0); +#endif } else { uint64_t wait = target_time - time_now; if (wait > TASK_MAX_WAIT_US) |