aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjorn Helgaas <bhelgaas@google.com>2017-11-14 13:11:30 -0500
committerBjorn Helgaas <bhelgaas@google.com>2017-11-14 13:11:30 -0500
commitd535969614d547f149e9d6d31e54d5434069a31e (patch)
tree726f1eb61b7fde244b3efa7a7ff5ebb2ff2baebb
parent807dcfee426b407f7175fefc4c255594c6f257f5 (diff)
parent19f3f22aade704f9ce82a55c853381e672629a1d (diff)
Merge branch 'pci/host-generic' into next
* pci/host-generic: dt-bindings: PCI: designware: Add binding for Designware PCIe in ECAM mode PCI: generic: Add support for Synopsys DesignWare RC in ECAM mode
-rw-r--r--Documentation/devicetree/bindings/pci/designware-pcie-ecam.txt42
-rw-r--r--drivers/pci/host/pci-host-generic.c43
2 files changed, 85 insertions, 0 deletions
diff --git a/Documentation/devicetree/bindings/pci/designware-pcie-ecam.txt b/Documentation/devicetree/bindings/pci/designware-pcie-ecam.txt
new file mode 100644
index 000000000000..515b2f9542e5
--- /dev/null
+++ b/Documentation/devicetree/bindings/pci/designware-pcie-ecam.txt
@@ -0,0 +1,42 @@
1* Synopsys DesignWare PCIe root complex in ECAM shift mode
2
3In some cases, firmware may already have configured the Synopsys DesignWare
4PCIe controller in RC mode with static ATU window mappings that cover all
5config, MMIO and I/O spaces in a [mostly] ECAM compatible fashion.
6In this case, there is no need for the OS to perform any low level setup
7of clocks, PHYs or device registers, nor is there any reason for the driver
8to reconfigure ATU windows for config and/or IO space accesses at runtime.
9
10In cases where the IP was synthesized with a minimum ATU window size of
1164 KB, it cannot be supported by the generic ECAM driver, because it
12requires special config space accessors that filter accesses to device #1
13and beyond on the first bus.
14
15Required properties:
16- compatible: "marvell,armada8k-pcie-ecam" or
17 "socionext,synquacer-pcie-ecam" or
18 "snps,dw-pcie-ecam" (must be preceded by a more specific match)
19
20Please refer to the binding document of "pci-host-ecam-generic" in the
21file host-generic-pci.txt for a description of the remaining required
22and optional properties.
23
24Example:
25
26 pcie1: pcie@7f000000 {
27 compatible = "socionext,synquacer-pcie-ecam", "snps,dw-pcie-ecam";
28 device_type = "pci";
29 reg = <0x0 0x7f000000 0x0 0xf00000>;
30 bus-range = <0x0 0xe>;
31 #address-cells = <3>;
32 #size-cells = <2>;
33 ranges = <0x1000000 0x00 0x00010000 0x00 0x7ff00000 0x0 0x00010000>,
34 <0x2000000 0x00 0x70000000 0x00 0x70000000 0x0 0x0f000000>,
35 <0x3000000 0x3f 0x00000000 0x3f 0x00000000 0x1 0x00000000>;
36
37 #interrupt-cells = <0x1>;
38 interrupt-map-mask = <0x0 0x0 0x0 0x0>;
39 interrupt-map = <0x0 0x0 0x0 0x0 &gic 0x0 0x0 0x0 182 0x4>;
40 msi-map = <0x0 &its 0x0 0x10000>;
41 dma-coherent;
42 };
diff --git a/drivers/pci/host/pci-host-generic.c b/drivers/pci/host/pci-host-generic.c
index 7d709a7e0aa8..2f05511ce718 100644
--- a/drivers/pci/host/pci-host-generic.c
+++ b/drivers/pci/host/pci-host-generic.c
@@ -35,6 +35,40 @@ static struct pci_ecam_ops gen_pci_cfg_cam_bus_ops = {
35 } 35 }
36}; 36};
37 37
38static bool pci_dw_valid_device(struct pci_bus *bus, unsigned int devfn)
39{
40 struct pci_config_window *cfg = bus->sysdata;
41
42 /*
43 * The Synopsys DesignWare PCIe controller in ECAM mode will not filter
44 * type 0 config TLPs sent to devices 1 and up on its downstream port,
45 * resulting in devices appearing multiple times on bus 0 unless we
46 * filter out those accesses here.
47 */
48 if (bus->number == cfg->busr.start && PCI_SLOT(devfn) > 0)
49 return false;
50
51 return true;
52}
53
54static void __iomem *pci_dw_ecam_map_bus(struct pci_bus *bus,
55 unsigned int devfn, int where)
56{
57 if (!pci_dw_valid_device(bus, devfn))
58 return NULL;
59
60 return pci_ecam_map_bus(bus, devfn, where);
61}
62
63static struct pci_ecam_ops pci_dw_ecam_bus_ops = {
64 .bus_shift = 20,
65 .pci_ops = {
66 .map_bus = pci_dw_ecam_map_bus,
67 .read = pci_generic_config_read,
68 .write = pci_generic_config_write,
69 }
70};
71
38static const struct of_device_id gen_pci_of_match[] = { 72static const struct of_device_id gen_pci_of_match[] = {
39 { .compatible = "pci-host-cam-generic", 73 { .compatible = "pci-host-cam-generic",
40 .data = &gen_pci_cfg_cam_bus_ops }, 74 .data = &gen_pci_cfg_cam_bus_ops },
@@ -42,6 +76,15 @@ static const struct of_device_id gen_pci_of_match[] = {
42 { .compatible = "pci-host-ecam-generic", 76 { .compatible = "pci-host-ecam-generic",
43 .data = &pci_generic_ecam_ops }, 77 .data = &pci_generic_ecam_ops },
44 78
79 { .compatible = "marvell,armada8k-pcie-ecam",
80 .data = &pci_dw_ecam_bus_ops },
81
82 { .compatible = "socionext,synquacer-pcie-ecam",
83 .data = &pci_dw_ecam_bus_ops },
84
85 { .compatible = "snps,dw-pcie-ecam",
86 .data = &pci_dw_ecam_bus_ops },
87
45 { }, 88 { },
46}; 89};
47 90