提交 9b0f7e39 编写于 作者: A Arnd Bergmann 提交者: Olof Johansson

arm: versatile: fix and enable PCI I/O space

With commit 4d5fc58d (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: NArnd Bergmann <arnd@arndb.de>
[rob: update to 3.5-rc2 and io.h cleanup related changes]
Signed-off-by: NRob Herring <rob.herring@calxeda.com>
Tested-by: NRobert Schwebel <r.schwebel@pengutronix.de>
Signed-off-by: NOlof Johansson <olof@lixom.net>
上级 7dea9e73
...@@ -294,6 +294,7 @@ config ARCH_VERSATILE ...@@ -294,6 +294,7 @@ config ARCH_VERSATILE
select ICST select ICST
select GENERIC_CLOCKEVENTS select GENERIC_CLOCKEVENTS
select ARCH_WANT_OPTIONAL_GPIOLIB select ARCH_WANT_OPTIONAL_GPIOLIB
select NEED_MACH_IO_H if PCI
select PLAT_VERSATILE select PLAT_VERSATILE
select PLAT_VERSATILE_CLCD select PLAT_VERSATILE_CLCD
select PLAT_VERSATILE_FPGA_IRQ select PLAT_VERSATILE_FPGA_IRQ
......
...@@ -169,26 +169,13 @@ static struct map_desc versatile_io_desc[] __initdata = { ...@@ -169,26 +169,13 @@ static struct map_desc versatile_io_desc[] __initdata = {
.pfn = __phys_to_pfn(VERSATILE_PCI_CFG_BASE), .pfn = __phys_to_pfn(VERSATILE_PCI_CFG_BASE),
.length = VERSATILE_PCI_CFG_BASE_SIZE, .length = VERSATILE_PCI_CFG_BASE_SIZE,
.type = MT_DEVICE .type = MT_DEVICE
},
#if 0
{
.virtual = VERSATILE_PCI_VIRT_MEM_BASE0,
.pfn = __phys_to_pfn(VERSATILE_PCI_MEM_BASE0),
.length = SZ_16M,
.type = MT_DEVICE
}, { }, {
.virtual = VERSATILE_PCI_VIRT_MEM_BASE1, .virtual = (unsigned long)VERSATILE_PCI_VIRT_MEM_BASE0,
.pfn = __phys_to_pfn(VERSATILE_PCI_MEM_BASE1), .pfn = __phys_to_pfn(VERSATILE_PCI_MEM_BASE0),
.length = SZ_16M, .length = IO_SPACE_LIMIT,
.type = MT_DEVICE
}, {
.virtual = VERSATILE_PCI_VIRT_MEM_BASE2,
.pfn = __phys_to_pfn(VERSATILE_PCI_MEM_BASE2),
.length = SZ_16M,
.type = MT_DEVICE .type = MT_DEVICE
}, },
#endif #endif
#endif
}; };
void __init versatile_map_io(void) void __init versatile_map_io(void)
......
...@@ -29,8 +29,9 @@ ...@@ -29,8 +29,9 @@
*/ */
#define VERSATILE_PCI_VIRT_BASE (void __iomem *)0xe8000000ul #define VERSATILE_PCI_VIRT_BASE (void __iomem *)0xe8000000ul
#define VERSATILE_PCI_CFG_VIRT_BASE (void __iomem *)0xe9000000ul #define VERSATILE_PCI_CFG_VIRT_BASE (void __iomem *)0xe9000000ul
#define VERSATILE_PCI_VIRT_MEM_BASE0 (void __iomem *)PCIO_BASE
/* macro to get at IO space when running virtually */ /* macro to get at MMIO space when running virtually */
#define IO_ADDRESS(x) (((x) & 0x0fffffff) + (((x) >> 4) & 0x0f000000) + 0xf0000000) #define IO_ADDRESS(x) (((x) & 0x0fffffff) + (((x) >> 4) & 0x0f000000) + 0xf0000000)
#define __io_address(n) ((void __iomem __force *)IO_ADDRESS(n)) #define __io_address(n) ((void __iomem __force *)IO_ADDRESS(n))
......
/*
* arch/arm/mach-versatile/include/mach/io.h
*
* Copyright (C) 2003 ARM Limited
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __ASM_ARM_ARCH_IO_H
#define __ASM_ARM_ARCH_IO_H
#define PCIO_BASE 0xeb000000ul
#define __io(a) ((a) + PCIO_BASE)
#endif
...@@ -169,11 +169,18 @@ static struct pci_ops pci_versatile_ops = { ...@@ -169,11 +169,18 @@ static struct pci_ops pci_versatile_ops = {
.write = versatile_write_config, .write = versatile_write_config,
}; };
static struct resource io_port = {
.name = "PCI",
.start = 0,
.end = IO_SPACE_LIMIT,
.flags = IORESOURCE_IO,
};
static struct resource io_mem = { static struct resource io_mem = {
.name = "PCI I/O space", .name = "PCI I/O space",
.start = VERSATILE_PCI_MEM_BASE0, .start = VERSATILE_PCI_MEM_BASE0,
.end = VERSATILE_PCI_MEM_BASE0+VERSATILE_PCI_MEM_BASE0_SIZE-1, .end = VERSATILE_PCI_MEM_BASE0+VERSATILE_PCI_MEM_BASE0_SIZE-1,
.flags = IORESOURCE_IO, .flags = IORESOURCE_MEM,
}; };
static struct resource non_mem = { static struct resource non_mem = {
...@@ -200,6 +207,12 @@ static int __init pci_versatile_setup_resources(struct pci_sys_data *sys) ...@@ -200,6 +207,12 @@ static int __init pci_versatile_setup_resources(struct pci_sys_data *sys)
"memory region (%d)\n", ret); "memory region (%d)\n", ret);
goto out; goto out;
} }
ret = request_resource(&ioport_resource, &io_port);
if (ret) {
printk(KERN_ERR "PCI: unable to allocate I/O "
"port region (%d)\n", ret);
goto out;
}
ret = request_resource(&iomem_resource, &non_mem); ret = request_resource(&iomem_resource, &non_mem);
if (ret) { if (ret) {
printk(KERN_ERR "PCI: unable to allocate non-prefetchable " 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,7 +231,7 @@ static int __init pci_versatile_setup_resources(struct pci_sys_data *sys)
* the mem resource for this bus * the mem resource for this bus
* the prefetch mem resource for this bus * the prefetch mem resource for this bus
*/ */
pci_add_resource_offset(&sys->resources, &io_mem, sys->io_offset); pci_add_resource_offset(&sys->resources, &io_port, sys->io_offset);
pci_add_resource_offset(&sys->resources, &non_mem, sys->mem_offset); pci_add_resource_offset(&sys->resources, &non_mem, sys->mem_offset);
pci_add_resource_offset(&sys->resources, &pre_mem, sys->mem_offset); pci_add_resource_offset(&sys->resources, &pre_mem, sys->mem_offset);
...@@ -249,6 +262,7 @@ int __init pci_versatile_setup(int nr, struct pci_sys_data *sys) ...@@ -249,6 +262,7 @@ int __init pci_versatile_setup(int nr, struct pci_sys_data *sys)
if (nr == 0) { if (nr == 0) {
sys->mem_offset = 0; sys->mem_offset = 0;
sys->io_offset = 0;
ret = pci_versatile_setup_resources(sys); ret = pci_versatile_setup_resources(sys);
if (ret < 0) { if (ret < 0) {
printk("pci_versatile_setup: resources... oops?\n"); printk("pci_versatile_setup: resources... oops?\n");
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册