1 /* 2 * pci.c -- PCI bus support for ColdFire processors 3 * 4 * (C) Copyright 2012, Greg Ungerer <gerg@uclinux.com> 5 * 6 * This file is subject to the terms and conditions of the GNU General Public 7 * License. See the file COPYING in the main directory of this archive 8 * for more details. 9 */ 10 11 #include <linux/types.h> 12 #include <linux/module.h> 13 #include <linux/init.h> 14 #include <linux/kernel.h> 15 #include <linux/interrupt.h> 16 #include <linux/irq.h> 17 #include <linux/io.h> 18 #include <linux/pci.h> 19 #include <linux/delay.h> 20 #include <asm/coldfire.h> 21 #include <asm/mcfsim.h> 22 #include <asm/m54xxpci.h> 23 24 /* 25 * Memory and IO mappings. We use a 1:1 mapping for local host memory to 26 * PCI bus memory (no reason not to really). IO space is mapped in its own 27 * separate address region. The device configuration space is mapped over 28 * the IO map space when we enable it in the PCICAR register. 29 */ 30 static struct pci_bus *rootbus; 31 static unsigned long iospace; 32 33 /* 34 * We need to be careful probing on bus 0 (directly connected to host 35 * bridge). We should only access the well defined possible devices in 36 * use, ignore aliases and the like. 37 */ 38 static unsigned char mcf_host_slot2sid[32] = { 39 0, 0, 0, 0, 0, 0, 0, 0, 40 0, 0, 0, 0, 0, 0, 0, 0, 41 0, 1, 2, 0, 3, 4, 0, 0, 42 0, 0, 0, 0, 0, 0, 0, 0, 43 }; 44 45 static unsigned char mcf_host_irq[] = { 46 0, 69, 69, 71, 71, 47 }; 48 49 /* 50 * Configuration space access functions. Configuration space access is 51 * through the IO mapping window, enabling it via the PCICAR register. 52 */ 53 static unsigned long mcf_mk_pcicar(int bus, unsigned int devfn, int where) 54 { 55 return (bus << PCICAR_BUSN) | (devfn << PCICAR_DEVFNN) | (where & 0xfc); 56 } 57 58 static int mcf_pci_readconfig(struct pci_bus *bus, unsigned int devfn, 59 int where, int size, u32 *value) 60 { 61 unsigned long addr; 62 63 *value = 0xffffffff; 64 65 if (bus->number == 0) { 66 if (mcf_host_slot2sid[PCI_SLOT(devfn)] == 0) 67 return PCIBIOS_SUCCESSFUL; 68 } 69 70 addr = mcf_mk_pcicar(bus->number, devfn, where); 71 __raw_writel(PCICAR_E | addr, PCICAR); 72 __raw_readl(PCICAR); 73 addr = iospace + (where & 0x3); 74 75 switch (size) { 76 case 1: 77 *value = __raw_readb(addr); 78 break; 79 case 2: 80 *value = le16_to_cpu(__raw_readw(addr)); 81 break; 82 default: 83 *value = le32_to_cpu(__raw_readl(addr)); 84 break; 85 } 86 87 __raw_writel(0, PCICAR); 88 __raw_readl(PCICAR); 89 return PCIBIOS_SUCCESSFUL; 90 } 91 92 static int mcf_pci_writeconfig(struct pci_bus *bus, unsigned int devfn, 93 int where, int size, u32 value) 94 { 95 unsigned long addr; 96 97 if (bus->number == 0) { 98 if (mcf_host_slot2sid[PCI_SLOT(devfn)] == 0) 99 return PCIBIOS_SUCCESSFUL; 100 } 101 102 addr = mcf_mk_pcicar(bus->number, devfn, where); 103 __raw_writel(PCICAR_E | addr, PCICAR); 104 __raw_readl(PCICAR); 105 addr = iospace + (where & 0x3); 106 107 switch (size) { 108 case 1: 109 __raw_writeb(value, addr); 110 break; 111 case 2: 112 __raw_writew(cpu_to_le16(value), addr); 113 break; 114 default: 115 __raw_writel(cpu_to_le32(value), addr); 116 break; 117 } 118 119 __raw_writel(0, PCICAR); 120 __raw_readl(PCICAR); 121 return PCIBIOS_SUCCESSFUL; 122 } 123 124 static struct pci_ops mcf_pci_ops = { 125 .read = mcf_pci_readconfig, 126 .write = mcf_pci_writeconfig, 127 }; 128 129 /* 130 * Initialize the PCI bus registers, and scan the bus. 131 */ 132 static struct resource mcf_pci_mem = { 133 .name = "PCI Memory space", 134 .start = PCI_MEM_PA, 135 .end = PCI_MEM_PA + PCI_MEM_SIZE - 1, 136 .flags = IORESOURCE_MEM, 137 }; 138 139 static struct resource mcf_pci_io = { 140 .name = "PCI IO space", 141 .start = 0x400, 142 .end = 0x10000 - 1, 143 .flags = IORESOURCE_IO, 144 }; 145 146 static struct resource busn_resource = { 147 .name = "PCI busn", 148 .start = 0, 149 .end = 255, 150 .flags = IORESOURCE_BUS, 151 }; 152 153 /* 154 * Interrupt mapping and setting. 155 */ 156 static int mcf_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) 157 { 158 int sid; 159 160 sid = mcf_host_slot2sid[slot]; 161 if (sid) 162 return mcf_host_irq[sid]; 163 return 0; 164 } 165 166 static int __init mcf_pci_init(void) 167 { 168 struct pci_host_bridge *bridge; 169 int ret; 170 171 bridge = pci_alloc_host_bridge(0); 172 if (!bridge) 173 return -ENOMEM; 174 175 pr_info("ColdFire: PCI bus initialization...\n"); 176 177 /* Reset the external PCI bus */ 178 __raw_writel(PCIGSCR_RESET, PCIGSCR); 179 __raw_writel(0, PCITCR); 180 181 request_resource(&iomem_resource, &mcf_pci_mem); 182 request_resource(&iomem_resource, &mcf_pci_io); 183 184 /* Configure PCI arbiter */ 185 __raw_writel(PACR_INTMPRI | PACR_INTMINTE | PACR_EXTMPRI(0x1f) | 186 PACR_EXTMINTE(0x1f), PACR); 187 188 /* Set required multi-function pins for PCI bus use */ 189 __raw_writew(0x3ff, MCFGPIO_PAR_PCIBG); 190 __raw_writew(0x3ff, MCFGPIO_PAR_PCIBR); 191 192 /* Set up config space for local host bus controller */ 193 __raw_writel(PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | 194 PCI_COMMAND_INVALIDATE, PCISCR); 195 __raw_writel(PCICR1_LT(32) | PCICR1_CL(8), PCICR1); 196 __raw_writel(0, PCICR2); 197 198 /* 199 * Set up the initiator windows for memory and IO mapping. 200 * These give the CPU bus access onto the PCI bus. One for each of 201 * PCI memory and IO address spaces. 202 */ 203 __raw_writel(WXBTAR(PCI_MEM_PA, PCI_MEM_BA, PCI_MEM_SIZE), 204 PCIIW0BTAR); 205 __raw_writel(WXBTAR(PCI_IO_PA, PCI_IO_BA, PCI_IO_SIZE), 206 PCIIW1BTAR); 207 __raw_writel(PCIIWCR_W0_MEM /*| PCIIWCR_W0_MRDL*/ | PCIIWCR_W0_E | 208 PCIIWCR_W1_IO | PCIIWCR_W1_E, PCIIWCR); 209 210 /* 211 * Set up the target windows for access from the PCI bus back to the 212 * CPU bus. All we need is access to system RAM (for mastering). 213 */ 214 __raw_writel(CONFIG_RAMBASE, PCIBAR1); 215 __raw_writel(CONFIG_RAMBASE | PCITBATR1_E, PCITBATR1); 216 217 /* Keep a virtual mapping to IO/config space active */ 218 iospace = (unsigned long) ioremap(PCI_IO_PA, PCI_IO_SIZE); 219 if (iospace == 0) { 220 pci_free_host_bridge(bridge); 221 return -ENODEV; 222 } 223 pr_info("Coldfire: PCI IO/config window mapped to 0x%x\n", 224 (u32) iospace); 225 226 /* Turn of PCI reset, and wait for devices to settle */ 227 __raw_writel(0, PCIGSCR); 228 set_current_state(TASK_UNINTERRUPTIBLE); 229 schedule_timeout(msecs_to_jiffies(200)); 230 231 232 pci_add_resource(&bridge->windows, &ioport_resource); 233 pci_add_resource(&bridge->windows, &iomem_resource); 234 pci_add_resource(&bridge->windows, &busn_resource); 235 bridge->dev.parent = NULL; 236 bridge->sysdata = NULL; 237 bridge->busnr = 0; 238 bridge->ops = &mcf_pci_ops; 239 bridge->swizzle_irq = pci_common_swizzle; 240 bridge->map_irq = mcf_pci_map_irq; 241 242 ret = pci_scan_root_bus_bridge(bridge); 243 if (ret) { 244 pci_free_host_bridge(bridge); 245 return ret; 246 } 247 248 rootbus = bridge->bus; 249 250 rootbus->resource[0] = &mcf_pci_io; 251 rootbus->resource[1] = &mcf_pci_mem; 252 253 pci_bus_size_bridges(rootbus); 254 pci_bus_assign_resources(rootbus); 255 pci_bus_add_devices(rootbus); 256 return 0; 257 } 258 259 subsys_initcall(mcf_pci_init); 260
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.