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/xscale/ixp425/cambria_exp_space.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 /*-
    2  * Copyright (c) 2009 Sam Leffler.  All rights reserved.
    3  *
    4  * Redistribution and use in source and binary forms, with or without
    5  * modification, are permitted provided that the following conditions
    6  * are met:
    7  * 1. Redistributions of source code must retain the above copyright
    8  *    notice, this list of conditions and the following disclaimer.
    9  * 2. Redistributions in binary form must reproduce the above copyright
   10  *    notice, this list of conditions and the following disclaimer in the
   11  *    documentation and/or other materials provided with the distribution.
   12  *
   13  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   14  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   15  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   16  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   17  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   18  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   19  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   20  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   21  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   22  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   23  */
   24 
   25 /*
   26  * Bus space tag for devices on the Cambria expansion bus.
   27  * This interlocks accesses to allow the optional GPS+RS485 UART's
   28  * to share access with the CF-IDE adapter.  Note this does not
   29  * slow the timing UART r/w ops because the lock operation does
   30  * this implicitly for us.  Also note we do not DELAY after byte/word
   31  * chip select changes; this doesn't seem necessary (as required
   32  * for IXP425/Avila boards).
   33  *
   34  * XXX should make this generic so all expansion bus devices can
   35  * use it but probably not until we eliminate the ATA hacks
   36  */
   37 
   38 #include <sys/cdefs.h>
   39 __FBSDID("$FreeBSD: releng/8.3/sys/arm/xscale/ixp425/cambria_exp_space.c 194753 2009-06-23 19:29:23Z sam $");
   40 
   41 #include <sys/param.h>
   42 #include <sys/systm.h>
   43 #include <sys/lock.h>
   44 #include <sys/mutex.h>
   45 #include <sys/bus.h>
   46 #include <sys/endian.h>
   47 
   48 #include <machine/bus.h>
   49 #include <machine/cpu.h>
   50 
   51 #include <arm/xscale/ixp425/ixp425reg.h>
   52 #include <arm/xscale/ixp425/ixp425var.h>
   53 
   54 /* Prototypes for all the bus_space structure functions */
   55 bs_protos(exp);
   56 bs_protos(generic);
   57 
   58 struct expbus_softc {
   59         struct ixp425_softc *sc;        /* bus space tag */
   60         struct mtx      lock;           /* i/o interlock */
   61         bus_size_t      csoff;          /* CS offset for 8/16 enable */
   62 };
   63 #define EXP_LOCK_INIT(exp) \
   64         mtx_init(&(exp)->lock, "ExpBus", NULL, MTX_SPIN)
   65 #define EXP_LOCK_DESTROY(exp) \
   66         mtx_destroy(&(exp)->lock)
   67 #define EXP_LOCK(exp)   mtx_lock_spin(&(exp)->lock)
   68 #define EXP_UNLOCK(exp) mtx_unlock_spin(&(exp)->lock)
   69 
   70 /*
   71  * Enable/disable 16-bit ops on the expansion bus.
   72  */
   73 static __inline void
   74 enable_16(struct ixp425_softc *sc, bus_size_t cs)
   75 {
   76         EXP_BUS_WRITE_4(sc, cs, EXP_BUS_READ_4(sc, cs) &~ EXP_BYTE_EN);
   77 }
   78 
   79 static __inline void
   80 disable_16(struct ixp425_softc *sc, bus_size_t cs)
   81 {
   82         EXP_BUS_WRITE_4(sc, cs, EXP_BUS_READ_4(sc, cs) | EXP_BYTE_EN);
   83 }
   84 
   85 static uint8_t
   86 cambria_bs_r_1(void *t, bus_space_handle_t h, bus_size_t o)
   87 {
   88         struct expbus_softc *exp = t;
   89         struct ixp425_softc *sc = exp->sc;
   90         uint8_t v;
   91 
   92         EXP_LOCK(exp);
   93         v = bus_space_read_1(sc->sc_iot, h, o);
   94         EXP_UNLOCK(exp);
   95         return v;
   96 }
   97 
   98 static void
   99 cambria_bs_w_1(void *t, bus_space_handle_t h, bus_size_t o, u_int8_t v)
  100 {
  101         struct expbus_softc *exp = t;
  102         struct ixp425_softc *sc = exp->sc;
  103 
  104         EXP_LOCK(exp);
  105         bus_space_write_1(sc->sc_iot, h, o, v);
  106         EXP_UNLOCK(exp);
  107 }
  108 
  109 static uint16_t
  110 cambria_bs_r_2(void *t, bus_space_handle_t h, bus_size_t o)
  111 {
  112         struct expbus_softc *exp = t;
  113         struct ixp425_softc *sc = exp->sc;
  114         uint16_t v;
  115 
  116         EXP_LOCK(exp);
  117         enable_16(sc, exp->csoff);
  118         v = bus_space_read_2(sc->sc_iot, h, o);
  119         disable_16(sc, exp->csoff);
  120         EXP_UNLOCK(exp);
  121         return v;
  122 }
  123 
  124 static void
  125 cambria_bs_w_2(void *t, bus_space_handle_t h, bus_size_t o, uint16_t v)
  126 {
  127         struct expbus_softc *exp = t;
  128         struct ixp425_softc *sc = exp->sc;
  129 
  130         EXP_LOCK(exp);
  131         enable_16(sc, exp->csoff);
  132         bus_space_write_2(sc->sc_iot, h, o, v);
  133         disable_16(sc, exp->csoff);
  134         EXP_UNLOCK(exp);
  135 }
  136 
  137 static void
  138 cambria_bs_rm_2(void *t, bus_space_handle_t h, bus_size_t o,
  139         u_int16_t *d, bus_size_t c)
  140 {
  141         struct expbus_softc *exp = t;
  142         struct ixp425_softc *sc = exp->sc;
  143 
  144         EXP_LOCK(exp);
  145         enable_16(sc, exp->csoff);
  146         bus_space_read_multi_2(sc->sc_iot, h, o, d, c);
  147         disable_16(sc, exp->csoff);
  148         EXP_UNLOCK(exp);
  149 }
  150 
  151 static void
  152 cambria_bs_wm_2(void *t, bus_space_handle_t h, bus_size_t o,
  153         const u_int16_t *d, bus_size_t c)
  154 {
  155         struct expbus_softc *exp = t;
  156         struct ixp425_softc *sc = exp->sc;
  157 
  158         EXP_LOCK(exp);
  159         enable_16(sc, exp->csoff);
  160         bus_space_write_multi_2(sc->sc_iot, h, o, d, c);
  161         disable_16(sc, exp->csoff);
  162         EXP_UNLOCK(exp);
  163 }
  164 
  165 /* XXX workaround ata driver by (incorrectly) byte swapping stream cases */
  166 
  167 static void
  168 cambria_bs_rm_2_s(void *t, bus_space_handle_t h, bus_size_t o,
  169         u_int16_t *d, bus_size_t c)
  170 {
  171         struct expbus_softc *exp = t;
  172         struct ixp425_softc *sc = exp->sc;
  173         uint16_t v;
  174         bus_size_t i;
  175 
  176         EXP_LOCK(exp);
  177         enable_16(sc, exp->csoff);
  178 #if 1
  179         for (i = 0; i < c; i++) {
  180                 v = bus_space_read_2(sc->sc_iot, h, o);
  181                 d[i] = bswap16(v);
  182         }
  183 #else
  184         bus_space_read_multi_stream_2(sc->sc_iot, h, o, d, c);
  185 #endif
  186         disable_16(sc, exp->csoff);
  187         EXP_UNLOCK(exp);
  188 }
  189 
  190 static void
  191 cambria_bs_wm_2_s(void *t, bus_space_handle_t h, bus_size_t o,
  192         const u_int16_t *d, bus_size_t c)
  193 {
  194         struct expbus_softc *exp = t;
  195         struct ixp425_softc *sc = exp->sc;
  196         bus_size_t i;
  197 
  198         EXP_LOCK(exp);
  199         enable_16(sc, exp->csoff);
  200 #if 1
  201         for (i = 0; i < c; i++)
  202                 bus_space_write_2(sc->sc_iot, h, o, bswap16(d[i]));
  203 #else
  204         bus_space_write_multi_stream_2(sc->sc_iot, h, o, d, c);
  205 #endif
  206         disable_16(sc, exp->csoff);
  207         EXP_UNLOCK(exp);
  208 }
  209 
  210 /* NB: we only define what's needed by ata+uart */
  211 struct bus_space cambria_exp_bs_tag = {
  212         /* mapping/unmapping */
  213         .bs_map         = generic_bs_map,
  214         .bs_unmap       = generic_bs_unmap,
  215 
  216         /* barrier */
  217         .bs_barrier     = generic_bs_barrier,
  218 
  219         /* read (single) */
  220         .bs_r_1         = cambria_bs_r_1,
  221         .bs_r_2         = cambria_bs_r_2,
  222 
  223         /* write (single) */
  224         .bs_w_1         = cambria_bs_w_1,
  225         .bs_w_2         = cambria_bs_w_2,
  226 
  227         /* read multiple */
  228         .bs_rm_2        = cambria_bs_rm_2,
  229         .bs_rm_2_s      = cambria_bs_rm_2_s,
  230 
  231         /* write multiple */
  232         .bs_wm_2        = cambria_bs_wm_2,
  233         .bs_wm_2_s      = cambria_bs_wm_2_s,
  234 };
  235 
  236 void
  237 cambria_exp_bus_init(struct ixp425_softc *sc)
  238 {
  239         static struct expbus_softc c3;          /* NB: no need to malloc */
  240         uint32_t cs3;
  241 
  242         KASSERT(cpu_is_ixp43x(), ("wrong cpu type"));
  243 
  244         c3.sc = sc;
  245         c3.csoff = EXP_TIMING_CS3_OFFSET;
  246         EXP_LOCK_INIT(&c3);
  247         cambria_exp_bs_tag.bs_cookie = &c3;
  248 
  249         cs3 = EXP_BUS_READ_4(sc, EXP_TIMING_CS3_OFFSET);
  250         /* XXX force slowest possible timings and byte mode */
  251         EXP_BUS_WRITE_4(sc, EXP_TIMING_CS3_OFFSET,
  252             cs3 | (EXP_T1|EXP_T2|EXP_T3|EXP_T4|EXP_T5) | 
  253                 EXP_BYTE_EN | EXP_WR_EN | EXP_BYTE_RD16 | EXP_CS_EN);
  254 
  255         /* XXX force GPIO 3+4 for GPS+RS485 uarts */
  256         ixp425_set_gpio(sc, 3, GPIO_TYPE_EDG_RISING);
  257         ixp425_set_gpio(sc, 4, GPIO_TYPE_EDG_RISING);
  258 }

Cache object: c70032999f6a1646f87c586e2ba73241


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