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