summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVic Yang <victoryang@chromium.org>2012-07-19 15:20:14 -0700
committerGerrit <chrome-bot@google.com>2012-07-19 17:01:55 -0700
commit3036dcdb1efb873656c3c56868e83441fce825cf (patch)
tree6220143c11b4d90510354e9fb6038ea5a598387d
parentb58c424a65dc46cb542941b65411e4b877a00e77 (diff)
downloadchrome-ec-3036dcdb1efb873656c3c56868e83441fce825cf.tar.gz
stm32f: Support hard reset
Now that we have hibernate ability, we can use this to perform a hard reset. BUG=chrome-os-partner:11579 TEST=Build success and working on 'snow': 'reboot' and see reset cause is 'reset-pin soft'. 'reboot hard' and see reset cause is 'hard'. Build success on 'daisy'. Change-Id: I18132eee2f0d574d7d1674f7be25249dbe19749d Signed-off-by: Vic Yang <victoryang@chromium.org> Reviewed-on: https://gerrit.chromium.org/gerrit/27930 Reviewed-by: Randall Spangler <rspangler@chromium.org>
-rw-r--r--chip/stm32/system.c39
1 files changed, 33 insertions, 6 deletions
diff --git a/chip/stm32/system.c b/chip/stm32/system.c
index 39b25305c6..a28abf41c9 100644
--- a/chip/stm32/system.c
+++ b/chip/stm32/system.c
@@ -14,9 +14,14 @@
enum bkpdata_index {
BKPDATA_INDEX_SCRATCHPAD, /* General-purpose scratchpad */
+ BKPDATA_INDEX_WAKE, /* Wake reasons for hibernate */
BKPDATA_INDEX_SAVED_RESET_FLAGS,/* Saved reset flags */
};
+/* Wake reason flags for hibernate */
+#define BKPDATA_WAKE_HIBERNATE (1 << 0) /* Hibernate */
+#define BKPDATA_WAKE_HARD_RESET (1 << 1) /* Hard reset */
+
/**
* Read backup register at specified index.
*
@@ -49,11 +54,14 @@ static void check_reset_cause(void)
uint32_t flags = 0;
uint32_t raw_cause = STM32_RCC_CSR;
uint32_t pwr_status = STM32_PWR_CSR;
+ uint32_t bkp_wake_flags = bkpdata_read(BKPDATA_INDEX_WAKE);
/* Clear the hardware reset cause by setting the RMVF bit */
STM32_RCC_CSR |= 1 << 24;
/* Clear SBF in PWR_CSR */
STM32_PWR_CR |= 1 << 3;
+ /* Clear hibernate wake flags */
+ bkpdata_write(BKPDATA_INDEX_WAKE, 0);
if (raw_cause & 0x60000000) {
/* IWDG or WWDG */
@@ -69,8 +77,14 @@ static void check_reset_cause(void)
if (raw_cause & 0x04000000)
flags |= RESET_FLAG_RESET_PIN;
- if (pwr_status & 0x00000002)
- flags |= RESET_FLAG_HIBERNATE;
+ if (pwr_status & 0x00000002) {
+ /* Hibernation and waked */
+ if (bkp_wake_flags & BKPDATA_WAKE_HIBERNATE)
+ flags |= RESET_FLAG_HIBERNATE;
+ /* Hibernation caused by software-triggered hard reset */
+ if (bkp_wake_flags & BKPDATA_WAKE_HARD_RESET)
+ flags |= RESET_FLAG_HARD;
+ }
if (!flags && (raw_cause & 0xfe000000))
flags |= RESET_FLAG_OTHER;
@@ -91,8 +105,12 @@ static inline void wait_for_RTOFF(void)
}
-static void __enter_hibernate_stm32f100(uint32_t seconds, uint32_t milliseconds)
+static void __enter_hibernate_stm32f100(uint32_t seconds, uint32_t milliseconds,
+ uint32_t flags)
{
+ /* Store the hibernate flags */
+ bkpdata_write(BKPDATA_INDEX_WAKE, flags);
+
/* Enter RTC configuration mode */
wait_for_RTOFF();
STM32_RTC_CRL |= 0x10;
@@ -150,7 +168,8 @@ void system_hibernate(uint32_t seconds, uint32_t microseconds)
{
/* we are going to hibernate ... */
#ifdef CHIP_VARIANT_stm32f100
- __enter_hibernate_stm32f100(seconds, (microseconds + 999) / 1000);
+ __enter_hibernate_stm32f100(seconds, (microseconds + 999) / 1000,
+ BKPDATA_WAKE_HIBERNATE);
#else
while (1)
/* NOT IMPLEMENTED */;
@@ -209,8 +228,16 @@ void system_reset(int flags)
else
bkpdata_write(BKPDATA_INDEX_SAVED_RESET_FLAGS, 0);
- /* TODO: (crosbug.com/p/7470) support hard boot; this is a soft boot. */
- CPU_NVIC_APINT = 0x05fa0004;
+ if (flags & SYSTEM_RESET_HARD) {
+#ifdef CHIP_VARIANT_stm32f100
+ /* Bounce through hibernate to trigger a hard reboot */
+ __enter_hibernate_stm32f100(0, 50, BKPDATA_WAKE_HARD_RESET);
+#else
+ /* Hard reset not supported yet. Using soft reset. */
+ CPU_NVIC_APINT = 0x05fa0004;
+#endif
+ } else
+ CPU_NVIC_APINT = 0x05fa0004;
/* Spin and wait for reboot; should never return */
while (1)