From dfbd5eb2aa7839076b5d5eb5d37f37a36bca91dd Mon Sep 17 00:00:00 2001 From: =?utf8?q?Lothar=20Wa=C3=9Fmann?= Date: Mon, 15 Jul 2013 11:38:46 +0200 Subject: [PATCH] mxs: clear the boot cause flags in RTC_PERSISTENT0 before resetting --- arch/arm/cpu/arm926ejs/mxs/mxs.c | 34 +++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/arch/arm/cpu/arm926ejs/mxs/mxs.c b/arch/arm/cpu/arm926ejs/mxs/mxs.c index d314144f50..52c56e94a4 100644 --- a/arch/arm/cpu/arm926ejs/mxs/mxs.c +++ b/arch/arm/cpu/arm926ejs/mxs/mxs.c @@ -47,6 +47,31 @@ DECLARE_GLOBAL_DATA_PTR; /* Lowlevel init isn't used on i.MX28, so just have a dummy here */ inline void lowlevel_init(void) {} +#define BOOT_CAUSE_MASK (RTC_PERSISTENT0_EXTERNAL_RESET | \ + RTC_PERSISTENT0_ALARM_WAKE | \ + RTC_PERSISTENT0_THERMAL_RESET) + +static int wait_rtc_stat(u32 mask) +{ + int timeout = 5000; + u32 val; + struct mxs_rtc_regs *rtc_regs = (void *)MXS_RTC_BASE; + u32 old_val = readl(&rtc_regs->hw_rtc_stat); + + debug("stat=%x\n", old_val); + + while ((val = readl(&rtc_regs->hw_rtc_stat)) & mask) { + if (val != old_val) { + old_val = val; + debug("stat: %x -> %x\n", old_val, val); + } + udelay(1); + if (timeout-- < 0) + break; + } + return !!(readl(&rtc_regs->hw_rtc_stat) & mask); +} + void reset_cpu(ulong ignored) __attribute__((noreturn)); void reset_cpu(ulong ignored) @@ -55,6 +80,7 @@ void reset_cpu(ulong ignored) (struct mxs_rtc_regs *)MXS_RTC_BASE; struct mxs_lcdif_regs *lcdif_regs = (struct mxs_lcdif_regs *)MXS_LCDIF_BASE; + u32 reg; /* * Shut down the LCD controller as it interferes with BootROM boot mode @@ -62,7 +88,13 @@ void reset_cpu(ulong ignored) */ writel(LCDIF_CTRL_RUN, &lcdif_regs->hw_lcdif_ctrl_clr); - /* Wait 1 uS before doing the actual watchdog reset */ + reg = readl(&rtc_regs->hw_rtc_persistent0); + if (reg & BOOT_CAUSE_MASK) { + writel(reg & ~BOOT_CAUSE_MASK, &rtc_regs->hw_rtc_persistent0); + wait_rtc_stat(RTC_STAT_NEW_REGS_PERSISTENT0); + } + + /* Wait 1 mS before doing the actual watchdog reset */ writel(1, &rtc_regs->hw_rtc_watchdog); writel(RTC_CTRL_WATCHDOGEN, &rtc_regs->hw_rtc_ctrl_set); -- 2.39.2