diff options
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.patch | 97 |
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", |