root/dev/ic/am79c930.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. io_write_1
  2. io_write_2
  3. io_write_4
  4. io_write_bytes
  5. io_read_1
  6. io_read_2
  7. io_read_4
  8. io_read_bytes
  9. mem_write_1
  10. mem_write_2
  11. mem_write_4
  12. mem_write_bytes
  13. mem_read_1
  14. mem_read_2
  15. mem_read_4
  16. mem_read_bytes
  17. am79c930_gcr_setbits
  18. am79c930_gcr_clearbits
  19. am79c930_gcr_read
  20. am79c930_regdump
  21. am79c930_chip_init

    1 /* $OpenBSD: am79c930.c,v 1.4 2002/03/14 01:26:54 millert Exp $ */
    2 /* $NetBSD: am79c930.c,v 1.5 2000/03/23 13:57:58 onoe Exp $ */
    3 
    4 /*-
    5  * Copyright (c) 1999 The NetBSD Foundation, Inc.
    6  * All rights reserved.
    7  *
    8  * This code is derived from software contributed to The NetBSD Foundation
    9  * by Bill Sommerfeld
   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 /*
   41  * Am79c930 chip driver.
   42  *
   43  * This is used by the awi driver to use the shared
   44  * memory attached to the 79c930 to communicate with the firmware running
   45  * in the 930's on-board 80188 core.
   46  *
   47  * The 79c930 can be mapped into just I/O space, or also have a
   48  * memory mapping; the mapping must be set up by the bus front-end
   49  * before am79c930_init is called.
   50  */
   51 
   52 /*
   53  * operations:
   54  *
   55  * read_8, read_16, read_32, read_64, read_bytes
   56  * write_8, write_16, write_32, write_64, write_bytes
   57  * (two versions, depending on whether memory-space or i/o space is in use).
   58  *
   59  * interrupt E.C.
   60  * start isr
   61  * end isr
   62  */
   63 
   64 #include <sys/param.h>
   65 #include <sys/systm.h>
   66 #ifndef __FreeBSD__
   67 #include <sys/device.h>
   68 #endif
   69 
   70 #include <machine/cpu.h>
   71 #ifdef __FreeBSD__
   72 #include <machine/bus_pio.h>
   73 #include <machine/bus_memio.h>
   74 #endif
   75 #include <machine/bus.h>
   76 #ifdef __NetBSD__
   77 #include <machine/intr.h>
   78 #endif
   79 
   80 #if defined(__NetBSD__) || defined(__OpenBSD__)
   81 #include <dev/ic/am79c930reg.h>
   82 #include <dev/ic/am79c930var.h>
   83 #endif
   84 #ifdef __FreeBSD__
   85 #include <dev/awi/am79c930reg.h>
   86 #include <dev/awi/am79c930var.h>
   87 #endif
   88 
   89 #define AM930_DELAY(x) /*nothing*/
   90 
   91 void am79c930_regdump(struct am79c930_softc *sc);
   92 
   93 static void io_write_1(struct am79c930_softc *, u_int32_t, u_int8_t);
   94 static void io_write_2(struct am79c930_softc *, u_int32_t, u_int16_t);
   95 static void io_write_4(struct am79c930_softc *, u_int32_t, u_int32_t);
   96 static void io_write_bytes(struct am79c930_softc *, u_int32_t, u_int8_t *, size_t);
   97 
   98 static u_int8_t io_read_1(struct am79c930_softc *, u_int32_t);
   99 static u_int16_t io_read_2(struct am79c930_softc *, u_int32_t);
  100 static u_int32_t io_read_4(struct am79c930_softc *, u_int32_t);
  101 static void io_read_bytes(struct am79c930_softc *, u_int32_t, u_int8_t *, size_t);
  102 
  103 static void mem_write_1(struct am79c930_softc *, u_int32_t, u_int8_t);
  104 static void mem_write_2(struct am79c930_softc *, u_int32_t, u_int16_t);
  105 static void mem_write_4(struct am79c930_softc *, u_int32_t, u_int32_t);
  106 static void mem_write_bytes(struct am79c930_softc *, u_int32_t, u_int8_t *, size_t);
  107 
  108 static u_int8_t mem_read_1(struct am79c930_softc *, u_int32_t);
  109 static u_int16_t mem_read_2(struct am79c930_softc *, u_int32_t);
  110 static u_int32_t mem_read_4(struct am79c930_softc *, u_int32_t);
  111 static void mem_read_bytes(struct am79c930_softc *, u_int32_t, u_int8_t *, size_t);
  112 
  113 static struct am79c930_ops iospace_ops = {
  114         io_write_1,
  115         io_write_2,
  116         io_write_4,
  117         io_write_bytes,
  118         io_read_1,
  119         io_read_2,
  120         io_read_4,
  121         io_read_bytes
  122 };
  123 
  124 struct am79c930_ops memspace_ops = {
  125         mem_write_1,
  126         mem_write_2,
  127         mem_write_4,
  128         mem_write_bytes,
  129         mem_read_1,
  130         mem_read_2,
  131         mem_read_4,
  132         mem_read_bytes
  133 };
  134 
  135 static void io_write_1 (sc, off, val)
  136         struct am79c930_softc *sc;
  137         u_int32_t off;
  138         u_int8_t val;
  139 {
  140         AM930_DELAY(1);
  141         bus_space_write_1(sc->sc_iot, sc->sc_ioh, AM79C930_LMA_HI,
  142             ((off>>8)& 0x7f));
  143         AM930_DELAY(1);
  144         bus_space_write_1(sc->sc_iot, sc->sc_ioh, AM79C930_LMA_LO, (off&0xff));
  145         AM930_DELAY(1);
  146         bus_space_write_1(sc->sc_iot, sc->sc_ioh, AM79C930_IODPA, val);
  147         AM930_DELAY(1);
  148 }
  149 
  150 static void io_write_2 (sc, off, val)
  151         struct am79c930_softc *sc;
  152         u_int32_t off;
  153         u_int16_t val;
  154 {
  155         AM930_DELAY(1);
  156         bus_space_write_1(sc->sc_iot, sc->sc_ioh, AM79C930_LMA_HI,
  157             ((off>>8)& 0x7f));
  158         AM930_DELAY(1);
  159         bus_space_write_1(sc->sc_iot,sc->sc_ioh,AM79C930_LMA_LO, (off&0xff));
  160         AM930_DELAY(1);
  161         bus_space_write_1(sc->sc_iot,sc->sc_ioh,AM79C930_IODPA, val & 0xff);
  162         AM930_DELAY(1);
  163         bus_space_write_1(sc->sc_iot,sc->sc_ioh,AM79C930_IODPA, (val>>8)&0xff);
  164         AM930_DELAY(1);
  165 }
  166 
  167 static void io_write_4 (sc, off, val)
  168         struct am79c930_softc *sc;
  169         u_int32_t off;
  170         u_int32_t val;
  171 {
  172         AM930_DELAY(1);
  173         bus_space_write_1(sc->sc_iot, sc->sc_ioh, AM79C930_LMA_HI,
  174             ((off>>8)& 0x7f));
  175         AM930_DELAY(1);
  176         bus_space_write_1(sc->sc_iot,sc->sc_ioh,AM79C930_LMA_LO, (off&0xff));
  177         AM930_DELAY(1);
  178         bus_space_write_1(sc->sc_iot,sc->sc_ioh,AM79C930_IODPA,val & 0xff);
  179         AM930_DELAY(1);
  180         bus_space_write_1(sc->sc_iot,sc->sc_ioh,AM79C930_IODPA,(val>>8)&0xff);
  181         AM930_DELAY(1);
  182         bus_space_write_1(sc->sc_iot,sc->sc_ioh,AM79C930_IODPA,(val>>16)&0xff);
  183         AM930_DELAY(1);
  184         bus_space_write_1(sc->sc_iot,sc->sc_ioh,AM79C930_IODPA,(val>>24)&0xff);
  185         AM930_DELAY(1);
  186 }
  187 
  188 static void io_write_bytes (sc, off, ptr, len)
  189         struct am79c930_softc *sc;
  190         u_int32_t off;
  191         u_int8_t *ptr;
  192         size_t len;
  193 {
  194         int i;
  195 
  196         AM930_DELAY(1);
  197         bus_space_write_1(sc->sc_iot, sc->sc_ioh, AM79C930_LMA_HI,
  198             ((off>>8)& 0x7f));
  199         AM930_DELAY(1);
  200         bus_space_write_1(sc->sc_iot,sc->sc_ioh,AM79C930_LMA_LO, (off&0xff));
  201         AM930_DELAY(1);
  202         for (i=0; i<len; i++)
  203                 bus_space_write_1(sc->sc_iot,sc->sc_ioh,AM79C930_IODPA,ptr[i]);
  204 }
  205 
  206 static u_int8_t io_read_1 (sc, off)
  207         struct am79c930_softc *sc;
  208         u_int32_t off;
  209 {
  210         u_int8_t val;
  211         
  212         bus_space_write_1(sc->sc_iot, sc->sc_ioh, AM79C930_LMA_HI,
  213             ((off>>8)& 0x7f));
  214         AM930_DELAY(1);
  215         bus_space_write_1(sc->sc_iot, sc->sc_ioh, AM79C930_LMA_LO, (off&0xff));
  216         AM930_DELAY(1);
  217         val = bus_space_read_1(sc->sc_iot, sc->sc_ioh, AM79C930_IODPA);
  218         AM930_DELAY(1);
  219         return val;
  220 }
  221 
  222 static u_int16_t io_read_2 (sc, off)
  223         struct am79c930_softc *sc;
  224         u_int32_t off;
  225 {
  226         u_int16_t val;
  227 
  228         bus_space_write_1(sc->sc_iot, sc->sc_ioh, AM79C930_LMA_HI,
  229             ((off>>8)& 0x7f));
  230         AM930_DELAY(1);
  231         bus_space_write_1(sc->sc_iot, sc->sc_ioh, AM79C930_LMA_LO, (off&0xff));
  232         AM930_DELAY(1);
  233         val = bus_space_read_1(sc->sc_iot, sc->sc_ioh, AM79C930_IODPA);
  234         AM930_DELAY(1);
  235         val |= bus_space_read_1(sc->sc_iot, sc->sc_ioh, AM79C930_IODPA) << 8;
  236         AM930_DELAY(1); 
  237         return val;
  238 }
  239 
  240 static u_int32_t io_read_4 (sc, off)
  241         struct am79c930_softc *sc;
  242         u_int32_t off;
  243 {
  244         u_int32_t val;
  245 
  246         bus_space_write_1(sc->sc_iot, sc->sc_ioh, AM79C930_LMA_HI,
  247             ((off>>8)& 0x7f));
  248         AM930_DELAY(1);
  249         bus_space_write_1(sc->sc_iot, sc->sc_ioh, AM79C930_LMA_LO, (off&0xff));
  250         AM930_DELAY(1);
  251         val = bus_space_read_1(sc->sc_iot, sc->sc_ioh, AM79C930_IODPA);
  252         AM930_DELAY(1);
  253         val |= bus_space_read_1(sc->sc_iot, sc->sc_ioh, AM79C930_IODPA) << 8;
  254         AM930_DELAY(1); 
  255         val |= bus_space_read_1(sc->sc_iot, sc->sc_ioh, AM79C930_IODPA) << 16;
  256         AM930_DELAY(1); 
  257         val |= bus_space_read_1(sc->sc_iot, sc->sc_ioh, AM79C930_IODPA) << 24;
  258         AM930_DELAY(1); 
  259         return val;
  260 }
  261 
  262 static void io_read_bytes (sc, off, ptr, len)
  263         struct am79c930_softc *sc;
  264         u_int32_t off;
  265         u_int8_t *ptr;
  266         size_t len;
  267 {
  268         int i;
  269         
  270         bus_space_write_1(sc->sc_iot, sc->sc_ioh, AM79C930_LMA_HI,
  271             ((off>>8)& 0x7f));
  272         AM930_DELAY(1);
  273         bus_space_write_1(sc->sc_iot, sc->sc_ioh, AM79C930_LMA_LO, (off&0xff));
  274         AM930_DELAY(1);
  275         for (i=0; i<len; i++) 
  276                 ptr[i] = bus_space_read_1(sc->sc_iot, sc->sc_ioh,
  277                     AM79C930_IODPA);
  278 }
  279 
  280 static void mem_write_1 (sc, off, val)
  281         struct am79c930_softc *sc;
  282         u_int32_t off;
  283         u_int8_t val;
  284 {
  285         bus_space_write_1(sc->sc_memt, sc->sc_memh, off, val);
  286 }
  287 
  288 static void mem_write_2 (sc, off, val)
  289         struct am79c930_softc *sc;
  290         u_int32_t off;
  291         u_int16_t val;
  292 {
  293         bus_space_tag_t t = sc->sc_memt;
  294         bus_space_handle_t h = sc->sc_memh;
  295 
  296         /* could be unaligned */
  297         if ((off & 0x1) == 0)
  298                 bus_space_write_2(t, h, off,    val);
  299         else {
  300                 bus_space_write_1(t, h, off,    val        & 0xff);
  301                 bus_space_write_1(t, h, off+1, (val >>  8) & 0xff);
  302         }
  303 }
  304 
  305 static void mem_write_4 (sc, off, val)
  306         struct am79c930_softc *sc;
  307         u_int32_t off;
  308         u_int32_t val;
  309 {
  310         bus_space_tag_t t = sc->sc_memt;
  311         bus_space_handle_t h = sc->sc_memh;
  312 
  313         /* could be unaligned */
  314         if ((off & 0x3) == 0)
  315                 bus_space_write_4(t, h, off,    val);
  316         else {
  317                 bus_space_write_1(t, h, off,    val        & 0xff);
  318                 bus_space_write_1(t, h, off+1, (val >>  8) & 0xff);
  319                 bus_space_write_1(t, h, off+2, (val >> 16) & 0xff);
  320                 bus_space_write_1(t, h, off+3, (val >> 24) & 0xff);
  321         }
  322 }
  323 
  324 static void mem_write_bytes (sc, off, ptr, len)
  325         struct am79c930_softc *sc;
  326         u_int32_t off;
  327         u_int8_t *ptr;
  328         size_t len;
  329 {
  330         bus_space_write_region_1 (sc->sc_memt, sc->sc_memh, off, ptr, len);
  331 }
  332 
  333 
  334 static u_int8_t mem_read_1 (sc, off)
  335         struct am79c930_softc *sc;
  336         u_int32_t off;
  337 {
  338         return bus_space_read_1(sc->sc_memt, sc->sc_memh, off);
  339 }
  340 
  341 static u_int16_t mem_read_2 (sc, off)
  342         struct am79c930_softc *sc;
  343         u_int32_t off;
  344 {
  345         /* could be unaligned */
  346         if ((off & 0x1) == 0)
  347                 return bus_space_read_2(sc->sc_memt, sc->sc_memh, off);
  348         else
  349                 return
  350                      bus_space_read_1(sc->sc_memt, sc->sc_memh, off  )       |
  351                     (bus_space_read_1(sc->sc_memt, sc->sc_memh, off+1) << 8);
  352 }
  353 
  354 static u_int32_t mem_read_4 (sc, off)
  355         struct am79c930_softc *sc;
  356         u_int32_t off;
  357 {
  358         /* could be unaligned */
  359         if ((off & 0x3) == 0)
  360                 return bus_space_read_4(sc->sc_memt, sc->sc_memh, off);
  361         else
  362                 return
  363                      bus_space_read_1(sc->sc_memt, sc->sc_memh, off  )       |
  364                     (bus_space_read_1(sc->sc_memt, sc->sc_memh, off+1) << 8) |
  365                     (bus_space_read_1(sc->sc_memt, sc->sc_memh, off+2) <<16) |
  366                     (bus_space_read_1(sc->sc_memt, sc->sc_memh, off+3) <<24);
  367 }
  368 
  369 
  370 
  371 static void mem_read_bytes (sc, off, ptr, len)
  372         struct am79c930_softc *sc;
  373         u_int32_t off;
  374         u_int8_t *ptr;
  375         size_t len;
  376 {
  377         bus_space_read_region_1 (sc->sc_memt, sc->sc_memh, off, ptr, len);
  378 }
  379 
  380 
  381 
  382 
  383 /*
  384  * Set bits in GCR.
  385  */
  386 
  387 void am79c930_gcr_setbits (sc, bits)
  388         struct am79c930_softc *sc;
  389         u_int8_t bits;
  390 {
  391         u_int8_t gcr = bus_space_read_1 (sc->sc_iot, sc->sc_ioh, AM79C930_GCR);
  392 
  393         gcr |= bits;
  394         
  395         bus_space_write_1(sc->sc_iot, sc->sc_ioh, AM79C930_GCR, gcr);
  396 }
  397 
  398 /*
  399  * Clear bits in GCR.
  400  */
  401 
  402 void am79c930_gcr_clearbits (sc, bits)
  403         struct am79c930_softc *sc;
  404         u_int8_t bits;
  405 {
  406         u_int8_t gcr = bus_space_read_1 (sc->sc_iot, sc->sc_ioh, AM79C930_GCR);
  407 
  408         gcr &= ~bits;
  409         
  410         bus_space_write_1(sc->sc_iot, sc->sc_ioh, AM79C930_GCR, gcr);
  411 }
  412 
  413 u_int8_t am79c930_gcr_read (sc)
  414         struct am79c930_softc *sc;
  415 {
  416         return bus_space_read_1 (sc->sc_iot, sc->sc_ioh, AM79C930_GCR);
  417 }
  418 
  419 #if 0 
  420 void am79c930_regdump (sc) 
  421         struct am79c930_softc *sc;
  422 {
  423         u_int8_t buf[8];
  424         int i;
  425 
  426         AM930_DELAY(5);
  427         for (i=0; i<8; i++) {
  428                 buf[i] = bus_space_read_1 (sc->sc_iot, sc->sc_ioh, i);
  429                 AM930_DELAY(5);
  430         }
  431         printf("am79c930: regdump:");
  432         for (i=0; i<8; i++) {
  433                 printf(" %02x", buf[i]);
  434         }
  435         printf("\n");
  436 }
  437 #endif
  438 
  439 void am79c930_chip_init (sc, how)
  440         struct am79c930_softc *sc;
  441 {
  442         /* zero the bank select register, and leave it that way.. */
  443         bus_space_write_1(sc->sc_iot, sc->sc_ioh, AM79C930_BSS, 0);
  444         if (how)
  445                 sc->sc_ops = &memspace_ops;
  446         else
  447                 sc->sc_ops = &iospace_ops;
  448 }
  449 
  450 

/* [<][>][^][v][top][bottom][index][help] */