1 /* $NetBSD: ppb.c,v 1.63 2017/05/10 03:24:31 msaitoh Exp $ */ 2 3 /* 4 * Copyright (c) 1996, 1998 Christopher G. Demetriou. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. All advertising materials mentioning features or use of this software 15 * must display the following acknowledgement: 16 * This product includes software developed by Christopher G. Demetriou 17 * for the NetBSD Project. 18 * 4. The name of the author may not be used to endorse or promote products 19 * derived from this software without specific prior written permission 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 #include <sys/cdefs.h> 34 __KERNEL_RCSID(0, "$NetBSD: ppb.c,v 1.63 2017/05/10 03:24:31 msaitoh Exp $"); 35 36 #include <sys/param.h> 37 #include <sys/systm.h> 38 #include <sys/kernel.h> 39 #include <sys/device.h> 40 #include <sys/evcnt.h> 41 42 #include <dev/pci/pcireg.h> 43 #include <dev/pci/pcivar.h> 44 #include <dev/pci/ppbreg.h> 45 #include <dev/pci/ppbvar.h> 46 #include <dev/pci/pcidevs.h> 47 48 #define PCIE_SLCSR_ENABLE_MASK \ 49 (PCIE_SLCSR_ABE | PCIE_SLCSR_PFE | PCIE_SLCSR_MSE | \ 50 PCIE_SLCSR_PDE | PCIE_SLCSR_CCE | PCIE_SLCSR_HPE | \ 51 PCIE_SLCSR_DLLSCE) 52 53 #define PCIE_SLCSR_STATCHG_MASK \ 54 (PCIE_SLCSR_ABP | PCIE_SLCSR_PFD | PCIE_SLCSR_MSC | \ 55 PCIE_SLCSR_PDC | PCIE_SLCSR_CC | PCIE_SLCSR_LACS) 56 57 static const char pcie_linkspeed_strings[4][5] = { 58 "1.25", "2.5", "5.0", "8.0", 59 }; 60 61 int ppb_printevent = 0; /* Print event type if the value is not 0 */ 62 63 static int ppbmatch(device_t, cfdata_t, void *); 64 static void ppbattach(device_t, device_t, void *); 65 static int ppbdetach(device_t, int); 66 static void ppbchilddet(device_t, device_t); 67 #ifdef PPB_USEINTR 68 static int ppb_intr(void *); 69 #endif 70 static bool ppb_resume(device_t, const pmf_qual_t *); 71 static bool ppb_suspend(device_t, const pmf_qual_t *); 72 73 CFATTACH_DECL3_NEW(ppb, sizeof(struct ppb_softc), 74 ppbmatch, ppbattach, ppbdetach, NULL, NULL, ppbchilddet, 75 DVF_DETACH_SHUTDOWN); 76 77 static int 78 ppbmatch(device_t parent, cfdata_t match, void *aux) 79 { 80 struct pci_attach_args *pa = aux; 81 82 /* 83 * Check the ID register to see that it's a PCI bridge. 84 * If it is, we assume that we can deal with it; it _should_ 85 * work in a standardized way... 86 */ 87 if (PCI_CLASS(pa->pa_class) == PCI_CLASS_BRIDGE && 88 PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_BRIDGE_PCI) 89 return 1; 90 91 #ifdef __powerpc__ 92 if (PCI_CLASS(pa->pa_class) == PCI_CLASS_PROCESSOR && 93 PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_PROCESSOR_POWERPC) { 94 pcireg_t bhlc = pci_conf_read(pa->pa_pc, pa->pa_tag, 95 PCI_BHLC_REG); 96 if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_FREESCALE 97 && PCI_HDRTYPE(bhlc) == PCI_HDRTYPE_RC) 98 return 1; 99 } 100 #endif 101 102 #ifdef _MIPS_PADDR_T_64BIT 103 /* The LDT HB acts just like a PPB. */ 104 if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_SIBYTE 105 && PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_SIBYTE_BCM1250_LDTHB) 106 return 1; 107 #endif 108 109 return 0; 110 } 111 112 static void 113 ppb_print_pcie(device_t self) 114 { 115 struct ppb_softc *sc = device_private(self); 116 pcireg_t reg; 117 int off, capversion, devtype; 118 119 if (!pci_get_capability(sc->sc_pc, sc->sc_tag, PCI_CAP_PCIEXPRESS, 120 &off, ®)) 121 return; /* Not a PCIe device */ 122 123 capversion = PCIE_XCAP_VER(reg); 124 devtype = PCIE_XCAP_TYPE(reg); 125 aprint_normal_dev(self, "PCI Express capability version "); 126 switch (capversion) { 127 case PCIE_XCAP_VER_1: 128 aprint_normal("1"); 129 break; 130 case PCIE_XCAP_VER_2: 131 aprint_normal("2"); 132 break; 133 default: 134 aprint_normal_dev(self, "unsupported (%d)\n", capversion); 135 return; 136 } 137 aprint_normal(" <"); 138 switch (devtype) { 139 case PCIE_XCAP_TYPE_PCIE_DEV: 140 aprint_normal("PCI-E Endpoint device"); 141 break; 142 case PCIE_XCAP_TYPE_PCI_DEV: 143 aprint_normal("Legacy PCI-E Endpoint device"); 144 break; 145 case PCIE_XCAP_TYPE_ROOT: 146 aprint_normal("Root Port of PCI-E Root Complex"); 147 break; 148 case PCIE_XCAP_TYPE_UP: 149 aprint_normal("Upstream Port of PCI-E Switch"); 150 break; 151 case PCIE_XCAP_TYPE_DOWN: 152 aprint_normal("Downstream Port of PCI-E Switch"); 153 break; 154 case PCIE_XCAP_TYPE_PCIE2PCI: 155 aprint_normal("PCI-E to PCI/PCI-X Bridge"); 156 break; 157 case PCIE_XCAP_TYPE_PCI2PCIE: 158 aprint_normal("PCI/PCI-X to PCI-E Bridge"); 159 break; 160 default: 161 aprint_normal("Device/Port Type %x", devtype); 162 break; 163 } 164 165 switch (devtype) { 166 case PCIE_XCAP_TYPE_ROOT: 167 case PCIE_XCAP_TYPE_DOWN: 168 case PCIE_XCAP_TYPE_PCI2PCIE: 169 reg = pci_conf_read(sc->sc_pc, sc->sc_tag, off + PCIE_LCAP); 170 u_int mlw = __SHIFTOUT(reg, PCIE_LCAP_MAX_WIDTH); 171 u_int mls = __SHIFTOUT(reg, PCIE_LCAP_MAX_SPEED); 172 173 if (mls < __arraycount(pcie_linkspeed_strings)) { 174 aprint_normal("> x%d @ %sGT/s\n", 175 mlw, pcie_linkspeed_strings[mls]); 176 } else { 177 aprint_normal("> x%d @ %d.%dGT/s\n", 178 mlw, (mls * 25) / 10, (mls * 25) % 10); 179 } 180 181 reg = pci_conf_read(sc->sc_pc, sc->sc_tag, off + PCIE_LCSR); 182 if (reg & PCIE_LCSR_DLACTIVE) { /* DLLA */ 183 u_int lw = __SHIFTOUT(reg, PCIE_LCSR_NLW); 184 u_int ls = __SHIFTOUT(reg, PCIE_LCSR_LINKSPEED); 185 186 if (lw != mlw || ls != mls) { 187 if (ls < __arraycount(pcie_linkspeed_strings)) { 188 aprint_normal_dev(self, 189 "link is x%d @ %sGT/s\n", 190 lw, pcie_linkspeed_strings[ls]); 191 } else { 192 aprint_normal_dev(self, 193 "link is x%d @ %d.%dGT/s\n", 194 lw, (ls * 25) / 10, (ls * 25) % 10); 195 } 196 } 197 } 198 break; 199 default: 200 aprint_normal(">\n"); 201 break; 202 } 203 } 204 205 static void 206 ppbattach(device_t parent, device_t self, void *aux) 207 { 208 struct ppb_softc *sc = device_private(self); 209 struct pci_attach_args *pa = aux; 210 pci_chipset_tag_t pc = pa->pa_pc; 211 struct pcibus_attach_args pba; 212 #ifdef PPB_USEINTR 213 char const *intrstr; 214 char intrbuf[PCI_INTRSTR_LEN]; 215 #endif 216 pcireg_t busdata, reg; 217 218 pci_aprint_devinfo(pa, NULL); 219 220 sc->sc_pc = pc; 221 sc->sc_tag = pa->pa_tag; 222 sc->sc_dev = self; 223 224 busdata = pci_conf_read(pc, pa->pa_tag, PPB_REG_BUSINFO); 225 226 if (PPB_BUSINFO_SECONDARY(busdata) == 0) { 227 aprint_normal_dev(self, "not configured by system firmware\n"); 228 return; 229 } 230 231 ppb_print_pcie(self); 232 233 #if 0 234 /* 235 * XXX can't do this, because we're not given our bus number 236 * (we shouldn't need it), and because we've no way to 237 * decompose our tag. 238 */ 239 /* sanity check. */ 240 if (pa->pa_bus != PPB_BUSINFO_PRIMARY(busdata)) 241 panic("ppbattach: bus in tag (%d) != bus in reg (%d)", 242 pa->pa_bus, PPB_BUSINFO_PRIMARY(busdata)); 243 #endif 244 245 /* Check for PCI Express capabilities and setup hotplug support. */ 246 if (pci_get_capability(pc, pa->pa_tag, PCI_CAP_PCIEXPRESS, 247 &sc->sc_pciecapoff, ®) && (reg & PCIE_XCAP_SI)) { 248 /* 249 * First, disable all interrupts because BIOS might 250 * enable them. 251 */ 252 reg = pci_conf_read(sc->sc_pc, sc->sc_tag, 253 sc->sc_pciecapoff + PCIE_SLCSR); 254 if (reg & PCIE_SLCSR_ENABLE_MASK) { 255 reg &= ~PCIE_SLCSR_ENABLE_MASK; 256 pci_conf_write(sc->sc_pc, sc->sc_tag, 257 sc->sc_pciecapoff + PCIE_SLCSR, reg); 258 } 259 #ifdef PPB_USEINTR 260 #if 0 /* notyet */ 261 /* 262 * XXX Initialize workqueue or something else for 263 * HotPlug support. 264 */ 265 #endif 266 if (pci_intr_alloc(pa, &sc->sc_pihp, NULL, 0) == 0) 267 sc->sc_intrhand = pci_intr_establish_xname(pc, 268 sc->sc_pihp[0], IPL_BIO, ppb_intr, sc, 269 device_xname(sc->sc_dev)); 270 #endif 271 } 272 273 #ifdef PPB_USEINTR 274 if (sc->sc_intrhand != NULL) { 275 pcireg_t slcap, slcsr, val; 276 277 intrstr = pci_intr_string(pc, sc->sc_pihp[0], intrbuf, 278 sizeof(intrbuf)); 279 aprint_normal_dev(self, "%s\n", intrstr); 280 281 /* Clear any pending events */ 282 slcsr = pci_conf_read(pc, pa->pa_tag, 283 sc->sc_pciecapoff + PCIE_SLCSR); 284 pci_conf_write(pc, pa->pa_tag, 285 sc->sc_pciecapoff + PCIE_SLCSR, slcsr); 286 287 /* Enable interrupt. */ 288 val = 0; 289 slcap = pci_conf_read(pc, pa->pa_tag, 290 sc->sc_pciecapoff + PCIE_SLCAP); 291 if (slcap & PCIE_SLCAP_ABP) 292 val |= PCIE_SLCSR_ABE; 293 if (slcap & PCIE_SLCAP_PCP) 294 val |= PCIE_SLCSR_PFE; 295 if (slcap & PCIE_SLCAP_MSP) 296 val |= PCIE_SLCSR_MSE; 297 #if 0 298 /* 299 * XXX Disable for a while because setting 300 * PCIE_SLCSR_CCE makes break device access on 301 * some environment. 302 */ 303 if ((slcap & PCIE_SLCAP_NCCS) == 0) 304 val |= PCIE_SLCSR_CCE; 305 #endif 306 /* Attention indicator off by default */ 307 if (slcap & PCIE_SLCAP_AIP) { 308 val |= __SHIFTIN(PCIE_SLCSR_IND_OFF, 309 PCIE_SLCSR_AIC); 310 } 311 /* Power indicator */ 312 if (slcap & PCIE_SLCAP_PIP) { 313 /* 314 * Indicator off: 315 * a) card not present 316 * b) power fault 317 * c) MRL sensor off 318 */ 319 if (((slcsr & PCIE_SLCSR_PDS) == 0) 320 || ((slcsr & PCIE_SLCSR_PFD) != 0) 321 || (((slcap & PCIE_SLCAP_MSP) != 0) 322 && ((slcsr & PCIE_SLCSR_MS) != 0))) 323 val |= __SHIFTIN(PCIE_SLCSR_IND_OFF, 324 PCIE_SLCSR_PIC); 325 else 326 val |= __SHIFTIN(PCIE_SLCSR_IND_ON, 327 PCIE_SLCSR_PIC); 328 } 329 330 val |= PCIE_SLCSR_DLLSCE | PCIE_SLCSR_HPE | PCIE_SLCSR_PDE; 331 slcsr = val; 332 pci_conf_write(pc, pa->pa_tag, 333 sc->sc_pciecapoff + PCIE_SLCSR, slcsr); 334 335 /* Attach event counters */ 336 evcnt_attach_dynamic(&sc->sc_ev_intr, EVCNT_TYPE_INTR, NULL, 337 device_xname(sc->sc_dev), "Interrupt"); 338 evcnt_attach_dynamic(&sc->sc_ev_abp, EVCNT_TYPE_MISC, NULL, 339 device_xname(sc->sc_dev), "Attention Button Pressed"); 340 evcnt_attach_dynamic(&sc->sc_ev_pfd, EVCNT_TYPE_MISC, NULL, 341 device_xname(sc->sc_dev), "Power Fault Detected"); 342 evcnt_attach_dynamic(&sc->sc_ev_msc, EVCNT_TYPE_MISC, NULL, 343 device_xname(sc->sc_dev), "MRL Sensor Changed"); 344 evcnt_attach_dynamic(&sc->sc_ev_pdc, EVCNT_TYPE_MISC, NULL, 345 device_xname(sc->sc_dev), "Presence Detect Changed"); 346 evcnt_attach_dynamic(&sc->sc_ev_cc, EVCNT_TYPE_MISC, NULL, 347 device_xname(sc->sc_dev), "Command Completed"); 348 evcnt_attach_dynamic(&sc->sc_ev_lacs, EVCNT_TYPE_MISC, NULL, 349 device_xname(sc->sc_dev), "Data Link Layer State Changed"); 350 } 351 #endif /* PPB_USEINTR */ 352 353 if (!pmf_device_register(self, ppb_suspend, ppb_resume)) 354 aprint_error_dev(self, "couldn't establish power handler\n"); 355 356 /* 357 * Attach the PCI bus that hangs off of it. 358 * 359 * XXX Don't pass-through Memory Read Multiple. Should we? 360 * XXX Consult the spec... 361 */ 362 pba.pba_iot = pa->pa_iot; 363 pba.pba_memt = pa->pa_memt; 364 pba.pba_dmat = pa->pa_dmat; 365 pba.pba_dmat64 = pa->pa_dmat64; 366 pba.pba_pc = pc; 367 pba.pba_flags = pa->pa_flags & ~PCI_FLAGS_MRM_OKAY; 368 pba.pba_bus = PPB_BUSINFO_SECONDARY(busdata); 369 pba.pba_sub = PPB_BUSINFO_SUBORDINATE(busdata); 370 pba.pba_bridgetag = &sc->sc_tag; 371 pba.pba_intrswiz = pa->pa_intrswiz; 372 pba.pba_intrtag = pa->pa_intrtag; 373 374 config_found_ia(self, "pcibus", &pba, pcibusprint); 375 } 376 377 static int 378 ppbdetach(device_t self, int flags) 379 { 380 #ifdef PPB_USEINTR 381 struct ppb_softc *sc = device_private(self); 382 pcireg_t slcsr; 383 #endif 384 int rc; 385 386 if ((rc = config_detach_children(self, flags)) != 0) 387 return rc; 388 389 #ifdef PPB_USEINTR 390 if (sc->sc_intrhand != NULL) { 391 /* Detach event counters */ 392 evcnt_detach(&sc->sc_ev_intr); 393 evcnt_detach(&sc->sc_ev_abp); 394 evcnt_detach(&sc->sc_ev_pfd); 395 evcnt_detach(&sc->sc_ev_msc); 396 evcnt_detach(&sc->sc_ev_pdc); 397 evcnt_detach(&sc->sc_ev_cc); 398 evcnt_detach(&sc->sc_ev_lacs); 399 400 /* Clear any pending events and disable interrupt */ 401 slcsr = pci_conf_read(sc->sc_pc, sc->sc_tag, 402 sc->sc_pciecapoff + PCIE_SLCSR); 403 slcsr &= ~PCIE_SLCSR_ENABLE_MASK; 404 pci_conf_write(sc->sc_pc, sc->sc_tag, 405 sc->sc_pciecapoff + PCIE_SLCSR, slcsr); 406 407 /* Disestablish the interrupt handler */ 408 pci_intr_disestablish(sc->sc_pc, sc->sc_intrhand); 409 pci_intr_release(sc->sc_pc, sc->sc_pihp, 1); 410 } 411 #endif 412 413 pmf_device_deregister(self); 414 return 0; 415 } 416 417 static bool 418 ppb_resume(device_t dv, const pmf_qual_t *qual) 419 { 420 struct ppb_softc *sc = device_private(dv); 421 int off; 422 pcireg_t val; 423 424 for (off = 0x40; off <= 0xff; off += 4) { 425 val = pci_conf_read(sc->sc_pc, sc->sc_tag, off); 426 if (val != sc->sc_pciconfext[(off - 0x40) / 4]) 427 pci_conf_write(sc->sc_pc, sc->sc_tag, off, 428 sc->sc_pciconfext[(off - 0x40)/4]); 429 } 430 431 return true; 432 } 433 434 static bool 435 ppb_suspend(device_t dv, const pmf_qual_t *qual) 436 { 437 struct ppb_softc *sc = device_private(dv); 438 int off; 439 440 for (off = 0x40; off <= 0xff; off += 4) 441 sc->sc_pciconfext[(off - 0x40) / 4] = 442 pci_conf_read(sc->sc_pc, sc->sc_tag, off); 443 444 return true; 445 } 446 447 static void 448 ppbchilddet(device_t self, device_t child) 449 { 450 /* we keep no references to child devices, so do nothing */ 451 } 452 453 #ifdef PPB_USEINTR 454 static int 455 ppb_intr(void *arg) 456 { 457 struct ppb_softc *sc = arg; 458 device_t dev = sc->sc_dev; 459 pcireg_t reg; 460 461 reg = pci_conf_read(sc->sc_pc, sc->sc_tag, 462 sc->sc_pciecapoff + PCIE_SLCSR); 463 464 /* 465 * Not me. This check is only required for INTx. 466 * ppb_intr() would be spilted int ppb_intr_legacy() and ppb_intr_msi() 467 */ 468 if ((reg & PCIE_SLCSR_STATCHG_MASK) == 0) 469 return 0; 470 471 /* Clear interrupts. */ 472 pci_conf_write(sc->sc_pc, sc->sc_tag, 473 sc->sc_pciecapoff + PCIE_SLCSR, reg); 474 475 sc->sc_ev_intr.ev_count++; 476 477 /* Attention Button Pressed */ 478 if (reg & PCIE_SLCSR_ABP) { 479 sc->sc_ev_abp.ev_count++; 480 if (ppb_printevent) 481 device_printf(dev, "Attention Button Pressed\n"); 482 } 483 484 /* Power Fault Detected */ 485 if (reg & PCIE_SLCSR_PFD) { 486 sc->sc_ev_pfd.ev_count++; 487 if (ppb_printevent) 488 device_printf(dev, "Power Fault Detected\n"); 489 } 490 491 /* MRL Sensor Changed */ 492 if (reg & PCIE_SLCSR_MSC) { 493 sc->sc_ev_msc.ev_count++; 494 if (ppb_printevent) 495 device_printf(dev, "MRL Sensor Changed\n"); 496 } 497 498 /* Presence Detect Changed */ 499 if (reg & PCIE_SLCSR_PDC) { 500 sc->sc_ev_pdc.ev_count++; 501 if (ppb_printevent) 502 device_printf(dev, "Presence Detect Changed\n"); 503 if (reg & PCIE_SLCSR_PDS) { 504 /* XXX Insert */ 505 } else { 506 /* XXX Remove */ 507 } 508 } 509 510 /* Command Completed */ 511 if (reg & PCIE_SLCSR_CC) { 512 sc->sc_ev_cc.ev_count++; 513 if (ppb_printevent) 514 device_printf(dev, "Command Completed\n"); 515 } 516 517 /* Data Link Layer State Changed */ 518 if (reg & PCIE_SLCSR_LACS) { 519 sc->sc_ev_lacs.ev_count++; 520 if (ppb_printevent) 521 device_printf(dev, "Data Link Layer State Changed\n"); 522 } 523 524 return 1; 525 } 526 #endif /* PPB_USEINTR */ 527