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