Sync usage with man page.
[netbsd-mini2440.git] / sys / arch / arm / omap / omap2_mputmr.c
blob0bfaea78f6a4dc41a84bad8990491b6ef00b0234
1 /* $NetBSD: omap2430_mputmr.c,v 1.3 2008/07/03 06:19:18 matt Exp $ */
3 /*
4 * OMAP 2430 GP timers
5 */
7 /*
8 * Based on i80321_timer.c and arch/arm/sa11x0/sa11x0_ost.c
10 * Copyright (c) 1997 Mark Brinicombe.
11 * Copyright (c) 1997 Causality Limited.
12 * All rights reserved.
14 * This code is derived from software contributed to The NetBSD Foundation
15 * by IWAMOTO Toshihiro and Ichiro FUKUHARA.
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions
19 * are met:
20 * 1. Redistributions of source code must retain the above copyright
21 * notice, this list of conditions and the following disclaimer.
22 * 2. Redistributions in binary form must reproduce the above copyright
23 * notice, this list of conditions and the following disclaimer in the
24 * documentation and/or other materials provided with the distribution.
25 * 3. All advertising materials mentioning features or use of this software
26 * must display the following acknowledgement:
27 * This product includes software developed by the NetBSD
28 * Foundation, Inc. and its contributors.
29 * 4. Neither the name of The NetBSD Foundation nor the names of its
30 * contributors may be used to endorse or promote products derived
31 * from this software without specific prior written permission.
33 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
34 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
35 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
36 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
37 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
38 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
39 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
40 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
41 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
42 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
43 * POSSIBILITY OF SUCH DAMAGE.
45 * Copyright (c) 2001, 2002 Wasabi Systems, Inc.
46 * All rights reserved.
48 * Written by Jason R. Thorpe for Wasabi Systems, Inc.
50 * Redistribution and use in source and binary forms, with or without
51 * modification, are permitted provided that the following conditions
52 * are met:
53 * 1. Redistributions of source code must retain the above copyright
54 * notice, this list of conditions and the following disclaimer.
55 * 2. Redistributions in binary form must reproduce the above copyright
56 * notice, this list of conditions and the following disclaimer in the
57 * documentation and/or other materials provided with the distribution.
58 * 3. All advertising materials mentioning features or use of this software
59 * must display the following acknowledgement:
60 * This product includes software developed for the NetBSD Project by
61 * Wasabi Systems, Inc.
62 * 4. The name of Wasabi Systems, Inc. may not be used to endorse
63 * or promote products derived from this software without specific prior
64 * written permission.
66 * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
67 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
68 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
69 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
70 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
71 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
72 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
73 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
74 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
75 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
76 * POSSIBILITY OF SUCH DAMAGE.
79 #include <sys/cdefs.h>
80 __KERNEL_RCSID(0, "$NetBSD: omap2430_mputmr.c,v 1.3 2008/07/03 06:19:18 matt Exp $");
82 #include "opt_omap.h"
83 #include "opt_cpuoptions.h"
85 #include <sys/types.h>
86 #include <sys/param.h>
87 #include <sys/systm.h>
88 #include <sys/kernel.h>
89 #include <sys/time.h>
90 #include <sys/timetc.h>
91 #include <sys/device.h>
93 #include <dev/clock_subr.h>
95 #include <machine/bus.h>
96 #include <machine/intr.h>
98 #include <arm/omap/omap_gptmrreg.h>
99 #include <arm/omap/omap2_mputmrvar.h>
101 #ifndef ARM11_PMC
102 uint32_t counts_per_usec, counts_per_hz;
103 #endif
104 struct mputmr_softc *clock_sc;
105 struct mputmr_softc *stat_sc;
106 struct mputmr_softc *ref_sc;
107 static uint32_t mpu_get_timecount(struct timecounter *);
109 static struct timecounter mpu_timecounter = {
110 .tc_get_timecount = mpu_get_timecount,
111 .tc_counter_mask = 0xffffffff,
112 .tc_frequency = OMAP_MPU_TIMER_CLOCK_FREQ,
113 .tc_name = "gpt",
114 .tc_quality = 100,
115 .tc_priv = NULL
118 static inline void
119 _timer_intr_dis(struct mputmr_softc *sc)
121 bus_space_write_4(sc->sc_iot, sc->sc_ioh, TIER, 0);
124 static inline void
125 _timer_intr_enb(struct mputmr_softc *sc)
127 bus_space_write_4(sc->sc_iot, sc->sc_ioh, TIER, TIER_OVF_IT_ENA);
130 static inline uint32_t
131 _timer_intr_sts(struct mputmr_softc *sc)
133 return bus_space_read_4(sc->sc_iot, sc->sc_ioh, TISR);
136 static inline void
137 _timer_intr_ack(struct mputmr_softc *sc)
139 bus_space_write_4(sc->sc_iot, sc->sc_ioh, TISR, TIER_OVF_IT_ENA);
142 static inline uint32_t
143 _timer_read(struct mputmr_softc *sc)
145 return bus_space_read_4(sc->sc_iot, sc->sc_ioh, TCRR);
148 static inline void
149 _timer_stop(struct mputmr_softc *sc)
151 uint32_t r;
153 r = bus_space_read_4(sc->sc_iot, sc->sc_ioh, TCLR);
154 r &= ~TCLR_ST;
155 bus_space_write_4(sc->sc_iot, sc->sc_ioh, TCLR, r);
158 static inline void
159 _timer_reload(struct mputmr_softc *sc, uint32_t val)
161 bus_space_write_4(sc->sc_iot, sc->sc_ioh, TLDR, val);
162 bus_space_write_4(sc->sc_iot, sc->sc_ioh, TCRR, val);
165 static inline void
166 _timer_start(struct mputmr_softc *sc, timer_factors *tfp)
168 uint32_t r=0;
170 if (tfp->ptv != 0) {
171 r |= TCLR_PRE(1);
172 r |= (TCLR_PTV(tfp->ptv - 1) & TCLR_PTV_MASK);
174 r |= (TCLR_CE | TCLR_AR | TCLR_ST);
176 bus_space_write_4(sc->sc_iot, sc->sc_ioh, TCLR, r);
179 static uint32_t
180 mpu_get_timecount(struct timecounter *tc)
182 return _timer_read(ref_sc);
186 clockintr(void *frame)
188 _timer_intr_ack(clock_sc);
189 hardclock(frame);
190 return 1;
194 statintr(void *frame)
196 _timer_intr_ack(stat_sc);
197 statclock(frame);
198 return 1;
201 static void
202 setclockrate(struct mputmr_softc *sc, int schz)
204 timer_factors tf;
206 _timer_stop(sc);
207 calc_timer_factors(schz, &tf);
208 _timer_reload(sc, tf.reload);
209 _timer_start(sc, &tf);
212 void
213 setstatclockrate(int schz)
215 setclockrate(stat_sc, schz);
218 void
219 cpu_initclocks(void)
221 if (clock_sc == NULL)
222 panic("Clock timer was not configured.");
223 if (stat_sc == NULL)
224 panic("Statistics timer was not configured.");
225 if (ref_sc == NULL)
226 panic("Microtime reference timer was not configured.");
229 * We already have the timers running, but not generating interrupts.
230 * In addition, we've set stathz and profhz.
232 printf("clock: hz=%d stathz=%d\n", hz, stathz);
234 _timer_intr_dis(clock_sc);
235 _timer_intr_dis(stat_sc);
236 _timer_intr_dis(ref_sc);
238 setclockrate(clock_sc, hz);
239 setclockrate(stat_sc, stathz);
240 setclockrate(ref_sc, 0);
244 * The "cookie" parameter must be zero to pass the interrupt frame
245 * through to hardclock() and statclock().
248 intr_establish(clock_sc->sc_intr, IPL_CLOCK, IST_LEVEL, clockintr, 0);
249 intr_establish(stat_sc->sc_intr, IPL_HIGH, IST_LEVEL, statintr, 0);
251 _timer_intr_enb(clock_sc);
252 _timer_intr_enb(stat_sc);
254 tc_init(&mpu_timecounter);
257 #ifndef ARM11_PMC
258 void
259 delay(u_int n)
261 uint32_t cur, last, delta, usecs;
263 if (clock_sc == NULL)
264 panic("The timer must be initialized sooner.");
267 * This works by polling the timer and counting the
268 * number of microseconds that go by.
270 last = _timer_read(clock_sc);
272 delta = usecs = 0;
274 while (n > usecs) {
275 cur = _timer_read(clock_sc);
277 /* Check to see if the timer has wrapped around. */
278 if (last < cur)
279 delta += (last + (counts_per_hz - cur));
280 else
281 delta += (last - cur);
283 last = cur;
285 if (delta >= counts_per_usec) {
286 usecs += delta / counts_per_usec;
287 delta %= counts_per_usec;
291 #endif /* ARM11_PMC */
294 * OVF_Rate =
295 * (0xFFFFFFFF - GPTn.TLDR + 1) * (timer functional clock period) * PS
297 void
298 calc_timer_factors(int ints_per_sec, timer_factors *tf)
300 uint32_t ptv_power; /* PS */
301 uint32_t count_freq;
302 const uint32_t us_per_sec = 1000000;
304 if (ints_per_sec == 0) {
306 * When ints_per_sec equal to zero there is mean full range
307 * timer usage. Nevertheless autoreload mode is still enabled.
309 tf->ptv = 0;
310 tf->reload = 0;
311 tf->counts_per_usec = OMAP_MPU_TIMER_CLOCK_FREQ / us_per_sec;
312 return;
316 tf->ptv = 8;
317 for (;;) {
318 ptv_power = 1 << tf->ptv;
319 count_freq = OMAP_MPU_TIMER_CLOCK_FREQ;
320 count_freq /= hz;
321 count_freq /= ptv_power;
322 tf->reload = -count_freq;
323 tf->counts_per_usec = count_freq / us_per_sec;
324 if ((tf->reload * ptv_power * ints_per_sec
325 == OMAP_MPU_TIMER_CLOCK_FREQ)
326 && (tf->counts_per_usec * ptv_power * us_per_sec
327 == OMAP_MPU_TIMER_CLOCK_FREQ))
328 { /* Exact match. Life is good. */
329 /* Currently reload is MPU_LOAD_TIMER+1. Fix it. */
330 tf->reload--;
331 return;
333 if (tf->ptv == 0) {
334 tf->counts_per_usec++;
335 return;
337 tf->ptv--;