xref: /rk3399_rockchip-uboot/drivers/watchdog/omap_wdt.c (revision b633b9c8fe26519f3abaee3724115fec7b86aab2)
1988ea355SHeiko Schocher /*
2988ea355SHeiko Schocher  * omap_wdt.c
3988ea355SHeiko Schocher  *
4988ea355SHeiko Schocher  * (C) Copyright 2013
5988ea355SHeiko Schocher  * Heiko Schocher, DENX Software Engineering, hs@denx.de.
6988ea355SHeiko Schocher  *
7988ea355SHeiko Schocher  * SPDX-License-Identifier:	GPL-2.0
8988ea355SHeiko Schocher  *
9988ea355SHeiko Schocher  * Based on:
10988ea355SHeiko Schocher  *
11988ea355SHeiko Schocher  * Watchdog driver for the TI OMAP 16xx & 24xx/34xx 32KHz (non-secure) watchdog
12988ea355SHeiko Schocher  *
13988ea355SHeiko Schocher  * commit 2d991a164a61858012651e13c59521975504e260
14988ea355SHeiko Schocher  * Author: Bill Pemberton <wfp5p@virginia.edu>
15988ea355SHeiko Schocher  * Date:   Mon Nov 19 13:21:41 2012 -0500
16988ea355SHeiko Schocher  *
17988ea355SHeiko Schocher  * watchdog: remove use of __devinit
18988ea355SHeiko Schocher  *
19988ea355SHeiko Schocher  * CONFIG_HOTPLUG is going away as an option so __devinit is no longer
20988ea355SHeiko Schocher  * needed.
21988ea355SHeiko Schocher  *
22988ea355SHeiko Schocher  * Author: MontaVista Software, Inc.
23988ea355SHeiko Schocher  *	 <gdavis@mvista.com> or <source@mvista.com>
24988ea355SHeiko Schocher  *
25988ea355SHeiko Schocher  * History:
26988ea355SHeiko Schocher  *
27988ea355SHeiko Schocher  * 20030527: George G. Davis <gdavis@mvista.com>
28988ea355SHeiko Schocher  *	Initially based on linux-2.4.19-rmk7-pxa1/drivers/char/sa1100_wdt.c
29988ea355SHeiko Schocher  *	(c) Copyright 2000 Oleg Drokin <green@crimea.edu>
30988ea355SHeiko Schocher  *	Based on SoftDog driver by Alan Cox <alan@lxorguk.ukuu.org.uk>
31988ea355SHeiko Schocher  *
32988ea355SHeiko Schocher  * Copyright (c) 2004 Texas Instruments.
33988ea355SHeiko Schocher  *	1. Modified to support OMAP1610 32-KHz watchdog timer
34988ea355SHeiko Schocher  *	2. Ported to 2.6 kernel
35988ea355SHeiko Schocher  *
36988ea355SHeiko Schocher  * Copyright (c) 2005 David Brownell
37988ea355SHeiko Schocher  *	Use the driver model and standard identifiers; handle bigger timeouts.
38988ea355SHeiko Schocher  */
39988ea355SHeiko Schocher 
40988ea355SHeiko Schocher #include <common.h>
41988ea355SHeiko Schocher #include <watchdog.h>
42988ea355SHeiko Schocher #include <asm/arch/hardware.h>
43988ea355SHeiko Schocher #include <asm/io.h>
44988ea355SHeiko Schocher #include <asm/processor.h>
45988ea355SHeiko Schocher #include <asm/arch/cpu.h>
46988ea355SHeiko Schocher 
47988ea355SHeiko Schocher /* Hardware timeout in seconds */
48988ea355SHeiko Schocher #define WDT_HW_TIMEOUT 60
49988ea355SHeiko Schocher 
50988ea355SHeiko Schocher static unsigned int wdt_trgr_pattern = 0x1234;
51988ea355SHeiko Schocher 
hw_watchdog_reset(void)52988ea355SHeiko Schocher void hw_watchdog_reset(void)
53988ea355SHeiko Schocher {
54988ea355SHeiko Schocher 	struct wd_timer *wdt = (struct wd_timer *)WDT_BASE;
55988ea355SHeiko Schocher 
56988ea355SHeiko Schocher 	/* wait for posted write to complete */
57988ea355SHeiko Schocher 	while ((readl(&wdt->wdtwwps)) & WDT_WWPS_PEND_WTGR)
58988ea355SHeiko Schocher 		;
59988ea355SHeiko Schocher 
60988ea355SHeiko Schocher 	wdt_trgr_pattern = ~wdt_trgr_pattern;
61988ea355SHeiko Schocher 	writel(wdt_trgr_pattern, &wdt->wdtwtgr);
62988ea355SHeiko Schocher 
63988ea355SHeiko Schocher 	/* wait for posted write to complete */
64988ea355SHeiko Schocher 	while ((readl(&wdt->wdtwwps) & WDT_WWPS_PEND_WTGR))
65988ea355SHeiko Schocher 		;
66988ea355SHeiko Schocher }
67988ea355SHeiko Schocher 
omap_wdt_set_timeout(unsigned int timeout)68988ea355SHeiko Schocher static int omap_wdt_set_timeout(unsigned int timeout)
69988ea355SHeiko Schocher {
70988ea355SHeiko Schocher 	struct wd_timer *wdt = (struct wd_timer *)WDT_BASE;
71988ea355SHeiko Schocher 	u32 pre_margin = GET_WLDR_VAL(timeout);
72988ea355SHeiko Schocher 
73988ea355SHeiko Schocher 	/* just count up at 32 KHz */
74988ea355SHeiko Schocher 	while (readl(&wdt->wdtwwps) & WDT_WWPS_PEND_WLDR)
75988ea355SHeiko Schocher 		;
76988ea355SHeiko Schocher 
77988ea355SHeiko Schocher 	writel(pre_margin, &wdt->wdtwldr);
78988ea355SHeiko Schocher 	while (readl(&wdt->wdtwwps) & WDT_WWPS_PEND_WLDR)
79988ea355SHeiko Schocher 		;
80988ea355SHeiko Schocher 
81988ea355SHeiko Schocher 	return 0;
82988ea355SHeiko Schocher }
83988ea355SHeiko Schocher 
hw_watchdog_disable(void)84*b633b9c8SLukasz Majewski void hw_watchdog_disable(void)
85*b633b9c8SLukasz Majewski {
86*b633b9c8SLukasz Majewski 	struct wd_timer *wdt = (struct wd_timer *)WDT_BASE;
87*b633b9c8SLukasz Majewski 
88*b633b9c8SLukasz Majewski 	/*
89*b633b9c8SLukasz Majewski 	 * Disable watchdog
90*b633b9c8SLukasz Majewski 	 */
91*b633b9c8SLukasz Majewski 	writel(0xAAAA, &wdt->wdtwspr);
92*b633b9c8SLukasz Majewski 	while (readl(&wdt->wdtwwps) != 0x0)
93*b633b9c8SLukasz Majewski 		;
94*b633b9c8SLukasz Majewski 	writel(0x5555, &wdt->wdtwspr);
95*b633b9c8SLukasz Majewski 	while (readl(&wdt->wdtwwps) != 0x0)
96*b633b9c8SLukasz Majewski 		;
97*b633b9c8SLukasz Majewski }
98*b633b9c8SLukasz Majewski 
hw_watchdog_init(void)99988ea355SHeiko Schocher void hw_watchdog_init(void)
100988ea355SHeiko Schocher {
101988ea355SHeiko Schocher 	struct wd_timer *wdt = (struct wd_timer *)WDT_BASE;
102988ea355SHeiko Schocher 
103*b633b9c8SLukasz Majewski 	/*
104*b633b9c8SLukasz Majewski 	 * Make sure the watchdog is disabled. This is unfortunately required
105*b633b9c8SLukasz Majewski 	 * because writing to various registers with the watchdog running has no
106*b633b9c8SLukasz Majewski 	 * effect.
107*b633b9c8SLukasz Majewski 	 */
108*b633b9c8SLukasz Majewski 	hw_watchdog_disable();
109*b633b9c8SLukasz Majewski 
110988ea355SHeiko Schocher 	/* initialize prescaler */
111988ea355SHeiko Schocher 	while (readl(&wdt->wdtwwps) & WDT_WWPS_PEND_WCLR)
112988ea355SHeiko Schocher 		;
113988ea355SHeiko Schocher 
114988ea355SHeiko Schocher 	writel(WDT_WCLR_PRE | (PTV << WDT_WCLR_PTV_OFF), &wdt->wdtwclr);
115988ea355SHeiko Schocher 	while (readl(&wdt->wdtwwps) & WDT_WWPS_PEND_WCLR)
116988ea355SHeiko Schocher 		;
117988ea355SHeiko Schocher 
118988ea355SHeiko Schocher 	omap_wdt_set_timeout(WDT_HW_TIMEOUT);
119988ea355SHeiko Schocher 
120988ea355SHeiko Schocher 	/* Sequence to enable the watchdog */
121988ea355SHeiko Schocher 	writel(0xBBBB, &wdt->wdtwspr);
122988ea355SHeiko Schocher 	while ((readl(&wdt->wdtwwps)) & WDT_WWPS_PEND_WSPR)
123988ea355SHeiko Schocher 		;
124988ea355SHeiko Schocher 
125988ea355SHeiko Schocher 	writel(0x4444, &wdt->wdtwspr);
126988ea355SHeiko Schocher 	while ((readl(&wdt->wdtwwps)) & WDT_WWPS_PEND_WSPR)
127988ea355SHeiko Schocher 		;
128988ea355SHeiko Schocher }
129