diff options
author | Shawn Nematbakhsh <shawnn@chromium.org> | 2016-08-23 15:02:10 -0700 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2016-08-25 01:45:26 -0700 |
commit | 6fefca3d6acc0ea5b5adebabd8593ed17265f5c8 (patch) | |
tree | 326092280abe01d1cf15b7f400ca47624df55a3a /power | |
parent | 3071b82b5847396136b19acd8c2aa3f4e8f6cd42 (diff) | |
download | chrome-ec-6fefca3d6acc0ea5b5adebabd8593ed17265f5c8.tar.gz |
power: rk3399: Debounce PGOOD_AP signal
PGOOD_AP may go low for a period < 100ms during regulator output voltage
transitions, so ignore such pulses.
BRANCH=None
BUG=chrome-os-partner:54814
TEST=On kevin, verify suspend / resume succeeds for 10 cycles.
Change-Id: I5b6240a570472e1ea74de6e5f2341472ea7afe6b
Reviewed-on: https://chromium-review.googlesource.com/374524
Commit-Ready: Shawn N <shawnn@chromium.org>
Tested-by: Douglas Anderson <dianders@chromium.org>
Tested-by: Shunqian Zheng <zhengsq@rock-chips.com>
Tested-by: Shawn N <shawnn@chromium.org>
Reviewed-by: Aseda Aboagye <aaboagye@chromium.org>
Diffstat (limited to 'power')
-rw-r--r-- | power/common.c | 15 | ||||
-rw-r--r-- | power/rk3399.c | 31 |
2 files changed, 39 insertions, 7 deletions
diff --git a/power/common.c b/power/common.c index 1916758482..b0d474831d 100644 --- a/power/common.c +++ b/power/common.c @@ -134,16 +134,23 @@ int power_has_signals(uint32_t want) int power_wait_signals(uint32_t want) { + int ret = power_wait_signals_timeout(want, DEFAULT_TIMEOUT); + + if (ret == EC_ERROR_TIMEOUT) + CPRINTS("power timeout on input; wanted 0x%04x, got 0x%04x", + want, in_signals & want); + return ret; +} + +int power_wait_signals_timeout(uint32_t want, int timeout) +{ in_want = want; if (!want) return EC_SUCCESS; while ((in_signals & in_want) != in_want) { - if (task_wait_event(DEFAULT_TIMEOUT) == TASK_EVENT_TIMER) { + if (task_wait_event(timeout) == TASK_EVENT_TIMER) { power_update_signals(); - CPRINTS("power timeout on input; " - "wanted 0x%04x, got 0x%04x", - in_want, in_signals & in_want); return EC_ERROR_TIMEOUT; } /* diff --git a/power/rk3399.c b/power/rk3399.c index 76b012c548..58056b98dc 100644 --- a/power/rk3399.c +++ b/power/rk3399.c @@ -91,6 +91,12 @@ static void force_shutdown(void) } DECLARE_DEFERRED(force_shutdown); +/* + * Debounce PGOOD_AP if we lose it suddenly during S0, since output voltage + * transitions may cause spurious pulses. + */ +#define PGOOD_AP_DEBOUNCE_TIMEOUT (100 * MSEC) + enum power_state power_handle_state(enum power_state state) { static int sys_reset_needed; @@ -110,15 +116,34 @@ enum power_state power_handle_state(enum power_state state) case POWER_S3: if (!power_has_signals(IN_PGOOD_S3) || forcing_shutdown) return POWER_S3S5; - else if (!gpio_get_level(GPIO_AP_EC_S3_S0_L)) + else if (power_get_signals() & IN_SUSPEND_DEASSERTED) return POWER_S3S0; break; case POWER_S0: - if (!power_has_signals(IN_PGOOD_S0) || + if (!power_has_signals(IN_PGOOD_S3) || + forcing_shutdown || + !(power_get_signals() & IN_SUSPEND_DEASSERTED)) + return POWER_S0S3; + + /* + * Wait up to PGOOD_AP_DEBOUNCE_TIMEOUT for IN_PGOOD_AP to + * come back before transitioning back to S3. + */ + if (power_wait_signals_timeout(IN_PGOOD_AP, + PGOOD_AP_DEBOUNCE_TIMEOUT) + == EC_ERROR_TIMEOUT) + return POWER_S0S3; + + /* + * power_wait_signals_timeout() can block and consume task + * wake events, so re-verify the state of the world. + */ + if (!power_has_signals(IN_PGOOD_S3) || forcing_shutdown || - gpio_get_level(GPIO_AP_EC_S3_S0_L)) + !(power_get_signals() & IN_SUSPEND_DEASSERTED)) return POWER_S0S3; + break; case POWER_G3S5: |