summaryrefslogtreecommitdiff
path: root/board/cr50/board.c
diff options
context:
space:
mode:
authorDuncan Laurie <dlaurie@google.com>2018-12-21 15:03:01 -0800
committerchrome-bot <chrome-bot@chromium.org>2019-01-22 21:05:23 -0800
commitca8b915b59822f9d464862b599ade8e35712abc3 (patch)
treea4469987d5275d029217737e58bd6301c0130fd5 /board/cr50/board.c
parent34ad90fb651e650f41194df4ff483af6daecd808 (diff)
downloadchrome-ec-ca8b915b59822f9d464862b599ade8e35712abc3.tar.gz
cr50: REFRESH+PWR combinatinon to enter recovery mode
Add support for entering recovery mode via the REFRESH_PWR key combination. This is needed on a platform with a closed source EC when the EC cannot be trusted to handle the normal ESC+REFRRESH+PWR combination. Add an interrupt handler for the RBOX key combo and when it is detected, generate an EC reset pulse via RBOX. The recovery state is latched into NVMEM so it can be queried by coreboot/verstage on the next boot. This change also ensures that all EC resets initiated by the Cr50 have a minimum pulse width of 30 ms to meet the EC requirement. BUG=b:122715254,b:119275910, BRANCH=cr50 TEST=make buildall. Verified boot to recovery mode screen after pressing REFRESH+PWR. Verified recovery mode entry from S0 and S5 states. Change-Id: I840ee1024bbfba00e47050eeb8b1ede244148c05 Signed-off-by: Duncan Laurie <dlaurie@google.com> Signed-off-by: Keith Short <keithshort@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/1389061 Reviewed-by: Vadim Bendebury <vbendeb@chromium.org>
Diffstat (limited to 'board/cr50/board.c')
-rw-r--r--board/cr50/board.c53
1 files changed, 49 insertions, 4 deletions
diff --git a/board/cr50/board.c b/board/cr50/board.c
index ef8a91ec98..e984b9be04 100644
--- a/board/cr50/board.c
+++ b/board/cr50/board.c
@@ -24,6 +24,7 @@
#include "nvmem_vars.h"
#include "rbox.h"
#include "rdd.h"
+#include "recovery_button.h"
#include "registers.h"
#include "scratch_reg1.h"
#include "signed_header.h"
@@ -757,6 +758,16 @@ static void board_init(void)
bitbang_config.uart_in = ec_uart.producer.queue;
/*
+ * Enable interrupt handler for RBOX key combo so it can be used to
+ * store the recovery request.
+ */
+ if (board_uses_closed_source_set1()) {
+ /* Enable interrupt handler for reset button combo */
+ task_enable_irq(GC_IRQNUM_RBOX0_INTR_BUTTON_COMBO0_RDY_INT);
+ GWRITE_FIELD(RBOX, INT_ENABLE, INTR_BUTTON_COMBO0_RDY, 1);
+ }
+
+ /*
* Note that the AP, EC, and servo state machines do not have explicit
* init_xxx_state() functions, because they don't need to configure
* registers prior to starting their state machines. Their state
@@ -953,6 +964,27 @@ void board_reboot_ap(void)
}
/**
+ * Reboot the EC
+ */
+static void board_reboot_ec(void)
+{
+ assert_ec_rst();
+ deassert_ec_rst();
+}
+
+/*
+ * This interrupt handler will be called if the RBOX key combo is detected.
+ */
+static void key_combo0_irq(void)
+{
+ GWRITE_FIELD(RBOX, INT_STATE, INTR_BUTTON_COMBO0_RDY, 1);
+ recovery_button_record();
+ board_reboot_ec();
+ CPRINTS("Recovery Requested");
+}
+DECLARE_IRQ(GC_IRQNUM_RBOX0_INTR_BUTTON_COMBO0_RDY_INT, key_combo0_irq, 0);
+
+/**
* Console command to toggle system (AP) reset
*/
static int command_sys_rst(int argc, char **argv)
@@ -1039,13 +1071,28 @@ void assert_ec_rst(void)
wait_ec_rst(1);
}
-void deassert_ec_rst(void)
+
+static void deassert_ec_rst_now(void)
{
wait_ec_rst(0);
if (uart_bitbang_is_enabled())
task_enable_irq(bitbang_config.rx_irq);
}
+DECLARE_DEFERRED(deassert_ec_rst_now);
+
+void deassert_ec_rst(void)
+{
+ /*
+ * On closed source set1, the EC requires a minimum 30 ms pulse to
+ * properly reset. Ensure EC reset is never de-asesrted for less
+ * than this time.
+ */
+ if (board_uses_closed_source_set1())
+ hook_call_deferred(&deassert_ec_rst_now_data, 30 * MSEC);
+ else
+ deassert_ec_rst_now();
+}
int is_ec_rst_asserted(void)
{
@@ -1065,9 +1112,7 @@ static int command_ec_rst(int argc, char **argv)
if (!strcasecmp("pulse", argv[1])) {
ccprintf("Pulsing EC reset\n");
- assert_ec_rst();
- usleep(200);
- deassert_ec_rst();
+ board_reboot_ec();
} else if (parse_bool(argv[1], &val)) {
if (val)
assert_ec_rst();