1 /* $OpenBSD: agp_i810.c,v 1.98 2024/10/10 03:36:10 jsg Exp $ */ 2 3 /*- 4 * Copyright (c) 2000 Doug Rabson 5 * Copyright (c) 2000 Ruslan Ermilov 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * 29 */ 30 31 #include "acpi.h" 32 #include "drm.h" 33 #include "vga.h" 34 35 #include <sys/param.h> 36 #include <sys/systm.h> 37 #include <sys/malloc.h> 38 #include <sys/device.h> 39 40 #include <dev/pci/pcivar.h> 41 #include <dev/pci/pcireg.h> 42 #include <dev/pci/pcidevs.h> 43 #include <dev/pci/agpvar.h> 44 #include <dev/pci/agpreg.h> 45 #include <dev/pci/drm/i915/i915_drv.h> 46 47 #include <machine/bus.h> 48 49 #define READ1(off) bus_space_read_1(isc->map->bst, isc->map->bsh, off) 50 #define READ4(off) bus_space_read_4(isc->map->bst, isc->map->bsh, off) 51 #define WRITE4(off,v) bus_space_write_4(isc->map->bst, isc->map->bsh, off, v) 52 53 /* 54 * Intel IGP gtt bits. 55 */ 56 /* PTE is enabled */ 57 #define INTEL_ENABLED 0x1 58 /* I810/I815 only, memory is in dcache */ 59 #define INTEL_LOCAL 0x2 60 /* Memory is snooped, must not be accessed through gtt from the cpu. */ 61 #define INTEL_COHERENT 0x6 62 63 enum { 64 CHIP_NONE = 0, /* not integrated graphics */ 65 CHIP_I810 = 1, /* i810/i815 */ 66 CHIP_I830 = 2, /* i830/i845 */ 67 CHIP_I855 = 3, /* i852GM/i855GM/i865G */ 68 CHIP_I915 = 4, /* i915G/i915GM */ 69 CHIP_I965 = 5, /* i965/i965GM */ 70 CHIP_G33 = 6, /* G33/Q33/Q35 */ 71 CHIP_G4X = 7, /* G4X */ 72 CHIP_PINEVIEW = 8, /* Pineview/Pineview M */ 73 CHIP_IRONLAKE = 9, /* Clarkdale/Arrandale */ 74 }; 75 76 struct agp_i810_softc { 77 struct device dev; 78 bus_dma_segment_t scrib_seg; 79 struct agp_softc *agpdev; 80 struct agp_gatt *gatt; 81 struct vga_pci_bar *map; 82 bus_space_tag_t gtt_bst; 83 bus_space_handle_t gtt_bsh; 84 bus_size_t gtt_size; 85 bus_dmamap_t scrib_dmamap; 86 bus_addr_t isc_apaddr; 87 bus_size_t isc_apsize; /* current aperture size */ 88 int chiptype; /* i810-like or i830 */ 89 u_int32_t dcache_size; /* i810 only */ 90 u_int32_t stolen; /* number of i830/845 gtt 91 entries for stolen memory */ 92 }; 93 94 void agp_i810_attach(struct device *, struct device *, void *); 95 int agp_i810_activate(struct device *, int); 96 void agp_i810_configure(struct agp_i810_softc *); 97 int agp_i810_probe(struct device *, void *, void *); 98 int agp_i810_get_chiptype(struct pci_attach_args *); 99 void agp_i810_bind_page(void *, bus_size_t, paddr_t, int); 100 void agp_i810_unbind_page(void *, bus_size_t); 101 void agp_i810_flush_tlb(void *); 102 int agp_i810_enable(void *, u_int32_t mode); 103 void intagp_write_gtt(struct agp_i810_softc *, bus_size_t, paddr_t); 104 int intagp_gmch_match(struct pci_attach_args *); 105 106 const struct cfattach intagp_ca = { 107 sizeof(struct agp_i810_softc), agp_i810_probe, agp_i810_attach, 108 NULL, agp_i810_activate, 109 }; 110 111 struct cfdriver intagp_cd = { 112 NULL, "intagp", DV_DULL 113 }; 114 115 struct agp_methods agp_i810_methods = { 116 agp_i810_bind_page, 117 agp_i810_unbind_page, 118 agp_i810_flush_tlb, 119 agp_i810_enable, 120 }; 121 122 int 123 agp_i810_get_chiptype(struct pci_attach_args *pa) 124 { 125 switch (PCI_PRODUCT(pa->pa_id)) { 126 case PCI_PRODUCT_INTEL_82810_IGD: 127 case PCI_PRODUCT_INTEL_82810_DC100_IGD: 128 case PCI_PRODUCT_INTEL_82810E_IGD: 129 case PCI_PRODUCT_INTEL_82815_IGD: 130 return (CHIP_I810); 131 break; 132 case PCI_PRODUCT_INTEL_82830M_IGD: 133 case PCI_PRODUCT_INTEL_82845G_IGD: 134 return (CHIP_I830); 135 break; 136 case PCI_PRODUCT_INTEL_82854_IGD: 137 case PCI_PRODUCT_INTEL_82855GM_IGD: 138 case PCI_PRODUCT_INTEL_82865G_IGD: 139 return (CHIP_I855); 140 break; 141 case PCI_PRODUCT_INTEL_E7221_IGD: 142 case PCI_PRODUCT_INTEL_82915G_IGD_1: 143 case PCI_PRODUCT_INTEL_82915G_IGD_2: 144 case PCI_PRODUCT_INTEL_82915GM_IGD_1: 145 case PCI_PRODUCT_INTEL_82915GM_IGD_2: 146 case PCI_PRODUCT_INTEL_82945G_IGD_1: 147 case PCI_PRODUCT_INTEL_82945G_IGD_2: 148 case PCI_PRODUCT_INTEL_82945GM_IGD_1: 149 case PCI_PRODUCT_INTEL_82945GM_IGD_2: 150 case PCI_PRODUCT_INTEL_82945GME_IGD_1: 151 return (CHIP_I915); 152 break; 153 case PCI_PRODUCT_INTEL_82946GZ_IGD_1: 154 case PCI_PRODUCT_INTEL_82946GZ_IGD_2: 155 case PCI_PRODUCT_INTEL_82Q965_IGD_1: 156 case PCI_PRODUCT_INTEL_82Q965_IGD_2: 157 case PCI_PRODUCT_INTEL_82G965_IGD_1: 158 case PCI_PRODUCT_INTEL_82G965_IGD_2: 159 case PCI_PRODUCT_INTEL_82GM965_IGD_1: 160 case PCI_PRODUCT_INTEL_82GM965_IGD_2: 161 case PCI_PRODUCT_INTEL_82GME965_IGD_1: 162 case PCI_PRODUCT_INTEL_82GME965_IGD_2: 163 case PCI_PRODUCT_INTEL_82G35_IGD_1: 164 case PCI_PRODUCT_INTEL_82G35_IGD_2: 165 return (CHIP_I965); 166 break; 167 case PCI_PRODUCT_INTEL_82G33_IGD_1: 168 case PCI_PRODUCT_INTEL_82G33_IGD_2: 169 case PCI_PRODUCT_INTEL_82Q35_IGD_1: 170 case PCI_PRODUCT_INTEL_82Q35_IGD_2: 171 case PCI_PRODUCT_INTEL_82Q33_IGD_1: 172 case PCI_PRODUCT_INTEL_82Q33_IGD_2: 173 return (CHIP_G33); 174 break; 175 case PCI_PRODUCT_INTEL_82GM45_IGD_1: 176 case PCI_PRODUCT_INTEL_4SERIES_IGD: 177 case PCI_PRODUCT_INTEL_82Q45_IGD_1: 178 case PCI_PRODUCT_INTEL_82G45_IGD_1: 179 case PCI_PRODUCT_INTEL_82G41_IGD_1: 180 case PCI_PRODUCT_INTEL_82B43_IGD_1: 181 case PCI_PRODUCT_INTEL_82B43_IGD_2: 182 return (CHIP_G4X); 183 break; 184 case PCI_PRODUCT_INTEL_PINEVIEW_IGC_1: 185 case PCI_PRODUCT_INTEL_PINEVIEW_M_IGC_1: 186 return (CHIP_PINEVIEW); 187 break; 188 case PCI_PRODUCT_INTEL_CLARKDALE_IGD: 189 case PCI_PRODUCT_INTEL_ARRANDALE_IGD: 190 return (CHIP_IRONLAKE); 191 break; 192 } 193 194 return (CHIP_NONE); 195 } 196 197 /* 198 * We're intel IGD, bus 0 function 0 dev 0 should be the GMCH, so it should 199 * be Intel 200 */ 201 int 202 intagp_gmch_match(struct pci_attach_args *pa) 203 { 204 if (pa->pa_bus == 0 && pa->pa_device == 0 && pa->pa_function == 0 && 205 PCI_VENDOR(pa->pa_id) == PCI_VENDOR_INTEL && 206 PCI_CLASS(pa->pa_class) == PCI_CLASS_BRIDGE && 207 PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_BRIDGE_HOST) 208 return (1); 209 return (0); 210 } 211 212 int 213 agp_i810_probe(struct device *parent, void *match, void *aux) 214 { 215 struct pci_attach_args *pa = aux; 216 217 if (PCI_CLASS(pa->pa_class) != PCI_CLASS_DISPLAY || 218 PCI_SUBCLASS(pa->pa_class) != PCI_SUBCLASS_DISPLAY_VGA) 219 return (0); 220 221 return (agp_i810_get_chiptype(pa) != CHIP_NONE); 222 } 223 224 void 225 agp_i810_attach(struct device *parent, struct device *self, void *aux) 226 { 227 struct agp_i810_softc *isc = (struct agp_i810_softc *)self; 228 struct agp_gatt *gatt; 229 struct pci_attach_args *pa = aux, bpa; 230 struct inteldrm_softc *psc = (struct inteldrm_softc *)parent; 231 bus_addr_t mmaddr, gmaddr, tmp; 232 bus_size_t gtt_off = 0; 233 pcireg_t memtype, reg; 234 u_int32_t stolen; 235 u_int16_t gcc1; 236 237 isc->chiptype = agp_i810_get_chiptype(pa); 238 239 switch (isc->chiptype) { 240 case CHIP_I915: 241 case CHIP_G33: 242 case CHIP_PINEVIEW: 243 gmaddr = AGP_I915_GMADR; 244 mmaddr = AGP_I915_MMADR; 245 memtype = PCI_MAPREG_TYPE_MEM; 246 break; 247 case CHIP_I965: 248 case CHIP_G4X: 249 case CHIP_IRONLAKE: 250 gmaddr = AGP_I965_GMADR; 251 mmaddr = AGP_I965_MMADR; 252 memtype = PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT; 253 if (isc->chiptype == CHIP_I965) 254 gtt_off = AGP_I965_GTT; 255 else 256 gtt_off = AGP_G4X_GTT; 257 break; 258 default: 259 gmaddr = AGP_APBASE; 260 mmaddr = AGP_I810_MMADR; 261 memtype = PCI_MAPREG_TYPE_MEM; 262 gtt_off = AGP_I810_GTT; 263 break; 264 } 265 266 if (pci_mapreg_info(pa->pa_pc, pa->pa_tag, gmaddr, memtype, 267 &isc->isc_apaddr, &isc->isc_apsize, NULL) != 0) { 268 printf("can't get aperture info\n"); 269 return; 270 } 271 272 isc->map = psc->vga_regs; 273 274 if (isc->chiptype == CHIP_I915 || isc->chiptype == CHIP_G33 || 275 isc->chiptype == CHIP_PINEVIEW) { 276 if (pci_mapreg_map(pa, AGP_I915_GTTADR, memtype, 277 BUS_SPACE_MAP_LINEAR, &isc->gtt_bst, &isc->gtt_bsh, 278 NULL, &isc->gtt_size, 0)) { 279 printf("can't map gatt registers\n"); 280 goto out; 281 } 282 } else if (gtt_off >= isc->map->size) { 283 isc->gtt_bst = isc->map->bst; 284 isc->gtt_size = (isc->isc_apsize >> AGP_PAGE_SHIFT) * 4; 285 if (bus_space_map(isc->gtt_bst, isc->map->base + gtt_off, 286 isc->gtt_size, BUS_SPACE_MAP_LINEAR, &isc->gtt_bsh)) { 287 printf("can't map gatt registers\n"); 288 isc->gtt_size = 0; 289 goto out; 290 } 291 } else { 292 isc->gtt_bst = isc->map->bst; 293 if (bus_space_subregion(isc->map->bst, isc->map->bsh, gtt_off, 294 (isc->isc_apsize >> AGP_PAGE_SHIFT) * 4, &isc->gtt_bsh)) { 295 printf("can't map gatt registers\n"); 296 goto out; 297 } 298 } 299 300 gatt = malloc(sizeof(*gatt), M_AGP, M_NOWAIT | M_ZERO); 301 if (gatt == NULL) { 302 printf("can't alloc gatt\n"); 303 goto out; 304 } 305 isc->gatt = gatt; 306 307 gatt->ag_entries = isc->isc_apsize >> AGP_PAGE_SHIFT; 308 309 /* 310 * Find the GMCH, some of the registers we need to read for 311 * configuration purposes are on there. it's always at 312 * 0/0/0 (bus/dev/func). 313 */ 314 if (pci_find_device(&bpa, intagp_gmch_match) == 0) { 315 printf("can't find GMCH\n"); 316 goto out; 317 } 318 319 switch (isc->chiptype) { 320 case CHIP_I810: 321 /* Some i810s have on-chip memory called dcache */ 322 if (READ1(AGP_I810_DRT) & AGP_I810_DRT_POPULATED) 323 isc->dcache_size = 4 * 1024 * 1024; 324 else 325 isc->dcache_size = 0; 326 327 /* According to the specs the gatt on the i810 must be 64k */ 328 if (agp_alloc_dmamem(pa->pa_dmat, 64 * 1024, &gatt->ag_dmamap, 329 &gatt->ag_physical, &gatt->ag_dmaseg) != 0) { 330 goto out; 331 } 332 gatt->ag_size = gatt->ag_entries * sizeof(u_int32_t); 333 334 if (bus_dmamem_map(pa->pa_dmat, &gatt->ag_dmaseg, 1, 64 * 1024, 335 (caddr_t *)&gatt->ag_virtual, BUS_DMA_NOWAIT) != 0) 336 goto out; 337 break; 338 339 case CHIP_I830: 340 /* The i830 automatically initializes the 128k gatt on boot. */ 341 342 reg = pci_conf_read(bpa.pa_pc, bpa.pa_tag, AGP_I830_GCC0); 343 gcc1 = (u_int16_t)(reg >> 16); 344 switch (gcc1 & AGP_I830_GCC1_GMS) { 345 case AGP_I830_GCC1_GMS_STOLEN_512: 346 isc->stolen = (512 - 132) * 1024 / 4096; 347 break; 348 case AGP_I830_GCC1_GMS_STOLEN_1024: 349 isc->stolen = (1024 - 132) * 1024 / 4096; 350 break; 351 case AGP_I830_GCC1_GMS_STOLEN_8192: 352 isc->stolen = (8192 - 132) * 1024 / 4096; 353 break; 354 default: 355 isc->stolen = 0; 356 printf("unknown memory configuration, disabling\n"); 357 goto out; 358 } 359 #ifdef DEBUG 360 if (isc->stolen > 0) { 361 printf(": detected %dk stolen memory", 362 isc->stolen * 4); 363 } else 364 printf(": no preallocated video memory\n"); 365 #endif 366 367 /* XXX */ 368 isc->stolen = 0; 369 370 /* GATT address is already in there, make sure it's enabled */ 371 gatt->ag_physical = READ4(AGP_I810_PGTBL_CTL) & ~1; 372 break; 373 374 case CHIP_I855: 375 /* FALLTHROUGH */ 376 case CHIP_I915: 377 /* FALLTHROUGH */ 378 case CHIP_I965: 379 /* FALLTHROUGH */ 380 case CHIP_G33: 381 /* FALLTHROUGH */ 382 case CHIP_G4X: 383 case CHIP_PINEVIEW: 384 case CHIP_IRONLAKE: 385 386 /* Stolen memory is set up at the beginning of the aperture by 387 * the BIOS, consisting of the GATT followed by 4kb for the 388 * BIOS display. 389 */ 390 391 reg = pci_conf_read(bpa.pa_pc, bpa.pa_tag, AGP_I855_GCC1); 392 gcc1 = (u_int16_t)(reg >> 16); 393 switch (isc->chiptype) { 394 case CHIP_I855: 395 /* The 855GM automatically initializes the 128k gatt on boot. */ 396 stolen = 128 + 4; 397 break; 398 case CHIP_I915: 399 /* The 915G automatically initializes the 256k gatt on boot. */ 400 stolen = 256 + 4; 401 break; 402 case CHIP_I965: 403 switch (READ4(AGP_I810_PGTBL_CTL) & 404 AGP_I810_PGTBL_SIZE_MASK) { 405 case AGP_I810_PGTBL_SIZE_512KB: 406 stolen = 512 + 4; 407 break; 408 case AGP_I810_PGTBL_SIZE_256KB: 409 stolen = 256 + 4; 410 break; 411 case AGP_I810_PGTBL_SIZE_128KB: 412 default: 413 stolen = 128 + 4; 414 break; 415 } 416 break; 417 case CHIP_G33: 418 switch (gcc1 & AGP_G33_PGTBL_SIZE_MASK) { 419 case AGP_G33_PGTBL_SIZE_2M: 420 stolen = 2048 + 4; 421 break; 422 case AGP_G33_PGTBL_SIZE_1M: 423 default: 424 stolen = 1024 + 4; 425 break; 426 } 427 break; 428 case CHIP_G4X: 429 case CHIP_PINEVIEW: 430 case CHIP_IRONLAKE: 431 /* 432 * GTT stolen is separate from graphics stolen on 433 * 4 series hardware. so ignore it in stolen gtt entries 434 * counting. However, 4Kb of stolen memory isn't mapped 435 * to the GTT. 436 */ 437 stolen = 4; 438 break; 439 default: 440 printf("bad chiptype\n"); 441 goto out; 442 } 443 444 switch (gcc1 & AGP_I855_GCC1_GMS) { 445 case AGP_I855_GCC1_GMS_STOLEN_1M: 446 isc->stolen = (1024 - stolen) * 1024 / 4096; 447 break; 448 case AGP_I855_GCC1_GMS_STOLEN_4M: 449 isc->stolen = (4096 - stolen) * 1024 / 4096; 450 break; 451 case AGP_I855_GCC1_GMS_STOLEN_8M: 452 isc->stolen = (8192 - stolen) * 1024 / 4096; 453 break; 454 case AGP_I855_GCC1_GMS_STOLEN_16M: 455 isc->stolen = (16384 - stolen) * 1024 / 4096; 456 break; 457 case AGP_I855_GCC1_GMS_STOLEN_32M: 458 isc->stolen = (32768 - stolen) * 1024 / 4096; 459 break; 460 case AGP_I915_GCC1_GMS_STOLEN_48M: 461 isc->stolen = (49152 - stolen) * 1024 / 4096; 462 break; 463 case AGP_I915_GCC1_GMS_STOLEN_64M: 464 isc->stolen = (65536 - stolen) * 1024 / 4096; 465 break; 466 case AGP_G33_GCC1_GMS_STOLEN_128M: 467 isc->stolen = (131072 - stolen) * 1024 / 4096; 468 break; 469 case AGP_G33_GCC1_GMS_STOLEN_256M: 470 isc->stolen = (262144 - stolen) * 1024 / 4096; 471 break; 472 case AGP_INTEL_GMCH_GMS_STOLEN_96M: 473 isc->stolen = (98304 - stolen) * 1024 / 4096; 474 break; 475 case AGP_INTEL_GMCH_GMS_STOLEN_160M: 476 isc->stolen = (163840 - stolen) * 1024 / 4096; 477 break; 478 case AGP_INTEL_GMCH_GMS_STOLEN_224M: 479 isc->stolen = (229376 - stolen) * 1024 / 4096; 480 break; 481 case AGP_INTEL_GMCH_GMS_STOLEN_352M: 482 isc->stolen = (360448 - stolen) * 1024 / 4096; 483 break; 484 default: 485 isc->stolen = 0; 486 printf("unknown memory configuration, disabling\n"); 487 goto out; 488 } 489 #ifdef DEBUG 490 if (isc->stolen > 0) { 491 printf(": detected %dk stolen memory", 492 isc->stolen * 4); 493 } else 494 printf(": no preallocated video memory\n"); 495 #endif 496 497 /* XXX */ 498 isc->stolen = 0; 499 500 /* GATT address is already in there, make sure it's enabled */ 501 gatt->ag_physical = READ4(AGP_I810_PGTBL_CTL) & ~1; 502 break; 503 504 default: 505 printf(": unknown initialisation\n"); 506 return; 507 } 508 /* Intel recommends that you have a fake page bound to the gtt always */ 509 if (agp_alloc_dmamem(pa->pa_dmat, AGP_PAGE_SIZE, &isc->scrib_dmamap, 510 &tmp, &isc->scrib_seg) != 0) { 511 printf(": can't get scribble page\n"); 512 return; 513 } 514 agp_i810_configure(isc); 515 516 isc->agpdev = (struct agp_softc *)agp_attach_bus(pa, &agp_i810_methods, 517 isc->isc_apaddr, isc->isc_apsize, &isc->dev); 518 return; 519 out: 520 521 if (isc->gatt) { 522 if (isc->gatt->ag_size != 0) 523 agp_free_dmamem(pa->pa_dmat, isc->gatt->ag_size, 524 isc->gatt->ag_dmamap, &isc->gatt->ag_dmaseg); 525 free(isc->gatt, M_AGP, sizeof (*isc->gatt)); 526 } 527 if (isc->gtt_size != 0) 528 bus_space_unmap(isc->gtt_bst, isc->gtt_bsh, isc->gtt_size); 529 } 530 531 int 532 agp_i810_activate(struct device *arg, int act) 533 { 534 struct agp_i810_softc *isc = (struct agp_i810_softc *)arg; 535 536 /* 537 * Anything kept in agp over a suspend/resume cycle (and thus by X 538 * over a vt switch cycle) is undefined upon resume. 539 */ 540 switch (act) { 541 case DVACT_RESUME: 542 agp_i810_configure(isc); 543 break; 544 } 545 546 return (0); 547 } 548 549 void 550 agp_i810_configure(struct agp_i810_softc *isc) 551 { 552 bus_addr_t tmp; 553 554 tmp = isc->isc_apaddr; 555 if (isc->chiptype == CHIP_I810) { 556 tmp += isc->dcache_size; 557 } else { 558 tmp += isc->stolen << AGP_PAGE_SHIFT; 559 } 560 561 agp_flush_cache(); 562 /* Install the GATT. */ 563 WRITE4(AGP_I810_PGTBL_CTL, isc->gatt->ag_physical | 1); 564 565 /* initialise all gtt entries to point to scribble page */ 566 for (; tmp < (isc->isc_apaddr + isc->isc_apsize); 567 tmp += AGP_PAGE_SIZE) 568 agp_i810_unbind_page(isc, tmp); 569 /* XXX we'll need to restore the GTT contents when we go kms */ 570 571 /* 572 * Make sure the chipset can see everything. 573 */ 574 agp_flush_cache(); 575 } 576 577 void 578 agp_i810_bind_page(void *sc, bus_addr_t offset, paddr_t physical, int flags) 579 { 580 struct agp_i810_softc *isc = sc; 581 582 /* 583 * COHERENT mappings mean set the snoop bit. this should never be 584 * accessed by the gpu through the gtt. 585 */ 586 if (flags & BUS_DMA_COHERENT) 587 physical |= INTEL_COHERENT; 588 589 intagp_write_gtt(isc, offset - isc->isc_apaddr, physical); 590 } 591 592 void 593 agp_i810_unbind_page(void *sc, bus_size_t offset) 594 { 595 struct agp_i810_softc *isc = sc; 596 597 intagp_write_gtt(isc, offset - isc->isc_apaddr, 598 isc->scrib_dmamap->dm_segs[0].ds_addr); 599 } 600 601 /* 602 * Writing via memory mapped registers already flushes all TLBs. 603 */ 604 void 605 agp_i810_flush_tlb(void *sc) 606 { 607 } 608 609 int 610 agp_i810_enable(void *sc, u_int32_t mode) 611 { 612 return (0); 613 } 614 615 void 616 intagp_write_gtt(struct agp_i810_softc *isc, bus_size_t off, paddr_t v) 617 { 618 u_int32_t pte = 0; 619 bus_size_t wroff; 620 621 if (isc->chiptype != CHIP_I810 && 622 (off >> AGP_PAGE_SHIFT) < isc->stolen) { 623 printf("intagp: binding into stolen memory! (0x%lx)\n", 624 (off >> AGP_PAGE_SHIFT)); 625 } 626 627 if (v != 0) { 628 pte = v | INTEL_ENABLED; 629 /* 965+ can do 36-bit addressing, add in the extra bits */ 630 switch (isc->chiptype) { 631 case CHIP_I965: 632 case CHIP_G4X: 633 case CHIP_PINEVIEW: 634 case CHIP_G33: 635 case CHIP_IRONLAKE: 636 pte |= (v & 0x0000000f00000000ULL) >> 28; 637 break; 638 } 639 } 640 641 wroff = (off >> AGP_PAGE_SHIFT) * 4; 642 bus_space_write_4(isc->gtt_bst, isc->gtt_bsh, wroff, pte); 643 } 644