[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/arm/sa11x0/sa11x0_ost.c

Version: -  FREEBSD  -  FREEBSD7  -  FREEBSD71  -  FREEBSD70  -  FREEBSD6  -  FREEBSD64  -  FREEBSD63  -  FREEBSD62  -  FREEBSD61  -  FREEBSD60  -  FREEBSD5  -  FREEBSD55  -  FREEBSD54  -  FREEBSD53  -  FREEBSD52  -  FREEBSD51  -  FREEBSD50  -  FREEBSD4  -  FREEBSD3  -  FREEBSD22  -  linux-2.6  -  linux-2.4.22  -  MK83  -  MK84  -  PLAN9  -  DFBSD  -  NETBSD  -  NETBSD5  -  NETBSD4  -  NETBSD3  -  NETBSD20  -  OPENBSD  -  xnu-517  -  xnu-792  -  xnu-792.6.70  -  xnu-1228  -  OPENSOLARIS  -  minix-3-1-1  -  TRUSTEDBSD-SEBSD  -  FREEBSD-LIBC  -  FREEBSD7-LIBC  -  FREEBSD6-LIBC  -  GLIBC27 
SearchContext: -  none  -  excerpts  -  bigexcerpts 

  1 /*      $NetBSD: sa11x0_ost.c,v 1.11 2003/07/15 00:24:51 lukem Exp $    */
  2 
  3 /*-
  4  * Copyright (c) 1997 Mark Brinicombe.
  5  * Copyright (c) 1997 Causality Limited.
  6  * All rights reserved.
  7  *
  8  * This code is derived from software contributed to The NetBSD Foundation
  9  * by IWAMOTO Toshihiro and Ichiro FUKUHARA.
 10  *
 11  * Redistribution and use in source and binary forms, with or without
 12  * modification, are permitted provided that the following conditions
 13  * are met:
 14  * 1. Redistributions of source code must retain the above copyright
 15  *    notice, this list of conditions and the following disclaimer.
 16  * 2. Redistributions in binary form must reproduce the above copyright
 17  *    notice, this list of conditions and the following disclaimer in the
 18  *    documentation and/or other materials provided with the distribution.
 19  * 3. All advertising materials mentioning features or use of this software
 20  *    must display the following acknowledgement:
 21  *      This product includes software developed by the NetBSD
 22  *      Foundation, Inc. and its contributors.
 23  * 4. Neither the name of The NetBSD Foundation nor the names of its
 24  *    contributors may be used to endorse or promote products derived
 25  *    from this software without specific prior written permission.
 26  *
 27  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
 28  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 29  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 30  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
 31  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 32  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 33  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 34  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 35  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 36  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 37  * POSSIBILITY OF SUCH DAMAGE.
 38  */
 39 
 40 #include <sys/cdefs.h>
 41 __FBSDID("$FreeBSD: src/sys/arm/sa11x0/sa11x0_ost.c,v 1.8 2008/04/22 19:38:27 phk Exp $");
 42 
 43 #include <sys/param.h>
 44 #include <sys/systm.h>
 45 #include <sys/kernel.h>
 46 #include <sys/time.h>
 47 #include <sys/bus.h>
 48 #include <sys/module.h>
 49 
 50 #include <machine/bus.h>
 51 #include <sys/rman.h>
 52 #include <machine/resource.h>
 53 #include <machine/intr.h>
 54 
 55 #include <machine/cpu.h>
 56 #include <machine/cpufunc.h>
 57 #include <machine/frame.h>
 58 
 59 #include <arm/sa11x0/sa11x0_reg.h> 
 60 #include <arm/sa11x0/sa11x0_var.h>
 61 #include <arm/sa11x0/sa11x0_ostreg.h>
 62 
 63 static int      saost_probe(device_t);
 64 static int      saost_attach(device_t);
 65 
 66 int             gettick(void);
 67 static int      clockintr(void *);
 68 #if 0
 69 static int      statintr(void *);
 70 #endif
 71 void            rtcinit(void);
 72 
 73 #if 0
 74 static struct mtx clock_lock;
 75 #endif
 76 
 77 struct saost_softc {
 78         device_t                sc_dev;
 79         bus_addr_t              sc_baseaddr;
 80         bus_space_tag_t         sc_iot;
 81         bus_space_handle_t      sc_ioh;
 82 
 83         u_int32_t       sc_clock_count;
 84         u_int32_t       sc_statclock_count;
 85         u_int32_t       sc_statclock_step;
 86 };
 87 
 88 static struct saost_softc *saost_sc = NULL;
 89 
 90 #define TIMER_FREQUENCY         3686400         /* 3.6864MHz */
 91 #define TICKS_PER_MICROSECOND   (TIMER_FREQUENCY/1000000)
 92 
 93 #ifndef STATHZ
 94 #define STATHZ  64
 95 #endif
 96 
 97 static device_method_t saost_methods[] = {
 98         DEVMETHOD(device_probe, saost_probe),
 99         DEVMETHOD(device_attach, saost_attach),
100         {0, 0},
101 };
102 
103 static driver_t saost_driver = {
104         "saost",
105         saost_methods,
106         sizeof(struct saost_softc),
107 };
108 static devclass_t saost_devclass;
109 
110 DRIVER_MODULE(saost, saip, saost_driver, saost_devclass, 0, 0);
111 static int
112 saost_probe(device_t dev)
113 {
114 
115         return (0);
116 }
117 
118 static int
119 saost_attach(device_t dev)
120 {
121         struct saost_softc *sc = device_get_softc(dev);
122         struct sa11x0_softc *sa = device_get_softc(device_get_parent(dev));
123 
124         sc->sc_dev = dev;
125         sc->sc_iot = sa->sc_iot;
126         sc->sc_baseaddr = 0x90000000;
127 
128         saost_sc = sc;
129 
130         if(bus_space_map(sa->sc_iot, sc->sc_baseaddr, 8, 0, 
131                         &sc->sc_ioh))
132                 panic("%s: Cannot map registers", device_get_name(dev));
133 
134         /* disable all channel and clear interrupt status */
135         bus_space_write_4(saost_sc->sc_iot, saost_sc->sc_ioh, SAOST_IR, 0);
136         bus_space_write_4(saost_sc->sc_iot, saost_sc->sc_ioh, SAOST_SR, 0xf);
137         return (0);
138 
139 }
140 
141 static int
142 clockintr(arg)
143         void *arg;
144 {
145         struct trapframe *frame = arg;
146         u_int32_t oscr, nextmatch, oldmatch;
147         int s;
148 
149 #if 0
150         mtx_lock_spin(&clock_lock);
151 #endif
152         bus_space_write_4(saost_sc->sc_iot, saost_sc->sc_ioh,
153                         SAOST_SR, 1);
154 
155         /* schedule next clock intr */
156         oldmatch = saost_sc->sc_clock_count;
157         nextmatch = oldmatch + TIMER_FREQUENCY / hz;
158 
159         oscr = bus_space_read_4(saost_sc->sc_iot, saost_sc->sc_ioh,
160                                 SAOST_CR);
161 
162         if ((nextmatch > oldmatch &&
163              (oscr > nextmatch || oscr < oldmatch)) ||
164             (nextmatch < oldmatch && oscr > nextmatch && oscr < oldmatch)) {
165                 /*
166                  * we couldn't set the matching register in time.
167                  * just set it to some value so that next interrupt happens.
168                  * XXX is it possible to compansate lost interrupts?
169                  */
170 
171                 s = splhigh();
172                 oscr = bus_space_read_4(saost_sc->sc_iot, saost_sc->sc_ioh,
173                                         SAOST_CR);
174                 nextmatch = oscr + 10;
175                 splx(s);
176         }
177         saost_sc->sc_clock_count = nextmatch;
178         bus_space_write_4(saost_sc->sc_iot, saost_sc->sc_ioh, SAOST_MR0,
179                           nextmatch);
180         hardclock(TRAPF_USERMODE(frame), TRAPF_PC(frame));
181 #if 0
182         mtx_unlock_spin(&clock_lock);
183 #endif
184         return (FILTER_HANDLED);
185 }
186 
187 #if 0
188 static int
189 statintr(arg)
190         void *arg;
191 {
192         struct trapframe *frame = arg;
193         u_int32_t oscr, nextmatch, oldmatch;
194         int s;
195 
196         bus_space_write_4(saost_sc->sc_iot, saost_sc->sc_ioh,
197                         SAOST_SR, 2);
198 
199         /* schedule next clock intr */
200         oldmatch = saost_sc->sc_statclock_count;
201         nextmatch = oldmatch + saost_sc->sc_statclock_step;
202 
203         bus_space_write_4(saost_sc->sc_iot, saost_sc->sc_ioh, SAOST_MR1,
204                           nextmatch);
205         oscr = bus_space_read_4(saost_sc->sc_iot, saost_sc->sc_ioh,
206                                 SAOST_CR);
207 
208         if ((nextmatch > oldmatch &&
209              (oscr > nextmatch || oscr < oldmatch)) ||
210             (nextmatch < oldmatch && oscr > nextmatch && oscr < oldmatch)) {
211                 /*
212                  * we couldn't set the matching register in time.
213                  * just set it to some value so that next interrupt happens.
214                  * XXX is it possible to compansate lost interrupts?
215                  */
216 
217                 s = splhigh();
218                 oscr = bus_space_read_4(saost_sc->sc_iot, saost_sc->sc_ioh,
219                                         SAOST_CR);
220                 nextmatch = oscr + 10;
221                 bus_space_write_4(saost_sc->sc_iot, saost_sc->sc_ioh,
222                                   SAOST_MR1, nextmatch);
223                 splx(s);
224         }
225 
226         saost_sc->sc_statclock_count = nextmatch;
227         statclock(TRAPF_USERMODE(frame));
228         return (FILTER_HANDLED);
229 }
230 #endif
231 
232 #if 0
233 void
234 setstatclockrate(int hz)
235 {
236         u_int32_t count;
237 
238         saost_sc->sc_statclock_step = TIMER_FREQUENCY / hz;
239         count = bus_space_read_4(saost_sc->sc_iot, saost_sc->sc_ioh, SAOST_CR);
240         count += saost_sc->sc_statclock_step;
241         saost_sc->sc_statclock_count = count;
242         bus_space_write_4(saost_sc->sc_iot, saost_sc->sc_ioh,
243                         SAOST_MR1, count);
244 }
245 #endif
246 void
247 cpu_initclocks()
248 {
249         device_t dev = saost_sc->sc_dev;
250 
251         stathz = STATHZ;
252         profhz = stathz;
253 #if 0
254         mtx_init(&clock_lock, "SA1110 Clock locké", NULL, MTX_SPIN);
255 #endif
256         saost_sc->sc_statclock_step = TIMER_FREQUENCY / stathz;
257         struct resource *irq1, *irq2;
258         int rid = 0;
259         void *ih1/*, *ih2 */;
260         
261         printf("clock: hz=%d stathz = %d\n", hz, stathz);
262 
263         /* Use the channels 0 and 1 for hardclock and statclock, respectively */
264         saost_sc->sc_clock_count = TIMER_FREQUENCY / hz;
265         saost_sc->sc_statclock_count = TIMER_FREQUENCY / stathz;
266 
267         irq1 = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0,
268             ~0, 1, RF_ACTIVE);
269         rid = 1;
270         irq2 = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1,
271             RF_ACTIVE);
272         bus_setup_intr(dev, irq1, INTR_TYPE_CLK, clockintr, NULL, NULL,
273             &ih1);
274 #if 0
275         bus_setup_intr(dev, irq2, INTR_TYPE_CLK, statintr, NULL, NULL,
276             ,&ih2);
277 #endif
278         bus_space_write_4(saost_sc->sc_iot, saost_sc->sc_ioh, SAOST_SR, 0xf);
279         bus_space_write_4(saost_sc->sc_iot, saost_sc->sc_ioh, SAOST_IR, 3);
280         bus_space_write_4(saost_sc->sc_iot, saost_sc->sc_ioh, SAOST_MR0,
281                           saost_sc->sc_clock_count);
282 #if 0
283         bus_space_write_4(saost_sc->sc_iot, saost_sc->sc_ioh, SAOST_MR1,
284                           0);
285 #endif
286         /* Zero the counter value */
287         bus_space_write_4(saost_sc->sc_iot, saost_sc->sc_ioh, SAOST_CR, 0);
288 }
289 
290 int
291 gettick()
292 {
293         int counter;
294         u_int savedints;
295         savedints = disable_interrupts(I32_bit);
296 
297         counter = bus_space_read_4(saost_sc->sc_iot, saost_sc->sc_ioh,
298                         SAOST_CR);
299 
300         restore_interrupts(savedints);
301         return counter;
302 }
303 
304 void
305 DELAY(usecs)
306         int usecs;
307 {
308         u_int32_t tick, otick, delta;
309         int j, csec, usec;
310 
311         csec = usecs / 10000;
312         usec = usecs % 10000;
313         
314         usecs = (TIMER_FREQUENCY / 100) * csec
315             + (TIMER_FREQUENCY / 100) * usec / 10000;
316 
317         if (! saost_sc) {
318                 /* clock isn't initialized yet */
319                 for(; usecs > 0; usecs--)
320                         for(j = 100; j > 0; j--)
321                                 ;
322                 return;
323         }
324 
325 #if 0
326         mtx_lock_spin(&clock_lock);
327 #endif
328         otick = gettick();
329 
330         while (1) {
331                 for(j = 100; j > 0; j--)
332                         ;
333                 tick = gettick();
334                 delta = tick - otick;
335                 if (delta > usecs) {
336                         break;
337                 }
338                 usecs -= delta;
339                 otick = tick;
340         }
341 #if 0
342         mtx_unlock_spin(&clock_lock);
343 #endif
344 }
345 
346 void
347 cpu_startprofclock(void)
348 {
349         printf("STARTPROFCLOCK\n");
350 }
351 
352 void
353 cpu_stopprofclock(void)
354 {
355 }
356 

Cache object: a7f0bf9b76a8b794d884715b602ebdf3


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.