18c2ecf20Sopenharmony_ci/* 28c2ecf20Sopenharmony_ci * Copyright 2003-2011 NetLogic Microsystems, Inc. (NetLogic). All rights 38c2ecf20Sopenharmony_ci * reserved. 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * This software is available to you under a choice of one of two 68c2ecf20Sopenharmony_ci * licenses. You may choose to be licensed under the terms of the GNU 78c2ecf20Sopenharmony_ci * General Public License (GPL) Version 2, available from the file 88c2ecf20Sopenharmony_ci * COPYING in the main directory of this source tree, or the NetLogic 98c2ecf20Sopenharmony_ci * license below: 108c2ecf20Sopenharmony_ci * 118c2ecf20Sopenharmony_ci * Redistribution and use in source and binary forms, with or without 128c2ecf20Sopenharmony_ci * modification, are permitted provided that the following conditions 138c2ecf20Sopenharmony_ci * are met: 148c2ecf20Sopenharmony_ci * 158c2ecf20Sopenharmony_ci * 1. Redistributions of source code must retain the above copyright 168c2ecf20Sopenharmony_ci * notice, this list of conditions and the following disclaimer. 178c2ecf20Sopenharmony_ci * 2. Redistributions in binary form must reproduce the above copyright 188c2ecf20Sopenharmony_ci * notice, this list of conditions and the following disclaimer in 198c2ecf20Sopenharmony_ci * the documentation and/or other materials provided with the 208c2ecf20Sopenharmony_ci * distribution. 218c2ecf20Sopenharmony_ci * 228c2ecf20Sopenharmony_ci * THIS SOFTWARE IS PROVIDED BY NETLOGIC ``AS IS'' AND ANY EXPRESS OR 238c2ecf20Sopenharmony_ci * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 248c2ecf20Sopenharmony_ci * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 258c2ecf20Sopenharmony_ci * ARE DISCLAIMED. IN NO EVENT SHALL NETLOGIC OR CONTRIBUTORS BE LIABLE 268c2ecf20Sopenharmony_ci * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 278c2ecf20Sopenharmony_ci * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 288c2ecf20Sopenharmony_ci * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 298c2ecf20Sopenharmony_ci * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 308c2ecf20Sopenharmony_ci * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 318c2ecf20Sopenharmony_ci * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 328c2ecf20Sopenharmony_ci * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 338c2ecf20Sopenharmony_ci */ 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_ci#include <linux/types.h> 368c2ecf20Sopenharmony_ci#include <linux/pci.h> 378c2ecf20Sopenharmony_ci#include <linux/kernel.h> 388c2ecf20Sopenharmony_ci#include <linux/init.h> 398c2ecf20Sopenharmony_ci#include <linux/msi.h> 408c2ecf20Sopenharmony_ci#include <linux/mm.h> 418c2ecf20Sopenharmony_ci#include <linux/irq.h> 428c2ecf20Sopenharmony_ci#include <linux/irqdesc.h> 438c2ecf20Sopenharmony_ci#include <linux/console.h> 448c2ecf20Sopenharmony_ci#include <linux/pci_regs.h> 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_ci#include <asm/io.h> 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_ci#include <asm/netlogic/interrupt.h> 498c2ecf20Sopenharmony_ci#include <asm/netlogic/haldefs.h> 508c2ecf20Sopenharmony_ci#include <asm/netlogic/common.h> 518c2ecf20Sopenharmony_ci 528c2ecf20Sopenharmony_ci#include <asm/netlogic/xlr/msidef.h> 538c2ecf20Sopenharmony_ci#include <asm/netlogic/xlr/iomap.h> 548c2ecf20Sopenharmony_ci#include <asm/netlogic/xlr/pic.h> 558c2ecf20Sopenharmony_ci#include <asm/netlogic/xlr/xlr.h> 568c2ecf20Sopenharmony_ci 578c2ecf20Sopenharmony_cistatic void *pci_config_base; 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_ci#define pci_cfg_addr(bus, devfn, off) (((bus) << 16) | ((devfn) << 8) | (off)) 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_ci/* PCI ops */ 628c2ecf20Sopenharmony_cistatic inline u32 pci_cfg_read_32bit(struct pci_bus *bus, unsigned int devfn, 638c2ecf20Sopenharmony_ci int where) 648c2ecf20Sopenharmony_ci{ 658c2ecf20Sopenharmony_ci u32 data; 668c2ecf20Sopenharmony_ci u32 *cfgaddr; 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_ci cfgaddr = (u32 *)(pci_config_base + 698c2ecf20Sopenharmony_ci pci_cfg_addr(bus->number, devfn, where & ~3)); 708c2ecf20Sopenharmony_ci data = *cfgaddr; 718c2ecf20Sopenharmony_ci return cpu_to_le32(data); 728c2ecf20Sopenharmony_ci} 738c2ecf20Sopenharmony_ci 748c2ecf20Sopenharmony_cistatic inline void pci_cfg_write_32bit(struct pci_bus *bus, unsigned int devfn, 758c2ecf20Sopenharmony_ci int where, u32 data) 768c2ecf20Sopenharmony_ci{ 778c2ecf20Sopenharmony_ci u32 *cfgaddr; 788c2ecf20Sopenharmony_ci 798c2ecf20Sopenharmony_ci cfgaddr = (u32 *)(pci_config_base + 808c2ecf20Sopenharmony_ci pci_cfg_addr(bus->number, devfn, where & ~3)); 818c2ecf20Sopenharmony_ci *cfgaddr = cpu_to_le32(data); 828c2ecf20Sopenharmony_ci} 838c2ecf20Sopenharmony_ci 848c2ecf20Sopenharmony_cistatic int nlm_pcibios_read(struct pci_bus *bus, unsigned int devfn, 858c2ecf20Sopenharmony_ci int where, int size, u32 *val) 868c2ecf20Sopenharmony_ci{ 878c2ecf20Sopenharmony_ci u32 data; 888c2ecf20Sopenharmony_ci 898c2ecf20Sopenharmony_ci if ((size == 2) && (where & 1)) 908c2ecf20Sopenharmony_ci return PCIBIOS_BAD_REGISTER_NUMBER; 918c2ecf20Sopenharmony_ci else if ((size == 4) && (where & 3)) 928c2ecf20Sopenharmony_ci return PCIBIOS_BAD_REGISTER_NUMBER; 938c2ecf20Sopenharmony_ci 948c2ecf20Sopenharmony_ci data = pci_cfg_read_32bit(bus, devfn, where); 958c2ecf20Sopenharmony_ci 968c2ecf20Sopenharmony_ci if (size == 1) 978c2ecf20Sopenharmony_ci *val = (data >> ((where & 3) << 3)) & 0xff; 988c2ecf20Sopenharmony_ci else if (size == 2) 998c2ecf20Sopenharmony_ci *val = (data >> ((where & 3) << 3)) & 0xffff; 1008c2ecf20Sopenharmony_ci else 1018c2ecf20Sopenharmony_ci *val = data; 1028c2ecf20Sopenharmony_ci 1038c2ecf20Sopenharmony_ci return PCIBIOS_SUCCESSFUL; 1048c2ecf20Sopenharmony_ci} 1058c2ecf20Sopenharmony_ci 1068c2ecf20Sopenharmony_ci 1078c2ecf20Sopenharmony_cistatic int nlm_pcibios_write(struct pci_bus *bus, unsigned int devfn, 1088c2ecf20Sopenharmony_ci int where, int size, u32 val) 1098c2ecf20Sopenharmony_ci{ 1108c2ecf20Sopenharmony_ci u32 data; 1118c2ecf20Sopenharmony_ci 1128c2ecf20Sopenharmony_ci if ((size == 2) && (where & 1)) 1138c2ecf20Sopenharmony_ci return PCIBIOS_BAD_REGISTER_NUMBER; 1148c2ecf20Sopenharmony_ci else if ((size == 4) && (where & 3)) 1158c2ecf20Sopenharmony_ci return PCIBIOS_BAD_REGISTER_NUMBER; 1168c2ecf20Sopenharmony_ci 1178c2ecf20Sopenharmony_ci data = pci_cfg_read_32bit(bus, devfn, where); 1188c2ecf20Sopenharmony_ci 1198c2ecf20Sopenharmony_ci if (size == 1) 1208c2ecf20Sopenharmony_ci data = (data & ~(0xff << ((where & 3) << 3))) | 1218c2ecf20Sopenharmony_ci (val << ((where & 3) << 3)); 1228c2ecf20Sopenharmony_ci else if (size == 2) 1238c2ecf20Sopenharmony_ci data = (data & ~(0xffff << ((where & 3) << 3))) | 1248c2ecf20Sopenharmony_ci (val << ((where & 3) << 3)); 1258c2ecf20Sopenharmony_ci else 1268c2ecf20Sopenharmony_ci data = val; 1278c2ecf20Sopenharmony_ci 1288c2ecf20Sopenharmony_ci pci_cfg_write_32bit(bus, devfn, where, data); 1298c2ecf20Sopenharmony_ci 1308c2ecf20Sopenharmony_ci return PCIBIOS_SUCCESSFUL; 1318c2ecf20Sopenharmony_ci} 1328c2ecf20Sopenharmony_ci 1338c2ecf20Sopenharmony_cistruct pci_ops nlm_pci_ops = { 1348c2ecf20Sopenharmony_ci .read = nlm_pcibios_read, 1358c2ecf20Sopenharmony_ci .write = nlm_pcibios_write 1368c2ecf20Sopenharmony_ci}; 1378c2ecf20Sopenharmony_ci 1388c2ecf20Sopenharmony_cistatic struct resource nlm_pci_mem_resource = { 1398c2ecf20Sopenharmony_ci .name = "XLR PCI MEM", 1408c2ecf20Sopenharmony_ci .start = 0xd0000000UL, /* 256MB PCI mem @ 0xd000_0000 */ 1418c2ecf20Sopenharmony_ci .end = 0xdfffffffUL, 1428c2ecf20Sopenharmony_ci .flags = IORESOURCE_MEM, 1438c2ecf20Sopenharmony_ci}; 1448c2ecf20Sopenharmony_ci 1458c2ecf20Sopenharmony_cistatic struct resource nlm_pci_io_resource = { 1468c2ecf20Sopenharmony_ci .name = "XLR IO MEM", 1478c2ecf20Sopenharmony_ci .start = 0x10000000UL, /* 16MB PCI IO @ 0x1000_0000 */ 1488c2ecf20Sopenharmony_ci .end = 0x100fffffUL, 1498c2ecf20Sopenharmony_ci .flags = IORESOURCE_IO, 1508c2ecf20Sopenharmony_ci}; 1518c2ecf20Sopenharmony_ci 1528c2ecf20Sopenharmony_cistruct pci_controller nlm_pci_controller = { 1538c2ecf20Sopenharmony_ci .index = 0, 1548c2ecf20Sopenharmony_ci .pci_ops = &nlm_pci_ops, 1558c2ecf20Sopenharmony_ci .mem_resource = &nlm_pci_mem_resource, 1568c2ecf20Sopenharmony_ci .mem_offset = 0x00000000UL, 1578c2ecf20Sopenharmony_ci .io_resource = &nlm_pci_io_resource, 1588c2ecf20Sopenharmony_ci .io_offset = 0x00000000UL, 1598c2ecf20Sopenharmony_ci}; 1608c2ecf20Sopenharmony_ci 1618c2ecf20Sopenharmony_ci/* 1628c2ecf20Sopenharmony_ci * The top level PCIe links on the XLS PCIe controller appear as 1638c2ecf20Sopenharmony_ci * bridges. Given a device, this function finds which link it is 1648c2ecf20Sopenharmony_ci * on. 1658c2ecf20Sopenharmony_ci */ 1668c2ecf20Sopenharmony_cistatic struct pci_dev *xls_get_pcie_link(const struct pci_dev *dev) 1678c2ecf20Sopenharmony_ci{ 1688c2ecf20Sopenharmony_ci struct pci_bus *bus, *p; 1698c2ecf20Sopenharmony_ci 1708c2ecf20Sopenharmony_ci /* Find the bridge on bus 0 */ 1718c2ecf20Sopenharmony_ci bus = dev->bus; 1728c2ecf20Sopenharmony_ci for (p = bus->parent; p && p->number != 0; p = p->parent) 1738c2ecf20Sopenharmony_ci bus = p; 1748c2ecf20Sopenharmony_ci 1758c2ecf20Sopenharmony_ci return p ? bus->self : NULL; 1768c2ecf20Sopenharmony_ci} 1778c2ecf20Sopenharmony_ci 1788c2ecf20Sopenharmony_cistatic int nlm_pci_link_to_irq(int link) 1798c2ecf20Sopenharmony_ci{ 1808c2ecf20Sopenharmony_ci switch (link) { 1818c2ecf20Sopenharmony_ci case 0: 1828c2ecf20Sopenharmony_ci return PIC_PCIE_LINK0_IRQ; 1838c2ecf20Sopenharmony_ci case 1: 1848c2ecf20Sopenharmony_ci return PIC_PCIE_LINK1_IRQ; 1858c2ecf20Sopenharmony_ci case 2: 1868c2ecf20Sopenharmony_ci if (nlm_chip_is_xls_b()) 1878c2ecf20Sopenharmony_ci return PIC_PCIE_XLSB0_LINK2_IRQ; 1888c2ecf20Sopenharmony_ci else 1898c2ecf20Sopenharmony_ci return PIC_PCIE_LINK2_IRQ; 1908c2ecf20Sopenharmony_ci case 3: 1918c2ecf20Sopenharmony_ci if (nlm_chip_is_xls_b()) 1928c2ecf20Sopenharmony_ci return PIC_PCIE_XLSB0_LINK3_IRQ; 1938c2ecf20Sopenharmony_ci else 1948c2ecf20Sopenharmony_ci return PIC_PCIE_LINK3_IRQ; 1958c2ecf20Sopenharmony_ci } 1968c2ecf20Sopenharmony_ci WARN(1, "Unexpected link %d\n", link); 1978c2ecf20Sopenharmony_ci return 0; 1988c2ecf20Sopenharmony_ci} 1998c2ecf20Sopenharmony_ci 2008c2ecf20Sopenharmony_cistatic int get_irq_vector(const struct pci_dev *dev) 2018c2ecf20Sopenharmony_ci{ 2028c2ecf20Sopenharmony_ci struct pci_dev *lnk; 2038c2ecf20Sopenharmony_ci int link; 2048c2ecf20Sopenharmony_ci 2058c2ecf20Sopenharmony_ci if (!nlm_chip_is_xls()) 2068c2ecf20Sopenharmony_ci return PIC_PCIX_IRQ; /* for XLR just one IRQ */ 2078c2ecf20Sopenharmony_ci 2088c2ecf20Sopenharmony_ci lnk = xls_get_pcie_link(dev); 2098c2ecf20Sopenharmony_ci if (lnk == NULL) 2108c2ecf20Sopenharmony_ci return 0; 2118c2ecf20Sopenharmony_ci 2128c2ecf20Sopenharmony_ci link = PCI_SLOT(lnk->devfn); 2138c2ecf20Sopenharmony_ci return nlm_pci_link_to_irq(link); 2148c2ecf20Sopenharmony_ci} 2158c2ecf20Sopenharmony_ci 2168c2ecf20Sopenharmony_ci#ifdef CONFIG_PCI_MSI 2178c2ecf20Sopenharmony_civoid arch_teardown_msi_irq(unsigned int irq) 2188c2ecf20Sopenharmony_ci{ 2198c2ecf20Sopenharmony_ci} 2208c2ecf20Sopenharmony_ci 2218c2ecf20Sopenharmony_ciint arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc) 2228c2ecf20Sopenharmony_ci{ 2238c2ecf20Sopenharmony_ci struct msi_msg msg; 2248c2ecf20Sopenharmony_ci struct pci_dev *lnk; 2258c2ecf20Sopenharmony_ci int irq, ret; 2268c2ecf20Sopenharmony_ci u16 val; 2278c2ecf20Sopenharmony_ci 2288c2ecf20Sopenharmony_ci /* MSI not supported on XLR */ 2298c2ecf20Sopenharmony_ci if (!nlm_chip_is_xls()) 2308c2ecf20Sopenharmony_ci return 1; 2318c2ecf20Sopenharmony_ci 2328c2ecf20Sopenharmony_ci /* 2338c2ecf20Sopenharmony_ci * Enable MSI on the XLS PCIe controller bridge which was disabled 2348c2ecf20Sopenharmony_ci * at enumeration, the bridge MSI capability is at 0x50 2358c2ecf20Sopenharmony_ci */ 2368c2ecf20Sopenharmony_ci lnk = xls_get_pcie_link(dev); 2378c2ecf20Sopenharmony_ci if (lnk == NULL) 2388c2ecf20Sopenharmony_ci return 1; 2398c2ecf20Sopenharmony_ci 2408c2ecf20Sopenharmony_ci pci_read_config_word(lnk, 0x50 + PCI_MSI_FLAGS, &val); 2418c2ecf20Sopenharmony_ci if ((val & PCI_MSI_FLAGS_ENABLE) == 0) { 2428c2ecf20Sopenharmony_ci val |= PCI_MSI_FLAGS_ENABLE; 2438c2ecf20Sopenharmony_ci pci_write_config_word(lnk, 0x50 + PCI_MSI_FLAGS, val); 2448c2ecf20Sopenharmony_ci } 2458c2ecf20Sopenharmony_ci 2468c2ecf20Sopenharmony_ci irq = get_irq_vector(dev); 2478c2ecf20Sopenharmony_ci if (irq <= 0) 2488c2ecf20Sopenharmony_ci return 1; 2498c2ecf20Sopenharmony_ci 2508c2ecf20Sopenharmony_ci msg.address_hi = MSI_ADDR_BASE_HI; 2518c2ecf20Sopenharmony_ci msg.address_lo = MSI_ADDR_BASE_LO | 2528c2ecf20Sopenharmony_ci MSI_ADDR_DEST_MODE_PHYSICAL | 2538c2ecf20Sopenharmony_ci MSI_ADDR_REDIRECTION_CPU; 2548c2ecf20Sopenharmony_ci 2558c2ecf20Sopenharmony_ci msg.data = MSI_DATA_TRIGGER_EDGE | 2568c2ecf20Sopenharmony_ci MSI_DATA_LEVEL_ASSERT | 2578c2ecf20Sopenharmony_ci MSI_DATA_DELIVERY_FIXED; 2588c2ecf20Sopenharmony_ci 2598c2ecf20Sopenharmony_ci ret = irq_set_msi_desc(irq, desc); 2608c2ecf20Sopenharmony_ci if (ret < 0) 2618c2ecf20Sopenharmony_ci return ret; 2628c2ecf20Sopenharmony_ci 2638c2ecf20Sopenharmony_ci pci_write_msi_msg(irq, &msg); 2648c2ecf20Sopenharmony_ci return 0; 2658c2ecf20Sopenharmony_ci} 2668c2ecf20Sopenharmony_ci#endif 2678c2ecf20Sopenharmony_ci 2688c2ecf20Sopenharmony_ci/* Extra ACK needed for XLR on chip PCI controller */ 2698c2ecf20Sopenharmony_cistatic void xlr_pci_ack(struct irq_data *d) 2708c2ecf20Sopenharmony_ci{ 2718c2ecf20Sopenharmony_ci uint64_t pcibase = nlm_mmio_base(NETLOGIC_IO_PCIX_OFFSET); 2728c2ecf20Sopenharmony_ci 2738c2ecf20Sopenharmony_ci nlm_read_reg(pcibase, (0x140 >> 2)); 2748c2ecf20Sopenharmony_ci} 2758c2ecf20Sopenharmony_ci 2768c2ecf20Sopenharmony_ci/* Extra ACK needed for XLS on chip PCIe controller */ 2778c2ecf20Sopenharmony_cistatic void xls_pcie_ack(struct irq_data *d) 2788c2ecf20Sopenharmony_ci{ 2798c2ecf20Sopenharmony_ci uint64_t pciebase_le = nlm_mmio_base(NETLOGIC_IO_PCIE_1_OFFSET); 2808c2ecf20Sopenharmony_ci 2818c2ecf20Sopenharmony_ci switch (d->irq) { 2828c2ecf20Sopenharmony_ci case PIC_PCIE_LINK0_IRQ: 2838c2ecf20Sopenharmony_ci nlm_write_reg(pciebase_le, (0x90 >> 2), 0xffffffff); 2848c2ecf20Sopenharmony_ci break; 2858c2ecf20Sopenharmony_ci case PIC_PCIE_LINK1_IRQ: 2868c2ecf20Sopenharmony_ci nlm_write_reg(pciebase_le, (0x94 >> 2), 0xffffffff); 2878c2ecf20Sopenharmony_ci break; 2888c2ecf20Sopenharmony_ci case PIC_PCIE_LINK2_IRQ: 2898c2ecf20Sopenharmony_ci nlm_write_reg(pciebase_le, (0x190 >> 2), 0xffffffff); 2908c2ecf20Sopenharmony_ci break; 2918c2ecf20Sopenharmony_ci case PIC_PCIE_LINK3_IRQ: 2928c2ecf20Sopenharmony_ci nlm_write_reg(pciebase_le, (0x194 >> 2), 0xffffffff); 2938c2ecf20Sopenharmony_ci break; 2948c2ecf20Sopenharmony_ci } 2958c2ecf20Sopenharmony_ci} 2968c2ecf20Sopenharmony_ci 2978c2ecf20Sopenharmony_ci/* For XLS B silicon, the 3,4 PCI interrupts are different */ 2988c2ecf20Sopenharmony_cistatic void xls_pcie_ack_b(struct irq_data *d) 2998c2ecf20Sopenharmony_ci{ 3008c2ecf20Sopenharmony_ci uint64_t pciebase_le = nlm_mmio_base(NETLOGIC_IO_PCIE_1_OFFSET); 3018c2ecf20Sopenharmony_ci 3028c2ecf20Sopenharmony_ci switch (d->irq) { 3038c2ecf20Sopenharmony_ci case PIC_PCIE_LINK0_IRQ: 3048c2ecf20Sopenharmony_ci nlm_write_reg(pciebase_le, (0x90 >> 2), 0xffffffff); 3058c2ecf20Sopenharmony_ci break; 3068c2ecf20Sopenharmony_ci case PIC_PCIE_LINK1_IRQ: 3078c2ecf20Sopenharmony_ci nlm_write_reg(pciebase_le, (0x94 >> 2), 0xffffffff); 3088c2ecf20Sopenharmony_ci break; 3098c2ecf20Sopenharmony_ci case PIC_PCIE_XLSB0_LINK2_IRQ: 3108c2ecf20Sopenharmony_ci nlm_write_reg(pciebase_le, (0x190 >> 2), 0xffffffff); 3118c2ecf20Sopenharmony_ci break; 3128c2ecf20Sopenharmony_ci case PIC_PCIE_XLSB0_LINK3_IRQ: 3138c2ecf20Sopenharmony_ci nlm_write_reg(pciebase_le, (0x194 >> 2), 0xffffffff); 3148c2ecf20Sopenharmony_ci break; 3158c2ecf20Sopenharmony_ci } 3168c2ecf20Sopenharmony_ci} 3178c2ecf20Sopenharmony_ci 3188c2ecf20Sopenharmony_ciint pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) 3198c2ecf20Sopenharmony_ci{ 3208c2ecf20Sopenharmony_ci return get_irq_vector(dev); 3218c2ecf20Sopenharmony_ci} 3228c2ecf20Sopenharmony_ci 3238c2ecf20Sopenharmony_ci/* Do platform specific device initialization at pci_enable_device() time */ 3248c2ecf20Sopenharmony_ciint pcibios_plat_dev_init(struct pci_dev *dev) 3258c2ecf20Sopenharmony_ci{ 3268c2ecf20Sopenharmony_ci return 0; 3278c2ecf20Sopenharmony_ci} 3288c2ecf20Sopenharmony_ci 3298c2ecf20Sopenharmony_cistatic int __init pcibios_init(void) 3308c2ecf20Sopenharmony_ci{ 3318c2ecf20Sopenharmony_ci void (*extra_ack)(struct irq_data *); 3328c2ecf20Sopenharmony_ci int link, irq; 3338c2ecf20Sopenharmony_ci 3348c2ecf20Sopenharmony_ci /* PSB assigns PCI resources */ 3358c2ecf20Sopenharmony_ci pci_set_flags(PCI_PROBE_ONLY); 3368c2ecf20Sopenharmony_ci pci_config_base = ioremap(DEFAULT_PCI_CONFIG_BASE, 16 << 20); 3378c2ecf20Sopenharmony_ci 3388c2ecf20Sopenharmony_ci /* Extend IO port for memory mapped io */ 3398c2ecf20Sopenharmony_ci ioport_resource.start = 0; 3408c2ecf20Sopenharmony_ci ioport_resource.end = ~0; 3418c2ecf20Sopenharmony_ci 3428c2ecf20Sopenharmony_ci set_io_port_base(CKSEG1); 3438c2ecf20Sopenharmony_ci nlm_pci_controller.io_map_base = CKSEG1; 3448c2ecf20Sopenharmony_ci 3458c2ecf20Sopenharmony_ci pr_info("Registering XLR/XLS PCIX/PCIE Controller.\n"); 3468c2ecf20Sopenharmony_ci register_pci_controller(&nlm_pci_controller); 3478c2ecf20Sopenharmony_ci 3488c2ecf20Sopenharmony_ci /* 3498c2ecf20Sopenharmony_ci * For PCI interrupts, we need to ack the PCI controller too, overload 3508c2ecf20Sopenharmony_ci * irq handler data to do this 3518c2ecf20Sopenharmony_ci */ 3528c2ecf20Sopenharmony_ci if (!nlm_chip_is_xls()) { 3538c2ecf20Sopenharmony_ci /* XLR PCI controller ACK */ 3548c2ecf20Sopenharmony_ci nlm_set_pic_extra_ack(0, PIC_PCIX_IRQ, xlr_pci_ack); 3558c2ecf20Sopenharmony_ci } else { 3568c2ecf20Sopenharmony_ci if (nlm_chip_is_xls_b()) 3578c2ecf20Sopenharmony_ci extra_ack = xls_pcie_ack_b; 3588c2ecf20Sopenharmony_ci else 3598c2ecf20Sopenharmony_ci extra_ack = xls_pcie_ack; 3608c2ecf20Sopenharmony_ci for (link = 0; link < 4; link++) { 3618c2ecf20Sopenharmony_ci irq = nlm_pci_link_to_irq(link); 3628c2ecf20Sopenharmony_ci nlm_set_pic_extra_ack(0, irq, extra_ack); 3638c2ecf20Sopenharmony_ci } 3648c2ecf20Sopenharmony_ci } 3658c2ecf20Sopenharmony_ci return 0; 3668c2ecf20Sopenharmony_ci} 3678c2ecf20Sopenharmony_ci 3688c2ecf20Sopenharmony_ciarch_initcall(pcibios_init); 369