Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * arch/arm/mach-mv78xx0/pcie.c
0004  *
0005  * PCIe functions for Marvell MV78xx0 SoCs
0006  */
0007 
0008 #include <linux/kernel.h>
0009 #include <linux/pci.h>
0010 #include <linux/mbus.h>
0011 #include <video/vga.h>
0012 #include <asm/irq.h>
0013 #include <asm/mach/pci.h>
0014 #include <plat/pcie.h>
0015 #include "mv78xx0.h"
0016 #include "common.h"
0017 
0018 #define MV78XX0_MBUS_PCIE_MEM_TARGET(port, lane) ((port) ? 8 : 4)
0019 #define MV78XX0_MBUS_PCIE_MEM_ATTR(port, lane)   (0xf8 & ~(0x10 << (lane)))
0020 #define MV78XX0_MBUS_PCIE_IO_TARGET(port, lane)  ((port) ? 8 : 4)
0021 #define MV78XX0_MBUS_PCIE_IO_ATTR(port, lane)    (0xf0 & ~(0x10 << (lane)))
0022 
0023 struct pcie_port {
0024     u8          maj;
0025     u8          min;
0026     u8          root_bus_nr;
0027     void __iomem        *base;
0028     spinlock_t      conf_lock;
0029     char            mem_space_name[20];
0030     struct resource     res;
0031 };
0032 
0033 static struct pcie_port pcie_port[8];
0034 static int num_pcie_ports;
0035 static struct resource pcie_io_space;
0036 
0037 void __init mv78xx0_pcie_id(u32 *dev, u32 *rev)
0038 {
0039     *dev = orion_pcie_dev_id(PCIE00_VIRT_BASE);
0040     *rev = orion_pcie_rev(PCIE00_VIRT_BASE);
0041 }
0042 
0043 u32 pcie_port_size[8] = {
0044     0,
0045     0x30000000,
0046     0x10000000,
0047     0x10000000,
0048     0x08000000,
0049     0x08000000,
0050     0x08000000,
0051     0x04000000,
0052 };
0053 
0054 static void __init mv78xx0_pcie_preinit(void)
0055 {
0056     int i;
0057     u32 size_each;
0058     u32 start;
0059 
0060     pcie_io_space.name = "PCIe I/O Space";
0061     pcie_io_space.start = MV78XX0_PCIE_IO_PHYS_BASE(0);
0062     pcie_io_space.end =
0063         MV78XX0_PCIE_IO_PHYS_BASE(0) + MV78XX0_PCIE_IO_SIZE * 8 - 1;
0064     pcie_io_space.flags = IORESOURCE_MEM;
0065     if (request_resource(&iomem_resource, &pcie_io_space))
0066         panic("can't allocate PCIe I/O space");
0067 
0068     if (num_pcie_ports > 7)
0069         panic("invalid number of PCIe ports");
0070 
0071     size_each = pcie_port_size[num_pcie_ports];
0072 
0073     start = MV78XX0_PCIE_MEM_PHYS_BASE;
0074     for (i = 0; i < num_pcie_ports; i++) {
0075         struct pcie_port *pp = pcie_port + i;
0076 
0077         snprintf(pp->mem_space_name, sizeof(pp->mem_space_name),
0078             "PCIe %d.%d MEM", pp->maj, pp->min);
0079         pp->mem_space_name[sizeof(pp->mem_space_name) - 1] = 0;
0080         pp->res.name = pp->mem_space_name;
0081         pp->res.flags = IORESOURCE_MEM;
0082         pp->res.start = start;
0083         pp->res.end = start + size_each - 1;
0084         start += size_each;
0085 
0086         if (request_resource(&iomem_resource, &pp->res))
0087             panic("can't allocate PCIe MEM sub-space");
0088 
0089         mvebu_mbus_add_window_by_id(MV78XX0_MBUS_PCIE_MEM_TARGET(pp->maj, pp->min),
0090                         MV78XX0_MBUS_PCIE_MEM_ATTR(pp->maj, pp->min),
0091                         pp->res.start, resource_size(&pp->res));
0092         mvebu_mbus_add_window_remap_by_id(MV78XX0_MBUS_PCIE_IO_TARGET(pp->maj, pp->min),
0093                           MV78XX0_MBUS_PCIE_IO_ATTR(pp->maj, pp->min),
0094                           i * SZ_64K, SZ_64K, 0);
0095     }
0096 }
0097 
0098 static int __init mv78xx0_pcie_setup(int nr, struct pci_sys_data *sys)
0099 {
0100     struct pcie_port *pp;
0101     struct resource realio;
0102 
0103     if (nr >= num_pcie_ports)
0104         return 0;
0105 
0106     pp = &pcie_port[nr];
0107     sys->private_data = pp;
0108     pp->root_bus_nr = sys->busnr;
0109 
0110     /*
0111      * Generic PCIe unit setup.
0112      */
0113     orion_pcie_set_local_bus_nr(pp->base, sys->busnr);
0114     orion_pcie_setup(pp->base);
0115 
0116     realio.start = nr * SZ_64K;
0117     realio.end = realio.start + SZ_64K - 1;
0118     pci_remap_iospace(&realio, MV78XX0_PCIE_IO_PHYS_BASE(nr));
0119 
0120     pci_add_resource_offset(&sys->resources, &pp->res, sys->mem_offset);
0121 
0122     return 1;
0123 }
0124 
0125 static int pcie_valid_config(struct pcie_port *pp, int bus, int dev)
0126 {
0127     /*
0128      * Don't go out when trying to access nonexisting devices
0129      * on the local bus.
0130      */
0131     if (bus == pp->root_bus_nr && dev > 1)
0132         return 0;
0133 
0134     return 1;
0135 }
0136 
0137 static int pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
0138             int size, u32 *val)
0139 {
0140     struct pci_sys_data *sys = bus->sysdata;
0141     struct pcie_port *pp = sys->private_data;
0142     unsigned long flags;
0143     int ret;
0144 
0145     if (pcie_valid_config(pp, bus->number, PCI_SLOT(devfn)) == 0) {
0146         *val = 0xffffffff;
0147         return PCIBIOS_DEVICE_NOT_FOUND;
0148     }
0149 
0150     spin_lock_irqsave(&pp->conf_lock, flags);
0151     ret = orion_pcie_rd_conf(pp->base, bus, devfn, where, size, val);
0152     spin_unlock_irqrestore(&pp->conf_lock, flags);
0153 
0154     return ret;
0155 }
0156 
0157 static int pcie_wr_conf(struct pci_bus *bus, u32 devfn,
0158             int where, int size, u32 val)
0159 {
0160     struct pci_sys_data *sys = bus->sysdata;
0161     struct pcie_port *pp = sys->private_data;
0162     unsigned long flags;
0163     int ret;
0164 
0165     if (pcie_valid_config(pp, bus->number, PCI_SLOT(devfn)) == 0)
0166         return PCIBIOS_DEVICE_NOT_FOUND;
0167 
0168     spin_lock_irqsave(&pp->conf_lock, flags);
0169     ret = orion_pcie_wr_conf(pp->base, bus, devfn, where, size, val);
0170     spin_unlock_irqrestore(&pp->conf_lock, flags);
0171 
0172     return ret;
0173 }
0174 
0175 static struct pci_ops pcie_ops = {
0176     .read = pcie_rd_conf,
0177     .write = pcie_wr_conf,
0178 };
0179 
0180 /*
0181  * The root complex has a hardwired class of PCI_CLASS_MEMORY_OTHER, when it
0182  * is operating as a root complex this needs to be switched to
0183  * PCI_CLASS_BRIDGE_HOST or Linux will errantly try to process the BAR's on
0184  * the device. Decoding setup is handled by the orion code.
0185  */
0186 static void rc_pci_fixup(struct pci_dev *dev)
0187 {
0188     if (dev->bus->parent == NULL && dev->devfn == 0) {
0189         int i;
0190 
0191         dev->class &= 0xff;
0192         dev->class |= PCI_CLASS_BRIDGE_HOST << 8;
0193         for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
0194             dev->resource[i].start = 0;
0195             dev->resource[i].end   = 0;
0196             dev->resource[i].flags = 0;
0197         }
0198     }
0199 }
0200 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL, PCI_ANY_ID, rc_pci_fixup);
0201 
0202 static int __init mv78xx0_pcie_scan_bus(int nr, struct pci_host_bridge *bridge)
0203 {
0204     struct pci_sys_data *sys = pci_host_bridge_priv(bridge);
0205 
0206     if (nr >= num_pcie_ports) {
0207         BUG();
0208         return -EINVAL;
0209     }
0210 
0211     list_splice_init(&sys->resources, &bridge->windows);
0212     bridge->dev.parent = NULL;
0213     bridge->sysdata = sys;
0214     bridge->busnr = sys->busnr;
0215     bridge->ops = &pcie_ops;
0216 
0217     return pci_scan_root_bus_bridge(bridge);
0218 }
0219 
0220 static int __init mv78xx0_pcie_map_irq(const struct pci_dev *dev, u8 slot,
0221     u8 pin)
0222 {
0223     struct pci_sys_data *sys = dev->bus->sysdata;
0224     struct pcie_port *pp = sys->private_data;
0225 
0226     return IRQ_MV78XX0_PCIE_00 + (pp->maj << 2) + pp->min;
0227 }
0228 
0229 static struct hw_pci mv78xx0_pci __initdata = {
0230     .nr_controllers = 8,
0231     .preinit    = mv78xx0_pcie_preinit,
0232     .setup      = mv78xx0_pcie_setup,
0233     .scan       = mv78xx0_pcie_scan_bus,
0234     .map_irq    = mv78xx0_pcie_map_irq,
0235 };
0236 
0237 static void __init add_pcie_port(int maj, int min, void __iomem *base)
0238 {
0239     printk(KERN_INFO "MV78xx0 PCIe port %d.%d: ", maj, min);
0240 
0241     if (orion_pcie_link_up(base)) {
0242         struct pcie_port *pp = &pcie_port[num_pcie_ports++];
0243 
0244         printk("link up\n");
0245 
0246         pp->maj = maj;
0247         pp->min = min;
0248         pp->root_bus_nr = -1;
0249         pp->base = base;
0250         spin_lock_init(&pp->conf_lock);
0251         memset(&pp->res, 0, sizeof(pp->res));
0252     } else {
0253         printk("link down, ignoring\n");
0254     }
0255 }
0256 
0257 void __init mv78xx0_pcie_init(int init_port0, int init_port1)
0258 {
0259     vga_base = MV78XX0_PCIE_MEM_PHYS_BASE;
0260 
0261     if (init_port0) {
0262         add_pcie_port(0, 0, PCIE00_VIRT_BASE);
0263         if (!orion_pcie_x4_mode(PCIE00_VIRT_BASE)) {
0264             add_pcie_port(0, 1, PCIE01_VIRT_BASE);
0265             add_pcie_port(0, 2, PCIE02_VIRT_BASE);
0266             add_pcie_port(0, 3, PCIE03_VIRT_BASE);
0267         }
0268     }
0269 
0270     if (init_port1) {
0271         add_pcie_port(1, 0, PCIE10_VIRT_BASE);
0272         if (!orion_pcie_x4_mode((void __iomem *)PCIE10_VIRT_BASE)) {
0273             add_pcie_port(1, 1, PCIE11_VIRT_BASE);
0274             add_pcie_port(1, 2, PCIE12_VIRT_BASE);
0275             add_pcie_port(1, 3, PCIE13_VIRT_BASE);
0276         }
0277     }
0278 
0279     pci_common_init(&mv78xx0_pci);
0280 }