diff options
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(); } /** |