diff options
75 files changed, 3145 insertions, 863 deletions
diff --git a/Documentation/ABI/testing/sysfs-bus-pci b/Documentation/ABI/testing/sysfs-bus-pci index b3bc50f650ee..5a1732b78707 100644 --- a/Documentation/ABI/testing/sysfs-bus-pci +++ b/Documentation/ABI/testing/sysfs-bus-pci | |||
@@ -294,3 +294,10 @@ Description: | |||
294 | a firmware bug to the system vendor. Writing to this file | 294 | a firmware bug to the system vendor. Writing to this file |
295 | taints the kernel with TAINT_FIRMWARE_WORKAROUND, which | 295 | taints the kernel with TAINT_FIRMWARE_WORKAROUND, which |
296 | reduces the supportability of your system. | 296 | reduces the supportability of your system. |
297 | |||
298 | What: /sys/bus/pci/devices/.../revision | ||
299 | Date: November 2016 | ||
300 | Contact: Emil Velikov <emil.l.velikov@gmail.com> | ||
301 | Description: | ||
302 | This file contains the revision field of the the PCI device. | ||
303 | The value comes from device config space. The file is read only. | ||
diff --git a/Documentation/devicetree/bindings/pci/brcm,iproc-pcie.txt b/Documentation/devicetree/bindings/pci/brcm,iproc-pcie.txt index 01b88f4e0d5b..b8e48b4762b2 100644 --- a/Documentation/devicetree/bindings/pci/brcm,iproc-pcie.txt +++ b/Documentation/devicetree/bindings/pci/brcm,iproc-pcie.txt | |||
@@ -1,10 +1,17 @@ | |||
1 | * Broadcom iProc PCIe controller with the platform bus interface | 1 | * Broadcom iProc PCIe controller with the platform bus interface |
2 | 2 | ||
3 | Required properties: | 3 | Required properties: |
4 | - compatible: Must be "brcm,iproc-pcie" for PAXB, or "brcm,iproc-pcie-paxc" | 4 | - compatible: |
5 | for PAXC. PAXB-based root complex is used for external endpoint devices. | 5 | "brcm,iproc-pcie" for the first generation of PAXB based controller, |
6 | PAXC-based root complex is connected to emulated endpoint devices | 6 | used in SoCs including NSP, Cygnus, NS2, and Pegasus |
7 | internal to the ASIC | 7 | "brcm,iproc-pcie-paxb-v2" for the second generation of PAXB-based |
8 | controllers, used in Stingray | ||
9 | "brcm,iproc-pcie-paxc" for the first generation of PAXC based | ||
10 | controller, used in NS2 | ||
11 | "brcm,iproc-pcie-paxc-v2" for the second generation of PAXC based | ||
12 | controller, used in Stingray | ||
13 | PAXB-based root complex is used for external endpoint devices. PAXC-based | ||
14 | root complex is connected to emulated endpoint devices internal to the ASIC | ||
8 | - reg: base address and length of the PCIe controller I/O register space | 15 | - reg: base address and length of the PCIe controller I/O register space |
9 | - #interrupt-cells: set to <1> | 16 | - #interrupt-cells: set to <1> |
10 | - interrupt-map-mask and interrupt-map, standard PCI properties to define the | 17 | - interrupt-map-mask and interrupt-map, standard PCI properties to define the |
@@ -19,6 +26,10 @@ Required properties: | |||
19 | Optional properties: | 26 | Optional properties: |
20 | - phys: phandle of the PCIe PHY device | 27 | - phys: phandle of the PCIe PHY device |
21 | - phy-names: must be "pcie-phy" | 28 | - phy-names: must be "pcie-phy" |
29 | - dma-coherent: present if DMA operations are coherent | ||
30 | - dma-ranges: Some PAXB-based root complexes do not have inbound mapping done | ||
31 | by the ASIC after power on reset. In this case, SW is required to configure | ||
32 | the mapping, based on inbound memory regions specified by this property. | ||
22 | 33 | ||
23 | - brcm,pcie-ob: Some iProc SoCs do not have the outbound address mapping done | 34 | - brcm,pcie-ob: Some iProc SoCs do not have the outbound address mapping done |
24 | by the ASIC after power on reset. In this case, SW needs to configure it | 35 | by the ASIC after power on reset. In this case, SW needs to configure it |
@@ -29,11 +40,6 @@ effective: | |||
29 | Required: | 40 | Required: |
30 | - brcm,pcie-ob-axi-offset: The offset from the AXI address to the internal | 41 | - brcm,pcie-ob-axi-offset: The offset from the AXI address to the internal |
31 | address used by the iProc PCIe core (not the PCIe address) | 42 | address used by the iProc PCIe core (not the PCIe address) |
32 | - brcm,pcie-ob-window-size: The outbound address mapping window size (in MB) | ||
33 | |||
34 | Optional: | ||
35 | - brcm,pcie-ob-oarr-size: Some iProc SoCs need the OARR size bit to be set to | ||
36 | increase the outbound window size | ||
37 | 43 | ||
38 | MSI support (optional): | 44 | MSI support (optional): |
39 | 45 | ||
@@ -41,10 +47,19 @@ For older platforms without MSI integrated in the GIC, iProc PCIe core provides | |||
41 | an event queue based MSI support. The iProc MSI uses host memories to store | 47 | an event queue based MSI support. The iProc MSI uses host memories to store |
42 | MSI posted writes in the event queues | 48 | MSI posted writes in the event queues |
43 | 49 | ||
44 | - msi-parent: Link to the device node of the MSI controller. On newer iProc | 50 | On newer iProc platforms, gicv2m or gicv3-its based MSI support should be used |
45 | platforms, the MSI controller may be gicv2m or gicv3-its. On older iProc | 51 | |
46 | platforms without MSI support in its interrupt controller, one may use the | 52 | - msi-map: Maps a Requester ID to an MSI controller and associated MSI |
47 | event queue based MSI support integrated within the iProc PCIe core. | 53 | sideband data |
54 | |||
55 | - msi-parent: Link to the device node of the MSI controller, used when no MSI | ||
56 | sideband data is passed between the iProc PCIe controller and the MSI | ||
57 | controller | ||
58 | |||
59 | Refer to the following binding documents for more detailed description on | ||
60 | the use of 'msi-map' and 'msi-parent': | ||
61 | Documentation/devicetree/bindings/pci/pci-msi.txt | ||
62 | Documentation/devicetree/bindings/interrupt-controller/msi.txt | ||
48 | 63 | ||
49 | When the iProc event queue based MSI is used, one needs to define the | 64 | When the iProc event queue based MSI is used, one needs to define the |
50 | following properties in the MSI device node: | 65 | following properties in the MSI device node: |
@@ -80,9 +95,7 @@ Example: | |||
80 | phy-names = "pcie-phy"; | 95 | phy-names = "pcie-phy"; |
81 | 96 | ||
82 | brcm,pcie-ob; | 97 | brcm,pcie-ob; |
83 | brcm,pcie-ob-oarr-size; | ||
84 | brcm,pcie-ob-axi-offset = <0x00000000>; | 98 | brcm,pcie-ob-axi-offset = <0x00000000>; |
85 | brcm,pcie-ob-window-size = <256>; | ||
86 | 99 | ||
87 | msi-parent = <&msi0>; | 100 | msi-parent = <&msi0>; |
88 | 101 | ||
diff --git a/Documentation/devicetree/bindings/pci/layerscape-pci.txt b/Documentation/devicetree/bindings/pci/layerscape-pci.txt index 41e9f55a1467..ee1c72d5162e 100644 --- a/Documentation/devicetree/bindings/pci/layerscape-pci.txt +++ b/Documentation/devicetree/bindings/pci/layerscape-pci.txt | |||
@@ -15,6 +15,7 @@ Required properties: | |||
15 | - compatible: should contain the platform identifier such as: | 15 | - compatible: should contain the platform identifier such as: |
16 | "fsl,ls1021a-pcie", "snps,dw-pcie" | 16 | "fsl,ls1021a-pcie", "snps,dw-pcie" |
17 | "fsl,ls2080a-pcie", "fsl,ls2085a-pcie", "snps,dw-pcie" | 17 | "fsl,ls2080a-pcie", "fsl,ls2085a-pcie", "snps,dw-pcie" |
18 | "fsl,ls1046a-pcie" | ||
18 | - reg: base addresses and lengths of the PCIe controller | 19 | - reg: base addresses and lengths of the PCIe controller |
19 | - interrupts: A list of interrupt outputs of the controller. Must contain an | 20 | - interrupts: A list of interrupt outputs of the controller. Must contain an |
20 | entry for each entry in the interrupt-names property. | 21 | entry for each entry in the interrupt-names property. |
diff --git a/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt b/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt index b8cc395fffea..982a74ea6df9 100644 --- a/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt +++ b/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt | |||
@@ -110,6 +110,20 @@ Power supplies for Tegra124: | |||
110 | - avdd-pll-erefe-supply: Power supply for PLLE (shared with USB3). Must | 110 | - avdd-pll-erefe-supply: Power supply for PLLE (shared with USB3). Must |
111 | supply 1.05 V. | 111 | supply 1.05 V. |
112 | 112 | ||
113 | Power supplies for Tegra210: | ||
114 | - Required: | ||
115 | - avdd-pll-uerefe-supply: Power supply for PLLE (shared with USB3). Must | ||
116 | supply 1.05 V. | ||
117 | - hvddio-pex-supply: High-voltage supply for PCIe I/O and PCIe output | ||
118 | clocks. Must supply 1.8 V. | ||
119 | - dvddio-pex-supply: Power supply for digital PCIe I/O. Must supply 1.05 V. | ||
120 | - dvdd-pex-pll-supply: Power supply for dedicated (internal) PCIe PLL. Must | ||
121 | supply 1.05 V. | ||
122 | - hvdd-pex-pll-e-supply: High-voltage supply for PLLE (shared with USB3). | ||
123 | Must supply 3.3 V. | ||
124 | - vddio-pex-ctl-supply: Power supply for PCIe control I/O partition. Must | ||
125 | supply 1.8 V. | ||
126 | |||
113 | Root ports are defined as subnodes of the PCIe controller node. | 127 | Root ports are defined as subnodes of the PCIe controller node. |
114 | 128 | ||
115 | Required properties: | 129 | Required properties: |
@@ -436,3 +450,99 @@ Board DTS: | |||
436 | status = "okay"; | 450 | status = "okay"; |
437 | }; | 451 | }; |
438 | }; | 452 | }; |
453 | |||
454 | Tegra210: | ||
455 | --------- | ||
456 | |||
457 | SoC DTSI: | ||
458 | |||
459 | pcie-controller@01003000 { | ||
460 | compatible = "nvidia,tegra210-pcie"; | ||
461 | device_type = "pci"; | ||
462 | reg = <0x0 0x01003000 0x0 0x00000800 /* PADS registers */ | ||
463 | 0x0 0x01003800 0x0 0x00000800 /* AFI registers */ | ||
464 | 0x0 0x02000000 0x0 0x10000000>; /* configuration space */ | ||
465 | reg-names = "pads", "afi", "cs"; | ||
466 | interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>, /* controller interrupt */ | ||
467 | <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>; /* MSI interrupt */ | ||
468 | interrupt-names = "intr", "msi"; | ||
469 | |||
470 | #interrupt-cells = <1>; | ||
471 | interrupt-map-mask = <0 0 0 0>; | ||
472 | interrupt-map = <0 0 0 0 &gic GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>; | ||
473 | |||
474 | bus-range = <0x00 0xff>; | ||
475 | #address-cells = <3>; | ||
476 | #size-cells = <2>; | ||
477 | |||
478 | ranges = <0x82000000 0 0x01000000 0x0 0x01000000 0 0x00001000 /* port 0 configuration space */ | ||
479 | 0x82000000 0 0x01001000 0x0 0x01001000 0 0x00001000 /* port 1 configuration space */ | ||
480 | 0x81000000 0 0x0 0x0 0x12000000 0 0x00010000 /* downstream I/O (64 KiB) */ | ||
481 | 0x82000000 0 0x13000000 0x0 0x13000000 0 0x0d000000 /* non-prefetchable memory (208 MiB) */ | ||
482 | 0xc2000000 0 0x20000000 0x0 0x20000000 0 0x20000000>; /* prefetchable memory (512 MiB) */ | ||
483 | |||
484 | clocks = <&tegra_car TEGRA210_CLK_PCIE>, | ||
485 | <&tegra_car TEGRA210_CLK_AFI>, | ||
486 | <&tegra_car TEGRA210_CLK_PLL_E>, | ||
487 | <&tegra_car TEGRA210_CLK_CML0>; | ||
488 | clock-names = "pex", "afi", "pll_e", "cml"; | ||
489 | resets = <&tegra_car 70>, | ||
490 | <&tegra_car 72>, | ||
491 | <&tegra_car 74>; | ||
492 | reset-names = "pex", "afi", "pcie_x"; | ||
493 | status = "disabled"; | ||
494 | |||
495 | pci@1,0 { | ||
496 | device_type = "pci"; | ||
497 | assigned-addresses = <0x82000800 0 0x01000000 0 0x1000>; | ||
498 | reg = <0x000800 0 0 0 0>; | ||
499 | status = "disabled"; | ||
500 | |||
501 | #address-cells = <3>; | ||
502 | #size-cells = <2>; | ||
503 | ranges; | ||
504 | |||
505 | nvidia,num-lanes = <4>; | ||
506 | }; | ||
507 | |||
508 | pci@2,0 { | ||
509 | device_type = "pci"; | ||
510 | assigned-addresses = <0x82001000 0 0x01001000 0 0x1000>; | ||
511 | reg = <0x001000 0 0 0 0>; | ||
512 | status = "disabled"; | ||
513 | |||
514 | #address-cells = <3>; | ||
515 | #size-cells = <2>; | ||
516 | ranges; | ||
517 | |||
518 | nvidia,num-lanes = <1>; | ||
519 | }; | ||
520 | }; | ||
521 | |||
522 | Board DTS: | ||
523 | |||
524 | pcie-controller@01003000 { | ||
525 | status = "okay"; | ||
526 | |||
527 | avdd-pll-uerefe-supply = <&avdd_1v05_pll>; | ||
528 | hvddio-pex-supply = <&vdd_1v8>; | ||
529 | dvddio-pex-supply = <&vdd_pex_1v05>; | ||
530 | dvdd-pex-pll-supply = <&vdd_pex_1v05>; | ||
531 | hvdd-pex-pll-e-supply = <&vdd_1v8>; | ||
532 | vddio-pex-ctl-supply = <&vdd_1v8>; | ||
533 | |||
534 | pci@1,0 { | ||
535 | phys = <&{/padctl@7009f000/pads/pcie/lanes/pcie-0}>, | ||
536 | <&{/padctl@7009f000/pads/pcie/lanes/pcie-1}>, | ||
537 | <&{/padctl@7009f000/pads/pcie/lanes/pcie-2}>, | ||
538 | <&{/padctl@7009f000/pads/pcie/lanes/pcie-3}>; | ||
539 | phy-names = "pcie-0", "pcie-1", "pcie-2", "pcie-3"; | ||
540 | status = "okay"; | ||
541 | }; | ||
542 | |||
543 | pci@2,0 { | ||
544 | phys = <&{/padctl@7009f000/pads/pcie/lanes/pcie-4}>; | ||
545 | phy-names = "pcie-0"; | ||
546 | status = "okay"; | ||
547 | }; | ||
548 | }; | ||
diff --git a/Documentation/devicetree/bindings/pci/pci.txt b/Documentation/devicetree/bindings/pci/pci.txt index 08dcfad09f8d..50f9e2ca5b13 100644 --- a/Documentation/devicetree/bindings/pci/pci.txt +++ b/Documentation/devicetree/bindings/pci/pci.txt | |||
@@ -18,3 +18,9 @@ driver implementation may support the following properties: | |||
18 | host bridges in the system, otherwise potentially conflicting domain numbers | 18 | host bridges in the system, otherwise potentially conflicting domain numbers |
19 | may be assigned to root buses behind different host bridges. The domain | 19 | may be assigned to root buses behind different host bridges. The domain |
20 | number for each host bridge in the system must be unique. | 20 | number for each host bridge in the system must be unique. |
21 | - max-link-speed: | ||
22 | If present this property specifies PCI gen for link capability. Host | ||
23 | drivers could add this as a strategy to avoid unnecessary operation for | ||
24 | unsupported link speed, for instance, trying to do training for | ||
25 | unsupported link speed, etc. Must be '4' for gen4, '3' for gen3, '2' | ||
26 | for gen2, and '1' for gen1. Any other values are invalid. | ||
diff --git a/Documentation/devicetree/bindings/pci/qcom,pcie.txt b/Documentation/devicetree/bindings/pci/qcom,pcie.txt index 4059a6f89bc1..e15f9b19901f 100644 --- a/Documentation/devicetree/bindings/pci/qcom,pcie.txt +++ b/Documentation/devicetree/bindings/pci/qcom,pcie.txt | |||
@@ -7,6 +7,7 @@ | |||
7 | - "qcom,pcie-ipq8064" for ipq8064 | 7 | - "qcom,pcie-ipq8064" for ipq8064 |
8 | - "qcom,pcie-apq8064" for apq8064 | 8 | - "qcom,pcie-apq8064" for apq8064 |
9 | - "qcom,pcie-apq8084" for apq8084 | 9 | - "qcom,pcie-apq8084" for apq8084 |
10 | - "qcom,pcie-msm8996" for msm8996 or apq8096 | ||
10 | 11 | ||
11 | - reg: | 12 | - reg: |
12 | Usage: required | 13 | Usage: required |
@@ -92,6 +93,17 @@ | |||
92 | - "aux" Auxiliary (AUX) clock | 93 | - "aux" Auxiliary (AUX) clock |
93 | - "bus_master" Master AXI clock | 94 | - "bus_master" Master AXI clock |
94 | - "bus_slave" Slave AXI clock | 95 | - "bus_slave" Slave AXI clock |
96 | |||
97 | - clock-names: | ||
98 | Usage: required for msm8996/apq8096 | ||
99 | Value type: <stringlist> | ||
100 | Definition: Should contain the following entries | ||
101 | - "pipe" Pipe Clock driving internal logic | ||
102 | - "aux" Auxiliary (AUX) clock | ||
103 | - "cfg" Configuration clock | ||
104 | - "bus_master" Master AXI clock | ||
105 | - "bus_slave" Slave AXI clock | ||
106 | |||
95 | - resets: | 107 | - resets: |
96 | Usage: required | 108 | Usage: required |
97 | Value type: <prop-encoded-array> | 109 | Value type: <prop-encoded-array> |
@@ -115,7 +127,7 @@ | |||
115 | - "core" Core reset | 127 | - "core" Core reset |
116 | 128 | ||
117 | - power-domains: | 129 | - power-domains: |
118 | Usage: required for apq8084 | 130 | Usage: required for apq8084 and msm8996/apq8096 |
119 | Value type: <prop-encoded-array> | 131 | Value type: <prop-encoded-array> |
120 | Definition: A phandle and power domain specifier pair to the | 132 | Definition: A phandle and power domain specifier pair to the |
121 | power domain which is responsible for collapsing | 133 | power domain which is responsible for collapsing |
diff --git a/Documentation/devicetree/bindings/pci/rcar-pci.txt b/Documentation/devicetree/bindings/pci/rcar-pci.txt index 6cf99690eef9..eee518db90b9 100644 --- a/Documentation/devicetree/bindings/pci/rcar-pci.txt +++ b/Documentation/devicetree/bindings/pci/rcar-pci.txt | |||
@@ -7,6 +7,7 @@ compatible: "renesas,pcie-r8a7779" for the R8A7779 SoC; | |||
7 | "renesas,pcie-r8a7793" for the R8A7793 SoC; | 7 | "renesas,pcie-r8a7793" for the R8A7793 SoC; |
8 | "renesas,pcie-r8a7795" for the R8A7795 SoC; | 8 | "renesas,pcie-r8a7795" for the R8A7795 SoC; |
9 | "renesas,pcie-rcar-gen2" for a generic R-Car Gen2 compatible device. | 9 | "renesas,pcie-rcar-gen2" for a generic R-Car Gen2 compatible device. |
10 | "renesas,pcie-rcar-gen3" for a generic R-Car Gen3 compatible device. | ||
10 | 11 | ||
11 | When compatible with the generic version, nodes must list the | 12 | When compatible with the generic version, nodes must list the |
12 | SoC-specific version corresponding to the platform first | 13 | SoC-specific version corresponding to the platform first |
diff --git a/Documentation/devicetree/bindings/pci/rockchip-pcie.txt b/Documentation/devicetree/bindings/pci/rockchip-pcie.txt index ba67b39939c1..71aeda1ca055 100644 --- a/Documentation/devicetree/bindings/pci/rockchip-pcie.txt +++ b/Documentation/devicetree/bindings/pci/rockchip-pcie.txt | |||
@@ -26,13 +26,16 @@ Required properties: | |||
26 | - "sys" | 26 | - "sys" |
27 | - "legacy" | 27 | - "legacy" |
28 | - "client" | 28 | - "client" |
29 | - resets: Must contain five entries for each entry in reset-names. | 29 | - resets: Must contain seven entries for each entry in reset-names. |
30 | See ../reset/reset.txt for details. | 30 | See ../reset/reset.txt for details. |
31 | - reset-names: Must include the following names | 31 | - reset-names: Must include the following names |
32 | - "core" | 32 | - "core" |
33 | - "mgmt" | 33 | - "mgmt" |
34 | - "mgmt-sticky" | 34 | - "mgmt-sticky" |
35 | - "pipe" | 35 | - "pipe" |
36 | - "pm" | ||
37 | - "aclk" | ||
38 | - "pclk" | ||
36 | - pinctrl-names : The pin control state names | 39 | - pinctrl-names : The pin control state names |
37 | - pinctrl-0: The "default" pinctrl state | 40 | - pinctrl-0: The "default" pinctrl state |
38 | - #interrupt-cells: specifies the number of cells needed to encode an | 41 | - #interrupt-cells: specifies the number of cells needed to encode an |
@@ -86,8 +89,10 @@ pcie0: pcie@f8000000 { | |||
86 | reg = <0x0 0xf8000000 0x0 0x2000000>, <0x0 0xfd000000 0x0 0x1000000>; | 89 | reg = <0x0 0xf8000000 0x0 0x2000000>, <0x0 0xfd000000 0x0 0x1000000>; |
87 | reg-names = "axi-base", "apb-base"; | 90 | reg-names = "axi-base", "apb-base"; |
88 | resets = <&cru SRST_PCIE_CORE>, <&cru SRST_PCIE_MGMT>, | 91 | resets = <&cru SRST_PCIE_CORE>, <&cru SRST_PCIE_MGMT>, |
89 | <&cru SRST_PCIE_MGMT_STICKY>, <&cru SRST_PCIE_PIPE>; | 92 | <&cru SRST_PCIE_MGMT_STICKY>, <&cru SRST_PCIE_PIPE> , |
90 | reset-names = "core", "mgmt", "mgmt-sticky", "pipe"; | 93 | <&cru SRST_PCIE_PM>, <&cru SRST_P_PCIE>, <&cru SRST_A_PCIE>; |
94 | reset-names = "core", "mgmt", "mgmt-sticky", "pipe", | ||
95 | "pm", "pclk", "aclk"; | ||
91 | phys = <&pcie_phy>; | 96 | phys = <&pcie_phy>; |
92 | phy-names = "pcie-phy"; | 97 | phy-names = "pcie-phy"; |
93 | pinctrl-names = "default"; | 98 | pinctrl-names = "default"; |
diff --git a/Documentation/filesystems/sysfs-pci.txt b/Documentation/filesystems/sysfs-pci.txt index 74eaac26f8b8..6ea1ceda6f52 100644 --- a/Documentation/filesystems/sysfs-pci.txt +++ b/Documentation/filesystems/sysfs-pci.txt | |||
@@ -17,6 +17,7 @@ that support it. For example, a given bus might look like this: | |||
17 | | |-- resource0 | 17 | | |-- resource0 |
18 | | |-- resource1 | 18 | | |-- resource1 |
19 | | |-- resource2 | 19 | | |-- resource2 |
20 | | |-- revision | ||
20 | | |-- rom | 21 | | |-- rom |
21 | | |-- subsystem_device | 22 | | |-- subsystem_device |
22 | | |-- subsystem_vendor | 23 | | |-- subsystem_vendor |
@@ -41,6 +42,7 @@ files, each with their own function. | |||
41 | resource PCI resource host addresses (ascii, ro) | 42 | resource PCI resource host addresses (ascii, ro) |
42 | resource0..N PCI resource N, if present (binary, mmap, rw[1]) | 43 | resource0..N PCI resource N, if present (binary, mmap, rw[1]) |
43 | resource0_wc..N_wc PCI WC map resource N, if prefetchable (binary, mmap) | 44 | resource0_wc..N_wc PCI WC map resource N, if prefetchable (binary, mmap) |
45 | revision PCI revision (ascii, ro) | ||
44 | rom PCI ROM resource, if present (binary, ro) | 46 | rom PCI ROM resource, if present (binary, ro) |
45 | subsystem_device PCI subsystem device (ascii, ro) | 47 | subsystem_device PCI subsystem device (ascii, ro) |
46 | subsystem_vendor PCI subsystem vendor (ascii, ro) | 48 | subsystem_vendor PCI subsystem vendor (ascii, ro) |
diff --git a/MAINTAINERS b/MAINTAINERS index 1cd38a7e0064..2a7ea17c449a 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -9230,11 +9230,12 @@ S: Maintained | |||
9230 | F: drivers/pci/host/*layerscape* | 9230 | F: drivers/pci/host/*layerscape* |
9231 | 9231 | ||
9232 | PCI DRIVER FOR IMX6 | 9232 | PCI DRIVER FOR IMX6 |
9233 | M: Richard Zhu <Richard.Zhu@freescale.com> | 9233 | M: Richard Zhu <hongxing.zhu@nxp.com> |
9234 | M: Lucas Stach <l.stach@pengutronix.de> | 9234 | M: Lucas Stach <l.stach@pengutronix.de> |
9235 | L: linux-pci@vger.kernel.org | 9235 | L: linux-pci@vger.kernel.org |
9236 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | 9236 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
9237 | S: Maintained | 9237 | S: Maintained |
9238 | F: Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt | ||
9238 | F: drivers/pci/host/*imx6* | 9239 | F: drivers/pci/host/*imx6* |
9239 | 9240 | ||
9240 | PCI DRIVER FOR TI KEYSTONE | 9241 | PCI DRIVER FOR TI KEYSTONE |
@@ -9299,7 +9300,7 @@ S: Maintained | |||
9299 | F: drivers/pci/host/*designware* | 9300 | F: drivers/pci/host/*designware* |
9300 | 9301 | ||
9301 | PCI DRIVER FOR SYNOPSYS PROTOTYPING DEVICE | 9302 | PCI DRIVER FOR SYNOPSYS PROTOTYPING DEVICE |
9302 | M: Joao Pinto <jpinto@synopsys.com> | 9303 | M: Jose Abreu <Jose.Abreu@synopsys.com> |
9303 | L: linux-pci@vger.kernel.org | 9304 | L: linux-pci@vger.kernel.org |
9304 | S: Maintained | 9305 | S: Maintained |
9305 | F: Documentation/devicetree/bindings/pci/designware-pcie.txt | 9306 | F: Documentation/devicetree/bindings/pci/designware-pcie.txt |
diff --git a/arch/arm64/boot/dts/nvidia/tegra210-p2371-2180.dts b/arch/arm64/boot/dts/nvidia/tegra210-p2371-2180.dts index 983775e637a4..4c1ea7a08d43 100644 --- a/arch/arm64/boot/dts/nvidia/tegra210-p2371-2180.dts +++ b/arch/arm64/boot/dts/nvidia/tegra210-p2371-2180.dts | |||
@@ -7,6 +7,32 @@ | |||
7 | model = "NVIDIA Jetson TX1 Developer Kit"; | 7 | model = "NVIDIA Jetson TX1 Developer Kit"; |
8 | compatible = "nvidia,p2371-2180", "nvidia,tegra210"; | 8 | compatible = "nvidia,p2371-2180", "nvidia,tegra210"; |
9 | 9 | ||
10 | pcie-controller@01003000 { | ||
11 | status = "okay"; | ||
12 | |||
13 | avdd-pll-uerefe-supply = <&avdd_1v05_pll>; | ||
14 | hvddio-pex-supply = <&vdd_1v8>; | ||
15 | dvddio-pex-supply = <&vdd_pex_1v05>; | ||
16 | dvdd-pex-pll-supply = <&vdd_pex_1v05>; | ||
17 | hvdd-pex-pll-e-supply = <&vdd_1v8>; | ||
18 | vddio-pex-ctl-supply = <&vdd_1v8>; | ||
19 | |||
20 | pci@1,0 { | ||
21 | phys = <&{/padctl@7009f000/pads/pcie/lanes/pcie-0}>, | ||
22 | <&{/padctl@7009f000/pads/pcie/lanes/pcie-1}>, | ||
23 | <&{/padctl@7009f000/pads/pcie/lanes/pcie-2}>, | ||
24 | <&{/padctl@7009f000/pads/pcie/lanes/pcie-3}>; | ||
25 | phy-names = "pcie-0", "pcie-1", "pcie-2", "pcie-3"; | ||
26 | status = "okay"; | ||
27 | }; | ||
28 | |||
29 | pci@2,0 { | ||
30 | phys = <&{/padctl@7009f000/pads/pcie/lanes/pcie-4}>; | ||
31 | phy-names = "pcie-0"; | ||
32 | status = "okay"; | ||
33 | }; | ||
34 | }; | ||
35 | |||
10 | host1x@50000000 { | 36 | host1x@50000000 { |
11 | dsi@54300000 { | 37 | dsi@54300000 { |
12 | status = "okay"; | 38 | status = "okay"; |
diff --git a/arch/arm64/boot/dts/nvidia/tegra210.dtsi b/arch/arm64/boot/dts/nvidia/tegra210.dtsi index 46045fe719da..2f832df29da8 100644 --- a/arch/arm64/boot/dts/nvidia/tegra210.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra210.dtsi | |||
@@ -11,6 +11,69 @@ | |||
11 | #address-cells = <2>; | 11 | #address-cells = <2>; |
12 | #size-cells = <2>; | 12 | #size-cells = <2>; |
13 | 13 | ||
14 | pcie-controller@01003000 { | ||
15 | compatible = "nvidia,tegra210-pcie"; | ||
16 | device_type = "pci"; | ||
17 | reg = <0x0 0x01003000 0x0 0x00000800 /* PADS registers */ | ||
18 | 0x0 0x01003800 0x0 0x00000800 /* AFI registers */ | ||
19 | 0x0 0x02000000 0x0 0x10000000>; /* configuration space */ | ||
20 | reg-names = "pads", "afi", "cs"; | ||
21 | interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>, /* controller interrupt */ | ||
22 | <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>; /* MSI interrupt */ | ||
23 | interrupt-names = "intr", "msi"; | ||
24 | |||
25 | #interrupt-cells = <1>; | ||
26 | interrupt-map-mask = <0 0 0 0>; | ||
27 | interrupt-map = <0 0 0 0 &gic GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>; | ||
28 | |||
29 | bus-range = <0x00 0xff>; | ||
30 | #address-cells = <3>; | ||
31 | #size-cells = <2>; | ||
32 | |||
33 | ranges = <0x82000000 0 0x01000000 0x0 0x01000000 0 0x00001000 /* port 0 configuration space */ | ||
34 | 0x82000000 0 0x01001000 0x0 0x01001000 0 0x00001000 /* port 1 configuration space */ | ||
35 | 0x81000000 0 0x0 0x0 0x12000000 0 0x00010000 /* downstream I/O (64 KiB) */ | ||
36 | 0x82000000 0 0x13000000 0x0 0x13000000 0 0x0d000000 /* non-prefetchable memory (208 MiB) */ | ||
37 | 0xc2000000 0 0x20000000 0x0 0x20000000 0 0x20000000>; /* prefetchable memory (512 MiB) */ | ||
38 | |||
39 | clocks = <&tegra_car TEGRA210_CLK_PCIE>, | ||
40 | <&tegra_car TEGRA210_CLK_AFI>, | ||
41 | <&tegra_car TEGRA210_CLK_PLL_E>, | ||
42 | <&tegra_car TEGRA210_CLK_CML0>; | ||
43 | clock-names = "pex", "afi", "pll_e", "cml"; | ||
44 | resets = <&tegra_car 70>, | ||
45 | <&tegra_car 72>, | ||
46 | <&tegra_car 74>; | ||
47 | reset-names = "pex", "afi", "pcie_x"; | ||
48 | status = "disabled"; | ||
49 | |||
50 | pci@1,0 { | ||
51 | device_type = "pci"; | ||
52 | assigned-addresses = <0x82000800 0 0x01000000 0 0x1000>; | ||
53 | reg = <0x000800 0 0 0 0>; | ||
54 | status = "disabled"; | ||
55 | |||
56 | #address-cells = <3>; | ||
57 | #size-cells = <2>; | ||
58 | ranges; | ||
59 | |||
60 | nvidia,num-lanes = <4>; | ||
61 | }; | ||
62 | |||
63 | pci@2,0 { | ||
64 | device_type = "pci"; | ||
65 | assigned-addresses = <0x82001000 0 0x01001000 0 0x1000>; | ||
66 | reg = <0x001000 0 0 0 0>; | ||
67 | status = "disabled"; | ||
68 | |||
69 | #address-cells = <3>; | ||
70 | #size-cells = <2>; | ||
71 | ranges; | ||
72 | |||
73 | nvidia,num-lanes = <1>; | ||
74 | }; | ||
75 | }; | ||
76 | |||
14 | host1x@50000000 { | 77 | host1x@50000000 { |
15 | compatible = "nvidia,tegra210-host1x", "simple-bus"; | 78 | compatible = "nvidia,tegra210-host1x", "simple-bus"; |
16 | reg = <0x0 0x50000000 0x0 0x00034000>; | 79 | reg = <0x0 0x50000000 0x0 0x00034000>; |
diff --git a/arch/arm64/kernel/pci.c b/arch/arm64/kernel/pci.c index acf38722457b..4f0e3ebfea4b 100644 --- a/arch/arm64/kernel/pci.c +++ b/arch/arm64/kernel/pci.c | |||
@@ -114,6 +114,19 @@ int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge) | |||
114 | return 0; | 114 | return 0; |
115 | } | 115 | } |
116 | 116 | ||
117 | static int pci_acpi_root_prepare_resources(struct acpi_pci_root_info *ci) | ||
118 | { | ||
119 | struct resource_entry *entry, *tmp; | ||
120 | int status; | ||
121 | |||
122 | status = acpi_pci_probe_root_resources(ci); | ||
123 | resource_list_for_each_entry_safe(entry, tmp, &ci->resources) { | ||
124 | if (!(entry->res->flags & IORESOURCE_WINDOW)) | ||
125 | resource_list_destroy_entry(entry); | ||
126 | } | ||
127 | return status; | ||
128 | } | ||
129 | |||
117 | /* | 130 | /* |
118 | * Lookup the bus range for the domain in MCFG, and set up config space | 131 | * Lookup the bus range for the domain in MCFG, and set up config space |
119 | * mapping. | 132 | * mapping. |
@@ -121,31 +134,33 @@ int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge) | |||
121 | static struct pci_config_window * | 134 | static struct pci_config_window * |
122 | pci_acpi_setup_ecam_mapping(struct acpi_pci_root *root) | 135 | pci_acpi_setup_ecam_mapping(struct acpi_pci_root *root) |
123 | { | 136 | { |
137 | struct device *dev = &root->device->dev; | ||
124 | struct resource *bus_res = &root->secondary; | 138 | struct resource *bus_res = &root->secondary; |
125 | u16 seg = root->segment; | 139 | u16 seg = root->segment; |
126 | struct pci_config_window *cfg; | 140 | struct pci_ecam_ops *ecam_ops; |
127 | struct resource cfgres; | 141 | struct resource cfgres; |
128 | unsigned int bsz; | 142 | struct acpi_device *adev; |
129 | 143 | struct pci_config_window *cfg; | |
130 | /* Use address from _CBA if present, otherwise lookup MCFG */ | 144 | int ret; |
131 | if (!root->mcfg_addr) | ||
132 | root->mcfg_addr = pci_mcfg_lookup(seg, bus_res); | ||
133 | 145 | ||
134 | if (!root->mcfg_addr) { | 146 | ret = pci_mcfg_lookup(root, &cfgres, &ecam_ops); |
135 | dev_err(&root->device->dev, "%04x:%pR ECAM region not found\n", | 147 | if (ret) { |
136 | seg, bus_res); | 148 | dev_err(dev, "%04x:%pR ECAM region not found\n", seg, bus_res); |
137 | return NULL; | 149 | return NULL; |
138 | } | 150 | } |
139 | 151 | ||
140 | bsz = 1 << pci_generic_ecam_ops.bus_shift; | 152 | adev = acpi_resource_consumer(&cfgres); |
141 | cfgres.start = root->mcfg_addr + bus_res->start * bsz; | 153 | if (adev) |
142 | cfgres.end = cfgres.start + resource_size(bus_res) * bsz - 1; | 154 | dev_info(dev, "ECAM area %pR reserved by %s\n", &cfgres, |
143 | cfgres.flags = IORESOURCE_MEM; | 155 | dev_name(&adev->dev)); |
144 | cfg = pci_ecam_create(&root->device->dev, &cfgres, bus_res, | 156 | else |
145 | &pci_generic_ecam_ops); | 157 | dev_warn(dev, FW_BUG "ECAM area %pR not reserved in ACPI namespace\n", |
158 | &cfgres); | ||
159 | |||
160 | cfg = pci_ecam_create(dev, &cfgres, bus_res, ecam_ops); | ||
146 | if (IS_ERR(cfg)) { | 161 | if (IS_ERR(cfg)) { |
147 | dev_err(&root->device->dev, "%04x:%pR error %ld mapping ECAM\n", | 162 | dev_err(dev, "%04x:%pR error %ld mapping ECAM\n", seg, bus_res, |
148 | seg, bus_res, PTR_ERR(cfg)); | 163 | PTR_ERR(cfg)); |
149 | return NULL; | 164 | return NULL; |
150 | } | 165 | } |
151 | 166 | ||
@@ -159,33 +174,37 @@ static void pci_acpi_generic_release_info(struct acpi_pci_root_info *ci) | |||
159 | 174 | ||
160 | ri = container_of(ci, struct acpi_pci_generic_root_info, common); | 175 | ri = container_of(ci, struct acpi_pci_generic_root_info, common); |
161 | pci_ecam_free(ri->cfg); | 176 | pci_ecam_free(ri->cfg); |
177 | kfree(ci->ops); | ||
162 | kfree(ri); | 178 | kfree(ri); |
163 | } | 179 | } |
164 | 180 | ||
165 | static struct acpi_pci_root_ops acpi_pci_root_ops = { | ||
166 | .release_info = pci_acpi_generic_release_info, | ||
167 | }; | ||
168 | |||
169 | /* Interface called from ACPI code to setup PCI host controller */ | 181 | /* Interface called from ACPI code to setup PCI host controller */ |
170 | struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root) | 182 | struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root) |
171 | { | 183 | { |
172 | int node = acpi_get_node(root->device->handle); | 184 | int node = acpi_get_node(root->device->handle); |
173 | struct acpi_pci_generic_root_info *ri; | 185 | struct acpi_pci_generic_root_info *ri; |
174 | struct pci_bus *bus, *child; | 186 | struct pci_bus *bus, *child; |
187 | struct acpi_pci_root_ops *root_ops; | ||
175 | 188 | ||
176 | ri = kzalloc_node(sizeof(*ri), GFP_KERNEL, node); | 189 | ri = kzalloc_node(sizeof(*ri), GFP_KERNEL, node); |
177 | if (!ri) | 190 | if (!ri) |
178 | return NULL; | 191 | return NULL; |
179 | 192 | ||
193 | root_ops = kzalloc_node(sizeof(*root_ops), GFP_KERNEL, node); | ||
194 | if (!root_ops) | ||
195 | return NULL; | ||
196 | |||
180 | ri->cfg = pci_acpi_setup_ecam_mapping(root); | 197 | ri->cfg = pci_acpi_setup_ecam_mapping(root); |
181 | if (!ri->cfg) { | 198 | if (!ri->cfg) { |
182 | kfree(ri); | 199 | kfree(ri); |
200 | kfree(root_ops); | ||
183 | return NULL; | 201 | return NULL; |
184 | } | 202 | } |
185 | 203 | ||
186 | acpi_pci_root_ops.pci_ops = &ri->cfg->ops->pci_ops; | 204 | root_ops->release_info = pci_acpi_generic_release_info; |
187 | bus = acpi_pci_root_create(root, &acpi_pci_root_ops, &ri->common, | 205 | root_ops->prepare_resources = pci_acpi_root_prepare_resources; |
188 | ri->cfg); | 206 | root_ops->pci_ops = &ri->cfg->ops->pci_ops; |
207 | bus = acpi_pci_root_create(root, root_ops, &ri->common, ri->cfg); | ||
189 | if (!bus) | 208 | if (!bus) |
190 | return NULL; | 209 | return NULL; |
191 | 210 | ||
diff --git a/drivers/acpi/pci_mcfg.c b/drivers/acpi/pci_mcfg.c index b5b376e081f5..a6a4ceaa6cc3 100644 --- a/drivers/acpi/pci_mcfg.c +++ b/drivers/acpi/pci_mcfg.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/kernel.h> | 22 | #include <linux/kernel.h> |
23 | #include <linux/pci.h> | 23 | #include <linux/pci.h> |
24 | #include <linux/pci-acpi.h> | 24 | #include <linux/pci-acpi.h> |
25 | #include <linux/pci-ecam.h> | ||
25 | 26 | ||
26 | /* Structure to hold entries from the MCFG table */ | 27 | /* Structure to hold entries from the MCFG table */ |
27 | struct mcfg_entry { | 28 | struct mcfg_entry { |
@@ -32,12 +33,166 @@ struct mcfg_entry { | |||
32 | u8 bus_end; | 33 | u8 bus_end; |
33 | }; | 34 | }; |
34 | 35 | ||
36 | #ifdef CONFIG_PCI_QUIRKS | ||
37 | struct mcfg_fixup { | ||
38 | char oem_id[ACPI_OEM_ID_SIZE + 1]; | ||
39 | char oem_table_id[ACPI_OEM_TABLE_ID_SIZE + 1]; | ||
40 | u32 oem_revision; | ||
41 | u16 segment; | ||
42 | struct resource bus_range; | ||
43 | struct pci_ecam_ops *ops; | ||
44 | struct resource cfgres; | ||
45 | }; | ||
46 | |||
47 | #define MCFG_BUS_RANGE(start, end) DEFINE_RES_NAMED((start), \ | ||
48 | ((end) - (start) + 1), \ | ||
49 | NULL, IORESOURCE_BUS) | ||
50 | #define MCFG_BUS_ANY MCFG_BUS_RANGE(0x0, 0xff) | ||
51 | |||
52 | static struct mcfg_fixup mcfg_quirks[] = { | ||
53 | /* { OEM_ID, OEM_TABLE_ID, REV, SEGMENT, BUS_RANGE, ops, cfgres }, */ | ||
54 | |||
55 | #define QCOM_ECAM32(seg) \ | ||
56 | { "QCOM ", "QDF2432 ", 1, seg, MCFG_BUS_ANY, &pci_32b_ops } | ||
57 | QCOM_ECAM32(0), | ||
58 | QCOM_ECAM32(1), | ||
59 | QCOM_ECAM32(2), | ||
60 | QCOM_ECAM32(3), | ||
61 | QCOM_ECAM32(4), | ||
62 | QCOM_ECAM32(5), | ||
63 | QCOM_ECAM32(6), | ||
64 | QCOM_ECAM32(7), | ||
65 | |||
66 | #define HISI_QUAD_DOM(table_id, seg, ops) \ | ||
67 | { "HISI ", table_id, 0, (seg) + 0, MCFG_BUS_ANY, ops }, \ | ||
68 | { "HISI ", table_id, 0, (seg) + 1, MCFG_BUS_ANY, ops }, \ | ||
69 | { "HISI ", table_id, 0, (seg) + 2, MCFG_BUS_ANY, ops }, \ | ||
70 | { "HISI ", table_id, 0, (seg) + 3, MCFG_BUS_ANY, ops } | ||
71 | HISI_QUAD_DOM("HIP05 ", 0, &hisi_pcie_ops), | ||
72 | HISI_QUAD_DOM("HIP06 ", 0, &hisi_pcie_ops), | ||
73 | HISI_QUAD_DOM("HIP07 ", 0, &hisi_pcie_ops), | ||
74 | HISI_QUAD_DOM("HIP07 ", 4, &hisi_pcie_ops), | ||
75 | HISI_QUAD_DOM("HIP07 ", 8, &hisi_pcie_ops), | ||
76 | HISI_QUAD_DOM("HIP07 ", 12, &hisi_pcie_ops), | ||
77 | |||
78 | #define THUNDER_PEM_RES(addr, node) \ | ||
79 | DEFINE_RES_MEM((addr) + ((u64) (node) << 44), 0x39 * SZ_16M) | ||
80 | #define THUNDER_PEM_QUIRK(rev, node) \ | ||
81 | { "CAVIUM", "THUNDERX", rev, 4 + (10 * (node)), MCFG_BUS_ANY, \ | ||
82 | &thunder_pem_ecam_ops, THUNDER_PEM_RES(0x88001f000000UL, node) }, \ | ||
83 | { "CAVIUM", "THUNDERX", rev, 5 + (10 * (node)), MCFG_BUS_ANY, \ | ||
84 | &thunder_pem_ecam_ops, THUNDER_PEM_RES(0x884057000000UL, node) }, \ | ||
85 | { "CAVIUM", "THUNDERX", rev, 6 + (10 * (node)), MCFG_BUS_ANY, \ | ||
86 | &thunder_pem_ecam_ops, THUNDER_PEM_RES(0x88808f000000UL, node) }, \ | ||
87 | { "CAVIUM", "THUNDERX", rev, 7 + (10 * (node)), MCFG_BUS_ANY, \ | ||
88 | &thunder_pem_ecam_ops, THUNDER_PEM_RES(0x89001f000000UL, node) }, \ | ||
89 | { "CAVIUM", "THUNDERX", rev, 8 + (10 * (node)), MCFG_BUS_ANY, \ | ||
90 | &thunder_pem_ecam_ops, THUNDER_PEM_RES(0x894057000000UL, node) }, \ | ||
91 | { "CAVIUM", "THUNDERX", rev, 9 + (10 * (node)), MCFG_BUS_ANY, \ | ||
92 | &thunder_pem_ecam_ops, THUNDER_PEM_RES(0x89808f000000UL, node) } | ||
93 | /* SoC pass2.x */ | ||
94 | THUNDER_PEM_QUIRK(1, 0), | ||
95 | THUNDER_PEM_QUIRK(1, 1), | ||
96 | |||
97 | #define THUNDER_ECAM_QUIRK(rev, seg) \ | ||
98 | { "CAVIUM", "THUNDERX", rev, seg, MCFG_BUS_ANY, \ | ||
99 | &pci_thunder_ecam_ops } | ||
100 | /* SoC pass1.x */ | ||
101 | THUNDER_PEM_QUIRK(2, 0), /* off-chip devices */ | ||
102 | THUNDER_PEM_QUIRK(2, 1), /* off-chip devices */ | ||
103 | THUNDER_ECAM_QUIRK(2, 0), | ||
104 | THUNDER_ECAM_QUIRK(2, 1), | ||
105 | THUNDER_ECAM_QUIRK(2, 2), | ||
106 | THUNDER_ECAM_QUIRK(2, 3), | ||
107 | THUNDER_ECAM_QUIRK(2, 10), | ||
108 | THUNDER_ECAM_QUIRK(2, 11), | ||
109 | THUNDER_ECAM_QUIRK(2, 12), | ||
110 | THUNDER_ECAM_QUIRK(2, 13), | ||
111 | |||
112 | #define XGENE_V1_ECAM_MCFG(rev, seg) \ | ||
113 | {"APM ", "XGENE ", rev, seg, MCFG_BUS_ANY, \ | ||
114 | &xgene_v1_pcie_ecam_ops } | ||
115 | #define XGENE_V2_ECAM_MCFG(rev, seg) \ | ||
116 | {"APM ", "XGENE ", rev, seg, MCFG_BUS_ANY, \ | ||
117 | &xgene_v2_pcie_ecam_ops } | ||
118 | /* X-Gene SoC with v1 PCIe controller */ | ||
119 | XGENE_V1_ECAM_MCFG(1, 0), | ||
120 | XGENE_V1_ECAM_MCFG(1, 1), | ||
121 | XGENE_V1_ECAM_MCFG(1, 2), | ||
122 | XGENE_V1_ECAM_MCFG(1, 3), | ||
123 | XGENE_V1_ECAM_MCFG(1, 4), | ||
124 | XGENE_V1_ECAM_MCFG(2, 0), | ||
125 | XGENE_V1_ECAM_MCFG(2, 1), | ||
126 | XGENE_V1_ECAM_MCFG(2, 2), | ||
127 | XGENE_V1_ECAM_MCFG(2, 3), | ||
128 | XGENE_V1_ECAM_MCFG(2, 4), | ||
129 | /* X-Gene SoC with v2.1 PCIe controller */ | ||
130 | XGENE_V2_ECAM_MCFG(3, 0), | ||
131 | XGENE_V2_ECAM_MCFG(3, 1), | ||
132 | /* X-Gene SoC with v2.2 PCIe controller */ | ||
133 | XGENE_V2_ECAM_MCFG(4, 0), | ||
134 | XGENE_V2_ECAM_MCFG(4, 1), | ||
135 | XGENE_V2_ECAM_MCFG(4, 2), | ||
136 | }; | ||
137 | |||
138 | static char mcfg_oem_id[ACPI_OEM_ID_SIZE]; | ||
139 | static char mcfg_oem_table_id[ACPI_OEM_TABLE_ID_SIZE]; | ||
140 | static u32 mcfg_oem_revision; | ||
141 | |||
142 | static int pci_mcfg_quirk_matches(struct mcfg_fixup *f, u16 segment, | ||
143 | struct resource *bus_range) | ||
144 | { | ||
145 | if (!memcmp(f->oem_id, mcfg_oem_id, ACPI_OEM_ID_SIZE) && | ||
146 | !memcmp(f->oem_table_id, mcfg_oem_table_id, | ||
147 | ACPI_OEM_TABLE_ID_SIZE) && | ||
148 | f->oem_revision == mcfg_oem_revision && | ||
149 | f->segment == segment && | ||
150 | resource_contains(&f->bus_range, bus_range)) | ||
151 | return 1; | ||
152 | |||
153 | return 0; | ||
154 | } | ||
155 | #endif | ||
156 | |||
157 | static void pci_mcfg_apply_quirks(struct acpi_pci_root *root, | ||
158 | struct resource *cfgres, | ||
159 | struct pci_ecam_ops **ecam_ops) | ||
160 | { | ||
161 | #ifdef CONFIG_PCI_QUIRKS | ||
162 | u16 segment = root->segment; | ||
163 | struct resource *bus_range = &root->secondary; | ||
164 | struct mcfg_fixup *f; | ||
165 | int i; | ||
166 | |||
167 | for (i = 0, f = mcfg_quirks; i < ARRAY_SIZE(mcfg_quirks); i++, f++) { | ||
168 | if (pci_mcfg_quirk_matches(f, segment, bus_range)) { | ||
169 | if (f->cfgres.start) | ||
170 | *cfgres = f->cfgres; | ||
171 | if (f->ops) | ||
172 | *ecam_ops = f->ops; | ||
173 | dev_info(&root->device->dev, "MCFG quirk: ECAM at %pR for %pR with %ps\n", | ||
174 | cfgres, bus_range, *ecam_ops); | ||
175 | return; | ||
176 | } | ||
177 | } | ||
178 | #endif | ||
179 | } | ||
180 | |||
35 | /* List to save MCFG entries */ | 181 | /* List to save MCFG entries */ |
36 | static LIST_HEAD(pci_mcfg_list); | 182 | static LIST_HEAD(pci_mcfg_list); |
37 | 183 | ||
38 | phys_addr_t pci_mcfg_lookup(u16 seg, struct resource *bus_res) | 184 | int pci_mcfg_lookup(struct acpi_pci_root *root, struct resource *cfgres, |
185 | struct pci_ecam_ops **ecam_ops) | ||
39 | { | 186 | { |
187 | struct pci_ecam_ops *ops = &pci_generic_ecam_ops; | ||
188 | struct resource *bus_res = &root->secondary; | ||
189 | u16 seg = root->segment; | ||
40 | struct mcfg_entry *e; | 190 | struct mcfg_entry *e; |
191 | struct resource res; | ||
192 | |||
193 | /* Use address from _CBA if present, otherwise lookup MCFG */ | ||
194 | if (root->mcfg_addr) | ||
195 | goto skip_lookup; | ||
41 | 196 | ||
42 | /* | 197 | /* |
43 | * We expect exact match, unless MCFG entry end bus covers more than | 198 | * 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) | |||
45 | */ | 200 | */ |
46 | list_for_each_entry(e, &pci_mcfg_list, list) { | 201 | list_for_each_entry(e, &pci_mcfg_list, list) { |
47 | if (e->segment == seg && e->bus_start == bus_res->start && | 202 | if (e->segment == seg && e->bus_start == bus_res->start && |
48 | e->bus_end >= bus_res->end) | 203 | e->bus_end >= bus_res->end) { |
49 | return e->addr; | 204 | root->mcfg_addr = e->addr; |
205 | } | ||
206 | |||
207 | } | ||
208 | |||
209 | skip_lookup: | ||
210 | memset(&res, 0, sizeof(res)); | ||
211 | if (root->mcfg_addr) { | ||
212 | res.start = root->mcfg_addr + (bus_res->start << 20); | ||
213 | res.end = res.start + (resource_size(bus_res) << 20) - 1; | ||
214 | res.flags = IORESOURCE_MEM; | ||
50 | } | 215 | } |
51 | 216 | ||
217 | /* | ||
218 | * Allow quirks to override default ECAM ops and CFG resource | ||
219 | * range. This may even fabricate a CFG resource range in case | ||
220 | * MCFG does not have it. Invalid CFG start address means MCFG | ||
221 | * firmware bug or we need another quirk in array. | ||
222 | */ | ||
223 | pci_mcfg_apply_quirks(root, &res, &ops); | ||
224 | if (!res.start) | ||
225 | return -ENXIO; | ||
226 | |||
227 | *cfgres = res; | ||
228 | *ecam_ops = ops; | ||
52 | return 0; | 229 | return 0; |
53 | } | 230 | } |
54 | 231 | ||
@@ -79,6 +256,13 @@ static __init int pci_mcfg_parse(struct acpi_table_header *header) | |||
79 | list_add(&e->list, &pci_mcfg_list); | 256 | list_add(&e->list, &pci_mcfg_list); |
80 | } | 257 | } |
81 | 258 | ||
259 | #ifdef CONFIG_PCI_QUIRKS | ||
260 | /* Save MCFG IDs and revision for quirks matching */ | ||
261 | memcpy(mcfg_oem_id, header->oem_id, ACPI_OEM_ID_SIZE); | ||
262 | memcpy(mcfg_oem_table_id, header->oem_table_id, ACPI_OEM_TABLE_ID_SIZE); | ||
263 | mcfg_oem_revision = header->oem_revision; | ||
264 | #endif | ||
265 | |||
82 | pr_info("MCFG table detected, %d entries\n", n); | 266 | pr_info("MCFG table detected, %d entries\n", n); |
83 | return 0; | 267 | return 0; |
84 | } | 268 | } |
diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c index 56241eb341f4..cb57962ef7c4 100644 --- a/drivers/acpi/resource.c +++ b/drivers/acpi/resource.c | |||
@@ -664,3 +664,60 @@ int acpi_dev_filter_resource_type(struct acpi_resource *ares, | |||
664 | return (type & types) ? 0 : 1; | 664 | return (type & types) ? 0 : 1; |
665 | } | 665 | } |
666 | EXPORT_SYMBOL_GPL(acpi_dev_filter_resource_type); | 666 | EXPORT_SYMBOL_GPL(acpi_dev_filter_resource_type); |
667 | |||
668 | static int acpi_dev_consumes_res(struct acpi_device *adev, struct resource *res) | ||
669 | { | ||
670 | struct list_head resource_list; | ||
671 | struct resource_entry *rentry; | ||
672 | int ret, found = 0; | ||
673 | |||
674 | INIT_LIST_HEAD(&resource_list); | ||
675 | ret = acpi_dev_get_resources(adev, &resource_list, NULL, NULL); | ||
676 | if (ret < 0) | ||
677 | return 0; | ||
678 | |||
679 | list_for_each_entry(rentry, &resource_list, node) { | ||
680 | if (resource_contains(rentry->res, res)) { | ||
681 | found = 1; | ||
682 | break; | ||
683 | } | ||
684 | |||
685 | } | ||
686 | |||
687 | acpi_dev_free_resource_list(&resource_list); | ||
688 | return found; | ||
689 | } | ||
690 | |||
691 | static acpi_status acpi_res_consumer_cb(acpi_handle handle, u32 depth, | ||
692 | void *context, void **ret) | ||
693 | { | ||
694 | struct resource *res = context; | ||
695 | struct acpi_device **consumer = (struct acpi_device **) ret; | ||
696 | struct acpi_device *adev; | ||
697 | |||
698 | if (acpi_bus_get_device(handle, &adev)) | ||
699 | return AE_OK; | ||
700 | |||
701 | if (acpi_dev_consumes_res(adev, res)) { | ||
702 | *consumer = adev; | ||
703 | return AE_CTRL_TERMINATE; | ||
704 | } | ||
705 | |||
706 | return AE_OK; | ||
707 | } | ||
708 | |||
709 | /** | ||
710 | * acpi_resource_consumer - Find the ACPI device that consumes @res. | ||
711 | * @res: Resource to search for. | ||
712 | * | ||
713 | * Search the current resource settings (_CRS) of every ACPI device node | ||
714 | * for @res. If we find an ACPI device whose _CRS includes @res, return | ||
715 | * it. Otherwise, return NULL. | ||
716 | */ | ||
717 | struct acpi_device *acpi_resource_consumer(struct resource *res) | ||
718 | { | ||
719 | struct acpi_device *consumer = NULL; | ||
720 | |||
721 | acpi_get_devices(NULL, acpi_res_consumer_cb, res, (void **) &consumer); | ||
722 | return consumer; | ||
723 | } | ||
diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c index 7183ac4135d2..62788b7c728d 100644 --- a/drivers/net/ethernet/mellanox/mlx4/main.c +++ b/drivers/net/ethernet/mellanox/mlx4/main.c | |||
@@ -4012,49 +4012,51 @@ int mlx4_restart_one(struct pci_dev *pdev) | |||
4012 | return err; | 4012 | return err; |
4013 | } | 4013 | } |
4014 | 4014 | ||
4015 | #define MLX_SP(id) { PCI_VDEVICE(MELLANOX, id), MLX4_PCI_DEV_FORCE_SENSE_PORT } | ||
4016 | #define MLX_VF(id) { PCI_VDEVICE(MELLANOX, id), MLX4_PCI_DEV_IS_VF } | ||
4017 | #define MLX_GN(id) { PCI_VDEVICE(MELLANOX, id), 0 } | ||
4018 | |||
4015 | static const struct pci_device_id mlx4_pci_table[] = { | 4019 | static const struct pci_device_id mlx4_pci_table[] = { |
4016 | /* MT25408 "Hermon" SDR */ | 4020 | /* MT25408 "Hermon" */ |
4017 | { PCI_VDEVICE(MELLANOX, 0x6340), MLX4_PCI_DEV_FORCE_SENSE_PORT }, | 4021 | MLX_SP(PCI_DEVICE_ID_MELLANOX_HERMON_SDR), /* SDR */ |
4018 | /* MT25408 "Hermon" DDR */ | 4022 | MLX_SP(PCI_DEVICE_ID_MELLANOX_HERMON_DDR), /* DDR */ |
4019 | { PCI_VDEVICE(MELLANOX, 0x634a), MLX4_PCI_DEV_FORCE_SENSE_PORT }, | 4023 | MLX_SP(PCI_DEVICE_ID_MELLANOX_HERMON_QDR), /* QDR */ |
4020 | /* MT25408 "Hermon" QDR */ | 4024 | MLX_SP(PCI_DEVICE_ID_MELLANOX_HERMON_DDR_GEN2), /* DDR Gen2 */ |
4021 | { PCI_VDEVICE(MELLANOX, 0x6354), MLX4_PCI_DEV_FORCE_SENSE_PORT }, | 4025 | MLX_SP(PCI_DEVICE_ID_MELLANOX_HERMON_QDR_GEN2), /* QDR Gen2 */ |
4022 | /* MT25408 "Hermon" DDR PCIe gen2 */ | 4026 | MLX_SP(PCI_DEVICE_ID_MELLANOX_HERMON_EN), /* EN 10GigE */ |
4023 | { PCI_VDEVICE(MELLANOX, 0x6732), MLX4_PCI_DEV_FORCE_SENSE_PORT }, | 4027 | MLX_SP(PCI_DEVICE_ID_MELLANOX_HERMON_EN_GEN2), /* EN 10GigE Gen2 */ |
4024 | /* MT25408 "Hermon" QDR PCIe gen2 */ | 4028 | /* MT25458 ConnectX EN 10GBASE-T */ |
4025 | { PCI_VDEVICE(MELLANOX, 0x673c), MLX4_PCI_DEV_FORCE_SENSE_PORT }, | 4029 | MLX_SP(PCI_DEVICE_ID_MELLANOX_CONNECTX_EN), |
4026 | /* MT25408 "Hermon" EN 10GigE */ | 4030 | MLX_SP(PCI_DEVICE_ID_MELLANOX_CONNECTX_EN_T_GEN2), /* Gen2 */ |
4027 | { PCI_VDEVICE(MELLANOX, 0x6368), MLX4_PCI_DEV_FORCE_SENSE_PORT }, | 4031 | /* MT26468 ConnectX EN 10GigE PCIe Gen2*/ |
4028 | /* MT25408 "Hermon" EN 10GigE PCIe gen2 */ | 4032 | MLX_SP(PCI_DEVICE_ID_MELLANOX_CONNECTX_EN_GEN2), |
4029 | { PCI_VDEVICE(MELLANOX, 0x6750), MLX4_PCI_DEV_FORCE_SENSE_PORT }, | 4033 | /* MT26438 ConnectX EN 40GigE PCIe Gen2 5GT/s */ |
4030 | /* MT25458 ConnectX EN 10GBASE-T 10GigE */ | 4034 | MLX_SP(PCI_DEVICE_ID_MELLANOX_CONNECTX_EN_5_GEN2), |
4031 | { PCI_VDEVICE(MELLANOX, 0x6372), MLX4_PCI_DEV_FORCE_SENSE_PORT }, | 4035 | /* MT26478 ConnectX2 40GigE PCIe Gen2 */ |
4032 | /* MT25458 ConnectX EN 10GBASE-T+Gen2 10GigE */ | 4036 | MLX_SP(PCI_DEVICE_ID_MELLANOX_CONNECTX2), |
4033 | { PCI_VDEVICE(MELLANOX, 0x675a), MLX4_PCI_DEV_FORCE_SENSE_PORT }, | 4037 | /* MT25400 Family [ConnectX-2] */ |
4034 | /* MT26468 ConnectX EN 10GigE PCIe gen2*/ | 4038 | MLX_VF(0x1002), /* Virtual Function */ |
4035 | { PCI_VDEVICE(MELLANOX, 0x6764), MLX4_PCI_DEV_FORCE_SENSE_PORT }, | ||
4036 | /* MT26438 ConnectX EN 40GigE PCIe gen2 5GT/s */ | ||
4037 | { PCI_VDEVICE(MELLANOX, 0x6746), MLX4_PCI_DEV_FORCE_SENSE_PORT }, | ||
4038 | /* MT26478 ConnectX2 40GigE PCIe gen2 */ | ||
4039 | { PCI_VDEVICE(MELLANOX, 0x676e), MLX4_PCI_DEV_FORCE_SENSE_PORT }, | ||
4040 | /* MT25400 Family [ConnectX-2 Virtual Function] */ | ||
4041 | { PCI_VDEVICE(MELLANOX, 0x1002), MLX4_PCI_DEV_IS_VF }, | ||
4042 | /* MT27500 Family [ConnectX-3] */ | 4039 | /* MT27500 Family [ConnectX-3] */ |
4043 | { PCI_VDEVICE(MELLANOX, 0x1003), 0 }, | 4040 | MLX_GN(PCI_DEVICE_ID_MELLANOX_CONNECTX3), |
4044 | /* MT27500 Family [ConnectX-3 Virtual Function] */ | 4041 | MLX_VF(0x1004), /* Virtual Function */ |
4045 | { PCI_VDEVICE(MELLANOX, 0x1004), MLX4_PCI_DEV_IS_VF }, | 4042 | MLX_GN(0x1005), /* MT27510 Family */ |
4046 | { PCI_VDEVICE(MELLANOX, 0x1005), 0 }, /* MT27510 Family */ | 4043 | MLX_GN(0x1006), /* MT27511 Family */ |
4047 | { PCI_VDEVICE(MELLANOX, 0x1006), 0 }, /* MT27511 Family */ | 4044 | MLX_GN(PCI_DEVICE_ID_MELLANOX_CONNECTX3_PRO), /* MT27520 Family */ |
4048 | { PCI_VDEVICE(MELLANOX, 0x1007), 0 }, /* MT27520 Family */ | 4045 | MLX_GN(0x1008), /* MT27521 Family */ |
4049 | { PCI_VDEVICE(MELLANOX, 0x1008), 0 }, /* MT27521 Family */ | 4046 | MLX_GN(0x1009), /* MT27530 Family */ |
4050 | { PCI_VDEVICE(MELLANOX, 0x1009), 0 }, /* MT27530 Family */ | 4047 | MLX_GN(0x100a), /* MT27531 Family */ |
4051 | { PCI_VDEVICE(MELLANOX, 0x100a), 0 }, /* MT27531 Family */ | 4048 | MLX_GN(0x100b), /* MT27540 Family */ |
4052 | { PCI_VDEVICE(MELLANOX, 0x100b), 0 }, /* MT27540 Family */ | 4049 | MLX_GN(0x100c), /* MT27541 Family */ |
4053 | { PCI_VDEVICE(MELLANOX, 0x100c), 0 }, /* MT27541 Family */ | 4050 | MLX_GN(0x100d), /* MT27550 Family */ |
4054 | { PCI_VDEVICE(MELLANOX, 0x100d), 0 }, /* MT27550 Family */ | 4051 | MLX_GN(0x100e), /* MT27551 Family */ |
4055 | { PCI_VDEVICE(MELLANOX, 0x100e), 0 }, /* MT27551 Family */ | 4052 | MLX_GN(0x100f), /* MT27560 Family */ |
4056 | { PCI_VDEVICE(MELLANOX, 0x100f), 0 }, /* MT27560 Family */ | 4053 | MLX_GN(0x1010), /* MT27561 Family */ |
4057 | { PCI_VDEVICE(MELLANOX, 0x1010), 0 }, /* MT27561 Family */ | 4054 | |
4055 | /* | ||
4056 | * See the mellanox_check_broken_intx_masking() quirk when | ||
4057 | * adding devices | ||
4058 | */ | ||
4059 | |||
4058 | { 0, } | 4060 | { 0, } |
4059 | }; | 4061 | }; |
4060 | 4062 | ||
diff --git a/drivers/of/of_pci.c b/drivers/of/of_pci.c index b58be12ab277..0ee42c3e66a1 100644 --- a/drivers/of/of_pci.c +++ b/drivers/of/of_pci.c | |||
@@ -120,6 +120,27 @@ int of_get_pci_domain_nr(struct device_node *node) | |||
120 | EXPORT_SYMBOL_GPL(of_get_pci_domain_nr); | 120 | EXPORT_SYMBOL_GPL(of_get_pci_domain_nr); |
121 | 121 | ||
122 | /** | 122 | /** |
123 | * This function will try to find the limitation of link speed by finding | ||
124 | * a property called "max-link-speed" of the given device node. | ||
125 | * | ||
126 | * @node: device tree node with the max link speed information | ||
127 | * | ||
128 | * Returns the associated max link speed from DT, or a negative value if the | ||
129 | * required property is not found or is invalid. | ||
130 | */ | ||
131 | int of_pci_get_max_link_speed(struct device_node *node) | ||
132 | { | ||
133 | u32 max_link_speed; | ||
134 | |||
135 | if (of_property_read_u32(node, "max-link-speed", &max_link_speed) || | ||
136 | max_link_speed > 4) | ||
137 | return -EINVAL; | ||
138 | |||
139 | return max_link_speed; | ||
140 | } | ||
141 | EXPORT_SYMBOL_GPL(of_pci_get_max_link_speed); | ||
142 | |||
143 | /** | ||
123 | * of_pci_check_probe_only - Setup probe only mode if linux,pci-probe-only | 144 | * of_pci_check_probe_only - Setup probe only mode if linux,pci-probe-only |
124 | * is present and valid | 145 | * is present and valid |
125 | */ | 146 | */ |
diff --git a/drivers/pci/access.c b/drivers/pci/access.c index d11cdbb8fba3..db239547fefd 100644 --- a/drivers/pci/access.c +++ b/drivers/pci/access.c | |||
@@ -142,10 +142,22 @@ int pci_generic_config_write32(struct pci_bus *bus, unsigned int devfn, | |||
142 | if (size == 4) { | 142 | if (size == 4) { |
143 | writel(val, addr); | 143 | writel(val, addr); |
144 | return PCIBIOS_SUCCESSFUL; | 144 | return PCIBIOS_SUCCESSFUL; |
145 | } else { | ||
146 | mask = ~(((1 << (size * 8)) - 1) << ((where & 0x3) * 8)); | ||
147 | } | 145 | } |
148 | 146 | ||
147 | /* | ||
148 | * In general, hardware that supports only 32-bit writes on PCI is | ||
149 | * not spec-compliant. For example, software may perform a 16-bit | ||
150 | * write. If the hardware only supports 32-bit accesses, we must | ||
151 | * do a 32-bit read, merge in the 16 bits we intend to write, | ||
152 | * followed by a 32-bit write. If the 16 bits we *don't* intend to | ||
153 | * write happen to have any RW1C (write-one-to-clear) bits set, we | ||
154 | * just inadvertently cleared something we shouldn't have. | ||
155 | */ | ||
156 | dev_warn_ratelimited(&bus->dev, "%d-byte config write to %04x:%02x:%02x.%d offset %#x may corrupt adjacent RW1C bits\n", | ||
157 | size, pci_domain_nr(bus), bus->number, | ||
158 | PCI_SLOT(devfn), PCI_FUNC(devfn), where); | ||
159 | |||
160 | mask = ~(((1 << (size * 8)) - 1) << ((where & 0x3) * 8)); | ||
149 | tmp = readl(addr) & mask; | 161 | tmp = readl(addr) & mask; |
150 | tmp |= val << ((where & 0x3) * 8); | 162 | tmp |= val << ((where & 0x3) * 8); |
151 | writel(tmp, addr); | 163 | writel(tmp, addr); |
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c index c288e5a52575..bc56cf19afd3 100644 --- a/drivers/pci/bus.c +++ b/drivers/pci/bus.c | |||
@@ -320,7 +320,7 @@ void pci_bus_add_device(struct pci_dev *dev) | |||
320 | pci_fixup_device(pci_fixup_final, dev); | 320 | pci_fixup_device(pci_fixup_final, dev); |
321 | pci_create_sysfs_dev_files(dev); | 321 | pci_create_sysfs_dev_files(dev); |
322 | pci_proc_attach_device(dev); | 322 | pci_proc_attach_device(dev); |
323 | pci_bridge_d3_device_changed(dev); | 323 | pci_bridge_d3_update(dev); |
324 | 324 | ||
325 | dev->match_driver = true; | 325 | dev->match_driver = true; |
326 | retval = device_attach(&dev->dev); | 326 | retval = device_attach(&dev->dev); |
diff --git a/drivers/pci/ecam.c b/drivers/pci/ecam.c index 43ed08dd8b01..2fee61bb6559 100644 --- a/drivers/pci/ecam.c +++ b/drivers/pci/ecam.c | |||
@@ -162,3 +162,15 @@ struct pci_ecam_ops pci_generic_ecam_ops = { | |||
162 | .write = pci_generic_config_write, | 162 | .write = pci_generic_config_write, |
163 | } | 163 | } |
164 | }; | 164 | }; |
165 | |||
166 | #if defined(CONFIG_ACPI) && defined(CONFIG_PCI_QUIRKS) | ||
167 | /* ECAM ops for 32-bit access only (non-compliant) */ | ||
168 | struct pci_ecam_ops pci_32b_ops = { | ||
169 | .bus_shift = 20, | ||
170 | .pci_ops = { | ||
171 | .map_bus = pci_ecam_map_bus, | ||
172 | .read = pci_generic_config_read32, | ||
173 | .write = pci_generic_config_write32, | ||
174 | } | ||
175 | }; | ||
176 | #endif | ||
diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig index e020359b09bc..898d2c48239c 100644 --- a/drivers/pci/host/Kconfig +++ b/drivers/pci/host/Kconfig | |||
@@ -69,7 +69,7 @@ config PCI_IMX6 | |||
69 | 69 | ||
70 | config PCI_TEGRA | 70 | config PCI_TEGRA |
71 | bool "NVIDIA Tegra PCIe controller" | 71 | bool "NVIDIA Tegra PCIe controller" |
72 | depends on ARCH_TEGRA && !ARM64 | 72 | depends on ARCH_TEGRA |
73 | help | 73 | help |
74 | Say Y here if you want support for the PCIe host controller found | 74 | Say Y here if you want support for the PCIe host controller found |
75 | on NVIDIA Tegra SoCs. | 75 | on NVIDIA Tegra SoCs. |
@@ -133,8 +133,8 @@ config PCIE_XILINX | |||
133 | 133 | ||
134 | config PCI_XGENE | 134 | config PCI_XGENE |
135 | bool "X-Gene PCIe controller" | 135 | bool "X-Gene PCIe controller" |
136 | depends on ARCH_XGENE | 136 | depends on ARM64 |
137 | depends on OF | 137 | depends on OF || (ACPI && PCI_QUIRKS) |
138 | select PCIEPORTBUS | 138 | select PCIEPORTBUS |
139 | help | 139 | help |
140 | Say Y here if you want internal PCI support on APM X-Gene SoC. | 140 | Say Y here if you want internal PCI support on APM X-Gene SoC. |
@@ -240,14 +240,16 @@ config PCIE_QCOM | |||
240 | 240 | ||
241 | config PCI_HOST_THUNDER_PEM | 241 | config PCI_HOST_THUNDER_PEM |
242 | bool "Cavium Thunder PCIe controller to off-chip devices" | 242 | bool "Cavium Thunder PCIe controller to off-chip devices" |
243 | depends on OF && ARM64 | 243 | depends on ARM64 |
244 | depends on OF || (ACPI && PCI_QUIRKS) | ||
244 | select PCI_HOST_COMMON | 245 | select PCI_HOST_COMMON |
245 | help | 246 | help |
246 | Say Y here if you want PCIe support for CN88XX Cavium Thunder SoCs. | 247 | Say Y here if you want PCIe support for CN88XX Cavium Thunder SoCs. |
247 | 248 | ||
248 | config PCI_HOST_THUNDER_ECAM | 249 | config PCI_HOST_THUNDER_ECAM |
249 | bool "Cavium Thunder ECAM controller to on-chip devices on pass-1.x silicon" | 250 | bool "Cavium Thunder ECAM controller to on-chip devices on pass-1.x silicon" |
250 | depends on OF && ARM64 | 251 | depends on ARM64 |
252 | depends on OF || (ACPI && PCI_QUIRKS) | ||
251 | select PCI_HOST_COMMON | 253 | select PCI_HOST_COMMON |
252 | help | 254 | help |
253 | Say Y here if you want ECAM support for CN88XX-Pass-1.x Cavium Thunder SoCs. | 255 | Say Y here if you want ECAM support for CN88XX-Pass-1.x Cavium Thunder SoCs. |
@@ -276,7 +278,7 @@ config PCIE_ARTPEC6 | |||
276 | 278 | ||
277 | config PCIE_ROCKCHIP | 279 | config PCIE_ROCKCHIP |
278 | bool "Rockchip PCIe controller" | 280 | bool "Rockchip PCIe controller" |
279 | depends on ARCH_ROCKCHIP | 281 | depends on ARCH_ROCKCHIP || COMPILE_TEST |
280 | depends on OF | 282 | depends on OF |
281 | depends on PCI_MSI_IRQ_DOMAIN | 283 | depends on PCI_MSI_IRQ_DOMAIN |
282 | select MFD_SYSCON | 284 | select MFD_SYSCON |
diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile index 084cb4983645..bfe3179ae74c 100644 --- a/drivers/pci/host/Makefile +++ b/drivers/pci/host/Makefile | |||
@@ -15,7 +15,6 @@ obj-$(CONFIG_PCIE_SPEAR13XX) += pcie-spear13xx.o | |||
15 | obj-$(CONFIG_PCI_KEYSTONE) += pci-keystone-dw.o pci-keystone.o | 15 | obj-$(CONFIG_PCI_KEYSTONE) += pci-keystone-dw.o pci-keystone.o |
16 | obj-$(CONFIG_PCIE_XILINX) += pcie-xilinx.o | 16 | obj-$(CONFIG_PCIE_XILINX) += pcie-xilinx.o |
17 | obj-$(CONFIG_PCIE_XILINX_NWL) += pcie-xilinx-nwl.o | 17 | obj-$(CONFIG_PCIE_XILINX_NWL) += pcie-xilinx-nwl.o |
18 | obj-$(CONFIG_PCI_XGENE) += pci-xgene.o | ||
19 | obj-$(CONFIG_PCI_XGENE_MSI) += pci-xgene-msi.o | 18 | obj-$(CONFIG_PCI_XGENE_MSI) += pci-xgene-msi.o |
20 | obj-$(CONFIG_PCI_LAYERSCAPE) += pci-layerscape.o | 19 | obj-$(CONFIG_PCI_LAYERSCAPE) += pci-layerscape.o |
21 | obj-$(CONFIG_PCI_VERSATILE) += pci-versatile.o | 20 | obj-$(CONFIG_PCI_VERSATILE) += pci-versatile.o |
@@ -25,11 +24,23 @@ obj-$(CONFIG_PCIE_IPROC_PLATFORM) += pcie-iproc-platform.o | |||
25 | obj-$(CONFIG_PCIE_IPROC_BCMA) += pcie-iproc-bcma.o | 24 | obj-$(CONFIG_PCIE_IPROC_BCMA) += pcie-iproc-bcma.o |
26 | obj-$(CONFIG_PCIE_ALTERA) += pcie-altera.o | 25 | obj-$(CONFIG_PCIE_ALTERA) += pcie-altera.o |
27 | obj-$(CONFIG_PCIE_ALTERA_MSI) += pcie-altera-msi.o | 26 | obj-$(CONFIG_PCIE_ALTERA_MSI) += pcie-altera-msi.o |
28 | obj-$(CONFIG_PCI_HISI) += pcie-hisi.o | ||
29 | obj-$(CONFIG_PCIE_QCOM) += pcie-qcom.o | 27 | obj-$(CONFIG_PCIE_QCOM) += pcie-qcom.o |
30 | obj-$(CONFIG_PCI_HOST_THUNDER_ECAM) += pci-thunder-ecam.o | ||
31 | obj-$(CONFIG_PCI_HOST_THUNDER_PEM) += pci-thunder-pem.o | ||
32 | obj-$(CONFIG_PCIE_ARMADA_8K) += pcie-armada8k.o | 28 | obj-$(CONFIG_PCIE_ARMADA_8K) += pcie-armada8k.o |
33 | obj-$(CONFIG_PCIE_ARTPEC6) += pcie-artpec6.o | 29 | obj-$(CONFIG_PCIE_ARTPEC6) += pcie-artpec6.o |
34 | obj-$(CONFIG_PCIE_ROCKCHIP) += pcie-rockchip.o | 30 | obj-$(CONFIG_PCIE_ROCKCHIP) += pcie-rockchip.o |
35 | obj-$(CONFIG_VMD) += vmd.o | 31 | obj-$(CONFIG_VMD) += vmd.o |
32 | |||
33 | # The following drivers are for devices that use the generic ACPI | ||
34 | # pci_root.c driver but don't support standard ECAM config access. | ||
35 | # They contain MCFG quirks to replace the generic ECAM accessors with | ||
36 | # device-specific ones that are shared with the DT driver. | ||
37 | |||
38 | # The ACPI driver is generic and should not require driver-specific | ||
39 | # config options to be enabled, so we always build these drivers on | ||
40 | # ARM64 and use internal ifdefs to only build the pieces we need | ||
41 | # depending on whether ACPI, the DT driver, or both are enabled. | ||
42 | |||
43 | obj-$(CONFIG_ARM64) += pcie-hisi.o | ||
44 | obj-$(CONFIG_ARM64) += pci-thunder-ecam.o | ||
45 | obj-$(CONFIG_ARM64) += pci-thunder-pem.o | ||
46 | obj-$(CONFIG_ARM64) += pci-xgene.o | ||
diff --git a/drivers/pci/host/pci-hyperv.c b/drivers/pci/host/pci-hyperv.c index 763ff8745828..3efcc7bdc5fb 100644 --- a/drivers/pci/host/pci-hyperv.c +++ b/drivers/pci/host/pci-hyperv.c | |||
@@ -378,6 +378,8 @@ struct hv_pcibus_device { | |||
378 | struct msi_domain_info msi_info; | 378 | struct msi_domain_info msi_info; |
379 | struct msi_controller msi_chip; | 379 | struct msi_controller msi_chip; |
380 | struct irq_domain *irq_domain; | 380 | struct irq_domain *irq_domain; |
381 | struct retarget_msi_interrupt retarget_msi_interrupt_params; | ||
382 | spinlock_t retarget_msi_interrupt_lock; | ||
381 | }; | 383 | }; |
382 | 384 | ||
383 | /* | 385 | /* |
@@ -755,7 +757,7 @@ static int hv_set_affinity(struct irq_data *data, const struct cpumask *dest, | |||
755 | return parent->chip->irq_set_affinity(parent, dest, force); | 757 | return parent->chip->irq_set_affinity(parent, dest, force); |
756 | } | 758 | } |
757 | 759 | ||
758 | void hv_irq_mask(struct irq_data *data) | 760 | static void hv_irq_mask(struct irq_data *data) |
759 | { | 761 | { |
760 | pci_msi_mask_irq(data); | 762 | pci_msi_mask_irq(data); |
761 | } | 763 | } |
@@ -770,38 +772,44 @@ void hv_irq_mask(struct irq_data *data) | |||
770 | * is built out of this PCI bus's instance GUID and the function | 772 | * is built out of this PCI bus's instance GUID and the function |
771 | * number of the device. | 773 | * number of the device. |
772 | */ | 774 | */ |
773 | void hv_irq_unmask(struct irq_data *data) | 775 | static void hv_irq_unmask(struct irq_data *data) |
774 | { | 776 | { |
775 | struct msi_desc *msi_desc = irq_data_get_msi_desc(data); | 777 | struct msi_desc *msi_desc = irq_data_get_msi_desc(data); |
776 | struct irq_cfg *cfg = irqd_cfg(data); | 778 | struct irq_cfg *cfg = irqd_cfg(data); |
777 | struct retarget_msi_interrupt params; | 779 | struct retarget_msi_interrupt *params; |
778 | struct hv_pcibus_device *hbus; | 780 | struct hv_pcibus_device *hbus; |
779 | struct cpumask *dest; | 781 | struct cpumask *dest; |
780 | struct pci_bus *pbus; | 782 | struct pci_bus *pbus; |
781 | struct pci_dev *pdev; | 783 | struct pci_dev *pdev; |
782 | int cpu; | 784 | int cpu; |
785 | unsigned long flags; | ||
783 | 786 | ||
784 | dest = irq_data_get_affinity_mask(data); | 787 | dest = irq_data_get_affinity_mask(data); |
785 | pdev = msi_desc_to_pci_dev(msi_desc); | 788 | pdev = msi_desc_to_pci_dev(msi_desc); |
786 | pbus = pdev->bus; | 789 | pbus = pdev->bus; |
787 | hbus = container_of(pbus->sysdata, struct hv_pcibus_device, sysdata); | 790 | hbus = container_of(pbus->sysdata, struct hv_pcibus_device, sysdata); |
788 | 791 | ||
789 | memset(¶ms, 0, sizeof(params)); | 792 | spin_lock_irqsave(&hbus->retarget_msi_interrupt_lock, flags); |
790 | params.partition_id = HV_PARTITION_ID_SELF; | 793 | |
791 | params.source = 1; /* MSI(-X) */ | 794 | params = &hbus->retarget_msi_interrupt_params; |
792 | params.address = msi_desc->msg.address_lo; | 795 | memset(params, 0, sizeof(*params)); |
793 | params.data = msi_desc->msg.data; | 796 | params->partition_id = HV_PARTITION_ID_SELF; |
794 | params.device_id = (hbus->hdev->dev_instance.b[5] << 24) | | 797 | params->source = 1; /* MSI(-X) */ |
798 | params->address = msi_desc->msg.address_lo; | ||
799 | params->data = msi_desc->msg.data; | ||
800 | params->device_id = (hbus->hdev->dev_instance.b[5] << 24) | | ||
795 | (hbus->hdev->dev_instance.b[4] << 16) | | 801 | (hbus->hdev->dev_instance.b[4] << 16) | |
796 | (hbus->hdev->dev_instance.b[7] << 8) | | 802 | (hbus->hdev->dev_instance.b[7] << 8) | |
797 | (hbus->hdev->dev_instance.b[6] & 0xf8) | | 803 | (hbus->hdev->dev_instance.b[6] & 0xf8) | |
798 | PCI_FUNC(pdev->devfn); | 804 | PCI_FUNC(pdev->devfn); |
799 | params.vector = cfg->vector; | 805 | params->vector = cfg->vector; |
800 | 806 | ||
801 | for_each_cpu_and(cpu, dest, cpu_online_mask) | 807 | for_each_cpu_and(cpu, dest, cpu_online_mask) |
802 | params.vp_mask |= (1ULL << vmbus_cpu_number_to_vp_number(cpu)); | 808 | params->vp_mask |= (1ULL << vmbus_cpu_number_to_vp_number(cpu)); |
803 | 809 | ||
804 | hv_do_hypercall(HVCALL_RETARGET_INTERRUPT, ¶ms, NULL); | 810 | hv_do_hypercall(HVCALL_RETARGET_INTERRUPT, params, NULL); |
811 | |||
812 | spin_unlock_irqrestore(&hbus->retarget_msi_interrupt_lock, flags); | ||
805 | 813 | ||
806 | pci_msi_unmask_irq(data); | 814 | pci_msi_unmask_irq(data); |
807 | } | 815 | } |
@@ -1271,9 +1279,9 @@ static struct hv_pci_dev *new_pcichild_device(struct hv_pcibus_device *hbus, | |||
1271 | struct hv_pci_dev *hpdev; | 1279 | struct hv_pci_dev *hpdev; |
1272 | struct pci_child_message *res_req; | 1280 | struct pci_child_message *res_req; |
1273 | struct q_res_req_compl comp_pkt; | 1281 | struct q_res_req_compl comp_pkt; |
1274 | union { | 1282 | struct { |
1275 | struct pci_packet init_packet; | 1283 | struct pci_packet init_packet; |
1276 | u8 buffer[0x100]; | 1284 | u8 buffer[sizeof(struct pci_child_message)]; |
1277 | } pkt; | 1285 | } pkt; |
1278 | unsigned long flags; | 1286 | unsigned long flags; |
1279 | int ret; | 1287 | int ret; |
@@ -1582,6 +1590,10 @@ static void hv_eject_device_work(struct work_struct *work) | |||
1582 | pci_dev_put(pdev); | 1590 | pci_dev_put(pdev); |
1583 | } | 1591 | } |
1584 | 1592 | ||
1593 | spin_lock_irqsave(&hpdev->hbus->device_list_lock, flags); | ||
1594 | list_del(&hpdev->list_entry); | ||
1595 | spin_unlock_irqrestore(&hpdev->hbus->device_list_lock, flags); | ||
1596 | |||
1585 | memset(&ctxt, 0, sizeof(ctxt)); | 1597 | memset(&ctxt, 0, sizeof(ctxt)); |
1586 | ejct_pkt = (struct pci_eject_response *)&ctxt.pkt.message; | 1598 | ejct_pkt = (struct pci_eject_response *)&ctxt.pkt.message; |
1587 | ejct_pkt->message_type.type = PCI_EJECTION_COMPLETE; | 1599 | ejct_pkt->message_type.type = PCI_EJECTION_COMPLETE; |
@@ -1590,10 +1602,6 @@ static void hv_eject_device_work(struct work_struct *work) | |||
1590 | sizeof(*ejct_pkt), (unsigned long)&ctxt.pkt, | 1602 | sizeof(*ejct_pkt), (unsigned long)&ctxt.pkt, |
1591 | VM_PKT_DATA_INBAND, 0); | 1603 | VM_PKT_DATA_INBAND, 0); |
1592 | 1604 | ||
1593 | spin_lock_irqsave(&hpdev->hbus->device_list_lock, flags); | ||
1594 | list_del(&hpdev->list_entry); | ||
1595 | spin_unlock_irqrestore(&hpdev->hbus->device_list_lock, flags); | ||
1596 | |||
1597 | put_pcichild(hpdev, hv_pcidev_ref_childlist); | 1605 | put_pcichild(hpdev, hv_pcidev_ref_childlist); |
1598 | put_pcichild(hpdev, hv_pcidev_ref_pnp); | 1606 | put_pcichild(hpdev, hv_pcidev_ref_pnp); |
1599 | put_hvpcibus(hpdev->hbus); | 1607 | put_hvpcibus(hpdev->hbus); |
@@ -2186,6 +2194,7 @@ static int hv_pci_probe(struct hv_device *hdev, | |||
2186 | INIT_LIST_HEAD(&hbus->resources_for_children); | 2194 | INIT_LIST_HEAD(&hbus->resources_for_children); |
2187 | spin_lock_init(&hbus->config_lock); | 2195 | spin_lock_init(&hbus->config_lock); |
2188 | spin_lock_init(&hbus->device_list_lock); | 2196 | spin_lock_init(&hbus->device_list_lock); |
2197 | spin_lock_init(&hbus->retarget_msi_interrupt_lock); | ||
2189 | sema_init(&hbus->enum_sem, 1); | 2198 | sema_init(&hbus->enum_sem, 1); |
2190 | init_completion(&hbus->remove_event); | 2199 | init_completion(&hbus->remove_event); |
2191 | 2200 | ||
@@ -2266,24 +2275,32 @@ free_bus: | |||
2266 | return ret; | 2275 | return ret; |
2267 | } | 2276 | } |
2268 | 2277 | ||
2269 | /** | 2278 | static void hv_pci_bus_exit(struct hv_device *hdev) |
2270 | * hv_pci_remove() - Remove routine for this VMBus channel | ||
2271 | * @hdev: VMBus's tracking struct for this root PCI bus | ||
2272 | * | ||
2273 | * Return: 0 on success, -errno on failure | ||
2274 | */ | ||
2275 | static int hv_pci_remove(struct hv_device *hdev) | ||
2276 | { | 2279 | { |
2277 | int ret; | 2280 | struct hv_pcibus_device *hbus = hv_get_drvdata(hdev); |
2278 | struct hv_pcibus_device *hbus; | 2281 | struct { |
2279 | union { | ||
2280 | struct pci_packet teardown_packet; | 2282 | struct pci_packet teardown_packet; |
2281 | u8 buffer[0x100]; | 2283 | u8 buffer[sizeof(struct pci_message)]; |
2282 | } pkt; | 2284 | } pkt; |
2283 | struct pci_bus_relations relations; | 2285 | struct pci_bus_relations relations; |
2284 | struct hv_pci_compl comp_pkt; | 2286 | struct hv_pci_compl comp_pkt; |
2287 | int ret; | ||
2285 | 2288 | ||
2286 | hbus = hv_get_drvdata(hdev); | 2289 | /* |
2290 | * After the host sends the RESCIND_CHANNEL message, it doesn't | ||
2291 | * access the per-channel ringbuffer any longer. | ||
2292 | */ | ||
2293 | if (hdev->channel->rescind) | ||
2294 | return; | ||
2295 | |||
2296 | /* Delete any children which might still exist. */ | ||
2297 | memset(&relations, 0, sizeof(relations)); | ||
2298 | hv_pci_devices_present(hbus, &relations); | ||
2299 | |||
2300 | ret = hv_send_resources_released(hdev); | ||
2301 | if (ret) | ||
2302 | dev_err(&hdev->device, | ||
2303 | "Couldn't send resources released packet(s)\n"); | ||
2287 | 2304 | ||
2288 | memset(&pkt.teardown_packet, 0, sizeof(pkt.teardown_packet)); | 2305 | memset(&pkt.teardown_packet, 0, sizeof(pkt.teardown_packet)); |
2289 | init_completion(&comp_pkt.host_event); | 2306 | init_completion(&comp_pkt.host_event); |
@@ -2298,7 +2315,19 @@ static int hv_pci_remove(struct hv_device *hdev) | |||
2298 | VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); | 2315 | VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); |
2299 | if (!ret) | 2316 | if (!ret) |
2300 | wait_for_completion_timeout(&comp_pkt.host_event, 10 * HZ); | 2317 | wait_for_completion_timeout(&comp_pkt.host_event, 10 * HZ); |
2318 | } | ||
2319 | |||
2320 | /** | ||
2321 | * hv_pci_remove() - Remove routine for this VMBus channel | ||
2322 | * @hdev: VMBus's tracking struct for this root PCI bus | ||
2323 | * | ||
2324 | * Return: 0 on success, -errno on failure | ||
2325 | */ | ||
2326 | static int hv_pci_remove(struct hv_device *hdev) | ||
2327 | { | ||
2328 | struct hv_pcibus_device *hbus; | ||
2301 | 2329 | ||
2330 | hbus = hv_get_drvdata(hdev); | ||
2302 | if (hbus->state == hv_pcibus_installed) { | 2331 | if (hbus->state == hv_pcibus_installed) { |
2303 | /* Remove the bus from PCI's point of view. */ | 2332 | /* Remove the bus from PCI's point of view. */ |
2304 | pci_lock_rescan_remove(); | 2333 | pci_lock_rescan_remove(); |
@@ -2307,17 +2336,10 @@ static int hv_pci_remove(struct hv_device *hdev) | |||
2307 | pci_unlock_rescan_remove(); | 2336 | pci_unlock_rescan_remove(); |
2308 | } | 2337 | } |
2309 | 2338 | ||
2310 | ret = hv_send_resources_released(hdev); | 2339 | hv_pci_bus_exit(hdev); |
2311 | if (ret) | ||
2312 | dev_err(&hdev->device, | ||
2313 | "Couldn't send resources released packet(s)\n"); | ||
2314 | 2340 | ||
2315 | vmbus_close(hdev->channel); | 2341 | vmbus_close(hdev->channel); |
2316 | 2342 | ||
2317 | /* Delete any children which might still exist. */ | ||
2318 | memset(&relations, 0, sizeof(relations)); | ||
2319 | hv_pci_devices_present(hbus, &relations); | ||
2320 | |||
2321 | iounmap(hbus->cfg_addr); | 2343 | iounmap(hbus->cfg_addr); |
2322 | hv_free_config_window(hbus); | 2344 | hv_free_config_window(hbus); |
2323 | pci_free_resource_list(&hbus->resources_for_children); | 2345 | pci_free_resource_list(&hbus->resources_for_children); |
diff --git a/drivers/pci/host/pci-layerscape.c b/drivers/pci/host/pci-layerscape.c index 2cb7315e26d0..ea789138531b 100644 --- a/drivers/pci/host/pci-layerscape.c +++ b/drivers/pci/host/pci-layerscape.c | |||
@@ -35,12 +35,10 @@ | |||
35 | #define PCIE_STRFMR1 0x71c /* Symbol Timer & Filter Mask Register1 */ | 35 | #define PCIE_STRFMR1 0x71c /* Symbol Timer & Filter Mask Register1 */ |
36 | #define PCIE_DBI_RO_WR_EN 0x8bc /* DBI Read-Only Write Enable Register */ | 36 | #define PCIE_DBI_RO_WR_EN 0x8bc /* DBI Read-Only Write Enable Register */ |
37 | 37 | ||
38 | /* PEX LUT registers */ | ||
39 | #define PCIE_LUT_DBG 0x7FC /* PEX LUT Debug Register */ | ||
40 | |||
41 | struct ls_pcie_drvdata { | 38 | struct ls_pcie_drvdata { |
42 | u32 lut_offset; | 39 | u32 lut_offset; |
43 | u32 ltssm_shift; | 40 | u32 ltssm_shift; |
41 | u32 lut_dbg; | ||
44 | struct pcie_host_ops *ops; | 42 | struct pcie_host_ops *ops; |
45 | }; | 43 | }; |
46 | 44 | ||
@@ -134,7 +132,7 @@ static int ls_pcie_link_up(struct pcie_port *pp) | |||
134 | struct ls_pcie *pcie = to_ls_pcie(pp); | 132 | struct ls_pcie *pcie = to_ls_pcie(pp); |
135 | u32 state; | 133 | u32 state; |
136 | 134 | ||
137 | state = (ioread32(pcie->lut + PCIE_LUT_DBG) >> | 135 | state = (ioread32(pcie->lut + pcie->drvdata->lut_dbg) >> |
138 | pcie->drvdata->ltssm_shift) & | 136 | pcie->drvdata->ltssm_shift) & |
139 | LTSSM_STATE_MASK; | 137 | LTSSM_STATE_MASK; |
140 | 138 | ||
@@ -196,18 +194,28 @@ static struct ls_pcie_drvdata ls1021_drvdata = { | |||
196 | static struct ls_pcie_drvdata ls1043_drvdata = { | 194 | static struct ls_pcie_drvdata ls1043_drvdata = { |
197 | .lut_offset = 0x10000, | 195 | .lut_offset = 0x10000, |
198 | .ltssm_shift = 24, | 196 | .ltssm_shift = 24, |
197 | .lut_dbg = 0x7fc, | ||
198 | .ops = &ls_pcie_host_ops, | ||
199 | }; | ||
200 | |||
201 | static struct ls_pcie_drvdata ls1046_drvdata = { | ||
202 | .lut_offset = 0x80000, | ||
203 | .ltssm_shift = 24, | ||
204 | .lut_dbg = 0x407fc, | ||
199 | .ops = &ls_pcie_host_ops, | 205 | .ops = &ls_pcie_host_ops, |
200 | }; | 206 | }; |
201 | 207 | ||
202 | static struct ls_pcie_drvdata ls2080_drvdata = { | 208 | static struct ls_pcie_drvdata ls2080_drvdata = { |
203 | .lut_offset = 0x80000, | 209 | .lut_offset = 0x80000, |
204 | .ltssm_shift = 0, | 210 | .ltssm_shift = 0, |
211 | .lut_dbg = 0x7fc, | ||
205 | .ops = &ls_pcie_host_ops, | 212 | .ops = &ls_pcie_host_ops, |
206 | }; | 213 | }; |
207 | 214 | ||
208 | static const struct of_device_id ls_pcie_of_match[] = { | 215 | static const struct of_device_id ls_pcie_of_match[] = { |
209 | { .compatible = "fsl,ls1021a-pcie", .data = &ls1021_drvdata }, | 216 | { .compatible = "fsl,ls1021a-pcie", .data = &ls1021_drvdata }, |
210 | { .compatible = "fsl,ls1043a-pcie", .data = &ls1043_drvdata }, | 217 | { .compatible = "fsl,ls1043a-pcie", .data = &ls1043_drvdata }, |
218 | { .compatible = "fsl,ls1046a-pcie", .data = &ls1046_drvdata }, | ||
211 | { .compatible = "fsl,ls2080a-pcie", .data = &ls2080_drvdata }, | 219 | { .compatible = "fsl,ls2080a-pcie", .data = &ls2080_drvdata }, |
212 | { .compatible = "fsl,ls2085a-pcie", .data = &ls2080_drvdata }, | 220 | { .compatible = "fsl,ls2085a-pcie", .data = &ls2080_drvdata }, |
213 | { }, | 221 | { }, |
@@ -247,16 +255,14 @@ static int __init ls_pcie_probe(struct platform_device *pdev) | |||
247 | 255 | ||
248 | pp = &pcie->pp; | 256 | pp = &pcie->pp; |
249 | pp->dev = dev; | 257 | pp->dev = dev; |
258 | pcie->drvdata = match->data; | ||
250 | pp->ops = pcie->drvdata->ops; | 259 | pp->ops = pcie->drvdata->ops; |
251 | 260 | ||
252 | dbi_base = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs"); | 261 | dbi_base = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs"); |
253 | pcie->pp.dbi_base = devm_ioremap_resource(dev, dbi_base); | 262 | pcie->pp.dbi_base = devm_ioremap_resource(dev, dbi_base); |
254 | if (IS_ERR(pcie->pp.dbi_base)) { | 263 | if (IS_ERR(pcie->pp.dbi_base)) |
255 | dev_err(dev, "missing *regs* space\n"); | ||
256 | return PTR_ERR(pcie->pp.dbi_base); | 264 | return PTR_ERR(pcie->pp.dbi_base); |
257 | } | ||
258 | 265 | ||
259 | pcie->drvdata = match->data; | ||
260 | pcie->lut = pcie->pp.dbi_base + pcie->drvdata->lut_offset; | 266 | pcie->lut = pcie->pp.dbi_base + pcie->drvdata->lut_offset; |
261 | 267 | ||
262 | if (!ls_pcie_is_bridge(pcie)) | 268 | if (!ls_pcie_is_bridge(pcie)) |
diff --git a/drivers/pci/host/pci-rcar-gen2.c b/drivers/pci/host/pci-rcar-gen2.c index 1eeefa4df64c..85348590848b 100644 --- a/drivers/pci/host/pci-rcar-gen2.c +++ b/drivers/pci/host/pci-rcar-gen2.c | |||
@@ -430,10 +430,10 @@ static int rcar_pci_probe(struct platform_device *pdev) | |||
430 | } | 430 | } |
431 | 431 | ||
432 | static struct of_device_id rcar_pci_of_match[] = { | 432 | static struct of_device_id rcar_pci_of_match[] = { |
433 | { .compatible = "renesas,pci-rcar-gen2", }, | ||
434 | { .compatible = "renesas,pci-r8a7790", }, | 433 | { .compatible = "renesas,pci-r8a7790", }, |
435 | { .compatible = "renesas,pci-r8a7791", }, | 434 | { .compatible = "renesas,pci-r8a7791", }, |
436 | { .compatible = "renesas,pci-r8a7794", }, | 435 | { .compatible = "renesas,pci-r8a7794", }, |
436 | { .compatible = "renesas,pci-rcar-gen2", }, | ||
437 | { }, | 437 | { }, |
438 | }; | 438 | }; |
439 | 439 | ||
diff --git a/drivers/pci/host/pci-tegra.c b/drivers/pci/host/pci-tegra.c index 8dfccf733241..ed8a93f2bfb5 100644 --- a/drivers/pci/host/pci-tegra.c +++ b/drivers/pci/host/pci-tegra.c | |||
@@ -51,10 +51,6 @@ | |||
51 | #include <soc/tegra/cpuidle.h> | 51 | #include <soc/tegra/cpuidle.h> |
52 | #include <soc/tegra/pmc.h> | 52 | #include <soc/tegra/pmc.h> |
53 | 53 | ||
54 | #include <asm/mach/irq.h> | ||
55 | #include <asm/mach/map.h> | ||
56 | #include <asm/mach/pci.h> | ||
57 | |||
58 | #define INT_PCI_MSI_NR (8 * 32) | 54 | #define INT_PCI_MSI_NR (8 * 32) |
59 | 55 | ||
60 | /* register definitions */ | 56 | /* register definitions */ |
@@ -188,6 +184,9 @@ | |||
188 | #define RP_VEND_XP 0x00000f00 | 184 | #define RP_VEND_XP 0x00000f00 |
189 | #define RP_VEND_XP_DL_UP (1 << 30) | 185 | #define RP_VEND_XP_DL_UP (1 << 30) |
190 | 186 | ||
187 | #define RP_VEND_CTL2 0x00000fa8 | ||
188 | #define RP_VEND_CTL2_PCA_ENABLE (1 << 7) | ||
189 | |||
191 | #define RP_PRIV_MISC 0x00000fe0 | 190 | #define RP_PRIV_MISC 0x00000fe0 |
192 | #define RP_PRIV_MISC_PRSNT_MAP_EP_PRSNT (0xe << 0) | 191 | #define RP_PRIV_MISC_PRSNT_MAP_EP_PRSNT (0xe << 0) |
193 | #define RP_PRIV_MISC_PRSNT_MAP_EP_ABSNT (0xf << 0) | 192 | #define RP_PRIV_MISC_PRSNT_MAP_EP_ABSNT (0xf << 0) |
@@ -252,6 +251,7 @@ struct tegra_pcie_soc { | |||
252 | bool has_intr_prsnt_sense; | 251 | bool has_intr_prsnt_sense; |
253 | bool has_cml_clk; | 252 | bool has_cml_clk; |
254 | bool has_gen2; | 253 | bool has_gen2; |
254 | bool force_pca_enable; | ||
255 | }; | 255 | }; |
256 | 256 | ||
257 | static inline struct tegra_msi *to_tegra_msi(struct msi_controller *chip) | 257 | static inline struct tegra_msi *to_tegra_msi(struct msi_controller *chip) |
@@ -322,11 +322,6 @@ struct tegra_pcie_bus { | |||
322 | unsigned int nr; | 322 | unsigned int nr; |
323 | }; | 323 | }; |
324 | 324 | ||
325 | static inline struct tegra_pcie *sys_to_pcie(struct pci_sys_data *sys) | ||
326 | { | ||
327 | return sys->private_data; | ||
328 | } | ||
329 | |||
330 | static inline void afi_writel(struct tegra_pcie *pcie, u32 value, | 325 | static inline void afi_writel(struct tegra_pcie *pcie, u32 value, |
331 | unsigned long offset) | 326 | unsigned long offset) |
332 | { | 327 | { |
@@ -385,8 +380,7 @@ static struct tegra_pcie_bus *tegra_pcie_bus_alloc(struct tegra_pcie *pcie, | |||
385 | unsigned int busnr) | 380 | unsigned int busnr) |
386 | { | 381 | { |
387 | struct device *dev = pcie->dev; | 382 | struct device *dev = pcie->dev; |
388 | pgprot_t prot = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | | 383 | pgprot_t prot = pgprot_device(PAGE_KERNEL); |
389 | L_PTE_XN | L_PTE_MT_DEV_SHARED | L_PTE_SHARED); | ||
390 | phys_addr_t cs = pcie->cs->start; | 384 | phys_addr_t cs = pcie->cs->start; |
391 | struct tegra_pcie_bus *bus; | 385 | struct tegra_pcie_bus *bus; |
392 | unsigned int i; | 386 | unsigned int i; |
@@ -430,7 +424,8 @@ free: | |||
430 | 424 | ||
431 | static int tegra_pcie_add_bus(struct pci_bus *bus) | 425 | static int tegra_pcie_add_bus(struct pci_bus *bus) |
432 | { | 426 | { |
433 | struct tegra_pcie *pcie = sys_to_pcie(bus->sysdata); | 427 | struct pci_host_bridge *host = pci_find_host_bridge(bus); |
428 | struct tegra_pcie *pcie = pci_host_bridge_priv(host); | ||
434 | struct tegra_pcie_bus *b; | 429 | struct tegra_pcie_bus *b; |
435 | 430 | ||
436 | b = tegra_pcie_bus_alloc(pcie, bus->number); | 431 | b = tegra_pcie_bus_alloc(pcie, bus->number); |
@@ -444,7 +439,8 @@ static int tegra_pcie_add_bus(struct pci_bus *bus) | |||
444 | 439 | ||
445 | static void tegra_pcie_remove_bus(struct pci_bus *child) | 440 | static void tegra_pcie_remove_bus(struct pci_bus *child) |
446 | { | 441 | { |
447 | struct tegra_pcie *pcie = sys_to_pcie(child->sysdata); | 442 | struct pci_host_bridge *host = pci_find_host_bridge(child); |
443 | struct tegra_pcie *pcie = pci_host_bridge_priv(host); | ||
448 | struct tegra_pcie_bus *bus, *tmp; | 444 | struct tegra_pcie_bus *bus, *tmp; |
449 | 445 | ||
450 | list_for_each_entry_safe(bus, tmp, &pcie->buses, list) { | 446 | list_for_each_entry_safe(bus, tmp, &pcie->buses, list) { |
@@ -461,7 +457,8 @@ static void __iomem *tegra_pcie_map_bus(struct pci_bus *bus, | |||
461 | unsigned int devfn, | 457 | unsigned int devfn, |
462 | int where) | 458 | int where) |
463 | { | 459 | { |
464 | struct tegra_pcie *pcie = sys_to_pcie(bus->sysdata); | 460 | struct pci_host_bridge *host = pci_find_host_bridge(bus); |
461 | struct tegra_pcie *pcie = pci_host_bridge_priv(host); | ||
465 | struct device *dev = pcie->dev; | 462 | struct device *dev = pcie->dev; |
466 | void __iomem *addr = NULL; | 463 | void __iomem *addr = NULL; |
467 | 464 | ||
@@ -558,6 +555,12 @@ static void tegra_pcie_port_enable(struct tegra_pcie_port *port) | |||
558 | afi_writel(port->pcie, value, ctrl); | 555 | afi_writel(port->pcie, value, ctrl); |
559 | 556 | ||
560 | tegra_pcie_port_reset(port); | 557 | tegra_pcie_port_reset(port); |
558 | |||
559 | if (soc->force_pca_enable) { | ||
560 | value = readl(port->base + RP_VEND_CTL2); | ||
561 | value |= RP_VEND_CTL2_PCA_ENABLE; | ||
562 | writel(value, port->base + RP_VEND_CTL2); | ||
563 | } | ||
561 | } | 564 | } |
562 | 565 | ||
563 | static void tegra_pcie_port_disable(struct tegra_pcie_port *port) | 566 | static void tegra_pcie_port_disable(struct tegra_pcie_port *port) |
@@ -610,39 +613,31 @@ static void tegra_pcie_relax_enable(struct pci_dev *dev) | |||
610 | } | 613 | } |
611 | DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, tegra_pcie_relax_enable); | 614 | DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, tegra_pcie_relax_enable); |
612 | 615 | ||
613 | static int tegra_pcie_setup(int nr, struct pci_sys_data *sys) | 616 | static int tegra_pcie_request_resources(struct tegra_pcie *pcie) |
614 | { | 617 | { |
615 | struct tegra_pcie *pcie = sys_to_pcie(sys); | 618 | struct pci_host_bridge *host = pci_host_bridge_from_priv(pcie); |
619 | struct list_head *windows = &host->windows; | ||
616 | struct device *dev = pcie->dev; | 620 | struct device *dev = pcie->dev; |
617 | int err; | 621 | int err; |
618 | 622 | ||
619 | sys->mem_offset = pcie->offset.mem; | 623 | pci_add_resource_offset(windows, &pcie->pio, pcie->offset.io); |
620 | sys->io_offset = pcie->offset.io; | 624 | pci_add_resource_offset(windows, &pcie->mem, pcie->offset.mem); |
625 | pci_add_resource_offset(windows, &pcie->prefetch, pcie->offset.mem); | ||
626 | pci_add_resource(windows, &pcie->busn); | ||
621 | 627 | ||
622 | err = devm_request_resource(dev, &iomem_resource, &pcie->io); | 628 | err = devm_request_pci_bus_resources(dev, windows); |
623 | if (err < 0) | 629 | if (err < 0) |
624 | return err; | 630 | return err; |
625 | 631 | ||
626 | err = pci_remap_iospace(&pcie->pio, pcie->io.start); | 632 | pci_remap_iospace(&pcie->pio, pcie->io.start); |
627 | if (!err) | ||
628 | pci_add_resource_offset(&sys->resources, &pcie->pio, | ||
629 | sys->io_offset); | ||
630 | 633 | ||
631 | pci_add_resource_offset(&sys->resources, &pcie->mem, sys->mem_offset); | 634 | return 0; |
632 | pci_add_resource_offset(&sys->resources, &pcie->prefetch, | ||
633 | sys->mem_offset); | ||
634 | pci_add_resource(&sys->resources, &pcie->busn); | ||
635 | |||
636 | err = devm_request_pci_bus_resources(dev, &sys->resources); | ||
637 | if (err < 0) | ||
638 | return err; | ||
639 | |||
640 | return 1; | ||
641 | } | 635 | } |
642 | 636 | ||
643 | static int tegra_pcie_map_irq(const struct pci_dev *pdev, u8 slot, u8 pin) | 637 | static int tegra_pcie_map_irq(const struct pci_dev *pdev, u8 slot, u8 pin) |
644 | { | 638 | { |
645 | struct tegra_pcie *pcie = sys_to_pcie(pdev->bus->sysdata); | 639 | struct pci_host_bridge *host = pci_find_host_bridge(pdev->bus); |
640 | struct tegra_pcie *pcie = pci_host_bridge_priv(host); | ||
646 | int irq; | 641 | int irq; |
647 | 642 | ||
648 | tegra_cpuidle_pcie_irqs_in_use(); | 643 | tegra_cpuidle_pcie_irqs_in_use(); |
@@ -1499,10 +1494,11 @@ static const struct irq_domain_ops msi_domain_ops = { | |||
1499 | 1494 | ||
1500 | static int tegra_pcie_enable_msi(struct tegra_pcie *pcie) | 1495 | static int tegra_pcie_enable_msi(struct tegra_pcie *pcie) |
1501 | { | 1496 | { |
1502 | struct device *dev = pcie->dev; | 1497 | struct pci_host_bridge *host = pci_host_bridge_from_priv(pcie); |
1503 | struct platform_device *pdev = to_platform_device(dev); | 1498 | struct platform_device *pdev = to_platform_device(pcie->dev); |
1504 | const struct tegra_pcie_soc *soc = pcie->soc; | 1499 | const struct tegra_pcie_soc *soc = pcie->soc; |
1505 | struct tegra_msi *msi = &pcie->msi; | 1500 | struct tegra_msi *msi = &pcie->msi; |
1501 | struct device *dev = pcie->dev; | ||
1506 | unsigned long base; | 1502 | unsigned long base; |
1507 | int err; | 1503 | int err; |
1508 | u32 reg; | 1504 | u32 reg; |
@@ -1559,6 +1555,8 @@ static int tegra_pcie_enable_msi(struct tegra_pcie *pcie) | |||
1559 | reg |= AFI_INTR_MASK_MSI_MASK; | 1555 | reg |= AFI_INTR_MASK_MSI_MASK; |
1560 | afi_writel(pcie, reg, AFI_INTR_MASK); | 1556 | afi_writel(pcie, reg, AFI_INTR_MASK); |
1561 | 1557 | ||
1558 | host->msi = &msi->chip; | ||
1559 | |||
1562 | return 0; | 1560 | return 0; |
1563 | 1561 | ||
1564 | err: | 1562 | err: |
@@ -1609,7 +1607,8 @@ static int tegra_pcie_get_xbar_config(struct tegra_pcie *pcie, u32 lanes, | |||
1609 | struct device *dev = pcie->dev; | 1607 | struct device *dev = pcie->dev; |
1610 | struct device_node *np = dev->of_node; | 1608 | struct device_node *np = dev->of_node; |
1611 | 1609 | ||
1612 | if (of_device_is_compatible(np, "nvidia,tegra124-pcie")) { | 1610 | if (of_device_is_compatible(np, "nvidia,tegra124-pcie") || |
1611 | of_device_is_compatible(np, "nvidia,tegra210-pcie")) { | ||
1613 | switch (lanes) { | 1612 | switch (lanes) { |
1614 | case 0x0000104: | 1613 | case 0x0000104: |
1615 | dev_info(dev, "4x1, 1x1 configuration\n"); | 1614 | dev_info(dev, "4x1, 1x1 configuration\n"); |
@@ -1730,7 +1729,22 @@ static int tegra_pcie_get_regulators(struct tegra_pcie *pcie, u32 lane_mask) | |||
1730 | struct device_node *np = dev->of_node; | 1729 | struct device_node *np = dev->of_node; |
1731 | unsigned int i = 0; | 1730 | unsigned int i = 0; |
1732 | 1731 | ||
1733 | if (of_device_is_compatible(np, "nvidia,tegra124-pcie")) { | 1732 | if (of_device_is_compatible(np, "nvidia,tegra210-pcie")) { |
1733 | pcie->num_supplies = 6; | ||
1734 | |||
1735 | pcie->supplies = devm_kcalloc(pcie->dev, pcie->num_supplies, | ||
1736 | sizeof(*pcie->supplies), | ||
1737 | GFP_KERNEL); | ||
1738 | if (!pcie->supplies) | ||
1739 | return -ENOMEM; | ||
1740 | |||
1741 | pcie->supplies[i++].supply = "avdd-pll-uerefe"; | ||
1742 | pcie->supplies[i++].supply = "hvddio-pex"; | ||
1743 | pcie->supplies[i++].supply = "dvddio-pex"; | ||
1744 | pcie->supplies[i++].supply = "dvdd-pex-pll"; | ||
1745 | pcie->supplies[i++].supply = "hvdd-pex-pll-e"; | ||
1746 | pcie->supplies[i++].supply = "vddio-pex-ctl"; | ||
1747 | } else if (of_device_is_compatible(np, "nvidia,tegra124-pcie")) { | ||
1734 | pcie->num_supplies = 7; | 1748 | pcie->num_supplies = 7; |
1735 | 1749 | ||
1736 | pcie->supplies = devm_kcalloc(dev, pcie->num_supplies, | 1750 | pcie->supplies = devm_kcalloc(dev, pcie->num_supplies, |
@@ -2021,11 +2035,10 @@ retry: | |||
2021 | return false; | 2035 | return false; |
2022 | } | 2036 | } |
2023 | 2037 | ||
2024 | static int tegra_pcie_enable(struct tegra_pcie *pcie) | 2038 | static void tegra_pcie_enable_ports(struct tegra_pcie *pcie) |
2025 | { | 2039 | { |
2026 | struct device *dev = pcie->dev; | 2040 | struct device *dev = pcie->dev; |
2027 | struct tegra_pcie_port *port, *tmp; | 2041 | struct tegra_pcie_port *port, *tmp; |
2028 | struct hw_pci hw; | ||
2029 | 2042 | ||
2030 | list_for_each_entry_safe(port, tmp, &pcie->ports, list) { | 2043 | list_for_each_entry_safe(port, tmp, &pcie->ports, list) { |
2031 | dev_info(dev, "probing port %u, using %u lanes\n", | 2044 | dev_info(dev, "probing port %u, using %u lanes\n", |
@@ -2041,21 +2054,6 @@ static int tegra_pcie_enable(struct tegra_pcie *pcie) | |||
2041 | tegra_pcie_port_disable(port); | 2054 | tegra_pcie_port_disable(port); |
2042 | tegra_pcie_port_free(port); | 2055 | tegra_pcie_port_free(port); |
2043 | } | 2056 | } |
2044 | |||
2045 | memset(&hw, 0, sizeof(hw)); | ||
2046 | |||
2047 | #ifdef CONFIG_PCI_MSI | ||
2048 | hw.msi_ctrl = &pcie->msi.chip; | ||
2049 | #endif | ||
2050 | |||
2051 | hw.nr_controllers = 1; | ||
2052 | hw.private_data = (void **)&pcie; | ||
2053 | hw.setup = tegra_pcie_setup; | ||
2054 | hw.map_irq = tegra_pcie_map_irq; | ||
2055 | hw.ops = &tegra_pcie_ops; | ||
2056 | |||
2057 | pci_common_init_dev(dev, &hw); | ||
2058 | return 0; | ||
2059 | } | 2057 | } |
2060 | 2058 | ||
2061 | static const struct tegra_pcie_soc tegra20_pcie = { | 2059 | static const struct tegra_pcie_soc tegra20_pcie = { |
@@ -2069,6 +2067,7 @@ static const struct tegra_pcie_soc tegra20_pcie = { | |||
2069 | .has_intr_prsnt_sense = false, | 2067 | .has_intr_prsnt_sense = false, |
2070 | .has_cml_clk = false, | 2068 | .has_cml_clk = false, |
2071 | .has_gen2 = false, | 2069 | .has_gen2 = false, |
2070 | .force_pca_enable = false, | ||
2072 | }; | 2071 | }; |
2073 | 2072 | ||
2074 | static const struct tegra_pcie_soc tegra30_pcie = { | 2073 | static const struct tegra_pcie_soc tegra30_pcie = { |
@@ -2083,6 +2082,7 @@ static const struct tegra_pcie_soc tegra30_pcie = { | |||
2083 | .has_intr_prsnt_sense = true, | 2082 | .has_intr_prsnt_sense = true, |
2084 | .has_cml_clk = true, | 2083 | .has_cml_clk = true, |
2085 | .has_gen2 = false, | 2084 | .has_gen2 = false, |
2085 | .force_pca_enable = false, | ||
2086 | }; | 2086 | }; |
2087 | 2087 | ||
2088 | static const struct tegra_pcie_soc tegra124_pcie = { | 2088 | static const struct tegra_pcie_soc tegra124_pcie = { |
@@ -2096,9 +2096,25 @@ static const struct tegra_pcie_soc tegra124_pcie = { | |||
2096 | .has_intr_prsnt_sense = true, | 2096 | .has_intr_prsnt_sense = true, |
2097 | .has_cml_clk = true, | 2097 | .has_cml_clk = true, |
2098 | .has_gen2 = true, | 2098 | .has_gen2 = true, |
2099 | .force_pca_enable = false, | ||
2100 | }; | ||
2101 | |||
2102 | static const struct tegra_pcie_soc tegra210_pcie = { | ||
2103 | .num_ports = 2, | ||
2104 | .msi_base_shift = 8, | ||
2105 | .pads_pll_ctl = PADS_PLL_CTL_TEGRA30, | ||
2106 | .tx_ref_sel = PADS_PLL_CTL_TXCLKREF_BUF_EN, | ||
2107 | .pads_refclk_cfg0 = 0x90b890b8, | ||
2108 | .has_pex_clkreq_en = true, | ||
2109 | .has_pex_bias_ctrl = true, | ||
2110 | .has_intr_prsnt_sense = true, | ||
2111 | .has_cml_clk = true, | ||
2112 | .has_gen2 = true, | ||
2113 | .force_pca_enable = true, | ||
2099 | }; | 2114 | }; |
2100 | 2115 | ||
2101 | static const struct of_device_id tegra_pcie_of_match[] = { | 2116 | static const struct of_device_id tegra_pcie_of_match[] = { |
2117 | { .compatible = "nvidia,tegra210-pcie", .data = &tegra210_pcie }, | ||
2102 | { .compatible = "nvidia,tegra124-pcie", .data = &tegra124_pcie }, | 2118 | { .compatible = "nvidia,tegra124-pcie", .data = &tegra124_pcie }, |
2103 | { .compatible = "nvidia,tegra30-pcie", .data = &tegra30_pcie }, | 2119 | { .compatible = "nvidia,tegra30-pcie", .data = &tegra30_pcie }, |
2104 | { .compatible = "nvidia,tegra20-pcie", .data = &tegra20_pcie }, | 2120 | { .compatible = "nvidia,tegra20-pcie", .data = &tegra20_pcie }, |
@@ -2217,13 +2233,17 @@ remove: | |||
2217 | static int tegra_pcie_probe(struct platform_device *pdev) | 2233 | static int tegra_pcie_probe(struct platform_device *pdev) |
2218 | { | 2234 | { |
2219 | struct device *dev = &pdev->dev; | 2235 | struct device *dev = &pdev->dev; |
2236 | struct pci_host_bridge *host; | ||
2220 | struct tegra_pcie *pcie; | 2237 | struct tegra_pcie *pcie; |
2238 | struct pci_bus *child; | ||
2221 | int err; | 2239 | int err; |
2222 | 2240 | ||
2223 | pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL); | 2241 | host = pci_alloc_host_bridge(sizeof(*pcie)); |
2224 | if (!pcie) | 2242 | if (!host) |
2225 | return -ENOMEM; | 2243 | return -ENOMEM; |
2226 | 2244 | ||
2245 | pcie = pci_host_bridge_priv(host); | ||
2246 | |||
2227 | pcie->soc = of_device_get_match_data(dev); | 2247 | pcie->soc = of_device_get_match_data(dev); |
2228 | INIT_LIST_HEAD(&pcie->buses); | 2248 | INIT_LIST_HEAD(&pcie->buses); |
2229 | INIT_LIST_HEAD(&pcie->ports); | 2249 | INIT_LIST_HEAD(&pcie->ports); |
@@ -2243,6 +2263,10 @@ static int tegra_pcie_probe(struct platform_device *pdev) | |||
2243 | if (err) | 2263 | if (err) |
2244 | goto put_resources; | 2264 | goto put_resources; |
2245 | 2265 | ||
2266 | err = tegra_pcie_request_resources(pcie); | ||
2267 | if (err) | ||
2268 | goto put_resources; | ||
2269 | |||
2246 | /* setup the AFI address translations */ | 2270 | /* setup the AFI address translations */ |
2247 | tegra_pcie_setup_translations(pcie); | 2271 | tegra_pcie_setup_translations(pcie); |
2248 | 2272 | ||
@@ -2254,12 +2278,30 @@ static int tegra_pcie_probe(struct platform_device *pdev) | |||
2254 | } | 2278 | } |
2255 | } | 2279 | } |
2256 | 2280 | ||
2257 | err = tegra_pcie_enable(pcie); | 2281 | tegra_pcie_enable_ports(pcie); |
2282 | |||
2283 | pci_add_flags(PCI_REASSIGN_ALL_RSRC | PCI_REASSIGN_ALL_BUS); | ||
2284 | host->busnr = pcie->busn.start; | ||
2285 | host->dev.parent = &pdev->dev; | ||
2286 | host->ops = &tegra_pcie_ops; | ||
2287 | |||
2288 | err = pci_register_host_bridge(host); | ||
2258 | if (err < 0) { | 2289 | if (err < 0) { |
2259 | dev_err(dev, "failed to enable PCIe ports: %d\n", err); | 2290 | dev_err(dev, "failed to register host: %d\n", err); |
2260 | goto disable_msi; | 2291 | goto disable_msi; |
2261 | } | 2292 | } |
2262 | 2293 | ||
2294 | pci_scan_child_bus(host->bus); | ||
2295 | |||
2296 | pci_fixup_irqs(pci_common_swizzle, tegra_pcie_map_irq); | ||
2297 | pci_bus_size_bridges(host->bus); | ||
2298 | pci_bus_assign_resources(host->bus); | ||
2299 | |||
2300 | list_for_each_entry(child, &host->bus->children, node) | ||
2301 | pcie_bus_configure_settings(child); | ||
2302 | |||
2303 | pci_bus_add_devices(host->bus); | ||
2304 | |||
2263 | if (IS_ENABLED(CONFIG_DEBUG_FS)) { | 2305 | if (IS_ENABLED(CONFIG_DEBUG_FS)) { |
2264 | err = tegra_pcie_debugfs_init(pcie); | 2306 | err = tegra_pcie_debugfs_init(pcie); |
2265 | if (err < 0) | 2307 | if (err < 0) |
diff --git a/drivers/pci/host/pci-thunder-ecam.c b/drivers/pci/host/pci-thunder-ecam.c index d50a3dc2d8db..3f54a43bbbea 100644 --- a/drivers/pci/host/pci-thunder-ecam.c +++ b/drivers/pci/host/pci-thunder-ecam.c | |||
@@ -14,6 +14,8 @@ | |||
14 | #include <linux/pci-ecam.h> | 14 | #include <linux/pci-ecam.h> |
15 | #include <linux/platform_device.h> | 15 | #include <linux/platform_device.h> |
16 | 16 | ||
17 | #if defined(CONFIG_PCI_HOST_THUNDER_ECAM) || (defined(CONFIG_ACPI) && defined(CONFIG_PCI_QUIRKS)) | ||
18 | |||
17 | static void set_val(u32 v, int where, int size, u32 *val) | 19 | static void set_val(u32 v, int where, int size, u32 *val) |
18 | { | 20 | { |
19 | int shift = (where & 3) * 8; | 21 | int shift = (where & 3) * 8; |
@@ -346,7 +348,7 @@ static int thunder_ecam_config_write(struct pci_bus *bus, unsigned int devfn, | |||
346 | return pci_generic_config_write(bus, devfn, where, size, val); | 348 | return pci_generic_config_write(bus, devfn, where, size, val); |
347 | } | 349 | } |
348 | 350 | ||
349 | static struct pci_ecam_ops pci_thunder_ecam_ops = { | 351 | struct pci_ecam_ops pci_thunder_ecam_ops = { |
350 | .bus_shift = 20, | 352 | .bus_shift = 20, |
351 | .pci_ops = { | 353 | .pci_ops = { |
352 | .map_bus = pci_ecam_map_bus, | 354 | .map_bus = pci_ecam_map_bus, |
@@ -355,6 +357,8 @@ static struct pci_ecam_ops pci_thunder_ecam_ops = { | |||
355 | } | 357 | } |
356 | }; | 358 | }; |
357 | 359 | ||
360 | #ifdef CONFIG_PCI_HOST_THUNDER_ECAM | ||
361 | |||
358 | static const struct of_device_id thunder_ecam_of_match[] = { | 362 | static const struct of_device_id thunder_ecam_of_match[] = { |
359 | { .compatible = "cavium,pci-host-thunder-ecam" }, | 363 | { .compatible = "cavium,pci-host-thunder-ecam" }, |
360 | { }, | 364 | { }, |
@@ -373,3 +377,6 @@ static struct platform_driver thunder_ecam_driver = { | |||
373 | .probe = thunder_ecam_probe, | 377 | .probe = thunder_ecam_probe, |
374 | }; | 378 | }; |
375 | builtin_platform_driver(thunder_ecam_driver); | 379 | builtin_platform_driver(thunder_ecam_driver); |
380 | |||
381 | #endif | ||
382 | #endif | ||
diff --git a/drivers/pci/host/pci-thunder-pem.c b/drivers/pci/host/pci-thunder-pem.c index 6abaf80ffb39..af722eb0ca75 100644 --- a/drivers/pci/host/pci-thunder-pem.c +++ b/drivers/pci/host/pci-thunder-pem.c | |||
@@ -18,8 +18,12 @@ | |||
18 | #include <linux/init.h> | 18 | #include <linux/init.h> |
19 | #include <linux/of_address.h> | 19 | #include <linux/of_address.h> |
20 | #include <linux/of_pci.h> | 20 | #include <linux/of_pci.h> |
21 | #include <linux/pci-acpi.h> | ||
21 | #include <linux/pci-ecam.h> | 22 | #include <linux/pci-ecam.h> |
22 | #include <linux/platform_device.h> | 23 | #include <linux/platform_device.h> |
24 | #include "../pci.h" | ||
25 | |||
26 | #if defined(CONFIG_PCI_HOST_THUNDER_PEM) || (defined(CONFIG_ACPI) && defined(CONFIG_PCI_QUIRKS)) | ||
23 | 27 | ||
24 | #define PEM_CFG_WR 0x28 | 28 | #define PEM_CFG_WR 0x28 |
25 | #define PEM_CFG_RD 0x30 | 29 | #define PEM_CFG_RD 0x30 |
@@ -284,35 +288,16 @@ static int thunder_pem_config_write(struct pci_bus *bus, unsigned int devfn, | |||
284 | return pci_generic_config_write(bus, devfn, where, size, val); | 288 | return pci_generic_config_write(bus, devfn, where, size, val); |
285 | } | 289 | } |
286 | 290 | ||
287 | static int thunder_pem_init(struct pci_config_window *cfg) | 291 | static int thunder_pem_init(struct device *dev, struct pci_config_window *cfg, |
292 | struct resource *res_pem) | ||
288 | { | 293 | { |
289 | struct device *dev = cfg->parent; | ||
290 | resource_size_t bar4_start; | ||
291 | struct resource *res_pem; | ||
292 | struct thunder_pem_pci *pem_pci; | 294 | struct thunder_pem_pci *pem_pci; |
293 | struct platform_device *pdev; | 295 | resource_size_t bar4_start; |
294 | |||
295 | /* Only OF support for now */ | ||
296 | if (!dev->of_node) | ||
297 | return -EINVAL; | ||
298 | 296 | ||
299 | pem_pci = devm_kzalloc(dev, sizeof(*pem_pci), GFP_KERNEL); | 297 | pem_pci = devm_kzalloc(dev, sizeof(*pem_pci), GFP_KERNEL); |
300 | if (!pem_pci) | 298 | if (!pem_pci) |
301 | return -ENOMEM; | 299 | return -ENOMEM; |
302 | 300 | ||
303 | pdev = to_platform_device(dev); | ||
304 | |||
305 | /* | ||
306 | * The second register range is the PEM bridge to the PCIe | ||
307 | * bus. It has a different config access method than those | ||
308 | * devices behind the bridge. | ||
309 | */ | ||
310 | res_pem = platform_get_resource(pdev, IORESOURCE_MEM, 1); | ||
311 | if (!res_pem) { | ||
312 | dev_err(dev, "missing \"reg[1]\"property\n"); | ||
313 | return -EINVAL; | ||
314 | } | ||
315 | |||
316 | pem_pci->pem_reg_base = devm_ioremap(dev, res_pem->start, 0x10000); | 301 | pem_pci->pem_reg_base = devm_ioremap(dev, res_pem->start, 0x10000); |
317 | if (!pem_pci->pem_reg_base) | 302 | if (!pem_pci->pem_reg_base) |
318 | return -ENOMEM; | 303 | return -ENOMEM; |
@@ -332,9 +317,69 @@ static int thunder_pem_init(struct pci_config_window *cfg) | |||
332 | return 0; | 317 | return 0; |
333 | } | 318 | } |
334 | 319 | ||
320 | #if defined(CONFIG_ACPI) && defined(CONFIG_PCI_QUIRKS) | ||
321 | |||
322 | static int thunder_pem_acpi_init(struct pci_config_window *cfg) | ||
323 | { | ||
324 | struct device *dev = cfg->parent; | ||
325 | struct acpi_device *adev = to_acpi_device(dev); | ||
326 | struct acpi_pci_root *root = acpi_driver_data(adev); | ||
327 | struct resource *res_pem; | ||
328 | int ret; | ||
329 | |||
330 | res_pem = devm_kzalloc(&adev->dev, sizeof(*res_pem), GFP_KERNEL); | ||
331 | if (!res_pem) | ||
332 | return -ENOMEM; | ||
333 | |||
334 | ret = acpi_get_rc_resources(dev, "THRX0002", root->segment, res_pem); | ||
335 | if (ret) { | ||
336 | dev_err(dev, "can't get rc base address\n"); | ||
337 | return ret; | ||
338 | } | ||
339 | |||
340 | return thunder_pem_init(dev, cfg, res_pem); | ||
341 | } | ||
342 | |||
343 | struct pci_ecam_ops thunder_pem_ecam_ops = { | ||
344 | .bus_shift = 24, | ||
345 | .init = thunder_pem_acpi_init, | ||
346 | .pci_ops = { | ||
347 | .map_bus = pci_ecam_map_bus, | ||
348 | .read = thunder_pem_config_read, | ||
349 | .write = thunder_pem_config_write, | ||
350 | } | ||
351 | }; | ||
352 | |||
353 | #endif | ||
354 | |||
355 | #ifdef CONFIG_PCI_HOST_THUNDER_PEM | ||
356 | |||
357 | static int thunder_pem_platform_init(struct pci_config_window *cfg) | ||
358 | { | ||
359 | struct device *dev = cfg->parent; | ||
360 | struct platform_device *pdev = to_platform_device(dev); | ||
361 | struct resource *res_pem; | ||
362 | |||
363 | if (!dev->of_node) | ||
364 | return -EINVAL; | ||
365 | |||
366 | /* | ||
367 | * The second register range is the PEM bridge to the PCIe | ||
368 | * bus. It has a different config access method than those | ||
369 | * devices behind the bridge. | ||
370 | */ | ||
371 | res_pem = platform_get_resource(pdev, IORESOURCE_MEM, 1); | ||
372 | if (!res_pem) { | ||
373 | dev_err(dev, "missing \"reg[1]\"property\n"); | ||
374 | return -EINVAL; | ||
375 | } | ||
376 | |||
377 | return thunder_pem_init(dev, cfg, res_pem); | ||
378 | } | ||
379 | |||
335 | static struct pci_ecam_ops pci_thunder_pem_ops = { | 380 | static struct pci_ecam_ops pci_thunder_pem_ops = { |
336 | .bus_shift = 24, | 381 | .bus_shift = 24, |
337 | .init = thunder_pem_init, | 382 | .init = thunder_pem_platform_init, |
338 | .pci_ops = { | 383 | .pci_ops = { |
339 | .map_bus = pci_ecam_map_bus, | 384 | .map_bus = pci_ecam_map_bus, |
340 | .read = thunder_pem_config_read, | 385 | .read = thunder_pem_config_read, |
@@ -360,3 +405,6 @@ static struct platform_driver thunder_pem_driver = { | |||
360 | .probe = thunder_pem_probe, | 405 | .probe = thunder_pem_probe, |
361 | }; | 406 | }; |
362 | builtin_platform_driver(thunder_pem_driver); | 407 | builtin_platform_driver(thunder_pem_driver); |
408 | |||
409 | #endif | ||
410 | #endif | ||
diff --git a/drivers/pci/host/pci-xgene.c b/drivers/pci/host/pci-xgene.c index 1de23d74783f..7c3b54b9eb17 100644 --- a/drivers/pci/host/pci-xgene.c +++ b/drivers/pci/host/pci-xgene.c | |||
@@ -27,6 +27,8 @@ | |||
27 | #include <linux/of_irq.h> | 27 | #include <linux/of_irq.h> |
28 | #include <linux/of_pci.h> | 28 | #include <linux/of_pci.h> |
29 | #include <linux/pci.h> | 29 | #include <linux/pci.h> |
30 | #include <linux/pci-acpi.h> | ||
31 | #include <linux/pci-ecam.h> | ||
30 | #include <linux/platform_device.h> | 32 | #include <linux/platform_device.h> |
31 | #include <linux/slab.h> | 33 | #include <linux/slab.h> |
32 | 34 | ||
@@ -64,7 +66,9 @@ | |||
64 | /* PCIe IP version */ | 66 | /* PCIe IP version */ |
65 | #define XGENE_PCIE_IP_VER_UNKN 0 | 67 | #define XGENE_PCIE_IP_VER_UNKN 0 |
66 | #define XGENE_PCIE_IP_VER_1 1 | 68 | #define XGENE_PCIE_IP_VER_1 1 |
69 | #define XGENE_PCIE_IP_VER_2 2 | ||
67 | 70 | ||
71 | #if defined(CONFIG_PCI_XGENE) || (defined(CONFIG_ACPI) && defined(CONFIG_PCI_QUIRKS)) | ||
68 | struct xgene_pcie_port { | 72 | struct xgene_pcie_port { |
69 | struct device_node *node; | 73 | struct device_node *node; |
70 | struct device *dev; | 74 | struct device *dev; |
@@ -91,13 +95,24 @@ static inline u32 pcie_bar_low_val(u32 addr, u32 flags) | |||
91 | return (addr & PCI_BASE_ADDRESS_MEM_MASK) | flags; | 95 | return (addr & PCI_BASE_ADDRESS_MEM_MASK) | flags; |
92 | } | 96 | } |
93 | 97 | ||
98 | static inline struct xgene_pcie_port *pcie_bus_to_port(struct pci_bus *bus) | ||
99 | { | ||
100 | struct pci_config_window *cfg; | ||
101 | |||
102 | if (acpi_disabled) | ||
103 | return (struct xgene_pcie_port *)(bus->sysdata); | ||
104 | |||
105 | cfg = bus->sysdata; | ||
106 | return (struct xgene_pcie_port *)(cfg->priv); | ||
107 | } | ||
108 | |||
94 | /* | 109 | /* |
95 | * When the address bit [17:16] is 2'b01, the Configuration access will be | 110 | * When the address bit [17:16] is 2'b01, the Configuration access will be |
96 | * treated as Type 1 and it will be forwarded to external PCIe device. | 111 | * treated as Type 1 and it will be forwarded to external PCIe device. |
97 | */ | 112 | */ |
98 | static void __iomem *xgene_pcie_get_cfg_base(struct pci_bus *bus) | 113 | static void __iomem *xgene_pcie_get_cfg_base(struct pci_bus *bus) |
99 | { | 114 | { |
100 | struct xgene_pcie_port *port = bus->sysdata; | 115 | struct xgene_pcie_port *port = pcie_bus_to_port(bus); |
101 | 116 | ||
102 | if (bus->number >= (bus->primary + 1)) | 117 | if (bus->number >= (bus->primary + 1)) |
103 | return port->cfg_base + AXI_EP_CFG_ACCESS; | 118 | return port->cfg_base + AXI_EP_CFG_ACCESS; |
@@ -111,7 +126,7 @@ static void __iomem *xgene_pcie_get_cfg_base(struct pci_bus *bus) | |||
111 | */ | 126 | */ |
112 | static void xgene_pcie_set_rtdid_reg(struct pci_bus *bus, uint devfn) | 127 | static void xgene_pcie_set_rtdid_reg(struct pci_bus *bus, uint devfn) |
113 | { | 128 | { |
114 | struct xgene_pcie_port *port = bus->sysdata; | 129 | struct xgene_pcie_port *port = pcie_bus_to_port(bus); |
115 | unsigned int b, d, f; | 130 | unsigned int b, d, f; |
116 | u32 rtdid_val = 0; | 131 | u32 rtdid_val = 0; |
117 | 132 | ||
@@ -158,7 +173,7 @@ static void __iomem *xgene_pcie_map_bus(struct pci_bus *bus, unsigned int devfn, | |||
158 | static int xgene_pcie_config_read32(struct pci_bus *bus, unsigned int devfn, | 173 | static int xgene_pcie_config_read32(struct pci_bus *bus, unsigned int devfn, |
159 | int where, int size, u32 *val) | 174 | int where, int size, u32 *val) |
160 | { | 175 | { |
161 | struct xgene_pcie_port *port = bus->sysdata; | 176 | struct xgene_pcie_port *port = pcie_bus_to_port(bus); |
162 | 177 | ||
163 | if (pci_generic_config_read32(bus, devfn, where & ~0x3, 4, val) != | 178 | if (pci_generic_config_read32(bus, devfn, where & ~0x3, 4, val) != |
164 | PCIBIOS_SUCCESSFUL) | 179 | PCIBIOS_SUCCESSFUL) |
@@ -182,13 +197,103 @@ static int xgene_pcie_config_read32(struct pci_bus *bus, unsigned int devfn, | |||
182 | 197 | ||
183 | return PCIBIOS_SUCCESSFUL; | 198 | return PCIBIOS_SUCCESSFUL; |
184 | } | 199 | } |
200 | #endif | ||
185 | 201 | ||
186 | static struct pci_ops xgene_pcie_ops = { | 202 | #if defined(CONFIG_ACPI) && defined(CONFIG_PCI_QUIRKS) |
187 | .map_bus = xgene_pcie_map_bus, | 203 | static int xgene_get_csr_resource(struct acpi_device *adev, |
188 | .read = xgene_pcie_config_read32, | 204 | struct resource *res) |
189 | .write = pci_generic_config_write32, | 205 | { |
206 | struct device *dev = &adev->dev; | ||
207 | struct resource_entry *entry; | ||
208 | struct list_head list; | ||
209 | unsigned long flags; | ||
210 | int ret; | ||
211 | |||
212 | INIT_LIST_HEAD(&list); | ||
213 | flags = IORESOURCE_MEM; | ||
214 | ret = acpi_dev_get_resources(adev, &list, | ||
215 | acpi_dev_filter_resource_type_cb, | ||
216 | (void *) flags); | ||
217 | if (ret < 0) { | ||
218 | dev_err(dev, "failed to parse _CRS method, error code %d\n", | ||
219 | ret); | ||
220 | return ret; | ||
221 | } | ||
222 | |||
223 | if (ret == 0) { | ||
224 | dev_err(dev, "no IO and memory resources present in _CRS\n"); | ||
225 | return -EINVAL; | ||
226 | } | ||
227 | |||
228 | entry = list_first_entry(&list, struct resource_entry, node); | ||
229 | *res = *entry->res; | ||
230 | acpi_dev_free_resource_list(&list); | ||
231 | return 0; | ||
232 | } | ||
233 | |||
234 | static int xgene_pcie_ecam_init(struct pci_config_window *cfg, u32 ipversion) | ||
235 | { | ||
236 | struct device *dev = cfg->parent; | ||
237 | struct acpi_device *adev = to_acpi_device(dev); | ||
238 | struct xgene_pcie_port *port; | ||
239 | struct resource csr; | ||
240 | int ret; | ||
241 | |||
242 | port = devm_kzalloc(dev, sizeof(*port), GFP_KERNEL); | ||
243 | if (!port) | ||
244 | return -ENOMEM; | ||
245 | |||
246 | ret = xgene_get_csr_resource(adev, &csr); | ||
247 | if (ret) { | ||
248 | dev_err(dev, "can't get CSR resource\n"); | ||
249 | kfree(port); | ||
250 | return ret; | ||
251 | } | ||
252 | port->csr_base = devm_ioremap_resource(dev, &csr); | ||
253 | if (IS_ERR(port->csr_base)) { | ||
254 | kfree(port); | ||
255 | return -ENOMEM; | ||
256 | } | ||
257 | |||
258 | port->cfg_base = cfg->win; | ||
259 | port->version = ipversion; | ||
260 | |||
261 | cfg->priv = port; | ||
262 | return 0; | ||
263 | } | ||
264 | |||
265 | static int xgene_v1_pcie_ecam_init(struct pci_config_window *cfg) | ||
266 | { | ||
267 | return xgene_pcie_ecam_init(cfg, XGENE_PCIE_IP_VER_1); | ||
268 | } | ||
269 | |||
270 | struct pci_ecam_ops xgene_v1_pcie_ecam_ops = { | ||
271 | .bus_shift = 16, | ||
272 | .init = xgene_v1_pcie_ecam_init, | ||
273 | .pci_ops = { | ||
274 | .map_bus = xgene_pcie_map_bus, | ||
275 | .read = xgene_pcie_config_read32, | ||
276 | .write = pci_generic_config_write, | ||
277 | } | ||
278 | }; | ||
279 | |||
280 | static int xgene_v2_pcie_ecam_init(struct pci_config_window *cfg) | ||
281 | { | ||
282 | return xgene_pcie_ecam_init(cfg, XGENE_PCIE_IP_VER_2); | ||
283 | } | ||
284 | |||
285 | struct pci_ecam_ops xgene_v2_pcie_ecam_ops = { | ||
286 | .bus_shift = 16, | ||
287 | .init = xgene_v2_pcie_ecam_init, | ||
288 | .pci_ops = { | ||
289 | .map_bus = xgene_pcie_map_bus, | ||
290 | .read = xgene_pcie_config_read32, | ||
291 | .write = pci_generic_config_write, | ||
292 | } | ||
190 | }; | 293 | }; |
294 | #endif | ||
191 | 295 | ||
296 | #if defined(CONFIG_PCI_XGENE) | ||
192 | static u64 xgene_pcie_set_ib_mask(struct xgene_pcie_port *port, u32 addr, | 297 | static u64 xgene_pcie_set_ib_mask(struct xgene_pcie_port *port, u32 addr, |
193 | u32 flags, u64 size) | 298 | u32 flags, u64 size) |
194 | { | 299 | { |
@@ -521,6 +626,12 @@ static int xgene_pcie_setup(struct xgene_pcie_port *port, | |||
521 | return 0; | 626 | return 0; |
522 | } | 627 | } |
523 | 628 | ||
629 | static struct pci_ops xgene_pcie_ops = { | ||
630 | .map_bus = xgene_pcie_map_bus, | ||
631 | .read = xgene_pcie_config_read32, | ||
632 | .write = pci_generic_config_write32, | ||
633 | }; | ||
634 | |||
524 | static int xgene_pcie_probe_bridge(struct platform_device *pdev) | 635 | static int xgene_pcie_probe_bridge(struct platform_device *pdev) |
525 | { | 636 | { |
526 | struct device *dev = &pdev->dev; | 637 | struct device *dev = &pdev->dev; |
@@ -591,3 +702,4 @@ static struct platform_driver xgene_pcie_driver = { | |||
591 | .probe = xgene_pcie_probe_bridge, | 702 | .probe = xgene_pcie_probe_bridge, |
592 | }; | 703 | }; |
593 | builtin_platform_driver(xgene_pcie_driver); | 704 | builtin_platform_driver(xgene_pcie_driver); |
705 | #endif | ||
diff --git a/drivers/pci/host/pcie-altera.c b/drivers/pci/host/pcie-altera.c index b0ac4dfafa0b..0c1540225ca3 100644 --- a/drivers/pci/host/pcie-altera.c +++ b/drivers/pci/host/pcie-altera.c | |||
@@ -550,10 +550,8 @@ static int altera_pcie_parse_dt(struct altera_pcie *pcie) | |||
550 | 550 | ||
551 | cra = platform_get_resource_byname(pdev, IORESOURCE_MEM, "Cra"); | 551 | cra = platform_get_resource_byname(pdev, IORESOURCE_MEM, "Cra"); |
552 | pcie->cra_base = devm_ioremap_resource(dev, cra); | 552 | pcie->cra_base = devm_ioremap_resource(dev, cra); |
553 | if (IS_ERR(pcie->cra_base)) { | 553 | if (IS_ERR(pcie->cra_base)) |
554 | dev_err(dev, "failed to map cra memory\n"); | ||
555 | return PTR_ERR(pcie->cra_base); | 554 | return PTR_ERR(pcie->cra_base); |
556 | } | ||
557 | 555 | ||
558 | /* setup IRQ */ | 556 | /* setup IRQ */ |
559 | pcie->irq = platform_get_irq(pdev, 0); | 557 | pcie->irq = platform_get_irq(pdev, 0); |
@@ -641,8 +639,4 @@ static struct platform_driver altera_pcie_driver = { | |||
641 | }, | 639 | }, |
642 | }; | 640 | }; |
643 | 641 | ||
644 | static int altera_pcie_init(void) | 642 | builtin_platform_driver(altera_pcie_driver); |
645 | { | ||
646 | return platform_driver_register(&altera_pcie_driver); | ||
647 | } | ||
648 | device_initcall(altera_pcie_init); | ||
diff --git a/drivers/pci/host/pcie-designware-plat.c b/drivers/pci/host/pcie-designware-plat.c index 537f58a664fa..8df6312ed300 100644 --- a/drivers/pci/host/pcie-designware-plat.c +++ b/drivers/pci/host/pcie-designware-plat.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Copyright (C) 2015-2016 Synopsys, Inc. (www.synopsys.com) | 4 | * Copyright (C) 2015-2016 Synopsys, Inc. (www.synopsys.com) |
5 | * | 5 | * |
6 | * Authors: Joao Pinto <jpinto@synopsys.com> | 6 | * Authors: Joao Pinto <jpmpinto@gmail.com> |
7 | * | 7 | * |
8 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
9 | * it under the terms of the GNU General Public License version 2 as | 9 | * it under the terms of the GNU General Public License version 2 as |
diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c index 035f50c03281..bed19994c1e9 100644 --- a/drivers/pci/host/pcie-designware.c +++ b/drivers/pci/host/pcie-designware.c | |||
@@ -637,8 +637,6 @@ int dw_pcie_host_init(struct pcie_port *pp) | |||
637 | } | 637 | } |
638 | } | 638 | } |
639 | 639 | ||
640 | pp->iatu_unroll_enabled = dw_pcie_iatu_unroll_enabled(pp); | ||
641 | |||
642 | if (pp->ops->host_init) | 640 | if (pp->ops->host_init) |
643 | pp->ops->host_init(pp); | 641 | pp->ops->host_init(pp); |
644 | 642 | ||
@@ -809,6 +807,11 @@ void dw_pcie_setup_rc(struct pcie_port *pp) | |||
809 | { | 807 | { |
810 | u32 val; | 808 | u32 val; |
811 | 809 | ||
810 | /* get iATU unroll support */ | ||
811 | pp->iatu_unroll_enabled = dw_pcie_iatu_unroll_enabled(pp); | ||
812 | dev_dbg(pp->dev, "iATU unroll: %s\n", | ||
813 | pp->iatu_unroll_enabled ? "enabled" : "disabled"); | ||
814 | |||
812 | /* set the number of lanes */ | 815 | /* set the number of lanes */ |
813 | val = dw_pcie_readl_rc(pp, PCIE_PORT_LINK_CONTROL); | 816 | val = dw_pcie_readl_rc(pp, PCIE_PORT_LINK_CONTROL); |
814 | val &= ~PORT_LINK_MODE_MASK; | 817 | val &= ~PORT_LINK_MODE_MASK; |
diff --git a/drivers/pci/host/pcie-hisi.c b/drivers/pci/host/pcie-hisi.c index 56154c25980c..a301a7187b30 100644 --- a/drivers/pci/host/pcie-hisi.c +++ b/drivers/pci/host/pcie-hisi.c | |||
@@ -18,7 +18,106 @@ | |||
18 | #include <linux/of_pci.h> | 18 | #include <linux/of_pci.h> |
19 | #include <linux/platform_device.h> | 19 | #include <linux/platform_device.h> |
20 | #include <linux/of_device.h> | 20 | #include <linux/of_device.h> |
21 | #include <linux/pci.h> | ||
22 | #include <linux/pci-acpi.h> | ||
23 | #include <linux/pci-ecam.h> | ||
21 | #include <linux/regmap.h> | 24 | #include <linux/regmap.h> |
25 | #include "../pci.h" | ||
26 | |||
27 | #if defined(CONFIG_ACPI) && defined(CONFIG_PCI_QUIRKS) | ||
28 | |||
29 | static int hisi_pcie_acpi_rd_conf(struct pci_bus *bus, u32 devfn, int where, | ||
30 | int size, u32 *val) | ||
31 | { | ||
32 | struct pci_config_window *cfg = bus->sysdata; | ||
33 | int dev = PCI_SLOT(devfn); | ||
34 | |||
35 | if (bus->number == cfg->busr.start) { | ||
36 | /* access only one slot on each root port */ | ||
37 | if (dev > 0) | ||
38 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
39 | else | ||
40 | return pci_generic_config_read32(bus, devfn, where, | ||
41 | size, val); | ||
42 | } | ||
43 | |||
44 | return pci_generic_config_read(bus, devfn, where, size, val); | ||
45 | } | ||
46 | |||
47 | static int hisi_pcie_acpi_wr_conf(struct pci_bus *bus, u32 devfn, | ||
48 | int where, int size, u32 val) | ||
49 | { | ||
50 | struct pci_config_window *cfg = bus->sysdata; | ||
51 | int dev = PCI_SLOT(devfn); | ||
52 | |||
53 | if (bus->number == cfg->busr.start) { | ||
54 | /* access only one slot on each root port */ | ||
55 | if (dev > 0) | ||
56 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
57 | else | ||
58 | return pci_generic_config_write32(bus, devfn, where, | ||
59 | size, val); | ||
60 | } | ||
61 | |||
62 | return pci_generic_config_write(bus, devfn, where, size, val); | ||
63 | } | ||
64 | |||
65 | static void __iomem *hisi_pcie_map_bus(struct pci_bus *bus, unsigned int devfn, | ||
66 | int where) | ||
67 | { | ||
68 | struct pci_config_window *cfg = bus->sysdata; | ||
69 | void __iomem *reg_base = cfg->priv; | ||
70 | |||
71 | if (bus->number == cfg->busr.start) | ||
72 | return reg_base + where; | ||
73 | else | ||
74 | return pci_ecam_map_bus(bus, devfn, where); | ||
75 | } | ||
76 | |||
77 | static int hisi_pcie_init(struct pci_config_window *cfg) | ||
78 | { | ||
79 | struct device *dev = cfg->parent; | ||
80 | struct acpi_device *adev = to_acpi_device(dev); | ||
81 | struct acpi_pci_root *root = acpi_driver_data(adev); | ||
82 | struct resource *res; | ||
83 | void __iomem *reg_base; | ||
84 | int ret; | ||
85 | |||
86 | /* | ||
87 | * Retrieve RC base and size from a HISI0081 device with _UID | ||
88 | * matching our segment. | ||
89 | */ | ||
90 | res = devm_kzalloc(dev, sizeof(*res), GFP_KERNEL); | ||
91 | if (!res) | ||
92 | return -ENOMEM; | ||
93 | |||
94 | ret = acpi_get_rc_resources(dev, "HISI0081", root->segment, res); | ||
95 | if (ret) { | ||
96 | dev_err(dev, "can't get rc base address\n"); | ||
97 | return -ENOMEM; | ||
98 | } | ||
99 | |||
100 | reg_base = devm_ioremap(dev, res->start, resource_size(res)); | ||
101 | if (!reg_base) | ||
102 | return -ENOMEM; | ||
103 | |||
104 | cfg->priv = reg_base; | ||
105 | return 0; | ||
106 | } | ||
107 | |||
108 | struct pci_ecam_ops hisi_pcie_ops = { | ||
109 | .bus_shift = 20, | ||
110 | .init = hisi_pcie_init, | ||
111 | .pci_ops = { | ||
112 | .map_bus = hisi_pcie_map_bus, | ||
113 | .read = hisi_pcie_acpi_rd_conf, | ||
114 | .write = hisi_pcie_acpi_wr_conf, | ||
115 | } | ||
116 | }; | ||
117 | |||
118 | #endif | ||
119 | |||
120 | #ifdef CONFIG_PCI_HISI | ||
22 | 121 | ||
23 | #include "pcie-designware.h" | 122 | #include "pcie-designware.h" |
24 | 123 | ||
@@ -185,17 +284,13 @@ static int hisi_pcie_probe(struct platform_device *pdev) | |||
185 | 284 | ||
186 | reg = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rc_dbi"); | 285 | reg = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rc_dbi"); |
187 | pp->dbi_base = devm_ioremap_resource(dev, reg); | 286 | pp->dbi_base = devm_ioremap_resource(dev, reg); |
188 | if (IS_ERR(pp->dbi_base)) { | 287 | if (IS_ERR(pp->dbi_base)) |
189 | dev_err(dev, "cannot get rc_dbi base\n"); | ||
190 | return PTR_ERR(pp->dbi_base); | 288 | return PTR_ERR(pp->dbi_base); |
191 | } | ||
192 | 289 | ||
193 | ret = hisi_add_pcie_port(hisi_pcie, pdev); | 290 | ret = hisi_add_pcie_port(hisi_pcie, pdev); |
194 | if (ret) | 291 | if (ret) |
195 | return ret; | 292 | return ret; |
196 | 293 | ||
197 | dev_warn(dev, "only 32-bit config accesses supported; smaller writes may corrupt adjacent RW1C fields\n"); | ||
198 | |||
199 | return 0; | 294 | return 0; |
200 | } | 295 | } |
201 | 296 | ||
@@ -227,3 +322,5 @@ static struct platform_driver hisi_pcie_driver = { | |||
227 | }, | 322 | }, |
228 | }; | 323 | }; |
229 | builtin_platform_driver(hisi_pcie_driver); | 324 | builtin_platform_driver(hisi_pcie_driver); |
325 | |||
326 | #endif | ||
diff --git a/drivers/pci/host/pcie-iproc-bcma.c b/drivers/pci/host/pcie-iproc-bcma.c index 8ce089043a27..bd4c9ec25edc 100644 --- a/drivers/pci/host/pcie-iproc-bcma.c +++ b/drivers/pci/host/pcie-iproc-bcma.c | |||
@@ -54,6 +54,7 @@ static int iproc_pcie_bcma_probe(struct bcma_device *bdev) | |||
54 | 54 | ||
55 | pcie->dev = dev; | 55 | pcie->dev = dev; |
56 | 56 | ||
57 | pcie->type = IPROC_PCIE_PAXB_BCMA; | ||
57 | pcie->base = bdev->io_addr; | 58 | pcie->base = bdev->io_addr; |
58 | if (!pcie->base) { | 59 | if (!pcie->base) { |
59 | dev_err(dev, "no controller registers\n"); | 60 | dev_err(dev, "no controller registers\n"); |
diff --git a/drivers/pci/host/pcie-iproc-msi.c b/drivers/pci/host/pcie-iproc-msi.c index 9a2973bdc78a..9fad7915f82a 100644 --- a/drivers/pci/host/pcie-iproc-msi.c +++ b/drivers/pci/host/pcie-iproc-msi.c | |||
@@ -563,6 +563,7 @@ int iproc_msi_init(struct iproc_pcie *pcie, struct device_node *node) | |||
563 | } | 563 | } |
564 | 564 | ||
565 | switch (pcie->type) { | 565 | switch (pcie->type) { |
566 | case IPROC_PCIE_PAXB_BCMA: | ||
566 | case IPROC_PCIE_PAXB: | 567 | case IPROC_PCIE_PAXB: |
567 | msi->reg_offsets = iproc_msi_reg_paxb; | 568 | msi->reg_offsets = iproc_msi_reg_paxb; |
568 | msi->nr_eq_region = 1; | 569 | msi->nr_eq_region = 1; |
diff --git a/drivers/pci/host/pcie-iproc-platform.c b/drivers/pci/host/pcie-iproc-platform.c index a3de087976b3..22d814a78a78 100644 --- a/drivers/pci/host/pcie-iproc-platform.c +++ b/drivers/pci/host/pcie-iproc-platform.c | |||
@@ -31,8 +31,14 @@ static const struct of_device_id iproc_pcie_of_match_table[] = { | |||
31 | .compatible = "brcm,iproc-pcie", | 31 | .compatible = "brcm,iproc-pcie", |
32 | .data = (int *)IPROC_PCIE_PAXB, | 32 | .data = (int *)IPROC_PCIE_PAXB, |
33 | }, { | 33 | }, { |
34 | .compatible = "brcm,iproc-pcie-paxb-v2", | ||
35 | .data = (int *)IPROC_PCIE_PAXB_V2, | ||
36 | }, { | ||
34 | .compatible = "brcm,iproc-pcie-paxc", | 37 | .compatible = "brcm,iproc-pcie-paxc", |
35 | .data = (int *)IPROC_PCIE_PAXC, | 38 | .data = (int *)IPROC_PCIE_PAXC, |
39 | }, { | ||
40 | .compatible = "brcm,iproc-pcie-paxc-v2", | ||
41 | .data = (int *)IPROC_PCIE_PAXC_V2, | ||
36 | }, | 42 | }, |
37 | { /* sentinel */ } | 43 | { /* sentinel */ } |
38 | }; | 44 | }; |
@@ -84,19 +90,6 @@ static int iproc_pcie_pltfm_probe(struct platform_device *pdev) | |||
84 | return ret; | 90 | return ret; |
85 | } | 91 | } |
86 | pcie->ob.axi_offset = val; | 92 | pcie->ob.axi_offset = val; |
87 | |||
88 | ret = of_property_read_u32(np, "brcm,pcie-ob-window-size", | ||
89 | &val); | ||
90 | if (ret) { | ||
91 | dev_err(dev, | ||
92 | "missing brcm,pcie-ob-window-size property\n"); | ||
93 | return ret; | ||
94 | } | ||
95 | pcie->ob.window_size = (resource_size_t)val * SZ_1M; | ||
96 | |||
97 | if (of_property_read_bool(np, "brcm,pcie-ob-oarr-size")) | ||
98 | pcie->ob.set_oarr_size = true; | ||
99 | |||
100 | pcie->need_ob_cfg = true; | 93 | pcie->need_ob_cfg = true; |
101 | } | 94 | } |
102 | 95 | ||
@@ -115,7 +108,14 @@ static int iproc_pcie_pltfm_probe(struct platform_device *pdev) | |||
115 | return ret; | 108 | return ret; |
116 | } | 109 | } |
117 | 110 | ||
118 | pcie->map_irq = of_irq_parse_and_map_pci; | 111 | /* PAXC doesn't support legacy IRQs, skip mapping */ |
112 | switch (pcie->type) { | ||
113 | case IPROC_PCIE_PAXC: | ||
114 | case IPROC_PCIE_PAXC_V2: | ||
115 | break; | ||
116 | default: | ||
117 | pcie->map_irq = of_irq_parse_and_map_pci; | ||
118 | } | ||
119 | 119 | ||
120 | ret = iproc_pcie_setup(pcie, &res); | 120 | ret = iproc_pcie_setup(pcie, &res); |
121 | if (ret) | 121 | if (ret) |
diff --git a/drivers/pci/host/pcie-iproc.c b/drivers/pci/host/pcie-iproc.c index 0b999a9fb843..3ebc025499b9 100644 --- a/drivers/pci/host/pcie-iproc.c +++ b/drivers/pci/host/pcie-iproc.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
22 | #include <linux/delay.h> | 22 | #include <linux/delay.h> |
23 | #include <linux/interrupt.h> | 23 | #include <linux/interrupt.h> |
24 | #include <linux/irqchip/arm-gic-v3.h> | ||
24 | #include <linux/platform_device.h> | 25 | #include <linux/platform_device.h> |
25 | #include <linux/of_address.h> | 26 | #include <linux/of_address.h> |
26 | #include <linux/of_pci.h> | 27 | #include <linux/of_pci.h> |
@@ -38,6 +39,12 @@ | |||
38 | #define RC_PCIE_RST_OUTPUT BIT(RC_PCIE_RST_OUTPUT_SHIFT) | 39 | #define RC_PCIE_RST_OUTPUT BIT(RC_PCIE_RST_OUTPUT_SHIFT) |
39 | #define PAXC_RESET_MASK 0x7f | 40 | #define PAXC_RESET_MASK 0x7f |
40 | 41 | ||
42 | #define GIC_V3_CFG_SHIFT 0 | ||
43 | #define GIC_V3_CFG BIT(GIC_V3_CFG_SHIFT) | ||
44 | |||
45 | #define MSI_ENABLE_CFG_SHIFT 0 | ||
46 | #define MSI_ENABLE_CFG BIT(MSI_ENABLE_CFG_SHIFT) | ||
47 | |||
41 | #define CFG_IND_ADDR_MASK 0x00001ffc | 48 | #define CFG_IND_ADDR_MASK 0x00001ffc |
42 | 49 | ||
43 | #define CFG_ADDR_BUS_NUM_SHIFT 20 | 50 | #define CFG_ADDR_BUS_NUM_SHIFT 20 |
@@ -58,59 +65,319 @@ | |||
58 | #define PCIE_DL_ACTIVE_SHIFT 2 | 65 | #define PCIE_DL_ACTIVE_SHIFT 2 |
59 | #define PCIE_DL_ACTIVE BIT(PCIE_DL_ACTIVE_SHIFT) | 66 | #define PCIE_DL_ACTIVE BIT(PCIE_DL_ACTIVE_SHIFT) |
60 | 67 | ||
68 | #define APB_ERR_EN_SHIFT 0 | ||
69 | #define APB_ERR_EN BIT(APB_ERR_EN_SHIFT) | ||
70 | |||
71 | /* derive the enum index of the outbound/inbound mapping registers */ | ||
72 | #define MAP_REG(base_reg, index) ((base_reg) + (index) * 2) | ||
73 | |||
74 | /* | ||
75 | * Maximum number of outbound mapping window sizes that can be supported by any | ||
76 | * OARR/OMAP mapping pair | ||
77 | */ | ||
78 | #define MAX_NUM_OB_WINDOW_SIZES 4 | ||
79 | |||
61 | #define OARR_VALID_SHIFT 0 | 80 | #define OARR_VALID_SHIFT 0 |
62 | #define OARR_VALID BIT(OARR_VALID_SHIFT) | 81 | #define OARR_VALID BIT(OARR_VALID_SHIFT) |
63 | #define OARR_SIZE_CFG_SHIFT 1 | 82 | #define OARR_SIZE_CFG_SHIFT 1 |
64 | #define OARR_SIZE_CFG BIT(OARR_SIZE_CFG_SHIFT) | ||
65 | 83 | ||
66 | #define PCI_EXP_CAP 0xac | 84 | /* |
85 | * Maximum number of inbound mapping region sizes that can be supported by an | ||
86 | * IARR | ||
87 | */ | ||
88 | #define MAX_NUM_IB_REGION_SIZES 9 | ||
89 | |||
90 | #define IMAP_VALID_SHIFT 0 | ||
91 | #define IMAP_VALID BIT(IMAP_VALID_SHIFT) | ||
67 | 92 | ||
68 | #define MAX_NUM_OB_WINDOWS 2 | 93 | #define PCI_EXP_CAP 0xac |
69 | 94 | ||
70 | #define IPROC_PCIE_REG_INVALID 0xffff | 95 | #define IPROC_PCIE_REG_INVALID 0xffff |
71 | 96 | ||
97 | /** | ||
98 | * iProc PCIe outbound mapping controller specific parameters | ||
99 | * | ||
100 | * @window_sizes: list of supported outbound mapping window sizes in MB | ||
101 | * @nr_sizes: number of supported outbound mapping window sizes | ||
102 | */ | ||
103 | struct iproc_pcie_ob_map { | ||
104 | resource_size_t window_sizes[MAX_NUM_OB_WINDOW_SIZES]; | ||
105 | unsigned int nr_sizes; | ||
106 | }; | ||
107 | |||
108 | static const struct iproc_pcie_ob_map paxb_ob_map[] = { | ||
109 | { | ||
110 | /* OARR0/OMAP0 */ | ||
111 | .window_sizes = { 128, 256 }, | ||
112 | .nr_sizes = 2, | ||
113 | }, | ||
114 | { | ||
115 | /* OARR1/OMAP1 */ | ||
116 | .window_sizes = { 128, 256 }, | ||
117 | .nr_sizes = 2, | ||
118 | }, | ||
119 | }; | ||
120 | |||
121 | static const struct iproc_pcie_ob_map paxb_v2_ob_map[] = { | ||
122 | { | ||
123 | /* OARR0/OMAP0 */ | ||
124 | .window_sizes = { 128, 256 }, | ||
125 | .nr_sizes = 2, | ||
126 | }, | ||
127 | { | ||
128 | /* OARR1/OMAP1 */ | ||
129 | .window_sizes = { 128, 256 }, | ||
130 | .nr_sizes = 2, | ||
131 | }, | ||
132 | { | ||
133 | /* OARR2/OMAP2 */ | ||
134 | .window_sizes = { 128, 256, 512, 1024 }, | ||
135 | .nr_sizes = 4, | ||
136 | }, | ||
137 | { | ||
138 | /* OARR3/OMAP3 */ | ||
139 | .window_sizes = { 128, 256, 512, 1024 }, | ||
140 | .nr_sizes = 4, | ||
141 | }, | ||
142 | }; | ||
143 | |||
144 | /** | ||
145 | * iProc PCIe inbound mapping type | ||
146 | */ | ||
147 | enum iproc_pcie_ib_map_type { | ||
148 | /* for DDR memory */ | ||
149 | IPROC_PCIE_IB_MAP_MEM = 0, | ||
150 | |||
151 | /* for device I/O memory */ | ||
152 | IPROC_PCIE_IB_MAP_IO, | ||
153 | |||
154 | /* invalid or unused */ | ||
155 | IPROC_PCIE_IB_MAP_INVALID | ||
156 | }; | ||
157 | |||
158 | /** | ||
159 | * iProc PCIe inbound mapping controller specific parameters | ||
160 | * | ||
161 | * @type: inbound mapping region type | ||
162 | * @size_unit: inbound mapping region size unit, could be SZ_1K, SZ_1M, or | ||
163 | * SZ_1G | ||
164 | * @region_sizes: list of supported inbound mapping region sizes in KB, MB, or | ||
165 | * GB, depedning on the size unit | ||
166 | * @nr_sizes: number of supported inbound mapping region sizes | ||
167 | * @nr_windows: number of supported inbound mapping windows for the region | ||
168 | * @imap_addr_offset: register offset between the upper and lower 32-bit | ||
169 | * IMAP address registers | ||
170 | * @imap_window_offset: register offset between each IMAP window | ||
171 | */ | ||
172 | struct iproc_pcie_ib_map { | ||
173 | enum iproc_pcie_ib_map_type type; | ||
174 | unsigned int size_unit; | ||
175 | resource_size_t region_sizes[MAX_NUM_IB_REGION_SIZES]; | ||
176 | unsigned int nr_sizes; | ||
177 | unsigned int nr_windows; | ||
178 | u16 imap_addr_offset; | ||
179 | u16 imap_window_offset; | ||
180 | }; | ||
181 | |||
182 | static const struct iproc_pcie_ib_map paxb_v2_ib_map[] = { | ||
183 | { | ||
184 | /* IARR0/IMAP0 */ | ||
185 | .type = IPROC_PCIE_IB_MAP_IO, | ||
186 | .size_unit = SZ_1K, | ||
187 | .region_sizes = { 32 }, | ||
188 | .nr_sizes = 1, | ||
189 | .nr_windows = 8, | ||
190 | .imap_addr_offset = 0x40, | ||
191 | .imap_window_offset = 0x4, | ||
192 | }, | ||
193 | { | ||
194 | /* IARR1/IMAP1 (currently unused) */ | ||
195 | .type = IPROC_PCIE_IB_MAP_INVALID, | ||
196 | }, | ||
197 | { | ||
198 | /* IARR2/IMAP2 */ | ||
199 | .type = IPROC_PCIE_IB_MAP_MEM, | ||
200 | .size_unit = SZ_1M, | ||
201 | .region_sizes = { 64, 128, 256, 512, 1024, 2048, 4096, 8192, | ||
202 | 16384 }, | ||
203 | .nr_sizes = 9, | ||
204 | .nr_windows = 1, | ||
205 | .imap_addr_offset = 0x4, | ||
206 | .imap_window_offset = 0x8, | ||
207 | }, | ||
208 | { | ||
209 | /* IARR3/IMAP3 */ | ||
210 | .type = IPROC_PCIE_IB_MAP_MEM, | ||
211 | .size_unit = SZ_1G, | ||
212 | .region_sizes = { 1, 2, 4, 8, 16, 32 }, | ||
213 | .nr_sizes = 6, | ||
214 | .nr_windows = 8, | ||
215 | .imap_addr_offset = 0x4, | ||
216 | .imap_window_offset = 0x8, | ||
217 | }, | ||
218 | { | ||
219 | /* IARR4/IMAP4 */ | ||
220 | .type = IPROC_PCIE_IB_MAP_MEM, | ||
221 | .size_unit = SZ_1G, | ||
222 | .region_sizes = { 32, 64, 128, 256, 512 }, | ||
223 | .nr_sizes = 5, | ||
224 | .nr_windows = 8, | ||
225 | .imap_addr_offset = 0x4, | ||
226 | .imap_window_offset = 0x8, | ||
227 | }, | ||
228 | }; | ||
229 | |||
230 | /* | ||
231 | * iProc PCIe host registers | ||
232 | */ | ||
72 | enum iproc_pcie_reg { | 233 | enum iproc_pcie_reg { |
234 | /* clock/reset signal control */ | ||
73 | IPROC_PCIE_CLK_CTRL = 0, | 235 | IPROC_PCIE_CLK_CTRL = 0, |
236 | |||
237 | /* | ||
238 | * To allow MSI to be steered to an external MSI controller (e.g., ARM | ||
239 | * GICv3 ITS) | ||
240 | */ | ||
241 | IPROC_PCIE_MSI_GIC_MODE, | ||
242 | |||
243 | /* | ||
244 | * IPROC_PCIE_MSI_BASE_ADDR and IPROC_PCIE_MSI_WINDOW_SIZE define the | ||
245 | * window where the MSI posted writes are written, for the writes to be | ||
246 | * interpreted as MSI writes. | ||
247 | */ | ||
248 | IPROC_PCIE_MSI_BASE_ADDR, | ||
249 | IPROC_PCIE_MSI_WINDOW_SIZE, | ||
250 | |||
251 | /* | ||
252 | * To hold the address of the register where the MSI writes are | ||
253 | * programed. When ARM GICv3 ITS is used, this should be programmed | ||
254 | * with the address of the GITS_TRANSLATER register. | ||
255 | */ | ||
256 | IPROC_PCIE_MSI_ADDR_LO, | ||
257 | IPROC_PCIE_MSI_ADDR_HI, | ||
258 | |||
259 | /* enable MSI */ | ||
260 | IPROC_PCIE_MSI_EN_CFG, | ||
261 | |||
262 | /* allow access to root complex configuration space */ | ||
74 | IPROC_PCIE_CFG_IND_ADDR, | 263 | IPROC_PCIE_CFG_IND_ADDR, |
75 | IPROC_PCIE_CFG_IND_DATA, | 264 | IPROC_PCIE_CFG_IND_DATA, |
265 | |||
266 | /* allow access to device configuration space */ | ||
76 | IPROC_PCIE_CFG_ADDR, | 267 | IPROC_PCIE_CFG_ADDR, |
77 | IPROC_PCIE_CFG_DATA, | 268 | IPROC_PCIE_CFG_DATA, |
269 | |||
270 | /* enable INTx */ | ||
78 | IPROC_PCIE_INTX_EN, | 271 | IPROC_PCIE_INTX_EN, |
79 | IPROC_PCIE_OARR_LO, | 272 | |
80 | IPROC_PCIE_OARR_HI, | 273 | /* outbound address mapping */ |
81 | IPROC_PCIE_OMAP_LO, | 274 | IPROC_PCIE_OARR0, |
82 | IPROC_PCIE_OMAP_HI, | 275 | IPROC_PCIE_OMAP0, |
276 | IPROC_PCIE_OARR1, | ||
277 | IPROC_PCIE_OMAP1, | ||
278 | IPROC_PCIE_OARR2, | ||
279 | IPROC_PCIE_OMAP2, | ||
280 | IPROC_PCIE_OARR3, | ||
281 | IPROC_PCIE_OMAP3, | ||
282 | |||
283 | /* inbound address mapping */ | ||
284 | IPROC_PCIE_IARR0, | ||
285 | IPROC_PCIE_IMAP0, | ||
286 | IPROC_PCIE_IARR1, | ||
287 | IPROC_PCIE_IMAP1, | ||
288 | IPROC_PCIE_IARR2, | ||
289 | IPROC_PCIE_IMAP2, | ||
290 | IPROC_PCIE_IARR3, | ||
291 | IPROC_PCIE_IMAP3, | ||
292 | IPROC_PCIE_IARR4, | ||
293 | IPROC_PCIE_IMAP4, | ||
294 | |||
295 | /* link status */ | ||
83 | IPROC_PCIE_LINK_STATUS, | 296 | IPROC_PCIE_LINK_STATUS, |
297 | |||
298 | /* enable APB error for unsupported requests */ | ||
299 | IPROC_PCIE_APB_ERR_EN, | ||
300 | |||
301 | /* total number of core registers */ | ||
302 | IPROC_PCIE_MAX_NUM_REG, | ||
303 | }; | ||
304 | |||
305 | /* iProc PCIe PAXB BCMA registers */ | ||
306 | static const u16 iproc_pcie_reg_paxb_bcma[] = { | ||
307 | [IPROC_PCIE_CLK_CTRL] = 0x000, | ||
308 | [IPROC_PCIE_CFG_IND_ADDR] = 0x120, | ||
309 | [IPROC_PCIE_CFG_IND_DATA] = 0x124, | ||
310 | [IPROC_PCIE_CFG_ADDR] = 0x1f8, | ||
311 | [IPROC_PCIE_CFG_DATA] = 0x1fc, | ||
312 | [IPROC_PCIE_INTX_EN] = 0x330, | ||
313 | [IPROC_PCIE_LINK_STATUS] = 0xf0c, | ||
84 | }; | 314 | }; |
85 | 315 | ||
86 | /* iProc PCIe PAXB registers */ | 316 | /* iProc PCIe PAXB registers */ |
87 | static const u16 iproc_pcie_reg_paxb[] = { | 317 | static const u16 iproc_pcie_reg_paxb[] = { |
88 | [IPROC_PCIE_CLK_CTRL] = 0x000, | 318 | [IPROC_PCIE_CLK_CTRL] = 0x000, |
89 | [IPROC_PCIE_CFG_IND_ADDR] = 0x120, | 319 | [IPROC_PCIE_CFG_IND_ADDR] = 0x120, |
90 | [IPROC_PCIE_CFG_IND_DATA] = 0x124, | 320 | [IPROC_PCIE_CFG_IND_DATA] = 0x124, |
91 | [IPROC_PCIE_CFG_ADDR] = 0x1f8, | 321 | [IPROC_PCIE_CFG_ADDR] = 0x1f8, |
92 | [IPROC_PCIE_CFG_DATA] = 0x1fc, | 322 | [IPROC_PCIE_CFG_DATA] = 0x1fc, |
93 | [IPROC_PCIE_INTX_EN] = 0x330, | 323 | [IPROC_PCIE_INTX_EN] = 0x330, |
94 | [IPROC_PCIE_OARR_LO] = 0xd20, | 324 | [IPROC_PCIE_OARR0] = 0xd20, |
95 | [IPROC_PCIE_OARR_HI] = 0xd24, | 325 | [IPROC_PCIE_OMAP0] = 0xd40, |
96 | [IPROC_PCIE_OMAP_LO] = 0xd40, | 326 | [IPROC_PCIE_OARR1] = 0xd28, |
97 | [IPROC_PCIE_OMAP_HI] = 0xd44, | 327 | [IPROC_PCIE_OMAP1] = 0xd48, |
98 | [IPROC_PCIE_LINK_STATUS] = 0xf0c, | 328 | [IPROC_PCIE_LINK_STATUS] = 0xf0c, |
329 | [IPROC_PCIE_APB_ERR_EN] = 0xf40, | ||
330 | }; | ||
331 | |||
332 | /* iProc PCIe PAXB v2 registers */ | ||
333 | static const u16 iproc_pcie_reg_paxb_v2[] = { | ||
334 | [IPROC_PCIE_CLK_CTRL] = 0x000, | ||
335 | [IPROC_PCIE_CFG_IND_ADDR] = 0x120, | ||
336 | [IPROC_PCIE_CFG_IND_DATA] = 0x124, | ||
337 | [IPROC_PCIE_CFG_ADDR] = 0x1f8, | ||
338 | [IPROC_PCIE_CFG_DATA] = 0x1fc, | ||
339 | [IPROC_PCIE_INTX_EN] = 0x330, | ||
340 | [IPROC_PCIE_OARR0] = 0xd20, | ||
341 | [IPROC_PCIE_OMAP0] = 0xd40, | ||
342 | [IPROC_PCIE_OARR1] = 0xd28, | ||
343 | [IPROC_PCIE_OMAP1] = 0xd48, | ||
344 | [IPROC_PCIE_OARR2] = 0xd60, | ||
345 | [IPROC_PCIE_OMAP2] = 0xd68, | ||
346 | [IPROC_PCIE_OARR3] = 0xdf0, | ||
347 | [IPROC_PCIE_OMAP3] = 0xdf8, | ||
348 | [IPROC_PCIE_IARR0] = 0xd00, | ||
349 | [IPROC_PCIE_IMAP0] = 0xc00, | ||
350 | [IPROC_PCIE_IARR2] = 0xd10, | ||
351 | [IPROC_PCIE_IMAP2] = 0xcc0, | ||
352 | [IPROC_PCIE_IARR3] = 0xe00, | ||
353 | [IPROC_PCIE_IMAP3] = 0xe08, | ||
354 | [IPROC_PCIE_IARR4] = 0xe68, | ||
355 | [IPROC_PCIE_IMAP4] = 0xe70, | ||
356 | [IPROC_PCIE_LINK_STATUS] = 0xf0c, | ||
357 | [IPROC_PCIE_APB_ERR_EN] = 0xf40, | ||
99 | }; | 358 | }; |
100 | 359 | ||
101 | /* iProc PCIe PAXC v1 registers */ | 360 | /* iProc PCIe PAXC v1 registers */ |
102 | static const u16 iproc_pcie_reg_paxc[] = { | 361 | static const u16 iproc_pcie_reg_paxc[] = { |
103 | [IPROC_PCIE_CLK_CTRL] = 0x000, | 362 | [IPROC_PCIE_CLK_CTRL] = 0x000, |
104 | [IPROC_PCIE_CFG_IND_ADDR] = 0x1f0, | 363 | [IPROC_PCIE_CFG_IND_ADDR] = 0x1f0, |
105 | [IPROC_PCIE_CFG_IND_DATA] = 0x1f4, | 364 | [IPROC_PCIE_CFG_IND_DATA] = 0x1f4, |
106 | [IPROC_PCIE_CFG_ADDR] = 0x1f8, | 365 | [IPROC_PCIE_CFG_ADDR] = 0x1f8, |
107 | [IPROC_PCIE_CFG_DATA] = 0x1fc, | 366 | [IPROC_PCIE_CFG_DATA] = 0x1fc, |
108 | [IPROC_PCIE_INTX_EN] = IPROC_PCIE_REG_INVALID, | 367 | }; |
109 | [IPROC_PCIE_OARR_LO] = IPROC_PCIE_REG_INVALID, | 368 | |
110 | [IPROC_PCIE_OARR_HI] = IPROC_PCIE_REG_INVALID, | 369 | /* iProc PCIe PAXC v2 registers */ |
111 | [IPROC_PCIE_OMAP_LO] = IPROC_PCIE_REG_INVALID, | 370 | static const u16 iproc_pcie_reg_paxc_v2[] = { |
112 | [IPROC_PCIE_OMAP_HI] = IPROC_PCIE_REG_INVALID, | 371 | [IPROC_PCIE_MSI_GIC_MODE] = 0x050, |
113 | [IPROC_PCIE_LINK_STATUS] = IPROC_PCIE_REG_INVALID, | 372 | [IPROC_PCIE_MSI_BASE_ADDR] = 0x074, |
373 | [IPROC_PCIE_MSI_WINDOW_SIZE] = 0x078, | ||
374 | [IPROC_PCIE_MSI_ADDR_LO] = 0x07c, | ||
375 | [IPROC_PCIE_MSI_ADDR_HI] = 0x080, | ||
376 | [IPROC_PCIE_MSI_EN_CFG] = 0x09c, | ||
377 | [IPROC_PCIE_CFG_IND_ADDR] = 0x1f0, | ||
378 | [IPROC_PCIE_CFG_IND_DATA] = 0x1f4, | ||
379 | [IPROC_PCIE_CFG_ADDR] = 0x1f8, | ||
380 | [IPROC_PCIE_CFG_DATA] = 0x1fc, | ||
114 | }; | 381 | }; |
115 | 382 | ||
116 | static inline struct iproc_pcie *iproc_data(struct pci_bus *bus) | 383 | static inline struct iproc_pcie *iproc_data(struct pci_bus *bus) |
@@ -159,16 +426,26 @@ static inline void iproc_pcie_write_reg(struct iproc_pcie *pcie, | |||
159 | writel(val, pcie->base + offset); | 426 | writel(val, pcie->base + offset); |
160 | } | 427 | } |
161 | 428 | ||
162 | static inline void iproc_pcie_ob_write(struct iproc_pcie *pcie, | 429 | /** |
163 | enum iproc_pcie_reg reg, | 430 | * APB error forwarding can be disabled during access of configuration |
164 | unsigned window, u32 val) | 431 | * registers of the endpoint device, to prevent unsupported requests |
432 | * (typically seen during enumeration with multi-function devices) from | ||
433 | * triggering a system exception. | ||
434 | */ | ||
435 | static inline void iproc_pcie_apb_err_disable(struct pci_bus *bus, | ||
436 | bool disable) | ||
165 | { | 437 | { |
166 | u16 offset = iproc_pcie_reg_offset(pcie, reg); | 438 | struct iproc_pcie *pcie = iproc_data(bus); |
167 | 439 | u32 val; | |
168 | if (iproc_pcie_reg_is_invalid(offset)) | ||
169 | return; | ||
170 | 440 | ||
171 | writel(val, pcie->base + offset + (window * 8)); | 441 | if (bus->number && pcie->has_apb_err_disable) { |
442 | val = iproc_pcie_read_reg(pcie, IPROC_PCIE_APB_ERR_EN); | ||
443 | if (disable) | ||
444 | val &= ~APB_ERR_EN; | ||
445 | else | ||
446 | val |= APB_ERR_EN; | ||
447 | iproc_pcie_write_reg(pcie, IPROC_PCIE_APB_ERR_EN, val); | ||
448 | } | ||
172 | } | 449 | } |
173 | 450 | ||
174 | /** | 451 | /** |
@@ -204,7 +481,7 @@ static void __iomem *iproc_pcie_map_cfg_bus(struct pci_bus *bus, | |||
204 | * PAXC is connected to an internally emulated EP within the SoC. It | 481 | * PAXC is connected to an internally emulated EP within the SoC. It |
205 | * allows only one device. | 482 | * allows only one device. |
206 | */ | 483 | */ |
207 | if (pcie->type == IPROC_PCIE_PAXC) | 484 | if (pcie->ep_is_internal) |
208 | if (slot > 0) | 485 | if (slot > 0) |
209 | return NULL; | 486 | return NULL; |
210 | 487 | ||
@@ -222,26 +499,47 @@ static void __iomem *iproc_pcie_map_cfg_bus(struct pci_bus *bus, | |||
222 | return (pcie->base + offset); | 499 | return (pcie->base + offset); |
223 | } | 500 | } |
224 | 501 | ||
502 | static int iproc_pcie_config_read32(struct pci_bus *bus, unsigned int devfn, | ||
503 | int where, int size, u32 *val) | ||
504 | { | ||
505 | int ret; | ||
506 | |||
507 | iproc_pcie_apb_err_disable(bus, true); | ||
508 | ret = pci_generic_config_read32(bus, devfn, where, size, val); | ||
509 | iproc_pcie_apb_err_disable(bus, false); | ||
510 | |||
511 | return ret; | ||
512 | } | ||
513 | |||
514 | static int iproc_pcie_config_write32(struct pci_bus *bus, unsigned int devfn, | ||
515 | int where, int size, u32 val) | ||
516 | { | ||
517 | int ret; | ||
518 | |||
519 | iproc_pcie_apb_err_disable(bus, true); | ||
520 | ret = pci_generic_config_write32(bus, devfn, where, size, val); | ||
521 | iproc_pcie_apb_err_disable(bus, false); | ||
522 | |||
523 | return ret; | ||
524 | } | ||
525 | |||
225 | static struct pci_ops iproc_pcie_ops = { | 526 | static struct pci_ops iproc_pcie_ops = { |
226 | .map_bus = iproc_pcie_map_cfg_bus, | 527 | .map_bus = iproc_pcie_map_cfg_bus, |
227 | .read = pci_generic_config_read32, | 528 | .read = iproc_pcie_config_read32, |
228 | .write = pci_generic_config_write32, | 529 | .write = iproc_pcie_config_write32, |
229 | }; | 530 | }; |
230 | 531 | ||
231 | static void iproc_pcie_reset(struct iproc_pcie *pcie) | 532 | static void iproc_pcie_reset(struct iproc_pcie *pcie) |
232 | { | 533 | { |
233 | u32 val; | 534 | u32 val; |
234 | 535 | ||
235 | if (pcie->type == IPROC_PCIE_PAXC) { | 536 | /* |
236 | val = iproc_pcie_read_reg(pcie, IPROC_PCIE_CLK_CTRL); | 537 | * PAXC and the internal emulated endpoint device downstream should not |
237 | val &= ~PAXC_RESET_MASK; | 538 | * be reset. If firmware has been loaded on the endpoint device at an |
238 | iproc_pcie_write_reg(pcie, IPROC_PCIE_CLK_CTRL, val); | 539 | * earlier boot stage, reset here causes issues. |
239 | udelay(100); | 540 | */ |
240 | val |= PAXC_RESET_MASK; | 541 | if (pcie->ep_is_internal) |
241 | iproc_pcie_write_reg(pcie, IPROC_PCIE_CLK_CTRL, val); | ||
242 | udelay(100); | ||
243 | return; | 542 | return; |
244 | } | ||
245 | 543 | ||
246 | /* | 544 | /* |
247 | * Select perst_b signal as reset source. Put the device into reset, | 545 | * Select perst_b signal as reset source. Put the device into reset, |
@@ -270,7 +568,7 @@ static int iproc_pcie_check_link(struct iproc_pcie *pcie, struct pci_bus *bus) | |||
270 | * PAXC connects to emulated endpoint devices directly and does not | 568 | * PAXC connects to emulated endpoint devices directly and does not |
271 | * have a Serdes. Therefore skip the link detection logic here. | 569 | * have a Serdes. Therefore skip the link detection logic here. |
272 | */ | 570 | */ |
273 | if (pcie->type == IPROC_PCIE_PAXC) | 571 | if (pcie->ep_is_internal) |
274 | return 0; | 572 | return 0; |
275 | 573 | ||
276 | val = iproc_pcie_read_reg(pcie, IPROC_PCIE_LINK_STATUS); | 574 | val = iproc_pcie_read_reg(pcie, IPROC_PCIE_LINK_STATUS); |
@@ -334,6 +632,58 @@ static void iproc_pcie_enable(struct iproc_pcie *pcie) | |||
334 | iproc_pcie_write_reg(pcie, IPROC_PCIE_INTX_EN, SYS_RC_INTX_MASK); | 632 | iproc_pcie_write_reg(pcie, IPROC_PCIE_INTX_EN, SYS_RC_INTX_MASK); |
335 | } | 633 | } |
336 | 634 | ||
635 | static inline bool iproc_pcie_ob_is_valid(struct iproc_pcie *pcie, | ||
636 | int window_idx) | ||
637 | { | ||
638 | u32 val; | ||
639 | |||
640 | val = iproc_pcie_read_reg(pcie, MAP_REG(IPROC_PCIE_OARR0, window_idx)); | ||
641 | |||
642 | return !!(val & OARR_VALID); | ||
643 | } | ||
644 | |||
645 | static inline int iproc_pcie_ob_write(struct iproc_pcie *pcie, int window_idx, | ||
646 | int size_idx, u64 axi_addr, u64 pci_addr) | ||
647 | { | ||
648 | struct device *dev = pcie->dev; | ||
649 | u16 oarr_offset, omap_offset; | ||
650 | |||
651 | /* | ||
652 | * Derive the OARR/OMAP offset from the first pair (OARR0/OMAP0) based | ||
653 | * on window index. | ||
654 | */ | ||
655 | oarr_offset = iproc_pcie_reg_offset(pcie, MAP_REG(IPROC_PCIE_OARR0, | ||
656 | window_idx)); | ||
657 | omap_offset = iproc_pcie_reg_offset(pcie, MAP_REG(IPROC_PCIE_OMAP0, | ||
658 | window_idx)); | ||
659 | if (iproc_pcie_reg_is_invalid(oarr_offset) || | ||
660 | iproc_pcie_reg_is_invalid(omap_offset)) | ||
661 | return -EINVAL; | ||
662 | |||
663 | /* | ||
664 | * Program the OARR registers. The upper 32-bit OARR register is | ||
665 | * always right after the lower 32-bit OARR register. | ||
666 | */ | ||
667 | writel(lower_32_bits(axi_addr) | (size_idx << OARR_SIZE_CFG_SHIFT) | | ||
668 | OARR_VALID, pcie->base + oarr_offset); | ||
669 | writel(upper_32_bits(axi_addr), pcie->base + oarr_offset + 4); | ||
670 | |||
671 | /* now program the OMAP registers */ | ||
672 | writel(lower_32_bits(pci_addr), pcie->base + omap_offset); | ||
673 | writel(upper_32_bits(pci_addr), pcie->base + omap_offset + 4); | ||
674 | |||
675 | dev_info(dev, "ob window [%d]: offset 0x%x axi %pap pci %pap\n", | ||
676 | window_idx, oarr_offset, &axi_addr, &pci_addr); | ||
677 | dev_info(dev, "oarr lo 0x%x oarr hi 0x%x\n", | ||
678 | readl(pcie->base + oarr_offset), | ||
679 | readl(pcie->base + oarr_offset + 4)); | ||
680 | dev_info(dev, "omap lo 0x%x omap hi 0x%x\n", | ||
681 | readl(pcie->base + omap_offset), | ||
682 | readl(pcie->base + omap_offset + 4)); | ||
683 | |||
684 | return 0; | ||
685 | } | ||
686 | |||
337 | /** | 687 | /** |
338 | * Some iProc SoCs require the SW to configure the outbound address mapping | 688 | * Some iProc SoCs require the SW to configure the outbound address mapping |
339 | * | 689 | * |
@@ -350,24 +700,7 @@ static int iproc_pcie_setup_ob(struct iproc_pcie *pcie, u64 axi_addr, | |||
350 | { | 700 | { |
351 | struct iproc_pcie_ob *ob = &pcie->ob; | 701 | struct iproc_pcie_ob *ob = &pcie->ob; |
352 | struct device *dev = pcie->dev; | 702 | struct device *dev = pcie->dev; |
353 | unsigned i; | 703 | int ret = -EINVAL, window_idx, size_idx; |
354 | u64 max_size = (u64)ob->window_size * MAX_NUM_OB_WINDOWS; | ||
355 | u64 remainder; | ||
356 | |||
357 | if (size > max_size) { | ||
358 | dev_err(dev, | ||
359 | "res size %pap exceeds max supported size 0x%llx\n", | ||
360 | &size, max_size); | ||
361 | return -EINVAL; | ||
362 | } | ||
363 | |||
364 | div64_u64_rem(size, ob->window_size, &remainder); | ||
365 | if (remainder) { | ||
366 | dev_err(dev, | ||
367 | "res size %pap needs to be multiple of window size %pap\n", | ||
368 | &size, &ob->window_size); | ||
369 | return -EINVAL; | ||
370 | } | ||
371 | 704 | ||
372 | if (axi_addr < ob->axi_offset) { | 705 | if (axi_addr < ob->axi_offset) { |
373 | dev_err(dev, "axi address %pap less than offset %pap\n", | 706 | dev_err(dev, "axi address %pap less than offset %pap\n", |
@@ -381,26 +714,70 @@ static int iproc_pcie_setup_ob(struct iproc_pcie *pcie, u64 axi_addr, | |||
381 | */ | 714 | */ |
382 | axi_addr -= ob->axi_offset; | 715 | axi_addr -= ob->axi_offset; |
383 | 716 | ||
384 | for (i = 0; i < MAX_NUM_OB_WINDOWS; i++) { | 717 | /* iterate through all OARR/OMAP mapping windows */ |
385 | iproc_pcie_ob_write(pcie, IPROC_PCIE_OARR_LO, i, | 718 | for (window_idx = ob->nr_windows - 1; window_idx >= 0; window_idx--) { |
386 | lower_32_bits(axi_addr) | OARR_VALID | | 719 | const struct iproc_pcie_ob_map *ob_map = |
387 | (ob->set_oarr_size ? 1 : 0)); | 720 | &pcie->ob_map[window_idx]; |
388 | iproc_pcie_ob_write(pcie, IPROC_PCIE_OARR_HI, i, | 721 | |
389 | upper_32_bits(axi_addr)); | 722 | /* |
390 | iproc_pcie_ob_write(pcie, IPROC_PCIE_OMAP_LO, i, | 723 | * If current outbound window is already in use, move on to the |
391 | lower_32_bits(pci_addr)); | 724 | * next one. |
392 | iproc_pcie_ob_write(pcie, IPROC_PCIE_OMAP_HI, i, | 725 | */ |
393 | upper_32_bits(pci_addr)); | 726 | if (iproc_pcie_ob_is_valid(pcie, window_idx)) |
394 | 727 | continue; | |
395 | size -= ob->window_size; | 728 | |
396 | if (size == 0) | 729 | /* |
730 | * Iterate through all supported window sizes within the | ||
731 | * OARR/OMAP pair to find a match. Go through the window sizes | ||
732 | * in a descending order. | ||
733 | */ | ||
734 | for (size_idx = ob_map->nr_sizes - 1; size_idx >= 0; | ||
735 | size_idx--) { | ||
736 | resource_size_t window_size = | ||
737 | ob_map->window_sizes[size_idx] * SZ_1M; | ||
738 | |||
739 | if (size < window_size) | ||
740 | continue; | ||
741 | |||
742 | if (!IS_ALIGNED(axi_addr, window_size) || | ||
743 | !IS_ALIGNED(pci_addr, window_size)) { | ||
744 | dev_err(dev, | ||
745 | "axi %pap or pci %pap not aligned\n", | ||
746 | &axi_addr, &pci_addr); | ||
747 | return -EINVAL; | ||
748 | } | ||
749 | |||
750 | /* | ||
751 | * Match found! Program both OARR and OMAP and mark | ||
752 | * them as a valid entry. | ||
753 | */ | ||
754 | ret = iproc_pcie_ob_write(pcie, window_idx, size_idx, | ||
755 | axi_addr, pci_addr); | ||
756 | if (ret) | ||
757 | goto err_ob; | ||
758 | |||
759 | size -= window_size; | ||
760 | if (size == 0) | ||
761 | return 0; | ||
762 | |||
763 | /* | ||
764 | * If we are here, we are done with the current window, | ||
765 | * but not yet finished all mappings. Need to move on | ||
766 | * to the next window. | ||
767 | */ | ||
768 | axi_addr += window_size; | ||
769 | pci_addr += window_size; | ||
397 | break; | 770 | break; |
398 | 771 | } | |
399 | axi_addr += ob->window_size; | ||
400 | pci_addr += ob->window_size; | ||
401 | } | 772 | } |
402 | 773 | ||
403 | return 0; | 774 | err_ob: |
775 | dev_err(dev, "unable to configure outbound mapping\n"); | ||
776 | dev_err(dev, | ||
777 | "axi %pap, axi offset %pap, pci %pap, res size %pap\n", | ||
778 | &axi_addr, &ob->axi_offset, &pci_addr, &size); | ||
779 | |||
780 | return ret; | ||
404 | } | 781 | } |
405 | 782 | ||
406 | static int iproc_pcie_map_ranges(struct iproc_pcie *pcie, | 783 | static int iproc_pcie_map_ranges(struct iproc_pcie *pcie, |
@@ -434,13 +811,323 @@ static int iproc_pcie_map_ranges(struct iproc_pcie *pcie, | |||
434 | return 0; | 811 | return 0; |
435 | } | 812 | } |
436 | 813 | ||
814 | static inline bool iproc_pcie_ib_is_in_use(struct iproc_pcie *pcie, | ||
815 | int region_idx) | ||
816 | { | ||
817 | const struct iproc_pcie_ib_map *ib_map = &pcie->ib_map[region_idx]; | ||
818 | u32 val; | ||
819 | |||
820 | val = iproc_pcie_read_reg(pcie, MAP_REG(IPROC_PCIE_IARR0, region_idx)); | ||
821 | |||
822 | return !!(val & (BIT(ib_map->nr_sizes) - 1)); | ||
823 | } | ||
824 | |||
825 | static inline bool iproc_pcie_ib_check_type(const struct iproc_pcie_ib_map *ib_map, | ||
826 | enum iproc_pcie_ib_map_type type) | ||
827 | { | ||
828 | return !!(ib_map->type == type); | ||
829 | } | ||
830 | |||
831 | static int iproc_pcie_ib_write(struct iproc_pcie *pcie, int region_idx, | ||
832 | int size_idx, int nr_windows, u64 axi_addr, | ||
833 | u64 pci_addr, resource_size_t size) | ||
834 | { | ||
835 | struct device *dev = pcie->dev; | ||
836 | const struct iproc_pcie_ib_map *ib_map = &pcie->ib_map[region_idx]; | ||
837 | u16 iarr_offset, imap_offset; | ||
838 | u32 val; | ||
839 | int window_idx; | ||
840 | |||
841 | iarr_offset = iproc_pcie_reg_offset(pcie, | ||
842 | MAP_REG(IPROC_PCIE_IARR0, region_idx)); | ||
843 | imap_offset = iproc_pcie_reg_offset(pcie, | ||
844 | MAP_REG(IPROC_PCIE_IMAP0, region_idx)); | ||
845 | if (iproc_pcie_reg_is_invalid(iarr_offset) || | ||
846 | iproc_pcie_reg_is_invalid(imap_offset)) | ||
847 | return -EINVAL; | ||
848 | |||
849 | dev_info(dev, "ib region [%d]: offset 0x%x axi %pap pci %pap\n", | ||
850 | region_idx, iarr_offset, &axi_addr, &pci_addr); | ||
851 | |||
852 | /* | ||
853 | * Program the IARR registers. The upper 32-bit IARR register is | ||
854 | * always right after the lower 32-bit IARR register. | ||
855 | */ | ||
856 | writel(lower_32_bits(pci_addr) | BIT(size_idx), | ||
857 | pcie->base + iarr_offset); | ||
858 | writel(upper_32_bits(pci_addr), pcie->base + iarr_offset + 4); | ||
859 | |||
860 | dev_info(dev, "iarr lo 0x%x iarr hi 0x%x\n", | ||
861 | readl(pcie->base + iarr_offset), | ||
862 | readl(pcie->base + iarr_offset + 4)); | ||
863 | |||
864 | /* | ||
865 | * Now program the IMAP registers. Each IARR region may have one or | ||
866 | * more IMAP windows. | ||
867 | */ | ||
868 | size >>= ilog2(nr_windows); | ||
869 | for (window_idx = 0; window_idx < nr_windows; window_idx++) { | ||
870 | val = readl(pcie->base + imap_offset); | ||
871 | val |= lower_32_bits(axi_addr) | IMAP_VALID; | ||
872 | writel(val, pcie->base + imap_offset); | ||
873 | writel(upper_32_bits(axi_addr), | ||
874 | pcie->base + imap_offset + ib_map->imap_addr_offset); | ||
875 | |||
876 | dev_info(dev, "imap window [%d] lo 0x%x hi 0x%x\n", | ||
877 | window_idx, readl(pcie->base + imap_offset), | ||
878 | readl(pcie->base + imap_offset + | ||
879 | ib_map->imap_addr_offset)); | ||
880 | |||
881 | imap_offset += ib_map->imap_window_offset; | ||
882 | axi_addr += size; | ||
883 | } | ||
884 | |||
885 | return 0; | ||
886 | } | ||
887 | |||
888 | static int iproc_pcie_setup_ib(struct iproc_pcie *pcie, | ||
889 | struct of_pci_range *range, | ||
890 | enum iproc_pcie_ib_map_type type) | ||
891 | { | ||
892 | struct device *dev = pcie->dev; | ||
893 | struct iproc_pcie_ib *ib = &pcie->ib; | ||
894 | int ret; | ||
895 | unsigned int region_idx, size_idx; | ||
896 | u64 axi_addr = range->cpu_addr, pci_addr = range->pci_addr; | ||
897 | resource_size_t size = range->size; | ||
898 | |||
899 | /* iterate through all IARR mapping regions */ | ||
900 | for (region_idx = 0; region_idx < ib->nr_regions; region_idx++) { | ||
901 | const struct iproc_pcie_ib_map *ib_map = | ||
902 | &pcie->ib_map[region_idx]; | ||
903 | |||
904 | /* | ||
905 | * If current inbound region is already in use or not a | ||
906 | * compatible type, move on to the next. | ||
907 | */ | ||
908 | if (iproc_pcie_ib_is_in_use(pcie, region_idx) || | ||
909 | !iproc_pcie_ib_check_type(ib_map, type)) | ||
910 | continue; | ||
911 | |||
912 | /* iterate through all supported region sizes to find a match */ | ||
913 | for (size_idx = 0; size_idx < ib_map->nr_sizes; size_idx++) { | ||
914 | resource_size_t region_size = | ||
915 | ib_map->region_sizes[size_idx] * ib_map->size_unit; | ||
916 | |||
917 | if (size != region_size) | ||
918 | continue; | ||
919 | |||
920 | if (!IS_ALIGNED(axi_addr, region_size) || | ||
921 | !IS_ALIGNED(pci_addr, region_size)) { | ||
922 | dev_err(dev, | ||
923 | "axi %pap or pci %pap not aligned\n", | ||
924 | &axi_addr, &pci_addr); | ||
925 | return -EINVAL; | ||
926 | } | ||
927 | |||
928 | /* Match found! Program IARR and all IMAP windows. */ | ||
929 | ret = iproc_pcie_ib_write(pcie, region_idx, size_idx, | ||
930 | ib_map->nr_windows, axi_addr, | ||
931 | pci_addr, size); | ||
932 | if (ret) | ||
933 | goto err_ib; | ||
934 | else | ||
935 | return 0; | ||
936 | |||
937 | } | ||
938 | } | ||
939 | ret = -EINVAL; | ||
940 | |||
941 | err_ib: | ||
942 | dev_err(dev, "unable to configure inbound mapping\n"); | ||
943 | dev_err(dev, "axi %pap, pci %pap, res size %pap\n", | ||
944 | &axi_addr, &pci_addr, &size); | ||
945 | |||
946 | return ret; | ||
947 | } | ||
948 | |||
949 | static int pci_dma_range_parser_init(struct of_pci_range_parser *parser, | ||
950 | struct device_node *node) | ||
951 | { | ||
952 | const int na = 3, ns = 2; | ||
953 | int rlen; | ||
954 | |||
955 | parser->node = node; | ||
956 | parser->pna = of_n_addr_cells(node); | ||
957 | parser->np = parser->pna + na + ns; | ||
958 | |||
959 | parser->range = of_get_property(node, "dma-ranges", &rlen); | ||
960 | if (!parser->range) | ||
961 | return -ENOENT; | ||
962 | |||
963 | parser->end = parser->range + rlen / sizeof(__be32); | ||
964 | return 0; | ||
965 | } | ||
966 | |||
967 | static int iproc_pcie_map_dma_ranges(struct iproc_pcie *pcie) | ||
968 | { | ||
969 | struct of_pci_range range; | ||
970 | struct of_pci_range_parser parser; | ||
971 | int ret; | ||
972 | |||
973 | /* Get the dma-ranges from DT */ | ||
974 | ret = pci_dma_range_parser_init(&parser, pcie->dev->of_node); | ||
975 | if (ret) | ||
976 | return ret; | ||
977 | |||
978 | for_each_of_pci_range(&parser, &range) { | ||
979 | /* Each range entry corresponds to an inbound mapping region */ | ||
980 | ret = iproc_pcie_setup_ib(pcie, &range, IPROC_PCIE_IB_MAP_MEM); | ||
981 | if (ret) | ||
982 | return ret; | ||
983 | } | ||
984 | |||
985 | return 0; | ||
986 | } | ||
987 | |||
988 | static int iproce_pcie_get_msi(struct iproc_pcie *pcie, | ||
989 | struct device_node *msi_node, | ||
990 | u64 *msi_addr) | ||
991 | { | ||
992 | struct device *dev = pcie->dev; | ||
993 | int ret; | ||
994 | struct resource res; | ||
995 | |||
996 | /* | ||
997 | * Check if 'msi-map' points to ARM GICv3 ITS, which is the only | ||
998 | * supported external MSI controller that requires steering. | ||
999 | */ | ||
1000 | if (!of_device_is_compatible(msi_node, "arm,gic-v3-its")) { | ||
1001 | dev_err(dev, "unable to find compatible MSI controller\n"); | ||
1002 | return -ENODEV; | ||
1003 | } | ||
1004 | |||
1005 | /* derive GITS_TRANSLATER address from GICv3 */ | ||
1006 | ret = of_address_to_resource(msi_node, 0, &res); | ||
1007 | if (ret < 0) { | ||
1008 | dev_err(dev, "unable to obtain MSI controller resources\n"); | ||
1009 | return ret; | ||
1010 | } | ||
1011 | |||
1012 | *msi_addr = res.start + GITS_TRANSLATER; | ||
1013 | return 0; | ||
1014 | } | ||
1015 | |||
1016 | static int iproc_pcie_paxb_v2_msi_steer(struct iproc_pcie *pcie, u64 msi_addr) | ||
1017 | { | ||
1018 | int ret; | ||
1019 | struct of_pci_range range; | ||
1020 | |||
1021 | memset(&range, 0, sizeof(range)); | ||
1022 | range.size = SZ_32K; | ||
1023 | range.pci_addr = range.cpu_addr = msi_addr & ~(range.size - 1); | ||
1024 | |||
1025 | ret = iproc_pcie_setup_ib(pcie, &range, IPROC_PCIE_IB_MAP_IO); | ||
1026 | return ret; | ||
1027 | } | ||
1028 | |||
1029 | static void iproc_pcie_paxc_v2_msi_steer(struct iproc_pcie *pcie, u64 msi_addr) | ||
1030 | { | ||
1031 | u32 val; | ||
1032 | |||
1033 | /* | ||
1034 | * Program bits [43:13] of address of GITS_TRANSLATER register into | ||
1035 | * bits [30:0] of the MSI base address register. In fact, in all iProc | ||
1036 | * based SoCs, all I/O register bases are well below the 32-bit | ||
1037 | * boundary, so we can safely assume bits [43:32] are always zeros. | ||
1038 | */ | ||
1039 | iproc_pcie_write_reg(pcie, IPROC_PCIE_MSI_BASE_ADDR, | ||
1040 | (u32)(msi_addr >> 13)); | ||
1041 | |||
1042 | /* use a default 8K window size */ | ||
1043 | iproc_pcie_write_reg(pcie, IPROC_PCIE_MSI_WINDOW_SIZE, 0); | ||
1044 | |||
1045 | /* steering MSI to GICv3 ITS */ | ||
1046 | val = iproc_pcie_read_reg(pcie, IPROC_PCIE_MSI_GIC_MODE); | ||
1047 | val |= GIC_V3_CFG; | ||
1048 | iproc_pcie_write_reg(pcie, IPROC_PCIE_MSI_GIC_MODE, val); | ||
1049 | |||
1050 | /* | ||
1051 | * Program bits [43:2] of address of GITS_TRANSLATER register into the | ||
1052 | * iProc MSI address registers. | ||
1053 | */ | ||
1054 | msi_addr >>= 2; | ||
1055 | iproc_pcie_write_reg(pcie, IPROC_PCIE_MSI_ADDR_HI, | ||
1056 | upper_32_bits(msi_addr)); | ||
1057 | iproc_pcie_write_reg(pcie, IPROC_PCIE_MSI_ADDR_LO, | ||
1058 | lower_32_bits(msi_addr)); | ||
1059 | |||
1060 | /* enable MSI */ | ||
1061 | val = iproc_pcie_read_reg(pcie, IPROC_PCIE_MSI_EN_CFG); | ||
1062 | val |= MSI_ENABLE_CFG; | ||
1063 | iproc_pcie_write_reg(pcie, IPROC_PCIE_MSI_EN_CFG, val); | ||
1064 | } | ||
1065 | |||
1066 | static int iproc_pcie_msi_steer(struct iproc_pcie *pcie, | ||
1067 | struct device_node *msi_node) | ||
1068 | { | ||
1069 | struct device *dev = pcie->dev; | ||
1070 | int ret; | ||
1071 | u64 msi_addr; | ||
1072 | |||
1073 | ret = iproce_pcie_get_msi(pcie, msi_node, &msi_addr); | ||
1074 | if (ret < 0) { | ||
1075 | dev_err(dev, "msi steering failed\n"); | ||
1076 | return ret; | ||
1077 | } | ||
1078 | |||
1079 | switch (pcie->type) { | ||
1080 | case IPROC_PCIE_PAXB_V2: | ||
1081 | ret = iproc_pcie_paxb_v2_msi_steer(pcie, msi_addr); | ||
1082 | if (ret) | ||
1083 | return ret; | ||
1084 | break; | ||
1085 | case IPROC_PCIE_PAXC_V2: | ||
1086 | iproc_pcie_paxc_v2_msi_steer(pcie, msi_addr); | ||
1087 | break; | ||
1088 | default: | ||
1089 | return -EINVAL; | ||
1090 | } | ||
1091 | |||
1092 | return 0; | ||
1093 | } | ||
1094 | |||
437 | static int iproc_pcie_msi_enable(struct iproc_pcie *pcie) | 1095 | static int iproc_pcie_msi_enable(struct iproc_pcie *pcie) |
438 | { | 1096 | { |
439 | struct device_node *msi_node; | 1097 | struct device_node *msi_node; |
1098 | int ret; | ||
1099 | |||
1100 | /* | ||
1101 | * Either the "msi-parent" or the "msi-map" phandle needs to exist | ||
1102 | * for us to obtain the MSI node. | ||
1103 | */ | ||
440 | 1104 | ||
441 | msi_node = of_parse_phandle(pcie->dev->of_node, "msi-parent", 0); | 1105 | msi_node = of_parse_phandle(pcie->dev->of_node, "msi-parent", 0); |
442 | if (!msi_node) | 1106 | if (!msi_node) { |
443 | return -ENODEV; | 1107 | const __be32 *msi_map = NULL; |
1108 | int len; | ||
1109 | u32 phandle; | ||
1110 | |||
1111 | msi_map = of_get_property(pcie->dev->of_node, "msi-map", &len); | ||
1112 | if (!msi_map) | ||
1113 | return -ENODEV; | ||
1114 | |||
1115 | phandle = be32_to_cpup(msi_map + 1); | ||
1116 | msi_node = of_find_node_by_phandle(phandle); | ||
1117 | if (!msi_node) | ||
1118 | return -ENODEV; | ||
1119 | } | ||
1120 | |||
1121 | /* | ||
1122 | * Certain revisions of the iProc PCIe controller require additional | ||
1123 | * configurations to steer the MSI writes towards an external MSI | ||
1124 | * controller. | ||
1125 | */ | ||
1126 | if (pcie->need_msi_steer) { | ||
1127 | ret = iproc_pcie_msi_steer(pcie, msi_node); | ||
1128 | if (ret) | ||
1129 | return ret; | ||
1130 | } | ||
444 | 1131 | ||
445 | /* | 1132 | /* |
446 | * If another MSI controller is being used, the call below should fail | 1133 | * If another MSI controller is being used, the call below should fail |
@@ -454,6 +1141,65 @@ static void iproc_pcie_msi_disable(struct iproc_pcie *pcie) | |||
454 | iproc_msi_exit(pcie); | 1141 | iproc_msi_exit(pcie); |
455 | } | 1142 | } |
456 | 1143 | ||
1144 | static int iproc_pcie_rev_init(struct iproc_pcie *pcie) | ||
1145 | { | ||
1146 | struct device *dev = pcie->dev; | ||
1147 | unsigned int reg_idx; | ||
1148 | const u16 *regs; | ||
1149 | |||
1150 | switch (pcie->type) { | ||
1151 | case IPROC_PCIE_PAXB_BCMA: | ||
1152 | regs = iproc_pcie_reg_paxb_bcma; | ||
1153 | break; | ||
1154 | case IPROC_PCIE_PAXB: | ||
1155 | regs = iproc_pcie_reg_paxb; | ||
1156 | pcie->has_apb_err_disable = true; | ||
1157 | if (pcie->need_ob_cfg) { | ||
1158 | pcie->ob_map = paxb_ob_map; | ||
1159 | pcie->ob.nr_windows = ARRAY_SIZE(paxb_ob_map); | ||
1160 | } | ||
1161 | break; | ||
1162 | case IPROC_PCIE_PAXB_V2: | ||
1163 | regs = iproc_pcie_reg_paxb_v2; | ||
1164 | pcie->has_apb_err_disable = true; | ||
1165 | if (pcie->need_ob_cfg) { | ||
1166 | pcie->ob_map = paxb_v2_ob_map; | ||
1167 | pcie->ob.nr_windows = ARRAY_SIZE(paxb_v2_ob_map); | ||
1168 | } | ||
1169 | pcie->ib.nr_regions = ARRAY_SIZE(paxb_v2_ib_map); | ||
1170 | pcie->ib_map = paxb_v2_ib_map; | ||
1171 | pcie->need_msi_steer = true; | ||
1172 | break; | ||
1173 | case IPROC_PCIE_PAXC: | ||
1174 | regs = iproc_pcie_reg_paxc; | ||
1175 | pcie->ep_is_internal = true; | ||
1176 | break; | ||
1177 | case IPROC_PCIE_PAXC_V2: | ||
1178 | regs = iproc_pcie_reg_paxc_v2; | ||
1179 | pcie->ep_is_internal = true; | ||
1180 | pcie->need_msi_steer = true; | ||
1181 | break; | ||
1182 | default: | ||
1183 | dev_err(dev, "incompatible iProc PCIe interface\n"); | ||
1184 | return -EINVAL; | ||
1185 | } | ||
1186 | |||
1187 | pcie->reg_offsets = devm_kcalloc(dev, IPROC_PCIE_MAX_NUM_REG, | ||
1188 | sizeof(*pcie->reg_offsets), | ||
1189 | GFP_KERNEL); | ||
1190 | if (!pcie->reg_offsets) | ||
1191 | return -ENOMEM; | ||
1192 | |||
1193 | /* go through the register table and populate all valid registers */ | ||
1194 | pcie->reg_offsets[0] = (pcie->type == IPROC_PCIE_PAXC_V2) ? | ||
1195 | IPROC_PCIE_REG_INVALID : regs[0]; | ||
1196 | for (reg_idx = 1; reg_idx < IPROC_PCIE_MAX_NUM_REG; reg_idx++) | ||
1197 | pcie->reg_offsets[reg_idx] = regs[reg_idx] ? | ||
1198 | regs[reg_idx] : IPROC_PCIE_REG_INVALID; | ||
1199 | |||
1200 | return 0; | ||
1201 | } | ||
1202 | |||
457 | int iproc_pcie_setup(struct iproc_pcie *pcie, struct list_head *res) | 1203 | int iproc_pcie_setup(struct iproc_pcie *pcie, struct list_head *res) |
458 | { | 1204 | { |
459 | struct device *dev; | 1205 | struct device *dev; |
@@ -462,6 +1208,13 @@ int iproc_pcie_setup(struct iproc_pcie *pcie, struct list_head *res) | |||
462 | struct pci_bus *bus; | 1208 | struct pci_bus *bus; |
463 | 1209 | ||
464 | dev = pcie->dev; | 1210 | dev = pcie->dev; |
1211 | |||
1212 | ret = iproc_pcie_rev_init(pcie); | ||
1213 | if (ret) { | ||
1214 | dev_err(dev, "unable to initialize controller parameters\n"); | ||
1215 | return ret; | ||
1216 | } | ||
1217 | |||
465 | ret = devm_request_pci_bus_resources(dev, res); | 1218 | ret = devm_request_pci_bus_resources(dev, res); |
466 | if (ret) | 1219 | if (ret) |
467 | return ret; | 1220 | return ret; |
@@ -478,19 +1231,6 @@ int iproc_pcie_setup(struct iproc_pcie *pcie, struct list_head *res) | |||
478 | goto err_exit_phy; | 1231 | goto err_exit_phy; |
479 | } | 1232 | } |
480 | 1233 | ||
481 | switch (pcie->type) { | ||
482 | case IPROC_PCIE_PAXB: | ||
483 | pcie->reg_offsets = iproc_pcie_reg_paxb; | ||
484 | break; | ||
485 | case IPROC_PCIE_PAXC: | ||
486 | pcie->reg_offsets = iproc_pcie_reg_paxc; | ||
487 | break; | ||
488 | default: | ||
489 | dev_err(dev, "incompatible iProc PCIe interface\n"); | ||
490 | ret = -EINVAL; | ||
491 | goto err_power_off_phy; | ||
492 | } | ||
493 | |||
494 | iproc_pcie_reset(pcie); | 1234 | iproc_pcie_reset(pcie); |
495 | 1235 | ||
496 | if (pcie->need_ob_cfg) { | 1236 | if (pcie->need_ob_cfg) { |
@@ -501,6 +1241,10 @@ int iproc_pcie_setup(struct iproc_pcie *pcie, struct list_head *res) | |||
501 | } | 1241 | } |
502 | } | 1242 | } |
503 | 1243 | ||
1244 | ret = iproc_pcie_map_dma_ranges(pcie); | ||
1245 | if (ret && ret != -ENOENT) | ||
1246 | goto err_power_off_phy; | ||
1247 | |||
504 | #ifdef CONFIG_ARM | 1248 | #ifdef CONFIG_ARM |
505 | pcie->sysdata.private_data = pcie; | 1249 | pcie->sysdata.private_data = pcie; |
506 | sysdata = &pcie->sysdata; | 1250 | sysdata = &pcie->sysdata; |
@@ -530,7 +1274,10 @@ int iproc_pcie_setup(struct iproc_pcie *pcie, struct list_head *res) | |||
530 | 1274 | ||
531 | pci_scan_child_bus(bus); | 1275 | pci_scan_child_bus(bus); |
532 | pci_assign_unassigned_bus_resources(bus); | 1276 | pci_assign_unassigned_bus_resources(bus); |
533 | pci_fixup_irqs(pci_common_swizzle, pcie->map_irq); | 1277 | |
1278 | if (pcie->map_irq) | ||
1279 | pci_fixup_irqs(pci_common_swizzle, pcie->map_irq); | ||
1280 | |||
534 | pci_bus_add_devices(bus); | 1281 | pci_bus_add_devices(bus); |
535 | 1282 | ||
536 | return 0; | 1283 | return 0; |
diff --git a/drivers/pci/host/pcie-iproc.h b/drivers/pci/host/pcie-iproc.h index e84d93c53c7b..04fed8e907f1 100644 --- a/drivers/pci/host/pcie-iproc.h +++ b/drivers/pci/host/pcie-iproc.h | |||
@@ -24,23 +24,34 @@ | |||
24 | * endpoint devices. | 24 | * endpoint devices. |
25 | */ | 25 | */ |
26 | enum iproc_pcie_type { | 26 | enum iproc_pcie_type { |
27 | IPROC_PCIE_PAXB = 0, | 27 | IPROC_PCIE_PAXB_BCMA = 0, |
28 | IPROC_PCIE_PAXB, | ||
29 | IPROC_PCIE_PAXB_V2, | ||
28 | IPROC_PCIE_PAXC, | 30 | IPROC_PCIE_PAXC, |
31 | IPROC_PCIE_PAXC_V2, | ||
29 | }; | 32 | }; |
30 | 33 | ||
31 | /** | 34 | /** |
32 | * iProc PCIe outbound mapping | 35 | * iProc PCIe outbound mapping |
33 | * @set_oarr_size: indicates the OARR size bit needs to be set | ||
34 | * @axi_offset: offset from the AXI address to the internal address used by | 36 | * @axi_offset: offset from the AXI address to the internal address used by |
35 | * the iProc PCIe core | 37 | * the iProc PCIe core |
36 | * @window_size: outbound window size | 38 | * @nr_windows: total number of supported outbound mapping windows |
37 | */ | 39 | */ |
38 | struct iproc_pcie_ob { | 40 | struct iproc_pcie_ob { |
39 | bool set_oarr_size; | ||
40 | resource_size_t axi_offset; | 41 | resource_size_t axi_offset; |
41 | resource_size_t window_size; | 42 | unsigned int nr_windows; |
42 | }; | 43 | }; |
43 | 44 | ||
45 | /** | ||
46 | * iProc PCIe inbound mapping | ||
47 | * @nr_regions: total number of supported inbound mapping regions | ||
48 | */ | ||
49 | struct iproc_pcie_ib { | ||
50 | unsigned int nr_regions; | ||
51 | }; | ||
52 | |||
53 | struct iproc_pcie_ob_map; | ||
54 | struct iproc_pcie_ib_map; | ||
44 | struct iproc_msi; | 55 | struct iproc_msi; |
45 | 56 | ||
46 | /** | 57 | /** |
@@ -55,14 +66,25 @@ struct iproc_msi; | |||
55 | * @root_bus: pointer to root bus | 66 | * @root_bus: pointer to root bus |
56 | * @phy: optional PHY device that controls the Serdes | 67 | * @phy: optional PHY device that controls the Serdes |
57 | * @map_irq: function callback to map interrupts | 68 | * @map_irq: function callback to map interrupts |
69 | * @ep_is_internal: indicates an internal emulated endpoint device is connected | ||
70 | * @has_apb_err_disable: indicates the controller can be configured to prevent | ||
71 | * unsupported request from being forwarded as an APB bus error | ||
72 | * | ||
58 | * @need_ob_cfg: indicates SW needs to configure the outbound mapping window | 73 | * @need_ob_cfg: indicates SW needs to configure the outbound mapping window |
59 | * @ob: outbound mapping parameters | 74 | * @ob: outbound mapping related parameters |
75 | * @ob_map: outbound mapping related parameters specific to the controller | ||
76 | * | ||
77 | * @ib: inbound mapping related parameters | ||
78 | * @ib_map: outbound mapping region related parameters | ||
79 | * | ||
80 | * @need_msi_steer: indicates additional configuration of the iProc PCIe | ||
81 | * controller is required to steer MSI writes to external interrupt controller | ||
60 | * @msi: MSI data | 82 | * @msi: MSI data |
61 | */ | 83 | */ |
62 | struct iproc_pcie { | 84 | struct iproc_pcie { |
63 | struct device *dev; | 85 | struct device *dev; |
64 | enum iproc_pcie_type type; | 86 | enum iproc_pcie_type type; |
65 | const u16 *reg_offsets; | 87 | u16 *reg_offsets; |
66 | void __iomem *base; | 88 | void __iomem *base; |
67 | phys_addr_t base_addr; | 89 | phys_addr_t base_addr; |
68 | #ifdef CONFIG_ARM | 90 | #ifdef CONFIG_ARM |
@@ -71,8 +93,17 @@ struct iproc_pcie { | |||
71 | struct pci_bus *root_bus; | 93 | struct pci_bus *root_bus; |
72 | struct phy *phy; | 94 | struct phy *phy; |
73 | int (*map_irq)(const struct pci_dev *, u8, u8); | 95 | int (*map_irq)(const struct pci_dev *, u8, u8); |
96 | bool ep_is_internal; | ||
97 | bool has_apb_err_disable; | ||
98 | |||
74 | bool need_ob_cfg; | 99 | bool need_ob_cfg; |
75 | struct iproc_pcie_ob ob; | 100 | struct iproc_pcie_ob ob; |
101 | const struct iproc_pcie_ob_map *ob_map; | ||
102 | |||
103 | struct iproc_pcie_ib ib; | ||
104 | const struct iproc_pcie_ib_map *ib_map; | ||
105 | |||
106 | bool need_msi_steer; | ||
76 | struct iproc_msi *msi; | 107 | struct iproc_msi *msi; |
77 | }; | 108 | }; |
78 | 109 | ||
diff --git a/drivers/pci/host/pcie-qcom.c b/drivers/pci/host/pcie-qcom.c index ef0a84c7a588..734ba0d4a5c8 100644 --- a/drivers/pci/host/pcie-qcom.c +++ b/drivers/pci/host/pcie-qcom.c | |||
@@ -36,11 +36,17 @@ | |||
36 | 36 | ||
37 | #include "pcie-designware.h" | 37 | #include "pcie-designware.h" |
38 | 38 | ||
39 | #define PCIE20_PARF_SYS_CTRL 0x00 | ||
39 | #define PCIE20_PARF_PHY_CTRL 0x40 | 40 | #define PCIE20_PARF_PHY_CTRL 0x40 |
40 | #define PCIE20_PARF_PHY_REFCLK 0x4C | 41 | #define PCIE20_PARF_PHY_REFCLK 0x4C |
41 | #define PCIE20_PARF_DBI_BASE_ADDR 0x168 | 42 | #define PCIE20_PARF_DBI_BASE_ADDR 0x168 |
42 | #define PCIE20_PARF_SLV_ADDR_SPACE_SIZE 0x16c | 43 | #define PCIE20_PARF_SLV_ADDR_SPACE_SIZE 0x16C |
44 | #define PCIE20_PARF_MHI_CLOCK_RESET_CTRL 0x174 | ||
43 | #define PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT 0x178 | 45 | #define PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT 0x178 |
46 | #define PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT_V2 0x1A8 | ||
47 | #define PCIE20_PARF_LTSSM 0x1B0 | ||
48 | #define PCIE20_PARF_SID_OFFSET 0x234 | ||
49 | #define PCIE20_PARF_BDF_TRANSLATE_CFG 0x24C | ||
44 | 50 | ||
45 | #define PCIE20_ELBI_SYS_CTRL 0x04 | 51 | #define PCIE20_ELBI_SYS_CTRL 0x04 |
46 | #define PCIE20_ELBI_SYS_CTRL_LT_ENABLE BIT(0) | 52 | #define PCIE20_ELBI_SYS_CTRL_LT_ENABLE BIT(0) |
@@ -72,9 +78,18 @@ struct qcom_pcie_resources_v1 { | |||
72 | struct regulator *vdda; | 78 | struct regulator *vdda; |
73 | }; | 79 | }; |
74 | 80 | ||
81 | struct qcom_pcie_resources_v2 { | ||
82 | struct clk *aux_clk; | ||
83 | struct clk *master_clk; | ||
84 | struct clk *slave_clk; | ||
85 | struct clk *cfg_clk; | ||
86 | struct clk *pipe_clk; | ||
87 | }; | ||
88 | |||
75 | union qcom_pcie_resources { | 89 | union qcom_pcie_resources { |
76 | struct qcom_pcie_resources_v0 v0; | 90 | struct qcom_pcie_resources_v0 v0; |
77 | struct qcom_pcie_resources_v1 v1; | 91 | struct qcom_pcie_resources_v1 v1; |
92 | struct qcom_pcie_resources_v2 v2; | ||
78 | }; | 93 | }; |
79 | 94 | ||
80 | struct qcom_pcie; | 95 | struct qcom_pcie; |
@@ -82,7 +97,9 @@ struct qcom_pcie; | |||
82 | struct qcom_pcie_ops { | 97 | struct qcom_pcie_ops { |
83 | int (*get_resources)(struct qcom_pcie *pcie); | 98 | int (*get_resources)(struct qcom_pcie *pcie); |
84 | int (*init)(struct qcom_pcie *pcie); | 99 | int (*init)(struct qcom_pcie *pcie); |
100 | int (*post_init)(struct qcom_pcie *pcie); | ||
85 | void (*deinit)(struct qcom_pcie *pcie); | 101 | void (*deinit)(struct qcom_pcie *pcie); |
102 | void (*ltssm_enable)(struct qcom_pcie *pcie); | ||
86 | }; | 103 | }; |
87 | 104 | ||
88 | struct qcom_pcie { | 105 | struct qcom_pcie { |
@@ -116,17 +133,35 @@ static irqreturn_t qcom_pcie_msi_irq_handler(int irq, void *arg) | |||
116 | return dw_handle_msi_irq(pp); | 133 | return dw_handle_msi_irq(pp); |
117 | } | 134 | } |
118 | 135 | ||
119 | static int qcom_pcie_establish_link(struct qcom_pcie *pcie) | 136 | static void qcom_pcie_v0_v1_ltssm_enable(struct qcom_pcie *pcie) |
120 | { | 137 | { |
121 | u32 val; | 138 | u32 val; |
122 | 139 | ||
123 | if (dw_pcie_link_up(&pcie->pp)) | ||
124 | return 0; | ||
125 | |||
126 | /* enable link training */ | 140 | /* enable link training */ |
127 | val = readl(pcie->elbi + PCIE20_ELBI_SYS_CTRL); | 141 | val = readl(pcie->elbi + PCIE20_ELBI_SYS_CTRL); |
128 | val |= PCIE20_ELBI_SYS_CTRL_LT_ENABLE; | 142 | val |= PCIE20_ELBI_SYS_CTRL_LT_ENABLE; |
129 | writel(val, pcie->elbi + PCIE20_ELBI_SYS_CTRL); | 143 | writel(val, pcie->elbi + PCIE20_ELBI_SYS_CTRL); |
144 | } | ||
145 | |||
146 | static void qcom_pcie_v2_ltssm_enable(struct qcom_pcie *pcie) | ||
147 | { | ||
148 | u32 val; | ||
149 | |||
150 | /* enable link training */ | ||
151 | val = readl(pcie->parf + PCIE20_PARF_LTSSM); | ||
152 | val |= BIT(8); | ||
153 | writel(val, pcie->parf + PCIE20_PARF_LTSSM); | ||
154 | } | ||
155 | |||
156 | static int qcom_pcie_establish_link(struct qcom_pcie *pcie) | ||
157 | { | ||
158 | |||
159 | if (dw_pcie_link_up(&pcie->pp)) | ||
160 | return 0; | ||
161 | |||
162 | /* Enable Link Training state machine */ | ||
163 | if (pcie->ops->ltssm_enable) | ||
164 | pcie->ops->ltssm_enable(pcie); | ||
130 | 165 | ||
131 | return dw_pcie_wait_for_link(&pcie->pp); | 166 | return dw_pcie_wait_for_link(&pcie->pp); |
132 | } | 167 | } |
@@ -421,6 +456,113 @@ err_res: | |||
421 | return ret; | 456 | return ret; |
422 | } | 457 | } |
423 | 458 | ||
459 | static int qcom_pcie_get_resources_v2(struct qcom_pcie *pcie) | ||
460 | { | ||
461 | struct qcom_pcie_resources_v2 *res = &pcie->res.v2; | ||
462 | struct device *dev = pcie->pp.dev; | ||
463 | |||
464 | res->aux_clk = devm_clk_get(dev, "aux"); | ||
465 | if (IS_ERR(res->aux_clk)) | ||
466 | return PTR_ERR(res->aux_clk); | ||
467 | |||
468 | res->cfg_clk = devm_clk_get(dev, "cfg"); | ||
469 | if (IS_ERR(res->cfg_clk)) | ||
470 | return PTR_ERR(res->cfg_clk); | ||
471 | |||
472 | res->master_clk = devm_clk_get(dev, "bus_master"); | ||
473 | if (IS_ERR(res->master_clk)) | ||
474 | return PTR_ERR(res->master_clk); | ||
475 | |||
476 | res->slave_clk = devm_clk_get(dev, "bus_slave"); | ||
477 | if (IS_ERR(res->slave_clk)) | ||
478 | return PTR_ERR(res->slave_clk); | ||
479 | |||
480 | res->pipe_clk = devm_clk_get(dev, "pipe"); | ||
481 | if (IS_ERR(res->pipe_clk)) | ||
482 | return PTR_ERR(res->pipe_clk); | ||
483 | |||
484 | return 0; | ||
485 | } | ||
486 | |||
487 | static int qcom_pcie_init_v2(struct qcom_pcie *pcie) | ||
488 | { | ||
489 | struct qcom_pcie_resources_v2 *res = &pcie->res.v2; | ||
490 | struct device *dev = pcie->pp.dev; | ||
491 | u32 val; | ||
492 | int ret; | ||
493 | |||
494 | ret = clk_prepare_enable(res->aux_clk); | ||
495 | if (ret) { | ||
496 | dev_err(dev, "cannot prepare/enable aux clock\n"); | ||
497 | return ret; | ||
498 | } | ||
499 | |||
500 | ret = clk_prepare_enable(res->cfg_clk); | ||
501 | if (ret) { | ||
502 | dev_err(dev, "cannot prepare/enable cfg clock\n"); | ||
503 | goto err_cfg_clk; | ||
504 | } | ||
505 | |||
506 | ret = clk_prepare_enable(res->master_clk); | ||
507 | if (ret) { | ||
508 | dev_err(dev, "cannot prepare/enable master clock\n"); | ||
509 | goto err_master_clk; | ||
510 | } | ||
511 | |||
512 | ret = clk_prepare_enable(res->slave_clk); | ||
513 | if (ret) { | ||
514 | dev_err(dev, "cannot prepare/enable slave clock\n"); | ||
515 | goto err_slave_clk; | ||
516 | } | ||
517 | |||
518 | /* enable PCIe clocks and resets */ | ||
519 | val = readl(pcie->parf + PCIE20_PARF_PHY_CTRL); | ||
520 | val &= ~BIT(0); | ||
521 | writel(val, pcie->parf + PCIE20_PARF_PHY_CTRL); | ||
522 | |||
523 | /* change DBI base address */ | ||
524 | writel(0, pcie->parf + PCIE20_PARF_DBI_BASE_ADDR); | ||
525 | |||
526 | /* MAC PHY_POWERDOWN MUX DISABLE */ | ||
527 | val = readl(pcie->parf + PCIE20_PARF_SYS_CTRL); | ||
528 | val &= ~BIT(29); | ||
529 | writel(val, pcie->parf + PCIE20_PARF_SYS_CTRL); | ||
530 | |||
531 | val = readl(pcie->parf + PCIE20_PARF_MHI_CLOCK_RESET_CTRL); | ||
532 | val |= BIT(4); | ||
533 | writel(val, pcie->parf + PCIE20_PARF_MHI_CLOCK_RESET_CTRL); | ||
534 | |||
535 | val = readl(pcie->parf + PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT_V2); | ||
536 | val |= BIT(31); | ||
537 | writel(val, pcie->parf + PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT_V2); | ||
538 | |||
539 | return 0; | ||
540 | |||
541 | err_slave_clk: | ||
542 | clk_disable_unprepare(res->master_clk); | ||
543 | err_master_clk: | ||
544 | clk_disable_unprepare(res->cfg_clk); | ||
545 | err_cfg_clk: | ||
546 | clk_disable_unprepare(res->aux_clk); | ||
547 | |||
548 | return ret; | ||
549 | } | ||
550 | |||
551 | static int qcom_pcie_post_init_v2(struct qcom_pcie *pcie) | ||
552 | { | ||
553 | struct qcom_pcie_resources_v2 *res = &pcie->res.v2; | ||
554 | struct device *dev = pcie->pp.dev; | ||
555 | int ret; | ||
556 | |||
557 | ret = clk_prepare_enable(res->pipe_clk); | ||
558 | if (ret) { | ||
559 | dev_err(dev, "cannot prepare/enable pipe clock\n"); | ||
560 | return ret; | ||
561 | } | ||
562 | |||
563 | return 0; | ||
564 | } | ||
565 | |||
424 | static int qcom_pcie_link_up(struct pcie_port *pp) | 566 | static int qcom_pcie_link_up(struct pcie_port *pp) |
425 | { | 567 | { |
426 | struct qcom_pcie *pcie = to_qcom_pcie(pp); | 568 | struct qcom_pcie *pcie = to_qcom_pcie(pp); |
@@ -429,6 +571,17 @@ static int qcom_pcie_link_up(struct pcie_port *pp) | |||
429 | return !!(val & PCI_EXP_LNKSTA_DLLLA); | 571 | return !!(val & PCI_EXP_LNKSTA_DLLLA); |
430 | } | 572 | } |
431 | 573 | ||
574 | static void qcom_pcie_deinit_v2(struct qcom_pcie *pcie) | ||
575 | { | ||
576 | struct qcom_pcie_resources_v2 *res = &pcie->res.v2; | ||
577 | |||
578 | clk_disable_unprepare(res->pipe_clk); | ||
579 | clk_disable_unprepare(res->slave_clk); | ||
580 | clk_disable_unprepare(res->master_clk); | ||
581 | clk_disable_unprepare(res->cfg_clk); | ||
582 | clk_disable_unprepare(res->aux_clk); | ||
583 | } | ||
584 | |||
432 | static void qcom_pcie_host_init(struct pcie_port *pp) | 585 | static void qcom_pcie_host_init(struct pcie_port *pp) |
433 | { | 586 | { |
434 | struct qcom_pcie *pcie = to_qcom_pcie(pp); | 587 | struct qcom_pcie *pcie = to_qcom_pcie(pp); |
@@ -444,6 +597,9 @@ static void qcom_pcie_host_init(struct pcie_port *pp) | |||
444 | if (ret) | 597 | if (ret) |
445 | goto err_deinit; | 598 | goto err_deinit; |
446 | 599 | ||
600 | if (pcie->ops->post_init) | ||
601 | pcie->ops->post_init(pcie); | ||
602 | |||
447 | dw_pcie_setup_rc(pp); | 603 | dw_pcie_setup_rc(pp); |
448 | 604 | ||
449 | if (IS_ENABLED(CONFIG_PCI_MSI)) | 605 | if (IS_ENABLED(CONFIG_PCI_MSI)) |
@@ -487,12 +643,22 @@ static const struct qcom_pcie_ops ops_v0 = { | |||
487 | .get_resources = qcom_pcie_get_resources_v0, | 643 | .get_resources = qcom_pcie_get_resources_v0, |
488 | .init = qcom_pcie_init_v0, | 644 | .init = qcom_pcie_init_v0, |
489 | .deinit = qcom_pcie_deinit_v0, | 645 | .deinit = qcom_pcie_deinit_v0, |
646 | .ltssm_enable = qcom_pcie_v0_v1_ltssm_enable, | ||
490 | }; | 647 | }; |
491 | 648 | ||
492 | static const struct qcom_pcie_ops ops_v1 = { | 649 | static const struct qcom_pcie_ops ops_v1 = { |
493 | .get_resources = qcom_pcie_get_resources_v1, | 650 | .get_resources = qcom_pcie_get_resources_v1, |
494 | .init = qcom_pcie_init_v1, | 651 | .init = qcom_pcie_init_v1, |
495 | .deinit = qcom_pcie_deinit_v1, | 652 | .deinit = qcom_pcie_deinit_v1, |
653 | .ltssm_enable = qcom_pcie_v0_v1_ltssm_enable, | ||
654 | }; | ||
655 | |||
656 | static const struct qcom_pcie_ops ops_v2 = { | ||
657 | .get_resources = qcom_pcie_get_resources_v2, | ||
658 | .init = qcom_pcie_init_v2, | ||
659 | .post_init = qcom_pcie_post_init_v2, | ||
660 | .deinit = qcom_pcie_deinit_v2, | ||
661 | .ltssm_enable = qcom_pcie_v2_ltssm_enable, | ||
496 | }; | 662 | }; |
497 | 663 | ||
498 | static int qcom_pcie_probe(struct platform_device *pdev) | 664 | static int qcom_pcie_probe(struct platform_device *pdev) |
@@ -533,11 +699,11 @@ static int qcom_pcie_probe(struct platform_device *pdev) | |||
533 | if (IS_ERR(pcie->phy)) | 699 | if (IS_ERR(pcie->phy)) |
534 | return PTR_ERR(pcie->phy); | 700 | return PTR_ERR(pcie->phy); |
535 | 701 | ||
702 | pp->dev = dev; | ||
536 | ret = pcie->ops->get_resources(pcie); | 703 | ret = pcie->ops->get_resources(pcie); |
537 | if (ret) | 704 | if (ret) |
538 | return ret; | 705 | return ret; |
539 | 706 | ||
540 | pp->dev = dev; | ||
541 | pp->root_bus_nr = -1; | 707 | pp->root_bus_nr = -1; |
542 | pp->ops = &qcom_pcie_dw_ops; | 708 | pp->ops = &qcom_pcie_dw_ops; |
543 | 709 | ||
@@ -572,6 +738,7 @@ static const struct of_device_id qcom_pcie_match[] = { | |||
572 | { .compatible = "qcom,pcie-ipq8064", .data = &ops_v0 }, | 738 | { .compatible = "qcom,pcie-ipq8064", .data = &ops_v0 }, |
573 | { .compatible = "qcom,pcie-apq8064", .data = &ops_v0 }, | 739 | { .compatible = "qcom,pcie-apq8064", .data = &ops_v0 }, |
574 | { .compatible = "qcom,pcie-apq8084", .data = &ops_v1 }, | 740 | { .compatible = "qcom,pcie-apq8084", .data = &ops_v1 }, |
741 | { .compatible = "qcom,pcie-msm8996", .data = &ops_v2 }, | ||
575 | { } | 742 | { } |
576 | }; | 743 | }; |
577 | 744 | ||
diff --git a/drivers/pci/host/pcie-rcar.c b/drivers/pci/host/pcie-rcar.c index 62700d1896f4..aca85be101f8 100644 --- a/drivers/pci/host/pcie-rcar.c +++ b/drivers/pci/host/pcie-rcar.c | |||
@@ -1071,13 +1071,14 @@ static int rcar_pcie_parse_map_dma_ranges(struct rcar_pcie *pcie, | |||
1071 | 1071 | ||
1072 | static const struct of_device_id rcar_pcie_of_match[] = { | 1072 | static const struct of_device_id rcar_pcie_of_match[] = { |
1073 | { .compatible = "renesas,pcie-r8a7779", .data = rcar_pcie_hw_init_h1 }, | 1073 | { .compatible = "renesas,pcie-r8a7779", .data = rcar_pcie_hw_init_h1 }, |
1074 | { .compatible = "renesas,pcie-rcar-gen2", | ||
1075 | .data = rcar_pcie_hw_init_gen2 }, | ||
1076 | { .compatible = "renesas,pcie-r8a7790", | 1074 | { .compatible = "renesas,pcie-r8a7790", |
1077 | .data = rcar_pcie_hw_init_gen2 }, | 1075 | .data = rcar_pcie_hw_init_gen2 }, |
1078 | { .compatible = "renesas,pcie-r8a7791", | 1076 | { .compatible = "renesas,pcie-r8a7791", |
1079 | .data = rcar_pcie_hw_init_gen2 }, | 1077 | .data = rcar_pcie_hw_init_gen2 }, |
1078 | { .compatible = "renesas,pcie-rcar-gen2", | ||
1079 | .data = rcar_pcie_hw_init_gen2 }, | ||
1080 | { .compatible = "renesas,pcie-r8a7795", .data = rcar_pcie_hw_init }, | 1080 | { .compatible = "renesas,pcie-r8a7795", .data = rcar_pcie_hw_init }, |
1081 | { .compatible = "renesas,pcie-rcar-gen3", .data = rcar_pcie_hw_init }, | ||
1081 | {}, | 1082 | {}, |
1082 | }; | 1083 | }; |
1083 | 1084 | ||
diff --git a/drivers/pci/host/pcie-rockchip.c b/drivers/pci/host/pcie-rockchip.c index e0b22dab9b7a..f2dca7bb0b39 100644 --- a/drivers/pci/host/pcie-rockchip.c +++ b/drivers/pci/host/pcie-rockchip.c | |||
@@ -53,6 +53,7 @@ | |||
53 | #define PCIE_CLIENT_ARI_ENABLE HIWORD_UPDATE_BIT(0x0008) | 53 | #define PCIE_CLIENT_ARI_ENABLE HIWORD_UPDATE_BIT(0x0008) |
54 | #define PCIE_CLIENT_CONF_LANE_NUM(x) HIWORD_UPDATE(0x0030, ENCODE_LANES(x)) | 54 | #define PCIE_CLIENT_CONF_LANE_NUM(x) HIWORD_UPDATE(0x0030, ENCODE_LANES(x)) |
55 | #define PCIE_CLIENT_MODE_RC HIWORD_UPDATE_BIT(0x0040) | 55 | #define PCIE_CLIENT_MODE_RC HIWORD_UPDATE_BIT(0x0040) |
56 | #define PCIE_CLIENT_GEN_SEL_1 HIWORD_UPDATE(0x0080, 0) | ||
56 | #define PCIE_CLIENT_GEN_SEL_2 HIWORD_UPDATE_BIT(0x0080) | 57 | #define PCIE_CLIENT_GEN_SEL_2 HIWORD_UPDATE_BIT(0x0080) |
57 | #define PCIE_CLIENT_BASIC_STATUS1 (PCIE_CLIENT_BASE + 0x48) | 58 | #define PCIE_CLIENT_BASIC_STATUS1 (PCIE_CLIENT_BASE + 0x48) |
58 | #define PCIE_CLIENT_LINK_STATUS_UP 0x00300000 | 59 | #define PCIE_CLIENT_LINK_STATUS_UP 0x00300000 |
@@ -135,13 +136,14 @@ | |||
135 | #define PCIE_RC_CONFIG_VENDOR (PCIE_RC_CONFIG_BASE + 0x00) | 136 | #define PCIE_RC_CONFIG_VENDOR (PCIE_RC_CONFIG_BASE + 0x00) |
136 | #define PCIE_RC_CONFIG_RID_CCR (PCIE_RC_CONFIG_BASE + 0x08) | 137 | #define PCIE_RC_CONFIG_RID_CCR (PCIE_RC_CONFIG_BASE + 0x08) |
137 | #define PCIE_RC_CONFIG_SCC_SHIFT 16 | 138 | #define PCIE_RC_CONFIG_SCC_SHIFT 16 |
139 | #define PCIE_RC_CONFIG_DCR (PCIE_RC_CONFIG_BASE + 0xc4) | ||
140 | #define PCIE_RC_CONFIG_DCR_CSPL_SHIFT 18 | ||
141 | #define PCIE_RC_CONFIG_DCR_CSPL_LIMIT 0xff | ||
142 | #define PCIE_RC_CONFIG_DCR_CPLS_SHIFT 26 | ||
138 | #define PCIE_RC_CONFIG_LCS (PCIE_RC_CONFIG_BASE + 0xd0) | 143 | #define PCIE_RC_CONFIG_LCS (PCIE_RC_CONFIG_BASE + 0xd0) |
139 | #define PCIE_RC_CONFIG_LCS_RETRAIN_LINK BIT(5) | ||
140 | #define PCIE_RC_CONFIG_LCS_LBMIE BIT(10) | ||
141 | #define PCIE_RC_CONFIG_LCS_LABIE BIT(11) | ||
142 | #define PCIE_RC_CONFIG_LCS_LBMS BIT(30) | ||
143 | #define PCIE_RC_CONFIG_LCS_LAMS BIT(31) | ||
144 | #define PCIE_RC_CONFIG_L1_SUBSTATE_CTRL2 (PCIE_RC_CONFIG_BASE + 0x90c) | 144 | #define PCIE_RC_CONFIG_L1_SUBSTATE_CTRL2 (PCIE_RC_CONFIG_BASE + 0x90c) |
145 | #define PCIE_RC_CONFIG_THP_CAP (PCIE_RC_CONFIG_BASE + 0x274) | ||
146 | #define PCIE_RC_CONFIG_THP_CAP_NEXT_MASK GENMASK(31, 20) | ||
145 | 147 | ||
146 | #define PCIE_CORE_AXI_CONF_BASE 0xc00000 | 148 | #define PCIE_CORE_AXI_CONF_BASE 0xc00000 |
147 | #define PCIE_CORE_OB_REGION_ADDR0 (PCIE_CORE_AXI_CONF_BASE + 0x0) | 149 | #define PCIE_CORE_OB_REGION_ADDR0 (PCIE_CORE_AXI_CONF_BASE + 0x0) |
@@ -190,6 +192,9 @@ struct rockchip_pcie { | |||
190 | struct reset_control *mgmt_rst; | 192 | struct reset_control *mgmt_rst; |
191 | struct reset_control *mgmt_sticky_rst; | 193 | struct reset_control *mgmt_sticky_rst; |
192 | struct reset_control *pipe_rst; | 194 | struct reset_control *pipe_rst; |
195 | struct reset_control *pm_rst; | ||
196 | struct reset_control *aclk_rst; | ||
197 | struct reset_control *pclk_rst; | ||
193 | struct clk *aclk_pcie; | 198 | struct clk *aclk_pcie; |
194 | struct clk *aclk_perf_pcie; | 199 | struct clk *aclk_perf_pcie; |
195 | struct clk *hclk_pcie; | 200 | struct clk *hclk_pcie; |
@@ -200,8 +205,14 @@ struct rockchip_pcie { | |||
200 | struct gpio_desc *ep_gpio; | 205 | struct gpio_desc *ep_gpio; |
201 | u32 lanes; | 206 | u32 lanes; |
202 | u8 root_bus_nr; | 207 | u8 root_bus_nr; |
208 | int link_gen; | ||
203 | struct device *dev; | 209 | struct device *dev; |
204 | struct irq_domain *irq_domain; | 210 | struct irq_domain *irq_domain; |
211 | u32 io_size; | ||
212 | int offset; | ||
213 | phys_addr_t io_bus_addr; | ||
214 | u32 mem_size; | ||
215 | phys_addr_t mem_bus_addr; | ||
205 | }; | 216 | }; |
206 | 217 | ||
207 | static u32 rockchip_pcie_read(struct rockchip_pcie *rockchip, u32 reg) | 218 | static u32 rockchip_pcie_read(struct rockchip_pcie *rockchip, u32 reg) |
@@ -220,7 +231,7 @@ static void rockchip_pcie_enable_bw_int(struct rockchip_pcie *rockchip) | |||
220 | u32 status; | 231 | u32 status; |
221 | 232 | ||
222 | status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_LCS); | 233 | status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_LCS); |
223 | status |= (PCIE_RC_CONFIG_LCS_LBMIE | PCIE_RC_CONFIG_LCS_LABIE); | 234 | status |= (PCI_EXP_LNKCTL_LBMIE | PCI_EXP_LNKCTL_LABIE); |
224 | rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_LCS); | 235 | rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_LCS); |
225 | } | 236 | } |
226 | 237 | ||
@@ -229,7 +240,7 @@ static void rockchip_pcie_clr_bw_int(struct rockchip_pcie *rockchip) | |||
229 | u32 status; | 240 | u32 status; |
230 | 241 | ||
231 | status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_LCS); | 242 | status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_LCS); |
232 | status |= (PCIE_RC_CONFIG_LCS_LBMS | PCIE_RC_CONFIG_LCS_LAMS); | 243 | status |= (PCI_EXP_LNKSTA_LBMS | PCI_EXP_LNKSTA_LABS) << 16; |
233 | rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_LCS); | 244 | rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_LCS); |
234 | } | 245 | } |
235 | 246 | ||
@@ -395,6 +406,40 @@ static struct pci_ops rockchip_pcie_ops = { | |||
395 | .write = rockchip_pcie_wr_conf, | 406 | .write = rockchip_pcie_wr_conf, |
396 | }; | 407 | }; |
397 | 408 | ||
409 | static void rockchip_pcie_set_power_limit(struct rockchip_pcie *rockchip) | ||
410 | { | ||
411 | u32 status, curr, scale, power; | ||
412 | |||
413 | if (IS_ERR(rockchip->vpcie3v3)) | ||
414 | return; | ||
415 | |||
416 | /* | ||
417 | * Set RC's captured slot power limit and scale if | ||
418 | * vpcie3v3 available. The default values are both zero | ||
419 | * which means the software should set these two according | ||
420 | * to the actual power supply. | ||
421 | */ | ||
422 | curr = regulator_get_current_limit(rockchip->vpcie3v3); | ||
423 | if (curr > 0) { | ||
424 | scale = 3; /* 0.001x */ | ||
425 | curr = curr / 1000; /* convert to mA */ | ||
426 | power = (curr * 3300) / 1000; /* milliwatt */ | ||
427 | while (power > PCIE_RC_CONFIG_DCR_CSPL_LIMIT) { | ||
428 | if (!scale) { | ||
429 | dev_warn(rockchip->dev, "invalid power supply\n"); | ||
430 | return; | ||
431 | } | ||
432 | scale--; | ||
433 | power = power / 10; | ||
434 | } | ||
435 | |||
436 | status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_DCR); | ||
437 | status |= (power << PCIE_RC_CONFIG_DCR_CSPL_SHIFT) | | ||
438 | (scale << PCIE_RC_CONFIG_DCR_CPLS_SHIFT); | ||
439 | rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_DCR); | ||
440 | } | ||
441 | } | ||
442 | |||
398 | /** | 443 | /** |
399 | * rockchip_pcie_init_port - Initialize hardware | 444 | * rockchip_pcie_init_port - Initialize hardware |
400 | * @rockchip: PCIe port information | 445 | * @rockchip: PCIe port information |
@@ -408,6 +453,24 @@ static int rockchip_pcie_init_port(struct rockchip_pcie *rockchip) | |||
408 | 453 | ||
409 | gpiod_set_value(rockchip->ep_gpio, 0); | 454 | gpiod_set_value(rockchip->ep_gpio, 0); |
410 | 455 | ||
456 | err = reset_control_assert(rockchip->aclk_rst); | ||
457 | if (err) { | ||
458 | dev_err(dev, "assert aclk_rst err %d\n", err); | ||
459 | return err; | ||
460 | } | ||
461 | |||
462 | err = reset_control_assert(rockchip->pclk_rst); | ||
463 | if (err) { | ||
464 | dev_err(dev, "assert pclk_rst err %d\n", err); | ||
465 | return err; | ||
466 | } | ||
467 | |||
468 | err = reset_control_assert(rockchip->pm_rst); | ||
469 | if (err) { | ||
470 | dev_err(dev, "assert pm_rst err %d\n", err); | ||
471 | return err; | ||
472 | } | ||
473 | |||
411 | err = phy_init(rockchip->phy); | 474 | err = phy_init(rockchip->phy); |
412 | if (err < 0) { | 475 | if (err < 0) { |
413 | dev_err(dev, "fail to init phy, err %d\n", err); | 476 | dev_err(dev, "fail to init phy, err %d\n", err); |
@@ -438,14 +501,40 @@ static int rockchip_pcie_init_port(struct rockchip_pcie *rockchip) | |||
438 | return err; | 501 | return err; |
439 | } | 502 | } |
440 | 503 | ||
504 | udelay(10); | ||
505 | |||
506 | err = reset_control_deassert(rockchip->pm_rst); | ||
507 | if (err) { | ||
508 | dev_err(dev, "deassert pm_rst err %d\n", err); | ||
509 | return err; | ||
510 | } | ||
511 | |||
512 | err = reset_control_deassert(rockchip->aclk_rst); | ||
513 | if (err) { | ||
514 | dev_err(dev, "deassert aclk_rst err %d\n", err); | ||
515 | return err; | ||
516 | } | ||
517 | |||
518 | err = reset_control_deassert(rockchip->pclk_rst); | ||
519 | if (err) { | ||
520 | dev_err(dev, "deassert pclk_rst err %d\n", err); | ||
521 | return err; | ||
522 | } | ||
523 | |||
524 | if (rockchip->link_gen == 2) | ||
525 | rockchip_pcie_write(rockchip, PCIE_CLIENT_GEN_SEL_2, | ||
526 | PCIE_CLIENT_CONFIG); | ||
527 | else | ||
528 | rockchip_pcie_write(rockchip, PCIE_CLIENT_GEN_SEL_1, | ||
529 | PCIE_CLIENT_CONFIG); | ||
530 | |||
441 | rockchip_pcie_write(rockchip, | 531 | rockchip_pcie_write(rockchip, |
442 | PCIE_CLIENT_CONF_ENABLE | | 532 | PCIE_CLIENT_CONF_ENABLE | |
443 | PCIE_CLIENT_LINK_TRAIN_ENABLE | | 533 | PCIE_CLIENT_LINK_TRAIN_ENABLE | |
444 | PCIE_CLIENT_ARI_ENABLE | | 534 | PCIE_CLIENT_ARI_ENABLE | |
445 | PCIE_CLIENT_CONF_LANE_NUM(rockchip->lanes) | | 535 | PCIE_CLIENT_CONF_LANE_NUM(rockchip->lanes) | |
446 | PCIE_CLIENT_MODE_RC | | 536 | PCIE_CLIENT_MODE_RC, |
447 | PCIE_CLIENT_GEN_SEL_2, | 537 | PCIE_CLIENT_CONFIG); |
448 | PCIE_CLIENT_CONFIG); | ||
449 | 538 | ||
450 | err = phy_power_on(rockchip->phy); | 539 | err = phy_power_on(rockchip->phy); |
451 | if (err) { | 540 | if (err) { |
@@ -481,21 +570,19 @@ static int rockchip_pcie_init_port(struct rockchip_pcie *rockchip) | |||
481 | return err; | 570 | return err; |
482 | } | 571 | } |
483 | 572 | ||
484 | /* | ||
485 | * We need to read/write PCIE_RC_CONFIG_L1_SUBSTATE_CTRL2 before | ||
486 | * enabling ASPM. Otherwise L1PwrOnSc and L1PwrOnVal isn't | ||
487 | * reliable and enabling ASPM doesn't work. This is a controller | ||
488 | * bug we need to work around. | ||
489 | */ | ||
490 | status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_L1_SUBSTATE_CTRL2); | ||
491 | rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_L1_SUBSTATE_CTRL2); | ||
492 | |||
493 | /* Fix the transmitted FTS count desired to exit from L0s. */ | 573 | /* Fix the transmitted FTS count desired to exit from L0s. */ |
494 | status = rockchip_pcie_read(rockchip, PCIE_CORE_CTRL_PLC1); | 574 | status = rockchip_pcie_read(rockchip, PCIE_CORE_CTRL_PLC1); |
495 | status = (status & PCIE_CORE_CTRL_PLC1_FTS_MASK) | | 575 | status = (status & ~PCIE_CORE_CTRL_PLC1_FTS_MASK) | |
496 | (PCIE_CORE_CTRL_PLC1_FTS_CNT << PCIE_CORE_CTRL_PLC1_FTS_SHIFT); | 576 | (PCIE_CORE_CTRL_PLC1_FTS_CNT << PCIE_CORE_CTRL_PLC1_FTS_SHIFT); |
497 | rockchip_pcie_write(rockchip, status, PCIE_CORE_CTRL_PLC1); | 577 | rockchip_pcie_write(rockchip, status, PCIE_CORE_CTRL_PLC1); |
498 | 578 | ||
579 | rockchip_pcie_set_power_limit(rockchip); | ||
580 | |||
581 | /* Set RC's clock architecture as common clock */ | ||
582 | status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_LCS); | ||
583 | status |= PCI_EXP_LNKCTL_CCC; | ||
584 | rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_LCS); | ||
585 | |||
499 | /* Enable Gen1 training */ | 586 | /* Enable Gen1 training */ |
500 | rockchip_pcie_write(rockchip, PCIE_CLIENT_LINK_TRAIN_ENABLE, | 587 | rockchip_pcie_write(rockchip, PCIE_CLIENT_LINK_TRAIN_ENABLE, |
501 | PCIE_CLIENT_CONFIG); | 588 | PCIE_CLIENT_CONFIG); |
@@ -522,35 +609,37 @@ static int rockchip_pcie_init_port(struct rockchip_pcie *rockchip) | |||
522 | msleep(20); | 609 | msleep(20); |
523 | } | 610 | } |
524 | 611 | ||
525 | /* | 612 | if (rockchip->link_gen == 2) { |
526 | * Enable retrain for gen2. This should be configured only after | 613 | /* |
527 | * gen1 finished. | 614 | * Enable retrain for gen2. This should be configured only after |
528 | */ | 615 | * gen1 finished. |
529 | status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_LCS); | 616 | */ |
530 | status |= PCIE_RC_CONFIG_LCS_RETRAIN_LINK; | 617 | status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_LCS); |
531 | rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_LCS); | 618 | status |= PCI_EXP_LNKCTL_RL; |
619 | rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_LCS); | ||
620 | |||
621 | timeout = jiffies + msecs_to_jiffies(500); | ||
622 | for (;;) { | ||
623 | status = rockchip_pcie_read(rockchip, PCIE_CORE_CTRL); | ||
624 | if ((status & PCIE_CORE_PL_CONF_SPEED_MASK) == | ||
625 | PCIE_CORE_PL_CONF_SPEED_5G) { | ||
626 | dev_dbg(dev, "PCIe link training gen2 pass!\n"); | ||
627 | break; | ||
628 | } | ||
532 | 629 | ||
533 | timeout = jiffies + msecs_to_jiffies(500); | 630 | if (time_after(jiffies, timeout)) { |
534 | for (;;) { | 631 | dev_dbg(dev, "PCIe link training gen2 timeout, fall back to gen1!\n"); |
535 | status = rockchip_pcie_read(rockchip, PCIE_CORE_CTRL); | 632 | break; |
536 | if ((status & PCIE_CORE_PL_CONF_SPEED_MASK) == | 633 | } |
537 | PCIE_CORE_PL_CONF_SPEED_5G) { | ||
538 | dev_dbg(dev, "PCIe link training gen2 pass!\n"); | ||
539 | break; | ||
540 | } | ||
541 | 634 | ||
542 | if (time_after(jiffies, timeout)) { | 635 | msleep(20); |
543 | dev_dbg(dev, "PCIe link training gen2 timeout, fall back to gen1!\n"); | ||
544 | break; | ||
545 | } | 636 | } |
546 | |||
547 | msleep(20); | ||
548 | } | 637 | } |
549 | 638 | ||
550 | /* Check the final link width from negotiated lane counter from MGMT */ | 639 | /* Check the final link width from negotiated lane counter from MGMT */ |
551 | status = rockchip_pcie_read(rockchip, PCIE_CORE_CTRL); | 640 | status = rockchip_pcie_read(rockchip, PCIE_CORE_CTRL); |
552 | status = 0x1 << ((status & PCIE_CORE_PL_CONF_LANE_MASK) >> | 641 | status = 0x1 << ((status & PCIE_CORE_PL_CONF_LANE_MASK) >> |
553 | PCIE_CORE_PL_CONF_LANE_MASK); | 642 | PCIE_CORE_PL_CONF_LANE_SHIFT); |
554 | dev_dbg(dev, "current link width is x%d\n", status); | 643 | dev_dbg(dev, "current link width is x%d\n", status); |
555 | 644 | ||
556 | rockchip_pcie_write(rockchip, ROCKCHIP_VENDOR_ID, | 645 | rockchip_pcie_write(rockchip, ROCKCHIP_VENDOR_ID, |
@@ -558,6 +647,12 @@ static int rockchip_pcie_init_port(struct rockchip_pcie *rockchip) | |||
558 | rockchip_pcie_write(rockchip, | 647 | rockchip_pcie_write(rockchip, |
559 | PCI_CLASS_BRIDGE_PCI << PCIE_RC_CONFIG_SCC_SHIFT, | 648 | PCI_CLASS_BRIDGE_PCI << PCIE_RC_CONFIG_SCC_SHIFT, |
560 | PCIE_RC_CONFIG_RID_CCR); | 649 | PCIE_RC_CONFIG_RID_CCR); |
650 | |||
651 | /* Clear THP cap's next cap pointer to remove L1 substate cap */ | ||
652 | status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_THP_CAP); | ||
653 | status &= ~PCIE_RC_CONFIG_THP_CAP_NEXT_MASK; | ||
654 | rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_THP_CAP); | ||
655 | |||
561 | rockchip_pcie_write(rockchip, 0x0, PCIE_RC_BAR_CONF); | 656 | rockchip_pcie_write(rockchip, 0x0, PCIE_RC_BAR_CONF); |
562 | 657 | ||
563 | rockchip_pcie_write(rockchip, | 658 | rockchip_pcie_write(rockchip, |
@@ -753,6 +848,10 @@ static int rockchip_pcie_parse_dt(struct rockchip_pcie *rockchip) | |||
753 | rockchip->lanes = 1; | 848 | rockchip->lanes = 1; |
754 | } | 849 | } |
755 | 850 | ||
851 | rockchip->link_gen = of_pci_get_max_link_speed(node); | ||
852 | if (rockchip->link_gen < 0 || rockchip->link_gen > 2) | ||
853 | rockchip->link_gen = 2; | ||
854 | |||
756 | rockchip->core_rst = devm_reset_control_get(dev, "core"); | 855 | rockchip->core_rst = devm_reset_control_get(dev, "core"); |
757 | if (IS_ERR(rockchip->core_rst)) { | 856 | if (IS_ERR(rockchip->core_rst)) { |
758 | if (PTR_ERR(rockchip->core_rst) != -EPROBE_DEFER) | 857 | if (PTR_ERR(rockchip->core_rst) != -EPROBE_DEFER) |
@@ -781,6 +880,27 @@ static int rockchip_pcie_parse_dt(struct rockchip_pcie *rockchip) | |||
781 | return PTR_ERR(rockchip->pipe_rst); | 880 | return PTR_ERR(rockchip->pipe_rst); |
782 | } | 881 | } |
783 | 882 | ||
883 | rockchip->pm_rst = devm_reset_control_get(dev, "pm"); | ||
884 | if (IS_ERR(rockchip->pm_rst)) { | ||
885 | if (PTR_ERR(rockchip->pm_rst) != -EPROBE_DEFER) | ||
886 | dev_err(dev, "missing pm reset property in node\n"); | ||
887 | return PTR_ERR(rockchip->pm_rst); | ||
888 | } | ||
889 | |||
890 | rockchip->pclk_rst = devm_reset_control_get(dev, "pclk"); | ||
891 | if (IS_ERR(rockchip->pclk_rst)) { | ||
892 | if (PTR_ERR(rockchip->pclk_rst) != -EPROBE_DEFER) | ||
893 | dev_err(dev, "missing pclk reset property in node\n"); | ||
894 | return PTR_ERR(rockchip->pclk_rst); | ||
895 | } | ||
896 | |||
897 | rockchip->aclk_rst = devm_reset_control_get(dev, "aclk"); | ||
898 | if (IS_ERR(rockchip->aclk_rst)) { | ||
899 | if (PTR_ERR(rockchip->aclk_rst) != -EPROBE_DEFER) | ||
900 | dev_err(dev, "missing aclk reset property in node\n"); | ||
901 | return PTR_ERR(rockchip->aclk_rst); | ||
902 | } | ||
903 | |||
784 | rockchip->ep_gpio = devm_gpiod_get(dev, "ep", GPIOD_OUT_HIGH); | 904 | rockchip->ep_gpio = devm_gpiod_get(dev, "ep", GPIOD_OUT_HIGH); |
785 | if (IS_ERR(rockchip->ep_gpio)) { | 905 | if (IS_ERR(rockchip->ep_gpio)) { |
786 | dev_err(dev, "missing ep-gpios property in node\n"); | 906 | dev_err(dev, "missing ep-gpios property in node\n"); |
@@ -1025,6 +1145,50 @@ static int rockchip_pcie_prog_ib_atu(struct rockchip_pcie *rockchip, | |||
1025 | return 0; | 1145 | return 0; |
1026 | } | 1146 | } |
1027 | 1147 | ||
1148 | static int rockchip_cfg_atu(struct rockchip_pcie *rockchip) | ||
1149 | { | ||
1150 | struct device *dev = rockchip->dev; | ||
1151 | int offset; | ||
1152 | int err; | ||
1153 | int reg_no; | ||
1154 | |||
1155 | for (reg_no = 0; reg_no < (rockchip->mem_size >> 20); reg_no++) { | ||
1156 | err = rockchip_pcie_prog_ob_atu(rockchip, reg_no + 1, | ||
1157 | AXI_WRAPPER_MEM_WRITE, | ||
1158 | 20 - 1, | ||
1159 | rockchip->mem_bus_addr + | ||
1160 | (reg_no << 20), | ||
1161 | 0); | ||
1162 | if (err) { | ||
1163 | dev_err(dev, "program RC mem outbound ATU failed\n"); | ||
1164 | return err; | ||
1165 | } | ||
1166 | } | ||
1167 | |||
1168 | err = rockchip_pcie_prog_ib_atu(rockchip, 2, 32 - 1, 0x0, 0); | ||
1169 | if (err) { | ||
1170 | dev_err(dev, "program RC mem inbound ATU failed\n"); | ||
1171 | return err; | ||
1172 | } | ||
1173 | |||
1174 | offset = rockchip->mem_size >> 20; | ||
1175 | for (reg_no = 0; reg_no < (rockchip->io_size >> 20); reg_no++) { | ||
1176 | err = rockchip_pcie_prog_ob_atu(rockchip, | ||
1177 | reg_no + 1 + offset, | ||
1178 | AXI_WRAPPER_IO_WRITE, | ||
1179 | 20 - 1, | ||
1180 | rockchip->io_bus_addr + | ||
1181 | (reg_no << 20), | ||
1182 | 0); | ||
1183 | if (err) { | ||
1184 | dev_err(dev, "program RC io outbound ATU failed\n"); | ||
1185 | return err; | ||
1186 | } | ||
1187 | } | ||
1188 | |||
1189 | return 0; | ||
1190 | } | ||
1191 | |||
1028 | static int rockchip_pcie_probe(struct platform_device *pdev) | 1192 | static int rockchip_pcie_probe(struct platform_device *pdev) |
1029 | { | 1193 | { |
1030 | struct rockchip_pcie *rockchip; | 1194 | struct rockchip_pcie *rockchip; |
@@ -1034,13 +1198,7 @@ static int rockchip_pcie_probe(struct platform_device *pdev) | |||
1034 | resource_size_t io_base; | 1198 | resource_size_t io_base; |
1035 | struct resource *mem; | 1199 | struct resource *mem; |
1036 | struct resource *io; | 1200 | struct resource *io; |
1037 | phys_addr_t io_bus_addr = 0; | ||
1038 | u32 io_size; | ||
1039 | phys_addr_t mem_bus_addr = 0; | ||
1040 | u32 mem_size = 0; | ||
1041 | int reg_no; | ||
1042 | int err; | 1201 | int err; |
1043 | int offset; | ||
1044 | 1202 | ||
1045 | LIST_HEAD(res); | 1203 | LIST_HEAD(res); |
1046 | 1204 | ||
@@ -1107,14 +1265,13 @@ static int rockchip_pcie_probe(struct platform_device *pdev) | |||
1107 | goto err_vpcie; | 1265 | goto err_vpcie; |
1108 | 1266 | ||
1109 | /* Get the I/O and memory ranges from DT */ | 1267 | /* Get the I/O and memory ranges from DT */ |
1110 | io_size = 0; | ||
1111 | resource_list_for_each_entry(win, &res) { | 1268 | resource_list_for_each_entry(win, &res) { |
1112 | switch (resource_type(win->res)) { | 1269 | switch (resource_type(win->res)) { |
1113 | case IORESOURCE_IO: | 1270 | case IORESOURCE_IO: |
1114 | io = win->res; | 1271 | io = win->res; |
1115 | io->name = "I/O"; | 1272 | io->name = "I/O"; |
1116 | io_size = resource_size(io); | 1273 | rockchip->io_size = resource_size(io); |
1117 | io_bus_addr = io->start - win->offset; | 1274 | rockchip->io_bus_addr = io->start - win->offset; |
1118 | err = pci_remap_iospace(io, io_base); | 1275 | err = pci_remap_iospace(io, io_base); |
1119 | if (err) { | 1276 | if (err) { |
1120 | dev_warn(dev, "error %d: failed to map resource %pR\n", | 1277 | dev_warn(dev, "error %d: failed to map resource %pR\n", |
@@ -1125,8 +1282,8 @@ static int rockchip_pcie_probe(struct platform_device *pdev) | |||
1125 | case IORESOURCE_MEM: | 1282 | case IORESOURCE_MEM: |
1126 | mem = win->res; | 1283 | mem = win->res; |
1127 | mem->name = "MEM"; | 1284 | mem->name = "MEM"; |
1128 | mem_size = resource_size(mem); | 1285 | rockchip->mem_size = resource_size(mem); |
1129 | mem_bus_addr = mem->start - win->offset; | 1286 | rockchip->mem_bus_addr = mem->start - win->offset; |
1130 | break; | 1287 | break; |
1131 | case IORESOURCE_BUS: | 1288 | case IORESOURCE_BUS: |
1132 | rockchip->root_bus_nr = win->res->start; | 1289 | rockchip->root_bus_nr = win->res->start; |
@@ -1136,45 +1293,9 @@ static int rockchip_pcie_probe(struct platform_device *pdev) | |||
1136 | } | 1293 | } |
1137 | } | 1294 | } |
1138 | 1295 | ||
1139 | if (mem_size) { | 1296 | err = rockchip_cfg_atu(rockchip); |
1140 | for (reg_no = 0; reg_no < (mem_size >> 20); reg_no++) { | 1297 | if (err) |
1141 | err = rockchip_pcie_prog_ob_atu(rockchip, reg_no + 1, | ||
1142 | AXI_WRAPPER_MEM_WRITE, | ||
1143 | 20 - 1, | ||
1144 | mem_bus_addr + | ||
1145 | (reg_no << 20), | ||
1146 | 0); | ||
1147 | if (err) { | ||
1148 | dev_err(dev, "program RC mem outbound ATU failed\n"); | ||
1149 | goto err_vpcie; | ||
1150 | } | ||
1151 | } | ||
1152 | } | ||
1153 | |||
1154 | err = rockchip_pcie_prog_ib_atu(rockchip, 2, 32 - 1, 0x0, 0); | ||
1155 | if (err) { | ||
1156 | dev_err(dev, "program RC mem inbound ATU failed\n"); | ||
1157 | goto err_vpcie; | 1298 | goto err_vpcie; |
1158 | } | ||
1159 | |||
1160 | offset = mem_size >> 20; | ||
1161 | |||
1162 | if (io_size) { | ||
1163 | for (reg_no = 0; reg_no < (io_size >> 20); reg_no++) { | ||
1164 | err = rockchip_pcie_prog_ob_atu(rockchip, | ||
1165 | reg_no + 1 + offset, | ||
1166 | AXI_WRAPPER_IO_WRITE, | ||
1167 | 20 - 1, | ||
1168 | io_bus_addr + | ||
1169 | (reg_no << 20), | ||
1170 | 0); | ||
1171 | if (err) { | ||
1172 | dev_err(dev, "program RC io outbound ATU failed\n"); | ||
1173 | goto err_vpcie; | ||
1174 | } | ||
1175 | } | ||
1176 | } | ||
1177 | |||
1178 | bus = pci_scan_root_bus(&pdev->dev, 0, &rockchip_pcie_ops, rockchip, &res); | 1299 | bus = pci_scan_root_bus(&pdev->dev, 0, &rockchip_pcie_ops, rockchip, &res); |
1179 | if (!bus) { | 1300 | if (!bus) { |
1180 | err = -ENOMEM; | 1301 | err = -ENOMEM; |
@@ -1187,9 +1308,6 @@ static int rockchip_pcie_probe(struct platform_device *pdev) | |||
1187 | pcie_bus_configure_settings(child); | 1308 | pcie_bus_configure_settings(child); |
1188 | 1309 | ||
1189 | pci_bus_add_devices(bus); | 1310 | pci_bus_add_devices(bus); |
1190 | |||
1191 | dev_warn(dev, "only 32-bit config accesses supported; smaller writes may corrupt adjacent RW1C fields\n"); | ||
1192 | |||
1193 | return err; | 1311 | return err; |
1194 | 1312 | ||
1195 | err_vpcie: | 1313 | err_vpcie: |
diff --git a/drivers/pci/host/pcie-spear13xx.c b/drivers/pci/host/pcie-spear13xx.c index 3cf197ba7f37..dafe8b88d97d 100644 --- a/drivers/pci/host/pcie-spear13xx.c +++ b/drivers/pci/host/pcie-spear13xx.c | |||
@@ -296,8 +296,4 @@ static struct platform_driver spear13xx_pcie_driver = { | |||
296 | }, | 296 | }, |
297 | }; | 297 | }; |
298 | 298 | ||
299 | static int __init spear13xx_pcie_init(void) | 299 | builtin_platform_driver(spear13xx_pcie_driver); |
300 | { | ||
301 | return platform_driver_register(&spear13xx_pcie_driver); | ||
302 | } | ||
303 | device_initcall(spear13xx_pcie_init); | ||
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index a46b585fae31..5ed2dcaa8e27 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c | |||
@@ -222,35 +222,6 @@ static void acpiphp_post_dock_fixup(struct acpi_device *adev) | |||
222 | acpiphp_let_context_go(context); | 222 | acpiphp_let_context_go(context); |
223 | } | 223 | } |
224 | 224 | ||
225 | /* Check whether the PCI device is managed by native PCIe hotplug driver */ | ||
226 | static bool device_is_managed_by_native_pciehp(struct pci_dev *pdev) | ||
227 | { | ||
228 | u32 reg32; | ||
229 | acpi_handle tmp; | ||
230 | struct acpi_pci_root *root; | ||
231 | |||
232 | /* Check whether the PCIe port supports native PCIe hotplug */ | ||
233 | if (pcie_capability_read_dword(pdev, PCI_EXP_SLTCAP, ®32)) | ||
234 | return false; | ||
235 | if (!(reg32 & PCI_EXP_SLTCAP_HPC)) | ||
236 | return false; | ||
237 | |||
238 | /* | ||
239 | * Check whether native PCIe hotplug has been enabled for | ||
240 | * this PCIe hierarchy. | ||
241 | */ | ||
242 | tmp = acpi_find_root_bridge_handle(pdev); | ||
243 | if (!tmp) | ||
244 | return false; | ||
245 | root = acpi_pci_find_root(tmp); | ||
246 | if (!root) | ||
247 | return false; | ||
248 | if (!(root->osc_control_set & OSC_PCI_EXPRESS_NATIVE_HP_CONTROL)) | ||
249 | return false; | ||
250 | |||
251 | return true; | ||
252 | } | ||
253 | |||
254 | /** | 225 | /** |
255 | * acpiphp_add_context - Add ACPIPHP context to an ACPI device object. | 226 | * acpiphp_add_context - Add ACPIPHP context to an ACPI device object. |
256 | * @handle: ACPI handle of the object to add a context to. | 227 | * @handle: ACPI handle of the object to add a context to. |
@@ -334,7 +305,7 @@ static acpi_status acpiphp_add_context(acpi_handle handle, u32 lvl, void *data, | |||
334 | * expose slots to user space in those cases. | 305 | * expose slots to user space in those cases. |
335 | */ | 306 | */ |
336 | if ((acpi_pci_check_ejectable(pbus, handle) || is_dock_device(adev)) | 307 | if ((acpi_pci_check_ejectable(pbus, handle) || is_dock_device(adev)) |
337 | && !(pdev && device_is_managed_by_native_pciehp(pdev))) { | 308 | && !(pdev && pdev->is_hotplug_bridge && pciehp_is_native(pdev))) { |
338 | unsigned long long sun; | 309 | unsigned long long sun; |
339 | int retval; | 310 | int retval; |
340 | 311 | ||
diff --git a/drivers/pci/hotplug/cpqphp_core.c b/drivers/pci/hotplug/cpqphp_core.c index 74f3a0695b43..ec009a7dba20 100644 --- a/drivers/pci/hotplug/cpqphp_core.c +++ b/drivers/pci/hotplug/cpqphp_core.c | |||
@@ -867,7 +867,8 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
867 | */ | 867 | */ |
868 | if ((pdev->revision <= 2) && (vendor_id != PCI_VENDOR_ID_INTEL)) { | 868 | if ((pdev->revision <= 2) && (vendor_id != PCI_VENDOR_ID_INTEL)) { |
869 | err(msg_HPC_not_supported); | 869 | err(msg_HPC_not_supported); |
870 | return -ENODEV; | 870 | rc = -ENODEV; |
871 | goto err_disable_device; | ||
871 | } | 872 | } |
872 | 873 | ||
873 | /* TODO: This code can be made to support non-Compaq or Intel | 874 | /* TODO: This code can be made to support non-Compaq or Intel |
diff --git a/drivers/pci/hotplug/pci_hotplug_core.c b/drivers/pci/hotplug/pci_hotplug_core.c index fea0b8b33589..56013d0daf7f 100644 --- a/drivers/pci/hotplug/pci_hotplug_core.c +++ b/drivers/pci/hotplug/pci_hotplug_core.c | |||
@@ -23,6 +23,9 @@ | |||
23 | * | 23 | * |
24 | * Send feedback to <kristen.c.accardi@intel.com> | 24 | * Send feedback to <kristen.c.accardi@intel.com> |
25 | * | 25 | * |
26 | * Authors: | ||
27 | * Greg Kroah-Hartman <greg@kroah.com> | ||
28 | * Scott Murray <scottm@somanetworks.com> | ||
26 | */ | 29 | */ |
27 | 30 | ||
28 | #include <linux/module.h> /* try_module_get & module_put */ | 31 | #include <linux/module.h> /* try_module_get & module_put */ |
@@ -50,15 +53,9 @@ | |||
50 | #define info(format, arg...) printk(KERN_INFO "%s: " format, MY_NAME, ## arg) | 53 | #define info(format, arg...) printk(KERN_INFO "%s: " format, MY_NAME, ## arg) |
51 | #define warn(format, arg...) printk(KERN_WARNING "%s: " format, MY_NAME, ## arg) | 54 | #define warn(format, arg...) printk(KERN_WARNING "%s: " format, MY_NAME, ## arg) |
52 | 55 | ||
53 | |||
54 | /* local variables */ | 56 | /* local variables */ |
55 | static bool debug; | 57 | static bool debug; |
56 | 58 | ||
57 | #define DRIVER_VERSION "0.5" | ||
58 | #define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>, Scott Murray <scottm@somanetworks.com>" | ||
59 | #define DRIVER_DESC "PCI Hot Plug PCI Core" | ||
60 | |||
61 | |||
62 | static LIST_HEAD(pci_hotplug_slot_list); | 59 | static LIST_HEAD(pci_hotplug_slot_list); |
63 | static DEFINE_MUTEX(pci_hp_mutex); | 60 | static DEFINE_MUTEX(pci_hp_mutex); |
64 | 61 | ||
@@ -534,7 +531,6 @@ static int __init pci_hotplug_init(void) | |||
534 | return result; | 531 | return result; |
535 | } | 532 | } |
536 | 533 | ||
537 | info(DRIVER_DESC " version: " DRIVER_VERSION "\n"); | ||
538 | return result; | 534 | return result; |
539 | } | 535 | } |
540 | device_initcall(pci_hotplug_init); | 536 | device_initcall(pci_hotplug_init); |
diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c index 7d32fa33dcef..35d84845d5af 100644 --- a/drivers/pci/hotplug/pciehp_core.c +++ b/drivers/pci/hotplug/pciehp_core.c | |||
@@ -25,6 +25,10 @@ | |||
25 | * | 25 | * |
26 | * Send feedback to <greg@kroah.com>, <kristen.c.accardi@intel.com> | 26 | * Send feedback to <greg@kroah.com>, <kristen.c.accardi@intel.com> |
27 | * | 27 | * |
28 | * Authors: | ||
29 | * Dan Zink <dan.zink@compaq.com> | ||
30 | * Greg Kroah-Hartman <greg@kroah.com> | ||
31 | * Dely Sy <dely.l.sy@intel.com>" | ||
28 | */ | 32 | */ |
29 | 33 | ||
30 | #include <linux/moduleparam.h> | 34 | #include <linux/moduleparam.h> |
@@ -42,10 +46,6 @@ bool pciehp_poll_mode; | |||
42 | int pciehp_poll_time; | 46 | int pciehp_poll_time; |
43 | static bool pciehp_force; | 47 | static bool pciehp_force; |
44 | 48 | ||
45 | #define DRIVER_VERSION "0.4" | ||
46 | #define DRIVER_AUTHOR "Dan Zink <dan.zink@compaq.com>, Greg Kroah-Hartman <greg@kroah.com>, Dely Sy <dely.l.sy@intel.com>" | ||
47 | #define DRIVER_DESC "PCI Express Hot Plug Controller Driver" | ||
48 | |||
49 | /* | 49 | /* |
50 | * not really modular, but the easiest way to keep compat with existing | 50 | * not really modular, but the easiest way to keep compat with existing |
51 | * bootargs behaviour is to continue using module_param here. | 51 | * bootargs behaviour is to continue using module_param here. |
@@ -333,7 +333,6 @@ static int __init pcied_init(void) | |||
333 | 333 | ||
334 | retval = pcie_port_service_register(&hpdriver_portdrv); | 334 | retval = pcie_port_service_register(&hpdriver_portdrv); |
335 | dbg("pcie_port_service_register = %d\n", retval); | 335 | dbg("pcie_port_service_register = %d\n", retval); |
336 | info(DRIVER_DESC " version: " DRIVER_VERSION "\n"); | ||
337 | if (retval) | 336 | if (retval) |
338 | dbg("Failure to register service\n"); | 337 | dbg("Failure to register service\n"); |
339 | 338 | ||
diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c index efe69e879455..10c9c0ba8ff2 100644 --- a/drivers/pci/hotplug/pciehp_ctrl.c +++ b/drivers/pci/hotplug/pciehp_ctrl.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/kernel.h> | 31 | #include <linux/kernel.h> |
32 | #include <linux/types.h> | 32 | #include <linux/types.h> |
33 | #include <linux/slab.h> | 33 | #include <linux/slab.h> |
34 | #include <linux/pm_runtime.h> | ||
34 | #include <linux/pci.h> | 35 | #include <linux/pci.h> |
35 | #include "../pci.h" | 36 | #include "../pci.h" |
36 | #include "pciehp.h" | 37 | #include "pciehp.h" |
@@ -98,6 +99,7 @@ static int board_added(struct slot *p_slot) | |||
98 | pciehp_green_led_blink(p_slot); | 99 | pciehp_green_led_blink(p_slot); |
99 | 100 | ||
100 | /* Check link training status */ | 101 | /* Check link training status */ |
102 | pm_runtime_get_sync(&ctrl->pcie->port->dev); | ||
101 | retval = pciehp_check_link_status(ctrl); | 103 | retval = pciehp_check_link_status(ctrl); |
102 | if (retval) { | 104 | if (retval) { |
103 | ctrl_err(ctrl, "Failed to check link status\n"); | 105 | ctrl_err(ctrl, "Failed to check link status\n"); |
@@ -118,12 +120,14 @@ static int board_added(struct slot *p_slot) | |||
118 | if (retval != -EEXIST) | 120 | if (retval != -EEXIST) |
119 | goto err_exit; | 121 | goto err_exit; |
120 | } | 122 | } |
123 | pm_runtime_put(&ctrl->pcie->port->dev); | ||
121 | 124 | ||
122 | pciehp_green_led_on(p_slot); | 125 | pciehp_green_led_on(p_slot); |
123 | pciehp_set_attention_status(p_slot, 0); | 126 | pciehp_set_attention_status(p_slot, 0); |
124 | return 0; | 127 | return 0; |
125 | 128 | ||
126 | err_exit: | 129 | err_exit: |
130 | pm_runtime_put(&ctrl->pcie->port->dev); | ||
127 | set_slot_off(ctrl, p_slot); | 131 | set_slot_off(ctrl, p_slot); |
128 | return retval; | 132 | return retval; |
129 | } | 133 | } |
@@ -137,7 +141,9 @@ static int remove_board(struct slot *p_slot) | |||
137 | int retval; | 141 | int retval; |
138 | struct controller *ctrl = p_slot->ctrl; | 142 | struct controller *ctrl = p_slot->ctrl; |
139 | 143 | ||
144 | pm_runtime_get_sync(&ctrl->pcie->port->dev); | ||
140 | retval = pciehp_unconfigure_device(p_slot); | 145 | retval = pciehp_unconfigure_device(p_slot); |
146 | pm_runtime_put(&ctrl->pcie->port->dev); | ||
141 | if (retval) | 147 | if (retval) |
142 | return retval; | 148 | return retval; |
143 | 149 | ||
@@ -410,7 +416,7 @@ int pciehp_enable_slot(struct slot *p_slot) | |||
410 | if (getstatus) { | 416 | if (getstatus) { |
411 | ctrl_info(ctrl, "Slot(%s): Already enabled\n", | 417 | ctrl_info(ctrl, "Slot(%s): Already enabled\n", |
412 | slot_name(p_slot)); | 418 | slot_name(p_slot)); |
413 | return -EINVAL; | 419 | return 0; |
414 | } | 420 | } |
415 | } | 421 | } |
416 | 422 | ||
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index b57fc6d6e28a..026830a138ae 100644 --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c | |||
@@ -620,8 +620,18 @@ static irqreturn_t pciehp_isr(int irq, void *dev_id) | |||
620 | pciehp_queue_interrupt_event(slot, INT_BUTTON_PRESS); | 620 | pciehp_queue_interrupt_event(slot, INT_BUTTON_PRESS); |
621 | } | 621 | } |
622 | 622 | ||
623 | /* Check Presence Detect Changed */ | 623 | /* |
624 | if (events & PCI_EXP_SLTSTA_PDC) { | 624 | * Check Link Status Changed at higher precedence than Presence |
625 | * Detect Changed. The PDS value may be set to "card present" from | ||
626 | * out-of-band detection, which may be in conflict with a Link Down | ||
627 | * and cause the wrong event to queue. | ||
628 | */ | ||
629 | if (events & PCI_EXP_SLTSTA_DLLSC) { | ||
630 | ctrl_info(ctrl, "Slot(%s): Link %s\n", slot_name(slot), | ||
631 | link ? "Up" : "Down"); | ||
632 | pciehp_queue_interrupt_event(slot, link ? INT_LINK_UP : | ||
633 | INT_LINK_DOWN); | ||
634 | } else if (events & PCI_EXP_SLTSTA_PDC) { | ||
625 | present = !!(status & PCI_EXP_SLTSTA_PDS); | 635 | present = !!(status & PCI_EXP_SLTSTA_PDS); |
626 | ctrl_info(ctrl, "Slot(%s): Card %spresent\n", slot_name(slot), | 636 | ctrl_info(ctrl, "Slot(%s): Card %spresent\n", slot_name(slot), |
627 | present ? "" : "not "); | 637 | present ? "" : "not "); |
@@ -636,13 +646,6 @@ static irqreturn_t pciehp_isr(int irq, void *dev_id) | |||
636 | pciehp_queue_interrupt_event(slot, INT_POWER_FAULT); | 646 | pciehp_queue_interrupt_event(slot, INT_POWER_FAULT); |
637 | } | 647 | } |
638 | 648 | ||
639 | if (events & PCI_EXP_SLTSTA_DLLSC) { | ||
640 | ctrl_info(ctrl, "Slot(%s): Link %s\n", slot_name(slot), | ||
641 | link ? "Up" : "Down"); | ||
642 | pciehp_queue_interrupt_event(slot, link ? INT_LINK_UP : | ||
643 | INT_LINK_DOWN); | ||
644 | } | ||
645 | |||
646 | return IRQ_HANDLED; | 649 | return IRQ_HANDLED; |
647 | } | 650 | } |
648 | 651 | ||
diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c index e30f05c8517f..47227820406d 100644 --- a/drivers/pci/iov.c +++ b/drivers/pci/iov.c | |||
@@ -306,13 +306,6 @@ static int sriov_enable(struct pci_dev *dev, int nr_virtfn) | |||
306 | return rc; | 306 | return rc; |
307 | } | 307 | } |
308 | 308 | ||
309 | pci_iov_set_numvfs(dev, nr_virtfn); | ||
310 | iov->ctrl |= PCI_SRIOV_CTRL_VFE | PCI_SRIOV_CTRL_MSE; | ||
311 | pci_cfg_access_lock(dev); | ||
312 | pci_write_config_word(dev, iov->pos + PCI_SRIOV_CTRL, iov->ctrl); | ||
313 | msleep(100); | ||
314 | pci_cfg_access_unlock(dev); | ||
315 | |||
316 | iov->initial_VFs = initial; | 309 | iov->initial_VFs = initial; |
317 | if (nr_virtfn < initial) | 310 | if (nr_virtfn < initial) |
318 | initial = nr_virtfn; | 311 | initial = nr_virtfn; |
@@ -323,6 +316,13 @@ static int sriov_enable(struct pci_dev *dev, int nr_virtfn) | |||
323 | goto err_pcibios; | 316 | goto err_pcibios; |
324 | } | 317 | } |
325 | 318 | ||
319 | pci_iov_set_numvfs(dev, nr_virtfn); | ||
320 | iov->ctrl |= PCI_SRIOV_CTRL_VFE | PCI_SRIOV_CTRL_MSE; | ||
321 | pci_cfg_access_lock(dev); | ||
322 | pci_write_config_word(dev, iov->pos + PCI_SRIOV_CTRL, iov->ctrl); | ||
323 | msleep(100); | ||
324 | pci_cfg_access_unlock(dev); | ||
325 | |||
326 | for (i = 0; i < initial; i++) { | 326 | for (i = 0; i < initial; i++) { |
327 | rc = pci_iov_add_virtfn(dev, i, 0); | 327 | rc = pci_iov_add_virtfn(dev, i, 0); |
328 | if (rc) | 328 | if (rc) |
@@ -554,21 +554,61 @@ void pci_iov_release(struct pci_dev *dev) | |||
554 | } | 554 | } |
555 | 555 | ||
556 | /** | 556 | /** |
557 | * pci_iov_resource_bar - get position of the SR-IOV BAR | 557 | * pci_iov_update_resource - update a VF BAR |
558 | * @dev: the PCI device | 558 | * @dev: the PCI device |
559 | * @resno: the resource number | 559 | * @resno: the resource number |
560 | * | 560 | * |
561 | * Returns position of the BAR encapsulated in the SR-IOV capability. | 561 | * Update a VF BAR in the SR-IOV capability of a PF. |
562 | */ | 562 | */ |
563 | int pci_iov_resource_bar(struct pci_dev *dev, int resno) | 563 | void pci_iov_update_resource(struct pci_dev *dev, int resno) |
564 | { | 564 | { |
565 | if (resno < PCI_IOV_RESOURCES || resno > PCI_IOV_RESOURCE_END) | 565 | struct pci_sriov *iov = dev->is_physfn ? dev->sriov : NULL; |
566 | return 0; | 566 | struct resource *res = dev->resource + resno; |
567 | int vf_bar = resno - PCI_IOV_RESOURCES; | ||
568 | struct pci_bus_region region; | ||
569 | u16 cmd; | ||
570 | u32 new; | ||
571 | int reg; | ||
572 | |||
573 | /* | ||
574 | * The generic pci_restore_bars() path calls this for all devices, | ||
575 | * including VFs and non-SR-IOV devices. If this is not a PF, we | ||
576 | * have nothing to do. | ||
577 | */ | ||
578 | if (!iov) | ||
579 | return; | ||
580 | |||
581 | pci_read_config_word(dev, iov->pos + PCI_SRIOV_CTRL, &cmd); | ||
582 | if ((cmd & PCI_SRIOV_CTRL_VFE) && (cmd & PCI_SRIOV_CTRL_MSE)) { | ||
583 | dev_WARN(&dev->dev, "can't update enabled VF BAR%d %pR\n", | ||
584 | vf_bar, res); | ||
585 | return; | ||
586 | } | ||
587 | |||
588 | /* | ||
589 | * Ignore unimplemented BARs, unused resource slots for 64-bit | ||
590 | * BARs, and non-movable resources, e.g., those described via | ||
591 | * Enhanced Allocation. | ||
592 | */ | ||
593 | if (!res->flags) | ||
594 | return; | ||
595 | |||
596 | if (res->flags & IORESOURCE_UNSET) | ||
597 | return; | ||
598 | |||
599 | if (res->flags & IORESOURCE_PCI_FIXED) | ||
600 | return; | ||
567 | 601 | ||
568 | BUG_ON(!dev->is_physfn); | 602 | pcibios_resource_to_bus(dev->bus, ®ion, res); |
603 | new = region.start; | ||
604 | new |= res->flags & ~PCI_BASE_ADDRESS_MEM_MASK; | ||
569 | 605 | ||
570 | return dev->sriov->pos + PCI_SRIOV_BAR + | 606 | reg = iov->pos + PCI_SRIOV_BAR + 4 * vf_bar; |
571 | 4 * (resno - PCI_IOV_RESOURCES); | 607 | pci_write_config_dword(dev, reg, new); |
608 | if (res->flags & IORESOURCE_MEM_64) { | ||
609 | new = region.start >> 16 >> 16; | ||
610 | pci_write_config_dword(dev, reg + 4, new); | ||
611 | } | ||
572 | } | 612 | } |
573 | 613 | ||
574 | resource_size_t __weak pcibios_iov_resource_alignment(struct pci_dev *dev, | 614 | resource_size_t __weak pcibios_iov_resource_alignment(struct pci_dev *dev, |
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index bfdd0744b686..da4e3c1248db 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c | |||
@@ -1292,7 +1292,8 @@ const struct cpumask *pci_irq_get_affinity(struct pci_dev *dev, int nr) | |||
1292 | } else if (dev->msi_enabled) { | 1292 | } else if (dev->msi_enabled) { |
1293 | struct msi_desc *entry = first_pci_msi_entry(dev); | 1293 | struct msi_desc *entry = first_pci_msi_entry(dev); |
1294 | 1294 | ||
1295 | if (WARN_ON_ONCE(!entry || nr >= entry->nvec_used)) | 1295 | if (WARN_ON_ONCE(!entry || !entry->affinity || |
1296 | nr >= entry->nvec_used)) | ||
1296 | return NULL; | 1297 | return NULL; |
1297 | 1298 | ||
1298 | return &entry->affinity[nr]; | 1299 | return &entry->affinity[nr]; |
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index d966d47c9e80..001860361434 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c | |||
@@ -29,6 +29,82 @@ const u8 pci_acpi_dsm_uuid[] = { | |||
29 | 0x91, 0x17, 0xea, 0x4d, 0x19, 0xc3, 0x43, 0x4d | 29 | 0x91, 0x17, 0xea, 0x4d, 0x19, 0xc3, 0x43, 0x4d |
30 | }; | 30 | }; |
31 | 31 | ||
32 | #if defined(CONFIG_PCI_QUIRKS) && defined(CONFIG_ARM64) | ||
33 | static int acpi_get_rc_addr(struct acpi_device *adev, struct resource *res) | ||
34 | { | ||
35 | struct device *dev = &adev->dev; | ||
36 | struct resource_entry *entry; | ||
37 | struct list_head list; | ||
38 | unsigned long flags; | ||
39 | int ret; | ||
40 | |||
41 | INIT_LIST_HEAD(&list); | ||
42 | flags = IORESOURCE_MEM; | ||
43 | ret = acpi_dev_get_resources(adev, &list, | ||
44 | acpi_dev_filter_resource_type_cb, | ||
45 | (void *) flags); | ||
46 | if (ret < 0) { | ||
47 | dev_err(dev, "failed to parse _CRS method, error code %d\n", | ||
48 | ret); | ||
49 | return ret; | ||
50 | } | ||
51 | |||
52 | if (ret == 0) { | ||
53 | dev_err(dev, "no IO and memory resources present in _CRS\n"); | ||
54 | return -EINVAL; | ||
55 | } | ||
56 | |||
57 | entry = list_first_entry(&list, struct resource_entry, node); | ||
58 | *res = *entry->res; | ||
59 | acpi_dev_free_resource_list(&list); | ||
60 | return 0; | ||
61 | } | ||
62 | |||
63 | static acpi_status acpi_match_rc(acpi_handle handle, u32 lvl, void *context, | ||
64 | void **retval) | ||
65 | { | ||
66 | u16 *segment = context; | ||
67 | unsigned long long uid; | ||
68 | acpi_status status; | ||
69 | |||
70 | status = acpi_evaluate_integer(handle, "_UID", NULL, &uid); | ||
71 | if (ACPI_FAILURE(status) || uid != *segment) | ||
72 | return AE_CTRL_DEPTH; | ||
73 | |||
74 | *(acpi_handle *)retval = handle; | ||
75 | return AE_CTRL_TERMINATE; | ||
76 | } | ||
77 | |||
78 | int acpi_get_rc_resources(struct device *dev, const char *hid, u16 segment, | ||
79 | struct resource *res) | ||
80 | { | ||
81 | struct acpi_device *adev; | ||
82 | acpi_status status; | ||
83 | acpi_handle handle; | ||
84 | int ret; | ||
85 | |||
86 | status = acpi_get_devices(hid, acpi_match_rc, &segment, &handle); | ||
87 | if (ACPI_FAILURE(status)) { | ||
88 | dev_err(dev, "can't find _HID %s device to locate resources\n", | ||
89 | hid); | ||
90 | return -ENODEV; | ||
91 | } | ||
92 | |||
93 | ret = acpi_bus_get_device(handle, &adev); | ||
94 | if (ret) | ||
95 | return ret; | ||
96 | |||
97 | ret = acpi_get_rc_addr(adev, res); | ||
98 | if (ret) { | ||
99 | dev_err(dev, "can't get resource from %s\n", | ||
100 | dev_name(&adev->dev)); | ||
101 | return ret; | ||
102 | } | ||
103 | |||
104 | return 0; | ||
105 | } | ||
106 | #endif | ||
107 | |||
32 | phys_addr_t acpi_pci_root_get_mcfg_addr(acpi_handle handle) | 108 | phys_addr_t acpi_pci_root_get_mcfg_addr(acpi_handle handle) |
33 | { | 109 | { |
34 | acpi_status status = AE_NOT_EXIST; | 110 | acpi_status status = AE_NOT_EXIST; |
@@ -294,6 +370,30 @@ int pci_get_hp_params(struct pci_dev *dev, struct hotplug_params *hpp) | |||
294 | EXPORT_SYMBOL_GPL(pci_get_hp_params); | 370 | EXPORT_SYMBOL_GPL(pci_get_hp_params); |
295 | 371 | ||
296 | /** | 372 | /** |
373 | * pciehp_is_native - Check whether a hotplug port is handled by the OS | ||
374 | * @pdev: Hotplug port to check | ||
375 | * | ||
376 | * Walk up from @pdev to the host bridge, obtain its cached _OSC Control Field | ||
377 | * and return the value of the "PCI Express Native Hot Plug control" bit. | ||
378 | * On failure to obtain the _OSC Control Field return %false. | ||
379 | */ | ||
380 | bool pciehp_is_native(struct pci_dev *pdev) | ||
381 | { | ||
382 | struct acpi_pci_root *root; | ||
383 | acpi_handle handle; | ||
384 | |||
385 | handle = acpi_find_root_bridge_handle(pdev); | ||
386 | if (!handle) | ||
387 | return false; | ||
388 | |||
389 | root = acpi_pci_find_root(handle); | ||
390 | if (!root) | ||
391 | return false; | ||
392 | |||
393 | return root->osc_control_set & OSC_PCI_EXPRESS_NATIVE_HP_CONTROL; | ||
394 | } | ||
395 | |||
396 | /** | ||
297 | * pci_acpi_wake_bus - Root bus wakeup notification fork function. | 397 | * pci_acpi_wake_bus - Root bus wakeup notification fork function. |
298 | * @work: Work item to handle. | 398 | * @work: Work item to handle. |
299 | */ | 399 | */ |
diff --git a/drivers/pci/pci-mid.c b/drivers/pci/pci-mid.c index 55f453de562e..23ed7316c891 100644 --- a/drivers/pci/pci-mid.c +++ b/drivers/pci/pci-mid.c | |||
@@ -49,7 +49,7 @@ static bool mid_pci_need_resume(struct pci_dev *dev) | |||
49 | return false; | 49 | return false; |
50 | } | 50 | } |
51 | 51 | ||
52 | static struct pci_platform_pm_ops mid_pci_platform_pm = { | 52 | static const struct pci_platform_pm_ops mid_pci_platform_pm = { |
53 | .is_manageable = mid_pci_power_manageable, | 53 | .is_manageable = mid_pci_power_manageable, |
54 | .set_state = mid_pci_set_power_state, | 54 | .set_state = mid_pci_set_power_state, |
55 | .choose_state = mid_pci_choose_state, | 55 | .choose_state = mid_pci_choose_state, |
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index bcd10c795284..066628776e1b 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c | |||
@@ -50,6 +50,7 @@ pci_config_attr(vendor, "0x%04x\n"); | |||
50 | pci_config_attr(device, "0x%04x\n"); | 50 | pci_config_attr(device, "0x%04x\n"); |
51 | pci_config_attr(subsystem_vendor, "0x%04x\n"); | 51 | pci_config_attr(subsystem_vendor, "0x%04x\n"); |
52 | pci_config_attr(subsystem_device, "0x%04x\n"); | 52 | pci_config_attr(subsystem_device, "0x%04x\n"); |
53 | pci_config_attr(revision, "0x%02x\n"); | ||
53 | pci_config_attr(class, "0x%06x\n"); | 54 | pci_config_attr(class, "0x%06x\n"); |
54 | pci_config_attr(irq, "%u\n"); | 55 | pci_config_attr(irq, "%u\n"); |
55 | 56 | ||
@@ -568,6 +569,7 @@ static struct attribute *pci_dev_attrs[] = { | |||
568 | &dev_attr_device.attr, | 569 | &dev_attr_device.attr, |
569 | &dev_attr_subsystem_vendor.attr, | 570 | &dev_attr_subsystem_vendor.attr, |
570 | &dev_attr_subsystem_device.attr, | 571 | &dev_attr_subsystem_device.attr, |
572 | &dev_attr_revision.attr, | ||
571 | &dev_attr_class.attr, | 573 | &dev_attr_class.attr, |
572 | &dev_attr_irq.attr, | 574 | &dev_attr_irq.attr, |
573 | &dev_attr_local_cpus.attr, | 575 | &dev_attr_local_cpus.attr, |
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index ba34907538f6..a881c0d3d2e8 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -564,10 +564,6 @@ static void pci_restore_bars(struct pci_dev *dev) | |||
564 | { | 564 | { |
565 | int i; | 565 | int i; |
566 | 566 | ||
567 | /* Per SR-IOV spec 3.4.1.11, VF BARs are RO zero */ | ||
568 | if (dev->is_virtfn) | ||
569 | return; | ||
570 | |||
571 | for (i = 0; i < PCI_BRIDGE_RESOURCES; i++) | 567 | for (i = 0; i < PCI_BRIDGE_RESOURCES; i++) |
572 | pci_update_resource(dev, i); | 568 | pci_update_resource(dev, i); |
573 | } | 569 | } |
@@ -2106,6 +2102,10 @@ bool pci_dev_run_wake(struct pci_dev *dev) | |||
2106 | if (!dev->pme_support) | 2102 | if (!dev->pme_support) |
2107 | return false; | 2103 | return false; |
2108 | 2104 | ||
2105 | /* PME-capable in principle, but not from the intended sleep state */ | ||
2106 | if (!pci_pme_capable(dev, pci_target_state(dev))) | ||
2107 | return false; | ||
2108 | |||
2109 | while (bus->parent) { | 2109 | while (bus->parent) { |
2110 | struct pci_dev *bridge = bus->self; | 2110 | struct pci_dev *bridge = bus->self; |
2111 | 2111 | ||
@@ -2226,7 +2226,7 @@ void pci_config_pm_runtime_put(struct pci_dev *pdev) | |||
2226 | * This function checks if it is possible to move the bridge to D3. | 2226 | * This function checks if it is possible to move the bridge to D3. |
2227 | * Currently we only allow D3 for recent enough PCIe ports. | 2227 | * Currently we only allow D3 for recent enough PCIe ports. |
2228 | */ | 2228 | */ |
2229 | static bool pci_bridge_d3_possible(struct pci_dev *bridge) | 2229 | bool pci_bridge_d3_possible(struct pci_dev *bridge) |
2230 | { | 2230 | { |
2231 | unsigned int year; | 2231 | unsigned int year; |
2232 | 2232 | ||
@@ -2239,6 +2239,14 @@ static bool pci_bridge_d3_possible(struct pci_dev *bridge) | |||
2239 | case PCI_EXP_TYPE_DOWNSTREAM: | 2239 | case PCI_EXP_TYPE_DOWNSTREAM: |
2240 | if (pci_bridge_d3_disable) | 2240 | if (pci_bridge_d3_disable) |
2241 | return false; | 2241 | return false; |
2242 | |||
2243 | /* | ||
2244 | * Hotplug ports handled by firmware in System Management Mode | ||
2245 | * may not be put into D3 by the OS (Thunderbolt on non-Macs). | ||
2246 | */ | ||
2247 | if (bridge->is_hotplug_bridge && !pciehp_is_native(bridge)) | ||
2248 | return false; | ||
2249 | |||
2242 | if (pci_bridge_d3_force) | 2250 | if (pci_bridge_d3_force) |
2243 | return true; | 2251 | return true; |
2244 | 2252 | ||
@@ -2259,32 +2267,36 @@ static bool pci_bridge_d3_possible(struct pci_dev *bridge) | |||
2259 | static int pci_dev_check_d3cold(struct pci_dev *dev, void *data) | 2267 | static int pci_dev_check_d3cold(struct pci_dev *dev, void *data) |
2260 | { | 2268 | { |
2261 | bool *d3cold_ok = data; | 2269 | bool *d3cold_ok = data; |
2262 | bool no_d3cold; | ||
2263 | 2270 | ||
2264 | /* | 2271 | if (/* The device needs to be allowed to go D3cold ... */ |
2265 | * The device needs to be allowed to go D3cold and if it is wake | 2272 | dev->no_d3cold || !dev->d3cold_allowed || |
2266 | * capable to do so from D3cold. | ||
2267 | */ | ||
2268 | no_d3cold = dev->no_d3cold || !dev->d3cold_allowed || | ||
2269 | (device_may_wakeup(&dev->dev) && !pci_pme_capable(dev, PCI_D3cold)) || | ||
2270 | !pci_power_manageable(dev); | ||
2271 | 2273 | ||
2272 | *d3cold_ok = !no_d3cold; | 2274 | /* ... and if it is wakeup capable to do so from D3cold. */ |
2275 | (device_may_wakeup(&dev->dev) && | ||
2276 | !pci_pme_capable(dev, PCI_D3cold)) || | ||
2273 | 2277 | ||
2274 | return no_d3cold; | 2278 | /* If it is a bridge it must be allowed to go to D3. */ |
2279 | !pci_power_manageable(dev) || | ||
2280 | |||
2281 | /* Hotplug interrupts cannot be delivered if the link is down. */ | ||
2282 | dev->is_hotplug_bridge) | ||
2283 | |||
2284 | *d3cold_ok = false; | ||
2285 | |||
2286 | return !*d3cold_ok; | ||
2275 | } | 2287 | } |
2276 | 2288 | ||
2277 | /* | 2289 | /* |
2278 | * pci_bridge_d3_update - Update bridge D3 capabilities | 2290 | * pci_bridge_d3_update - Update bridge D3 capabilities |
2279 | * @dev: PCI device which is changed | 2291 | * @dev: PCI device which is changed |
2280 | * @remove: Is the device being removed | ||
2281 | * | 2292 | * |
2282 | * Update upstream bridge PM capabilities accordingly depending on if the | 2293 | * Update upstream bridge PM capabilities accordingly depending on if the |
2283 | * device PM configuration was changed or the device is being removed. The | 2294 | * device PM configuration was changed or the device is being removed. The |
2284 | * change is also propagated upstream. | 2295 | * change is also propagated upstream. |
2285 | */ | 2296 | */ |
2286 | static void pci_bridge_d3_update(struct pci_dev *dev, bool remove) | 2297 | void pci_bridge_d3_update(struct pci_dev *dev) |
2287 | { | 2298 | { |
2299 | bool remove = !device_is_registered(&dev->dev); | ||
2288 | struct pci_dev *bridge; | 2300 | struct pci_dev *bridge; |
2289 | bool d3cold_ok = true; | 2301 | bool d3cold_ok = true; |
2290 | 2302 | ||
@@ -2292,55 +2304,39 @@ static void pci_bridge_d3_update(struct pci_dev *dev, bool remove) | |||
2292 | if (!bridge || !pci_bridge_d3_possible(bridge)) | 2304 | if (!bridge || !pci_bridge_d3_possible(bridge)) |
2293 | return; | 2305 | return; |
2294 | 2306 | ||
2295 | pci_dev_get(bridge); | ||
2296 | /* | 2307 | /* |
2297 | * If the device is removed we do not care about its D3cold | 2308 | * If D3 is currently allowed for the bridge, removing one of its |
2298 | * capabilities. | 2309 | * children won't change that. |
2310 | */ | ||
2311 | if (remove && bridge->bridge_d3) | ||
2312 | return; | ||
2313 | |||
2314 | /* | ||
2315 | * If D3 is currently allowed for the bridge and a child is added or | ||
2316 | * changed, disallowance of D3 can only be caused by that child, so | ||
2317 | * we only need to check that single device, not any of its siblings. | ||
2318 | * | ||
2319 | * If D3 is currently not allowed for the bridge, checking the device | ||
2320 | * first may allow us to skip checking its siblings. | ||
2299 | */ | 2321 | */ |
2300 | if (!remove) | 2322 | if (!remove) |
2301 | pci_dev_check_d3cold(dev, &d3cold_ok); | 2323 | pci_dev_check_d3cold(dev, &d3cold_ok); |
2302 | 2324 | ||
2303 | if (d3cold_ok) { | 2325 | /* |
2304 | /* | 2326 | * If D3 is currently not allowed for the bridge, this may be caused |
2305 | * We need to go through all children to find out if all of | 2327 | * either by the device being changed/removed or any of its siblings, |
2306 | * them can still go to D3cold. | 2328 | * so we need to go through all children to find out if one of them |
2307 | */ | 2329 | * continues to block D3. |
2330 | */ | ||
2331 | if (d3cold_ok && !bridge->bridge_d3) | ||
2308 | pci_walk_bus(bridge->subordinate, pci_dev_check_d3cold, | 2332 | pci_walk_bus(bridge->subordinate, pci_dev_check_d3cold, |
2309 | &d3cold_ok); | 2333 | &d3cold_ok); |
2310 | } | ||
2311 | 2334 | ||
2312 | if (bridge->bridge_d3 != d3cold_ok) { | 2335 | if (bridge->bridge_d3 != d3cold_ok) { |
2313 | bridge->bridge_d3 = d3cold_ok; | 2336 | bridge->bridge_d3 = d3cold_ok; |
2314 | /* Propagate change to upstream bridges */ | 2337 | /* Propagate change to upstream bridges */ |
2315 | pci_bridge_d3_update(bridge, false); | 2338 | pci_bridge_d3_update(bridge); |
2316 | } | 2339 | } |
2317 | |||
2318 | pci_dev_put(bridge); | ||
2319 | } | ||
2320 | |||
2321 | /** | ||
2322 | * pci_bridge_d3_device_changed - Update bridge D3 capabilities on change | ||
2323 | * @dev: PCI device that was changed | ||
2324 | * | ||
2325 | * If a device is added or its PM configuration, such as is it allowed to | ||
2326 | * enter D3cold, is changed this function updates upstream bridge PM | ||
2327 | * capabilities accordingly. | ||
2328 | */ | ||
2329 | void pci_bridge_d3_device_changed(struct pci_dev *dev) | ||
2330 | { | ||
2331 | pci_bridge_d3_update(dev, false); | ||
2332 | } | ||
2333 | |||
2334 | /** | ||
2335 | * pci_bridge_d3_device_removed - Update bridge D3 capabilities on remove | ||
2336 | * @dev: PCI device being removed | ||
2337 | * | ||
2338 | * Function updates upstream bridge PM capabilities based on other devices | ||
2339 | * still left on the bus. | ||
2340 | */ | ||
2341 | void pci_bridge_d3_device_removed(struct pci_dev *dev) | ||
2342 | { | ||
2343 | pci_bridge_d3_update(dev, true); | ||
2344 | } | 2340 | } |
2345 | 2341 | ||
2346 | /** | 2342 | /** |
@@ -2355,7 +2351,7 @@ void pci_d3cold_enable(struct pci_dev *dev) | |||
2355 | { | 2351 | { |
2356 | if (dev->no_d3cold) { | 2352 | if (dev->no_d3cold) { |
2357 | dev->no_d3cold = false; | 2353 | dev->no_d3cold = false; |
2358 | pci_bridge_d3_device_changed(dev); | 2354 | pci_bridge_d3_update(dev); |
2359 | } | 2355 | } |
2360 | } | 2356 | } |
2361 | EXPORT_SYMBOL_GPL(pci_d3cold_enable); | 2357 | EXPORT_SYMBOL_GPL(pci_d3cold_enable); |
@@ -2372,7 +2368,7 @@ void pci_d3cold_disable(struct pci_dev *dev) | |||
2372 | { | 2368 | { |
2373 | if (!dev->no_d3cold) { | 2369 | if (!dev->no_d3cold) { |
2374 | dev->no_d3cold = true; | 2370 | dev->no_d3cold = true; |
2375 | pci_bridge_d3_device_changed(dev); | 2371 | pci_bridge_d3_update(dev); |
2376 | } | 2372 | } |
2377 | } | 2373 | } |
2378 | EXPORT_SYMBOL_GPL(pci_d3cold_disable); | 2374 | EXPORT_SYMBOL_GPL(pci_d3cold_disable); |
@@ -4831,36 +4827,6 @@ int pci_select_bars(struct pci_dev *dev, unsigned long flags) | |||
4831 | } | 4827 | } |
4832 | EXPORT_SYMBOL(pci_select_bars); | 4828 | EXPORT_SYMBOL(pci_select_bars); |
4833 | 4829 | ||
4834 | /** | ||
4835 | * pci_resource_bar - get position of the BAR associated with a resource | ||
4836 | * @dev: the PCI device | ||
4837 | * @resno: the resource number | ||
4838 | * @type: the BAR type to be filled in | ||
4839 | * | ||
4840 | * Returns BAR position in config space, or 0 if the BAR is invalid. | ||
4841 | */ | ||
4842 | int pci_resource_bar(struct pci_dev *dev, int resno, enum pci_bar_type *type) | ||
4843 | { | ||
4844 | int reg; | ||
4845 | |||
4846 | if (resno < PCI_ROM_RESOURCE) { | ||
4847 | *type = pci_bar_unknown; | ||
4848 | return PCI_BASE_ADDRESS_0 + 4 * resno; | ||
4849 | } else if (resno == PCI_ROM_RESOURCE) { | ||
4850 | *type = pci_bar_mem32; | ||
4851 | return dev->rom_base_reg; | ||
4852 | } else if (resno < PCI_BRIDGE_RESOURCES) { | ||
4853 | /* device specific resource */ | ||
4854 | *type = pci_bar_unknown; | ||
4855 | reg = pci_iov_resource_bar(dev, resno); | ||
4856 | if (reg) | ||
4857 | return reg; | ||
4858 | } | ||
4859 | |||
4860 | dev_err(&dev->dev, "BAR %d: invalid resource\n", resno); | ||
4861 | return 0; | ||
4862 | } | ||
4863 | |||
4864 | /* Some architectures require additional programming to enable VGA */ | 4830 | /* Some architectures require additional programming to enable VGA */ |
4865 | static arch_set_vga_state_t arch_set_vga_state; | 4831 | static arch_set_vga_state_t arch_set_vga_state; |
4866 | 4832 | ||
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 451856210e18..cb17db242f30 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h | |||
@@ -1,9 +1,6 @@ | |||
1 | #ifndef DRIVERS_PCI_H | 1 | #ifndef DRIVERS_PCI_H |
2 | #define DRIVERS_PCI_H | 2 | #define DRIVERS_PCI_H |
3 | 3 | ||
4 | #define PCI_CFG_SPACE_SIZE 256 | ||
5 | #define PCI_CFG_SPACE_EXP_SIZE 4096 | ||
6 | |||
7 | #define PCI_FIND_CAP_TTL 48 | 4 | #define PCI_FIND_CAP_TTL 48 |
8 | 5 | ||
9 | extern const unsigned char pcie_link_speed[]; | 6 | extern const unsigned char pcie_link_speed[]; |
@@ -85,8 +82,8 @@ void pci_pm_init(struct pci_dev *dev); | |||
85 | void pci_ea_init(struct pci_dev *dev); | 82 | void pci_ea_init(struct pci_dev *dev); |
86 | void pci_allocate_cap_save_buffers(struct pci_dev *dev); | 83 | void pci_allocate_cap_save_buffers(struct pci_dev *dev); |
87 | void pci_free_cap_save_buffers(struct pci_dev *dev); | 84 | void pci_free_cap_save_buffers(struct pci_dev *dev); |
88 | void pci_bridge_d3_device_changed(struct pci_dev *dev); | 85 | bool pci_bridge_d3_possible(struct pci_dev *dev); |
89 | void pci_bridge_d3_device_removed(struct pci_dev *dev); | 86 | void pci_bridge_d3_update(struct pci_dev *dev); |
90 | 87 | ||
91 | static inline void pci_wakeup_event(struct pci_dev *dev) | 88 | static inline void pci_wakeup_event(struct pci_dev *dev) |
92 | { | 89 | { |
@@ -245,7 +242,6 @@ bool pci_bus_read_dev_vendor_id(struct pci_bus *bus, int devfn, u32 *pl, | |||
245 | int pci_setup_device(struct pci_dev *dev); | 242 | int pci_setup_device(struct pci_dev *dev); |
246 | int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, | 243 | int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, |
247 | struct resource *res, unsigned int reg); | 244 | struct resource *res, unsigned int reg); |
248 | int pci_resource_bar(struct pci_dev *dev, int resno, enum pci_bar_type *type); | ||
249 | void pci_configure_ari(struct pci_dev *dev); | 245 | void pci_configure_ari(struct pci_dev *dev); |
250 | void __pci_bus_size_bridges(struct pci_bus *bus, | 246 | void __pci_bus_size_bridges(struct pci_bus *bus, |
251 | struct list_head *realloc_head); | 247 | struct list_head *realloc_head); |
@@ -289,7 +285,7 @@ static inline void pci_restore_ats_state(struct pci_dev *dev) | |||
289 | #ifdef CONFIG_PCI_IOV | 285 | #ifdef CONFIG_PCI_IOV |
290 | int pci_iov_init(struct pci_dev *dev); | 286 | int pci_iov_init(struct pci_dev *dev); |
291 | void pci_iov_release(struct pci_dev *dev); | 287 | void pci_iov_release(struct pci_dev *dev); |
292 | int pci_iov_resource_bar(struct pci_dev *dev, int resno); | 288 | void pci_iov_update_resource(struct pci_dev *dev, int resno); |
293 | resource_size_t pci_sriov_resource_alignment(struct pci_dev *dev, int resno); | 289 | resource_size_t pci_sriov_resource_alignment(struct pci_dev *dev, int resno); |
294 | void pci_restore_iov_state(struct pci_dev *dev); | 290 | void pci_restore_iov_state(struct pci_dev *dev); |
295 | int pci_iov_bus_range(struct pci_bus *bus); | 291 | int pci_iov_bus_range(struct pci_bus *bus); |
@@ -303,10 +299,6 @@ static inline void pci_iov_release(struct pci_dev *dev) | |||
303 | 299 | ||
304 | { | 300 | { |
305 | } | 301 | } |
306 | static inline int pci_iov_resource_bar(struct pci_dev *dev, int resno) | ||
307 | { | ||
308 | return 0; | ||
309 | } | ||
310 | static inline void pci_restore_iov_state(struct pci_dev *dev) | 302 | static inline void pci_restore_iov_state(struct pci_dev *dev) |
311 | { | 303 | { |
312 | } | 304 | } |
@@ -356,4 +348,9 @@ static inline int pci_dev_specific_reset(struct pci_dev *dev, int probe) | |||
356 | } | 348 | } |
357 | #endif | 349 | #endif |
358 | 350 | ||
351 | #if defined(CONFIG_PCI_QUIRKS) && defined(CONFIG_ARM64) | ||
352 | int acpi_get_rc_resources(struct device *dev, const char *hid, u16 segment, | ||
353 | struct resource *res); | ||
354 | #endif | ||
355 | |||
359 | #endif /* DRIVERS_PCI_H */ | 356 | #endif /* DRIVERS_PCI_H */ |
diff --git a/drivers/pci/pcie/aer/aerdrv.c b/drivers/pci/pcie/aer/aerdrv.c index 139150b2bdfd..dea186a9d6b6 100644 --- a/drivers/pci/pcie/aer/aerdrv.c +++ b/drivers/pci/pcie/aer/aerdrv.c | |||
@@ -30,13 +30,6 @@ | |||
30 | #include "aerdrv.h" | 30 | #include "aerdrv.h" |
31 | #include "../../pci.h" | 31 | #include "../../pci.h" |
32 | 32 | ||
33 | /* | ||
34 | * Version Information | ||
35 | */ | ||
36 | #define DRIVER_VERSION "v1.0" | ||
37 | #define DRIVER_AUTHOR "tom.l.nguyen@intel.com" | ||
38 | #define DRIVER_DESC "Root Port Advanced Error Reporting Driver" | ||
39 | |||
40 | static int aer_probe(struct pcie_device *dev); | 33 | static int aer_probe(struct pcie_device *dev); |
41 | static void aer_remove(struct pcie_device *dev); | 34 | static void aer_remove(struct pcie_device *dev); |
42 | static pci_ers_result_t aer_error_detected(struct pci_dev *dev, | 35 | static pci_ers_result_t aer_error_detected(struct pci_dev *dev, |
@@ -297,12 +290,12 @@ static int aer_probe(struct pcie_device *dev) | |||
297 | { | 290 | { |
298 | int status; | 291 | int status; |
299 | struct aer_rpc *rpc; | 292 | struct aer_rpc *rpc; |
300 | struct device *device = &dev->device; | 293 | struct device *device = &dev->port->dev; |
301 | 294 | ||
302 | /* Alloc rpc data structure */ | 295 | /* Alloc rpc data structure */ |
303 | rpc = aer_alloc_rpc(dev); | 296 | rpc = aer_alloc_rpc(dev); |
304 | if (!rpc) { | 297 | if (!rpc) { |
305 | dev_printk(KERN_DEBUG, device, "alloc rpc failed\n"); | 298 | dev_printk(KERN_DEBUG, device, "alloc AER rpc failed\n"); |
306 | aer_remove(dev); | 299 | aer_remove(dev); |
307 | return -ENOMEM; | 300 | return -ENOMEM; |
308 | } | 301 | } |
@@ -310,7 +303,8 @@ static int aer_probe(struct pcie_device *dev) | |||
310 | /* Request IRQ ISR */ | 303 | /* Request IRQ ISR */ |
311 | status = request_irq(dev->irq, aer_irq, IRQF_SHARED, "aerdrv", dev); | 304 | status = request_irq(dev->irq, aer_irq, IRQF_SHARED, "aerdrv", dev); |
312 | if (status) { | 305 | if (status) { |
313 | dev_printk(KERN_DEBUG, device, "request IRQ failed\n"); | 306 | dev_printk(KERN_DEBUG, device, "request AER IRQ %d failed\n", |
307 | dev->irq); | ||
314 | aer_remove(dev); | 308 | aer_remove(dev); |
315 | return status; | 309 | return status; |
316 | } | 310 | } |
@@ -318,8 +312,8 @@ static int aer_probe(struct pcie_device *dev) | |||
318 | rpc->isr = 1; | 312 | rpc->isr = 1; |
319 | 313 | ||
320 | aer_enable_rootport(rpc); | 314 | aer_enable_rootport(rpc); |
321 | 315 | dev_info(device, "AER enabled with IRQ %d\n", dev->irq); | |
322 | return status; | 316 | return 0; |
323 | } | 317 | } |
324 | 318 | ||
325 | /** | 319 | /** |
diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c index 0ec649d961d7..17ac1dce3286 100644 --- a/drivers/pci/pcie/aspm.c +++ b/drivers/pci/pcie/aspm.c | |||
@@ -351,12 +351,26 @@ static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist) | |||
351 | return; | 351 | return; |
352 | } | 352 | } |
353 | 353 | ||
354 | /* Get upstream/downstream components' register state */ | ||
355 | pcie_get_aspm_reg(parent, &upreg); | ||
356 | child = list_entry(linkbus->devices.next, struct pci_dev, bus_list); | ||
357 | pcie_get_aspm_reg(child, &dwreg); | ||
358 | |||
359 | /* | ||
360 | * If ASPM not supported, don't mess with the clocks and link, | ||
361 | * bail out now. | ||
362 | */ | ||
363 | if (!(upreg.support & dwreg.support)) | ||
364 | return; | ||
365 | |||
354 | /* Configure common clock before checking latencies */ | 366 | /* Configure common clock before checking latencies */ |
355 | pcie_aspm_configure_common_clock(link); | 367 | pcie_aspm_configure_common_clock(link); |
356 | 368 | ||
357 | /* Get upstream/downstream components' register state */ | 369 | /* |
370 | * Re-read upstream/downstream components' register state | ||
371 | * after clock configuration | ||
372 | */ | ||
358 | pcie_get_aspm_reg(parent, &upreg); | 373 | pcie_get_aspm_reg(parent, &upreg); |
359 | child = list_entry(linkbus->devices.next, struct pci_dev, bus_list); | ||
360 | pcie_get_aspm_reg(child, &dwreg); | 374 | pcie_get_aspm_reg(child, &dwreg); |
361 | 375 | ||
362 | /* | 376 | /* |
@@ -886,8 +900,8 @@ static ssize_t clk_ctl_store(struct device *dev, | |||
886 | return n; | 900 | return n; |
887 | } | 901 | } |
888 | 902 | ||
889 | static DEVICE_ATTR(link_state, 0644, link_state_show, link_state_store); | 903 | static DEVICE_ATTR_RW(link_state); |
890 | static DEVICE_ATTR(clk_ctl, 0644, clk_ctl_show, clk_ctl_store); | 904 | static DEVICE_ATTR_RW(clk_ctl); |
891 | 905 | ||
892 | static char power_group[] = "power"; | 906 | static char power_group[] = "power"; |
893 | void pcie_aspm_create_sysfs_dev_files(struct pci_dev *pdev) | 907 | void pcie_aspm_create_sysfs_dev_files(struct pci_dev *pdev) |
diff --git a/drivers/pci/pcie/pme.c b/drivers/pci/pcie/pme.c index 884bad5320f8..717529331dac 100644 --- a/drivers/pci/pcie/pme.c +++ b/drivers/pci/pcie/pme.c | |||
@@ -300,8 +300,6 @@ static irqreturn_t pcie_pme_irq(int irq, void *context) | |||
300 | */ | 300 | */ |
301 | static int pcie_pme_set_native(struct pci_dev *dev, void *ign) | 301 | static int pcie_pme_set_native(struct pci_dev *dev, void *ign) |
302 | { | 302 | { |
303 | dev_info(&dev->dev, "Signaling PME through PCIe PME interrupt\n"); | ||
304 | |||
305 | device_set_run_wake(&dev->dev, true); | 303 | device_set_run_wake(&dev->dev, true); |
306 | dev->pme_interrupt = true; | 304 | dev->pme_interrupt = true; |
307 | return 0; | 305 | return 0; |
@@ -319,23 +317,8 @@ static int pcie_pme_set_native(struct pci_dev *dev, void *ign) | |||
319 | static void pcie_pme_mark_devices(struct pci_dev *port) | 317 | static void pcie_pme_mark_devices(struct pci_dev *port) |
320 | { | 318 | { |
321 | pcie_pme_set_native(port, NULL); | 319 | pcie_pme_set_native(port, NULL); |
322 | if (port->subordinate) { | 320 | if (port->subordinate) |
323 | pci_walk_bus(port->subordinate, pcie_pme_set_native, NULL); | 321 | pci_walk_bus(port->subordinate, pcie_pme_set_native, NULL); |
324 | } else { | ||
325 | struct pci_bus *bus = port->bus; | ||
326 | struct pci_dev *dev; | ||
327 | |||
328 | /* Check if this is a root port event collector. */ | ||
329 | if (pci_pcie_type(port) != PCI_EXP_TYPE_RC_EC || !bus) | ||
330 | return; | ||
331 | |||
332 | down_read(&pci_bus_sem); | ||
333 | list_for_each_entry(dev, &bus->devices, bus_list) | ||
334 | if (pci_is_pcie(dev) | ||
335 | && pci_pcie_type(dev) == PCI_EXP_TYPE_RC_END) | ||
336 | pcie_pme_set_native(dev, NULL); | ||
337 | up_read(&pci_bus_sem); | ||
338 | } | ||
339 | } | 322 | } |
340 | 323 | ||
341 | /** | 324 | /** |
@@ -364,12 +347,14 @@ static int pcie_pme_probe(struct pcie_device *srv) | |||
364 | ret = request_irq(srv->irq, pcie_pme_irq, IRQF_SHARED, "PCIe PME", srv); | 347 | ret = request_irq(srv->irq, pcie_pme_irq, IRQF_SHARED, "PCIe PME", srv); |
365 | if (ret) { | 348 | if (ret) { |
366 | kfree(data); | 349 | kfree(data); |
367 | } else { | 350 | return ret; |
368 | pcie_pme_mark_devices(port); | ||
369 | pcie_pme_interrupt_enable(port, true); | ||
370 | } | 351 | } |
371 | 352 | ||
372 | return ret; | 353 | dev_info(&port->dev, "Signaling PME with IRQ %d\n", srv->irq); |
354 | |||
355 | pcie_pme_mark_devices(port); | ||
356 | pcie_pme_interrupt_enable(port, true); | ||
357 | return 0; | ||
373 | } | 358 | } |
374 | 359 | ||
375 | static bool pcie_pme_check_wakeup(struct pci_bus *bus) | 360 | static bool pcie_pme_check_wakeup(struct pci_bus *bus) |
diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c index e9270b4026f3..9698289f105c 100644 --- a/drivers/pci/pcie/portdrv_core.c +++ b/drivers/pci/pcie/portdrv_core.c | |||
@@ -499,7 +499,6 @@ static int pcie_port_probe_service(struct device *dev) | |||
499 | if (status) | 499 | if (status) |
500 | return status; | 500 | return status; |
501 | 501 | ||
502 | dev_printk(KERN_DEBUG, dev, "service driver %s loaded\n", driver->name); | ||
503 | get_device(dev); | 502 | get_device(dev); |
504 | return 0; | 503 | return 0; |
505 | } | 504 | } |
@@ -524,8 +523,6 @@ static int pcie_port_remove_service(struct device *dev) | |||
524 | pciedev = to_pcie_device(dev); | 523 | pciedev = to_pcie_device(dev); |
525 | driver = to_service_driver(dev->driver); | 524 | driver = to_service_driver(dev->driver); |
526 | if (driver && driver->remove) { | 525 | if (driver && driver->remove) { |
527 | dev_printk(KERN_DEBUG, dev, "unloading service driver %s\n", | ||
528 | driver->name); | ||
529 | driver->remove(pciedev); | 526 | driver->remove(pciedev); |
530 | put_device(dev); | 527 | put_device(dev); |
531 | } | 528 | } |
diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c index 79327cc14e7d..8aa3f14bc87d 100644 --- a/drivers/pci/pcie/portdrv_pci.c +++ b/drivers/pci/pcie/portdrv_pci.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/dmi.h> | 19 | #include <linux/dmi.h> |
20 | #include <linux/pci-aspm.h> | 20 | #include <linux/pci-aspm.h> |
21 | 21 | ||
22 | #include "../pci.h" | ||
22 | #include "portdrv.h" | 23 | #include "portdrv.h" |
23 | #include "aer/aerdrv.h" | 24 | #include "aer/aerdrv.h" |
24 | 25 | ||
@@ -149,15 +150,7 @@ static int pcie_portdrv_probe(struct pci_dev *dev, | |||
149 | 150 | ||
150 | pci_save_state(dev); | 151 | pci_save_state(dev); |
151 | 152 | ||
152 | /* | 153 | if (pci_bridge_d3_possible(dev)) { |
153 | * Prevent runtime PM if the port is advertising support for PCIe | ||
154 | * hotplug. Otherwise the BIOS hotplug SMI code might not be able | ||
155 | * to enumerate devices behind this port properly (the port is | ||
156 | * powered down preventing all config space accesses to the | ||
157 | * subordinate devices). We can't be sure for native PCIe hotplug | ||
158 | * either so prevent that as well. | ||
159 | */ | ||
160 | if (!dev->is_hotplug_bridge) { | ||
161 | /* | 154 | /* |
162 | * Keep the port resumed 100ms to make sure things like | 155 | * Keep the port resumed 100ms to make sure things like |
163 | * config space accesses from userspace (lspci) will not | 156 | * config space accesses from userspace (lspci) will not |
@@ -175,7 +168,7 @@ static int pcie_portdrv_probe(struct pci_dev *dev, | |||
175 | 168 | ||
176 | static void pcie_portdrv_remove(struct pci_dev *dev) | 169 | static void pcie_portdrv_remove(struct pci_dev *dev) |
177 | { | 170 | { |
178 | if (!dev->is_hotplug_bridge) { | 171 | if (pci_bridge_d3_possible(dev)) { |
179 | pm_runtime_forbid(&dev->dev); | 172 | pm_runtime_forbid(&dev->dev); |
180 | pm_runtime_get_noresume(&dev->dev); | 173 | pm_runtime_get_noresume(&dev->dev); |
181 | pm_runtime_dont_use_autosuspend(&dev->dev); | 174 | pm_runtime_dont_use_autosuspend(&dev->dev); |
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index ab002671fa60..3f64b0d78911 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c | |||
@@ -227,7 +227,8 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, | |||
227 | mask64 = (u32)PCI_BASE_ADDRESS_MEM_MASK; | 227 | mask64 = (u32)PCI_BASE_ADDRESS_MEM_MASK; |
228 | } | 228 | } |
229 | } else { | 229 | } else { |
230 | res->flags |= (l & IORESOURCE_ROM_ENABLE); | 230 | if (l & PCI_ROM_ADDRESS_ENABLE) |
231 | res->flags |= IORESOURCE_ROM_ENABLE; | ||
231 | l64 = l & PCI_ROM_ADDRESS_MASK; | 232 | l64 = l & PCI_ROM_ADDRESS_MASK; |
232 | sz64 = sz & PCI_ROM_ADDRESS_MASK; | 233 | sz64 = sz & PCI_ROM_ADDRESS_MASK; |
233 | mask64 = (u32)PCI_ROM_ADDRESS_MASK; | 234 | mask64 = (u32)PCI_ROM_ADDRESS_MASK; |
@@ -521,18 +522,19 @@ static void pci_release_host_bridge_dev(struct device *dev) | |||
521 | kfree(bridge); | 522 | kfree(bridge); |
522 | } | 523 | } |
523 | 524 | ||
524 | static struct pci_host_bridge *pci_alloc_host_bridge(struct pci_bus *b) | 525 | struct pci_host_bridge *pci_alloc_host_bridge(size_t priv) |
525 | { | 526 | { |
526 | struct pci_host_bridge *bridge; | 527 | struct pci_host_bridge *bridge; |
527 | 528 | ||
528 | bridge = kzalloc(sizeof(*bridge), GFP_KERNEL); | 529 | bridge = kzalloc(sizeof(*bridge) + priv, GFP_KERNEL); |
529 | if (!bridge) | 530 | if (!bridge) |
530 | return NULL; | 531 | return NULL; |
531 | 532 | ||
532 | INIT_LIST_HEAD(&bridge->windows); | 533 | INIT_LIST_HEAD(&bridge->windows); |
533 | bridge->bus = b; | 534 | |
534 | return bridge; | 535 | return bridge; |
535 | } | 536 | } |
537 | EXPORT_SYMBOL(pci_alloc_host_bridge); | ||
536 | 538 | ||
537 | static const unsigned char pcix_bus_speed[] = { | 539 | static const unsigned char pcix_bus_speed[] = { |
538 | PCI_SPEED_UNKNOWN, /* 0 */ | 540 | PCI_SPEED_UNKNOWN, /* 0 */ |
@@ -717,6 +719,123 @@ static void pci_set_bus_msi_domain(struct pci_bus *bus) | |||
717 | dev_set_msi_domain(&bus->dev, d); | 719 | dev_set_msi_domain(&bus->dev, d); |
718 | } | 720 | } |
719 | 721 | ||
722 | int pci_register_host_bridge(struct pci_host_bridge *bridge) | ||
723 | { | ||
724 | struct device *parent = bridge->dev.parent; | ||
725 | struct resource_entry *window, *n; | ||
726 | struct pci_bus *bus, *b; | ||
727 | resource_size_t offset; | ||
728 | LIST_HEAD(resources); | ||
729 | struct resource *res; | ||
730 | char addr[64], *fmt; | ||
731 | const char *name; | ||
732 | int err; | ||
733 | |||
734 | bus = pci_alloc_bus(NULL); | ||
735 | if (!bus) | ||
736 | return -ENOMEM; | ||
737 | |||
738 | bridge->bus = bus; | ||
739 | |||
740 | /* temporarily move resources off the list */ | ||
741 | list_splice_init(&bridge->windows, &resources); | ||
742 | bus->sysdata = bridge->sysdata; | ||
743 | bus->msi = bridge->msi; | ||
744 | bus->ops = bridge->ops; | ||
745 | bus->number = bus->busn_res.start = bridge->busnr; | ||
746 | #ifdef CONFIG_PCI_DOMAINS_GENERIC | ||
747 | bus->domain_nr = pci_bus_find_domain_nr(bus, parent); | ||
748 | #endif | ||
749 | |||
750 | b = pci_find_bus(pci_domain_nr(bus), bridge->busnr); | ||
751 | if (b) { | ||
752 | /* If we already got to this bus through a different bridge, ignore it */ | ||
753 | dev_dbg(&b->dev, "bus already known\n"); | ||
754 | err = -EEXIST; | ||
755 | goto free; | ||
756 | } | ||
757 | |||
758 | dev_set_name(&bridge->dev, "pci%04x:%02x", pci_domain_nr(bus), | ||
759 | bridge->busnr); | ||
760 | |||
761 | err = pcibios_root_bridge_prepare(bridge); | ||
762 | if (err) | ||
763 | goto free; | ||
764 | |||
765 | err = device_register(&bridge->dev); | ||
766 | if (err) | ||
767 | put_device(&bridge->dev); | ||
768 | |||
769 | bus->bridge = get_device(&bridge->dev); | ||
770 | device_enable_async_suspend(bus->bridge); | ||
771 | pci_set_bus_of_node(bus); | ||
772 | pci_set_bus_msi_domain(bus); | ||
773 | |||
774 | if (!parent) | ||
775 | set_dev_node(bus->bridge, pcibus_to_node(bus)); | ||
776 | |||
777 | bus->dev.class = &pcibus_class; | ||
778 | bus->dev.parent = bus->bridge; | ||
779 | |||
780 | dev_set_name(&bus->dev, "%04x:%02x", pci_domain_nr(bus), bus->number); | ||
781 | name = dev_name(&bus->dev); | ||
782 | |||
783 | err = device_register(&bus->dev); | ||
784 | if (err) | ||
785 | goto unregister; | ||
786 | |||
787 | pcibios_add_bus(bus); | ||
788 | |||
789 | /* Create legacy_io and legacy_mem files for this bus */ | ||
790 | pci_create_legacy_files(bus); | ||
791 | |||
792 | if (parent) | ||
793 | dev_info(parent, "PCI host bridge to bus %s\n", name); | ||
794 | else | ||
795 | pr_info("PCI host bridge to bus %s\n", name); | ||
796 | |||
797 | /* Add initial resources to the bus */ | ||
798 | resource_list_for_each_entry_safe(window, n, &resources) { | ||
799 | list_move_tail(&window->node, &bridge->windows); | ||
800 | offset = window->offset; | ||
801 | res = window->res; | ||
802 | |||
803 | if (res->flags & IORESOURCE_BUS) | ||
804 | pci_bus_insert_busn_res(bus, bus->number, res->end); | ||
805 | else | ||
806 | pci_bus_add_resource(bus, res, 0); | ||
807 | |||
808 | if (offset) { | ||
809 | if (resource_type(res) == IORESOURCE_IO) | ||
810 | fmt = " (bus address [%#06llx-%#06llx])"; | ||
811 | else | ||
812 | fmt = " (bus address [%#010llx-%#010llx])"; | ||
813 | |||
814 | snprintf(addr, sizeof(addr), fmt, | ||
815 | (unsigned long long)(res->start - offset), | ||
816 | (unsigned long long)(res->end - offset)); | ||
817 | } else | ||
818 | addr[0] = '\0'; | ||
819 | |||
820 | dev_info(&bus->dev, "root bus resource %pR%s\n", res, addr); | ||
821 | } | ||
822 | |||
823 | down_write(&pci_bus_sem); | ||
824 | list_add_tail(&bus->node, &pci_root_buses); | ||
825 | up_write(&pci_bus_sem); | ||
826 | |||
827 | return 0; | ||
828 | |||
829 | unregister: | ||
830 | put_device(&bridge->dev); | ||
831 | device_unregister(&bridge->dev); | ||
832 | |||
833 | free: | ||
834 | kfree(bus); | ||
835 | return err; | ||
836 | } | ||
837 | EXPORT_SYMBOL(pci_register_host_bridge); | ||
838 | |||
720 | static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent, | 839 | static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent, |
721 | struct pci_dev *bridge, int busnr) | 840 | struct pci_dev *bridge, int busnr) |
722 | { | 841 | { |
@@ -2130,113 +2249,43 @@ void __weak pcibios_remove_bus(struct pci_bus *bus) | |||
2130 | { | 2249 | { |
2131 | } | 2250 | } |
2132 | 2251 | ||
2133 | struct pci_bus *pci_create_root_bus(struct device *parent, int bus, | 2252 | static struct pci_bus *pci_create_root_bus_msi(struct device *parent, |
2134 | struct pci_ops *ops, void *sysdata, struct list_head *resources) | 2253 | int bus, struct pci_ops *ops, void *sysdata, |
2254 | struct list_head *resources, struct msi_controller *msi) | ||
2135 | { | 2255 | { |
2136 | int error; | 2256 | int error; |
2137 | struct pci_host_bridge *bridge; | 2257 | struct pci_host_bridge *bridge; |
2138 | struct pci_bus *b, *b2; | ||
2139 | struct resource_entry *window, *n; | ||
2140 | struct resource *res; | ||
2141 | resource_size_t offset; | ||
2142 | char bus_addr[64]; | ||
2143 | char *fmt; | ||
2144 | |||
2145 | b = pci_alloc_bus(NULL); | ||
2146 | if (!b) | ||
2147 | return NULL; | ||
2148 | 2258 | ||
2149 | b->sysdata = sysdata; | 2259 | bridge = pci_alloc_host_bridge(0); |
2150 | b->ops = ops; | ||
2151 | b->number = b->busn_res.start = bus; | ||
2152 | #ifdef CONFIG_PCI_DOMAINS_GENERIC | ||
2153 | b->domain_nr = pci_bus_find_domain_nr(b, parent); | ||
2154 | #endif | ||
2155 | b2 = pci_find_bus(pci_domain_nr(b), bus); | ||
2156 | if (b2) { | ||
2157 | /* If we already got to this bus through a different bridge, ignore it */ | ||
2158 | dev_dbg(&b2->dev, "bus already known\n"); | ||
2159 | goto err_out; | ||
2160 | } | ||
2161 | |||
2162 | bridge = pci_alloc_host_bridge(b); | ||
2163 | if (!bridge) | 2260 | if (!bridge) |
2164 | goto err_out; | 2261 | return NULL; |
2165 | 2262 | ||
2166 | bridge->dev.parent = parent; | 2263 | bridge->dev.parent = parent; |
2167 | bridge->dev.release = pci_release_host_bridge_dev; | 2264 | bridge->dev.release = pci_release_host_bridge_dev; |
2168 | dev_set_name(&bridge->dev, "pci%04x:%02x", pci_domain_nr(b), bus); | ||
2169 | error = pcibios_root_bridge_prepare(bridge); | ||
2170 | if (error) { | ||
2171 | kfree(bridge); | ||
2172 | goto err_out; | ||
2173 | } | ||
2174 | |||
2175 | error = device_register(&bridge->dev); | ||
2176 | if (error) { | ||
2177 | put_device(&bridge->dev); | ||
2178 | goto err_out; | ||
2179 | } | ||
2180 | b->bridge = get_device(&bridge->dev); | ||
2181 | device_enable_async_suspend(b->bridge); | ||
2182 | pci_set_bus_of_node(b); | ||
2183 | pci_set_bus_msi_domain(b); | ||
2184 | 2265 | ||
2185 | if (!parent) | 2266 | list_splice_init(resources, &bridge->windows); |
2186 | set_dev_node(b->bridge, pcibus_to_node(b)); | 2267 | bridge->sysdata = sysdata; |
2187 | 2268 | bridge->busnr = bus; | |
2188 | b->dev.class = &pcibus_class; | 2269 | bridge->ops = ops; |
2189 | b->dev.parent = b->bridge; | 2270 | bridge->msi = msi; |
2190 | dev_set_name(&b->dev, "%04x:%02x", pci_domain_nr(b), bus); | ||
2191 | error = device_register(&b->dev); | ||
2192 | if (error) | ||
2193 | goto class_dev_reg_err; | ||
2194 | 2271 | ||
2195 | pcibios_add_bus(b); | 2272 | error = pci_register_host_bridge(bridge); |
2196 | 2273 | if (error < 0) | |
2197 | /* Create legacy_io and legacy_mem files for this bus */ | 2274 | goto err_out; |
2198 | pci_create_legacy_files(b); | ||
2199 | |||
2200 | if (parent) | ||
2201 | dev_info(parent, "PCI host bridge to bus %s\n", dev_name(&b->dev)); | ||
2202 | else | ||
2203 | printk(KERN_INFO "PCI host bridge to bus %s\n", dev_name(&b->dev)); | ||
2204 | |||
2205 | /* Add initial resources to the bus */ | ||
2206 | resource_list_for_each_entry_safe(window, n, resources) { | ||
2207 | list_move_tail(&window->node, &bridge->windows); | ||
2208 | res = window->res; | ||
2209 | offset = window->offset; | ||
2210 | if (res->flags & IORESOURCE_BUS) | ||
2211 | pci_bus_insert_busn_res(b, bus, res->end); | ||
2212 | else | ||
2213 | pci_bus_add_resource(b, res, 0); | ||
2214 | if (offset) { | ||
2215 | if (resource_type(res) == IORESOURCE_IO) | ||
2216 | fmt = " (bus address [%#06llx-%#06llx])"; | ||
2217 | else | ||
2218 | fmt = " (bus address [%#010llx-%#010llx])"; | ||
2219 | snprintf(bus_addr, sizeof(bus_addr), fmt, | ||
2220 | (unsigned long long) (res->start - offset), | ||
2221 | (unsigned long long) (res->end - offset)); | ||
2222 | } else | ||
2223 | bus_addr[0] = '\0'; | ||
2224 | dev_info(&b->dev, "root bus resource %pR%s\n", res, bus_addr); | ||
2225 | } | ||
2226 | 2275 | ||
2227 | down_write(&pci_bus_sem); | 2276 | return bridge->bus; |
2228 | list_add_tail(&b->node, &pci_root_buses); | ||
2229 | up_write(&pci_bus_sem); | ||
2230 | 2277 | ||
2231 | return b; | ||
2232 | |||
2233 | class_dev_reg_err: | ||
2234 | put_device(&bridge->dev); | ||
2235 | device_unregister(&bridge->dev); | ||
2236 | err_out: | 2278 | err_out: |
2237 | kfree(b); | 2279 | kfree(bridge); |
2238 | return NULL; | 2280 | return NULL; |
2239 | } | 2281 | } |
2282 | |||
2283 | struct pci_bus *pci_create_root_bus(struct device *parent, int bus, | ||
2284 | struct pci_ops *ops, void *sysdata, struct list_head *resources) | ||
2285 | { | ||
2286 | return pci_create_root_bus_msi(parent, bus, ops, sysdata, resources, | ||
2287 | NULL); | ||
2288 | } | ||
2240 | EXPORT_SYMBOL_GPL(pci_create_root_bus); | 2289 | EXPORT_SYMBOL_GPL(pci_create_root_bus); |
2241 | 2290 | ||
2242 | int pci_bus_insert_busn_res(struct pci_bus *b, int bus, int bus_max) | 2291 | int pci_bus_insert_busn_res(struct pci_bus *b, int bus, int bus_max) |
@@ -2317,12 +2366,10 @@ struct pci_bus *pci_scan_root_bus_msi(struct device *parent, int bus, | |||
2317 | break; | 2366 | break; |
2318 | } | 2367 | } |
2319 | 2368 | ||
2320 | b = pci_create_root_bus(parent, bus, ops, sysdata, resources); | 2369 | b = pci_create_root_bus_msi(parent, bus, ops, sysdata, resources, msi); |
2321 | if (!b) | 2370 | if (!b) |
2322 | return NULL; | 2371 | return NULL; |
2323 | 2372 | ||
2324 | b->msi = msi; | ||
2325 | |||
2326 | if (!found) { | 2373 | if (!found) { |
2327 | dev_info(&b->dev, | 2374 | dev_info(&b->dev, |
2328 | "No busn resource found for root bus, will use [bus %02x-ff]\n", | 2375 | "No busn resource found for root bus, will use [bus %02x-ff]\n", |
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index c232729f5b1b..9236e40ac055 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
@@ -2156,7 +2156,7 @@ static void quirk_blacklist_vpd(struct pci_dev *dev) | |||
2156 | { | 2156 | { |
2157 | if (dev->vpd) { | 2157 | if (dev->vpd) { |
2158 | dev->vpd->len = 0; | 2158 | dev->vpd->len = 0; |
2159 | dev_warn(&dev->dev, FW_BUG "VPD access disabled\n"); | 2159 | dev_warn(&dev->dev, FW_BUG "disabling VPD access (can't determine size of non-standard VPD format)\n"); |
2160 | } | 2160 | } |
2161 | } | 2161 | } |
2162 | 2162 | ||
@@ -3137,8 +3137,9 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x22b5, quirk_remove_d3_delay); | |||
3137 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x22b7, quirk_remove_d3_delay); | 3137 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x22b7, quirk_remove_d3_delay); |
3138 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x2298, quirk_remove_d3_delay); | 3138 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x2298, quirk_remove_d3_delay); |
3139 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x229c, quirk_remove_d3_delay); | 3139 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x229c, quirk_remove_d3_delay); |
3140 | |||
3140 | /* | 3141 | /* |
3141 | * Some devices may pass our check in pci_intx_mask_supported if | 3142 | * Some devices may pass our check in pci_intx_mask_supported() if |
3142 | * PCI_COMMAND_INTX_DISABLE works though they actually do not properly | 3143 | * PCI_COMMAND_INTX_DISABLE works though they actually do not properly |
3143 | * support this feature. | 3144 | * support this feature. |
3144 | */ | 3145 | */ |
@@ -3146,53 +3147,139 @@ static void quirk_broken_intx_masking(struct pci_dev *dev) | |||
3146 | { | 3147 | { |
3147 | dev->broken_intx_masking = 1; | 3148 | dev->broken_intx_masking = 1; |
3148 | } | 3149 | } |
3149 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_CHELSIO, 0x0030, | 3150 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x0030, |
3150 | quirk_broken_intx_masking); | 3151 | quirk_broken_intx_masking); |
3151 | DECLARE_PCI_FIXUP_HEADER(0x1814, 0x0601, /* Ralink RT2800 802.11n PCI */ | 3152 | DECLARE_PCI_FIXUP_FINAL(0x1814, 0x0601, /* Ralink RT2800 802.11n PCI */ |
3152 | quirk_broken_intx_masking); | 3153 | quirk_broken_intx_masking); |
3154 | |||
3153 | /* | 3155 | /* |
3154 | * Realtek RTL8169 PCI Gigabit Ethernet Controller (rev 10) | 3156 | * Realtek RTL8169 PCI Gigabit Ethernet Controller (rev 10) |
3155 | * Subsystem: Realtek RTL8169/8110 Family PCI Gigabit Ethernet NIC | 3157 | * Subsystem: Realtek RTL8169/8110 Family PCI Gigabit Ethernet NIC |
3156 | * | 3158 | * |
3157 | * RTL8110SC - Fails under PCI device assignment using DisINTx masking. | 3159 | * RTL8110SC - Fails under PCI device assignment using DisINTx masking. |
3158 | */ | 3160 | */ |
3159 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_REALTEK, 0x8169, | 3161 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_REALTEK, 0x8169, |
3160 | quirk_broken_intx_masking); | 3162 | quirk_broken_intx_masking); |
3161 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MELLANOX, PCI_ANY_ID, | ||
3162 | quirk_broken_intx_masking); | ||
3163 | 3163 | ||
3164 | /* | 3164 | /* |
3165 | * Intel i40e (XL710/X710) 10/20/40GbE NICs all have broken INTx masking, | 3165 | * Intel i40e (XL710/X710) 10/20/40GbE NICs all have broken INTx masking, |
3166 | * DisINTx can be set but the interrupt status bit is non-functional. | 3166 | * DisINTx can be set but the interrupt status bit is non-functional. |
3167 | */ | 3167 | */ |
3168 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1572, | 3168 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1572, |
3169 | quirk_broken_intx_masking); | 3169 | quirk_broken_intx_masking); |
3170 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1574, | 3170 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1574, |
3171 | quirk_broken_intx_masking); | 3171 | quirk_broken_intx_masking); |
3172 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1580, | 3172 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1580, |
3173 | quirk_broken_intx_masking); | 3173 | quirk_broken_intx_masking); |
3174 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1581, | 3174 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1581, |
3175 | quirk_broken_intx_masking); | 3175 | quirk_broken_intx_masking); |
3176 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1583, | 3176 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1583, |
3177 | quirk_broken_intx_masking); | 3177 | quirk_broken_intx_masking); |
3178 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1584, | 3178 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1584, |
3179 | quirk_broken_intx_masking); | 3179 | quirk_broken_intx_masking); |
3180 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1585, | 3180 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1585, |
3181 | quirk_broken_intx_masking); | 3181 | quirk_broken_intx_masking); |
3182 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1586, | 3182 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1586, |
3183 | quirk_broken_intx_masking); | 3183 | quirk_broken_intx_masking); |
3184 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1587, | 3184 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1587, |
3185 | quirk_broken_intx_masking); | 3185 | quirk_broken_intx_masking); |
3186 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1588, | 3186 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1588, |
3187 | quirk_broken_intx_masking); | 3187 | quirk_broken_intx_masking); |
3188 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1589, | 3188 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1589, |
3189 | quirk_broken_intx_masking); | 3189 | quirk_broken_intx_masking); |
3190 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x37d0, | 3190 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x37d0, |
3191 | quirk_broken_intx_masking); | 3191 | quirk_broken_intx_masking); |
3192 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x37d1, | 3192 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x37d1, |
3193 | quirk_broken_intx_masking); | 3193 | quirk_broken_intx_masking); |
3194 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x37d2, | 3194 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x37d2, |
3195 | quirk_broken_intx_masking); | 3195 | quirk_broken_intx_masking); |
3196 | |||
3197 | static u16 mellanox_broken_intx_devs[] = { | ||
3198 | PCI_DEVICE_ID_MELLANOX_HERMON_SDR, | ||
3199 | PCI_DEVICE_ID_MELLANOX_HERMON_DDR, | ||
3200 | PCI_DEVICE_ID_MELLANOX_HERMON_QDR, | ||
3201 | PCI_DEVICE_ID_MELLANOX_HERMON_DDR_GEN2, | ||
3202 | PCI_DEVICE_ID_MELLANOX_HERMON_QDR_GEN2, | ||
3203 | PCI_DEVICE_ID_MELLANOX_HERMON_EN, | ||
3204 | PCI_DEVICE_ID_MELLANOX_HERMON_EN_GEN2, | ||
3205 | PCI_DEVICE_ID_MELLANOX_CONNECTX_EN, | ||
3206 | PCI_DEVICE_ID_MELLANOX_CONNECTX_EN_T_GEN2, | ||
3207 | PCI_DEVICE_ID_MELLANOX_CONNECTX_EN_GEN2, | ||
3208 | PCI_DEVICE_ID_MELLANOX_CONNECTX_EN_5_GEN2, | ||
3209 | PCI_DEVICE_ID_MELLANOX_CONNECTX2, | ||
3210 | PCI_DEVICE_ID_MELLANOX_CONNECTX3, | ||
3211 | PCI_DEVICE_ID_MELLANOX_CONNECTX3_PRO, | ||
3212 | }; | ||
3213 | |||
3214 | #define CONNECTX_4_CURR_MAX_MINOR 99 | ||
3215 | #define CONNECTX_4_INTX_SUPPORT_MINOR 14 | ||
3216 | |||
3217 | /* | ||
3218 | * Check ConnectX-4/LX FW version to see if it supports legacy interrupts. | ||
3219 | * If so, don't mark it as broken. | ||
3220 | * FW minor > 99 means older FW version format and no INTx masking support. | ||
3221 | * FW minor < 14 means new FW version format and no INTx masking support. | ||
3222 | */ | ||
3223 | static void mellanox_check_broken_intx_masking(struct pci_dev *pdev) | ||
3224 | { | ||
3225 | __be32 __iomem *fw_ver; | ||
3226 | u16 fw_major; | ||
3227 | u16 fw_minor; | ||
3228 | u16 fw_subminor; | ||
3229 | u32 fw_maj_min; | ||
3230 | u32 fw_sub_min; | ||
3231 | int i; | ||
3232 | |||
3233 | for (i = 0; i < ARRAY_SIZE(mellanox_broken_intx_devs); i++) { | ||
3234 | if (pdev->device == mellanox_broken_intx_devs[i]) { | ||
3235 | pdev->broken_intx_masking = 1; | ||
3236 | return; | ||
3237 | } | ||
3238 | } | ||
3239 | |||
3240 | /* Getting here means Connect-IB cards and up. Connect-IB has no INTx | ||
3241 | * support so shouldn't be checked further | ||
3242 | */ | ||
3243 | if (pdev->device == PCI_DEVICE_ID_MELLANOX_CONNECTIB) | ||
3244 | return; | ||
3245 | |||
3246 | if (pdev->device != PCI_DEVICE_ID_MELLANOX_CONNECTX4 && | ||
3247 | pdev->device != PCI_DEVICE_ID_MELLANOX_CONNECTX4_LX) | ||
3248 | return; | ||
3249 | |||
3250 | /* For ConnectX-4 and ConnectX-4LX, need to check FW support */ | ||
3251 | if (pci_enable_device_mem(pdev)) { | ||
3252 | dev_warn(&pdev->dev, "Can't enable device memory\n"); | ||
3253 | return; | ||
3254 | } | ||
3255 | |||
3256 | fw_ver = ioremap(pci_resource_start(pdev, 0), 4); | ||
3257 | if (!fw_ver) { | ||
3258 | dev_warn(&pdev->dev, "Can't map ConnectX-4 initialization segment\n"); | ||
3259 | goto out; | ||
3260 | } | ||
3261 | |||
3262 | /* Reading from resource space should be 32b aligned */ | ||
3263 | fw_maj_min = ioread32be(fw_ver); | ||
3264 | fw_sub_min = ioread32be(fw_ver + 1); | ||
3265 | fw_major = fw_maj_min & 0xffff; | ||
3266 | fw_minor = fw_maj_min >> 16; | ||
3267 | fw_subminor = fw_sub_min & 0xffff; | ||
3268 | if (fw_minor > CONNECTX_4_CURR_MAX_MINOR || | ||
3269 | fw_minor < CONNECTX_4_INTX_SUPPORT_MINOR) { | ||
3270 | dev_warn(&pdev->dev, "ConnectX-4: FW %u.%u.%u doesn't support INTx masking, disabling. Please upgrade FW to %d.14.1100 and up for INTx support\n", | ||
3271 | fw_major, fw_minor, fw_subminor, pdev->device == | ||
3272 | PCI_DEVICE_ID_MELLANOX_CONNECTX4 ? 12 : 14); | ||
3273 | pdev->broken_intx_masking = 1; | ||
3274 | } | ||
3275 | |||
3276 | iounmap(fw_ver); | ||
3277 | |||
3278 | out: | ||
3279 | pci_disable_device(pdev); | ||
3280 | } | ||
3281 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_MELLANOX, PCI_ANY_ID, | ||
3282 | mellanox_check_broken_intx_masking); | ||
3196 | 3283 | ||
3197 | static void quirk_no_bus_reset(struct pci_dev *dev) | 3284 | static void quirk_no_bus_reset(struct pci_dev *dev) |
3198 | { | 3285 | { |
@@ -3255,6 +3342,25 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CACTUS_RIDGE_4C | |||
3255 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PORT_RIDGE, | 3342 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PORT_RIDGE, |
3256 | quirk_thunderbolt_hotplug_msi); | 3343 | quirk_thunderbolt_hotplug_msi); |
3257 | 3344 | ||
3345 | static void quirk_chelsio_extend_vpd(struct pci_dev *dev) | ||
3346 | { | ||
3347 | pci_set_vpd_size(dev, 8192); | ||
3348 | } | ||
3349 | |||
3350 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x20, quirk_chelsio_extend_vpd); | ||
3351 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x21, quirk_chelsio_extend_vpd); | ||
3352 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x22, quirk_chelsio_extend_vpd); | ||
3353 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x23, quirk_chelsio_extend_vpd); | ||
3354 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x24, quirk_chelsio_extend_vpd); | ||
3355 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x25, quirk_chelsio_extend_vpd); | ||
3356 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x26, quirk_chelsio_extend_vpd); | ||
3357 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x30, quirk_chelsio_extend_vpd); | ||
3358 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x31, quirk_chelsio_extend_vpd); | ||
3359 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x32, quirk_chelsio_extend_vpd); | ||
3360 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x35, quirk_chelsio_extend_vpd); | ||
3361 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x36, quirk_chelsio_extend_vpd); | ||
3362 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x37, quirk_chelsio_extend_vpd); | ||
3363 | |||
3258 | #ifdef CONFIG_ACPI | 3364 | #ifdef CONFIG_ACPI |
3259 | /* | 3365 | /* |
3260 | * Apple: Shutdown Cactus Ridge Thunderbolt controller. | 3366 | * Apple: Shutdown Cactus Ridge Thunderbolt controller. |
diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c index f9357e09e9b3..73a03d382590 100644 --- a/drivers/pci/remove.c +++ b/drivers/pci/remove.c | |||
@@ -40,7 +40,7 @@ static void pci_destroy_dev(struct pci_dev *dev) | |||
40 | list_del(&dev->bus_list); | 40 | list_del(&dev->bus_list); |
41 | up_write(&pci_bus_sem); | 41 | up_write(&pci_bus_sem); |
42 | 42 | ||
43 | pci_bridge_d3_device_removed(dev); | 43 | pci_bridge_d3_update(dev); |
44 | pci_free_resources(dev); | 44 | pci_free_resources(dev); |
45 | put_device(&dev->dev); | 45 | put_device(&dev->dev); |
46 | } | 46 | } |
diff --git a/drivers/pci/rom.c b/drivers/pci/rom.c index 06663d391b39..b6edb187d160 100644 --- a/drivers/pci/rom.c +++ b/drivers/pci/rom.c | |||
@@ -35,6 +35,11 @@ int pci_enable_rom(struct pci_dev *pdev) | |||
35 | if (res->flags & IORESOURCE_ROM_SHADOW) | 35 | if (res->flags & IORESOURCE_ROM_SHADOW) |
36 | return 0; | 36 | return 0; |
37 | 37 | ||
38 | /* | ||
39 | * Ideally pci_update_resource() would update the ROM BAR address, | ||
40 | * and we would only set the enable bit here. But apparently some | ||
41 | * devices have buggy ROM BARs that read as zero when disabled. | ||
42 | */ | ||
38 | pcibios_resource_to_bus(pdev->bus, ®ion, res); | 43 | pcibios_resource_to_bus(pdev->bus, ®ion, res); |
39 | pci_read_config_dword(pdev, pdev->rom_base_reg, &rom_addr); | 44 | pci_read_config_dword(pdev, pdev->rom_base_reg, &rom_addr); |
40 | rom_addr &= ~PCI_ROM_ADDRESS_MASK; | 45 | rom_addr &= ~PCI_ROM_ADDRESS_MASK; |
diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c index 66c4d8f42233..4bc589ee78d0 100644 --- a/drivers/pci/setup-res.c +++ b/drivers/pci/setup-res.c | |||
@@ -25,21 +25,18 @@ | |||
25 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
26 | #include "pci.h" | 26 | #include "pci.h" |
27 | 27 | ||
28 | 28 | static void pci_std_update_resource(struct pci_dev *dev, int resno) | |
29 | void pci_update_resource(struct pci_dev *dev, int resno) | ||
30 | { | 29 | { |
31 | struct pci_bus_region region; | 30 | struct pci_bus_region region; |
32 | bool disable; | 31 | bool disable; |
33 | u16 cmd; | 32 | u16 cmd; |
34 | u32 new, check, mask; | 33 | u32 new, check, mask; |
35 | int reg; | 34 | int reg; |
36 | enum pci_bar_type type; | ||
37 | struct resource *res = dev->resource + resno; | 35 | struct resource *res = dev->resource + resno; |
38 | 36 | ||
39 | if (dev->is_virtfn) { | 37 | /* Per SR-IOV spec 3.4.1.11, VF BARs are RO zero */ |
40 | dev_warn(&dev->dev, "can't update VF BAR%d\n", resno); | 38 | if (dev->is_virtfn) |
41 | return; | 39 | return; |
42 | } | ||
43 | 40 | ||
44 | /* | 41 | /* |
45 | * Ignore resources for unimplemented BARs and unused resource slots | 42 | * Ignore resources for unimplemented BARs and unused resource slots |
@@ -60,21 +57,34 @@ void pci_update_resource(struct pci_dev *dev, int resno) | |||
60 | return; | 57 | return; |
61 | 58 | ||
62 | pcibios_resource_to_bus(dev->bus, ®ion, res); | 59 | pcibios_resource_to_bus(dev->bus, ®ion, res); |
60 | new = region.start; | ||
63 | 61 | ||
64 | new = region.start | (res->flags & PCI_REGION_FLAG_MASK); | 62 | if (res->flags & IORESOURCE_IO) { |
65 | if (res->flags & IORESOURCE_IO) | ||
66 | mask = (u32)PCI_BASE_ADDRESS_IO_MASK; | 63 | mask = (u32)PCI_BASE_ADDRESS_IO_MASK; |
67 | else | 64 | new |= res->flags & ~PCI_BASE_ADDRESS_IO_MASK; |
65 | } else if (resno == PCI_ROM_RESOURCE) { | ||
66 | mask = (u32)PCI_ROM_ADDRESS_MASK; | ||
67 | } else { | ||
68 | mask = (u32)PCI_BASE_ADDRESS_MEM_MASK; | 68 | mask = (u32)PCI_BASE_ADDRESS_MEM_MASK; |
69 | new |= res->flags & ~PCI_BASE_ADDRESS_MEM_MASK; | ||
70 | } | ||
69 | 71 | ||
70 | reg = pci_resource_bar(dev, resno, &type); | 72 | if (resno < PCI_ROM_RESOURCE) { |
71 | if (!reg) | 73 | reg = PCI_BASE_ADDRESS_0 + 4 * resno; |
72 | return; | 74 | } else if (resno == PCI_ROM_RESOURCE) { |
73 | if (type != pci_bar_unknown) { | 75 | |
76 | /* | ||
77 | * Apparently some Matrox devices have ROM BARs that read | ||
78 | * as zero when disabled, so don't update ROM BARs unless | ||
79 | * they're enabled. See https://lkml.org/lkml/2005/8/30/138. | ||
80 | */ | ||
74 | if (!(res->flags & IORESOURCE_ROM_ENABLE)) | 81 | if (!(res->flags & IORESOURCE_ROM_ENABLE)) |
75 | return; | 82 | return; |
83 | |||
84 | reg = dev->rom_base_reg; | ||
76 | new |= PCI_ROM_ADDRESS_ENABLE; | 85 | new |= PCI_ROM_ADDRESS_ENABLE; |
77 | } | 86 | } else |
87 | return; | ||
78 | 88 | ||
79 | /* | 89 | /* |
80 | * We can't update a 64-bit BAR atomically, so when possible, | 90 | * We can't update a 64-bit BAR atomically, so when possible, |
@@ -110,6 +120,16 @@ void pci_update_resource(struct pci_dev *dev, int resno) | |||
110 | pci_write_config_word(dev, PCI_COMMAND, cmd); | 120 | pci_write_config_word(dev, PCI_COMMAND, cmd); |
111 | } | 121 | } |
112 | 122 | ||
123 | void pci_update_resource(struct pci_dev *dev, int resno) | ||
124 | { | ||
125 | if (resno <= PCI_ROM_RESOURCE) | ||
126 | pci_std_update_resource(dev, resno); | ||
127 | #ifdef CONFIG_PCI_IOV | ||
128 | else if (resno >= PCI_IOV_RESOURCES && resno <= PCI_IOV_RESOURCE_END) | ||
129 | pci_iov_update_resource(dev, resno); | ||
130 | #endif | ||
131 | } | ||
132 | |||
113 | int pci_claim_resource(struct pci_dev *dev, int resource) | 133 | int pci_claim_resource(struct pci_dev *dev, int resource) |
114 | { | 134 | { |
115 | struct resource *res = &dev->resource[resource]; | 135 | struct resource *res = &dev->resource[resource]; |
@@ -121,6 +141,14 @@ int pci_claim_resource(struct pci_dev *dev, int resource) | |||
121 | return -EINVAL; | 141 | return -EINVAL; |
122 | } | 142 | } |
123 | 143 | ||
144 | /* | ||
145 | * If we have a shadow copy in RAM, the PCI device doesn't respond | ||
146 | * to the shadow range, so we don't need to claim it, and upstream | ||
147 | * bridges don't need to route the range to the device. | ||
148 | */ | ||
149 | if (res->flags & IORESOURCE_ROM_SHADOW) | ||
150 | return 0; | ||
151 | |||
124 | root = pci_find_parent_resource(dev, res); | 152 | root = pci_find_parent_resource(dev, res); |
125 | if (!root) { | 153 | if (!root) { |
126 | dev_info(&dev->dev, "can't claim BAR %d %pR: no compatible bridge window\n", | 154 | dev_info(&dev->dev, "can't claim BAR %d %pR: no compatible bridge window\n", |
diff --git a/drivers/usb/host/uhci-pci.c b/drivers/usb/host/uhci-pci.c index 940304c33224..02260cfdedb1 100644 --- a/drivers/usb/host/uhci-pci.c +++ b/drivers/usb/host/uhci-pci.c | |||
@@ -129,6 +129,10 @@ static int uhci_pci_init(struct usb_hcd *hcd) | |||
129 | if (to_pci_dev(uhci_dev(uhci))->vendor == PCI_VENDOR_ID_HP) | 129 | if (to_pci_dev(uhci_dev(uhci))->vendor == PCI_VENDOR_ID_HP) |
130 | uhci->wait_for_hp = 1; | 130 | uhci->wait_for_hp = 1; |
131 | 131 | ||
132 | /* Intel controllers use non-PME wakeup signalling */ | ||
133 | if (to_pci_dev(uhci_dev(uhci))->vendor == PCI_VENDOR_ID_INTEL) | ||
134 | device_set_run_wake(uhci_dev(uhci), 1); | ||
135 | |||
132 | /* Set up pointers to PCI-specific functions */ | 136 | /* Set up pointers to PCI-specific functions */ |
133 | uhci->reset_hc = uhci_pci_reset_hc; | 137 | uhci->reset_hc = uhci_pci_reset_hc; |
134 | uhci->check_and_reset_hc = uhci_pci_check_and_reset_hc; | 138 | uhci->check_and_reset_hc = uhci_pci_check_and_reset_hc; |
diff --git a/drivers/vfio/pci/vfio_pci_config.c b/drivers/vfio/pci/vfio_pci_config.c index 65d4a3015542..871af74fc4ce 100644 --- a/drivers/vfio/pci/vfio_pci_config.c +++ b/drivers/vfio/pci/vfio_pci_config.c | |||
@@ -31,8 +31,6 @@ | |||
31 | 31 | ||
32 | #include "vfio_pci_private.h" | 32 | #include "vfio_pci_private.h" |
33 | 33 | ||
34 | #define PCI_CFG_SPACE_SIZE 256 | ||
35 | |||
36 | /* Fake capability ID for standard config space */ | 34 | /* Fake capability ID for standard config space */ |
37 | #define PCI_CAP_ID_BASIC 0 | 35 | #define PCI_CAP_ID_BASIC 0 |
38 | 36 | ||
diff --git a/include/linux/acpi.h b/include/linux/acpi.h index ddbeda6dbdc8..b00ad73c946d 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h | |||
@@ -419,6 +419,8 @@ static inline int acpi_dev_filter_resource_type_cb(struct acpi_resource *ares, | |||
419 | return acpi_dev_filter_resource_type(ares, (unsigned long)arg); | 419 | return acpi_dev_filter_resource_type(ares, (unsigned long)arg); |
420 | } | 420 | } |
421 | 421 | ||
422 | struct acpi_device *acpi_resource_consumer(struct resource *res); | ||
423 | |||
422 | int acpi_check_resource_conflict(const struct resource *res); | 424 | int acpi_check_resource_conflict(const struct resource *res); |
423 | 425 | ||
424 | int acpi_check_region(resource_size_t start, resource_size_t n, | 426 | int acpi_check_region(resource_size_t start, resource_size_t n, |
@@ -762,6 +764,11 @@ static inline int acpi_reconfig_notifier_unregister(struct notifier_block *nb) | |||
762 | return -EINVAL; | 764 | return -EINVAL; |
763 | } | 765 | } |
764 | 766 | ||
767 | static inline struct acpi_device *acpi_resource_consumer(struct resource *res) | ||
768 | { | ||
769 | return NULL; | ||
770 | } | ||
771 | |||
765 | #endif /* !CONFIG_ACPI */ | 772 | #endif /* !CONFIG_ACPI */ |
766 | 773 | ||
767 | #ifdef CONFIG_ACPI_HOTPLUG_IOAPIC | 774 | #ifdef CONFIG_ACPI_HOTPLUG_IOAPIC |
diff --git a/include/linux/of_pci.h b/include/linux/of_pci.h index 7fd5cfce9140..0e0974eceb80 100644 --- a/include/linux/of_pci.h +++ b/include/linux/of_pci.h | |||
@@ -16,6 +16,7 @@ int of_pci_get_devfn(struct device_node *np); | |||
16 | int of_irq_parse_and_map_pci(const struct pci_dev *dev, u8 slot, u8 pin); | 16 | int of_irq_parse_and_map_pci(const struct pci_dev *dev, u8 slot, u8 pin); |
17 | int of_pci_parse_bus_range(struct device_node *node, struct resource *res); | 17 | int of_pci_parse_bus_range(struct device_node *node, struct resource *res); |
18 | int of_get_pci_domain_nr(struct device_node *node); | 18 | int of_get_pci_domain_nr(struct device_node *node); |
19 | int of_pci_get_max_link_speed(struct device_node *node); | ||
19 | void of_pci_check_probe_only(void); | 20 | void of_pci_check_probe_only(void); |
20 | int of_pci_map_rid(struct device_node *np, u32 rid, | 21 | int of_pci_map_rid(struct device_node *np, u32 rid, |
21 | const char *map_name, const char *map_mask_name, | 22 | const char *map_name, const char *map_mask_name, |
@@ -62,6 +63,12 @@ static inline int of_pci_map_rid(struct device_node *np, u32 rid, | |||
62 | return -EINVAL; | 63 | return -EINVAL; |
63 | } | 64 | } |
64 | 65 | ||
66 | static inline int | ||
67 | of_pci_get_max_link_speed(struct device_node *node) | ||
68 | { | ||
69 | return -EINVAL; | ||
70 | } | ||
71 | |||
65 | static inline void of_pci_check_probe_only(void) { } | 72 | static inline void of_pci_check_probe_only(void) { } |
66 | #endif | 73 | #endif |
67 | 74 | ||
diff --git a/include/linux/pci-acpi.h b/include/linux/pci-acpi.h index 7d63a66e8ed4..7a4e83a8c89c 100644 --- a/include/linux/pci-acpi.h +++ b/include/linux/pci-acpi.h | |||
@@ -24,7 +24,9 @@ static inline acpi_status pci_acpi_remove_pm_notifier(struct acpi_device *dev) | |||
24 | } | 24 | } |
25 | extern phys_addr_t acpi_pci_root_get_mcfg_addr(acpi_handle handle); | 25 | extern phys_addr_t acpi_pci_root_get_mcfg_addr(acpi_handle handle); |
26 | 26 | ||
27 | extern phys_addr_t pci_mcfg_lookup(u16 domain, struct resource *bus_res); | 27 | struct pci_ecam_ops; |
28 | extern int pci_mcfg_lookup(struct acpi_pci_root *root, struct resource *cfgres, | ||
29 | struct pci_ecam_ops **ecam_ops); | ||
28 | 30 | ||
29 | static inline acpi_handle acpi_find_root_bridge_handle(struct pci_dev *pdev) | 31 | static inline acpi_handle acpi_find_root_bridge_handle(struct pci_dev *pdev) |
30 | { | 32 | { |
diff --git a/include/linux/pci-ecam.h b/include/linux/pci-ecam.h index 7adad206b1f4..f0d2b9451270 100644 --- a/include/linux/pci-ecam.h +++ b/include/linux/pci-ecam.h | |||
@@ -59,6 +59,15 @@ void __iomem *pci_ecam_map_bus(struct pci_bus *bus, unsigned int devfn, | |||
59 | /* default ECAM ops */ | 59 | /* default ECAM ops */ |
60 | extern struct pci_ecam_ops pci_generic_ecam_ops; | 60 | extern struct pci_ecam_ops pci_generic_ecam_ops; |
61 | 61 | ||
62 | #if defined(CONFIG_ACPI) && defined(CONFIG_PCI_QUIRKS) | ||
63 | extern struct pci_ecam_ops pci_32b_ops; /* 32-bit accesses only */ | ||
64 | extern struct pci_ecam_ops hisi_pcie_ops; /* HiSilicon */ | ||
65 | extern struct pci_ecam_ops thunder_pem_ecam_ops; /* Cavium ThunderX 1.x & 2.x */ | ||
66 | extern struct pci_ecam_ops pci_thunder_ecam_ops; /* Cavium ThunderX 1.x */ | ||
67 | extern struct pci_ecam_ops xgene_v1_pcie_ecam_ops; /* APM X-Gene PCIe v1 */ | ||
68 | extern struct pci_ecam_ops xgene_v2_pcie_ecam_ops; /* APM X-Gene PCIe v2.x */ | ||
69 | #endif | ||
70 | |||
62 | #ifdef CONFIG_PCI_HOST_GENERIC | 71 | #ifdef CONFIG_PCI_HOST_GENERIC |
63 | /* for DT-based PCI controllers that support ECAM */ | 72 | /* for DT-based PCI controllers that support ECAM */ |
64 | int pci_host_common_probe(struct platform_device *pdev, | 73 | int pci_host_common_probe(struct platform_device *pdev, |
diff --git a/include/linux/pci.h b/include/linux/pci.h index 0e49f70dbd9b..aa5e8af16cfc 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h | |||
@@ -420,9 +420,13 @@ static inline int pci_channel_offline(struct pci_dev *pdev) | |||
420 | struct pci_host_bridge { | 420 | struct pci_host_bridge { |
421 | struct device dev; | 421 | struct device dev; |
422 | struct pci_bus *bus; /* root bus */ | 422 | struct pci_bus *bus; /* root bus */ |
423 | struct pci_ops *ops; | ||
424 | void *sysdata; | ||
425 | int busnr; | ||
423 | struct list_head windows; /* resource_entry */ | 426 | struct list_head windows; /* resource_entry */ |
424 | void (*release_fn)(struct pci_host_bridge *); | 427 | void (*release_fn)(struct pci_host_bridge *); |
425 | void *release_data; | 428 | void *release_data; |
429 | struct msi_controller *msi; | ||
426 | unsigned int ignore_reset_delay:1; /* for entire hierarchy */ | 430 | unsigned int ignore_reset_delay:1; /* for entire hierarchy */ |
427 | /* Resource alignment requirements */ | 431 | /* Resource alignment requirements */ |
428 | resource_size_t (*align_resource)(struct pci_dev *dev, | 432 | resource_size_t (*align_resource)(struct pci_dev *dev, |
@@ -430,10 +434,23 @@ struct pci_host_bridge { | |||
430 | resource_size_t start, | 434 | resource_size_t start, |
431 | resource_size_t size, | 435 | resource_size_t size, |
432 | resource_size_t align); | 436 | resource_size_t align); |
437 | unsigned long private[0] ____cacheline_aligned; | ||
433 | }; | 438 | }; |
434 | 439 | ||
435 | #define to_pci_host_bridge(n) container_of(n, struct pci_host_bridge, dev) | 440 | #define to_pci_host_bridge(n) container_of(n, struct pci_host_bridge, dev) |
436 | 441 | ||
442 | static inline void *pci_host_bridge_priv(struct pci_host_bridge *bridge) | ||
443 | { | ||
444 | return (void *)bridge->private; | ||
445 | } | ||
446 | |||
447 | static inline struct pci_host_bridge *pci_host_bridge_from_priv(void *priv) | ||
448 | { | ||
449 | return container_of(priv, struct pci_host_bridge, private); | ||
450 | } | ||
451 | |||
452 | struct pci_host_bridge *pci_alloc_host_bridge(size_t priv); | ||
453 | int pci_register_host_bridge(struct pci_host_bridge *bridge); | ||
437 | struct pci_host_bridge *pci_find_host_bridge(struct pci_bus *bus); | 454 | struct pci_host_bridge *pci_find_host_bridge(struct pci_bus *bus); |
438 | 455 | ||
439 | void pci_set_host_bridge_release(struct pci_host_bridge *bridge, | 456 | void pci_set_host_bridge_release(struct pci_host_bridge *bridge, |
diff --git a/include/linux/pci_hotplug.h b/include/linux/pci_hotplug.h index 8c7895061121..2e855afa0212 100644 --- a/include/linux/pci_hotplug.h +++ b/include/linux/pci_hotplug.h | |||
@@ -176,6 +176,7 @@ struct hotplug_params { | |||
176 | #ifdef CONFIG_ACPI | 176 | #ifdef CONFIG_ACPI |
177 | #include <linux/acpi.h> | 177 | #include <linux/acpi.h> |
178 | int pci_get_hp_params(struct pci_dev *dev, struct hotplug_params *hpp); | 178 | int pci_get_hp_params(struct pci_dev *dev, struct hotplug_params *hpp); |
179 | bool pciehp_is_native(struct pci_dev *pdev); | ||
179 | int acpi_get_hp_hw_control_from_firmware(struct pci_dev *dev, u32 flags); | 180 | int acpi_get_hp_hw_control_from_firmware(struct pci_dev *dev, u32 flags); |
180 | int acpi_pci_check_ejectable(struct pci_bus *pbus, acpi_handle handle); | 181 | int acpi_pci_check_ejectable(struct pci_bus *pbus, acpi_handle handle); |
181 | int acpi_pci_detect_ejectable(acpi_handle handle); | 182 | int acpi_pci_detect_ejectable(acpi_handle handle); |
@@ -185,5 +186,6 @@ static inline int pci_get_hp_params(struct pci_dev *dev, | |||
185 | { | 186 | { |
186 | return -ENODEV; | 187 | return -ENODEV; |
187 | } | 188 | } |
189 | static inline bool pciehp_is_native(struct pci_dev *pdev) { return true; } | ||
188 | #endif | 190 | #endif |
189 | #endif | 191 | #endif |
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index c58752fe16c4..f020ab4079d3 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h | |||
@@ -2256,12 +2256,29 @@ | |||
2256 | #define PCI_DEVICE_ID_ZOLTRIX_2BD0 0x2bd0 | 2256 | #define PCI_DEVICE_ID_ZOLTRIX_2BD0 0x2bd0 |
2257 | 2257 | ||
2258 | #define PCI_VENDOR_ID_MELLANOX 0x15b3 | 2258 | #define PCI_VENDOR_ID_MELLANOX 0x15b3 |
2259 | #define PCI_DEVICE_ID_MELLANOX_TAVOR 0x5a44 | 2259 | #define PCI_DEVICE_ID_MELLANOX_CONNECTX3 0x1003 |
2260 | #define PCI_DEVICE_ID_MELLANOX_CONNECTX3_PRO 0x1007 | ||
2261 | #define PCI_DEVICE_ID_MELLANOX_CONNECTIB 0x1011 | ||
2262 | #define PCI_DEVICE_ID_MELLANOX_CONNECTX4 0x1013 | ||
2263 | #define PCI_DEVICE_ID_MELLANOX_CONNECTX4_LX 0x1015 | ||
2264 | #define PCI_DEVICE_ID_MELLANOX_TAVOR 0x5a44 | ||
2260 | #define PCI_DEVICE_ID_MELLANOX_TAVOR_BRIDGE 0x5a46 | 2265 | #define PCI_DEVICE_ID_MELLANOX_TAVOR_BRIDGE 0x5a46 |
2261 | #define PCI_DEVICE_ID_MELLANOX_ARBEL_COMPAT 0x6278 | 2266 | #define PCI_DEVICE_ID_MELLANOX_SINAI_OLD 0x5e8c |
2262 | #define PCI_DEVICE_ID_MELLANOX_ARBEL 0x6282 | 2267 | #define PCI_DEVICE_ID_MELLANOX_SINAI 0x6274 |
2263 | #define PCI_DEVICE_ID_MELLANOX_SINAI_OLD 0x5e8c | 2268 | #define PCI_DEVICE_ID_MELLANOX_ARBEL_COMPAT 0x6278 |
2264 | #define PCI_DEVICE_ID_MELLANOX_SINAI 0x6274 | 2269 | #define PCI_DEVICE_ID_MELLANOX_ARBEL 0x6282 |
2270 | #define PCI_DEVICE_ID_MELLANOX_HERMON_SDR 0x6340 | ||
2271 | #define PCI_DEVICE_ID_MELLANOX_HERMON_DDR 0x634a | ||
2272 | #define PCI_DEVICE_ID_MELLANOX_HERMON_QDR 0x6354 | ||
2273 | #define PCI_DEVICE_ID_MELLANOX_HERMON_EN 0x6368 | ||
2274 | #define PCI_DEVICE_ID_MELLANOX_CONNECTX_EN 0x6372 | ||
2275 | #define PCI_DEVICE_ID_MELLANOX_HERMON_DDR_GEN2 0x6732 | ||
2276 | #define PCI_DEVICE_ID_MELLANOX_HERMON_QDR_GEN2 0x673c | ||
2277 | #define PCI_DEVICE_ID_MELLANOX_CONNECTX_EN_5_GEN2 0x6746 | ||
2278 | #define PCI_DEVICE_ID_MELLANOX_HERMON_EN_GEN2 0x6750 | ||
2279 | #define PCI_DEVICE_ID_MELLANOX_CONNECTX_EN_T_GEN2 0x675a | ||
2280 | #define PCI_DEVICE_ID_MELLANOX_CONNECTX_EN_GEN2 0x6764 | ||
2281 | #define PCI_DEVICE_ID_MELLANOX_CONNECTX2 0x676e | ||
2265 | 2282 | ||
2266 | #define PCI_VENDOR_ID_DFI 0x15bd | 2283 | #define PCI_VENDOR_ID_DFI 0x15bd |
2267 | 2284 | ||
diff --git a/include/uapi/linux/pci_regs.h b/include/uapi/linux/pci_regs.h index e5a2e68b2236..174d1147081b 100644 --- a/include/uapi/linux/pci_regs.h +++ b/include/uapi/linux/pci_regs.h | |||
@@ -23,6 +23,14 @@ | |||
23 | #define LINUX_PCI_REGS_H | 23 | #define LINUX_PCI_REGS_H |
24 | 24 | ||
25 | /* | 25 | /* |
26 | * Conventional PCI and PCI-X Mode 1 devices have 256 bytes of | ||
27 | * configuration space. PCI-X Mode 2 and PCIe devices have 4096 bytes of | ||
28 | * configuration space. | ||
29 | */ | ||
30 | #define PCI_CFG_SPACE_SIZE 256 | ||
31 | #define PCI_CFG_SPACE_EXP_SIZE 4096 | ||
32 | |||
33 | /* | ||
26 | * Under PCI, each device has 256 bytes of configuration address space, | 34 | * Under PCI, each device has 256 bytes of configuration address space, |
27 | * of which the first 64 bytes are standardized as follows: | 35 | * of which the first 64 bytes are standardized as follows: |
28 | */ | 36 | */ |