1 /* $NetBSD: agp_i810.c,v 1.54 2008/06/09 06:49:54 freza 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 * $FreeBSD: src/sys/pci/agp_i810.c,v 1.4 2001/07/05 21:28:47 jhb Exp $ 30 */ 31 32 #include <sys/cdefs.h> 33 __KERNEL_RCSID(0, "$NetBSD: agp_i810.c,v 1.54 2008/06/09 06:49:54 freza Exp $"); 34 35 #include <sys/param.h> 36 #include <sys/systm.h> 37 #include <sys/malloc.h> 38 #include <sys/kernel.h> 39 #include <sys/proc.h> 40 #include <sys/device.h> 41 #include <sys/conf.h> 42 43 #include <uvm/uvm_extern.h> 44 45 #include <dev/pci/pcivar.h> 46 #include <dev/pci/pcireg.h> 47 #include <dev/pci/pcidevs.h> 48 #include <dev/pci/agpvar.h> 49 #include <dev/pci/agpreg.h> 50 51 #include <sys/agpio.h> 52 53 #include <sys/bus.h> 54 55 #include "agp_intel.h" 56 57 #define READ1(off) bus_space_read_1(isc->bst, isc->bsh, off) 58 #define READ4(off) bus_space_read_4(isc->bst, isc->bsh, off) 59 #define WRITE4(off,v) bus_space_write_4(isc->bst, isc->bsh, off, v) 60 #define WRITEGTT(off, v) \ 61 do { \ 62 if (isc->chiptype == CHIP_I915 || isc->chiptype == CHIP_G33) { \ 63 bus_space_write_4(isc->gtt_bst, isc->gtt_bsh, \ 64 (u_int32_t)((off) >> AGP_PAGE_SHIFT) * 4, \ 65 (v)); \ 66 } else if (isc->chiptype == CHIP_I965) { \ 67 WRITE4(AGP_I965_GTT + \ 68 (u_int32_t)((off) >> AGP_PAGE_SHIFT) * 4, \ 69 (v)); \ 70 } else { \ 71 WRITE4(AGP_I810_GTT + \ 72 (u_int32_t)((off) >> AGP_PAGE_SHIFT) * 4, \ 73 (v)); \ 74 } \ 75 } while (0) 76 77 #define CHIP_I810 0 /* i810/i815 */ 78 #define CHIP_I830 1 /* 830M/845G */ 79 #define CHIP_I855 2 /* 852GM/855GM/865G */ 80 #define CHIP_I915 3 /* 915G/915GM/945G/945GM */ 81 #define CHIP_I965 4 /* 965Q/965PM */ 82 #define CHIP_G33 5 /* G33/Q33/Q35 */ 83 84 struct agp_i810_softc { 85 u_int32_t initial_aperture; /* aperture size at startup */ 86 struct agp_gatt *gatt; 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 entries 90 for stolen memory */ 91 bus_space_tag_t bst; /* register bus_space tag */ 92 bus_space_handle_t bsh; /* register bus_space handle */ 93 bus_space_tag_t gtt_bst; /* GTT bus_space tag */ 94 bus_space_handle_t gtt_bsh; /* GTT bus_space handle */ 95 struct pci_attach_args vga_pa; 96 97 u_int32_t pgtblctl; 98 }; 99 100 /* XXX hack, see below */ 101 static bus_addr_t agp_i810_vga_regbase; 102 static bus_space_handle_t agp_i810_vga_bsh; 103 104 static u_int32_t agp_i810_get_aperture(struct agp_softc *); 105 static int agp_i810_set_aperture(struct agp_softc *, u_int32_t); 106 static int agp_i810_bind_page(struct agp_softc *, off_t, bus_addr_t); 107 static int agp_i810_unbind_page(struct agp_softc *, off_t); 108 static void agp_i810_flush_tlb(struct agp_softc *); 109 static int agp_i810_enable(struct agp_softc *, u_int32_t mode); 110 static struct agp_memory *agp_i810_alloc_memory(struct agp_softc *, int, 111 vsize_t); 112 static int agp_i810_free_memory(struct agp_softc *, struct agp_memory *); 113 static int agp_i810_bind_memory(struct agp_softc *, struct agp_memory *, off_t); 114 static int agp_i810_unbind_memory(struct agp_softc *, struct agp_memory *); 115 116 static bool agp_i810_resume(device_t PMF_FN_PROTO); 117 static int agp_i810_init(struct agp_softc *); 118 119 static int agp_i810_init(struct agp_softc *); 120 121 static struct agp_methods agp_i810_methods = { 122 agp_i810_get_aperture, 123 agp_i810_set_aperture, 124 agp_i810_bind_page, 125 agp_i810_unbind_page, 126 agp_i810_flush_tlb, 127 agp_i810_enable, 128 agp_i810_alloc_memory, 129 agp_i810_free_memory, 130 agp_i810_bind_memory, 131 agp_i810_unbind_memory, 132 }; 133 134 /* XXXthorpej -- duplicated code (see arch/i386/pci/pchb.c) */ 135 static int 136 agp_i810_vgamatch(struct pci_attach_args *pa) 137 { 138 139 if (PCI_CLASS(pa->pa_class) != PCI_CLASS_DISPLAY || 140 PCI_SUBCLASS(pa->pa_class) != PCI_SUBCLASS_DISPLAY_VGA) 141 return (0); 142 143 switch (PCI_PRODUCT(pa->pa_id)) { 144 case PCI_PRODUCT_INTEL_82810_GC: 145 case PCI_PRODUCT_INTEL_82810_DC100_GC: 146 case PCI_PRODUCT_INTEL_82810E_GC: 147 case PCI_PRODUCT_INTEL_82815_FULL_GRAPH: 148 case PCI_PRODUCT_INTEL_82830MP_IV: 149 case PCI_PRODUCT_INTEL_82845G_IGD: 150 case PCI_PRODUCT_INTEL_82855GM_IGD: 151 case PCI_PRODUCT_INTEL_82865_IGD: 152 case PCI_PRODUCT_INTEL_82915G_IGD: 153 case PCI_PRODUCT_INTEL_82915GM_IGD: 154 case PCI_PRODUCT_INTEL_82945P_IGD: 155 case PCI_PRODUCT_INTEL_82945GM_IGD: 156 case PCI_PRODUCT_INTEL_82945GM_IGD_1: 157 case PCI_PRODUCT_INTEL_82965Q_IGD: 158 case PCI_PRODUCT_INTEL_82965Q_IGD_1: 159 case PCI_PRODUCT_INTEL_82965PM_IGD: 160 case PCI_PRODUCT_INTEL_82965PM_IGD_1: 161 case PCI_PRODUCT_INTEL_82G33_IGD: 162 case PCI_PRODUCT_INTEL_82G33_IGD_1: 163 case PCI_PRODUCT_INTEL_82965G_IGD: 164 case PCI_PRODUCT_INTEL_82965G_IGD_1: 165 case PCI_PRODUCT_INTEL_82Q35_IGD: 166 case PCI_PRODUCT_INTEL_82Q35_IGD_1: 167 case PCI_PRODUCT_INTEL_82Q33_IGD: 168 case PCI_PRODUCT_INTEL_82Q33_IGD_1: 169 return (1); 170 } 171 172 return (0); 173 } 174 175 static int 176 agp_i965_map_aperture(struct pci_attach_args *pa, struct agp_softc *sc, int reg) 177 { 178 /* 179 * Find the aperture. Don't map it (yet), this would 180 * eat KVA. 181 */ 182 if (pci_mapreg_info(pa->pa_pc, pa->pa_tag, reg, 183 PCI_MAPREG_TYPE_MEM|PCI_MAPREG_MEM_TYPE_64BIT, &sc->as_apaddr, &sc->as_apsize, 184 &sc->as_apflags) != 0) 185 return ENXIO; 186 187 sc->as_apt = pa->pa_memt; 188 189 return 0; 190 } 191 192 int 193 agp_i810_attach(device_t parent, device_t self, void *aux) 194 { 195 struct agp_softc *sc = device_private(self); 196 struct agp_i810_softc *isc; 197 struct agp_gatt *gatt; 198 int error, apbase; 199 bus_addr_t mmadr; 200 bus_size_t mmadrsize; 201 202 isc = malloc(sizeof *isc, M_AGP, M_NOWAIT|M_ZERO); 203 if (isc == NULL) { 204 aprint_error(": can't allocate chipset-specific softc\n"); 205 return ENOMEM; 206 } 207 sc->as_chipc = isc; 208 sc->as_methods = &agp_i810_methods; 209 210 if (pci_find_device(&isc->vga_pa, agp_i810_vgamatch) == 0) { 211 #if NAGP_INTEL > 0 212 const struct pci_attach_args *pa = aux; 213 214 switch (PCI_PRODUCT(pa->pa_id)) { 215 case PCI_PRODUCT_INTEL_82840_HB: 216 case PCI_PRODUCT_INTEL_82865_HB: 217 case PCI_PRODUCT_INTEL_82845G_DRAM: 218 case PCI_PRODUCT_INTEL_82815_FULL_HUB: 219 return agp_intel_attach(parent, self, aux); 220 } 221 #endif 222 aprint_error(": can't find internal VGA device config space\n"); 223 free(isc, M_AGP); 224 return ENOENT; 225 } 226 227 /* XXXfvdl */ 228 sc->as_dmat = isc->vga_pa.pa_dmat; 229 230 switch (PCI_PRODUCT(isc->vga_pa.pa_id)) { 231 case PCI_PRODUCT_INTEL_82810_GC: 232 case PCI_PRODUCT_INTEL_82810_DC100_GC: 233 case PCI_PRODUCT_INTEL_82810E_GC: 234 case PCI_PRODUCT_INTEL_82815_FULL_GRAPH: 235 isc->chiptype = CHIP_I810; 236 break; 237 case PCI_PRODUCT_INTEL_82830MP_IV: 238 case PCI_PRODUCT_INTEL_82845G_IGD: 239 isc->chiptype = CHIP_I830; 240 break; 241 case PCI_PRODUCT_INTEL_82855GM_IGD: 242 case PCI_PRODUCT_INTEL_82865_IGD: 243 isc->chiptype = CHIP_I855; 244 break; 245 case PCI_PRODUCT_INTEL_82915G_IGD: 246 case PCI_PRODUCT_INTEL_82915GM_IGD: 247 case PCI_PRODUCT_INTEL_82945P_IGD: 248 case PCI_PRODUCT_INTEL_82945GM_IGD: 249 case PCI_PRODUCT_INTEL_82945GM_IGD_1: 250 isc->chiptype = CHIP_I915; 251 break; 252 case PCI_PRODUCT_INTEL_82965Q_IGD: 253 case PCI_PRODUCT_INTEL_82965Q_IGD_1: 254 case PCI_PRODUCT_INTEL_82965PM_IGD: 255 case PCI_PRODUCT_INTEL_82965PM_IGD_1: 256 case PCI_PRODUCT_INTEL_82965G_IGD: 257 case PCI_PRODUCT_INTEL_82965G_IGD_1: 258 isc->chiptype = CHIP_I965; 259 break; 260 case PCI_PRODUCT_INTEL_82Q35_IGD: 261 case PCI_PRODUCT_INTEL_82Q35_IGD_1: 262 case PCI_PRODUCT_INTEL_82G33_IGD: 263 case PCI_PRODUCT_INTEL_82G33_IGD_1: 264 case PCI_PRODUCT_INTEL_82Q33_IGD: 265 case PCI_PRODUCT_INTEL_82Q33_IGD_1: 266 isc->chiptype = CHIP_G33; 267 break; 268 } 269 270 switch (isc->chiptype) { 271 case CHIP_I915: 272 case CHIP_G33: 273 apbase = AGP_I915_GMADR; 274 break; 275 default: 276 apbase = AGP_I810_GMADR; 277 break; 278 } 279 if (isc->chiptype == CHIP_I965) { 280 error = agp_i965_map_aperture(&isc->vga_pa, sc, AGP_I965_GMADR); 281 } else { 282 error = agp_map_aperture(&isc->vga_pa, sc, apbase); 283 } 284 if (error != 0) { 285 aprint_error(": can't map aperture\n"); 286 free(isc, M_AGP); 287 return error; 288 } 289 290 if (isc->chiptype == CHIP_I915 || isc->chiptype == CHIP_G33) { 291 error = pci_mapreg_map(&isc->vga_pa, AGP_I915_MMADR, 292 PCI_MAPREG_TYPE_MEM, 0, &isc->bst, &isc->bsh, 293 &mmadr, &mmadrsize); 294 if (error != 0) { 295 aprint_error(": can't map mmadr registers\n"); 296 agp_generic_detach(sc); 297 return error; 298 } 299 error = pci_mapreg_map(&isc->vga_pa, AGP_I915_GTTADR, 300 PCI_MAPREG_TYPE_MEM, 0, &isc->gtt_bst, &isc->gtt_bsh, 301 NULL, NULL); 302 if (error != 0) { 303 aprint_error(": can't map gttadr registers\n"); 304 /* XXX we should release mmadr here */ 305 agp_generic_detach(sc); 306 return error; 307 } 308 } else if (isc->chiptype == CHIP_I965) { 309 error = pci_mapreg_map(&isc->vga_pa, AGP_I965_MMADR, 310 PCI_MAPREG_TYPE_MEM, 0, &isc->bst, &isc->bsh, 311 &mmadr, &mmadrsize); 312 if (error != 0) { 313 aprint_error(": can't map mmadr registers\n"); 314 agp_generic_detach(sc); 315 return error; 316 } 317 } else { 318 error = pci_mapreg_map(&isc->vga_pa, AGP_I810_MMADR, 319 PCI_MAPREG_TYPE_MEM, 0, &isc->bst, &isc->bsh, 320 &mmadr, &mmadrsize); 321 if (error != 0) { 322 aprint_error(": can't map mmadr registers\n"); 323 agp_generic_detach(sc); 324 return error; 325 } 326 } 327 328 isc->initial_aperture = AGP_GET_APERTURE(sc); 329 330 gatt = malloc(sizeof(struct agp_gatt), M_AGP, M_NOWAIT); 331 if (!gatt) { 332 agp_generic_detach(sc); 333 return ENOMEM; 334 } 335 isc->gatt = gatt; 336 337 gatt->ag_entries = AGP_GET_APERTURE(sc) >> AGP_PAGE_SHIFT; 338 339 if (!pmf_device_register(self, NULL, agp_i810_resume)) 340 aprint_error_dev(self, "couldn't establish power handler\n"); 341 342 /* 343 * XXX horrible hack to allow drm code to use our mapping 344 * of VGA chip registers 345 */ 346 agp_i810_vga_regbase = mmadr; 347 agp_i810_vga_bsh = isc->bsh; 348 349 return agp_i810_init(sc); 350 } 351 352 /* 353 * XXX horrible hack to allow drm code to use our mapping 354 * of VGA chip registers 355 */ 356 int 357 agp_i810_borrow(bus_addr_t base, bus_space_handle_t *hdlp) 358 { 359 360 if (!agp_i810_vga_regbase || base != agp_i810_vga_regbase) 361 return 0; 362 *hdlp = agp_i810_vga_bsh; 363 return 1; 364 } 365 366 static int agp_i810_init(struct agp_softc *sc) 367 { 368 struct agp_i810_softc *isc; 369 struct agp_gatt *gatt; 370 371 isc = sc->as_chipc; 372 gatt = isc->gatt; 373 374 if (isc->chiptype == CHIP_I810) { 375 void *virtual; 376 int dummyseg; 377 378 /* Some i810s have on-chip memory called dcache */ 379 if (READ1(AGP_I810_DRT) & AGP_I810_DRT_POPULATED) 380 isc->dcache_size = 4 * 1024 * 1024; 381 else 382 isc->dcache_size = 0; 383 384 /* According to the specs the gatt on the i810 must be 64k */ 385 if (agp_alloc_dmamem(sc->as_dmat, 64 * 1024, 386 0, &gatt->ag_dmamap, &virtual, &gatt->ag_physical, 387 &gatt->ag_dmaseg, 1, &dummyseg) != 0) { 388 free(gatt, M_AGP); 389 agp_generic_detach(sc); 390 return ENOMEM; 391 } 392 gatt->ag_virtual = (uint32_t *)virtual; 393 gatt->ag_size = gatt->ag_entries * sizeof(u_int32_t); 394 memset(gatt->ag_virtual, 0, gatt->ag_size); 395 396 agp_flush_cache(); 397 /* Install the GATT. */ 398 WRITE4(AGP_I810_PGTBL_CTL, gatt->ag_physical | 1); 399 } else if (isc->chiptype == CHIP_I830) { 400 /* The i830 automatically initializes the 128k gatt on boot. */ 401 pcireg_t reg; 402 u_int32_t pgtblctl; 403 u_int16_t gcc1; 404 405 reg = pci_conf_read(sc->as_pc, sc->as_tag, AGP_I830_GCC0); 406 gcc1 = (u_int16_t)(reg >> 16); 407 switch (gcc1 & AGP_I830_GCC1_GMS) { 408 case AGP_I830_GCC1_GMS_STOLEN_512: 409 isc->stolen = (512 - 132) * 1024 / 4096; 410 break; 411 case AGP_I830_GCC1_GMS_STOLEN_1024: 412 isc->stolen = (1024 - 132) * 1024 / 4096; 413 break; 414 case AGP_I830_GCC1_GMS_STOLEN_8192: 415 isc->stolen = (8192 - 132) * 1024 / 4096; 416 break; 417 default: 418 isc->stolen = 0; 419 aprint_error( 420 ": unknown memory configuration, disabling\n"); 421 agp_generic_detach(sc); 422 return EINVAL; 423 } 424 425 if (isc->stolen > 0) { 426 aprint_normal(": detected %dk stolen memory\n%s", 427 isc->stolen * 4, device_xname(sc->as_dev)); 428 } 429 430 /* GATT address is already in there, make sure it's enabled */ 431 pgtblctl = READ4(AGP_I810_PGTBL_CTL); 432 pgtblctl |= 1; 433 WRITE4(AGP_I810_PGTBL_CTL, pgtblctl); 434 435 gatt->ag_physical = pgtblctl & ~1; 436 } else if (isc->chiptype == CHIP_I855 || isc->chiptype == CHIP_I915 || 437 isc->chiptype == CHIP_I965 || isc->chiptype == CHIP_G33) { 438 pcireg_t reg; 439 u_int32_t pgtblctl, stolen; 440 u_int16_t gcc1; 441 442 reg = pci_conf_read(sc->as_pc, sc->as_tag, AGP_I855_GCC1); 443 gcc1 = (u_int16_t)(reg >> 16); 444 445 /* Stolen memory is set up at the beginning of the aperture by 446 * the BIOS, consisting of the GATT followed by 4kb for the 447 * BIOS display. 448 */ 449 switch (isc->chiptype) { 450 case CHIP_I855: 451 stolen = 128 + 4; 452 break; 453 case CHIP_I915: 454 stolen = 256 + 4; 455 break; 456 case CHIP_I965: 457 stolen = 512 + 4; 458 break; 459 case CHIP_G33: 460 switch (gcc1 & AGP_G33_PGTBL_SIZE_MASK) { 461 case AGP_G33_PGTBL_SIZE_1M: 462 stolen = 1024 + 4; 463 break; 464 case AGP_G33_PGTBL_SIZE_2M: 465 stolen = 2048 + 4; 466 break; 467 default: 468 aprint_error(": bad gtt size\n"); 469 agp_generic_detach(sc); 470 return EINVAL; 471 } 472 break; 473 default: 474 aprint_error(": bad chiptype\n"); 475 agp_generic_detach(sc); 476 return EINVAL; 477 } 478 479 switch (gcc1 & AGP_I855_GCC1_GMS) { 480 case AGP_I855_GCC1_GMS_STOLEN_1M: 481 isc->stolen = (1024 - stolen) * 1024 / 4096; 482 break; 483 case AGP_I855_GCC1_GMS_STOLEN_4M: 484 isc->stolen = (4096 - stolen) * 1024 / 4096; 485 break; 486 case AGP_I855_GCC1_GMS_STOLEN_8M: 487 isc->stolen = (8192 - stolen) * 1024 / 4096; 488 break; 489 case AGP_I855_GCC1_GMS_STOLEN_16M: 490 isc->stolen = (16384 - stolen) * 1024 / 4096; 491 break; 492 case AGP_I855_GCC1_GMS_STOLEN_32M: 493 isc->stolen = (32768 - stolen) * 1024 / 4096; 494 break; 495 case AGP_I915_GCC1_GMS_STOLEN_48M: 496 isc->stolen = (49152 - stolen) * 1024 / 4096; 497 break; 498 case AGP_I915_GCC1_GMS_STOLEN_64M: 499 isc->stolen = (65536 - stolen) * 1024 / 4096; 500 break; 501 case AGP_G33_GCC1_GMS_STOLEN_128M: 502 isc->stolen = ((128 * 1024) - stolen) * 1024 / 4096; 503 break; 504 case AGP_G33_GCC1_GMS_STOLEN_256M: 505 isc->stolen = ((256 * 1024) - stolen) * 1024 / 4096; 506 break; 507 default: 508 isc->stolen = 0; 509 aprint_error( 510 ": unknown memory configuration, disabling\n"); 511 agp_generic_detach(sc); 512 return EINVAL; 513 } 514 if (isc->stolen > 0) { 515 aprint_normal(": detected %dk stolen memory\n%s", 516 isc->stolen * 4, device_xname(sc->as_dev)); 517 } 518 519 /* GATT address is already in there, make sure it's enabled */ 520 pgtblctl = READ4(AGP_I810_PGTBL_CTL); 521 pgtblctl |= 1; 522 WRITE4(AGP_I810_PGTBL_CTL, pgtblctl); 523 524 gatt->ag_physical = pgtblctl & ~1; 525 } 526 527 /* 528 * Make sure the chipset can see everything. 529 */ 530 agp_flush_cache(); 531 532 return 0; 533 } 534 535 #if 0 536 static int 537 agp_i810_detach(struct agp_softc *sc) 538 { 539 int error; 540 struct agp_i810_softc *isc = sc->as_chipc; 541 542 error = agp_generic_detach(sc); 543 if (error) 544 return error; 545 546 /* Clear the GATT base. */ 547 if (sc->chiptype == CHIP_I810) { 548 WRITE4(AGP_I810_PGTBL_CTL, 0); 549 } else { 550 unsigned int pgtblctl; 551 pgtblctl = READ4(AGP_I810_PGTBL_CTL); 552 pgtblctl &= ~1; 553 WRITE4(AGP_I810_PGTBL_CTL, pgtblctl); 554 } 555 556 /* Put the aperture back the way it started. */ 557 AGP_SET_APERTURE(sc, isc->initial_aperture); 558 559 if (sc->chiptype == CHIP_I810) { 560 agp_free_dmamem(sc->as_dmat, gatt->ag_size, gatt->ag_dmamap, 561 (void *)gatt->ag_virtual, &gatt->ag_dmaseg, 1); 562 } 563 free(sc->gatt, M_AGP); 564 565 return 0; 566 } 567 #endif 568 569 static u_int32_t 570 agp_i810_get_aperture(struct agp_softc *sc) 571 { 572 struct agp_i810_softc *isc = sc->as_chipc; 573 pcireg_t reg; 574 u_int16_t miscc, gcc1, msac; 575 576 switch (isc->chiptype) { 577 case CHIP_I810: 578 reg = pci_conf_read(sc->as_pc, sc->as_tag, AGP_I810_SMRAM); 579 miscc = (u_int16_t)(reg >> 16); 580 if ((miscc & AGP_I810_MISCC_WINSIZE) == 581 AGP_I810_MISCC_WINSIZE_32) 582 return 32 * 1024 * 1024; 583 else 584 return 64 * 1024 * 1024; 585 case CHIP_I830: 586 reg = pci_conf_read(sc->as_pc, sc->as_tag, AGP_I830_GCC0); 587 gcc1 = (u_int16_t)(reg >> 16); 588 if ((gcc1 & AGP_I830_GCC1_GMASIZE) == AGP_I830_GCC1_GMASIZE_64) 589 return 64 * 1024 * 1024; 590 else 591 return 128 * 1024 * 1024; 592 case CHIP_I855: 593 return 128 * 1024 * 1024; 594 case CHIP_I915: 595 case CHIP_G33: 596 reg = pci_conf_read(sc->as_pc, sc->as_tag, AGP_I915_MSAC); 597 msac = (u_int16_t)(reg >> 16); 598 if (msac & AGP_I915_MSAC_APER_128M) 599 return 128 * 1024 * 1024; 600 else 601 return 256 * 1024 * 1024; 602 case CHIP_I965: 603 return 512 * 1024 * 1024; 604 default: 605 aprint_error(": Unknown chipset\n"); 606 } 607 608 return 0; 609 } 610 611 static int 612 agp_i810_set_aperture(struct agp_softc *sc, u_int32_t aperture) 613 { 614 struct agp_i810_softc *isc = sc->as_chipc; 615 pcireg_t reg; 616 u_int16_t miscc, gcc1; 617 618 switch (isc->chiptype) { 619 case CHIP_I810: 620 /* 621 * Double check for sanity. 622 */ 623 if (aperture != (32 * 1024 * 1024) && 624 aperture != (64 * 1024 * 1024)) { 625 aprint_error_dev(sc->as_dev, "bad aperture size %d\n", 626 aperture); 627 return EINVAL; 628 } 629 630 reg = pci_conf_read(sc->as_pc, sc->as_tag, AGP_I810_SMRAM); 631 miscc = (u_int16_t)(reg >> 16); 632 miscc &= ~AGP_I810_MISCC_WINSIZE; 633 if (aperture == 32 * 1024 * 1024) 634 miscc |= AGP_I810_MISCC_WINSIZE_32; 635 else 636 miscc |= AGP_I810_MISCC_WINSIZE_64; 637 638 reg &= 0x0000ffff; 639 reg |= ((pcireg_t)miscc) << 16; 640 pci_conf_write(sc->as_pc, sc->as_tag, AGP_I810_SMRAM, reg); 641 break; 642 case CHIP_I830: 643 if (aperture != (64 * 1024 * 1024) && 644 aperture != (128 * 1024 * 1024)) { 645 aprint_error_dev(sc->as_dev, "bad aperture size %d\n", 646 aperture); 647 return EINVAL; 648 } 649 reg = pci_conf_read(sc->as_pc, sc->as_tag, AGP_I830_GCC0); 650 gcc1 = (u_int16_t)(reg >> 16); 651 gcc1 &= ~AGP_I830_GCC1_GMASIZE; 652 if (aperture == 64 * 1024 * 1024) 653 gcc1 |= AGP_I830_GCC1_GMASIZE_64; 654 else 655 gcc1 |= AGP_I830_GCC1_GMASIZE_128; 656 657 reg &= 0x0000ffff; 658 reg |= ((pcireg_t)gcc1) << 16; 659 pci_conf_write(sc->as_pc, sc->as_tag, AGP_I830_GCC0, reg); 660 break; 661 case CHIP_I855: 662 case CHIP_I915: 663 if (aperture != agp_i810_get_aperture(sc)) { 664 aprint_error_dev(sc->as_dev, "bad aperture size %d\n", 665 aperture); 666 return EINVAL; 667 } 668 break; 669 case CHIP_I965: 670 if (aperture != 512 * 1024 * 1024) { 671 aprint_error_dev(sc->as_dev, "bad aperture size %d\n", 672 aperture); 673 return EINVAL; 674 } 675 break; 676 } 677 678 return 0; 679 } 680 681 static int 682 agp_i810_bind_page(struct agp_softc *sc, off_t offset, bus_addr_t physical) 683 { 684 struct agp_i810_softc *isc = sc->as_chipc; 685 686 if (offset < 0 || offset >= (isc->gatt->ag_entries << AGP_PAGE_SHIFT)) { 687 #ifdef AGP_DEBUG 688 printf("%s: failed: offset 0x%08x, shift %d, entries %d\n", 689 device_xname(sc->as_dev), (int)offset, AGP_PAGE_SHIFT, 690 isc->gatt->ag_entries); 691 #endif 692 return EINVAL; 693 } 694 695 if (isc->chiptype != CHIP_I830) { 696 if ((offset >> AGP_PAGE_SHIFT) < isc->stolen) { 697 #ifdef AGP_DEBUG 698 printf("%s: trying to bind into stolen memory", 699 device_xname(sc->as_dev)); 700 #endif 701 return EINVAL; 702 } 703 } 704 705 WRITEGTT(offset, physical | 1); 706 return 0; 707 } 708 709 static int 710 agp_i810_unbind_page(struct agp_softc *sc, off_t offset) 711 { 712 struct agp_i810_softc *isc = sc->as_chipc; 713 714 if (offset < 0 || offset >= (isc->gatt->ag_entries << AGP_PAGE_SHIFT)) 715 return EINVAL; 716 717 if (isc->chiptype != CHIP_I810 ) { 718 if ((offset >> AGP_PAGE_SHIFT) < isc->stolen) { 719 #ifdef AGP_DEBUG 720 printf("%s: trying to unbind from stolen memory", 721 device_xname(sc->as_dev)); 722 #endif 723 return EINVAL; 724 } 725 } 726 727 WRITEGTT(offset, 0); 728 return 0; 729 } 730 731 /* 732 * Writing via memory mapped registers already flushes all TLBs. 733 */ 734 static void 735 agp_i810_flush_tlb(struct agp_softc *sc) 736 { 737 } 738 739 static int 740 agp_i810_enable(struct agp_softc *sc, u_int32_t mode) 741 { 742 743 return 0; 744 } 745 746 static struct agp_memory * 747 agp_i810_alloc_memory(struct agp_softc *sc, int type, vsize_t size) 748 { 749 struct agp_i810_softc *isc = sc->as_chipc; 750 struct agp_memory *mem; 751 752 #ifdef AGP_DEBUG 753 printf("AGP: alloc(%d, 0x%x)\n", type, (int) size); 754 #endif 755 756 if ((size & (AGP_PAGE_SIZE - 1)) != 0) 757 return 0; 758 759 if (sc->as_allocated + size > sc->as_maxmem) 760 return 0; 761 762 if (type == 1) { 763 /* 764 * Mapping local DRAM into GATT. 765 */ 766 if (isc->chiptype != CHIP_I810 ) 767 return 0; 768 if (size != isc->dcache_size) 769 return 0; 770 } else if (type == 2) { 771 /* 772 * Bogus mapping for the hardware cursor. 773 */ 774 if (size != AGP_PAGE_SIZE && size != 4 * AGP_PAGE_SIZE) 775 return 0; 776 } 777 778 mem = malloc(sizeof *mem, M_AGP, M_WAITOK|M_ZERO); 779 if (mem == NULL) 780 return NULL; 781 mem->am_id = sc->as_nextid++; 782 mem->am_size = size; 783 mem->am_type = type; 784 785 if (type == 2) { 786 /* 787 * Allocate and wire down the memory now so that we can 788 * get its physical address. 789 */ 790 mem->am_dmaseg = malloc(sizeof *mem->am_dmaseg, M_AGP, 791 M_WAITOK); 792 if (mem->am_dmaseg == NULL) { 793 free(mem, M_AGP); 794 return NULL; 795 } 796 if (agp_alloc_dmamem(sc->as_dmat, size, 0, 797 &mem->am_dmamap, &mem->am_virtual, &mem->am_physical, 798 mem->am_dmaseg, 1, &mem->am_nseg) != 0) { 799 free(mem->am_dmaseg, M_AGP); 800 free(mem, M_AGP); 801 return NULL; 802 } 803 memset(mem->am_virtual, 0, size); 804 } else if (type != 1) { 805 if (bus_dmamap_create(sc->as_dmat, size, size / PAGE_SIZE + 1, 806 size, 0, BUS_DMA_NOWAIT, 807 &mem->am_dmamap) != 0) { 808 free(mem, M_AGP); 809 return NULL; 810 } 811 } 812 813 TAILQ_INSERT_TAIL(&sc->as_memory, mem, am_link); 814 sc->as_allocated += size; 815 816 return mem; 817 } 818 819 static int 820 agp_i810_free_memory(struct agp_softc *sc, struct agp_memory *mem) 821 { 822 if (mem->am_is_bound) 823 return EBUSY; 824 825 if (mem->am_type == 2) { 826 agp_free_dmamem(sc->as_dmat, mem->am_size, mem->am_dmamap, 827 mem->am_virtual, mem->am_dmaseg, mem->am_nseg); 828 free(mem->am_dmaseg, M_AGP); 829 } 830 831 sc->as_allocated -= mem->am_size; 832 TAILQ_REMOVE(&sc->as_memory, mem, am_link); 833 free(mem, M_AGP); 834 return 0; 835 } 836 837 static int 838 agp_i810_bind_memory(struct agp_softc *sc, struct agp_memory *mem, 839 off_t offset) 840 { 841 struct agp_i810_softc *isc = sc->as_chipc; 842 u_int32_t regval, i; 843 844 /* 845 * XXX evil hack: the PGTBL_CTL appearently gets overwritten by the 846 * X server for mysterious reasons which leads to crashes if we write 847 * to the GTT through the MMIO window. 848 * Until the issue is solved, simply restore it. 849 */ 850 regval = bus_space_read_4(isc->bst, isc->bsh, AGP_I810_PGTBL_CTL); 851 if (regval != (isc->gatt->ag_physical | 1)) { 852 printf("agp_i810_bind_memory: PGTBL_CTL is 0x%x - fixing\n", 853 regval); 854 bus_space_write_4(isc->bst, isc->bsh, AGP_I810_PGTBL_CTL, 855 isc->gatt->ag_physical | 1); 856 } 857 858 if (mem->am_type == 2) { 859 WRITEGTT(offset, mem->am_physical | 1); 860 mem->am_offset = offset; 861 mem->am_is_bound = 1; 862 return 0; 863 } 864 865 if (mem->am_type != 1) 866 return agp_generic_bind_memory(sc, mem, offset); 867 868 if (isc->chiptype != CHIP_I810) 869 return EINVAL; 870 871 for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE) 872 WRITEGTT(offset, i | 3); 873 mem->am_is_bound = 1; 874 return 0; 875 } 876 877 static int 878 agp_i810_unbind_memory(struct agp_softc *sc, struct agp_memory *mem) 879 { 880 struct agp_i810_softc *isc = sc->as_chipc; 881 u_int32_t i; 882 883 if (mem->am_type == 2) { 884 WRITEGTT(mem->am_offset, 0); 885 mem->am_offset = 0; 886 mem->am_is_bound = 0; 887 return 0; 888 } 889 890 if (mem->am_type != 1) 891 return agp_generic_unbind_memory(sc, mem); 892 893 if (isc->chiptype != CHIP_I810) 894 return EINVAL; 895 896 for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE) 897 WRITEGTT(i, 0); 898 mem->am_is_bound = 0; 899 return 0; 900 } 901 902 static bool 903 agp_i810_resume(device_t dv PMF_FN_ARGS) 904 { 905 struct agp_softc *sc = device_private(dv); 906 struct agp_i810_softc *isc = sc->as_chipc; 907 908 isc->pgtblctl = READ4(AGP_I810_PGTBL_CTL); 909 agp_flush_cache(); 910 911 return true; 912 } 913