diff options
author | Louis Yung-Chieh Lo <yjlou@chromium.org> | 2013-11-21 16:35:12 -0800 |
---|---|---|
committer | chrome-internal-fetch <chrome-internal-fetch@google.com> | 2013-12-05 01:51:28 +0000 |
commit | 90d83d2a6743a48d7ec8209781c4e820e8bdf296 (patch) | |
tree | c17edb461b9ac54f63fff8fc13092b0ce170995f /power | |
parent | 06e60734910d952830c2102cd2ab002ddc99029b (diff) | |
download | chrome-ec-90d83d2a6743a48d7ec8209781c4e820e8bdf296.tar.gz |
nyan: force shutdown uses PMIC THERM instead.
Add a new pin PMIC_THERM_L (PA1) since AP_RESET_L (PA15) is removed.
To force shutdown, drive PMIC_THERM_L to low (default high) for 32us.
Also rename set_pmic_pwrok() -> set_pmic_pwron(). And add a debounce time
for PMIC_PWRON_L pin.
BUG=chrome-os-partner:24206
BRANCH=nyan
TEST=Verified on the frank's rework board.
'power off' shutdowns the AP immediately.
'reboot' reboots the EC and resets the AP as well.
'sysjump RW' still keeps AP alive.
Change-Id: I8643e19081a824e1f6adc812dfad0269222db8ea
Signed-off-by: Louis Yung-Chieh Lo <yjlou@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/178631
Diffstat (limited to 'power')
-rw-r--r-- | power/tegra.c | 67 |
1 files changed, 45 insertions, 22 deletions
diff --git a/power/tegra.c b/power/tegra.c index 99c350c658..9b44d39f56 100644 --- a/power/tegra.c +++ b/power/tegra.c @@ -46,6 +46,19 @@ #define DELAY_FORCE_SHUTDOWN (10200 * MSEC) /* 10.2 seconds */ /* + * The minimum time to assert the PMIC PWRON pin is 20ms. + * Give it longer to ensure the PMIC doesn't lose it. + */ +#define PMIC_PWRON_DEBOUNCE_TIME (20 * MSEC * 3) + +/* + * The minimum time to assert the PMIC THERM pin is 32us. However, + * it needs to be extended to about 50ms to let the 5V rail + * dissipate fully. + */ +#define PMIC_THERM_HOLD_TIME (50 * MSEC) + +/* * If the power key is pressed to turn on, then held for this long, we * power off. * @@ -132,27 +145,29 @@ static int wait_in_signal(enum gpio_signal signal, int value, int timeout) } /** - * Set the PMIC PWROK signal. + * Set the PMIC PWRON signal. + * + * Note that asserting requires holding for PMIC_PWRON_DEBOUNCE_TIME. * * @param asserted Assert (=1) or deassert (=0) the signal. This is the * logical level of the pin, not the physical level. */ -static void set_pmic_pwrok(int asserted) +static void set_pmic_pwron(int asserted) { /* Signal is active-low */ gpio_set_level(GPIO_PMIC_PWRON_L, asserted ? 0 : 1); } /** - * Set the AP RESET signal. + * Set the PMIC THERM to force shutdown the AP. * * @param asserted Assert (=1) or deassert (=0) the signal. This is the * logical level of the pin, not the physical level. */ -static void set_ap_reset(int asserted) +static void set_pmic_therm(int asserted) { /* Signal is active-low */ - gpio_set_level(GPIO_AP_RESET_L, asserted ? 0 : 1); + gpio_set_level(GPIO_PMIC_THERM_L, asserted ? 0 : 1); } /** @@ -188,7 +203,8 @@ static int check_for_power_off_event(void) now = get_time(); if (pressed) { - set_pmic_pwrok(1); + set_pmic_pwron(1); + usleep(PMIC_PWRON_DEBOUNCE_TIME); if (!power_button_was_pressed) { power_off_deadline.val = now.val + DELAY_FORCE_SHUTDOWN; @@ -202,7 +218,7 @@ static int check_for_power_off_event(void) } } else if (power_button_was_pressed) { CPRINTF("[%T power off cancel]\n"); - set_pmic_pwrok(0); + set_pmic_pwron(0); } power_button_was_pressed = pressed; @@ -283,6 +299,15 @@ static int tegra_power_init(void) gpio_enable_interrupt(GPIO_SOC1V8_XPSHOLD); gpio_enable_interrupt(GPIO_SUSPEND_L); + /* + * Force the AP shutdown unless we are doing SYSJUMP. Otherwise, + * the AP could stay in strange state. + */ + if (!(system_get_reset_flags() & RESET_FLAG_SYSJUMP)) { + CPRINTF("[%T not sysjump; forcing AP shutdown]\n"); + chipset_force_shutdown(); + } + /* Leave power off only if requested by reset flags */ if (!(system_get_reset_flags() & RESET_FLAG_AP_OFF)) { CPRINTF("[%T auto_power_on is set due to reset_flag 0x%x]\n", @@ -341,11 +366,13 @@ void chipset_reset(int is_cold) void chipset_force_shutdown(void) { - /* Assert AP reset to shutdown immediately */ - set_ap_reset(1); - /* Release the power button, if it was asserted */ - set_pmic_pwrok(0); + set_pmic_pwron(0); + + /* Assert AP reset to shutdown immediately */ + set_pmic_therm(1); + udelay(PMIC_THERM_HOLD_TIME); + set_pmic_therm(0); } /*****************************************************************************/ @@ -360,13 +387,8 @@ void chipset_force_shutdown(void) */ static int check_for_power_on_event(void) { - /* - * check if system is already ON: - * 1. XPSHOLD is high (power is supplied), and - * 2. AP_RESET_L is high (not a force shutdown). - */ - if (gpio_get_level(GPIO_SOC1V8_XPSHOLD) && - gpio_get_level(GPIO_AP_RESET_L)) { + /* check if system is already ON */ + if (gpio_get_level(GPIO_SOC1V8_XPSHOLD)) { CPRINTF("[%T system is on, thus clear auto_power_on]\n"); auto_power_on = 0; /* no need to arrange another power on */ return 1; @@ -406,11 +428,12 @@ static int check_for_power_on_event(void) */ static int power_on(void) { - /* Make sure we de-assert the AP_RESET_L pin. */ - set_ap_reset(0); + /* Make sure we de-assert the PMI_THERM_L pin. */ + set_pmic_therm(0); /* Push the power button */ - set_pmic_pwrok(1); + set_pmic_pwron(1); + usleep(PMIC_PWRON_DEBOUNCE_TIME); /* Initialize non-AP components if the AP is off. */ if (!ap_on) @@ -553,7 +576,7 @@ void chipset_task(void) DELAY_SHUTDOWN_ON_POWER_HOLD)) continue_power = 1; } - set_pmic_pwrok(0); + set_pmic_pwron(0); if (continue_power) { power_button_was_pressed = 0; while (!(value = check_for_power_off_event())) |