]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - sys/arm/at91/at91_rtc.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / sys / arm / at91 / at91_rtc.c
1 /*-
2  * Copyright (c) 2006 M. Warner Losh.  All rights reserved.
3  * Copyright (c) 2012 Ian Lepore.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  */
26
27 /*
28  * Driver for the at91 on-chip realtime clock.
29  *
30  * This driver does not currently support alarms, just date and time.
31  *
32  * The RTC on the AT91RM9200 resets when the core rests, so it is useless as a
33  * source of time (except when the CPU clock is powered down to save power,
34  * which we don't currently do).  On AT91SAM9 chips, the RTC survives chip
35  * reset, and there's provisions for it to keep time via battery backup if the
36  * system loses power.  On those systems, we use it as a RTC.  We tell the two
37  * apart because the century field is 19 on AT91RM9200 on reset, or on AT91SAM9
38  * chips that haven't had their time properly set.
39  */
40
41 #include <sys/cdefs.h>
42 __FBSDID("$FreeBSD$");
43
44 #include <sys/param.h>
45 #include <sys/systm.h>
46 #include <sys/bus.h>
47 #include <sys/clock.h>
48 #include <sys/conf.h>
49 #include <sys/kernel.h>
50 #include <sys/lock.h>
51 #include <sys/mbuf.h>
52 #include <sys/malloc.h>
53 #include <sys/module.h>
54 #include <sys/mutex.h>
55 #include <sys/rman.h>
56 #include <machine/bus.h>
57 #include <machine/cpu.h>
58
59 #include <arm/at91/at91_rtcreg.h>
60
61 #include "clock_if.h"
62
63 /*
64  * The driver has all the infrastructure to use interrupts but doesn't actually
65  * have any need to do so right now.  There's a non-zero cost for installing the
66  * handler because the RTC shares the system interrupt (IRQ 1), and thus will
67  * get called a lot for no reason at all.
68  */
69 #define AT91_RTC_USE_INTERRUPTS_NOT
70
71 struct at91_rtc_softc
72 {
73         device_t dev;                   /* Myself */
74         void *intrhand;                 /* Interrupt handle */
75         struct resource *irq_res;       /* IRQ resource */
76         struct resource *mem_res;       /* Memory resource */
77         struct mtx sc_mtx;              /* basically a perimeter lock */
78 };
79
80 static inline uint32_t
81 RD4(struct at91_rtc_softc *sc, bus_size_t off)
82 {
83         return bus_read_4(sc->mem_res, off);
84 }
85
86 static inline void
87 WR4(struct at91_rtc_softc *sc, bus_size_t off, uint32_t val)
88 {
89         bus_write_4(sc->mem_res, off, val);
90 }
91
92 #define AT91_RTC_LOCK(_sc)              mtx_lock_spin(&(_sc)->sc_mtx)
93 #define AT91_RTC_UNLOCK(_sc)            mtx_unlock_spin(&(_sc)->sc_mtx)
94 #define AT91_RTC_LOCK_INIT(_sc) \
95         mtx_init(&_sc->sc_mtx, device_get_nameunit(_sc->dev), \
96             "rtc", MTX_SPIN)
97 #define AT91_RTC_LOCK_DESTROY(_sc)      mtx_destroy(&_sc->sc_mtx);
98 #define AT91_RTC_ASSERT_LOCKED(_sc)     mtx_assert(&_sc->sc_mtx, MA_OWNED);
99 #define AT91_RTC_ASSERT_UNLOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_NOTOWNED);
100
101 static devclass_t at91_rtc_devclass;
102
103 /* bus entry points */
104
105 static int at91_rtc_probe(device_t dev);
106 static int at91_rtc_attach(device_t dev);
107 static int at91_rtc_detach(device_t dev);
108
109 /* helper routines */
110 static int at91_rtc_activate(device_t dev);
111 static void at91_rtc_deactivate(device_t dev);
112
113 #ifdef AT91_RTC_USE_INTERRUPTS
114 static int
115 at91_rtc_intr(void *xsc)
116 {
117         struct at91_rtc_softc *sc;
118         uint32_t status;
119
120         sc = xsc;
121         /* Must clear the status bits after reading them to re-arm. */
122         status = RD4(sc, RTC_SR);
123         WR4(sc, RTC_SCCR, status);
124         if (status == 0)
125                 return;
126         AT91_RTC_LOCK(sc);
127         /* Do something here */
128         AT91_RTC_UNLOCK(sc);
129         wakeup(sc);
130         return (FILTER_HANDLED);
131 }
132 #endif
133
134 static int
135 at91_rtc_probe(device_t dev)
136 {
137         device_set_desc(dev, "RTC");
138         return (0);
139 }
140
141 static int
142 at91_rtc_attach(device_t dev)
143 {
144         struct at91_rtc_softc *sc = device_get_softc(dev);
145         int err;
146
147         sc->dev = dev;
148         err = at91_rtc_activate(dev);
149         if (err)
150                 goto out;
151
152         AT91_RTC_LOCK_INIT(sc);
153
154         /*
155          * Disable all interrupts in the hardware.
156          * Clear all bits in the status register.
157          * Set 24-hour-clock mode.
158          */
159         WR4(sc, RTC_IDR, 0xffffffff);
160         WR4(sc, RTC_SCCR, 0x1f);
161         WR4(sc, RTC_MR, 0);
162
163 #ifdef AT91_RTC_USE_INTERRUPTS
164         err = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_MISC,
165             at91_rtc_intr, NULL, sc, &sc->intrhand);
166         if (err) {
167                 AT91_RTC_LOCK_DESTROY(sc);
168                 goto out;
169         }
170 #endif  
171
172         /*
173          * Read the calendar register.  If the century is 19 then the clock has
174          * never been set.  Try to store an invalid value into the register,
175          * which will turn on the error bit in RTC_VER, and our getclock code
176          * knows to return EINVAL if any error bits are on.
177          */
178         if (RTC_CALR_CEN(RD4(sc, RTC_CALR)) == 19)
179                 WR4(sc, RTC_CALR, 0);
180
181         /*
182          * Register as a time of day clock with 1-second resolution.
183          */
184         clock_register(dev, 1000000);
185 out:
186         if (err)
187                 at91_rtc_deactivate(dev);
188         return (err);
189 }
190
191 /*
192  * Cannot support detach, since there's no clock_unregister function.
193  */
194 static int
195 at91_rtc_detach(device_t dev)
196 {
197         return (EBUSY);
198 }
199
200 static int
201 at91_rtc_activate(device_t dev)
202 {
203         struct at91_rtc_softc *sc;
204         int rid;
205
206         sc = device_get_softc(dev);
207         rid = 0;
208         sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
209             RF_ACTIVE);
210         if (sc->mem_res == NULL)
211                 goto errout;
212 #ifdef AT91_RTC_USE_INTERRUPTS
213         rid = 0;
214         sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
215             RF_ACTIVE | RF_SHAREABLE);
216         if (sc->irq_res == NULL)
217                 goto errout;
218 #endif  
219         return (0);
220 errout:
221         at91_rtc_deactivate(dev);
222         return (ENOMEM);
223 }
224
225 static void
226 at91_rtc_deactivate(device_t dev)
227 {
228         struct at91_rtc_softc *sc;
229
230         sc = device_get_softc(dev);
231 #ifdef AT91_RTC_USE_INTERRUPTS
232         WR4(sc, RTC_IDR, 0xffffffff);
233         if (sc->intrhand)
234                 bus_teardown_intr(dev, sc->irq_res, sc->intrhand);
235         sc->intrhand = 0;
236 #endif
237         bus_generic_detach(sc->dev);
238         if (sc->mem_res)
239                 bus_release_resource(dev, SYS_RES_MEMORY,
240                     rman_get_rid(sc->mem_res), sc->mem_res);
241         sc->mem_res = 0;
242 #ifdef AT91_RTC_USE_INTERRUPTS
243         if (sc->irq_res)
244                 bus_release_resource(dev, SYS_RES_IRQ,
245                     rman_get_rid(sc->irq_res), sc->irq_res);
246         sc->irq_res = 0;
247 #endif  
248         return;
249 }
250
251 /*
252  * Get the time of day clock and return it in ts.
253  * Return 0 on success, an error number otherwise.
254  */
255 static int
256 at91_rtc_gettime(device_t dev, struct timespec *ts)
257 {
258         struct clocktime ct;
259         uint32_t calr, calr2, timr, timr2;
260         struct at91_rtc_softc *sc;
261
262         sc = device_get_softc(dev);
263
264         /* If the error bits are set we can't return useful values. */
265
266         if (RD4(sc, RTC_VER) & (RTC_VER_NVTIM | RTC_VER_NVCAL))
267                 return EINVAL;
268
269         /*
270          * The RTC hardware can update registers while the CPU is reading them.
271          * The manual advises reading until you obtain the same values twice.
272          * Interleaving the reads (rather than timr, timr2, calr, calr2 order)
273          * also ensures we don't miss a midnight rollover/carry between reads.
274          */
275         do {
276                 timr = RD4(sc, RTC_TIMR);
277                 calr = RD4(sc, RTC_CALR);
278                 timr2 = RD4(sc, RTC_TIMR);
279                 calr2 = RD4(sc, RTC_CALR);
280         } while (timr != timr2 || calr != calr2);
281
282         ct.nsec = 0;
283         ct.sec = RTC_TIMR_SEC(timr);
284         ct.min = RTC_TIMR_MIN(timr);
285         ct.hour = RTC_TIMR_HR(timr);
286         ct.year = RTC_CALR_CEN(calr) * 100 + RTC_CALR_YEAR(calr);
287         ct.mon = RTC_CALR_MON(calr);
288         ct.day = RTC_CALR_DAY(calr);
289         ct.dow = -1;
290         return clock_ct_to_ts(&ct, ts);
291 }
292
293 /*
294  * Set the time of day clock based on the value of the struct timespec arg.
295  * Return 0 on success, an error number otherwise.
296  */
297 static int
298 at91_rtc_settime(device_t dev, struct timespec *ts)
299 {
300         struct at91_rtc_softc *sc;
301         struct clocktime ct;
302         int rv;
303
304         sc = device_get_softc(dev);
305         clock_ts_to_ct(ts, &ct);
306
307         /*
308          * Can't set the clock unless a second has elapsed since we last did so.
309          */
310         while ((RD4(sc, RTC_SR) & RTC_SR_SECEV) == 0)
311                 cpu_spinwait();
312
313         /*
314          * Stop the clocks for an update; wait until hardware is ready.
315          * Clear the update-ready status after it gets asserted (the manual says
316          * to do this before updating the value registers).
317          */
318         WR4(sc, RTC_CR, RTC_CR_UPDCAL | RTC_CR_UPDTIM);
319         while ((RD4(sc, RTC_SR) & RTC_SR_ACKUPD) == 0)
320                 cpu_spinwait();
321         WR4(sc, RTC_SCCR, RTC_SR_ACKUPD);
322
323         /*
324          * Set the values in the hardware, then check whether the hardware was
325          * happy with them so we can return the correct status.
326          */
327         WR4(sc, RTC_TIMR, RTC_TIMR_MK(ct.hour, ct.min, ct.sec));
328         WR4(sc, RTC_CALR, RTC_CALR_MK(ct.year, ct.mon, ct.day, ct.dow+1));
329
330         if (RD4(sc, RTC_VER) & (RTC_VER_NVTIM | RTC_VER_NVCAL))
331                 rv = EINVAL;
332         else
333                 rv = 0;
334
335         /*
336          * Restart the clocks (turn off the update bits).
337          * Clear the second-event bit (because the manual says to).
338          */
339         WR4(sc, RTC_CR, RD4(sc, RTC_CR) & ~(RTC_CR_UPDCAL | RTC_CR_UPDTIM));
340         WR4(sc, RTC_SCCR, RTC_SR_SECEV);
341
342         return (0);
343 }
344
345 static device_method_t at91_rtc_methods[] = {
346         /* Device interface */
347         DEVMETHOD(device_probe,         at91_rtc_probe),
348         DEVMETHOD(device_attach,        at91_rtc_attach),
349         DEVMETHOD(device_detach,        at91_rtc_detach),
350
351         /* clock interface */
352         DEVMETHOD(clock_gettime,        at91_rtc_gettime),
353         DEVMETHOD(clock_settime,        at91_rtc_settime),
354
355         DEVMETHOD_END
356 };
357
358 static driver_t at91_rtc_driver = {
359         "at91_rtc",
360         at91_rtc_methods,
361         sizeof(struct at91_rtc_softc),
362 };
363
364 DRIVER_MODULE(at91_rtc, atmelarm, at91_rtc_driver, at91_rtc_devclass, 0, 0);