1 /* $NetBSD: pci_machdep.c,v 1.41 2016/10/19 00:08:41 nonaka Exp $ */ 2 3 /* 4 * Copyright (c) 1996 Christopher G. Demetriou. All rights reserved. 5 * Copyright (c) 1994 Charles M. Hannum. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. All advertising materials mentioning features or use of this software 16 * must display the following acknowledgement: 17 * This product includes software developed by Charles M. Hannum. 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 /* 34 * Machine-specific functions for PCI autoconfiguration. 35 * 36 * On PCs, there are two methods of generating PCI configuration cycles. 37 * We try to detect the appropriate mechanism for this machine and set 38 * up a few function pointers to access the correct method directly. 39 * 40 * The configuration method can be hard-coded in the config file by 41 * using `options PCI_CONF_MODE=N', where `N' is the configuration mode 42 * as defined section 3.6.4.1, `Generating Configuration Cycles'. 43 */ 44 45 #include <sys/cdefs.h> 46 __KERNEL_RCSID(0, "$NetBSD: pci_machdep.c,v 1.41 2016/10/19 00:08:41 nonaka Exp $"); 47 48 #include <sys/types.h> 49 #include <sys/param.h> 50 #include <sys/time.h> 51 #include <sys/systm.h> 52 #include <sys/errno.h> 53 #include <sys/device.h> 54 55 #define _POWERPC_BUS_DMA_PRIVATE 56 #include <sys/bus.h> 57 58 #include <machine/autoconf.h> 59 #include <machine/intr.h> 60 61 #include <dev/pci/pcivar.h> 62 #include <dev/pci/pcireg.h> 63 #include <dev/pci/ppbreg.h> 64 #include <dev/pci/pcidevs.h> 65 66 #include <dev/ofw/openfirm.h> 67 #include <dev/ofw/ofw_pci.h> 68 69 #include "opt_macppc.h" 70 71 static void fixpci(int, pci_chipset_tag_t); 72 static int find_node_intr(int, u_int32_t *, u_int32_t *); 73 static void fix_cardbus_bridge(int, pci_chipset_tag_t, pcitag_t); 74 75 #ifdef PB3400_CARDBUS_HACK 76 int cardbus_number = 2; 77 const char *pb3400_compat[] = {"AAPL,3400/2400", NULL}; 78 #endif 79 80 pcitag_t genppc_pci_indirect_make_tag(void *, int, int, int); 81 void genppc_pci_indirect_decompose_tag(void *, pcitag_t, int *, int *, int *); 82 83 void 84 macppc_pci_attach_hook(device_t parent, device_t self, struct pcibus_attach_args *pba) 85 { 86 pci_chipset_tag_t pc = pba->pba_pc; 87 int bus = pba->pba_bus; 88 int node, nn, sz; 89 int32_t busrange[2]; 90 91 for (node = pc->pc_node; node; node = nn) { 92 sz = OF_getprop(node, "bus-range", busrange, 8); 93 if (sz == 8 && busrange[0] == bus) { 94 fixpci(node, pc); 95 return; 96 } 97 if ((nn = OF_child(node)) != 0) 98 continue; 99 while ((nn = OF_peer(node)) == 0) { 100 node = OF_parent(node); 101 if (node == pc->pc_node) 102 return; /* not found */ 103 } 104 } 105 } 106 107 void 108 macppc_pci_get_chipset_tag(pci_chipset_tag_t pc) 109 { 110 111 pc->pc_conf_v = (void *)pc; 112 113 pc->pc_attach_hook = macppc_pci_attach_hook; 114 pc->pc_bus_maxdevs = genppc_pci_bus_maxdevs; 115 116 pc->pc_make_tag = genppc_pci_indirect_make_tag; 117 pc->pc_decompose_tag = genppc_pci_indirect_decompose_tag; 118 119 pc->pc_intr_v = (void *)pc; 120 121 pc->pc_intr_map = genppc_pci_intr_map; 122 pc->pc_intr_string = genppc_pci_intr_string; 123 pc->pc_intr_evcnt = genppc_pci_intr_evcnt; 124 pc->pc_intr_establish = genppc_pci_intr_establish; 125 pc->pc_intr_disestablish = genppc_pci_intr_disestablish; 126 pc->pc_intr_setattr = genppc_pci_intr_setattr; 127 pc->pc_intr_type = genppc_pci_intr_type; 128 pc->pc_intr_alloc = genppc_pci_intr_alloc; 129 pc->pc_intr_release = genppc_pci_intr_release; 130 pc->pc_intx_alloc = genppc_pci_intx_alloc; 131 132 pc->pc_msi_v = (void *)pc; 133 genppc_pci_chipset_msi_init(pc); 134 135 pc->pc_msix_v = (void *)pc; 136 genppc_pci_chipset_msix_init(pc); 137 138 pc->pc_conf_interrupt = genppc_pci_conf_interrupt; 139 pc->pc_conf_hook = genppc_pci_conf_hook; 140 141 pc->pc_bus = 0; 142 pc->pc_node = 0; 143 pc->pc_memt = 0; 144 pc->pc_iot = 0; 145 } 146 147 #define pcibus(x) \ 148 (((x) & OFW_PCI_PHYS_HI_BUSMASK) >> OFW_PCI_PHYS_HI_BUSSHIFT) 149 #define pcidev(x) \ 150 (((x) & OFW_PCI_PHYS_HI_DEVICEMASK) >> OFW_PCI_PHYS_HI_DEVICESHIFT) 151 #define pcifunc(x) \ 152 (((x) & OFW_PCI_PHYS_HI_FUNCTIONMASK) >> OFW_PCI_PHYS_HI_FUNCTIONSHIFT) 153 154 static void 155 fixpci(int parent, pci_chipset_tag_t pc) 156 { 157 int node; 158 pcitag_t tag; 159 pcireg_t csr, intr, id, cr; 160 int len, i, ilen; 161 int32_t irqs[4]; 162 struct { 163 u_int32_t phys_hi, phys_mid, phys_lo; 164 u_int32_t size_hi, size_lo; 165 } addr[8]; 166 struct { 167 u_int32_t phys_hi, phys_mid, phys_lo; 168 u_int32_t icells[5]; 169 } iaddr; 170 171 /* 172 * first hack - here we make the Ethernet portion of a 173 * UMAX E100 card work 174 */ 175 #ifdef UMAX_E100_HACK 176 tag = pci_make_tag(pc, 0, 17, 0); 177 id = pci_conf_read(pc, tag, PCI_ID_REG); 178 if ((PCI_VENDOR(id) == PCI_VENDOR_DEC) && 179 (PCI_PRODUCT(id) == PCI_PRODUCT_DEC_21140)) { 180 /* this could be one */ 181 pcireg_t isp, reg; 182 pcitag_t tag_isp = pci_make_tag(pc, 0, 13, 0); 183 /* 184 * here we go. We shouldn't encounter this anywhere else 185 * than on a UMAX S900 with an E100 board 186 * look at 00:0d:00 for a Qlogic ISP 1020 to 187 * make sure we really have an E100 here 188 */ 189 aprint_debug("\nfound E100 candidate tlp"); 190 isp = pci_conf_read(pc, tag_isp, PCI_ID_REG); 191 if ((PCI_VENDOR(isp) == PCI_VENDOR_QLOGIC) && 192 (PCI_PRODUCT(isp) == PCI_PRODUCT_QLOGIC_ISP1020)) { 193 194 aprint_verbose("\nenabling UMAX E100 ethernet"); 195 196 pci_conf_write(pc, tag, 0x14, 0x80000000); 197 198 /* now enable MMIO and busmastering */ 199 reg = pci_conf_read(pc, tag, 200 PCI_COMMAND_STATUS_REG); 201 reg |= PCI_COMMAND_MEM_ENABLE | 202 PCI_COMMAND_MASTER_ENABLE; 203 pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG, 204 reg); 205 206 /* and finally the interrupt */ 207 reg = pci_conf_read(pc, tag, PCI_INTERRUPT_REG); 208 reg &= ~PCI_INTERRUPT_LINE_MASK; 209 reg |= 23; 210 pci_conf_write(pc, tag, PCI_INTERRUPT_REG, reg); 211 } 212 } 213 #endif 214 215 len = OF_getprop(parent, "#interrupt-cells", &ilen, sizeof(ilen)); 216 if (len < 0) 217 ilen = 0; 218 for (node = OF_child(parent); node; node = OF_peer(node)) { 219 len = OF_getprop(node, "assigned-addresses", addr, 220 sizeof(addr)); 221 if (len < (int)sizeof(addr[0])) 222 continue; 223 224 tag = pci_make_tag(pc, pcibus(addr[0].phys_hi), 225 pcidev(addr[0].phys_hi), 226 pcifunc(addr[0].phys_hi)); 227 228 /* 229 * Make sure the IO and MEM enable bits are set in the CSR. 230 */ 231 csr = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG); 232 csr &= ~(PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE); 233 234 for (i = 0; i < len / sizeof(addr[0]); i++) { 235 switch (addr[i].phys_hi & OFW_PCI_PHYS_HI_SPACEMASK) { 236 case OFW_PCI_PHYS_HI_SPACE_IO: 237 csr |= PCI_COMMAND_IO_ENABLE; 238 break; 239 240 case OFW_PCI_PHYS_HI_SPACE_MEM32: 241 case OFW_PCI_PHYS_HI_SPACE_MEM64: 242 csr |= PCI_COMMAND_MEM_ENABLE; 243 break; 244 } 245 } 246 247 pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG, csr); 248 249 /* 250 * Make sure the line register is programmed with the 251 * interrupt mapping. 252 */ 253 if (ilen == 0) { 254 /* 255 * Early Apple OFW implementation don't handle 256 * interrupts as defined by the OFW PCI bindings. 257 */ 258 len = OF_getprop(node, "AAPL,interrupts", irqs, 4); 259 } else { 260 iaddr.phys_hi = addr[0].phys_hi; 261 iaddr.phys_mid = addr[0].phys_mid; 262 iaddr.phys_lo = addr[0].phys_lo; 263 /* 264 * Thankfully, PCI can only have one entry in its 265 * "interrupts" property. 266 */ 267 len = OF_getprop(node, "interrupts", &iaddr.icells[0], 268 4*ilen); 269 if (len != 4*ilen) 270 continue; 271 len = find_node_intr(node, &iaddr.phys_hi, irqs); 272 } 273 if (len <= 0) { 274 /* 275 * If we still don't have an interrupt, try one 276 * more time. This case covers devices behind the 277 * PCI-PCI bridge in a UMAX S900 or similar (9500?) 278 * system. These slots all share the bridge's 279 * interrupt. 280 */ 281 len = find_node_intr(node, &addr[0].phys_hi, irqs); 282 if (len <= 0) 283 continue; 284 } 285 286 /* 287 * For PowerBook 2400, 3400 and original G3: 288 * check if we have a 2nd ohare PIC - if so frob the built-in 289 * tlp's IRQ to 60 290 * first see if we have something on bus 0 device 13 and if 291 * it's a DEC 21041 292 */ 293 id = pci_conf_read(pc, tag, PCI_ID_REG); 294 if ((tag == pci_make_tag(pc, 0, 13, 0)) && 295 (PCI_VENDOR(id) == PCI_VENDOR_DEC) && 296 (PCI_PRODUCT(id) == PCI_PRODUCT_DEC_21041)) { 297 298 /* now look for the 2nd ohare */ 299 if (OF_finddevice("/bandit/pci106b,7") != -1) { 300 301 irqs[0] = 60; 302 aprint_verbose("\nohare: frobbing tlp IRQ to 60"); 303 } 304 } 305 306 intr = pci_conf_read(pc, tag, PCI_INTERRUPT_REG); 307 intr &= ~PCI_INTERRUPT_LINE_MASK; 308 intr |= irqs[0] & PCI_INTERRUPT_LINE_MASK; 309 pci_conf_write(pc, tag, PCI_INTERRUPT_REG, intr); 310 311 /* fix secondary bus numbers on CardBus bridges */ 312 cr = pci_conf_read(pc, tag, PCI_CLASS_REG); 313 if ((PCI_CLASS(cr) == PCI_CLASS_BRIDGE) && 314 (PCI_SUBCLASS(cr) == PCI_SUBCLASS_BRIDGE_CARDBUS)) { 315 uint32_t bi, busid; 316 317 /* 318 * we found a CardBus bridge. Check if the bus number 319 * is sane 320 */ 321 bi = pci_conf_read(pc, tag, PPB_REG_BUSINFO); 322 busid = bi & 0xff; 323 if (busid == 0) { 324 fix_cardbus_bridge(node, pc, tag); 325 } 326 } 327 } 328 } 329 330 static void 331 fix_cardbus_bridge(int node, pci_chipset_tag_t pc, pcitag_t tag) 332 { 333 uint32_t bus_number = 0xffffffff; 334 pcireg_t bi; 335 int bus, dev, fn, ih, len; 336 char path[256]; 337 338 #if PB3400_CARDBUS_HACK 339 int root_node; 340 341 root_node = OF_finddevice("/"); 342 if (of_compatible(root_node, pb3400_compat) != -1) { 343 344 bus_number = cardbus_number; 345 cardbus_number++; 346 } else { 347 #endif 348 ih = OF_open(path); 349 OF_call_method("load-ata", ih, 0, 0); 350 OF_close(ih); 351 352 OF_getprop(node, "AAPL,bus-id", &bus_number, 353 sizeof(bus_number)); 354 #if PB3400_CARDBUS_HACK 355 } 356 #endif 357 if (bus_number != 0xffffffff) { 358 359 len = OF_package_to_path(node, path, sizeof(path)); 360 path[len] = 0; 361 aprint_verbose("\n%s: fixing bus number to %d", path, bus_number); 362 pci_decompose_tag(pc, tag, &bus, &dev, &fn); 363 bi = pci_conf_read(pc, tag, PPB_REG_BUSINFO); 364 bi &= 0xff000000; 365 /* XXX subordinate is always 32 here */ 366 bi |= (bus & 0xff) | (bus_number << 8) | 0x200000; 367 pci_conf_write(pc, tag, PPB_REG_BUSINFO, bi); 368 } 369 } 370 371 /* 372 * Find PCI IRQ of the node from OF tree. 373 */ 374 static int 375 find_node_intr(int node, u_int32_t *addr, uint32_t *intr) 376 { 377 int parent, len, mlen, iparent; 378 int match, i; 379 u_int32_t map[160]; 380 const u_int32_t *mp; 381 u_int32_t imapmask[8], maskedaddr[8]; 382 u_int32_t acells, icells; 383 char name[32]; 384 385 /* XXXSL: 1st check for a interrupt-parent property */ 386 if (OF_getprop(node, "interrupt-parent", &iparent, sizeof(iparent)) == sizeof(iparent)) 387 { 388 /* How many cells to specify an interrupt ?? */ 389 if (OF_getprop(iparent, "#interrupt-cells", &icells, 4) != 4) 390 return -1; 391 392 if (OF_getprop(node, "interrupts", &map, sizeof(map)) != (icells * 4)) 393 return -1; 394 395 memcpy(intr, map, icells * 4); 396 return (icells * 4); 397 } 398 399 parent = OF_parent(node); 400 len = OF_getprop(parent, "interrupt-map", map, sizeof(map)); 401 mlen = OF_getprop(parent, "interrupt-map-mask", imapmask, 402 sizeof(imapmask)); 403 404 if (mlen != -1) 405 memcpy(maskedaddr, addr, mlen); 406 again: 407 if (len == -1 || mlen == -1) 408 goto nomap; 409 410 #ifdef DIAGNOSTIC 411 if (mlen == sizeof(imapmask)) { 412 aprint_error("interrupt-map too long\n"); 413 return -1; 414 } 415 #endif 416 417 /* mask addr by "interrupt-map-mask" */ 418 for (i = 0; i < mlen / 4; i++) 419 maskedaddr[i] &= imapmask[i]; 420 421 mp = map; 422 i = 0; 423 while (len > mlen) { 424 match = memcmp(maskedaddr, mp, mlen); 425 mp += mlen / 4; 426 len -= mlen; 427 428 /* 429 * We must read "#address-cells" and "#interrupt-cells" each 430 * time because each interrupt-parent may be different. 431 */ 432 iparent = *mp++; 433 len -= 4; 434 i = OF_getprop(iparent, "#address-cells", &acells, 4); 435 if (i <= 0) 436 acells = 0; 437 else if (i != 4) 438 return -1; 439 if (OF_getprop(iparent, "#interrupt-cells", &icells, 4) != 4) 440 return -1; 441 442 /* Found. */ 443 if (match == 0) { 444 /* 445 * We matched on address/interrupt, but are we done? 446 */ 447 if (acells == 0) { /* XXX */ 448 /* 449 * If we are at the interrupt controller, 450 * we are finally done. Save the result and 451 * return. 452 */ 453 memcpy(intr, mp, icells * 4); 454 return icells * 4; 455 } 456 /* 457 * We are now at an intermedia interrupt node. We 458 * need to use its interrupt mask and map the 459 * supplied address/interrupt via its map. 460 */ 461 mlen = OF_getprop(iparent, "interrupt-map-mask", 462 imapmask, sizeof(imapmask)); 463 #ifdef DIAGNOSTIC 464 if (mlen != (acells + icells)*4) { 465 aprint_error("interrupt-map inconsistent (%d, %d)\n", 466 mlen, (acells + icells)*4); 467 return -1; 468 } 469 #endif 470 memcpy(maskedaddr, mp, mlen); 471 len = OF_getprop(iparent, "interrupt-map", map, 472 sizeof(map)); 473 goto again; 474 } 475 476 mp += (acells + icells); 477 len -= (acells + icells) * 4; 478 } 479 480 nomap: 481 /* 482 * If the node has no interrupt property and the parent is a 483 * pci-bridge, use parent's interrupt. This occurs on a PCI 484 * slot. (e.g. AHA-3940) 485 */ 486 memset(name, 0, sizeof(name)); 487 OF_getprop(parent, "name", name, sizeof(name)); 488 if (strcmp(name, "pci-bridge") == 0) { 489 len = OF_getprop(parent, "AAPL,interrupts", intr, 4) ; 490 if (len == 4) 491 return len; 492 #if 0 493 /* 494 * XXX I don't know what is the correct local address. 495 * XXX Use the first entry for now. 496 */ 497 len = OF_getprop(parent, "interrupt-map", map, sizeof(map)); 498 if (len >= 36) { 499 addr = &map[5]; 500 return find_node_intr(parent, addr, intr); 501 } 502 #endif 503 } 504 505 /* 506 * If all else fails, attempt to get AAPL, interrupts property. 507 * Grackle, at least, uses this instead of above in some cases. 508 */ 509 len = OF_getprop(node, "AAPL,interrupts", intr, 4) ; 510 if (len == 4) 511 return len; 512 513 return -1; 514 } 515