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>
Thu, 29 Apr 2021 07:56:32 +0000 (00:56 -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)
(cherry picked from commit 29cf0fa20f54ca80e9ba4baf9eee3e53c1c634fa)

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

index 2ae816e..70a7438 100644 (file)
@@ -157,14 +157,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)