2 * OMAP watchdog timers, common code
4 * Copyright (c) 2007 Microsoft
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by Microsoft
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
20 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTERS BE LIABLE FOR ANY DIRECT,
23 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 #include <sys/cdefs.h>
34 #include <sys/param.h>
35 #include <sys/callout.h>
36 #include <sys/cdefs.h>
37 #include <sys/device.h>
38 #include <sys/kernel.h>
39 #include <sys/systm.h>
42 #include <machine/param.h>
43 #include <machine/bus.h>
44 #include <dev/sysmon/sysmonvar.h>
46 #include <arm/omap/omap_wdtvar.h>
47 #include <arm/omap/omap_wdtreg.h>
49 struct omapwdt32k_softc
*omapwdt32k_sc
;
50 int omapwdt_sysconfig
;
55 /* The WCLR, WCRR, WLDR, WTGR and WSPR registers are
56 * synchronized to the 32kHz clock. Each has an
57 * associated status bit that's set when there's
58 * a pending write. This function will wait for
59 * all of those status bits to become clear so
60 * the caller can safely write to any of the registers.
62 while (bus_space_read_4(omapwdt32k_sc
->sc_iot
, omapwdt32k_sc
->sc_ioh
,
64 (W_PEND_WSPR
| W_PEND_WTGR
| W_PEND_WLDR
| W_PEND_WCRR
|
70 omapwdt32k_start(void)
73 bus_space_write_4(omapwdt32k_sc
->sc_iot
, omapwdt32k_sc
->sc_ioh
, WSPR
,
76 bus_space_write_4(omapwdt32k_sc
->sc_iot
, omapwdt32k_sc
->sc_ioh
, WSPR
,
84 bus_space_write_4(omapwdt32k_sc
->sc_iot
, omapwdt32k_sc
->sc_ioh
, WSPR
,
87 bus_space_write_4(omapwdt32k_sc
->sc_iot
, omapwdt32k_sc
->sc_ioh
, WSPR
,
92 omapwdt32k_do_set_timeout(void)
94 if (omapwdt32k_sc
->sc_armed
) {
96 * The watchdog must be disabled before writing to
97 * the WCRR, WCLR:PTV, or WLDR registers.
102 /* Make sure WLDR, WCRR, and WCLR are ready to be written to.
106 /* Make sure that the prescaler is set.
108 bus_space_write_4(omapwdt32k_sc
->sc_iot
, omapwdt32k_sc
->sc_ioh
, WCLR
,
109 (WCLR_PTV(PTV
) | WCLR_PRE(PRE
)));
111 /* Write the new count value to the load and
115 bus_space_write_4(omapwdt32k_sc
->sc_iot
, omapwdt32k_sc
->sc_ioh
, WLDR
,
116 omapwdt32k_sc
->sc_smw
.smw_period
?
117 WATCHDOG_COUNT(omapwdt32k_sc
->sc_smw
.smw_period
)
119 bus_space_write_4(omapwdt32k_sc
->sc_iot
, omapwdt32k_sc
->sc_ioh
, WCRR
,
120 omapwdt32k_sc
->sc_smw
.smw_period
?
121 WATCHDOG_COUNT(omapwdt32k_sc
->sc_smw
.smw_period
)
124 /* Wait for the pending writes to go through.
128 /* Resume the watchdog if we had stopped it.
130 if (omapwdt32k_sc
->sc_armed
)
135 omapwdt32k_set_timeout(unsigned int period
)
139 if (period
!= omapwdt32k_sc
->sc_smw
.smw_period
) {
140 omapwdt32k_sc
->sc_smw
.smw_period
= period
;
141 omapwdt32k_do_set_timeout();
148 omapwdt32k_enable(int enable
)
151 int prev_state
= omapwdt32k_sc
->sc_armed
;
153 /* Normalize the int to a boolean so we can compare values directly.
159 if (enable
!= omapwdt32k_sc
->sc_armed
) {
161 /* Make sure that the watchdog timeout is up to date.
163 omapwdt32k_do_set_timeout();
168 omapwdt32k_sc
->sc_armed
= enable
;
176 omapwdt32k_setmode(struct sysmon_wdog
*smw
)
178 struct omapwdt32k_softc
*sc
= smw
->smw_cookie
;
181 if ((smw
->smw_mode
& WDOG_MODE_MASK
) == WDOG_MODE_DISARMED
) {
182 omapwdt32k_enable(0);
184 if (smw
->smw_period
== WDOG_PERIOD_DEFAULT
)
185 sc
->sc_smw
.smw_period
= OMAPWDT32K_DEFAULT_PERIOD
;
187 sc
->sc_smw
.smw_period
= smw
->smw_period
;
188 omapwdt32k_set_timeout(sc
->sc_smw
.smw_period
);
189 omapwdt32k_enable(1);
195 omapwdt32k_tickle(struct sysmon_wdog
*smw
)
200 * To reload the timer counter and reset the prescaler counter
201 * values without reaching overflow, a reload command can be
202 * executed by accessing the watchdog trigger register (WTGR)
203 * using a specific reload sequence.
205 * The specific reload sequence is performed when the written
206 * value on the watchdog trigger register (WTGR) is different
207 * from its previous value. In this case, reload is executed in
208 * the same way as overflow autoreload, without a reset pulse
209 * generation. The timer is loaded with the watchdog load register
210 * (WLDR) value and the prescaler counter is reset.
212 * Write a new value into WTGR to reload WCRR (counter register)
213 * with the value in WLDR (load register), thereby resetting the
217 bus_space_write_4(omapwdt32k_sc
->sc_iot
, omapwdt32k_sc
->sc_ioh
, WTGR
,
218 ~bus_space_read_4(omapwdt32k_sc
->sc_iot
,
219 omapwdt32k_sc
->sc_ioh
, WTGR
));
226 omapwdt32k_reboot(void)
230 omapwdt32k_set_timeout(0);