1 /* $NetBSD: pchb.c,v 1.32 2011/08/20 20:01:08 jakllsch Exp $ */ 2 3 /*- 4 * Copyright (c) 1996, 1998, 2000 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Jason R. Thorpe. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 #include <sys/cdefs.h> 33 __KERNEL_RCSID(0, "$NetBSD: pchb.c,v 1.32 2011/08/20 20:01:08 jakllsch Exp $"); 34 35 #include <sys/types.h> 36 #include <sys/param.h> 37 #include <sys/systm.h> 38 #include <sys/device.h> 39 40 #include <sys/bus.h> 41 42 #include <dev/pci/pcivar.h> 43 #include <dev/pci/pcireg.h> 44 45 #include <dev/pci/pcidevs.h> 46 47 #include <dev/pci/agpreg.h> 48 #include <dev/pci/agpvar.h> 49 50 #include <arch/x86/pci/pchbvar.h> 51 52 #define PCISET_BRIDGETYPE_MASK 0x3 53 #define PCISET_TYPE_COMPAT 0x1 54 #define PCISET_TYPE_AUX 0x2 55 56 #define PCISET_BUSCONFIG_REG 0x48 57 #define PCISET_BRIDGE_NUMBER(reg) (((reg) >> 8) & 0xff) 58 #define PCISET_PCI_BUS_NUMBER(reg) (((reg) >> 16) & 0xff) 59 60 /* XXX should be in dev/ic/i82443reg.h */ 61 #define I82443BX_SDRAMC_REG 0x74 /* upper 16 bits */ 62 63 /* XXX should be in dev/ic/i82424{reg.var}.h */ 64 #define I82424_CPU_BCTL_REG 0x53 65 #define I82424_PCI_BCTL_REG 0x54 66 67 #define I82424_BCTL_CPUMEM_POSTEN 0x01 68 #define I82424_BCTL_CPUPCI_POSTEN 0x02 69 #define I82424_BCTL_PCIMEM_BURSTEN 0x01 70 #define I82424_BCTL_PCI_BURSTEN 0x02 71 72 static int pchbmatch(device_t, cfdata_t, void *); 73 static void pchbattach(device_t, device_t, void *); 74 static int pchbdetach(device_t, int); 75 static int pchbrescan(device_t, const char *, const int *); 76 static void pchbchilddet(device_t, device_t); 77 78 static bool pchb_resume(device_t, const pmf_qual_t *); 79 static bool pchb_suspend(device_t, const pmf_qual_t *); 80 81 static void pchb_amdtempbus_configure(struct pchb_softc *); 82 83 CFATTACH_DECL3_NEW(pchb, sizeof(struct pchb_softc), 84 pchbmatch, pchbattach, pchbdetach, NULL, pchbrescan, pchbchilddet, DVF_DETACH_SHUTDOWN); 85 86 static int 87 pchbmatch(device_t parent, cfdata_t match, void *aux) 88 { 89 struct pci_attach_args *pa = aux; 90 91 if (PCI_CLASS(pa->pa_class) == PCI_CLASS_BRIDGE && 92 PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_BRIDGE_HOST) 93 return 1; 94 95 return 0; 96 } 97 98 int 99 pchb_get_bus_number(pci_chipset_tag_t pc, pcitag_t tag) 100 { 101 pcireg_t dev_id; 102 int bus, dev, func; 103 int bcreg, pbnum; 104 105 pci_decompose_tag(pc, tag, &bus, &dev, &func); 106 107 dev_id = pci_conf_read(pc, tag, PCI_ID_REG); 108 switch (PCI_VENDOR(dev_id)) { 109 case PCI_VENDOR_SERVERWORKS: 110 return pci_conf_read(pc, tag, 0x44) & 0xff; 111 case PCI_VENDOR_INTEL: 112 switch (PCI_PRODUCT(dev_id)) { 113 case PCI_PRODUCT_INTEL_82452_PB: 114 bcreg = pci_conf_read(pc, tag, 0x40); 115 pbnum = PCISET_BRIDGE_NUMBER(bcreg); 116 if (pbnum != 0xff) 117 return pbnum + 1; 118 119 break; 120 case PCI_PRODUCT_INTEL_PCI450_PB: 121 bcreg = pci_conf_read(pc, tag, PCISET_BUSCONFIG_REG); 122 return PCISET_PCI_BUS_NUMBER(bcreg); 123 case PCI_PRODUCT_INTEL_82451NX_PXB: 124 pbnum = 0; 125 switch (dev) { 126 case 18: /* PXB 0 bus A - primary bus */ 127 break; 128 case 19: /* PXB 0 bus B */ 129 /* read SUBA0 from MIOC */ 130 tag = pci_make_tag(pc, 0, 16, 0); 131 bcreg = pci_conf_read(pc, tag, 0xd0); 132 pbnum = ((bcreg & 0x0000ff00) >> 8) + 1; 133 break; 134 case 20: /* PXB 1 bus A */ 135 /* read BUSNO1 from MIOC */ 136 tag = pci_make_tag(pc, 0, 16, 0); 137 bcreg = pci_conf_read(pc, tag, 0xd0); 138 pbnum = (bcreg & 0xff000000) >> 24; 139 break; 140 case 21: /* PXB 1 bus B */ 141 /* read SUBA1 from MIOC */ 142 tag = pci_make_tag(pc, 0, 16, 0); 143 bcreg = pci_conf_read(pc, tag, 0xd4); 144 pbnum = (bcreg & 0x000000ff) + 1; 145 break; 146 } 147 return pbnum; 148 } 149 } 150 return -1; 151 } 152 153 static void 154 pchbattach(device_t parent, device_t self, void *aux) 155 { 156 struct pchb_softc *sc = device_private(self); 157 const struct pci_attach_args *pa = aux; 158 char devinfo[256]; 159 struct pcibus_attach_args pba; 160 struct agpbus_attach_args apa; 161 pcireg_t bcreg; 162 u_char bdnum, pbnum = 0; /* XXX: gcc */ 163 pcitag_t tag; 164 int doattach, attachflags, has_agp; 165 166 aprint_naive("\n"); 167 168 doattach = 0; 169 has_agp = 0; 170 attachflags = pa->pa_flags; 171 172 sc->sc_dev = self; 173 sc->sc_pa = *pa; 174 175 /* 176 * Print out a description, and configure certain chipsets which 177 * have auxiliary PCI buses. 178 */ 179 180 pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo, sizeof(devinfo)); 181 aprint_normal(": %s (rev. 0x%02x)\n", devinfo, 182 PCI_REVISION(pa->pa_class)); 183 184 switch (PCI_VENDOR(pa->pa_id)) { 185 /* 186 * i386 stuff. 187 */ 188 case PCI_VENDOR_SERVERWORKS: 189 pbnum = pci_conf_read(pa->pa_pc, pa->pa_tag, 0x44) & 0xff; 190 191 if (pbnum == 0) 192 break; 193 194 /* 195 * This host bridge has a second PCI bus. 196 * Configure it. 197 */ 198 switch (PCI_PRODUCT(pa->pa_id)) { 199 case PCI_PRODUCT_SERVERWORKS_CSB5: 200 case PCI_PRODUCT_SERVERWORKS_CSB6: 201 /* These devices show up as host bridges, but are 202 really southbridges. */ 203 break; 204 case PCI_PRODUCT_SERVERWORKS_CMIC_HE: 205 case PCI_PRODUCT_SERVERWORKS_CMIC_LE: 206 case PCI_PRODUCT_SERVERWORKS_CMIC_SL: 207 /* CNBs and CIOBs are connected to these using a 208 private bus. The bus number register is that of 209 the first PCI bus hanging off the CIOB. We let 210 the CIOB attachment handle configuring the PCI 211 buses. */ 212 break; 213 default: 214 aprint_error_dev(self, 215 "unknown ServerWorks chip ID 0x%04x; trying " 216 "to attach PCI buses behind it\n", 217 PCI_PRODUCT(pa->pa_id)); 218 /* FALLTHROUGH */ 219 case PCI_PRODUCT_SERVERWORKS_CNB20_LE_AGP: 220 case PCI_PRODUCT_SERVERWORKS_CNB30_LE_PCI: 221 case PCI_PRODUCT_SERVERWORKS_CNB20_LE_PCI: 222 case PCI_PRODUCT_SERVERWORKS_CNB20_HE_PCI: 223 case PCI_PRODUCT_SERVERWORKS_CNB20_HE_AGP: 224 case PCI_PRODUCT_SERVERWORKS_CIOB_X: 225 case PCI_PRODUCT_SERVERWORKS_CNB30_HE: 226 case PCI_PRODUCT_SERVERWORKS_CNB20_HE_PCI2: 227 case PCI_PRODUCT_SERVERWORKS_CIOB_X2: 228 case PCI_PRODUCT_SERVERWORKS_CIOB_E: 229 switch (attachflags & 230 (PCI_FLAGS_IO_OKAY | PCI_FLAGS_MEM_OKAY)) { 231 case 0: 232 /* Doesn't smell like there's anything there. */ 233 break; 234 case PCI_FLAGS_MEM_OKAY: 235 attachflags |= PCI_FLAGS_IO_OKAY; 236 /* FALLTHROUGH */ 237 default: 238 doattach = 1; 239 break; 240 } 241 break; 242 } 243 break; 244 case PCI_VENDOR_INTEL: 245 switch (PCI_PRODUCT(pa->pa_id)) { 246 case PCI_PRODUCT_INTEL_82452_PB: 247 bcreg = pci_conf_read(pa->pa_pc, pa->pa_tag, 0x40); 248 pbnum = PCISET_BRIDGE_NUMBER(bcreg); 249 if (pbnum != 0xff) { 250 pbnum++; 251 doattach = 1; 252 } 253 break; 254 case PCI_PRODUCT_INTEL_82443BX_AGP: 255 case PCI_PRODUCT_INTEL_82443BX_NOAGP: 256 /* 257 * http://www.intel.com/design/chipsets/specupdt/290639.htm 258 * says this bug is fixed in steppings >= C0 (erratum 11), 259 * so don't tweak the bits in that case. 260 */ 261 if (!(PCI_REVISION(pa->pa_class) >= 0x03)) { 262 /* 263 * BIOS BUG WORKAROUND! The 82443BX 264 * datasheet indicates that the only 265 * legal setting for the "Idle/Pipeline 266 * DRAM Leadoff Timing (IPLDT)" parameter 267 * (bits 9:8) is 01. Unfortunately, some 268 * BIOSs do not set these bits properly. 269 */ 270 bcreg = pci_conf_read(pa->pa_pc, pa->pa_tag, 271 I82443BX_SDRAMC_REG); 272 if ((bcreg & 0x03000000) != 0x01000000) { 273 aprint_verbose_dev(self, "fixing " 274 "Idle/Pipeline DRAM " 275 "Leadoff Timing\n"); 276 bcreg &= ~0x03000000; 277 bcreg |= 0x01000000; 278 pci_conf_write(pa->pa_pc, pa->pa_tag, 279 I82443BX_SDRAMC_REG, bcreg); 280 } 281 } 282 break; 283 284 case PCI_PRODUCT_INTEL_PCI450_PB: 285 bcreg = pci_conf_read(pa->pa_pc, pa->pa_tag, 286 PCISET_BUSCONFIG_REG); 287 bdnum = PCISET_BRIDGE_NUMBER(bcreg); 288 pbnum = PCISET_PCI_BUS_NUMBER(bcreg); 289 switch (bdnum & PCISET_BRIDGETYPE_MASK) { 290 default: 291 aprint_error_dev(self, "bdnum=%x (reserved)\n", 292 bdnum); 293 break; 294 case PCISET_TYPE_COMPAT: 295 aprint_verbose_dev(self, 296 "Compatibility PB (bus %d)\n", pbnum); 297 break; 298 case PCISET_TYPE_AUX: 299 aprint_verbose_dev(self, 300 "Auxiliary PB (bus %d)\n",pbnum); 301 /* 302 * This host bridge has a second PCI bus. 303 * Configure it. 304 */ 305 doattach = 1; 306 break; 307 } 308 break; 309 case PCI_PRODUCT_INTEL_CDC: 310 bcreg = pci_conf_read(pa->pa_pc, pa->pa_tag, 311 I82424_CPU_BCTL_REG); 312 if (bcreg & I82424_BCTL_CPUPCI_POSTEN) { 313 bcreg &= ~I82424_BCTL_CPUPCI_POSTEN; 314 pci_conf_write(pa->pa_pc, pa->pa_tag, 315 I82424_CPU_BCTL_REG, bcreg); 316 aprint_verbose_dev(self, 317 "disabled CPU-PCI write posting\n"); 318 } 319 break; 320 case PCI_PRODUCT_INTEL_82451NX_PXB: 321 /* 322 * The NX chipset supports up to 2 "PXB" chips 323 * which can drive 2 PCI buses each. Each bus 324 * shows up as logical PCI device, with fixed 325 * device numbers between 18 and 21. 326 * See the datasheet at 327 ftp://download.intel.com/design/chipsets/datashts/24377102.pdf 328 * for details. 329 * (It would be easier to attach all the buses 330 * at the MIOC, but less aesthetical imho.) 331 */ 332 if ((attachflags & 333 (PCI_FLAGS_IO_OKAY | PCI_FLAGS_MEM_OKAY)) == 334 PCI_FLAGS_MEM_OKAY) 335 attachflags |= PCI_FLAGS_IO_OKAY; 336 337 pbnum = 0; 338 switch (pa->pa_device) { 339 case 18: /* PXB 0 bus A - primary bus */ 340 break; 341 case 19: /* PXB 0 bus B */ 342 /* read SUBA0 from MIOC */ 343 tag = pci_make_tag(pa->pa_pc, 0, 16, 0); 344 bcreg = pci_conf_read(pa->pa_pc, tag, 0xd0); 345 pbnum = ((bcreg & 0x0000ff00) >> 8) + 1; 346 break; 347 case 20: /* PXB 1 bus A */ 348 /* read BUSNO1 from MIOC */ 349 tag = pci_make_tag(pa->pa_pc, 0, 16, 0); 350 bcreg = pci_conf_read(pa->pa_pc, tag, 0xd0); 351 pbnum = (bcreg & 0xff000000) >> 24; 352 break; 353 case 21: /* PXB 1 bus B */ 354 /* read SUBA1 from MIOC */ 355 tag = pci_make_tag(pa->pa_pc, 0, 16, 0); 356 bcreg = pci_conf_read(pa->pa_pc, tag, 0xd4); 357 pbnum = (bcreg & 0x000000ff) + 1; 358 break; 359 } 360 if (pbnum != 0) 361 doattach = 1; 362 break; 363 364 /* 365 * i386 and amd64 stuff. 366 */ 367 case PCI_PRODUCT_INTEL_82810_MCH: 368 case PCI_PRODUCT_INTEL_82810_DC100_MCH: 369 case PCI_PRODUCT_INTEL_82810E_MCH: 370 case PCI_PRODUCT_INTEL_82815_FULL_HUB: 371 case PCI_PRODUCT_INTEL_82830MP_IO_1: 372 case PCI_PRODUCT_INTEL_82845G_DRAM: 373 case PCI_PRODUCT_INTEL_82855GM_MCH: 374 case PCI_PRODUCT_INTEL_82865_HB: 375 case PCI_PRODUCT_INTEL_82915G_HB: 376 case PCI_PRODUCT_INTEL_82915GM_HB: 377 case PCI_PRODUCT_INTEL_82945P_MCH: 378 case PCI_PRODUCT_INTEL_82945GM_HB: 379 case PCI_PRODUCT_INTEL_82945GME_HB: 380 case PCI_PRODUCT_INTEL_82946GZ_HB: 381 case PCI_PRODUCT_INTEL_82965Q_HB: 382 case PCI_PRODUCT_INTEL_82965G_HB: 383 case PCI_PRODUCT_INTEL_82965PM_HB: 384 case PCI_PRODUCT_INTEL_82Q35_HB: 385 case PCI_PRODUCT_INTEL_82G33_HB: 386 case PCI_PRODUCT_INTEL_82Q33_HB: 387 case PCI_PRODUCT_INTEL_82G35_HB: 388 case PCI_PRODUCT_INTEL_82GM45_HB: 389 case PCI_PRODUCT_INTEL_82IGD_E_HB: 390 case PCI_PRODUCT_INTEL_82Q45_HB: 391 case PCI_PRODUCT_INTEL_82G45_HB: 392 case PCI_PRODUCT_INTEL_82G41_HB: 393 case PCI_PRODUCT_INTEL_E7221_HB: 394 case PCI_PRODUCT_INTEL_82965GME_HB: 395 case PCI_PRODUCT_INTEL_82B43_HB: 396 case PCI_PRODUCT_INTEL_IRONLAKE_D_HB: 397 case PCI_PRODUCT_INTEL_IRONLAKE_M_HB: 398 case PCI_PRODUCT_INTEL_IRONLAKE_MA_HB: 399 case PCI_PRODUCT_INTEL_IRONLAKE_MC2_HB: 400 case PCI_PRODUCT_INTEL_PINEVIEW_HB: 401 case PCI_PRODUCT_INTEL_PINEVIEW_M_HB: 402 /* 403 * The host bridge is either in GFX mode (internal 404 * graphics) or in AGP mode. In GFX mode, we pretend 405 * to have AGP because the graphics memory access 406 * is very similar and the AGP GATT code will 407 * deal with this. In the latter case, the 408 * pci_get_capability(PCI_CAP_AGP) test below will 409 * fire, so we do no harm by already setting the flag. 410 */ 411 has_agp = 1; 412 break; 413 } 414 break; 415 } 416 417 if (!pmf_device_register(self, pchb_suspend, pchb_resume)) 418 aprint_error_dev(self, "couldn't establish power handler\n"); 419 420 /* 421 * If we haven't detected AGP yet (via a product ID), 422 * then check for AGP capability on the device. 423 */ 424 if (has_agp || 425 pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_AGP, 426 NULL, NULL) != 0) { 427 apa.apa_pci_args = *pa; 428 config_found_ia(self, "agpbus", &apa, agpbusprint); 429 } 430 431 if (doattach) { 432 pba.pba_iot = pa->pa_iot; 433 pba.pba_memt = pa->pa_memt; 434 pba.pba_dmat = pa->pa_dmat; 435 pba.pba_dmat64 = pa->pa_dmat64; 436 pba.pba_pc = pa->pa_pc; 437 pba.pba_flags = attachflags; 438 pba.pba_bus = pbnum; 439 pba.pba_bridgetag = NULL; 440 pba.pba_pc = pa->pa_pc; 441 pba.pba_intrswiz = 0; 442 memset(&pba.pba_intrtag, 0, sizeof(pba.pba_intrtag)); 443 config_found_ia(self, "pcibus", &pba, pcibusprint); 444 } 445 446 pchb_amdtempbus_configure(sc); 447 } 448 449 static int 450 pchbdetach(device_t self, int flags) 451 { 452 int rc; 453 454 if ((rc = config_detach_children(self, flags)) != 0) 455 return rc; 456 457 pmf_device_deregister(self); 458 459 return 0; 460 } 461 462 static int 463 pchbrescan(device_t self, const char *ifattr, const int *locators) 464 { 465 struct pchb_softc *sc = device_private(self); 466 467 if (ifattr_match(ifattr, "amdtempbus")) 468 pchb_amdtempbus_configure(sc); 469 470 return 0; 471 } 472 473 static void 474 pchbchilddet(device_t self, device_t child) 475 { 476 struct pchb_softc *sc = device_private(self); 477 478 if (sc->sc_amdtempbus == child) { 479 sc->sc_amdtempbus = NULL; 480 return; 481 } 482 } 483 484 static bool 485 pchb_suspend(device_t dv, const pmf_qual_t *qual) 486 { 487 struct pchb_softc *sc = device_private(dv); 488 pci_chipset_tag_t pc; 489 pcitag_t tag; 490 int off; 491 492 pc = sc->sc_pa.pa_pc; 493 tag = sc->sc_pa.pa_tag; 494 495 for (off = 0x40; off <= 0xff; off += 4) 496 sc->sc_pciconfext[(off - 0x40) / 4] = pci_conf_read(pc, tag, off); 497 498 return true; 499 } 500 501 static bool 502 pchb_resume(device_t dv, const pmf_qual_t *qual) 503 { 504 struct pchb_softc *sc = device_private(dv); 505 pci_chipset_tag_t pc; 506 pcitag_t tag; 507 int off; 508 509 pc = sc->sc_pa.pa_pc; 510 tag = sc->sc_pa.pa_tag; 511 512 for (off = 0x40; off <= 0xff; off += 4) 513 pci_conf_write(pc, tag, off, sc->sc_pciconfext[(off - 0x40) / 4]); 514 515 return true; 516 } 517 518 static void 519 pchb_amdtempbus_configure(struct pchb_softc *sc) 520 { 521 if (sc->sc_amdtempbus != NULL) 522 return; 523 524 sc->sc_amdtempbus = config_found_ia(sc->sc_dev, "amdtempbus", &sc->sc_pa, NULL); 525 } 526