MLK-22654 mx7ulp: Update wdog disable sequence
authorYe Li <ye.li@nxp.com>
Wed, 18 Sep 2019 08:56:34 +0000 (01:56 -0700)
committerYe Li <ye.li@nxp.com>
Mon, 23 Sep 2019 07:57:22 +0000 (00:57 -0700)
Update the mx7ulp wdog disable sequence to avoid potential reset issue
in unlock or refresh sequence. Both sequence need two words write
to wdog CNT register in 16 bus clocks window, if miss the window,
the write will cause violation in wdog and reset the chip.

Current u-boot code is using writel() function which has a DMB barrier
to order the memory access. The DMB between two words write may introduce
some delay in certain circumstance, causing the wdog reset due to 16 bus
clock window requirement.

This patch replaces writel() function by __raw_writel() to avoid such issue,
and improve to check if watchdog is already disabled or unlocked.

Signed-off-by: Ye Li <ye.li@nxp.com>
Tested-by: Breno Lima <breno.lima@nxp.com>
Reviewed-by: Peng Fan <peng.fan@nxp.com>
(cherry picked from commit b8c99d5f5bcc5573d3394b68890db16b6bb5fc88)

arch/arm/mach-imx/mx7ulp/soc.c

index 7d5bb80..de0ac0e 100644 (file)
@@ -137,14 +137,29 @@ int board_postclk_init(void)
 
 static void disable_wdog(u32 wdog_base)
 {
-       writel(UNLOCK_WORD0, (wdog_base + 0x04));
-       writel(UNLOCK_WORD1, (wdog_base + 0x04));
+       u32 val_cs = readl(wdog_base + 0x00);
+
+       if (!(val_cs & 0x80))
+               return;
+
+       dmb();
+       __raw_writel(REFRESH_WORD0, (wdog_base + 0x04)); /* Refresh the CNT */
+       __raw_writel(REFRESH_WORD1, (wdog_base + 0x04));
+       dmb();
+
+       if (!(val_cs & 800)) {
+               dmb();
+               __raw_writel(UNLOCK_WORD0, (wdog_base + 0x04));
+               __raw_writel(UNLOCK_WORD1, (wdog_base + 0x04));
+               dmb();
+
+               while (!(readl(wdog_base + 0x00) & 0x800));
+       }
        writel(0x0, (wdog_base + 0x0C)); /* Set WIN to 0 */
        writel(0x400, (wdog_base + 0x08)); /* Set timeout to default 0x400 */
        writel(0x120, (wdog_base + 0x00)); /* Disable it and set update */
 
-       writel(REFRESH_WORD0, (wdog_base + 0x04)); /* Refresh the CNT */
-       writel(REFRESH_WORD1, (wdog_base + 0x04));
+       while (!(readl(wdog_base + 0x00) & 0x400));
 }
 
 void init_wdog(void)