* [PATCH 0/6] Series short description
@ 2010-12-22 14:03 Colin Tuckley
2010-12-22 14:03 ` [PATCH 1/6] ARM: enable bridges in pci_common_init Colin Tuckley
` (5 more replies)
0 siblings, 6 replies; 11+ messages in thread
From: Colin Tuckley @ 2010-12-22 14:03 UTC (permalink / raw)
To: linux-arm-kernel
The following series implements...
---
Colin Tuckley (6):
ARM Realview PCIX build file changes
ARM Realview PCIX board file changes
ARM Realview PCIX IRQ include file changes
ARM Realview PCIX map include file changes
Realview PCIX support - add main support module code
ARM: enable bridges in pci_common_init.
arch/arm/Kconfig | 6
arch/arm/kernel/bios32.c | 5
arch/arm/mach-realview/Makefile | 6
arch/arm/mach-realview/include/mach/board-pb11mp.h | 11
arch/arm/mach-realview/include/mach/board-pba8.h | 11
arch/arm/mach-realview/include/mach/board-pbx.h | 11
arch/arm/mach-realview/include/mach/hardware.h | 53 ++
arch/arm/mach-realview/include/mach/io.h | 18 +
arch/arm/mach-realview/include/mach/irqs-pb11mp.h | 11
arch/arm/mach-realview/include/mach/irqs-pba8.h | 7
arch/arm/mach-realview/include/mach/irqs-pbx.h | 7
arch/arm/mach-realview/include/mach/platform.h | 15 -
arch/arm/mach-realview/pcix.c | 503 ++++++++++++++++++++
arch/arm/mach-realview/realview_pb11mp.c | 18 +
arch/arm/mach-realview/realview_pba8.c | 18 +
arch/arm/mach-realview/realview_pbx.c | 16 +
16 files changed, 659 insertions(+), 57 deletions(-)
create mode 100755 arch/arm/mach-realview/pcix.c
--
Signature
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 1/6] ARM: enable bridges in pci_common_init.
2010-12-22 14:03 [PATCH 0/6] Series short description Colin Tuckley
@ 2010-12-22 14:03 ` Colin Tuckley
2010-12-22 14:04 ` [PATCH 2/6] Realview PCIX support - add main support module code Colin Tuckley
` (4 subsequent siblings)
5 siblings, 0 replies; 11+ messages in thread
From: Colin Tuckley @ 2010-12-22 14:03 UTC (permalink / raw)
To: linux-arm-kernel
Add a missing call to pci_enable_bridges() so that devices behind
bridges get found by the pci bus scan.
Signed-off-by: Chris Partington <chris.partington@arm.com>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
---
arch/arm/kernel/bios32.c | 5 +++++
1 files changed, 5 insertions(+), 0 deletions(-)
diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c
index c6273a3..d86fcd4 100644
--- a/arch/arm/kernel/bios32.c
+++ b/arch/arm/kernel/bios32.c
@@ -583,6 +583,11 @@ void __init pci_common_init(struct hw_pci *hw)
* Assign resources.
*/
pci_bus_assign_resources(bus);
+
+ /*
+ * Enable bridges
+ */
+ pci_enable_bridges(bus);
}
/*
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 2/6] Realview PCIX support - add main support module code
2010-12-22 14:03 [PATCH 0/6] Series short description Colin Tuckley
2010-12-22 14:03 ` [PATCH 1/6] ARM: enable bridges in pci_common_init Colin Tuckley
@ 2010-12-22 14:04 ` Colin Tuckley
2011-01-19 13:00 ` Russell King - ARM Linux
2010-12-22 14:04 ` [PATCH 3/6] ARM Realview PCIX map include file changes Colin Tuckley
` (3 subsequent siblings)
5 siblings, 1 reply; 11+ messages in thread
From: Colin Tuckley @ 2010-12-22 14:04 UTC (permalink / raw)
To: linux-arm-kernel
This patch adds pcix.c - the main pci sub-system code for
the RealView boards which have PCI and PCIe interfaces
via a custom NEC northbridge chip and two bridges.
Signed-off-by: Colin Tuckley <colin.tuckley@arm.com>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
---
arch/arm/mach-realview/pcix.c | 503 +++++++++++++++++++++++++++++++++++++++++
1 files changed, 503 insertions(+), 0 deletions(-)
create mode 100755 arch/arm/mach-realview/pcix.c
diff --git a/arch/arm/mach-realview/pcix.c b/arch/arm/mach-realview/pcix.c
new file mode 100755
index 0000000..5793915
--- /dev/null
+++ b/arch/arm/mach-realview/pcix.c
@@ -0,0 +1,503 @@
+/*
+ * Realview PCIX Support
+ *
+ * Copyright (C) 2007-2010 ARM
+ *
+ * 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.
+ *
+ * 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
+ */
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/slab.h>
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <mach/platform.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/mach/pci.h>
+
+#define PCIX_READ_ACCESS 0x06000000
+#define PCIX_WRITE_ACCESS 0x07000000
+
+/* PCI-X Configuration registers */
+#define PCI_PTBADDR0L 0x10
+#define PCI_PTBADDR0M 0x14
+#define PCI_PTBADDR1L 0x18
+#define PCI_PTBADDR1M 0x1C
+#define PCI_CFGADDR 0x40
+#define PCI_CFGDATA 0x44
+#define PCI_CFGATTR 0x48
+#define PCI_PINTACNT 0x50
+#define PCI_PINTXSTAT 0x54
+#define PCI_PINTXMASK 0x58
+#define PCI_SERRSTAT 0x5C
+#define PCI_PERRADDRL 0x60
+#define PCI_PERRADDRH 0x64
+#define PCI_PERRSTAT 0x68
+#define PCI_PERRMASK 0x6C
+#define PCI_OCBERRSTAT 0x78
+#define PCI_OCBERRMASK 0x7C
+#define PCI_MSICAPID 0x80
+#define PCI_MSINXTCAP 0x81
+#define PCI_MSGCNT 0x82
+#define PCI_MSGADDR 0x84
+#define PCI_MSGUPADDR 0x88
+#define PCI_MSGDATA 0x8C
+#define PCI_PCIXCAPID 0x90
+#define PCI_PCIXNXTCAP 0x91
+#define PCI_PCIXCOMMAND 0x92
+#define PCI_PCIXSTAT 0x94
+#define PCI_SPCMPERRMSG 0x98
+#define PCI_PTMEMSEG0 0xA0
+#define PCI_PTMEMMSK0 0xA4
+#define PCI_PTMEMENSW0 0xA8
+#define PCI_PTMEMSEG1 0xB0
+#define PCI_PTMEMMSK1 0xB4
+#define PCI_PTMEMENSW1 0xB8
+#define PCI_PMSEGL 0xC0
+#define PCI_PMSEGH 0xC4
+#define PCI_DRSTCNT 0xEC
+#define PCI_PRST 0xF0
+#define PCI_UNITCNT 0xF4
+#define PCI_CNTOTIMER 0xF8
+#define PCI_PSLADAFLASH 0xFC
+
+static int irq_gic_start;
+
+/*
+ * Software is exposed to downstream half of the PCI-X bridge registers
+ * rather than a real PCI interface. Therefore there's no config memory
+ * region as such.
+ *
+ * PCI Regions:
+ * MEM 0xA0000000 - 0xBFFFFFFF
+ * IO 0x00000000 - 0x0000FFFF
+ * CONFIG -
+ */
+
+static void realview_pb_pcix_sync(void)
+{
+ readl(PCIX_UNIT_BASE + PCI_VENDOR_ID);
+}
+
+static void realview_pb_pcix_unit_init(void)
+{
+ u32 data = readl(PCIX_UNIT_BASE + PCI_UNITCNT);
+
+ if (data & 0x10)
+ writel(0x00000000, PCIX_UNIT_BASE + PCI_PRST); /* Assert PCI reset */
+ else {
+ printk(KERN_ERR "Error: PCI-X unit not in PCI-X mode.\n");
+ writel(data | 0x80000000, PCIX_UNIT_BASE + PCI_UNITCNT);
+ }
+
+ writew(0x0006, PCIX_UNIT_BASE + PCI_COMMAND); /* Master-Memory enable */
+ writew(0xfb30, PCIX_UNIT_BASE + PCI_STATUS); /* Error bit clear */
+
+ writeb(0x08, PCIX_UNIT_BASE + PCI_CACHE_LINE_SIZE); /* Cache line size */
+ writeb(0x40, PCIX_UNIT_BASE + PCI_LATENCY_TIMER); /* Latency Timer */
+
+ /* Master Segment Address[31:24] */
+ writel(0x00000003, PCIX_UNIT_BASE + PCI_PMSEGL); /* no swap */
+ /* Master Segment Address[63:32] */
+ writel(0x00000000, PCIX_UNIT_BASE + PCI_PMSEGH);
+
+ /* Data endian swap mode */
+ writel(0x00000003, PCIX_UNIT_BASE + PCI_PTMEMENSW0); /* no swap */
+ writel(0x00000003, PCIX_UNIT_BASE + PCI_PTMEMENSW1); /* no swap */
+
+#ifdef CONFIG_REALVIEW_HIGH_PHYS_OFFSET
+ /* 512MB of DMA capable RAM is available - mapped at 0x70000000
+ * Note :- 0x70000000 is *not* on a 512MB boundary so it
+ * must be mapped in two parts */
+ /* Window#0 256MB and enable */
+ writel(0x0fff0001, PCIX_UNIT_BASE + PCI_PTMEMMSK0);
+ /* Window#1 256MB and enable */
+ writel(0x0fff0001, PCIX_UNIT_BASE + PCI_PTMEMMSK1);
+
+ /* Window base address setting */
+ /* Memory Base Address, Ptrefetch Disable, 64bit */
+ writel(0x70000004, PCIX_UNIT_BASE + PCI_PTBADDR0L);
+ /* Memory Base Address[63:32] */
+ writel(0x00000000, PCIX_UNIT_BASE + PCI_PTBADDR0M);
+
+ /* Memory Base Address, Ptrefetch Disable, 64bit */
+ writel(0x80000004, PCIX_UNIT_BASE + PCI_PTBADDR1L);
+ /* Memory Base Address[63:32] */
+ writel(0x00000000, PCIX_UNIT_BASE + PCI_PTBADDR1M);
+#else
+ /* Only 256MB of RAM is available - mapped at zero */
+ /* Window#0 256MB and enable */
+ writel(0x0fff0001, PCIX_UNIT_BASE + PCI_PTMEMMSK0);
+ /* Window#1 Disable */
+ writel(0x00000000, PCIX_UNIT_BASE + PCI_PTMEMMSK1);
+
+ /* Window base address setting */
+ /* Memory Base Address, Ptrefetch Disable, 64bit */
+ writel(0x00000004, PCIX_UNIT_BASE + PCI_PTBADDR0L);
+ /* Memory Base Address[63:32] */
+ writel(0x00000000, PCIX_UNIT_BASE + PCI_PTBADDR0M);
+
+ /* Memory Base Address, Ptrefetch Disable, 64bit */
+ writel(0x00000004, PCIX_UNIT_BASE + PCI_PTBADDR1L);
+ /* Memory Base Address[63:32] */
+ writel(0x00000000, PCIX_UNIT_BASE + PCI_PTBADDR1M);
+#endif
+
+ /* OnChipBus Address#0[35:24] */
+ writel(0x00000000, PCIX_UNIT_BASE + PCI_PTMEMSEG0);
+ /* OnChipBus Address#1[35:24] */
+ writel(0x00000000, PCIX_UNIT_BASE + PCI_PTMEMSEG1);
+
+ /* 66MHz, 64bit device */
+ writel(0x00010000, PCIX_UNIT_BASE + PCI_PCIXSTAT);
+ /* Interrupt Mask */
+ writel(0x00000000, PCIX_UNIT_BASE + PCI_PINTXMASK);
+ /* Enable PCI error status */
+ writel(0x000307f7, PCIX_UNIT_BASE + PCI_PERRMASK);
+ /* Clear PCI error status */
+ writel(0x000307f7, PCIX_UNIT_BASE + PCI_PERRSTAT);
+ /* Enable count out */
+ writel(0x10FFFFFF, PCIX_UNIT_BASE + PCI_CNTOTIMER);
+
+ realview_pb_pcix_sync();
+ udelay(1500); /* Allow hardware to settle as per NEC docs and example */
+
+ /* Deassert PCI reset */
+ writel(0x00000001, PCIX_UNIT_BASE + PCI_PRST);
+ /* Initial end, Enable arbiter */
+ writel(data | 0x80000020, PCIX_UNIT_BASE + PCI_UNITCNT);
+ realview_pb_pcix_sync();
+ udelay(1500); /* Allow hardware to settle as per NEC docs and example */
+
+ /* Enable bursts on PCI-X */
+ writel(0x1, __io_address(REALVIEW_ISSP_REG_BASE + 0x18));
+}
+
+static void realview_pb_pcix_set_attr(unsigned int tag)
+{
+ /* Get Device and Funcion number */
+ u32 data = readl(PCIX_UNIT_BASE + PCI_PCIXSTAT) & 0x0ff;
+ /* attribute set */
+ writel(tag | (data << 8), PCIX_UNIT_BASE + PCI_CFGATTR);
+}
+
+static int realview_pb_pcix_set_config(u32 bus, u32 dev, u32 func, int offset)
+{
+ u32 mode;
+ u32 config_addr;
+
+ writel(0x000307F7, PCIX_UNIT_BASE + PCI_PERRSTAT); /* clear error bit */
+ writew(0xfb30, PCIX_UNIT_BASE + PCI_STATUS); /* error bit clear */
+
+ if (bus == 0) {
+ /* Type0 Configuration cycle */
+ mode = readl(PCIX_UNIT_BASE + PCI_UNITCNT);
+ if (mode & 0x1) {
+ /* check PCI mode */
+ printk(KERN_ERR "PCI mode detected during config cycle"
+ "attempt. Should really be in PCI-X mode.\n");
+ BUG();
+ } else {
+ /* PCI-X Mode
+ *
+ * Note that the root complex appears as id 0x1f
+ * since we don't want to allocate this as a device
+ * we stop scanning before we find it.
+ */
+ if (dev < 0x10 || dev > 0x1e) {
+ realview_pb_pcix_sync();
+ return -1;
+ }
+ config_addr = (1 << dev) | ((dev & 0x1f) << 11) |
+ ((func & 0x7) << 8) | (offset & 0xfc);
+ writel(config_addr, PCIX_UNIT_BASE + PCI_CFGADDR);
+ }
+ } else {
+ config_addr = ((bus & 0xff) << 16) | ((dev & 0x1f) << 11) |
+ ((func & 0x7) << 8) | (offset & 0xfc) | 0x1;
+ /* Type1 Configuration cycle */
+ writel(config_addr, PCIX_UNIT_BASE + PCI_CFGADDR);
+ }
+ realview_pb_pcix_sync();
+ return 0;
+}
+
+int realview_pb_pcix_check_error(void)
+{
+ u32 data;
+ realview_pb_pcix_sync();
+ data = readl(PCIX_UNIT_BASE + PCI_PERRSTAT);
+ if (data) {
+ writel(data, PCIX_UNIT_BASE + PCI_PERRSTAT);
+ return data;
+ }
+ return 0;
+}
+
+int realview_pb_pcix_read_config(struct pci_bus *pbus, u32 devfn,
+ int offset, int size, u32 *data)
+{
+ u32 bus = pbus->number;
+ u32 slot = PCI_SLOT(devfn);
+ u32 function = PCI_FUNC(devfn);
+
+ realview_pb_pcix_set_attr(PCIX_READ_ACCESS);
+ if (realview_pb_pcix_set_config(bus, slot, function, offset) != 0) {
+ *data = ((size == 1) ? 0xFF : ((size == 2) ? 0xFFFF : 0xFFFFFFFF));
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ }
+ switch (size) {
+ case 1:
+ *data = (readl(PCIX_UNIT_BASE + PCI_CFGDATA) >>
+ (8 * (offset & 3))) & 0xff;
+ break;
+ case 2:
+ *data = (u32)readw(PCIX_UNIT_BASE + PCI_CFGDATA +
+ (offset & 3));
+ break;
+ default:
+ *data = readl(PCIX_UNIT_BASE + PCI_CFGDATA);
+ }
+ /* Error codes from downstream bus don't mean much for software. */
+ if (!realview_pb_pcix_check_error())
+ return PCIBIOS_SUCCESSFUL;
+
+ return PCIBIOS_DEVICE_NOT_FOUND;
+}
+
+int realview_pb_pcix_write_config(struct pci_bus *pbus, u32 devfn,
+ int offset, int size, u32 data)
+{
+ u32 slot = PCI_SLOT(devfn);
+ u32 function = PCI_FUNC(devfn);
+ u32 bus = pbus->number;
+ int err;
+
+ realview_pb_pcix_set_attr(PCIX_WRITE_ACCESS);
+ if (realview_pb_pcix_set_config(bus, slot, function, offset) != 0)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ switch (size) {
+ case 1:
+ writeb(data, PCIX_UNIT_BASE + PCI_CFGDATA + (offset & 3));
+ break;
+ case 2:
+ writew(data, PCIX_UNIT_BASE + PCI_CFGDATA + (offset & 3));
+ break;
+ default:
+ writel(data, PCIX_UNIT_BASE + PCI_CFGDATA);
+ break;
+ }
+ /* Write errors don't really matter */
+ err = realview_pb_pcix_check_error();
+ realview_pb_pcix_set_attr(PCIX_READ_ACCESS);
+ return err;
+}
+
+static struct pci_ops pci_realview_pb_ops = {
+ .read = realview_pb_pcix_read_config,
+ .write = realview_pb_pcix_write_config,
+};
+
+static int __init pci_realview_pb_setup(int nr, struct pci_sys_data *sys)
+{
+ if (machine_is_realview_pb11mp())
+ irq_gic_start = IRQ_PB11MP_GIC_START;
+ else
+ irq_gic_start = IRQ_PBA8_GIC_START;
+
+ realview_pb_pcix_unit_init();
+
+ /* set bus->cpu mapping */
+ sys->mem_offset = 0;
+ sys->io_offset = REALVIEW_PB_PCI_IO_BASE;
+
+ /* Note: we don't reserve the addresses for PCI space here because the
+ * window allocator won't be able to get any if we do.
+ */
+
+ return 1;
+}
+
+
+static struct pci_bus *pci_realview_pb_scan_bus(int nr, struct pci_sys_data *sys)
+{
+ return pci_scan_bus(sys->busnr, &pci_realview_pb_ops, sys);
+}
+
+static void __init pci_realview_pb_preinit(void)
+{
+ u32 data = readl(__io_address(REALVIEW_SYS_PCI_STAT));
+ data &= ~0x00000100; /* Clear the Clock Control bit */
+ writel(data, __io_address(REALVIEW_SYS_PCI_STAT));
+ udelay(1500); /* Allow hardware to settle as per NEC docs and example */
+}
+
+static struct pci_dev *pcie_bridge;
+
+/* Maps scrambled IRQ pins to IRQ lines. Scrambling depends on device slot. */
+static int __init pci_realview_pb_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ int irq;
+ int devslot = PCI_SLOT(dev->devfn);
+
+ /* Upstream port of 8518 device */
+ if (unlikely(dev->device == 0x8518 && dev->bus->primary == 0)) {
+ BUG_ON(pcie_bridge); /* Can't be already assigned */
+ pcie_bridge = dev;
+ }
+
+ if (pcie_bridge) {
+ if (dev->bus->primary >= pcie_bridge->bus->secondary &&
+ dev->bus->primary <= pcie_bridge->bus->subordinate) {
+ /*
+ * The problem is that in PCIE in different slots a device
+ * could still get the same slot/pin/devslot triplet. Therefore
+ * we check the slot/pin/devslot triplet of an underlying PCIE port.
+ *
+ * slot pin irq
+ * 0 #A(1) 56
+ * 0 #B(2) 57
+ * 0 #C(3) 54
+ * 0 #D(4) 55
+ * 1 #A(1) 55
+ * 1 #B(2) 56
+ * 1 #C(3) 57
+ * 1 #D(4) 54
+ * 2 1 54
+ * 2 2 55
+ * 2 3 56
+ * 2 4 57
+ * 3 1 57
+ * 3 2 54
+ * 3 3 55
+ * 3 4 56
+ * 4 1 56
+ * 4 2 57
+ * 4 3 54
+ * 4 4 55
+ */
+
+ if (dev->bus->self) {
+ /* We do have a bus above us
+ * Device is right behind a PCIE hub port, and its not a PCIE
+ * hub port itself. */
+ if (dev->bus->self->device == 0x8518 &&
+ dev->device != 0x8518) {
+ /* Depend on devslot of 8518 port we're connected to */
+ devslot = PCI_SLOT(dev->bus->self->devfn);
+ /* These are the two cases for PCIE ports on PB boards.
+ * Any other downstream bus topology (e.g. with further
+ * PCIE bridges) does not scramble, and get the same
+ * irq number as the upstream bus. */
+ irq = irq_gic_start + 54 + ((devslot & 3) + (pin - 1)) % 4;
+ } else if ((dev->bus->self->class & 0xff0000) == 0x060000 &&
+ (dev->class & 0xff0000) != 0x060000) {
+ /* It's a device behind a bridge that isn't an 8518 */
+ irq = irq_gic_start + 54 + ((devslot & 3) + pin +
+ PCI_SLOT(dev->bus->self->bus->self->devfn) - 1) % 4;
+ } else {
+ /* It's another bridge */
+ irq = dev->bus->self->irq;
+ }
+ } else
+ irq = 0;
+
+ printk(KERN_INFO "PCI Express irq mapping: device: 0x%x, slot %d, pin %d, devslot %d, irq: %d\n",
+ dev->device, slot, pin, devslot, irq);
+
+ return irq;
+ }
+ }
+
+ /*
+ * slot pin irq
+ * 0 #A(3) 53
+ * 0 #B(0) 50
+ * 0 #C(1) 51
+ * 0 #D(2) 52
+ *
+ * 1 #A(2) 52
+ * 1 #B(3) 53
+ * 1 #C(0) 50
+ * 1 #D(1) 51
+ *
+ * 2 1 51
+ * 2 2 52
+ * 2 3 53
+ * 2 0 50
+ *
+ * 3 0 50
+ * 3 1 51
+ * 3 2 52
+ * 3 3 53
+ *
+ * Note: pin is actually 1..4 not 0..3
+ */
+
+ irq = irq_gic_start + 50 + (((pin - 1) + 3 - (devslot & 3)) & 3);
+
+ printk(KERN_INFO "PCI map irq: slot %d, pin %d, devslot %d, irq: %d\n",
+ slot, pin, devslot, irq);
+
+ return irq;
+
+}
+
+static struct hw_pci realview_pb_pcix __initdata = {
+ .swizzle = NULL,
+ .map_irq = pci_realview_pb_map_irq,
+ .nr_controllers = 1,
+ .setup = pci_realview_pb_setup,
+ .scan = pci_realview_pb_scan_bus,
+ .preinit = pci_realview_pb_preinit
+};
+
+static int __init realview_pb_pcix_init(void)
+{
+ if (machine_is_realview_pb11mp() ||
+ machine_is_realview_pba8() || machine_is_realview_pbx())
+ pci_common_init(&realview_pb_pcix);
+ return 0;
+}
+
+subsys_initcall(realview_pb_pcix_init);
+
+static int max_rrq __devinitdata = 4096;
+
+static void __devinit find_max_rrq(struct pci_dev *dev)
+{
+ /* Set the max read request size for all devices to the
+ * smallest in the tree and limit it to 4096.
+ * This is a workaround for a root complex
+ * bug. So far, the only device we've seen
+ * that fails without this is the Marvell Yukon 88E8053 but
+ * this may fix other devices too.
+ */
+ int rrq = pcie_get_readrq(dev);
+ if (rrq > 0 && rrq < max_rrq)
+ max_rrq = rrq;
+}
+DECLARE_PCI_FIXUP_EARLY(PCI_ANY_ID, PCI_ANY_ID, find_max_rrq);
+
+static void __devinit set_max_rrq(struct pci_dev *dev)
+{
+ pcie_set_readrq(dev, max_rrq);
+}
+DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, set_max_rrq);
+
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 3/6] ARM Realview PCIX map include file changes
2010-12-22 14:03 [PATCH 0/6] Series short description Colin Tuckley
2010-12-22 14:03 ` [PATCH 1/6] ARM: enable bridges in pci_common_init Colin Tuckley
2010-12-22 14:04 ` [PATCH 2/6] Realview PCIX support - add main support module code Colin Tuckley
@ 2010-12-22 14:04 ` Colin Tuckley
2010-12-22 15:33 ` Arnd Bergmann
2010-12-22 14:04 ` [PATCH 4/6] ARM Realview PCIX IRQ " Colin Tuckley
` (2 subsequent siblings)
5 siblings, 1 reply; 11+ messages in thread
From: Colin Tuckley @ 2010-12-22 14:04 UTC (permalink / raw)
To: linux-arm-kernel
This patch adds the memory map PCI support to the include
files for the Realview Northbridge based boards.
Signed-off-by: Colin Tuckley <colin.tuckley@arm.com>
---
arch/arm/mach-realview/include/mach/board-pb11mp.h | 11 ----
arch/arm/mach-realview/include/mach/board-pba8.h | 11 ----
arch/arm/mach-realview/include/mach/board-pbx.h | 11 ----
arch/arm/mach-realview/include/mach/hardware.h | 53 ++++++++++++++++++++
arch/arm/mach-realview/include/mach/io.h | 18 ++++++-
arch/arm/mach-realview/include/mach/platform.h | 15 +-----
6 files changed, 72 insertions(+), 47 deletions(-)
diff --git a/arch/arm/mach-realview/include/mach/board-pb11mp.h b/arch/arm/mach-realview/include/mach/board-pb11mp.h
index 7abf918..0114edb 100644
--- a/arch/arm/mach-realview/include/mach/board-pb11mp.h
+++ b/arch/arm/mach-realview/include/mach/board-pb11mp.h
@@ -62,17 +62,6 @@
#define REALVIEW_PB11MP_SYS_PLD_CTRL1 0x74
/*
- * PB11MPCore PCI regions
- */
-#define REALVIEW_PB11MP_PCI_BASE 0x90040000 /* PCI-X Unit base */
-#define REALVIEW_PB11MP_PCI_IO_BASE 0x90050000 /* IO Region on AHB */
-#define REALVIEW_PB11MP_PCI_MEM_BASE 0xA0000000 /* MEM Region on AHB */
-
-#define REALVIEW_PB11MP_PCI_BASE_SIZE 0x10000 /* 16 Kb */
-#define REALVIEW_PB11MP_PCI_IO_SIZE 0x1000 /* 4 Kb */
-#define REALVIEW_PB11MP_PCI_MEM_SIZE 0x20000000 /* 512 MB */
-
-/*
* Testchip peripheral and fpga gic regions
*/
#define REALVIEW_TC11MP_SCU_BASE 0x1F000000 /* IRQ, Test chip */
diff --git a/arch/arm/mach-realview/include/mach/board-pba8.h b/arch/arm/mach-realview/include/mach/board-pba8.h
index 4dfc67a..f8ad328 100644
--- a/arch/arm/mach-realview/include/mach/board-pba8.h
+++ b/arch/arm/mach-realview/include/mach/board-pba8.h
@@ -59,15 +59,4 @@
#define REALVIEW_PBA8_SYS_PLD_CTRL1 0x74
-/*
- * PBA8 PCI regions
- */
-#define REALVIEW_PBA8_PCI_BASE 0x90040000 /* PCI-X Unit base */
-#define REALVIEW_PBA8_PCI_IO_BASE 0x90050000 /* IO Region on AHB */
-#define REALVIEW_PBA8_PCI_MEM_BASE 0xA0000000 /* MEM Region on AHB */
-
-#define REALVIEW_PBA8_PCI_BASE_SIZE 0x10000 /* 16 Kb */
-#define REALVIEW_PBA8_PCI_IO_SIZE 0x1000 /* 4 Kb */
-#define REALVIEW_PBA8_PCI_MEM_SIZE 0x20000000 /* 512 MB */
-
#endif /* __ASM_ARCH_BOARD_PBA8_H */
diff --git a/arch/arm/mach-realview/include/mach/board-pbx.h b/arch/arm/mach-realview/include/mach/board-pbx.h
index 848bfff..93a975e 100644
--- a/arch/arm/mach-realview/include/mach/board-pbx.h
+++ b/arch/arm/mach-realview/include/mach/board-pbx.h
@@ -70,17 +70,6 @@
#define REALVIEW_PBX_SYS_PLD_CTRL1 0x74
/*
- * PBX PCI regions
- */
-#define REALVIEW_PBX_PCI_BASE 0x90040000 /* PCI-X Unit base */
-#define REALVIEW_PBX_PCI_IO_BASE 0x90050000 /* IO Region on AHB */
-#define REALVIEW_PBX_PCI_MEM_BASE 0xA0000000 /* MEM Region on AHB */
-
-#define REALVIEW_PBX_PCI_BASE_SIZE 0x10000 /* 16 Kb */
-#define REALVIEW_PBX_PCI_IO_SIZE 0x1000 /* 4 Kb */
-#define REALVIEW_PBX_PCI_MEM_SIZE 0x20000000 /* 512 MB */
-
-/*
* Core tile identification (REALVIEW_SYS_PROCID)
*/
#define REALVIEW_PBX_PROC_MASK 0xFF000000
diff --git a/arch/arm/mach-realview/include/mach/hardware.h b/arch/arm/mach-realview/include/mach/hardware.h
index 8a638d1..dcc64f2 100644
--- a/arch/arm/mach-realview/include/mach/hardware.h
+++ b/arch/arm/mach-realview/include/mach/hardware.h
@@ -23,6 +23,59 @@
#define __ASM_ARCH_HARDWARE_H
#include <asm/sizes.h>
+#include <asm/mach-types.h>
+
+/*
+ * PCI space virtual addresses
+ */
+#define REALVIEW_PCI_VIRT_BASE (void __iomem *)0xF8000000ul
+#define REALVIEW_PCI_CFG_VIRT_BASE (void __iomem *)0xF9000000ul
+#define PCIX_UNIT_BASE (void __iomem *)0xF8000000ul
+#define REALVIEW_PCI_IO_VBASE (void __iomem *)0xFA000000ul
+/*
+ * PCI space physical addresses and sizes
+ */
+#define REALVIEW_PB_PCI_BASE 0x90040000 /* PCI-X Unit base */
+#define REALVIEW_PB_PCI_BASE_SIZE 0x00010000 /* 4 Kb + 60Kb reserved */
+#define REALVIEW_PB_PCI_IO_BASE 0x90050000 /* IO Region on AHB */
+#define REALVIEW_PB_PCI_IO_SIZE 0x00010000 /* 64 Kb */
+#define REALVIEW_PB_PCI_IO_LIMIT (REALVIEW_PB_PCI_IO_BASE + REALVIEW_PB_PCI_IO_SIZE - 1)
+#define REALVIEW_PB_PCI_MEM_BASE 0xA0000000 /* MEM Region on AHB */
+#define REALVIEW_PB_PCI_MEM_SIZE 0x20000000 /* 512 MB */
+
+#define REALVIEW_ISSP_REG_BASE 0x100E3000
+
+#ifdef CONFIG_PCI
+#if !defined(__ASSEMBLY__)
+static inline unsigned int pcibios_min_io(void)
+{
+ if (machine_is_realview_pb11mp() || machine_is_realview_pba8() ||
+ machine_is_realview_pbx())
+ return REALVIEW_PB_PCI_IO_BASE;
+ else
+ return 0;
+}
+
+static inline unsigned int pcibios_min_mem(void)
+{
+ if (machine_is_realview_pb11mp() || machine_is_realview_pba8() ||
+ machine_is_realview_pbx())
+ return REALVIEW_PB_PCI_MEM_BASE;
+ else
+ return 0;
+}
+#endif
+
+/*
+ * These are needed so that generic pci code doesn't know about our
+ * machine specific details.
+ */
+#define PCIBIOS_MIN_IO pcibios_min_io()
+#define PCIBIOS_MIN_MEM pcibios_min_mem()
+
+#define pcibios_assign_all_busses() 1
+
+#endif
/* macro to get at IO space when running virtually */
#ifdef CONFIG_MMU
diff --git a/arch/arm/mach-realview/include/mach/io.h b/arch/arm/mach-realview/include/mach/io.h
index f05bcdf..aa97d18 100644
--- a/arch/arm/mach-realview/include/mach/io.h
+++ b/arch/arm/mach-realview/include/mach/io.h
@@ -20,9 +20,25 @@
#ifndef __ASM_ARM_ARCH_IO_H
#define __ASM_ARM_ARCH_IO_H
+#include <asm/mach-types.h>
+#include <mach/hardware.h>
+
#define IO_SPACE_LIMIT 0xffffffff
-#define __io(a) __typesafe_io(a)
+static inline void __iomem *__io(unsigned long addr)
+{
+#ifdef CONFIG_PCI
+ /* check for PCI I/O space */
+ if (addr >= REALVIEW_PB_PCI_IO_BASE && addr <= REALVIEW_PB_PCI_IO_LIMIT)
+ return (void __iomem *)((addr - REALVIEW_PB_PCI_IO_BASE) + REALVIEW_PCI_IO_VBASE);
+ else
+ return (void __iomem *)addr;
+#else
+ return (void __iomem *)addr;
+#endif
+}
+
+#define __io(a) __io(a)
#define __mem_pci(a) (a)
#endif
diff --git a/arch/arm/mach-realview/include/mach/platform.h b/arch/arm/mach-realview/include/mach/platform.h
index 1b77a27..75bddc4 100644
--- a/arch/arm/mach-realview/include/mach/platform.h
+++ b/arch/arm/mach-realview/include/mach/platform.h
@@ -77,6 +77,7 @@
#define REALVIEW_SYS_BOOTCS_OFFSET 0x58
#define REALVIEW_SYS_24MHz_OFFSET 0x5C
#define REALVIEW_SYS_MISC_OFFSET 0x60
+#define REALVIEW_SYS_PCI_STAT_OFFSET 0x6C
#define REALVIEW_SYS_IOSEL_OFFSET 0x70
#define REALVIEW_SYS_PROCID_OFFSET 0x84
#define REALVIEW_SYS_TEST_OSC0_OFFSET 0xC0
@@ -111,6 +112,7 @@
#define REALVIEW_SYS_BOOTCS (REALVIEW_SYS_BASE + REALVIEW_SYS_BOOTCS_OFFSET)
#define REALVIEW_SYS_24MHz (REALVIEW_SYS_BASE + REALVIEW_SYS_24MHz_OFFSET)
#define REALVIEW_SYS_MISC (REALVIEW_SYS_BASE + REALVIEW_SYS_MISC_OFFSET)
+#define REALVIEW_SYS_PCI_STAT (REALVIEW_SYS_BASE + REALVIEW_SYS_PCI_STAT_OFFSET)
#define REALVIEW_SYS_IOSEL (REALVIEW_SYS_BASE + REALVIEW_SYS_IOSEL_OFFSET)
#define REALVIEW_SYS_PROCID (REALVIEW_SYS_BASE + REALVIEW_SYS_PROCID_OFFSET)
#define REALVIEW_SYS_TEST_OSC0 (REALVIEW_SYS_BASE + REALVIEW_SYS_TEST_OSC0_OFFSET)
@@ -174,19 +176,6 @@
#define REALVIEW_DMC_BASE 0x10018000 /* DMC configuration */
#define REALVIEW_DMAC_BASE 0x10030000 /* DMA controller */
-/* PCI space */
-#define REALVIEW_PCI_BASE 0x41000000 /* PCI Interface */
-#define REALVIEW_PCI_CFG_BASE 0x42000000
-#define REALVIEW_PCI_MEM_BASE0 0x44000000
-#define REALVIEW_PCI_MEM_BASE1 0x50000000
-#define REALVIEW_PCI_MEM_BASE2 0x60000000
-/* Sizes of above maps */
-#define REALVIEW_PCI_BASE_SIZE 0x01000000
-#define REALVIEW_PCI_CFG_BASE_SIZE 0x02000000
-#define REALVIEW_PCI_MEM_BASE0_SIZE 0x0c000000 /* 32Mb */
-#define REALVIEW_PCI_MEM_BASE1_SIZE 0x10000000 /* 256Mb */
-#define REALVIEW_PCI_MEM_BASE2_SIZE 0x10000000 /* 256Mb */
-
#define REALVIEW_SDRAM67_BASE 0x70000000 /* SDRAM banks 6 and 7 */
#define REALVIEW_LT_BASE 0x80000000 /* Logic Tile expansion */
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 4/6] ARM Realview PCIX IRQ include file changes
2010-12-22 14:03 [PATCH 0/6] Series short description Colin Tuckley
` (2 preceding siblings ...)
2010-12-22 14:04 ` [PATCH 3/6] ARM Realview PCIX map include file changes Colin Tuckley
@ 2010-12-22 14:04 ` Colin Tuckley
2010-12-22 14:04 ` [PATCH 5/6] ARM Realview PCIX board " Colin Tuckley
2010-12-22 14:04 ` [PATCH 6/6] ARM Realview PCIX build " Colin Tuckley
5 siblings, 0 replies; 11+ messages in thread
From: Colin Tuckley @ 2010-12-22 14:04 UTC (permalink / raw)
To: linux-arm-kernel
This patch adds the Interrupt definitions for the PCI
support on the Realview boards.
Signed-off-by: Colin Tuckley <colin.tuckley@arm.com>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
---
arch/arm/mach-realview/include/mach/irqs-pb11mp.h | 11 +++++++++++
arch/arm/mach-realview/include/mach/irqs-pba8.h | 7 ++++++-
arch/arm/mach-realview/include/mach/irqs-pbx.h | 7 ++++++-
3 files changed, 23 insertions(+), 2 deletions(-)
diff --git a/arch/arm/mach-realview/include/mach/irqs-pb11mp.h b/arch/arm/mach-realview/include/mach/irqs-pb11mp.h
index 34e255a..cd3e3e6 100644
--- a/arch/arm/mach-realview/include/mach/irqs-pb11mp.h
+++ b/arch/arm/mach-realview/include/mach/irqs-pb11mp.h
@@ -95,6 +95,17 @@
#define IRQ_PB11MP_TSPEN (IRQ_PB11MP_GIC_START + 30) /* Touchscreen pen */
#define IRQ_PB11MP_TSKPAD (IRQ_PB11MP_GIC_START + 31) /* Touchscreen keypad */
+/* These PCI/PCIe IRQ definitions are here as placeholders
+ * The PCI code actually calculates the irq used at runtime */
+#define IRQ_PB11MP_PCI0 (IRQ_PB11MP_GIC_START + 50)
+#define IRQ_PB11MP_PCI1 (IRQ_PB11MP_GIC_START + 51)
+#define IRQ_PB11MP_PCI2 (IRQ_PB11MP_GIC_START + 52)
+#define IRQ_PB11MP_PCI3 (IRQ_PB11MP_GIC_START + 53)
+#define IRQ_PB11MP_PCIE0 (IRQ_PB11MP_GIC_START + 54)
+#define IRQ_PB11MP_PCIE1 (IRQ_PB11MP_GIC_START + 55)
+#define IRQ_PB11MP_PCIE2 (IRQ_PB11MP_GIC_START + 56)
+#define IRQ_PB11MP_PCIE3 (IRQ_PB11MP_GIC_START + 57)
+
#define IRQ_PB11MP_SMC -1
#define IRQ_PB11MP_SCTL -1
diff --git a/arch/arm/mach-realview/include/mach/irqs-pba8.h b/arch/arm/mach-realview/include/mach/irqs-pba8.h
index 4a88a4e..da6d583 100644
--- a/arch/arm/mach-realview/include/mach/irqs-pba8.h
+++ b/arch/arm/mach-realview/include/mach/irqs-pba8.h
@@ -61,11 +61,16 @@
#define IRQ_PBA8_PMU (IRQ_PBA8_GIC_START + 47) /* Cortex-A8 PMU */
-/* ... */
+/* These PCI/PCIe IRQ definitions are here as placeholders
+ * The PCI code actually calculates the irq used at runtime */
#define IRQ_PBA8_PCI0 (IRQ_PBA8_GIC_START + 50)
#define IRQ_PBA8_PCI1 (IRQ_PBA8_GIC_START + 51)
#define IRQ_PBA8_PCI2 (IRQ_PBA8_GIC_START + 52)
#define IRQ_PBA8_PCI3 (IRQ_PBA8_GIC_START + 53)
+#define IRQ_PBA8_PCIE0 (IRQ_PBA8_GIC_START + 54)
+#define IRQ_PBA8_PCIE1 (IRQ_PBA8_GIC_START + 55)
+#define IRQ_PBA8_PCIE2 (IRQ_PBA8_GIC_START + 56)
+#define IRQ_PBA8_PCIE3 (IRQ_PBA8_GIC_START + 57)
#define IRQ_PBA8_SMC -1
#define IRQ_PBA8_SCTL -1
diff --git a/arch/arm/mach-realview/include/mach/irqs-pbx.h b/arch/arm/mach-realview/include/mach/irqs-pbx.h
index 206a300..f661702 100644
--- a/arch/arm/mach-realview/include/mach/irqs-pbx.h
+++ b/arch/arm/mach-realview/include/mach/irqs-pbx.h
@@ -76,11 +76,16 @@
#define IRQ_PBX_PMU_CPU2 (IRQ_PBX_GIC_START + 46)
#define IRQ_PBX_PMU_CPU3 (IRQ_PBX_GIC_START + 47)
-/* ... */
+/* These PCI/PCIe IRQ definitions are here as placeholders
+ * The PCI code actually calculates the irq used at runtime */
#define IRQ_PBX_PCI0 (IRQ_PBX_GIC_START + 50)
#define IRQ_PBX_PCI1 (IRQ_PBX_GIC_START + 51)
#define IRQ_PBX_PCI2 (IRQ_PBX_GIC_START + 52)
#define IRQ_PBX_PCI3 (IRQ_PBX_GIC_START + 53)
+#define IRQ_PBX_PCIE0 (IRQ_PBX_GIC_START + 54)
+#define IRQ_PBX_PCIE1 (IRQ_PBX_GIC_START + 55)
+#define IRQ_PBX_PCIE2 (IRQ_PBX_GIC_START + 56)
+#define IRQ_PBX_PCIE3 (IRQ_PBX_GIC_START + 57)
#define IRQ_PBX_SMC -1
#define IRQ_PBX_SCTL -1
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 5/6] ARM Realview PCIX board file changes
2010-12-22 14:03 [PATCH 0/6] Series short description Colin Tuckley
` (3 preceding siblings ...)
2010-12-22 14:04 ` [PATCH 4/6] ARM Realview PCIX IRQ " Colin Tuckley
@ 2010-12-22 14:04 ` Colin Tuckley
2010-12-22 14:04 ` [PATCH 6/6] ARM Realview PCIX build " Colin Tuckley
5 siblings, 0 replies; 11+ messages in thread
From: Colin Tuckley @ 2010-12-22 14:04 UTC (permalink / raw)
To: linux-arm-kernel
This patch adds the PCI support to the board files
for the Realview Northbridge boards.
Signed-off-by: Colin Tuckley <colin.tuckley@arm.com>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
---
arch/arm/mach-realview/realview_pb11mp.c | 18 ++++++++++++++++++
arch/arm/mach-realview/realview_pba8.c | 18 ++++++++++++++----
arch/arm/mach-realview/realview_pbx.c | 16 +++++++++++++---
3 files changed, 45 insertions(+), 7 deletions(-)
diff --git a/arch/arm/mach-realview/realview_pb11mp.c b/arch/arm/mach-realview/realview_pb11mp.c
index 117b95b..8acb76b 100644
--- a/arch/arm/mach-realview/realview_pb11mp.c
+++ b/arch/arm/mach-realview/realview_pb11mp.c
@@ -95,6 +95,24 @@ static struct map_desc realview_pb11mp_io_desc[] __initdata = {
.length = SZ_8K,
.type = MT_DEVICE,
},
+#ifdef CONFIG_PCI
+ {
+ .virtual = (unsigned long)PCIX_UNIT_BASE,
+ .pfn = __phys_to_pfn(REALVIEW_PB_PCI_BASE),
+ .length = REALVIEW_PB_PCI_BASE_SIZE,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)REALVIEW_PCI_IO_VBASE,
+ .pfn = __phys_to_pfn(REALVIEW_PB_PCI_IO_BASE),
+ .length = REALVIEW_PB_PCI_IO_SIZE,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = IO_ADDRESS(REALVIEW_ISSP_REG_BASE),
+ .pfn = __phys_to_pfn(REALVIEW_ISSP_REG_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ },
+#endif
#ifdef CONFIG_DEBUG_LL
{
.virtual = IO_ADDRESS(REALVIEW_PB11MP_UART0_BASE),
diff --git a/arch/arm/mach-realview/realview_pba8.c b/arch/arm/mach-realview/realview_pba8.c
index 929b8dc..e7f4c36 100644
--- a/arch/arm/mach-realview/realview_pba8.c
+++ b/arch/arm/mach-realview/realview_pba8.c
@@ -79,10 +79,20 @@ static struct map_desc realview_pba8_io_desc[] __initdata = {
},
#ifdef CONFIG_PCI
{
- .virtual = PCIX_UNIT_BASE,
- .pfn = __phys_to_pfn(REALVIEW_PBA8_PCI_BASE),
- .length = REALVIEW_PBA8_PCI_BASE_SIZE,
- .type = MT_DEVICE
+ .virtual = (unsigned long)PCIX_UNIT_BASE,
+ .pfn = __phys_to_pfn(REALVIEW_PB_PCI_BASE),
+ .length = REALVIEW_PB_PCI_BASE_SIZE,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)REALVIEW_PCI_IO_VBASE,
+ .pfn = __phys_to_pfn(REALVIEW_PB_PCI_IO_BASE),
+ .length = REALVIEW_PB_PCI_IO_SIZE,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = IO_ADDRESS(REALVIEW_ISSP_REG_BASE),
+ .pfn = __phys_to_pfn(REALVIEW_ISSP_REG_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
},
#endif
#ifdef CONFIG_DEBUG_LL
diff --git a/arch/arm/mach-realview/realview_pbx.c b/arch/arm/mach-realview/realview_pbx.c
index b9f9e20..42fc304 100644
--- a/arch/arm/mach-realview/realview_pbx.c
+++ b/arch/arm/mach-realview/realview_pbx.c
@@ -80,9 +80,19 @@ static struct map_desc realview_pbx_io_desc[] __initdata = {
},
#ifdef CONFIG_PCI
{
- .virtual = PCIX_UNIT_BASE,
- .pfn = __phys_to_pfn(REALVIEW_PBX_PCI_BASE),
- .length = REALVIEW_PBX_PCI_BASE_SIZE,
+ .virtual = (unsigned long)PCIX_UNIT_BASE,
+ .pfn = __phys_to_pfn(REALVIEW_PB_PCI_BASE),
+ .length = REALVIEW_PB_PCI_BASE_SIZE,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)REALVIEW_PCI_IO_VBASE,
+ .pfn = __phys_to_pfn(REALVIEW_PB_PCI_IO_BASE),
+ .length = REALVIEW_PB_PCI_IO_SIZE,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = IO_ADDRESS(REALVIEW_ISSP_REG_BASE),
+ .pfn = __phys_to_pfn(REALVIEW_ISSP_REG_BASE),
+ .length = SZ_4K,
.type = MT_DEVICE,
},
#endif
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 6/6] ARM Realview PCIX build file changes
2010-12-22 14:03 [PATCH 0/6] Series short description Colin Tuckley
` (4 preceding siblings ...)
2010-12-22 14:04 ` [PATCH 5/6] ARM Realview PCIX board " Colin Tuckley
@ 2010-12-22 14:04 ` Colin Tuckley
5 siblings, 0 replies; 11+ messages in thread
From: Colin Tuckley @ 2010-12-22 14:04 UTC (permalink / raw)
To: linux-arm-kernel
This patch adds PCI support for the Realview boards
to the mach-realview build system.
Signed-off-by: Colin Tuckley <colin.tuckley@arm.com>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
---
arch/arm/Kconfig | 6 +++++-
arch/arm/mach-realview/Makefile | 6 ++++++
2 files changed, 11 insertions(+), 1 deletions(-)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index d56d21c..c653f04 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1164,7 +1164,9 @@ 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 || \
+ MACH_REALVIEW_PB11MP || MACH_REALVIEW_PBA8 || MACH_REALVIEW_PBX
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
@@ -1192,6 +1194,8 @@ config PCI_HOST_ITE8152
source "drivers/pci/Kconfig"
+source "drivers/pci/pcie/Kconfig"
+
source "drivers/pcmcia/Kconfig"
endmenu
diff --git a/arch/arm/mach-realview/Makefile b/arch/arm/mach-realview/Makefile
index a01b76b..bb2d414 100644
--- a/arch/arm/mach-realview/Makefile
+++ b/arch/arm/mach-realview/Makefile
@@ -10,4 +10,10 @@ obj-$(CONFIG_MACH_REALVIEW_PBA8) += realview_pba8.o
obj-$(CONFIG_MACH_REALVIEW_PBX) += realview_pbx.o
obj-$(CONFIG_SMP) += platsmp.o headsmp.o
obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
+ifeq ($(CONFIG_PCI),y)
+obj-$(CONFIG_MACH_REALVIEW_PB11MP) += pcix.o
+obj-$(CONFIG_MACH_REALVIEW_PBA8) += pcix.o
+obj-$(CONFIG_MACH_REALVIEW_PBX) += pcix.o
+endif
+
obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 3/6] ARM Realview PCIX map include file changes
2010-12-22 14:04 ` [PATCH 3/6] ARM Realview PCIX map include file changes Colin Tuckley
@ 2010-12-22 15:33 ` Arnd Bergmann
2010-12-22 16:12 ` Colin Tuckley
2010-12-22 16:48 ` Arnd Bergmann
0 siblings, 2 replies; 11+ messages in thread
From: Arnd Bergmann @ 2010-12-22 15:33 UTC (permalink / raw)
To: linux-arm-kernel
On Wednesday 22 December 2010 15:04:09 Colin Tuckley wrote:
> #define REALVIEW_PB11MP_PCI_IO_SIZE 0x1000 /* 4 Kb */
Is the I/O space really just 4 kb? This may easily cause problems,
because the first 4 kb of I/O space are usually reserved for PCI-ISA
bridges and the like. At least the public documentation for PB-X
describes a 64 kb space, which is also what everyone else has.
> +static inline unsigned int pcibios_min_io(void)
> +{
> + if (machine_is_realview_pb11mp() || machine_is_realview_pba8() ||
> + machine_is_realview_pbx())
> + return REALVIEW_PB_PCI_IO_BASE;
> + else
> + return 0;
> +}
...
> +
> #define IO_SPACE_LIMIT 0xffffffff
>
> -#define __io(a) __typesafe_io(a)
> +static inline void __iomem *__io(unsigned long addr)
> +{
> +#ifdef CONFIG_PCI
> + /* check for PCI I/O space */
> + if (addr >= REALVIEW_PB_PCI_IO_BASE && addr <= REALVIEW_PB_PCI_IO_LIMIT)
> + return (void __iomem *)((addr - REALVIEW_PB_PCI_IO_BASE) + REALVIEW_PCI_IO_VBASE);
> + else
> + return (void __iomem *)addr;
> +#else
> + return (void __iomem *)addr;
> +#endif
> +}
The I/O space handling still looks really wrong. Why not simply do this:
#define PCIBIOS_MIN_IO 0x1000 /* skip the first 4kb */
#define IO_SPACE_LIMIT 0xffff /* regular 64 kb I/O space */
#define __io(a) (REALVIEW_PCI_IO_VBASE + (a & IO_SPACE_LIMIT)
If you start the I/O space at REALVIEW_PB_PCI_IO_BASE instead of 0x1000
or 0, you get into all sorts of trouble, e.g. when using /dev/ioport.
Arnd
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 3/6] ARM Realview PCIX map include file changes
2010-12-22 15:33 ` Arnd Bergmann
@ 2010-12-22 16:12 ` Colin Tuckley
2010-12-22 16:48 ` Arnd Bergmann
1 sibling, 0 replies; 11+ messages in thread
From: Colin Tuckley @ 2010-12-22 16:12 UTC (permalink / raw)
To: linux-arm-kernel
> -----Original Message-----
> From: Arnd Bergmann [mailto:arnd at arndb.de]
> On Wednesday 22 December 2010 15:04:09 Colin Tuckley wrote:
>
> > #define REALVIEW_PB11MP_PCI_IO_SIZE 0x1000 /* 4
> Kb */
I think you are miss-reading the patch, that is one of the lines that is being deleted!
Colin
-- IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 3/6] ARM Realview PCIX map include file changes
2010-12-22 15:33 ` Arnd Bergmann
2010-12-22 16:12 ` Colin Tuckley
@ 2010-12-22 16:48 ` Arnd Bergmann
1 sibling, 0 replies; 11+ messages in thread
From: Arnd Bergmann @ 2010-12-22 16:48 UTC (permalink / raw)
To: linux-arm-kernel
On Wednesday 22 December 2010 16:33:20 Arnd Bergmann wrote:
> On Wednesday 22 December 2010 15:04:09 Colin Tuckley wrote:
>
> > #define REALVIEW_PB11MP_PCI_IO_SIZE 0x1000 /* 4 Kb */
>
> Is the I/O space really just 4 kb? This may easily cause problems,
> because the first 4 kb of I/O space are usually reserved for PCI-ISA
> bridges and the like. At least the public documentation for PB-X
> describes a 64 kb space, which is also what everyone else has.
Nevermind, I misread this -- the definition was getting deleted, not added
and the new one for this is right.
Arnd
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 2/6] Realview PCIX support - add main support module code
2010-12-22 14:04 ` [PATCH 2/6] Realview PCIX support - add main support module code Colin Tuckley
@ 2011-01-19 13:00 ` Russell King - ARM Linux
0 siblings, 0 replies; 11+ messages in thread
From: Russell King - ARM Linux @ 2011-01-19 13:00 UTC (permalink / raw)
To: linux-arm-kernel
I thought someone picked up on the swizzling (or lack of it) but maybe
not.
On Wed, Dec 22, 2010 at 02:04:04PM +0000, Colin Tuckley wrote:
> +/* Maps scrambled IRQ pins to IRQ lines. Scrambling depends on device slot. */
> +static int __init pci_realview_pb_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
> +{
> + int irq;
> + int devslot = PCI_SLOT(dev->devfn);
> +
> + /* Upstream port of 8518 device */
> + if (unlikely(dev->device == 0x8518 && dev->bus->primary == 0)) {
> + BUG_ON(pcie_bridge); /* Can't be already assigned */
> + pcie_bridge = dev;
> + }
> +
> + if (pcie_bridge) {
> + if (dev->bus->primary >= pcie_bridge->bus->secondary &&
> + dev->bus->primary <= pcie_bridge->bus->subordinate) {
> + /*
> + * The problem is that in PCIE in different slots a device
> + * could still get the same slot/pin/devslot triplet. Therefore
> + * we check the slot/pin/devslot triplet of an underlying PCIE port.
> + *
> + * slot pin irq
> + * 0 #A(1) 56
> + * 0 #B(2) 57
> + * 0 #C(3) 54
> + * 0 #D(4) 55
> + * 1 #A(1) 55
> + * 1 #B(2) 56
> + * 1 #C(3) 57
> + * 1 #D(4) 54
> + * 2 1 54
> + * 2 2 55
> + * 2 3 56
> + * 2 4 57
> + * 3 1 57
> + * 3 2 54
> + * 3 3 55
> + * 3 4 56
> + * 4 1 56
> + * 4 2 57
> + * 4 3 54
> + * 4 4 55
> + */
Isn't this is the standard PCI IRQ layout - four interrupt lines rotated
one place across each socket? It's easier to see (and a shorter comment)
to lay it out as it appears on the board:
slot: 0 1 2 3 4
pin A 56 55 54 57 56
pin B 57 56 55 54 57
pin C 54 57 56 55 54
pin D 55 54 57 56 55
> + if (dev->bus->self) {
> + /* We do have a bus above us
> + * Device is right behind a PCIE hub port, and its not a PCIE
> + * hub port itself. */
> + if (dev->bus->self->device == 0x8518 &&
> + dev->device != 0x8518) {
> + /* Depend on devslot of 8518 port we're connected to */
> + devslot = PCI_SLOT(dev->bus->self->devfn);
> + /* These are the two cases for PCIE ports on PB boards.
> + * Any other downstream bus topology (e.g. with further
> + * PCIE bridges) does not scramble, and get the same
> + * irq number as the upstream bus. */
> + irq = irq_gic_start + 54 + ((devslot & 3) + (pin - 1)) % 4;
> + } else if ((dev->bus->self->class & 0xff0000) == 0x060000 &&
> + (dev->class & 0xff0000) != 0x060000) {
> + /* It's a device behind a bridge that isn't an 8518 */
> + irq = irq_gic_start + 54 + ((devslot & 3) + pin +
> + PCI_SLOT(dev->bus->self->bus->self->devfn) - 1) % 4;
> + } else {
> + /* It's another bridge */
> + irq = dev->bus->self->irq;
> + }
You should not be dealing with bridges behind slots in this code. That's
what the swizzle function is for, and PCI defines a standard swizzling
method for devices behind bridges, and that algorithm is implemented by
pci_common_swizzle (which should be in the .swizzle initializer.)
If pci_is_root_bus(dev->bus) for your PCIe bridge doesn't return true,
then the standard swizzling will go all the way to the PCI root bridge,
which is probably not what you want. In that case, you need to
implement your own version of pci_common_swizzle which knows to stop
at the PCIe bridge when it finds it, or the PCI root bridge.
Note that you almost certainly should not be matching the PCIe bridge
by PCI device number alone. PCI device numbers are not unique - only
when coupled with the vendor number do they become (more or less) unique.
The slot and pin arguments from the swizzle function are then passed into
the map_irq function. I suggest you keep the normal pin numbering, but
(maybe) define a PCIE_SLOT offset for PCIe slots, which you can then use
to detect whether we want the PCIe IRQ numbers or PCI IRQ numbers.
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2011-01-19 13:00 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-12-22 14:03 [PATCH 0/6] Series short description Colin Tuckley
2010-12-22 14:03 ` [PATCH 1/6] ARM: enable bridges in pci_common_init Colin Tuckley
2010-12-22 14:04 ` [PATCH 2/6] Realview PCIX support - add main support module code Colin Tuckley
2011-01-19 13:00 ` Russell King - ARM Linux
2010-12-22 14:04 ` [PATCH 3/6] ARM Realview PCIX map include file changes Colin Tuckley
2010-12-22 15:33 ` Arnd Bergmann
2010-12-22 16:12 ` Colin Tuckley
2010-12-22 16:48 ` Arnd Bergmann
2010-12-22 14:04 ` [PATCH 4/6] ARM Realview PCIX IRQ " Colin Tuckley
2010-12-22 14:04 ` [PATCH 5/6] ARM Realview PCIX board " Colin Tuckley
2010-12-22 14:04 ` [PATCH 6/6] ARM Realview PCIX build " Colin Tuckley
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).