xref: /openbmc/u-boot/drivers/watchdog/ulp_wdog.c (revision 83d290c56fab2d38cd1ab4c4cc7099559c1d5046)
1*83d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+
2253531bbSYe Li /*
3253531bbSYe Li  * Copyright (C) 2016 Freescale Semiconductor, Inc.
4253531bbSYe Li  */
5253531bbSYe Li 
6253531bbSYe Li #include <common.h>
7253531bbSYe Li #include <asm/io.h>
8253531bbSYe Li #include <asm/arch/imx-regs.h>
9253531bbSYe Li 
10253531bbSYe Li /*
11253531bbSYe Li  * MX7ULP WDOG Register Map
12253531bbSYe Li  */
13253531bbSYe Li struct wdog_regs {
14253531bbSYe Li 	u8 cs1;
15253531bbSYe Li 	u8 cs2;
16253531bbSYe Li 	u16 reserve0;
17253531bbSYe Li 	u32 cnt;
18253531bbSYe Li 	u32 toval;
19253531bbSYe Li 	u32 win;
20253531bbSYe Li };
21253531bbSYe Li 
22253531bbSYe Li #ifndef CONFIG_WATCHDOG_TIMEOUT_MSECS
23253531bbSYe Li #define CONFIG_WATCHDOG_TIMEOUT_MSECS 0x1500
24253531bbSYe Li #endif
25253531bbSYe Li 
26253531bbSYe Li #define REFRESH_WORD0 0xA602 /* 1st refresh word */
27253531bbSYe Li #define REFRESH_WORD1 0xB480 /* 2nd refresh word */
28253531bbSYe Li 
29253531bbSYe Li #define UNLOCK_WORD0 0xC520 /* 1st unlock word */
30253531bbSYe Li #define UNLOCK_WORD1 0xD928 /* 2nd unlock word */
31253531bbSYe Li 
32253531bbSYe Li #define WDGCS1_WDGE                      (1<<7)
33253531bbSYe Li #define WDGCS1_WDGUPDATE                 (1<<5)
34253531bbSYe Li 
35253531bbSYe Li #define WDGCS2_FLG                       (1<<6)
36253531bbSYe Li 
37253531bbSYe Li #define WDG_BUS_CLK                      (0x0)
38253531bbSYe Li #define WDG_LPO_CLK                      (0x1)
39253531bbSYe Li #define WDG_32KHZ_CLK                    (0x2)
40253531bbSYe Li #define WDG_EXT_CLK                      (0x3)
41253531bbSYe Li 
hw_watchdog_set_timeout(u16 val)42253531bbSYe Li void hw_watchdog_set_timeout(u16 val)
43253531bbSYe Li {
44253531bbSYe Li 	/* setting timeout value */
45253531bbSYe Li 	struct wdog_regs *wdog = (struct wdog_regs *)WDOG_BASE_ADDR;
46253531bbSYe Li 
47253531bbSYe Li 	writel(val, &wdog->toval);
48253531bbSYe Li }
49253531bbSYe Li 
hw_watchdog_reset(void)50253531bbSYe Li void hw_watchdog_reset(void)
51253531bbSYe Li {
52253531bbSYe Li 	struct wdog_regs *wdog = (struct wdog_regs *)WDOG_BASE_ADDR;
53253531bbSYe Li 
54253531bbSYe Li 	writel(REFRESH_WORD0, &wdog->cnt);
55253531bbSYe Li 	writel(REFRESH_WORD1, &wdog->cnt);
56253531bbSYe Li }
57253531bbSYe Li 
hw_watchdog_init(void)58253531bbSYe Li void hw_watchdog_init(void)
59253531bbSYe Li {
60253531bbSYe Li 	u8 val;
61253531bbSYe Li 	struct wdog_regs *wdog = (struct wdog_regs *)WDOG_BASE_ADDR;
62253531bbSYe Li 
63253531bbSYe Li 	writel(UNLOCK_WORD0, &wdog->cnt);
64253531bbSYe Li 	writel(UNLOCK_WORD1, &wdog->cnt);
65253531bbSYe Li 
66253531bbSYe Li 	val = readb(&wdog->cs2);
67253531bbSYe Li 	val |= WDGCS2_FLG;
68253531bbSYe Li 	writeb(val, &wdog->cs2);
69253531bbSYe Li 
70253531bbSYe Li 	hw_watchdog_set_timeout(CONFIG_WATCHDOG_TIMEOUT_MSECS);
71253531bbSYe Li 	writel(0, &wdog->win);
72253531bbSYe Li 
73253531bbSYe Li 	writeb(WDG_LPO_CLK, &wdog->cs2);/* setting 1-kHz clock source */
74253531bbSYe Li 	writeb((WDGCS1_WDGE | WDGCS1_WDGUPDATE), &wdog->cs1);/* enable counter running */
75253531bbSYe Li 
76253531bbSYe Li 	hw_watchdog_reset();
77253531bbSYe Li }
78253531bbSYe Li 
reset_cpu(ulong addr)79253531bbSYe Li void reset_cpu(ulong addr)
80253531bbSYe Li {
81253531bbSYe Li 	struct wdog_regs *wdog = (struct wdog_regs *)WDOG_BASE_ADDR;
82253531bbSYe Li 
83253531bbSYe Li 	writel(UNLOCK_WORD0, &wdog->cnt);
84253531bbSYe Li 	writel(UNLOCK_WORD1, &wdog->cnt);
85253531bbSYe Li 
86253531bbSYe Li 	hw_watchdog_set_timeout(5); /* 5ms timeout */
87253531bbSYe Li 	writel(0, &wdog->win);
88253531bbSYe Li 
89253531bbSYe Li 	writeb(WDG_LPO_CLK, &wdog->cs2);/* setting 1-kHz clock source */
90253531bbSYe Li 	writeb(WDGCS1_WDGE, &wdog->cs1);/* enable counter running */
91253531bbSYe Li 
92253531bbSYe Li 	hw_watchdog_reset();
93253531bbSYe Li 
94253531bbSYe Li 	while (1);
95253531bbSYe Li }
96