1 /* $OpenBSD: agp_i810.c,v 1.70 2011/09/14 10:26:16 oga 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 <sys/param.h> 32 #include <sys/systm.h> 33 #include <sys/malloc.h> 34 #include <sys/kernel.h> 35 #include <sys/lock.h> 36 #include <sys/device.h> 37 #include <sys/conf.h> 38 #include <sys/agpio.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/vga_pcivar.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 CHIP_SANDYBRIDGE=10, /* Sandybridge */ 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 struct vga_pci_bar *gtt_map; 84 bus_dmamap_t scrib_dmamap; 85 bus_addr_t isc_apaddr; 86 bus_size_t isc_apsize; /* current aperture size */ 87 int chiptype; /* i810-like or i830 */ 88 u_int32_t dcache_size; /* i810 only */ 89 u_int32_t stolen; /* number of i830/845 gtt 90 entries for stolen memory */ 91 }; 92 93 void agp_i810_attach(struct device *, struct device *, void *); 94 int agp_i810_activate(struct device *, int); 95 void agp_i810_configure(struct agp_i810_softc *); 96 int agp_i810_probe(struct device *, void *, void *); 97 int agp_i810_get_chiptype(struct pci_attach_args *); 98 void agp_i810_bind_page(void *, bus_size_t, paddr_t, int); 99 void agp_i810_unbind_page(void *, bus_size_t); 100 void agp_i810_flush_tlb(void *); 101 int agp_i810_enable(void *, u_int32_t mode); 102 struct agp_memory * agp_i810_alloc_memory(void *, int, vsize_t); 103 int agp_i810_free_memory(void *, struct agp_memory *); 104 int agp_i810_bind_memory(void *, struct agp_memory *, bus_size_t); 105 int agp_i810_unbind_memory(void *, struct agp_memory *); 106 void intagp_write_gtt(struct agp_i810_softc *, bus_size_t, paddr_t); 107 int intagp_gmch_match(struct pci_attach_args *); 108 109 extern void intagp_dma_sync(bus_dma_tag_t, bus_dmamap_t, 110 bus_addr_t, bus_size_t, int); 111 112 struct cfattach intagp_ca = { 113 sizeof(struct agp_i810_softc), agp_i810_probe, agp_i810_attach, 114 NULL, agp_i810_activate, 115 }; 116 117 struct cfdriver intagp_cd = { 118 NULL, "intagp", DV_DULL 119 }; 120 121 struct agp_methods agp_i810_methods = { 122 agp_i810_bind_page, 123 agp_i810_unbind_page, 124 agp_i810_flush_tlb, 125 intagp_dma_sync, 126 agp_i810_enable, 127 agp_i810_alloc_memory, 128 agp_i810_free_memory, 129 agp_i810_bind_memory, 130 agp_i810_unbind_memory, 131 }; 132 133 int 134 agp_i810_get_chiptype(struct pci_attach_args *pa) 135 { 136 switch (PCI_PRODUCT(pa->pa_id)) { 137 case PCI_PRODUCT_INTEL_82810_IGD: 138 case PCI_PRODUCT_INTEL_82810_DC100_IGD: 139 case PCI_PRODUCT_INTEL_82810E_IGD: 140 case PCI_PRODUCT_INTEL_82815_IGD: 141 return (CHIP_I810); 142 break; 143 case PCI_PRODUCT_INTEL_82830M_IGD: 144 case PCI_PRODUCT_INTEL_82845G_IGD: 145 return (CHIP_I830); 146 break; 147 case PCI_PRODUCT_INTEL_82855GM_IGD: 148 case PCI_PRODUCT_INTEL_82865G_IGD: 149 return (CHIP_I855); 150 break; 151 case PCI_PRODUCT_INTEL_82915G_IGD_1: 152 case PCI_PRODUCT_INTEL_82915G_IGD_2: 153 case PCI_PRODUCT_INTEL_82915GM_IGD_1: 154 case PCI_PRODUCT_INTEL_82915GM_IGD_2: 155 case PCI_PRODUCT_INTEL_82945G_IGD_1: 156 case PCI_PRODUCT_INTEL_82945G_IGD_2: 157 case PCI_PRODUCT_INTEL_82945GM_IGD_1: 158 case PCI_PRODUCT_INTEL_82945GM_IGD_2: 159 case PCI_PRODUCT_INTEL_82945GME_IGD_1: 160 return (CHIP_I915); 161 break; 162 case PCI_PRODUCT_INTEL_82946GZ_IGD_1: 163 case PCI_PRODUCT_INTEL_82946GZ_IGD_2: 164 case PCI_PRODUCT_INTEL_82Q965_IGD_1: 165 case PCI_PRODUCT_INTEL_82Q965_IGD_2: 166 case PCI_PRODUCT_INTEL_82G965_IGD_1: 167 case PCI_PRODUCT_INTEL_82G965_IGD_2: 168 case PCI_PRODUCT_INTEL_82GM965_IGD_1: 169 case PCI_PRODUCT_INTEL_82GM965_IGD_2: 170 case PCI_PRODUCT_INTEL_82GME965_IGD_1: 171 case PCI_PRODUCT_INTEL_82GME965_IGD_2: 172 case PCI_PRODUCT_INTEL_82G35_IGD_1: 173 case PCI_PRODUCT_INTEL_82G35_IGD_2: 174 return (CHIP_I965); 175 break; 176 case PCI_PRODUCT_INTEL_82G33_IGD_1: 177 case PCI_PRODUCT_INTEL_82G33_IGD_2: 178 case PCI_PRODUCT_INTEL_82Q35_IGD_1: 179 case PCI_PRODUCT_INTEL_82Q35_IGD_2: 180 return (CHIP_G33); 181 break; 182 case PCI_PRODUCT_INTEL_82GM45_IGD_1: 183 case PCI_PRODUCT_INTEL_82Q45_IGD_1: 184 case PCI_PRODUCT_INTEL_82G45_IGD_1: 185 case PCI_PRODUCT_INTEL_82G41_IGD_1: 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 case PCI_PRODUCT_INTEL_CORE2G_GT1: 197 case PCI_PRODUCT_INTEL_CORE2G_M_GT1: 198 case PCI_PRODUCT_INTEL_CORE2G_GT2: 199 case PCI_PRODUCT_INTEL_CORE2G_M_GT2: 200 case PCI_PRODUCT_INTEL_CORE2G_GT2_PLUS: 201 case PCI_PRODUCT_INTEL_CORE2G_M_GT2_PLUS: 202 return (CHIP_SANDYBRIDGE); 203 break; 204 } 205 return (CHIP_NONE); 206 } 207 208 /* 209 * We're intel IGD, bus 0 function 0 dev 0 should be the GMCH, so it should 210 * be Intel 211 */ 212 int 213 intagp_gmch_match(struct pci_attach_args *pa) 214 { 215 if (pa->pa_bus == 0 && pa->pa_device == 0 && pa->pa_function == 0 && 216 PCI_VENDOR(pa->pa_id) == PCI_VENDOR_INTEL && 217 PCI_CLASS(pa->pa_class) == PCI_CLASS_BRIDGE && 218 PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_BRIDGE_HOST) 219 return (1); 220 return (0); 221 } 222 223 int 224 agp_i810_probe(struct device *parent, void *match, void *aux) 225 { 226 struct pci_attach_args *pa = aux; 227 228 if (PCI_CLASS(pa->pa_class) != PCI_CLASS_DISPLAY || 229 PCI_SUBCLASS(pa->pa_class) != PCI_SUBCLASS_DISPLAY_VGA) 230 return (0); 231 232 return (agp_i810_get_chiptype(pa) != CHIP_NONE); 233 } 234 235 void 236 agp_i810_attach(struct device *parent, struct device *self, void *aux) 237 { 238 struct agp_i810_softc *isc = (struct agp_i810_softc *)self; 239 struct agp_gatt *gatt; 240 struct pci_attach_args *pa = aux, bpa; 241 struct vga_pci_softc *vga = (struct vga_pci_softc *)parent; 242 bus_addr_t mmaddr, gmaddr, tmp; 243 pcireg_t memtype, reg; 244 u_int32_t stolen; 245 u_int16_t gcc1; 246 247 isc->chiptype = agp_i810_get_chiptype(pa); 248 249 switch (isc->chiptype) { 250 case CHIP_I915: 251 case CHIP_G33: 252 case CHIP_PINEVIEW: 253 gmaddr = AGP_I915_GMADR; 254 mmaddr = AGP_I915_MMADR; 255 memtype = PCI_MAPREG_TYPE_MEM; 256 break; 257 case CHIP_I965: 258 case CHIP_G4X: 259 case CHIP_IRONLAKE: 260 case CHIP_SANDYBRIDGE: 261 gmaddr = AGP_I965_GMADR; 262 mmaddr = AGP_I965_MMADR; 263 memtype = PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT; 264 break; 265 default: 266 gmaddr = AGP_APBASE; 267 mmaddr = AGP_I810_MMADR; 268 memtype = PCI_MAPREG_TYPE_MEM; 269 break; 270 } 271 272 if (pci_mapreg_info(pa->pa_pc, pa->pa_tag, gmaddr, memtype, 273 &isc->isc_apaddr, &isc->isc_apsize, NULL) != 0) { 274 printf("can't get aperture info\n"); 275 return; 276 } 277 278 isc->map = vga_pci_bar_map(vga, mmaddr, 0, BUS_SPACE_MAP_LINEAR); 279 if (isc->map == NULL) { 280 printf("can't map mmadr registers\n"); 281 return; 282 } 283 284 if (isc->chiptype == CHIP_I915 || isc->chiptype == CHIP_G33 || 285 isc->chiptype == CHIP_PINEVIEW) { 286 isc->gtt_map = vga_pci_bar_map(vga, AGP_I915_GTTADR, 0, 287 BUS_SPACE_MAP_LINEAR); 288 if (isc->gtt_map == NULL) { 289 printf("can't map gatt registers\n"); 290 goto out; 291 } 292 } 293 294 gatt = malloc(sizeof(*gatt), M_AGP, M_NOWAIT | M_ZERO); 295 if (gatt == NULL) { 296 printf("can't alloc gatt\n"); 297 goto out; 298 } 299 isc->gatt = gatt; 300 301 gatt->ag_entries = isc->isc_apsize >> AGP_PAGE_SHIFT; 302 303 /* 304 * Find the GMCH, some of the registers we need to read for 305 * configuration purposes are on there. it's always at 306 * 0/0/0 (bus/dev/func). 307 */ 308 if (pci_find_device(&bpa, intagp_gmch_match) == 0) { 309 printf("can't find GMCH\n"); 310 goto out; 311 } 312 313 switch (isc->chiptype) { 314 case CHIP_I810: 315 /* Some i810s have on-chip memory called dcache */ 316 if (READ1(AGP_I810_DRT) & AGP_I810_DRT_POPULATED) 317 isc->dcache_size = 4 * 1024 * 1024; 318 else 319 isc->dcache_size = 0; 320 321 /* According to the specs the gatt on the i810 must be 64k */ 322 if (agp_alloc_dmamem(pa->pa_dmat, 64 * 1024, &gatt->ag_dmamap, 323 &gatt->ag_physical, &gatt->ag_dmaseg) != 0) { 324 goto out; 325 } 326 gatt->ag_size = gatt->ag_entries * sizeof(u_int32_t); 327 328 if (bus_dmamem_map(pa->pa_dmat, &gatt->ag_dmaseg, 1, 64 * 1024, 329 (caddr_t *)&gatt->ag_virtual, BUS_DMA_NOWAIT) != 0) 330 goto out; 331 break; 332 333 case CHIP_I830: 334 /* The i830 automatically initializes the 128k gatt on boot. */ 335 336 reg = pci_conf_read(bpa.pa_pc, bpa.pa_tag, AGP_I830_GCC0); 337 gcc1 = (u_int16_t)(reg >> 16); 338 switch (gcc1 & AGP_I830_GCC1_GMS) { 339 case AGP_I830_GCC1_GMS_STOLEN_512: 340 isc->stolen = (512 - 132) * 1024 / 4096; 341 break; 342 case AGP_I830_GCC1_GMS_STOLEN_1024: 343 isc->stolen = (1024 - 132) * 1024 / 4096; 344 break; 345 case AGP_I830_GCC1_GMS_STOLEN_8192: 346 isc->stolen = (8192 - 132) * 1024 / 4096; 347 break; 348 default: 349 isc->stolen = 0; 350 printf("unknown memory configuration, disabling\n"); 351 goto out; 352 } 353 #ifdef DEBUG 354 if (isc->stolen > 0) { 355 printf(": detected %dk stolen memory", 356 isc->stolen * 4); 357 } else 358 printf(": no preallocated video memory\n"); 359 #endif 360 361 /* GATT address is already in there, make sure it's enabled */ 362 gatt->ag_physical = READ4(AGP_I810_PGTBL_CTL) & ~1; 363 break; 364 365 case CHIP_I855: 366 /* FALLTHROUGH */ 367 case CHIP_I915: 368 /* FALLTHROUGH */ 369 case CHIP_I965: 370 /* FALLTHROUGH */ 371 case CHIP_G33: 372 /* FALLTHROUGH */ 373 case CHIP_G4X: 374 case CHIP_PINEVIEW: 375 case CHIP_IRONLAKE: 376 377 /* Stolen memory is set up at the beginning of the aperture by 378 * the BIOS, consisting of the GATT followed by 4kb for the 379 * BIOS display. 380 */ 381 382 reg = pci_conf_read(bpa.pa_pc, bpa.pa_tag, AGP_I855_GCC1); 383 gcc1 = (u_int16_t)(reg >> 16); 384 switch (isc->chiptype) { 385 case CHIP_I855: 386 /* The 855GM automatically initializes the 128k gatt on boot. */ 387 stolen = 128 + 4; 388 break; 389 case CHIP_I915: 390 /* The 915G automatically initializes the 256k gatt on boot. */ 391 stolen = 256 + 4; 392 break; 393 case CHIP_I965: 394 switch (READ4(AGP_I810_PGTBL_CTL) & 395 AGP_I810_PGTBL_SIZE_MASK) { 396 case AGP_I810_PGTBL_SIZE_512KB: 397 stolen = 512 + 4; 398 break; 399 case AGP_I810_PGTBL_SIZE_256KB: 400 stolen = 256 + 4; 401 break; 402 case AGP_I810_PGTBL_SIZE_128KB: 403 default: 404 stolen = 128 + 4; 405 break; 406 } 407 break; 408 case CHIP_G33: 409 switch (gcc1 & AGP_G33_PGTBL_SIZE_MASK) { 410 case AGP_G33_PGTBL_SIZE_2M: 411 stolen = 2048 + 4; 412 break; 413 case AGP_G33_PGTBL_SIZE_1M: 414 default: 415 stolen = 1024 + 4; 416 break; 417 } 418 break; 419 case CHIP_G4X: 420 case CHIP_PINEVIEW: 421 case CHIP_IRONLAKE: 422 /* 423 * GTT stolen is separate from graphics stolen on 424 * 4 series hardware. so ignore it in stolen gtt entries 425 * counting. However, 4Kb of stolen memory isn't mapped 426 * to the GTT. 427 */ 428 stolen = 4; 429 break; 430 default: 431 printf("bad chiptype\n"); 432 goto out; 433 } 434 435 switch (gcc1 & AGP_I855_GCC1_GMS) { 436 case AGP_I855_GCC1_GMS_STOLEN_1M: 437 isc->stolen = (1024 - stolen) * 1024 / 4096; 438 break; 439 case AGP_I855_GCC1_GMS_STOLEN_4M: 440 isc->stolen = (4096 - stolen) * 1024 / 4096; 441 break; 442 case AGP_I855_GCC1_GMS_STOLEN_8M: 443 isc->stolen = (8192 - stolen) * 1024 / 4096; 444 break; 445 case AGP_I855_GCC1_GMS_STOLEN_16M: 446 isc->stolen = (16384 - stolen) * 1024 / 4096; 447 break; 448 case AGP_I855_GCC1_GMS_STOLEN_32M: 449 isc->stolen = (32768 - stolen) * 1024 / 4096; 450 break; 451 case AGP_I915_GCC1_GMS_STOLEN_48M: 452 isc->stolen = (49152 - stolen) * 1024 / 4096; 453 break; 454 case AGP_I915_GCC1_GMS_STOLEN_64M: 455 isc->stolen = (65536 - stolen) * 1024 / 4096; 456 break; 457 case AGP_G33_GCC1_GMS_STOLEN_128M: 458 isc->stolen = (131072 - stolen) * 1024 / 4096; 459 break; 460 case AGP_G33_GCC1_GMS_STOLEN_256M: 461 isc->stolen = (262144 - stolen) * 1024 / 4096; 462 break; 463 case AGP_INTEL_GMCH_GMS_STOLEN_96M: 464 isc->stolen = (98304 - stolen) * 1024 / 4096; 465 break; 466 case AGP_INTEL_GMCH_GMS_STOLEN_160M: 467 isc->stolen = (163840 - stolen) * 1024 / 4096; 468 break; 469 case AGP_INTEL_GMCH_GMS_STOLEN_224M: 470 isc->stolen = (229376 - stolen) * 1024 / 4096; 471 break; 472 case AGP_INTEL_GMCH_GMS_STOLEN_352M: 473 isc->stolen = (360448 - stolen) * 1024 / 4096; 474 break; 475 default: 476 isc->stolen = 0; 477 printf("unknown memory configuration, disabling\n"); 478 goto out; 479 } 480 #ifdef DEBUG 481 if (isc->stolen > 0) { 482 printf(": detected %dk stolen memory", 483 isc->stolen * 4); 484 } else 485 printf(": no preallocated video memory\n"); 486 #endif 487 488 /* GATT address is already in there, make sure it's enabled */ 489 gatt->ag_physical = READ4(AGP_I810_PGTBL_CTL) & ~1; 490 break; 491 492 case CHIP_SANDYBRIDGE: 493 494 /* Stolen memory is set up at the beginning of the aperture by 495 * the BIOS, consisting of the GATT followed by 4kb for the 496 * BIOS display. 497 */ 498 499 gcc1 = (u_int16_t)pci_conf_read(bpa.pa_pc, bpa.pa_tag, 500 AGP_INTEL_SNB_GMCH_CTRL); 501 502 stolen = 4; 503 504 switch (gcc1 & AGP_INTEL_SNB_GMCH_GMS_STOLEN_MASK) { 505 case AGP_INTEL_SNB_GMCH_GMS_STOLEN_32M: 506 isc->stolen = (32768 - stolen) * 1024 / 4096; 507 break; 508 case AGP_INTEL_SNB_GMCH_GMS_STOLEN_64M: 509 isc->stolen = (65536 - stolen) * 1024 / 4096; 510 break; 511 case AGP_INTEL_SNB_GMCH_GMS_STOLEN_96M: 512 isc->stolen = (98304 - stolen) * 1024 / 4096; 513 break; 514 case AGP_INTEL_SNB_GMCH_GMS_STOLEN_128M: 515 isc->stolen = (131072 - stolen) * 1024 / 4096; 516 break; 517 case AGP_INTEL_SNB_GMCH_GMS_STOLEN_160M: 518 isc->stolen = (163840 - stolen) * 1024 / 4096; 519 break; 520 case AGP_INTEL_SNB_GMCH_GMS_STOLEN_192M: 521 isc->stolen = (196608 - stolen) * 1024 / 4096; 522 break; 523 case AGP_INTEL_SNB_GMCH_GMS_STOLEN_224M: 524 isc->stolen = (229376 - stolen) * 1024 / 4096; 525 break; 526 case AGP_INTEL_SNB_GMCH_GMS_STOLEN_256M: 527 isc->stolen = (262144 - stolen) * 1024 / 4096; 528 break; 529 case AGP_INTEL_SNB_GMCH_GMS_STOLEN_288M: 530 isc->stolen = (294912 - stolen) * 1024 / 4096; 531 break; 532 case AGP_INTEL_SNB_GMCH_GMS_STOLEN_320M: 533 isc->stolen = (327680 - stolen) * 1024 / 4096; 534 break; 535 case AGP_INTEL_SNB_GMCH_GMS_STOLEN_352M: 536 isc->stolen = (360448 - stolen) * 1024 / 4096; 537 break; 538 case AGP_INTEL_SNB_GMCH_GMS_STOLEN_384M: 539 isc->stolen = (393216 - stolen) * 1024 / 4096; 540 break; 541 case AGP_INTEL_SNB_GMCH_GMS_STOLEN_416M: 542 isc->stolen = (425984 - stolen) * 1024 / 4096; 543 break; 544 case AGP_INTEL_SNB_GMCH_GMS_STOLEN_448M: 545 isc->stolen = (458752 - stolen) * 1024 / 4096; 546 break; 547 case AGP_INTEL_SNB_GMCH_GMS_STOLEN_480M: 548 isc->stolen = (491520 - stolen) * 1024 / 4096; 549 break; 550 case AGP_INTEL_SNB_GMCH_GMS_STOLEN_512M: 551 isc->stolen = (524288 - stolen) * 1024 / 4096; 552 break; 553 default: 554 isc->stolen = 0; 555 printf("unknown memory configuration, disabling\n"); 556 goto out; 557 } 558 559 #ifdef DEBUG 560 if (isc->stolen > 0) { 561 printf(": detected %dk stolen memory", 562 isc->stolen * 4); 563 } else 564 printf(": no preallocated video memory\n"); 565 #endif 566 567 /* GATT address is already in there, make sure it's enabled */ 568 gatt->ag_physical = READ4(AGP_I810_PGTBL_CTL) & ~1; 569 break; 570 571 default: 572 printf(": unknown initialisation\n"); 573 return; 574 } 575 /* Intel recommends that you have a fake page bound to the gtt always */ 576 if (agp_alloc_dmamem(pa->pa_dmat, AGP_PAGE_SIZE, &isc->scrib_dmamap, 577 &tmp, &isc->scrib_seg) != 0) { 578 printf(": can't get scribble page\n"); 579 return; 580 } 581 agp_i810_configure(isc); 582 583 isc->agpdev = (struct agp_softc *)agp_attach_bus(pa, &agp_i810_methods, 584 isc->isc_apaddr, isc->isc_apsize, &isc->dev); 585 return; 586 out: 587 588 if (isc->gatt) { 589 if (isc->gatt->ag_size != 0) 590 agp_free_dmamem(pa->pa_dmat, isc->gatt->ag_size, 591 isc->gatt->ag_dmamap, &isc->gatt->ag_dmaseg); 592 free(isc->gatt, M_AGP); 593 } 594 if (isc->gtt_map != NULL) 595 vga_pci_bar_unmap(isc->gtt_map); 596 if (isc->map != NULL) 597 vga_pci_bar_unmap(isc->map); 598 } 599 600 int 601 agp_i810_activate(struct device *arg, int act) 602 { 603 struct agp_i810_softc *isc = (struct agp_i810_softc *)arg; 604 bus_space_tag_t bst = isc->map->bst; 605 bus_space_handle_t bsh = isc->map->bsh; 606 bus_size_t offset; 607 608 if (isc->chiptype == CHIP_I915 || 609 isc->chiptype == CHIP_G33 || 610 isc->chiptype == CHIP_PINEVIEW) { 611 bst = isc->gtt_map->bst; 612 bsh = isc->gtt_map->bsh; 613 } 614 615 switch(isc->chiptype) { 616 case CHIP_I915: 617 case CHIP_G33: 618 case CHIP_PINEVIEW: 619 offset = 0; 620 break; 621 case CHIP_I965: 622 offset = AGP_I965_GTT; 623 break; 624 case CHIP_G4X: 625 case CHIP_IRONLAKE: 626 case CHIP_SANDYBRIDGE: 627 offset = AGP_G4X_GTT; 628 break; 629 default: 630 offset = AGP_I810_GTT; 631 break; 632 } 633 634 /* 635 * Anything kept in agp over a suspend/resume cycle (and thus by X 636 * over a vt switch cycle) is undefined upon resume. 637 */ 638 switch (act) { 639 case DVACT_RESUME: 640 agp_i810_configure(isc); 641 break; 642 } 643 644 return (0); 645 } 646 void 647 agp_i810_configure(struct agp_i810_softc *isc) 648 { 649 bus_addr_t tmp; 650 651 tmp = isc->isc_apaddr; 652 if (isc->chiptype == CHIP_I810) { 653 tmp += isc->dcache_size; 654 } else { 655 tmp += isc->stolen << AGP_PAGE_SHIFT; 656 } 657 658 agp_flush_cache(); 659 /* Install the GATT. */ 660 WRITE4(AGP_I810_PGTBL_CTL, isc->gatt->ag_physical | 1); 661 662 /* initialise all gtt entries to point to scribble page */ 663 for (; tmp < (isc->isc_apaddr + isc->isc_apsize); 664 tmp += AGP_PAGE_SIZE) 665 agp_i810_unbind_page(isc, tmp); 666 /* XXX we'll need to restore the GTT contents when we go kms */ 667 668 /* 669 * Make sure the chipset can see everything. 670 */ 671 agp_flush_cache(); 672 } 673 674 #if 0 675 int 676 agp_i810_detach(struct agp_softc *sc) 677 { 678 int error; 679 struct agp_i810_softc *isc = sc->sc_chipc; 680 681 error = agp_generic_detach(sc); 682 if (error) 683 return (error); 684 685 /* Clear the GATT base. */ 686 if (sc->chiptype == CHIP_I810) { 687 WRITE4(AGP_I810_PGTBL_CTL, 0); 688 } else { 689 unsigned int pgtblctl; 690 pgtblctl = READ4(AGP_I810_PGTBL_CTL); 691 pgtblctl &= ~1; 692 WRITE4(AGP_I810_PGTBL_CTL, pgtblctl); 693 } 694 695 if (sc->chiptype == CHIP_I810) { 696 bus_dmamem_unmap(pa->pa_dmat, isc->gatt->ag_virtual, 697 gatt->ag_size); 698 agp_free_dmamem(sc->sc_dmat, gatt->ag_size, gatt->ag_dmamap, 699 &gatt->ag_dmaseg); 700 } 701 free(sc->gatt, M_AGP); 702 703 return (0); 704 } 705 #endif 706 707 void 708 agp_i810_bind_page(void *sc, bus_addr_t offset, paddr_t physical, int flags) 709 { 710 struct agp_i810_softc *isc = sc; 711 /* 712 * COHERENT mappings mean set the snoop bit. this should never be 713 * accessed by the gpu through the gtt. 714 */ 715 if (flags & BUS_DMA_COHERENT) 716 physical |= INTEL_COHERENT; 717 718 intagp_write_gtt(isc, offset - isc->isc_apaddr, physical); 719 } 720 721 void 722 agp_i810_unbind_page(void *sc, bus_size_t offset) 723 { 724 struct agp_i810_softc *isc = sc; 725 726 intagp_write_gtt(isc, offset - isc->isc_apaddr, 727 isc->scrib_dmamap->dm_segs[0].ds_addr); 728 } 729 730 /* 731 * Writing via memory mapped registers already flushes all TLBs. 732 */ 733 void 734 agp_i810_flush_tlb(void *sc) 735 { 736 } 737 738 int 739 agp_i810_enable(void *sc, u_int32_t mode) 740 { 741 return (0); 742 } 743 744 struct agp_memory * 745 agp_i810_alloc_memory(void *softc, int type, vsize_t size) 746 { 747 struct agp_i810_softc *isc = softc; 748 struct agp_softc *sc = isc->agpdev; 749 struct agp_memory *mem; 750 int error; 751 752 if ((size & (AGP_PAGE_SIZE - 1)) != 0) 753 return (NULL); 754 755 if (sc->sc_allocated + size > sc->sc_maxmem) 756 return (NULL); 757 758 if (type == 1) { 759 /* 760 * Mapping local DRAM into GATT. 761 */ 762 if (isc->chiptype != CHIP_I810 || size != isc->dcache_size) 763 return (NULL); 764 } else if (type == 2) { 765 /* 766 * Bogus mapping of 1 or 4 pages for the hardware cursor. 767 */ 768 if (size != AGP_PAGE_SIZE && size != 4 * AGP_PAGE_SIZE) { 769 #ifdef DEBUG 770 printf("agp: trying to map %lu for hw cursor\n", size); 771 #endif 772 return (NULL); 773 } 774 } 775 776 mem = malloc(sizeof *mem, M_AGP, M_WAITOK | M_ZERO); 777 mem->am_id = sc->sc_nextid++; 778 mem->am_size = size; 779 mem->am_type = type; 780 781 if (type == 2) { 782 /* 783 * Allocate and wire down the pages now so that we can 784 * get their physical address. 785 */ 786 if ((mem->am_dmaseg = malloc(sizeof (*mem->am_dmaseg), M_AGP, 787 M_WAITOK | M_CANFAIL)) == NULL) { 788 free(mem, M_AGP); 789 return (NULL); 790 } 791 792 if ((error = agp_alloc_dmamem(sc->sc_dmat, size, 793 &mem->am_dmamap, &mem->am_physical, mem->am_dmaseg)) != 0) { 794 free(mem->am_dmaseg, M_AGP); 795 free(mem, M_AGP); 796 printf("agp: agp_alloc_dmamem(%d)\n", error); 797 return (NULL); 798 } 799 } else if (type != 1) { 800 if ((error = bus_dmamap_create(sc->sc_dmat, size, 801 size / PAGE_SIZE + 1, size, 0, BUS_DMA_NOWAIT, 802 &mem->am_dmamap)) != 0) { 803 free(mem, M_AGP); 804 printf("agp: bus_dmamap_create(%d)\n", error); 805 return (NULL); 806 } 807 } 808 809 TAILQ_INSERT_TAIL(&sc->sc_memory, mem, am_link); 810 sc->sc_allocated += size; 811 812 return (mem); 813 } 814 815 int 816 agp_i810_free_memory(void *softc, struct agp_memory *mem) 817 { 818 struct agp_i810_softc *isc = softc; 819 struct agp_softc *sc = isc->agpdev; 820 821 if (mem->am_is_bound) 822 return (EBUSY); 823 824 if (mem->am_type == 2) { 825 agp_free_dmamem(sc->sc_dmat, mem->am_size, mem->am_dmamap, 826 mem->am_dmaseg); 827 free(mem->am_dmaseg, M_AGP); 828 } else if (mem->am_type != 1) { 829 bus_dmamap_destroy(sc->sc_dmat, mem->am_dmamap); 830 } 831 832 sc->sc_allocated -= mem->am_size; 833 TAILQ_REMOVE(&sc->sc_memory, mem, am_link); 834 free(mem, M_AGP); 835 return (0); 836 } 837 838 int 839 agp_i810_bind_memory(void *sc, struct agp_memory *mem, bus_size_t offset) 840 { 841 struct agp_i810_softc *isc = sc; 842 u_int32_t regval, i; 843 844 if (mem->am_is_bound != 0) 845 return (EINVAL); 846 847 if (isc->chiptype != CHIP_I810 && (offset >> AGP_PAGE_SHIFT) < 848 isc->stolen) { 849 #ifdef DEBUG 850 printf("agp: trying to bind into stolen memory\n"); 851 #endif 852 return (EINVAL); 853 } 854 855 /* 856 * XXX evil hack: the PGTBL_CTL appearently gets overwritten by the 857 * X server for mysterious reasons which leads to crashes if we write 858 * to the GTT through the MMIO window. 859 * Until the issue is solved, simply restore it. 860 */ 861 regval = READ4(AGP_I810_PGTBL_CTL); 862 if (regval != (isc->gatt->ag_physical | 1)) { 863 printf("agp_i810_bind_memory: PGTBL_CTL is 0x%x - fixing\n", 864 regval); 865 WRITE4(AGP_I810_PGTBL_CTL, isc->gatt->ag_physical | 866 INTEL_ENABLED); 867 } 868 869 if (mem->am_type == 2) { 870 for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE) 871 agp_i810_bind_page(isc, isc->isc_apaddr + offset + i, 872 mem->am_physical + i, 0); 873 mem->am_offset = offset; 874 mem->am_is_bound = 1; 875 return (0); 876 } 877 878 if (mem->am_type != 1) 879 return (agp_generic_bind_memory(isc->agpdev, mem, offset)); 880 881 if (isc->chiptype != CHIP_I810) 882 return (EINVAL); 883 884 for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE) 885 intagp_write_gtt(isc, i, i | INTEL_ENABLED | INTEL_LOCAL); 886 mem->am_is_bound = 1; 887 return (0); 888 } 889 890 int 891 agp_i810_unbind_memory(void *sc, struct agp_memory *mem) 892 { 893 struct agp_i810_softc *isc = sc; 894 u_int32_t i; 895 896 if (mem->am_is_bound == 0) 897 return (EINVAL); 898 899 if (mem->am_type == 2) { 900 for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE) 901 agp_i810_unbind_page(isc, isc->isc_apaddr + 902 mem->am_offset + i); 903 mem->am_offset = 0; 904 mem->am_is_bound = 0; 905 return (0); 906 } 907 908 if (mem->am_type != 1) 909 return (agp_generic_unbind_memory(isc->agpdev, mem)); 910 911 if (isc->chiptype != CHIP_I810) 912 return (EINVAL); 913 914 for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE) 915 intagp_write_gtt(isc, i, 0); 916 mem->am_is_bound = 0; 917 return (0); 918 } 919 920 void 921 intagp_write_gtt(struct agp_i810_softc *isc, bus_size_t off, paddr_t v) 922 { 923 u_int32_t pte = 0; 924 bus_size_t baseoff, wroff; 925 926 if (isc->chiptype != CHIP_I810 && 927 (off >> AGP_PAGE_SHIFT) < isc->stolen) { 928 printf("intagp: binding into stolen memory! (0x%lx)\n", 929 (off >> AGP_PAGE_SHIFT)); 930 } 931 932 if (v != 0) { 933 pte = v | INTEL_ENABLED; 934 /* 965+ can do 36-bit addressing, add in the extra bits */ 935 if (isc->chiptype == CHIP_I965 || 936 isc->chiptype == CHIP_G4X || 937 isc->chiptype == CHIP_PINEVIEW || 938 isc->chiptype == CHIP_G33 || 939 isc->chiptype == CHIP_IRONLAKE || 940 isc->chiptype == CHIP_SANDYBRIDGE) { 941 pte |= (v & 0x0000000f00000000ULL) >> 28; 942 } 943 } 944 945 wroff = (off >> AGP_PAGE_SHIFT) * 4; 946 947 switch(isc->chiptype) { 948 case CHIP_I915: 949 /* FALLTHROUGH */ 950 case CHIP_G33: 951 case CHIP_PINEVIEW: 952 bus_space_write_4(isc->gtt_map->bst, isc->gtt_map->bsh, 953 wroff, pte); 954 return; 955 case CHIP_I965: 956 baseoff = AGP_I965_GTT; 957 break; 958 case CHIP_G4X: 959 case CHIP_IRONLAKE: 960 case CHIP_SANDYBRIDGE: 961 baseoff = AGP_G4X_GTT; 962 break; 963 default: 964 baseoff = AGP_I810_GTT; 965 break; 966 } 967 bus_space_write_4(isc->map->bst, isc->map->bsh, baseoff + wroff, pte); 968 } 969