diff options
-rw-r--r-- | board/lazor/gpio.inc | 2 | ||||
-rw-r--r-- | board/pompom/gpio.inc | 2 | ||||
-rw-r--r-- | board/trogdor/gpio.inc | 2 | ||||
-rw-r--r-- | include/chipset.h | 9 | ||||
-rw-r--r-- | power/sc7180.c | 57 |
5 files changed, 69 insertions, 3 deletions
diff --git a/board/lazor/gpio.inc b/board/lazor/gpio.inc index 932423f72a..bfe23fdf03 100644 --- a/board/lazor/gpio.inc +++ b/board/lazor/gpio.inc @@ -24,7 +24,7 @@ GPIO_INT(EC_VOLDN_BTN_ODL, PIN(7, 0), GPIO_INT_BOTH | GPIO_PULL_UP, button_inte GPIO_INT(EC_VOLUP_BTN_ODL, PIN(F, 2), GPIO_INT_BOTH | GPIO_PULL_UP, button_interrupt) /* Volume Down button */ GPIO_INT(EC_WP_ODL, PIN(A, 1), GPIO_INT_BOTH, switch_interrupt) /* Write protection */ GPIO_INT(LID_OPEN_EC, PIN(D, 2), GPIO_INT_BOTH | GPIO_HIB_WAKE_HIGH, lid_interrupt) /* Lid open? */ -GPIO_INT(AP_RST_L, PIN(C, 1), GPIO_INT_BOTH | GPIO_SEL_1P8V, power_signal_interrupt) /* PMIC to signal AP reset */ +GPIO_INT(AP_RST_L, PIN(C, 1), GPIO_INT_BOTH | GPIO_SEL_1P8V, chipset_ap_rst_interrupt) /* PMIC to signal AP reset */ GPIO_INT(PS_HOLD, PIN(A, 4), GPIO_INT_BOTH | GPIO_PULL_DOWN | GPIO_SEL_1P8V, power_signal_interrupt) /* Indicate when AP triggers reset/shutdown */ GPIO_INT(PMIC_FAULT_L, PIN(A, 3), GPIO_INT_BOTH | GPIO_SEL_1P8V, power_signal_interrupt) /* Any PMIC fault? */ GPIO_INT(AP_SUSPEND, PIN(5, 7), GPIO_INT_BOTH | GPIO_SEL_1P8V, power_signal_interrupt) /* Suspend signal from PMIC */ diff --git a/board/pompom/gpio.inc b/board/pompom/gpio.inc index ebe1c023bf..239da6222d 100644 --- a/board/pompom/gpio.inc +++ b/board/pompom/gpio.inc @@ -24,7 +24,7 @@ GPIO_INT(EC_VOLDN_BTN_ODL, PIN(7, 0), GPIO_INT_BOTH | GPIO_PULL_UP, button_inte GPIO_INT(EC_VOLUP_BTN_ODL, PIN(F, 2), GPIO_INT_BOTH | GPIO_PULL_UP, button_interrupt) /* Volume Down button */ GPIO_INT(EC_WP_ODL, PIN(A, 1), GPIO_INT_BOTH, switch_interrupt) /* Write protection */ GPIO_INT(LID_OPEN_EC, PIN(D, 2), GPIO_INT_BOTH | GPIO_HIB_WAKE_HIGH, lid_interrupt) /* Lid open? */ -GPIO_INT(AP_RST_L, PIN(C, 1), GPIO_INT_BOTH | GPIO_SEL_1P8V, power_signal_interrupt) /* PMIC to signal AP reset */ +GPIO_INT(AP_RST_L, PIN(C, 1), GPIO_INT_BOTH | GPIO_SEL_1P8V, chipset_ap_rst_interrupt) /* PMIC to signal AP reset */ GPIO_INT(PS_HOLD, PIN(A, 4), GPIO_INT_BOTH | GPIO_PULL_DOWN | GPIO_SEL_1P8V, power_signal_interrupt) /* Indicate when AP triggers reset/shutdown */ GPIO_INT(PMIC_FAULT_L, PIN(A, 3), GPIO_INT_BOTH | GPIO_SEL_1P8V, power_signal_interrupt) /* Any PMIC fault? */ GPIO_INT(AP_SUSPEND, PIN(5, 7), GPIO_INT_BOTH | GPIO_SEL_1P8V, power_signal_interrupt) /* Suspend signal from PMIC */ diff --git a/board/trogdor/gpio.inc b/board/trogdor/gpio.inc index ef93c3b25e..e8b560f9a6 100644 --- a/board/trogdor/gpio.inc +++ b/board/trogdor/gpio.inc @@ -24,7 +24,7 @@ GPIO_INT(EC_VOLDN_BTN_ODL, PIN(7, 0), GPIO_INT_BOTH | GPIO_PULL_UP, button_inte GPIO_INT(EC_VOLUP_BTN_ODL, PIN(F, 2), GPIO_INT_BOTH | GPIO_PULL_UP, button_interrupt) /* Volume Down button */ GPIO_INT(EC_WP_ODL, PIN(A, 1), GPIO_INT_BOTH, switch_interrupt) /* Write protection */ GPIO_INT(LID_OPEN_EC, PIN(D, 2), GPIO_INT_BOTH | GPIO_HIB_WAKE_HIGH, lid_interrupt) /* Lid open? */ -GPIO_INT(AP_RST_L, PIN(C, 1), GPIO_INT_BOTH | GPIO_SEL_1P8V, power_signal_interrupt) /* PMIC to signal AP reset */ +GPIO_INT(AP_RST_L, PIN(C, 1), GPIO_INT_BOTH | GPIO_SEL_1P8V, chipset_ap_rst_interrupt) /* PMIC to signal AP reset */ GPIO_INT(PS_HOLD, PIN(A, 4), GPIO_INT_BOTH | GPIO_PULL_DOWN | GPIO_SEL_1P8V, power_signal_interrupt) /* Indicate when AP triggers reset/shutdown */ GPIO_INT(PMIC_FAULT_L, PIN(A, 3), GPIO_INT_BOTH | GPIO_SEL_1P8V, power_signal_interrupt) /* Any PMIC fault? */ GPIO_INT(AP_SUSPEND, PIN(5, 7), GPIO_INT_BOTH | GPIO_SEL_1P8V, power_signal_interrupt) /* Suspend signal from PMIC */ diff --git a/include/chipset.h b/include/chipset.h index 8664f6ecf3..e2c1421ec6 100644 --- a/include/chipset.h +++ b/include/chipset.h @@ -207,6 +207,7 @@ static inline void chipset_handle_espi_reset_assert(void) { } static inline void chipset_handle_reboot(void) { } static inline void chipset_reset_request_interrupt(enum gpio_signal signal) { } static inline void chipset_warm_reset_interrupt(enum gpio_signal signal) { } +static inline void chipset_ap_rst_interrupt(enum gpio_signal signal) { } static inline void chipset_power_good_interrupt(enum gpio_signal signal) { } static inline void chipset_watchdog_interrupt(enum gpio_signal signal) { } @@ -234,6 +235,14 @@ void chipset_handle_reboot(void); void chipset_reset_request_interrupt(enum gpio_signal signal); /** + * GPIO interrupt handler of AP_RST_L signal from PMIC. + * PMIC uses this signal to notify AP reset. + * + * It is used in Qualcomm chipset power sequence. + */ +void chipset_ap_rst_interrupt(enum gpio_signal signal); + +/** * GPIO interrupt handler of warm reset signal from servo or H1. * * It is used in Qualcomm chipset power sequence. diff --git a/power/sc7180.c b/power/sc7180.c index fe093ad535..69c64206d4 100644 --- a/power/sc7180.c +++ b/power/sc7180.c @@ -100,6 +100,16 @@ */ #define PMIC_POWER_OFF_DELAY (70 * MSEC) +/* The AP_RST_L transition count of a normal AP warm reset */ +#define EXPECTED_AP_RST_TRANSITIONS 3 + +/* + * The timeout of waiting the next AP_RST_L transition. We measured + * the interval between AP_RST_L transitions is 130ms ~ 150ms. Pick + * a safer value. + */ +#define AP_RST_TRANSITION_TIMEOUT (450 * MSEC) + /* TODO(crosbug.com/p/25047): move to HOOK_POWER_BUTTON_CHANGE */ /* 1 if the power button was pressed last time we checked */ static char power_button_was_pressed; @@ -155,6 +165,53 @@ enum power_on_event_t { POWER_ON_EVENT_COUNT, }; +#ifdef CONFIG_CHIPSET_RESET_HOOK +static int ap_rst_transitions; + +static void notify_chipset_reset(void) +{ + if (ap_rst_transitions != EXPECTED_AP_RST_TRANSITIONS) + CPRINTS("AP_RST_L transitions not expected: %d", + ap_rst_transitions); + + ap_rst_transitions = 0; + hook_notify(HOOK_CHIPSET_RESET); +} +DECLARE_DEFERRED(notify_chipset_reset); +#endif + +void chipset_ap_rst_interrupt(enum gpio_signal signal) +{ +#ifdef CONFIG_CHIPSET_RESET_HOOK + int delay; + + /* + * Only care the raising edge and AP in S0/S3. The single raising edge + * of AP power-on during S5S3 is ignored. + */ + if (gpio_get_level(GPIO_AP_RST_L) && + chipset_in_state(CHIPSET_STATE_ON | CHIPSET_STATE_SUSPEND)) { + ap_rst_transitions++; + if (ap_rst_transitions >= EXPECTED_AP_RST_TRANSITIONS) { + /* + * Reach the expected transition count. AP is booting + * up. Notify HOOK_CHIPSET_RESET immediately. + */ + delay = 0; + } else { + /* + * Should have more transitions of the AP_RST_L signal. + * In case the AP_RST_L signal is not toggled, still + * notify HOOK_CHIPSET_RESET. + */ + delay = AP_RST_TRANSITION_TIMEOUT; + } + hook_call_deferred(¬ify_chipset_reset_data, delay); + } +#endif + power_signal_interrupt(signal); +} + /* Issue a request to initiate a reset sequence */ static void request_cold_reset(void) { |