root/dev/pci/agp_via.c

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

DEFINITIONS

This source file includes following definitions.
  1. agp_via_attach
  2. agp_via_detach
  3. agp_via_get_aperture
  4. agp_via_set_aperture
  5. agp_via_bind_page
  6. agp_via_unbind_page
  7. agp_via_flush_tlb

    1 /*      $OpenBSD: agp_via.c,v 1.3 2007/08/04 19:40:25 reyk Exp $        */
    2 /*      $NetBSD: agp_via.c,v 1.2 2001/09/15 00:25:00 thorpej Exp $      */
    3 
    4 /*-
    5  * Copyright (c) 2000 Doug Rabson
    6  * All rights reserved.
    7  *
    8  * Redistribution and use in source and binary forms, with or without
    9  * modification, are permitted provided that the following conditions
   10  * are met:
   11  * 1. Redistributions of source code must retain the above copyright
   12  *    notice, this list of conditions and the following disclaimer.
   13  * 2. Redistributions in binary form must reproduce the above copyright
   14  *    notice, this list of conditions and the following disclaimer in the
   15  *    documentation and/or other materials provided with the distribution.
   16  *
   17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   27  * SUCH DAMAGE.
   28  *
   29  *      $FreeBSD: src/sys/pci/agp_via.c,v 1.3 2001/07/05 21:28:47 jhb Exp $
   30  */
   31 
   32 
   33 #include <sys/param.h>
   34 #include <sys/systm.h>
   35 #include <sys/malloc.h>
   36 #include <sys/kernel.h>
   37 #include <sys/lock.h>
   38 #include <sys/proc.h>
   39 #include <sys/conf.h>
   40 #include <sys/device.h>
   41 #include <sys/agpio.h>
   42 
   43 #include <dev/pci/pcivar.h>
   44 #include <dev/pci/pcireg.h>
   45 #include <dev/pci/vga_pcivar.h>
   46 #include <dev/pci/agpvar.h>
   47 #include <dev/pci/agpreg.h>
   48 
   49 #include <machine/bus.h>
   50 
   51 static u_int32_t agp_via_get_aperture(struct vga_pci_softc *);
   52 static int agp_via_set_aperture(struct vga_pci_softc *, u_int32_t);
   53 static int agp_via_bind_page(struct vga_pci_softc *, off_t, bus_addr_t);
   54 static int agp_via_unbind_page(struct vga_pci_softc *, off_t);
   55 static void agp_via_flush_tlb(struct vga_pci_softc *);
   56 
   57 struct agp_methods agp_via_methods = {
   58         agp_via_get_aperture,
   59         agp_via_set_aperture,
   60         agp_via_bind_page,
   61         agp_via_unbind_page,
   62         agp_via_flush_tlb,
   63         agp_generic_enable,
   64         agp_generic_alloc_memory,
   65         agp_generic_free_memory,
   66         agp_generic_bind_memory,
   67         agp_generic_unbind_memory,
   68 };
   69 
   70 struct agp_via_softc {
   71         u_int32_t       initial_aperture; /* aperture size at startup */
   72         struct agp_gatt *gatt;
   73 };
   74 
   75 
   76 int
   77 agp_via_attach(struct vga_pci_softc *sc, struct pci_attach_args *pa,
   78                struct pci_attach_args *pchb_pa)
   79 {
   80         struct agp_via_softc *asc;
   81         struct agp_gatt *gatt;
   82 
   83         asc = malloc(sizeof *asc, M_DEVBUF, M_NOWAIT);
   84         if (asc == NULL) {
   85                 printf(": can't allocate chipset-specific softc\n");
   86                 return (ENOMEM);
   87         }
   88         memset(asc, 0, sizeof *asc);
   89         sc->sc_chipc = asc;
   90         sc->sc_methods = &agp_via_methods;
   91 
   92         if (agp_map_aperture(sc, AGP_APBASE, PCI_MAPREG_TYPE_MEM) != 0) {
   93                 printf(": can't map aperture\n");
   94                 free(asc, M_DEVBUF);
   95                 return (ENXIO);
   96         }
   97 
   98         asc->initial_aperture = AGP_GET_APERTURE(sc);
   99 
  100         for (;;) {
  101                 gatt = agp_alloc_gatt(sc);
  102                 if (gatt)
  103                         break;
  104 
  105                 /*
  106                  * Probably contigmalloc failure. Try reducing the
  107                  * aperture so that the gatt size reduces.
  108                  */
  109                 if (AGP_SET_APERTURE(sc, AGP_GET_APERTURE(sc) / 2)) {
  110                         agp_generic_detach(sc);
  111                         printf(": can't set aperture size\n");
  112                         return (ENOMEM);
  113                 }
  114         }
  115         asc->gatt = gatt;
  116 
  117         /* Install the gatt. */
  118         pci_conf_write(sc->sc_pc, sc->sc_pcitag, AGP_VIA_ATTBASE,
  119             gatt->ag_physical | 3);
  120         
  121         /* Enable the aperture. */
  122         pci_conf_write(sc->sc_pc, sc->sc_pcitag, AGP_VIA_GARTCTRL, 0x0000000f);
  123 
  124         return (0);
  125 }
  126 
  127 #if 0
  128 static int
  129 agp_via_detach(struct vga_pci_softc *sc)
  130 {
  131         struct agp_via_softc *asc = sc->sc_chipc;
  132         int error;
  133 
  134         error = agp_generic_detach(sc);
  135         if (error)
  136                 return (error);
  137 
  138         pci_conf_write(sc->sc_pc, sc->sc_pcitag, AGP_VIA_GARTCTRL, 0);
  139         pci_conf_write(sc->sc_pc, sc->sc_pcitag, AGP_VIA_ATTBASE, 0);
  140         AGP_SET_APERTURE(sc, asc->initial_aperture);
  141         agp_free_gatt(sc, asc->gatt);
  142 
  143         return (0);
  144 }
  145 #endif
  146 
  147 static u_int32_t
  148 agp_via_get_aperture(struct vga_pci_softc *sc)
  149 {
  150         u_int32_t apsize;
  151 
  152         apsize = pci_conf_read(sc->sc_pc, sc->sc_pcitag,
  153             AGP_VIA_APSIZE) & 0x1f;
  154 
  155         /*
  156          * The size is determined by the number of low bits of
  157          * register APBASE which are forced to zero. The low 20 bits
  158          * are always forced to zero and each zero bit in the apsize
  159          * field just read forces the corresponding bit in the 27:20
  160          * to be zero. We calculate the aperture size accordingly.
  161          */
  162         return ((((apsize ^ 0xff) << 20) | ((1 << 20) - 1)) + 1);
  163 }
  164 
  165 static int
  166 agp_via_set_aperture(struct vga_pci_softc *sc, u_int32_t aperture)
  167 {
  168         u_int32_t apsize;
  169         pcireg_t reg;
  170 
  171         /*
  172          * Reverse the magic from get_aperture.
  173          */
  174         apsize = ((aperture - 1) >> 20) ^ 0xff;
  175 
  176         /*
  177          * Double check for sanity.
  178          */
  179         if ((((apsize ^ 0xff) << 20) | ((1 << 20) - 1)) + 1 != aperture)
  180                 return (EINVAL);
  181 
  182         reg = pci_conf_read(sc->sc_pc, sc->sc_pcitag, AGP_VIA_APSIZE);
  183         reg &= ~0xff;
  184         reg |= apsize;
  185         pci_conf_write(sc->sc_pc, sc->sc_pcitag, AGP_VIA_APSIZE, reg);
  186 
  187         return (0);
  188 }
  189 
  190 static int
  191 agp_via_bind_page(struct vga_pci_softc *sc, off_t offset, bus_addr_t physical)
  192 {
  193         struct agp_via_softc *asc = sc->sc_chipc;
  194 
  195         if (offset < 0 || offset >= (asc->gatt->ag_entries << AGP_PAGE_SHIFT))
  196                 return (EINVAL);
  197 
  198         asc->gatt->ag_virtual[offset >> AGP_PAGE_SHIFT] = physical;
  199         return (0);
  200 }
  201 
  202 static int
  203 agp_via_unbind_page(struct vga_pci_softc *sc, off_t offset)
  204 {
  205         struct agp_via_softc *asc = sc->sc_chipc;
  206 
  207         if (offset < 0 || offset >= (asc->gatt->ag_entries << AGP_PAGE_SHIFT))
  208                 return (EINVAL);
  209 
  210         asc->gatt->ag_virtual[offset >> AGP_PAGE_SHIFT] = 0;
  211         return (0);
  212 }
  213 
  214 static void
  215 agp_via_flush_tlb(struct vga_pci_softc *sc)
  216 {
  217         pci_conf_write(sc->sc_pc, sc->sc_pcitag, AGP_VIA_GARTCTRL, 0x8f);
  218         pci_conf_write(sc->sc_pc, sc->sc_pcitag, AGP_VIA_GARTCTRL, 0x0f);
  219 }

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