summaryrefslogtreecommitdiff
path: root/power/mt8186.c
diff options
context:
space:
mode:
authorEric Yilun Lin <yllin@chromium.org>2022-05-30 15:26:53 +0800
committerChromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com>2022-05-30 09:21:01 +0000
commit8b0bb66056cd2aa6eff887fa9bf04cccd71bcb6e (patch)
tree538832ee90a6cbc416476a09a4f94b002d35a44e /power/mt8186.c
parent042f73594fc0dd58c159f4cbec5133cc0b7be475 (diff)
downloadchrome-ec-8b0bb66056cd2aa6eff887fa9bf04cccd71bcb6e.tar.gz
power/mt8186: stay at S5 before PMIC is fully off
If we command the device to enter hibernate mode before PMIC is fully off, then there will be power leakage from AP_EC_WDTRST_L which is pulled up by PMIC. On MT8186, the S5 was a transition state, it passed through S5 and entered G3 before the PMIC is fully off. In normal cases, this won't be an issue that it takes long enough time to hibernate from G3. However, firmware_ECWakeFromULP force EC enter hibernation once the DUT gets into the G3, and this hits the PMIC issue. To fix this, we force the DUT staying at S5 until the EC_PMIC_EN_ODL released (8 seconds), and then enter the G3 state. BUG=b:233988259 TEST=stay at S5 until EC_PMIC_EN_ODL deasserted and then into G3. TEST=Test following items: * Cold reset: $ dut-control cold_reset:on sleep:0.2 cold_reset:off Result: G3 -> S0 * Long power press to shutdown: $ dut-control 'ec_uart_cmd:powerbtn 8200' Result: S0 -> S5 -> G3 * Long power press to power-on but then shutdown: $ dut-control 'ec_uart_cmd:powerbtn 8200' Result: G3 -> S0 -> S5 -> G3 * Short power press to power-on: $ dut-control 'ec_uart_cmd:powerbtn 200' Result: G3 -> S0 * Console command: apreset Result: S0 -> S5 -> S0, AP reboots * Console command: apshutdown Result: S0 -> S5 -> G3 * Lid open to power-on: $ dut-control lid_open:no sleep:0.2 lid_open:yes Result: G3 -> S0 BRANCH=none Change-Id: Id5809ff5dc72e35a75d9b20b2013522610ae4eaf Signed-off-by: Eric Yilun Lin <yllin@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3676896 Commit-Queue: Eric Yilun Lin <yllin@google.com> Tested-by: Eric Yilun Lin <yllin@google.com> Reviewed-by: Ting Shen <phoenixshen@chromium.org>
Diffstat (limited to 'power/mt8186.c')
-rw-r--r--power/mt8186.c45
1 files changed, 35 insertions, 10 deletions
diff --git a/power/mt8186.c b/power/mt8186.c
index b83a46856b..8373319109 100644
--- a/power/mt8186.c
+++ b/power/mt8186.c
@@ -83,6 +83,11 @@ BUILD_ASSERT(ARRAY_SIZE(power_signal_list) == POWER_SIGNAL_COUNT);
static bool is_resetting;
/* indicate MT8186 is processing a AP shutdown. */
static bool is_shutdown;
+/*
+ * indicate exiting off state, and don't respect the power signals until chipset
+ * on.
+ */
+static bool is_exiting_off = true;
static void reset_request_interrupt_deferred(void)
{
@@ -124,7 +129,7 @@ void chipset_watchdog_interrupt(enum gpio_signal signal)
static void release_power_button(void)
{
- CPRINTS("release power button after 8 seconds.");
+ CPRINTS("release power button");
GPIO_SET_LEVEL(GPIO_EC_PMIC_EN_ODL, 1);
}
DECLARE_DEFERRED(release_power_button);
@@ -154,6 +159,12 @@ void chipset_force_shutdown_button(void)
}
DECLARE_DEFERRED(chipset_force_shutdown_button);
+static void mt8186_exit_off(void)
+{
+ is_exiting_off = true;
+ chipset_exit_hard_off();
+}
+
void chipset_exit_hard_off_button(void)
{
/*
@@ -163,7 +174,7 @@ void chipset_exit_hard_off_button(void)
hook_call_deferred(&release_power_button_data, -1);
release_power_button();
/* Power up from off */
- chipset_exit_hard_off();
+ mt8186_exit_off();
}
DECLARE_DEFERRED(chipset_exit_hard_off_button);
@@ -233,8 +244,14 @@ static enum power_state power_get_signal_state(void)
*/
if (is_resetting)
return POWER_S0;
- if (is_shutdown)
- return POWER_G3;
+ if (is_shutdown) {
+ /* We are in S5 and pressing the powerkey to shutdown PMIC. */
+ if (!gpio_get_level(GPIO_EC_PMIC_EN_ODL))
+ return POWER_S5;
+ /* Powerkey released, PMIC full off. */
+ else
+ return POWER_G3;
+ }
if (power_get_signals() & IN_AP_RST)
return POWER_G3;
if (power_get_signals() & IN_SUSPEND_ASSERTED)
@@ -282,7 +299,7 @@ enum power_state power_chipset_init(void)
if (exit_hard_off)
/* Auto-power on */
- chipset_exit_hard_off();
+ mt8186_exit_off();
if (init_state != POWER_G3 && !exit_hard_off)
/* Force shutdown from S5 if the PMIC is already up. */
@@ -303,10 +320,17 @@ enum power_state power_handle_state(enum power_state state)
break;
case POWER_S5:
- return POWER_S5S3;
+ if (is_exiting_off)
+ return POWER_S5S3;
+ else if (next_state == POWER_S5)
+ return POWER_S5;
+ else if (next_state == POWER_G3)
+ return POWER_S5G3;
+ else
+ return POWER_S5S3;
case POWER_S3:
- if (next_state == POWER_G3)
+ if (next_state == POWER_G3 || next_state == POWER_S5)
return POWER_S3S5;
else if (next_state == POWER_S0)
return POWER_S3S0;
@@ -323,6 +347,8 @@ enum power_state power_handle_state(enum power_state state)
return POWER_S5;
case POWER_S5S3:
+ /* Off state exited. */
+ is_exiting_off = false;
hook_notify(HOOK_CHIPSET_PRE_INIT);
gpio_enable_interrupt(GPIO_AP_EC_WARM_RST_REQ);
@@ -406,8 +432,7 @@ enum power_state power_handle_state(enum power_state state)
hook_notify(HOOK_CHIPSET_SHUTDOWN);
hook_notify(HOOK_CHIPSET_SHUTDOWN_COMPLETE);
- /* Skip S5 */
- return POWER_S5G3;
+ return POWER_S5;
case POWER_S5G3:
return POWER_G3;
@@ -478,7 +503,7 @@ static void lid_changed(void)
{
/* Power-up from off on lid open */
if (lid_is_open() && chipset_in_state(CHIPSET_STATE_ANY_OFF))
- chipset_exit_hard_off();
+ mt8186_exit_off();
}
DECLARE_HOOK(HOOK_LID_CHANGE, lid_changed, HOOK_PRIO_DEFAULT);
#endif