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