root/dev/pci/agp_ali.c

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

DEFINITIONS

This source file includes following definitions.
  1. agp_ali_attach
  2. agp_ali_detach
  3. agp_ali_get_aperture
  4. agp_ali_set_aperture
  5. agp_ali_bind_page
  6. agp_ali_unbind_page
  7. agp_ali_flush_tlb

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

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