The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ 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  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    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: releng/9.0/sys/arm/sa11x0/sa11x0_ost.c 178429 2008-04-22 19:38:30Z phk $");
   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 }

Cache object: c5580a703e99ed2ecfdd479c2b462d92


[ 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.