PCI: mvebu: add compatible string for orion5x
orion5x uses an older version of the same PCIe hardware as kirkwood,
so we should be able to use the same driver.
The existing orion pcie driver contains a workaround for PCI config
space access, this adds a similar function ot the mvebu driver.
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
diff --git a/Documentation/devicetree/bindings/pci/mvebu-pci.txt b/Documentation/devicetree/bindings/pci/mvebu-pci.txt
index 08c716b..1b81e0a 100644
--- a/Documentation/devicetree/bindings/pci/mvebu-pci.txt
+++ b/Documentation/devicetree/bindings/pci/mvebu-pci.txt
@@ -7,6 +7,7 @@
marvell,armada-xp-pcie
marvell,dove-pcie
marvell,kirkwood-pcie
+ marvell,orion-pcie
- #address-cells, set to <3>
- #size-cells, set to <2>
- #interrupt-cells, set to <1>
@@ -61,6 +62,9 @@
are used to refer to the correct bus number and device number.
- assigned-addresses: reference to the MMIO registers used to control
this PCIe interface.
+ If the device is compatible with marvell,orion-pcie and a second
+ address range is present, that is a reference to the configuration
+ space.
- clocks: the clock associated to this PCIe interface
- marvell,pcie-port: the physical PCIe port number
- status: either "disabled" or "okay"
diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig
index c4b6568..3ac1318 100644
--- a/drivers/pci/host/Kconfig
+++ b/drivers/pci/host/Kconfig
@@ -12,7 +12,7 @@
config PCI_MVEBU
bool "Marvell EBU PCIe controller"
- depends on ARCH_MVEBU || ARCH_DOVE
+ depends on ARCH_MVEBU || ARCH_DOVE || ARCH_ORION5X_DT
depends on OF
config PCIE_DW
diff --git a/drivers/pci/host/pci-mvebu.c b/drivers/pci/host/pci-mvebu.c
index 1dd7595..3e987d6 100644
--- a/drivers/pci/host/pci-mvebu.c
+++ b/drivers/pci/host/pci-mvebu.c
@@ -113,6 +113,7 @@
struct mvebu_pcie_port {
char *name;
void __iomem *base;
+ void __iomem *wa_base;
u32 port;
u32 lane;
int devfn;
@@ -268,6 +269,33 @@
return PCIBIOS_SUCCESSFUL;
}
+static int mvebu_pcie_hw_rd_conf_wa(struct mvebu_pcie_port *port,
+ struct pci_bus *bus,
+ u32 devfn, int where, int size, u32 *val)
+{
+ /*
+ * We only support access to the non-extended configuration
+ * space when using the WA access method (or we would have to
+ * sacrifice 256M of CPU virtual address space.)
+ */
+ if (where >= 0x100) {
+ *val = 0xffffffff;
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ }
+
+ *val = readl(port->wa_base + (PCIE_CONF_BUS(bus->number) |
+ PCIE_CONF_DEV(PCI_SLOT(devfn)) |
+ PCIE_CONF_FUNC(PCI_FUNC(devfn)) |
+ PCIE_CONF_REG(where)));
+
+ if (size == 1)
+ *val = (*val >> (8 * (where & 3))) & 0xff;
+ else if (size == 2)
+ *val = (*val >> (8 * (where & 3))) & 0xffff;
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
static int mvebu_pcie_hw_wr_conf(struct mvebu_pcie_port *port,
struct pci_bus *bus,
u32 devfn, int where, int size, u32 val)
@@ -707,6 +735,9 @@
return PCIBIOS_DEVICE_NOT_FOUND;
}
+ if (port->wa_base)
+ return mvebu_pcie_hw_rd_conf_wa(port, bus, devfn,
+ where, size, val);
/* Access the real PCIe interface */
ret = mvebu_pcie_hw_rd_conf(port, bus, devfn,
where, size, val);
@@ -834,12 +865,13 @@
*/
static void __iomem *mvebu_pcie_map_registers(struct platform_device *pdev,
struct device_node *np,
- struct mvebu_pcie_port *port)
+ struct mvebu_pcie_port *port,
+ int index)
{
struct resource regs;
int ret = 0;
- ret = of_address_to_resource(np, 0, ®s);
+ ret = of_address_to_resource(np, index, ®s);
if (ret)
return ERR_PTR(ret);
@@ -1043,7 +1075,7 @@
if (ret)
continue;
- port->base = mvebu_pcie_map_registers(pdev, child, port);
+ port->base = mvebu_pcie_map_registers(pdev, child, port, 0);
if (IS_ERR(port->base)) {
dev_err(&pdev->dev, "PCIe%d.%d: cannot map registers\n",
port->port, port->lane);
@@ -1052,6 +1084,16 @@
continue;
}
+ if (of_device_is_compatible(np, "marvell,orion-pcie")) {
+ port->wa_base = mvebu_pcie_map_registers(pdev, child,
+ port, 1);
+ if (IS_ERR(port->wa_base))
+ port->wa_base = NULL;
+ else
+ dev_info(&pdev->dev,
+ "enabling config space workaround\n");
+ }
+
mvebu_pcie_set_local_dev_nr(port, 1);
port->dn = child;
@@ -1075,6 +1117,7 @@
{ .compatible = "marvell,armada-370-pcie", },
{ .compatible = "marvell,dove-pcie", },
{ .compatible = "marvell,kirkwood-pcie", },
+ { .compatible = "marvell,orion-pcie", },
{},
};
MODULE_DEVICE_TABLE(of, mvebu_pcie_of_match_table);