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