mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2026-01-08 16:41:55 +00:00
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:
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user