Merge branch 'cleanup/io-pci' into next/cleanups

From Rob Herring <robherring2@gmail.com>:

This is the 2nd part of mach/io.h removals. This series removes io.h on
platforms with PCI by creating a fixed virtual I/O mapping and a common
__io() macro.

This version has changed a bit to accommodate Tegra converting its PCIe
host to a platform driver. Now the virtual space is only reserved during
early boot before .map_io() is called. The mapping is not created until
calling pci_ioremap_io which can be done at any point after vmalloc is
initialized.

I've gone back to fixed 64K windows for each PCI bus. This allows
removing all the i/o resource setup from the individually platforms and
placing it within the common ARM PCI code.

I've only tested versatilepb under qemu (with the model hacked up to
actually enable i/o space), so any testing is appreciated. iop3xx and
mv78xx0 have some risk of breaking as the PCI bus addresses are moved
to 0 from matching the cpu host bus addesss.

* cleanup/io-pci:
  ARM: iop3xx: use fixed PCI i/o mapping
  ARM: mv78xx0: use fixed pci i/o mapping
  ARM: iop13xx: use fixed PCI i/o mapping
  iop13xx: use more regular PCI I/O space handling
  ARM: orion5x: use fixed PCI i/o mapping
  ARM: kirkwood: use fixed PCI i/o mapping
  ARM: dove: use fixed PCI i/o mapping
  ARM: footbridge: use fixed PCI i/o mapping
  ARM: shark: use fixed PCI i/o mapping
  ARM: integrator: remove trailing whitespace on pci_v3.c
  ARM: integrator: use fixed PCI i/o mapping
  ARM: tegra: use fixed PCI i/o mapping
  ARM: versatile: use fixed PCI i/o mapping
  ARM: move PCI i/o resource setup into common code
  ARM: Add fixed PCI i/o mapping
  i2c: iop3xx: use standard gpiolib functions
  i2c: iop3xx: clean-up trailing whitespace

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
This commit is contained in:
Arnd Bergmann 2012-08-13 16:56:29 +02:00
commit 19ec6caca2
56 changed files with 416 additions and 912 deletions

View file

@ -51,6 +51,9 @@ ffc00000 ffefffff DMA memory mapping region. Memory returned
ff000000 ffbfffff Reserved for future expansion of DMA ff000000 ffbfffff Reserved for future expansion of DMA
mapping region. mapping region.
fee00000 feffffff Mapping of PCI I/O space. This is a static
mapping within the vmalloc space.
VMALLOC_START VMALLOC_END-1 vmalloc() / ioremap() space. VMALLOC_START VMALLOC_END-1 vmalloc() / ioremap() space.
Memory returned by vmalloc/ioremap will Memory returned by vmalloc/ioremap will
be dynamically placed in this region. be dynamically placed in this region.

View file

@ -285,7 +285,6 @@ config ARCH_INTEGRATOR
select GENERIC_CLOCKEVENTS select GENERIC_CLOCKEVENTS
select PLAT_VERSATILE select PLAT_VERSATILE
select PLAT_VERSATILE_FPGA_IRQ select PLAT_VERSATILE_FPGA_IRQ
select NEED_MACH_IO_H
select NEED_MACH_MEMORY_H select NEED_MACH_MEMORY_H
select SPARSE_IRQ select SPARSE_IRQ
select MULTI_IRQ_HANDLER select MULTI_IRQ_HANDLER
@ -318,7 +317,6 @@ 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_CLOCK select PLAT_VERSATILE_CLOCK
select PLAT_VERSATILE_CLCD select PLAT_VERSATILE_CLCD
@ -462,7 +460,7 @@ config ARCH_FOOTBRIDGE
select FOOTBRIDGE select FOOTBRIDGE
select GENERIC_CLOCKEVENTS select GENERIC_CLOCKEVENTS
select HAVE_IDE select HAVE_IDE
select NEED_MACH_IO_H select NEED_MACH_IO_H if !MMU
select NEED_MACH_MEMORY_H select NEED_MACH_MEMORY_H
help help
Support for systems based on the DC21285 companion chip Support for systems based on the DC21285 companion chip
@ -519,7 +517,6 @@ config ARCH_IOP13XX
select PCI select PCI
select ARCH_SUPPORTS_MSI select ARCH_SUPPORTS_MSI
select VMSPLIT_1G select VMSPLIT_1G
select NEED_MACH_IO_H
select NEED_MACH_MEMORY_H select NEED_MACH_MEMORY_H
select NEED_RET_TO_USER select NEED_RET_TO_USER
help help
@ -529,7 +526,6 @@ config ARCH_IOP32X
bool "IOP32x-based" bool "IOP32x-based"
depends on MMU depends on MMU
select CPU_XSCALE select CPU_XSCALE
select NEED_MACH_IO_H
select NEED_RET_TO_USER select NEED_RET_TO_USER
select PLAT_IOP select PLAT_IOP
select PCI select PCI
@ -542,7 +538,6 @@ config ARCH_IOP33X
bool "IOP33x-based" bool "IOP33x-based"
depends on MMU depends on MMU
select CPU_XSCALE select CPU_XSCALE
select NEED_MACH_IO_H
select NEED_RET_TO_USER select NEED_RET_TO_USER
select PLAT_IOP select PLAT_IOP
select PCI select PCI
@ -582,7 +577,6 @@ config ARCH_DOVE
select PCI select PCI
select ARCH_REQUIRE_GPIOLIB select ARCH_REQUIRE_GPIOLIB
select GENERIC_CLOCKEVENTS select GENERIC_CLOCKEVENTS
select NEED_MACH_IO_H
select PLAT_ORION select PLAT_ORION
help help
Support for the Marvell Dove SoC 88AP510 Support for the Marvell Dove SoC 88AP510
@ -593,7 +587,6 @@ config ARCH_KIRKWOOD
select PCI select PCI
select ARCH_REQUIRE_GPIOLIB select ARCH_REQUIRE_GPIOLIB
select GENERIC_CLOCKEVENTS select GENERIC_CLOCKEVENTS
select NEED_MACH_IO_H
select PLAT_ORION select PLAT_ORION
help help
Support for the following Marvell Kirkwood series SoCs: Support for the following Marvell Kirkwood series SoCs:
@ -620,7 +613,6 @@ config ARCH_MV78XX0
select PCI select PCI
select ARCH_REQUIRE_GPIOLIB select ARCH_REQUIRE_GPIOLIB
select GENERIC_CLOCKEVENTS select GENERIC_CLOCKEVENTS
select NEED_MACH_IO_H
select PLAT_ORION select PLAT_ORION
help help
Support for the following Marvell MV78xx0 series SoCs: Support for the following Marvell MV78xx0 series SoCs:
@ -633,7 +625,6 @@ config ARCH_ORION5X
select PCI select PCI
select ARCH_REQUIRE_GPIOLIB select ARCH_REQUIRE_GPIOLIB
select GENERIC_CLOCKEVENTS select GENERIC_CLOCKEVENTS
select NEED_MACH_IO_H
select PLAT_ORION select PLAT_ORION
help help
Support for the following Marvell Orion 5x series SoCs: Support for the following Marvell Orion 5x series SoCs:
@ -689,7 +680,6 @@ config ARCH_TEGRA
select HAVE_CLK select HAVE_CLK
select HAVE_SMP select HAVE_SMP
select MIGHT_HAVE_CACHE_L2X0 select MIGHT_HAVE_CACHE_L2X0
select NEED_MACH_IO_H if PCI
select ARCH_HAS_CPUFREQ select ARCH_HAS_CPUFREQ
select USE_OF select USE_OF
help help
@ -918,7 +908,6 @@ config ARCH_SHARK
select PCI select PCI
select ARCH_USES_GETTIMEOFFSET select ARCH_USES_GETTIMEOFFSET
select NEED_MACH_MEMORY_H select NEED_MACH_MEMORY_H
select NEED_MACH_IO_H
help help
Support for the StrongARM based Digital DNARD machine, also known Support for the StrongARM based Digital DNARD machine, also known
as "Shark" (<http://www.shark-linux.de/shark.html>). as "Shark" (<http://www.shark-linux.de/shark.html>).

View file

@ -217,18 +217,8 @@ extern int iop3xx_get_init_atu(void);
#define IOP3XX_PCI_LOWER_MEM_PA 0x80000000 #define IOP3XX_PCI_LOWER_MEM_PA 0x80000000
#define IOP3XX_PCI_MEM_WINDOW_SIZE 0x08000000 #define IOP3XX_PCI_MEM_WINDOW_SIZE 0x08000000
#define IOP3XX_PCI_IO_WINDOW_SIZE 0x00010000
#define IOP3XX_PCI_LOWER_IO_PA 0x90000000 #define IOP3XX_PCI_LOWER_IO_PA 0x90000000
#define IOP3XX_PCI_LOWER_IO_VA 0xfe000000 #define IOP3XX_PCI_LOWER_IO_BA 0x00000000
#define IOP3XX_PCI_LOWER_IO_BA 0x90000000
#define IOP3XX_PCI_UPPER_IO_PA (IOP3XX_PCI_LOWER_IO_PA +\
IOP3XX_PCI_IO_WINDOW_SIZE - 1)
#define IOP3XX_PCI_UPPER_IO_VA (IOP3XX_PCI_LOWER_IO_VA +\
IOP3XX_PCI_IO_WINDOW_SIZE - 1)
#define IOP3XX_PCI_IO_PHYS_TO_VIRT(addr) (((u32) (addr) -\
IOP3XX_PCI_LOWER_IO_PA) +\
IOP3XX_PCI_LOWER_IO_VA)
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__

View file

@ -113,11 +113,19 @@ static inline void __iomem *__typesafe_io(unsigned long addr)
#define __iowmb() do { } while (0) #define __iowmb() do { } while (0)
#endif #endif
/* PCI fixed i/o mapping */
#define PCI_IO_VIRT_BASE 0xfee00000
extern int pci_ioremap_io(unsigned int offset, phys_addr_t phys_addr);
/* /*
* Now, pick up the machine-defined IO definitions * Now, pick up the machine-defined IO definitions
*/ */
#ifdef CONFIG_NEED_MACH_IO_H #ifdef CONFIG_NEED_MACH_IO_H
#include <mach/io.h> #include <mach/io.h>
#elif defined(CONFIG_PCI)
#define IO_SPACE_LIMIT ((resource_size_t)0xfffff)
#define __io(a) __typesafe_io(PCI_IO_VIRT_BASE + ((a) & IO_SPACE_LIMIT))
#else #else
#define __io(a) __typesafe_io((a) & IO_SPACE_LIMIT) #define __io(a) __typesafe_io((a) & IO_SPACE_LIMIT)
#endif #endif

View file

@ -9,6 +9,9 @@
* *
* Page table mapping constructs and function prototypes * Page table mapping constructs and function prototypes
*/ */
#ifndef __ASM_MACH_MAP_H
#define __ASM_MACH_MAP_H
#include <asm/io.h> #include <asm/io.h>
struct map_desc { struct map_desc {
@ -34,6 +37,8 @@ struct map_desc {
#ifdef CONFIG_MMU #ifdef CONFIG_MMU
extern void iotable_init(struct map_desc *, int); extern void iotable_init(struct map_desc *, int);
extern void vm_reserve_area_early(unsigned long addr, unsigned long size,
void *caller);
struct mem_type; struct mem_type;
extern const struct mem_type *get_mem_type(unsigned int type); extern const struct mem_type *get_mem_type(unsigned int type);
@ -44,4 +49,7 @@ extern int ioremap_page(unsigned long virt, unsigned long phys,
const struct mem_type *mtype); const struct mem_type *mtype);
#else #else
#define iotable_init(map,num) do { } while (0) #define iotable_init(map,num) do { } while (0)
#define vm_reserve_area_early(a,s,c) do { } while (0)
#endif
#endif #endif

View file

@ -11,6 +11,8 @@
#ifndef __ASM_MACH_PCI_H #ifndef __ASM_MACH_PCI_H
#define __ASM_MACH_PCI_H #define __ASM_MACH_PCI_H
#include <linux/ioport.h>
struct pci_sys_data; struct pci_sys_data;
struct pci_ops; struct pci_ops;
struct pci_bus; struct pci_bus;
@ -42,6 +44,8 @@ struct pci_sys_data {
unsigned long io_offset; /* bus->cpu IO mapping offset */ unsigned long io_offset; /* bus->cpu IO mapping offset */
struct pci_bus *bus; /* PCI bus */ struct pci_bus *bus; /* PCI bus */
struct list_head resources; /* root bus resources (apertures) */ struct list_head resources; /* root bus resources (apertures) */
struct resource io_res;
char io_res_name[12];
/* Bridge swizzling */ /* Bridge swizzling */
u8 (*swizzle)(struct pci_dev *, u8 *); u8 (*swizzle)(struct pci_dev *, u8 *);
/* IRQ mapping */ /* IRQ mapping */
@ -54,6 +58,15 @@ struct pci_sys_data {
*/ */
void pci_common_init(struct hw_pci *); void pci_common_init(struct hw_pci *);
/*
* Setup early fixed I/O mapping.
*/
#if defined(CONFIG_PCI)
extern void pci_map_io_early(unsigned long pfn);
#else
static inline void pci_map_io_early(unsigned long pfn) {}
#endif
/* /*
* PCI controllers * PCI controllers
*/ */

View file

@ -13,6 +13,7 @@
#include <linux/io.h> #include <linux/io.h>
#include <asm/mach-types.h> #include <asm/mach-types.h>
#include <asm/mach/map.h>
#include <asm/mach/pci.h> #include <asm/mach/pci.h>
static int debug_pci; static int debug_pci;
@ -423,6 +424,38 @@ static int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
return irq; return irq;
} }
static int __init pcibios_init_resources(int busnr, struct pci_sys_data *sys)
{
int ret;
struct pci_host_bridge_window *window;
if (list_empty(&sys->resources)) {
pci_add_resource_offset(&sys->resources,
&iomem_resource, sys->mem_offset);
}
list_for_each_entry(window, &sys->resources, list) {
if (resource_type(window->res) == IORESOURCE_IO)
return 0;
}
sys->io_res.start = (busnr * SZ_64K) ? : pcibios_min_io;
sys->io_res.end = (busnr + 1) * SZ_64K - 1;
sys->io_res.flags = IORESOURCE_IO;
sys->io_res.name = sys->io_res_name;
sprintf(sys->io_res_name, "PCI%d I/O", busnr);
ret = request_resource(&ioport_resource, &sys->io_res);
if (ret) {
pr_err("PCI: unable to allocate I/O port region (%d)\n", ret);
return ret;
}
pci_add_resource_offset(&sys->resources, &sys->io_res,
sys->io_offset);
return 0;
}
static void __init pcibios_init_hw(struct hw_pci *hw, struct list_head *head) static void __init pcibios_init_hw(struct hw_pci *hw, struct list_head *head)
{ {
struct pci_sys_data *sys = NULL; struct pci_sys_data *sys = NULL;
@ -445,11 +478,10 @@ static void __init pcibios_init_hw(struct hw_pci *hw, struct list_head *head)
ret = hw->setup(nr, sys); ret = hw->setup(nr, sys);
if (ret > 0) { if (ret > 0) {
if (list_empty(&sys->resources)) { ret = pcibios_init_resources(nr, sys);
pci_add_resource_offset(&sys->resources, if (ret) {
&ioport_resource, sys->io_offset); kfree(sys);
pci_add_resource_offset(&sys->resources, break;
&iomem_resource, sys->mem_offset);
} }
if (hw->scan) if (hw->scan)
@ -627,3 +659,15 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
return 0; return 0;
} }
void __init pci_map_io_early(unsigned long pfn)
{
struct map_desc pci_io_desc = {
.virtual = PCI_IO_VIRT_BASE,
.type = MT_DEVICE,
.length = SZ_64K,
};
pci_io_desc.pfn = pfn;
iotable_init(&pci_io_desc, 1);
}

View file

@ -49,16 +49,6 @@ static struct map_desc dove_io_desc[] __initdata = {
.pfn = __phys_to_pfn(DOVE_NB_REGS_PHYS_BASE), .pfn = __phys_to_pfn(DOVE_NB_REGS_PHYS_BASE),
.length = DOVE_NB_REGS_SIZE, .length = DOVE_NB_REGS_SIZE,
.type = MT_DEVICE, .type = MT_DEVICE,
}, {
.virtual = DOVE_PCIE0_IO_VIRT_BASE,
.pfn = __phys_to_pfn(DOVE_PCIE0_IO_PHYS_BASE),
.length = DOVE_PCIE0_IO_SIZE,
.type = MT_DEVICE,
}, {
.virtual = DOVE_PCIE1_IO_VIRT_BASE,
.pfn = __phys_to_pfn(DOVE_PCIE1_IO_PHYS_BASE),
.length = DOVE_PCIE1_IO_SIZE,
.type = MT_DEVICE,
}, },
}; };

View file

@ -50,14 +50,12 @@
#define DOVE_NB_REGS_SIZE SZ_8M #define DOVE_NB_REGS_SIZE SZ_8M
#define DOVE_PCIE0_IO_PHYS_BASE 0xf2000000 #define DOVE_PCIE0_IO_PHYS_BASE 0xf2000000
#define DOVE_PCIE0_IO_VIRT_BASE 0xfee00000
#define DOVE_PCIE0_IO_BUS_BASE 0x00000000 #define DOVE_PCIE0_IO_BUS_BASE 0x00000000
#define DOVE_PCIE0_IO_SIZE SZ_1M #define DOVE_PCIE0_IO_SIZE SZ_64K
#define DOVE_PCIE1_IO_PHYS_BASE 0xf2100000 #define DOVE_PCIE1_IO_PHYS_BASE 0xf2100000
#define DOVE_PCIE1_IO_VIRT_BASE 0xfef00000 #define DOVE_PCIE1_IO_BUS_BASE 0x00010000
#define DOVE_PCIE1_IO_BUS_BASE 0x00100000 #define DOVE_PCIE1_IO_SIZE SZ_64K
#define DOVE_PCIE1_IO_SIZE SZ_1M
/* /*
* Dove Core Registers Map * Dove Core Registers Map

View file

@ -1,19 +0,0 @@
/*
* arch/arm/mach-dove/include/mach/io.h
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
#ifndef __ASM_ARCH_IO_H
#define __ASM_ARCH_IO_H
#include "dove.h"
#define IO_SPACE_LIMIT 0xffffffff
#define __io(a) ((void __iomem *)(((a) - DOVE_PCIE0_IO_BUS_BASE) + \
DOVE_PCIE0_IO_VIRT_BASE))
#endif

View file

@ -26,9 +26,8 @@ struct pcie_port {
u8 root_bus_nr; u8 root_bus_nr;
void __iomem *base; void __iomem *base;
spinlock_t conf_lock; spinlock_t conf_lock;
char io_space_name[16];
char mem_space_name[16]; char mem_space_name[16];
struct resource res[2]; struct resource res;
}; };
static struct pcie_port pcie_port[2]; static struct pcie_port pcie_port[2];
@ -53,24 +52,10 @@ static int __init dove_pcie_setup(int nr, struct pci_sys_data *sys)
orion_pcie_setup(pp->base); orion_pcie_setup(pp->base);
/* if (pp->index == 0)
* IORESOURCE_IO pci_ioremap_io(sys->busnr * SZ_64K, DOVE_PCIE0_IO_PHYS_BASE);
*/ else
snprintf(pp->io_space_name, sizeof(pp->io_space_name), pci_ioremap_io(sys->busnr * SZ_64K, DOVE_PCIE1_IO_PHYS_BASE);
"PCIe %d I/O", pp->index);
pp->io_space_name[sizeof(pp->io_space_name) - 1] = 0;
pp->res[0].name = pp->io_space_name;
if (pp->index == 0) {
pp->res[0].start = DOVE_PCIE0_IO_PHYS_BASE;
pp->res[0].end = pp->res[0].start + DOVE_PCIE0_IO_SIZE - 1;
} else {
pp->res[0].start = DOVE_PCIE1_IO_PHYS_BASE;
pp->res[0].end = pp->res[0].start + DOVE_PCIE1_IO_SIZE - 1;
}
pp->res[0].flags = IORESOURCE_IO;
if (request_resource(&ioport_resource, &pp->res[0]))
panic("Request PCIe IO resource failed\n");
pci_add_resource_offset(&sys->resources, &pp->res[0], sys->io_offset);
/* /*
* IORESOURCE_MEM * IORESOURCE_MEM
@ -78,18 +63,18 @@ static int __init dove_pcie_setup(int nr, struct pci_sys_data *sys)
snprintf(pp->mem_space_name, sizeof(pp->mem_space_name), snprintf(pp->mem_space_name, sizeof(pp->mem_space_name),
"PCIe %d MEM", pp->index); "PCIe %d MEM", pp->index);
pp->mem_space_name[sizeof(pp->mem_space_name) - 1] = 0; pp->mem_space_name[sizeof(pp->mem_space_name) - 1] = 0;
pp->res[1].name = pp->mem_space_name; pp->res.name = pp->mem_space_name;
if (pp->index == 0) { if (pp->index == 0) {
pp->res[1].start = DOVE_PCIE0_MEM_PHYS_BASE; pp->res.start = DOVE_PCIE0_MEM_PHYS_BASE;
pp->res[1].end = pp->res[1].start + DOVE_PCIE0_MEM_SIZE - 1; pp->res.end = pp->res.start + DOVE_PCIE0_MEM_SIZE - 1;
} else { } else {
pp->res[1].start = DOVE_PCIE1_MEM_PHYS_BASE; pp->res.start = DOVE_PCIE1_MEM_PHYS_BASE;
pp->res[1].end = pp->res[1].start + DOVE_PCIE1_MEM_SIZE - 1; pp->res.end = pp->res.start + DOVE_PCIE1_MEM_SIZE - 1;
} }
pp->res[1].flags = IORESOURCE_MEM; pp->res.flags = IORESOURCE_MEM;
if (request_resource(&iomem_resource, &pp->res[1])) if (request_resource(&iomem_resource, &pp->res))
panic("Request PCIe Memory resource failed\n"); panic("Request PCIe Memory resource failed\n");
pci_add_resource_offset(&sys->resources, &pp->res[1], sys->mem_offset); pci_add_resource_offset(&sys->resources, &pp->res, sys->mem_offset);
return 1; return 1;
} }
@ -210,7 +195,7 @@ static void __init add_pcie_port(int index, unsigned long base)
pp->root_bus_nr = -1; pp->root_bus_nr = -1;
pp->base = (void __iomem *)base; pp->base = (void __iomem *)base;
spin_lock_init(&pp->conf_lock); spin_lock_init(&pp->conf_lock);
memset(pp->res, 0, sizeof(pp->res)); memset(&pp->res, 0, sizeof(pp->res));
} else { } else {
printk(KERN_INFO "link down, ignoring\n"); printk(KERN_INFO "link down, ignoring\n");
} }

View file

@ -15,7 +15,7 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <asm/pgtable.h> #include <asm/pgtable.h>
#include <asm/page.h> #include <asm/page.h>
#include <asm/irq.h> #include <asm/irq.h>
@ -26,6 +26,7 @@
#include <asm/mach/irq.h> #include <asm/mach/irq.h>
#include <asm/mach/map.h> #include <asm/mach/map.h>
#include <asm/mach/pci.h>
#include "common.h" #include "common.h"
@ -175,11 +176,6 @@ static struct map_desc ebsa285_host_io_desc[] __initdata = {
.pfn = __phys_to_pfn(DC21285_PCI_IACK), .pfn = __phys_to_pfn(DC21285_PCI_IACK),
.length = PCIIACK_SIZE, .length = PCIIACK_SIZE,
.type = MT_DEVICE, .type = MT_DEVICE,
}, {
.virtual = PCIO_BASE,
.pfn = __phys_to_pfn(DC21285_PCI_IO),
.length = PCIO_SIZE,
.type = MT_DEVICE,
}, },
#endif #endif
}; };
@ -196,8 +192,10 @@ void __init footbridge_map_io(void)
* Now, work out what we've got to map in addition on this * Now, work out what we've got to map in addition on this
* platform. * platform.
*/ */
if (footbridge_cfn_mode()) if (footbridge_cfn_mode()) {
iotable_init(ebsa285_host_io_desc, ARRAY_SIZE(ebsa285_host_io_desc)); iotable_init(ebsa285_host_io_desc, ARRAY_SIZE(ebsa285_host_io_desc));
pci_map_io_early(__phys_to_pfn(DC21285_PCI_IO));
}
} }
void footbridge_restart(char mode, const char *cmd) void footbridge_restart(char mode, const char *cmd)

View file

@ -276,8 +276,8 @@ int __init dc21285_setup(int nr, struct pci_sys_data *sys)
sys->mem_offset = DC21285_PCI_MEM; sys->mem_offset = DC21285_PCI_MEM;
pci_add_resource_offset(&sys->resources, pci_ioremap_io(0, DC21285_PCI_IO);
&ioport_resource, sys->io_offset);
pci_add_resource_offset(&sys->resources, &res[0], sys->mem_offset); pci_add_resource_offset(&sys->resources, &res[0], sys->mem_offset);
pci_add_resource_offset(&sys->resources, &res[1], sys->mem_offset); pci_add_resource_offset(&sys->resources, &res[1], sys->mem_offset);
@ -298,7 +298,7 @@ void __init dc21285_preinit(void)
mem_size = (unsigned int)high_memory - PAGE_OFFSET; mem_size = (unsigned int)high_memory - PAGE_OFFSET;
for (mem_mask = 0x00100000; mem_mask < 0x10000000; mem_mask <<= 1) for (mem_mask = 0x00100000; mem_mask < 0x10000000; mem_mask <<= 1)
if (mem_mask >= mem_size) if (mem_mask >= mem_size)
break; break;
/* /*
* These registers need to be set up whether we're the * These registers need to be set up whether we're the
@ -350,14 +350,6 @@ void __init dc21285_preinit(void)
"PCI data parity", NULL); "PCI data parity", NULL);
if (cfn_mode) { if (cfn_mode) {
static struct resource csrio;
csrio.flags = IORESOURCE_IO;
csrio.name = "Footbridge";
allocate_resource(&ioport_resource, &csrio, 128,
0xff00, 0xffff, 128, NULL, NULL);
/* /*
* Map our SDRAM at a known address in PCI space, just in case * Map our SDRAM at a known address in PCI space, just in case
* the firmware had other ideas. Using a nonzero base is * the firmware had other ideas. Using a nonzero base is
@ -365,7 +357,7 @@ void __init dc21285_preinit(void)
* in the range 0x000a0000 to 0x000c0000. (eg, S3 cards). * in the range 0x000a0000 to 0x000c0000. (eg, S3 cards).
*/ */
*CSR_PCICSRBASE = 0xf4000000; *CSR_PCICSRBASE = 0xf4000000;
*CSR_PCICSRIOBASE = csrio.start; *CSR_PCICSRIOBASE = 0;
*CSR_PCISDRAMBASE = __virt_to_bus(PAGE_OFFSET); *CSR_PCISDRAMBASE = __virt_to_bus(PAGE_OFFSET);
*CSR_PCIROMBASE = 0; *CSR_PCIROMBASE = 0;
*CSR_PCICMD = PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | *CSR_PCICMD = PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |

View file

@ -17,7 +17,8 @@
/* For NetWinder debugging */ /* For NetWinder debugging */
.macro addruart, rp, rv, tmp .macro addruart, rp, rv, tmp
mov \rp, #0x000003f8 mov \rp, #0x000003f8
orr \rv, \rp, #0xff000000 @ virtual orr \rv, \rp, #0xfe000000 @ virtual
orr \rv, \rv, #0x00e00000 @ virtual
orr \rp, \rp, #0x7c000000 @ physical orr \rp, \rp, #0x7c000000 @ physical
.endm .endm

View file

@ -14,18 +14,10 @@
#ifndef __ASM_ARM_ARCH_IO_H #ifndef __ASM_ARM_ARCH_IO_H
#define __ASM_ARM_ARCH_IO_H #define __ASM_ARM_ARCH_IO_H
#ifdef CONFIG_MMU
#define MMU_IO(a, b) (a)
#else
#define MMU_IO(a, b) (b)
#endif
#define PCIO_SIZE 0x00100000
#define PCIO_BASE MMU_IO(0xff000000, 0x7c000000)
/* /*
* Translation of various region addresses to virtual addresses * Translation of various i/o addresses to host addresses for !CONFIG_MMU
*/ */
#define PCIO_BASE 0x7c000000
#define __io(a) ((void __iomem *)(PCIO_BASE + (a))) #define __io(a) ((void __iomem *)(PCIO_BASE + (a)))
#endif #endif

View file

@ -1,33 +0,0 @@
/*
* arch/arm/mach-integrator/include/mach/io.h
*
* Copyright (C) 1999 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
/*
* WARNING: this has to mirror definitions in platform.h
*/
#define PCI_MEMORY_VADDR 0xe8000000
#define PCI_CONFIG_VADDR 0xec000000
#define PCI_V3_VADDR 0xed000000
#define PCI_IO_VADDR 0xee000000
#define __io(a) ((void __iomem *)(PCI_IO_VADDR + (a)))
#endif

View file

@ -324,6 +324,10 @@
*/ */
#define PHYS_PCI_V3_BASE 0x62000000 #define PHYS_PCI_V3_BASE 0x62000000
#define PCI_MEMORY_VADDR 0xe8000000
#define PCI_CONFIG_VADDR 0xec000000
#define PCI_V3_VADDR 0xed000000
/* ------------------------------------------------------------------------ /* ------------------------------------------------------------------------
* Integrator Interrupt Controllers * Integrator Interrupt Controllers
* ------------------------------------------------------------------------ * ------------------------------------------------------------------------

View file

@ -50,6 +50,7 @@
#include <asm/mach/arch.h> #include <asm/mach/arch.h>
#include <asm/mach/irq.h> #include <asm/mach/irq.h>
#include <asm/mach/map.h> #include <asm/mach/map.h>
#include <asm/mach/pci.h>
#include <asm/mach/time.h> #include <asm/mach/time.h>
#include <plat/fpga-irq.h> #include <plat/fpga-irq.h>
@ -73,7 +74,7 @@
* e8000000 40000000 PCI memory PHYS_PCI_MEM_BASE (max 512M) * e8000000 40000000 PCI memory PHYS_PCI_MEM_BASE (max 512M)
* ec000000 61000000 PCI config space PHYS_PCI_CONFIG_BASE (max 16M) * ec000000 61000000 PCI config space PHYS_PCI_CONFIG_BASE (max 16M)
* ed000000 62000000 PCI V3 regs PHYS_PCI_V3_BASE (max 64k) * ed000000 62000000 PCI V3 regs PHYS_PCI_V3_BASE (max 64k)
* ee000000 60000000 PCI IO PHYS_PCI_IO_BASE (max 16M) * fee00000 60000000 PCI IO PHYS_PCI_IO_BASE (max 16M)
* ef000000 Cache flush * ef000000 Cache flush
* f1000000 10000000 Core module registers * f1000000 10000000 Core module registers
* f1100000 11000000 System controller registers * f1100000 11000000 System controller registers
@ -147,11 +148,6 @@ static struct map_desc ap_io_desc[] __initdata = {
.pfn = __phys_to_pfn(PHYS_PCI_V3_BASE), .pfn = __phys_to_pfn(PHYS_PCI_V3_BASE),
.length = SZ_64K, .length = SZ_64K,
.type = MT_DEVICE .type = MT_DEVICE
}, {
.virtual = PCI_IO_VADDR,
.pfn = __phys_to_pfn(PHYS_PCI_IO_BASE),
.length = SZ_64K,
.type = MT_DEVICE
} }
}; };
@ -159,6 +155,7 @@ static void __init ap_map_io(void)
{ {
iotable_init(ap_io_desc, ARRAY_SIZE(ap_io_desc)); iotable_init(ap_io_desc, ARRAY_SIZE(ap_io_desc));
vga_base = PCI_MEMORY_VADDR; vga_base = PCI_MEMORY_VADDR;
pci_map_io_early(__phys_to_pfn(PHYS_PCI_IO_BASE));
} }
#define INTEGRATOR_SC_VALID_INT 0x003fffff #define INTEGRATOR_SC_VALID_INT 0x003fffff

View file

@ -41,61 +41,61 @@
/* /*
* The V3 PCI interface chip in Integrator provides several windows from * The V3 PCI interface chip in Integrator provides several windows from
* local bus memory into the PCI memory areas. Unfortunately, there * local bus memory into the PCI memory areas. Unfortunately, there
* are not really enough windows for our usage, therefore we reuse * are not really enough windows for our usage, therefore we reuse
* one of the windows for access to PCI configuration space. The * one of the windows for access to PCI configuration space. The
* memory map is as follows: * memory map is as follows:
* *
* Local Bus Memory Usage * Local Bus Memory Usage
* *
* 40000000 - 4FFFFFFF PCI memory. 256M non-prefetchable * 40000000 - 4FFFFFFF PCI memory. 256M non-prefetchable
* 50000000 - 5FFFFFFF PCI memory. 256M prefetchable * 50000000 - 5FFFFFFF PCI memory. 256M prefetchable
* 60000000 - 60FFFFFF PCI IO. 16M * 60000000 - 60FFFFFF PCI IO. 16M
* 61000000 - 61FFFFFF PCI Configuration. 16M * 61000000 - 61FFFFFF PCI Configuration. 16M
* *
* There are three V3 windows, each described by a pair of V3 registers. * There are three V3 windows, each described by a pair of V3 registers.
* These are LB_BASE0/LB_MAP0, LB_BASE1/LB_MAP1 and LB_BASE2/LB_MAP2. * These are LB_BASE0/LB_MAP0, LB_BASE1/LB_MAP1 and LB_BASE2/LB_MAP2.
* Base0 and Base1 can be used for any type of PCI memory access. Base2 * Base0 and Base1 can be used for any type of PCI memory access. Base2
* can be used either for PCI I/O or for I20 accesses. By default, uHAL * can be used either for PCI I/O or for I20 accesses. By default, uHAL
* uses this only for PCI IO space. * uses this only for PCI IO space.
* *
* Normally these spaces are mapped using the following base registers: * Normally these spaces are mapped using the following base registers:
* *
* Usage Local Bus Memory Base/Map registers used * Usage Local Bus Memory Base/Map registers used
* *
* Mem 40000000 - 4FFFFFFF LB_BASE0/LB_MAP0 * Mem 40000000 - 4FFFFFFF LB_BASE0/LB_MAP0
* Mem 50000000 - 5FFFFFFF LB_BASE1/LB_MAP1 * Mem 50000000 - 5FFFFFFF LB_BASE1/LB_MAP1
* IO 60000000 - 60FFFFFF LB_BASE2/LB_MAP2 * IO 60000000 - 60FFFFFF LB_BASE2/LB_MAP2
* Cfg 61000000 - 61FFFFFF * Cfg 61000000 - 61FFFFFF
* *
* This means that I20 and PCI configuration space accesses will fail. * This means that I20 and PCI configuration space accesses will fail.
* When PCI configuration accesses are needed (via the uHAL PCI * When PCI configuration accesses are needed (via the uHAL PCI
* configuration space primitives) we must remap the spaces as follows: * configuration space primitives) we must remap the spaces as follows:
* *
* Usage Local Bus Memory Base/Map registers used * Usage Local Bus Memory Base/Map registers used
* *
* Mem 40000000 - 4FFFFFFF LB_BASE0/LB_MAP0 * Mem 40000000 - 4FFFFFFF LB_BASE0/LB_MAP0
* Mem 50000000 - 5FFFFFFF LB_BASE0/LB_MAP0 * Mem 50000000 - 5FFFFFFF LB_BASE0/LB_MAP0
* IO 60000000 - 60FFFFFF LB_BASE2/LB_MAP2 * IO 60000000 - 60FFFFFF LB_BASE2/LB_MAP2
* Cfg 61000000 - 61FFFFFF LB_BASE1/LB_MAP1 * Cfg 61000000 - 61FFFFFF LB_BASE1/LB_MAP1
* *
* To make this work, the code depends on overlapping windows working. * To make this work, the code depends on overlapping windows working.
* The V3 chip translates an address by checking its range within * The V3 chip translates an address by checking its range within
* each of the BASE/MAP pairs in turn (in ascending register number * each of the BASE/MAP pairs in turn (in ascending register number
* order). It will use the first matching pair. So, for example, * order). It will use the first matching pair. So, for example,
* if the same address is mapped by both LB_BASE0/LB_MAP0 and * if the same address is mapped by both LB_BASE0/LB_MAP0 and
* LB_BASE1/LB_MAP1, the V3 will use the translation from * LB_BASE1/LB_MAP1, the V3 will use the translation from
* LB_BASE0/LB_MAP0. * LB_BASE0/LB_MAP0.
* *
* To allow PCI Configuration space access, the code enlarges the * To allow PCI Configuration space access, the code enlarges the
* window mapped by LB_BASE0/LB_MAP0 from 256M to 512M. This occludes * window mapped by LB_BASE0/LB_MAP0 from 256M to 512M. This occludes
* the windows currently mapped by LB_BASE1/LB_MAP1 so that it can * the windows currently mapped by LB_BASE1/LB_MAP1 so that it can
* be remapped for use by configuration cycles. * be remapped for use by configuration cycles.
* *
* At the end of the PCI Configuration space accesses, * At the end of the PCI Configuration space accesses,
* LB_BASE1/LB_MAP1 is reset to map PCI Memory. Finally the window * LB_BASE1/LB_MAP1 is reset to map PCI Memory. Finally the window
* mapped by LB_BASE0/LB_MAP0 is reduced in size from 512M to 256M to * mapped by LB_BASE0/LB_MAP0 is reduced in size from 512M to 256M to
* reveal the now restored LB_BASE1/LB_MAP1 window. * reveal the now restored LB_BASE1/LB_MAP1 window.
* *
* NOTE: We do not set up I2O mapping. I suspect that this is only * NOTE: We do not set up I2O mapping. I suspect that this is only
* for an intelligent (target) device. Using I2O disables most of * for an intelligent (target) device. Using I2O disables most of
* the mappings into PCI memory. * the mappings into PCI memory.
@ -127,8 +127,8 @@
* *
* returns: configuration address to play on the PCI bus * returns: configuration address to play on the PCI bus
* *
* To generate the appropriate PCI configuration cycles in the PCI * To generate the appropriate PCI configuration cycles in the PCI
* configuration address space, you present the V3 with the following pattern * configuration address space, you present the V3 with the following pattern
* (which is very nearly a type 1 (except that the lower two bits are 00 and * (which is very nearly a type 1 (except that the lower two bits are 00 and
* not 01). In order for this mapping to work you need to set up one of * not 01). In order for this mapping to work you need to set up one of
* the local to PCI aperatures to 16Mbytes in length translating to * the local to PCI aperatures to 16Mbytes in length translating to
@ -138,7 +138,7 @@
* *
* Type 0: * Type 0:
* *
* 3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1 * 3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1
* 3 2|1 0 9 8|7 6 5 4|3 2 1 0|9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0 * 3 2|1 0 9 8|7 6 5 4|3 2 1 0|9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | | |D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|F|F|F|R|R|R|R|R|R|0|0| * | | |D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|F|F|F|R|R|R|R|R|R|0|0|
@ -150,7 +150,7 @@
* *
* Type 1: * Type 1:
* *
* 3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1 * 3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1
* 3 2|1 0 9 8|7 6 5 4|3 2 1 0|9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0 * 3 2|1 0 9 8|7 6 5 4|3 2 1 0|9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | | | | | | | | | | |B|B|B|B|B|B|B|B|D|D|D|D|D|F|F|F|R|R|R|R|R|R|0|1| * | | | | | | | | | | |B|B|B|B|B|B|B|B|D|D|D|D|D|F|F|F|R|R|R|R|R|R|0|1|
@ -161,7 +161,7 @@
* 15:11 Device number (5 bits) * 15:11 Device number (5 bits)
* 10:8 function number * 10:8 function number
* 7:2 register number * 7:2 register number
* *
*/ */
static DEFINE_RAW_SPINLOCK(v3_lock); static DEFINE_RAW_SPINLOCK(v3_lock);
@ -374,12 +374,9 @@ static int __init pci_v3_setup_resources(struct pci_sys_data *sys)
} }
/* /*
* the IO resource for this bus
* 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,
&ioport_resource, 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);
@ -498,7 +495,6 @@ void __init pci_v3_preinit(void)
unsigned int temp; unsigned int temp;
int ret; int ret;
pcibios_min_io = 0x6000;
pcibios_min_mem = 0x00100000; pcibios_min_mem = 0x00100000;
/* /*

View file

@ -1,28 +0,0 @@
/*
* iop13xx custom ioremap implementation
* Copyright (c) 2005-2006, Intel Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope 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 IO_SPACE_LIMIT 0xffffffff
#define __io(a) __iop13xx_io(a)
extern void __iomem * __iop13xx_io(unsigned long io_addr);
#endif

View file

@ -69,21 +69,11 @@ extern unsigned long get_iop_tick_rate(void);
* 0x8000.0000 + 928M 0x2.8000.0000 (ioremap) PCIE outbound memory window * 0x8000.0000 + 928M 0x2.8000.0000 (ioremap) PCIE outbound memory window
* *
* IO MAP * IO MAP
* 0x1000 + 64K 0x0.fffb.1000 0xfec6.1000 PCIX outbound i/o window * 0x00000 + 64K 0x0.fffb.0000 0xfee0.0000 PCIX outbound i/o window
* 0x1000 + 64K 0x0.fffd.1000 0xfed7.1000 PCIE outbound i/o window * 0x10000 + 64K 0x0.fffd.0000 0xfee1.0000 PCIE outbound i/o window
*/ */
#define IOP13XX_PCIX_IO_WINDOW_SIZE 0x10000UL
#define IOP13XX_PCIX_LOWER_IO_PA 0xfffb0000UL #define IOP13XX_PCIX_LOWER_IO_PA 0xfffb0000UL
#define IOP13XX_PCIX_LOWER_IO_VA 0xfec60000UL
#define IOP13XX_PCIX_LOWER_IO_BA 0x0UL /* OIOTVR */ #define IOP13XX_PCIX_LOWER_IO_BA 0x0UL /* OIOTVR */
#define IOP13XX_PCIX_IO_BUS_OFFSET 0x1000UL
#define IOP13XX_PCIX_UPPER_IO_PA (IOP13XX_PCIX_LOWER_IO_PA +\
IOP13XX_PCIX_IO_WINDOW_SIZE - 1)
#define IOP13XX_PCIX_UPPER_IO_VA (IOP13XX_PCIX_LOWER_IO_VA +\
IOP13XX_PCIX_IO_WINDOW_SIZE - 1)
#define IOP13XX_PCIX_IO_PHYS_TO_VIRT(addr) (u32) ((u32) addr -\
(IOP13XX_PCIX_LOWER_IO_PA\
- IOP13XX_PCIX_LOWER_IO_VA))
#define IOP13XX_PCIX_MEM_PHYS_OFFSET 0x100000000ULL #define IOP13XX_PCIX_MEM_PHYS_OFFSET 0x100000000ULL
#define IOP13XX_PCIX_MEM_WINDOW_SIZE 0x3a000000UL #define IOP13XX_PCIX_MEM_WINDOW_SIZE 0x3a000000UL
@ -103,20 +93,8 @@ extern unsigned long get_iop_tick_rate(void);
IOP13XX_PCIX_LOWER_MEM_BA) IOP13XX_PCIX_LOWER_MEM_BA)
/* PCI-E ranges */ /* PCI-E ranges */
#define IOP13XX_PCIE_IO_WINDOW_SIZE 0x10000UL
#define IOP13XX_PCIE_LOWER_IO_PA 0xfffd0000UL #define IOP13XX_PCIE_LOWER_IO_PA 0xfffd0000UL
#define IOP13XX_PCIE_LOWER_IO_VA 0xfed70000UL #define IOP13XX_PCIE_LOWER_IO_BA 0x10000UL /* OIOTVR */
#define IOP13XX_PCIE_LOWER_IO_BA 0x0UL /* OIOTVR */
#define IOP13XX_PCIE_IO_BUS_OFFSET 0x1000UL
#define IOP13XX_PCIE_UPPER_IO_PA (IOP13XX_PCIE_LOWER_IO_PA +\
IOP13XX_PCIE_IO_WINDOW_SIZE - 1)
#define IOP13XX_PCIE_UPPER_IO_VA (IOP13XX_PCIE_LOWER_IO_VA +\
IOP13XX_PCIE_IO_WINDOW_SIZE - 1)
#define IOP13XX_PCIE_UPPER_IO_BA (IOP13XX_PCIE_LOWER_IO_BA +\
IOP13XX_PCIE_IO_WINDOW_SIZE - 1)
#define IOP13XX_PCIE_IO_PHYS_TO_VIRT(addr) (u32) ((u32) addr -\
(IOP13XX_PCIE_LOWER_IO_PA\
- IOP13XX_PCIE_LOWER_IO_VA))
#define IOP13XX_PCIE_MEM_PHYS_OFFSET 0x200000000ULL #define IOP13XX_PCIE_MEM_PHYS_OFFSET 0x200000000ULL
#define IOP13XX_PCIE_MEM_WINDOW_SIZE 0x3a000000UL #define IOP13XX_PCIE_MEM_WINDOW_SIZE 0x3a000000UL

View file

@ -23,25 +23,6 @@
#include "pci.h" #include "pci.h"
void * __iomem __iop13xx_io(unsigned long io_addr)
{
void __iomem * io_virt;
switch (io_addr) {
case IOP13XX_PCIE_LOWER_IO_PA ... IOP13XX_PCIE_UPPER_IO_PA:
io_virt = (void *) IOP13XX_PCIE_IO_PHYS_TO_VIRT(io_addr);
break;
case IOP13XX_PCIX_LOWER_IO_PA ... IOP13XX_PCIX_UPPER_IO_PA:
io_virt = (void *) IOP13XX_PCIX_IO_PHYS_TO_VIRT(io_addr);
break;
default:
BUG();
}
return io_virt;
}
EXPORT_SYMBOL(__iop13xx_io);
static void __iomem *__iop13xx_ioremap_caller(unsigned long cookie, static void __iomem *__iop13xx_ioremap_caller(unsigned long cookie,
size_t size, unsigned int mtype, void *caller) size_t size, unsigned int mtype, void *caller)
{ {
@ -67,12 +48,6 @@ static void __iomem *__iop13xx_ioremap_caller(unsigned long cookie,
(cookie - IOP13XX_PBI_LOWER_MEM_RA), (cookie - IOP13XX_PBI_LOWER_MEM_RA),
size, mtype, __builtin_return_address(0)); size, mtype, __builtin_return_address(0));
break; break;
case IOP13XX_PCIE_LOWER_IO_PA ... IOP13XX_PCIE_UPPER_IO_PA:
retval = (void *) IOP13XX_PCIE_IO_PHYS_TO_VIRT(cookie);
break;
case IOP13XX_PCIX_LOWER_IO_PA ... IOP13XX_PCIX_UPPER_IO_PA:
retval = (void *) IOP13XX_PCIX_IO_PHYS_TO_VIRT(cookie);
break;
case IOP13XX_PMMR_PHYS_MEM_BASE ... IOP13XX_PMMR_UPPER_MEM_PA: case IOP13XX_PMMR_PHYS_MEM_BASE ... IOP13XX_PMMR_UPPER_MEM_PA:
retval = (void *) IOP13XX_PMMR_PHYS_TO_VIRT(cookie); retval = (void *) IOP13XX_PMMR_PHYS_TO_VIRT(cookie);
break; break;
@ -99,8 +74,6 @@ static void __iop13xx_iounmap(volatile void __iomem *addr)
goto skip; goto skip;
switch ((u32) addr) { switch ((u32) addr) {
case IOP13XX_PCIE_LOWER_IO_VA ... IOP13XX_PCIE_UPPER_IO_VA:
case IOP13XX_PCIX_LOWER_IO_VA ... IOP13XX_PCIX_UPPER_IO_VA:
case IOP13XX_PMMR_VIRT_MEM_BASE ... IOP13XX_PMMR_UPPER_MEM_VA: case IOP13XX_PMMR_VIRT_MEM_BASE ... IOP13XX_PMMR_UPPER_MEM_VA:
goto skip; goto skip;
} }

View file

@ -970,7 +970,6 @@ void __init iop13xx_pci_init(void)
__raw_writel(__raw_readl(IOP13XX_XBG_BECSR) & 3, IOP13XX_XBG_BECSR); __raw_writel(__raw_readl(IOP13XX_XBG_BECSR) & 3, IOP13XX_XBG_BECSR);
/* Setup the Min Address for PCI memory... */ /* Setup the Min Address for PCI memory... */
pcibios_min_io = 0;
pcibios_min_mem = IOP13XX_PCIX_LOWER_MEM_BA; pcibios_min_mem = IOP13XX_PCIX_LOWER_MEM_BA;
/* if Linux is given control of an ATU /* if Linux is given control of an ATU
@ -1003,7 +1002,7 @@ int iop13xx_pci_setup(int nr, struct pci_sys_data *sys)
if (nr > 1) if (nr > 1)
return 0; return 0;
res = kcalloc(2, sizeof(struct resource), GFP_KERNEL); res = kzalloc(sizeof(struct resource), GFP_KERNEL);
if (!res) if (!res)
panic("PCI: unable to alloc resources"); panic("PCI: unable to alloc resources");
@ -1042,17 +1041,13 @@ int iop13xx_pci_setup(int nr, struct pci_sys_data *sys)
<< IOP13XX_ATUX_PCIXSR_FUNC_NUM; << IOP13XX_ATUX_PCIXSR_FUNC_NUM;
__raw_writel(pcixsr, IOP13XX_ATUX_PCIXSR); __raw_writel(pcixsr, IOP13XX_ATUX_PCIXSR);
res[0].start = IOP13XX_PCIX_LOWER_IO_PA + IOP13XX_PCIX_IO_BUS_OFFSET; pci_ioremap_io(0, IOP13XX_PCIX_LOWER_IO_PA);
res[0].end = IOP13XX_PCIX_UPPER_IO_PA;
res[0].name = "IQ81340 ATUX PCI I/O Space";
res[0].flags = IORESOURCE_IO;
res[1].start = IOP13XX_PCIX_LOWER_MEM_RA; res->start = IOP13XX_PCIX_LOWER_MEM_RA;
res[1].end = IOP13XX_PCIX_UPPER_MEM_RA; res->end = IOP13XX_PCIX_UPPER_MEM_RA;
res[1].name = "IQ81340 ATUX PCI Memory Space"; res->name = "IQ81340 ATUX PCI Memory Space";
res[1].flags = IORESOURCE_MEM; res->flags = IORESOURCE_MEM;
sys->mem_offset = IOP13XX_PCIX_MEM_OFFSET; sys->mem_offset = IOP13XX_PCIX_MEM_OFFSET;
sys->io_offset = IOP13XX_PCIX_LOWER_IO_PA;
break; break;
case IOP13XX_INIT_ATU_ATUE: case IOP13XX_INIT_ATU_ATUE:
/* Note: the function number field in the PCSR is ro */ /* Note: the function number field in the PCSR is ro */
@ -1063,17 +1058,13 @@ int iop13xx_pci_setup(int nr, struct pci_sys_data *sys)
__raw_writel(pcsr, IOP13XX_ATUE_PCSR); __raw_writel(pcsr, IOP13XX_ATUE_PCSR);
res[0].start = IOP13XX_PCIE_LOWER_IO_PA + IOP13XX_PCIE_IO_BUS_OFFSET; pci_ioremap_io(SZ_64K, IOP13XX_PCIE_LOWER_IO_PA);
res[0].end = IOP13XX_PCIE_UPPER_IO_PA;
res[0].name = "IQ81340 ATUE PCI I/O Space";
res[0].flags = IORESOURCE_IO;
res[1].start = IOP13XX_PCIE_LOWER_MEM_RA; res->start = IOP13XX_PCIE_LOWER_MEM_RA;
res[1].end = IOP13XX_PCIE_UPPER_MEM_RA; res->end = IOP13XX_PCIE_UPPER_MEM_RA;
res[1].name = "IQ81340 ATUE PCI Memory Space"; res->name = "IQ81340 ATUE PCI Memory Space";
res[1].flags = IORESOURCE_MEM; res->flags = IORESOURCE_MEM;
sys->mem_offset = IOP13XX_PCIE_MEM_OFFSET; sys->mem_offset = IOP13XX_PCIE_MEM_OFFSET;
sys->io_offset = IOP13XX_PCIE_LOWER_IO_PA;
sys->map_irq = iop13xx_pcie_map_irq; sys->map_irq = iop13xx_pcie_map_irq;
break; break;
default: default:
@ -1081,11 +1072,9 @@ int iop13xx_pci_setup(int nr, struct pci_sys_data *sys)
return 0; return 0;
} }
request_resource(&ioport_resource, &res[0]); request_resource(&iomem_resource, res);
request_resource(&iomem_resource, &res[1]);
pci_add_resource_offset(&sys->resources, &res[0], sys->io_offset); pci_add_resource_offset(&sys->resources, res, sys->mem_offset);
pci_add_resource_offset(&sys->resources, &res[1], sys->mem_offset);
return 1; return 1;
} }

View file

@ -40,16 +40,6 @@ static struct map_desc iop13xx_std_desc[] __initdata = {
.pfn = __phys_to_pfn(IOP13XX_PMMR_PHYS_MEM_BASE), .pfn = __phys_to_pfn(IOP13XX_PMMR_PHYS_MEM_BASE),
.length = IOP13XX_PMMR_SIZE, .length = IOP13XX_PMMR_SIZE,
.type = MT_DEVICE, .type = MT_DEVICE,
}, { /* PCIE IO space */
.virtual = IOP13XX_PCIE_LOWER_IO_VA,
.pfn = __phys_to_pfn(IOP13XX_PCIE_LOWER_IO_PA),
.length = IOP13XX_PCIX_IO_WINDOW_SIZE,
.type = MT_DEVICE,
}, { /* PCIX IO space */
.virtual = IOP13XX_PCIX_LOWER_IO_VA,
.pfn = __phys_to_pfn(IOP13XX_PCIX_LOWER_IO_PA),
.length = IOP13XX_PCIX_IO_WINDOW_SIZE,
.type = MT_DEVICE,
}, },
}; };

View file

@ -1,19 +0,0 @@
/*
* arch/arm/mach-iop32x/include/mach/io.h
*
* Copyright (C) 2001 MontaVista Software, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef __IO_H
#define __IO_H
#include <asm/hardware/iop3xx.h>
#define IO_SPACE_LIMIT 0xffffffff
#define __io(p) ((void __iomem *)IOP3XX_PCI_IO_PHYS_TO_VIRT(p))
#endif

View file

@ -1,19 +0,0 @@
/*
* arch/arm/mach-iop33x/include/mach/io.h
*
* Copyright (C) 2001 MontaVista Software, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef __IO_H
#define __IO_H
#include <asm/hardware/iop3xx.h>
#define IO_SPACE_LIMIT 0xffffffff
#define __io(p) ((void __iomem *)IOP3XX_PCI_IO_PHYS_TO_VIRT(p))
#endif

View file

@ -42,16 +42,6 @@
****************************************************************************/ ****************************************************************************/
static struct map_desc kirkwood_io_desc[] __initdata = { static struct map_desc kirkwood_io_desc[] __initdata = {
{ {
.virtual = KIRKWOOD_PCIE_IO_VIRT_BASE,
.pfn = __phys_to_pfn(KIRKWOOD_PCIE_IO_PHYS_BASE),
.length = KIRKWOOD_PCIE_IO_SIZE,
.type = MT_DEVICE,
}, {
.virtual = KIRKWOOD_PCIE1_IO_VIRT_BASE,
.pfn = __phys_to_pfn(KIRKWOOD_PCIE1_IO_PHYS_BASE),
.length = KIRKWOOD_PCIE1_IO_SIZE,
.type = MT_DEVICE,
}, {
.virtual = KIRKWOOD_REGS_VIRT_BASE, .virtual = KIRKWOOD_REGS_VIRT_BASE,
.pfn = __phys_to_pfn(KIRKWOOD_REGS_PHYS_BASE), .pfn = __phys_to_pfn(KIRKWOOD_REGS_PHYS_BASE),
.length = KIRKWOOD_REGS_SIZE, .length = KIRKWOOD_REGS_SIZE,

View file

@ -1,24 +0,0 @@
/*
* arch/arm/mach-kirkwood/include/mach/io.h
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
#ifndef __ASM_ARCH_IO_H
#define __ASM_ARCH_IO_H
#include "kirkwood.h"
#define IO_SPACE_LIMIT 0xffffffff
static inline void __iomem *__io(unsigned long addr)
{
return (void __iomem *)((addr - KIRKWOOD_PCIE_IO_BUS_BASE)
+ KIRKWOOD_PCIE_IO_VIRT_BASE);
}
#define __io(a) __io(a)
#endif

View file

@ -37,14 +37,12 @@
#define KIRKWOOD_NAND_MEM_SIZE SZ_1K #define KIRKWOOD_NAND_MEM_SIZE SZ_1K
#define KIRKWOOD_PCIE1_IO_PHYS_BASE 0xf3000000 #define KIRKWOOD_PCIE1_IO_PHYS_BASE 0xf3000000
#define KIRKWOOD_PCIE1_IO_VIRT_BASE 0xfef00000 #define KIRKWOOD_PCIE1_IO_BUS_BASE 0x00010000
#define KIRKWOOD_PCIE1_IO_BUS_BASE 0x00100000 #define KIRKWOOD_PCIE1_IO_SIZE SZ_64K
#define KIRKWOOD_PCIE1_IO_SIZE SZ_1M
#define KIRKWOOD_PCIE_IO_PHYS_BASE 0xf2000000 #define KIRKWOOD_PCIE_IO_PHYS_BASE 0xf2000000
#define KIRKWOOD_PCIE_IO_VIRT_BASE 0xfee00000
#define KIRKWOOD_PCIE_IO_BUS_BASE 0x00000000 #define KIRKWOOD_PCIE_IO_BUS_BASE 0x00000000
#define KIRKWOOD_PCIE_IO_SIZE SZ_1M #define KIRKWOOD_PCIE_IO_SIZE SZ_64K
#define KIRKWOOD_REGS_PHYS_BASE 0xf1000000 #define KIRKWOOD_REGS_PHYS_BASE 0xf1000000
#define KIRKWOOD_REGS_VIRT_BASE 0xfed00000 #define KIRKWOOD_REGS_VIRT_BASE 0xfed00000

View file

@ -56,7 +56,7 @@ struct pcie_port {
void __iomem *base; void __iomem *base;
spinlock_t conf_lock; spinlock_t conf_lock;
int irq; int irq;
struct resource res[2]; struct resource res;
}; };
static int pcie_port_map[2]; static int pcie_port_map[2];
@ -136,21 +136,13 @@ static void __init pcie0_ioresources_init(struct pcie_port *pp)
pp->base = (void __iomem *)PCIE_VIRT_BASE; pp->base = (void __iomem *)PCIE_VIRT_BASE;
pp->irq = IRQ_KIRKWOOD_PCIE; pp->irq = IRQ_KIRKWOOD_PCIE;
/*
* IORESOURCE_IO
*/
pp->res[0].name = "PCIe 0 I/O Space";
pp->res[0].start = KIRKWOOD_PCIE_IO_BUS_BASE;
pp->res[0].end = pp->res[0].start + KIRKWOOD_PCIE_IO_SIZE - 1;
pp->res[0].flags = IORESOURCE_IO;
/* /*
* IORESOURCE_MEM * IORESOURCE_MEM
*/ */
pp->res[1].name = "PCIe 0 MEM"; pp->res.name = "PCIe 0 MEM";
pp->res[1].start = KIRKWOOD_PCIE_MEM_PHYS_BASE; pp->res.start = KIRKWOOD_PCIE_MEM_PHYS_BASE;
pp->res[1].end = pp->res[1].start + KIRKWOOD_PCIE_MEM_SIZE - 1; pp->res.end = pp->res.start + KIRKWOOD_PCIE_MEM_SIZE - 1;
pp->res[1].flags = IORESOURCE_MEM; pp->res.flags = IORESOURCE_MEM;
} }
static void __init pcie1_ioresources_init(struct pcie_port *pp) static void __init pcie1_ioresources_init(struct pcie_port *pp)
@ -158,21 +150,13 @@ static void __init pcie1_ioresources_init(struct pcie_port *pp)
pp->base = (void __iomem *)PCIE1_VIRT_BASE; pp->base = (void __iomem *)PCIE1_VIRT_BASE;
pp->irq = IRQ_KIRKWOOD_PCIE1; pp->irq = IRQ_KIRKWOOD_PCIE1;
/*
* IORESOURCE_IO
*/
pp->res[0].name = "PCIe 1 I/O Space";
pp->res[0].start = KIRKWOOD_PCIE1_IO_BUS_BASE;
pp->res[0].end = pp->res[0].start + KIRKWOOD_PCIE1_IO_SIZE - 1;
pp->res[0].flags = IORESOURCE_IO;
/* /*
* IORESOURCE_MEM * IORESOURCE_MEM
*/ */
pp->res[1].name = "PCIe 1 MEM"; pp->res.name = "PCIe 1 MEM";
pp->res[1].start = KIRKWOOD_PCIE1_MEM_PHYS_BASE; pp->res.start = KIRKWOOD_PCIE1_MEM_PHYS_BASE;
pp->res[1].end = pp->res[1].start + KIRKWOOD_PCIE1_MEM_SIZE - 1; pp->res.end = pp->res.start + KIRKWOOD_PCIE1_MEM_SIZE - 1;
pp->res[1].flags = IORESOURCE_MEM; pp->res.flags = IORESOURCE_MEM;
} }
static int __init kirkwood_pcie_setup(int nr, struct pci_sys_data *sys) static int __init kirkwood_pcie_setup(int nr, struct pci_sys_data *sys)
@ -197,23 +181,21 @@ static int __init kirkwood_pcie_setup(int nr, struct pci_sys_data *sys)
case 0: case 0:
kirkwood_enable_pcie_clk("0"); kirkwood_enable_pcie_clk("0");
pcie0_ioresources_init(pp); pcie0_ioresources_init(pp);
pci_ioremap_io(SZ_64K * sys->busnr, KIRKWOOD_PCIE_IO_PHYS_BASE);
break; break;
case 1: case 1:
kirkwood_enable_pcie_clk("1"); kirkwood_enable_pcie_clk("1");
pcie1_ioresources_init(pp); pcie1_ioresources_init(pp);
pci_ioremap_io(SZ_64K * sys->busnr, KIRKWOOD_PCIE1_IO_PHYS_BASE);
break; break;
default: default:
panic("PCIe setup: invalid controller %d", index); panic("PCIe setup: invalid controller %d", index);
} }
if (request_resource(&ioport_resource, &pp->res[0])) if (request_resource(&iomem_resource, &pp->res))
panic("Request PCIe%d IO resource failed\n", index);
if (request_resource(&iomem_resource, &pp->res[1]))
panic("Request PCIe%d Memory resource failed\n", index); panic("Request PCIe%d Memory resource failed\n", index);
sys->io_offset = 0; pci_add_resource_offset(&sys->resources, &pp->res, sys->mem_offset);
pci_add_resource_offset(&sys->resources, &pp->res[0], sys->io_offset);
pci_add_resource_offset(&sys->resources, &pp->res[1], sys->mem_offset);
/* /*
* Generic PCIe unit setup. * Generic PCIe unit setup.

View file

@ -13,6 +13,7 @@
#include <linux/mbus.h> #include <linux/mbus.h>
#include <linux/io.h> #include <linux/io.h>
#include <plat/addr-map.h> #include <plat/addr-map.h>
#include <mach/mv78xx0.h>
#include "common.h" #include "common.h"
/* /*
@ -81,7 +82,7 @@ void __init mv78xx0_setup_pcie_io_win(int window, u32 base, u32 size,
int maj, int min) int maj, int min)
{ {
orion_setup_cpu_win(&addr_map_cfg, window, base, size, orion_setup_cpu_win(&addr_map_cfg, window, base, size,
TARGET_PCIE(maj), ATTR_PCIE_IO(min), -1); TARGET_PCIE(maj), ATTR_PCIE_IO(min), 0);
} }
void __init mv78xx0_setup_pcie_mem_win(int window, u32 base, u32 size, void __init mv78xx0_setup_pcie_mem_win(int window, u32 base, u32 size,

View file

@ -134,11 +134,6 @@ static struct map_desc mv78xx0_io_desc[] __initdata = {
.pfn = 0, .pfn = 0,
.length = MV78XX0_CORE_REGS_SIZE, .length = MV78XX0_CORE_REGS_SIZE,
.type = MT_DEVICE, .type = MT_DEVICE,
}, {
.virtual = MV78XX0_PCIE_IO_VIRT_BASE(0),
.pfn = __phys_to_pfn(MV78XX0_PCIE_IO_PHYS_BASE(0)),
.length = MV78XX0_PCIE_IO_SIZE * 8,
.type = MT_DEVICE,
}, { }, {
.virtual = MV78XX0_REGS_VIRT_BASE, .virtual = MV78XX0_REGS_VIRT_BASE,
.pfn = __phys_to_pfn(MV78XX0_REGS_PHYS_BASE), .pfn = __phys_to_pfn(MV78XX0_REGS_PHYS_BASE),

View file

@ -1,24 +0,0 @@
/*
* arch/arm/mach-mv78xx0/include/mach/io.h
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
#ifndef __ASM_ARCH_IO_H
#define __ASM_ARCH_IO_H
#include "mv78xx0.h"
#define IO_SPACE_LIMIT 0xffffffff
static inline void __iomem *__io(unsigned long addr)
{
return (void __iomem *)((addr - MV78XX0_PCIE_IO_PHYS_BASE(0))
+ MV78XX0_PCIE_IO_VIRT_BASE(0));
}
#define __io(a) __io(a)
#endif

View file

@ -29,15 +29,15 @@
* *
* virt phys size * virt phys size
* fe400000 f102x000 16K core-specific peripheral registers * fe400000 f102x000 16K core-specific peripheral registers
* fe700000 f0800000 1M PCIe #0 I/O space * fee00000 f0800000 64K PCIe #0 I/O space
* fe800000 f0900000 1M PCIe #1 I/O space * fee10000 f0900000 64K PCIe #1 I/O space
* fe900000 f0a00000 1M PCIe #2 I/O space * fee20000 f0a00000 64K PCIe #2 I/O space
* fea00000 f0b00000 1M PCIe #3 I/O space * fee30000 f0b00000 64K PCIe #3 I/O space
* feb00000 f0c00000 1M PCIe #4 I/O space * fee40000 f0c00000 64K PCIe #4 I/O space
* fec00000 f0d00000 1M PCIe #5 I/O space * fee50000 f0d00000 64K PCIe #5 I/O space
* fed00000 f0e00000 1M PCIe #6 I/O space * fee60000 f0e00000 64K PCIe #6 I/O space
* fee00000 f0f00000 1M PCIe #7 I/O space * fee70000 f0f00000 64K PCIe #7 I/O space
* fef00000 f1000000 1M on-chip peripheral registers * fd000000 f1000000 1M on-chip peripheral registers
*/ */
#define MV78XX0_CORE0_REGS_PHYS_BASE 0xf1020000 #define MV78XX0_CORE0_REGS_PHYS_BASE 0xf1020000
#define MV78XX0_CORE1_REGS_PHYS_BASE 0xf1024000 #define MV78XX0_CORE1_REGS_PHYS_BASE 0xf1024000
@ -46,11 +46,10 @@
#define MV78XX0_CORE_REGS_SIZE SZ_16K #define MV78XX0_CORE_REGS_SIZE SZ_16K
#define MV78XX0_PCIE_IO_PHYS_BASE(i) (0xf0800000 + ((i) << 20)) #define MV78XX0_PCIE_IO_PHYS_BASE(i) (0xf0800000 + ((i) << 20))
#define MV78XX0_PCIE_IO_VIRT_BASE(i) (0xfe700000 + ((i) << 20))
#define MV78XX0_PCIE_IO_SIZE SZ_1M #define MV78XX0_PCIE_IO_SIZE SZ_1M
#define MV78XX0_REGS_PHYS_BASE 0xf1000000 #define MV78XX0_REGS_PHYS_BASE 0xf1000000
#define MV78XX0_REGS_VIRT_BASE 0xfef00000 #define MV78XX0_REGS_VIRT_BASE 0xfd000000
#define MV78XX0_REGS_SIZE SZ_1M #define MV78XX0_REGS_SIZE SZ_1M
#define MV78XX0_PCIE_MEM_PHYS_BASE 0xc0000000 #define MV78XX0_PCIE_MEM_PHYS_BASE 0xc0000000

View file

@ -15,6 +15,7 @@
#include <asm/mach/pci.h> #include <asm/mach/pci.h>
#include <plat/pcie.h> #include <plat/pcie.h>
#include <plat/addr-map.h> #include <plat/addr-map.h>
#include <mach/mv78xx0.h>
#include "common.h" #include "common.h"
struct pcie_port { struct pcie_port {
@ -23,16 +24,13 @@ struct pcie_port {
u8 root_bus_nr; u8 root_bus_nr;
void __iomem *base; void __iomem *base;
spinlock_t conf_lock; spinlock_t conf_lock;
char io_space_name[16];
char mem_space_name[16]; char mem_space_name[16];
struct resource res[2]; struct resource res;
}; };
static struct pcie_port pcie_port[8]; static struct pcie_port pcie_port[8];
static int num_pcie_ports; static int num_pcie_ports;
static struct resource pcie_io_space; static struct resource pcie_io_space;
static struct resource pcie_mem_space;
void __init mv78xx0_pcie_id(u32 *dev, u32 *rev) void __init mv78xx0_pcie_id(u32 *dev, u32 *rev)
{ {
@ -40,102 +38,59 @@ void __init mv78xx0_pcie_id(u32 *dev, u32 *rev)
*rev = orion_pcie_rev((void __iomem *)PCIE00_VIRT_BASE); *rev = orion_pcie_rev((void __iomem *)PCIE00_VIRT_BASE);
} }
u32 pcie_port_size[8] = {
0,
0x30000000,
0x10000000,
0x10000000,
0x08000000,
0x08000000,
0x08000000,
0x04000000,
};
static void __init mv78xx0_pcie_preinit(void) static void __init mv78xx0_pcie_preinit(void)
{ {
int i; int i;
u32 size_each; u32 size_each;
u32 start; u32 start;
int win; int win = 0;
pcie_io_space.name = "PCIe I/O Space"; pcie_io_space.name = "PCIe I/O Space";
pcie_io_space.start = MV78XX0_PCIE_IO_PHYS_BASE(0); pcie_io_space.start = MV78XX0_PCIE_IO_PHYS_BASE(0);
pcie_io_space.end = pcie_io_space.end =
MV78XX0_PCIE_IO_PHYS_BASE(0) + MV78XX0_PCIE_IO_SIZE * 8 - 1; MV78XX0_PCIE_IO_PHYS_BASE(0) + MV78XX0_PCIE_IO_SIZE * 8 - 1;
pcie_io_space.flags = IORESOURCE_IO; pcie_io_space.flags = IORESOURCE_MEM;
if (request_resource(&iomem_resource, &pcie_io_space)) if (request_resource(&iomem_resource, &pcie_io_space))
panic("can't allocate PCIe I/O space"); panic("can't allocate PCIe I/O space");
pcie_mem_space.name = "PCIe MEM Space"; if (num_pcie_ports > 7)
pcie_mem_space.start = MV78XX0_PCIE_MEM_PHYS_BASE;
pcie_mem_space.end =
MV78XX0_PCIE_MEM_PHYS_BASE + MV78XX0_PCIE_MEM_SIZE - 1;
pcie_mem_space.flags = IORESOURCE_MEM;
if (request_resource(&iomem_resource, &pcie_mem_space))
panic("can't allocate PCIe MEM space");
for (i = 0; i < num_pcie_ports; i++) {
struct pcie_port *pp = pcie_port + i;
snprintf(pp->io_space_name, sizeof(pp->io_space_name),
"PCIe %d.%d I/O", pp->maj, pp->min);
pp->io_space_name[sizeof(pp->io_space_name) - 1] = 0;
pp->res[0].name = pp->io_space_name;
pp->res[0].start = MV78XX0_PCIE_IO_PHYS_BASE(i);
pp->res[0].end = pp->res[0].start + MV78XX0_PCIE_IO_SIZE - 1;
pp->res[0].flags = IORESOURCE_IO;
snprintf(pp->mem_space_name, sizeof(pp->mem_space_name),
"PCIe %d.%d MEM", pp->maj, pp->min);
pp->mem_space_name[sizeof(pp->mem_space_name) - 1] = 0;
pp->res[1].name = pp->mem_space_name;
pp->res[1].flags = IORESOURCE_MEM;
}
switch (num_pcie_ports) {
case 0:
size_each = 0;
break;
case 1:
size_each = 0x30000000;
break;
case 2 ... 3:
size_each = 0x10000000;
break;
case 4 ... 6:
size_each = 0x08000000;
break;
case 7:
size_each = 0x04000000;
break;
default:
panic("invalid number of PCIe ports"); panic("invalid number of PCIe ports");
}
size_each = pcie_port_size[num_pcie_ports];
start = MV78XX0_PCIE_MEM_PHYS_BASE; start = MV78XX0_PCIE_MEM_PHYS_BASE;
for (i = 0; i < num_pcie_ports; i++) { for (i = 0; i < num_pcie_ports; i++) {
struct pcie_port *pp = pcie_port + i; struct pcie_port *pp = pcie_port + i;
pp->res[1].start = start; snprintf(pp->mem_space_name, sizeof(pp->mem_space_name),
pp->res[1].end = start + size_each - 1; "PCIe %d.%d MEM", pp->maj, pp->min);
pp->mem_space_name[sizeof(pp->mem_space_name) - 1] = 0;
pp->res.name = pp->mem_space_name;
pp->res.flags = IORESOURCE_MEM;
pp->res.start = start;
pp->res.end = start + size_each - 1;
start += size_each; start += size_each;
}
for (i = 0; i < num_pcie_ports; i++) { if (request_resource(&iomem_resource, &pp->res))
struct pcie_port *pp = pcie_port + i;
if (request_resource(&pcie_io_space, &pp->res[0]))
panic("can't allocate PCIe I/O sub-space");
if (request_resource(&pcie_mem_space, &pp->res[1]))
panic("can't allocate PCIe MEM sub-space"); panic("can't allocate PCIe MEM sub-space");
}
win = 0; mv78xx0_setup_pcie_mem_win(win + i + 8, pp->res.start,
for (i = 0; i < num_pcie_ports; i++) { resource_size(&pp->res),
struct pcie_port *pp = pcie_port + i;
mv78xx0_setup_pcie_io_win(win++, pp->res[0].start,
resource_size(&pp->res[0]),
pp->maj, pp->min);
mv78xx0_setup_pcie_mem_win(win++, pp->res[1].start,
resource_size(&pp->res[1]),
pp->maj, pp->min); pp->maj, pp->min);
mv78xx0_setup_pcie_io_win(win + i, i * SZ_64K, SZ_64K,
pp->maj, pp->min);
} }
} }
@ -156,8 +111,9 @@ static int __init mv78xx0_pcie_setup(int nr, struct pci_sys_data *sys)
orion_pcie_set_local_bus_nr(pp->base, sys->busnr); orion_pcie_set_local_bus_nr(pp->base, sys->busnr);
orion_pcie_setup(pp->base); orion_pcie_setup(pp->base);
pci_add_resource_offset(&sys->resources, &pp->res[0], sys->io_offset); pci_ioremap_io(nr * SZ_64K, MV78XX0_PCIE_IO_PHYS_BASE(nr));
pci_add_resource_offset(&sys->resources, &pp->res[1], sys->mem_offset);
pci_add_resource_offset(&sys->resources, &pp->res, sys->mem_offset);
return 1; return 1;
} }
@ -281,7 +237,7 @@ static void __init add_pcie_port(int maj, int min, unsigned long base)
pp->root_bus_nr = -1; pp->root_bus_nr = -1;
pp->base = (void __iomem *)base; pp->base = (void __iomem *)base;
spin_lock_init(&pp->conf_lock); spin_lock_init(&pp->conf_lock);
memset(pp->res, 0, sizeof(pp->res)); memset(&pp->res, 0, sizeof(pp->res));
} else { } else {
printk("link down, ignoring\n"); printk("link down, ignoring\n");
} }

View file

@ -46,16 +46,6 @@ static struct map_desc orion5x_io_desc[] __initdata = {
.pfn = __phys_to_pfn(ORION5X_REGS_PHYS_BASE), .pfn = __phys_to_pfn(ORION5X_REGS_PHYS_BASE),
.length = ORION5X_REGS_SIZE, .length = ORION5X_REGS_SIZE,
.type = MT_DEVICE, .type = MT_DEVICE,
}, {
.virtual = ORION5X_PCIE_IO_VIRT_BASE,
.pfn = __phys_to_pfn(ORION5X_PCIE_IO_PHYS_BASE),
.length = ORION5X_PCIE_IO_SIZE,
.type = MT_DEVICE,
}, {
.virtual = ORION5X_PCI_IO_VIRT_BASE,
.pfn = __phys_to_pfn(ORION5X_PCI_IO_PHYS_BASE),
.length = ORION5X_PCI_IO_SIZE,
.type = MT_DEVICE,
}, { }, {
.virtual = ORION5X_PCIE_WA_VIRT_BASE, .virtual = ORION5X_PCIE_WA_VIRT_BASE,
.pfn = __phys_to_pfn(ORION5X_PCIE_WA_PHYS_BASE), .pfn = __phys_to_pfn(ORION5X_PCIE_WA_PHYS_BASE),

View file

@ -1,22 +0,0 @@
/*
* arch/arm/mach-orion5x/include/mach/io.h
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
#ifndef __ASM_ARCH_IO_H
#define __ASM_ARCH_IO_H
#include <mach/orion5x.h>
#include <asm/sizes.h>
#define IO_SPACE_LIMIT SZ_2M
static inline void __iomem *__io(unsigned long addr)
{
return (void __iomem *)(addr + ORION5X_PCIE_IO_VIRT_BASE);
}
#define __io(a) __io(a)
#endif

View file

@ -31,31 +31,29 @@
* fc000000 device bus mappings (cs0/cs1) * fc000000 device bus mappings (cs0/cs1)
* *
* virt phys size * virt phys size
* fdd00000 f1000000 1M on-chip peripheral registers * fe000000 f1000000 1M on-chip peripheral registers
* fde00000 f2000000 1M PCIe I/O space * fee00000 f2000000 64K PCIe I/O space
* fdf00000 f2100000 1M PCI I/O space * fee10000 f2100000 64K PCI I/O space
* fe000000 f0000000 16M PCIe WA space (Orion-1/Orion-NAS only) * fd000000 f0000000 16M PCIe WA space (Orion-1/Orion-NAS only)
****************************************************************************/ ****************************************************************************/
#define ORION5X_REGS_PHYS_BASE 0xf1000000 #define ORION5X_REGS_PHYS_BASE 0xf1000000
#define ORION5X_REGS_VIRT_BASE 0xfdd00000 #define ORION5X_REGS_VIRT_BASE 0xfe000000
#define ORION5X_REGS_SIZE SZ_1M #define ORION5X_REGS_SIZE SZ_1M
#define ORION5X_PCIE_IO_PHYS_BASE 0xf2000000 #define ORION5X_PCIE_IO_PHYS_BASE 0xf2000000
#define ORION5X_PCIE_IO_VIRT_BASE 0xfde00000
#define ORION5X_PCIE_IO_BUS_BASE 0x00000000 #define ORION5X_PCIE_IO_BUS_BASE 0x00000000
#define ORION5X_PCIE_IO_SIZE SZ_1M #define ORION5X_PCIE_IO_SIZE SZ_64K
#define ORION5X_PCI_IO_PHYS_BASE 0xf2100000 #define ORION5X_PCI_IO_PHYS_BASE 0xf2100000
#define ORION5X_PCI_IO_VIRT_BASE 0xfdf00000 #define ORION5X_PCI_IO_BUS_BASE 0x00010000
#define ORION5X_PCI_IO_BUS_BASE 0x00100000 #define ORION5X_PCI_IO_SIZE SZ_64K
#define ORION5X_PCI_IO_SIZE SZ_1M
#define ORION5X_SRAM_PHYS_BASE (0xf2200000) #define ORION5X_SRAM_PHYS_BASE (0xf2200000)
#define ORION5X_SRAM_SIZE SZ_8K #define ORION5X_SRAM_SIZE SZ_8K
/* Relevant only for Orion-1/Orion-NAS */ /* Relevant only for Orion-1/Orion-NAS */
#define ORION5X_PCIE_WA_PHYS_BASE 0xf0000000 #define ORION5X_PCIE_WA_PHYS_BASE 0xf0000000
#define ORION5X_PCIE_WA_VIRT_BASE 0xfe000000 #define ORION5X_PCIE_WA_VIRT_BASE 0xfd000000
#define ORION5X_PCIE_WA_SIZE SZ_16M #define ORION5X_PCIE_WA_SIZE SZ_16M
#define ORION5X_PCIE_MEM_PHYS_BASE 0xe0000000 #define ORION5X_PCIE_MEM_PHYS_BASE 0xe0000000

View file

@ -162,35 +162,25 @@ static int __init pcie_setup(struct pci_sys_data *sys)
pcie_ops.read = pcie_rd_conf_wa; pcie_ops.read = pcie_rd_conf_wa;
} }
pci_ioremap_io(sys->busnr * SZ_64K, ORION5X_PCIE_IO_PHYS_BASE);
/* /*
* Request resources. * Request resources.
*/ */
res = kzalloc(sizeof(struct resource) * 2, GFP_KERNEL); res = kzalloc(sizeof(struct resource), GFP_KERNEL);
if (!res) if (!res)
panic("pcie_setup unable to alloc resources"); panic("pcie_setup unable to alloc resources");
/*
* IORESOURCE_IO
*/
sys->io_offset = 0;
res[0].name = "PCIe I/O Space";
res[0].flags = IORESOURCE_IO;
res[0].start = ORION5X_PCIE_IO_BUS_BASE;
res[0].end = res[0].start + ORION5X_PCIE_IO_SIZE - 1;
if (request_resource(&ioport_resource, &res[0]))
panic("Request PCIe IO resource failed\n");
pci_add_resource_offset(&sys->resources, &res[0], sys->io_offset);
/* /*
* IORESOURCE_MEM * IORESOURCE_MEM
*/ */
res[1].name = "PCIe Memory Space"; res->name = "PCIe Memory Space";
res[1].flags = IORESOURCE_MEM; res->flags = IORESOURCE_MEM;
res[1].start = ORION5X_PCIE_MEM_PHYS_BASE; res->start = ORION5X_PCIE_MEM_PHYS_BASE;
res[1].end = res[1].start + ORION5X_PCIE_MEM_SIZE - 1; res->end = res->start + ORION5X_PCIE_MEM_SIZE - 1;
if (request_resource(&iomem_resource, &res[1])) if (request_resource(&iomem_resource, res))
panic("Request PCIe Memory resource failed\n"); panic("Request PCIe Memory resource failed\n");
pci_add_resource_offset(&sys->resources, &res[1], sys->mem_offset); pci_add_resource_offset(&sys->resources, res, sys->mem_offset);
return 1; return 1;
} }
@ -489,35 +479,25 @@ static int __init pci_setup(struct pci_sys_data *sys)
*/ */
orion5x_setbits(PCI_CMD, PCI_CMD_HOST_REORDER); orion5x_setbits(PCI_CMD, PCI_CMD_HOST_REORDER);
pci_ioremap_io(sys->busnr * SZ_64K, ORION5X_PCI_IO_PHYS_BASE);
/* /*
* Request resources * Request resources
*/ */
res = kzalloc(sizeof(struct resource) * 2, GFP_KERNEL); res = kzalloc(sizeof(struct resource), GFP_KERNEL);
if (!res) if (!res)
panic("pci_setup unable to alloc resources"); panic("pci_setup unable to alloc resources");
/*
* IORESOURCE_IO
*/
sys->io_offset = 0;
res[0].name = "PCI I/O Space";
res[0].flags = IORESOURCE_IO;
res[0].start = ORION5X_PCI_IO_BUS_BASE;
res[0].end = res[0].start + ORION5X_PCI_IO_SIZE - 1;
if (request_resource(&ioport_resource, &res[0]))
panic("Request PCI IO resource failed\n");
pci_add_resource_offset(&sys->resources, &res[0], sys->io_offset);
/* /*
* IORESOURCE_MEM * IORESOURCE_MEM
*/ */
res[1].name = "PCI Memory Space"; res->name = "PCI Memory Space";
res[1].flags = IORESOURCE_MEM; res->flags = IORESOURCE_MEM;
res[1].start = ORION5X_PCI_MEM_PHYS_BASE; res->start = ORION5X_PCI_MEM_PHYS_BASE;
res[1].end = res[1].start + ORION5X_PCI_MEM_SIZE - 1; res->end = res->start + ORION5X_PCI_MEM_SIZE - 1;
if (request_resource(&iomem_resource, &res[1])) if (request_resource(&iomem_resource, res))
panic("Request PCI Memory resource failed\n"); panic("Request PCI Memory resource failed\n");
pci_add_resource_offset(&sys->resources, &res[1], sys->mem_offset); pci_add_resource_offset(&sys->resources, res, sys->mem_offset);
return 1; return 1;
} }

View file

@ -21,9 +21,6 @@
#include <asm/mach/arch.h> #include <asm/mach/arch.h>
#include <asm/mach/time.h> #include <asm/mach/time.h>
#define IO_BASE 0xe0000000
#define IO_SIZE 0x08000000
#define IO_START 0x40000000
#define ROMCARD_SIZE 0x08000000 #define ROMCARD_SIZE 0x08000000
#define ROMCARD_START 0x10000000 #define ROMCARD_START 0x10000000
@ -104,20 +101,6 @@ arch_initcall(shark_init);
extern void shark_init_irq(void); extern void shark_init_irq(void);
static struct map_desc shark_io_desc[] __initdata = {
{
.virtual = IO_BASE,
.pfn = __phys_to_pfn(IO_START),
.length = IO_SIZE,
.type = MT_DEVICE
}
};
static void __init shark_map_io(void)
{
iotable_init(shark_io_desc, ARRAY_SIZE(shark_io_desc));
}
#define IRQ_TIMER 0 #define IRQ_TIMER 0
#define HZ_TIME ((1193180 + HZ/2) / HZ) #define HZ_TIME ((1193180 + HZ/2) / HZ)
@ -158,7 +141,6 @@ static void shark_init_early(void)
MACHINE_START(SHARK, "Shark") MACHINE_START(SHARK, "Shark")
/* Maintainer: Alexander Schulz */ /* Maintainer: Alexander Schulz */
.atag_offset = 0x3000, .atag_offset = 0x3000,
.map_io = shark_map_io,
.init_early = shark_init_early, .init_early = shark_init_early,
.init_irq = shark_init_irq, .init_irq = shark_init_irq,
.timer = &shark_timer, .timer = &shark_timer,

View file

@ -12,9 +12,10 @@
*/ */
.macro addruart, rp, rv, tmp .macro addruart, rp, rv, tmp
mov \rp, #0xe0000000 mov \rp, #0x3f8
orr \rp, \rp, #0x000003f8 orr \rv, \rp, #0xfe000000
mov \rv, \rp orr \rv, \rv, #0x00e00000
orr \rp, \rp, #0x40000000
.endm .endm
.macro senduart,rd,rx .macro senduart,rd,rx

View file

@ -8,7 +8,8 @@
* warranty of any kind, whether express or implied. * warranty of any kind, whether express or implied.
*/ */
.macro get_irqnr_preamble, base, tmp .macro get_irqnr_preamble, base, tmp
mov \base, #0xe0000000 mov \base, #0xfe000000
orr \base, \base, #0x00e00000
.endm .endm
.macro get_irqnr_and_base, irqnr, irqstat, base, tmp .macro get_irqnr_and_base, irqnr, irqstat, base, tmp

View file

@ -1,18 +0,0 @@
/*
* arch/arm/mach-shark/include/mach/io.h
*
* by Alexander Schulz
*
* derived from:
* arch/arm/mach-ebsa110/include/mach/io.h
* Copyright (C) 1997,1998 Russell King
*/
#ifndef __ASM_ARM_ARCH_IO_H
#define __ASM_ARM_ARCH_IO_H
#define IO_SPACE_LIMIT 0xffffffff
#define __io(a) ((void __iomem *)(0xe0000000 + (a)))
#endif

View file

@ -8,12 +8,15 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/io.h>
#include <video/vga.h> #include <video/vga.h>
#include <asm/irq.h> #include <asm/irq.h>
#include <asm/mach/pci.h> #include <asm/mach/pci.h>
#include <asm/mach-types.h> #include <asm/mach-types.h>
#define IO_START 0x40000000
static int __init shark_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) static int __init shark_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
{ {
if (dev->bus->number == 0) if (dev->bus->number == 0)
@ -44,6 +47,8 @@ static int __init shark_pci_init(void)
pcibios_min_mem = 0x50000000; pcibios_min_mem = 0x50000000;
vga_base = 0xe8000000; vga_base = 0xe8000000;
pci_ioremap_io(0, IO_START);
pci_common_init(&shark_pci); pci_common_init(&shark_pci);
return 0; return 0;

View file

@ -1,46 +0,0 @@
/*
* arch/arm/mach-tegra/include/mach/io.h
*
* Copyright (C) 2010 Google, Inc.
*
* Author:
* Colin Cross <ccross@google.com>
* Erik Gilling <konkers@google.com>
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* 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.
*
*/
#ifndef __MACH_TEGRA_IO_H
#define __MACH_TEGRA_IO_H
#define IO_SPACE_LIMIT 0xffff
#ifndef __ASSEMBLER__
#ifdef CONFIG_TEGRA_PCI
extern void __iomem *tegra_pcie_io_base;
static inline void __iomem *__io(unsigned long addr)
{
return tegra_pcie_io_base + (addr & IO_SPACE_LIMIT);
}
#else
static inline void __iomem *__io(unsigned long addr)
{
return (void __iomem *)addr;
}
#endif
#define __io(a) __io(a)
#endif
#endif

View file

@ -303,6 +303,9 @@
#define IO_APB_VIRT IOMEM(0xFE300000) #define IO_APB_VIRT IOMEM(0xFE300000)
#define IO_APB_SIZE SZ_1M #define IO_APB_SIZE SZ_1M
#define TEGRA_PCIE_BASE 0x80000000
#define TEGRA_PCIE_IO_BASE (TEGRA_PCIE_BASE + SZ_4M)
#define IO_TO_VIRT_BETWEEN(p, st, sz) ((p) >= (st) && (p) < ((st) + (sz))) #define IO_TO_VIRT_BETWEEN(p, st, sz) ((p) >= (st) && (p) < ((st) + (sz)))
#define IO_TO_VIRT_XLATE(p, pst, vst) (((p) - (pst) + (vst))) #define IO_TO_VIRT_XLATE(p, pst, vst) (((p) - (pst) + (vst)))

View file

@ -171,8 +171,6 @@ static void __iomem *reg_pmc_base = IO_ADDRESS(TEGRA_PMC_BASE);
* 0x90000000 - 0x9fffffff - non-prefetchable memory * 0x90000000 - 0x9fffffff - non-prefetchable memory
* 0xa0000000 - 0xbfffffff - prefetchable memory * 0xa0000000 - 0xbfffffff - prefetchable memory
*/ */
#define TEGRA_PCIE_BASE 0x80000000
#define PCIE_REGS_SZ SZ_16K #define PCIE_REGS_SZ SZ_16K
#define PCIE_CFG_OFF PCIE_REGS_SZ #define PCIE_CFG_OFF PCIE_REGS_SZ
#define PCIE_CFG_SZ SZ_1M #define PCIE_CFG_SZ SZ_1M
@ -180,8 +178,6 @@ static void __iomem *reg_pmc_base = IO_ADDRESS(TEGRA_PMC_BASE);
#define PCIE_EXT_CFG_SZ SZ_1M #define PCIE_EXT_CFG_SZ SZ_1M
#define PCIE_IOMAP_SZ (PCIE_REGS_SZ + PCIE_CFG_SZ + PCIE_EXT_CFG_SZ) #define PCIE_IOMAP_SZ (PCIE_REGS_SZ + PCIE_CFG_SZ + PCIE_EXT_CFG_SZ)
#define MMIO_BASE (TEGRA_PCIE_BASE + SZ_4M)
#define MMIO_SIZE SZ_64K
#define MEM_BASE_0 (TEGRA_PCIE_BASE + SZ_256M) #define MEM_BASE_0 (TEGRA_PCIE_BASE + SZ_256M)
#define MEM_SIZE_0 SZ_128M #define MEM_SIZE_0 SZ_128M
#define MEM_BASE_1 (MEM_BASE_0 + MEM_SIZE_0) #define MEM_BASE_1 (MEM_BASE_0 + MEM_SIZE_0)
@ -204,10 +200,9 @@ struct tegra_pcie_port {
bool link_up; bool link_up;
char io_space_name[16];
char mem_space_name[16]; char mem_space_name[16];
char prefetch_space_name[20]; char prefetch_space_name[20];
struct resource res[3]; struct resource res[2];
}; };
struct tegra_pcie_info { struct tegra_pcie_info {
@ -223,17 +218,7 @@ struct tegra_pcie_info {
struct clk *pll_e; struct clk *pll_e;
}; };
static struct tegra_pcie_info tegra_pcie = { static struct tegra_pcie_info tegra_pcie;
.res_mmio = {
.name = "PCI IO",
.start = MMIO_BASE,
.end = MMIO_BASE + MMIO_SIZE - 1,
.flags = IORESOURCE_MEM,
},
};
void __iomem *tegra_pcie_io_base;
EXPORT_SYMBOL(tegra_pcie_io_base);
static inline void afi_writel(u32 value, unsigned long offset) static inline void afi_writel(u32 value, unsigned long offset)
{ {
@ -391,24 +376,7 @@ static int tegra_pcie_setup(int nr, struct pci_sys_data *sys)
pp = tegra_pcie.port + nr; pp = tegra_pcie.port + nr;
pp->root_bus_nr = sys->busnr; pp->root_bus_nr = sys->busnr;
/* pci_ioremap_io(nr * SZ_64K, TEGRA_PCIE_IO_BASE);
* IORESOURCE_IO
*/
snprintf(pp->io_space_name, sizeof(pp->io_space_name),
"PCIe %d I/O", pp->index);
pp->io_space_name[sizeof(pp->io_space_name) - 1] = 0;
pp->res[0].name = pp->io_space_name;
if (pp->index == 0) {
pp->res[0].start = PCIBIOS_MIN_IO;
pp->res[0].end = pp->res[0].start + SZ_32K - 1;
} else {
pp->res[0].start = PCIBIOS_MIN_IO + SZ_32K;
pp->res[0].end = IO_SPACE_LIMIT;
}
pp->res[0].flags = IORESOURCE_IO;
if (request_resource(&ioport_resource, &pp->res[0]))
panic("Request PCIe IO resource failed\n");
pci_add_resource_offset(&sys->resources, &pp->res[0], sys->io_offset);
/* /*
* IORESOURCE_MEM * IORESOURCE_MEM
@ -416,18 +384,18 @@ static int tegra_pcie_setup(int nr, struct pci_sys_data *sys)
snprintf(pp->mem_space_name, sizeof(pp->mem_space_name), snprintf(pp->mem_space_name, sizeof(pp->mem_space_name),
"PCIe %d MEM", pp->index); "PCIe %d MEM", pp->index);
pp->mem_space_name[sizeof(pp->mem_space_name) - 1] = 0; pp->mem_space_name[sizeof(pp->mem_space_name) - 1] = 0;
pp->res[1].name = pp->mem_space_name; pp->res[0].name = pp->mem_space_name;
if (pp->index == 0) { if (pp->index == 0) {
pp->res[1].start = MEM_BASE_0; pp->res[0].start = MEM_BASE_0;
pp->res[1].end = pp->res[1].start + MEM_SIZE_0 - 1; pp->res[0].end = pp->res[0].start + MEM_SIZE_0 - 1;
} else { } else {
pp->res[1].start = MEM_BASE_1; pp->res[0].start = MEM_BASE_1;
pp->res[1].end = pp->res[1].start + MEM_SIZE_1 - 1; pp->res[0].end = pp->res[0].start + MEM_SIZE_1 - 1;
} }
pp->res[1].flags = IORESOURCE_MEM; pp->res[0].flags = IORESOURCE_MEM;
if (request_resource(&iomem_resource, &pp->res[1])) if (request_resource(&iomem_resource, &pp->res[0]))
panic("Request PCIe Memory resource failed\n"); panic("Request PCIe Memory resource failed\n");
pci_add_resource_offset(&sys->resources, &pp->res[1], sys->mem_offset); pci_add_resource_offset(&sys->resources, &pp->res[0], sys->mem_offset);
/* /*
* IORESOURCE_MEM | IORESOURCE_PREFETCH * IORESOURCE_MEM | IORESOURCE_PREFETCH
@ -435,18 +403,18 @@ static int tegra_pcie_setup(int nr, struct pci_sys_data *sys)
snprintf(pp->prefetch_space_name, sizeof(pp->prefetch_space_name), snprintf(pp->prefetch_space_name, sizeof(pp->prefetch_space_name),
"PCIe %d PREFETCH MEM", pp->index); "PCIe %d PREFETCH MEM", pp->index);
pp->prefetch_space_name[sizeof(pp->prefetch_space_name) - 1] = 0; pp->prefetch_space_name[sizeof(pp->prefetch_space_name) - 1] = 0;
pp->res[2].name = pp->prefetch_space_name; pp->res[1].name = pp->prefetch_space_name;
if (pp->index == 0) { if (pp->index == 0) {
pp->res[2].start = PREFETCH_MEM_BASE_0; pp->res[1].start = PREFETCH_MEM_BASE_0;
pp->res[2].end = pp->res[2].start + PREFETCH_MEM_SIZE_0 - 1; pp->res[1].end = pp->res[1].start + PREFETCH_MEM_SIZE_0 - 1;
} else { } else {
pp->res[2].start = PREFETCH_MEM_BASE_1; pp->res[1].start = PREFETCH_MEM_BASE_1;
pp->res[2].end = pp->res[2].start + PREFETCH_MEM_SIZE_1 - 1; pp->res[1].end = pp->res[1].start + PREFETCH_MEM_SIZE_1 - 1;
} }
pp->res[2].flags = IORESOURCE_MEM | IORESOURCE_PREFETCH; pp->res[1].flags = IORESOURCE_MEM | IORESOURCE_PREFETCH;
if (request_resource(&iomem_resource, &pp->res[2])) if (request_resource(&iomem_resource, &pp->res[1]))
panic("Request PCIe Prefetch Memory resource failed\n"); panic("Request PCIe Prefetch Memory resource failed\n");
pci_add_resource_offset(&sys->resources, &pp->res[2], sys->mem_offset); pci_add_resource_offset(&sys->resources, &pp->res[1], sys->mem_offset);
return 1; return 1;
} }
@ -541,8 +509,8 @@ static void tegra_pcie_setup_translations(void)
/* Bar 2: downstream IO bar */ /* Bar 2: downstream IO bar */
fpci_bar = ((__u32)0xfdfc << 16); fpci_bar = ((__u32)0xfdfc << 16);
size = MMIO_SIZE; size = SZ_128K;
axi_address = MMIO_BASE; axi_address = TEGRA_PCIE_IO_BASE;
afi_writel(axi_address, AFI_AXI_BAR2_START); afi_writel(axi_address, AFI_AXI_BAR2_START);
afi_writel(size >> 12, AFI_AXI_BAR2_SZ); afi_writel(size >> 12, AFI_AXI_BAR2_SZ);
afi_writel(fpci_bar, AFI_FPCI_BAR2); afi_writel(fpci_bar, AFI_FPCI_BAR2);
@ -776,7 +744,6 @@ static void tegra_pcie_clocks_put(void)
static int __init tegra_pcie_get_resources(void) static int __init tegra_pcie_get_resources(void)
{ {
struct resource *res_mmio = &tegra_pcie.res_mmio;
int err; int err;
err = tegra_pcie_clocks_get(); err = tegra_pcie_clocks_get();
@ -798,34 +765,16 @@ static int __init tegra_pcie_get_resources(void)
goto err_map_reg; goto err_map_reg;
} }
err = request_resource(&iomem_resource, res_mmio);
if (err) {
pr_err("PCIE: Failed to request resources: %d\n", err);
goto err_req_io;
}
tegra_pcie_io_base = ioremap_nocache(res_mmio->start,
resource_size(res_mmio));
if (tegra_pcie_io_base == NULL) {
pr_err("PCIE: Failed to map IO\n");
err = -ENOMEM;
goto err_map_io;
}
err = request_irq(INT_PCIE_INTR, tegra_pcie_isr, err = request_irq(INT_PCIE_INTR, tegra_pcie_isr,
IRQF_SHARED, "PCIE", &tegra_pcie); IRQF_SHARED, "PCIE", &tegra_pcie);
if (err) { if (err) {
pr_err("PCIE: Failed to register IRQ: %d\n", err); pr_err("PCIE: Failed to register IRQ: %d\n", err);
goto err_irq; goto err_req_io;
} }
set_irq_flags(INT_PCIE_INTR, IRQF_VALID); set_irq_flags(INT_PCIE_INTR, IRQF_VALID);
return 0; return 0;
err_irq:
iounmap(tegra_pcie_io_base);
err_map_io:
release_resource(&tegra_pcie.res_mmio);
err_req_io: err_req_io:
iounmap(tegra_pcie.regs); iounmap(tegra_pcie.regs);
err_map_reg: err_map_reg:

View file

@ -169,11 +169,6 @@ 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
}, {
.virtual = (unsigned long)VERSATILE_PCI_VIRT_MEM_BASE0,
.pfn = __phys_to_pfn(VERSATILE_PCI_MEM_BASE0),
.length = IO_SPACE_LIMIT,
.type = MT_DEVICE
}, },
#endif #endif
}; };

View file

@ -29,7 +29,6 @@
*/ */
#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 MMIO 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)

View file

@ -1,27 +0,0 @@
/*
* 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

View file

@ -169,13 +169,6 @@ 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,
@ -207,12 +200,6 @@ 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 "
@ -227,11 +214,9 @@ static int __init pci_versatile_setup_resources(struct pci_sys_data *sys)
} }
/* /*
* the IO resource for this bus
* 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_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);
@ -260,9 +245,11 @@ int __init pci_versatile_setup(int nr, struct pci_sys_data *sys)
goto out; goto out;
} }
ret = pci_ioremap_io(0, VERSATILE_PCI_MEM_BASE0);
if (ret)
goto out;
if (nr == 0) { if (nr == 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");
@ -319,7 +306,6 @@ int __init pci_versatile_setup(int nr, struct pci_sys_data *sys)
void __init pci_versatile_preinit(void) void __init pci_versatile_preinit(void)
{ {
pcibios_min_io = 0x44000000;
pcibios_min_mem = 0x50000000; pcibios_min_mem = 0x50000000;
__raw_writel(VERSATILE_PCI_MEM_BASE0 >> 28, PCI_IMAP0); __raw_writel(VERSATILE_PCI_MEM_BASE0 >> 28, PCI_IMAP0);

View file

@ -36,6 +36,7 @@
#include <asm/system_info.h> #include <asm/system_info.h>
#include <asm/mach/map.h> #include <asm/mach/map.h>
#include <asm/mach/pci.h>
#include "mm.h" #include "mm.h"
int ioremap_page(unsigned long virt, unsigned long phys, int ioremap_page(unsigned long virt, unsigned long phys,
@ -383,3 +384,16 @@ void __arm_iounmap(volatile void __iomem *io_addr)
arch_iounmap(io_addr); arch_iounmap(io_addr);
} }
EXPORT_SYMBOL(__arm_iounmap); EXPORT_SYMBOL(__arm_iounmap);
#ifdef CONFIG_PCI
int pci_ioremap_io(unsigned int offset, phys_addr_t phys_addr)
{
BUG_ON(offset + SZ_64K > IO_SPACE_LIMIT);
return ioremap_page_range(PCI_IO_VIRT_BASE + offset,
PCI_IO_VIRT_BASE + offset + SZ_64K,
phys_addr,
__pgprot(get_mem_type(MT_DEVICE)->prot_pte));
}
EXPORT_SYMBOL_GPL(pci_ioremap_io);
#endif

View file

@ -31,6 +31,7 @@
#include <asm/mach/arch.h> #include <asm/mach/arch.h>
#include <asm/mach/map.h> #include <asm/mach/map.h>
#include <asm/mach/pci.h>
#include "mm.h" #include "mm.h"
@ -216,7 +217,7 @@ static struct mem_type mem_types[] = {
.prot_l1 = PMD_TYPE_TABLE, .prot_l1 = PMD_TYPE_TABLE,
.prot_sect = PROT_SECT_DEVICE | PMD_SECT_WB, .prot_sect = PROT_SECT_DEVICE | PMD_SECT_WB,
.domain = DOMAIN_IO, .domain = DOMAIN_IO,
}, },
[MT_DEVICE_WC] = { /* ioremap_wc */ [MT_DEVICE_WC] = { /* ioremap_wc */
.prot_pte = PROT_PTE_DEVICE | L_PTE_MT_DEV_WC, .prot_pte = PROT_PTE_DEVICE | L_PTE_MT_DEV_WC,
.prot_l1 = PMD_TYPE_TABLE, .prot_l1 = PMD_TYPE_TABLE,
@ -777,14 +778,27 @@ void __init iotable_init(struct map_desc *io_desc, int nr)
create_mapping(md); create_mapping(md);
vm->addr = (void *)(md->virtual & PAGE_MASK); vm->addr = (void *)(md->virtual & PAGE_MASK);
vm->size = PAGE_ALIGN(md->length + (md->virtual & ~PAGE_MASK)); vm->size = PAGE_ALIGN(md->length + (md->virtual & ~PAGE_MASK));
vm->phys_addr = __pfn_to_phys(md->pfn); vm->phys_addr = __pfn_to_phys(md->pfn);
vm->flags = VM_IOREMAP | VM_ARM_STATIC_MAPPING; vm->flags = VM_IOREMAP | VM_ARM_STATIC_MAPPING;
vm->flags |= VM_ARM_MTYPE(md->type); vm->flags |= VM_ARM_MTYPE(md->type);
vm->caller = iotable_init; vm->caller = iotable_init;
vm_area_add_early(vm++); vm_area_add_early(vm++);
} }
} }
void __init vm_reserve_area_early(unsigned long addr, unsigned long size,
void *caller)
{
struct vm_struct *vm;
vm = early_alloc_aligned(sizeof(*vm), __alignof__(*vm));
vm->addr = (void *)addr;
vm->size = size;
vm->flags = VM_IOREMAP | VM_ARM_STATIC_MAPPING;
vm->caller = caller;
vm_area_add_early(vm);
}
#ifndef CONFIG_ARM_LPAE #ifndef CONFIG_ARM_LPAE
/* /*
@ -802,14 +816,7 @@ void __init iotable_init(struct map_desc *io_desc, int nr)
static void __init pmd_empty_section_gap(unsigned long addr) static void __init pmd_empty_section_gap(unsigned long addr)
{ {
struct vm_struct *vm; vm_reserve_area_early(addr, SECTION_SIZE, pmd_empty_section_gap);
vm = early_alloc_aligned(sizeof(*vm), __alignof__(*vm));
vm->addr = (void *)addr;
vm->size = SECTION_SIZE;
vm->flags = VM_IOREMAP | VM_ARM_STATIC_MAPPING;
vm->caller = pmd_empty_section_gap;
vm_area_add_early(vm);
} }
static void __init fill_pmd_gaps(void) static void __init fill_pmd_gaps(void)
@ -858,6 +865,28 @@ static void __init fill_pmd_gaps(void)
#define fill_pmd_gaps() do { } while (0) #define fill_pmd_gaps() do { } while (0)
#endif #endif
#if defined(CONFIG_PCI) && !defined(CONFIG_NEED_MACH_IO_H)
static void __init pci_reserve_io(void)
{
struct vm_struct *vm;
unsigned long addr;
/* we're still single threaded hence no lock needed here */
for (vm = vmlist; vm; vm = vm->next) {
if (!(vm->flags & VM_ARM_STATIC_MAPPING))
continue;
addr = (unsigned long)vm->addr;
addr &= ~(SZ_2M - 1);
if (addr == PCI_IO_VIRT_BASE)
return;
}
vm_reserve_area_early(PCI_IO_VIRT_BASE, SZ_2M, pci_reserve_io);
}
#else
#define pci_reserve_io() do { } while (0)
#endif
static void * __initdata vmalloc_min = static void * __initdata vmalloc_min =
(void *)(VMALLOC_END - (240 << 20) - VMALLOC_OFFSET); (void *)(VMALLOC_END - (240 << 20) - VMALLOC_OFFSET);
@ -1141,6 +1170,9 @@ static void __init devicemaps_init(struct machine_desc *mdesc)
mdesc->map_io(); mdesc->map_io();
fill_pmd_gaps(); fill_pmd_gaps();
/* Reserve fixed i/o space in VMALLOC region */
pci_reserve_io();
/* /*
* Finally flush the caches and tlb to ensure that we're in a * Finally flush the caches and tlb to ensure that we're in a
* consistent state wrt the writebuffer. This also ensures that * consistent state wrt the writebuffer. This also ensures that

View file

@ -192,30 +192,24 @@ int iop3xx_pci_setup(int nr, struct pci_sys_data *sys)
if (nr != 0) if (nr != 0)
return 0; return 0;
res = kzalloc(2 * sizeof(struct resource), GFP_KERNEL); res = kzalloc(sizeof(struct resource), GFP_KERNEL);
if (!res) if (!res)
panic("PCI: unable to alloc resources"); panic("PCI: unable to alloc resources");
res[0].start = IOP3XX_PCI_LOWER_IO_PA; res->start = IOP3XX_PCI_LOWER_MEM_PA;
res[0].end = IOP3XX_PCI_LOWER_IO_PA + IOP3XX_PCI_IO_WINDOW_SIZE - 1; res->end = IOP3XX_PCI_LOWER_MEM_PA + IOP3XX_PCI_MEM_WINDOW_SIZE - 1;
res[0].name = "IOP3XX PCI I/O Space"; res->name = "IOP3XX PCI Memory Space";
res[0].flags = IORESOURCE_IO; res->flags = IORESOURCE_MEM;
request_resource(&ioport_resource, &res[0]); request_resource(&iomem_resource, res);
res[1].start = IOP3XX_PCI_LOWER_MEM_PA;
res[1].end = IOP3XX_PCI_LOWER_MEM_PA + IOP3XX_PCI_MEM_WINDOW_SIZE - 1;
res[1].name = "IOP3XX PCI Memory Space";
res[1].flags = IORESOURCE_MEM;
request_resource(&iomem_resource, &res[1]);
/* /*
* Use whatever translation is already setup. * Use whatever translation is already setup.
*/ */
sys->mem_offset = IOP3XX_PCI_LOWER_MEM_PA - *IOP3XX_OMWTVR0; sys->mem_offset = IOP3XX_PCI_LOWER_MEM_PA - *IOP3XX_OMWTVR0;
sys->io_offset = IOP3XX_PCI_LOWER_IO_PA - *IOP3XX_OIOWTVR;
pci_add_resource_offset(&sys->resources, &res[0], sys->io_offset); pci_add_resource_offset(&sys->resources, res, sys->mem_offset);
pci_add_resource_offset(&sys->resources, &res[1], sys->mem_offset);
pci_ioremap_io(0, IOP3XX_PCI_LOWER_IO_PA);
return 1; return 1;
} }
@ -367,7 +361,6 @@ void __init iop3xx_pci_preinit_cond(void)
void __init iop3xx_pci_preinit(void) void __init iop3xx_pci_preinit(void)
{ {
pcibios_min_io = 0;
pcibios_min_mem = 0; pcibios_min_mem = 0;
iop3xx_atu_disable(); iop3xx_atu_disable();

View file

@ -25,11 +25,6 @@ static struct map_desc iop3xx_std_desc[] __initdata = {
.pfn = __phys_to_pfn(IOP3XX_PERIPHERAL_PHYS_BASE), .pfn = __phys_to_pfn(IOP3XX_PERIPHERAL_PHYS_BASE),
.length = IOP3XX_PERIPHERAL_SIZE, .length = IOP3XX_PERIPHERAL_SIZE,
.type = MT_UNCACHED, .type = MT_UNCACHED,
}, { /* PCI IO space */
.virtual = IOP3XX_PCI_LOWER_IO_VA,
.pfn = __phys_to_pfn(IOP3XX_PCI_LOWER_IO_PA),
.length = IOP3XX_PCI_IO_WINDOW_SIZE,
.type = MT_DEVICE,
}, },
}; };

View file

@ -4,13 +4,13 @@
/* Copyright (C) 2003 Peter Milne, D-TACQ Solutions Ltd /* Copyright (C) 2003 Peter Milne, D-TACQ Solutions Ltd
* <Peter dot Milne at D hyphen TACQ dot com> * <Peter dot Milne at D hyphen TACQ dot com>
* *
* With acknowledgements to i2c-algo-ibm_ocp.c by * With acknowledgements to i2c-algo-ibm_ocp.c by
* Ian DaSilva, MontaVista Software, Inc. idasilva@mvista.com * Ian DaSilva, MontaVista Software, Inc. idasilva@mvista.com
* *
* And i2c-algo-pcf.c, which was created by Simon G. Vogl and Hans Berglund: * And i2c-algo-pcf.c, which was created by Simon G. Vogl and Hans Berglund:
* *
* Copyright (C) 1995-1997 Simon G. Vogl, 1998-2000 Hans Berglund * Copyright (C) 1995-1997 Simon G. Vogl, 1998-2000 Hans Berglund
* *
* And which acknowledged Kyösti Mälkki <kmalkki@cc.hut.fi>, * And which acknowledged Kyösti Mälkki <kmalkki@cc.hut.fi>,
* Frodo Looijaard <frodol@dds.nl>, Martin Bailey<mbailey@littlefeet-inc.com> * Frodo Looijaard <frodol@dds.nl>, Martin Bailey<mbailey@littlefeet-inc.com>
* *
@ -39,14 +39,15 @@
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/gpio.h>
#include "i2c-iop3xx.h" #include "i2c-iop3xx.h"
/* global unit counter */ /* global unit counter */
static int i2c_id; static int i2c_id;
static inline unsigned char static inline unsigned char
iic_cook_addr(struct i2c_msg *msg) iic_cook_addr(struct i2c_msg *msg)
{ {
unsigned char addr; unsigned char addr;
@ -55,38 +56,38 @@ iic_cook_addr(struct i2c_msg *msg)
if (msg->flags & I2C_M_RD) if (msg->flags & I2C_M_RD)
addr |= 1; addr |= 1;
return addr; return addr;
} }
static void static void
iop3xx_i2c_reset(struct i2c_algo_iop3xx_data *iop3xx_adap) iop3xx_i2c_reset(struct i2c_algo_iop3xx_data *iop3xx_adap)
{ {
/* Follows devman 9.3 */ /* Follows devman 9.3 */
__raw_writel(IOP3XX_ICR_UNIT_RESET, iop3xx_adap->ioaddr + CR_OFFSET); __raw_writel(IOP3XX_ICR_UNIT_RESET, iop3xx_adap->ioaddr + CR_OFFSET);
__raw_writel(IOP3XX_ISR_CLEARBITS, iop3xx_adap->ioaddr + SR_OFFSET); __raw_writel(IOP3XX_ISR_CLEARBITS, iop3xx_adap->ioaddr + SR_OFFSET);
__raw_writel(0, iop3xx_adap->ioaddr + CR_OFFSET); __raw_writel(0, iop3xx_adap->ioaddr + CR_OFFSET);
} }
static void static void
iop3xx_i2c_enable(struct i2c_algo_iop3xx_data *iop3xx_adap) iop3xx_i2c_enable(struct i2c_algo_iop3xx_data *iop3xx_adap)
{ {
u32 cr = IOP3XX_ICR_GCD | IOP3XX_ICR_SCLEN | IOP3XX_ICR_UE; u32 cr = IOP3XX_ICR_GCD | IOP3XX_ICR_SCLEN | IOP3XX_ICR_UE;
/* /*
* Every time unit enable is asserted, GPOD needs to be cleared * Every time unit enable is asserted, GPOD needs to be cleared
* on IOP3XX to avoid data corruption on the bus. * on IOP3XX to avoid data corruption on the bus.
*/ */
#if defined(CONFIG_ARCH_IOP32X) || defined(CONFIG_ARCH_IOP33X) #if defined(CONFIG_ARCH_IOP32X) || defined(CONFIG_ARCH_IOP33X)
if (iop3xx_adap->id == 0) { if (iop3xx_adap->id == 0) {
gpio_line_set(IOP3XX_GPIO_LINE(7), GPIO_LOW); gpio_set_value(7, 0);
gpio_line_set(IOP3XX_GPIO_LINE(6), GPIO_LOW); gpio_set_value(6, 0);
} else { } else {
gpio_line_set(IOP3XX_GPIO_LINE(5), GPIO_LOW); gpio_set_value(5, 0);
gpio_line_set(IOP3XX_GPIO_LINE(4), GPIO_LOW); gpio_set_value(4, 0);
} }
#endif #endif
/* NB SR bits not same position as CR IE bits :-( */ /* NB SR bits not same position as CR IE bits :-( */
iop3xx_adap->SR_enabled = iop3xx_adap->SR_enabled =
IOP3XX_ISR_ALD | IOP3XX_ISR_BERRD | IOP3XX_ISR_ALD | IOP3XX_ISR_BERRD |
IOP3XX_ISR_RXFULL | IOP3XX_ISR_TXEMPTY; IOP3XX_ISR_RXFULL | IOP3XX_ISR_TXEMPTY;
@ -96,23 +97,23 @@ iop3xx_i2c_enable(struct i2c_algo_iop3xx_data *iop3xx_adap)
__raw_writel(cr, iop3xx_adap->ioaddr + CR_OFFSET); __raw_writel(cr, iop3xx_adap->ioaddr + CR_OFFSET);
} }
static void static void
iop3xx_i2c_transaction_cleanup(struct i2c_algo_iop3xx_data *iop3xx_adap) iop3xx_i2c_transaction_cleanup(struct i2c_algo_iop3xx_data *iop3xx_adap)
{ {
unsigned long cr = __raw_readl(iop3xx_adap->ioaddr + CR_OFFSET); unsigned long cr = __raw_readl(iop3xx_adap->ioaddr + CR_OFFSET);
cr &= ~(IOP3XX_ICR_MSTART | IOP3XX_ICR_TBYTE | cr &= ~(IOP3XX_ICR_MSTART | IOP3XX_ICR_TBYTE |
IOP3XX_ICR_MSTOP | IOP3XX_ICR_SCLEN); IOP3XX_ICR_MSTOP | IOP3XX_ICR_SCLEN);
__raw_writel(cr, iop3xx_adap->ioaddr + CR_OFFSET); __raw_writel(cr, iop3xx_adap->ioaddr + CR_OFFSET);
} }
/* /*
* NB: the handler has to clear the source of the interrupt! * NB: the handler has to clear the source of the interrupt!
* Then it passes the SR flags of interest to BH via adap data * Then it passes the SR flags of interest to BH via adap data
*/ */
static irqreturn_t static irqreturn_t
iop3xx_i2c_irq_handler(int this_irq, void *dev_id) iop3xx_i2c_irq_handler(int this_irq, void *dev_id)
{ {
struct i2c_algo_iop3xx_data *iop3xx_adap = dev_id; struct i2c_algo_iop3xx_data *iop3xx_adap = dev_id;
u32 sr = __raw_readl(iop3xx_adap->ioaddr + SR_OFFSET); u32 sr = __raw_readl(iop3xx_adap->ioaddr + SR_OFFSET);
@ -126,7 +127,7 @@ iop3xx_i2c_irq_handler(int this_irq, void *dev_id)
} }
/* check all error conditions, clear them , report most important */ /* check all error conditions, clear them , report most important */
static int static int
iop3xx_i2c_error(u32 sr) iop3xx_i2c_error(u32 sr)
{ {
int rc = 0; int rc = 0;
@ -135,12 +136,12 @@ iop3xx_i2c_error(u32 sr)
if ( !rc ) rc = -I2C_ERR_BERR; if ( !rc ) rc = -I2C_ERR_BERR;
} }
if ((sr & IOP3XX_ISR_ALD)) { if ((sr & IOP3XX_ISR_ALD)) {
if ( !rc ) rc = -I2C_ERR_ALD; if ( !rc ) rc = -I2C_ERR_ALD;
} }
return rc; return rc;
} }
static inline u32 static inline u32
iop3xx_i2c_get_srstat(struct i2c_algo_iop3xx_data *iop3xx_adap) iop3xx_i2c_get_srstat(struct i2c_algo_iop3xx_data *iop3xx_adap)
{ {
unsigned long flags; unsigned long flags;
@ -161,8 +162,8 @@ iop3xx_i2c_get_srstat(struct i2c_algo_iop3xx_data *iop3xx_adap)
typedef int (* compare_func)(unsigned test, unsigned mask); typedef int (* compare_func)(unsigned test, unsigned mask);
/* returns 1 on correct comparison */ /* returns 1 on correct comparison */
static int static int
iop3xx_i2c_wait_event(struct i2c_algo_iop3xx_data *iop3xx_adap, iop3xx_i2c_wait_event(struct i2c_algo_iop3xx_data *iop3xx_adap,
unsigned flags, unsigned* status, unsigned flags, unsigned* status,
compare_func compare) compare_func compare)
{ {
@ -192,47 +193,47 @@ iop3xx_i2c_wait_event(struct i2c_algo_iop3xx_data *iop3xx_adap,
} }
/* /*
* Concrete compare_funcs * Concrete compare_funcs
*/ */
static int static int
all_bits_clear(unsigned test, unsigned mask) all_bits_clear(unsigned test, unsigned mask)
{ {
return (test & mask) == 0; return (test & mask) == 0;
} }
static int static int
any_bits_set(unsigned test, unsigned mask) any_bits_set(unsigned test, unsigned mask)
{ {
return (test & mask) != 0; return (test & mask) != 0;
} }
static int static int
iop3xx_i2c_wait_tx_done(struct i2c_algo_iop3xx_data *iop3xx_adap, int *status) iop3xx_i2c_wait_tx_done(struct i2c_algo_iop3xx_data *iop3xx_adap, int *status)
{ {
return iop3xx_i2c_wait_event( return iop3xx_i2c_wait_event(
iop3xx_adap, iop3xx_adap,
IOP3XX_ISR_TXEMPTY | IOP3XX_ISR_ALD | IOP3XX_ISR_BERRD, IOP3XX_ISR_TXEMPTY | IOP3XX_ISR_ALD | IOP3XX_ISR_BERRD,
status, any_bits_set); status, any_bits_set);
} }
static int static int
iop3xx_i2c_wait_rx_done(struct i2c_algo_iop3xx_data *iop3xx_adap, int *status) iop3xx_i2c_wait_rx_done(struct i2c_algo_iop3xx_data *iop3xx_adap, int *status)
{ {
return iop3xx_i2c_wait_event( return iop3xx_i2c_wait_event(
iop3xx_adap, iop3xx_adap,
IOP3XX_ISR_RXFULL | IOP3XX_ISR_ALD | IOP3XX_ISR_BERRD, IOP3XX_ISR_RXFULL | IOP3XX_ISR_ALD | IOP3XX_ISR_BERRD,
status, any_bits_set); status, any_bits_set);
} }
static int static int
iop3xx_i2c_wait_idle(struct i2c_algo_iop3xx_data *iop3xx_adap, int *status) iop3xx_i2c_wait_idle(struct i2c_algo_iop3xx_data *iop3xx_adap, int *status)
{ {
return iop3xx_i2c_wait_event( return iop3xx_i2c_wait_event(
iop3xx_adap, IOP3XX_ISR_UNITBUSY, status, all_bits_clear); iop3xx_adap, IOP3XX_ISR_UNITBUSY, status, all_bits_clear);
} }
static int static int
iop3xx_i2c_send_target_addr(struct i2c_algo_iop3xx_data *iop3xx_adap, iop3xx_i2c_send_target_addr(struct i2c_algo_iop3xx_data *iop3xx_adap,
struct i2c_msg* msg) struct i2c_msg* msg)
{ {
unsigned long cr = __raw_readl(iop3xx_adap->ioaddr + CR_OFFSET); unsigned long cr = __raw_readl(iop3xx_adap->ioaddr + CR_OFFSET);
@ -247,7 +248,7 @@ iop3xx_i2c_send_target_addr(struct i2c_algo_iop3xx_data *iop3xx_adap,
} }
__raw_writel(iic_cook_addr(msg), iop3xx_adap->ioaddr + DBR_OFFSET); __raw_writel(iic_cook_addr(msg), iop3xx_adap->ioaddr + DBR_OFFSET);
cr &= ~(IOP3XX_ICR_MSTOP | IOP3XX_ICR_NACK); cr &= ~(IOP3XX_ICR_MSTOP | IOP3XX_ICR_NACK);
cr |= IOP3XX_ICR_MSTART | IOP3XX_ICR_TBYTE; cr |= IOP3XX_ICR_MSTART | IOP3XX_ICR_TBYTE;
@ -257,8 +258,8 @@ iop3xx_i2c_send_target_addr(struct i2c_algo_iop3xx_data *iop3xx_adap,
return rc; return rc;
} }
static int static int
iop3xx_i2c_write_byte(struct i2c_algo_iop3xx_data *iop3xx_adap, char byte, iop3xx_i2c_write_byte(struct i2c_algo_iop3xx_data *iop3xx_adap, char byte,
int stop) int stop)
{ {
unsigned long cr = __raw_readl(iop3xx_adap->ioaddr + CR_OFFSET); unsigned long cr = __raw_readl(iop3xx_adap->ioaddr + CR_OFFSET);
@ -277,10 +278,10 @@ iop3xx_i2c_write_byte(struct i2c_algo_iop3xx_data *iop3xx_adap, char byte,
rc = iop3xx_i2c_wait_tx_done(iop3xx_adap, &status); rc = iop3xx_i2c_wait_tx_done(iop3xx_adap, &status);
return rc; return rc;
} }
static int static int
iop3xx_i2c_read_byte(struct i2c_algo_iop3xx_data *iop3xx_adap, char* byte, iop3xx_i2c_read_byte(struct i2c_algo_iop3xx_data *iop3xx_adap, char* byte,
int stop) int stop)
{ {
unsigned long cr = __raw_readl(iop3xx_adap->ioaddr + CR_OFFSET); unsigned long cr = __raw_readl(iop3xx_adap->ioaddr + CR_OFFSET);
@ -304,19 +305,19 @@ iop3xx_i2c_read_byte(struct i2c_algo_iop3xx_data *iop3xx_adap, char* byte,
return rc; return rc;
} }
static int static int
iop3xx_i2c_writebytes(struct i2c_adapter *i2c_adap, const char *buf, int count) iop3xx_i2c_writebytes(struct i2c_adapter *i2c_adap, const char *buf, int count)
{ {
struct i2c_algo_iop3xx_data *iop3xx_adap = i2c_adap->algo_data; struct i2c_algo_iop3xx_data *iop3xx_adap = i2c_adap->algo_data;
int ii; int ii;
int rc = 0; int rc = 0;
for (ii = 0; rc == 0 && ii != count; ++ii) for (ii = 0; rc == 0 && ii != count; ++ii)
rc = iop3xx_i2c_write_byte(iop3xx_adap, buf[ii], ii==count-1); rc = iop3xx_i2c_write_byte(iop3xx_adap, buf[ii], ii==count-1);
return rc; return rc;
} }
static int static int
iop3xx_i2c_readbytes(struct i2c_adapter *i2c_adap, char *buf, int count) iop3xx_i2c_readbytes(struct i2c_adapter *i2c_adap, char *buf, int count)
{ {
struct i2c_algo_iop3xx_data *iop3xx_adap = i2c_adap->algo_data; struct i2c_algo_iop3xx_data *iop3xx_adap = i2c_adap->algo_data;
@ -325,7 +326,7 @@ iop3xx_i2c_readbytes(struct i2c_adapter *i2c_adap, char *buf, int count)
for (ii = 0; rc == 0 && ii != count; ++ii) for (ii = 0; rc == 0 && ii != count; ++ii)
rc = iop3xx_i2c_read_byte(iop3xx_adap, &buf[ii], ii==count-1); rc = iop3xx_i2c_read_byte(iop3xx_adap, &buf[ii], ii==count-1);
return rc; return rc;
} }
@ -336,8 +337,8 @@ iop3xx_i2c_readbytes(struct i2c_adapter *i2c_adap, char *buf, int count)
* Each transfer (i.e. a read or a write) is separated by a repeated start * Each transfer (i.e. a read or a write) is separated by a repeated start
* condition. * condition.
*/ */
static int static int
iop3xx_i2c_handle_msg(struct i2c_adapter *i2c_adap, struct i2c_msg* pmsg) iop3xx_i2c_handle_msg(struct i2c_adapter *i2c_adap, struct i2c_msg* pmsg)
{ {
struct i2c_algo_iop3xx_data *iop3xx_adap = i2c_adap->algo_data; struct i2c_algo_iop3xx_data *iop3xx_adap = i2c_adap->algo_data;
int rc; int rc;
@ -357,8 +358,8 @@ iop3xx_i2c_handle_msg(struct i2c_adapter *i2c_adap, struct i2c_msg* pmsg)
/* /*
* master_xfer() - main read/write entry * master_xfer() - main read/write entry
*/ */
static int static int
iop3xx_i2c_master_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, iop3xx_i2c_master_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs,
int num) int num)
{ {
struct i2c_algo_iop3xx_data *iop3xx_adap = i2c_adap->algo_data; struct i2c_algo_iop3xx_data *iop3xx_adap = i2c_adap->algo_data;
@ -375,14 +376,14 @@ iop3xx_i2c_master_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs,
} }
iop3xx_i2c_transaction_cleanup(iop3xx_adap); iop3xx_i2c_transaction_cleanup(iop3xx_adap);
if(ret) if(ret)
return ret; return ret;
return im; return im;
} }
static u32 static u32
iop3xx_i2c_func(struct i2c_adapter *adap) iop3xx_i2c_func(struct i2c_adapter *adap)
{ {
return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
@ -393,11 +394,11 @@ static const struct i2c_algorithm iop3xx_i2c_algo = {
.functionality = iop3xx_i2c_func, .functionality = iop3xx_i2c_func,
}; };
static int static int
iop3xx_i2c_remove(struct platform_device *pdev) iop3xx_i2c_remove(struct platform_device *pdev)
{ {
struct i2c_adapter *padapter = platform_get_drvdata(pdev); struct i2c_adapter *padapter = platform_get_drvdata(pdev);
struct i2c_algo_iop3xx_data *adapter_data = struct i2c_algo_iop3xx_data *adapter_data =
(struct i2c_algo_iop3xx_data *)padapter->algo_data; (struct i2c_algo_iop3xx_data *)padapter->algo_data;
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
unsigned long cr = __raw_readl(adapter_data->ioaddr + CR_OFFSET); unsigned long cr = __raw_readl(adapter_data->ioaddr + CR_OFFSET);
@ -419,7 +420,7 @@ iop3xx_i2c_remove(struct platform_device *pdev)
return 0; return 0;
} }
static int static int
iop3xx_i2c_probe(struct platform_device *pdev) iop3xx_i2c_probe(struct platform_device *pdev)
{ {
struct resource *res; struct resource *res;