diff options
author | Vic Yang <victoryang@chromium.org> | 2012-07-19 15:20:14 -0700 |
---|---|---|
committer | Gerrit <chrome-bot@google.com> | 2012-07-19 17:01:55 -0700 |
commit | 3036dcdb1efb873656c3c56868e83441fce825cf (patch) | |
tree | 6220143c11b4d90510354e9fb6038ea5a598387d | |
parent | b58c424a65dc46cb542941b65411e4b877a00e77 (diff) | |
download | chrome-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.c | 39 |
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) |