summaryrefslogtreecommitdiff
path: root/power/mt8183.c
diff options
context:
space:
mode:
authorNicolas Boichat <drinkcat@chromium.org>2018-08-28 17:32:43 +0800
committerchrome-bot <chrome-bot@chromium.org>2018-08-31 11:20:02 -0700
commit148c28c9f61a1d9633ef3570670c64f1acc76d64 (patch)
treeaf48116b5619a9080f8f111ca9bfe2b2497fc7b8 /power/mt8183.c
parentd13deb3437db0acc573dfa00ad40d0a227211189 (diff)
downloadchrome-ec-148c28c9f61a1d9633ef3570670c64f1acc76d64.tar.gz
power/mt8183: Fix power sequencing
Fix power sequencing: 1. Replace power_has_signals(...) with power_get_signals() & ... to reduce unwanted noise during boot 2. PMIC_FORCE_RESET only takes about 5ms to work. 3. In G3, switch back to S5->G3 if the PMIC happens to be on again. 4. On boot, start from S5 instead of G3 if the PMIC is on. 5. In S5->S3, retry to turn on PMIC if the first attempt fails (this is necessary after a force reset) BRANCH=none BUG=b:109850749 TEST=Cycles of apshutdown, powerbtn; EC reboot TEST=apshutdown, sysjump rw, powerbtn works properly Change-Id: I2e52e267eab9d45d30036f75cfd6b821d3b13638 Signed-off-by: Nicolas Boichat <drinkcat@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/1194546 Reviewed-by: Yilun Lin <yllin@chromium.org>
Diffstat (limited to 'power/mt8183.c')
-rw-r--r--power/mt8183.c38
1 files changed, 32 insertions, 6 deletions
diff --git a/power/mt8183.c b/power/mt8183.c
index 221e315892..4522efcd02 100644
--- a/power/mt8183.c
+++ b/power/mt8183.c
@@ -43,6 +43,9 @@
#define PMIC_EN_PULSE_MS 50
+/* Maximum time it should for PMIC to turn on after toggling PMIC_EN_ODL. */
+#define PMIC_EN_TIMEOUT (300 * MSEC)
+
/* Data structure for a GPIO operation for power sequencing */
struct power_seq_op {
/* enum gpio_signal in 8 bits */
@@ -135,6 +138,10 @@ enum power_state power_chipset_init(void)
chipset_exit_hard_off();
}
+ /* Start from S5 if the PMIC is already up. */
+ if (power_get_signals() & IN_PGOOD_PMIC)
+ return POWER_S5;
+
return POWER_G3;
}
@@ -160,14 +167,21 @@ static void power_seq_run(const struct power_seq_op *power_seq_ops,
enum power_state power_handle_state(enum power_state state)
{
+ /* Retry S5->S3 transition, if not zero. */
+ static int s5s3_retry;
+
switch (state) {
case POWER_G3:
+ /* Go back to S5->G3 if the PMIC unexpectedly starts again. */
+ if (power_get_signals() & IN_PGOOD_PMIC)
+ return POWER_S5G3;
break;
case POWER_S5:
if (forcing_shutdown) {
return POWER_S5G3;
} else {
+ s5s3_retry = 1;
return POWER_S5S3;
}
break;
@@ -197,7 +211,7 @@ enum power_state power_handle_state(enum power_state state)
case POWER_S5S3:
/* If PMIC is off, switch it on by pulsing PMIC enable. */
- if (!power_has_signals(IN_PGOOD_PMIC)) {
+ if (!(power_get_signals() & IN_PGOOD_PMIC)) {
gpio_set_level(GPIO_PMIC_EN_ODL, 0);
msleep(PMIC_EN_PULSE_MS);
gpio_set_level(GPIO_PMIC_EN_ODL, 1);
@@ -215,9 +229,20 @@ enum power_state power_handle_state(enum power_state state)
chipset_reset(CHIPSET_RESET_INIT);
}
- /* Wait for PMIC to bring up rails. */
- if (power_wait_signals(IN_PGOOD_PMIC))
- return POWER_G3;
+ /*
+ * Wait for PMIC to bring up rails. Retry if it fails
+ * (it may take 2 attempts on restart after we use
+ * force reset).
+ */
+ if (power_wait_signals_timeout(IN_PGOOD_PMIC,
+ PMIC_EN_TIMEOUT)) {
+ if (s5s3_retry) {
+ s5s3_retry = 0;
+ return POWER_S5S3;
+ }
+ /* Give up, go back to G3. */
+ return POWER_S5G3;
+ }
/* Enable S3 power supplies, release AP reset. */
power_seq_run(s5s3_power_seq, ARRAY_SIZE(s5s3_power_seq));
@@ -292,13 +317,14 @@ enum power_state power_handle_state(enum power_state state)
* This should not happen if PMIC is configured properly, and
* shuts down upon receiving WATCHDOG.
*/
- if (power_has_signals(IN_PGOOD_PMIC)) {
+ if (power_get_signals() & IN_PGOOD_PMIC) {
#if defined(BOARD_KUKUI) && BOARD_REV == 0
CPRINTS("Cannot force PMIC off (rev0)");
#else
CPRINTS("Forcing PMIC off");
gpio_set_level(GPIO_PMIC_FORCE_RESET_ODL, 0);
- msleep(50);
+ msleep(5);
+
return POWER_S5G3;
#endif
}