1 /* $OpenBSD: omdog.c,v 1.5 2014/12/10 12:27:56 mikeb Exp $ */
3 * Copyright (c) 2013 Federico G. Schwindt <fgsch@openbsd.org>
4 * Copyright (c) 2007,2009 Dale Rahn <drahn@openbsd.org>
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 #include <sys/param.h>
20 #include <sys/systm.h>
21 #include <sys/queue.h>
22 #include <sys/malloc.h>
23 #include <sys/device.h>
24 #include <sys/evcount.h>
25 #include <sys/socket.h>
26 #include <sys/timeout.h>
27 #include <machine/intr.h>
28 #include <machine/bus.h>
29 #include <armv7/armv7/armv7var.h>
31 #define WIDR 0x00 /* Identification Register */
32 #define WCLR 0x24 /* Control Register */
33 #define WCLR_PRE (1 << 5)
34 #define WCLR_PTV (0 << 2)
35 #define WCRR 0x28 /* Counter Register */
36 #define WLDR 0x2c /* Load Register */
37 #define WTGR 0x30 /* Trigger Register */
38 #define WWPS 0x34 /* Write Posting Bits Reg. */
39 #define WWPS_WSPR (1 << 4)
40 #define WWPS_WTGR (1 << 3)
41 #define WWPS_WLDR (1 << 2)
42 #define WWPS_WCRR (1 << 1)
43 #define WWPS_WCLR (1 << 0)
44 #define WSPR 0x48 /* Start/Stop Register */
46 #define OMDOG_VAL(secs) (0xffffffff - ((secs) * (32768 / (1 << 0))) + 1)
51 bus_space_tag_t sc_iot
;
52 bus_space_handle_t sc_ioh
;
57 struct omdog_softc
*omdog_sc
;
59 void omdog_attach(struct device
*, struct device
*, void *);
60 int omdog_activate(struct device
*, int);
61 void omdog_start(struct omdog_softc
*);
62 void omdog_stop(struct omdog_softc
*);
63 void omdog_sync(struct omdog_softc
*);
64 int omdog_cb(void *, int);
65 void omdog_reset(void);
67 struct cfattach omdog_ca
= {
68 sizeof (struct omdog_softc
), NULL
, omdog_attach
, NULL
, omdog_activate
71 struct cfdriver omdog_cd
= {
72 NULL
, "omdog", DV_DULL
76 omdog_attach(struct device
*parent
, struct device
*self
, void *args
)
78 struct armv7_attach_args
*aa
= args
;
79 struct omdog_softc
*sc
= (struct omdog_softc
*) self
;
82 sc
->sc_iot
= aa
->aa_iot
;
83 if (bus_space_map(sc
->sc_iot
, aa
->aa_dev
->mem
[0].addr
,
84 aa
->aa_dev
->mem
[0].size
, 0, &sc
->sc_ioh
))
85 panic("%s: bus_space_map failed!", __func__
);
87 rev
= bus_space_read_4(sc
->sc_iot
, sc
->sc_ioh
, WIDR
);
89 printf(" rev %d.%d\n", rev
>> 4 & 0xf, rev
& 0xf);
95 wdog_register(omdog_cb
, sc
);
100 omdog_activate(struct device
*self
, int act
)
103 case DVACT_POWERDOWN
:
114 omdog_start(struct omdog_softc
*sc
)
116 /* Write the enable sequence data BBBBh followed by 4444h */
117 bus_space_write_4(sc
->sc_iot
, sc
->sc_ioh
, WSPR
, 0xbbbb);
119 bus_space_write_4(sc
->sc_iot
, sc
->sc_ioh
, WSPR
, 0x4444);
124 omdog_stop(struct omdog_softc
*sc
)
126 /* Write the disable sequence data AAAAh followed by 5555h */
127 bus_space_write_4(sc
->sc_iot
, sc
->sc_ioh
, WSPR
, 0xaaaa);
129 bus_space_write_4(sc
->sc_iot
, sc
->sc_ioh
, WSPR
, 0x5555);
134 omdog_sync(struct omdog_softc
*sc
)
136 while (bus_space_read_4(sc
->sc_iot
, sc
->sc_ioh
, WWPS
) &
137 (WWPS_WSPR
|WWPS_WTGR
|WWPS_WLDR
|WWPS_WCRR
|WWPS_WCLR
))
142 omdog_cb(void *self
, int period
)
144 struct omdog_softc
*sc
= self
;
146 if (sc
->sc_period
!= 0 && sc
->sc_period
!= period
)
150 if (sc
->sc_period
!= period
) {
151 /* Set the prescaler */
152 bus_space_write_4(sc
->sc_iot
, sc
->sc_ioh
, WCLR
,
153 (WCLR_PRE
|WCLR_PTV
));
155 /* Set the reload counter */
156 bus_space_write_4(sc
->sc_iot
, sc
->sc_ioh
, WLDR
,
162 /* Trigger the reload */
163 bus_space_write_4(sc
->sc_iot
, sc
->sc_ioh
, WTGR
,
164 ~bus_space_read_4(sc
->sc_iot
, sc
->sc_ioh
, WTGR
));
166 if (sc
->sc_period
!= period
)
170 sc
->sc_period
= period
;
178 if (omdog_sc
== NULL
)
181 if (omdog_sc
->sc_period
!= 0)
182 omdog_stop(omdog_sc
);
184 bus_space_write_4(omdog_sc
->sc_iot
, omdog_sc
->sc_ioh
, WCRR
,
187 omdog_start(omdog_sc
);