xref: /netbsd/sys/arch/arm/gemini/obio_timer.c (revision 6550d01e)
1 /*	$NetBSD: obio_timer.c,v 1.4 2008/12/04 00:38:07 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.4 2008/12/04 00:38:07 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 option GEMINI_TIMER_CLOCK_FREQ
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 #ifndef GEMINI_SLAVE
206 	static int once=1;
207 #endif
208 
209 	ip = obiotimer_lookup(obio);
210 	if (ip == NULL)
211 		panic("%s: bad lookup", device_xname(self));
212 			/* should not fail since we already matched */
213 
214 	sc->sc_timerno = ip->timerno;
215 	sc->sc_iot = obio->obio_iot;
216 	sc->sc_intr = obio->obio_intr;
217 	sc->sc_addr = obio->obio_addr;
218 	sc->sc_size = (obio->obio_size == OBIOCF_SIZE_DEFAULT)
219 		? (GEMINI_TIMER_INTRMASK + 4)
220 		: obio->obio_size;
221 
222 	if (bus_space_map(sc->sc_iot, sc->sc_addr, sc->sc_size, 0, &sc->sc_ioh))
223 		panic("%s: Cannot map registers", device_xname(self));
224 
225 	obiotimer_enable(sc, obio, obiotimer_lookup(obio));
226 	aprint_normal("\n");
227 	aprint_naive("\n");
228 
229 #ifndef GEMINI_SLAVE
230 	if (once) {
231 		once = 0;
232 		bus_space_write_4(sc->sc_iot, sc->sc_ioh,
233 			GEMINI_TIMER_TMCR, 0);
234 		bus_space_write_4(sc->sc_iot, sc->sc_ioh,
235 			GEMINI_TIMER_INTRMASK, (uint32_t)~TIMER_INTRMASK_Resv);
236 		bus_space_write_4(sc->sc_iot, sc->sc_ioh,
237 			GEMINI_TIMER_INTRSTATE, 0);
238 	}
239 #endif
240 
241 	switch (sc->sc_timerno) {
242 	case 1:
243 #ifndef GEMINI_SLAVE
244 		/*
245 		 * timer #1 is the combined system clock and stat clock
246 		 * for the Master or Single Gemini CPU
247 		 * it gets started later
248 		 */
249 		profhz = stathz = hz;
250 		stat_sc = clock_sc = sc;
251 #endif
252 		break;
253 	case 2:
254 #ifdef GEMINI_SLAVE
255 		/*
256 		 * timer #2 is the combined system clock and stat clock
257 		 * for the Slave Gemini CPU
258 		 * it gets started later
259 		 */
260 		profhz = stathz = hz;
261 		stat_sc = clock_sc = sc;
262 #endif
263 		break;
264 	case 3:
265 		/*
266 		 * Timer #3 is used for microtime reference clock and delay()
267 		 * autoloading, non-interrupting, just wraps around
268 		 * we start it now to make delay() available
269 		 */
270 		ref_sc = sc;
271 #ifndef GEMINI_SLAVE
272 		gemini_microtime_init();
273 #endif
274 		break;
275 	default:
276 		panic("bad gemini timer number %d\n", sc->sc_timerno);
277 		break;
278 	}
279 }
280 
281 static const obiotimer_instance_t *
282 obiotimer_lookup(struct obio_attach_args *obio)
283 {
284 	const obiotimer_instance_t *ip;
285 	uint i;
286 
287 	for (i = 0, ip = obiotimer_instance_tab;
288 	     i < GPTIMER_INSTANCE_CNT; i++, ip++) {
289 		if (ip->addr == obio->obio_addr && ip->intr == obio->obio_intr)
290 			return ip;
291 	}
292 
293 	return NULL;
294 }
295 
296 void
297 obiotimer_enable(
298 	struct geminitmr_softc *sc,
299 	struct obio_attach_args *obio,
300 	const obiotimer_instance_t *ip)
301 {
302 	/* nothing to do */
303 }
304