diff options
Diffstat (limited to 'power')
-rw-r--r-- | power/mt8186.c | 38 |
1 files changed, 29 insertions, 9 deletions
diff --git a/power/mt8186.c b/power/mt8186.c index d5d5056ffc..0653c70ba0 100644 --- a/power/mt8186.c +++ b/power/mt8186.c @@ -82,6 +82,8 @@ static bool is_resetting; /* indicate MT8186 is processing a AP forcing shutdown. */ static bool is_shutdown; +/* indicate MT8186 has been dropped to S5G3 from the last IN_AP_RST state . */ +static bool is_s5g3_passed; /* * indicate exiting off state, and don't respect the power signals until chipset * on. @@ -213,15 +215,18 @@ static void power_reset_host_sleep_state(void) /* * Power state is determined from the following table: * - * | IN_AP_RST | IN_SUSPEND_ASSERTED | - * ---------------------------------------------- - * S0 | 0 | 0 | - * S3 | 0 | 1 | - * G3 | 1 | x | + * | IN_AP_RST | IN_SUSPEND_ASSERTED | is_s5g3_passed | + * -------------------------------------------------------- + * S0 | 0 | 0 | x| + * S3 | 0 | 1 | x| + * S5 | 1 | x | 0| + * G3 | 1 | x | 1| * - * S5 is only used when exit from G3 in power_common_state(). + * S5 is a temp stage, which will be put into G3 after s5_inactivity_timeout. * is_resetting flag indicate it's resetting chipset, and it's always S0. * is_shutdown flag indicates it's shutting down the AP, it goes for S5. + * is_s5g3_passed flag indicates it has shutdown from S5 to G3 since last + * shutdown. */ static enum power_state power_get_signal_state(void) { @@ -235,8 +240,12 @@ static enum power_state power_get_signal_state(void) return POWER_S0; if (is_shutdown) return POWER_S5; - if (power_get_signals() & IN_AP_RST) - return POWER_G3; + if (power_get_signals() & IN_AP_RST) { + /* If it has been put to G3 from S5 idle, then stay at G3.*/ + if (is_s5g3_passed) + return POWER_G3; + return POWER_S5; + } if (power_get_signals() & IN_SUSPEND_ASSERTED) return POWER_S3; return POWER_S0; @@ -311,6 +320,8 @@ enum power_state power_handle_state(enum power_state state) return POWER_S5S3; else if (next_state == POWER_G3) return POWER_S5G3; + else if (next_state == POWER_S5) + return POWER_S5; else return POWER_S5S3; @@ -342,6 +353,7 @@ enum power_state power_handle_state(enum power_state state) case POWER_S5S3: /* Off state exited. */ is_exiting_off = false; + is_s5g3_passed = false; hook_notify(HOOK_CHIPSET_PRE_INIT); power_signal_enable_interrupt(GPIO_AP_IN_SLEEP_L); @@ -415,7 +427,14 @@ enum power_state power_handle_state(enum power_state state) power_signal_disable_interrupt(GPIO_AP_IN_SLEEP_L); power_signal_disable_interrupt(GPIO_AP_EC_WDTRST_L); power_signal_disable_interrupt(GPIO_AP_EC_WARM_RST_REQ); - GPIO_SET_LEVEL(GPIO_SYS_RST_ODL, 0); + + /* Only actively reset AP with hard shutdown. + * For AP initiated shutdown, the AP has been reset by PMIC. + * For servo, gsc initiaed warm reset, EC doesn't need to hold + * it. + */ + if (is_shutdown) + GPIO_SET_LEVEL(GPIO_SYS_RST_ODL, 0); /* Call hooks before we remove power rails */ hook_notify(HOOK_CHIPSET_SHUTDOWN); @@ -432,6 +451,7 @@ enum power_state power_handle_state(enum power_state state) return POWER_S5; case POWER_S5G3: + is_s5g3_passed = true; #if DT_NODE_EXISTS(DT_NODELABEL(en_pp4200_s5)) if (power_wait_mask_signals_timeout(IN_PMIC_AP_RST, IN_PMIC_AP_RST, |