diff options
author | Vadim Bendebury <vbendeb@chromium.org> | 2018-09-05 18:00:36 -0700 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2018-09-08 06:49:51 -0700 |
commit | eda7d344b9fdd25f1eee9abb21f14a28190d79a1 (patch) | |
tree | 9d49b0622232ba8972475c94d7e18cae7e567758 | |
parent | bd34ba0abea5246d47571eb12416b07b68b3c692 (diff) | |
download | chrome-ec-eda7d344b9fdd25f1eee9abb21f14a28190d79a1.tar.gz |
cr50: make EC RST synchronous
When the RBOX register controlling the EC reset output is written,
RBOX does not act immediately, as it is controlled by its own clock.
This results in the program continuing executing before RBOX output
value change.
This patch makes sure that execution does not continue until RBOX
reacted to the request to change the EC RST output value.
BRANCH=cr50. cr50-mp
BUG=b:75976718
TEST=verified with logic analyzer that processing does not continue
until EC RST output value changes.
Change-Id: I72814d3c9ea11721e1b361e7f6d300658306562d
Signed-off-by: Vadim Bendebury <vbendeb@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/1214101
Reviewed-by: Mary Ruthven <mruthven@chromium.org>
-rw-r--r-- | board/cr50/board.c | 53 |
1 files changed, 39 insertions, 14 deletions
diff --git a/board/cr50/board.c b/board/cr50/board.c index f9b36d8eed..3059a4ab9d 100644 --- a/board/cr50/board.c +++ b/board/cr50/board.c @@ -937,29 +937,54 @@ DECLARE_SAFE_CONSOLE_COMMAND(sysrst, command_sys_rst, "[pulse [time] | <BOOLEAN>]", "Assert/deassert SYS_RST_L to reset the AP"); -void assert_ec_rst(void) +/* + * Set RBOX register controlling EC reset and wait until RBOX updates the + * output. + * + * Input parameter is treated as a Boolean, 1 means reset needs to be + * asserted, 0 means reset needs to be deasserted. + */ +static void wait_ec_rst(int level) { - /* Prevent bit bang interrupt storm. */ - if (uart_bitbang_is_enabled()) - task_disable_irq(bitbang_config.rx_irq); + int i; + + + /* Just in case. */ + level = !!level; + + GWRITE(RBOX, ASSERT_EC_RST, level); /* - * If ec_rst was explicitly asserted, then do not let - * "power button release" deassert it if set earlier to do so. + * If ec_rst value is being explicitly set while power button is held + * pressed after reset, do not let "power button release" ISR change + * the ec_rst value. */ power_button_release_enable_interrupt(0); - GWRITE(RBOX, ASSERT_EC_RST, 1); -} -void deassert_ec_rst(void) -{ /* - * If ec_rst was explicitly deasserted, then do not let - * "power button release" deassert it again if set earlier to do so. + * RBOX is running on its own clock, let's make sure we don't exit + * this function until the ecr_rst output matches the desired setting. + * 1000 cycles is way more than needed for RBOX to react. + * + * Note that the read back value is the inversion of the value written + * into the register once it propagates through RBOX. */ - power_button_release_enable_interrupt(0); + for (i = 0; i < 1000; i++) + if (GREAD_FIELD(RBOX, CHECK_OUTPUT, EC_RST) != level) + break; +} - GWRITE(RBOX, ASSERT_EC_RST, 0); +void assert_ec_rst(void) +{ + /* Prevent bit bang interrupt storm. */ + if (uart_bitbang_is_enabled()) + task_disable_irq(bitbang_config.rx_irq); + + wait_ec_rst(1); +} +void deassert_ec_rst(void) +{ + wait_ec_rst(0); if (uart_bitbang_is_enabled()) task_enable_irq(bitbang_config.rx_irq); |