agp_i810.c revision 274378
1/*- 2 * Copyright (c) 2000 Doug Rabson 3 * Copyright (c) 2000 Ruslan Ermilov 4 * Copyright (c) 2011 The FreeBSD Foundation 5 * All rights reserved. 6 * 7 * Portions of this software were developed by Konstantin Belousov 8 * under sponsorship from the FreeBSD Foundation. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 */ 31 32/* 33 * Fixes for 830/845G support: David Dawes <dawes@xfree86.org> 34 * 852GM/855GM/865G support added by David Dawes <dawes@xfree86.org> 35 * 36 * This is generic Intel GTT handling code, morphed from the AGP 37 * bridge code. 38 */ 39 40#include <sys/cdefs.h> 41__FBSDID("$FreeBSD: head/sys/dev/agp/agp_i810.c 274378 2014-11-11 12:52:45Z kib $"); 42 43#if 0 44#define KTR_AGP_I810 KTR_DEV 45#else 46#define KTR_AGP_I810 0 47#endif 48 49#include <sys/param.h> 50#include <sys/systm.h> 51#include <sys/malloc.h> 52#include <sys/kernel.h> 53#include <sys/ktr.h> 54#include <sys/module.h> 55#include <sys/bus.h> 56#include <sys/lock.h> 57#include <sys/mutex.h> 58#include <sys/proc.h> 59#include <sys/rwlock.h> 60 61#include <dev/agp/agppriv.h> 62#include <dev/agp/agpreg.h> 63#include <dev/agp/agp_i810.h> 64#include <dev/pci/pcivar.h> 65#include <dev/pci/pcireg.h> 66#include <dev/pci/pci_private.h> 67 68#include <vm/vm.h> 69#include <vm/vm_extern.h> 70#include <vm/vm_kern.h> 71#include <vm/vm_param.h> 72#include <vm/vm_object.h> 73#include <vm/vm_page.h> 74#include <vm/vm_pageout.h> 75#include <vm/pmap.h> 76 77#include <machine/bus.h> 78#include <machine/resource.h> 79#include <machine/md_var.h> 80#include <sys/rman.h> 81 82MALLOC_DECLARE(M_AGP); 83 84struct agp_i810_match; 85 86static int agp_i810_check_active(device_t bridge_dev); 87static int agp_i830_check_active(device_t bridge_dev); 88static int agp_i915_check_active(device_t bridge_dev); 89static int agp_sb_check_active(device_t bridge_dev); 90 91static void agp_82852_set_desc(device_t dev, 92 const struct agp_i810_match *match); 93static void agp_i810_set_desc(device_t dev, const struct agp_i810_match *match); 94 95static void agp_i810_dump_regs(device_t dev); 96static void agp_i830_dump_regs(device_t dev); 97static void agp_i855_dump_regs(device_t dev); 98static void agp_i915_dump_regs(device_t dev); 99static void agp_i965_dump_regs(device_t dev); 100static void agp_sb_dump_regs(device_t dev); 101 102static int agp_i810_get_stolen_size(device_t dev); 103static int agp_i830_get_stolen_size(device_t dev); 104static int agp_i915_get_stolen_size(device_t dev); 105static int agp_sb_get_stolen_size(device_t dev); 106 107static int agp_i810_get_gtt_mappable_entries(device_t dev); 108static int agp_i830_get_gtt_mappable_entries(device_t dev); 109static int agp_i915_get_gtt_mappable_entries(device_t dev); 110 111static int agp_i810_get_gtt_total_entries(device_t dev); 112static int agp_i965_get_gtt_total_entries(device_t dev); 113static int agp_gen5_get_gtt_total_entries(device_t dev); 114static int agp_sb_get_gtt_total_entries(device_t dev); 115 116static int agp_i810_install_gatt(device_t dev); 117static int agp_i830_install_gatt(device_t dev); 118static int agp_i965_install_gatt(device_t dev); 119static int agp_g4x_install_gatt(device_t dev); 120 121static void agp_i810_deinstall_gatt(device_t dev); 122static void agp_i830_deinstall_gatt(device_t dev); 123 124static void agp_i810_install_gtt_pte(device_t dev, u_int index, 125 vm_offset_t physical, int flags); 126static void agp_i830_install_gtt_pte(device_t dev, u_int index, 127 vm_offset_t physical, int flags); 128static void agp_i915_install_gtt_pte(device_t dev, u_int index, 129 vm_offset_t physical, int flags); 130static void agp_i965_install_gtt_pte(device_t dev, u_int index, 131 vm_offset_t physical, int flags); 132static void agp_g4x_install_gtt_pte(device_t dev, u_int index, 133 vm_offset_t physical, int flags); 134static void agp_sb_install_gtt_pte(device_t dev, u_int index, 135 vm_offset_t physical, int flags); 136 137static void agp_i810_write_gtt(device_t dev, u_int index, uint32_t pte); 138static void agp_i915_write_gtt(device_t dev, u_int index, uint32_t pte); 139static void agp_i965_write_gtt(device_t dev, u_int index, uint32_t pte); 140static void agp_g4x_write_gtt(device_t dev, u_int index, uint32_t pte); 141static void agp_sb_write_gtt(device_t dev, u_int index, uint32_t pte); 142 143static u_int32_t agp_i810_read_gtt_pte(device_t dev, u_int index); 144static u_int32_t agp_i915_read_gtt_pte(device_t dev, u_int index); 145static u_int32_t agp_i965_read_gtt_pte(device_t dev, u_int index); 146static u_int32_t agp_g4x_read_gtt_pte(device_t dev, u_int index); 147 148static vm_paddr_t agp_i810_read_gtt_pte_paddr(device_t dev, u_int index); 149static vm_paddr_t agp_i915_read_gtt_pte_paddr(device_t dev, u_int index); 150static vm_paddr_t agp_sb_read_gtt_pte_paddr(device_t dev, u_int index); 151 152static int agp_i810_set_aperture(device_t dev, u_int32_t aperture); 153static int agp_i830_set_aperture(device_t dev, u_int32_t aperture); 154static int agp_i915_set_aperture(device_t dev, u_int32_t aperture); 155 156static int agp_i810_chipset_flush_setup(device_t dev); 157static int agp_i915_chipset_flush_setup(device_t dev); 158static int agp_i965_chipset_flush_setup(device_t dev); 159 160static void agp_i810_chipset_flush_teardown(device_t dev); 161static void agp_i915_chipset_flush_teardown(device_t dev); 162static void agp_i965_chipset_flush_teardown(device_t dev); 163 164static void agp_i810_chipset_flush(device_t dev); 165static void agp_i830_chipset_flush(device_t dev); 166static void agp_i915_chipset_flush(device_t dev); 167 168enum { 169 CHIP_I810, /* i810/i815 */ 170 CHIP_I830, /* 830M/845G */ 171 CHIP_I855, /* 852GM/855GM/865G */ 172 CHIP_I915, /* 915G/915GM */ 173 CHIP_I965, /* G965 */ 174 CHIP_G33, /* G33/Q33/Q35 */ 175 CHIP_IGD, /* Pineview */ 176 CHIP_G4X, /* G45/Q45 */ 177 CHIP_SB, /* SandyBridge */ 178}; 179 180/* The i810 through i855 have the registers at BAR 1, and the GATT gets 181 * allocated by us. The i915 has registers in BAR 0 and the GATT is at the 182 * start of the stolen memory, and should only be accessed by the OS through 183 * BAR 3. The G965 has registers and GATT in the same BAR (0) -- first 512KB 184 * is registers, second 512KB is GATT. 185 */ 186static struct resource_spec agp_i810_res_spec[] = { 187 { SYS_RES_MEMORY, AGP_I810_MMADR, RF_ACTIVE | RF_SHAREABLE }, 188 { -1, 0 } 189}; 190 191static struct resource_spec agp_i915_res_spec[] = { 192 { SYS_RES_MEMORY, AGP_I915_MMADR, RF_ACTIVE | RF_SHAREABLE }, 193 { SYS_RES_MEMORY, AGP_I915_GTTADR, RF_ACTIVE | RF_SHAREABLE }, 194 { -1, 0 } 195}; 196 197static struct resource_spec agp_i965_res_spec[] = { 198 { SYS_RES_MEMORY, AGP_I965_GTTMMADR, RF_ACTIVE | RF_SHAREABLE }, 199 { -1, 0 } 200}; 201 202static struct resource_spec agp_g4x_res_spec[] = { 203 { SYS_RES_MEMORY, AGP_G4X_MMADR, RF_ACTIVE | RF_SHAREABLE }, 204 { SYS_RES_MEMORY, AGP_G4X_GTTADR, RF_ACTIVE | RF_SHAREABLE }, 205 { -1, 0 } 206}; 207 208struct agp_i810_softc { 209 struct agp_softc agp; 210 u_int32_t initial_aperture; /* aperture size at startup */ 211 struct agp_gatt *gatt; 212 u_int32_t dcache_size; /* i810 only */ 213 u_int32_t stolen; /* number of i830/845 gtt 214 entries for stolen memory */ 215 u_int stolen_size; /* BIOS-reserved graphics memory */ 216 u_int gtt_total_entries; /* Total number of gtt ptes */ 217 u_int gtt_mappable_entries; /* Number of gtt ptes mappable by CPU */ 218 device_t bdev; /* bridge device */ 219 void *argb_cursor; /* contigmalloc area for ARGB cursor */ 220 struct resource *sc_res[2]; 221 const struct agp_i810_match *match; 222 int sc_flush_page_rid; 223 struct resource *sc_flush_page_res; 224 void *sc_flush_page_vaddr; 225 int sc_bios_allocated_flush_page; 226}; 227 228static device_t intel_agp; 229 230struct agp_i810_driver { 231 int chiptype; 232 int gen; 233 int busdma_addr_mask_sz; 234 struct resource_spec *res_spec; 235 int (*check_active)(device_t); 236 void (*set_desc)(device_t, const struct agp_i810_match *); 237 void (*dump_regs)(device_t); 238 int (*get_stolen_size)(device_t); 239 int (*get_gtt_total_entries)(device_t); 240 int (*get_gtt_mappable_entries)(device_t); 241 int (*install_gatt)(device_t); 242 void (*deinstall_gatt)(device_t); 243 void (*write_gtt)(device_t, u_int, uint32_t); 244 void (*install_gtt_pte)(device_t, u_int, vm_offset_t, int); 245 u_int32_t (*read_gtt_pte)(device_t, u_int); 246 vm_paddr_t (*read_gtt_pte_paddr)(device_t , u_int); 247 int (*set_aperture)(device_t, u_int32_t); 248 int (*chipset_flush_setup)(device_t); 249 void (*chipset_flush_teardown)(device_t); 250 void (*chipset_flush)(device_t); 251}; 252 253static const struct agp_i810_driver agp_i810_i810_driver = { 254 .chiptype = CHIP_I810, 255 .gen = 1, 256 .busdma_addr_mask_sz = 32, 257 .res_spec = agp_i810_res_spec, 258 .check_active = agp_i810_check_active, 259 .set_desc = agp_i810_set_desc, 260 .dump_regs = agp_i810_dump_regs, 261 .get_stolen_size = agp_i810_get_stolen_size, 262 .get_gtt_mappable_entries = agp_i810_get_gtt_mappable_entries, 263 .get_gtt_total_entries = agp_i810_get_gtt_total_entries, 264 .install_gatt = agp_i810_install_gatt, 265 .deinstall_gatt = agp_i810_deinstall_gatt, 266 .write_gtt = agp_i810_write_gtt, 267 .install_gtt_pte = agp_i810_install_gtt_pte, 268 .read_gtt_pte = agp_i810_read_gtt_pte, 269 .read_gtt_pte_paddr = agp_i810_read_gtt_pte_paddr, 270 .set_aperture = agp_i810_set_aperture, 271 .chipset_flush_setup = agp_i810_chipset_flush_setup, 272 .chipset_flush_teardown = agp_i810_chipset_flush_teardown, 273 .chipset_flush = agp_i810_chipset_flush, 274}; 275 276static const struct agp_i810_driver agp_i810_i815_driver = { 277 .chiptype = CHIP_I810, 278 .gen = 2, 279 .busdma_addr_mask_sz = 32, 280 .res_spec = agp_i810_res_spec, 281 .check_active = agp_i810_check_active, 282 .set_desc = agp_i810_set_desc, 283 .dump_regs = agp_i810_dump_regs, 284 .get_stolen_size = agp_i810_get_stolen_size, 285 .get_gtt_mappable_entries = agp_i830_get_gtt_mappable_entries, 286 .get_gtt_total_entries = agp_i810_get_gtt_total_entries, 287 .install_gatt = agp_i810_install_gatt, 288 .deinstall_gatt = agp_i810_deinstall_gatt, 289 .write_gtt = agp_i810_write_gtt, 290 .install_gtt_pte = agp_i810_install_gtt_pte, 291 .read_gtt_pte = agp_i810_read_gtt_pte, 292 .read_gtt_pte_paddr = agp_i810_read_gtt_pte_paddr, 293 .set_aperture = agp_i810_set_aperture, 294 .chipset_flush_setup = agp_i810_chipset_flush_setup, 295 .chipset_flush_teardown = agp_i810_chipset_flush_teardown, 296 .chipset_flush = agp_i830_chipset_flush, 297}; 298 299static const struct agp_i810_driver agp_i810_i830_driver = { 300 .chiptype = CHIP_I830, 301 .gen = 2, 302 .busdma_addr_mask_sz = 32, 303 .res_spec = agp_i810_res_spec, 304 .check_active = agp_i830_check_active, 305 .set_desc = agp_i810_set_desc, 306 .dump_regs = agp_i830_dump_regs, 307 .get_stolen_size = agp_i830_get_stolen_size, 308 .get_gtt_mappable_entries = agp_i830_get_gtt_mappable_entries, 309 .get_gtt_total_entries = agp_i810_get_gtt_total_entries, 310 .install_gatt = agp_i830_install_gatt, 311 .deinstall_gatt = agp_i830_deinstall_gatt, 312 .write_gtt = agp_i810_write_gtt, 313 .install_gtt_pte = agp_i830_install_gtt_pte, 314 .read_gtt_pte = agp_i810_read_gtt_pte, 315 .read_gtt_pte_paddr = agp_i810_read_gtt_pte_paddr, 316 .set_aperture = agp_i830_set_aperture, 317 .chipset_flush_setup = agp_i810_chipset_flush_setup, 318 .chipset_flush_teardown = agp_i810_chipset_flush_teardown, 319 .chipset_flush = agp_i830_chipset_flush, 320}; 321 322static const struct agp_i810_driver agp_i810_i855_driver = { 323 .chiptype = CHIP_I855, 324 .gen = 2, 325 .busdma_addr_mask_sz = 32, 326 .res_spec = agp_i810_res_spec, 327 .check_active = agp_i830_check_active, 328 .set_desc = agp_82852_set_desc, 329 .dump_regs = agp_i855_dump_regs, 330 .get_stolen_size = agp_i915_get_stolen_size, 331 .get_gtt_mappable_entries = agp_i915_get_gtt_mappable_entries, 332 .get_gtt_total_entries = agp_i810_get_gtt_total_entries, 333 .install_gatt = agp_i830_install_gatt, 334 .deinstall_gatt = agp_i830_deinstall_gatt, 335 .write_gtt = agp_i810_write_gtt, 336 .install_gtt_pte = agp_i830_install_gtt_pte, 337 .read_gtt_pte = agp_i810_read_gtt_pte, 338 .read_gtt_pte_paddr = agp_i810_read_gtt_pte_paddr, 339 .set_aperture = agp_i830_set_aperture, 340 .chipset_flush_setup = agp_i810_chipset_flush_setup, 341 .chipset_flush_teardown = agp_i810_chipset_flush_teardown, 342 .chipset_flush = agp_i830_chipset_flush, 343}; 344 345static const struct agp_i810_driver agp_i810_i865_driver = { 346 .chiptype = CHIP_I855, 347 .gen = 2, 348 .busdma_addr_mask_sz = 32, 349 .res_spec = agp_i810_res_spec, 350 .check_active = agp_i830_check_active, 351 .set_desc = agp_i810_set_desc, 352 .dump_regs = agp_i855_dump_regs, 353 .get_stolen_size = agp_i915_get_stolen_size, 354 .get_gtt_mappable_entries = agp_i915_get_gtt_mappable_entries, 355 .get_gtt_total_entries = agp_i810_get_gtt_total_entries, 356 .install_gatt = agp_i830_install_gatt, 357 .deinstall_gatt = agp_i830_deinstall_gatt, 358 .write_gtt = agp_i810_write_gtt, 359 .install_gtt_pte = agp_i830_install_gtt_pte, 360 .read_gtt_pte = agp_i810_read_gtt_pte, 361 .read_gtt_pte_paddr = agp_i810_read_gtt_pte_paddr, 362 .set_aperture = agp_i915_set_aperture, 363 .chipset_flush_setup = agp_i810_chipset_flush_setup, 364 .chipset_flush_teardown = agp_i810_chipset_flush_teardown, 365 .chipset_flush = agp_i830_chipset_flush, 366}; 367 368static const struct agp_i810_driver agp_i810_i915_driver = { 369 .chiptype = CHIP_I915, 370 .gen = 3, 371 .busdma_addr_mask_sz = 32, 372 .res_spec = agp_i915_res_spec, 373 .check_active = agp_i915_check_active, 374 .set_desc = agp_i810_set_desc, 375 .dump_regs = agp_i915_dump_regs, 376 .get_stolen_size = agp_i915_get_stolen_size, 377 .get_gtt_mappable_entries = agp_i915_get_gtt_mappable_entries, 378 .get_gtt_total_entries = agp_i810_get_gtt_total_entries, 379 .install_gatt = agp_i830_install_gatt, 380 .deinstall_gatt = agp_i830_deinstall_gatt, 381 .write_gtt = agp_i915_write_gtt, 382 .install_gtt_pte = agp_i915_install_gtt_pte, 383 .read_gtt_pte = agp_i915_read_gtt_pte, 384 .read_gtt_pte_paddr = agp_i915_read_gtt_pte_paddr, 385 .set_aperture = agp_i915_set_aperture, 386 .chipset_flush_setup = agp_i915_chipset_flush_setup, 387 .chipset_flush_teardown = agp_i915_chipset_flush_teardown, 388 .chipset_flush = agp_i915_chipset_flush, 389}; 390 391static const struct agp_i810_driver agp_i810_g965_driver = { 392 .chiptype = CHIP_I965, 393 .gen = 4, 394 .busdma_addr_mask_sz = 36, 395 .res_spec = agp_i965_res_spec, 396 .check_active = agp_i915_check_active, 397 .set_desc = agp_i810_set_desc, 398 .dump_regs = agp_i965_dump_regs, 399 .get_stolen_size = agp_i915_get_stolen_size, 400 .get_gtt_mappable_entries = agp_i915_get_gtt_mappable_entries, 401 .get_gtt_total_entries = agp_i965_get_gtt_total_entries, 402 .install_gatt = agp_i965_install_gatt, 403 .deinstall_gatt = agp_i830_deinstall_gatt, 404 .write_gtt = agp_i965_write_gtt, 405 .install_gtt_pte = agp_i965_install_gtt_pte, 406 .read_gtt_pte = agp_i965_read_gtt_pte, 407 .read_gtt_pte_paddr = agp_i915_read_gtt_pte_paddr, 408 .set_aperture = agp_i915_set_aperture, 409 .chipset_flush_setup = agp_i965_chipset_flush_setup, 410 .chipset_flush_teardown = agp_i965_chipset_flush_teardown, 411 .chipset_flush = agp_i915_chipset_flush, 412}; 413 414static const struct agp_i810_driver agp_i810_g33_driver = { 415 .chiptype = CHIP_G33, 416 .gen = 3, 417 .busdma_addr_mask_sz = 36, 418 .res_spec = agp_i915_res_spec, 419 .check_active = agp_i915_check_active, 420 .set_desc = agp_i810_set_desc, 421 .dump_regs = agp_i965_dump_regs, 422 .get_stolen_size = agp_i915_get_stolen_size, 423 .get_gtt_mappable_entries = agp_i915_get_gtt_mappable_entries, 424 .get_gtt_total_entries = agp_i965_get_gtt_total_entries, 425 .install_gatt = agp_i830_install_gatt, 426 .deinstall_gatt = agp_i830_deinstall_gatt, 427 .write_gtt = agp_i915_write_gtt, 428 .install_gtt_pte = agp_i915_install_gtt_pte, 429 .read_gtt_pte = agp_i915_read_gtt_pte, 430 .read_gtt_pte_paddr = agp_i915_read_gtt_pte_paddr, 431 .set_aperture = agp_i915_set_aperture, 432 .chipset_flush_setup = agp_i965_chipset_flush_setup, 433 .chipset_flush_teardown = agp_i965_chipset_flush_teardown, 434 .chipset_flush = agp_i915_chipset_flush, 435}; 436 437static const struct agp_i810_driver agp_i810_igd_driver = { 438 .chiptype = CHIP_IGD, 439 .gen = 3, 440 .busdma_addr_mask_sz = 36, 441 .res_spec = agp_i915_res_spec, 442 .check_active = agp_i915_check_active, 443 .set_desc = agp_i810_set_desc, 444 .dump_regs = agp_i915_dump_regs, 445 .get_stolen_size = agp_i915_get_stolen_size, 446 .get_gtt_mappable_entries = agp_i915_get_gtt_mappable_entries, 447 .get_gtt_total_entries = agp_i965_get_gtt_total_entries, 448 .install_gatt = agp_i830_install_gatt, 449 .deinstall_gatt = agp_i830_deinstall_gatt, 450 .write_gtt = agp_i915_write_gtt, 451 .install_gtt_pte = agp_i915_install_gtt_pte, 452 .read_gtt_pte = agp_i915_read_gtt_pte, 453 .read_gtt_pte_paddr = agp_i915_read_gtt_pte_paddr, 454 .set_aperture = agp_i915_set_aperture, 455 .chipset_flush_setup = agp_i965_chipset_flush_setup, 456 .chipset_flush_teardown = agp_i965_chipset_flush_teardown, 457 .chipset_flush = agp_i915_chipset_flush, 458}; 459 460static const struct agp_i810_driver agp_i810_g4x_driver = { 461 .chiptype = CHIP_G4X, 462 .gen = 5, 463 .busdma_addr_mask_sz = 36, 464 .res_spec = agp_i965_res_spec, 465 .check_active = agp_i915_check_active, 466 .set_desc = agp_i810_set_desc, 467 .dump_regs = agp_i965_dump_regs, 468 .get_stolen_size = agp_i915_get_stolen_size, 469 .get_gtt_mappable_entries = agp_i915_get_gtt_mappable_entries, 470 .get_gtt_total_entries = agp_gen5_get_gtt_total_entries, 471 .install_gatt = agp_g4x_install_gatt, 472 .deinstall_gatt = agp_i830_deinstall_gatt, 473 .write_gtt = agp_g4x_write_gtt, 474 .install_gtt_pte = agp_g4x_install_gtt_pte, 475 .read_gtt_pte = agp_g4x_read_gtt_pte, 476 .read_gtt_pte_paddr = agp_i915_read_gtt_pte_paddr, 477 .set_aperture = agp_i915_set_aperture, 478 .chipset_flush_setup = agp_i965_chipset_flush_setup, 479 .chipset_flush_teardown = agp_i965_chipset_flush_teardown, 480 .chipset_flush = agp_i915_chipset_flush, 481}; 482 483static const struct agp_i810_driver agp_i810_sb_driver = { 484 .chiptype = CHIP_SB, 485 .gen = 6, 486 .busdma_addr_mask_sz = 40, 487 .res_spec = agp_g4x_res_spec, 488 .check_active = agp_sb_check_active, 489 .set_desc = agp_i810_set_desc, 490 .dump_regs = agp_sb_dump_regs, 491 .get_stolen_size = agp_sb_get_stolen_size, 492 .get_gtt_mappable_entries = agp_i915_get_gtt_mappable_entries, 493 .get_gtt_total_entries = agp_sb_get_gtt_total_entries, 494 .install_gatt = agp_g4x_install_gatt, 495 .deinstall_gatt = agp_i830_deinstall_gatt, 496 .write_gtt = agp_sb_write_gtt, 497 .install_gtt_pte = agp_sb_install_gtt_pte, 498 .read_gtt_pte = agp_g4x_read_gtt_pte, 499 .read_gtt_pte_paddr = agp_sb_read_gtt_pte_paddr, 500 .set_aperture = agp_i915_set_aperture, 501 .chipset_flush_setup = agp_i810_chipset_flush_setup, 502 .chipset_flush_teardown = agp_i810_chipset_flush_teardown, 503 .chipset_flush = agp_i810_chipset_flush, 504}; 505 506/* For adding new devices, devid is the id of the graphics controller 507 * (pci:0:2:0, for example). The placeholder (usually at pci:0:2:1) for the 508 * second head should never be added. The bridge_offset is the offset to 509 * subtract from devid to get the id of the hostb that the device is on. 510 */ 511static const struct agp_i810_match { 512 int devid; 513 char *name; 514 const struct agp_i810_driver *driver; 515} agp_i810_matches[] = { 516 { 517 .devid = 0x71218086, 518 .name = "Intel 82810 (i810 GMCH) SVGA controller", 519 .driver = &agp_i810_i810_driver 520 }, 521 { 522 .devid = 0x71238086, 523 .name = "Intel 82810-DC100 (i810-DC100 GMCH) SVGA controller", 524 .driver = &agp_i810_i810_driver 525 }, 526 { 527 .devid = 0x71258086, 528 .name = "Intel 82810E (i810E GMCH) SVGA controller", 529 .driver = &agp_i810_i810_driver 530 }, 531 { 532 .devid = 0x11328086, 533 .name = "Intel 82815 (i815 GMCH) SVGA controller", 534 .driver = &agp_i810_i815_driver 535 }, 536 { 537 .devid = 0x35778086, 538 .name = "Intel 82830M (830M GMCH) SVGA controller", 539 .driver = &agp_i810_i830_driver 540 }, 541 { 542 .devid = 0x25628086, 543 .name = "Intel 82845M (845M GMCH) SVGA controller", 544 .driver = &agp_i810_i830_driver 545 }, 546 { 547 .devid = 0x35828086, 548 .name = "Intel 82852/855GM SVGA controller", 549 .driver = &agp_i810_i855_driver 550 }, 551 { 552 .devid = 0x25728086, 553 .name = "Intel 82865G (865G GMCH) SVGA controller", 554 .driver = &agp_i810_i865_driver 555 }, 556 { 557 .devid = 0x25828086, 558 .name = "Intel 82915G (915G GMCH) SVGA controller", 559 .driver = &agp_i810_i915_driver 560 }, 561 { 562 .devid = 0x258A8086, 563 .name = "Intel E7221 SVGA controller", 564 .driver = &agp_i810_i915_driver 565 }, 566 { 567 .devid = 0x25928086, 568 .name = "Intel 82915GM (915GM GMCH) SVGA controller", 569 .driver = &agp_i810_i915_driver 570 }, 571 { 572 .devid = 0x27728086, 573 .name = "Intel 82945G (945G GMCH) SVGA controller", 574 .driver = &agp_i810_i915_driver 575 }, 576 { 577 .devid = 0x27A28086, 578 .name = "Intel 82945GM (945GM GMCH) SVGA controller", 579 .driver = &agp_i810_i915_driver 580 }, 581 { 582 .devid = 0x27AE8086, 583 .name = "Intel 945GME SVGA controller", 584 .driver = &agp_i810_i915_driver 585 }, 586 { 587 .devid = 0x29728086, 588 .name = "Intel 946GZ SVGA controller", 589 .driver = &agp_i810_g965_driver 590 }, 591 { 592 .devid = 0x29828086, 593 .name = "Intel G965 SVGA controller", 594 .driver = &agp_i810_g965_driver 595 }, 596 { 597 .devid = 0x29928086, 598 .name = "Intel Q965 SVGA controller", 599 .driver = &agp_i810_g965_driver 600 }, 601 { 602 .devid = 0x29A28086, 603 .name = "Intel G965 SVGA controller", 604 .driver = &agp_i810_g965_driver 605 }, 606 { 607 .devid = 0x29B28086, 608 .name = "Intel Q35 SVGA controller", 609 .driver = &agp_i810_g33_driver 610 }, 611 { 612 .devid = 0x29C28086, 613 .name = "Intel G33 SVGA controller", 614 .driver = &agp_i810_g33_driver 615 }, 616 { 617 .devid = 0x29D28086, 618 .name = "Intel Q33 SVGA controller", 619 .driver = &agp_i810_g33_driver 620 }, 621 { 622 .devid = 0xA0018086, 623 .name = "Intel Pineview SVGA controller", 624 .driver = &agp_i810_igd_driver 625 }, 626 { 627 .devid = 0xA0118086, 628 .name = "Intel Pineview (M) SVGA controller", 629 .driver = &agp_i810_igd_driver 630 }, 631 { 632 .devid = 0x2A028086, 633 .name = "Intel GM965 SVGA controller", 634 .driver = &agp_i810_g965_driver 635 }, 636 { 637 .devid = 0x2A128086, 638 .name = "Intel GME965 SVGA controller", 639 .driver = &agp_i810_g965_driver 640 }, 641 { 642 .devid = 0x2A428086, 643 .name = "Intel GM45 SVGA controller", 644 .driver = &agp_i810_g4x_driver 645 }, 646 { 647 .devid = 0x2E028086, 648 .name = "Intel Eaglelake SVGA controller", 649 .driver = &agp_i810_g4x_driver 650 }, 651 { 652 .devid = 0x2E128086, 653 .name = "Intel Q45 SVGA controller", 654 .driver = &agp_i810_g4x_driver 655 }, 656 { 657 .devid = 0x2E228086, 658 .name = "Intel G45 SVGA controller", 659 .driver = &agp_i810_g4x_driver 660 }, 661 { 662 .devid = 0x2E328086, 663 .name = "Intel G41 SVGA controller", 664 .driver = &agp_i810_g4x_driver 665 }, 666 { 667 .devid = 0x00428086, 668 .name = "Intel Ironlake (D) SVGA controller", 669 .driver = &agp_i810_g4x_driver 670 }, 671 { 672 .devid = 0x00468086, 673 .name = "Intel Ironlake (M) SVGA controller", 674 .driver = &agp_i810_g4x_driver 675 }, 676 { 677 .devid = 0x01028086, 678 .name = "SandyBridge desktop GT1 IG", 679 .driver = &agp_i810_sb_driver 680 }, 681 { 682 .devid = 0x01128086, 683 .name = "SandyBridge desktop GT2 IG", 684 .driver = &agp_i810_sb_driver 685 }, 686 { 687 .devid = 0x01228086, 688 .name = "SandyBridge desktop GT2+ IG", 689 .driver = &agp_i810_sb_driver 690 }, 691 { 692 .devid = 0x01068086, 693 .name = "SandyBridge mobile GT1 IG", 694 .driver = &agp_i810_sb_driver 695 }, 696 { 697 .devid = 0x01168086, 698 .name = "SandyBridge mobile GT2 IG", 699 .driver = &agp_i810_sb_driver 700 }, 701 { 702 .devid = 0x01268086, 703 .name = "SandyBridge mobile GT2+ IG", 704 .driver = &agp_i810_sb_driver 705 }, 706 { 707 .devid = 0x010a8086, 708 .name = "SandyBridge server IG", 709 .driver = &agp_i810_sb_driver 710 }, 711 { 712 .devid = 0x01528086, 713 .name = "IvyBridge desktop GT1 IG", 714 .driver = &agp_i810_sb_driver 715 }, 716 { 717 .devid = 0x01628086, 718 .name = "IvyBridge desktop GT2 IG", 719 .driver = &agp_i810_sb_driver 720 }, 721 { 722 .devid = 0x01568086, 723 .name = "IvyBridge mobile GT1 IG", 724 .driver = &agp_i810_sb_driver 725 }, 726 { 727 .devid = 0x01668086, 728 .name = "IvyBridge mobile GT2 IG", 729 .driver = &agp_i810_sb_driver 730 }, 731 { 732 .devid = 0x015a8086, 733 .name = "IvyBridge server GT1 IG", 734 .driver = &agp_i810_sb_driver 735 }, 736 { 737 .devid = 0x016a8086, 738 .name = "IvyBridge server GT2 IG", 739 .driver = &agp_i810_sb_driver 740 }, 741 { 742 .devid = 0, 743 } 744}; 745 746static const struct agp_i810_match* 747agp_i810_match(device_t dev) 748{ 749 int i, devid; 750 751 if (pci_get_class(dev) != PCIC_DISPLAY 752 || (pci_get_subclass(dev) != PCIS_DISPLAY_VGA && 753 pci_get_subclass(dev) != PCIS_DISPLAY_OTHER)) 754 return (NULL); 755 756 devid = pci_get_devid(dev); 757 for (i = 0; agp_i810_matches[i].devid != 0; i++) { 758 if (agp_i810_matches[i].devid == devid) 759 break; 760 } 761 if (agp_i810_matches[i].devid == 0) 762 return (NULL); 763 else 764 return (&agp_i810_matches[i]); 765} 766 767/* 768 * Find bridge device. 769 */ 770static device_t 771agp_i810_find_bridge(device_t dev) 772{ 773 774 return (pci_find_dbsf(0, 0, 0, 0)); 775} 776 777static void 778agp_i810_identify(driver_t *driver, device_t parent) 779{ 780 781 if (device_find_child(parent, "agp", -1) == NULL && 782 agp_i810_match(parent)) 783 device_add_child(parent, "agp", -1); 784} 785 786static int 787agp_i810_check_active(device_t bridge_dev) 788{ 789 u_int8_t smram; 790 791 smram = pci_read_config(bridge_dev, AGP_I810_SMRAM, 1); 792 if ((smram & AGP_I810_SMRAM_GMS) == AGP_I810_SMRAM_GMS_DISABLED) 793 return (ENXIO); 794 return (0); 795} 796 797static int 798agp_i830_check_active(device_t bridge_dev) 799{ 800 int gcc1; 801 802 gcc1 = pci_read_config(bridge_dev, AGP_I830_GCC1, 1); 803 if ((gcc1 & AGP_I830_GCC1_DEV2) == AGP_I830_GCC1_DEV2_DISABLED) 804 return (ENXIO); 805 return (0); 806} 807 808static int 809agp_i915_check_active(device_t bridge_dev) 810{ 811 int deven; 812 813 deven = pci_read_config(bridge_dev, AGP_I915_DEVEN, 4); 814 if ((deven & AGP_I915_DEVEN_D2F0) == AGP_I915_DEVEN_D2F0_DISABLED) 815 return (ENXIO); 816 return (0); 817} 818 819static int 820agp_sb_check_active(device_t bridge_dev) 821{ 822 int deven; 823 824 deven = pci_read_config(bridge_dev, AGP_I915_DEVEN, 4); 825 if ((deven & AGP_SB_DEVEN_D2EN) == AGP_SB_DEVEN_D2EN_DISABLED) 826 return (ENXIO); 827 return (0); 828} 829 830static void 831agp_82852_set_desc(device_t dev, const struct agp_i810_match *match) 832{ 833 834 switch (pci_read_config(dev, AGP_I85X_CAPID, 1)) { 835 case AGP_I855_GME: 836 device_set_desc(dev, 837 "Intel 82855GME (855GME GMCH) SVGA controller"); 838 break; 839 case AGP_I855_GM: 840 device_set_desc(dev, 841 "Intel 82855GM (855GM GMCH) SVGA controller"); 842 break; 843 case AGP_I852_GME: 844 device_set_desc(dev, 845 "Intel 82852GME (852GME GMCH) SVGA controller"); 846 break; 847 case AGP_I852_GM: 848 device_set_desc(dev, 849 "Intel 82852GM (852GM GMCH) SVGA controller"); 850 break; 851 default: 852 device_set_desc(dev, 853 "Intel 8285xM (85xGM GMCH) SVGA controller"); 854 break; 855 } 856} 857 858static void 859agp_i810_set_desc(device_t dev, const struct agp_i810_match *match) 860{ 861 862 device_set_desc(dev, match->name); 863} 864 865static int 866agp_i810_probe(device_t dev) 867{ 868 device_t bdev; 869 const struct agp_i810_match *match; 870 int err; 871 872 if (resource_disabled("agp", device_get_unit(dev))) 873 return (ENXIO); 874 match = agp_i810_match(dev); 875 if (match == NULL) 876 return (ENXIO); 877 878 bdev = agp_i810_find_bridge(dev); 879 if (bdev == NULL) { 880 if (bootverbose) 881 printf("I810: can't find bridge device\n"); 882 return (ENXIO); 883 } 884 885 /* 886 * checking whether internal graphics device has been activated. 887 */ 888 err = match->driver->check_active(bdev); 889 if (err != 0) { 890 if (bootverbose) 891 printf("i810: disabled, not probing\n"); 892 return (err); 893 } 894 895 match->driver->set_desc(dev, match); 896 return (BUS_PROBE_DEFAULT); 897} 898 899static void 900agp_i810_dump_regs(device_t dev) 901{ 902 struct agp_i810_softc *sc = device_get_softc(dev); 903 904 device_printf(dev, "AGP_I810_PGTBL_CTL: %08x\n", 905 bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL)); 906 device_printf(dev, "AGP_I810_MISCC: 0x%04x\n", 907 pci_read_config(sc->bdev, AGP_I810_MISCC, 2)); 908} 909 910static void 911agp_i830_dump_regs(device_t dev) 912{ 913 struct agp_i810_softc *sc = device_get_softc(dev); 914 915 device_printf(dev, "AGP_I810_PGTBL_CTL: %08x\n", 916 bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL)); 917 device_printf(dev, "AGP_I830_GCC1: 0x%02x\n", 918 pci_read_config(sc->bdev, AGP_I830_GCC1, 1)); 919} 920 921static void 922agp_i855_dump_regs(device_t dev) 923{ 924 struct agp_i810_softc *sc = device_get_softc(dev); 925 926 device_printf(dev, "AGP_I810_PGTBL_CTL: %08x\n", 927 bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL)); 928 device_printf(dev, "AGP_I855_GCC1: 0x%02x\n", 929 pci_read_config(sc->bdev, AGP_I855_GCC1, 1)); 930} 931 932static void 933agp_i915_dump_regs(device_t dev) 934{ 935 struct agp_i810_softc *sc = device_get_softc(dev); 936 937 device_printf(dev, "AGP_I810_PGTBL_CTL: %08x\n", 938 bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL)); 939 device_printf(dev, "AGP_I855_GCC1: 0x%02x\n", 940 pci_read_config(sc->bdev, AGP_I855_GCC1, 1)); 941 device_printf(dev, "AGP_I915_MSAC: 0x%02x\n", 942 pci_read_config(sc->bdev, AGP_I915_MSAC, 1)); 943} 944 945static void 946agp_i965_dump_regs(device_t dev) 947{ 948 struct agp_i810_softc *sc = device_get_softc(dev); 949 950 device_printf(dev, "AGP_I965_PGTBL_CTL2: %08x\n", 951 bus_read_4(sc->sc_res[0], AGP_I965_PGTBL_CTL2)); 952 device_printf(dev, "AGP_I855_GCC1: 0x%02x\n", 953 pci_read_config(sc->bdev, AGP_I855_GCC1, 1)); 954 device_printf(dev, "AGP_I965_MSAC: 0x%02x\n", 955 pci_read_config(sc->bdev, AGP_I965_MSAC, 1)); 956} 957 958static void 959agp_sb_dump_regs(device_t dev) 960{ 961 struct agp_i810_softc *sc = device_get_softc(dev); 962 963 device_printf(dev, "AGP_SNB_GFX_MODE: %08x\n", 964 bus_read_4(sc->sc_res[0], AGP_SNB_GFX_MODE)); 965 device_printf(dev, "AGP_SNB_GCC1: 0x%04x\n", 966 pci_read_config(sc->bdev, AGP_SNB_GCC1, 2)); 967} 968 969static int 970agp_i810_get_stolen_size(device_t dev) 971{ 972 struct agp_i810_softc *sc; 973 974 sc = device_get_softc(dev); 975 sc->stolen = 0; 976 sc->stolen_size = 0; 977 return (0); 978} 979 980static int 981agp_i830_get_stolen_size(device_t dev) 982{ 983 struct agp_i810_softc *sc; 984 unsigned int gcc1; 985 986 sc = device_get_softc(dev); 987 988 gcc1 = pci_read_config(sc->bdev, AGP_I830_GCC1, 1); 989 switch (gcc1 & AGP_I830_GCC1_GMS) { 990 case AGP_I830_GCC1_GMS_STOLEN_512: 991 sc->stolen = (512 - 132) * 1024 / 4096; 992 sc->stolen_size = 512 * 1024; 993 break; 994 case AGP_I830_GCC1_GMS_STOLEN_1024: 995 sc->stolen = (1024 - 132) * 1024 / 4096; 996 sc->stolen_size = 1024 * 1024; 997 break; 998 case AGP_I830_GCC1_GMS_STOLEN_8192: 999 sc->stolen = (8192 - 132) * 1024 / 4096; 1000 sc->stolen_size = 8192 * 1024; 1001 break; 1002 default: 1003 sc->stolen = 0; 1004 device_printf(dev, 1005 "unknown memory configuration, disabling (GCC1 %x)\n", 1006 gcc1); 1007 return (EINVAL); 1008 } 1009 return (0); 1010} 1011 1012static int 1013agp_i915_get_stolen_size(device_t dev) 1014{ 1015 struct agp_i810_softc *sc; 1016 unsigned int gcc1, stolen, gtt_size; 1017 1018 sc = device_get_softc(dev); 1019 1020 /* 1021 * Stolen memory is set up at the beginning of the aperture by 1022 * the BIOS, consisting of the GATT followed by 4kb for the 1023 * BIOS display. 1024 */ 1025 switch (sc->match->driver->chiptype) { 1026 case CHIP_I855: 1027 gtt_size = 128; 1028 break; 1029 case CHIP_I915: 1030 gtt_size = 256; 1031 break; 1032 case CHIP_I965: 1033 switch (bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL) & 1034 AGP_I810_PGTBL_SIZE_MASK) { 1035 case AGP_I810_PGTBL_SIZE_128KB: 1036 gtt_size = 128; 1037 break; 1038 case AGP_I810_PGTBL_SIZE_256KB: 1039 gtt_size = 256; 1040 break; 1041 case AGP_I810_PGTBL_SIZE_512KB: 1042 gtt_size = 512; 1043 break; 1044 case AGP_I965_PGTBL_SIZE_1MB: 1045 gtt_size = 1024; 1046 break; 1047 case AGP_I965_PGTBL_SIZE_2MB: 1048 gtt_size = 2048; 1049 break; 1050 case AGP_I965_PGTBL_SIZE_1_5MB: 1051 gtt_size = 1024 + 512; 1052 break; 1053 default: 1054 device_printf(dev, "Bad PGTBL size\n"); 1055 return (EINVAL); 1056 } 1057 break; 1058 case CHIP_G33: 1059 gcc1 = pci_read_config(sc->bdev, AGP_I855_GCC1, 2); 1060 switch (gcc1 & AGP_G33_MGGC_GGMS_MASK) { 1061 case AGP_G33_MGGC_GGMS_SIZE_1M: 1062 gtt_size = 1024; 1063 break; 1064 case AGP_G33_MGGC_GGMS_SIZE_2M: 1065 gtt_size = 2048; 1066 break; 1067 default: 1068 device_printf(dev, "Bad PGTBL size\n"); 1069 return (EINVAL); 1070 } 1071 break; 1072 case CHIP_IGD: 1073 case CHIP_G4X: 1074 gtt_size = 0; 1075 break; 1076 default: 1077 device_printf(dev, "Bad chiptype\n"); 1078 return (EINVAL); 1079 } 1080 1081 /* GCC1 is called MGGC on i915+ */ 1082 gcc1 = pci_read_config(sc->bdev, AGP_I855_GCC1, 1); 1083 switch (gcc1 & AGP_I855_GCC1_GMS) { 1084 case AGP_I855_GCC1_GMS_STOLEN_1M: 1085 stolen = 1024; 1086 break; 1087 case AGP_I855_GCC1_GMS_STOLEN_4M: 1088 stolen = 4 * 1024; 1089 break; 1090 case AGP_I855_GCC1_GMS_STOLEN_8M: 1091 stolen = 8 * 1024; 1092 break; 1093 case AGP_I855_GCC1_GMS_STOLEN_16M: 1094 stolen = 16 * 1024; 1095 break; 1096 case AGP_I855_GCC1_GMS_STOLEN_32M: 1097 stolen = 32 * 1024; 1098 break; 1099 case AGP_I915_GCC1_GMS_STOLEN_48M: 1100 stolen = sc->match->driver->gen > 2 ? 48 * 1024 : 0; 1101 break; 1102 case AGP_I915_GCC1_GMS_STOLEN_64M: 1103 stolen = sc->match->driver->gen > 2 ? 64 * 1024 : 0; 1104 break; 1105 case AGP_G33_GCC1_GMS_STOLEN_128M: 1106 stolen = sc->match->driver->gen > 2 ? 128 * 1024 : 0; 1107 break; 1108 case AGP_G33_GCC1_GMS_STOLEN_256M: 1109 stolen = sc->match->driver->gen > 2 ? 256 * 1024 : 0; 1110 break; 1111 case AGP_G4X_GCC1_GMS_STOLEN_96M: 1112 if (sc->match->driver->chiptype == CHIP_I965 || 1113 sc->match->driver->chiptype == CHIP_G4X) 1114 stolen = 96 * 1024; 1115 else 1116 stolen = 0; 1117 break; 1118 case AGP_G4X_GCC1_GMS_STOLEN_160M: 1119 if (sc->match->driver->chiptype == CHIP_I965 || 1120 sc->match->driver->chiptype == CHIP_G4X) 1121 stolen = 160 * 1024; 1122 else 1123 stolen = 0; 1124 break; 1125 case AGP_G4X_GCC1_GMS_STOLEN_224M: 1126 if (sc->match->driver->chiptype == CHIP_I965 || 1127 sc->match->driver->chiptype == CHIP_G4X) 1128 stolen = 224 * 1024; 1129 else 1130 stolen = 0; 1131 break; 1132 case AGP_G4X_GCC1_GMS_STOLEN_352M: 1133 if (sc->match->driver->chiptype == CHIP_I965 || 1134 sc->match->driver->chiptype == CHIP_G4X) 1135 stolen = 352 * 1024; 1136 else 1137 stolen = 0; 1138 break; 1139 default: 1140 device_printf(dev, 1141 "unknown memory configuration, disabling (GCC1 %x)\n", 1142 gcc1); 1143 return (EINVAL); 1144 } 1145 1146 gtt_size += 4; 1147 sc->stolen_size = stolen * 1024; 1148 sc->stolen = (stolen - gtt_size) * 1024 / 4096; 1149 1150 return (0); 1151} 1152 1153static int 1154agp_sb_get_stolen_size(device_t dev) 1155{ 1156 struct agp_i810_softc *sc; 1157 uint16_t gmch_ctl; 1158 1159 sc = device_get_softc(dev); 1160 gmch_ctl = pci_read_config(sc->bdev, AGP_SNB_GCC1, 2); 1161 switch (gmch_ctl & AGP_SNB_GMCH_GMS_STOLEN_MASK) { 1162 case AGP_SNB_GMCH_GMS_STOLEN_32M: 1163 sc->stolen_size = 32 * 1024 * 1024; 1164 break; 1165 case AGP_SNB_GMCH_GMS_STOLEN_64M: 1166 sc->stolen_size = 64 * 1024 * 1024; 1167 break; 1168 case AGP_SNB_GMCH_GMS_STOLEN_96M: 1169 sc->stolen_size = 96 * 1024 * 1024; 1170 break; 1171 case AGP_SNB_GMCH_GMS_STOLEN_128M: 1172 sc->stolen_size = 128 * 1024 * 1024; 1173 break; 1174 case AGP_SNB_GMCH_GMS_STOLEN_160M: 1175 sc->stolen_size = 160 * 1024 * 1024; 1176 break; 1177 case AGP_SNB_GMCH_GMS_STOLEN_192M: 1178 sc->stolen_size = 192 * 1024 * 1024; 1179 break; 1180 case AGP_SNB_GMCH_GMS_STOLEN_224M: 1181 sc->stolen_size = 224 * 1024 * 1024; 1182 break; 1183 case AGP_SNB_GMCH_GMS_STOLEN_256M: 1184 sc->stolen_size = 256 * 1024 * 1024; 1185 break; 1186 case AGP_SNB_GMCH_GMS_STOLEN_288M: 1187 sc->stolen_size = 288 * 1024 * 1024; 1188 break; 1189 case AGP_SNB_GMCH_GMS_STOLEN_320M: 1190 sc->stolen_size = 320 * 1024 * 1024; 1191 break; 1192 case AGP_SNB_GMCH_GMS_STOLEN_352M: 1193 sc->stolen_size = 352 * 1024 * 1024; 1194 break; 1195 case AGP_SNB_GMCH_GMS_STOLEN_384M: 1196 sc->stolen_size = 384 * 1024 * 1024; 1197 break; 1198 case AGP_SNB_GMCH_GMS_STOLEN_416M: 1199 sc->stolen_size = 416 * 1024 * 1024; 1200 break; 1201 case AGP_SNB_GMCH_GMS_STOLEN_448M: 1202 sc->stolen_size = 448 * 1024 * 1024; 1203 break; 1204 case AGP_SNB_GMCH_GMS_STOLEN_480M: 1205 sc->stolen_size = 480 * 1024 * 1024; 1206 break; 1207 case AGP_SNB_GMCH_GMS_STOLEN_512M: 1208 sc->stolen_size = 512 * 1024 * 1024; 1209 break; 1210 } 1211 sc->stolen = (sc->stolen_size - 4) / 4096; 1212 return (0); 1213} 1214 1215static int 1216agp_i810_get_gtt_mappable_entries(device_t dev) 1217{ 1218 struct agp_i810_softc *sc; 1219 uint32_t ap; 1220 uint16_t miscc; 1221 1222 sc = device_get_softc(dev); 1223 miscc = pci_read_config(sc->bdev, AGP_I810_MISCC, 2); 1224 if ((miscc & AGP_I810_MISCC_WINSIZE) == AGP_I810_MISCC_WINSIZE_32) 1225 ap = 32; 1226 else 1227 ap = 64; 1228 sc->gtt_mappable_entries = (ap * 1024 * 1024) >> AGP_PAGE_SHIFT; 1229 return (0); 1230} 1231 1232static int 1233agp_i830_get_gtt_mappable_entries(device_t dev) 1234{ 1235 struct agp_i810_softc *sc; 1236 uint32_t ap; 1237 uint16_t gmch_ctl; 1238 1239 sc = device_get_softc(dev); 1240 gmch_ctl = pci_read_config(sc->bdev, AGP_I830_GCC1, 2); 1241 if ((gmch_ctl & AGP_I830_GCC1_GMASIZE) == AGP_I830_GCC1_GMASIZE_64) 1242 ap = 64; 1243 else 1244 ap = 128; 1245 sc->gtt_mappable_entries = (ap * 1024 * 1024) >> AGP_PAGE_SHIFT; 1246 return (0); 1247} 1248 1249static int 1250agp_i915_get_gtt_mappable_entries(device_t dev) 1251{ 1252 struct agp_i810_softc *sc; 1253 uint32_t ap; 1254 1255 sc = device_get_softc(dev); 1256 ap = AGP_GET_APERTURE(dev); 1257 sc->gtt_mappable_entries = ap >> AGP_PAGE_SHIFT; 1258 return (0); 1259} 1260 1261static int 1262agp_i810_get_gtt_total_entries(device_t dev) 1263{ 1264 struct agp_i810_softc *sc; 1265 1266 sc = device_get_softc(dev); 1267 sc->gtt_total_entries = sc->gtt_mappable_entries; 1268 return (0); 1269} 1270 1271static int 1272agp_i965_get_gtt_total_entries(device_t dev) 1273{ 1274 struct agp_i810_softc *sc; 1275 uint32_t pgetbl_ctl; 1276 int error; 1277 1278 sc = device_get_softc(dev); 1279 error = 0; 1280 pgetbl_ctl = bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL); 1281 switch (pgetbl_ctl & AGP_I810_PGTBL_SIZE_MASK) { 1282 case AGP_I810_PGTBL_SIZE_128KB: 1283 sc->gtt_total_entries = 128 * 1024 / 4; 1284 break; 1285 case AGP_I810_PGTBL_SIZE_256KB: 1286 sc->gtt_total_entries = 256 * 1024 / 4; 1287 break; 1288 case AGP_I810_PGTBL_SIZE_512KB: 1289 sc->gtt_total_entries = 512 * 1024 / 4; 1290 break; 1291 /* GTT pagetable sizes bigger than 512KB are not possible on G33! */ 1292 case AGP_I810_PGTBL_SIZE_1MB: 1293 sc->gtt_total_entries = 1024 * 1024 / 4; 1294 break; 1295 case AGP_I810_PGTBL_SIZE_2MB: 1296 sc->gtt_total_entries = 2 * 1024 * 1024 / 4; 1297 break; 1298 case AGP_I810_PGTBL_SIZE_1_5MB: 1299 sc->gtt_total_entries = (1024 + 512) * 1024 / 4; 1300 break; 1301 default: 1302 device_printf(dev, "Unknown page table size\n"); 1303 error = ENXIO; 1304 } 1305 return (error); 1306} 1307 1308static void 1309agp_gen5_adjust_pgtbl_size(device_t dev, uint32_t sz) 1310{ 1311 struct agp_i810_softc *sc; 1312 uint32_t pgetbl_ctl, pgetbl_ctl2; 1313 1314 sc = device_get_softc(dev); 1315 1316 /* Disable per-process page table. */ 1317 pgetbl_ctl2 = bus_read_4(sc->sc_res[0], AGP_I965_PGTBL_CTL2); 1318 pgetbl_ctl2 &= ~AGP_I810_PGTBL_ENABLED; 1319 bus_write_4(sc->sc_res[0], AGP_I965_PGTBL_CTL2, pgetbl_ctl2); 1320 1321 /* Write the new ggtt size. */ 1322 pgetbl_ctl = bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL); 1323 pgetbl_ctl &= ~AGP_I810_PGTBL_SIZE_MASK; 1324 pgetbl_ctl |= sz; 1325 bus_write_4(sc->sc_res[0], AGP_I810_PGTBL_CTL, pgetbl_ctl); 1326} 1327 1328static int 1329agp_gen5_get_gtt_total_entries(device_t dev) 1330{ 1331 struct agp_i810_softc *sc; 1332 uint16_t gcc1; 1333 1334 sc = device_get_softc(dev); 1335 1336 gcc1 = pci_read_config(sc->bdev, AGP_I830_GCC1, 2); 1337 switch (gcc1 & AGP_G4x_GCC1_SIZE_MASK) { 1338 case AGP_G4x_GCC1_SIZE_1M: 1339 case AGP_G4x_GCC1_SIZE_VT_1M: 1340 agp_gen5_adjust_pgtbl_size(dev, AGP_I810_PGTBL_SIZE_1MB); 1341 break; 1342 case AGP_G4x_GCC1_SIZE_VT_1_5M: 1343 agp_gen5_adjust_pgtbl_size(dev, AGP_I810_PGTBL_SIZE_1_5MB); 1344 break; 1345 case AGP_G4x_GCC1_SIZE_2M: 1346 case AGP_G4x_GCC1_SIZE_VT_2M: 1347 agp_gen5_adjust_pgtbl_size(dev, AGP_I810_PGTBL_SIZE_2MB); 1348 break; 1349 default: 1350 device_printf(dev, "Unknown page table size\n"); 1351 return (ENXIO); 1352 } 1353 1354 return (agp_i965_get_gtt_total_entries(dev)); 1355} 1356 1357static int 1358agp_sb_get_gtt_total_entries(device_t dev) 1359{ 1360 struct agp_i810_softc *sc; 1361 uint16_t gcc1; 1362 1363 sc = device_get_softc(dev); 1364 1365 gcc1 = pci_read_config(sc->bdev, AGP_SNB_GCC1, 2); 1366 switch (gcc1 & AGP_SNB_GTT_SIZE_MASK) { 1367 default: 1368 case AGP_SNB_GTT_SIZE_0M: 1369 printf("Bad GTT size mask: 0x%04x\n", gcc1); 1370 return (ENXIO); 1371 case AGP_SNB_GTT_SIZE_1M: 1372 sc->gtt_total_entries = 1024 * 1024 / 4; 1373 break; 1374 case AGP_SNB_GTT_SIZE_2M: 1375 sc->gtt_total_entries = 2 * 1024 * 1024 / 4; 1376 break; 1377 } 1378 return (0); 1379} 1380 1381static int 1382agp_i810_install_gatt(device_t dev) 1383{ 1384 struct agp_i810_softc *sc; 1385 1386 sc = device_get_softc(dev); 1387 1388 /* Some i810s have on-chip memory called dcache. */ 1389 if ((bus_read_1(sc->sc_res[0], AGP_I810_DRT) & AGP_I810_DRT_POPULATED) 1390 != 0) 1391 sc->dcache_size = 4 * 1024 * 1024; 1392 else 1393 sc->dcache_size = 0; 1394 1395 /* According to the specs the gatt on the i810 must be 64k. */ 1396 sc->gatt->ag_virtual = (void *)kmem_alloc_contig(kernel_arena, 1397 64 * 1024, M_NOWAIT | M_ZERO, 0, ~0, PAGE_SIZE, 1398 0, VM_MEMATTR_WRITE_COMBINING); 1399 if (sc->gatt->ag_virtual == NULL) { 1400 if (bootverbose) 1401 device_printf(dev, "contiguous allocation failed\n"); 1402 return (ENOMEM); 1403 } 1404 1405 sc->gatt->ag_physical = vtophys((vm_offset_t)sc->gatt->ag_virtual); 1406 /* Install the GATT. */ 1407 bus_write_4(sc->sc_res[0], AGP_I810_PGTBL_CTL, 1408 sc->gatt->ag_physical | 1); 1409 return (0); 1410} 1411 1412static void 1413agp_i830_install_gatt_init(struct agp_i810_softc *sc) 1414{ 1415 uint32_t pgtblctl; 1416 1417 /* 1418 * The i830 automatically initializes the 128k gatt on boot. 1419 * GATT address is already in there, make sure it's enabled. 1420 */ 1421 pgtblctl = bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL); 1422 pgtblctl |= 1; 1423 bus_write_4(sc->sc_res[0], AGP_I810_PGTBL_CTL, pgtblctl); 1424 1425 sc->gatt->ag_physical = pgtblctl & ~1; 1426} 1427 1428static int 1429agp_i830_install_gatt(device_t dev) 1430{ 1431 struct agp_i810_softc *sc; 1432 1433 sc = device_get_softc(dev); 1434 agp_i830_install_gatt_init(sc); 1435 return (0); 1436} 1437 1438static int 1439agp_gen4_install_gatt(device_t dev, const vm_size_t gtt_offset) 1440{ 1441 struct agp_i810_softc *sc; 1442 1443 sc = device_get_softc(dev); 1444 pmap_change_attr((vm_offset_t)rman_get_virtual(sc->sc_res[0]) + 1445 gtt_offset, rman_get_size(sc->sc_res[0]) - gtt_offset, 1446 VM_MEMATTR_WRITE_COMBINING); 1447 agp_i830_install_gatt_init(sc); 1448 return (0); 1449} 1450 1451static int 1452agp_i965_install_gatt(device_t dev) 1453{ 1454 1455 return (agp_gen4_install_gatt(dev, 512 * 1024)); 1456} 1457 1458static int 1459agp_g4x_install_gatt(device_t dev) 1460{ 1461 1462 return (agp_gen4_install_gatt(dev, 2 * 1024 * 1024)); 1463} 1464 1465static int 1466agp_i810_attach(device_t dev) 1467{ 1468 struct agp_i810_softc *sc; 1469 int error; 1470 1471 sc = device_get_softc(dev); 1472 sc->bdev = agp_i810_find_bridge(dev); 1473 if (sc->bdev == NULL) 1474 return (ENOENT); 1475 1476 sc->match = agp_i810_match(dev); 1477 1478 agp_set_aperture_resource(dev, sc->match->driver->gen <= 2 ? 1479 AGP_APBASE : AGP_I915_GMADR); 1480 error = agp_generic_attach(dev); 1481 if (error) 1482 return (error); 1483 1484 if (ptoa((vm_paddr_t)Maxmem) > 1485 (1ULL << sc->match->driver->busdma_addr_mask_sz) - 1) { 1486 device_printf(dev, "agp_i810 does not support physical " 1487 "memory above %ju.\n", (uintmax_t)(1ULL << 1488 sc->match->driver->busdma_addr_mask_sz) - 1); 1489 return (ENOENT); 1490 } 1491 1492 if (bus_alloc_resources(dev, sc->match->driver->res_spec, sc->sc_res)) { 1493 agp_generic_detach(dev); 1494 return (ENODEV); 1495 } 1496 1497 sc->initial_aperture = AGP_GET_APERTURE(dev); 1498 sc->gatt = malloc(sizeof(struct agp_gatt), M_AGP, M_WAITOK); 1499 sc->gatt->ag_entries = AGP_GET_APERTURE(dev) >> AGP_PAGE_SHIFT; 1500 1501 if ((error = sc->match->driver->get_stolen_size(dev)) != 0 || 1502 (error = sc->match->driver->install_gatt(dev)) != 0 || 1503 (error = sc->match->driver->get_gtt_mappable_entries(dev)) != 0 || 1504 (error = sc->match->driver->get_gtt_total_entries(dev)) != 0 || 1505 (error = sc->match->driver->chipset_flush_setup(dev)) != 0) { 1506 bus_release_resources(dev, sc->match->driver->res_spec, 1507 sc->sc_res); 1508 free(sc->gatt, M_AGP); 1509 agp_generic_detach(dev); 1510 return (error); 1511 } 1512 1513 intel_agp = dev; 1514 device_printf(dev, "aperture size is %dM", 1515 sc->initial_aperture / 1024 / 1024); 1516 if (sc->stolen > 0) 1517 printf(", detected %dk stolen memory\n", sc->stolen * 4); 1518 else 1519 printf("\n"); 1520 if (bootverbose) { 1521 sc->match->driver->dump_regs(dev); 1522 device_printf(dev, "Mappable GTT entries: %d\n", 1523 sc->gtt_mappable_entries); 1524 device_printf(dev, "Total GTT entries: %d\n", 1525 sc->gtt_total_entries); 1526 } 1527 return (0); 1528} 1529 1530static void 1531agp_i810_deinstall_gatt(device_t dev) 1532{ 1533 struct agp_i810_softc *sc; 1534 1535 sc = device_get_softc(dev); 1536 bus_write_4(sc->sc_res[0], AGP_I810_PGTBL_CTL, 0); 1537 kmem_free(kernel_arena, (vm_offset_t)sc->gatt->ag_virtual, 64 * 1024); 1538} 1539 1540static void 1541agp_i830_deinstall_gatt(device_t dev) 1542{ 1543 struct agp_i810_softc *sc; 1544 unsigned int pgtblctl; 1545 1546 sc = device_get_softc(dev); 1547 pgtblctl = bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL); 1548 pgtblctl &= ~1; 1549 bus_write_4(sc->sc_res[0], AGP_I810_PGTBL_CTL, pgtblctl); 1550} 1551 1552static int 1553agp_i810_detach(device_t dev) 1554{ 1555 struct agp_i810_softc *sc; 1556 1557 sc = device_get_softc(dev); 1558 agp_free_cdev(dev); 1559 1560 /* Clear the GATT base. */ 1561 sc->match->driver->deinstall_gatt(dev); 1562 1563 sc->match->driver->chipset_flush_teardown(dev); 1564 1565 /* Put the aperture back the way it started. */ 1566 AGP_SET_APERTURE(dev, sc->initial_aperture); 1567 1568 free(sc->gatt, M_AGP); 1569 bus_release_resources(dev, sc->match->driver->res_spec, sc->sc_res); 1570 agp_free_res(dev); 1571 1572 return (0); 1573} 1574 1575static int 1576agp_i810_resume(device_t dev) 1577{ 1578 struct agp_i810_softc *sc; 1579 sc = device_get_softc(dev); 1580 1581 AGP_SET_APERTURE(dev, sc->initial_aperture); 1582 1583 /* Install the GATT. */ 1584 bus_write_4(sc->sc_res[0], AGP_I810_PGTBL_CTL, 1585 sc->gatt->ag_physical | 1); 1586 1587 return (bus_generic_resume(dev)); 1588} 1589 1590/** 1591 * Sets the PCI resource size of the aperture on i830-class and below chipsets, 1592 * while returning failure on later chipsets when an actual change is 1593 * requested. 1594 * 1595 * This whole function is likely bogus, as the kernel would probably need to 1596 * reconfigure the placement of the AGP aperture if a larger size is requested, 1597 * which doesn't happen currently. 1598 */ 1599static int 1600agp_i810_set_aperture(device_t dev, u_int32_t aperture) 1601{ 1602 struct agp_i810_softc *sc; 1603 u_int16_t miscc; 1604 1605 sc = device_get_softc(dev); 1606 /* 1607 * Double check for sanity. 1608 */ 1609 if (aperture != 32 * 1024 * 1024 && aperture != 64 * 1024 * 1024) { 1610 device_printf(dev, "bad aperture size %d\n", aperture); 1611 return (EINVAL); 1612 } 1613 1614 miscc = pci_read_config(sc->bdev, AGP_I810_MISCC, 2); 1615 miscc &= ~AGP_I810_MISCC_WINSIZE; 1616 if (aperture == 32 * 1024 * 1024) 1617 miscc |= AGP_I810_MISCC_WINSIZE_32; 1618 else 1619 miscc |= AGP_I810_MISCC_WINSIZE_64; 1620 1621 pci_write_config(sc->bdev, AGP_I810_MISCC, miscc, 2); 1622 return (0); 1623} 1624 1625static int 1626agp_i830_set_aperture(device_t dev, u_int32_t aperture) 1627{ 1628 struct agp_i810_softc *sc; 1629 u_int16_t gcc1; 1630 1631 sc = device_get_softc(dev); 1632 1633 if (aperture != 64 * 1024 * 1024 && 1634 aperture != 128 * 1024 * 1024) { 1635 device_printf(dev, "bad aperture size %d\n", aperture); 1636 return (EINVAL); 1637 } 1638 gcc1 = pci_read_config(sc->bdev, AGP_I830_GCC1, 2); 1639 gcc1 &= ~AGP_I830_GCC1_GMASIZE; 1640 if (aperture == 64 * 1024 * 1024) 1641 gcc1 |= AGP_I830_GCC1_GMASIZE_64; 1642 else 1643 gcc1 |= AGP_I830_GCC1_GMASIZE_128; 1644 1645 pci_write_config(sc->bdev, AGP_I830_GCC1, gcc1, 2); 1646 return (0); 1647} 1648 1649static int 1650agp_i915_set_aperture(device_t dev, u_int32_t aperture) 1651{ 1652 1653 return (agp_generic_set_aperture(dev, aperture)); 1654} 1655 1656static int 1657agp_i810_method_set_aperture(device_t dev, u_int32_t aperture) 1658{ 1659 struct agp_i810_softc *sc; 1660 1661 sc = device_get_softc(dev); 1662 return (sc->match->driver->set_aperture(dev, aperture)); 1663} 1664 1665/** 1666 * Writes a GTT entry mapping the page at the given offset from the 1667 * beginning of the aperture to the given physical address. Setup the 1668 * caching mode according to flags. 1669 * 1670 * For gen 1, 2 and 3, GTT start is located at AGP_I810_GTT offset 1671 * from corresponding BAR start. For gen 4, offset is 512KB + 1672 * AGP_I810_GTT, for gen 5 and 6 it is 2MB + AGP_I810_GTT. 1673 * 1674 * Also, the bits of the physical page address above 4GB needs to be 1675 * placed into bits 40-32 of PTE. 1676 */ 1677static void 1678agp_i810_install_gtt_pte(device_t dev, u_int index, vm_offset_t physical, 1679 int flags) 1680{ 1681 uint32_t pte; 1682 1683 pte = (u_int32_t)physical | I810_PTE_VALID; 1684 if (flags == AGP_DCACHE_MEMORY) 1685 pte |= I810_PTE_LOCAL; 1686 else if (flags == AGP_USER_CACHED_MEMORY) 1687 pte |= I830_PTE_SYSTEM_CACHED; 1688 agp_i810_write_gtt(dev, index, pte); 1689} 1690 1691static void 1692agp_i810_write_gtt(device_t dev, u_int index, uint32_t pte) 1693{ 1694 struct agp_i810_softc *sc; 1695 1696 sc = device_get_softc(dev); 1697 bus_write_4(sc->sc_res[0], AGP_I810_GTT + index * 4, pte); 1698 CTR2(KTR_AGP_I810, "810_pte %x %x", index, pte); 1699} 1700 1701static void 1702agp_i830_install_gtt_pte(device_t dev, u_int index, vm_offset_t physical, 1703 int flags) 1704{ 1705 uint32_t pte; 1706 1707 pte = (u_int32_t)physical | I810_PTE_VALID; 1708 if (flags == AGP_USER_CACHED_MEMORY) 1709 pte |= I830_PTE_SYSTEM_CACHED; 1710 agp_i810_write_gtt(dev, index, pte); 1711} 1712 1713static void 1714agp_i915_install_gtt_pte(device_t dev, u_int index, vm_offset_t physical, 1715 int flags) 1716{ 1717 uint32_t pte; 1718 1719 pte = (u_int32_t)physical | I810_PTE_VALID; 1720 if (flags == AGP_USER_CACHED_MEMORY) 1721 pte |= I830_PTE_SYSTEM_CACHED; 1722 pte |= (physical & 0x0000000f00000000ull) >> 28; 1723 agp_i915_write_gtt(dev, index, pte); 1724} 1725 1726static void 1727agp_i915_write_gtt(device_t dev, u_int index, uint32_t pte) 1728{ 1729 struct agp_i810_softc *sc; 1730 1731 sc = device_get_softc(dev); 1732 bus_write_4(sc->sc_res[1], index * 4, pte); 1733 CTR2(KTR_AGP_I810, "915_pte %x %x", index, pte); 1734} 1735 1736static void 1737agp_i965_install_gtt_pte(device_t dev, u_int index, vm_offset_t physical, 1738 int flags) 1739{ 1740 uint32_t pte; 1741 1742 pte = (u_int32_t)physical | I810_PTE_VALID; 1743 if (flags == AGP_USER_CACHED_MEMORY) 1744 pte |= I830_PTE_SYSTEM_CACHED; 1745 pte |= (physical & 0x0000000f00000000ull) >> 28; 1746 agp_i965_write_gtt(dev, index, pte); 1747} 1748 1749static void 1750agp_i965_write_gtt(device_t dev, u_int index, uint32_t pte) 1751{ 1752 struct agp_i810_softc *sc; 1753 1754 sc = device_get_softc(dev); 1755 bus_write_4(sc->sc_res[0], index * 4 + (512 * 1024), pte); 1756 CTR2(KTR_AGP_I810, "965_pte %x %x", index, pte); 1757} 1758 1759static void 1760agp_g4x_install_gtt_pte(device_t dev, u_int index, vm_offset_t physical, 1761 int flags) 1762{ 1763 uint32_t pte; 1764 1765 pte = (u_int32_t)physical | I810_PTE_VALID; 1766 if (flags == AGP_USER_CACHED_MEMORY) 1767 pte |= I830_PTE_SYSTEM_CACHED; 1768 pte |= (physical & 0x0000000f00000000ull) >> 28; 1769 agp_g4x_write_gtt(dev, index, pte); 1770} 1771 1772static void 1773agp_g4x_write_gtt(device_t dev, u_int index, uint32_t pte) 1774{ 1775 struct agp_i810_softc *sc; 1776 1777 sc = device_get_softc(dev); 1778 bus_write_4(sc->sc_res[0], index * 4 + (2 * 1024 * 1024), pte); 1779 CTR2(KTR_AGP_I810, "g4x_pte %x %x", index, pte); 1780} 1781 1782static void 1783agp_sb_install_gtt_pte(device_t dev, u_int index, vm_offset_t physical, 1784 int flags) 1785{ 1786 int type_mask, gfdt; 1787 uint32_t pte; 1788 1789 pte = (u_int32_t)physical | I810_PTE_VALID; 1790 type_mask = flags & ~AGP_USER_CACHED_MEMORY_GFDT; 1791 gfdt = (flags & AGP_USER_CACHED_MEMORY_GFDT) != 0 ? GEN6_PTE_GFDT : 0; 1792 1793 if (type_mask == AGP_USER_MEMORY) 1794 pte |= GEN6_PTE_UNCACHED; 1795 else if (type_mask == AGP_USER_CACHED_MEMORY_LLC_MLC) 1796 pte |= GEN6_PTE_LLC_MLC | gfdt; 1797 else 1798 pte |= GEN6_PTE_LLC | gfdt; 1799 1800 pte |= (physical & 0x000000ff00000000ull) >> 28; 1801 agp_sb_write_gtt(dev, index, pte); 1802} 1803 1804static void 1805agp_sb_write_gtt(device_t dev, u_int index, uint32_t pte) 1806{ 1807 struct agp_i810_softc *sc; 1808 1809 sc = device_get_softc(dev); 1810 bus_write_4(sc->sc_res[0], index * 4 + (2 * 1024 * 1024), pte); 1811 CTR2(KTR_AGP_I810, "sb_pte %x %x", index, pte); 1812} 1813 1814static int 1815agp_i810_bind_page(device_t dev, vm_offset_t offset, vm_offset_t physical) 1816{ 1817 struct agp_i810_softc *sc = device_get_softc(dev); 1818 u_int index; 1819 1820 if (offset >= (sc->gatt->ag_entries << AGP_PAGE_SHIFT)) { 1821 device_printf(dev, "failed: offset is 0x%08jx, " 1822 "shift is %d, entries is %d\n", (intmax_t)offset, 1823 AGP_PAGE_SHIFT, sc->gatt->ag_entries); 1824 return (EINVAL); 1825 } 1826 index = offset >> AGP_PAGE_SHIFT; 1827 if (sc->stolen != 0 && index < sc->stolen) { 1828 device_printf(dev, "trying to bind into stolen memory\n"); 1829 return (EINVAL); 1830 } 1831 sc->match->driver->install_gtt_pte(dev, index, physical, 0); 1832 return (0); 1833} 1834 1835static int 1836agp_i810_unbind_page(device_t dev, vm_offset_t offset) 1837{ 1838 struct agp_i810_softc *sc; 1839 u_int index; 1840 1841 sc = device_get_softc(dev); 1842 if (offset >= (sc->gatt->ag_entries << AGP_PAGE_SHIFT)) 1843 return (EINVAL); 1844 index = offset >> AGP_PAGE_SHIFT; 1845 if (sc->stolen != 0 && index < sc->stolen) { 1846 device_printf(dev, "trying to unbind from stolen memory\n"); 1847 return (EINVAL); 1848 } 1849 sc->match->driver->install_gtt_pte(dev, index, 0, 0); 1850 return (0); 1851} 1852 1853static u_int32_t 1854agp_i810_read_gtt_pte(device_t dev, u_int index) 1855{ 1856 struct agp_i810_softc *sc; 1857 u_int32_t pte; 1858 1859 sc = device_get_softc(dev); 1860 pte = bus_read_4(sc->sc_res[0], AGP_I810_GTT + index * 4); 1861 return (pte); 1862} 1863 1864static u_int32_t 1865agp_i915_read_gtt_pte(device_t dev, u_int index) 1866{ 1867 struct agp_i810_softc *sc; 1868 u_int32_t pte; 1869 1870 sc = device_get_softc(dev); 1871 pte = bus_read_4(sc->sc_res[1], index * 4); 1872 return (pte); 1873} 1874 1875static u_int32_t 1876agp_i965_read_gtt_pte(device_t dev, u_int index) 1877{ 1878 struct agp_i810_softc *sc; 1879 u_int32_t pte; 1880 1881 sc = device_get_softc(dev); 1882 pte = bus_read_4(sc->sc_res[0], index * 4 + (512 * 1024)); 1883 return (pte); 1884} 1885 1886static u_int32_t 1887agp_g4x_read_gtt_pte(device_t dev, u_int index) 1888{ 1889 struct agp_i810_softc *sc; 1890 u_int32_t pte; 1891 1892 sc = device_get_softc(dev); 1893 pte = bus_read_4(sc->sc_res[0], index * 4 + (2 * 1024 * 1024)); 1894 return (pte); 1895} 1896 1897static vm_paddr_t 1898agp_i810_read_gtt_pte_paddr(device_t dev, u_int index) 1899{ 1900 struct agp_i810_softc *sc; 1901 u_int32_t pte; 1902 vm_paddr_t res; 1903 1904 sc = device_get_softc(dev); 1905 pte = sc->match->driver->read_gtt_pte(dev, index); 1906 res = pte & ~PAGE_MASK; 1907 return (res); 1908} 1909 1910static vm_paddr_t 1911agp_i915_read_gtt_pte_paddr(device_t dev, u_int index) 1912{ 1913 struct agp_i810_softc *sc; 1914 u_int32_t pte; 1915 vm_paddr_t res; 1916 1917 sc = device_get_softc(dev); 1918 pte = sc->match->driver->read_gtt_pte(dev, index); 1919 res = (pte & ~PAGE_MASK) | ((pte & 0xf0) << 28); 1920 return (res); 1921} 1922 1923static vm_paddr_t 1924agp_sb_read_gtt_pte_paddr(device_t dev, u_int index) 1925{ 1926 struct agp_i810_softc *sc; 1927 u_int32_t pte; 1928 vm_paddr_t res; 1929 1930 sc = device_get_softc(dev); 1931 pte = sc->match->driver->read_gtt_pte(dev, index); 1932 res = (pte & ~PAGE_MASK) | ((pte & 0xff0) << 28); 1933 return (res); 1934} 1935 1936/* 1937 * Writing via memory mapped registers already flushes all TLBs. 1938 */ 1939static void 1940agp_i810_flush_tlb(device_t dev) 1941{ 1942} 1943 1944static int 1945agp_i810_enable(device_t dev, u_int32_t mode) 1946{ 1947 1948 return (0); 1949} 1950 1951static struct agp_memory * 1952agp_i810_alloc_memory(device_t dev, int type, vm_size_t size) 1953{ 1954 struct agp_i810_softc *sc; 1955 struct agp_memory *mem; 1956 vm_page_t m; 1957 1958 sc = device_get_softc(dev); 1959 1960 if ((size & (AGP_PAGE_SIZE - 1)) != 0 || 1961 sc->agp.as_allocated + size > sc->agp.as_maxmem) 1962 return (0); 1963 1964 if (type == 1) { 1965 /* 1966 * Mapping local DRAM into GATT. 1967 */ 1968 if (sc->match->driver->chiptype != CHIP_I810) 1969 return (0); 1970 if (size != sc->dcache_size) 1971 return (0); 1972 } else if (type == 2) { 1973 /* 1974 * Type 2 is the contiguous physical memory type, that hands 1975 * back a physical address. This is used for cursors on i810. 1976 * Hand back as many single pages with physical as the user 1977 * wants, but only allow one larger allocation (ARGB cursor) 1978 * for simplicity. 1979 */ 1980 if (size != AGP_PAGE_SIZE) { 1981 if (sc->argb_cursor != NULL) 1982 return (0); 1983 1984 /* Allocate memory for ARGB cursor, if we can. */ 1985 sc->argb_cursor = contigmalloc(size, M_AGP, 1986 0, 0, ~0, PAGE_SIZE, 0); 1987 if (sc->argb_cursor == NULL) 1988 return (0); 1989 } 1990 } 1991 1992 mem = malloc(sizeof *mem, M_AGP, M_WAITOK); 1993 mem->am_id = sc->agp.as_nextid++; 1994 mem->am_size = size; 1995 mem->am_type = type; 1996 if (type != 1 && (type != 2 || size == AGP_PAGE_SIZE)) 1997 mem->am_obj = vm_object_allocate(OBJT_DEFAULT, 1998 atop(round_page(size))); 1999 else 2000 mem->am_obj = 0; 2001 2002 if (type == 2) { 2003 if (size == AGP_PAGE_SIZE) { 2004 /* 2005 * Allocate and wire down the page now so that we can 2006 * get its physical address. 2007 */ 2008 VM_OBJECT_WLOCK(mem->am_obj); 2009 m = vm_page_grab(mem->am_obj, 0, VM_ALLOC_NOBUSY | 2010 VM_ALLOC_WIRED | VM_ALLOC_ZERO); 2011 VM_OBJECT_WUNLOCK(mem->am_obj); 2012 mem->am_physical = VM_PAGE_TO_PHYS(m); 2013 } else { 2014 /* Our allocation is already nicely wired down for us. 2015 * Just grab the physical address. 2016 */ 2017 mem->am_physical = vtophys(sc->argb_cursor); 2018 } 2019 } else 2020 mem->am_physical = 0; 2021 2022 mem->am_offset = 0; 2023 mem->am_is_bound = 0; 2024 TAILQ_INSERT_TAIL(&sc->agp.as_memory, mem, am_link); 2025 sc->agp.as_allocated += size; 2026 2027 return (mem); 2028} 2029 2030static int 2031agp_i810_free_memory(device_t dev, struct agp_memory *mem) 2032{ 2033 struct agp_i810_softc *sc; 2034 vm_page_t m; 2035 2036 if (mem->am_is_bound) 2037 return (EBUSY); 2038 2039 sc = device_get_softc(dev); 2040 2041 if (mem->am_type == 2) { 2042 if (mem->am_size == AGP_PAGE_SIZE) { 2043 /* 2044 * Unwire the page which we wired in alloc_memory. 2045 */ 2046 VM_OBJECT_WLOCK(mem->am_obj); 2047 m = vm_page_lookup(mem->am_obj, 0); 2048 vm_page_lock(m); 2049 vm_page_unwire(m, PQ_INACTIVE); 2050 vm_page_unlock(m); 2051 VM_OBJECT_WUNLOCK(mem->am_obj); 2052 } else { 2053 contigfree(sc->argb_cursor, mem->am_size, M_AGP); 2054 sc->argb_cursor = NULL; 2055 } 2056 } 2057 2058 sc->agp.as_allocated -= mem->am_size; 2059 TAILQ_REMOVE(&sc->agp.as_memory, mem, am_link); 2060 if (mem->am_obj) 2061 vm_object_deallocate(mem->am_obj); 2062 free(mem, M_AGP); 2063 return (0); 2064} 2065 2066static int 2067agp_i810_bind_memory(device_t dev, struct agp_memory *mem, vm_offset_t offset) 2068{ 2069 struct agp_i810_softc *sc; 2070 vm_offset_t i; 2071 2072 /* Do some sanity checks first. */ 2073 if ((offset & (AGP_PAGE_SIZE - 1)) != 0 || 2074 offset + mem->am_size > AGP_GET_APERTURE(dev)) { 2075 device_printf(dev, "binding memory at bad offset %#x\n", 2076 (int)offset); 2077 return (EINVAL); 2078 } 2079 2080 sc = device_get_softc(dev); 2081 if (mem->am_type == 2 && mem->am_size != AGP_PAGE_SIZE) { 2082 mtx_lock(&sc->agp.as_lock); 2083 if (mem->am_is_bound) { 2084 mtx_unlock(&sc->agp.as_lock); 2085 return (EINVAL); 2086 } 2087 /* The memory's already wired down, just stick it in the GTT. */ 2088 for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE) { 2089 sc->match->driver->install_gtt_pte(dev, (offset + i) >> 2090 AGP_PAGE_SHIFT, mem->am_physical + i, 0); 2091 } 2092 mem->am_offset = offset; 2093 mem->am_is_bound = 1; 2094 mtx_unlock(&sc->agp.as_lock); 2095 return (0); 2096 } 2097 2098 if (mem->am_type != 1) 2099 return (agp_generic_bind_memory(dev, mem, offset)); 2100 2101 /* 2102 * Mapping local DRAM into GATT. 2103 */ 2104 if (sc->match->driver->chiptype != CHIP_I810) 2105 return (EINVAL); 2106 for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE) 2107 bus_write_4(sc->sc_res[0], 2108 AGP_I810_GTT + (i >> AGP_PAGE_SHIFT) * 4, i | 3); 2109 2110 return (0); 2111} 2112 2113static int 2114agp_i810_unbind_memory(device_t dev, struct agp_memory *mem) 2115{ 2116 struct agp_i810_softc *sc; 2117 vm_offset_t i; 2118 2119 sc = device_get_softc(dev); 2120 2121 if (mem->am_type == 2 && mem->am_size != AGP_PAGE_SIZE) { 2122 mtx_lock(&sc->agp.as_lock); 2123 if (!mem->am_is_bound) { 2124 mtx_unlock(&sc->agp.as_lock); 2125 return (EINVAL); 2126 } 2127 2128 for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE) { 2129 sc->match->driver->install_gtt_pte(dev, 2130 (mem->am_offset + i) >> AGP_PAGE_SHIFT, 0, 0); 2131 } 2132 mem->am_is_bound = 0; 2133 mtx_unlock(&sc->agp.as_lock); 2134 return (0); 2135 } 2136 2137 if (mem->am_type != 1) 2138 return (agp_generic_unbind_memory(dev, mem)); 2139 2140 if (sc->match->driver->chiptype != CHIP_I810) 2141 return (EINVAL); 2142 for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE) { 2143 sc->match->driver->install_gtt_pte(dev, i >> AGP_PAGE_SHIFT, 2144 0, 0); 2145 } 2146 return (0); 2147} 2148 2149static device_method_t agp_i810_methods[] = { 2150 /* Device interface */ 2151 DEVMETHOD(device_identify, agp_i810_identify), 2152 DEVMETHOD(device_probe, agp_i810_probe), 2153 DEVMETHOD(device_attach, agp_i810_attach), 2154 DEVMETHOD(device_detach, agp_i810_detach), 2155 DEVMETHOD(device_suspend, bus_generic_suspend), 2156 DEVMETHOD(device_resume, agp_i810_resume), 2157 2158 /* AGP interface */ 2159 DEVMETHOD(agp_get_aperture, agp_generic_get_aperture), 2160 DEVMETHOD(agp_set_aperture, agp_i810_method_set_aperture), 2161 DEVMETHOD(agp_bind_page, agp_i810_bind_page), 2162 DEVMETHOD(agp_unbind_page, agp_i810_unbind_page), 2163 DEVMETHOD(agp_flush_tlb, agp_i810_flush_tlb), 2164 DEVMETHOD(agp_enable, agp_i810_enable), 2165 DEVMETHOD(agp_alloc_memory, agp_i810_alloc_memory), 2166 DEVMETHOD(agp_free_memory, agp_i810_free_memory), 2167 DEVMETHOD(agp_bind_memory, agp_i810_bind_memory), 2168 DEVMETHOD(agp_unbind_memory, agp_i810_unbind_memory), 2169 DEVMETHOD(agp_chipset_flush, agp_intel_gtt_chipset_flush), 2170 2171 { 0, 0 } 2172}; 2173 2174static driver_t agp_i810_driver = { 2175 "agp", 2176 agp_i810_methods, 2177 sizeof(struct agp_i810_softc), 2178}; 2179 2180static devclass_t agp_devclass; 2181 2182DRIVER_MODULE(agp_i810, vgapci, agp_i810_driver, agp_devclass, 0, 0); 2183MODULE_DEPEND(agp_i810, agp, 1, 1, 1); 2184MODULE_DEPEND(agp_i810, pci, 1, 1, 1); 2185 2186extern vm_page_t bogus_page; 2187 2188void 2189agp_intel_gtt_clear_range(device_t dev, u_int first_entry, u_int num_entries) 2190{ 2191 struct agp_i810_softc *sc; 2192 u_int i; 2193 2194 sc = device_get_softc(dev); 2195 for (i = 0; i < num_entries; i++) 2196 sc->match->driver->install_gtt_pte(dev, first_entry + i, 2197 VM_PAGE_TO_PHYS(bogus_page), 0); 2198 sc->match->driver->read_gtt_pte(dev, first_entry + num_entries - 1); 2199} 2200 2201void 2202agp_intel_gtt_insert_pages(device_t dev, u_int first_entry, u_int num_entries, 2203 vm_page_t *pages, u_int flags) 2204{ 2205 struct agp_i810_softc *sc; 2206 u_int i; 2207 2208 sc = device_get_softc(dev); 2209 for (i = 0; i < num_entries; i++) { 2210 MPASS(pages[i]->valid == VM_PAGE_BITS_ALL); 2211 MPASS(pages[i]->wire_count > 0); 2212 sc->match->driver->install_gtt_pte(dev, first_entry + i, 2213 VM_PAGE_TO_PHYS(pages[i]), flags); 2214 } 2215 sc->match->driver->read_gtt_pte(dev, first_entry + num_entries - 1); 2216} 2217 2218struct intel_gtt 2219agp_intel_gtt_get(device_t dev) 2220{ 2221 struct agp_i810_softc *sc; 2222 struct intel_gtt res; 2223 2224 sc = device_get_softc(dev); 2225 res.stolen_size = sc->stolen_size; 2226 res.gtt_total_entries = sc->gtt_total_entries; 2227 res.gtt_mappable_entries = sc->gtt_mappable_entries; 2228 res.do_idle_maps = 0; 2229 res.scratch_page_dma = VM_PAGE_TO_PHYS(bogus_page); 2230 return (res); 2231} 2232 2233static int 2234agp_i810_chipset_flush_setup(device_t dev) 2235{ 2236 2237 return (0); 2238} 2239 2240static void 2241agp_i810_chipset_flush_teardown(device_t dev) 2242{ 2243 2244 /* Nothing to do. */ 2245} 2246 2247static void 2248agp_i810_chipset_flush(device_t dev) 2249{ 2250 2251 /* Nothing to do. */ 2252} 2253 2254static void 2255agp_i830_chipset_flush(device_t dev) 2256{ 2257 struct agp_i810_softc *sc; 2258 uint32_t hic; 2259 int i; 2260 2261 sc = device_get_softc(dev); 2262 pmap_invalidate_cache(); 2263 hic = bus_read_4(sc->sc_res[0], AGP_I830_HIC); 2264 bus_write_4(sc->sc_res[0], AGP_I830_HIC, hic | (1U << 31)); 2265 for (i = 0; i < 20000 /* 1 sec */; i++) { 2266 hic = bus_read_4(sc->sc_res[0], AGP_I830_HIC); 2267 if ((hic & (1U << 31)) == 0) 2268 break; 2269 DELAY(50); 2270 } 2271} 2272 2273static int 2274agp_i915_chipset_flush_alloc_page(device_t dev, uint64_t start, uint64_t end) 2275{ 2276 struct agp_i810_softc *sc; 2277 device_t vga; 2278 2279 sc = device_get_softc(dev); 2280 vga = device_get_parent(dev); 2281 sc->sc_flush_page_rid = 100; 2282 sc->sc_flush_page_res = BUS_ALLOC_RESOURCE(device_get_parent(vga), dev, 2283 SYS_RES_MEMORY, &sc->sc_flush_page_rid, start, end, PAGE_SIZE, 2284 RF_ACTIVE); 2285 if (sc->sc_flush_page_res == NULL) { 2286 device_printf(dev, "Failed to allocate flush page at 0x%jx\n", 2287 (uintmax_t)start); 2288 return (EINVAL); 2289 } 2290 sc->sc_flush_page_vaddr = rman_get_virtual(sc->sc_flush_page_res); 2291 if (bootverbose) { 2292 device_printf(dev, "Allocated flush page phys 0x%jx virt %p\n", 2293 (uintmax_t)rman_get_start(sc->sc_flush_page_res), 2294 sc->sc_flush_page_vaddr); 2295 } 2296 return (0); 2297} 2298 2299static void 2300agp_i915_chipset_flush_free_page(device_t dev) 2301{ 2302 struct agp_i810_softc *sc; 2303 device_t vga; 2304 2305 sc = device_get_softc(dev); 2306 vga = device_get_parent(dev); 2307 if (sc->sc_flush_page_res == NULL) 2308 return; 2309 BUS_DEACTIVATE_RESOURCE(device_get_parent(vga), dev, SYS_RES_MEMORY, 2310 sc->sc_flush_page_rid, sc->sc_flush_page_res); 2311 BUS_RELEASE_RESOURCE(device_get_parent(vga), dev, SYS_RES_MEMORY, 2312 sc->sc_flush_page_rid, sc->sc_flush_page_res); 2313} 2314 2315static int 2316agp_i915_chipset_flush_setup(device_t dev) 2317{ 2318 struct agp_i810_softc *sc; 2319 uint32_t temp; 2320 int error; 2321 2322 sc = device_get_softc(dev); 2323 temp = pci_read_config(sc->bdev, AGP_I915_IFPADDR, 4); 2324 if ((temp & 1) != 0) { 2325 temp &= ~1; 2326 if (bootverbose) 2327 device_printf(dev, 2328 "Found already configured flush page at 0x%jx\n", 2329 (uintmax_t)temp); 2330 sc->sc_bios_allocated_flush_page = 1; 2331 /* 2332 * In the case BIOS initialized the flush pointer (?) 2333 * register, expect that BIOS also set up the resource 2334 * for the page. 2335 */ 2336 error = agp_i915_chipset_flush_alloc_page(dev, temp, 2337 temp + PAGE_SIZE - 1); 2338 if (error != 0) 2339 return (error); 2340 } else { 2341 sc->sc_bios_allocated_flush_page = 0; 2342 error = agp_i915_chipset_flush_alloc_page(dev, 0, 0xffffffff); 2343 if (error != 0) 2344 return (error); 2345 temp = rman_get_start(sc->sc_flush_page_res); 2346 pci_write_config(sc->bdev, AGP_I915_IFPADDR, temp | 1, 4); 2347 } 2348 return (0); 2349} 2350 2351static void 2352agp_i915_chipset_flush_teardown(device_t dev) 2353{ 2354 struct agp_i810_softc *sc; 2355 uint32_t temp; 2356 2357 sc = device_get_softc(dev); 2358 if (sc->sc_flush_page_res == NULL) 2359 return; 2360 if (!sc->sc_bios_allocated_flush_page) { 2361 temp = pci_read_config(sc->bdev, AGP_I915_IFPADDR, 4); 2362 temp &= ~1; 2363 pci_write_config(sc->bdev, AGP_I915_IFPADDR, temp, 4); 2364 } 2365 agp_i915_chipset_flush_free_page(dev); 2366} 2367 2368static int 2369agp_i965_chipset_flush_setup(device_t dev) 2370{ 2371 struct agp_i810_softc *sc; 2372 uint64_t temp; 2373 uint32_t temp_hi, temp_lo; 2374 int error; 2375 2376 sc = device_get_softc(dev); 2377 2378 temp_hi = pci_read_config(sc->bdev, AGP_I965_IFPADDR + 4, 4); 2379 temp_lo = pci_read_config(sc->bdev, AGP_I965_IFPADDR, 4); 2380 2381 if ((temp_lo & 1) != 0) { 2382 temp = ((uint64_t)temp_hi << 32) | (temp_lo & ~1); 2383 if (bootverbose) 2384 device_printf(dev, 2385 "Found already configured flush page at 0x%jx\n", 2386 (uintmax_t)temp); 2387 sc->sc_bios_allocated_flush_page = 1; 2388 /* 2389 * In the case BIOS initialized the flush pointer (?) 2390 * register, expect that BIOS also set up the resource 2391 * for the page. 2392 */ 2393 error = agp_i915_chipset_flush_alloc_page(dev, temp, 2394 temp + PAGE_SIZE - 1); 2395 if (error != 0) 2396 return (error); 2397 } else { 2398 sc->sc_bios_allocated_flush_page = 0; 2399 error = agp_i915_chipset_flush_alloc_page(dev, 0, ~0); 2400 if (error != 0) 2401 return (error); 2402 temp = rman_get_start(sc->sc_flush_page_res); 2403 pci_write_config(sc->bdev, AGP_I965_IFPADDR + 4, 2404 (temp >> 32) & UINT32_MAX, 4); 2405 pci_write_config(sc->bdev, AGP_I965_IFPADDR, 2406 (temp & UINT32_MAX) | 1, 4); 2407 } 2408 return (0); 2409} 2410 2411static void 2412agp_i965_chipset_flush_teardown(device_t dev) 2413{ 2414 struct agp_i810_softc *sc; 2415 uint32_t temp_lo; 2416 2417 sc = device_get_softc(dev); 2418 if (sc->sc_flush_page_res == NULL) 2419 return; 2420 if (!sc->sc_bios_allocated_flush_page) { 2421 temp_lo = pci_read_config(sc->bdev, AGP_I965_IFPADDR, 4); 2422 temp_lo &= ~1; 2423 pci_write_config(sc->bdev, AGP_I965_IFPADDR, temp_lo, 4); 2424 } 2425 agp_i915_chipset_flush_free_page(dev); 2426} 2427 2428static void 2429agp_i915_chipset_flush(device_t dev) 2430{ 2431 struct agp_i810_softc *sc; 2432 2433 sc = device_get_softc(dev); 2434 *(uint32_t *)sc->sc_flush_page_vaddr = 1; 2435} 2436 2437int 2438agp_intel_gtt_chipset_flush(device_t dev) 2439{ 2440 struct agp_i810_softc *sc; 2441 2442 sc = device_get_softc(dev); 2443 sc->match->driver->chipset_flush(dev); 2444 return (0); 2445} 2446 2447void 2448agp_intel_gtt_unmap_memory(device_t dev, struct sglist *sg_list) 2449{ 2450} 2451 2452int 2453agp_intel_gtt_map_memory(device_t dev, vm_page_t *pages, u_int num_entries, 2454 struct sglist **sg_list) 2455{ 2456 struct agp_i810_softc *sc; 2457 struct sglist *sg; 2458 int i; 2459#if 0 2460 int error; 2461 bus_dma_tag_t dmat; 2462#endif 2463 2464 if (*sg_list != NULL) 2465 return (0); 2466 sc = device_get_softc(dev); 2467 sg = sglist_alloc(num_entries, M_WAITOK /* XXXKIB */); 2468 for (i = 0; i < num_entries; i++) { 2469 sg->sg_segs[i].ss_paddr = VM_PAGE_TO_PHYS(pages[i]); 2470 sg->sg_segs[i].ss_len = PAGE_SIZE; 2471 } 2472 2473#if 0 2474 error = bus_dma_tag_create(bus_get_dma_tag(dev), 2475 1 /* alignment */, 0 /* boundary */, 2476 1ULL << sc->match->busdma_addr_mask_sz /* lowaddr */, 2477 BUS_SPACE_MAXADDR /* highaddr */, 2478 NULL /* filtfunc */, NULL /* filtfuncarg */, 2479 BUS_SPACE_MAXADDR /* maxsize */, 2480 BUS_SPACE_UNRESTRICTED /* nsegments */, 2481 BUS_SPACE_MAXADDR /* maxsegsz */, 2482 0 /* flags */, NULL /* lockfunc */, NULL /* lockfuncarg */, 2483 &dmat); 2484 if (error != 0) { 2485 sglist_free(sg); 2486 return (error); 2487 } 2488 /* XXXKIB */ 2489#endif 2490 *sg_list = sg; 2491 return (0); 2492} 2493 2494void 2495agp_intel_gtt_insert_sg_entries(device_t dev, struct sglist *sg_list, 2496 u_int first_entry, u_int flags) 2497{ 2498 struct agp_i810_softc *sc; 2499 vm_paddr_t spaddr; 2500 size_t slen; 2501 u_int i, j; 2502 2503 sc = device_get_softc(dev); 2504 for (i = j = 0; j < sg_list->sg_nseg; j++) { 2505 spaddr = sg_list->sg_segs[i].ss_paddr; 2506 slen = sg_list->sg_segs[i].ss_len; 2507 for (; slen > 0; i++) { 2508 sc->match->driver->install_gtt_pte(dev, first_entry + i, 2509 spaddr, flags); 2510 spaddr += AGP_PAGE_SIZE; 2511 slen -= AGP_PAGE_SIZE; 2512 } 2513 } 2514 sc->match->driver->read_gtt_pte(dev, first_entry + i - 1); 2515} 2516 2517void 2518intel_gtt_clear_range(u_int first_entry, u_int num_entries) 2519{ 2520 2521 agp_intel_gtt_clear_range(intel_agp, first_entry, num_entries); 2522} 2523 2524void 2525intel_gtt_insert_pages(u_int first_entry, u_int num_entries, vm_page_t *pages, 2526 u_int flags) 2527{ 2528 2529 agp_intel_gtt_insert_pages(intel_agp, first_entry, num_entries, 2530 pages, flags); 2531} 2532 2533struct intel_gtt 2534intel_gtt_get(void) 2535{ 2536 2537 return (agp_intel_gtt_get(intel_agp)); 2538} 2539 2540int 2541intel_gtt_chipset_flush(void) 2542{ 2543 2544 return (agp_intel_gtt_chipset_flush(intel_agp)); 2545} 2546 2547void 2548intel_gtt_unmap_memory(struct sglist *sg_list) 2549{ 2550 2551 agp_intel_gtt_unmap_memory(intel_agp, sg_list); 2552} 2553 2554int 2555intel_gtt_map_memory(vm_page_t *pages, u_int num_entries, 2556 struct sglist **sg_list) 2557{ 2558 2559 return (agp_intel_gtt_map_memory(intel_agp, pages, num_entries, 2560 sg_list)); 2561} 2562 2563void 2564intel_gtt_insert_sg_entries(struct sglist *sg_list, u_int first_entry, 2565 u_int flags) 2566{ 2567 2568 agp_intel_gtt_insert_sg_entries(intel_agp, sg_list, first_entry, flags); 2569} 2570 2571device_t 2572intel_gtt_get_bridge_device(void) 2573{ 2574 struct agp_i810_softc *sc; 2575 2576 sc = device_get_softc(intel_agp); 2577 return (sc->bdev); 2578} 2579 2580vm_paddr_t 2581intel_gtt_read_pte_paddr(u_int entry) 2582{ 2583 struct agp_i810_softc *sc; 2584 2585 sc = device_get_softc(intel_agp); 2586 return (sc->match->driver->read_gtt_pte_paddr(intel_agp, entry)); 2587} 2588 2589u_int32_t 2590intel_gtt_read_pte(u_int entry) 2591{ 2592 struct agp_i810_softc *sc; 2593 2594 sc = device_get_softc(intel_agp); 2595 return (sc->match->driver->read_gtt_pte(intel_agp, entry)); 2596} 2597 2598void 2599intel_gtt_write(u_int entry, uint32_t val) 2600{ 2601 struct agp_i810_softc *sc; 2602 2603 sc = device_get_softc(intel_agp); 2604 return (sc->match->driver->write_gtt(intel_agp, entry, val)); 2605} 2606