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