xref: /openbmc/u-boot/drivers/watchdog/imx_watchdog.c (revision abbab70363dcdb270cbf24d47849214dd3a3e010)
1*abbab703STroy Kisky /*
2*abbab703STroy Kisky  * watchdog.c - driver for i.mx on-chip watchdog
3*abbab703STroy Kisky  *
4*abbab703STroy Kisky  * Licensed under the GPL-2 or later.
5*abbab703STroy Kisky  */
6*abbab703STroy Kisky 
7*abbab703STroy Kisky #include <common.h>
8*abbab703STroy Kisky #include <asm/io.h>
9*abbab703STroy Kisky #include <watchdog.h>
10*abbab703STroy Kisky #include <asm/arch/imx-regs.h>
11*abbab703STroy Kisky 
12*abbab703STroy Kisky struct watchdog_regs {
13*abbab703STroy Kisky 	u16	wcr;	/* Control */
14*abbab703STroy Kisky 	u16	wsr;	/* Service */
15*abbab703STroy Kisky 	u16	wrsr;	/* Reset Status */
16*abbab703STroy Kisky };
17*abbab703STroy Kisky 
18*abbab703STroy Kisky #define WCR_WDZST	0x01
19*abbab703STroy Kisky #define WCR_WDBG	0x02
20*abbab703STroy Kisky #define WCR_WDE		0x04	/* WDOG enable */
21*abbab703STroy Kisky #define WCR_WDT		0x08
22*abbab703STroy Kisky #define WCR_WDW		0x80
23*abbab703STroy Kisky #define SET_WCR_WT(x)	(x << 8)
24*abbab703STroy Kisky 
25*abbab703STroy Kisky #ifdef CONFIG_IMX_WATCHDOG
26*abbab703STroy Kisky void hw_watchdog_reset(void)
27*abbab703STroy Kisky {
28*abbab703STroy Kisky 	struct watchdog_regs *wdog = (struct watchdog_regs *)WDOG1_BASE_ADDR;
29*abbab703STroy Kisky 
30*abbab703STroy Kisky 	writew(0x5555, &wdog->wsr);
31*abbab703STroy Kisky 	writew(0xaaaa, &wdog->wsr);
32*abbab703STroy Kisky }
33*abbab703STroy Kisky 
34*abbab703STroy Kisky void hw_watchdog_init(void)
35*abbab703STroy Kisky {
36*abbab703STroy Kisky 	struct watchdog_regs *wdog = (struct watchdog_regs *)WDOG1_BASE_ADDR;
37*abbab703STroy Kisky 	u16 timeout;
38*abbab703STroy Kisky 
39*abbab703STroy Kisky 	/*
40*abbab703STroy Kisky 	 * The timer watchdog can be set between
41*abbab703STroy Kisky 	 * 0.5 and 128 Seconds. If not defined
42*abbab703STroy Kisky 	 * in configuration file, sets 128 Seconds
43*abbab703STroy Kisky 	 */
44*abbab703STroy Kisky #ifndef CONFIG_WATCHDOG_TIMEOUT_MSECS
45*abbab703STroy Kisky #define CONFIG_WATCHDOG_TIMEOUT_MSECS 128000
46*abbab703STroy Kisky #endif
47*abbab703STroy Kisky 	timeout = (CONFIG_WATCHDOG_TIMEOUT_MSECS / 500) - 1;
48*abbab703STroy Kisky 	writew(WCR_WDZST | WCR_WDBG | WCR_WDE | WCR_WDT |
49*abbab703STroy Kisky 		WCR_WDW | SET_WCR_WT(timeout), &wdog->wcr);
50*abbab703STroy Kisky 	hw_watchdog_reset();
51*abbab703STroy Kisky }
52*abbab703STroy Kisky #endif
53*abbab703STroy Kisky 
54*abbab703STroy Kisky void reset_cpu(ulong addr)
55*abbab703STroy Kisky {
56*abbab703STroy Kisky 	struct watchdog_regs *wdog = (struct watchdog_regs *)WDOG1_BASE_ADDR;
57*abbab703STroy Kisky 
58*abbab703STroy Kisky 	writew(WCR_WDE, &wdog->wcr);
59*abbab703STroy Kisky 	writew(0x5555, &wdog->wsr);
60*abbab703STroy Kisky 	writew(0xaaaa, &wdog->wsr);	/* load minimum 1/2 second timeout */
61*abbab703STroy Kisky 	while (1) {
62*abbab703STroy Kisky 		/*
63*abbab703STroy Kisky 		 * spin for .5 seconds before reset
64*abbab703STroy Kisky 		 */
65*abbab703STroy Kisky 	}
66*abbab703STroy Kisky }
67