Message ID | 20210923140116.60318-2-oleksandr.suvorov@foundries.io |
---|---|
State | Awaiting Upstream |
Delegated to: | Stefano Babic |
Headers | show |
Series | mx7ulp: Update wdog disable sequence | expand |
> From: Ye Li <ye.li@nxp.com> > 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. > Also, WDOG1 might have been enabled already depending on FUSE hence > we need to be as close as possible to its reconfiguration timing > requirement of 128 bus clock limit. > 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> > Co-developed-by: Jorge Ramirez-Ortiz <jorge@foundries.io> > Signed-off-by: Jorge Ramirez-Ortiz <jorge@foundries.io> > Co-developed-by: Ricardo Salveti <ricardo@foundries.io> > Signed-off-by: Ricardo Salveti <ricardo@foundries.io> > Signed-off-by: Oleksandr Suvorov <oleksandr.suvorov@foundries.io> Applied to u-boot-imx, master, thanks ! Best regards, Stefano Babic
diff --git a/arch/arm/mach-imx/mx7ulp/soc.c b/arch/arm/mach-imx/mx7ulp/soc.c index 320f24dd29..7f097d6850 100644 --- a/arch/arm/mach-imx/mx7ulp/soc.c +++ b/arch/arm/mach-imx/mx7ulp/soc.c @@ -93,14 +93,31 @@ int board_postclk_init(void) static void disable_wdog(u32 wdog_base) { - writel(UNLOCK_WORD0, (wdog_base + 0x04)); - writel(UNLOCK_WORD1, (wdog_base + 0x04)); - 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 */ + u32 val_cs = readl(wdog_base + 0x00); - writel(REFRESH_WORD0, (wdog_base + 0x04)); /* Refresh the CNT */ - writel(REFRESH_WORD1, (wdog_base + 0x04)); + 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)); + } + dmb(); + __raw_writel(0x0, wdog_base + 0x0C); /* Set WIN to 0 */ + __raw_writel(0x400, wdog_base + 0x08); /* Set timeout to default 0x400 */ + __raw_writel(0x120, wdog_base + 0x00); /* Disable it and set update */ + dmb(); + + while (!(readl(wdog_base + 0x00) & 0x400)); } void init_wdog(void)