pl030_rtc.c revision 1.1.2.3 1 /* $NetBSD: pl030_rtc.c,v 1.1.2.3 2002/10/18 02:36:28 nathanw Exp $ */
2
3 /*
4 * Copyright (c) 2001 ARM Ltd
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
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. The name of the company may not be used to endorse or promote
16 * products derived from this software without specific prior written
17 * permission.
18 *
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 CONTRIBUTORS 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
29 * SUCH DAMAGE.
30 */
31
32 /* Include header files */
33
34 #include <sys/types.h>
35 #include <sys/param.h>
36 #include <sys/systm.h>
37 #include <sys/kernel.h>
38 #include <sys/time.h>
39 #include <sys/device.h>
40
41 #include <arm/cpufunc.h>
42 #include <machine/intr.h>
43 #include <evbarm/ifpga/ifpgavar.h>
44 #include <evbarm/ifpga/ifpgamem.h>
45 #include <evbarm/ifpga/ifpgareg.h>
46
47 #define PL030_RTC_SIZE 0x14
48
49 struct plrtc_softc {
50 struct device sc_dev;
51 bus_space_tag_t sc_iot;
52 bus_space_handle_t sc_ioh;
53 };
54
55 static int plrtc_probe (struct device *, struct cfdata *, void *);
56 static void plrtc_attach (struct device *, struct device *, void *);
57
58 CFATTACH_DECL(plrtc, sizeof(struct plrtc_softc),
59 plrtc_probe, plrtc_attach, NULL, NULL);
60
61 /* Remember our handle, since it isn't passed in by inittodr and
62 resettodr. */
63 static struct plrtc_softc *plrtc_sc;
64
65 static int timeset = 0;
66
67 static int
68 plrtc_probe(struct device *parent, struct cfdata *cf, void *aux)
69 {
70 return 1;
71 }
72
73 static void
74 plrtc_attach(struct device *parent, struct device *self, void *aux)
75 {
76 struct ifpga_attach_args *ifa = aux;
77 struct plrtc_softc *sc = (struct plrtc_softc *)self;
78
79 sc->sc_iot = ifa->ifa_iot;
80 if (bus_space_map(ifa->ifa_iot, ifa->ifa_addr, PL030_RTC_SIZE, 0,
81 &sc->sc_ioh)) {
82 printf("%s: unable to map device\n", sc->sc_dev.dv_xname);
83 return;
84 }
85
86 plrtc_sc = sc;
87
88 printf("\n");
89 }
90
91 void
92 inittodr(time_t base)
93 {
94 time_t rtc_time;
95 struct plrtc_softc *sc = plrtc_sc;
96
97 if (sc == NULL)
98 panic("RTC not attached");
99
100 /* Default to the suggested time, but replace that with one from the
101 RTC if it seems more sensible. */
102 rtc_time = bus_space_read_4(sc->sc_iot, sc->sc_ioh, IFPGA_RTC_DR);
103
104 time.tv_usec = 0;
105 time.tv_sec = rtc_time;
106
107 timeset = 1;
108
109 if (base > rtc_time) {
110 printf("inittodr: rtc value suspect, ignoring it.\n");
111 time.tv_usec = 0;
112 time.tv_sec = base;
113 return;
114 }
115 }
116
117 void
118 resettodr()
119 {
120 struct plrtc_softc *sc = plrtc_sc;
121
122 /* The time hasn't been set yet, so avoid writing a dubious value
123 to the RTC. */
124 if (!timeset)
125 return;
126
127 bus_space_write_4(sc->sc_iot, sc->sc_ioh, IFPGA_RTC_LR, time.tv_sec);
128 }
129