xlp_pci.c revision 233563
1/*- 2 * Copyright (c) 2003-2012 Broadcom Corporation 3 * All Rights Reserved 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 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 13 * the documentation and/or other materials provided with the 14 * distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY BROADCOM ``AS IS'' AND ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29#include <sys/cdefs.h> 30__FBSDID("$FreeBSD: head/sys/mips/nlm/xlp_pci.c 233563 2012-03-27 15:39:55Z jchandra $"); 31 32#include <sys/param.h> 33#include <sys/systm.h> 34#include <sys/types.h> 35#include <sys/kernel.h> 36#include <sys/module.h> 37#include <sys/malloc.h> 38#include <sys/bus.h> 39#include <sys/endian.h> 40#include <sys/rman.h> 41#include <sys/pciio.h> 42 43#include <vm/vm.h> 44#include <vm/vm_param.h> 45#include <vm/pmap.h> 46 47#include <dev/pci/pcivar.h> 48#include <dev/pci/pcireg.h> 49#include <dev/pci/pci_private.h> 50 51#include <dev/uart/uart.h> 52#include <dev/uart/uart_bus.h> 53#include <dev/uart/uart_cpu.h> 54 55#include <machine/bus.h> 56#include <machine/md_var.h> 57#include <machine/intr_machdep.h> 58#include <machine/cpuregs.h> 59 60#include <mips/nlm/hal/haldefs.h> 61#include <mips/nlm/interrupt.h> 62#include <mips/nlm/hal/iomap.h> 63#include <mips/nlm/hal/mips-extns.h> 64#include <mips/nlm/hal/pic.h> 65#include <mips/nlm/hal/bridge.h> 66#include <mips/nlm/hal/gbu.h> 67#include <mips/nlm/hal/pcibus.h> 68#include <mips/nlm/hal/uart.h> 69#include <mips/nlm/xlp.h> 70 71#include "pcib_if.h" 72#include "pci_if.h" 73 74#define EMUL_MEM_START 0x16000000UL 75#define EMUL_MEM_END 0x18ffffffUL 76 77/* SoC device qurik handling */ 78static int irt_irq_map[4 * 256]; 79static int irq_irt_map[64]; 80 81static void 82xlp_add_irq(int node, int irt, int irq) 83{ 84 int nodeirt = node * 256 + irt; 85 86 irt_irq_map[nodeirt] = irq; 87 irq_irt_map[irq] = nodeirt; 88} 89 90int 91xlp_irq_to_irt(int irq) 92{ 93 return irq_irt_map[irq]; 94} 95 96int 97xlp_irt_to_irq(int nodeirt) 98{ 99 return irt_irq_map[nodeirt]; 100} 101 102/* Override PCI a bit for SoC devices */ 103 104enum { 105 INTERNAL_DEV = 0x1, /* internal device, skip on enumeration */ 106 MEM_RES_EMUL = 0x2, /* no MEM or IO bar, custom res alloc */ 107 SHARED_IRQ = 0x4, 108 DEV_MMIO32 = 0x8, /* byte access not allowed to mmio */ 109}; 110 111struct soc_dev_desc { 112 u_int devid; /* device ID */ 113 int irqbase; /* start IRQ */ 114 u_int flags; /* flags */ 115 int ndevs; /* to keep track of number of devices */ 116}; 117 118struct soc_dev_desc xlp_dev_desc[] = { 119 { PCI_DEVICE_ID_NLM_ICI, 0, INTERNAL_DEV }, 120 { PCI_DEVICE_ID_NLM_PIC, 0, INTERNAL_DEV }, 121 { PCI_DEVICE_ID_NLM_FMN, 0, INTERNAL_DEV }, 122 { PCI_DEVICE_ID_NLM_UART, PIC_UART_0_IRQ, MEM_RES_EMUL | DEV_MMIO32}, 123 { PCI_DEVICE_ID_NLM_I2C, 0, MEM_RES_EMUL | DEV_MMIO32 }, 124 { PCI_DEVICE_ID_NLM_NOR, 0, MEM_RES_EMUL }, 125 { PCI_DEVICE_ID_NLM_MMC, PIC_MMC_IRQ, MEM_RES_EMUL }, 126 { PCI_DEVICE_ID_NLM_EHCI, PIC_EHCI_0_IRQ, 0 } 127}; 128 129struct xlp_devinfo { 130 struct pci_devinfo pcidev; 131 int irq; 132 int flags; 133 u_long mem_res_start; 134}; 135 136static __inline struct soc_dev_desc * 137xlp_find_soc_desc(int devid) 138{ 139 struct soc_dev_desc *p; 140 int i, n; 141 142 n = sizeof(xlp_dev_desc) / sizeof(xlp_dev_desc[0]); 143 for (i = 0, p = xlp_dev_desc; i < n; i++, p++) 144 if (p->devid == devid) 145 return (p); 146 return (NULL); 147} 148 149static struct resource * 150xlp_pci_alloc_resource(device_t bus, device_t child, int type, int *rid, 151 u_long start, u_long end, u_long count, u_int flags) 152{ 153 struct resource *r; 154 struct xlp_devinfo *xlp_devinfo; 155 int busno; 156 157 /* 158 * Do custom allocation for MEMORY resource for SoC device if 159 * MEM_RES_EMUL flag is set 160 */ 161 busno = pci_get_bus(child); 162 if ((type == SYS_RES_MEMORY || type == SYS_RES_IOPORT) && busno == 0) { 163 xlp_devinfo = (struct xlp_devinfo *)device_get_ivars(child); 164 if ((xlp_devinfo->flags & MEM_RES_EMUL) != 0) { 165 /* no emulation for IO ports */ 166 if (type == SYS_RES_IOPORT) 167 return (NULL); 168 start = xlp_devinfo->mem_res_start; 169 count = XLP_PCIE_CFG_SIZE - XLP_IO_PCI_HDRSZ; 170 end = start + count - 1; 171 r = BUS_ALLOC_RESOURCE(device_get_parent(bus), child, 172 type, rid, start, end, count, flags); 173 if (r == NULL) 174 return (NULL); 175 if ((xlp_devinfo->flags & DEV_MMIO32) != 0) 176 rman_set_bustag(r, rmi_uart_bus_space); 177 return (r); 178 } 179 } 180 181 /* Not custom alloc, use PCI code */ 182 return (pci_alloc_resource(bus, child, type, rid, start, end, count, 183 flags)); 184} 185 186static int 187xlp_pci_release_resource(device_t bus, device_t child, int type, int rid, 188 struct resource *r) 189{ 190 u_long start; 191 192 /* If custom alloc, handle that */ 193 start = rman_get_start(r); 194 if (type == SYS_RES_MEMORY && pci_get_bus(child) == 0 && 195 start >= EMUL_MEM_START && start <= EMUL_MEM_END) 196 return (BUS_RELEASE_RESOURCE(device_get_parent(bus), child, 197 type, rid, r)); 198 199 /* use default PCI function */ 200 return (bus_generic_rl_release_resource(bus, child, type, rid, r)); 201} 202 203static void 204xlp_add_soc_child(device_t pcib, device_t dev, int b, int s, int f) 205{ 206 struct pci_devinfo *dinfo; 207 struct xlp_devinfo *xlp_dinfo; 208 struct soc_dev_desc *si; 209 uint64_t pcibase; 210 int domain, node, irt, irq, flags, devoffset, num; 211 uint16_t devid; 212 213 domain = pcib_get_domain(dev); 214 node = s / 8; 215 devoffset = XLP_HDR_OFFSET(node, 0, s % 8, f); 216 if (!nlm_dev_exists(devoffset)) 217 return; 218 219 /* Find if there is a desc for the SoC device */ 220 devid = PCIB_READ_CONFIG(pcib, b, s, f, PCIR_DEVICE, 2); 221 si = xlp_find_soc_desc(devid); 222 223 /* update flags and irq from desc if available */ 224 irq = 0; 225 flags = 0; 226 if (si != NULL) { 227 if (si->irqbase != 0) 228 irq = si->irqbase + si->ndevs; 229 flags = si->flags; 230 si->ndevs++; 231 } 232 233 /* skip internal devices */ 234 if ((flags & INTERNAL_DEV) != 0) 235 return; 236 237 /* PCIe interfaces are special, bug in Ax */ 238 if (devid == PCI_DEVICE_ID_NLM_PCIE) { 239 xlp_add_irq(node, xlp_pcie_link_irt(f), PIC_PCIE_0_IRQ + f); 240 } else { 241 /* Stash intline and pin in shadow reg for devices */ 242 pcibase = nlm_pcicfg_base(devoffset); 243 irt = nlm_irtstart(pcibase); 244 num = nlm_irtnum(pcibase); 245 if (irq != 0 && num > 0) { 246 xlp_add_irq(node, irt, irq); 247 nlm_write_reg(pcibase, XLP_PCI_DEVSCRATCH_REG0, 248 (1 << 8) | irq); 249 } 250 } 251 dinfo = pci_read_device(pcib, domain, b, s, f, sizeof(*xlp_dinfo)); 252 if (dinfo == NULL) 253 return; 254 xlp_dinfo = (struct xlp_devinfo *)dinfo; 255 xlp_dinfo->irq = irq; 256 xlp_dinfo->flags = flags; 257 if ((flags & MEM_RES_EMUL) != 0) 258 xlp_dinfo->mem_res_start = XLP_DEFAULT_IO_BASE + devoffset + 259 XLP_IO_PCI_HDRSZ; 260 pci_add_child(dev, dinfo); 261} 262 263static int 264xlp_pci_attach(device_t dev) 265{ 266 device_t pcib = device_get_parent(dev); 267 int maxslots, s, f, pcifunchigh; 268 int busno; 269 uint8_t hdrtype; 270 271 /* 272 * The on-chip devices are on a bus that is almost, but not 273 * quite, completely like PCI. Add those things by hand. 274 */ 275 busno = pcib_get_bus(dev); 276 maxslots = PCIB_MAXSLOTS(pcib); 277 for (s = 0; s <= maxslots; s++) { 278 pcifunchigh = 0; 279 f = 0; 280 hdrtype = PCIB_READ_CONFIG(pcib, busno, s, f, PCIR_HDRTYPE, 1); 281 if ((hdrtype & PCIM_HDRTYPE) > PCI_MAXHDRTYPE) 282 continue; 283 if (hdrtype & PCIM_MFDEV) 284 pcifunchigh = PCI_FUNCMAX; 285 for (f = 0; f <= pcifunchigh; f++) 286 xlp_add_soc_child(pcib, dev, busno, s, f); 287 } 288 return (bus_generic_attach(dev)); 289} 290 291static int 292xlp_pci_probe(device_t dev) 293{ 294 device_t pcib; 295 296 pcib = device_get_parent(dev); 297 /* 298 * Only the top level bus has SoC devices, leave the rest to 299 * Generic PCI code 300 */ 301 if (strcmp(device_get_nameunit(pcib), "pcib0") != 0) 302 return (ENXIO); 303 device_set_desc(dev, "XLP SoCbus"); 304 return (BUS_PROBE_DEFAULT); 305} 306 307static devclass_t pci_devclass; 308static device_method_t xlp_pci_methods[] = { 309 /* Device interface */ 310 DEVMETHOD(device_probe, xlp_pci_probe), 311 DEVMETHOD(device_attach, xlp_pci_attach), 312 DEVMETHOD(bus_alloc_resource, xlp_pci_alloc_resource), 313 DEVMETHOD(bus_release_resource, xlp_pci_release_resource), 314 315 DEVMETHOD_END 316}; 317 318DEFINE_CLASS_1(pci, xlp_pci_driver, xlp_pci_methods, 0, pci_driver); 319DRIVER_MODULE(xlp_pci, pcib, xlp_pci_driver, pci_devclass, 0, 0); 320 321static devclass_t pcib_devclass; 322static struct rman irq_rman, port_rman, mem_rman, emul_rman; 323 324static void 325xlp_pcib_init_resources(void) 326{ 327 irq_rman.rm_start = 0; 328 irq_rman.rm_end = 255; 329 irq_rman.rm_type = RMAN_ARRAY; 330 irq_rman.rm_descr = "PCI Mapped Interrupts"; 331 if (rman_init(&irq_rman) 332 || rman_manage_region(&irq_rman, 0, 255)) 333 panic("pci_init_resources irq_rman"); 334 335 port_rman.rm_start = 0; 336 port_rman.rm_end = ~0ul; 337 port_rman.rm_type = RMAN_ARRAY; 338 port_rman.rm_descr = "I/O ports"; 339 if (rman_init(&port_rman) 340 || rman_manage_region(&port_rman, PCIE_IO_BASE, PCIE_IO_LIMIT)) 341 panic("pci_init_resources port_rman"); 342 343 mem_rman.rm_start = 0; 344 mem_rman.rm_end = ~0ul; 345 mem_rman.rm_type = RMAN_ARRAY; 346 mem_rman.rm_descr = "I/O memory"; 347 if (rman_init(&mem_rman) 348 || rman_manage_region(&mem_rman, PCIE_MEM_BASE, PCIE_MEM_LIMIT)) 349 panic("pci_init_resources mem_rman"); 350 351 /* 352 * This includes the GBU (nor flash) memory range and the PCIe 353 * memory area. 354 */ 355 emul_rman.rm_start = 0; 356 emul_rman.rm_end = ~0ul; 357 emul_rman.rm_type = RMAN_ARRAY; 358 emul_rman.rm_descr = "Emulated MEMIO"; 359 if (rman_init(&emul_rman) 360 || rman_manage_region(&emul_rman, EMUL_MEM_START, EMUL_MEM_END)) 361 panic("pci_init_resources emul_rman"); 362} 363 364static int 365xlp_pcib_probe(device_t dev) 366{ 367 368 device_set_desc(dev, "XLP PCI bus"); 369 xlp_pcib_init_resources(); 370 return (0); 371} 372 373static int 374xlp_pcib_read_ivar(device_t dev, device_t child, int which, uintptr_t *result) 375{ 376 377 switch (which) { 378 case PCIB_IVAR_DOMAIN: 379 *result = 0; 380 return (0); 381 case PCIB_IVAR_BUS: 382 *result = 0; 383 return (0); 384 } 385 return (ENOENT); 386} 387 388static int 389xlp_pcib_write_ivar(device_t dev, device_t child, int which, uintptr_t result) 390{ 391 switch (which) { 392 case PCIB_IVAR_DOMAIN: 393 return (EINVAL); 394 case PCIB_IVAR_BUS: 395 return (EINVAL); 396 } 397 return (ENOENT); 398} 399 400static int 401xlp_pcib_maxslots(device_t dev) 402{ 403 404 return (PCI_SLOTMAX); 405} 406 407static u_int32_t 408xlp_pcib_read_config(device_t dev, u_int b, u_int s, u_int f, 409 u_int reg, int width) 410{ 411 uint32_t data = 0; 412 uint64_t cfgaddr; 413 int regindex = reg/sizeof(uint32_t); 414 415 cfgaddr = nlm_pcicfg_base(XLP_HDR_OFFSET(0, b, s, f)); 416 if ((width == 2) && (reg & 1)) 417 return 0xFFFFFFFF; 418 else if ((width == 4) && (reg & 3)) 419 return 0xFFFFFFFF; 420 421 /* 422 * The intline and int pin of SoC devices are DOA, except 423 * for bridges (slot %8 == 1). 424 * use the values we stashed in a writable PCI scratch reg. 425 */ 426 if (b == 0 && regindex == 0xf && s % 8 > 1) 427 regindex = XLP_PCI_DEVSCRATCH_REG0; 428 429 data = nlm_read_pci_reg(cfgaddr, regindex); 430 if (width == 1) 431 return ((data >> ((reg & 3) << 3)) & 0xff); 432 else if (width == 2) 433 return ((data >> ((reg & 3) << 3)) & 0xffff); 434 else 435 return (data); 436} 437 438static void 439xlp_pcib_write_config(device_t dev, u_int b, u_int s, u_int f, 440 u_int reg, u_int32_t val, int width) 441{ 442 uint64_t cfgaddr; 443 uint32_t data = 0; 444 int regindex = reg / sizeof(uint32_t); 445 446 cfgaddr = nlm_pcicfg_base(XLP_HDR_OFFSET(0, b, s, f)); 447 if ((width == 2) && (reg & 1)) 448 return; 449 else if ((width == 4) && (reg & 3)) 450 return; 451 452 if (width == 1) { 453 data = nlm_read_pci_reg(cfgaddr, regindex); 454 data = (data & ~(0xff << ((reg & 3) << 3))) | 455 (val << ((reg & 3) << 3)); 456 } else if (width == 2) { 457 data = nlm_read_pci_reg(cfgaddr, regindex); 458 data = (data & ~(0xffff << ((reg & 3) << 3))) | 459 (val << ((reg & 3) << 3)); 460 } else { 461 data = val; 462 } 463 464 /* 465 * use shadow reg for intpin/intline which are dead 466 */ 467 if (b == 0 && regindex == 0xf && s % 8 > 1) 468 regindex = XLP_PCI_DEVSCRATCH_REG0; 469 nlm_write_pci_reg(cfgaddr, regindex, data); 470} 471 472/* 473 * Enable byte swap in hardware. Program a link's PCIe SWAP regions 474 * from the link's IO and MEM address ranges. 475 */ 476static void 477xlp_pcib_hardware_swap_enable(int node, int link) 478{ 479 uint64_t bbase, linkpcibase; 480 uint32_t bar; 481 int pcieoffset; 482 483 pcieoffset = XLP_IO_PCIE_OFFSET(node, link); 484 if (!nlm_dev_exists(pcieoffset)) 485 return; 486 487 bbase = nlm_get_bridge_regbase(node); 488 linkpcibase = nlm_pcicfg_base(pcieoffset); 489 bar = nlm_read_bridge_reg(bbase, BRIDGE_PCIEMEM_BASE0 + link); 490 nlm_write_pci_reg(linkpcibase, PCIE_BYTE_SWAP_MEM_BASE, bar); 491 492 bar = nlm_read_bridge_reg(bbase, BRIDGE_PCIEMEM_LIMIT0 + link); 493 nlm_write_pci_reg(linkpcibase, PCIE_BYTE_SWAP_MEM_LIM, bar); 494 495 bar = nlm_read_bridge_reg(bbase, BRIDGE_PCIEIO_BASE0 + link); 496 nlm_write_pci_reg(linkpcibase, PCIE_BYTE_SWAP_IO_BASE, bar); 497 498 bar = nlm_read_bridge_reg(bbase, BRIDGE_PCIEIO_LIMIT0 + link); 499 nlm_write_pci_reg(linkpcibase, PCIE_BYTE_SWAP_IO_LIM, bar); 500} 501 502static int 503xlp_pcib_attach(device_t dev) 504{ 505 int node, link; 506 507 /* enable hardware swap on all nodes/links */ 508 for (node = 0; node < XLP_MAX_NODES; node++) 509 for (link = 0; link < 4; link++) 510 xlp_pcib_hardware_swap_enable(node, link); 511 512 device_add_child(dev, "pci", 0); 513 bus_generic_attach(dev); 514 return (0); 515} 516 517static void 518xlp_pcib_identify(driver_t * driver, device_t parent) 519{ 520 521 BUS_ADD_CHILD(parent, 0, "pcib", 0); 522} 523 524/* 525 * XLS PCIe can have upto 4 links, and each link has its on IRQ 526 * Find the link on which the device is on 527 */ 528static int 529xlp_pcie_link(device_t pcib, device_t dev) 530{ 531 device_t parent, tmp; 532 533 /* find the lane on which the slot is connected to */ 534 tmp = dev; 535 while (1) { 536 parent = device_get_parent(tmp); 537 if (parent == NULL || parent == pcib) { 538 device_printf(dev, "Cannot find parent bus\n"); 539 return (-1); 540 } 541 if (strcmp(device_get_nameunit(parent), "pci0") == 0) 542 break; 543 tmp = parent; 544 } 545 return (pci_get_function(tmp)); 546} 547 548static int 549xlp_alloc_msi(device_t pcib, device_t dev, int count, int maxcount, int *irqs) 550{ 551 int i, link; 552 553 /* 554 * Each link has 32 MSIs that can be allocated, but for now 555 * we only support one device per link. 556 * msi_alloc() equivalent is needed when we start supporting 557 * bridges on the PCIe link. 558 */ 559 link = xlp_pcie_link(pcib, dev); 560 if (link == -1) 561 return (ENXIO); 562 563 /* 564 * encode the irq so that we know it is a MSI interrupt when we 565 * setup interrupts 566 */ 567 for (i = 0; i < count; i++) 568 irqs[i] = 64 + link * 32 + i; 569 570 return (0); 571} 572 573static int 574xlp_release_msi(device_t pcib, device_t dev, int count, int *irqs) 575{ 576 return (0); 577} 578 579static int 580xlp_map_msi(device_t pcib, device_t dev, int irq, uint64_t *addr, 581 uint32_t *data) 582{ 583 int msi, irt; 584 585 if (irq >= 64) { 586 msi = irq - 64; 587 *addr = MIPS_MSI_ADDR(0); 588 589 irt = xlp_pcie_link_irt(msi/32); 590 if (irt != -1) 591 *data = MIPS_MSI_DATA(xlp_irt_to_irq(irt)); 592 return (0); 593 } else { 594 device_printf(dev, "%s: map_msi for irq %d - ignored", 595 device_get_nameunit(pcib), irq); 596 return (ENXIO); 597 } 598} 599 600static void 601bridge_pcie_ack(int irq) 602{ 603 uint32_t node,reg; 604 uint64_t base; 605 606 node = nlm_nodeid(); 607 reg = PCIE_MSI_STATUS; 608 609 switch (irq) { 610 case PIC_PCIE_0_IRQ: 611 base = nlm_pcicfg_base(XLP_IO_PCIE0_OFFSET(node)); 612 break; 613 case PIC_PCIE_1_IRQ: 614 base = nlm_pcicfg_base(XLP_IO_PCIE1_OFFSET(node)); 615 break; 616 case PIC_PCIE_2_IRQ: 617 base = nlm_pcicfg_base(XLP_IO_PCIE2_OFFSET(node)); 618 break; 619 case PIC_PCIE_3_IRQ: 620 base = nlm_pcicfg_base(XLP_IO_PCIE3_OFFSET(node)); 621 break; 622 default: 623 return; 624 } 625 626 nlm_write_pci_reg(base, reg, 0xFFFFFFFF); 627 return; 628} 629 630static int 631mips_platform_pcib_setup_intr(device_t dev, device_t child, 632 struct resource *irq, int flags, driver_filter_t *filt, 633 driver_intr_t *intr, void *arg, void **cookiep) 634{ 635 int error = 0; 636 int xlpirq; 637 void *extra_ack; 638 639 error = rman_activate_resource(irq); 640 if (error) 641 return error; 642 if (rman_get_start(irq) != rman_get_end(irq)) { 643 device_printf(dev, "Interrupt allocation %lu != %lu\n", 644 rman_get_start(irq), rman_get_end(irq)); 645 return (EINVAL); 646 } 647 xlpirq = rman_get_start(irq); 648 if (xlpirq == 0) 649 return (0); 650 651 if (strcmp(device_get_name(dev), "pcib") != 0) 652 return (0); 653 654 /* 655 * temporary hack for MSI, we support just one device per 656 * link, and assign the link interrupt to the device interrupt 657 */ 658 if (xlpirq >= 64) { 659 int node, val, link; 660 uint64_t base; 661 662 xlpirq -= 64; 663 if (xlpirq % 32 != 0) 664 return (0); 665 666 node = nlm_nodeid(); 667 link = xlpirq / 32; 668 base = nlm_pcicfg_base(XLP_IO_PCIE_OFFSET(node,link)); 669 670 /* MSI Interrupt Vector enable at bridge's configuration */ 671 nlm_write_pci_reg(base, PCIE_MSI_EN, PCIE_MSI_VECTOR_INT_EN); 672 673 val = nlm_read_pci_reg(base, PCIE_INT_EN0); 674 /* MSI Interrupt enable at bridge's configuration */ 675 nlm_write_pci_reg(base, PCIE_INT_EN0, 676 (val | PCIE_MSI_INT_EN)); 677 678 /* legacy interrupt disable at bridge */ 679 val = nlm_read_pci_reg(base, PCIE_BRIDGE_CMD); 680 nlm_write_pci_reg(base, PCIE_BRIDGE_CMD, 681 (val | PCIM_CMD_INTxDIS)); 682 683 /* MSI address update at bridge */ 684 nlm_write_pci_reg(base, PCIE_BRIDGE_MSI_ADDRL, 685 MSI_MIPS_ADDR_BASE); 686 nlm_write_pci_reg(base, PCIE_BRIDGE_MSI_ADDRH, 0); 687 688 val = nlm_read_pci_reg(base, PCIE_BRIDGE_MSI_CAP); 689 /* MSI capability enable at bridge */ 690 nlm_write_pci_reg(base, PCIE_BRIDGE_MSI_CAP, 691 (val | (PCIM_MSICTRL_MSI_ENABLE << 16) | 692 (PCIM_MSICTRL_MMC_32 << 16))); 693 694 xlpirq = xlp_pcie_link_irt(xlpirq / 32); 695 if (xlpirq == -1) 696 return (EINVAL); 697 xlpirq = xlp_irt_to_irq(xlpirq); 698 } 699 /* Set all irqs to CPU 0 for now */ 700 nlm_pic_write_irt_direct(xlp_pic_base, xlp_irq_to_irt(xlpirq), 1, 0, 701 PIC_LOCAL_SCHEDULING, xlpirq, 0); 702 extra_ack = NULL; 703 if (xlpirq >= PIC_PCIE_0_IRQ && xlpirq <= PIC_PCIE_3_IRQ) 704 extra_ack = bridge_pcie_ack; 705 xlp_establish_intr(device_get_name(child), filt, 706 intr, arg, xlpirq, flags, cookiep, extra_ack); 707 708 return (0); 709} 710 711static int 712mips_platform_pcib_teardown_intr(device_t dev, device_t child, 713 struct resource *irq, void *cookie) 714{ 715 if (strcmp(device_get_name(child), "pci") == 0) { 716 /* if needed reprogram the pic to clear pcix related entry */ 717 device_printf(dev, "teardown intr\n"); 718 } 719 return (bus_generic_teardown_intr(dev, child, irq, cookie)); 720} 721 722static struct resource * 723xlp_pcib_alloc_resource(device_t bus, device_t child, int type, int *rid, 724 u_long start, u_long end, u_long count, u_int flags) 725{ 726 struct rman *rm = NULL; 727 struct resource *rv; 728 void *va; 729 int needactivate = flags & RF_ACTIVE; 730 731 switch (type) { 732 case SYS_RES_IRQ: 733 rm = &irq_rman; 734 break; 735 736 case SYS_RES_IOPORT: 737 rm = &port_rman; 738 break; 739 740 case SYS_RES_MEMORY: 741 if (start >= EMUL_MEM_START && start <= EMUL_MEM_END) 742 rm = &emul_rman; 743 else 744 rm = &mem_rman; 745 break; 746 747 default: 748 return (0); 749 } 750 751 rv = rman_reserve_resource(rm, start, end, count, flags, child); 752 if (rv == NULL) 753 return (NULL); 754 755 rman_set_rid(rv, *rid); 756 757 if (type == SYS_RES_MEMORY || type == SYS_RES_IOPORT) { 758 va = pmap_mapdev(start, count); 759 rman_set_bushandle(rv, (bus_space_handle_t)va); 760 rman_set_bustag(rv, rmi_bus_space); 761 } 762 if (needactivate) { 763 if (bus_activate_resource(child, type, *rid, rv)) { 764 rman_release_resource(rv); 765 return (NULL); 766 } 767 } 768 return (rv); 769} 770 771static int 772xlp_pcib_release_resource(device_t bus, device_t child, int type, int rid, 773 struct resource *r) 774{ 775 776 return (rman_release_resource(r)); 777} 778 779static int 780xlp_pcib_activate_resource(device_t bus, device_t child, int type, int rid, 781 struct resource *r) 782{ 783 784 return (rman_activate_resource(r)); 785} 786 787static int 788xlp_pcib_deactivate_resource(device_t bus, device_t child, int type, int rid, 789 struct resource *r) 790{ 791 792 return (rman_deactivate_resource(r)); 793} 794 795static int 796mips_pcib_route_interrupt(device_t bus, device_t dev, int pin) 797{ 798 int irt, link; 799 800 /* 801 * Validate requested pin number. 802 */ 803 if ((pin < 1) || (pin > 4)) 804 return (255); 805 806 if (pci_get_bus(dev) == 0 && 807 pci_get_vendor(dev) == PCI_VENDOR_NETLOGIC) { 808 /* SoC devices */ 809 uint64_t pcibase; 810 int f, n, d, num; 811 812 f = pci_get_function(dev); 813 n = pci_get_slot(dev) / 8; 814 d = pci_get_slot(dev) % 8; 815 816 /* 817 * For PCIe links, return link IRT, for other SoC devices 818 * get the IRT from its PCIe header 819 */ 820 if (d == 1) { 821 irt = xlp_pcie_link_irt(f); 822 } else { 823 pcibase = nlm_pcicfg_base(XLP_HDR_OFFSET(n, 0, d, f)); 824 irt = nlm_irtstart(pcibase); 825 num = nlm_irtnum(pcibase); 826 if (num != 1) 827 device_printf(bus, "[%d:%d:%d] Error %d IRQs\n", 828 n, d, f, num); 829 } 830 } else { 831 /* Regular PCI devices */ 832 link = xlp_pcie_link(bus, dev); 833 irt = xlp_pcie_link_irt(link); 834 } 835 836 if (irt != -1) 837 return (xlp_irt_to_irq(irt)); 838 839 return (255); 840} 841 842static device_method_t xlp_pcib_methods[] = { 843 /* Device interface */ 844 DEVMETHOD(device_identify, xlp_pcib_identify), 845 DEVMETHOD(device_probe, xlp_pcib_probe), 846 DEVMETHOD(device_attach, xlp_pcib_attach), 847 848 /* Bus interface */ 849 DEVMETHOD(bus_read_ivar, xlp_pcib_read_ivar), 850 DEVMETHOD(bus_write_ivar, xlp_pcib_write_ivar), 851 DEVMETHOD(bus_alloc_resource, xlp_pcib_alloc_resource), 852 DEVMETHOD(bus_release_resource, xlp_pcib_release_resource), 853 DEVMETHOD(bus_activate_resource, xlp_pcib_activate_resource), 854 DEVMETHOD(bus_deactivate_resource, xlp_pcib_deactivate_resource), 855 DEVMETHOD(bus_setup_intr, mips_platform_pcib_setup_intr), 856 DEVMETHOD(bus_teardown_intr, mips_platform_pcib_teardown_intr), 857 858 /* pcib interface */ 859 DEVMETHOD(pcib_maxslots, xlp_pcib_maxslots), 860 DEVMETHOD(pcib_read_config, xlp_pcib_read_config), 861 DEVMETHOD(pcib_write_config, xlp_pcib_write_config), 862 DEVMETHOD(pcib_route_interrupt, mips_pcib_route_interrupt), 863 864 DEVMETHOD(pcib_alloc_msi, xlp_alloc_msi), 865 DEVMETHOD(pcib_release_msi, xlp_release_msi), 866 DEVMETHOD(pcib_map_msi, xlp_map_msi), 867 868 DEVMETHOD_END 869}; 870 871static driver_t xlp_pcib_driver = { 872 "pcib", 873 xlp_pcib_methods, 874 1, /* no softc */ 875}; 876 877DRIVER_MODULE(pcib, nexus, xlp_pcib_driver, pcib_devclass, 0, 0); 878