159747216SDoug Rabson /*- 259747216SDoug Rabson * Copyright (c) 2000 Doug Rabson 359747216SDoug Rabson * All rights reserved. 459747216SDoug Rabson * 559747216SDoug Rabson * Redistribution and use in source and binary forms, with or without 659747216SDoug Rabson * modification, are permitted provided that the following conditions 759747216SDoug Rabson * are met: 859747216SDoug Rabson * 1. Redistributions of source code must retain the above copyright 959747216SDoug Rabson * notice, this list of conditions and the following disclaimer. 1059747216SDoug Rabson * 2. Redistributions in binary form must reproduce the above copyright 1159747216SDoug Rabson * notice, this list of conditions and the following disclaimer in the 1259747216SDoug Rabson * documentation and/or other materials provided with the distribution. 1359747216SDoug Rabson * 1459747216SDoug Rabson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1559747216SDoug Rabson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1659747216SDoug Rabson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1759747216SDoug Rabson * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1859747216SDoug Rabson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1959747216SDoug Rabson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2059747216SDoug Rabson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2159747216SDoug Rabson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2259747216SDoug Rabson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2359747216SDoug Rabson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2459747216SDoug Rabson * SUCH DAMAGE. 2559747216SDoug Rabson */ 2659747216SDoug Rabson 27f4636c59SDavid E. O'Brien #include <sys/cdefs.h> 28f4636c59SDavid E. O'Brien __FBSDID("$FreeBSD$"); 29f4636c59SDavid E. O'Brien 3059747216SDoug Rabson #include "opt_bus.h" 3159747216SDoug Rabson 3259747216SDoug Rabson #include <sys/param.h> 3359747216SDoug Rabson #include <sys/systm.h> 3459747216SDoug Rabson #include <sys/malloc.h> 3559747216SDoug Rabson #include <sys/kernel.h> 36f11d01c3SPoul-Henning Kamp #include <sys/module.h> 3759747216SDoug Rabson #include <sys/bus.h> 3859747216SDoug Rabson #include <sys/lock.h> 3923955314SAlfred Perlstein #include <sys/mutex.h> 4052b3919dSJohn Baldwin #include <sys/proc.h> 4159747216SDoug Rabson 4219b7ffd1SWarner Losh #include <dev/pci/pcivar.h> 4319b7ffd1SWarner Losh #include <dev/pci/pcireg.h> 4459747216SDoug Rabson #include <pci/agppriv.h> 4559747216SDoug Rabson #include <pci/agpreg.h> 4659747216SDoug Rabson 4759747216SDoug Rabson #include <vm/vm.h> 4859747216SDoug Rabson #include <vm/vm_object.h> 4959747216SDoug Rabson #include <vm/pmap.h> 5059747216SDoug Rabson #include <machine/bus.h> 5159747216SDoug Rabson #include <machine/resource.h> 5259747216SDoug Rabson #include <sys/rman.h> 5359747216SDoug Rabson 54111618cbSDoug Rabson MALLOC_DECLARE(M_AGP); 55111618cbSDoug Rabson 5659747216SDoug Rabson #define READ2(off) bus_space_read_2(sc->bst, sc->bsh, off) 5759747216SDoug Rabson #define READ4(off) bus_space_read_4(sc->bst, sc->bsh, off) 5859747216SDoug Rabson #define WRITE2(off,v) bus_space_write_2(sc->bst, sc->bsh, off, v) 5959747216SDoug Rabson #define WRITE4(off,v) bus_space_write_4(sc->bst, sc->bsh, off, v) 6059747216SDoug Rabson 61111618cbSDoug Rabson struct agp_amd_gatt { 62111618cbSDoug Rabson u_int32_t ag_entries; 63a2892093SColeman Kane u_int32_t *ag_virtual; /* virtual address of gatt */ 64a2892093SColeman Kane vm_offset_t ag_physical; 65111618cbSDoug Rabson u_int32_t *ag_vdir; /* virtual address of page dir */ 66111618cbSDoug Rabson vm_offset_t ag_pdir; /* physical address of page dir */ 67111618cbSDoug Rabson }; 68111618cbSDoug Rabson 6959747216SDoug Rabson struct agp_amd_softc { 7059747216SDoug Rabson struct agp_softc agp; 7159747216SDoug Rabson struct resource *regs; /* memory mapped control registers */ 7259747216SDoug Rabson bus_space_tag_t bst; /* bus_space tag */ 7359747216SDoug Rabson bus_space_handle_t bsh; /* bus_space handle */ 7459747216SDoug Rabson u_int32_t initial_aperture; /* aperture size at startup */ 75111618cbSDoug Rabson struct agp_amd_gatt *gatt; 7659747216SDoug Rabson }; 7759747216SDoug Rabson 78111618cbSDoug Rabson static struct agp_amd_gatt * 79111618cbSDoug Rabson agp_amd_alloc_gatt(device_t dev) 80111618cbSDoug Rabson { 81111618cbSDoug Rabson u_int32_t apsize = AGP_GET_APERTURE(dev); 82111618cbSDoug Rabson u_int32_t entries = apsize >> AGP_PAGE_SHIFT; 83111618cbSDoug Rabson struct agp_amd_gatt *gatt; 84a2892093SColeman Kane int i, npages, pdir_offset; 85111618cbSDoug Rabson 86111618cbSDoug Rabson if (bootverbose) 87111618cbSDoug Rabson device_printf(dev, 88111618cbSDoug Rabson "allocating GATT for aperture of size %dM\n", 89111618cbSDoug Rabson apsize / (1024*1024)); 90111618cbSDoug Rabson 91111618cbSDoug Rabson gatt = malloc(sizeof(struct agp_amd_gatt), M_AGP, M_NOWAIT); 92111618cbSDoug Rabson if (!gatt) 93111618cbSDoug Rabson return 0; 94111618cbSDoug Rabson 95111618cbSDoug Rabson /* 96111618cbSDoug Rabson * The AMD751 uses a page directory to map a non-contiguous 97111618cbSDoug Rabson * gatt so we don't need to use contigmalloc. 98a2892093SColeman Kane * Malloc individual gatt pages and map them into the page 99a2892093SColeman Kane * directory. 100111618cbSDoug Rabson */ 101111618cbSDoug Rabson gatt->ag_entries = entries; 102111618cbSDoug Rabson gatt->ag_virtual = malloc(entries * sizeof(u_int32_t), 103111618cbSDoug Rabson M_AGP, M_NOWAIT); 104111618cbSDoug Rabson if (!gatt->ag_virtual) { 105111618cbSDoug Rabson if (bootverbose) 106111618cbSDoug Rabson device_printf(dev, "allocation failed\n"); 107111618cbSDoug Rabson free(gatt, M_AGP); 108111618cbSDoug Rabson return 0; 109111618cbSDoug Rabson } 110111618cbSDoug Rabson bzero(gatt->ag_virtual, entries * sizeof(u_int32_t)); 111111618cbSDoug Rabson 112111618cbSDoug Rabson /* 113111618cbSDoug Rabson * Allocate the page directory. 114111618cbSDoug Rabson */ 115111618cbSDoug Rabson gatt->ag_vdir = malloc(AGP_PAGE_SIZE, M_AGP, M_NOWAIT); 116111618cbSDoug Rabson if (!gatt->ag_vdir) { 117111618cbSDoug Rabson if (bootverbose) 118111618cbSDoug Rabson device_printf(dev, 119111618cbSDoug Rabson "failed to allocate page directory\n"); 120111618cbSDoug Rabson free(gatt->ag_virtual, M_AGP); 121111618cbSDoug Rabson free(gatt, M_AGP); 122111618cbSDoug Rabson return 0; 123111618cbSDoug Rabson } 1249264fbc8SColeman Kane bzero(gatt->ag_vdir, AGP_PAGE_SIZE); 1259264fbc8SColeman Kane 126111618cbSDoug Rabson gatt->ag_pdir = vtophys((vm_offset_t) gatt->ag_vdir); 127a2892093SColeman Kane if(bootverbose) 12818e0cd7dSMarcel Moolenaar device_printf(dev, "gatt -> ag_pdir %#lx\n", 12918e0cd7dSMarcel Moolenaar (u_long)gatt->ag_pdir); 130a2892093SColeman Kane /* 131a2892093SColeman Kane * Allocate the gatt pages 132a2892093SColeman Kane */ 133a2892093SColeman Kane gatt->ag_entries = entries; 134a2892093SColeman Kane if(bootverbose) 135a2892093SColeman Kane device_printf(dev, "allocating GATT for %d AGP page entries\n", 136a2892093SColeman Kane gatt->ag_entries); 1379264fbc8SColeman Kane 138a2892093SColeman Kane gatt->ag_physical = vtophys((vm_offset_t) gatt->ag_virtual); 139111618cbSDoug Rabson 140111618cbSDoug Rabson /* 141111618cbSDoug Rabson * Map the pages of the GATT into the page directory. 142a2892093SColeman Kane * 143a2892093SColeman Kane * The GATT page addresses are mapped into the directory offset by 144a2892093SColeman Kane * an amount dependent on the base address of the aperture. This 145a2892093SColeman Kane * is and offset into the page directory, not an offset added to 146a2892093SColeman Kane * the addresses of the gatt pages. 147111618cbSDoug Rabson */ 148a2892093SColeman Kane 149a2892093SColeman Kane pdir_offset = pci_read_config(dev, AGP_AMD751_APBASE, 4) >> 22; 150a2892093SColeman Kane 151111618cbSDoug Rabson npages = ((entries * sizeof(u_int32_t) + AGP_PAGE_SIZE - 1) 152111618cbSDoug Rabson >> AGP_PAGE_SHIFT); 153a2892093SColeman Kane 154111618cbSDoug Rabson for (i = 0; i < npages; i++) { 155111618cbSDoug Rabson vm_offset_t va; 156111618cbSDoug Rabson vm_offset_t pa; 157111618cbSDoug Rabson 158111618cbSDoug Rabson va = ((vm_offset_t) gatt->ag_virtual) + i * AGP_PAGE_SIZE; 159111618cbSDoug Rabson pa = vtophys(va); 160a2892093SColeman Kane gatt->ag_vdir[i + pdir_offset] = pa | 1; 161111618cbSDoug Rabson } 162111618cbSDoug Rabson 163111618cbSDoug Rabson /* 164111618cbSDoug Rabson * Make sure the chipset can see everything. 165111618cbSDoug Rabson */ 166111618cbSDoug Rabson agp_flush_cache(); 167111618cbSDoug Rabson 168111618cbSDoug Rabson return gatt; 169111618cbSDoug Rabson } 170111618cbSDoug Rabson 171111618cbSDoug Rabson static void 172111618cbSDoug Rabson agp_amd_free_gatt(struct agp_amd_gatt *gatt) 173111618cbSDoug Rabson { 174111618cbSDoug Rabson free(gatt->ag_virtual, M_AGP); 175111618cbSDoug Rabson free(gatt->ag_vdir, M_AGP); 176111618cbSDoug Rabson free(gatt, M_AGP); 177111618cbSDoug Rabson } 178111618cbSDoug Rabson 17959747216SDoug Rabson static const char* 18059747216SDoug Rabson agp_amd_match(device_t dev) 18159747216SDoug Rabson { 18259747216SDoug Rabson if (pci_get_class(dev) != PCIC_BRIDGE 18359747216SDoug Rabson || pci_get_subclass(dev) != PCIS_BRIDGE_HOST) 18459747216SDoug Rabson return NULL; 18559747216SDoug Rabson 18659747216SDoug Rabson if (agp_find_caps(dev) == 0) 18759747216SDoug Rabson return NULL; 18859747216SDoug Rabson 18959747216SDoug Rabson switch (pci_get_devid(dev)) { 190a2892093SColeman Kane 19157110f76SColeman Kane case 0x700e1022: 19257110f76SColeman Kane return ("AMD 761 host to AGP bridge"); 193a2892093SColeman Kane 19459747216SDoug Rabson case 0x70061022: 19559747216SDoug Rabson return ("AMD 751 host to AGP bridge"); 196a2892093SColeman Kane 197a2892093SColeman Kane case 0x700c1022: 198a2892093SColeman Kane return ("AMD 762 host to AGP bridge"); 199a2892093SColeman Kane 20059747216SDoug Rabson }; 20159747216SDoug Rabson 20259747216SDoug Rabson return NULL; 20359747216SDoug Rabson } 20459747216SDoug Rabson 20559747216SDoug Rabson static int 20659747216SDoug Rabson agp_amd_probe(device_t dev) 20759747216SDoug Rabson { 20859747216SDoug Rabson const char *desc; 20959747216SDoug Rabson 21025128fccSNate Lawson if (resource_disabled("agp", device_get_unit(dev))) 21125128fccSNate Lawson return (ENXIO); 21259747216SDoug Rabson desc = agp_amd_match(dev); 21359747216SDoug Rabson if (desc) { 21459747216SDoug Rabson device_verbose(dev); 21559747216SDoug Rabson device_set_desc(dev, desc); 21659747216SDoug Rabson return 0; 21759747216SDoug Rabson } 21859747216SDoug Rabson 21959747216SDoug Rabson return ENXIO; 22059747216SDoug Rabson } 22159747216SDoug Rabson 22259747216SDoug Rabson static int 22359747216SDoug Rabson agp_amd_attach(device_t dev) 22459747216SDoug Rabson { 22559747216SDoug Rabson struct agp_amd_softc *sc = device_get_softc(dev); 226111618cbSDoug Rabson struct agp_amd_gatt *gatt; 22759747216SDoug Rabson int error, rid; 22859747216SDoug Rabson 22959747216SDoug Rabson error = agp_generic_attach(dev); 23059747216SDoug Rabson if (error) 23159747216SDoug Rabson return error; 23259747216SDoug Rabson 23359747216SDoug Rabson rid = AGP_AMD751_REGISTERS; 2345f96beb9SNate Lawson sc->regs = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, 2355f96beb9SNate Lawson RF_ACTIVE); 23659747216SDoug Rabson if (!sc->regs) { 23759747216SDoug Rabson agp_generic_detach(dev); 23859747216SDoug Rabson return ENOMEM; 23959747216SDoug Rabson } 24059747216SDoug Rabson 24159747216SDoug Rabson sc->bst = rman_get_bustag(sc->regs); 24259747216SDoug Rabson sc->bsh = rman_get_bushandle(sc->regs); 24359747216SDoug Rabson 24459747216SDoug Rabson sc->initial_aperture = AGP_GET_APERTURE(dev); 24559747216SDoug Rabson 24659747216SDoug Rabson for (;;) { 247111618cbSDoug Rabson gatt = agp_amd_alloc_gatt(dev); 24859747216SDoug Rabson if (gatt) 24959747216SDoug Rabson break; 25059747216SDoug Rabson 25159747216SDoug Rabson /* 25259747216SDoug Rabson * Probably contigmalloc failure. Try reducing the 25359747216SDoug Rabson * aperture so that the gatt size reduces. 25459747216SDoug Rabson */ 25559747216SDoug Rabson if (AGP_SET_APERTURE(dev, AGP_GET_APERTURE(dev) / 2)) 25659747216SDoug Rabson return ENOMEM; 25759747216SDoug Rabson } 25859747216SDoug Rabson sc->gatt = gatt; 25959747216SDoug Rabson 26059747216SDoug Rabson /* Install the gatt. */ 261111618cbSDoug Rabson WRITE4(AGP_AMD751_ATTBASE, gatt->ag_pdir); 26259747216SDoug Rabson 26359747216SDoug Rabson /* Enable synchronisation between host and agp. */ 264111618cbSDoug Rabson pci_write_config(dev, 265111618cbSDoug Rabson AGP_AMD751_MODECTRL, 266111618cbSDoug Rabson AGP_AMD751_MODECTRL_SYNEN, 1); 267111618cbSDoug Rabson 268111618cbSDoug Rabson /* Set indexing mode for two-level and enable page dir cache */ 269111618cbSDoug Rabson pci_write_config(dev, 270111618cbSDoug Rabson AGP_AMD751_MODECTRL2, 271111618cbSDoug Rabson AGP_AMD751_MODECTRL2_GPDCE, 1); 27259747216SDoug Rabson 27359747216SDoug Rabson /* Enable the TLB and flush */ 27459747216SDoug Rabson WRITE2(AGP_AMD751_STATUS, 27559747216SDoug Rabson READ2(AGP_AMD751_STATUS) | AGP_AMD751_STATUS_GCE); 27659747216SDoug Rabson AGP_FLUSH_TLB(dev); 27759747216SDoug Rabson 278111618cbSDoug Rabson return 0; 27959747216SDoug Rabson } 28059747216SDoug Rabson 28159747216SDoug Rabson static int 28259747216SDoug Rabson agp_amd_detach(device_t dev) 28359747216SDoug Rabson { 28459747216SDoug Rabson struct agp_amd_softc *sc = device_get_softc(dev); 285068b0778SDoug Rabson int error; 286068b0778SDoug Rabson 287068b0778SDoug Rabson error = agp_generic_detach(dev); 288068b0778SDoug Rabson if (error) 289068b0778SDoug Rabson return error; 29059747216SDoug Rabson 29159747216SDoug Rabson /* Disable the TLB.. */ 29259747216SDoug Rabson WRITE2(AGP_AMD751_STATUS, 29359747216SDoug Rabson READ2(AGP_AMD751_STATUS) & ~AGP_AMD751_STATUS_GCE); 29459747216SDoug Rabson 29559747216SDoug Rabson /* Disable host-agp sync */ 29659747216SDoug Rabson pci_write_config(dev, AGP_AMD751_MODECTRL, 0x00, 1); 29759747216SDoug Rabson 29859747216SDoug Rabson /* Clear the GATT base */ 29959747216SDoug Rabson WRITE4(AGP_AMD751_ATTBASE, 0); 30059747216SDoug Rabson 30159747216SDoug Rabson /* Put the aperture back the way it started. */ 30259747216SDoug Rabson AGP_SET_APERTURE(dev, sc->initial_aperture); 30359747216SDoug Rabson 304111618cbSDoug Rabson agp_amd_free_gatt(sc->gatt); 305068b0778SDoug Rabson 306068b0778SDoug Rabson bus_release_resource(dev, SYS_RES_MEMORY, 307068b0778SDoug Rabson AGP_AMD751_REGISTERS, sc->regs); 308068b0778SDoug Rabson 30959747216SDoug Rabson return 0; 31059747216SDoug Rabson } 31159747216SDoug Rabson 31259747216SDoug Rabson static u_int32_t 31359747216SDoug Rabson agp_amd_get_aperture(device_t dev) 31459747216SDoug Rabson { 31559747216SDoug Rabson int vas; 31659747216SDoug Rabson 31759747216SDoug Rabson /* 31859747216SDoug Rabson * The aperture size is equal to 32M<<vas. 31959747216SDoug Rabson */ 32059747216SDoug Rabson vas = (pci_read_config(dev, AGP_AMD751_APCTRL, 1) & 0x06) >> 1; 32159747216SDoug Rabson return (32*1024*1024) << vas; 32259747216SDoug Rabson } 32359747216SDoug Rabson 32459747216SDoug Rabson static int 32559747216SDoug Rabson agp_amd_set_aperture(device_t dev, u_int32_t aperture) 32659747216SDoug Rabson { 32759747216SDoug Rabson int vas; 32859747216SDoug Rabson 32959747216SDoug Rabson /* 33059747216SDoug Rabson * Check for a power of two and make sure its within the 33159747216SDoug Rabson * programmable range. 33259747216SDoug Rabson */ 33359747216SDoug Rabson if (aperture & (aperture - 1) 33459747216SDoug Rabson || aperture < 32*1024*1024 33559747216SDoug Rabson || aperture > 2U*1024*1024*1024) 33659747216SDoug Rabson return EINVAL; 33759747216SDoug Rabson 33859747216SDoug Rabson vas = ffs(aperture / 32*1024*1024) - 1; 33959747216SDoug Rabson 340a2892093SColeman Kane /* 341a2892093SColeman Kane * While the size register is bits 1-3 of APCTRL, bit 0 must be 342a2892093SColeman Kane * set for the size value to be 'valid' 343a2892093SColeman Kane */ 34459747216SDoug Rabson pci_write_config(dev, AGP_AMD751_APCTRL, 345a2892093SColeman Kane (((pci_read_config(dev, AGP_AMD751_APCTRL, 1) & ~0x06) 346a2892093SColeman Kane | ((vas << 1) | 1))), 1); 34759747216SDoug Rabson 34859747216SDoug Rabson return 0; 34959747216SDoug Rabson } 35059747216SDoug Rabson 35159747216SDoug Rabson static int 35259747216SDoug Rabson agp_amd_bind_page(device_t dev, int offset, vm_offset_t physical) 35359747216SDoug Rabson { 35459747216SDoug Rabson struct agp_amd_softc *sc = device_get_softc(dev); 35559747216SDoug Rabson 35659747216SDoug Rabson if (offset < 0 || offset >= (sc->gatt->ag_entries << AGP_PAGE_SHIFT)) 35759747216SDoug Rabson return EINVAL; 35859747216SDoug Rabson 35959747216SDoug Rabson sc->gatt->ag_virtual[offset >> AGP_PAGE_SHIFT] = physical | 1; 360a2892093SColeman Kane 361a2892093SColeman Kane /* invalidate the cache */ 362a2892093SColeman Kane AGP_FLUSH_TLB(dev); 36359747216SDoug Rabson return 0; 36459747216SDoug Rabson } 36559747216SDoug Rabson 36659747216SDoug Rabson static int 36759747216SDoug Rabson agp_amd_unbind_page(device_t dev, int offset) 36859747216SDoug Rabson { 36959747216SDoug Rabson struct agp_amd_softc *sc = device_get_softc(dev); 37059747216SDoug Rabson 37159747216SDoug Rabson if (offset < 0 || offset >= (sc->gatt->ag_entries << AGP_PAGE_SHIFT)) 37259747216SDoug Rabson return EINVAL; 37359747216SDoug Rabson 37459747216SDoug Rabson sc->gatt->ag_virtual[offset >> AGP_PAGE_SHIFT] = 0; 37559747216SDoug Rabson return 0; 37659747216SDoug Rabson } 37759747216SDoug Rabson 37859747216SDoug Rabson static void 37959747216SDoug Rabson agp_amd_flush_tlb(device_t dev) 38059747216SDoug Rabson { 38159747216SDoug Rabson struct agp_amd_softc *sc = device_get_softc(dev); 38259747216SDoug Rabson 38359747216SDoug Rabson /* Set the cache invalidate bit and wait for the chipset to clear */ 38459747216SDoug Rabson WRITE4(AGP_AMD751_TLBCTRL, 1); 38559747216SDoug Rabson do { 38659747216SDoug Rabson DELAY(1); 38759747216SDoug Rabson } while (READ4(AGP_AMD751_TLBCTRL)); 38859747216SDoug Rabson } 38959747216SDoug Rabson 39059747216SDoug Rabson static device_method_t agp_amd_methods[] = { 39159747216SDoug Rabson /* Device interface */ 39259747216SDoug Rabson DEVMETHOD(device_probe, agp_amd_probe), 39359747216SDoug Rabson DEVMETHOD(device_attach, agp_amd_attach), 39459747216SDoug Rabson DEVMETHOD(device_detach, agp_amd_detach), 39559747216SDoug Rabson DEVMETHOD(device_shutdown, bus_generic_shutdown), 39659747216SDoug Rabson DEVMETHOD(device_suspend, bus_generic_suspend), 39759747216SDoug Rabson DEVMETHOD(device_resume, bus_generic_resume), 39859747216SDoug Rabson 39959747216SDoug Rabson /* AGP interface */ 40059747216SDoug Rabson DEVMETHOD(agp_get_aperture, agp_amd_get_aperture), 40159747216SDoug Rabson DEVMETHOD(agp_set_aperture, agp_amd_set_aperture), 40259747216SDoug Rabson DEVMETHOD(agp_bind_page, agp_amd_bind_page), 40359747216SDoug Rabson DEVMETHOD(agp_unbind_page, agp_amd_unbind_page), 40459747216SDoug Rabson DEVMETHOD(agp_flush_tlb, agp_amd_flush_tlb), 40559747216SDoug Rabson DEVMETHOD(agp_enable, agp_generic_enable), 40659747216SDoug Rabson DEVMETHOD(agp_alloc_memory, agp_generic_alloc_memory), 40759747216SDoug Rabson DEVMETHOD(agp_free_memory, agp_generic_free_memory), 40859747216SDoug Rabson DEVMETHOD(agp_bind_memory, agp_generic_bind_memory), 40959747216SDoug Rabson DEVMETHOD(agp_unbind_memory, agp_generic_unbind_memory), 41059747216SDoug Rabson 41159747216SDoug Rabson { 0, 0 } 41259747216SDoug Rabson }; 41359747216SDoug Rabson 41459747216SDoug Rabson static driver_t agp_amd_driver = { 41559747216SDoug Rabson "agp", 41659747216SDoug Rabson agp_amd_methods, 41759747216SDoug Rabson sizeof(struct agp_amd_softc), 41859747216SDoug Rabson }; 41959747216SDoug Rabson 42059747216SDoug Rabson static devclass_t agp_devclass; 42159747216SDoug Rabson 42259747216SDoug Rabson DRIVER_MODULE(agp_amd, pci, agp_amd_driver, agp_devclass, 0, 0); 423f246e4a1SMatthew N. Dodd MODULE_DEPEND(agp_amd, agp, 1, 1, 1); 424f246e4a1SMatthew N. Dodd MODULE_DEPEND(agp_amd, pci, 1, 1, 1); 425