[PATCH 6/7] arm/realview: enable PCI for realview-eb and realview-pb1176

Arnd Bergmann arnd at arndb.de
Thu Oct 14 12:10:56 EDT 2010


These two boards use the Xilinx PCI macro, so enable the
code and set up all the I/O windows for it.

Signed-off-by: Arnd Bergmann <arnd at arndb.de>
---
 arch/arm/Kconfig                                   |    2 +-
 arch/arm/mach-realview/include/mach/board-eb.h     |   19 ++++
 arch/arm/mach-realview/include/mach/board-pb1176.h |    1 +
 arch/arm/mach-realview/include/mach/hardware.h     |   14 +++-
 arch/arm/mach-realview/include/mach/io.h           |    6 +-
 arch/arm/mach-realview/include/mach/irqs-eb.h      |    5 +
 arch/arm/mach-realview/include/mach/irqs-pb1176.h  |    5 +-
 arch/arm/mach-realview/realview_eb.c               |   84 ++++++++++++++++-
 arch/arm/mach-realview/realview_pb1176.c           |  102 ++++++++++++++++++++
 9 files changed, 232 insertions(+), 6 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 5bf08c7..8533bbe 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1146,7 +1146,7 @@ config ISA_DMA_API
 	bool
 
 config PCI
-	bool "PCI support" if ARCH_INTEGRATOR_AP || ARCH_VERSATILE_PB || ARCH_IXP4XX || ARCH_KS8695 || MACH_ARMCORE || ARCH_CNS3XXX
+	bool "PCI support" if ARCH_INTEGRATOR_AP || ARCH_VERSATILE_PB || ARCH_IXP4XX || ARCH_KS8695 || MACH_ARMCORE || ARCH_CNS3XXX || ARCH_REALVIEW
 	help
 	  Find out whether you have a PCI motherboard. PCI is the name of a
 	  bus system, i.e. the way the CPU talks to the other stuff inside
diff --git a/arch/arm/mach-realview/include/mach/board-eb.h b/arch/arm/mach-realview/include/mach/board-eb.h
index 794a8d9..7510516 100644
--- a/arch/arm/mach-realview/include/mach/board-eb.h
+++ b/arch/arm/mach-realview/include/mach/board-eb.h
@@ -36,6 +36,7 @@
 #define REALVIEW_EB_TIMER2_3_BASE	0x10012000	/* Timer 2 and 3 */
 #define REALVIEW_EB_GPIO0_BASE		0x10013000	/* GPIO port 0 */
 #define REALVIEW_EB_RTC_BASE		0x10017000	/* Real Time Clock */
+#define REALVIEW_EB_PCI_CORE_BASE	0x10019000	/* PCI map and control */
 #define REALVIEW_EB_CLCD_BASE		0x10020000	/* CLCD */
 #define REALVIEW_EB_GIC_CPU_BASE	0x10040000	/* Generic interrupt controller CPU interface */
 #define REALVIEW_EB_GIC_DIST_BASE	0x10041000	/* Generic interrupt controller distributor */
@@ -63,6 +64,24 @@
 #endif
 
 /*
+ * PCI regions
+ */
+#define REALVIEW_EB_PCI_BASE		0x60000000 /* PCI self config */
+#define REALVIEW_EB_PCI_CFG_BASE	0x61000000 /* PCI config */
+#define REALVIEW_EB_PCI_IO_BASE0	0x62000000 /* PCI IO region */
+#define REALVIEW_EB_PCI_MEM_BASE0	0x63000000 /* Memory region 1 */
+#define REALVIEW_EB_PCI_MEM_BASE1	0x64000000 /* Memory region 2 */
+#define REALVIEW_EB_PCI_MEM_BASE2	0x68000000 /* Memory region 3 */
+
+#define REALVIEW_EB_PCI_BASE_SIZE	0x01000000 /* 16MB */
+#define REALVIEW_EB_PCI_CFG_BASE_SIZE	0x01000000 /* 16MB */
+#define REALVIEW_EB_PCI_IO_BASE0_SIZE	0x01000000 /* 16MB */
+#define REALVIEW_EB_PCI_MEM_BASE0_SIZE	0x01000000 /* 16MB */
+#define REALVIEW_EB_PCI_MEM_BASE1_SIZE	0x04000000 /* 64MB */
+#define REALVIEW_EB_PCI_MEM_BASE2_SIZE	0x08000000 /* 128MB */
+
+
+/*
  * Core tile identification (REALVIEW_SYS_PROCID)
  */
 #define REALVIEW_EB_PROC_MASK		0xFF000000
diff --git a/arch/arm/mach-realview/include/mach/board-pb1176.h b/arch/arm/mach-realview/include/mach/board-pb1176.h
index 002ab5d..b11a159 100644
--- a/arch/arm/mach-realview/include/mach/board-pb1176.h
+++ b/arch/arm/mach-realview/include/mach/board-pb1176.h
@@ -27,6 +27,7 @@
  * Peripheral addresses
  */
 #define REALVIEW_PB1176_UART4_BASE		0x10009000 /* UART 4 */
+#define REALVIEW_PB1176_PCI_CORE_BASE		0x10019000 /* PCI map and control */
 #define REALVIEW_PB1176_SCTL_BASE		0x10100000 /* System controller */
 #define REALVIEW_PB1176_SMC_BASE		0x10111000 /* SMC */
 #define REALVIEW_PB1176_DMC_BASE		0x10109000 /* DMC configuration */
diff --git a/arch/arm/mach-realview/include/mach/hardware.h b/arch/arm/mach-realview/include/mach/hardware.h
index 8a638d1..ff60011 100644
--- a/arch/arm/mach-realview/include/mach/hardware.h
+++ b/arch/arm/mach-realview/include/mach/hardware.h
@@ -37,6 +37,18 @@
 #else
 #define IO_ADDRESS(x)		(x)
 #endif
-#define __io_address(n)		__io(IO_ADDRESS(n))
+#define __io_address(n)		((void __iomem *)(IO_ADDRESS(n)))
+
+/*
+ * PCI space virtual addresses
+ */
+#define REALVIEW_PCI_VIRT_BASE		(void __iomem *)0xf8000000ul
+#define REALVIEW_PCI_CFG_VIRT_BASE	(void __iomem *)0xf9000000ul
+#define REALVIEW_PCI_IO_VIRT_BASE	(void __iomem *)PCIO_BASE
+
+#define PCIBIOS_MIN_IO			0x00001000
+#define PCIBIOS_MIN_MEM			0x00000000
+
+#define pcibios_assign_all_busses()     1
 
 #endif
diff --git a/arch/arm/mach-realview/include/mach/io.h b/arch/arm/mach-realview/include/mach/io.h
index f05bcdf..14304f9 100644
--- a/arch/arm/mach-realview/include/mach/io.h
+++ b/arch/arm/mach-realview/include/mach/io.h
@@ -20,9 +20,11 @@
 #ifndef __ASM_ARM_ARCH_IO_H
 #define __ASM_ARM_ARCH_IO_H
 
-#define IO_SPACE_LIMIT 0xffffffff
+#define PCIO_BASE	(void __iomem *)0xfa000000ul
+#define PCIO_SIZE	0x00100000ul
+#define IO_SPACE_LIMIT  (PCIO_SIZE - 1)
 
-#define __io(a)		__typesafe_io(a)
+#define __io(a)		((a) + PCIO_BASE)
 #define __mem_pci(a)	(a)
 
 #endif
diff --git a/arch/arm/mach-realview/include/mach/irqs-eb.h b/arch/arm/mach-realview/include/mach/irqs-eb.h
index 204d537..1511518 100644
--- a/arch/arm/mach-realview/include/mach/irqs-eb.h
+++ b/arch/arm/mach-realview/include/mach/irqs-eb.h
@@ -59,6 +59,11 @@
 #define IRQ_EB_TSPEN		(IRQ_EB_GIC_START + 30)		/* Touchscreen pen */
 #define IRQ_EB_TSKPAD		(IRQ_EB_GIC_START + 31)		/* Touchscreen keypad */
 
+#define IRQ_EB_PCI0		(IRQ_EB_GIC_START + 48)		/* PCI IntA */
+#define IRQ_EB_PCI1		(IRQ_EB_GIC_START + 49)		/* PCI IntB */
+#define IRQ_EB_PCI2		(IRQ_EB_GIC_START + 50)		/* PCI IntC */
+#define IRQ_EB_PCI3		(IRQ_EB_GIC_START + 51)		/* PCI IntD */
+
 /*
  * RealView EB + ARM11MPCore interrupt sources (primary GIC on the core tile)
  */
diff --git a/arch/arm/mach-realview/include/mach/irqs-pb1176.h b/arch/arm/mach-realview/include/mach/irqs-pb1176.h
index 5c3c625..cf92425 100644
--- a/arch/arm/mach-realview/include/mach/irqs-pb1176.h
+++ b/arch/arm/mach-realview/include/mach/irqs-pb1176.h
@@ -63,7 +63,10 @@
 #define IRQ_PB1176_GPIO2	(IRQ_PB1176_GIC_START + 9)
 #define IRQ_PB1176_ETH		(IRQ_PB1176_GIC_START + 10)	/* Ethernet controller */
 #define IRQ_PB1176_USB		(IRQ_PB1176_GIC_START + 11)	/* USB controller */
-
+#define IRQ_PB1176_PCI_INTA	(IRQ_PB1176_GIC_START + 12)	/* PCI IntA */
+#define IRQ_PB1176_PCI_INTB	(IRQ_PB1176_GIC_START + 13)	/* PCI IntB */
+#define IRQ_PB1176_PCI_INTC	(IRQ_PB1176_GIC_START + 14)	/* PCI IntC */
+#define IRQ_PB1176_PCI_INTD	(IRQ_PB1176_GIC_START + 15)	/* PCI IntD */
 #define IRQ_PB1176_PISMO	(IRQ_PB1176_GIC_START + 16)
 
 #define IRQ_PB1176_AACI		(IRQ_PB1176_GIC_START + 19)	/* Audio Codec */
diff --git a/arch/arm/mach-realview/realview_eb.c b/arch/arm/mach-realview/realview_eb.c
index 991c1f8..5e4e119 100644
--- a/arch/arm/mach-realview/realview_eb.c
+++ b/arch/arm/mach-realview/realview_eb.c
@@ -44,6 +44,7 @@
 
 #include <mach/board-eb.h>
 #include <mach/irqs.h>
+#include <plat/xilinx-pci.h>
 
 #include "core.h"
 
@@ -85,7 +86,30 @@ static struct map_desc realview_eb_io_desc[] __initdata = {
 		.pfn		= __phys_to_pfn(REALVIEW_EB_UART0_BASE),
 		.length		= SZ_4K,
 		.type		= MT_DEVICE,
-	}
+	},
+#endif
+#ifdef CONFIG_PCI
+	{
+		.virtual	= IO_ADDRESS(REALVIEW_PCI_CORE_BASE),
+		.pfn		= __phys_to_pfn(REALVIEW_PCI_CORE_BASE),
+		.length		= SZ_4K,
+		.type		= MT_DEVICE
+	}, {
+		.virtual	=  (unsigned long)REALVIEW_PCI_VIRT_BASE,
+		.pfn		= __phys_to_pfn(REALVIEW_PCI_BASE),
+		.length		= REALVIEW_PCI_BASE_SIZE,
+		.type		= MT_DEVICE
+	}, {
+		.virtual	=  (unsigned long)REALVIEW_PCI_CFG_VIRT_BASE,
+		.pfn		= __phys_to_pfn(REALVIEW_PCI_CFG_BASE),
+		.length		= REALVIEW_PCI_CFG_BASE_SIZE,
+		.type		= MT_DEVICE
+	}, {
+		.virtual	=  (unsigned long)REALVIEW_PCI_IO_VIRT_BASE,
+		.pfn		= __phys_to_pfn(REALVIEW_PCI_IO_BASE),
+		.length		= REALVIEW_PCI_IO_BASE_SIZE,
+		.type		= MT_DEVICE
+	},
 #endif
 };
 
@@ -452,6 +476,63 @@ static void realview_eb_reset(char mode)
 		__raw_writel(0x0008, reset_ctrl);
 }
 
+#ifdef CONFIG_PCI_HOST_XILINX
+/*
+ * Realview/EB and /PB1176 use a the following base registers
+ *
+ * Usage Local Bus Memory         Base/Map registers used
+ *
+ * Self  60000000 - 60FFFFFF	  PCI selfconfig
+ * Cfg   61000000 - 61FFFFFF	  PCI config
+ * IO    62000000 - 62FFFFFF      PCI IO
+ * Mem   63000000 - 63FFFFFF      LB_BASE0/LB_MAP0,  unused
+ * Mem   64000000 - 67FFFFFF      LB_BASE1/LB_MAP1,  non-prefetch
+ * Mem   68000000 - 6FFFFFFF      LB_BASE2/LB_MAP2,  prefetch
+ */
+#define __IO_ADDRESS(n) ((void __iomem *)(unsigned long)IO_ADDRESS(n))
+static struct xilinx_pci_data realview_eb_pci = {
+	.base		= REALVIEW_PCI_VIRT_BASE,
+	.cfg_base	= REALVIEW_PCI_CFG_VIRT_BASE,
+	.io_base	= PCIO_BASE,
+	.sys_pcictl	= __IO_ADDRESS(REALVIEW_SYS_PCICTL),
+	.core_base	= __IO_ADDRESS(REALVIEW_EB_PCI_CORE_BASE),
+	.base_irq	= IRQ_EB_PCI0,
+	.irq_rotate	= 3, /* guessed, probably same as pb1176 */
+
+	/* This mapping is according to the Realview/EB user manual. */
+	.imap		= {
+		REALVIEW_EB_PCI_MEM_BASE0 & 0xff000000, /* 0x63000000 */
+		REALVIEW_EB_PCI_MEM_BASE1 & 0xfc000000, /* 0x64000000 */
+		REALVIEW_EB_PCI_MEM_BASE2 & 0xf8000000, /* 0x68000000 */
+	 },
+
+	.smap		= {
+		PHYS_OFFSET && 0xff000000, /* inbound memory BAR 0 */
+		PHYS_OFFSET && 0xff000000, /* inbound memory BAR 1 */
+		PHYS_OFFSET && 0xff000000, /* inbound IO BAR */
+	 },
+
+	.mem_spaces	= {
+		{
+			.name	= "PCI unused",
+			.start	= REALVIEW_EB_PCI_MEM_BASE0,
+			.end	= REALVIEW_EB_PCI_MEM_BASE0+REALVIEW_EB_PCI_MEM_BASE0_SIZE-1,
+			.flags	= IORESOURCE_MEM,
+		}, {
+			.name	= "PCI non-prefetchable",
+			.start	= REALVIEW_EB_PCI_MEM_BASE1,
+			.end	= REALVIEW_EB_PCI_MEM_BASE1+REALVIEW_EB_PCI_MEM_BASE1_SIZE-1,
+			.flags	= IORESOURCE_MEM,
+		}, {
+			.name	= "PCI prefetchable",
+			.start	= REALVIEW_EB_PCI_MEM_BASE2,
+			.end	= REALVIEW_EB_PCI_MEM_BASE2+REALVIEW_EB_PCI_MEM_BASE2_SIZE-1,
+			.flags	= IORESOURCE_MEM | IORESOURCE_PREFETCH,
+		},
+	},
+};
+#endif
+
 static void __init realview_eb_init(void)
 {
 	int i;
@@ -471,6 +552,7 @@ static void __init realview_eb_init(void)
 	platform_device_register(&realview_i2c_device);
 	platform_device_register(&char_lcd_device);
 	eth_device_register();
+	xilinx_pci_init(&realview_eb_pci);
 	realview_usb_register(realview_eb_isp1761_resources);
 
 	for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
diff --git a/arch/arm/mach-realview/realview_pb1176.c b/arch/arm/mach-realview/realview_pb1176.c
index d2be12e..5801102 100644
--- a/arch/arm/mach-realview/realview_pb1176.c
+++ b/arch/arm/mach-realview/realview_pb1176.c
@@ -44,6 +44,7 @@
 
 #include <mach/board-pb1176.h>
 #include <mach/irqs.h>
+#include <plat/xilinx-pci.h>
 
 #include "core.h"
 
@@ -102,6 +103,29 @@ static struct map_desc realview_pb1176_io_desc[] __initdata = {
 		.type		= MT_DEVICE,
 	},
 #endif
+#ifdef CONFIG_PCI
+	{
+		.virtual	= IO_ADDRESS(REALVIEW_PB1176_PCI_CORE_BASE),
+		.pfn		= __phys_to_pfn(REALVIEW_PB1176_PCI_CORE_BASE),
+		.length		= SZ_4K,
+		.type		= MT_DEVICE
+	}, {
+		.virtual	=  (unsigned long)REALVIEW_PCI_VIRT_BASE,
+		.pfn		= __phys_to_pfn(REALVIEW_PB1176_PCI_BASE),
+		.length		= REALVIEW_PB1176_PCI_BASE_SIZE,
+		.type		= MT_DEVICE
+	}, {
+		.virtual	=  (unsigned long)REALVIEW_PCI_CFG_VIRT_BASE,
+		.pfn		= __phys_to_pfn(REALVIEW_PB1176_PCI_CFG_BASE),
+		.length		= REALVIEW_PB1176_PCI_CFG_BASE_SIZE,
+		.type		= MT_DEVICE
+	}, {
+		.virtual	=  (unsigned long)REALVIEW_PCI_IO_VIRT_BASE,
+		.pfn		= __phys_to_pfn(REALVIEW_PB1176_PCI_IO_BASE0),
+		.length		= REALVIEW_PB1176_PCI_IO_BASE0_SIZE,
+		.type		= MT_DEVICE
+	},
+#endif
 };
 
 static void __init realview_pb1176_map_io(void)
@@ -348,6 +372,83 @@ static void realview_pb1176_fixup(struct machine_desc *mdesc,
 	meminfo->nr_banks = 1;
 }
 
+#ifdef CONFIG_PCI_HOST_XILINX
+/*
+ * Realview/PB1176 uses the following base registers
+ *
+ * Usage Local Bus Memory         Base/Map registers used
+ *
+ * Self  60000000 - 60FFFFFF	  PCI selfconfig
+ * Cfg   61000000 - 61FFFFFF	  PCI config
+ * IO    62000000 - 62FFFFFF      PCI IO
+ * Mem   63000000 - 63FFFFFF      LB_BASE0/LB_MAP0,  unused
+ * Mem   64000000 - 67FFFFFF      LB_BASE1/LB_MAP1,  non-prefetch
+ * Mem   68000000 - 6FFFFFFF      LB_BASE2/LB_MAP2,  prefetch
+ *
+ */
+#define __IO_ADDRESS(n) ((void __iomem *)(unsigned long)IO_ADDRESS(n))
+static struct xilinx_pci_data realview_pb1176_pci = {
+	.base		= REALVIEW_PCI_VIRT_BASE,
+	.cfg_base	= REALVIEW_PCI_CFG_VIRT_BASE,
+	.io_base	= PCIO_BASE,
+	.sys_pcictl	= __IO_ADDRESS(REALVIEW_SYS_PCICTL),
+	.core_base	= __IO_ADDRESS(REALVIEW_PB1176_PCI_CORE_BASE),
+	.base_irq	= IRQ_PB1176_PCI_INTA,
+	.irq_rotate	= 3,
+#if 0
+	/*
+	 * This mapping is according to the PB1176 user manual but doesn't
+	 * seem to work.
+	 */
+	.imap		= {
+		REALVIEW_PB1176_PCI_MEM_BASE0 >> 24, /* 0x63000000 */
+		REALVIEW_PB1176_PCI_MEM_BASE1 >> 26, /* 0x64000000 */
+		REALVIEW_PB1176_PCI_MEM_BASE2 >> 27, /* 0x68000000 */
+	 },
+
+	.smap		= {
+		PHYS_OFFSET >> 24, /* inbound memory BAR 0 */
+		PHYS_OFFSET >> 24, /* inbound memory BAR 1 */
+		PHYS_OFFSET >> 24, /* inbound IO BAR */
+	 },
+#else
+	/*
+	 * This mapping is according to the Realview/EB user manual,
+	 * i.e. for another board, but apparently works to some degree.
+	 */
+	.imap		= {
+		REALVIEW_PB1176_PCI_MEM_BASE0 & 0xff000000, /* 0x63000000 */
+		REALVIEW_PB1176_PCI_MEM_BASE1 & 0xfc000000, /* 0x64000000 */
+		REALVIEW_PB1176_PCI_MEM_BASE2 & 0xf8000000, /* 0x68000000 */
+	 },
+
+	.smap		= {
+		PHYS_OFFSET && 0xff000000, /* inbound memory BAR 0 */
+		PHYS_OFFSET && 0xff000000, /* inbound memory BAR 1 */
+		PHYS_OFFSET && 0xff000000, /* inbound IO BAR */
+	 },
+#endif
+	.mem_spaces	= {
+		{
+			.name	= "PCI unused",
+			.start	= REALVIEW_PB1176_PCI_MEM_BASE0,
+			.end	= REALVIEW_PB1176_PCI_MEM_BASE0+REALVIEW_PB1176_PCI_MEM_BASE0_SIZE-1,
+			.flags	= IORESOURCE_MEM,
+		}, {
+			.name	= "PCI non-prefetchable",
+			.start	= REALVIEW_PB1176_PCI_MEM_BASE1,
+			.end	= REALVIEW_PB1176_PCI_MEM_BASE1+REALVIEW_PB1176_PCI_MEM_BASE1_SIZE-1,
+			.flags	= IORESOURCE_MEM,
+		}, {
+			.name	= "PCI prefetchable",
+			.start	= REALVIEW_PB1176_PCI_MEM_BASE2,
+			.end	= REALVIEW_PB1176_PCI_MEM_BASE2+REALVIEW_PB1176_PCI_MEM_BASE2_SIZE-1,
+			.flags	= IORESOURCE_MEM | IORESOURCE_PREFETCH,
+		},
+	},
+};
+#endif
+
 static void __init realview_pb1176_init(void)
 {
 	int i;
@@ -364,6 +465,7 @@ static void __init realview_pb1176_init(void)
 	realview_usb_register(realview_pb1176_isp1761_resources);
 	platform_device_register(&pmu_device);
 	platform_device_register(&char_lcd_device);
+	xilinx_pci_init(&realview_pb1176_pci);
 
 	for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
 		struct amba_device *d = amba_devs[i];
-- 
1.7.1




More information about the linux-arm-kernel mailing list