]> git.kernelconcepts.de Git - karo-tx-uboot.git/commitdiff
mxs: clear the boot cause flags in RTC_PERSISTENT0 before resetting
authorLothar Waßmann <LW@KARO-electronics.de>
Mon, 15 Jul 2013 09:38:46 +0000 (11:38 +0200)
committerLothar Waßmann <LW@KARO-electronics.de>
Mon, 15 Jul 2013 09:38:46 +0000 (11:38 +0200)
arch/arm/cpu/arm926ejs/mxs/mxs.c

index d314144f50055a498fd3466da46ee3bfccddc6e0..52c56e94a432a359c0f047336f562b88d0ae5841 100644 (file)
@@ -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);