summaryrefslogtreecommitdiffstats
path: root/target/linux/kirkwood/patches-3.10/0017-pci-mvebu-no-longer-fake-the-slot-location-of-downst.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/kirkwood/patches-3.10/0017-pci-mvebu-no-longer-fake-the-slot-location-of-downst.patch')
-rw-r--r--target/linux/kirkwood/patches-3.10/0017-pci-mvebu-no-longer-fake-the-slot-location-of-downst.patch97
1 files changed, 97 insertions, 0 deletions
diff --git a/target/linux/kirkwood/patches-3.10/0017-pci-mvebu-no-longer-fake-the-slot-location-of-downst.patch b/target/linux/kirkwood/patches-3.10/0017-pci-mvebu-no-longer-fake-the-slot-location-of-downst.patch
new file mode 100644
index 0000000000..b1f252f7d9
--- /dev/null
+++ b/target/linux/kirkwood/patches-3.10/0017-pci-mvebu-no-longer-fake-the-slot-location-of-downst.patch
@@ -0,0 +1,97 @@
+From 5db3b7ccb319679ac9c5791112c7eb42c25331e3 Mon Sep 17 00:00:00 2001
+From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+Date: Thu, 23 May 2013 16:32:51 +0200
+Subject: [PATCH 17/29] pci: mvebu: no longer fake the slot location of
+ downstream devices
+
+By default, the Marvell hardware, for each PCIe interface, exhibits
+the following devices:
+
+ * On slot 0, a "Marvell Memory controller", identical on all PCIe
+ interfaces, and which isn't useful when the Marvell SoC is the PCIe
+ root complex (i.e, the normal case when we run Linux on the Marvell
+ SoC).
+
+ * On slot 1, the real PCIe card connected into the PCIe slot of the
+ board.
+
+So, what the Marvell PCIe driver was doing in its PCI-to-PCI bridge
+emulation is that when the Linux PCI core was trying to access the
+device in slot 0, we were in fact forwarding the configuration
+transaction to the device in slot 1. For all other slots, we were
+telling the Linux PCI core that there was no device connected.
+
+However, new versions of bootloaders from Marvell change the default
+PCIe configuration, and make the real device appear in slot 0, and the
+"Marvell Memory controller" in slot 1.
+
+Therefore, this commit modifies the Marvell PCIe driver to adjust the
+PCIe hardware configuration to make sure that this behavior (real
+device in slot 0, "Marvell Memory controller" in slot 1) is the one
+we'll see regardless of what the bootloader has done. It allows to
+remove the little hack that was forwarding configuration transactions
+on slot 0 to slot 1, which is nice.
+
+Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+Acked-by: Bjorn Helgaas <bhelgaas@google.com>
+Signed-off-by: Jason Cooper <jason@lakedaemon.net>
+---
+ drivers/pci/host/pci-mvebu.c | 19 +++++++++++++++----
+ 1 file changed, 15 insertions(+), 4 deletions(-)
+
+--- a/drivers/pci/host/pci-mvebu.c
++++ b/drivers/pci/host/pci-mvebu.c
+@@ -51,6 +51,7 @@
+ #define PCIE_CTRL_X1_MODE 0x0001
+ #define PCIE_STAT_OFF 0x1a04
+ #define PCIE_STAT_BUS 0xff00
++#define PCIE_STAT_DEV 0x1f0000
+ #define PCIE_STAT_LINK_DOWN BIT(0)
+ #define PCIE_DEBUG_CTRL 0x1a60
+ #define PCIE_DEBUG_SOFT_RESET BIT(20)
+@@ -148,6 +149,16 @@ static void mvebu_pcie_set_local_bus_nr(
+ writel(stat, port->base + PCIE_STAT_OFF);
+ }
+
++static void mvebu_pcie_set_local_dev_nr(struct mvebu_pcie_port *port, int nr)
++{
++ u32 stat;
++
++ stat = readl(port->base + PCIE_STAT_OFF);
++ stat &= ~PCIE_STAT_DEV;
++ stat |= nr << 16;
++ writel(stat, port->base + PCIE_STAT_OFF);
++}
++
+ /*
+ * Setup PCIE BARs and Address Decode Wins:
+ * BAR[0,2] -> disabled, BAR[1] -> covers all DRAM banks
+@@ -572,8 +583,7 @@ static int mvebu_pcie_wr_conf(struct pci
+
+ /* Access the real PCIe interface */
+ spin_lock_irqsave(&port->conf_lock, flags);
+- ret = mvebu_pcie_hw_wr_conf(port, bus,
+- PCI_DEVFN(1, PCI_FUNC(devfn)),
++ ret = mvebu_pcie_hw_wr_conf(port, bus, devfn,
+ where, size, val);
+ spin_unlock_irqrestore(&port->conf_lock, flags);
+
+@@ -606,8 +616,7 @@ static int mvebu_pcie_rd_conf(struct pci
+
+ /* Access the real PCIe interface */
+ spin_lock_irqsave(&port->conf_lock, flags);
+- ret = mvebu_pcie_hw_rd_conf(port, bus,
+- PCI_DEVFN(1, PCI_FUNC(devfn)),
++ ret = mvebu_pcie_hw_rd_conf(port, bus, devfn,
+ where, size, val);
+ spin_unlock_irqrestore(&port->conf_lock, flags);
+
+@@ -817,6 +826,8 @@ static int __init mvebu_pcie_probe(struc
+ continue;
+ }
+
++ mvebu_pcie_set_local_dev_nr(port, 1);
++
+ if (mvebu_pcie_link_up(port)) {
+ port->haslink = 1;
+ dev_info(&pdev->dev, "PCIe%d.%d: link up\n",