root/dev/pci/agp_sis.c

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

DEFINITIONS

This source file includes following definitions.
  1. agp_sis_attach
  2. agp_sis_detach
  3. agp_sis_get_aperture
  4. agp_sis_set_aperture
  5. agp_sis_bind_page
  6. agp_sis_unbind_page
  7. agp_sis_flush_tlb

    1 /*      $OpenBSD: agp_sis.c,v 1.3 2007/08/04 19:40:25 reyk Exp $        */
    2 /*      $NetBSD: agp_sis.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_sis.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 struct agp_sis_softc {
   52         u_int32_t       initial_aperture; /* aperture size at startup */
   53         struct agp_gatt *gatt;
   54 };
   55 
   56 static u_int32_t agp_sis_get_aperture(struct vga_pci_softc *);
   57 static int agp_sis_set_aperture(struct vga_pci_softc *, u_int32_t);
   58 static int agp_sis_bind_page(struct vga_pci_softc *, off_t, bus_addr_t);
   59 static int agp_sis_unbind_page(struct vga_pci_softc *, off_t);
   60 static void agp_sis_flush_tlb(struct vga_pci_softc *);
   61 
   62 struct agp_methods agp_sis_methods = {
   63         agp_sis_get_aperture,
   64         agp_sis_set_aperture,
   65         agp_sis_bind_page,
   66         agp_sis_unbind_page,
   67         agp_sis_flush_tlb,
   68         agp_generic_enable,
   69         agp_generic_alloc_memory,
   70         agp_generic_free_memory,
   71         agp_generic_bind_memory,
   72         agp_generic_unbind_memory,
   73 };
   74 
   75 
   76 int
   77 agp_sis_attach(struct vga_pci_softc *sc, struct pci_attach_args *pa,
   78                struct pci_attach_args *pchb_pa)
   79 {
   80         struct agp_sis_softc *ssc;
   81         struct agp_gatt *gatt;
   82         pcireg_t reg;
   83 
   84         ssc = malloc(sizeof *ssc, M_DEVBUF, M_NOWAIT);
   85         if (ssc == NULL) {
   86                 printf(": can't allocate chipset-specific softc\n");
   87                 return (ENOMEM);
   88         }
   89         sc->sc_methods = &agp_sis_methods;
   90         sc->sc_chipc = ssc;
   91 
   92         if (agp_map_aperture(sc, AGP_APBASE, PCI_MAPREG_TYPE_MEM) != 0) {
   93                 printf(": can't map aperture\n");
   94                 free(ssc, M_DEVBUF);
   95                 return (ENXIO);
   96         }
   97 
   98         ssc->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(": failed to set aperture\n");
  112                         return (ENOMEM);
  113                 }
  114         }
  115         ssc->gatt = gatt;
  116 
  117         /* Install the gatt. */
  118         pci_conf_write(sc->sc_pc, sc->sc_pcitag, AGP_SIS_ATTBASE,
  119             gatt->ag_physical);
  120         
  121         /* Enable the aperture and auto-tlb-inval */
  122         reg = pci_conf_read(sc->sc_pc, sc->sc_pcitag, AGP_SIS_WINCTRL);
  123         reg |= (0x05 << 24) | 3;
  124         pci_conf_write(sc->sc_pc, sc->sc_pcitag, AGP_SIS_WINCTRL, reg);
  125 
  126         return (0);
  127 }
  128 
  129 #if 0
  130 static int
  131 agp_sis_detach(struct vga_pci_softc *sc)
  132 {
  133         struct agp_sis_softc *ssc = sc->sc_chipc;
  134         pcireg_t reg;
  135         int error;
  136 
  137         error = agp_generic_detach(sc);
  138         if (error)
  139                 return (error);
  140 
  141         reg = pci_conf_read(sc->sc_pc, sc->sc_pcitag, AGP_SIS_WINCTRL);
  142         reg &= ~3;
  143         reg &= 0x00ffffff;
  144         pci_conf_write(sc->sc_pc, sc->sc_pcitag, AGP_SIS_WINCTRL, reg);
  145 
  146         /* Put the aperture back the way it started. */
  147         AGP_SET_APERTURE(sc, ssc->initial_aperture);
  148 
  149         agp_free_gatt(sc, ssc->gatt);
  150         return (0);
  151 }
  152 #endif
  153 
  154 static u_int32_t
  155 agp_sis_get_aperture(struct vga_pci_softc *sc)
  156 {
  157         int gws;
  158 
  159         /*
  160          * The aperture size is equal to 4M<<gws.
  161          */
  162         gws = (pci_conf_read(sc->sc_pc, sc->sc_pcitag,
  163             AGP_SIS_WINCTRL)&0x70) >> 4;
  164         return ((4 * 1024 * 1024) << gws);
  165 }
  166 
  167 static int
  168 agp_sis_set_aperture(struct vga_pci_softc *sc, u_int32_t aperture)
  169 {
  170         int gws;
  171         pcireg_t reg;
  172 
  173         /*
  174          * Check for a power of two and make sure its within the
  175          * programmable range.
  176          */
  177         if (aperture & (aperture - 1)
  178             || aperture < 4*1024*1024
  179             || aperture > 256*1024*1024)
  180                 return (EINVAL);
  181 
  182         gws = ffs(aperture / 4*1024*1024) - 1;
  183 
  184         reg = pci_conf_read(sc->sc_pc, sc->sc_pcitag, AGP_SIS_WINCTRL); 
  185         reg &= ~0x00000070;
  186         reg |= gws << 4;
  187         pci_conf_write(sc->sc_pc, sc->sc_pcitag, AGP_SIS_WINCTRL, reg);
  188 
  189         return (0);
  190 }
  191 
  192 static int
  193 agp_sis_bind_page(struct vga_pci_softc *sc, off_t offset, bus_addr_t physical)
  194 {
  195         struct agp_sis_softc *ssc = sc->sc_chipc;
  196 
  197         if (offset < 0 || offset >= (ssc->gatt->ag_entries << AGP_PAGE_SHIFT))
  198                 return (EINVAL);
  199 
  200         ssc->gatt->ag_virtual[offset >> AGP_PAGE_SHIFT] = physical;
  201         return (0);
  202 }
  203 
  204 static int
  205 agp_sis_unbind_page(struct vga_pci_softc *sc, off_t offset)
  206 {
  207         struct agp_sis_softc *ssc = sc->sc_chipc;
  208 
  209         if (offset < 0 || offset >= (ssc->gatt->ag_entries << AGP_PAGE_SHIFT))
  210                 return (EINVAL);
  211 
  212         ssc->gatt->ag_virtual[offset >> AGP_PAGE_SHIFT] = 0;
  213         return (0);
  214 }
  215 
  216 static void
  217 agp_sis_flush_tlb(struct vga_pci_softc *sc)
  218 {
  219         pcireg_t reg;
  220 
  221         reg = pci_conf_read(sc->sc_pc, sc->sc_pcitag, AGP_SIS_TLBFLUSH);
  222         reg &= 0xffffff00;
  223         reg |= 0x02;
  224         pci_conf_write(sc->sc_pc, sc->sc_pcitag, AGP_SIS_TLBFLUSH, reg);
  225 }

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