1 /* 2 * arch/arm/mach-mv78xx0/pcie.c 3 * 4 * PCIe functions for Marvell MV78xx0 SoCs 5 * 6 * This file is licensed under the terms of the GNU General Public 7 * License version 2. This program is licensed "as is" without any 8 * warranty of any kind, whether express or implied. 9 */ 10 11 #include <linux/kernel.h> 12 #include <linux/pci.h> 13 #include <linux/mbus.h> 14 #include <asm/irq.h> 15 #include <asm/mach/pci.h> 16 #include <plat/pcie.h> 17 #include "common.h" 18 19 struct pcie_port { 20 u8 maj; 21 u8 min; 22 u8 root_bus_nr; 23 void __iomem *base; 24 spinlock_t conf_lock; 25 char io_space_name[16]; 26 char mem_space_name[16]; 27 struct resource res[2]; 28 }; 29 30 static struct pcie_port pcie_port[8]; 31 static int num_pcie_ports; 32 static struct resource pcie_io_space; 33 static struct resource pcie_mem_space; 34 35 36 void __init mv78xx0_pcie_id(u32 *dev, u32 *rev) 37 { 38 *dev = orion_pcie_dev_id((void __iomem *)PCIE00_VIRT_BASE); 39 *rev = orion_pcie_rev((void __iomem *)PCIE00_VIRT_BASE); 40 } 41 42 static void __init mv78xx0_pcie_preinit(void) 43 { 44 int i; 45 u32 size_each; 46 u32 start; 47 int win; 48 49 pcie_io_space.name = "PCIe I/O Space"; 50 pcie_io_space.start = MV78XX0_PCIE_IO_PHYS_BASE(0); 51 pcie_io_space.end = 52 MV78XX0_PCIE_IO_PHYS_BASE(0) + MV78XX0_PCIE_IO_SIZE * 8 - 1; 53 pcie_io_space.flags = IORESOURCE_IO; 54 if (request_resource(&iomem_resource, &pcie_io_space)) 55 panic("can't allocate PCIe I/O space"); 56 57 pcie_mem_space.name = "PCIe MEM Space"; 58 pcie_mem_space.start = MV78XX0_PCIE_MEM_PHYS_BASE; 59 pcie_mem_space.end = 60 MV78XX0_PCIE_MEM_PHYS_BASE + MV78XX0_PCIE_MEM_SIZE - 1; 61 pcie_mem_space.flags = IORESOURCE_MEM; 62 if (request_resource(&iomem_resource, &pcie_mem_space)) 63 panic("can't allocate PCIe MEM space"); 64 65 for (i = 0; i < num_pcie_ports; i++) { 66 struct pcie_port *pp = pcie_port + i; 67 68 snprintf(pp->io_space_name, sizeof(pp->io_space_name), 69 "PCIe %d.%d I/O", pp->maj, pp->min); 70 pp->io_space_name[sizeof(pp->io_space_name) - 1] = 0; 71 pp->res[0].name = pp->io_space_name; 72 pp->res[0].start = MV78XX0_PCIE_IO_PHYS_BASE(i); 73 pp->res[0].end = pp->res[0].start + MV78XX0_PCIE_IO_SIZE - 1; 74 pp->res[0].flags = IORESOURCE_IO; 75 76 snprintf(pp->mem_space_name, sizeof(pp->mem_space_name), 77 "PCIe %d.%d MEM", pp->maj, pp->min); 78 pp->mem_space_name[sizeof(pp->mem_space_name) - 1] = 0; 79 pp->res[1].name = pp->mem_space_name; 80 pp->res[1].flags = IORESOURCE_MEM; 81 } 82 83 switch (num_pcie_ports) { 84 case 0: 85 size_each = 0; 86 break; 87 88 case 1: 89 size_each = 0x30000000; 90 break; 91 92 case 2 ... 3: 93 size_each = 0x10000000; 94 break; 95 96 case 4 ... 6: 97 size_each = 0x08000000; 98 break; 99 100 case 7: 101 size_each = 0x04000000; 102 break; 103 104 default: 105 panic("invalid number of PCIe ports"); 106 } 107 108 start = MV78XX0_PCIE_MEM_PHYS_BASE; 109 for (i = 0; i < num_pcie_ports; i++) { 110 struct pcie_port *pp = pcie_port + i; 111 112 pp->res[1].start = start; 113 pp->res[1].end = start + size_each - 1; 114 start += size_each; 115 } 116 117 for (i = 0; i < num_pcie_ports; i++) { 118 struct pcie_port *pp = pcie_port + i; 119 120 if (request_resource(&pcie_io_space, &pp->res[0])) 121 panic("can't allocate PCIe I/O sub-space"); 122 123 if (request_resource(&pcie_mem_space, &pp->res[1])) 124 panic("can't allocate PCIe MEM sub-space"); 125 } 126 127 win = 0; 128 for (i = 0; i < num_pcie_ports; i++) { 129 struct pcie_port *pp = pcie_port + i; 130 131 mv78xx0_setup_pcie_io_win(win++, pp->res[0].start, 132 pp->res[0].end - pp->res[0].start + 1, 133 pp->maj, pp->min); 134 135 mv78xx0_setup_pcie_mem_win(win++, pp->res[1].start, 136 pp->res[1].end - pp->res[1].start + 1, 137 pp->maj, pp->min); 138 } 139 } 140 141 static int __init mv78xx0_pcie_setup(int nr, struct pci_sys_data *sys) 142 { 143 struct pcie_port *pp; 144 145 if (nr >= num_pcie_ports) 146 return 0; 147 148 pp = &pcie_port[nr]; 149 pp->root_bus_nr = sys->busnr; 150 151 /* 152 * Generic PCIe unit setup. 153 */ 154 orion_pcie_set_local_bus_nr(pp->base, sys->busnr); 155 orion_pcie_setup(pp->base, &mv78xx0_mbus_dram_info); 156 157 sys->resource[0] = &pp->res[0]; 158 sys->resource[1] = &pp->res[1]; 159 sys->resource[2] = NULL; 160 161 return 1; 162 } 163 164 static struct pcie_port *bus_to_port(int bus) 165 { 166 int i; 167 168 for (i = num_pcie_ports - 1; i >= 0; i--) { 169 int rbus = pcie_port[i].root_bus_nr; 170 if (rbus != -1 && rbus <= bus) 171 break; 172 } 173 174 return i >= 0 ? pcie_port + i : NULL; 175 } 176 177 static int pcie_valid_config(struct pcie_port *pp, int bus, int dev) 178 { 179 /* 180 * Don't go out when trying to access nonexisting devices 181 * on the local bus. 182 */ 183 if (bus == pp->root_bus_nr && dev > 1) 184 return 0; 185 186 return 1; 187 } 188 189 static int pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where, 190 int size, u32 *val) 191 { 192 struct pcie_port *pp = bus_to_port(bus->number); 193 unsigned long flags; 194 int ret; 195 196 if (pcie_valid_config(pp, bus->number, PCI_SLOT(devfn)) == 0) { 197 *val = 0xffffffff; 198 return PCIBIOS_DEVICE_NOT_FOUND; 199 } 200 201 spin_lock_irqsave(&pp->conf_lock, flags); 202 ret = orion_pcie_rd_conf(pp->base, bus, devfn, where, size, val); 203 spin_unlock_irqrestore(&pp->conf_lock, flags); 204 205 return ret; 206 } 207 208 static int pcie_wr_conf(struct pci_bus *bus, u32 devfn, 209 int where, int size, u32 val) 210 { 211 struct pcie_port *pp = bus_to_port(bus->number); 212 unsigned long flags; 213 int ret; 214 215 if (pcie_valid_config(pp, bus->number, PCI_SLOT(devfn)) == 0) 216 return PCIBIOS_DEVICE_NOT_FOUND; 217 218 spin_lock_irqsave(&pp->conf_lock, flags); 219 ret = orion_pcie_wr_conf(pp->base, bus, devfn, where, size, val); 220 spin_unlock_irqrestore(&pp->conf_lock, flags); 221 222 return ret; 223 } 224 225 static struct pci_ops pcie_ops = { 226 .read = pcie_rd_conf, 227 .write = pcie_wr_conf, 228 }; 229 230 static void __devinit rc_pci_fixup(struct pci_dev *dev) 231 { 232 /* 233 * Prevent enumeration of root complex. 234 */ 235 if (dev->bus->parent == NULL && dev->devfn == 0) { 236 int i; 237 238 for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { 239 dev->resource[i].start = 0; 240 dev->resource[i].end = 0; 241 dev->resource[i].flags = 0; 242 } 243 } 244 } 245 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL, PCI_ANY_ID, rc_pci_fixup); 246 247 static struct pci_bus __init * 248 mv78xx0_pcie_scan_bus(int nr, struct pci_sys_data *sys) 249 { 250 struct pci_bus *bus; 251 252 if (nr < num_pcie_ports) { 253 bus = pci_scan_bus(sys->busnr, &pcie_ops, sys); 254 } else { 255 bus = NULL; 256 BUG(); 257 } 258 259 return bus; 260 } 261 262 static int __init mv78xx0_pcie_map_irq(struct pci_dev *dev, u8 slot, u8 pin) 263 { 264 struct pcie_port *pp = bus_to_port(dev->bus->number); 265 266 return IRQ_MV78XX0_PCIE_00 + (pp->maj << 2) + pp->min; 267 } 268 269 static struct hw_pci mv78xx0_pci __initdata = { 270 .nr_controllers = 8, 271 .preinit = mv78xx0_pcie_preinit, 272 .swizzle = pci_std_swizzle, 273 .setup = mv78xx0_pcie_setup, 274 .scan = mv78xx0_pcie_scan_bus, 275 .map_irq = mv78xx0_pcie_map_irq, 276 }; 277 278 static void __init add_pcie_port(int maj, int min, unsigned long base) 279 { 280 printk(KERN_INFO "MV78xx0 PCIe port %d.%d: ", maj, min); 281 282 if (orion_pcie_link_up((void __iomem *)base)) { 283 struct pcie_port *pp = &pcie_port[num_pcie_ports++]; 284 285 printk("link up\n"); 286 287 pp->maj = maj; 288 pp->min = min; 289 pp->root_bus_nr = -1; 290 pp->base = (void __iomem *)base; 291 spin_lock_init(&pp->conf_lock); 292 memset(pp->res, 0, sizeof(pp->res)); 293 } else { 294 printk("link down, ignoring\n"); 295 } 296 } 297 298 void __init mv78xx0_pcie_init(int init_port0, int init_port1) 299 { 300 if (init_port0) { 301 add_pcie_port(0, 0, PCIE00_VIRT_BASE); 302 if (!orion_pcie_x4_mode((void __iomem *)PCIE00_VIRT_BASE)) { 303 add_pcie_port(0, 1, PCIE01_VIRT_BASE); 304 add_pcie_port(0, 2, PCIE02_VIRT_BASE); 305 add_pcie_port(0, 3, PCIE03_VIRT_BASE); 306 } 307 } 308 309 if (init_port1) { 310 add_pcie_port(1, 0, PCIE10_VIRT_BASE); 311 if (!orion_pcie_x4_mode((void __iomem *)PCIE10_VIRT_BASE)) { 312 add_pcie_port(1, 1, PCIE11_VIRT_BASE); 313 add_pcie_port(1, 2, PCIE12_VIRT_BASE); 314 add_pcie_port(1, 3, PCIE13_VIRT_BASE); 315 } 316 } 317 318 pci_common_init(&mv78xx0_pci); 319 } 320