Skip to content

Commit

Permalink
Merge branch 'pci/host-generic' into next
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
bjorn-helgaas committed Nov 14, 2017
2 parents 807dcfe + 19f3f22 commit d535969
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 0 deletions.
42 changes: 42 additions & 0 deletions Documentation/devicetree/bindings/pci/designware-pcie-ecam.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
* Synopsys DesignWare PCIe root complex in ECAM shift mode

In some cases, firmware may already have configured the Synopsys DesignWare
PCIe controller in RC mode with static ATU window mappings that cover all
config, MMIO and I/O spaces in a [mostly] ECAM compatible fashion.
In this case, there is no need for the OS to perform any low level setup
of clocks, PHYs or device registers, nor is there any reason for the driver
to reconfigure ATU windows for config and/or IO space accesses at runtime.

In cases where the IP was synthesized with a minimum ATU window size of
64 KB, it cannot be supported by the generic ECAM driver, because it
requires special config space accessors that filter accesses to device #1
and beyond on the first bus.

Required properties:
- compatible: "marvell,armada8k-pcie-ecam" or
"socionext,synquacer-pcie-ecam" or
"snps,dw-pcie-ecam" (must be preceded by a more specific match)

Please refer to the binding document of "pci-host-ecam-generic" in the
file host-generic-pci.txt for a description of the remaining required
and optional properties.

Example:

pcie1: pcie@7f000000 {
compatible = "socionext,synquacer-pcie-ecam", "snps,dw-pcie-ecam";
device_type = "pci";
reg = <0x0 0x7f000000 0x0 0xf00000>;
bus-range = <0x0 0xe>;
#address-cells = <3>;
#size-cells = <2>;
ranges = <0x1000000 0x00 0x00010000 0x00 0x7ff00000 0x0 0x00010000>,
<0x2000000 0x00 0x70000000 0x00 0x70000000 0x0 0x0f000000>,
<0x3000000 0x3f 0x00000000 0x3f 0x00000000 0x1 0x00000000>;

#interrupt-cells = <0x1>;
interrupt-map-mask = <0x0 0x0 0x0 0x0>;
interrupt-map = <0x0 0x0 0x0 0x0 &gic 0x0 0x0 0x0 182 0x4>;
msi-map = <0x0 &its 0x0 0x10000>;
dma-coherent;
};
43 changes: 43 additions & 0 deletions drivers/pci/host/pci-host-generic.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,56 @@ static struct pci_ecam_ops gen_pci_cfg_cam_bus_ops = {
}
};

static bool pci_dw_valid_device(struct pci_bus *bus, unsigned int devfn)
{
struct pci_config_window *cfg = bus->sysdata;

/*
* The Synopsys DesignWare PCIe controller in ECAM mode will not filter
* type 0 config TLPs sent to devices 1 and up on its downstream port,
* resulting in devices appearing multiple times on bus 0 unless we
* filter out those accesses here.
*/
if (bus->number == cfg->busr.start && PCI_SLOT(devfn) > 0)
return false;

return true;
}

static void __iomem *pci_dw_ecam_map_bus(struct pci_bus *bus,
unsigned int devfn, int where)
{
if (!pci_dw_valid_device(bus, devfn))
return NULL;

return pci_ecam_map_bus(bus, devfn, where);
}

static struct pci_ecam_ops pci_dw_ecam_bus_ops = {
.bus_shift = 20,
.pci_ops = {
.map_bus = pci_dw_ecam_map_bus,
.read = pci_generic_config_read,
.write = pci_generic_config_write,
}
};

static const struct of_device_id gen_pci_of_match[] = {
{ .compatible = "pci-host-cam-generic",
.data = &gen_pci_cfg_cam_bus_ops },

{ .compatible = "pci-host-ecam-generic",
.data = &pci_generic_ecam_ops },

{ .compatible = "marvell,armada8k-pcie-ecam",
.data = &pci_dw_ecam_bus_ops },

{ .compatible = "socionext,synquacer-pcie-ecam",
.data = &pci_dw_ecam_bus_ops },

{ .compatible = "snps,dw-pcie-ecam",
.data = &pci_dw_ecam_bus_ops },

{ },
};

Expand Down

0 comments on commit d535969

Please sign in to comment.