Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ARM: mv78xx0: use fixed pci i/o mapping

Move mv78xx0 PCI to fixed i/o mapping and remove io.h. This changes the PCI
bus addresses from the cpu address to 0 based. It appears that there is
translation h/w for this, but its untested.

Signed-off-by: Rob Herring <rob.herring@calxeda.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Andrew Lunn <andrew@lunn.ch>
Reviewed-by: Arnd Bergmann <arnd@arndb.de>

+47 -121
-1
arch/arm/Kconfig
··· 571 571 select PCI 572 572 select ARCH_REQUIRE_GPIOLIB 573 573 select GENERIC_CLOCKEVENTS 574 - select NEED_MACH_IO_H 575 574 select PLAT_ORION 576 575 help 577 576 Support for the following Marvell MV78xx0 series SoCs:
+2 -1
arch/arm/mach-mv78xx0/addr-map.c
··· 13 13 #include <linux/mbus.h> 14 14 #include <linux/io.h> 15 15 #include <plat/addr-map.h> 16 + #include <mach/mv78xx0.h> 16 17 #include "common.h" 17 18 18 19 /* ··· 82 81 int maj, int min) 83 82 { 84 83 orion_setup_cpu_win(&addr_map_cfg, window, base, size, 85 - TARGET_PCIE(maj), ATTR_PCIE_IO(min), -1); 84 + TARGET_PCIE(maj), ATTR_PCIE_IO(min), 0); 86 85 } 87 86 88 87 void __init mv78xx0_setup_pcie_mem_win(int window, u32 base, u32 size,
-5
arch/arm/mach-mv78xx0/common.c
··· 135 135 .length = MV78XX0_CORE_REGS_SIZE, 136 136 .type = MT_DEVICE, 137 137 }, { 138 - .virtual = MV78XX0_PCIE_IO_VIRT_BASE(0), 139 - .pfn = __phys_to_pfn(MV78XX0_PCIE_IO_PHYS_BASE(0)), 140 - .length = MV78XX0_PCIE_IO_SIZE * 8, 141 - .type = MT_DEVICE, 142 - }, { 143 138 .virtual = MV78XX0_REGS_VIRT_BASE, 144 139 .pfn = __phys_to_pfn(MV78XX0_REGS_PHYS_BASE), 145 140 .length = MV78XX0_REGS_SIZE,
-24
arch/arm/mach-mv78xx0/include/mach/io.h
··· 1 - /* 2 - * arch/arm/mach-mv78xx0/include/mach/io.h 3 - * 4 - * This file is licensed under the terms of the GNU General Public 5 - * License version 2. This program is licensed "as is" without any 6 - * warranty of any kind, whether express or implied. 7 - */ 8 - 9 - #ifndef __ASM_ARCH_IO_H 10 - #define __ASM_ARCH_IO_H 11 - 12 - #include "mv78xx0.h" 13 - 14 - #define IO_SPACE_LIMIT 0xffffffff 15 - 16 - static inline void __iomem *__io(unsigned long addr) 17 - { 18 - return (void __iomem *)((addr - MV78XX0_PCIE_IO_PHYS_BASE(0)) 19 - + MV78XX0_PCIE_IO_VIRT_BASE(0)); 20 - } 21 - 22 - #define __io(a) __io(a) 23 - 24 - #endif
+10 -11
arch/arm/mach-mv78xx0/include/mach/mv78xx0.h
··· 29 29 * 30 30 * virt phys size 31 31 * fe400000 f102x000 16K core-specific peripheral registers 32 - * fe700000 f0800000 1M PCIe #0 I/O space 33 - * fe800000 f0900000 1M PCIe #1 I/O space 34 - * fe900000 f0a00000 1M PCIe #2 I/O space 35 - * fea00000 f0b00000 1M PCIe #3 I/O space 36 - * feb00000 f0c00000 1M PCIe #4 I/O space 37 - * fec00000 f0d00000 1M PCIe #5 I/O space 38 - * fed00000 f0e00000 1M PCIe #6 I/O space 39 - * fee00000 f0f00000 1M PCIe #7 I/O space 40 - * fef00000 f1000000 1M on-chip peripheral registers 32 + * fee00000 f0800000 64K PCIe #0 I/O space 33 + * fee10000 f0900000 64K PCIe #1 I/O space 34 + * fee20000 f0a00000 64K PCIe #2 I/O space 35 + * fee30000 f0b00000 64K PCIe #3 I/O space 36 + * fee40000 f0c00000 64K PCIe #4 I/O space 37 + * fee50000 f0d00000 64K PCIe #5 I/O space 38 + * fee60000 f0e00000 64K PCIe #6 I/O space 39 + * fee70000 f0f00000 64K PCIe #7 I/O space 40 + * fd000000 f1000000 1M on-chip peripheral registers 41 41 */ 42 42 #define MV78XX0_CORE0_REGS_PHYS_BASE 0xf1020000 43 43 #define MV78XX0_CORE1_REGS_PHYS_BASE 0xf1024000 ··· 46 46 #define MV78XX0_CORE_REGS_SIZE SZ_16K 47 47 48 48 #define MV78XX0_PCIE_IO_PHYS_BASE(i) (0xf0800000 + ((i) << 20)) 49 - #define MV78XX0_PCIE_IO_VIRT_BASE(i) (0xfe700000 + ((i) << 20)) 50 49 #define MV78XX0_PCIE_IO_SIZE SZ_1M 51 50 52 51 #define MV78XX0_REGS_PHYS_BASE 0xf1000000 53 - #define MV78XX0_REGS_VIRT_BASE 0xfef00000 52 + #define MV78XX0_REGS_VIRT_BASE 0xfd000000 54 53 #define MV78XX0_REGS_SIZE SZ_1M 55 54 56 55 #define MV78XX0_PCIE_MEM_PHYS_BASE 0xc0000000
+35 -79
arch/arm/mach-mv78xx0/pcie.c
··· 15 15 #include <asm/mach/pci.h> 16 16 #include <plat/pcie.h> 17 17 #include <plat/addr-map.h> 18 + #include <mach/mv78xx0.h> 18 19 #include "common.h" 19 20 20 21 struct pcie_port { ··· 24 23 u8 root_bus_nr; 25 24 void __iomem *base; 26 25 spinlock_t conf_lock; 27 - char io_space_name[16]; 28 26 char mem_space_name[16]; 29 - struct resource res[2]; 27 + struct resource res; 30 28 }; 31 29 32 30 static struct pcie_port pcie_port[8]; 33 31 static int num_pcie_ports; 34 32 static struct resource pcie_io_space; 35 - static struct resource pcie_mem_space; 36 - 37 33 38 34 void __init mv78xx0_pcie_id(u32 *dev, u32 *rev) 39 35 { ··· 38 40 *rev = orion_pcie_rev((void __iomem *)PCIE00_VIRT_BASE); 39 41 } 40 42 43 + u32 pcie_port_size[8] = { 44 + 0, 45 + 0x30000000, 46 + 0x10000000, 47 + 0x10000000, 48 + 0x08000000, 49 + 0x08000000, 50 + 0x08000000, 51 + 0x04000000, 52 + }; 53 + 41 54 static void __init mv78xx0_pcie_preinit(void) 42 55 { 43 56 int i; 44 57 u32 size_each; 45 58 u32 start; 46 - int win; 59 + int win = 0; 47 60 48 61 pcie_io_space.name = "PCIe I/O Space"; 49 62 pcie_io_space.start = MV78XX0_PCIE_IO_PHYS_BASE(0); 50 63 pcie_io_space.end = 51 64 MV78XX0_PCIE_IO_PHYS_BASE(0) + MV78XX0_PCIE_IO_SIZE * 8 - 1; 52 - pcie_io_space.flags = IORESOURCE_IO; 65 + pcie_io_space.flags = IORESOURCE_MEM; 53 66 if (request_resource(&iomem_resource, &pcie_io_space)) 54 67 panic("can't allocate PCIe I/O space"); 55 68 56 - pcie_mem_space.name = "PCIe MEM Space"; 57 - pcie_mem_space.start = MV78XX0_PCIE_MEM_PHYS_BASE; 58 - pcie_mem_space.end = 59 - MV78XX0_PCIE_MEM_PHYS_BASE + MV78XX0_PCIE_MEM_SIZE - 1; 60 - pcie_mem_space.flags = IORESOURCE_MEM; 61 - if (request_resource(&iomem_resource, &pcie_mem_space)) 62 - panic("can't allocate PCIe MEM space"); 63 - 64 - for (i = 0; i < num_pcie_ports; i++) { 65 - struct pcie_port *pp = pcie_port + i; 66 - 67 - snprintf(pp->io_space_name, sizeof(pp->io_space_name), 68 - "PCIe %d.%d I/O", pp->maj, pp->min); 69 - pp->io_space_name[sizeof(pp->io_space_name) - 1] = 0; 70 - pp->res[0].name = pp->io_space_name; 71 - pp->res[0].start = MV78XX0_PCIE_IO_PHYS_BASE(i); 72 - pp->res[0].end = pp->res[0].start + MV78XX0_PCIE_IO_SIZE - 1; 73 - pp->res[0].flags = IORESOURCE_IO; 74 - 75 - snprintf(pp->mem_space_name, sizeof(pp->mem_space_name), 76 - "PCIe %d.%d MEM", pp->maj, pp->min); 77 - pp->mem_space_name[sizeof(pp->mem_space_name) - 1] = 0; 78 - pp->res[1].name = pp->mem_space_name; 79 - pp->res[1].flags = IORESOURCE_MEM; 80 - } 81 - 82 - switch (num_pcie_ports) { 83 - case 0: 84 - size_each = 0; 85 - break; 86 - 87 - case 1: 88 - size_each = 0x30000000; 89 - break; 90 - 91 - case 2 ... 3: 92 - size_each = 0x10000000; 93 - break; 94 - 95 - case 4 ... 6: 96 - size_each = 0x08000000; 97 - break; 98 - 99 - case 7: 100 - size_each = 0x04000000; 101 - break; 102 - 103 - default: 69 + if (num_pcie_ports > 7) 104 70 panic("invalid number of PCIe ports"); 105 - } 71 + 72 + size_each = pcie_port_size[num_pcie_ports]; 106 73 107 74 start = MV78XX0_PCIE_MEM_PHYS_BASE; 108 75 for (i = 0; i < num_pcie_ports; i++) { 109 76 struct pcie_port *pp = pcie_port + i; 110 77 111 - pp->res[1].start = start; 112 - pp->res[1].end = start + size_each - 1; 78 + snprintf(pp->mem_space_name, sizeof(pp->mem_space_name), 79 + "PCIe %d.%d MEM", pp->maj, pp->min); 80 + pp->mem_space_name[sizeof(pp->mem_space_name) - 1] = 0; 81 + pp->res.name = pp->mem_space_name; 82 + pp->res.flags = IORESOURCE_MEM; 83 + pp->res.start = start; 84 + pp->res.end = start + size_each - 1; 113 85 start += size_each; 114 - } 115 86 116 - for (i = 0; i < num_pcie_ports; i++) { 117 - struct pcie_port *pp = pcie_port + i; 118 - 119 - if (request_resource(&pcie_io_space, &pp->res[0])) 120 - panic("can't allocate PCIe I/O sub-space"); 121 - 122 - if (request_resource(&pcie_mem_space, &pp->res[1])) 87 + if (request_resource(&iomem_resource, &pp->res)) 123 88 panic("can't allocate PCIe MEM sub-space"); 124 - } 125 89 126 - win = 0; 127 - for (i = 0; i < num_pcie_ports; i++) { 128 - struct pcie_port *pp = pcie_port + i; 129 - 130 - mv78xx0_setup_pcie_io_win(win++, pp->res[0].start, 131 - resource_size(&pp->res[0]), 132 - pp->maj, pp->min); 133 - 134 - mv78xx0_setup_pcie_mem_win(win++, pp->res[1].start, 135 - resource_size(&pp->res[1]), 90 + mv78xx0_setup_pcie_mem_win(win + i + 8, pp->res.start, 91 + resource_size(&pp->res), 136 92 pp->maj, pp->min); 93 + 94 + mv78xx0_setup_pcie_io_win(win + i, i * SZ_64K, SZ_64K, 95 + pp->maj, pp->min); 137 96 } 138 97 } 139 98 ··· 111 156 orion_pcie_set_local_bus_nr(pp->base, sys->busnr); 112 157 orion_pcie_setup(pp->base); 113 158 114 - pci_add_resource_offset(&sys->resources, &pp->res[0], sys->io_offset); 115 - pci_add_resource_offset(&sys->resources, &pp->res[1], sys->mem_offset); 159 + pci_ioremap_io(nr * SZ_64K, MV78XX0_PCIE_IO_PHYS_BASE(nr)); 160 + 161 + pci_add_resource_offset(&sys->resources, &pp->res, sys->mem_offset); 116 162 117 163 return 1; 118 164 } ··· 237 281 pp->root_bus_nr = -1; 238 282 pp->base = (void __iomem *)base; 239 283 spin_lock_init(&pp->conf_lock); 240 - memset(pp->res, 0, sizeof(pp->res)); 284 + memset(&pp->res, 0, sizeof(pp->res)); 241 285 } else { 242 286 printk("link down, ignoring\n"); 243 287 }