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>
This commit is contained in:
Vic Yang
2012-07-19 15:20:14 -07:00
committed by Gerrit
parent b58c424a65
commit 3036dcdb1e

View File

@@ -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)