summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVincent Palatin <vpalatin@chromium.org>2014-12-05 11:08:11 -0800
committerchrome-internal-fetch <chrome-internal-fetch@google.com>2014-12-06 01:11:41 +0000
commit4ef1969a5026b457ff9f9194042e065f4dd129e5 (patch)
tree9a2976a2a683e2c69a5f89c1e797a0c358ebf050
parentd097e25bf4796a83b122876c70c21ab8d2daf256 (diff)
downloadchrome-ec-4ef1969a5026b457ff9f9194042e065f4dd129e5.tar.gz
g: update reset code
- record and display reset cause - add the hard reset option - add the scratchpad to store values across reboots. Signed-off-by: Vincent Palatin <vpalatin@chromium.org> BRANCH=none BUG=chrome-os-partner:33818 TEST=On the console command line, chech the "[Reset cause: xxx]" string - for the initial reset cause - use "waitms 4000" to trigger a watchdog reset - use "reboot soft" - use "reboot hard" The "utils" test is now building and passing. Change-Id: I68c7096e5b7bfd102be89fd8eef6fe20da37a6f8 Reviewed-on: https://chromium-review.googlesource.com/233581 Reviewed-by: Bill Richardson <wfrichar@chromium.org> Commit-Queue: Vincent Palatin <vpalatin@chromium.org> Trybot-Ready: Vincent Palatin <vpalatin@chromium.org> Tested-by: Vincent Palatin <vpalatin@chromium.org>
-rw-r--r--chip/g/registers.h72
-rw-r--r--chip/g/system.c65
2 files changed, 121 insertions, 16 deletions
diff --git a/chip/g/registers.h b/chip/g/registers.h
index b257ec1cd4..1a4c9ab456 100644
--- a/chip/g/registers.h
+++ b/chip/g/registers.h
@@ -23,15 +23,69 @@
#define GR_PINMUX_UART0_RX_SEL REG32(GC_PINMUX_BASE_ADDR + GC_PINMUX_UART0_RX_SEL_OFFSET)
#define GR_PINMUX_UART0_TX_SEL REG32(GC_PINMUX_BASE_ADDR + GC_PINMUX_UART0_TX_SEL_OFFSET)
-#define GR_PMU_CLRDIS REG32(GC_PMU_BASE_ADDR + GC_PMU_CLRDIS_OFFSET)
-#define GR_PMU_OSC_HOLD_SET REG32(GC_PMU_BASE_ADDR + GC_PMU_OSC_HOLD_SET_OFFSET)
-#define GR_PMU_OSC_HOLD_CLR REG32(GC_PMU_BASE_ADDR + GC_PMU_OSC_HOLD_CLR_OFFSET)
-#define GR_PMU_OSC_SELECT REG32(GC_PMU_BASE_ADDR + GC_PMU_OSC_SELECT_OFFSET)
-#define GR_PMU_OSC_SELECT_STAT REG32(GC_PMU_BASE_ADDR + GC_PMU_OSC_SELECT_STAT_OFFSET)
-#define GR_PMU_OSC_CTRL REG32(GC_PMU_BASE_ADDR + GC_PMU_OSC_CTRL_OFFSET)
-#define GR_PMU_PERICLKSET0 REG32(GC_PMU_BASE_ADDR + GC_PMU_PERICLKSET0_OFFSET)
-#define GR_PMU_FUSE_RD_RC_OSC_26MHZ REG32(GC_PMU_BASE_ADDR + GC_PMU_FUSE_RD_RC_OSC_26MHZ_OFFSET)
-#define GR_PMU_FUSE_RD_XTL_OSC_26MHZ REG32(GC_PMU_BASE_ADDR + GC_PMU_FUSE_RD_XTL_OSC_26MHZ_OFFSET)
+/* Power Management Unit */
+#define GR_PMU_REG(off) REG32(GC_PMU_BASE_ADDR + (off))
+
+#define GR_PMU_RESET GR_PMU_REG(GC_PMU_RESET_OFFSET)
+#define GR_PMU_SETRST GR_PMU_REG(GC_PMU_SETRST_OFFSET)
+#define GR_PMU_CLRRST GR_PMU_REG(GC_PMU_CLRRST_OFFSET)
+#define GR_PMU_RSTSRC GR_PMU_REG(GC_PMU_RSTSRC_OFFSET)
+#define GR_PMU_GLOBAL_RESET GR_PMU_REG(GC_PMU_GLOBAL_RESET_OFFSET)
+#define GR_PMU_SETDIS GR_PMU_REG(GC_PMU_SETDIS_OFFSET)
+#define GR_PMU_CLRDIS GR_PMU_REG(GC_PMU_CLRDIS_OFFSET)
+#define GR_PMU_STATDIS GR_PMU_REG(GC_PMU_STATDIS_OFFSET)
+#define GR_PMU_SETWIC GR_PMU_REG(GC_PMU_SETWIC_OFFSET)
+#define GR_PMU_CLRWIC GR_PMU_REG(GC_PMU_CLRWIC_OFFSET)
+#define GR_PMU_SYSVTOR GR_PMU_REG(GC_PMU_SYSVTOR_OFFSET)
+#define GR_PMU_EXCLUSIVE GR_PMU_REG(GC_PMU_EXCLUSIVE_OFFSET)
+#define GR_PMU_DAP_ID0 GR_PMU_REG(GC_PMU_DAP_ID0_OFFSET)
+#define GR_PMU_DAP_EN GR_PMU_REG(GC_PMU_DAP_EN_OFFSET)
+#define GR_PMU_DAP_LOCK GR_PMU_REG(GC_PMU_DAP_LOCK_OFFSET)
+#define GR_PMU_DAP_UNLOCK GR_PMU_REG(GC_PMU_DAP_UNLOCK_OFFSET)
+#define GR_PMU_NAP_EN GR_PMU_REG(GC_PMU_NAP_EN_OFFSET)
+#define GR_PMU_VREF GR_PMU_REG(GC_PMU_VREF_OFFSET)
+#define GR_PMU_VREFCMP GR_PMU_REG(GC_PMU_VREFCMP_OFFSET)
+#define GR_PMU_RBIAS GR_PMU_REG(GC_PMU_RBIAS_OFFSET)
+#define GR_PMU_RBIASLO GR_PMU_REG(GC_PMU_RBIASLO_OFFSET)
+#define GR_PMU_RBIASHI GR_PMU_REG(GC_PMU_RBIASHI_OFFSET)
+#define GR_PMU_SETHOLDVREF GR_PMU_REG(GC_PMU_SETHOLDVREF_OFFSET)
+#define GR_PMU_CLRHOLDVREF GR_PMU_REG(GC_PMU_CLRHOLDVREF_OFFSET)
+#define GR_PMU_BAT_LVL_OK GR_PMU_REG(GC_PMU_BAT_LVL_OK_OFFSET)
+#define GR_PMU_B_REG_DIG_CTRL GR_PMU_REG(GC_PMU_B_REG_DIG_CTRL_OFFSET)
+#define GR_PMU_B_REG_DIG_LATCH_CTRL GR_PMU_REG(GC_PMU_B_REG_DIG_LATCH_CTRL_OFFSET)
+#define GR_PMU_EXITPD_HOLD_SET GR_PMU_REG(GC_PMU_EXITPD_HOLD_SET_OFFSET)
+#define GR_PMU_EXITPD_HOLD_CLR GR_PMU_REG(GC_PMU_EXITPD_HOLD_CLR_OFFSET)
+#define GR_PMU_EXITPD_MASK GR_PMU_REG(GC_PMU_EXITPD_MASK_OFFSET)
+#define GR_PMU_EXITPD_SRC GR_PMU_REG(GC_PMU_EXITPD_SRC_OFFSET)
+#define GR_PMU_EXITPD_MON GR_PMU_REG(GC_PMU_EXITPD_MON_OFFSET)
+#define GR_PMU_OSC_HOLD_SET GR_PMU_REG(GC_PMU_OSC_HOLD_SET_OFFSET)
+#define GR_PMU_OSC_HOLD_CLR GR_PMU_REG(GC_PMU_OSC_HOLD_CLR_OFFSET)
+#define GR_PMU_OSC_SELECT GR_PMU_REG(GC_PMU_OSC_SELECT_OFFSET)
+#define GR_PMU_OSC_SELECT_STAT GR_PMU_REG(GC_PMU_OSC_SELECT_STAT_OFFSET)
+#define GR_PMU_OSC_CTRL GR_PMU_REG(GC_PMU_OSC_CTRL_OFFSET)
+#define GR_PMU_MEMCLKSET GR_PMU_REG(GC_PMU_MEMCLKSET_OFFSET)
+#define GR_PMU_MEMCLKCLR GR_PMU_REG(GC_PMU_MEMCLKCLR_OFFSET)
+#define GR_PMU_PERICLKSET0 GR_PMU_REG(GC_PMU_PERICLKSET0_OFFSET)
+#define GR_PMU_PERICLKCLR0 GR_PMU_REG(GC_PMU_PERICLKCLR0_OFFSET)
+#define GR_PMU_PERICLKSET1 GR_PMU_REG(GC_PMU_PERICLKSET1_OFFSET)
+#define GR_PMU_PERICLKCLR1 GR_PMU_REG(GC_PMU_PERICLKCLR1_OFFSET)
+#define GR_PMU_PERIGATEONSLEEPSET0 GR_PMU_REG(GC_PMU_PERIGATEONSLEEPSET0_OFFSET)
+#define GR_PMU_PERIGATEONSLEEPCLR0 GR_PMU_REG(GC_PMU_PERIGATEONSLEEPCLR0_OFFSET)
+#define GR_PMU_PERIGATEONSLEEPSET1 GR_PMU_REG(GC_PMU_PERIGATEONSLEEPSET1_OFFSET)
+#define GR_PMU_PERIGATEONSLEEPCLR1 GR_PMU_REG(GC_PMU_PERIGATEONSLEEPCLR1_OFFSET)
+#define GR_PMU_CLK0 GR_PMU_REG(GC_PMU_CLK0_OFFSET)
+#define GR_PMU_CLK1 GR_PMU_REG(GC_PMU_CLK1_OFFSET)
+#define GR_PMU_RST0 GR_PMU_REG(GC_PMU_RST0_OFFSET)
+#define GR_PMU_RST1 GR_PMU_REG(GC_PMU_RST1_OFFSET)
+#define GR_PMU_PWRDN_SCRATCH_HOLD_SET GR_PMU_REG(GC_PMU_PWRDN_SCRATCH_HOLD_SET_OFFSET)
+#define GR_PMU_PWRDN_SCRATCH_HOLD_CLR GR_PMU_REG(GC_PMU_PWRDN_SCRATCH_HOLD_CLR_OFFSET)
+#define GR_PMU_PWRDN_SCRATCH0 GR_PMU_REG(GC_PMU_PWRDN_SCRATCH0_OFFSET)
+#define GR_PMU_PWRDN_SCRATCH1 GR_PMU_REG(GC_PMU_PWRDN_SCRATCH1_OFFSET)
+#define GR_PMU_PWRDN_SCRATCH2 GR_PMU_REG(GC_PMU_PWRDN_SCRATCH2_OFFSET)
+#define GR_PMU_PWRDN_SCRATCH3 GR_PMU_REG(GC_PMU_PWRDN_SCRATCH3_OFFSET)
+
+#define GR_PMU_FUSE_RD_RC_OSC_26MHZ GR_PMU_REG(GC_PMU_FUSE_RD_RC_OSC_26MHZ_OFFSET)
+#define GR_PMU_FUSE_RD_XTL_OSC_26MHZ GR_PMU_REG(GC_PMU_FUSE_RD_XTL_OSC_26MHZ_OFFSET)
/* More than one UART */
BUILD_ASSERT(GC_UART1_BASE_ADDR - GC_UART0_BASE_ADDR == GC_UART2_BASE_ADDR - GC_UART1_BASE_ADDR);
diff --git a/chip/g/system.c b/chip/g/system.c
index 342998b6ce..f22f2b819d 100644
--- a/chip/g/system.c
+++ b/chip/g/system.c
@@ -4,20 +4,58 @@
*/
#include "cpu.h"
-#include "system.h"
#include "registers.h"
+#include "system.h"
+#include "task.h"
-void system_pre_init(void)
+static void check_reset_cause(void)
{
+ uint32_t reset_source = GR_PMU_RSTSRC;
+ uint32_t flags = 0;
+
+ /* Clear the reset source now we have recorded it */
+ GR_PMU_CLRRST = 1;
+
+ if (reset_source & (1 << GC_PMU_RSTSRC_POR_LSB))
+ flags |= RESET_FLAG_POWER_ON;
+ else if (reset_source & (1 << GC_PMU_RSTSRC_RESETB_LSB))
+ flags |= RESET_FLAG_RESET_PIN;
+ else if (reset_source & (1 << GC_PMU_RSTSRC_EXIT_LSB))
+ flags |= RESET_FLAG_WAKE_PIN;
+
+ if (reset_source & (1 << GC_PMU_RSTSRC_WDOG_LSB))
+ flags |= RESET_FLAG_WATCHDOG;
+ if (reset_source & (1 << GC_PMU_RSTSRC_SOFTWARE_LSB))
+ flags |= RESET_FLAG_HARD;
+ if (reset_source & (1 << GC_PMU_RSTSRC_SYSRESET_LSB))
+ flags |= RESET_FLAG_SOFT;
+
+ if (reset_source & (1 << GC_PMU_RSTSRC_FST_BRNOUT_LSB))
+ flags |= RESET_FLAG_BROWNOUT;
+
+ if (reset_source && !flags)
+ flags |= RESET_FLAG_OTHER;
+
+ system_set_reset_flags(flags);
+}
+
+void system_pre_init(void)
+{
+ check_reset_cause();
}
-/* TODO(crosbug.com/p/33818): How do we force a reset? */
void system_reset(int flags)
{
- /* Until we have a full microcontroller, at least reset the CPU core */
- CPU_NVIC_APINT = 0x05fa0004;
- /* should be gone here */
+ /* Disable interrupts to avoid task swaps during reboot */
+ interrupt_disable();
+
+ if (flags & SYSTEM_RESET_HARD) /* Reset the full microcontroller */
+ GR_PMU_GLOBAL_RESET = GC_PMU_GLOBAL_RESET_KEY;
+ else /* Reset only the CPU core */
+ CPU_NVIC_APINT = 0x05fa0004;
+
+ /* Spin and wait for reboot; should never return */
while (1)
;
}
@@ -37,8 +75,21 @@ const char *system_get_chip_revision(void)
return GC_REVISION_STR;
}
-/* TODO(crosbug.com/p/33822): Where can we store stuff persistently? */
+int system_set_scratchpad(uint32_t value)
+{
+ GR_PMU_PWRDN_SCRATCH_HOLD_CLR = 1;
+ GR_PMU_PWRDN_SCRATCH0 = value;
+ GR_PMU_PWRDN_SCRATCH_HOLD_SET = 1;
+ return EC_SUCCESS;
+}
+
+uint32_t system_get_scratchpad(void)
+{
+ return GR_PMU_PWRDN_SCRATCH0;
+}
+
+/* TODO(crosbug.com/p/33822): Where can we store stuff persistently? */
int system_get_vbnvcontext(uint8_t *block)
{
return 0;