agp_amd64.c revision 241856
1254885Sdumbbell/*- 2254885Sdumbbell * Copyright (c) 2004, 2005 Jung-uk Kim <jkim@FreeBSD.org> 3254885Sdumbbell * All rights reserved. 4254885Sdumbbell * 5254885Sdumbbell * Redistribution and use in source and binary forms, with or without 6254885Sdumbbell * modification, are permitted provided that the following conditions 7254885Sdumbbell * are met: 8254885Sdumbbell * 1. Redistributions of source code must retain the above copyright 9254885Sdumbbell * notice, this list of conditions and the following disclaimer. 10254885Sdumbbell * 2. Redistributions in binary form must reproduce the above copyright 11254885Sdumbbell * notice, this list of conditions and the following disclaimer in the 12254885Sdumbbell * documentation and/or other materials provided with the distribution. 13254885Sdumbbell * 14254885Sdumbbell * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15254885Sdumbbell * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16254885Sdumbbell * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17254885Sdumbbell * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18254885Sdumbbell * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19254885Sdumbbell * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20254885Sdumbbell * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21254885Sdumbbell * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22254885Sdumbbell * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23254885Sdumbbell * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24254885Sdumbbell * SUCH DAMAGE. 25254885Sdumbbell */ 26254885Sdumbbell 27254885Sdumbbell#include <sys/cdefs.h> 28254885Sdumbbell__FBSDID("$FreeBSD: head/sys/dev/agp/agp_amd64.c 241856 2012-10-22 03:41:14Z eadler $"); 29254885Sdumbbell 30254885Sdumbbell#include "opt_bus.h" 31254885Sdumbbell 32254885Sdumbbell#include <sys/param.h> 33254885Sdumbbell#include <sys/systm.h> 34254885Sdumbbell#include <sys/malloc.h> 35254885Sdumbbell#include <sys/kernel.h> 36254885Sdumbbell#include <sys/module.h> 37254885Sdumbbell#include <sys/bus.h> 38254885Sdumbbell#include <sys/lock.h> 39254885Sdumbbell#include <sys/mutex.h> 40254885Sdumbbell#include <sys/proc.h> 41254885Sdumbbell 42254885Sdumbbell#include <dev/agp/agppriv.h> 43254885Sdumbbell#include <dev/agp/agpreg.h> 44254885Sdumbbell#include <dev/pci/pcivar.h> 45254885Sdumbbell#include <dev/pci/pcireg.h> 46254885Sdumbbell 47254885Sdumbbell#include <vm/vm.h> 48254885Sdumbbell#include <vm/vm_object.h> 49254885Sdumbbell#include <vm/pmap.h> 50254885Sdumbbell#include <machine/bus.h> 51254885Sdumbbell#include <machine/resource.h> 52254885Sdumbbell#include <sys/rman.h> 53254885Sdumbbell 54254885Sdumbbell/* XXX */ 55254885Sdumbbellextern void pci_cfgregwrite(int, int, int, int, uint32_t, int); 56254885Sdumbbellextern uint32_t pci_cfgregread(int, int, int, int, int); 57254885Sdumbbell 58254885Sdumbbellstatic void agp_amd64_apbase_fixup(device_t); 59254885Sdumbbell 60254885Sdumbbellstatic void agp_amd64_uli_init(device_t); 61254885Sdumbbellstatic int agp_amd64_uli_set_aperture(device_t, uint32_t); 62254885Sdumbbell 63254885Sdumbbellstatic int agp_amd64_nvidia_match(uint16_t); 64254885Sdumbbellstatic void agp_amd64_nvidia_init(device_t); 65254885Sdumbbellstatic int agp_amd64_nvidia_set_aperture(device_t, uint32_t); 66254885Sdumbbell 67254885Sdumbbellstatic int agp_amd64_via_match(void); 68254885Sdumbbellstatic void agp_amd64_via_init(device_t); 69254885Sdumbbellstatic int agp_amd64_via_set_aperture(device_t, uint32_t); 70254885Sdumbbell 71254885SdumbbellMALLOC_DECLARE(M_AGP); 72254885Sdumbbell 73254885Sdumbbell#define AMD64_MAX_MCTRL 8 74254885Sdumbbell 75254885Sdumbbellstruct agp_amd64_softc { 76254885Sdumbbell struct agp_softc agp; 77254885Sdumbbell uint32_t initial_aperture; 78254885Sdumbbell struct agp_gatt *gatt; 79254885Sdumbbell uint32_t apbase; 80254885Sdumbbell int mctrl[AMD64_MAX_MCTRL]; 81254885Sdumbbell int n_mctrl; 82254885Sdumbbell int via_agp; 83254885Sdumbbell}; 84254885Sdumbbell 85254885Sdumbbellstatic const char* 86254885Sdumbbellagp_amd64_match(device_t dev) 87254885Sdumbbell{ 88254885Sdumbbell if (pci_get_class(dev) != PCIC_BRIDGE || 89254885Sdumbbell pci_get_subclass(dev) != PCIS_BRIDGE_HOST || 90254885Sdumbbell agp_find_caps(dev) == 0) 91254885Sdumbbell return (NULL); 92254885Sdumbbell 93254885Sdumbbell switch (pci_get_devid(dev)) { 94254885Sdumbbell case 0x74541022: 95254885Sdumbbell return ("AMD 8151 AGP graphics tunnel"); 96254885Sdumbbell case 0x07551039: 97254885Sdumbbell return ("SiS 755 host to AGP bridge"); 98254885Sdumbbell case 0x07601039: 99254885Sdumbbell return ("SiS 760 host to AGP bridge"); 100254885Sdumbbell case 0x168910b9: 101254885Sdumbbell return ("ULi M1689 AGP Controller"); 102254885Sdumbbell case 0x00d110de: 103254885Sdumbbell if (agp_amd64_nvidia_match(0x00d2)) 104254885Sdumbbell return (NULL); 105254885Sdumbbell return ("NVIDIA nForce3 AGP Controller"); 106254885Sdumbbell case 0x00e110de: 107254885Sdumbbell if (agp_amd64_nvidia_match(0x00e2)) 108254885Sdumbbell return (NULL); 109254885Sdumbbell return ("NVIDIA nForce3-250 AGP Controller"); 110254885Sdumbbell case 0x02041106: 111254885Sdumbbell return ("VIA 8380 host to PCI bridge"); 112254885Sdumbbell case 0x02381106: 113254885Sdumbbell return ("VIA 3238 host to PCI bridge"); 114254885Sdumbbell case 0x02821106: 115254885Sdumbbell return ("VIA K8T800Pro host to PCI bridge"); 116254885Sdumbbell case 0x31881106: 117254885Sdumbbell return ("VIA 8385 host to PCI bridge"); 118254885Sdumbbell }; 119254885Sdumbbell 120254885Sdumbbell return (NULL); 121254885Sdumbbell} 122254885Sdumbbell 123254885Sdumbbellstatic int 124254885Sdumbbellagp_amd64_nvidia_match(uint16_t devid) 125254885Sdumbbell{ 126254885Sdumbbell /* XXX nForce3 requires secondary AGP bridge at 0:11:0. */ 127254885Sdumbbell if (pci_cfgregread(0, 11, 0, PCIR_CLASS, 1) != PCIC_BRIDGE || 128254885Sdumbbell pci_cfgregread(0, 11, 0, PCIR_SUBCLASS, 1) != PCIS_BRIDGE_PCI || 129254885Sdumbbell pci_cfgregread(0, 11, 0, PCIR_VENDOR, 2) != 0x10de || 130254885Sdumbbell pci_cfgregread(0, 11, 0, PCIR_DEVICE, 2) != devid) 131254885Sdumbbell return (ENXIO); 132254885Sdumbbell 133254885Sdumbbell return (0); 134254885Sdumbbell} 135254885Sdumbbell 136254885Sdumbbellstatic int 137254885Sdumbbellagp_amd64_via_match(void) 138254885Sdumbbell{ 139254885Sdumbbell /* XXX Some VIA bridge requires secondary AGP bridge at 0:1:0. */ 140254885Sdumbbell if (pci_cfgregread(0, 1, 0, PCIR_CLASS, 1) != PCIC_BRIDGE || 141254885Sdumbbell pci_cfgregread(0, 1, 0, PCIR_SUBCLASS, 1) != PCIS_BRIDGE_PCI || 142254885Sdumbbell pci_cfgregread(0, 1, 0, PCIR_VENDOR, 2) != 0x1106 || 143254885Sdumbbell pci_cfgregread(0, 1, 0, PCIR_DEVICE, 2) != 0xb188 || 144254885Sdumbbell (pci_cfgregread(0, 1, 0, AGP_VIA_AGPSEL, 1) & 2)) 145254885Sdumbbell return (0); 146254885Sdumbbell 147254885Sdumbbell return (1); 148254885Sdumbbell} 149254885Sdumbbell 150254885Sdumbbellstatic int 151254885Sdumbbellagp_amd64_probe(device_t dev) 152254885Sdumbbell{ 153254885Sdumbbell const char *desc; 154254885Sdumbbell 155254885Sdumbbell if ((desc = agp_amd64_match(dev))) { 156254885Sdumbbell device_set_desc(dev, desc); 157254885Sdumbbell return (BUS_PROBE_DEFAULT); 158254885Sdumbbell } 159254885Sdumbbell 160254885Sdumbbell return (ENXIO); 161254885Sdumbbell} 162254885Sdumbbell 163254885Sdumbbellstatic int 164254885Sdumbbellagp_amd64_attach(device_t dev) 165254885Sdumbbell{ 166254885Sdumbbell struct agp_amd64_softc *sc = device_get_softc(dev); 167254885Sdumbbell struct agp_gatt *gatt; 168254885Sdumbbell uint32_t devid; 169254885Sdumbbell int i, n, error; 170254885Sdumbbell 171254885Sdumbbell for (i = 0, n = 0; i < PCI_SLOTMAX && n < AMD64_MAX_MCTRL; i++) { 172254885Sdumbbell devid = pci_cfgregread(0, i, 3, 0, 4); 173254885Sdumbbell if (devid == 0x11031022 || devid == 0x12031022) { 174254885Sdumbbell sc->mctrl[n] = i; 175254885Sdumbbell n++; 176254885Sdumbbell } 177254885Sdumbbell } 178254885Sdumbbell if (n == 0) 179254885Sdumbbell return (ENXIO); 180254885Sdumbbell 181254885Sdumbbell sc->n_mctrl = n; 182254885Sdumbbell 183254885Sdumbbell if (bootverbose) 184254885Sdumbbell device_printf(dev, "%d Miscellaneous Control unit(s) found.\n", 185254885Sdumbbell sc->n_mctrl); 186254885Sdumbbell 187254885Sdumbbell if ((error = agp_generic_attach(dev))) 188254885Sdumbbell return (error); 189254885Sdumbbell 190254885Sdumbbell sc->initial_aperture = AGP_GET_APERTURE(dev); 191254885Sdumbbell 192254885Sdumbbell for (;;) { 193254885Sdumbbell gatt = agp_alloc_gatt(dev); 194254885Sdumbbell if (gatt) 195254885Sdumbbell break; 196254885Sdumbbell 197254885Sdumbbell /* 198254885Sdumbbell * Probably contigmalloc failure. Try reducing the 199254885Sdumbbell * aperture so that the gatt size reduces. 200254885Sdumbbell */ 201254885Sdumbbell if (AGP_SET_APERTURE(dev, AGP_GET_APERTURE(dev) / 2)) { 202254885Sdumbbell agp_generic_detach(dev); 203254885Sdumbbell return (ENOMEM); 204254885Sdumbbell } 205254885Sdumbbell } 206254885Sdumbbell sc->gatt = gatt; 207254885Sdumbbell 208254885Sdumbbell switch (pci_get_vendor(dev)) { 209254885Sdumbbell case 0x10b9: /* ULi */ 210254885Sdumbbell agp_amd64_uli_init(dev); 211254885Sdumbbell if (agp_amd64_uli_set_aperture(dev, sc->initial_aperture)) 212254885Sdumbbell return (ENXIO); 213254885Sdumbbell break; 214254885Sdumbbell 215254885Sdumbbell case 0x10de: /* nVidia */ 216254885Sdumbbell agp_amd64_nvidia_init(dev); 217254885Sdumbbell if (agp_amd64_nvidia_set_aperture(dev, sc->initial_aperture)) 218254885Sdumbbell return (ENXIO); 219254885Sdumbbell break; 220254885Sdumbbell 221254885Sdumbbell case 0x1106: /* VIA */ 222254885Sdumbbell sc->via_agp = agp_amd64_via_match(); 223254885Sdumbbell if (sc->via_agp) { 224254885Sdumbbell agp_amd64_via_init(dev); 225254885Sdumbbell if (agp_amd64_via_set_aperture(dev, 226254885Sdumbbell sc->initial_aperture)) 227254885Sdumbbell return (ENXIO); 228254885Sdumbbell } 229254885Sdumbbell break; 230254885Sdumbbell } 231254885Sdumbbell 232254885Sdumbbell /* Install the gatt and enable aperture. */ 233254885Sdumbbell for (i = 0; i < sc->n_mctrl; i++) { 234254885Sdumbbell pci_cfgregwrite(0, sc->mctrl[i], 3, AGP_AMD64_ATTBASE, 235254885Sdumbbell (uint32_t)(gatt->ag_physical >> 8) & AGP_AMD64_ATTBASE_MASK, 236254885Sdumbbell 4); 237254885Sdumbbell pci_cfgregwrite(0, sc->mctrl[i], 3, AGP_AMD64_APCTRL, 238254885Sdumbbell (pci_cfgregread(0, sc->mctrl[i], 3, AGP_AMD64_APCTRL, 4) | 239254885Sdumbbell AGP_AMD64_APCTRL_GARTEN) & 240254885Sdumbbell ~(AGP_AMD64_APCTRL_DISGARTCPU | AGP_AMD64_APCTRL_DISGARTIO), 241254885Sdumbbell 4); 242254885Sdumbbell } 243254885Sdumbbell 244254885Sdumbbell agp_flush_cache(); 245254885Sdumbbell 246254885Sdumbbell return (0); 247254885Sdumbbell} 248254885Sdumbbell 249254885Sdumbbellstatic int 250254885Sdumbbellagp_amd64_detach(device_t dev) 251254885Sdumbbell{ 252254885Sdumbbell struct agp_amd64_softc *sc = device_get_softc(dev); 253254885Sdumbbell int i; 254254885Sdumbbell 255254885Sdumbbell agp_free_cdev(dev); 256254885Sdumbbell 257254885Sdumbbell for (i = 0; i < sc->n_mctrl; i++) 258254885Sdumbbell pci_cfgregwrite(0, sc->mctrl[i], 3, AGP_AMD64_APCTRL, 259254885Sdumbbell pci_cfgregread(0, sc->mctrl[i], 3, AGP_AMD64_APCTRL, 4) & 260254885Sdumbbell ~AGP_AMD64_APCTRL_GARTEN, 4); 261254885Sdumbbell 262254885Sdumbbell AGP_SET_APERTURE(dev, sc->initial_aperture); 263254885Sdumbbell agp_free_gatt(sc->gatt); 264254885Sdumbbell agp_free_res(dev); 265254885Sdumbbell 266254885Sdumbbell return (0); 267254885Sdumbbell} 268254885Sdumbbell 269254885Sdumbbellstatic uint32_t agp_amd64_table[] = { 270254885Sdumbbell 0x02000000, /* 32 MB */ 271254885Sdumbbell 0x04000000, /* 64 MB */ 272254885Sdumbbell 0x08000000, /* 128 MB */ 273254885Sdumbbell 0x10000000, /* 256 MB */ 274254885Sdumbbell 0x20000000, /* 512 MB */ 275254885Sdumbbell 0x40000000, /* 1024 MB */ 276254885Sdumbbell 0x80000000, /* 2048 MB */ 277254885Sdumbbell}; 278254885Sdumbbell 279254885Sdumbbell#define AGP_AMD64_TABLE_SIZE \ 280254885Sdumbbell (sizeof(agp_amd64_table) / sizeof(agp_amd64_table[0])) 281254885Sdumbbell 282254885Sdumbbellstatic uint32_t 283254885Sdumbbellagp_amd64_get_aperture(device_t dev) 284254885Sdumbbell{ 285254885Sdumbbell struct agp_amd64_softc *sc = device_get_softc(dev); 286254885Sdumbbell uint32_t i; 287254885Sdumbbell 288254885Sdumbbell i = (pci_cfgregread(0, sc->mctrl[0], 3, AGP_AMD64_APCTRL, 4) & 289254885Sdumbbell AGP_AMD64_APCTRL_SIZE_MASK) >> 1; 290254885Sdumbbell 291254885Sdumbbell if (i >= AGP_AMD64_TABLE_SIZE) 292254885Sdumbbell return (0); 293254885Sdumbbell 294254885Sdumbbell return (agp_amd64_table[i]); 295254885Sdumbbell} 296254885Sdumbbell 297254885Sdumbbellstatic int 298254885Sdumbbellagp_amd64_set_aperture(device_t dev, uint32_t aperture) 299254885Sdumbbell{ 300254885Sdumbbell struct agp_amd64_softc *sc = device_get_softc(dev); 301254885Sdumbbell uint32_t i; 302254885Sdumbbell int j; 303254885Sdumbbell 304254885Sdumbbell for (i = 0; i < AGP_AMD64_TABLE_SIZE; i++) 305254885Sdumbbell if (agp_amd64_table[i] == aperture) 306254885Sdumbbell break; 307254885Sdumbbell if (i >= AGP_AMD64_TABLE_SIZE) 308254885Sdumbbell return (EINVAL); 309254885Sdumbbell 310254885Sdumbbell for (j = 0; j < sc->n_mctrl; j++) 311269790Ssbruno pci_cfgregwrite(0, sc->mctrl[j], 3, AGP_AMD64_APCTRL, 312269790Ssbruno (pci_cfgregread(0, sc->mctrl[j], 3, AGP_AMD64_APCTRL, 4) & 313269790Ssbruno ~(AGP_AMD64_APCTRL_SIZE_MASK)) | (i << 1), 4); 314269790Ssbruno 315269790Ssbruno switch (pci_get_vendor(dev)) { 316254885Sdumbbell case 0x10b9: /* ULi */ 317254885Sdumbbell return (agp_amd64_uli_set_aperture(dev, aperture)); 318254885Sdumbbell break; 319254885Sdumbbell 320254885Sdumbbell case 0x10de: /* nVidia */ 321254885Sdumbbell return (agp_amd64_nvidia_set_aperture(dev, aperture)); 322254885Sdumbbell break; 323254885Sdumbbell 324254885Sdumbbell case 0x1106: /* VIA */ 325254885Sdumbbell if (sc->via_agp) 326254885Sdumbbell return (agp_amd64_via_set_aperture(dev, aperture)); 327254885Sdumbbell break; 328254885Sdumbbell } 329254885Sdumbbell 330254885Sdumbbell return (0); 331254885Sdumbbell} 332254885Sdumbbell 333254885Sdumbbellstatic int 334254885Sdumbbellagp_amd64_bind_page(device_t dev, vm_offset_t offset, vm_offset_t physical) 335254885Sdumbbell{ 336254885Sdumbbell struct agp_amd64_softc *sc = device_get_softc(dev); 337254885Sdumbbell 338254885Sdumbbell if (offset >= (sc->gatt->ag_entries << AGP_PAGE_SHIFT)) 339254885Sdumbbell return (EINVAL); 340254885Sdumbbell 341254885Sdumbbell sc->gatt->ag_virtual[offset >> AGP_PAGE_SHIFT] = 342254885Sdumbbell (physical & 0xfffff000) | ((physical >> 28) & 0x00000ff0) | 3; 343254885Sdumbbell 344254885Sdumbbell return (0); 345254885Sdumbbell} 346254885Sdumbbell 347254885Sdumbbellstatic int 348254885Sdumbbellagp_amd64_unbind_page(device_t dev, vm_offset_t offset) 349254885Sdumbbell{ 350254885Sdumbbell struct agp_amd64_softc *sc = device_get_softc(dev); 351254885Sdumbbell 352254885Sdumbbell if (offset >= (sc->gatt->ag_entries << AGP_PAGE_SHIFT)) 353254885Sdumbbell return (EINVAL); 354254885Sdumbbell 355254885Sdumbbell sc->gatt->ag_virtual[offset >> AGP_PAGE_SHIFT] = 0; 356254885Sdumbbell 357254885Sdumbbell return (0); 358254885Sdumbbell} 359254885Sdumbbell 360254885Sdumbbellstatic void 361254885Sdumbbellagp_amd64_flush_tlb(device_t dev) 362254885Sdumbbell{ 363254885Sdumbbell struct agp_amd64_softc *sc = device_get_softc(dev); 364254885Sdumbbell int i; 365254885Sdumbbell 366254885Sdumbbell for (i = 0; i < sc->n_mctrl; i++) 367254885Sdumbbell pci_cfgregwrite(0, sc->mctrl[i], 3, AGP_AMD64_CACHECTRL, 368254885Sdumbbell pci_cfgregread(0, sc->mctrl[i], 3, AGP_AMD64_CACHECTRL, 4) | 369254885Sdumbbell AGP_AMD64_CACHECTRL_INVGART, 4); 370254885Sdumbbell} 371254885Sdumbbell 372254885Sdumbbellstatic void 373254885Sdumbbellagp_amd64_apbase_fixup(device_t dev) 374254885Sdumbbell{ 375254885Sdumbbell struct agp_amd64_softc *sc = device_get_softc(dev); 376254885Sdumbbell uint32_t apbase; 377254885Sdumbbell int i; 378254885Sdumbbell 379254885Sdumbbell sc->apbase = rman_get_start(sc->agp.as_aperture); 380254885Sdumbbell apbase = (sc->apbase >> 25) & AGP_AMD64_APBASE_MASK; 381254885Sdumbbell for (i = 0; i < sc->n_mctrl; i++) 382254885Sdumbbell pci_cfgregwrite(0, sc->mctrl[i], 3, 383254885Sdumbbell AGP_AMD64_APBASE, apbase, 4); 384254885Sdumbbell} 385254885Sdumbbell 386254885Sdumbbellstatic void 387254885Sdumbbellagp_amd64_uli_init(device_t dev) 388254885Sdumbbell{ 389254885Sdumbbell struct agp_amd64_softc *sc = device_get_softc(dev); 390254885Sdumbbell 391254885Sdumbbell agp_amd64_apbase_fixup(dev); 392254885Sdumbbell pci_write_config(dev, AGP_AMD64_ULI_APBASE, 393254885Sdumbbell (pci_read_config(dev, AGP_AMD64_ULI_APBASE, 4) & 0x0000000f) | 394254885Sdumbbell sc->apbase, 4); 395254885Sdumbbell pci_write_config(dev, AGP_AMD64_ULI_HTT_FEATURE, sc->apbase, 4); 396254885Sdumbbell} 397254885Sdumbbell 398254885Sdumbbellstatic int 399254885Sdumbbellagp_amd64_uli_set_aperture(device_t dev, uint32_t aperture) 400254885Sdumbbell{ 401254885Sdumbbell struct agp_amd64_softc *sc = device_get_softc(dev); 402254885Sdumbbell 403254885Sdumbbell switch (aperture) { 404254885Sdumbbell case 0x02000000: /* 32 MB */ 405254885Sdumbbell case 0x04000000: /* 64 MB */ 406254885Sdumbbell case 0x08000000: /* 128 MB */ 407254885Sdumbbell case 0x10000000: /* 256 MB */ 408254885Sdumbbell break; 409254885Sdumbbell default: 410254885Sdumbbell return (EINVAL); 411254885Sdumbbell } 412254885Sdumbbell 413254885Sdumbbell pci_write_config(dev, AGP_AMD64_ULI_ENU_SCR, 414254885Sdumbbell sc->apbase + aperture - 1, 4); 415254885Sdumbbell 416254885Sdumbbell return (0); 417254885Sdumbbell} 418254885Sdumbbell 419254885Sdumbbellstatic void 420254885Sdumbbellagp_amd64_nvidia_init(device_t dev) 421254885Sdumbbell{ 422254885Sdumbbell struct agp_amd64_softc *sc = device_get_softc(dev); 423254885Sdumbbell 424254885Sdumbbell agp_amd64_apbase_fixup(dev); 425254885Sdumbbell pci_write_config(dev, AGP_AMD64_NVIDIA_0_APBASE, 426254885Sdumbbell (pci_read_config(dev, AGP_AMD64_NVIDIA_0_APBASE, 4) & 0x0000000f) | 427254885Sdumbbell sc->apbase, 4); 428254885Sdumbbell pci_cfgregwrite(0, 11, 0, AGP_AMD64_NVIDIA_1_APBASE1, sc->apbase, 4); 429254885Sdumbbell pci_cfgregwrite(0, 11, 0, AGP_AMD64_NVIDIA_1_APBASE2, sc->apbase, 4); 430254885Sdumbbell} 431254885Sdumbbell 432254885Sdumbbellstatic int 433254885Sdumbbellagp_amd64_nvidia_set_aperture(device_t dev, uint32_t aperture) 434254885Sdumbbell{ 435254885Sdumbbell struct agp_amd64_softc *sc = device_get_softc(dev); 436254885Sdumbbell uint32_t apsize; 437254885Sdumbbell 438254885Sdumbbell switch (aperture) { 439254885Sdumbbell case 0x02000000: apsize = 0x0f; break; /* 32 MB */ 440254885Sdumbbell case 0x04000000: apsize = 0x0e; break; /* 64 MB */ 441254885Sdumbbell case 0x08000000: apsize = 0x0c; break; /* 128 MB */ 442254885Sdumbbell case 0x10000000: apsize = 0x08; break; /* 256 MB */ 443254885Sdumbbell case 0x20000000: apsize = 0x00; break; /* 512 MB */ 444254885Sdumbbell default: 445254885Sdumbbell return (EINVAL); 446254885Sdumbbell } 447254885Sdumbbell 448254885Sdumbbell pci_cfgregwrite(0, 11, 0, AGP_AMD64_NVIDIA_1_APSIZE, 449254885Sdumbbell (pci_cfgregread(0, 11, 0, AGP_AMD64_NVIDIA_1_APSIZE, 4) & 450254885Sdumbbell 0xfffffff0) | apsize, 4); 451254885Sdumbbell pci_cfgregwrite(0, 11, 0, AGP_AMD64_NVIDIA_1_APLIMIT1, 452254885Sdumbbell sc->apbase + aperture - 1, 4); 453254885Sdumbbell pci_cfgregwrite(0, 11, 0, AGP_AMD64_NVIDIA_1_APLIMIT2, 454254885Sdumbbell sc->apbase + aperture - 1, 4); 455254885Sdumbbell 456254885Sdumbbell return (0); 457254885Sdumbbell} 458254885Sdumbbell 459254885Sdumbbellstatic void 460254885Sdumbbellagp_amd64_via_init(device_t dev) 461254885Sdumbbell{ 462254885Sdumbbell struct agp_amd64_softc *sc = device_get_softc(dev); 463254885Sdumbbell 464254885Sdumbbell agp_amd64_apbase_fixup(dev); 465254885Sdumbbell pci_cfgregwrite(0, 1, 0, AGP3_VIA_ATTBASE, sc->gatt->ag_physical, 4); 466254885Sdumbbell pci_cfgregwrite(0, 1, 0, AGP3_VIA_GARTCTRL, 467254885Sdumbbell pci_cfgregread(0, 1, 0, AGP3_VIA_ATTBASE, 4) | 0x180, 4); 468254885Sdumbbell} 469254885Sdumbbell 470254885Sdumbbellstatic int 471254885Sdumbbellagp_amd64_via_set_aperture(device_t dev, uint32_t aperture) 472254885Sdumbbell{ 473254885Sdumbbell uint32_t apsize; 474254885Sdumbbell 475254885Sdumbbell apsize = ((aperture - 1) >> 20) ^ 0xff; 476254885Sdumbbell if ((((apsize ^ 0xff) << 20) | ((1 << 20) - 1)) + 1 != aperture) 477254885Sdumbbell return (EINVAL); 478254885Sdumbbell pci_cfgregwrite(0, 1, 0, AGP3_VIA_APSIZE, apsize, 1); 479254885Sdumbbell 480254885Sdumbbell return (0); 481254885Sdumbbell} 482254885Sdumbbell 483254885Sdumbbellstatic device_method_t agp_amd64_methods[] = { 484254885Sdumbbell /* Device interface */ 485254885Sdumbbell DEVMETHOD(device_probe, agp_amd64_probe), 486254885Sdumbbell DEVMETHOD(device_attach, agp_amd64_attach), 487254885Sdumbbell DEVMETHOD(device_detach, agp_amd64_detach), 488254885Sdumbbell DEVMETHOD(device_shutdown, bus_generic_shutdown), 489254885Sdumbbell DEVMETHOD(device_suspend, bus_generic_suspend), 490254885Sdumbbell DEVMETHOD(device_resume, bus_generic_resume), 491254885Sdumbbell 492254885Sdumbbell /* AGP interface */ 493254885Sdumbbell DEVMETHOD(agp_get_aperture, agp_amd64_get_aperture), 494254885Sdumbbell DEVMETHOD(agp_set_aperture, agp_amd64_set_aperture), 495254885Sdumbbell DEVMETHOD(agp_bind_page, agp_amd64_bind_page), 496254885Sdumbbell DEVMETHOD(agp_unbind_page, agp_amd64_unbind_page), 497254885Sdumbbell DEVMETHOD(agp_flush_tlb, agp_amd64_flush_tlb), 498254885Sdumbbell DEVMETHOD(agp_enable, agp_generic_enable), 499254885Sdumbbell DEVMETHOD(agp_alloc_memory, agp_generic_alloc_memory), 500254885Sdumbbell DEVMETHOD(agp_free_memory, agp_generic_free_memory), 501254885Sdumbbell DEVMETHOD(agp_bind_memory, agp_generic_bind_memory), 502254885Sdumbbell DEVMETHOD(agp_unbind_memory, agp_generic_unbind_memory), 503254885Sdumbbell 504254885Sdumbbell { 0, 0 } 505254885Sdumbbell}; 506254885Sdumbbell 507254885Sdumbbellstatic driver_t agp_amd64_driver = { 508254885Sdumbbell "agp", 509254885Sdumbbell agp_amd64_methods, 510254885Sdumbbell sizeof(struct agp_amd64_softc), 511254885Sdumbbell}; 512254885Sdumbbell 513254885Sdumbbellstatic devclass_t agp_devclass; 514254885Sdumbbell 515254885SdumbbellDRIVER_MODULE(agp_amd64, hostb, agp_amd64_driver, agp_devclass, 0, 0); 516254885SdumbbellMODULE_DEPEND(agp_amd64, agp, 1, 1, 1); 517254885SdumbbellMODULE_DEPEND(agp_amd64, pci, 1, 1, 1); 518254885Sdumbbell