diff options
author | Wai-Hong Tam <waihong@google.com> | 2018-11-09 16:13:43 -0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2018-12-09 00:48:16 -0800 |
commit | 768ce709a6dd85921e60bf871ff0d34824eba990 (patch) | |
tree | 80e542e70ab9c08383becbaec67b773de5edcf8e /power | |
parent | a47d02a9411d5ec2e6397eaf9ec0b8a73aebaa29 (diff) | |
download | chrome-ec-768ce709a6dd85921e60bf871ff0d34824eba990.tar.gz |
cheza: Make chipset_reset do a warm reset
Make the chipset_reset function do a warm reset to match the
expectation of what AP-initiated reset does, which is also a
warm reset but triggered by PS_HOLD.
The warm reset is done by sending a low pulse to the PMIC
RESIN_L pin, which requires PMIC registers being reprogrammed
that makes it as a warm reset trigger.
If the PMIC registers not reprogrammed properly, it falls back
to do a cold reset power sequence. It is done by EC monitoring
the AP_RST_L signal, which is already one of the power signals.
BRANCH=none
BUG=b:117941911
TEST=Typed "apreset" just after "reboot" (PMIC registers not
programmed), checked the transition S0 -> S5 -> S0.
TEST=Typed "apreset" when AP booted into userspace (PMIC
registers programmed), checked a warm reset happened, AP_RST_L
toggled.
Change-Id: Ia1c5c7a8fd56a9e4867d4dd4c8bf2333c083c616
Signed-off-by: Wai-Hong Tam <waihong@google.com>
Reviewed-on: https://chromium-review.googlesource.com/1330117
Commit-Ready: ChromeOS CL Exonerator Bot <chromiumos-cl-exonerator@appspot.gserviceaccount.com>
Reviewed-by: Stephen Boyd <swboyd@chromium.org>
Diffstat (limited to 'power')
-rw-r--r-- | power/sdm845.c | 42 |
1 files changed, 36 insertions, 6 deletions
diff --git a/power/sdm845.c b/power/sdm845.c index 9fb4bcd141..837a54875d 100644 --- a/power/sdm845.c +++ b/power/sdm845.c @@ -37,7 +37,9 @@ #define CPRINTS(format, args...) cprints(CC_CHIPSET, format, ## args) /* Masks for power signals */ -#define IN_POWER_GOOD POWER_SIGNAL_MASK(SDM845_POWER_GOOD) +#define IN_POWER_GOOD POWER_SIGNAL_MASK(SDM845_POWER_GOOD) +#define IN_AP_RST_ASSERTED POWER_SIGNAL_MASK(SDM845_AP_RST_ASSERTED) + /* Long power key press to force shutdown */ #define DELAY_FORCE_SHUTDOWN (8 * SECOND) @@ -67,6 +69,9 @@ /* Wait for polling the AP on signal */ #define PMIC_POWER_AP_WAIT (1 * MSEC) +/* The length of an issued low pulse to the PM845_RESIN_L signal */ +#define PMIC_RESIN_PULSE_LENGTH (20 * MSEC) + /* The timeout of the check if the system can boot AP */ #define CAN_BOOT_AP_CHECK_TIMEOUT (500 * MSEC) @@ -670,14 +675,39 @@ void chipset_force_shutdown(enum chipset_shutdown_reason reason) void chipset_reset(enum chipset_reset_reason reason) { - /* - * Before we can reprogram the PMIC to make the PMIC RESIN_N pin as - * reset pin and zero-latency. We do cold reset instead. - */ + int rv; + CPRINTS("%s(%d)", __func__, reason); report_ap_reset(reason); - request_cold_reset(); + /* The host command is used to hard reset AP. Check b/119261783 */ + if (reason == CHIPSET_RESET_HOST_CMD) { + request_cold_reset(); + return; + } + + /* + * Warm reset sequence: + * 1. Issue a low pulse to PM845_RESIN_L, which triggers PMIC + * to do a warm reset (requiring reprogramming PMIC registers + * to make PM845_RESIN_L as a warm reset trigger). + * 2. PMIC then issues a low pulse to AP_RST_L to reset AP. + * EC monitors the signal to see any low pulse. + * 2.1. If a low pulse found, done. + * 2.2. If a low pulse not found (the above PMIC registers + * not programmed or programmed wrong), issue a request + * to initiate a cold reset power sequence. + */ + + gpio_set_level(GPIO_PM845_RESIN_L, 0); + usleep(PMIC_RESIN_PULSE_LENGTH); + gpio_set_level(GPIO_PM845_RESIN_L, 1); + + rv = power_wait_signals_timeout(IN_AP_RST_ASSERTED, + PMIC_POWER_AP_RESPONSE_TIMEOUT); + /* Exception case: PMIC not work as expected, request a cold reset */ + if (rv != EC_SUCCESS) + request_cold_reset(); } /** |