aboutsummaryrefslogtreecommitdiff
path: root/drivers/watchdog
diff options
context:
space:
mode:
authorBreno Lima <breno.lima@nxp.com>2021-06-29 10:32:34 +0800
committerStefano Babic <sbabic@denx.de>2021-07-17 14:59:56 +0200
commitc6ae713c7ccf2a6a30b6bffb47d7806c43d9d05f (patch)
treeae31176626eb2ba35628904141ce749ba08380cf /drivers/watchdog
parentcb391e339932d9e87477082b2b4b491a78b9ca41 (diff)
downloadu-boot-c6ae713c7ccf2a6a30b6bffb47d7806c43d9d05f.zip
u-boot-c6ae713c7ccf2a6a30b6bffb47d7806c43d9d05f.tar.gz
u-boot-c6ae713c7ccf2a6a30b6bffb47d7806c43d9d05f.tar.bz2
mx7ulp: Update unlock and refresh sequences in sWDOG driver
According to i.MX7ULP Reference Manual the second word write for both UNLOCK and REFRESH operations must occur in maximum 16 bus clock. The current 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 a WDOG timeout due to 16 bus clock window requirement. Replace writel() function by __raw_writel() to achieve a faster memory access and avoid such issue. Reviewed-by: Ye Li <ye.li@nxp.com> Signed-off-by: Breno Lima <breno.lima@nxp.com>
Diffstat (limited to 'drivers/watchdog')
-rw-r--r--drivers/watchdog/ulp_wdog.c18
1 files changed, 12 insertions, 6 deletions
diff --git a/drivers/watchdog/ulp_wdog.c b/drivers/watchdog/ulp_wdog.c
index 6f63b11..490a2c9 100644
--- a/drivers/watchdog/ulp_wdog.c
+++ b/drivers/watchdog/ulp_wdog.c
@@ -52,8 +52,10 @@ void hw_watchdog_reset(void)
{
struct wdog_regs *wdog = (struct wdog_regs *)WDOG_BASE_ADDR;
- writel(REFRESH_WORD0, &wdog->cnt);
- writel(REFRESH_WORD1, &wdog->cnt);
+ dmb();
+ __raw_writel(REFRESH_WORD0, &wdog->cnt);
+ __raw_writel(REFRESH_WORD1, &wdog->cnt);
+ dmb();
}
void hw_watchdog_init(void)
@@ -61,8 +63,10 @@ void hw_watchdog_init(void)
u8 val;
struct wdog_regs *wdog = (struct wdog_regs *)WDOG_BASE_ADDR;
- writel(UNLOCK_WORD0, &wdog->cnt);
- writel(UNLOCK_WORD1, &wdog->cnt);
+ dmb();
+ __raw_writel(UNLOCK_WORD0, &wdog->cnt);
+ __raw_writel(UNLOCK_WORD1, &wdog->cnt);
+ dmb();
val = readb(&wdog->cs2);
val |= WDGCS2_FLG;
@@ -81,8 +85,10 @@ void reset_cpu(void)
{
struct wdog_regs *wdog = (struct wdog_regs *)WDOG_BASE_ADDR;
- writel(UNLOCK_WORD0, &wdog->cnt);
- writel(UNLOCK_WORD1, &wdog->cnt);
+ dmb();
+ __raw_writel(UNLOCK_WORD0, &wdog->cnt);
+ __raw_writel(UNLOCK_WORD1, &wdog->cnt);
+ dmb();
hw_watchdog_set_timeout(5); /* 5ms timeout */
writel(0, &wdog->win);