Commit b26fb3c9b0e76075eada24a087d2db5f6fd3fc73

Authored by Ye Li
1 parent 8f4025381d

MLK-22654 mx7ulp: Update wdog disable sequence

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)

Showing 1 changed file with 19 additions and 4 deletions Side-by-side Diff

arch/arm/mach-imx/mx7ulp/soc.c
... ... @@ -137,14 +137,29 @@
137 137  
138 138 static void disable_wdog(u32 wdog_base)
139 139 {
140   - writel(UNLOCK_WORD0, (wdog_base + 0x04));
141   - writel(UNLOCK_WORD1, (wdog_base + 0x04));
  140 + u32 val_cs = readl(wdog_base + 0x00);
  141 +
  142 + if (!(val_cs & 0x80))
  143 + return;
  144 +
  145 + dmb();
  146 + __raw_writel(REFRESH_WORD0, (wdog_base + 0x04)); /* Refresh the CNT */
  147 + __raw_writel(REFRESH_WORD1, (wdog_base + 0x04));
  148 + dmb();
  149 +
  150 + if (!(val_cs & 800)) {
  151 + dmb();
  152 + __raw_writel(UNLOCK_WORD0, (wdog_base + 0x04));
  153 + __raw_writel(UNLOCK_WORD1, (wdog_base + 0x04));
  154 + dmb();
  155 +
  156 + while (!(readl(wdog_base + 0x00) & 0x800));
  157 + }
142 158 writel(0x0, (wdog_base + 0x0C)); /* Set WIN to 0 */
143 159 writel(0x400, (wdog_base + 0x08)); /* Set timeout to default 0x400 */
144 160 writel(0x120, (wdog_base + 0x00)); /* Disable it and set update */
145 161  
146   - writel(REFRESH_WORD0, (wdog_base + 0x04)); /* Refresh the CNT */
147   - writel(REFRESH_WORD1, (wdog_base + 0x04));
  162 + while (!(readl(wdog_base + 0x00) & 0x400));
148 163 }
149 164  
150 165 void init_wdog(void)