1 /*- 2 * Copyright (c) 2000 Doug Rabson 3 * Copyright (c) 2000 Ruslan Ermilov 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 */ 27 28 /* 29 * Fixes for 830/845G support: David Dawes <dawes@xfree86.org> 30 * 852GM/855GM/865G support added by David Dawes <dawes@xfree86.org> 31 */ 32 33 #include <sys/cdefs.h> 34 __FBSDID("$FreeBSD$"); 35 36 #include "opt_bus.h" 37 38 #include <sys/param.h> 39 #include <sys/systm.h> 40 #include <sys/malloc.h> 41 #include <sys/kernel.h> 42 #include <sys/module.h> 43 #include <sys/bus.h> 44 #include <sys/lock.h> 45 #include <sys/mutex.h> 46 #include <sys/proc.h> 47 48 #include <dev/pci/pcivar.h> 49 #include <dev/pci/pcireg.h> 50 #include <pci/agppriv.h> 51 #include <pci/agpreg.h> 52 53 #include <vm/vm.h> 54 #include <vm/vm_object.h> 55 #include <vm/vm_page.h> 56 #include <vm/vm_pageout.h> 57 #include <vm/pmap.h> 58 59 #include <machine/bus.h> 60 #include <machine/resource.h> 61 #include <sys/rman.h> 62 63 MALLOC_DECLARE(M_AGP); 64 65 #define READ1(off) bus_space_read_1(sc->bst, sc->bsh, off) 66 #define READ4(off) bus_space_read_4(sc->bst, sc->bsh, off) 67 #define WRITE4(off,v) bus_space_write_4(sc->bst, sc->bsh, off, v) 68 #define WRITEGTT(off,v) bus_space_write_4(sc->gtt_bst, sc->gtt_bsh, off, v) 69 70 #define CHIP_I810 0 /* i810/i815 */ 71 #define CHIP_I830 1 /* 830M/845G */ 72 #define CHIP_I855 2 /* 852GM/855GM/865G */ 73 #define CHIP_I915 3 /* 915G/915GM */ 74 75 struct agp_i810_softc { 76 struct agp_softc agp; 77 u_int32_t initial_aperture; /* aperture size at startup */ 78 struct agp_gatt *gatt; 79 int chiptype; /* i810-like or i830 */ 80 u_int32_t dcache_size; /* i810 only */ 81 u_int32_t stolen; /* number of i830/845 gtt entries for stolen memory */ 82 device_t bdev; /* bridge device */ 83 84 struct resource *regs; /* memory mapped GC registers */ 85 bus_space_tag_t bst; /* bus_space tag */ 86 bus_space_handle_t bsh; /* bus_space handle */ 87 88 struct resource *gtt; /* memory mapped GATT entries */ 89 bus_space_tag_t gtt_bst; /* bus_space tag */ 90 bus_space_handle_t gtt_bsh; /* bus_space handle */ 91 }; 92 93 static const char* 94 agp_i810_match(device_t dev) 95 { 96 if (pci_get_class(dev) != PCIC_DISPLAY 97 || pci_get_subclass(dev) != PCIS_DISPLAY_VGA) 98 return NULL; 99 100 switch (pci_get_devid(dev)) { 101 case 0x71218086: 102 return ("Intel 82810 (i810 GMCH) SVGA controller"); 103 104 case 0x71238086: 105 return ("Intel 82810-DC100 (i810-DC100 GMCH) SVGA controller"); 106 107 case 0x71258086: 108 return ("Intel 82810E (i810E GMCH) SVGA controller"); 109 110 case 0x11328086: 111 return ("Intel 82815 (i815 GMCH) SVGA controller"); 112 113 case 0x35778086: 114 return ("Intel 82830M (830M GMCH) SVGA controller"); 115 116 case 0x25628086: 117 return ("Intel 82845G (845G GMCH) SVGA controller"); 118 119 case 0x35828086: 120 switch (pci_read_config(dev, AGP_I85X_CAPID, 1)) { 121 case AGP_I855_GME: 122 return ("Intel 82855GME (855GME GMCH) SVGA controller"); 123 124 case AGP_I855_GM: 125 return ("Intel 82855GM (855GM GMCH) SVGA controller"); 126 127 case AGP_I852_GME: 128 return ("Intel 82852GME (852GME GMCH) SVGA controller"); 129 130 case AGP_I852_GM: 131 return ("Intel 82852GM (852GM GMCH) SVGA controller"); 132 133 default: 134 return ("Intel 8285xM (85xGM GMCH) SVGA controller"); 135 } 136 137 case 0x25728086: 138 return ("Intel 82865G (865G GMCH) SVGA controller"); 139 140 case 0x25828086: 141 return ("Intel 82915G (915G GMCH) SVGA controller"); 142 143 case 0x25928086: 144 return ("Intel 82915GM (915GM GMCH) SVGA controller"); 145 }; 146 147 return NULL; 148 } 149 150 /* 151 * Find bridge device. 152 */ 153 static device_t 154 agp_i810_find_bridge(device_t dev) 155 { 156 device_t *children, child; 157 int nchildren, i; 158 u_int32_t devid; 159 160 /* 161 * Calculate bridge device's ID. 162 */ 163 devid = pci_get_devid(dev); 164 switch (devid) { 165 case 0x71218086: 166 case 0x71238086: 167 case 0x71258086: 168 devid -= 0x10000; 169 break; 170 171 case 0x11328086: 172 case 0x35778086: 173 case 0x25628086: 174 case 0x35828086: 175 case 0x25728086: 176 case 0x25828086: 177 case 0x25928086: 178 devid -= 0x20000; 179 break; 180 }; 181 if (device_get_children(device_get_parent(device_get_parent(dev)), 182 &children, &nchildren)) 183 return 0; 184 185 for (i = 0; i < nchildren; i++) { 186 child = children[i]; 187 188 if (pci_get_devid(child) == devid) { 189 free(children, M_TEMP); 190 return child; 191 } 192 } 193 free(children, M_TEMP); 194 return 0; 195 } 196 197 static void 198 agp_i810_identify(driver_t *driver, device_t parent) 199 { 200 201 if (device_find_child(parent, "agp", -1) == NULL && 202 agp_i810_match(parent)) 203 device_add_child(parent, "agp", -1); 204 } 205 206 static int 207 agp_i810_probe(device_t dev) 208 { 209 const char *desc; 210 211 if (resource_disabled("agp", device_get_unit(dev))) 212 return (ENXIO); 213 desc = agp_i810_match(dev); 214 if (desc) { 215 device_t bdev; 216 u_int8_t smram; 217 unsigned int gcc1; 218 int devid = pci_get_devid(dev); 219 220 bdev = agp_i810_find_bridge(dev); 221 if (!bdev) { 222 if (bootverbose) 223 printf("I810: can't find bridge device\n"); 224 return ENXIO; 225 } 226 227 /* 228 * checking whether internal graphics device has been activated. 229 */ 230 switch (devid) { 231 /* i810 */ 232 case 0x71218086: 233 case 0x71238086: 234 case 0x71258086: 235 case 0x11328086: 236 smram = pci_read_config(bdev, AGP_I810_SMRAM, 1); 237 if ((smram & AGP_I810_SMRAM_GMS) 238 == AGP_I810_SMRAM_GMS_DISABLED) { 239 if (bootverbose) 240 printf("I810: disabled, not probing\n"); 241 return ENXIO; 242 } 243 break; 244 245 /* i830 */ 246 case 0x35778086: 247 case 0x35828086: 248 case 0x25628086: 249 case 0x25728086: 250 gcc1 = pci_read_config(bdev, AGP_I830_GCC1, 1); 251 if ((gcc1 & AGP_I830_GCC1_DEV2) == AGP_I830_GCC1_DEV2_DISABLED) { 252 if (bootverbose) 253 printf("I830: disabled, not probing\n"); 254 return ENXIO; 255 } 256 break; 257 258 /* i915 */ 259 case 0x25828086: 260 case 0x25928086: 261 gcc1 = pci_read_config(bdev, AGP_I915_DEVEN, 4); 262 if ((gcc1 & AGP_I915_DEVEN_D2F0) == 263 AGP_I915_DEVEN_D2F0_DISABLED) { 264 if (bootverbose) 265 printf("I915: disabled, not probing\n"); 266 return ENXIO; 267 } 268 break; 269 270 default: 271 return ENXIO; 272 } 273 274 device_set_desc(dev, desc); 275 return BUS_PROBE_DEFAULT; 276 } 277 278 return ENXIO; 279 } 280 281 static int 282 agp_i810_attach(device_t dev) 283 { 284 struct agp_i810_softc *sc = device_get_softc(dev); 285 struct agp_gatt *gatt; 286 int error, rid; 287 288 sc->bdev = agp_i810_find_bridge(dev); 289 if (!sc->bdev) 290 return ENOENT; 291 292 error = agp_generic_attach(dev); 293 if (error) 294 return error; 295 296 switch (pci_get_devid(dev)) { 297 case 0x71218086: 298 case 0x71238086: 299 case 0x71258086: 300 case 0x11328086: 301 sc->chiptype = CHIP_I810; 302 break; 303 case 0x35778086: 304 case 0x25628086: 305 sc->chiptype = CHIP_I830; 306 break; 307 case 0x35828086: 308 case 0x25728086: 309 sc->chiptype = CHIP_I855; 310 break; 311 case 0x25828086: 312 case 0x25928086: 313 sc->chiptype = CHIP_I915; 314 break; 315 }; 316 317 /* Same for i810 and i830 */ 318 if (sc->chiptype == CHIP_I915) 319 rid = AGP_I915_MMADR; 320 else 321 rid = AGP_I810_MMADR; 322 323 sc->regs = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, 324 RF_ACTIVE); 325 if (!sc->regs) { 326 agp_generic_detach(dev); 327 return ENODEV; 328 } 329 sc->bst = rman_get_bustag(sc->regs); 330 sc->bsh = rman_get_bushandle(sc->regs); 331 332 if (sc->chiptype == CHIP_I915) { 333 rid = AGP_I915_GTTADR; 334 sc->gtt = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, 335 RF_ACTIVE); 336 if (!sc->gtt) { 337 bus_release_resource(dev, SYS_RES_MEMORY, 338 AGP_I810_MMADR, sc->regs); 339 agp_generic_detach(dev); 340 return ENODEV; 341 } 342 sc->gtt_bst = rman_get_bustag(sc->gtt); 343 sc->gtt_bsh = rman_get_bushandle(sc->gtt); 344 } 345 346 sc->initial_aperture = AGP_GET_APERTURE(dev); 347 348 gatt = malloc( sizeof(struct agp_gatt), M_AGP, M_NOWAIT); 349 if (!gatt) { 350 agp_generic_detach(dev); 351 return ENOMEM; 352 } 353 sc->gatt = gatt; 354 355 gatt->ag_entries = AGP_GET_APERTURE(dev) >> AGP_PAGE_SHIFT; 356 357 if ( sc->chiptype == CHIP_I810 ) { 358 /* Some i810s have on-chip memory called dcache */ 359 if (READ1(AGP_I810_DRT) & AGP_I810_DRT_POPULATED) 360 sc->dcache_size = 4 * 1024 * 1024; 361 else 362 sc->dcache_size = 0; 363 364 /* According to the specs the gatt on the i810 must be 64k */ 365 gatt->ag_virtual = contigmalloc( 64 * 1024, M_AGP, 0, 366 0, ~0, PAGE_SIZE, 0); 367 if (!gatt->ag_virtual) { 368 if (bootverbose) 369 device_printf(dev, "contiguous allocation failed\n"); 370 free(gatt, M_AGP); 371 agp_generic_detach(dev); 372 return ENOMEM; 373 } 374 bzero(gatt->ag_virtual, gatt->ag_entries * sizeof(u_int32_t)); 375 376 gatt->ag_physical = vtophys((vm_offset_t) gatt->ag_virtual); 377 agp_flush_cache(); 378 /* Install the GATT. */ 379 WRITE4(AGP_I810_PGTBL_CTL, gatt->ag_physical | 1); 380 } else if ( sc->chiptype == CHIP_I830 ) { 381 /* The i830 automatically initializes the 128k gatt on boot. */ 382 unsigned int gcc1, pgtblctl; 383 384 gcc1 = pci_read_config(sc->bdev, AGP_I830_GCC1, 1); 385 switch (gcc1 & AGP_I830_GCC1_GMS) { 386 case AGP_I830_GCC1_GMS_STOLEN_512: 387 sc->stolen = (512 - 132) * 1024 / 4096; 388 break; 389 case AGP_I830_GCC1_GMS_STOLEN_1024: 390 sc->stolen = (1024 - 132) * 1024 / 4096; 391 break; 392 case AGP_I830_GCC1_GMS_STOLEN_8192: 393 sc->stolen = (8192 - 132) * 1024 / 4096; 394 break; 395 default: 396 sc->stolen = 0; 397 device_printf(dev, "unknown memory configuration, disabling\n"); 398 agp_generic_detach(dev); 399 return EINVAL; 400 } 401 if (sc->stolen > 0) 402 device_printf(dev, "detected %dk stolen memory\n", sc->stolen * 4); 403 device_printf(dev, "aperture size is %dM\n", sc->initial_aperture / 1024 / 1024); 404 405 /* GATT address is already in there, make sure it's enabled */ 406 pgtblctl = READ4(AGP_I810_PGTBL_CTL); 407 pgtblctl |= 1; 408 WRITE4(AGP_I810_PGTBL_CTL, pgtblctl); 409 410 gatt->ag_physical = pgtblctl & ~1; 411 } else if (sc->chiptype == CHIP_I855 || sc->chiptype == CHIP_I915) { /* CHIP_I855 */ 412 unsigned int gcc1, pgtblctl, stolen; 413 414 /* Stolen memory is set up at the beginning of the aperture by 415 * the BIOS, consisting of the GATT followed by 4kb for the BIOS 416 * display. 417 */ 418 if (sc->chiptype == CHIP_I855) 419 stolen = 132; 420 else 421 stolen = 260; 422 423 gcc1 = pci_read_config(sc->bdev, AGP_I855_GCC1, 1); 424 switch (gcc1 & AGP_I855_GCC1_GMS) { 425 case AGP_I855_GCC1_GMS_STOLEN_1M: 426 sc->stolen = (1024 - stolen) * 1024 / 4096; 427 break; 428 case AGP_I855_GCC1_GMS_STOLEN_4M: 429 sc->stolen = (4096 - stolen) * 1024 / 4096; 430 break; 431 case AGP_I855_GCC1_GMS_STOLEN_8M: 432 sc->stolen = (8192 - stolen) * 1024 / 4096; 433 break; 434 case AGP_I855_GCC1_GMS_STOLEN_16M: 435 sc->stolen = (16384 - stolen) * 1024 / 4096; 436 break; 437 case AGP_I855_GCC1_GMS_STOLEN_32M: 438 sc->stolen = (32768 - stolen) * 1024 / 4096; 439 break; 440 case AGP_I915_GCC1_GMS_STOLEN_48M: 441 sc->stolen = (49152 - stolen) * 1024 / 4096; 442 break; 443 case AGP_I915_GCC1_GMS_STOLEN_64M: 444 sc->stolen = (65536 - stolen) * 1024 / 4096; 445 break; 446 default: 447 sc->stolen = 0; 448 device_printf(dev, "unknown memory configuration, disabling\n"); 449 agp_generic_detach(dev); 450 return EINVAL; 451 } 452 if (sc->stolen > 0) 453 device_printf(dev, "detected %dk stolen memory\n", sc->stolen * 4); 454 device_printf(dev, "aperture size is %dM\n", sc->initial_aperture / 1024 / 1024); 455 456 /* GATT address is already in there, make sure it's enabled */ 457 pgtblctl = READ4(AGP_I810_PGTBL_CTL); 458 pgtblctl |= 1; 459 WRITE4(AGP_I810_PGTBL_CTL, pgtblctl); 460 461 gatt->ag_physical = pgtblctl & ~1; 462 } 463 464 return 0; 465 } 466 467 static int 468 agp_i810_detach(device_t dev) 469 { 470 struct agp_i810_softc *sc = device_get_softc(dev); 471 int error; 472 473 error = agp_generic_detach(dev); 474 if (error) 475 return error; 476 477 /* Clear the GATT base. */ 478 if ( sc->chiptype == CHIP_I810 ) { 479 WRITE4(AGP_I810_PGTBL_CTL, 0); 480 } else { 481 unsigned int pgtblctl; 482 pgtblctl = READ4(AGP_I810_PGTBL_CTL); 483 pgtblctl &= ~1; 484 WRITE4(AGP_I810_PGTBL_CTL, pgtblctl); 485 } 486 487 /* Put the aperture back the way it started. */ 488 AGP_SET_APERTURE(dev, sc->initial_aperture); 489 490 if ( sc->chiptype == CHIP_I810 ) { 491 contigfree(sc->gatt->ag_virtual, 64 * 1024, M_AGP); 492 } 493 free(sc->gatt, M_AGP); 494 495 if (sc->chiptype == CHIP_I915) { 496 bus_release_resource(dev, SYS_RES_MEMORY, AGP_I915_GTTADR, 497 sc->gtt); 498 bus_release_resource(dev, SYS_RES_MEMORY, AGP_I915_MMADR, 499 sc->regs); 500 } else { 501 bus_release_resource(dev, SYS_RES_MEMORY, AGP_I810_MMADR, 502 sc->regs); 503 } 504 505 return 0; 506 } 507 508 static u_int32_t 509 agp_i810_get_aperture(device_t dev) 510 { 511 struct agp_i810_softc *sc = device_get_softc(dev); 512 uint32_t temp; 513 u_int16_t miscc; 514 515 switch (sc->chiptype) { 516 case CHIP_I810: 517 miscc = pci_read_config(sc->bdev, AGP_I810_MISCC, 2); 518 if ((miscc & AGP_I810_MISCC_WINSIZE) == AGP_I810_MISCC_WINSIZE_32) 519 return 32 * 1024 * 1024; 520 else 521 return 64 * 1024 * 1024; 522 case CHIP_I830: 523 temp = pci_read_config(sc->bdev, AGP_I830_GCC1, 2); 524 if ((temp & AGP_I830_GCC1_GMASIZE) == AGP_I830_GCC1_GMASIZE_64) 525 return 64 * 1024 * 1024; 526 else 527 return 128 * 1024 * 1024; 528 case CHIP_I855: 529 return 128 * 1024 * 1024; 530 case CHIP_I915: 531 temp = pci_read_config(dev, AGP_I915_MSAC, 1); 532 if ((temp & AGP_I915_MSAC_GMASIZE) == 533 AGP_I915_MSAC_GMASIZE_128) { 534 return 128 * 1024 * 1024; 535 } else { 536 return 256 * 1024 * 1024; 537 } 538 } 539 540 return 0; 541 } 542 543 static int 544 agp_i810_set_aperture(device_t dev, u_int32_t aperture) 545 { 546 struct agp_i810_softc *sc = device_get_softc(dev); 547 u_int16_t miscc, gcc1; 548 u_int32_t temp; 549 550 switch (sc->chiptype) { 551 case CHIP_I810: 552 /* 553 * Double check for sanity. 554 */ 555 if (aperture != 32 * 1024 * 1024 && aperture != 64 * 1024 * 1024) { 556 device_printf(dev, "bad aperture size %d\n", aperture); 557 return EINVAL; 558 } 559 560 miscc = pci_read_config(sc->bdev, AGP_I810_MISCC, 2); 561 miscc &= ~AGP_I810_MISCC_WINSIZE; 562 if (aperture == 32 * 1024 * 1024) 563 miscc |= AGP_I810_MISCC_WINSIZE_32; 564 else 565 miscc |= AGP_I810_MISCC_WINSIZE_64; 566 567 pci_write_config(sc->bdev, AGP_I810_MISCC, miscc, 2); 568 break; 569 case CHIP_I830: 570 if (aperture != 64 * 1024 * 1024 && 571 aperture != 128 * 1024 * 1024) { 572 device_printf(dev, "bad aperture size %d\n", aperture); 573 return EINVAL; 574 } 575 gcc1 = pci_read_config(sc->bdev, AGP_I830_GCC1, 2); 576 gcc1 &= ~AGP_I830_GCC1_GMASIZE; 577 if (aperture == 64 * 1024 * 1024) 578 gcc1 |= AGP_I830_GCC1_GMASIZE_64; 579 else 580 gcc1 |= AGP_I830_GCC1_GMASIZE_128; 581 582 pci_write_config(sc->bdev, AGP_I830_GCC1, gcc1, 2); 583 break; 584 case CHIP_I855: 585 if (aperture != 128 * 1024 * 1024) { 586 device_printf(dev, "bad aperture size %d\n", aperture); 587 return EINVAL; 588 } 589 break; 590 case CHIP_I915: 591 temp = pci_read_config(dev, AGP_I915_MSAC, 1); 592 temp &= ~AGP_I915_MSAC_GMASIZE; 593 594 switch (aperture) { 595 case 128 * 1024 * 1024: 596 temp |= AGP_I915_MSAC_GMASIZE_128; 597 break; 598 case 256 * 1024 * 1024: 599 temp |= AGP_I915_MSAC_GMASIZE_256; 600 break; 601 default: 602 device_printf(dev, "bad aperture size %d\n", aperture); 603 return EINVAL; 604 } 605 606 pci_write_config(dev, AGP_I915_MSAC, temp, 1); 607 break; 608 } 609 610 return 0; 611 } 612 613 static int 614 agp_i810_bind_page(device_t dev, int offset, vm_offset_t physical) 615 { 616 struct agp_i810_softc *sc = device_get_softc(dev); 617 618 if (offset < 0 || offset >= (sc->gatt->ag_entries << AGP_PAGE_SHIFT)) { 619 device_printf(dev, "failed: offset is 0x%08x, shift is %d, entries is %d\n", offset, AGP_PAGE_SHIFT, sc->gatt->ag_entries); 620 return EINVAL; 621 } 622 623 if ( sc->chiptype != CHIP_I810 ) { 624 if ( (offset >> AGP_PAGE_SHIFT) < sc->stolen ) { 625 device_printf(dev, "trying to bind into stolen memory"); 626 return EINVAL; 627 } 628 } 629 630 if (sc->chiptype == CHIP_I915) { 631 WRITEGTT((offset >> AGP_PAGE_SHIFT) * 4, physical | 1); 632 } else { 633 WRITE4(AGP_I810_GTT + (offset >> AGP_PAGE_SHIFT) * 4, physical | 1); 634 } 635 636 return 0; 637 } 638 639 static int 640 agp_i810_unbind_page(device_t dev, int offset) 641 { 642 struct agp_i810_softc *sc = device_get_softc(dev); 643 644 if (offset < 0 || offset >= (sc->gatt->ag_entries << AGP_PAGE_SHIFT)) 645 return EINVAL; 646 647 if ( sc->chiptype != CHIP_I810 ) { 648 if ( (offset >> AGP_PAGE_SHIFT) < sc->stolen ) { 649 device_printf(dev, "trying to unbind from stolen memory"); 650 return EINVAL; 651 } 652 } 653 654 if (sc->chiptype == CHIP_I915) { 655 WRITEGTT((offset >> AGP_PAGE_SHIFT) * 4, 0); 656 } else { 657 WRITE4(AGP_I810_GTT + (offset >> AGP_PAGE_SHIFT) * 4, 0); 658 } 659 660 return 0; 661 } 662 663 /* 664 * Writing via memory mapped registers already flushes all TLBs. 665 */ 666 static void 667 agp_i810_flush_tlb(device_t dev) 668 { 669 } 670 671 static int 672 agp_i810_enable(device_t dev, u_int32_t mode) 673 { 674 675 return 0; 676 } 677 678 static struct agp_memory * 679 agp_i810_alloc_memory(device_t dev, int type, vm_size_t size) 680 { 681 struct agp_i810_softc *sc = device_get_softc(dev); 682 struct agp_memory *mem; 683 684 if ((size & (AGP_PAGE_SIZE - 1)) != 0) 685 return 0; 686 687 if (sc->agp.as_allocated + size > sc->agp.as_maxmem) 688 return 0; 689 690 if (type == 1) { 691 /* 692 * Mapping local DRAM into GATT. 693 */ 694 if ( sc->chiptype != CHIP_I810 ) 695 return 0; 696 if (size != sc->dcache_size) 697 return 0; 698 } else if (type == 2) { 699 /* 700 * Bogus mapping of a single page for the hardware cursor. 701 */ 702 if (size != AGP_PAGE_SIZE) 703 return 0; 704 } 705 706 mem = malloc(sizeof *mem, M_AGP, M_WAITOK); 707 mem->am_id = sc->agp.as_nextid++; 708 mem->am_size = size; 709 mem->am_type = type; 710 if (type != 1) 711 mem->am_obj = vm_object_allocate(OBJT_DEFAULT, 712 atop(round_page(size))); 713 else 714 mem->am_obj = 0; 715 716 if (type == 2) { 717 /* 718 * Allocate and wire down the page now so that we can 719 * get its physical address. 720 */ 721 vm_page_t m; 722 723 VM_OBJECT_LOCK(mem->am_obj); 724 m = vm_page_grab(mem->am_obj, 0, VM_ALLOC_NOBUSY | 725 VM_ALLOC_WIRED | VM_ALLOC_ZERO | VM_ALLOC_RETRY); 726 VM_OBJECT_UNLOCK(mem->am_obj); 727 mem->am_physical = VM_PAGE_TO_PHYS(m); 728 } else { 729 mem->am_physical = 0; 730 } 731 732 mem->am_offset = 0; 733 mem->am_is_bound = 0; 734 TAILQ_INSERT_TAIL(&sc->agp.as_memory, mem, am_link); 735 sc->agp.as_allocated += size; 736 737 return mem; 738 } 739 740 static int 741 agp_i810_free_memory(device_t dev, struct agp_memory *mem) 742 { 743 struct agp_i810_softc *sc = device_get_softc(dev); 744 745 if (mem->am_is_bound) 746 return EBUSY; 747 748 if (mem->am_type == 2) { 749 /* 750 * Unwire the page which we wired in alloc_memory. 751 */ 752 vm_page_t m; 753 754 VM_OBJECT_LOCK(mem->am_obj); 755 m = vm_page_lookup(mem->am_obj, 0); 756 VM_OBJECT_UNLOCK(mem->am_obj); 757 vm_page_lock_queues(); 758 vm_page_unwire(m, 0); 759 vm_page_unlock_queues(); 760 } 761 762 sc->agp.as_allocated -= mem->am_size; 763 TAILQ_REMOVE(&sc->agp.as_memory, mem, am_link); 764 if (mem->am_obj) 765 vm_object_deallocate(mem->am_obj); 766 free(mem, M_AGP); 767 return 0; 768 } 769 770 static int 771 agp_i810_bind_memory(device_t dev, struct agp_memory *mem, 772 vm_offset_t offset) 773 { 774 struct agp_i810_softc *sc = device_get_softc(dev); 775 vm_offset_t i; 776 777 if (mem->am_type != 1) 778 return agp_generic_bind_memory(dev, mem, offset); 779 780 if ( sc->chiptype != CHIP_I810 ) 781 return EINVAL; 782 783 for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE) { 784 WRITE4(AGP_I810_GTT + (offset >> AGP_PAGE_SHIFT) * 4, 785 i | 3); 786 } 787 788 return 0; 789 } 790 791 static int 792 agp_i810_unbind_memory(device_t dev, struct agp_memory *mem) 793 { 794 struct agp_i810_softc *sc = device_get_softc(dev); 795 vm_offset_t i; 796 797 if (mem->am_type != 1) 798 return agp_generic_unbind_memory(dev, mem); 799 800 if ( sc->chiptype != CHIP_I810 ) 801 return EINVAL; 802 803 for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE) 804 WRITE4(AGP_I810_GTT + (i >> AGP_PAGE_SHIFT) * 4, 0); 805 806 return 0; 807 } 808 809 static device_method_t agp_i810_methods[] = { 810 /* Device interface */ 811 DEVMETHOD(device_identify, agp_i810_identify), 812 DEVMETHOD(device_probe, agp_i810_probe), 813 DEVMETHOD(device_attach, agp_i810_attach), 814 DEVMETHOD(device_detach, agp_i810_detach), 815 816 /* AGP interface */ 817 DEVMETHOD(agp_get_aperture, agp_i810_get_aperture), 818 DEVMETHOD(agp_set_aperture, agp_i810_set_aperture), 819 DEVMETHOD(agp_bind_page, agp_i810_bind_page), 820 DEVMETHOD(agp_unbind_page, agp_i810_unbind_page), 821 DEVMETHOD(agp_flush_tlb, agp_i810_flush_tlb), 822 DEVMETHOD(agp_enable, agp_i810_enable), 823 DEVMETHOD(agp_alloc_memory, agp_i810_alloc_memory), 824 DEVMETHOD(agp_free_memory, agp_i810_free_memory), 825 DEVMETHOD(agp_bind_memory, agp_i810_bind_memory), 826 DEVMETHOD(agp_unbind_memory, agp_i810_unbind_memory), 827 828 { 0, 0 } 829 }; 830 831 static driver_t agp_i810_driver = { 832 "agp", 833 agp_i810_methods, 834 sizeof(struct agp_i810_softc), 835 }; 836 837 static devclass_t agp_devclass; 838 839 DRIVER_MODULE(agp_i810, vgapci, agp_i810_driver, agp_devclass, 0, 0); 840 MODULE_DEPEND(agp_i810, agp, 1, 1, 1); 841 MODULE_DEPEND(agp_i810, pci, 1, 1, 1); 842