You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge tag 'pci-v4.10-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci
Pull PCI updates from Bjorn Helgaas:
"PCI changes:
- add support for PCI on ARM64 boxes with ACPI. We already had this
for theoretical spec-compliant hardware; now we're adding quirks
for the actual hardware (Cavium, HiSilicon, Qualcomm, X-Gene)
- add runtime PM support for hotplug ports
- enable runtime suspend for Intel UHCI that uses platform-specific
wakeup signaling
- add yet another host bridge registration interface. We hope this is
extensible enough to subsume the others
- expose device revision in sysfs for DRM
- to avoid device conflicts, make sure any VF BAR updates are done
before enabling the VF
- avoid unnecessary link retrains for ASPM
- allow INTx masking on Mellanox devices that support it
- allow access to non-standard VPD for Chelsio devices
- update Broadcom iProc support for PAXB v2, PAXC v2, inbound DMA,
etc
- update Rockchip support for max-link-speed
- add NVIDIA Tegra210 support
- add Layerscape LS1046a support
- update R-Car compatibility strings
- add Qualcomm MSM8996 support
- remove some uninformative bootup messages"
* tag 'pci-v4.10-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci: (115 commits)
PCI: Enable access to non-standard VPD for Chelsio devices (cxgb3)
PCI: Expand "VPD access disabled" quirk message
PCI: pciehp: Remove loading message
PCI: hotplug: Remove hotplug core message
PCI: Remove service driver load/unload messages
PCI/AER: Log AER IRQ when claiming Root Port
PCI/AER: Log errors with PCI device, not PCIe service device
PCI/AER: Remove unused version macros
PCI/PME: Log PME IRQ when claiming Root Port
PCI/PME: Drop unused support for PMEs from Root Complex Event Collectors
PCI: Move config space size macros to pci_regs.h
x86/platform/intel-mid: Constify mid_pci_platform_pm
PCI/ASPM: Don't retrain link if ASPM not possible
PCI: iproc: Skip check for legacy IRQ on PAXC buses
PCI: pciehp: Leave power indicator on when enabling already-enabled slot
PCI: pciehp: Prioritize data-link event over presence detect
PCI: rcar: Add gen3 fallback compatibility string for pcie-rcar
PCI: rcar: Use gen2 fallback compatibility last
PCI: rcar-gen2: Use gen2 fallback compatibility last
PCI: rockchip: Move the deassert of pm/aclk/pclk after phy_init()
..
This commit is contained in:
@@ -294,3 +294,10 @@ Description:
|
||||
a firmware bug to the system vendor. Writing to this file
|
||||
taints the kernel with TAINT_FIRMWARE_WORKAROUND, which
|
||||
reduces the supportability of your system.
|
||||
|
||||
What: /sys/bus/pci/devices/.../revision
|
||||
Date: November 2016
|
||||
Contact: Emil Velikov <emil.l.velikov@gmail.com>
|
||||
Description:
|
||||
This file contains the revision field of the the PCI device.
|
||||
The value comes from device config space. The file is read only.
|
||||
|
||||
@@ -1,10 +1,17 @@
|
||||
* Broadcom iProc PCIe controller with the platform bus interface
|
||||
|
||||
Required properties:
|
||||
- compatible: Must be "brcm,iproc-pcie" for PAXB, or "brcm,iproc-pcie-paxc"
|
||||
for PAXC. PAXB-based root complex is used for external endpoint devices.
|
||||
PAXC-based root complex is connected to emulated endpoint devices
|
||||
internal to the ASIC
|
||||
- compatible:
|
||||
"brcm,iproc-pcie" for the first generation of PAXB based controller,
|
||||
used in SoCs including NSP, Cygnus, NS2, and Pegasus
|
||||
"brcm,iproc-pcie-paxb-v2" for the second generation of PAXB-based
|
||||
controllers, used in Stingray
|
||||
"brcm,iproc-pcie-paxc" for the first generation of PAXC based
|
||||
controller, used in NS2
|
||||
"brcm,iproc-pcie-paxc-v2" for the second generation of PAXC based
|
||||
controller, used in Stingray
|
||||
PAXB-based root complex is used for external endpoint devices. PAXC-based
|
||||
root complex is connected to emulated endpoint devices internal to the ASIC
|
||||
- reg: base address and length of the PCIe controller I/O register space
|
||||
- #interrupt-cells: set to <1>
|
||||
- interrupt-map-mask and interrupt-map, standard PCI properties to define the
|
||||
@@ -19,6 +26,10 @@ Required properties:
|
||||
Optional properties:
|
||||
- phys: phandle of the PCIe PHY device
|
||||
- phy-names: must be "pcie-phy"
|
||||
- dma-coherent: present if DMA operations are coherent
|
||||
- dma-ranges: Some PAXB-based root complexes do not have inbound mapping done
|
||||
by the ASIC after power on reset. In this case, SW is required to configure
|
||||
the mapping, based on inbound memory regions specified by this property.
|
||||
|
||||
- brcm,pcie-ob: Some iProc SoCs do not have the outbound address mapping done
|
||||
by the ASIC after power on reset. In this case, SW needs to configure it
|
||||
@@ -29,11 +40,6 @@ effective:
|
||||
Required:
|
||||
- brcm,pcie-ob-axi-offset: The offset from the AXI address to the internal
|
||||
address used by the iProc PCIe core (not the PCIe address)
|
||||
- brcm,pcie-ob-window-size: The outbound address mapping window size (in MB)
|
||||
|
||||
Optional:
|
||||
- brcm,pcie-ob-oarr-size: Some iProc SoCs need the OARR size bit to be set to
|
||||
increase the outbound window size
|
||||
|
||||
MSI support (optional):
|
||||
|
||||
@@ -41,10 +47,19 @@ For older platforms without MSI integrated in the GIC, iProc PCIe core provides
|
||||
an event queue based MSI support. The iProc MSI uses host memories to store
|
||||
MSI posted writes in the event queues
|
||||
|
||||
- msi-parent: Link to the device node of the MSI controller. On newer iProc
|
||||
platforms, the MSI controller may be gicv2m or gicv3-its. On older iProc
|
||||
platforms without MSI support in its interrupt controller, one may use the
|
||||
event queue based MSI support integrated within the iProc PCIe core.
|
||||
On newer iProc platforms, gicv2m or gicv3-its based MSI support should be used
|
||||
|
||||
- msi-map: Maps a Requester ID to an MSI controller and associated MSI
|
||||
sideband data
|
||||
|
||||
- msi-parent: Link to the device node of the MSI controller, used when no MSI
|
||||
sideband data is passed between the iProc PCIe controller and the MSI
|
||||
controller
|
||||
|
||||
Refer to the following binding documents for more detailed description on
|
||||
the use of 'msi-map' and 'msi-parent':
|
||||
Documentation/devicetree/bindings/pci/pci-msi.txt
|
||||
Documentation/devicetree/bindings/interrupt-controller/msi.txt
|
||||
|
||||
When the iProc event queue based MSI is used, one needs to define the
|
||||
following properties in the MSI device node:
|
||||
@@ -80,9 +95,7 @@ Example:
|
||||
phy-names = "pcie-phy";
|
||||
|
||||
brcm,pcie-ob;
|
||||
brcm,pcie-ob-oarr-size;
|
||||
brcm,pcie-ob-axi-offset = <0x00000000>;
|
||||
brcm,pcie-ob-window-size = <256>;
|
||||
|
||||
msi-parent = <&msi0>;
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ Required properties:
|
||||
- compatible: should contain the platform identifier such as:
|
||||
"fsl,ls1021a-pcie", "snps,dw-pcie"
|
||||
"fsl,ls2080a-pcie", "fsl,ls2085a-pcie", "snps,dw-pcie"
|
||||
"fsl,ls1046a-pcie"
|
||||
- reg: base addresses and lengths of the PCIe controller
|
||||
- interrupts: A list of interrupt outputs of the controller. Must contain an
|
||||
entry for each entry in the interrupt-names property.
|
||||
|
||||
@@ -110,6 +110,20 @@ Power supplies for Tegra124:
|
||||
- avdd-pll-erefe-supply: Power supply for PLLE (shared with USB3). Must
|
||||
supply 1.05 V.
|
||||
|
||||
Power supplies for Tegra210:
|
||||
- Required:
|
||||
- avdd-pll-uerefe-supply: Power supply for PLLE (shared with USB3). Must
|
||||
supply 1.05 V.
|
||||
- hvddio-pex-supply: High-voltage supply for PCIe I/O and PCIe output
|
||||
clocks. Must supply 1.8 V.
|
||||
- dvddio-pex-supply: Power supply for digital PCIe I/O. Must supply 1.05 V.
|
||||
- dvdd-pex-pll-supply: Power supply for dedicated (internal) PCIe PLL. Must
|
||||
supply 1.05 V.
|
||||
- hvdd-pex-pll-e-supply: High-voltage supply for PLLE (shared with USB3).
|
||||
Must supply 3.3 V.
|
||||
- vddio-pex-ctl-supply: Power supply for PCIe control I/O partition. Must
|
||||
supply 1.8 V.
|
||||
|
||||
Root ports are defined as subnodes of the PCIe controller node.
|
||||
|
||||
Required properties:
|
||||
@@ -436,3 +450,99 @@ Board DTS:
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
|
||||
Tegra210:
|
||||
---------
|
||||
|
||||
SoC DTSI:
|
||||
|
||||
pcie-controller@01003000 {
|
||||
compatible = "nvidia,tegra210-pcie";
|
||||
device_type = "pci";
|
||||
reg = <0x0 0x01003000 0x0 0x00000800 /* PADS registers */
|
||||
0x0 0x01003800 0x0 0x00000800 /* AFI registers */
|
||||
0x0 0x02000000 0x0 0x10000000>; /* configuration space */
|
||||
reg-names = "pads", "afi", "cs";
|
||||
interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>, /* controller interrupt */
|
||||
<GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>; /* MSI interrupt */
|
||||
interrupt-names = "intr", "msi";
|
||||
|
||||
#interrupt-cells = <1>;
|
||||
interrupt-map-mask = <0 0 0 0>;
|
||||
interrupt-map = <0 0 0 0 &gic GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
|
||||
|
||||
bus-range = <0x00 0xff>;
|
||||
#address-cells = <3>;
|
||||
#size-cells = <2>;
|
||||
|
||||
ranges = <0x82000000 0 0x01000000 0x0 0x01000000 0 0x00001000 /* port 0 configuration space */
|
||||
0x82000000 0 0x01001000 0x0 0x01001000 0 0x00001000 /* port 1 configuration space */
|
||||
0x81000000 0 0x0 0x0 0x12000000 0 0x00010000 /* downstream I/O (64 KiB) */
|
||||
0x82000000 0 0x13000000 0x0 0x13000000 0 0x0d000000 /* non-prefetchable memory (208 MiB) */
|
||||
0xc2000000 0 0x20000000 0x0 0x20000000 0 0x20000000>; /* prefetchable memory (512 MiB) */
|
||||
|
||||
clocks = <&tegra_car TEGRA210_CLK_PCIE>,
|
||||
<&tegra_car TEGRA210_CLK_AFI>,
|
||||
<&tegra_car TEGRA210_CLK_PLL_E>,
|
||||
<&tegra_car TEGRA210_CLK_CML0>;
|
||||
clock-names = "pex", "afi", "pll_e", "cml";
|
||||
resets = <&tegra_car 70>,
|
||||
<&tegra_car 72>,
|
||||
<&tegra_car 74>;
|
||||
reset-names = "pex", "afi", "pcie_x";
|
||||
status = "disabled";
|
||||
|
||||
pci@1,0 {
|
||||
device_type = "pci";
|
||||
assigned-addresses = <0x82000800 0 0x01000000 0 0x1000>;
|
||||
reg = <0x000800 0 0 0 0>;
|
||||
status = "disabled";
|
||||
|
||||
#address-cells = <3>;
|
||||
#size-cells = <2>;
|
||||
ranges;
|
||||
|
||||
nvidia,num-lanes = <4>;
|
||||
};
|
||||
|
||||
pci@2,0 {
|
||||
device_type = "pci";
|
||||
assigned-addresses = <0x82001000 0 0x01001000 0 0x1000>;
|
||||
reg = <0x001000 0 0 0 0>;
|
||||
status = "disabled";
|
||||
|
||||
#address-cells = <3>;
|
||||
#size-cells = <2>;
|
||||
ranges;
|
||||
|
||||
nvidia,num-lanes = <1>;
|
||||
};
|
||||
};
|
||||
|
||||
Board DTS:
|
||||
|
||||
pcie-controller@01003000 {
|
||||
status = "okay";
|
||||
|
||||
avdd-pll-uerefe-supply = <&avdd_1v05_pll>;
|
||||
hvddio-pex-supply = <&vdd_1v8>;
|
||||
dvddio-pex-supply = <&vdd_pex_1v05>;
|
||||
dvdd-pex-pll-supply = <&vdd_pex_1v05>;
|
||||
hvdd-pex-pll-e-supply = <&vdd_1v8>;
|
||||
vddio-pex-ctl-supply = <&vdd_1v8>;
|
||||
|
||||
pci@1,0 {
|
||||
phys = <&{/padctl@7009f000/pads/pcie/lanes/pcie-0}>,
|
||||
<&{/padctl@7009f000/pads/pcie/lanes/pcie-1}>,
|
||||
<&{/padctl@7009f000/pads/pcie/lanes/pcie-2}>,
|
||||
<&{/padctl@7009f000/pads/pcie/lanes/pcie-3}>;
|
||||
phy-names = "pcie-0", "pcie-1", "pcie-2", "pcie-3";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
pci@2,0 {
|
||||
phys = <&{/padctl@7009f000/pads/pcie/lanes/pcie-4}>;
|
||||
phy-names = "pcie-0";
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
|
||||
@@ -18,3 +18,9 @@ driver implementation may support the following properties:
|
||||
host bridges in the system, otherwise potentially conflicting domain numbers
|
||||
may be assigned to root buses behind different host bridges. The domain
|
||||
number for each host bridge in the system must be unique.
|
||||
- max-link-speed:
|
||||
If present this property specifies PCI gen for link capability. Host
|
||||
drivers could add this as a strategy to avoid unnecessary operation for
|
||||
unsupported link speed, for instance, trying to do training for
|
||||
unsupported link speed, etc. Must be '4' for gen4, '3' for gen3, '2'
|
||||
for gen2, and '1' for gen1. Any other values are invalid.
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
- "qcom,pcie-ipq8064" for ipq8064
|
||||
- "qcom,pcie-apq8064" for apq8064
|
||||
- "qcom,pcie-apq8084" for apq8084
|
||||
- "qcom,pcie-msm8996" for msm8996 or apq8096
|
||||
|
||||
- reg:
|
||||
Usage: required
|
||||
@@ -92,6 +93,17 @@
|
||||
- "aux" Auxiliary (AUX) clock
|
||||
- "bus_master" Master AXI clock
|
||||
- "bus_slave" Slave AXI clock
|
||||
|
||||
- clock-names:
|
||||
Usage: required for msm8996/apq8096
|
||||
Value type: <stringlist>
|
||||
Definition: Should contain the following entries
|
||||
- "pipe" Pipe Clock driving internal logic
|
||||
- "aux" Auxiliary (AUX) clock
|
||||
- "cfg" Configuration clock
|
||||
- "bus_master" Master AXI clock
|
||||
- "bus_slave" Slave AXI clock
|
||||
|
||||
- resets:
|
||||
Usage: required
|
||||
Value type: <prop-encoded-array>
|
||||
@@ -115,7 +127,7 @@
|
||||
- "core" Core reset
|
||||
|
||||
- power-domains:
|
||||
Usage: required for apq8084
|
||||
Usage: required for apq8084 and msm8996/apq8096
|
||||
Value type: <prop-encoded-array>
|
||||
Definition: A phandle and power domain specifier pair to the
|
||||
power domain which is responsible for collapsing
|
||||
|
||||
@@ -7,6 +7,7 @@ compatible: "renesas,pcie-r8a7779" for the R8A7779 SoC;
|
||||
"renesas,pcie-r8a7793" for the R8A7793 SoC;
|
||||
"renesas,pcie-r8a7795" for the R8A7795 SoC;
|
||||
"renesas,pcie-rcar-gen2" for a generic R-Car Gen2 compatible device.
|
||||
"renesas,pcie-rcar-gen3" for a generic R-Car Gen3 compatible device.
|
||||
|
||||
When compatible with the generic version, nodes must list the
|
||||
SoC-specific version corresponding to the platform first
|
||||
|
||||
@@ -17,6 +17,7 @@ that support it. For example, a given bus might look like this:
|
||||
| |-- resource0
|
||||
| |-- resource1
|
||||
| |-- resource2
|
||||
| |-- revision
|
||||
| |-- rom
|
||||
| |-- subsystem_device
|
||||
| |-- subsystem_vendor
|
||||
@@ -41,6 +42,7 @@ files, each with their own function.
|
||||
resource PCI resource host addresses (ascii, ro)
|
||||
resource0..N PCI resource N, if present (binary, mmap, rw[1])
|
||||
resource0_wc..N_wc PCI WC map resource N, if prefetchable (binary, mmap)
|
||||
revision PCI revision (ascii, ro)
|
||||
rom PCI ROM resource, if present (binary, ro)
|
||||
subsystem_device PCI subsystem device (ascii, ro)
|
||||
subsystem_vendor PCI subsystem vendor (ascii, ro)
|
||||
|
||||
@@ -7,6 +7,32 @@
|
||||
model = "NVIDIA Jetson TX1 Developer Kit";
|
||||
compatible = "nvidia,p2371-2180", "nvidia,tegra210";
|
||||
|
||||
pcie-controller@01003000 {
|
||||
status = "okay";
|
||||
|
||||
avdd-pll-uerefe-supply = <&avdd_1v05_pll>;
|
||||
hvddio-pex-supply = <&vdd_1v8>;
|
||||
dvddio-pex-supply = <&vdd_pex_1v05>;
|
||||
dvdd-pex-pll-supply = <&vdd_pex_1v05>;
|
||||
hvdd-pex-pll-e-supply = <&vdd_1v8>;
|
||||
vddio-pex-ctl-supply = <&vdd_1v8>;
|
||||
|
||||
pci@1,0 {
|
||||
phys = <&{/padctl@7009f000/pads/pcie/lanes/pcie-0}>,
|
||||
<&{/padctl@7009f000/pads/pcie/lanes/pcie-1}>,
|
||||
<&{/padctl@7009f000/pads/pcie/lanes/pcie-2}>,
|
||||
<&{/padctl@7009f000/pads/pcie/lanes/pcie-3}>;
|
||||
phy-names = "pcie-0", "pcie-1", "pcie-2", "pcie-3";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
pci@2,0 {
|
||||
phys = <&{/padctl@7009f000/pads/pcie/lanes/pcie-4}>;
|
||||
phy-names = "pcie-0";
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
|
||||
host1x@50000000 {
|
||||
dsi@54300000 {
|
||||
status = "okay";
|
||||
|
||||
@@ -11,6 +11,69 @@
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
|
||||
pcie-controller@01003000 {
|
||||
compatible = "nvidia,tegra210-pcie";
|
||||
device_type = "pci";
|
||||
reg = <0x0 0x01003000 0x0 0x00000800 /* PADS registers */
|
||||
0x0 0x01003800 0x0 0x00000800 /* AFI registers */
|
||||
0x0 0x02000000 0x0 0x10000000>; /* configuration space */
|
||||
reg-names = "pads", "afi", "cs";
|
||||
interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>, /* controller interrupt */
|
||||
<GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>; /* MSI interrupt */
|
||||
interrupt-names = "intr", "msi";
|
||||
|
||||
#interrupt-cells = <1>;
|
||||
interrupt-map-mask = <0 0 0 0>;
|
||||
interrupt-map = <0 0 0 0 &gic GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
|
||||
|
||||
bus-range = <0x00 0xff>;
|
||||
#address-cells = <3>;
|
||||
#size-cells = <2>;
|
||||
|
||||
ranges = <0x82000000 0 0x01000000 0x0 0x01000000 0 0x00001000 /* port 0 configuration space */
|
||||
0x82000000 0 0x01001000 0x0 0x01001000 0 0x00001000 /* port 1 configuration space */
|
||||
0x81000000 0 0x0 0x0 0x12000000 0 0x00010000 /* downstream I/O (64 KiB) */
|
||||
0x82000000 0 0x13000000 0x0 0x13000000 0 0x0d000000 /* non-prefetchable memory (208 MiB) */
|
||||
0xc2000000 0 0x20000000 0x0 0x20000000 0 0x20000000>; /* prefetchable memory (512 MiB) */
|
||||
|
||||
clocks = <&tegra_car TEGRA210_CLK_PCIE>,
|
||||
<&tegra_car TEGRA210_CLK_AFI>,
|
||||
<&tegra_car TEGRA210_CLK_PLL_E>,
|
||||
<&tegra_car TEGRA210_CLK_CML0>;
|
||||
clock-names = "pex", "afi", "pll_e", "cml";
|
||||
resets = <&tegra_car 70>,
|
||||
<&tegra_car 72>,
|
||||
<&tegra_car 74>;
|
||||
reset-names = "pex", "afi", "pcie_x";
|
||||
status = "disabled";
|
||||
|
||||
pci@1,0 {
|
||||
device_type = "pci";
|
||||
assigned-addresses = <0x82000800 0 0x01000000 0 0x1000>;
|
||||
reg = <0x000800 0 0 0 0>;
|
||||
status = "disabled";
|
||||
|
||||
#address-cells = <3>;
|
||||
#size-cells = <2>;
|
||||
ranges;
|
||||
|
||||
nvidia,num-lanes = <4>;
|
||||
};
|
||||
|
||||
pci@2,0 {
|
||||
device_type = "pci";
|
||||
assigned-addresses = <0x82001000 0 0x01001000 0 0x1000>;
|
||||
reg = <0x001000 0 0 0 0>;
|
||||
status = "disabled";
|
||||
|
||||
#address-cells = <3>;
|
||||
#size-cells = <2>;
|
||||
ranges;
|
||||
|
||||
nvidia,num-lanes = <1>;
|
||||
};
|
||||
};
|
||||
|
||||
host1x@50000000 {
|
||||
compatible = "nvidia,tegra210-host1x", "simple-bus";
|
||||
reg = <0x0 0x50000000 0x0 0x00034000>;
|
||||
|
||||
+43
-24
@@ -114,6 +114,19 @@ int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pci_acpi_root_prepare_resources(struct acpi_pci_root_info *ci)
|
||||
{
|
||||
struct resource_entry *entry, *tmp;
|
||||
int status;
|
||||
|
||||
status = acpi_pci_probe_root_resources(ci);
|
||||
resource_list_for_each_entry_safe(entry, tmp, &ci->resources) {
|
||||
if (!(entry->res->flags & IORESOURCE_WINDOW))
|
||||
resource_list_destroy_entry(entry);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* Lookup the bus range for the domain in MCFG, and set up config space
|
||||
* mapping.
|
||||
@@ -121,31 +134,33 @@ int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge)
|
||||
static struct pci_config_window *
|
||||
pci_acpi_setup_ecam_mapping(struct acpi_pci_root *root)
|
||||
{
|
||||
struct device *dev = &root->device->dev;
|
||||
struct resource *bus_res = &root->secondary;
|
||||
u16 seg = root->segment;
|
||||
struct pci_config_window *cfg;
|
||||
struct pci_ecam_ops *ecam_ops;
|
||||
struct resource cfgres;
|
||||
unsigned int bsz;
|
||||
struct acpi_device *adev;
|
||||
struct pci_config_window *cfg;
|
||||
int ret;
|
||||
|
||||
/* Use address from _CBA if present, otherwise lookup MCFG */
|
||||
if (!root->mcfg_addr)
|
||||
root->mcfg_addr = pci_mcfg_lookup(seg, bus_res);
|
||||
|
||||
if (!root->mcfg_addr) {
|
||||
dev_err(&root->device->dev, "%04x:%pR ECAM region not found\n",
|
||||
seg, bus_res);
|
||||
ret = pci_mcfg_lookup(root, &cfgres, &ecam_ops);
|
||||
if (ret) {
|
||||
dev_err(dev, "%04x:%pR ECAM region not found\n", seg, bus_res);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bsz = 1 << pci_generic_ecam_ops.bus_shift;
|
||||
cfgres.start = root->mcfg_addr + bus_res->start * bsz;
|
||||
cfgres.end = cfgres.start + resource_size(bus_res) * bsz - 1;
|
||||
cfgres.flags = IORESOURCE_MEM;
|
||||
cfg = pci_ecam_create(&root->device->dev, &cfgres, bus_res,
|
||||
&pci_generic_ecam_ops);
|
||||
adev = acpi_resource_consumer(&cfgres);
|
||||
if (adev)
|
||||
dev_info(dev, "ECAM area %pR reserved by %s\n", &cfgres,
|
||||
dev_name(&adev->dev));
|
||||
else
|
||||
dev_warn(dev, FW_BUG "ECAM area %pR not reserved in ACPI namespace\n",
|
||||
&cfgres);
|
||||
|
||||
cfg = pci_ecam_create(dev, &cfgres, bus_res, ecam_ops);
|
||||
if (IS_ERR(cfg)) {
|
||||
dev_err(&root->device->dev, "%04x:%pR error %ld mapping ECAM\n",
|
||||
seg, bus_res, PTR_ERR(cfg));
|
||||
dev_err(dev, "%04x:%pR error %ld mapping ECAM\n", seg, bus_res,
|
||||
PTR_ERR(cfg));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -159,33 +174,37 @@ static void pci_acpi_generic_release_info(struct acpi_pci_root_info *ci)
|
||||
|
||||
ri = container_of(ci, struct acpi_pci_generic_root_info, common);
|
||||
pci_ecam_free(ri->cfg);
|
||||
kfree(ci->ops);
|
||||
kfree(ri);
|
||||
}
|
||||
|
||||
static struct acpi_pci_root_ops acpi_pci_root_ops = {
|
||||
.release_info = pci_acpi_generic_release_info,
|
||||
};
|
||||
|
||||
/* Interface called from ACPI code to setup PCI host controller */
|
||||
struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
|
||||
{
|
||||
int node = acpi_get_node(root->device->handle);
|
||||
struct acpi_pci_generic_root_info *ri;
|
||||
struct pci_bus *bus, *child;
|
||||
struct acpi_pci_root_ops *root_ops;
|
||||
|
||||
ri = kzalloc_node(sizeof(*ri), GFP_KERNEL, node);
|
||||
if (!ri)
|
||||
return NULL;
|
||||
|
||||
root_ops = kzalloc_node(sizeof(*root_ops), GFP_KERNEL, node);
|
||||
if (!root_ops)
|
||||
return NULL;
|
||||
|
||||
ri->cfg = pci_acpi_setup_ecam_mapping(root);
|
||||
if (!ri->cfg) {
|
||||
kfree(ri);
|
||||
kfree(root_ops);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
acpi_pci_root_ops.pci_ops = &ri->cfg->ops->pci_ops;
|
||||
bus = acpi_pci_root_create(root, &acpi_pci_root_ops, &ri->common,
|
||||
ri->cfg);
|
||||
root_ops->release_info = pci_acpi_generic_release_info;
|
||||
root_ops->prepare_resources = pci_acpi_root_prepare_resources;
|
||||
root_ops->pci_ops = &ri->cfg->ops->pci_ops;
|
||||
bus = acpi_pci_root_create(root, root_ops, &ri->common, ri->cfg);
|
||||
if (!bus)
|
||||
return NULL;
|
||||
|
||||
|
||||
+187
-3
@@ -22,6 +22,7 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/pci-acpi.h>
|
||||
#include <linux/pci-ecam.h>
|
||||
|
||||
/* Structure to hold entries from the MCFG table */
|
||||
struct mcfg_entry {
|
||||
@@ -32,12 +33,166 @@ struct mcfg_entry {
|
||||
u8 bus_end;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_PCI_QUIRKS
|
||||
struct mcfg_fixup {
|
||||
char oem_id[ACPI_OEM_ID_SIZE + 1];
|
||||
char oem_table_id[ACPI_OEM_TABLE_ID_SIZE + 1];
|
||||
u32 oem_revision;
|
||||
u16 segment;
|
||||
struct resource bus_range;
|
||||
struct pci_ecam_ops *ops;
|
||||
struct resource cfgres;
|
||||
};
|
||||
|
||||
#define MCFG_BUS_RANGE(start, end) DEFINE_RES_NAMED((start), \
|
||||
((end) - (start) + 1), \
|
||||
NULL, IORESOURCE_BUS)
|
||||
#define MCFG_BUS_ANY MCFG_BUS_RANGE(0x0, 0xff)
|
||||
|
||||
static struct mcfg_fixup mcfg_quirks[] = {
|
||||
/* { OEM_ID, OEM_TABLE_ID, REV, SEGMENT, BUS_RANGE, ops, cfgres }, */
|
||||
|
||||
#define QCOM_ECAM32(seg) \
|
||||
{ "QCOM ", "QDF2432 ", 1, seg, MCFG_BUS_ANY, &pci_32b_ops }
|
||||
QCOM_ECAM32(0),
|
||||
QCOM_ECAM32(1),
|
||||
QCOM_ECAM32(2),
|
||||
QCOM_ECAM32(3),
|
||||
QCOM_ECAM32(4),
|
||||
QCOM_ECAM32(5),
|
||||
QCOM_ECAM32(6),
|
||||
QCOM_ECAM32(7),
|
||||
|
||||
#define HISI_QUAD_DOM(table_id, seg, ops) \
|
||||
{ "HISI ", table_id, 0, (seg) + 0, MCFG_BUS_ANY, ops }, \
|
||||
{ "HISI ", table_id, 0, (seg) + 1, MCFG_BUS_ANY, ops }, \
|
||||
{ "HISI ", table_id, 0, (seg) + 2, MCFG_BUS_ANY, ops }, \
|
||||
{ "HISI ", table_id, 0, (seg) + 3, MCFG_BUS_ANY, ops }
|
||||
HISI_QUAD_DOM("HIP05 ", 0, &hisi_pcie_ops),
|
||||
HISI_QUAD_DOM("HIP06 ", 0, &hisi_pcie_ops),
|
||||
HISI_QUAD_DOM("HIP07 ", 0, &hisi_pcie_ops),
|
||||
HISI_QUAD_DOM("HIP07 ", 4, &hisi_pcie_ops),
|
||||
HISI_QUAD_DOM("HIP07 ", 8, &hisi_pcie_ops),
|
||||
HISI_QUAD_DOM("HIP07 ", 12, &hisi_pcie_ops),
|
||||
|
||||
#define THUNDER_PEM_RES(addr, node) \
|
||||
DEFINE_RES_MEM((addr) + ((u64) (node) << 44), 0x39 * SZ_16M)
|
||||
#define THUNDER_PEM_QUIRK(rev, node) \
|
||||
{ "CAVIUM", "THUNDERX", rev, 4 + (10 * (node)), MCFG_BUS_ANY, \
|
||||
&thunder_pem_ecam_ops, THUNDER_PEM_RES(0x88001f000000UL, node) }, \
|
||||
{ "CAVIUM", "THUNDERX", rev, 5 + (10 * (node)), MCFG_BUS_ANY, \
|
||||
&thunder_pem_ecam_ops, THUNDER_PEM_RES(0x884057000000UL, node) }, \
|
||||
{ "CAVIUM", "THUNDERX", rev, 6 + (10 * (node)), MCFG_BUS_ANY, \
|
||||
&thunder_pem_ecam_ops, THUNDER_PEM_RES(0x88808f000000UL, node) }, \
|
||||
{ "CAVIUM", "THUNDERX", rev, 7 + (10 * (node)), MCFG_BUS_ANY, \
|
||||
&thunder_pem_ecam_ops, THUNDER_PEM_RES(0x89001f000000UL, node) }, \
|
||||
{ "CAVIUM", "THUNDERX", rev, 8 + (10 * (node)), MCFG_BUS_ANY, \
|
||||
&thunder_pem_ecam_ops, THUNDER_PEM_RES(0x894057000000UL, node) }, \
|
||||
{ "CAVIUM", "THUNDERX", rev, 9 + (10 * (node)), MCFG_BUS_ANY, \
|
||||
&thunder_pem_ecam_ops, THUNDER_PEM_RES(0x89808f000000UL, node) }
|
||||
/* SoC pass2.x */
|
||||
THUNDER_PEM_QUIRK(1, 0),
|
||||
THUNDER_PEM_QUIRK(1, 1),
|
||||
|
||||
#define THUNDER_ECAM_QUIRK(rev, seg) \
|
||||
{ "CAVIUM", "THUNDERX", rev, seg, MCFG_BUS_ANY, \
|
||||
&pci_thunder_ecam_ops }
|
||||
/* SoC pass1.x */
|
||||
THUNDER_PEM_QUIRK(2, 0), /* off-chip devices */
|
||||
THUNDER_PEM_QUIRK(2, 1), /* off-chip devices */
|
||||
THUNDER_ECAM_QUIRK(2, 0),
|
||||
THUNDER_ECAM_QUIRK(2, 1),
|
||||
THUNDER_ECAM_QUIRK(2, 2),
|
||||
THUNDER_ECAM_QUIRK(2, 3),
|
||||
THUNDER_ECAM_QUIRK(2, 10),
|
||||
THUNDER_ECAM_QUIRK(2, 11),
|
||||
THUNDER_ECAM_QUIRK(2, 12),
|
||||
THUNDER_ECAM_QUIRK(2, 13),
|
||||
|
||||
#define XGENE_V1_ECAM_MCFG(rev, seg) \
|
||||
{"APM ", "XGENE ", rev, seg, MCFG_BUS_ANY, \
|
||||
&xgene_v1_pcie_ecam_ops }
|
||||
#define XGENE_V2_ECAM_MCFG(rev, seg) \
|
||||
{"APM ", "XGENE ", rev, seg, MCFG_BUS_ANY, \
|
||||
&xgene_v2_pcie_ecam_ops }
|
||||
/* X-Gene SoC with v1 PCIe controller */
|
||||
XGENE_V1_ECAM_MCFG(1, 0),
|
||||
XGENE_V1_ECAM_MCFG(1, 1),
|
||||
XGENE_V1_ECAM_MCFG(1, 2),
|
||||
XGENE_V1_ECAM_MCFG(1, 3),
|
||||
XGENE_V1_ECAM_MCFG(1, 4),
|
||||
XGENE_V1_ECAM_MCFG(2, 0),
|
||||
XGENE_V1_ECAM_MCFG(2, 1),
|
||||
XGENE_V1_ECAM_MCFG(2, 2),
|
||||
XGENE_V1_ECAM_MCFG(2, 3),
|
||||
XGENE_V1_ECAM_MCFG(2, 4),
|
||||
/* X-Gene SoC with v2.1 PCIe controller */
|
||||
XGENE_V2_ECAM_MCFG(3, 0),
|
||||
XGENE_V2_ECAM_MCFG(3, 1),
|
||||
/* X-Gene SoC with v2.2 PCIe controller */
|
||||
XGENE_V2_ECAM_MCFG(4, 0),
|
||||
XGENE_V2_ECAM_MCFG(4, 1),
|
||||
XGENE_V2_ECAM_MCFG(4, 2),
|
||||
};
|
||||
|
||||
static char mcfg_oem_id[ACPI_OEM_ID_SIZE];
|
||||
static char mcfg_oem_table_id[ACPI_OEM_TABLE_ID_SIZE];
|
||||
static u32 mcfg_oem_revision;
|
||||
|
||||
static int pci_mcfg_quirk_matches(struct mcfg_fixup *f, u16 segment,
|
||||
struct resource *bus_range)
|
||||
{
|
||||
if (!memcmp(f->oem_id, mcfg_oem_id, ACPI_OEM_ID_SIZE) &&
|
||||
!memcmp(f->oem_table_id, mcfg_oem_table_id,
|
||||
ACPI_OEM_TABLE_ID_SIZE) &&
|
||||
f->oem_revision == mcfg_oem_revision &&
|
||||
f->segment == segment &&
|
||||
resource_contains(&f->bus_range, bus_range))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void pci_mcfg_apply_quirks(struct acpi_pci_root *root,
|
||||
struct resource *cfgres,
|
||||
struct pci_ecam_ops **ecam_ops)
|
||||
{
|
||||
#ifdef CONFIG_PCI_QUIRKS
|
||||
u16 segment = root->segment;
|
||||
struct resource *bus_range = &root->secondary;
|
||||
struct mcfg_fixup *f;
|
||||
int i;
|
||||
|
||||
for (i = 0, f = mcfg_quirks; i < ARRAY_SIZE(mcfg_quirks); i++, f++) {
|
||||
if (pci_mcfg_quirk_matches(f, segment, bus_range)) {
|
||||
if (f->cfgres.start)
|
||||
*cfgres = f->cfgres;
|
||||
if (f->ops)
|
||||
*ecam_ops = f->ops;
|
||||
dev_info(&root->device->dev, "MCFG quirk: ECAM at %pR for %pR with %ps\n",
|
||||
cfgres, bus_range, *ecam_ops);
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* List to save MCFG entries */
|
||||
static LIST_HEAD(pci_mcfg_list);
|
||||
|
||||
phys_addr_t pci_mcfg_lookup(u16 seg, struct resource *bus_res)
|
||||
int pci_mcfg_lookup(struct acpi_pci_root *root, struct resource *cfgres,
|
||||
struct pci_ecam_ops **ecam_ops)
|
||||
{
|
||||
struct pci_ecam_ops *ops = &pci_generic_ecam_ops;
|
||||
struct resource *bus_res = &root->secondary;
|
||||
u16 seg = root->segment;
|
||||
struct mcfg_entry *e;
|
||||
struct resource res;
|
||||
|
||||
/* Use address from _CBA if present, otherwise lookup MCFG */
|
||||
if (root->mcfg_addr)
|
||||
goto skip_lookup;
|
||||
|
||||
/*
|
||||
* We expect exact match, unless MCFG entry end bus covers more than
|
||||
@@ -45,10 +200,32 @@ phys_addr_t pci_mcfg_lookup(u16 seg, struct resource *bus_res)
|
||||
*/
|
||||
list_for_each_entry(e, &pci_mcfg_list, list) {
|
||||
if (e->segment == seg && e->bus_start == bus_res->start &&
|
||||
e->bus_end >= bus_res->end)
|
||||
return e->addr;
|
||||
e->bus_end >= bus_res->end) {
|
||||
root->mcfg_addr = e->addr;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
skip_lookup:
|
||||
memset(&res, 0, sizeof(res));
|
||||
if (root->mcfg_addr) {
|
||||
res.start = root->mcfg_addr + (bus_res->start << 20);
|
||||
res.end = res.start + (resource_size(bus_res) << 20) - 1;
|
||||
res.flags = IORESOURCE_MEM;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allow quirks to override default ECAM ops and CFG resource
|
||||
* range. This may even fabricate a CFG resource range in case
|
||||
* MCFG does not have it. Invalid CFG start address means MCFG
|
||||
* firmware bug or we need another quirk in array.
|
||||
*/
|
||||
pci_mcfg_apply_quirks(root, &res, &ops);
|
||||
if (!res.start)
|
||||
return -ENXIO;
|
||||
|
||||
*cfgres = res;
|
||||
*ecam_ops = ops;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -79,6 +256,13 @@ static __init int pci_mcfg_parse(struct acpi_table_header *header)
|
||||
list_add(&e->list, &pci_mcfg_list);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PCI_QUIRKS
|
||||
/* Save MCFG IDs and revision for quirks matching */
|
||||
memcpy(mcfg_oem_id, header->oem_id, ACPI_OEM_ID_SIZE);
|
||||
memcpy(mcfg_oem_table_id, header->oem_table_id, ACPI_OEM_TABLE_ID_SIZE);
|
||||
mcfg_oem_revision = header->oem_revision;
|
||||
#endif
|
||||
|
||||
pr_info("MCFG table detected, %d entries\n", n);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -664,3 +664,60 @@ int acpi_dev_filter_resource_type(struct acpi_resource *ares,
|
||||
return (type & types) ? 0 : 1;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(acpi_dev_filter_resource_type);
|
||||
|
||||
static int acpi_dev_consumes_res(struct acpi_device *adev, struct resource *res)
|
||||
{
|
||||
struct list_head resource_list;
|
||||
struct resource_entry *rentry;
|
||||
int ret, found = 0;
|
||||
|
||||
INIT_LIST_HEAD(&resource_list);
|
||||
ret = acpi_dev_get_resources(adev, &resource_list, NULL, NULL);
|
||||
if (ret < 0)
|
||||
return 0;
|
||||
|
||||
list_for_each_entry(rentry, &resource_list, node) {
|
||||
if (resource_contains(rentry->res, res)) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
acpi_dev_free_resource_list(&resource_list);
|
||||
return found;
|
||||
}
|
||||
|
||||
static acpi_status acpi_res_consumer_cb(acpi_handle handle, u32 depth,
|
||||
void *context, void **ret)
|
||||
{
|
||||
struct resource *res = context;
|
||||
struct acpi_device **consumer = (struct acpi_device **) ret;
|
||||
struct acpi_device *adev;
|
||||
|
||||
if (acpi_bus_get_device(handle, &adev))
|
||||
return AE_OK;
|
||||
|
||||
if (acpi_dev_consumes_res(adev, res)) {
|
||||
*consumer = adev;
|
||||
return AE_CTRL_TERMINATE;
|
||||
}
|
||||
|
||||
return AE_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* acpi_resource_consumer - Find the ACPI device that consumes @res.
|
||||
* @res: Resource to search for.
|
||||
*
|
||||
* Search the current resource settings (_CRS) of every ACPI device node
|
||||
* for @res. If we find an ACPI device whose _CRS includes @res, return
|
||||
* it. Otherwise, return NULL.
|
||||
*/
|
||||
struct acpi_device *acpi_resource_consumer(struct resource *res)
|
||||
{
|
||||
struct acpi_device *consumer = NULL;
|
||||
|
||||
acpi_get_devices(NULL, acpi_res_consumer_cb, res, (void **) &consumer);
|
||||
return consumer;
|
||||
}
|
||||
|
||||
@@ -4020,49 +4020,51 @@ int mlx4_restart_one(struct pci_dev *pdev)
|
||||
return err;
|
||||
}
|
||||
|
||||
#define MLX_SP(id) { PCI_VDEVICE(MELLANOX, id), MLX4_PCI_DEV_FORCE_SENSE_PORT }
|
||||
#define MLX_VF(id) { PCI_VDEVICE(MELLANOX, id), MLX4_PCI_DEV_IS_VF }
|
||||
#define MLX_GN(id) { PCI_VDEVICE(MELLANOX, id), 0 }
|
||||
|
||||
static const struct pci_device_id mlx4_pci_table[] = {
|
||||
/* MT25408 "Hermon" SDR */
|
||||
{ PCI_VDEVICE(MELLANOX, 0x6340), MLX4_PCI_DEV_FORCE_SENSE_PORT },
|
||||
/* MT25408 "Hermon" DDR */
|
||||
{ PCI_VDEVICE(MELLANOX, 0x634a), MLX4_PCI_DEV_FORCE_SENSE_PORT },
|
||||
/* MT25408 "Hermon" QDR */
|
||||
{ PCI_VDEVICE(MELLANOX, 0x6354), MLX4_PCI_DEV_FORCE_SENSE_PORT },
|
||||
/* MT25408 "Hermon" DDR PCIe gen2 */
|
||||
{ PCI_VDEVICE(MELLANOX, 0x6732), MLX4_PCI_DEV_FORCE_SENSE_PORT },
|
||||
/* MT25408 "Hermon" QDR PCIe gen2 */
|
||||
{ PCI_VDEVICE(MELLANOX, 0x673c), MLX4_PCI_DEV_FORCE_SENSE_PORT },
|
||||
/* MT25408 "Hermon" EN 10GigE */
|
||||
{ PCI_VDEVICE(MELLANOX, 0x6368), MLX4_PCI_DEV_FORCE_SENSE_PORT },
|
||||
/* MT25408 "Hermon" EN 10GigE PCIe gen2 */
|
||||
{ PCI_VDEVICE(MELLANOX, 0x6750), MLX4_PCI_DEV_FORCE_SENSE_PORT },
|
||||
/* MT25458 ConnectX EN 10GBASE-T 10GigE */
|
||||
{ PCI_VDEVICE(MELLANOX, 0x6372), MLX4_PCI_DEV_FORCE_SENSE_PORT },
|
||||
/* MT25458 ConnectX EN 10GBASE-T+Gen2 10GigE */
|
||||
{ PCI_VDEVICE(MELLANOX, 0x675a), MLX4_PCI_DEV_FORCE_SENSE_PORT },
|
||||
/* MT26468 ConnectX EN 10GigE PCIe gen2*/
|
||||
{ PCI_VDEVICE(MELLANOX, 0x6764), MLX4_PCI_DEV_FORCE_SENSE_PORT },
|
||||
/* MT26438 ConnectX EN 40GigE PCIe gen2 5GT/s */
|
||||
{ PCI_VDEVICE(MELLANOX, 0x6746), MLX4_PCI_DEV_FORCE_SENSE_PORT },
|
||||
/* MT26478 ConnectX2 40GigE PCIe gen2 */
|
||||
{ PCI_VDEVICE(MELLANOX, 0x676e), MLX4_PCI_DEV_FORCE_SENSE_PORT },
|
||||
/* MT25400 Family [ConnectX-2 Virtual Function] */
|
||||
{ PCI_VDEVICE(MELLANOX, 0x1002), MLX4_PCI_DEV_IS_VF },
|
||||
/* MT25408 "Hermon" */
|
||||
MLX_SP(PCI_DEVICE_ID_MELLANOX_HERMON_SDR), /* SDR */
|
||||
MLX_SP(PCI_DEVICE_ID_MELLANOX_HERMON_DDR), /* DDR */
|
||||
MLX_SP(PCI_DEVICE_ID_MELLANOX_HERMON_QDR), /* QDR */
|
||||
MLX_SP(PCI_DEVICE_ID_MELLANOX_HERMON_DDR_GEN2), /* DDR Gen2 */
|
||||
MLX_SP(PCI_DEVICE_ID_MELLANOX_HERMON_QDR_GEN2), /* QDR Gen2 */
|
||||
MLX_SP(PCI_DEVICE_ID_MELLANOX_HERMON_EN), /* EN 10GigE */
|
||||
MLX_SP(PCI_DEVICE_ID_MELLANOX_HERMON_EN_GEN2), /* EN 10GigE Gen2 */
|
||||
/* MT25458 ConnectX EN 10GBASE-T */
|
||||
MLX_SP(PCI_DEVICE_ID_MELLANOX_CONNECTX_EN),
|
||||
MLX_SP(PCI_DEVICE_ID_MELLANOX_CONNECTX_EN_T_GEN2), /* Gen2 */
|
||||
/* MT26468 ConnectX EN 10GigE PCIe Gen2*/
|
||||
MLX_SP(PCI_DEVICE_ID_MELLANOX_CONNECTX_EN_GEN2),
|
||||
/* MT26438 ConnectX EN 40GigE PCIe Gen2 5GT/s */
|
||||
MLX_SP(PCI_DEVICE_ID_MELLANOX_CONNECTX_EN_5_GEN2),
|
||||
/* MT26478 ConnectX2 40GigE PCIe Gen2 */
|
||||
MLX_SP(PCI_DEVICE_ID_MELLANOX_CONNECTX2),
|
||||
/* MT25400 Family [ConnectX-2] */
|
||||
MLX_VF(0x1002), /* Virtual Function */
|
||||
/* MT27500 Family [ConnectX-3] */
|
||||
{ PCI_VDEVICE(MELLANOX, 0x1003), 0 },
|
||||
/* MT27500 Family [ConnectX-3 Virtual Function] */
|
||||
{ PCI_VDEVICE(MELLANOX, 0x1004), MLX4_PCI_DEV_IS_VF },
|
||||
{ PCI_VDEVICE(MELLANOX, 0x1005), 0 }, /* MT27510 Family */
|
||||
{ PCI_VDEVICE(MELLANOX, 0x1006), 0 }, /* MT27511 Family */
|
||||
{ PCI_VDEVICE(MELLANOX, 0x1007), 0 }, /* MT27520 Family */
|
||||
{ PCI_VDEVICE(MELLANOX, 0x1008), 0 }, /* MT27521 Family */
|
||||
{ PCI_VDEVICE(MELLANOX, 0x1009), 0 }, /* MT27530 Family */
|
||||
{ PCI_VDEVICE(MELLANOX, 0x100a), 0 }, /* MT27531 Family */
|
||||
{ PCI_VDEVICE(MELLANOX, 0x100b), 0 }, /* MT27540 Family */
|
||||
{ PCI_VDEVICE(MELLANOX, 0x100c), 0 }, /* MT27541 Family */
|
||||
{ PCI_VDEVICE(MELLANOX, 0x100d), 0 }, /* MT27550 Family */
|
||||
{ PCI_VDEVICE(MELLANOX, 0x100e), 0 }, /* MT27551 Family */
|
||||
{ PCI_VDEVICE(MELLANOX, 0x100f), 0 }, /* MT27560 Family */
|
||||
{ PCI_VDEVICE(MELLANOX, 0x1010), 0 }, /* MT27561 Family */
|
||||
MLX_GN(PCI_DEVICE_ID_MELLANOX_CONNECTX3),
|
||||
MLX_VF(0x1004), /* Virtual Function */
|
||||
MLX_GN(0x1005), /* MT27510 Family */
|
||||
MLX_GN(0x1006), /* MT27511 Family */
|
||||
MLX_GN(PCI_DEVICE_ID_MELLANOX_CONNECTX3_PRO), /* MT27520 Family */
|
||||
MLX_GN(0x1008), /* MT27521 Family */
|
||||
MLX_GN(0x1009), /* MT27530 Family */
|
||||
MLX_GN(0x100a), /* MT27531 Family */
|
||||
MLX_GN(0x100b), /* MT27540 Family */
|
||||
MLX_GN(0x100c), /* MT27541 Family */
|
||||
MLX_GN(0x100d), /* MT27550 Family */
|
||||
MLX_GN(0x100e), /* MT27551 Family */
|
||||
MLX_GN(0x100f), /* MT27560 Family */
|
||||
MLX_GN(0x1010), /* MT27561 Family */
|
||||
|
||||
/*
|
||||
* See the mellanox_check_broken_intx_masking() quirk when
|
||||
* adding devices
|
||||
*/
|
||||
|
||||
{ 0, }
|
||||
};
|
||||
|
||||
|
||||
@@ -119,6 +119,27 @@ int of_get_pci_domain_nr(struct device_node *node)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(of_get_pci_domain_nr);
|
||||
|
||||
/**
|
||||
* This function will try to find the limitation of link speed by finding
|
||||
* a property called "max-link-speed" of the given device node.
|
||||
*
|
||||
* @node: device tree node with the max link speed information
|
||||
*
|
||||
* Returns the associated max link speed from DT, or a negative value if the
|
||||
* required property is not found or is invalid.
|
||||
*/
|
||||
int of_pci_get_max_link_speed(struct device_node *node)
|
||||
{
|
||||
u32 max_link_speed;
|
||||
|
||||
if (of_property_read_u32(node, "max-link-speed", &max_link_speed) ||
|
||||
max_link_speed > 4)
|
||||
return -EINVAL;
|
||||
|
||||
return max_link_speed;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(of_pci_get_max_link_speed);
|
||||
|
||||
/**
|
||||
* of_pci_check_probe_only - Setup probe only mode if linux,pci-probe-only
|
||||
* is present and valid
|
||||
|
||||
+14
-2
@@ -142,10 +142,22 @@ int pci_generic_config_write32(struct pci_bus *bus, unsigned int devfn,
|
||||
if (size == 4) {
|
||||
writel(val, addr);
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
} else {
|
||||
mask = ~(((1 << (size * 8)) - 1) << ((where & 0x3) * 8));
|
||||
}
|
||||
|
||||
/*
|
||||
* In general, hardware that supports only 32-bit writes on PCI is
|
||||
* not spec-compliant. For example, software may perform a 16-bit
|
||||
* write. If the hardware only supports 32-bit accesses, we must
|
||||
* do a 32-bit read, merge in the 16 bits we intend to write,
|
||||
* followed by a 32-bit write. If the 16 bits we *don't* intend to
|
||||
* write happen to have any RW1C (write-one-to-clear) bits set, we
|
||||
* just inadvertently cleared something we shouldn't have.
|
||||
*/
|
||||
dev_warn_ratelimited(&bus->dev, "%d-byte config write to %04x:%02x:%02x.%d offset %#x may corrupt adjacent RW1C bits\n",
|
||||
size, pci_domain_nr(bus), bus->number,
|
||||
PCI_SLOT(devfn), PCI_FUNC(devfn), where);
|
||||
|
||||
mask = ~(((1 << (size * 8)) - 1) << ((where & 0x3) * 8));
|
||||
tmp = readl(addr) & mask;
|
||||
tmp |= val << ((where & 0x3) * 8);
|
||||
writel(tmp, addr);
|
||||
|
||||
+1
-1
@@ -320,7 +320,7 @@ void pci_bus_add_device(struct pci_dev *dev)
|
||||
pci_fixup_device(pci_fixup_final, dev);
|
||||
pci_create_sysfs_dev_files(dev);
|
||||
pci_proc_attach_device(dev);
|
||||
pci_bridge_d3_device_changed(dev);
|
||||
pci_bridge_d3_update(dev);
|
||||
|
||||
dev->match_driver = true;
|
||||
retval = device_attach(&dev->dev);
|
||||
|
||||
@@ -162,3 +162,15 @@ struct pci_ecam_ops pci_generic_ecam_ops = {
|
||||
.write = pci_generic_config_write,
|
||||
}
|
||||
};
|
||||
|
||||
#if defined(CONFIG_ACPI) && defined(CONFIG_PCI_QUIRKS)
|
||||
/* ECAM ops for 32-bit access only (non-compliant) */
|
||||
struct pci_ecam_ops pci_32b_ops = {
|
||||
.bus_shift = 20,
|
||||
.pci_ops = {
|
||||
.map_bus = pci_ecam_map_bus,
|
||||
.read = pci_generic_config_read32,
|
||||
.write = pci_generic_config_write32,
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -69,7 +69,7 @@ config PCI_IMX6
|
||||
|
||||
config PCI_TEGRA
|
||||
bool "NVIDIA Tegra PCIe controller"
|
||||
depends on ARCH_TEGRA && !ARM64
|
||||
depends on ARCH_TEGRA
|
||||
help
|
||||
Say Y here if you want support for the PCIe host controller found
|
||||
on NVIDIA Tegra SoCs.
|
||||
@@ -133,8 +133,8 @@ config PCIE_XILINX
|
||||
|
||||
config PCI_XGENE
|
||||
bool "X-Gene PCIe controller"
|
||||
depends on ARCH_XGENE
|
||||
depends on OF
|
||||
depends on ARM64
|
||||
depends on OF || (ACPI && PCI_QUIRKS)
|
||||
select PCIEPORTBUS
|
||||
help
|
||||
Say Y here if you want internal PCI support on APM X-Gene SoC.
|
||||
@@ -240,14 +240,16 @@ config PCIE_QCOM
|
||||
|
||||
config PCI_HOST_THUNDER_PEM
|
||||
bool "Cavium Thunder PCIe controller to off-chip devices"
|
||||
depends on OF && ARM64
|
||||
depends on ARM64
|
||||
depends on OF || (ACPI && PCI_QUIRKS)
|
||||
select PCI_HOST_COMMON
|
||||
help
|
||||
Say Y here if you want PCIe support for CN88XX Cavium Thunder SoCs.
|
||||
|
||||
config PCI_HOST_THUNDER_ECAM
|
||||
bool "Cavium Thunder ECAM controller to on-chip devices on pass-1.x silicon"
|
||||
depends on OF && ARM64
|
||||
depends on ARM64
|
||||
depends on OF || (ACPI && PCI_QUIRKS)
|
||||
select PCI_HOST_COMMON
|
||||
help
|
||||
Say Y here if you want ECAM support for CN88XX-Pass-1.x Cavium Thunder SoCs.
|
||||
@@ -276,7 +278,7 @@ config PCIE_ARTPEC6
|
||||
|
||||
config PCIE_ROCKCHIP
|
||||
bool "Rockchip PCIe controller"
|
||||
depends on ARCH_ROCKCHIP
|
||||
depends on ARCH_ROCKCHIP || COMPILE_TEST
|
||||
depends on OF
|
||||
depends on PCI_MSI_IRQ_DOMAIN
|
||||
select MFD_SYSCON
|
||||
@@ -286,7 +288,7 @@ config PCIE_ROCKCHIP
|
||||
4 slots.
|
||||
|
||||
config VMD
|
||||
depends on PCI_MSI && X86_64
|
||||
depends on PCI_MSI && X86_64 && SRCU
|
||||
tristate "Intel Volume Management Device Driver"
|
||||
default N
|
||||
---help---
|
||||
|
||||
@@ -15,7 +15,6 @@ obj-$(CONFIG_PCIE_SPEAR13XX) += pcie-spear13xx.o
|
||||
obj-$(CONFIG_PCI_KEYSTONE) += pci-keystone-dw.o pci-keystone.o
|
||||
obj-$(CONFIG_PCIE_XILINX) += pcie-xilinx.o
|
||||
obj-$(CONFIG_PCIE_XILINX_NWL) += pcie-xilinx-nwl.o
|
||||
obj-$(CONFIG_PCI_XGENE) += pci-xgene.o
|
||||
obj-$(CONFIG_PCI_XGENE_MSI) += pci-xgene-msi.o
|
||||
obj-$(CONFIG_PCI_LAYERSCAPE) += pci-layerscape.o
|
||||
obj-$(CONFIG_PCI_VERSATILE) += pci-versatile.o
|
||||
@@ -25,11 +24,23 @@ obj-$(CONFIG_PCIE_IPROC_PLATFORM) += pcie-iproc-platform.o
|
||||
obj-$(CONFIG_PCIE_IPROC_BCMA) += pcie-iproc-bcma.o
|
||||
obj-$(CONFIG_PCIE_ALTERA) += pcie-altera.o
|
||||
obj-$(CONFIG_PCIE_ALTERA_MSI) += pcie-altera-msi.o
|
||||
obj-$(CONFIG_PCI_HISI) += pcie-hisi.o
|
||||
obj-$(CONFIG_PCIE_QCOM) += pcie-qcom.o
|
||||
obj-$(CONFIG_PCI_HOST_THUNDER_ECAM) += pci-thunder-ecam.o
|
||||
obj-$(CONFIG_PCI_HOST_THUNDER_PEM) += pci-thunder-pem.o
|
||||
obj-$(CONFIG_PCIE_ARMADA_8K) += pcie-armada8k.o
|
||||
obj-$(CONFIG_PCIE_ARTPEC6) += pcie-artpec6.o
|
||||
obj-$(CONFIG_PCIE_ROCKCHIP) += pcie-rockchip.o
|
||||
obj-$(CONFIG_VMD) += vmd.o
|
||||
|
||||
# The following drivers are for devices that use the generic ACPI
|
||||
# pci_root.c driver but don't support standard ECAM config access.
|
||||
# They contain MCFG quirks to replace the generic ECAM accessors with
|
||||
# device-specific ones that are shared with the DT driver.
|
||||
|
||||
# The ACPI driver is generic and should not require driver-specific
|
||||
# config options to be enabled, so we always build these drivers on
|
||||
# ARM64 and use internal ifdefs to only build the pieces we need
|
||||
# depending on whether ACPI, the DT driver, or both are enabled.
|
||||
|
||||
obj-$(CONFIG_ARM64) += pcie-hisi.o
|
||||
obj-$(CONFIG_ARM64) += pci-thunder-ecam.o
|
||||
obj-$(CONFIG_ARM64) += pci-thunder-pem.o
|
||||
obj-$(CONFIG_ARM64) += pci-xgene.o
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user