aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2012-06-11 10:03:58 -0400
committerOlof Johansson <olof@lixom.net>2012-06-16 21:41:35 -0400
commit9b0f7e399238c61f28539daeb65d72a8d7f91966 (patch)
tree9472c9c5efbad71279377b1e2637eb6982d0cecd /arch
parent7dea9e73614ba37914b8867dd0fef49193b22b8d (diff)
arm: versatile: fix and enable PCI I/O space
With commit 4d5fc58dbe34b (ARM: remove bunch of now unused mach/io.h files), the I/O space setup was completely broken on versatile. This patch fixes that and prepares for further I/O space clean-up. I/O space handling on the versatile platform is currently broken in multiple ways. Most importantly, the ports do not get mapped into the virtual address space at all. Also, there is some amount of confusion between PCI I/O space and other statically mapped MMIO registers in the platform code: * The __io_address() macro that is used to access the platform register maps to the same __io macro that gets used for I/O space. * The IO_SPACE_LIMIT is set to a value that is much larger than the total available space. * The I/O resource of the PCI bus is set to the physical address of the mapping, which is way outside of the actual I/O space limit as well as the address range that gets decoded by traditional PCI cards. * No attempt is made to stay outside of the ISA port range that some device drivers try access. * No resource gets requested as a child of ioport_resource, but an IORESOURCE_IO type mapping gets requested as a child of iomem_resource. This patch attempts to correct all of the above. This makes it possible to use virtio-pci based virtual devices as well as actual PCI cards including those with legacy ISA port ranges like VGA. Some of the issues seem to be duplicated on other platforms. Signed-off-by: Arnd Bergmann <arnd@arndb.de> [rob: update to 3.5-rc2 and io.h cleanup related changes] Signed-off-by: Rob Herring <rob.herring@calxeda.com> Tested-by: Robert Schwebel <r.schwebel@pengutronix.de> Signed-off-by: Olof Johansson <olof@lixom.net>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/Kconfig1
-rw-r--r--arch/arm/mach-versatile/core.c19
-rw-r--r--arch/arm/mach-versatile/include/mach/hardware.h3
-rw-r--r--arch/arm/mach-versatile/include/mach/io.h27
-rw-r--r--arch/arm/mach-versatile/pci.c18
5 files changed, 49 insertions, 19 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index b649c5904a4..567b4323c9e 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -294,6 +294,7 @@ config ARCH_VERSATILE
294 select ICST 294 select ICST
295 select GENERIC_CLOCKEVENTS 295 select GENERIC_CLOCKEVENTS
296 select ARCH_WANT_OPTIONAL_GPIOLIB 296 select ARCH_WANT_OPTIONAL_GPIOLIB
297 select NEED_MACH_IO_H if PCI
297 select PLAT_VERSATILE 298 select PLAT_VERSATILE
298 select PLAT_VERSATILE_CLCD 299 select PLAT_VERSATILE_CLCD
299 select PLAT_VERSATILE_FPGA_IRQ 300 select PLAT_VERSATILE_FPGA_IRQ
diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c
index cf4687ee2a7..cd8ea3588f9 100644
--- a/arch/arm/mach-versatile/core.c
+++ b/arch/arm/mach-versatile/core.c
@@ -169,26 +169,13 @@ static struct map_desc versatile_io_desc[] __initdata = {
169 .pfn = __phys_to_pfn(VERSATILE_PCI_CFG_BASE), 169 .pfn = __phys_to_pfn(VERSATILE_PCI_CFG_BASE),
170 .length = VERSATILE_PCI_CFG_BASE_SIZE, 170 .length = VERSATILE_PCI_CFG_BASE_SIZE,
171 .type = MT_DEVICE 171 .type = MT_DEVICE
172 },
173#if 0
174 {
175 .virtual = VERSATILE_PCI_VIRT_MEM_BASE0,
176 .pfn = __phys_to_pfn(VERSATILE_PCI_MEM_BASE0),
177 .length = SZ_16M,
178 .type = MT_DEVICE
179 }, { 172 }, {
180 .virtual = VERSATILE_PCI_VIRT_MEM_BASE1, 173 .virtual = (unsigned long)VERSATILE_PCI_VIRT_MEM_BASE0,
181 .pfn = __phys_to_pfn(VERSATILE_PCI_MEM_BASE1), 174 .pfn = __phys_to_pfn(VERSATILE_PCI_MEM_BASE0),
182 .length = SZ_16M, 175 .length = IO_SPACE_LIMIT,
183 .type = MT_DEVICE
184 }, {
185 .virtual = VERSATILE_PCI_VIRT_MEM_BASE2,
186 .pfn = __phys_to_pfn(VERSATILE_PCI_MEM_BASE2),
187 .length = SZ_16M,
188 .type = MT_DEVICE 176 .type = MT_DEVICE
189 }, 177 },
190#endif 178#endif
191#endif
192}; 179};
193 180
194void __init versatile_map_io(void) 181void __init versatile_map_io(void)
diff --git a/arch/arm/mach-versatile/include/mach/hardware.h b/arch/arm/mach-versatile/include/mach/hardware.h
index 4d4973dd8fb..408e58da46c 100644
--- a/arch/arm/mach-versatile/include/mach/hardware.h
+++ b/arch/arm/mach-versatile/include/mach/hardware.h
@@ -29,8 +29,9 @@
29 */ 29 */
30#define VERSATILE_PCI_VIRT_BASE (void __iomem *)0xe8000000ul 30#define VERSATILE_PCI_VIRT_BASE (void __iomem *)0xe8000000ul
31#define VERSATILE_PCI_CFG_VIRT_BASE (void __iomem *)0xe9000000ul 31#define VERSATILE_PCI_CFG_VIRT_BASE (void __iomem *)0xe9000000ul
32#define VERSATILE_PCI_VIRT_MEM_BASE0 (void __iomem *)PCIO_BASE
32 33
33/* macro to get at IO space when running virtually */ 34/* macro to get at MMIO space when running virtually */
34#define IO_ADDRESS(x) (((x) & 0x0fffffff) + (((x) >> 4) & 0x0f000000) + 0xf0000000) 35#define IO_ADDRESS(x) (((x) & 0x0fffffff) + (((x) >> 4) & 0x0f000000) + 0xf0000000)
35 36
36#define __io_address(n) ((void __iomem __force *)IO_ADDRESS(n)) 37#define __io_address(n) ((void __iomem __force *)IO_ADDRESS(n))
diff --git a/arch/arm/mach-versatile/include/mach/io.h b/arch/arm/mach-versatile/include/mach/io.h
new file mode 100644
index 00000000000..0406513be7d
--- /dev/null
+++ b/arch/arm/mach-versatile/include/mach/io.h
@@ -0,0 +1,27 @@
1/*
2 * arch/arm/mach-versatile/include/mach/io.h
3 *
4 * Copyright (C) 2003 ARM Limited
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20#ifndef __ASM_ARM_ARCH_IO_H
21#define __ASM_ARM_ARCH_IO_H
22
23#define PCIO_BASE 0xeb000000ul
24
25#define __io(a) ((a) + PCIO_BASE)
26
27#endif
diff --git a/arch/arm/mach-versatile/pci.c b/arch/arm/mach-versatile/pci.c
index 15c6a00000e..bec933b04ef 100644
--- a/arch/arm/mach-versatile/pci.c
+++ b/arch/arm/mach-versatile/pci.c
@@ -169,11 +169,18 @@ static struct pci_ops pci_versatile_ops = {
169 .write = versatile_write_config, 169 .write = versatile_write_config,
170}; 170};
171 171
172static struct resource io_port = {
173 .name = "PCI",
174 .start = 0,
175 .end = IO_SPACE_LIMIT,
176 .flags = IORESOURCE_IO,
177};
178
172static struct resource io_mem = { 179static struct resource io_mem = {
173 .name = "PCI I/O space", 180 .name = "PCI I/O space",
174 .start = VERSATILE_PCI_MEM_BASE0, 181 .start = VERSATILE_PCI_MEM_BASE0,
175 .end = VERSATILE_PCI_MEM_BASE0+VERSATILE_PCI_MEM_BASE0_SIZE-1, 182 .end = VERSATILE_PCI_MEM_BASE0+VERSATILE_PCI_MEM_BASE0_SIZE-1,
176 .flags = IORESOURCE_IO, 183 .flags = IORESOURCE_MEM,
177}; 184};
178 185
179static struct resource non_mem = { 186static struct resource non_mem = {
@@ -200,6 +207,12 @@ static int __init pci_versatile_setup_resources(struct pci_sys_data *sys)
200 "memory region (%d)\n", ret); 207 "memory region (%d)\n", ret);
201 goto out; 208 goto out;
202 } 209 }
210 ret = request_resource(&ioport_resource, &io_port);
211 if (ret) {
212 printk(KERN_ERR "PCI: unable to allocate I/O "
213 "port region (%d)\n", ret);
214 goto out;
215 }
203 ret = request_resource(&iomem_resource, &non_mem); 216 ret = request_resource(&iomem_resource, &non_mem);
204 if (ret) { 217 if (ret) {
205 printk(KERN_ERR "PCI: unable to allocate non-prefetchable " 218 printk(KERN_ERR "PCI: unable to allocate non-prefetchable "
@@ -218,7 +231,7 @@ static int __init pci_versatile_setup_resources(struct pci_sys_data *sys)
218 * the mem resource for this bus 231 * the mem resource for this bus
219 * the prefetch mem resource for this bus 232 * the prefetch mem resource for this bus
220 */ 233 */
221 pci_add_resource_offset(&sys->resources, &io_mem, sys->io_offset); 234 pci_add_resource_offset(&sys->resources, &io_port, sys->io_offset);
222 pci_add_resource_offset(&sys->resources, &non_mem, sys->mem_offset); 235 pci_add_resource_offset(&sys->resources, &non_mem, sys->mem_offset);
223 pci_add_resource_offset(&sys->resources, &pre_mem, sys->mem_offset); 236 pci_add_resource_offset(&sys->resources, &pre_mem, sys->mem_offset);
224 237
@@ -249,6 +262,7 @@ int __init pci_versatile_setup(int nr, struct pci_sys_data *sys)
249 262
250 if (nr == 0) { 263 if (nr == 0) {
251 sys->mem_offset = 0; 264 sys->mem_offset = 0;
265 sys->io_offset = 0;
252 ret = pci_versatile_setup_resources(sys); 266 ret = pci_versatile_setup_resources(sys);
253 if (ret < 0) { 267 if (ret < 0) {
254 printk("pci_versatile_setup: resources... oops?\n"); 268 printk("pci_versatile_setup: resources... oops?\n");