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