obio_timer.c revision 1.2 1 /* $NetBSD: obio_timer.c,v 1.2 2008/11/09 09:11:09 cliff Exp $ */
2
3 /* adapted from:
4 * NetBSD: obio_mputmr.c,v 1.3 2008/08/27 11:03:10 matt Exp
5 */
6
7 /*
8 * Based on omap_mputmr.c
9 * Based on i80321_timer.c and arch/arm/sa11x0/sa11x0_ost.c
10 *
11 * Copyright (c) 1997 Mark Brinicombe.
12 * Copyright (c) 1997 Causality Limited.
13 * All rights reserved.
14 *
15 * This code is derived from software contributed to The NetBSD Foundation
16 * by IWAMOTO Toshihiro and Ichiro FUKUHARA.
17 *
18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions
20 * are met:
21 * 1. Redistributions of source code must retain the above copyright
22 * notice, this list of conditions and the following disclaimer.
23 * 2. Redistributions in binary form must reproduce the above copyright
24 * notice, this list of conditions and the following disclaimer in the
25 * documentation and/or other materials provided with the distribution.
26 * 3. All advertising materials mentioning features or use of this software
27 * must display the following acknowledgement:
28 * This product includes software developed by the NetBSD
29 * Foundation, Inc. and its contributors.
30 * 4. Neither the name of The NetBSD Foundation nor the names of its
31 * contributors may be used to endorse or promote products derived
32 * from this software without specific prior written permission.
33 *
34 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
35 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
36 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
37 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
38 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
39 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
40 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
41 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
42 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
43 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
44 * POSSIBILITY OF SUCH DAMAGE.
45 *
46 * Copyright (c) 2001, 2002 Wasabi Systems, Inc.
47 * All rights reserved.
48 *
49 * Written by Jason R. Thorpe for Wasabi Systems, Inc.
50 *
51 * Redistribution and use in source and binary forms, with or without
52 * modification, are permitted provided that the following conditions
53 * are met:
54 * 1. Redistributions of source code must retain the above copyright
55 * notice, this list of conditions and the following disclaimer.
56 * 2. Redistributions in binary form must reproduce the above copyright
57 * notice, this list of conditions and the following disclaimer in the
58 * documentation and/or other materials provided with the distribution.
59 * 3. All advertising materials mentioning features or use of this software
60 * must display the following acknowledgement:
61 * This product includes software developed for the NetBSD Project by
62 * Wasabi Systems, Inc.
63 * 4. The name of Wasabi Systems, Inc. may not be used to endorse
64 * or promote products derived from this software without specific prior
65 * written permission.
66 *
67 * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
68 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
69 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
70 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
71 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
72 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
73 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
74 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
75 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
76 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
77 * POSSIBILITY OF SUCH DAMAGE.
78 *
79 * Copyright (c) 2007 Microsoft
80 * All rights reserved.
81 *
82 * Redistribution and use in source and binary forms, with or without
83 * modification, are permitted provided that the following conditions
84 * are met:
85 * 1. Redistributions of source code must retain the above copyright
86 * notice, this list of conditions and the following disclaimer.
87 * 2. Redistributions in binary form must reproduce the above copyright
88 * notice, this list of conditions and the following disclaimer in the
89 * documentation and/or other materials provided with the distribution.
90 * 3. All advertising materials mentioning features or use of this software
91 * must display the following acknowledgement:
92 * This product includes software developed by Microsoft
93 *
94 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
95 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
96 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
97 * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTERS BE LIABLE FOR ANY DIRECT,
98 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
99 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
100 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
101 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
102 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
103 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
104 * SUCH DAMAGE.
105 */
106
107 #include <sys/cdefs.h>
108 __KERNEL_RCSID(0, "$NetBSD: obio_timer.c,v 1.2 2008/11/09 09:11:09 cliff Exp $");
109
110 #include "opt_cpuoptions.h"
111 #include "opt_gemini.h"
112 #include "locators.h"
113
114 #include <sys/types.h>
115 #include <sys/param.h>
116 #include <sys/systm.h>
117 #include <sys/kernel.h>
118 #include <sys/time.h>
119 #include <sys/device.h>
120
121 #include <dev/clock_subr.h>
122
123 #include <machine/bus.h>
124 #include <machine/intr.h>
125
126 #include <arm/gemini/gemini_reg.h>
127 #include <arm/gemini/gemini_obiovar.h>
128 #include <arm/gemini/gemini_timervar.h>
129
130 #if STATHZ != HZ
131 # error system clock HZ and stat clock STATHZ must be same
132 #endif
133
134
135 #ifndef GEMINI_TIMER_CLOCK_FREQ
136 # error Specify the timer frequency in Hz with the GEMINI_TIMER_CLOCK_FREQ option.
137 #endif
138
139 static int obiotimer_match(device_t, struct cfdata *, void *);
140 static void obiotimer_attach(device_t, device_t, void *);
141
142 struct geminitmr_softc xsc;
143
144
145
146 typedef struct {
147 uint timerno;
148 bus_addr_t addr;
149 uint intr;
150 } obiotimer_instance_t;
151
152 /* XXX
153 * this table can be used to match the GP Timers
154 * until we use config(8) locators to distinguish between
155 * gemini "sub-timers".
156 */
157 #define GPT_ENTRY(n, i) { \
158 .timerno = (n), \
159 .addr = GEMINI_TIMER_BASE, \
160 .intr = i, \
161 }
162 static const obiotimer_instance_t obiotimer_instance_tab[] = {
163 GPT_ENTRY(1, 14),
164 GPT_ENTRY(2, 15),
165 GPT_ENTRY(3, 16),
166 };
167 #undef GPT_ENTRY
168 #define GPTIMER_INSTANCE_CNT __arraycount(obiotimer_instance_tab)
169
170 static const obiotimer_instance_t *
171 obiotimer_lookup(struct obio_attach_args *);
172 static void obiotimer_enable(struct geminitmr_softc *,
173 struct obio_attach_args *,
174 const obiotimer_instance_t *);
175
176 static int obiotimer_match(device_t, struct cfdata *, void *);
177 static void obiotimer_attach(device_t, device_t, void *);
178
179
180 CFATTACH_DECL_NEW(obiotimer, sizeof(struct geminitmr_softc),
181 obiotimer_match, obiotimer_attach, NULL, NULL);
182
183
184 static int
185 obiotimer_match(device_t parent, struct cfdata *match, void *aux)
186 {
187 struct obio_attach_args *obio = aux;
188
189 if ((obio->obio_addr == OBIOCF_ADDR_DEFAULT)
190 || (obio->obio_intr == OBIOCF_INTR_DEFAULT))
191 panic("geminitmr must have addr and intr specified in config.");
192
193 if (obiotimer_lookup(obio) == NULL)
194 return 0;
195
196 return 1;
197 }
198
199 void
200 obiotimer_attach(device_t parent, device_t self, void *aux)
201 {
202 struct geminitmr_softc *sc = device_private(self);
203 struct obio_attach_args *obio = aux;
204 const obiotimer_instance_t *ip;
205 static int once=1;
206
207 ip = obiotimer_lookup(obio);
208 if (ip == NULL)
209 panic("%s: bad lookup", device_xname(self));
210 /* should not fail since we already matched */
211
212 sc->sc_timerno = ip->timerno;
213 sc->sc_iot = obio->obio_iot;
214 sc->sc_intr = obio->obio_intr;
215 sc->sc_addr = obio->obio_addr;
216 sc->sc_size = (obio->obio_size == OBIOCF_SIZE_DEFAULT)
217 ? (GEMINI_TIMER_INTRMASK + 4)
218 : obio->obio_size;
219
220 if (bus_space_map(sc->sc_iot, sc->sc_addr, sc->sc_size, 0, &sc->sc_ioh))
221 panic("%s: Cannot map registers", device_xname(self));
222
223 obiotimer_enable(sc, obio, obiotimer_lookup(obio));
224 aprint_normal("\n");
225 aprint_naive("\n");
226
227 if (once) {
228 once = 0;
229 bus_space_write_4(sc->sc_iot, sc->sc_ioh,
230 GEMINI_TIMER_TMCR, 0);
231 bus_space_write_4(sc->sc_iot, sc->sc_ioh,
232 GEMINI_TIMER_INTRMASK, (uint32_t)~TIMER_INTRMASK_Resv);
233 bus_space_write_4(sc->sc_iot, sc->sc_ioh,
234 GEMINI_TIMER_INTRSTATE, 0);
235 }
236
237 switch (sc->sc_timerno) {
238 case 1:
239 #ifndef GEMINI_SLAVE
240 /*
241 * timer #1 is the combined system clock and stat clock
242 * for the Master (or only) Gemini CPU
243 * it gets started later
244 */
245 profhz = stathz = hz;
246 stat_sc = clock_sc = sc;
247 #endif
248 break;
249 case 2:
250 #ifdef GEMINI_SLAVE
251 /*
252 * timer #2 is the combined system clock and stat clock
253 * for the Slave Gemini CPU
254 * it gets started later
255 */
256 profhz = stathz = hz;
257 stat_sc = clock_sc = sc;
258 #endif
259 break;
260 case 3:
261 /*
262 * Timer #3 is used for microtime reference clock and for delay()
263 * autoloading, non-interrupting, just wraps around as an unsigned int.
264 * we start it now to make delay() available
265 */
266 ref_sc = sc;
267 gemini_microtime_init();
268 break;
269 default:
270 panic("bad gemini timer number %d\n", sc->sc_timerno);
271 break;
272 }
273 }
274
275 static const obiotimer_instance_t *
276 obiotimer_lookup(struct obio_attach_args *obio)
277 {
278 const obiotimer_instance_t *ip;
279 uint i;
280
281 for (i = 0, ip = obiotimer_instance_tab;
282 i < GPTIMER_INSTANCE_CNT; i++, ip++) {
283 if (ip->addr == obio->obio_addr && ip->intr == obio->obio_intr)
284 return ip;
285 }
286
287 return NULL;
288 }
289
290 void
291 obiotimer_enable(
292 struct geminitmr_softc *sc,
293 struct obio_attach_args *obio,
294 const obiotimer_instance_t *ip)
295 {
296 /* nothing to do */
297 }
298