aboutsummaryrefslogtreecommitdiff
path: root/drivers/watchdog
diff options
context:
space:
mode:
authorBreno Lima <breno.lima@nxp.com>2021-06-29 10:32:35 +0800
committerStefano Babic <sbabic@denx.de>2021-07-17 14:59:56 +0200
commitedf95bdeddeab8f0fd7b88d4865fbc6e99071c73 (patch)
treee1a42b31742fa6a352a1cd7fb756a56d1c25815c /drivers/watchdog
parentc6ae713c7ccf2a6a30b6bffb47d7806c43d9d05f (diff)
downloadu-boot-edf95bdeddeab8f0fd7b88d4865fbc6e99071c73.zip
u-boot-edf95bdeddeab8f0fd7b88d4865fbc6e99071c73.tar.gz
u-boot-edf95bdeddeab8f0fd7b88d4865fbc6e99071c73.tar.bz2
mx7ulp: wdog: Wait for WDOG unlock and reconfiguration to complete
According to i.MX7ULP Reference Manual we should wait for WDOG unlock and reconfiguration to complete. Section "59.5.3 Configure Watchdog" provides the following example: DisableInterrupts; //disable global interrupt WDOG_CNT = 0xD928C520; //unlock watchdog while(WDOG_CS[ULK]==0); //wait until registers are unlocked WDOG_TOVAL = 256; //set timeout value WDOG_CS = WDOG_CS_EN(1) | WDOG_CS_CLK(1) | WDOG_CS_INT(1) | WDOG_CS_WIN(0) | WDOG_CS_UPDATE(1); while(WDOG_CS[RCS]==0); //wait until new configuration takes effect EnableInterrupts; //enable global interrupt Update U-Boot WDOG driver to align with i.MX7ULP reference manual. Use 32 bits accessing to CS register. According to RM, the bits in this register only can write once after unlock. So using 8 bits access will cause problem. Reviewed-by: Ye Li <ye.li@nxp.com> Signed-off-by: Breno Lima <breno.lima@nxp.com> Signed-off-by: Peng Fan <peng.fan@nxp.com>
Diffstat (limited to 'drivers/watchdog')
-rw-r--r--drivers/watchdog/ulp_wdog.c39
1 files changed, 25 insertions, 14 deletions
diff --git a/drivers/watchdog/ulp_wdog.c b/drivers/watchdog/ulp_wdog.c
index 490a2c9..ecd35ef 100644
--- a/drivers/watchdog/ulp_wdog.c
+++ b/drivers/watchdog/ulp_wdog.c
@@ -12,9 +12,7 @@
* MX7ULP WDOG Register Map
*/
struct wdog_regs {
- u8 cs1;
- u8 cs2;
- u16 reserve0;
+ u32 cs;
u32 cnt;
u32 toval;
u32 win;
@@ -30,10 +28,12 @@ struct wdog_regs {
#define UNLOCK_WORD0 0xC520 /* 1st unlock word */
#define UNLOCK_WORD1 0xD928 /* 2nd unlock word */
-#define WDGCS1_WDGE (1<<7)
-#define WDGCS1_WDGUPDATE (1<<5)
+#define WDGCS_WDGE BIT(7)
+#define WDGCS_WDGUPDATE BIT(5)
-#define WDGCS2_FLG (1<<6)
+#define WDGCS_RCS BIT(10)
+#define WDGCS_ULK BIT(11)
+#define WDGCS_FLG BIT(14)
#define WDG_BUS_CLK (0x0)
#define WDG_LPO_CLK (0x1)
@@ -60,7 +60,6 @@ void hw_watchdog_reset(void)
void hw_watchdog_init(void)
{
- u8 val;
struct wdog_regs *wdog = (struct wdog_regs *)WDOG_BASE_ADDR;
dmb();
@@ -68,15 +67,19 @@ void hw_watchdog_init(void)
__raw_writel(UNLOCK_WORD1, &wdog->cnt);
dmb();
- val = readb(&wdog->cs2);
- val |= WDGCS2_FLG;
- writeb(val, &wdog->cs2);
+ /* Wait WDOG Unlock */
+ while (!(readl(&wdog->cs) & WDGCS_ULK))
+ ;
hw_watchdog_set_timeout(CONFIG_WATCHDOG_TIMEOUT_MSECS);
writel(0, &wdog->win);
- writeb(WDG_LPO_CLK, &wdog->cs2);/* setting 1-kHz clock source */
- writeb((WDGCS1_WDGE | WDGCS1_WDGUPDATE), &wdog->cs1);/* enable counter running */
+ /* setting 1-kHz clock source, enable counter running, and clear interrupt */
+ writel((WDGCS_WDGE | WDGCS_WDGUPDATE |(WDG_LPO_CLK << 8) | WDGCS_FLG), &wdog->cs);
+
+ /* Wait WDOG reconfiguration */
+ while (!(readl(&wdog->cs) & WDGCS_RCS))
+ ;
hw_watchdog_reset();
}
@@ -90,11 +93,19 @@ void reset_cpu(void)
__raw_writel(UNLOCK_WORD1, &wdog->cnt);
dmb();
+ /* Wait WDOG Unlock */
+ while (!(readl(&wdog->cs) & WDGCS_ULK))
+ ;
+
hw_watchdog_set_timeout(5); /* 5ms timeout */
writel(0, &wdog->win);
- writeb(WDG_LPO_CLK, &wdog->cs2);/* setting 1-kHz clock source */
- writeb(WDGCS1_WDGE, &wdog->cs1);/* enable counter running */
+ /* enable counter running */
+ writel((WDGCS_WDGE | (WDG_LPO_CLK << 8)), &wdog->cs);
+
+ /* Wait WDOG reconfiguration */
+ while (!(readl(&wdog->cs) & WDGCS_RCS))
+ ;
hw_watchdog_reset();