Commit 40419231e2bcba5892cb48fc9b55c42f8edf5017

Authored by Breno Lima
Committed by Ye Li
1 parent 63602a7cd5

MLK-22755 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.

Reviewed-by: Ye Li <ye.li@nxp.com>
Signed-off-by: Breno Lima <breno.lima@nxp.com>
(cherry picked from commit 3ffee301cb4570e0e7681448ec434f0689bcbaa3)

Showing 1 changed file with 14 additions and 0 deletions Inline Diff

drivers/watchdog/ulp_wdog.c
1 // SPDX-License-Identifier: GPL-2.0+ 1 // SPDX-License-Identifier: GPL-2.0+
2 /* 2 /*
3 * Copyright (C) 2016 Freescale Semiconductor, Inc. 3 * Copyright (C) 2016 Freescale Semiconductor, Inc.
4 */ 4 */
5 5
6 #include <common.h> 6 #include <common.h>
7 #include <asm/io.h> 7 #include <asm/io.h>
8 #include <asm/arch/imx-regs.h> 8 #include <asm/arch/imx-regs.h>
9 9
10 /* 10 /*
11 * MX7ULP WDOG Register Map 11 * MX7ULP WDOG Register Map
12 */ 12 */
13 struct wdog_regs { 13 struct wdog_regs {
14 u8 cs1; 14 u8 cs1;
15 u8 cs2; 15 u8 cs2;
16 u16 reserve0; 16 u16 reserve0;
17 u32 cnt; 17 u32 cnt;
18 u32 toval; 18 u32 toval;
19 u32 win; 19 u32 win;
20 }; 20 };
21 21
22 #ifndef CONFIG_WATCHDOG_TIMEOUT_MSECS 22 #ifndef CONFIG_WATCHDOG_TIMEOUT_MSECS
23 #define CONFIG_WATCHDOG_TIMEOUT_MSECS 0x1500 23 #define CONFIG_WATCHDOG_TIMEOUT_MSECS 0x1500
24 #endif 24 #endif
25 25
26 #define REFRESH_WORD0 0xA602 /* 1st refresh word */ 26 #define REFRESH_WORD0 0xA602 /* 1st refresh word */
27 #define REFRESH_WORD1 0xB480 /* 2nd refresh word */ 27 #define REFRESH_WORD1 0xB480 /* 2nd refresh word */
28 28
29 #define UNLOCK_WORD0 0xC520 /* 1st unlock word */ 29 #define UNLOCK_WORD0 0xC520 /* 1st unlock word */
30 #define UNLOCK_WORD1 0xD928 /* 2nd unlock word */ 30 #define UNLOCK_WORD1 0xD928 /* 2nd unlock word */
31 31
32 #define WDGCS1_WDGE (1<<7) 32 #define WDGCS1_WDGE (1<<7)
33 #define WDGCS1_WDGUPDATE (1<<5) 33 #define WDGCS1_WDGUPDATE (1<<5)
34 34
35 #define WDGCS2_RCS (1<<2)
36 #define WDGCS2_ULK (1<<3)
35 #define WDGCS2_FLG (1<<6) 37 #define WDGCS2_FLG (1<<6)
36 38
37 #define WDG_BUS_CLK (0x0) 39 #define WDG_BUS_CLK (0x0)
38 #define WDG_LPO_CLK (0x1) 40 #define WDG_LPO_CLK (0x1)
39 #define WDG_32KHZ_CLK (0x2) 41 #define WDG_32KHZ_CLK (0x2)
40 #define WDG_EXT_CLK (0x3) 42 #define WDG_EXT_CLK (0x3)
41 43
42 void hw_watchdog_set_timeout(u16 val) 44 void hw_watchdog_set_timeout(u16 val)
43 { 45 {
44 /* setting timeout value */ 46 /* setting timeout value */
45 struct wdog_regs *wdog = (struct wdog_regs *)WDOG_BASE_ADDR; 47 struct wdog_regs *wdog = (struct wdog_regs *)WDOG_BASE_ADDR;
46 48
47 writel(val, &wdog->toval); 49 writel(val, &wdog->toval);
48 } 50 }
49 51
50 void hw_watchdog_reset(void) 52 void hw_watchdog_reset(void)
51 { 53 {
52 struct wdog_regs *wdog = (struct wdog_regs *)WDOG_BASE_ADDR; 54 struct wdog_regs *wdog = (struct wdog_regs *)WDOG_BASE_ADDR;
53 55
54 dmb(); 56 dmb();
55 __raw_writel(REFRESH_WORD0, &wdog->cnt); 57 __raw_writel(REFRESH_WORD0, &wdog->cnt);
56 __raw_writel(REFRESH_WORD1, &wdog->cnt); 58 __raw_writel(REFRESH_WORD1, &wdog->cnt);
57 dmb(); 59 dmb();
58 } 60 }
59 61
60 void hw_watchdog_init(void) 62 void hw_watchdog_init(void)
61 { 63 {
62 u8 val; 64 u8 val;
63 struct wdog_regs *wdog = (struct wdog_regs *)WDOG_BASE_ADDR; 65 struct wdog_regs *wdog = (struct wdog_regs *)WDOG_BASE_ADDR;
64 66
65 dmb(); 67 dmb();
66 __raw_writel(UNLOCK_WORD0, &wdog->cnt); 68 __raw_writel(UNLOCK_WORD0, &wdog->cnt);
67 __raw_writel(UNLOCK_WORD1, &wdog->cnt); 69 __raw_writel(UNLOCK_WORD1, &wdog->cnt);
68 dmb(); 70 dmb();
69 71
72 /* Wait WDOG Unlock */
73 while (!(readl(&wdog->cs2) & WDGCS2_ULK));
74
70 val = readb(&wdog->cs2); 75 val = readb(&wdog->cs2);
71 val |= WDGCS2_FLG; 76 val |= WDGCS2_FLG;
72 writeb(val, &wdog->cs2); 77 writeb(val, &wdog->cs2);
73 78
74 hw_watchdog_set_timeout(CONFIG_WATCHDOG_TIMEOUT_MSECS); 79 hw_watchdog_set_timeout(CONFIG_WATCHDOG_TIMEOUT_MSECS);
75 writel(0, &wdog->win); 80 writel(0, &wdog->win);
76 81
77 writeb(WDG_LPO_CLK, &wdog->cs2);/* setting 1-kHz clock source */ 82 writeb(WDG_LPO_CLK, &wdog->cs2);/* setting 1-kHz clock source */
78 writeb((WDGCS1_WDGE | WDGCS1_WDGUPDATE), &wdog->cs1);/* enable counter running */ 83 writeb((WDGCS1_WDGE | WDGCS1_WDGUPDATE), &wdog->cs1);/* enable counter running */
79 84
85 /* Wait WDOG reconfiguration */
86 while (!(readl(&wdog->cs2) & WDGCS2_RCS));
87
80 hw_watchdog_reset(); 88 hw_watchdog_reset();
81 } 89 }
82 90
83 void reset_cpu(ulong addr) 91 void reset_cpu(ulong addr)
84 { 92 {
85 struct wdog_regs *wdog = (struct wdog_regs *)WDOG_BASE_ADDR; 93 struct wdog_regs *wdog = (struct wdog_regs *)WDOG_BASE_ADDR;
86 94
87 dmb(); 95 dmb();
88 __raw_writel(UNLOCK_WORD0, &wdog->cnt); 96 __raw_writel(UNLOCK_WORD0, &wdog->cnt);
89 __raw_writel(UNLOCK_WORD1, &wdog->cnt); 97 __raw_writel(UNLOCK_WORD1, &wdog->cnt);
90 dmb(); 98 dmb();
91 99
100 /* Wait WDOG Unlock */
101 while (!(readl(&wdog->cs2) & WDGCS2_ULK));
102
92 hw_watchdog_set_timeout(5); /* 5ms timeout */ 103 hw_watchdog_set_timeout(5); /* 5ms timeout */
93 writel(0, &wdog->win); 104 writel(0, &wdog->win);
94 105
95 writeb(WDG_LPO_CLK, &wdog->cs2);/* setting 1-kHz clock source */ 106 writeb(WDG_LPO_CLK, &wdog->cs2);/* setting 1-kHz clock source */
96 writeb(WDGCS1_WDGE, &wdog->cs1);/* enable counter running */ 107 writeb(WDGCS1_WDGE, &wdog->cs1);/* enable counter running */
108
109 /* Wait WDOG reconfiguration */
110 while (!(readl(&wdog->cs2) & WDGCS2_RCS));
97 111
98 hw_watchdog_reset(); 112 hw_watchdog_reset();
99 113
100 while (1); 114 while (1);
101 } 115 }
102 116