agp_i810.c revision 329527
167754Smsmith/*- 267754Smsmith * Copyright (c) 2000 Doug Rabson 377424Smsmith * Copyright (c) 2000 Ruslan Ermilov 467754Smsmith * Copyright (c) 2011 The FreeBSD Foundation 567754Smsmith * All rights reserved. 667754Smsmith * 7316303Sjkim * Portions of this software were developed by Konstantin Belousov 8316303Sjkim * under sponsorship from the FreeBSD Foundation. 9316303Sjkim * 10316303Sjkim * Redistribution and use in source and binary forms, with or without 11316303Sjkim * modification, are permitted provided that the following conditions 1270243Smsmith * are met: 1367754Smsmith * 1. Redistributions of source code must retain the above copyright 14316303Sjkim * notice, this list of conditions and the following disclaimer. 15316303Sjkim * 2. Redistributions in binary form must reproduce the above copyright 16316303Sjkim * notice, this list of conditions and the following disclaimer in the 17316303Sjkim * documentation and/or other materials provided with the distribution. 18316303Sjkim * 19316303Sjkim * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 20316303Sjkim * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21316303Sjkim * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22316303Sjkim * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 23316303Sjkim * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24316303Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25316303Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26316303Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27316303Sjkim * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28316303Sjkim * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29316303Sjkim * SUCH DAMAGE. 30316303Sjkim */ 31316303Sjkim 32316303Sjkim/* 33316303Sjkim * Fixes for 830/845G support: David Dawes <dawes@xfree86.org> 34316303Sjkim * 852GM/855GM/865G support added by David Dawes <dawes@xfree86.org> 35316303Sjkim * 36316303Sjkim * This is generic Intel GTT handling code, morphed from the AGP 37316303Sjkim * bridge code. 38316303Sjkim */ 39316303Sjkim 40316303Sjkim#include <sys/cdefs.h> 41316303Sjkim__FBSDID("$FreeBSD: stable/11/sys/dev/agp/agp_i810.c 329527 2018-02-18 19:46:57Z markj $"); 42316303Sjkim 43316303Sjkim#if 0 44316303Sjkim#define KTR_AGP_I810 KTR_DEV 45316303Sjkim#else 46316303Sjkim#define KTR_AGP_I810 0 47316303Sjkim#endif 48316303Sjkim 49316303Sjkim#include <sys/param.h> 50316303Sjkim#include <sys/systm.h> 51316303Sjkim#include <sys/malloc.h> 52316303Sjkim#include <sys/kernel.h> 53316303Sjkim#include <sys/ktr.h> 54316303Sjkim#include <sys/module.h> 55316303Sjkim#include <sys/bus.h> 56316303Sjkim#include <sys/lock.h> 57316303Sjkim#include <sys/mutex.h> 58316303Sjkim#include <sys/proc.h> 59316303Sjkim#include <sys/rwlock.h> 60316303Sjkim 61316303Sjkim#include <dev/agp/agppriv.h> 62316303Sjkim#include <dev/agp/agpreg.h> 63316303Sjkim#include <dev/agp/agp_i810.h> 64316303Sjkim#include <dev/pci/pcivar.h> 65316303Sjkim#include <dev/pci/pcireg.h> 66316303Sjkim#include <dev/pci/pci_private.h> 67316303Sjkim 68316303Sjkim#include <vm/vm.h> 69316303Sjkim#include <vm/vm_extern.h> 70316303Sjkim#include <vm/vm_kern.h> 71316303Sjkim#include <vm/vm_param.h> 72316303Sjkim#include <vm/vm_object.h> 73316303Sjkim#include <vm/vm_page.h> 74316303Sjkim#include <vm/vm_pageout.h> 75316303Sjkim#include <vm/pmap.h> 76316303Sjkim 77316303Sjkim#include <machine/bus.h> 78316303Sjkim#include <machine/resource.h> 79316303Sjkim#include <machine/md_var.h> 80316303Sjkim#include <sys/rman.h> 81316303Sjkim 82316303SjkimMALLOC_DECLARE(M_AGP); 83316303Sjkim 84316303Sjkimstruct agp_i810_match; 85316303Sjkim 86316303Sjkimstatic int agp_i810_check_active(device_t bridge_dev); 87316303Sjkimstatic int agp_i830_check_active(device_t bridge_dev); 88316303Sjkimstatic int agp_i915_check_active(device_t bridge_dev); 89316303Sjkim 90316303Sjkimstatic void agp_82852_set_desc(device_t dev, 91316303Sjkim const struct agp_i810_match *match); 92316303Sjkimstatic void agp_i810_set_desc(device_t dev, const struct agp_i810_match *match); 93316303Sjkim 94316303Sjkimstatic void agp_i810_dump_regs(device_t dev); 95316303Sjkimstatic void agp_i830_dump_regs(device_t dev); 96316303Sjkimstatic void agp_i855_dump_regs(device_t dev); 97316303Sjkimstatic void agp_i915_dump_regs(device_t dev); 98316303Sjkimstatic void agp_i965_dump_regs(device_t dev); 99316303Sjkim 100316303Sjkimstatic int agp_i810_get_stolen_size(device_t dev); 101316303Sjkimstatic int agp_i830_get_stolen_size(device_t dev); 102316303Sjkimstatic int agp_i915_get_stolen_size(device_t dev); 103316303Sjkim 104316303Sjkimstatic int agp_i810_get_gtt_mappable_entries(device_t dev); 105316303Sjkimstatic int agp_i830_get_gtt_mappable_entries(device_t dev); 106316303Sjkimstatic int agp_i915_get_gtt_mappable_entries(device_t dev); 107316303Sjkim 108316303Sjkimstatic int agp_i810_get_gtt_total_entries(device_t dev); 109316303Sjkimstatic int agp_i965_get_gtt_total_entries(device_t dev); 110316303Sjkimstatic int agp_gen5_get_gtt_total_entries(device_t dev); 111316303Sjkim 112316303Sjkimstatic int agp_i810_install_gatt(device_t dev); 113316303Sjkimstatic int agp_i830_install_gatt(device_t dev); 114316303Sjkimstatic int agp_i965_install_gatt(device_t dev); 115316303Sjkimstatic int agp_g4x_install_gatt(device_t dev); 116316303Sjkim 117316303Sjkimstatic void agp_i810_deinstall_gatt(device_t dev); 118316303Sjkimstatic void agp_i830_deinstall_gatt(device_t dev); 119217365Sjkim 120217365Sjkimstatic void agp_i810_install_gtt_pte(device_t dev, u_int index, 121217365Sjkim vm_offset_t physical, int flags); 122217365Sjkimstatic void agp_i830_install_gtt_pte(device_t dev, u_int index, 123217365Sjkim vm_offset_t physical, int flags); 124217365Sjkimstatic void agp_i915_install_gtt_pte(device_t dev, u_int index, 125217365Sjkim vm_offset_t physical, int flags); 126217365Sjkimstatic void agp_i965_install_gtt_pte(device_t dev, u_int index, 127217365Sjkim vm_offset_t physical, int flags); 128217365Sjkimstatic void agp_g4x_install_gtt_pte(device_t dev, u_int index, 129217365Sjkim vm_offset_t physical, int flags); 130217365Sjkim 131217365Sjkimstatic void agp_i810_write_gtt(device_t dev, u_int index, uint32_t pte); 132217365Sjkimstatic void agp_i915_write_gtt(device_t dev, u_int index, uint32_t pte); 13367754Smsmithstatic void agp_i965_write_gtt(device_t dev, u_int index, uint32_t pte); 134316303Sjkimstatic void agp_g4x_write_gtt(device_t dev, u_int index, uint32_t pte); 135316303Sjkim 136316303Sjkimstatic u_int32_t agp_i810_read_gtt_pte(device_t dev, u_int index); 137316303Sjkimstatic u_int32_t agp_i915_read_gtt_pte(device_t dev, u_int index); 138316303Sjkimstatic u_int32_t agp_i965_read_gtt_pte(device_t dev, u_int index); 139316303Sjkimstatic u_int32_t agp_g4x_read_gtt_pte(device_t dev, u_int index); 140316303Sjkim 141316303Sjkimstatic vm_paddr_t agp_i810_read_gtt_pte_paddr(device_t dev, u_int index); 142316303Sjkimstatic vm_paddr_t agp_i915_read_gtt_pte_paddr(device_t dev, u_int index); 143316303Sjkim 144316303Sjkimstatic int agp_i810_set_aperture(device_t dev, u_int32_t aperture); 145316303Sjkimstatic int agp_i830_set_aperture(device_t dev, u_int32_t aperture); 146316303Sjkimstatic int agp_i915_set_aperture(device_t dev, u_int32_t aperture); 147217365Sjkim 148217365Sjkimstatic int agp_i810_chipset_flush_setup(device_t dev); 14967754Smsmithstatic int agp_i915_chipset_flush_setup(device_t dev); 150316303Sjkimstatic int agp_i965_chipset_flush_setup(device_t dev); 15167754Smsmith 15277424Smsmithstatic void agp_i810_chipset_flush_teardown(device_t dev); 15377424Smsmithstatic void agp_i915_chipset_flush_teardown(device_t dev); 15467754Smsmithstatic void agp_i965_chipset_flush_teardown(device_t dev); 15567754Smsmith 156167802Sjkimstatic void agp_i810_chipset_flush(device_t dev); 157228110Sjkimstatic void agp_i830_chipset_flush(device_t dev); 158167802Sjkimstatic void agp_i915_chipset_flush(device_t dev); 159167802Sjkim 160167802Sjkimenum { 161272444Sjkim CHIP_I810, /* i810/i815 */ 162167802Sjkim CHIP_I830, /* 830M/845G */ 163167802Sjkim CHIP_I855, /* 852GM/855GM/865G */ 164167802Sjkim CHIP_I915, /* 915G/915GM */ 165167802Sjkim CHIP_I965, /* G965 */ 166167802Sjkim CHIP_G33, /* G33/Q33/Q35 */ 167167802Sjkim CHIP_IGD, /* Pineview */ 168167802Sjkim CHIP_G4X, /* G45/Q45 */ 169167802Sjkim}; 170167802Sjkim 171167802Sjkim/* The i810 through i855 have the registers at BAR 1, and the GATT gets 172167802Sjkim * allocated by us. The i915 has registers in BAR 0 and the GATT is at the 173167802Sjkim * start of the stolen memory, and should only be accessed by the OS through 174167802Sjkim * BAR 3. The G965 has registers and GATT in the same BAR (0) -- first 512KB 175167802Sjkim * is registers, second 512KB is GATT. 176167802Sjkim */ 177167802Sjkimstatic struct resource_spec agp_i810_res_spec[] = { 178167802Sjkim { SYS_RES_MEMORY, AGP_I810_MMADR, RF_ACTIVE | RF_SHAREABLE }, 179167802Sjkim { -1, 0 } 180167802Sjkim}; 181228110Sjkim 182228110Sjkimstatic struct resource_spec agp_i915_res_spec[] = { 183228110Sjkim { SYS_RES_MEMORY, AGP_I915_MMADR, RF_ACTIVE | RF_SHAREABLE }, 184228110Sjkim { SYS_RES_MEMORY, AGP_I915_GTTADR, RF_ACTIVE | RF_SHAREABLE }, 185228110Sjkim { -1, 0 } 186228110Sjkim}; 187228110Sjkim 188228110Sjkimstatic struct resource_spec agp_i965_res_spec[] = { 189228110Sjkim { SYS_RES_MEMORY, AGP_I965_GTTMMADR, RF_ACTIVE | RF_SHAREABLE }, 190228110Sjkim { SYS_RES_MEMORY, AGP_I965_APBASE, RF_ACTIVE | RF_SHAREABLE }, 191228110Sjkim { -1, 0 } 192228110Sjkim}; 193228110Sjkim 194228110Sjkimstruct agp_i810_softc { 195228110Sjkim struct agp_softc agp; 196228110Sjkim u_int32_t initial_aperture; /* aperture size at startup */ 197322877Sjkim struct agp_gatt *gatt; 198167802Sjkim u_int32_t dcache_size; /* i810 only */ 199167802Sjkim u_int32_t stolen; /* number of i830/845 gtt 200250838Sjkim entries for stolen memory */ 201250838Sjkim u_int stolen_size; /* BIOS-reserved graphics memory */ 202250838Sjkim u_int gtt_total_entries; /* Total number of gtt ptes */ 203250838Sjkim u_int gtt_mappable_entries; /* Number of gtt ptes mappable by CPU */ 204250838Sjkim device_t bdev; /* bridge device */ 205250838Sjkim void *argb_cursor; /* contigmalloc area for ARGB cursor */ 206250838Sjkim struct resource *sc_res[2]; 207250838Sjkim const struct agp_i810_match *match; 208250838Sjkim int sc_flush_page_rid; 209250838Sjkim struct resource *sc_flush_page_res; 210250838Sjkim void *sc_flush_page_vaddr; 211250838Sjkim int sc_bios_allocated_flush_page; 212250838Sjkim}; 213250838Sjkim 214250838Sjkimstatic device_t intel_agp; 215250838Sjkim 216250838Sjkimstruct agp_i810_driver { 217250838Sjkim int chiptype; 218250838Sjkim int gen; 219250838Sjkim int busdma_addr_mask_sz; 220250838Sjkim struct resource_spec *res_spec; 221250838Sjkim int (*check_active)(device_t); 222250838Sjkim void (*set_desc)(device_t, const struct agp_i810_match *); 223250838Sjkim void (*dump_regs)(device_t); 224250838Sjkim int (*get_stolen_size)(device_t); 225250838Sjkim int (*get_gtt_total_entries)(device_t); 226250838Sjkim int (*get_gtt_mappable_entries)(device_t); 227300879Sjkim int (*install_gatt)(device_t); 228250838Sjkim void (*deinstall_gatt)(device_t); 229300879Sjkim void (*write_gtt)(device_t, u_int, uint32_t); 230300879Sjkim void (*install_gtt_pte)(device_t, u_int, vm_offset_t, int); 231250838Sjkim u_int32_t (*read_gtt_pte)(device_t, u_int); 232300879Sjkim vm_paddr_t (*read_gtt_pte_paddr)(device_t , u_int); 233300879Sjkim int (*set_aperture)(device_t, u_int32_t); 234250838Sjkim int (*chipset_flush_setup)(device_t); 235300879Sjkim void (*chipset_flush_teardown)(device_t); 236250838Sjkim void (*chipset_flush)(device_t); 237300879Sjkim}; 238327557Sjkim 239300879Sjkimstatic struct { 240300879Sjkim struct intel_gtt base; 241327557Sjkim} intel_private; 242300879Sjkim 243250838Sjkimstatic const struct agp_i810_driver agp_i810_i810_driver = { 244250838Sjkim .chiptype = CHIP_I810, 245250838Sjkim .gen = 1, 246250838Sjkim .busdma_addr_mask_sz = 32, 247250838Sjkim .res_spec = agp_i810_res_spec, 248250838Sjkim .check_active = agp_i810_check_active, 249250838Sjkim .set_desc = agp_i810_set_desc, 250327557Sjkim .dump_regs = agp_i810_dump_regs, 251250838Sjkim .get_stolen_size = agp_i810_get_stolen_size, 252327557Sjkim .get_gtt_mappable_entries = agp_i810_get_gtt_mappable_entries, 253327557Sjkim .get_gtt_total_entries = agp_i810_get_gtt_total_entries, 254327557Sjkim .install_gatt = agp_i810_install_gatt, 255167802Sjkim .deinstall_gatt = agp_i810_deinstall_gatt, 256167802Sjkim .write_gtt = agp_i810_write_gtt, 257167802Sjkim .install_gtt_pte = agp_i810_install_gtt_pte, 258167802Sjkim .read_gtt_pte = agp_i810_read_gtt_pte, 259167802Sjkim .read_gtt_pte_paddr = agp_i810_read_gtt_pte_paddr, 260167802Sjkim .set_aperture = agp_i810_set_aperture, 261167802Sjkim .chipset_flush_setup = agp_i810_chipset_flush_setup, 26273561Smsmith .chipset_flush_teardown = agp_i810_chipset_flush_teardown, 263167802Sjkim .chipset_flush = agp_i810_chipset_flush, 264167802Sjkim}; 265167802Sjkim 266167802Sjkimstatic const struct agp_i810_driver agp_i810_i815_driver = { 267167802Sjkim .chiptype = CHIP_I810, 268245582Sjkim .gen = 2, 269167802Sjkim .busdma_addr_mask_sz = 32, 270167802Sjkim .res_spec = agp_i810_res_spec, 27173561Smsmith .check_active = agp_i810_check_active, 27273561Smsmith .set_desc = agp_i810_set_desc, 27373561Smsmith .dump_regs = agp_i810_dump_regs, 27473561Smsmith .get_stolen_size = agp_i810_get_stolen_size, 27573561Smsmith .get_gtt_mappable_entries = agp_i830_get_gtt_mappable_entries, 27673561Smsmith .get_gtt_total_entries = agp_i810_get_gtt_total_entries, 27773561Smsmith .install_gatt = agp_i810_install_gatt, 27873561Smsmith .deinstall_gatt = agp_i810_deinstall_gatt, 27973561Smsmith .write_gtt = agp_i810_write_gtt, 28091116Smsmith .install_gtt_pte = agp_i810_install_gtt_pte, 28173561Smsmith .read_gtt_pte = agp_i810_read_gtt_pte, 28273561Smsmith .read_gtt_pte_paddr = agp_i810_read_gtt_pte_paddr, 283114237Snjl .set_aperture = agp_i810_set_aperture, 28473561Smsmith .chipset_flush_setup = agp_i810_chipset_flush_setup, 28573561Smsmith .chipset_flush_teardown = agp_i810_chipset_flush_teardown, 286249112Sjkim .chipset_flush = agp_i830_chipset_flush, 287249112Sjkim}; 28867754Smsmith 28967754Smsmithstatic const struct agp_i810_driver agp_i810_i830_driver = { 29067754Smsmith .chiptype = CHIP_I830, 29177424Smsmith .gen = 2, 29267754Smsmith .busdma_addr_mask_sz = 32, 29367754Smsmith .res_spec = agp_i810_res_spec, 29467754Smsmith .check_active = agp_i830_check_active, 29567754Smsmith .set_desc = agp_i810_set_desc, 29667754Smsmith .dump_regs = agp_i830_dump_regs, 29767754Smsmith .get_stolen_size = agp_i830_get_stolen_size, 298285797Sjkim .get_gtt_mappable_entries = agp_i830_get_gtt_mappable_entries, 29967754Smsmith .get_gtt_total_entries = agp_i810_get_gtt_total_entries, 300298714Sjkim .install_gatt = agp_i830_install_gatt, 301298714Sjkim .deinstall_gatt = agp_i830_deinstall_gatt, 302298714Sjkim .write_gtt = agp_i810_write_gtt, 303298714Sjkim .install_gtt_pte = agp_i830_install_gtt_pte, 304298714Sjkim .read_gtt_pte = agp_i810_read_gtt_pte, 305298714Sjkim .read_gtt_pte_paddr = agp_i810_read_gtt_pte_paddr, 306298714Sjkim .set_aperture = agp_i830_set_aperture, 307298714Sjkim .chipset_flush_setup = agp_i810_chipset_flush_setup, 308298714Sjkim .chipset_flush_teardown = agp_i810_chipset_flush_teardown, 309298714Sjkim .chipset_flush = agp_i830_chipset_flush, 310298714Sjkim}; 311298714Sjkim 312298714Sjkimstatic const struct agp_i810_driver agp_i810_i855_driver = { 313298714Sjkim .chiptype = CHIP_I855, 314298714Sjkim .gen = 2, 315298714Sjkim .busdma_addr_mask_sz = 32, 316298714Sjkim .res_spec = agp_i810_res_spec, 317298714Sjkim .check_active = agp_i830_check_active, 318298714Sjkim .set_desc = agp_82852_set_desc, 319285797Sjkim .dump_regs = agp_i855_dump_regs, 320285797Sjkim .get_stolen_size = agp_i915_get_stolen_size, 321285797Sjkim .get_gtt_mappable_entries = agp_i915_get_gtt_mappable_entries, 322285797Sjkim .get_gtt_total_entries = agp_i810_get_gtt_total_entries, 323285797Sjkim .install_gatt = agp_i830_install_gatt, 324285797Sjkim .deinstall_gatt = agp_i830_deinstall_gatt, 325285797Sjkim .write_gtt = agp_i810_write_gtt, 326285797Sjkim .install_gtt_pte = agp_i830_install_gtt_pte, 327285797Sjkim .read_gtt_pte = agp_i810_read_gtt_pte, 328285797Sjkim .read_gtt_pte_paddr = agp_i810_read_gtt_pte_paddr, 329285797Sjkim .set_aperture = agp_i830_set_aperture, 330285797Sjkim .chipset_flush_setup = agp_i810_chipset_flush_setup, 331285797Sjkim .chipset_flush_teardown = agp_i810_chipset_flush_teardown, 332285797Sjkim .chipset_flush = agp_i830_chipset_flush, 333285797Sjkim}; 334327557Sjkim 335327557Sjkimstatic const struct agp_i810_driver agp_i810_i865_driver = { 336327557Sjkim .chiptype = CHIP_I855, 337327557Sjkim .gen = 2, 338285797Sjkim .busdma_addr_mask_sz = 32, 339327557Sjkim .res_spec = agp_i810_res_spec, 340285797Sjkim .check_active = agp_i830_check_active, 341327557Sjkim .set_desc = agp_i810_set_desc, 342285797Sjkim .dump_regs = agp_i855_dump_regs, 343327557Sjkim .get_stolen_size = agp_i915_get_stolen_size, 344327557Sjkim .get_gtt_mappable_entries = agp_i915_get_gtt_mappable_entries, 345327557Sjkim .get_gtt_total_entries = agp_i810_get_gtt_total_entries, 346327557Sjkim .install_gatt = agp_i830_install_gatt, 347327557Sjkim .deinstall_gatt = agp_i830_deinstall_gatt, 348327557Sjkim .write_gtt = agp_i810_write_gtt, 349327557Sjkim .install_gtt_pte = agp_i830_install_gtt_pte, 350327557Sjkim .read_gtt_pte = agp_i810_read_gtt_pte, 351327557Sjkim .read_gtt_pte_paddr = agp_i810_read_gtt_pte_paddr, 352327557Sjkim .set_aperture = agp_i915_set_aperture, 353327557Sjkim .chipset_flush_setup = agp_i810_chipset_flush_setup, 354327557Sjkim .chipset_flush_teardown = agp_i810_chipset_flush_teardown, 355327557Sjkim .chipset_flush = agp_i830_chipset_flush, 356327557Sjkim}; 357327557Sjkim 358327557Sjkimstatic const struct agp_i810_driver agp_i810_i915_driver = { 359327557Sjkim .chiptype = CHIP_I915, 360327557Sjkim .gen = 3, 361327557Sjkim .busdma_addr_mask_sz = 32, 362327557Sjkim .res_spec = agp_i915_res_spec, 363327557Sjkim .check_active = agp_i915_check_active, 364327557Sjkim .set_desc = agp_i810_set_desc, 365327557Sjkim .dump_regs = agp_i915_dump_regs, 366327557Sjkim .get_stolen_size = agp_i915_get_stolen_size, 367327557Sjkim .get_gtt_mappable_entries = agp_i915_get_gtt_mappable_entries, 368327557Sjkim .get_gtt_total_entries = agp_i810_get_gtt_total_entries, 369327557Sjkim .install_gatt = agp_i830_install_gatt, 370316303Sjkim .deinstall_gatt = agp_i830_deinstall_gatt, 371327557Sjkim .write_gtt = agp_i915_write_gtt, 372316303Sjkim .install_gtt_pte = agp_i915_install_gtt_pte, 373327557Sjkim .read_gtt_pte = agp_i915_read_gtt_pte, 374327557Sjkim .read_gtt_pte_paddr = agp_i915_read_gtt_pte_paddr, 375327557Sjkim .set_aperture = agp_i915_set_aperture, 376327557Sjkim .chipset_flush_setup = agp_i915_chipset_flush_setup, 377285797Sjkim .chipset_flush_teardown = agp_i915_chipset_flush_teardown, 378327557Sjkim .chipset_flush = agp_i915_chipset_flush, 379327557Sjkim}; 380327557Sjkim 381298714Sjkimstatic const struct agp_i810_driver agp_i810_g33_driver = { 382327557Sjkim .chiptype = CHIP_G33, 383327557Sjkim .gen = 3, 384327557Sjkim .busdma_addr_mask_sz = 36, 385327557Sjkim .res_spec = agp_i915_res_spec, 386327557Sjkim .check_active = agp_i915_check_active, 387285797Sjkim .set_desc = agp_i810_set_desc, 388151937Sjkim .dump_regs = agp_i965_dump_regs, 38967754Smsmith .get_stolen_size = agp_i915_get_stolen_size, 390193267Sjkim .get_gtt_mappable_entries = agp_i915_get_gtt_mappable_entries, 391151937Sjkim .get_gtt_total_entries = agp_i965_get_gtt_total_entries, 39267754Smsmith .install_gatt = agp_i830_install_gatt, 39367754Smsmith .deinstall_gatt = agp_i830_deinstall_gatt, 394298714Sjkim .write_gtt = agp_i915_write_gtt, 39577424Smsmith .install_gtt_pte = agp_i915_install_gtt_pte, 39667754Smsmith .read_gtt_pte = agp_i915_read_gtt_pte, 39767754Smsmith .read_gtt_pte_paddr = agp_i915_read_gtt_pte_paddr, 398327557Sjkim .set_aperture = agp_i915_set_aperture, 399327557Sjkim .chipset_flush_setup = agp_i965_chipset_flush_setup, 400193267Sjkim .chipset_flush_teardown = agp_i965_chipset_flush_teardown, 401193267Sjkim .chipset_flush = agp_i915_chipset_flush, 402272444Sjkim}; 403272444Sjkim 404100966Siwasakistatic const struct agp_i810_driver agp_i810_igd_driver = { 405100966Siwasaki .chiptype = CHIP_IGD, 406298714Sjkim .gen = 3, 40777424Smsmith .busdma_addr_mask_sz = 36, 40891116Smsmith .res_spec = agp_i915_res_spec, 40967754Smsmith .check_active = agp_i915_check_active, 410298714Sjkim .set_desc = agp_i810_set_desc, 411123315Snjl .dump_regs = agp_i915_dump_regs, 412123315Snjl .get_stolen_size = agp_i915_get_stolen_size, 413123315Snjl .get_gtt_mappable_entries = agp_i915_get_gtt_mappable_entries, 414298714Sjkim .get_gtt_total_entries = agp_i965_get_gtt_total_entries, 415123315Snjl .install_gatt = agp_i830_install_gatt, 416123315Snjl .deinstall_gatt = agp_i830_deinstall_gatt, 417123315Snjl .write_gtt = agp_i915_write_gtt, 418193267Sjkim .install_gtt_pte = agp_i915_install_gtt_pte, 419193267Sjkim .read_gtt_pte = agp_i915_read_gtt_pte, 420193267Sjkim .read_gtt_pte_paddr = agp_i915_read_gtt_pte_paddr, 421193267Sjkim .set_aperture = agp_i915_set_aperture, 422298714Sjkim .chipset_flush_setup = agp_i965_chipset_flush_setup, 42399679Siwasaki .chipset_flush_teardown = agp_i965_chipset_flush_teardown, 42499679Siwasaki .chipset_flush = agp_i915_chipset_flush, 42599679Siwasaki}; 426298714Sjkim 42777424Smsmithstatic const struct agp_i810_driver agp_i810_g965_driver = { 42869746Smsmith .chiptype = CHIP_I965, 42969746Smsmith .gen = 4, 430298714Sjkim .busdma_addr_mask_sz = 36, 43191116Smsmith .res_spec = agp_i965_res_spec, 43291116Smsmith .check_active = agp_i915_check_active, 43369746Smsmith .set_desc = agp_i810_set_desc, 434316303Sjkim .dump_regs = agp_i965_dump_regs, 435316303Sjkim .get_stolen_size = agp_i915_get_stolen_size, 436316303Sjkim .get_gtt_mappable_entries = agp_i915_get_gtt_mappable_entries, 437316303Sjkim .get_gtt_total_entries = agp_i965_get_gtt_total_entries, 43899679Siwasaki .install_gatt = agp_i965_install_gatt, 43982367Smsmith .deinstall_gatt = agp_i830_deinstall_gatt, 440202771Sjkim .write_gtt = agp_i965_write_gtt, 44182367Smsmith .install_gtt_pte = agp_i965_install_gtt_pte, 44282367Smsmith .read_gtt_pte = agp_i965_read_gtt_pte, 443316303Sjkim .read_gtt_pte_paddr = agp_i915_read_gtt_pte_paddr, 444316303Sjkim .set_aperture = agp_i915_set_aperture, 445316303Sjkim .chipset_flush_setup = agp_i965_chipset_flush_setup, 446316303Sjkim .chipset_flush_teardown = agp_i965_chipset_flush_teardown, 447316303Sjkim .chipset_flush = agp_i915_chipset_flush, 448272444Sjkim}; 449272444Sjkim 450272444Sjkimstatic const struct agp_i810_driver agp_i810_g4x_driver = { 451272444Sjkim .chiptype = CHIP_G4X, 45267754Smsmith .gen = 5, 45377424Smsmith .busdma_addr_mask_sz = 36, 45491116Smsmith .res_spec = agp_i965_res_spec, 45567754Smsmith .check_active = agp_i915_check_active, 45667754Smsmith .set_desc = agp_i810_set_desc, 457151937Sjkim .dump_regs = agp_i965_dump_regs, 458151937Sjkim .get_stolen_size = agp_i915_get_stolen_size, 459151937Sjkim .get_gtt_mappable_entries = agp_i915_get_gtt_mappable_entries, 460151937Sjkim .get_gtt_total_entries = agp_gen5_get_gtt_total_entries, 461151937Sjkim .install_gatt = agp_g4x_install_gatt, 462151937Sjkim .deinstall_gatt = agp_i830_deinstall_gatt, 46367754Smsmith .write_gtt = agp_g4x_write_gtt, 464151937Sjkim .install_gtt_pte = agp_g4x_install_gtt_pte, 465151937Sjkim .read_gtt_pte = agp_g4x_read_gtt_pte, 466151937Sjkim .read_gtt_pte_paddr = agp_i915_read_gtt_pte_paddr, 467151937Sjkim .set_aperture = agp_i915_set_aperture, 468151937Sjkim .chipset_flush_setup = agp_i965_chipset_flush_setup, 46967754Smsmith .chipset_flush_teardown = agp_i965_chipset_flush_teardown, 470151937Sjkim .chipset_flush = agp_i915_chipset_flush, 47167754Smsmith}; 47267754Smsmith 47377424Smsmith/* For adding new devices, devid is the id of the graphics controller 47467754Smsmith * (pci:0:2:0, for example). The placeholder (usually at pci:0:2:1) for the 47567754Smsmith * second head should never be added. The bridge_offset is the offset to 47667754Smsmith * subtract from devid to get the id of the hostb that the device is on. 47767754Smsmith */ 47867754Smsmithstatic const struct agp_i810_match { 47967754Smsmith int devid; 48077424Smsmith char *name; 48167754Smsmith const struct agp_i810_driver *driver; 48267754Smsmith} agp_i810_matches[] = { 48367754Smsmith { 48467754Smsmith .devid = 0x71218086, 48567754Smsmith .name = "Intel 82810 (i810 GMCH) SVGA controller", 48677424Smsmith .driver = &agp_i810_i810_driver 48767754Smsmith }, 48867754Smsmith { 48967754Smsmith .devid = 0x71238086, 49067754Smsmith .name = "Intel 82810-DC100 (i810-DC100 GMCH) SVGA controller", 49177424Smsmith .driver = &agp_i810_i810_driver 49267754Smsmith }, 49384491Smsmith { 49467754Smsmith .devid = 0x71258086, 49567754Smsmith .name = "Intel 82810E (i810E GMCH) SVGA controller", 49677424Smsmith .driver = &agp_i810_i810_driver 49767754Smsmith }, 49867754Smsmith { 49967754Smsmith .devid = 0x11328086, 50067754Smsmith .name = "Intel 82815 (i815 GMCH) SVGA controller", 50191116Smsmith .driver = &agp_i810_i815_driver 50291116Smsmith }, 50391116Smsmith { 50491116Smsmith .devid = 0x35778086, 50591116Smsmith .name = "Intel 82830M (830M GMCH) SVGA controller", 50691116Smsmith .driver = &agp_i810_i830_driver 50767754Smsmith }, 508151937Sjkim { 50967754Smsmith .devid = 0x25628086, 51067754Smsmith .name = "Intel 82845M (845M GMCH) SVGA controller", 51177424Smsmith .driver = &agp_i810_i830_driver 51267754Smsmith }, 51367754Smsmith { 51467754Smsmith .devid = 0x35828086, 51567754Smsmith .name = "Intel 82852/855GM SVGA controller", 51667754Smsmith .driver = &agp_i810_i855_driver 517151937Sjkim }, 51867754Smsmith { 51983174Smsmith .devid = 0x25728086, 52083174Smsmith .name = "Intel 82865G (865G GMCH) SVGA controller", 52167754Smsmith .driver = &agp_i810_i865_driver 52267754Smsmith }, 52367754Smsmith { 52483174Smsmith .devid = 0x25828086, 52583174Smsmith .name = "Intel 82915G (915G GMCH) SVGA controller", 52667754Smsmith .driver = &agp_i810_i915_driver 52767754Smsmith }, 52883174Smsmith { 52967754Smsmith .devid = 0x258A8086, 530151937Sjkim .name = "Intel E7221 SVGA controller", 531193267Sjkim .driver = &agp_i810_i915_driver 532151937Sjkim }, 53367754Smsmith { 53467754Smsmith .devid = 0x25928086, 53583174Smsmith .name = "Intel 82915GM (915GM GMCH) SVGA controller", 53667754Smsmith .driver = &agp_i810_i915_driver 537151937Sjkim }, 538193267Sjkim { 539151937Sjkim .devid = 0x27728086, 540298714Sjkim .name = "Intel 82945G (945G GMCH) SVGA controller", 54167754Smsmith .driver = &agp_i810_i915_driver 54267754Smsmith }, 54383174Smsmith { 54467754Smsmith .devid = 0x27A28086, 545151937Sjkim .name = "Intel 82945GM (945GM GMCH) SVGA controller", 546193267Sjkim .driver = &agp_i810_i915_driver 547151937Sjkim }, 54867754Smsmith { 54967754Smsmith .devid = 0x27AE8086, 55067754Smsmith .name = "Intel 945GME SVGA controller", 55183174Smsmith .driver = &agp_i810_i915_driver 55267754Smsmith }, 553151937Sjkim { 554193267Sjkim .devid = 0x29728086, 555151937Sjkim .name = "Intel 946GZ SVGA controller", 556298714Sjkim .driver = &agp_i810_g965_driver 55767754Smsmith }, 55867754Smsmith { 55983174Smsmith .devid = 0x29828086, 56067754Smsmith .name = "Intel G965 SVGA controller", 561151937Sjkim .driver = &agp_i810_g965_driver 562193267Sjkim }, 563151937Sjkim { 56467754Smsmith .devid = 0x29928086, 56567754Smsmith .name = "Intel Q965 SVGA controller", 56683174Smsmith .driver = &agp_i810_g965_driver 56767754Smsmith }, 568151937Sjkim { 569193267Sjkim .devid = 0x29A28086, 570151937Sjkim .name = "Intel G965 SVGA controller", 57167754Smsmith .driver = &agp_i810_g965_driver 57267754Smsmith }, 57367754Smsmith { 57483174Smsmith .devid = 0x29B28086, 57567754Smsmith .name = "Intel Q35 SVGA controller", 576151937Sjkim .driver = &agp_i810_g33_driver 577193267Sjkim }, 578151937Sjkim { 579202771Sjkim .devid = 0x29C28086, 58067754Smsmith .name = "Intel G33 SVGA controller", 58167754Smsmith .driver = &agp_i810_g33_driver 58283174Smsmith }, 58367754Smsmith { 584151937Sjkim .devid = 0x29D28086, 585193267Sjkim .name = "Intel Q33 SVGA controller", 586151937Sjkim .driver = &agp_i810_g33_driver 58767754Smsmith }, 58867754Smsmith { 58967754Smsmith .devid = 0xA0018086, 590298714Sjkim .name = "Intel Pineview SVGA controller", 591298714Sjkim .driver = &agp_i810_igd_driver 592298714Sjkim }, 593298714Sjkim { 594298714Sjkim .devid = 0xA0118086, 595298714Sjkim .name = "Intel Pineview (M) SVGA controller", 596298714Sjkim .driver = &agp_i810_igd_driver 597298714Sjkim }, 598241973Sjkim { 599167802Sjkim .devid = 0x2A028086, 600167802Sjkim .name = "Intel GM965 SVGA controller", 601167802Sjkim .driver = &agp_i810_g965_driver 602237412Sjkim }, 60367754Smsmith { 60467754Smsmith .devid = 0x2A128086, 605241973Sjkim .name = "Intel GME965 SVGA controller", 606167802Sjkim .driver = &agp_i810_g965_driver 607167802Sjkim }, 608241973Sjkim { 609241973Sjkim .devid = 0x2A428086, 610167802Sjkim .name = "Intel GM45 SVGA controller", 611272444Sjkim .driver = &agp_i810_g4x_driver 612167802Sjkim }, 613272444Sjkim { 614272444Sjkim .devid = 0x2E028086, 615272444Sjkim .name = "Intel Eaglelake SVGA controller", 616272444Sjkim .driver = &agp_i810_g4x_driver 617272444Sjkim }, 618272444Sjkim { 619272444Sjkim .devid = 0x2E128086, 620272444Sjkim .name = "Intel Q45 SVGA controller", 621272444Sjkim .driver = &agp_i810_g4x_driver 62283174Smsmith }, 623114237Snjl { 624167802Sjkim .devid = 0x2E228086, 62567754Smsmith .name = "Intel G45 SVGA controller", 62667754Smsmith .driver = &agp_i810_g4x_driver 627167802Sjkim }, 628114237Snjl { 629167802Sjkim .devid = 0x2E328086, 63067754Smsmith .name = "Intel G41 SVGA controller", 63167754Smsmith .driver = &agp_i810_g4x_driver 632167802Sjkim }, 633167802Sjkim { 634167802Sjkim .devid = 0x00428086, 63567754Smsmith .name = "Intel Ironlake (D) SVGA controller", 636285797Sjkim .driver = &agp_i810_g4x_driver 63767754Smsmith }, 638151937Sjkim { 63967754Smsmith .devid = 0x00468086, 640151937Sjkim .name = "Intel Ironlake (M) SVGA controller", 641151937Sjkim .driver = &agp_i810_g4x_driver 642151937Sjkim }, 64367754Smsmith { 64467754Smsmith .devid = 0, 645151937Sjkim } 64667754Smsmith}; 64767754Smsmith 64867754Smsmithstatic const struct agp_i810_match* 64977424Smsmithagp_i810_match(device_t dev) 65067754Smsmith{ 65167754Smsmith int i, devid; 65267754Smsmith 65377424Smsmith if (pci_get_class(dev) != PCIC_DISPLAY 65467754Smsmith || (pci_get_subclass(dev) != PCIS_DISPLAY_VGA && 65567754Smsmith pci_get_subclass(dev) != PCIS_DISPLAY_OTHER)) 65699679Siwasaki return (NULL); 65777424Smsmith 65867754Smsmith devid = pci_get_devid(dev); 65967754Smsmith for (i = 0; agp_i810_matches[i].devid != 0; i++) { 66067754Smsmith if (agp_i810_matches[i].devid == devid) 66167754Smsmith break; 662151937Sjkim } 66367754Smsmith if (agp_i810_matches[i].devid == 0) 66467754Smsmith return (NULL); 665114237Snjl else 666114237Snjl return (&agp_i810_matches[i]); 667298714Sjkim} 668114237Snjl 669114237Snjl/* 670114237Snjl * Find bridge device. 671114237Snjl */ 67277424Smsmithstatic device_t 673298714Sjkimagp_i810_find_bridge(device_t dev) 67467754Smsmith{ 675202771Sjkim 67667754Smsmith return (pci_find_dbsf(0, 0, 0, 0)); 67767754Smsmith} 678197104Sjkim 67967754Smsmithstatic void 680197104Sjkimagp_i810_identify(driver_t *driver, device_t parent) 68167754Smsmith{ 68267754Smsmith 683197104Sjkim if (device_find_child(parent, "agp", -1) == NULL && 68487031Smsmith agp_i810_match(parent)) 685197104Sjkim device_add_child(parent, "agp", -1); 686197104Sjkim} 687197104Sjkim 68887031Smsmithstatic int 689197104Sjkimagp_i810_check_active(device_t bridge_dev) 690197104Sjkim{ 691197104Sjkim u_int8_t smram; 692197104Sjkim 69387031Smsmith smram = pci_read_config(bridge_dev, AGP_I810_SMRAM, 1); 694197104Sjkim if ((smram & AGP_I810_SMRAM_GMS) == AGP_I810_SMRAM_GMS_DISABLED) 69567754Smsmith return (ENXIO); 696241973Sjkim return (0); 69767754Smsmith} 69867754Smsmith 69977424Smsmithstatic int 70067754Smsmithagp_i830_check_active(device_t bridge_dev) 701241973Sjkim{ 70267754Smsmith int gcc1; 703126372Snjl 704197104Sjkim gcc1 = pci_read_config(bridge_dev, AGP_I830_GCC1, 1); 705126372Snjl if ((gcc1 & AGP_I830_GCC1_DEV2) == AGP_I830_GCC1_DEV2_DISABLED) 706241973Sjkim return (ENXIO); 70767754Smsmith return (0); 708284583Sjkim} 709284583Sjkim 710284583Sjkimstatic int 711284583Sjkimagp_i915_check_active(device_t bridge_dev) 712197104Sjkim{ 713284583Sjkim int deven; 714193267Sjkim 715193267Sjkim deven = pci_read_config(bridge_dev, AGP_I915_DEVEN, 4); 716193267Sjkim if ((deven & AGP_I915_DEVEN_D2F0) == AGP_I915_DEVEN_D2F0_DISABLED) 717193267Sjkim return (ENXIO); 718193267Sjkim return (0); 719193267Sjkim} 72067754Smsmith 721193267Sjkimstatic void 722193267Sjkimagp_82852_set_desc(device_t dev, const struct agp_i810_match *match) 723193267Sjkim{ 724193267Sjkim 725193267Sjkim switch (pci_read_config(dev, AGP_I85X_CAPID, 1)) { 726193267Sjkim case AGP_I855_GME: 727193267Sjkim device_set_desc(dev, 728193267Sjkim "Intel 82855GME (855GME GMCH) SVGA controller"); 729193267Sjkim break; 730193267Sjkim case AGP_I855_GM: 731193267Sjkim device_set_desc(dev, 732193267Sjkim "Intel 82855GM (855GM GMCH) SVGA controller"); 733193267Sjkim break; 734193267Sjkim case AGP_I852_GME: 735193267Sjkim device_set_desc(dev, 736193267Sjkim "Intel 82852GME (852GME GMCH) SVGA controller"); 737193267Sjkim break; 738193267Sjkim case AGP_I852_GM: 739193267Sjkim device_set_desc(dev, 740193267Sjkim "Intel 82852GM (852GM GMCH) SVGA controller"); 741193267Sjkim break; 74267754Smsmith default: 743151937Sjkim device_set_desc(dev, 74467754Smsmith "Intel 8285xM (85xGM GMCH) SVGA controller"); 74583174Smsmith break; 74683174Smsmith } 747193267Sjkim} 74883174Smsmith 74983174Smsmithstatic void 75091116Smsmithagp_i810_set_desc(device_t dev, const struct agp_i810_match *match) 75183174Smsmith{ 75267754Smsmith 75383174Smsmith device_set_desc(dev, match->name); 754193267Sjkim} 75567754Smsmith 75667754Smsmithstatic int 75767754Smsmithagp_i810_probe(device_t dev) 758151937Sjkim{ 759151937Sjkim device_t bdev; 76067754Smsmith const struct agp_i810_match *match; 76167754Smsmith int err; 76277424Smsmith 76367754Smsmith if (resource_disabled("agp", device_get_unit(dev))) 76467754Smsmith return (ENXIO); 76567754Smsmith match = agp_i810_match(dev); 76677424Smsmith if (match == NULL) 76767754Smsmith return (ENXIO); 76867754Smsmith 769107325Siwasaki bdev = agp_i810_find_bridge(dev); 770193267Sjkim if (bdev == NULL) { 771193267Sjkim if (bootverbose) 772193267Sjkim printf("I810: can't find bridge device\n"); 773193267Sjkim return (ENXIO); 774199337Sjkim } 775199337Sjkim 776199337Sjkim /* 777199337Sjkim * checking whether internal graphics device has been activated. 778107325Siwasaki */ 779107325Siwasaki err = match->driver->check_active(bdev); 78067754Smsmith if (err != 0) { 781138287Smarks if (bootverbose) 782138287Smarks printf("i810: disabled, not probing\n"); 783138287Smarks return (err); 784107325Siwasaki } 78567754Smsmith 78677424Smsmith match->driver->set_desc(dev, match); 78767754Smsmith return (BUS_PROBE_DEFAULT); 78891116Smsmith} 78967754Smsmith 79067754Smsmithstatic void 79167754Smsmithagp_i810_dump_regs(device_t dev) 792210976Sjkim{ 793210976Sjkim struct agp_i810_softc *sc = device_get_softc(dev); 794210976Sjkim 795210976Sjkim device_printf(dev, "AGP_I810_PGTBL_CTL: %08x\n", 796210976Sjkim bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL)); 797210976Sjkim device_printf(dev, "AGP_I810_MISCC: 0x%04x\n", 798249112Sjkim pci_read_config(sc->bdev, AGP_I810_MISCC, 2)); 799210976Sjkim} 800210976Sjkim 801210976Sjkimstatic void 802210976Sjkimagp_i830_dump_regs(device_t dev) 803210976Sjkim{ 804210976Sjkim struct agp_i810_softc *sc = device_get_softc(dev); 805210976Sjkim 806210976Sjkim device_printf(dev, "AGP_I810_PGTBL_CTL: %08x\n", 807210976Sjkim bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL)); 808210976Sjkim device_printf(dev, "AGP_I830_GCC1: 0x%02x\n", 809210976Sjkim pci_read_config(sc->bdev, AGP_I830_GCC1, 1)); 810253690Sjkim} 811253690Sjkim 812253690Sjkimstatic void 813253690Sjkimagp_i855_dump_regs(device_t dev) 814210976Sjkim{ 815210976Sjkim struct agp_i810_softc *sc = device_get_softc(dev); 816210976Sjkim 817210976Sjkim device_printf(dev, "AGP_I810_PGTBL_CTL: %08x\n", 818210976Sjkim bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL)); 819210976Sjkim device_printf(dev, "AGP_I855_GCC1: 0x%02x\n", 820210976Sjkim pci_read_config(sc->bdev, AGP_I855_GCC1, 1)); 821210976Sjkim} 822210976Sjkim 823210976Sjkimstatic void 824249112Sjkimagp_i915_dump_regs(device_t dev) 825249112Sjkim{ 826249112Sjkim struct agp_i810_softc *sc = device_get_softc(dev); 827249112Sjkim 828249112Sjkim device_printf(dev, "AGP_I810_PGTBL_CTL: %08x\n", 829249112Sjkim bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL)); 830249112Sjkim device_printf(dev, "AGP_I855_GCC1: 0x%02x\n", 831249112Sjkim pci_read_config(sc->bdev, AGP_I855_GCC1, 1)); 832249112Sjkim device_printf(dev, "AGP_I915_MSAC: 0x%02x\n", 833249112Sjkim pci_read_config(sc->bdev, AGP_I915_MSAC, 1)); 834281396Sjkim} 835281396Sjkim 836281396Sjkimstatic void 837281396Sjkimagp_i965_dump_regs(device_t dev) 838281396Sjkim{ 839281396Sjkim struct agp_i810_softc *sc = device_get_softc(dev); 840249112Sjkim 841249112Sjkim device_printf(dev, "AGP_I965_PGTBL_CTL2: %08x\n", 842249112Sjkim bus_read_4(sc->sc_res[0], AGP_I965_PGTBL_CTL2)); 843249112Sjkim device_printf(dev, "AGP_I855_GCC1: 0x%02x\n", 844249112Sjkim pci_read_config(sc->bdev, AGP_I855_GCC1, 1)); 845249112Sjkim device_printf(dev, "AGP_I965_MSAC: 0x%02x\n", 846249112Sjkim pci_read_config(sc->bdev, AGP_I965_MSAC, 1)); 847249112Sjkim} 848249112Sjkim 849249112Sjkimstatic int 850249112Sjkimagp_i810_get_stolen_size(device_t dev) 851249112Sjkim{ 852249112Sjkim struct agp_i810_softc *sc; 853249112Sjkim 854281396Sjkim sc = device_get_softc(dev); 855249112Sjkim sc->stolen = 0; 856249112Sjkim sc->stolen_size = 0; 857249112Sjkim return (0); 858151937Sjkim} 85967754Smsmith 86067754Smsmithstatic int 86177424Smsmithagp_i830_get_stolen_size(device_t dev) 86267754Smsmith{ 86367754Smsmith struct agp_i810_softc *sc; 86467754Smsmith unsigned int gcc1; 86567754Smsmith 86677424Smsmith sc = device_get_softc(dev); 86767754Smsmith 86867754Smsmith gcc1 = pci_read_config(sc->bdev, AGP_I830_GCC1, 1); 86967754Smsmith switch (gcc1 & AGP_I830_GCC1_GMS) { 87067754Smsmith case AGP_I830_GCC1_GMS_STOLEN_512: 87177424Smsmith sc->stolen = (512 - 132) * 1024 / 4096; 87267754Smsmith sc->stolen_size = 512 * 1024; 87367754Smsmith break; 87487031Smsmith case AGP_I830_GCC1_GMS_STOLEN_1024: 87587031Smsmith sc->stolen = (1024 - 132) * 1024 / 4096; 87687031Smsmith sc->stolen_size = 1024 * 1024; 87787031Smsmith break; 87867754Smsmith case AGP_I830_GCC1_GMS_STOLEN_8192: 87977424Smsmith sc->stolen = (8192 - 132) * 1024 / 4096; 88067754Smsmith sc->stolen_size = 8192 * 1024; 88167754Smsmith break; 88267754Smsmith default: 88373561Smsmith sc->stolen = 0; 88477424Smsmith device_printf(dev, 88573561Smsmith "unknown memory configuration, disabling (GCC1 %x)\n", 88673561Smsmith gcc1); 887322877Sjkim return (EINVAL); 88873561Smsmith } 88967754Smsmith return (0); 89077424Smsmith} 89167754Smsmith 89267754Smsmithstatic int 89367754Smsmithagp_i915_get_stolen_size(device_t dev) 89467754Smsmith{ 89567754Smsmith struct agp_i810_softc *sc; 89677424Smsmith unsigned int gcc1, stolen, gtt_size; 89767754Smsmith 89867754Smsmith sc = device_get_softc(dev); 89967754Smsmith 90077424Smsmith /* 90167754Smsmith * Stolen memory is set up at the beginning of the aperture by 90267754Smsmith * the BIOS, consisting of the GATT followed by 4kb for the 90367754Smsmith * BIOS display. 90467754Smsmith */ 905151937Sjkim switch (sc->match->driver->chiptype) { 90667754Smsmith case CHIP_I855: 90784491Smsmith gtt_size = 128; 90884491Smsmith break; 909202771Sjkim case CHIP_I915: 910202771Sjkim gtt_size = 256; 911202771Sjkim break; 912202771Sjkim case CHIP_I965: 91384491Smsmith switch (bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL) & 91484491Smsmith AGP_I810_PGTBL_SIZE_MASK) { 91584491Smsmith case AGP_I810_PGTBL_SIZE_128KB: 916202771Sjkim gtt_size = 128; 91784491Smsmith break; 918202771Sjkim case AGP_I810_PGTBL_SIZE_256KB: 91984491Smsmith gtt_size = 256; 92084491Smsmith break; 921322877Sjkim case AGP_I810_PGTBL_SIZE_512KB: 922322877Sjkim gtt_size = 512; 923322877Sjkim break; 924322877Sjkim case AGP_I965_PGTBL_SIZE_1MB: 925322877Sjkim gtt_size = 1024; 926246849Sjkim break; 927322877Sjkim case AGP_I965_PGTBL_SIZE_2MB: 928322877Sjkim gtt_size = 2048; 929322877Sjkim break; 930322877Sjkim case AGP_I965_PGTBL_SIZE_1_5MB: 931322877Sjkim gtt_size = 1024 + 512; 932322877Sjkim break; 933322877Sjkim default: 934322877Sjkim device_printf(dev, "Bad PGTBL size\n"); 935322877Sjkim return (EINVAL); 936322877Sjkim } 937322877Sjkim break; 938322877Sjkim case CHIP_G33: 939322877Sjkim gcc1 = pci_read_config(sc->bdev, AGP_I855_GCC1, 2); 940151937Sjkim switch (gcc1 & AGP_G33_MGGC_GGMS_MASK) { 941151937Sjkim case AGP_G33_MGGC_GGMS_SIZE_1M: 942151937Sjkim gtt_size = 1024; 943246849Sjkim break; 944167802Sjkim case AGP_G33_MGGC_GGMS_SIZE_2M: 945167802Sjkim gtt_size = 2048; 946167802Sjkim break; 947167802Sjkim default: 948197104Sjkim device_printf(dev, "Bad PGTBL size\n"); 949197104Sjkim return (EINVAL); 950197104Sjkim } 951287168Sjkim break; 952197104Sjkim case CHIP_IGD: 953167802Sjkim case CHIP_G4X: 954167802Sjkim gtt_size = 0; 955281396Sjkim break; 956167802Sjkim default: 957151937Sjkim device_printf(dev, "Bad chiptype\n"); 958151937Sjkim return (EINVAL); 959151937Sjkim } 960151937Sjkim 961151937Sjkim /* GCC1 is called MGGC on i915+ */ 962151937Sjkim gcc1 = pci_read_config(sc->bdev, AGP_I855_GCC1, 1); 963151937Sjkim switch (gcc1 & AGP_I855_GCC1_GMS) { 964138287Smarks case AGP_I855_GCC1_GMS_STOLEN_1M: 965138287Smarks stolen = 1024; 966138287Smarks break; 967138287Smarks case AGP_I855_GCC1_GMS_STOLEN_4M: 968285797Sjkim stolen = 4 * 1024; 969151937Sjkim break; 97099679Siwasaki case AGP_I855_GCC1_GMS_STOLEN_8M: 97199679Siwasaki stolen = 8 * 1024; 97299679Siwasaki break; 97399679Siwasaki case AGP_I855_GCC1_GMS_STOLEN_16M: 97499679Siwasaki stolen = 16 * 1024; 97599679Siwasaki break; 97699679Siwasaki case AGP_I855_GCC1_GMS_STOLEN_32M: 977102550Siwasaki stolen = 32 * 1024; 97873561Smsmith break; 97977424Smsmith case AGP_I915_GCC1_GMS_STOLEN_48M: 980114237Snjl stolen = sc->match->driver->gen > 2 ? 48 * 1024 : 0; 981114237Snjl break; 982298714Sjkim case AGP_I915_GCC1_GMS_STOLEN_64M: 98373561Smsmith stolen = sc->match->driver->gen > 2 ? 64 * 1024 : 0; 98473561Smsmith break; 98573561Smsmith case AGP_G33_GCC1_GMS_STOLEN_128M: 98667754Smsmith stolen = sc->match->driver->gen > 2 ? 128 * 1024 : 0; 987245582Sjkim break; 988245582Sjkim case AGP_G33_GCC1_GMS_STOLEN_256M: 989245582Sjkim stolen = sc->match->driver->gen > 2 ? 256 * 1024 : 0; 990245582Sjkim break; 991245582Sjkim case AGP_G4X_GCC1_GMS_STOLEN_96M: 992245582Sjkim if (sc->match->driver->chiptype == CHIP_I965 || 993245582Sjkim sc->match->driver->chiptype == CHIP_G4X) 994245582Sjkim stolen = 96 * 1024; 995245582Sjkim else 996245582Sjkim stolen = 0; 997245582Sjkim break; 998245582Sjkim case AGP_G4X_GCC1_GMS_STOLEN_160M: 999167802Sjkim if (sc->match->driver->chiptype == CHIP_I965 || 1000167802Sjkim sc->match->driver->chiptype == CHIP_G4X) 1001167802Sjkim stolen = 160 * 1024; 1002167802Sjkim else 1003243347Sjkim stolen = 0; 1004167802Sjkim break; 1005167802Sjkim case AGP_G4X_GCC1_GMS_STOLEN_224M: 1006167802Sjkim if (sc->match->driver->chiptype == CHIP_I965 || 1007245582Sjkim sc->match->driver->chiptype == CHIP_G4X) 1008167802Sjkim stolen = 224 * 1024; 1009167802Sjkim else 1010167802Sjkim stolen = 0; 1011243347Sjkim break; 1012167802Sjkim case AGP_G4X_GCC1_GMS_STOLEN_352M: 1013167802Sjkim if (sc->match->driver->chiptype == CHIP_I965 || 1014167802Sjkim sc->match->driver->chiptype == CHIP_G4X) 1015167802Sjkim stolen = 352 * 1024; 1016167802Sjkim else 1017167802Sjkim stolen = 0; 1018167802Sjkim break; 1019167802Sjkim default: 1020167802Sjkim device_printf(dev, 1021167802Sjkim "unknown memory configuration, disabling (GCC1 %x)\n", 1022167802Sjkim gcc1); 1023167802Sjkim return (EINVAL); 1024167802Sjkim } 1025167802Sjkim 1026167802Sjkim gtt_size += 4; 1027167802Sjkim sc->stolen_size = stolen * 1024; 1028167802Sjkim sc->stolen = (stolen - gtt_size) * 1024 / 4096; 1029167802Sjkim 1030167802Sjkim return (0); 1031167802Sjkim} 1032167802Sjkim 1033167802Sjkimstatic int 1034167802Sjkimagp_i810_get_gtt_mappable_entries(device_t dev) 1035167802Sjkim{ 1036167802Sjkim struct agp_i810_softc *sc; 1037167802Sjkim uint32_t ap; 1038245582Sjkim uint16_t miscc; 1039245582Sjkim 1040245582Sjkim sc = device_get_softc(dev); 1041245582Sjkim miscc = pci_read_config(sc->bdev, AGP_I810_MISCC, 2); 1042245582Sjkim if ((miscc & AGP_I810_MISCC_WINSIZE) == AGP_I810_MISCC_WINSIZE_32) 1043252279Sjkim ap = 32; 1044245582Sjkim else 1045281396Sjkim ap = 64; 1046245582Sjkim sc->gtt_mappable_entries = (ap * 1024 * 1024) >> AGP_PAGE_SHIFT; 1047245582Sjkim return (0); 1048245582Sjkim} 1049281396Sjkim 1050245582Sjkimstatic int 1051245582Sjkimagp_i830_get_gtt_mappable_entries(device_t dev) 1052245582Sjkim{ 1053245582Sjkim struct agp_i810_softc *sc; 1054245582Sjkim uint32_t ap; 1055272444Sjkim uint16_t gmch_ctl; 1056272444Sjkim 1057272444Sjkim sc = device_get_softc(dev); 1058272444Sjkim gmch_ctl = pci_read_config(sc->bdev, AGP_I830_GCC1, 2); 1059272444Sjkim if ((gmch_ctl & AGP_I830_GCC1_GMASIZE) == AGP_I830_GCC1_GMASIZE_64) 1060272444Sjkim ap = 64; 1061245582Sjkim else 1062327557Sjkim ap = 128; 1063327557Sjkim sc->gtt_mappable_entries = (ap * 1024 * 1024) >> AGP_PAGE_SHIFT; 1064327557Sjkim return (0); 1065327557Sjkim} 1066327557Sjkim 1067327557Sjkimstatic int 1068272444Sjkimagp_i915_get_gtt_mappable_entries(device_t dev) 1069272444Sjkim{ 1070272444Sjkim struct agp_i810_softc *sc; 1071272444Sjkim uint32_t ap; 1072272444Sjkim 1073298714Sjkim sc = device_get_softc(dev); 1074298714Sjkim ap = AGP_GET_APERTURE(dev); 1075298714Sjkim sc->gtt_mappable_entries = ap >> AGP_PAGE_SHIFT; 1076298714Sjkim return (0); 1077298714Sjkim} 1078298714Sjkim 1079298714Sjkimstatic int 1080272444Sjkimagp_i810_get_gtt_total_entries(device_t dev) 1081272444Sjkim{ 1082272444Sjkim struct agp_i810_softc *sc; 1083245582Sjkim 1084151937Sjkim sc = device_get_softc(dev); 108567754Smsmith sc->gtt_total_entries = sc->gtt_mappable_entries; 1086151937Sjkim return (0); 1087151937Sjkim} 1088151937Sjkim 108967754Smsmithstatic int 109082367Smsmithagp_i965_get_gtt_total_entries(device_t dev) 1091151937Sjkim{ 1092151937Sjkim struct agp_i810_softc *sc; 109382367Smsmith uint32_t pgetbl_ctl; 1094151937Sjkim int error; 1095151937Sjkim 1096151937Sjkim sc = device_get_softc(dev); 109782367Smsmith error = 0; 109891116Smsmith pgetbl_ctl = bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL); 1099151937Sjkim switch (pgetbl_ctl & AGP_I810_PGTBL_SIZE_MASK) { 1100151937Sjkim case AGP_I810_PGTBL_SIZE_128KB: 1101151937Sjkim sc->gtt_total_entries = 128 * 1024 / 4; 1102151937Sjkim break; 1103151937Sjkim case AGP_I810_PGTBL_SIZE_256KB: 1104151937Sjkim sc->gtt_total_entries = 256 * 1024 / 4; 1105151937Sjkim break; 1106151937Sjkim case AGP_I810_PGTBL_SIZE_512KB: 1107151937Sjkim sc->gtt_total_entries = 512 * 1024 / 4; 1108151937Sjkim break; 1109151937Sjkim /* GTT pagetable sizes bigger than 512KB are not possible on G33! */ 1110151937Sjkim case AGP_I810_PGTBL_SIZE_1MB: 1111151937Sjkim sc->gtt_total_entries = 1024 * 1024 / 4; 1112151937Sjkim break; 1113151937Sjkim case AGP_I810_PGTBL_SIZE_2MB: 1114151937Sjkim sc->gtt_total_entries = 2 * 1024 * 1024 / 4; 111591116Smsmith break; 111691116Smsmith case AGP_I810_PGTBL_SIZE_1_5MB: 111782367Smsmith sc->gtt_total_entries = (1024 + 512) * 1024 / 4; 111891116Smsmith break; 111991116Smsmith default: 112091116Smsmith device_printf(dev, "Unknown page table size\n"); 112191116Smsmith error = ENXIO; 112282367Smsmith } 112391116Smsmith return (error); 112491116Smsmith} 112591116Smsmith 112691116Smsmithstatic void 112791116Smsmithagp_gen5_adjust_pgtbl_size(device_t dev, uint32_t sz) 1128193267Sjkim{ 112991116Smsmith struct agp_i810_softc *sc; 113091116Smsmith uint32_t pgetbl_ctl, pgetbl_ctl2; 113191116Smsmith 1132167802Sjkim sc = device_get_softc(dev); 113391116Smsmith 113491116Smsmith /* Disable per-process page table. */ 1135193267Sjkim pgetbl_ctl2 = bus_read_4(sc->sc_res[0], AGP_I965_PGTBL_CTL2); 113691116Smsmith pgetbl_ctl2 &= ~AGP_I810_PGTBL_ENABLED; 113791116Smsmith bus_write_4(sc->sc_res[0], AGP_I965_PGTBL_CTL2, pgetbl_ctl2); 113867754Smsmith 113991116Smsmith /* Write the new ggtt size. */ 114067754Smsmith pgetbl_ctl = bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL); 114167754Smsmith pgetbl_ctl &= ~AGP_I810_PGTBL_SIZE_MASK; 1142193267Sjkim pgetbl_ctl |= sz; 114367754Smsmith bus_write_4(sc->sc_res[0], AGP_I810_PGTBL_CTL, pgetbl_ctl); 114499679Siwasaki} 114567754Smsmith 114677424Smsmithstatic int 114767754Smsmithagp_gen5_get_gtt_total_entries(device_t dev) 114867754Smsmith{ 114967754Smsmith struct agp_i810_softc *sc; 115084491Smsmith uint16_t gcc1; 115167754Smsmith 1152193267Sjkim sc = device_get_softc(dev); 1153167802Sjkim 1154167802Sjkim gcc1 = pci_read_config(sc->bdev, AGP_I830_GCC1, 2); 1155167802Sjkim switch (gcc1 & AGP_G4x_GCC1_SIZE_MASK) { 1156298714Sjkim case AGP_G4x_GCC1_SIZE_1M: 1157167802Sjkim case AGP_G4x_GCC1_SIZE_VT_1M: 1158167802Sjkim agp_gen5_adjust_pgtbl_size(dev, AGP_I810_PGTBL_SIZE_1MB); 1159167802Sjkim break; 1160212761Sjkim case AGP_G4x_GCC1_SIZE_VT_1_5M: 1161167802Sjkim agp_gen5_adjust_pgtbl_size(dev, AGP_I810_PGTBL_SIZE_1_5MB); 1162285797Sjkim break; 1163229989Sjkim case AGP_G4x_GCC1_SIZE_2M: 1164229989Sjkim case AGP_G4x_GCC1_SIZE_VT_2M: 1165229989Sjkim agp_gen5_adjust_pgtbl_size(dev, AGP_I810_PGTBL_SIZE_2MB); 1166229989Sjkim break; 1167229989Sjkim default: 1168229989Sjkim device_printf(dev, "Unknown page table size\n"); 1169229989Sjkim return (ENXIO); 1170229989Sjkim } 1171229989Sjkim 117267754Smsmith return (agp_i965_get_gtt_total_entries(dev)); 1173229989Sjkim} 1174229989Sjkim 1175229989Sjkimstatic int 1176229989Sjkimagp_i810_install_gatt(device_t dev) 1177229989Sjkim{ 1178229989Sjkim struct agp_i810_softc *sc; 1179229989Sjkim 1180229989Sjkim sc = device_get_softc(dev); 1181229989Sjkim 1182229989Sjkim /* Some i810s have on-chip memory called dcache. */ 1183229989Sjkim if ((bus_read_1(sc->sc_res[0], AGP_I810_DRT) & AGP_I810_DRT_POPULATED) 1184229989Sjkim != 0) 1185229989Sjkim sc->dcache_size = 4 * 1024 * 1024; 1186229989Sjkim else 1187229989Sjkim sc->dcache_size = 0; 1188229989Sjkim 1189285797Sjkim /* According to the specs the gatt on the i810 must be 64k. */ 1190212761Sjkim sc->gatt->ag_virtual = (void *)kmem_alloc_contig(kernel_arena, 1191212761Sjkim 64 * 1024, M_NOWAIT | M_ZERO, 0, ~0, PAGE_SIZE, 1192212761Sjkim 0, VM_MEMATTR_WRITE_COMBINING); 1193212761Sjkim if (sc->gatt->ag_virtual == NULL) { 1194212761Sjkim if (bootverbose) 1195212761Sjkim device_printf(dev, "contiguous allocation failed\n"); 1196212761Sjkim return (ENOMEM); 1197212761Sjkim } 1198212761Sjkim 1199212761Sjkim sc->gatt->ag_physical = vtophys((vm_offset_t)sc->gatt->ag_virtual); 1200212761Sjkim /* Install the GATT. */ 1201212761Sjkim bus_write_4(sc->sc_res[0], AGP_I810_PGTBL_CTL, 1202212761Sjkim sc->gatt->ag_physical | 1); 1203212761Sjkim return (0); 1204212761Sjkim} 1205212761Sjkim 1206212761Sjkimstatic void 1207212761Sjkimagp_i830_install_gatt_init(struct agp_i810_softc *sc) 1208212761Sjkim{ 1209212761Sjkim uint32_t pgtblctl; 1210212761Sjkim 1211249663Sjkim /* 1212249663Sjkim * The i830 automatically initializes the 128k gatt on boot. 1213249663Sjkim * GATT address is already in there, make sure it's enabled. 1214249663Sjkim */ 1215249663Sjkim pgtblctl = bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL); 1216249663Sjkim pgtblctl |= 1; 1217249663Sjkim bus_write_4(sc->sc_res[0], AGP_I810_PGTBL_CTL, pgtblctl); 1218249663Sjkim 1219249663Sjkim sc->gatt->ag_physical = pgtblctl & ~1; 1220212761Sjkim} 1221327557Sjkim 1222212761Sjkimstatic int 1223212761Sjkimagp_i830_install_gatt(device_t dev) 1224327557Sjkim{ 1225212761Sjkim struct agp_i810_softc *sc; 1226212761Sjkim 1227212761Sjkim sc = device_get_softc(dev); 1228212761Sjkim agp_i830_install_gatt_init(sc); 1229212761Sjkim return (0); 1230212761Sjkim} 1231212761Sjkim 1232212761Sjkimstatic int 1233212761Sjkimagp_gen4_install_gatt(device_t dev, const vm_size_t gtt_offset) 1234212761Sjkim{ 1235212761Sjkim struct agp_i810_softc *sc; 1236212761Sjkim 1237285797Sjkim sc = device_get_softc(dev); 1238272444Sjkim pmap_change_attr((vm_offset_t)rman_get_virtual(sc->sc_res[0]) + 1239272444Sjkim gtt_offset, rman_get_size(sc->sc_res[0]) - gtt_offset, 1240272444Sjkim VM_MEMATTR_WRITE_COMBINING); 1241272444Sjkim agp_i830_install_gatt_init(sc); 1242272444Sjkim return (0); 1243272444Sjkim} 1244272444Sjkim 1245272444Sjkimstatic int 1246272444Sjkimagp_i965_install_gatt(device_t dev) 1247272444Sjkim{ 1248272444Sjkim 1249272444Sjkim return (agp_gen4_install_gatt(dev, 512 * 1024)); 1250272444Sjkim} 1251272444Sjkim 1252272444Sjkimstatic int 1253285797Sjkimagp_g4x_install_gatt(device_t dev) 1254272444Sjkim{ 1255272444Sjkim 1256272444Sjkim return (agp_gen4_install_gatt(dev, 2 * 1024 * 1024)); 1257281396Sjkim} 1258272444Sjkim 1259272444Sjkimstatic int 1260272444Sjkimagp_i810_attach(device_t dev) 1261272444Sjkim{ 1262281396Sjkim struct agp_i810_softc *sc; 1263272444Sjkim int error; 126477424Smsmith 1265 sc = device_get_softc(dev); 1266 sc->bdev = agp_i810_find_bridge(dev); 1267 if (sc->bdev == NULL) 1268 return (ENOENT); 1269 1270 sc->match = agp_i810_match(dev); 1271 1272 agp_set_aperture_resource(dev, sc->match->driver->gen <= 2 ? 1273 AGP_APBASE : AGP_I915_GMADR); 1274 error = agp_generic_attach(dev); 1275 if (error) 1276 return (error); 1277 1278 if (ptoa((vm_paddr_t)Maxmem) > 1279 (1ULL << sc->match->driver->busdma_addr_mask_sz) - 1) { 1280 device_printf(dev, "agp_i810 does not support physical " 1281 "memory above %ju.\n", (uintmax_t)(1ULL << 1282 sc->match->driver->busdma_addr_mask_sz) - 1); 1283 return (ENOENT); 1284 } 1285 1286 if (bus_alloc_resources(dev, sc->match->driver->res_spec, sc->sc_res)) { 1287 agp_generic_detach(dev); 1288 return (ENODEV); 1289 } 1290 1291 sc->initial_aperture = AGP_GET_APERTURE(dev); 1292 sc->gatt = malloc(sizeof(struct agp_gatt), M_AGP, M_WAITOK); 1293 sc->gatt->ag_entries = AGP_GET_APERTURE(dev) >> AGP_PAGE_SHIFT; 1294 1295 if ((error = sc->match->driver->get_stolen_size(dev)) != 0 || 1296 (error = sc->match->driver->install_gatt(dev)) != 0 || 1297 (error = sc->match->driver->get_gtt_mappable_entries(dev)) != 0 || 1298 (error = sc->match->driver->get_gtt_total_entries(dev)) != 0 || 1299 (error = sc->match->driver->chipset_flush_setup(dev)) != 0) { 1300 bus_release_resources(dev, sc->match->driver->res_spec, 1301 sc->sc_res); 1302 free(sc->gatt, M_AGP); 1303 agp_generic_detach(dev); 1304 return (error); 1305 } 1306 1307 intel_agp = dev; 1308 device_printf(dev, "aperture size is %dM", 1309 sc->initial_aperture / 1024 / 1024); 1310 if (sc->stolen > 0) 1311 printf(", detected %dk stolen memory\n", sc->stolen * 4); 1312 else 1313 printf("\n"); 1314 if (bootverbose) { 1315 sc->match->driver->dump_regs(dev); 1316 device_printf(dev, "Mappable GTT entries: %d\n", 1317 sc->gtt_mappable_entries); 1318 device_printf(dev, "Total GTT entries: %d\n", 1319 sc->gtt_total_entries); 1320 } 1321 return (0); 1322} 1323 1324static void 1325agp_i810_deinstall_gatt(device_t dev) 1326{ 1327 struct agp_i810_softc *sc; 1328 1329 sc = device_get_softc(dev); 1330 bus_write_4(sc->sc_res[0], AGP_I810_PGTBL_CTL, 0); 1331 kmem_free(kernel_arena, (vm_offset_t)sc->gatt->ag_virtual, 64 * 1024); 1332} 1333 1334static void 1335agp_i830_deinstall_gatt(device_t dev) 1336{ 1337 struct agp_i810_softc *sc; 1338 unsigned int pgtblctl; 1339 1340 sc = device_get_softc(dev); 1341 pgtblctl = bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL); 1342 pgtblctl &= ~1; 1343 bus_write_4(sc->sc_res[0], AGP_I810_PGTBL_CTL, pgtblctl); 1344} 1345 1346static int 1347agp_i810_detach(device_t dev) 1348{ 1349 struct agp_i810_softc *sc; 1350 1351 sc = device_get_softc(dev); 1352 agp_free_cdev(dev); 1353 1354 /* Clear the GATT base. */ 1355 sc->match->driver->deinstall_gatt(dev); 1356 1357 sc->match->driver->chipset_flush_teardown(dev); 1358 1359 /* Put the aperture back the way it started. */ 1360 AGP_SET_APERTURE(dev, sc->initial_aperture); 1361 1362 free(sc->gatt, M_AGP); 1363 bus_release_resources(dev, sc->match->driver->res_spec, sc->sc_res); 1364 agp_free_res(dev); 1365 1366 return (0); 1367} 1368 1369static int 1370agp_i810_resume(device_t dev) 1371{ 1372 struct agp_i810_softc *sc; 1373 sc = device_get_softc(dev); 1374 1375 AGP_SET_APERTURE(dev, sc->initial_aperture); 1376 1377 /* Install the GATT. */ 1378 bus_write_4(sc->sc_res[0], AGP_I810_PGTBL_CTL, 1379 sc->gatt->ag_physical | 1); 1380 1381 return (bus_generic_resume(dev)); 1382} 1383 1384/** 1385 * Sets the PCI resource size of the aperture on i830-class and below chipsets, 1386 * while returning failure on later chipsets when an actual change is 1387 * requested. 1388 * 1389 * This whole function is likely bogus, as the kernel would probably need to 1390 * reconfigure the placement of the AGP aperture if a larger size is requested, 1391 * which doesn't happen currently. 1392 */ 1393static int 1394agp_i810_set_aperture(device_t dev, u_int32_t aperture) 1395{ 1396 struct agp_i810_softc *sc; 1397 u_int16_t miscc; 1398 1399 sc = device_get_softc(dev); 1400 /* 1401 * Double check for sanity. 1402 */ 1403 if (aperture != 32 * 1024 * 1024 && aperture != 64 * 1024 * 1024) { 1404 device_printf(dev, "bad aperture size %d\n", aperture); 1405 return (EINVAL); 1406 } 1407 1408 miscc = pci_read_config(sc->bdev, AGP_I810_MISCC, 2); 1409 miscc &= ~AGP_I810_MISCC_WINSIZE; 1410 if (aperture == 32 * 1024 * 1024) 1411 miscc |= AGP_I810_MISCC_WINSIZE_32; 1412 else 1413 miscc |= AGP_I810_MISCC_WINSIZE_64; 1414 1415 pci_write_config(sc->bdev, AGP_I810_MISCC, miscc, 2); 1416 return (0); 1417} 1418 1419static int 1420agp_i830_set_aperture(device_t dev, u_int32_t aperture) 1421{ 1422 struct agp_i810_softc *sc; 1423 u_int16_t gcc1; 1424 1425 sc = device_get_softc(dev); 1426 1427 if (aperture != 64 * 1024 * 1024 && 1428 aperture != 128 * 1024 * 1024) { 1429 device_printf(dev, "bad aperture size %d\n", aperture); 1430 return (EINVAL); 1431 } 1432 gcc1 = pci_read_config(sc->bdev, AGP_I830_GCC1, 2); 1433 gcc1 &= ~AGP_I830_GCC1_GMASIZE; 1434 if (aperture == 64 * 1024 * 1024) 1435 gcc1 |= AGP_I830_GCC1_GMASIZE_64; 1436 else 1437 gcc1 |= AGP_I830_GCC1_GMASIZE_128; 1438 1439 pci_write_config(sc->bdev, AGP_I830_GCC1, gcc1, 2); 1440 return (0); 1441} 1442 1443static int 1444agp_i915_set_aperture(device_t dev, u_int32_t aperture) 1445{ 1446 1447 return (agp_generic_set_aperture(dev, aperture)); 1448} 1449 1450static int 1451agp_i810_method_set_aperture(device_t dev, u_int32_t aperture) 1452{ 1453 struct agp_i810_softc *sc; 1454 1455 sc = device_get_softc(dev); 1456 return (sc->match->driver->set_aperture(dev, aperture)); 1457} 1458 1459/** 1460 * Writes a GTT entry mapping the page at the given offset from the 1461 * beginning of the aperture to the given physical address. Setup the 1462 * caching mode according to flags. 1463 * 1464 * For gen 1, 2 and 3, GTT start is located at AGP_I810_GTT offset 1465 * from corresponding BAR start. For gen 4, offset is 512KB + 1466 * AGP_I810_GTT, for gen 5 and 6 it is 2MB + AGP_I810_GTT. 1467 * 1468 * Also, the bits of the physical page address above 4GB needs to be 1469 * placed into bits 40-32 of PTE. 1470 */ 1471static void 1472agp_i810_install_gtt_pte(device_t dev, u_int index, vm_offset_t physical, 1473 int flags) 1474{ 1475 uint32_t pte; 1476 1477 pte = (u_int32_t)physical | I810_PTE_VALID; 1478 if (flags == AGP_DCACHE_MEMORY) 1479 pte |= I810_PTE_LOCAL; 1480 else if (flags == AGP_USER_CACHED_MEMORY) 1481 pte |= I830_PTE_SYSTEM_CACHED; 1482 agp_i810_write_gtt(dev, index, pte); 1483} 1484 1485static void 1486agp_i810_write_gtt(device_t dev, u_int index, uint32_t pte) 1487{ 1488 struct agp_i810_softc *sc; 1489 1490 sc = device_get_softc(dev); 1491 bus_write_4(sc->sc_res[0], AGP_I810_GTT + index * 4, pte); 1492 CTR2(KTR_AGP_I810, "810_pte %x %x", index, pte); 1493} 1494 1495static void 1496agp_i830_install_gtt_pte(device_t dev, u_int index, vm_offset_t physical, 1497 int flags) 1498{ 1499 uint32_t pte; 1500 1501 pte = (u_int32_t)physical | I810_PTE_VALID; 1502 if (flags == AGP_USER_CACHED_MEMORY) 1503 pte |= I830_PTE_SYSTEM_CACHED; 1504 agp_i810_write_gtt(dev, index, pte); 1505} 1506 1507static void 1508agp_i915_install_gtt_pte(device_t dev, u_int index, vm_offset_t physical, 1509 int flags) 1510{ 1511 uint32_t pte; 1512 1513 pte = (u_int32_t)physical | I810_PTE_VALID; 1514 if (flags == AGP_USER_CACHED_MEMORY) 1515 pte |= I830_PTE_SYSTEM_CACHED; 1516 pte |= (physical & 0x0000000f00000000ull) >> 28; 1517 agp_i915_write_gtt(dev, index, pte); 1518} 1519 1520static void 1521agp_i915_write_gtt(device_t dev, u_int index, uint32_t pte) 1522{ 1523 struct agp_i810_softc *sc; 1524 1525 sc = device_get_softc(dev); 1526 bus_write_4(sc->sc_res[1], index * 4, pte); 1527 CTR2(KTR_AGP_I810, "915_pte %x %x", index, pte); 1528} 1529 1530static void 1531agp_i965_install_gtt_pte(device_t dev, u_int index, vm_offset_t physical, 1532 int flags) 1533{ 1534 uint32_t pte; 1535 1536 pte = (u_int32_t)physical | I810_PTE_VALID; 1537 if (flags == AGP_USER_CACHED_MEMORY) 1538 pte |= I830_PTE_SYSTEM_CACHED; 1539 pte |= (physical & 0x0000000f00000000ull) >> 28; 1540 agp_i965_write_gtt(dev, index, pte); 1541} 1542 1543static void 1544agp_i965_write_gtt(device_t dev, u_int index, uint32_t pte) 1545{ 1546 struct agp_i810_softc *sc; 1547 1548 sc = device_get_softc(dev); 1549 bus_write_4(sc->sc_res[0], index * 4 + (512 * 1024), pte); 1550 CTR2(KTR_AGP_I810, "965_pte %x %x", index, pte); 1551} 1552 1553static void 1554agp_g4x_install_gtt_pte(device_t dev, u_int index, vm_offset_t physical, 1555 int flags) 1556{ 1557 uint32_t pte; 1558 1559 pte = (u_int32_t)physical | I810_PTE_VALID; 1560 if (flags == AGP_USER_CACHED_MEMORY) 1561 pte |= I830_PTE_SYSTEM_CACHED; 1562 pte |= (physical & 0x0000000f00000000ull) >> 28; 1563 agp_g4x_write_gtt(dev, index, pte); 1564} 1565 1566static void 1567agp_g4x_write_gtt(device_t dev, u_int index, uint32_t pte) 1568{ 1569 struct agp_i810_softc *sc; 1570 1571 sc = device_get_softc(dev); 1572 bus_write_4(sc->sc_res[0], index * 4 + (2 * 1024 * 1024), pte); 1573 CTR2(KTR_AGP_I810, "g4x_pte %x %x", index, pte); 1574} 1575 1576static int 1577agp_i810_bind_page(device_t dev, vm_offset_t offset, vm_offset_t physical) 1578{ 1579 struct agp_i810_softc *sc = device_get_softc(dev); 1580 u_int index; 1581 1582 if (offset >= (sc->gatt->ag_entries << AGP_PAGE_SHIFT)) { 1583 device_printf(dev, "failed: offset is 0x%08jx, " 1584 "shift is %d, entries is %d\n", (intmax_t)offset, 1585 AGP_PAGE_SHIFT, sc->gatt->ag_entries); 1586 return (EINVAL); 1587 } 1588 index = offset >> AGP_PAGE_SHIFT; 1589 if (sc->stolen != 0 && index < sc->stolen) { 1590 device_printf(dev, "trying to bind into stolen memory\n"); 1591 return (EINVAL); 1592 } 1593 sc->match->driver->install_gtt_pte(dev, index, physical, 0); 1594 return (0); 1595} 1596 1597static int 1598agp_i810_unbind_page(device_t dev, vm_offset_t offset) 1599{ 1600 struct agp_i810_softc *sc; 1601 u_int index; 1602 1603 sc = device_get_softc(dev); 1604 if (offset >= (sc->gatt->ag_entries << AGP_PAGE_SHIFT)) 1605 return (EINVAL); 1606 index = offset >> AGP_PAGE_SHIFT; 1607 if (sc->stolen != 0 && index < sc->stolen) { 1608 device_printf(dev, "trying to unbind from stolen memory\n"); 1609 return (EINVAL); 1610 } 1611 sc->match->driver->install_gtt_pte(dev, index, 0, 0); 1612 return (0); 1613} 1614 1615static u_int32_t 1616agp_i810_read_gtt_pte(device_t dev, u_int index) 1617{ 1618 struct agp_i810_softc *sc; 1619 u_int32_t pte; 1620 1621 sc = device_get_softc(dev); 1622 pte = bus_read_4(sc->sc_res[0], AGP_I810_GTT + index * 4); 1623 return (pte); 1624} 1625 1626static u_int32_t 1627agp_i915_read_gtt_pte(device_t dev, u_int index) 1628{ 1629 struct agp_i810_softc *sc; 1630 u_int32_t pte; 1631 1632 sc = device_get_softc(dev); 1633 pte = bus_read_4(sc->sc_res[1], index * 4); 1634 return (pte); 1635} 1636 1637static u_int32_t 1638agp_i965_read_gtt_pte(device_t dev, u_int index) 1639{ 1640 struct agp_i810_softc *sc; 1641 u_int32_t pte; 1642 1643 sc = device_get_softc(dev); 1644 pte = bus_read_4(sc->sc_res[0], index * 4 + (512 * 1024)); 1645 return (pte); 1646} 1647 1648static u_int32_t 1649agp_g4x_read_gtt_pte(device_t dev, u_int index) 1650{ 1651 struct agp_i810_softc *sc; 1652 u_int32_t pte; 1653 1654 sc = device_get_softc(dev); 1655 pte = bus_read_4(sc->sc_res[0], index * 4 + (2 * 1024 * 1024)); 1656 return (pte); 1657} 1658 1659static vm_paddr_t 1660agp_i810_read_gtt_pte_paddr(device_t dev, u_int index) 1661{ 1662 struct agp_i810_softc *sc; 1663 u_int32_t pte; 1664 vm_paddr_t res; 1665 1666 sc = device_get_softc(dev); 1667 pte = sc->match->driver->read_gtt_pte(dev, index); 1668 res = pte & ~PAGE_MASK; 1669 return (res); 1670} 1671 1672static vm_paddr_t 1673agp_i915_read_gtt_pte_paddr(device_t dev, u_int index) 1674{ 1675 struct agp_i810_softc *sc; 1676 u_int32_t pte; 1677 vm_paddr_t res; 1678 1679 sc = device_get_softc(dev); 1680 pte = sc->match->driver->read_gtt_pte(dev, index); 1681 res = (pte & ~PAGE_MASK) | ((pte & 0xf0) << 28); 1682 return (res); 1683} 1684 1685/* 1686 * Writing via memory mapped registers already flushes all TLBs. 1687 */ 1688static void 1689agp_i810_flush_tlb(device_t dev) 1690{ 1691} 1692 1693static int 1694agp_i810_enable(device_t dev, u_int32_t mode) 1695{ 1696 1697 return (0); 1698} 1699 1700static struct agp_memory * 1701agp_i810_alloc_memory(device_t dev, int type, vm_size_t size) 1702{ 1703 struct agp_i810_softc *sc; 1704 struct agp_memory *mem; 1705 vm_page_t m; 1706 1707 sc = device_get_softc(dev); 1708 1709 if ((size & (AGP_PAGE_SIZE - 1)) != 0 || 1710 sc->agp.as_allocated + size > sc->agp.as_maxmem) 1711 return (0); 1712 1713 if (type == 1) { 1714 /* 1715 * Mapping local DRAM into GATT. 1716 */ 1717 if (sc->match->driver->chiptype != CHIP_I810) 1718 return (0); 1719 if (size != sc->dcache_size) 1720 return (0); 1721 } else if (type == 2) { 1722 /* 1723 * Type 2 is the contiguous physical memory type, that hands 1724 * back a physical address. This is used for cursors on i810. 1725 * Hand back as many single pages with physical as the user 1726 * wants, but only allow one larger allocation (ARGB cursor) 1727 * for simplicity. 1728 */ 1729 if (size != AGP_PAGE_SIZE) { 1730 if (sc->argb_cursor != NULL) 1731 return (0); 1732 1733 /* Allocate memory for ARGB cursor, if we can. */ 1734 sc->argb_cursor = contigmalloc(size, M_AGP, 1735 0, 0, ~0, PAGE_SIZE, 0); 1736 if (sc->argb_cursor == NULL) 1737 return (0); 1738 } 1739 } 1740 1741 mem = malloc(sizeof *mem, M_AGP, M_WAITOK); 1742 mem->am_id = sc->agp.as_nextid++; 1743 mem->am_size = size; 1744 mem->am_type = type; 1745 if (type != 1 && (type != 2 || size == AGP_PAGE_SIZE)) 1746 mem->am_obj = vm_object_allocate(OBJT_DEFAULT, 1747 atop(round_page(size))); 1748 else 1749 mem->am_obj = 0; 1750 1751 if (type == 2) { 1752 if (size == AGP_PAGE_SIZE) { 1753 /* 1754 * Allocate and wire down the page now so that we can 1755 * get its physical address. 1756 */ 1757 VM_OBJECT_WLOCK(mem->am_obj); 1758 m = vm_page_grab(mem->am_obj, 0, VM_ALLOC_NOBUSY | 1759 VM_ALLOC_WIRED | VM_ALLOC_ZERO); 1760 VM_OBJECT_WUNLOCK(mem->am_obj); 1761 mem->am_physical = VM_PAGE_TO_PHYS(m); 1762 } else { 1763 /* Our allocation is already nicely wired down for us. 1764 * Just grab the physical address. 1765 */ 1766 mem->am_physical = vtophys(sc->argb_cursor); 1767 } 1768 } else 1769 mem->am_physical = 0; 1770 1771 mem->am_offset = 0; 1772 mem->am_is_bound = 0; 1773 TAILQ_INSERT_TAIL(&sc->agp.as_memory, mem, am_link); 1774 sc->agp.as_allocated += size; 1775 1776 return (mem); 1777} 1778 1779static int 1780agp_i810_free_memory(device_t dev, struct agp_memory *mem) 1781{ 1782 struct agp_i810_softc *sc; 1783 vm_page_t m; 1784 1785 if (mem->am_is_bound) 1786 return (EBUSY); 1787 1788 sc = device_get_softc(dev); 1789 1790 if (mem->am_type == 2) { 1791 if (mem->am_size == AGP_PAGE_SIZE) { 1792 /* 1793 * Unwire the page which we wired in alloc_memory. 1794 */ 1795 VM_OBJECT_WLOCK(mem->am_obj); 1796 m = vm_page_lookup(mem->am_obj, 0); 1797 vm_page_lock(m); 1798 vm_page_unwire(m, PQ_INACTIVE); 1799 vm_page_unlock(m); 1800 VM_OBJECT_WUNLOCK(mem->am_obj); 1801 } else { 1802 contigfree(sc->argb_cursor, mem->am_size, M_AGP); 1803 sc->argb_cursor = NULL; 1804 } 1805 } 1806 1807 sc->agp.as_allocated -= mem->am_size; 1808 TAILQ_REMOVE(&sc->agp.as_memory, mem, am_link); 1809 if (mem->am_obj) 1810 vm_object_deallocate(mem->am_obj); 1811 free(mem, M_AGP); 1812 return (0); 1813} 1814 1815static int 1816agp_i810_bind_memory(device_t dev, struct agp_memory *mem, vm_offset_t offset) 1817{ 1818 struct agp_i810_softc *sc; 1819 vm_offset_t i; 1820 1821 /* Do some sanity checks first. */ 1822 if ((offset & (AGP_PAGE_SIZE - 1)) != 0 || 1823 offset + mem->am_size > AGP_GET_APERTURE(dev)) { 1824 device_printf(dev, "binding memory at bad offset %#x\n", 1825 (int)offset); 1826 return (EINVAL); 1827 } 1828 1829 sc = device_get_softc(dev); 1830 if (mem->am_type == 2 && mem->am_size != AGP_PAGE_SIZE) { 1831 mtx_lock(&sc->agp.as_lock); 1832 if (mem->am_is_bound) { 1833 mtx_unlock(&sc->agp.as_lock); 1834 return (EINVAL); 1835 } 1836 /* The memory's already wired down, just stick it in the GTT. */ 1837 for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE) { 1838 sc->match->driver->install_gtt_pte(dev, (offset + i) >> 1839 AGP_PAGE_SHIFT, mem->am_physical + i, 0); 1840 } 1841 mem->am_offset = offset; 1842 mem->am_is_bound = 1; 1843 mtx_unlock(&sc->agp.as_lock); 1844 return (0); 1845 } 1846 1847 if (mem->am_type != 1) 1848 return (agp_generic_bind_memory(dev, mem, offset)); 1849 1850 /* 1851 * Mapping local DRAM into GATT. 1852 */ 1853 if (sc->match->driver->chiptype != CHIP_I810) 1854 return (EINVAL); 1855 for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE) 1856 bus_write_4(sc->sc_res[0], 1857 AGP_I810_GTT + (i >> AGP_PAGE_SHIFT) * 4, i | 3); 1858 1859 return (0); 1860} 1861 1862static int 1863agp_i810_unbind_memory(device_t dev, struct agp_memory *mem) 1864{ 1865 struct agp_i810_softc *sc; 1866 vm_offset_t i; 1867 1868 sc = device_get_softc(dev); 1869 1870 if (mem->am_type == 2 && mem->am_size != AGP_PAGE_SIZE) { 1871 mtx_lock(&sc->agp.as_lock); 1872 if (!mem->am_is_bound) { 1873 mtx_unlock(&sc->agp.as_lock); 1874 return (EINVAL); 1875 } 1876 1877 for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE) { 1878 sc->match->driver->install_gtt_pte(dev, 1879 (mem->am_offset + i) >> AGP_PAGE_SHIFT, 0, 0); 1880 } 1881 mem->am_is_bound = 0; 1882 mtx_unlock(&sc->agp.as_lock); 1883 return (0); 1884 } 1885 1886 if (mem->am_type != 1) 1887 return (agp_generic_unbind_memory(dev, mem)); 1888 1889 if (sc->match->driver->chiptype != CHIP_I810) 1890 return (EINVAL); 1891 for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE) { 1892 sc->match->driver->install_gtt_pte(dev, i >> AGP_PAGE_SHIFT, 1893 0, 0); 1894 } 1895 return (0); 1896} 1897 1898static device_method_t agp_i810_methods[] = { 1899 /* Device interface */ 1900 DEVMETHOD(device_identify, agp_i810_identify), 1901 DEVMETHOD(device_probe, agp_i810_probe), 1902 DEVMETHOD(device_attach, agp_i810_attach), 1903 DEVMETHOD(device_detach, agp_i810_detach), 1904 DEVMETHOD(device_suspend, bus_generic_suspend), 1905 DEVMETHOD(device_resume, agp_i810_resume), 1906 1907 /* AGP interface */ 1908 DEVMETHOD(agp_get_aperture, agp_generic_get_aperture), 1909 DEVMETHOD(agp_set_aperture, agp_i810_method_set_aperture), 1910 DEVMETHOD(agp_bind_page, agp_i810_bind_page), 1911 DEVMETHOD(agp_unbind_page, agp_i810_unbind_page), 1912 DEVMETHOD(agp_flush_tlb, agp_i810_flush_tlb), 1913 DEVMETHOD(agp_enable, agp_i810_enable), 1914 DEVMETHOD(agp_alloc_memory, agp_i810_alloc_memory), 1915 DEVMETHOD(agp_free_memory, agp_i810_free_memory), 1916 DEVMETHOD(agp_bind_memory, agp_i810_bind_memory), 1917 DEVMETHOD(agp_unbind_memory, agp_i810_unbind_memory), 1918 DEVMETHOD(agp_chipset_flush, agp_intel_gtt_chipset_flush), 1919 1920 { 0, 0 } 1921}; 1922 1923static driver_t agp_i810_driver = { 1924 "agp", 1925 agp_i810_methods, 1926 sizeof(struct agp_i810_softc), 1927}; 1928 1929static devclass_t agp_devclass; 1930 1931DRIVER_MODULE(agp_i810, vgapci, agp_i810_driver, agp_devclass, 0, 0); 1932MODULE_DEPEND(agp_i810, agp, 1, 1, 1); 1933MODULE_DEPEND(agp_i810, pci, 1, 1, 1); 1934 1935extern vm_page_t bogus_page; 1936 1937void 1938agp_intel_gtt_clear_range(device_t dev, u_int first_entry, u_int num_entries) 1939{ 1940 struct agp_i810_softc *sc; 1941 u_int i; 1942 1943 sc = device_get_softc(dev); 1944 for (i = 0; i < num_entries; i++) 1945 sc->match->driver->install_gtt_pte(dev, first_entry + i, 1946 VM_PAGE_TO_PHYS(bogus_page), 0); 1947 sc->match->driver->read_gtt_pte(dev, first_entry + num_entries - 1); 1948} 1949 1950void 1951agp_intel_gtt_insert_pages(device_t dev, u_int first_entry, u_int num_entries, 1952 vm_page_t *pages, u_int flags) 1953{ 1954 struct agp_i810_softc *sc; 1955 u_int i; 1956 1957 sc = device_get_softc(dev); 1958 for (i = 0; i < num_entries; i++) { 1959 MPASS(pages[i]->valid == VM_PAGE_BITS_ALL); 1960 MPASS(pages[i]->wire_count > 0); 1961 sc->match->driver->install_gtt_pte(dev, first_entry + i, 1962 VM_PAGE_TO_PHYS(pages[i]), flags); 1963 } 1964 sc->match->driver->read_gtt_pte(dev, first_entry + num_entries - 1); 1965} 1966 1967struct intel_gtt 1968agp_intel_gtt_get(device_t dev) 1969{ 1970 struct agp_i810_softc *sc; 1971 struct intel_gtt res; 1972 1973 sc = device_get_softc(dev); 1974 res.stolen_size = sc->stolen_size; 1975 res.gtt_total_entries = sc->gtt_total_entries; 1976 res.gtt_mappable_entries = sc->gtt_mappable_entries; 1977 res.do_idle_maps = 0; 1978 res.scratch_page_dma = VM_PAGE_TO_PHYS(bogus_page); 1979 if (sc->agp.as_aperture != NULL) 1980 res.gma_bus_addr = rman_get_start(sc->agp.as_aperture); 1981 else 1982 res.gma_bus_addr = 0; 1983 return (res); 1984} 1985 1986static int 1987agp_i810_chipset_flush_setup(device_t dev) 1988{ 1989 1990 return (0); 1991} 1992 1993static void 1994agp_i810_chipset_flush_teardown(device_t dev) 1995{ 1996 1997 /* Nothing to do. */ 1998} 1999 2000static void 2001agp_i810_chipset_flush(device_t dev) 2002{ 2003 2004 /* Nothing to do. */ 2005} 2006 2007static void 2008agp_i830_chipset_flush(device_t dev) 2009{ 2010 struct agp_i810_softc *sc; 2011 uint32_t hic; 2012 int i; 2013 2014 sc = device_get_softc(dev); 2015 pmap_invalidate_cache(); 2016 hic = bus_read_4(sc->sc_res[0], AGP_I830_HIC); 2017 bus_write_4(sc->sc_res[0], AGP_I830_HIC, hic | (1U << 31)); 2018 for (i = 0; i < 20000 /* 1 sec */; i++) { 2019 hic = bus_read_4(sc->sc_res[0], AGP_I830_HIC); 2020 if ((hic & (1U << 31)) == 0) 2021 break; 2022 DELAY(50); 2023 } 2024} 2025 2026static int 2027agp_i915_chipset_flush_alloc_page(device_t dev, uint64_t start, uint64_t end) 2028{ 2029 struct agp_i810_softc *sc; 2030 device_t vga; 2031 2032 sc = device_get_softc(dev); 2033 vga = device_get_parent(dev); 2034 sc->sc_flush_page_rid = 100; 2035 sc->sc_flush_page_res = BUS_ALLOC_RESOURCE(device_get_parent(vga), dev, 2036 SYS_RES_MEMORY, &sc->sc_flush_page_rid, start, end, PAGE_SIZE, 2037 RF_ACTIVE); 2038 if (sc->sc_flush_page_res == NULL) { 2039 device_printf(dev, "Failed to allocate flush page at 0x%jx\n", 2040 (uintmax_t)start); 2041 return (EINVAL); 2042 } 2043 sc->sc_flush_page_vaddr = rman_get_virtual(sc->sc_flush_page_res); 2044 if (bootverbose) { 2045 device_printf(dev, "Allocated flush page phys 0x%jx virt %p\n", 2046 (uintmax_t)rman_get_start(sc->sc_flush_page_res), 2047 sc->sc_flush_page_vaddr); 2048 } 2049 return (0); 2050} 2051 2052static void 2053agp_i915_chipset_flush_free_page(device_t dev) 2054{ 2055 struct agp_i810_softc *sc; 2056 device_t vga; 2057 2058 sc = device_get_softc(dev); 2059 vga = device_get_parent(dev); 2060 if (sc->sc_flush_page_res == NULL) 2061 return; 2062 BUS_DEACTIVATE_RESOURCE(device_get_parent(vga), dev, SYS_RES_MEMORY, 2063 sc->sc_flush_page_rid, sc->sc_flush_page_res); 2064 BUS_RELEASE_RESOURCE(device_get_parent(vga), dev, SYS_RES_MEMORY, 2065 sc->sc_flush_page_rid, sc->sc_flush_page_res); 2066} 2067 2068static int 2069agp_i915_chipset_flush_setup(device_t dev) 2070{ 2071 struct agp_i810_softc *sc; 2072 uint32_t temp; 2073 int error; 2074 2075 sc = device_get_softc(dev); 2076 temp = pci_read_config(sc->bdev, AGP_I915_IFPADDR, 4); 2077 if ((temp & 1) != 0) { 2078 temp &= ~1; 2079 if (bootverbose) 2080 device_printf(dev, 2081 "Found already configured flush page at 0x%jx\n", 2082 (uintmax_t)temp); 2083 sc->sc_bios_allocated_flush_page = 1; 2084 /* 2085 * In the case BIOS initialized the flush pointer (?) 2086 * register, expect that BIOS also set up the resource 2087 * for the page. 2088 */ 2089 error = agp_i915_chipset_flush_alloc_page(dev, temp, 2090 temp + PAGE_SIZE - 1); 2091 if (error != 0) 2092 return (error); 2093 } else { 2094 sc->sc_bios_allocated_flush_page = 0; 2095 error = agp_i915_chipset_flush_alloc_page(dev, 0, 0xffffffff); 2096 if (error != 0) 2097 return (error); 2098 temp = rman_get_start(sc->sc_flush_page_res); 2099 pci_write_config(sc->bdev, AGP_I915_IFPADDR, temp | 1, 4); 2100 } 2101 return (0); 2102} 2103 2104static void 2105agp_i915_chipset_flush_teardown(device_t dev) 2106{ 2107 struct agp_i810_softc *sc; 2108 uint32_t temp; 2109 2110 sc = device_get_softc(dev); 2111 if (sc->sc_flush_page_res == NULL) 2112 return; 2113 if (!sc->sc_bios_allocated_flush_page) { 2114 temp = pci_read_config(sc->bdev, AGP_I915_IFPADDR, 4); 2115 temp &= ~1; 2116 pci_write_config(sc->bdev, AGP_I915_IFPADDR, temp, 4); 2117 } 2118 agp_i915_chipset_flush_free_page(dev); 2119} 2120 2121static int 2122agp_i965_chipset_flush_setup(device_t dev) 2123{ 2124 struct agp_i810_softc *sc; 2125 uint64_t temp; 2126 uint32_t temp_hi, temp_lo; 2127 int error; 2128 2129 sc = device_get_softc(dev); 2130 2131 temp_hi = pci_read_config(sc->bdev, AGP_I965_IFPADDR + 4, 4); 2132 temp_lo = pci_read_config(sc->bdev, AGP_I965_IFPADDR, 4); 2133 2134 if ((temp_lo & 1) != 0) { 2135 temp = ((uint64_t)temp_hi << 32) | (temp_lo & ~1); 2136 if (bootverbose) 2137 device_printf(dev, 2138 "Found already configured flush page at 0x%jx\n", 2139 (uintmax_t)temp); 2140 sc->sc_bios_allocated_flush_page = 1; 2141 /* 2142 * In the case BIOS initialized the flush pointer (?) 2143 * register, expect that BIOS also set up the resource 2144 * for the page. 2145 */ 2146 error = agp_i915_chipset_flush_alloc_page(dev, temp, 2147 temp + PAGE_SIZE - 1); 2148 if (error != 0) 2149 return (error); 2150 } else { 2151 sc->sc_bios_allocated_flush_page = 0; 2152 error = agp_i915_chipset_flush_alloc_page(dev, 0, ~0); 2153 if (error != 0) 2154 return (error); 2155 temp = rman_get_start(sc->sc_flush_page_res); 2156 pci_write_config(sc->bdev, AGP_I965_IFPADDR + 4, 2157 (temp >> 32) & UINT32_MAX, 4); 2158 pci_write_config(sc->bdev, AGP_I965_IFPADDR, 2159 (temp & UINT32_MAX) | 1, 4); 2160 } 2161 return (0); 2162} 2163 2164static void 2165agp_i965_chipset_flush_teardown(device_t dev) 2166{ 2167 struct agp_i810_softc *sc; 2168 uint32_t temp_lo; 2169 2170 sc = device_get_softc(dev); 2171 if (sc->sc_flush_page_res == NULL) 2172 return; 2173 if (!sc->sc_bios_allocated_flush_page) { 2174 temp_lo = pci_read_config(sc->bdev, AGP_I965_IFPADDR, 4); 2175 temp_lo &= ~1; 2176 pci_write_config(sc->bdev, AGP_I965_IFPADDR, temp_lo, 4); 2177 } 2178 agp_i915_chipset_flush_free_page(dev); 2179} 2180 2181static void 2182agp_i915_chipset_flush(device_t dev) 2183{ 2184 struct agp_i810_softc *sc; 2185 2186 sc = device_get_softc(dev); 2187 *(uint32_t *)sc->sc_flush_page_vaddr = 1; 2188} 2189 2190int 2191agp_intel_gtt_chipset_flush(device_t dev) 2192{ 2193 struct agp_i810_softc *sc; 2194 2195 sc = device_get_softc(dev); 2196 sc->match->driver->chipset_flush(dev); 2197 return (0); 2198} 2199 2200void 2201agp_intel_gtt_unmap_memory(device_t dev, struct sglist *sg_list) 2202{ 2203} 2204 2205int 2206agp_intel_gtt_map_memory(device_t dev, vm_page_t *pages, u_int num_entries, 2207 struct sglist **sg_list) 2208{ 2209 struct agp_i810_softc *sc; 2210 struct sglist *sg; 2211 int i; 2212#if 0 2213 int error; 2214 bus_dma_tag_t dmat; 2215#endif 2216 2217 if (*sg_list != NULL) 2218 return (0); 2219 sc = device_get_softc(dev); 2220 sg = sglist_alloc(num_entries, M_WAITOK /* XXXKIB */); 2221 for (i = 0; i < num_entries; i++) { 2222 sg->sg_segs[i].ss_paddr = VM_PAGE_TO_PHYS(pages[i]); 2223 sg->sg_segs[i].ss_len = PAGE_SIZE; 2224 } 2225 2226#if 0 2227 error = bus_dma_tag_create(bus_get_dma_tag(dev), 2228 1 /* alignment */, 0 /* boundary */, 2229 1ULL << sc->match->busdma_addr_mask_sz /* lowaddr */, 2230 BUS_SPACE_MAXADDR /* highaddr */, 2231 NULL /* filtfunc */, NULL /* filtfuncarg */, 2232 BUS_SPACE_MAXADDR /* maxsize */, 2233 BUS_SPACE_UNRESTRICTED /* nsegments */, 2234 BUS_SPACE_MAXADDR /* maxsegsz */, 2235 0 /* flags */, NULL /* lockfunc */, NULL /* lockfuncarg */, 2236 &dmat); 2237 if (error != 0) { 2238 sglist_free(sg); 2239 return (error); 2240 } 2241 /* XXXKIB */ 2242#endif 2243 *sg_list = sg; 2244 return (0); 2245} 2246 2247static void 2248agp_intel_gtt_install_pte(device_t dev, u_int index, vm_paddr_t addr, 2249 u_int flags) 2250{ 2251 struct agp_i810_softc *sc; 2252 2253 sc = device_get_softc(dev); 2254 sc->match->driver->install_gtt_pte(dev, index, addr, flags); 2255} 2256 2257void 2258agp_intel_gtt_insert_sg_entries(device_t dev, struct sglist *sg_list, 2259 u_int first_entry, u_int flags) 2260{ 2261 struct agp_i810_softc *sc; 2262 vm_paddr_t spaddr; 2263 size_t slen; 2264 u_int i, j; 2265 2266 sc = device_get_softc(dev); 2267 for (i = j = 0; j < sg_list->sg_nseg; j++) { 2268 spaddr = sg_list->sg_segs[i].ss_paddr; 2269 slen = sg_list->sg_segs[i].ss_len; 2270 for (; slen > 0; i++) { 2271 sc->match->driver->install_gtt_pte(dev, first_entry + i, 2272 spaddr, flags); 2273 spaddr += AGP_PAGE_SIZE; 2274 slen -= AGP_PAGE_SIZE; 2275 } 2276 } 2277 sc->match->driver->read_gtt_pte(dev, first_entry + i - 1); 2278} 2279 2280void 2281intel_gtt_clear_range(u_int first_entry, u_int num_entries) 2282{ 2283 2284 agp_intel_gtt_clear_range(intel_agp, first_entry, num_entries); 2285} 2286 2287void 2288intel_gtt_insert_pages(u_int first_entry, u_int num_entries, vm_page_t *pages, 2289 u_int flags) 2290{ 2291 2292 agp_intel_gtt_insert_pages(intel_agp, first_entry, num_entries, 2293 pages, flags); 2294} 2295 2296struct intel_gtt * 2297intel_gtt_get(void) 2298{ 2299 2300 intel_private.base = agp_intel_gtt_get(intel_agp); 2301 return (&intel_private.base); 2302} 2303 2304int 2305intel_gtt_chipset_flush(void) 2306{ 2307 2308 return (agp_intel_gtt_chipset_flush(intel_agp)); 2309} 2310 2311void 2312intel_gtt_unmap_memory(struct sglist *sg_list) 2313{ 2314 2315 agp_intel_gtt_unmap_memory(intel_agp, sg_list); 2316} 2317 2318int 2319intel_gtt_map_memory(vm_page_t *pages, u_int num_entries, 2320 struct sglist **sg_list) 2321{ 2322 2323 return (agp_intel_gtt_map_memory(intel_agp, pages, num_entries, 2324 sg_list)); 2325} 2326 2327void 2328intel_gtt_insert_sg_entries(struct sglist *sg_list, u_int first_entry, 2329 u_int flags) 2330{ 2331 2332 agp_intel_gtt_insert_sg_entries(intel_agp, sg_list, first_entry, flags); 2333} 2334 2335void 2336intel_gtt_install_pte(u_int index, vm_paddr_t addr, u_int flags) 2337{ 2338 2339 agp_intel_gtt_install_pte(intel_agp, index, addr, flags); 2340} 2341 2342device_t 2343intel_gtt_get_bridge_device(void) 2344{ 2345 struct agp_i810_softc *sc; 2346 2347 sc = device_get_softc(intel_agp); 2348 return (sc->bdev); 2349} 2350 2351vm_paddr_t 2352intel_gtt_read_pte_paddr(u_int entry) 2353{ 2354 struct agp_i810_softc *sc; 2355 2356 sc = device_get_softc(intel_agp); 2357 return (sc->match->driver->read_gtt_pte_paddr(intel_agp, entry)); 2358} 2359 2360u_int32_t 2361intel_gtt_read_pte(u_int entry) 2362{ 2363 struct agp_i810_softc *sc; 2364 2365 sc = device_get_softc(intel_agp); 2366 return (sc->match->driver->read_gtt_pte(intel_agp, entry)); 2367} 2368 2369void 2370intel_gtt_write(u_int entry, uint32_t val) 2371{ 2372 struct agp_i810_softc *sc; 2373 2374 sc = device_get_softc(intel_agp); 2375 return (sc->match->driver->write_gtt(intel_agp, entry, val)); 2376} 2377