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