summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVadim Bendebury <vbendeb@chromium.org>2018-09-05 18:00:36 -0700
committerchrome-bot <chrome-bot@chromium.org>2018-09-08 06:49:51 -0700
commiteda7d344b9fdd25f1eee9abb21f14a28190d79a1 (patch)
tree9d49b0622232ba8972475c94d7e18cae7e567758
parentbd34ba0abea5246d47571eb12416b07b68b3c692 (diff)
downloadchrome-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.c53
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);