1
2
3
4
5
6#include <common.h>
7#include <cpu_func.h>
8#include <asm/io.h>
9#include <asm/arch/imx-regs.h>
10
11
12
13
14struct wdog_regs {
15 u32 cs;
16 u32 cnt;
17 u32 toval;
18 u32 win;
19};
20
21#ifndef CONFIG_WATCHDOG_TIMEOUT_MSECS
22#define CONFIG_WATCHDOG_TIMEOUT_MSECS 0x1500
23#endif
24
25#define REFRESH_WORD0 0xA602
26#define REFRESH_WORD1 0xB480
27
28#define UNLOCK_WORD0 0xC520
29#define UNLOCK_WORD1 0xD928
30
31#define WDGCS_WDGE BIT(7)
32#define WDGCS_WDGUPDATE BIT(5)
33
34#define WDGCS_RCS BIT(10)
35#define WDGCS_ULK BIT(11)
36#define WDGCS_FLG BIT(14)
37
38#define WDG_BUS_CLK (0x0)
39#define WDG_LPO_CLK (0x1)
40#define WDG_32KHZ_CLK (0x2)
41#define WDG_EXT_CLK (0x3)
42
43void hw_watchdog_set_timeout(u16 val)
44{
45
46 struct wdog_regs *wdog = (struct wdog_regs *)WDOG_BASE_ADDR;
47
48 writel(val, &wdog->toval);
49}
50
51void hw_watchdog_reset(void)
52{
53 struct wdog_regs *wdog = (struct wdog_regs *)WDOG_BASE_ADDR;
54
55 dmb();
56 __raw_writel(REFRESH_WORD0, &wdog->cnt);
57 __raw_writel(REFRESH_WORD1, &wdog->cnt);
58 dmb();
59}
60
61void hw_watchdog_init(void)
62{
63 struct wdog_regs *wdog = (struct wdog_regs *)WDOG_BASE_ADDR;
64
65 dmb();
66 __raw_writel(UNLOCK_WORD0, &wdog->cnt);
67 __raw_writel(UNLOCK_WORD1, &wdog->cnt);
68 dmb();
69
70
71 while (!(readl(&wdog->cs) & WDGCS_ULK))
72 ;
73
74 hw_watchdog_set_timeout(CONFIG_WATCHDOG_TIMEOUT_MSECS);
75 writel(0, &wdog->win);
76
77
78 writel((WDGCS_WDGE | WDGCS_WDGUPDATE |(WDG_LPO_CLK << 8) | WDGCS_FLG), &wdog->cs);
79
80
81 while (!(readl(&wdog->cs) & WDGCS_RCS))
82 ;
83
84 hw_watchdog_reset();
85}
86
87void reset_cpu(void)
88{
89 struct wdog_regs *wdog = (struct wdog_regs *)WDOG_BASE_ADDR;
90
91 dmb();
92 __raw_writel(UNLOCK_WORD0, &wdog->cnt);
93 __raw_writel(UNLOCK_WORD1, &wdog->cnt);
94 dmb();
95
96
97 while (!(readl(&wdog->cs) & WDGCS_ULK))
98 ;
99
100 hw_watchdog_set_timeout(5);
101 writel(0, &wdog->win);
102
103
104 writel((WDGCS_WDGE | (WDG_LPO_CLK << 8)), &wdog->cs);
105
106
107 while (!(readl(&wdog->cs) & WDGCS_RCS))
108 ;
109
110 hw_watchdog_reset();
111
112 while (1);
113}
114