aboutsummaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorYe Li2021-09-23 17:01:15 +0300
committerStefano Babic2021-10-07 16:53:50 +0200
commit64fe0ffca0cd088cf0d74f76f6cd503a844ace49 (patch)
treedc0741b210fc7f7b8dceac080c6ccd76fdac9383 /arch
parente1918ce299a10797df0f0f8e3df992fd6ed89aa6 (diff)
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. 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>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mach-imx/mx7ulp/soc.c33
1 files changed, 25 insertions, 8 deletions
diff --git a/arch/arm/mach-imx/mx7ulp/soc.c b/arch/arm/mach-imx/mx7ulp/soc.c
index 320f24dd296..7f097d68503 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 */
-
- writel(REFRESH_WORD0, (wdog_base + 0x04)); /* Refresh the CNT */
- writel(REFRESH_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));
+ }
+ 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)