diff options
68 files changed, 1648 insertions, 515 deletions
diff --git a/Documentation/devicetree/bindings/pci/altera-pcie.txt b/Documentation/devicetree/bindings/pci/altera-pcie.txt index 6c396f17c91a..816b244a221e 100644 --- a/Documentation/devicetree/bindings/pci/altera-pcie.txt +++ b/Documentation/devicetree/bindings/pci/altera-pcie.txt | |||
| @@ -1,11 +1,13 @@ | |||
| 1 | * Altera PCIe controller | 1 | * Altera PCIe controller |
| 2 | 2 | ||
| 3 | Required properties: | 3 | Required properties: |
| 4 | - compatible : should contain "altr,pcie-root-port-1.0" | 4 | - compatible : should contain "altr,pcie-root-port-1.0" or "altr,pcie-root-port-2.0" |
| 5 | - reg: a list of physical base address and length for TXS and CRA. | 5 | - reg: a list of physical base address and length for TXS and CRA. |
| 6 | For "altr,pcie-root-port-2.0", additional HIP base address and length. | ||
| 6 | - reg-names: must include the following entries: | 7 | - reg-names: must include the following entries: |
| 7 | "Txs": TX slave port region | 8 | "Txs": TX slave port region |
| 8 | "Cra": Control register access region | 9 | "Cra": Control register access region |
| 10 | "Hip": Hard IP region (if "altr,pcie-root-port-2.0") | ||
| 9 | - interrupts: specifies the interrupt source of the parent interrupt | 11 | - interrupts: specifies the interrupt source of the parent interrupt |
| 10 | controller. The format of the interrupt specifier depends | 12 | controller. The format of the interrupt specifier depends |
| 11 | on the parent interrupt controller. | 13 | on the parent interrupt controller. |
diff --git a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt index d514c1f2365f..a7f5f5afa0e6 100644 --- a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt +++ b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt | |||
| @@ -9,6 +9,7 @@ Required properties: | |||
| 9 | - "fsl,imx6sx-pcie", | 9 | - "fsl,imx6sx-pcie", |
| 10 | - "fsl,imx6qp-pcie" | 10 | - "fsl,imx6qp-pcie" |
| 11 | - "fsl,imx7d-pcie" | 11 | - "fsl,imx7d-pcie" |
| 12 | - "fsl,imx8mq-pcie" | ||
| 12 | - reg: base address and length of the PCIe controller | 13 | - reg: base address and length of the PCIe controller |
| 13 | - interrupts: A list of interrupt outputs of the controller. Must contain an | 14 | - interrupts: A list of interrupt outputs of the controller. Must contain an |
| 14 | entry for each entry in the interrupt-names property. | 15 | entry for each entry in the interrupt-names property. |
| @@ -45,7 +46,7 @@ Additional required properties for imx6sx-pcie: | |||
| 45 | PCIE_PHY power domains | 46 | PCIE_PHY power domains |
| 46 | - power-domain-names: Must be "pcie", "pcie_phy" | 47 | - power-domain-names: Must be "pcie", "pcie_phy" |
| 47 | 48 | ||
| 48 | Additional required properties for imx7d-pcie: | 49 | Additional required properties for imx7d-pcie and imx8mq-pcie: |
| 49 | - power-domains: Must be set to a phandle pointing to PCIE_PHY power domain | 50 | - power-domains: Must be set to a phandle pointing to PCIE_PHY power domain |
| 50 | - resets: Must contain phandles to PCIe-related reset lines exposed by SRC | 51 | - resets: Must contain phandles to PCIe-related reset lines exposed by SRC |
| 51 | IP block | 52 | IP block |
| @@ -53,6 +54,11 @@ Additional required properties for imx7d-pcie: | |||
| 53 | - "pciephy" | 54 | - "pciephy" |
| 54 | - "apps" | 55 | - "apps" |
| 55 | - "turnoff" | 56 | - "turnoff" |
| 57 | - fsl,imx7d-pcie-phy: A phandle to an fsl,imx7d-pcie-phy node. | ||
| 58 | |||
| 59 | Additional required properties for imx8mq-pcie: | ||
| 60 | - clock-names: Must include the following additional entries: | ||
| 61 | - "pcie_aux" | ||
| 56 | 62 | ||
| 57 | Example: | 63 | Example: |
| 58 | 64 | ||
| @@ -79,3 +85,13 @@ Example: | |||
| 79 | clocks = <&clks 144>, <&clks 206>, <&clks 189>; | 85 | clocks = <&clks 144>, <&clks 206>, <&clks 189>; |
| 80 | clock-names = "pcie", "pcie_bus", "pcie_phy"; | 86 | clock-names = "pcie", "pcie_bus", "pcie_phy"; |
| 81 | }; | 87 | }; |
| 88 | |||
| 89 | * Freescale i.MX7d PCIe PHY | ||
| 90 | |||
| 91 | This is the PHY associated with the IMX7d PCIe controller. It's used by the | ||
| 92 | PCI-e controller via the fsl,imx7d-pcie-phy phandle. | ||
| 93 | |||
| 94 | Required properties: | ||
| 95 | - compatible: | ||
| 96 | - "fsl,imx7d-pcie-phy" | ||
| 97 | - reg: base address and length of the PCIe PHY controller | ||
diff --git a/Documentation/devicetree/bindings/pci/layerscape-pci.txt b/Documentation/devicetree/bindings/pci/layerscape-pci.txt index 9b2b8d66d1f4..e20ceaab9b38 100644 --- a/Documentation/devicetree/bindings/pci/layerscape-pci.txt +++ b/Documentation/devicetree/bindings/pci/layerscape-pci.txt | |||
| @@ -13,6 +13,7 @@ information. | |||
| 13 | 13 | ||
| 14 | Required properties: | 14 | Required properties: |
| 15 | - compatible: should contain the platform identifier such as: | 15 | - compatible: should contain the platform identifier such as: |
| 16 | RC mode: | ||
| 16 | "fsl,ls1021a-pcie" | 17 | "fsl,ls1021a-pcie" |
| 17 | "fsl,ls2080a-pcie", "fsl,ls2085a-pcie" | 18 | "fsl,ls2080a-pcie", "fsl,ls2085a-pcie" |
| 18 | "fsl,ls2088a-pcie" | 19 | "fsl,ls2088a-pcie" |
| @@ -20,6 +21,8 @@ Required properties: | |||
| 20 | "fsl,ls1046a-pcie" | 21 | "fsl,ls1046a-pcie" |
| 21 | "fsl,ls1043a-pcie" | 22 | "fsl,ls1043a-pcie" |
| 22 | "fsl,ls1012a-pcie" | 23 | "fsl,ls1012a-pcie" |
| 24 | EP mode: | ||
| 25 | "fsl,ls1046a-pcie-ep", "fsl,ls-pcie-ep" | ||
| 23 | - reg: base addresses and lengths of the PCIe controller register blocks. | 26 | - reg: base addresses and lengths of the PCIe controller register blocks. |
| 24 | - interrupts: A list of interrupt outputs of the controller. Must contain an | 27 | - interrupts: A list of interrupt outputs of the controller. Must contain an |
| 25 | entry for each entry in the interrupt-names property. | 28 | entry for each entry in the interrupt-names property. |
diff --git a/Documentation/devicetree/bindings/pci/rcar-pci.txt b/Documentation/devicetree/bindings/pci/rcar-pci.txt index 976ef7bfff93..6904882a0e94 100644 --- a/Documentation/devicetree/bindings/pci/rcar-pci.txt +++ b/Documentation/devicetree/bindings/pci/rcar-pci.txt | |||
| @@ -3,6 +3,7 @@ | |||
| 3 | Required properties: | 3 | Required properties: |
| 4 | compatible: "renesas,pcie-r8a7743" for the R8A7743 SoC; | 4 | compatible: "renesas,pcie-r8a7743" for the R8A7743 SoC; |
| 5 | "renesas,pcie-r8a7744" for the R8A7744 SoC; | 5 | "renesas,pcie-r8a7744" for the R8A7744 SoC; |
| 6 | "renesas,pcie-r8a774c0" for the R8A774C0 SoC; | ||
| 6 | "renesas,pcie-r8a7779" for the R8A7779 SoC; | 7 | "renesas,pcie-r8a7779" for the R8A7779 SoC; |
| 7 | "renesas,pcie-r8a7790" for the R8A7790 SoC; | 8 | "renesas,pcie-r8a7790" for the R8A7790 SoC; |
| 8 | "renesas,pcie-r8a7791" for the R8A7791 SoC; | 9 | "renesas,pcie-r8a7791" for the R8A7791 SoC; |
| @@ -13,7 +14,8 @@ compatible: "renesas,pcie-r8a7743" for the R8A7743 SoC; | |||
| 13 | "renesas,pcie-r8a77990" for the R8A77990 SoC; | 14 | "renesas,pcie-r8a77990" for the R8A77990 SoC; |
| 14 | "renesas,pcie-rcar-gen2" for a generic R-Car Gen2 or | 15 | "renesas,pcie-rcar-gen2" for a generic R-Car Gen2 or |
| 15 | RZ/G1 compatible device. | 16 | RZ/G1 compatible device. |
| 16 | "renesas,pcie-rcar-gen3" for a generic R-Car Gen3 compatible device. | 17 | "renesas,pcie-rcar-gen3" for a generic R-Car Gen3 or |
| 18 | RZ/G2 compatible device. | ||
| 17 | 19 | ||
| 18 | When compatible with the generic version, nodes must list the | 20 | When compatible with the generic version, nodes must list the |
| 19 | SoC-specific version corresponding to the platform first | 21 | SoC-specific version corresponding to the platform first |
diff --git a/Documentation/devicetree/bindings/pci/ti-pci.txt b/Documentation/devicetree/bindings/pci/ti-pci.txt index 452fe48c4fdd..d5cbfe6b0d89 100644 --- a/Documentation/devicetree/bindings/pci/ti-pci.txt +++ b/Documentation/devicetree/bindings/pci/ti-pci.txt | |||
| @@ -1,14 +1,21 @@ | |||
| 1 | TI PCI Controllers | 1 | TI PCI Controllers |
| 2 | 2 | ||
| 3 | PCIe DesignWare Controller | 3 | PCIe DesignWare Controller |
| 4 | - compatible: Should be "ti,dra7-pcie" for RC | 4 | - compatible: Should be "ti,dra7-pcie" for RC (deprecated) |
| 5 | Should be "ti,dra7-pcie-ep" for EP | 5 | Should be "ti,dra7-pcie-ep" for EP (deprecated) |
| 6 | Should be "ti,dra746-pcie-rc" for dra74x/dra76 in RC mode | ||
| 7 | Should be "ti,dra746-pcie-ep" for dra74x/dra76 in EP mode | ||
| 8 | Should be "ti,dra726-pcie-rc" for dra72x in RC mode | ||
| 9 | Should be "ti,dra726-pcie-ep" for dra72x in EP mode | ||
| 6 | - phys : list of PHY specifiers (used by generic PHY framework) | 10 | - phys : list of PHY specifiers (used by generic PHY framework) |
| 7 | - phy-names : must be "pcie-phy0", "pcie-phy1", "pcie-phyN".. based on the | 11 | - phy-names : must be "pcie-phy0", "pcie-phy1", "pcie-phyN".. based on the |
| 8 | number of PHYs as specified in *phys* property. | 12 | number of PHYs as specified in *phys* property. |
| 9 | - ti,hwmods : Name of the hwmod associated to the pcie, "pcie<X>", | 13 | - ti,hwmods : Name of the hwmod associated to the pcie, "pcie<X>", |
| 10 | where <X> is the instance number of the pcie from the HW spec. | 14 | where <X> is the instance number of the pcie from the HW spec. |
| 11 | - num-lanes as specified in ../designware-pcie.txt | 15 | - num-lanes as specified in ../designware-pcie.txt |
| 16 | - ti,syscon-lane-sel : phandle/offset pair. Phandle to the system control | ||
| 17 | module and the register offset to specify lane | ||
| 18 | selection. | ||
| 12 | 19 | ||
| 13 | HOST MODE | 20 | HOST MODE |
| 14 | ========= | 21 | ========= |
diff --git a/MAINTAINERS b/MAINTAINERS index f28288f1bf07..3cec1cfd2a53 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
| @@ -11830,7 +11830,7 @@ F: Documentation/devicetree/bindings/pci/pci-armada8k.txt | |||
| 11830 | F: drivers/pci/controller/dwc/pcie-armada8k.c | 11830 | F: drivers/pci/controller/dwc/pcie-armada8k.c |
| 11831 | 11831 | ||
| 11832 | PCI DRIVER FOR CADENCE PCIE IP | 11832 | PCI DRIVER FOR CADENCE PCIE IP |
| 11833 | M: Alan Douglas <adouglas@cadence.com> | 11833 | M: Tom Joseph <tjoseph@cadence.com> |
| 11834 | L: linux-pci@vger.kernel.org | 11834 | L: linux-pci@vger.kernel.org |
| 11835 | S: Maintained | 11835 | S: Maintained |
| 11836 | F: Documentation/devicetree/bindings/pci/cdns,*.txt | 11836 | F: Documentation/devicetree/bindings/pci/cdns,*.txt |
diff --git a/arch/arm/boot/dts/imx7d.dtsi b/arch/arm/boot/dts/imx7d.dtsi index 6b298e388f4b..6eb98e7c568d 100644 --- a/arch/arm/boot/dts/imx7d.dtsi +++ b/arch/arm/boot/dts/imx7d.dtsi | |||
| @@ -96,6 +96,14 @@ | |||
| 96 | }; | 96 | }; |
| 97 | }; | 97 | }; |
| 98 | 98 | ||
| 99 | &aips2 { | ||
| 100 | pcie_phy: pcie-phy@306d0000 { | ||
| 101 | compatible = "fsl,imx7d-pcie-phy"; | ||
| 102 | reg = <0x306d0000 0x10000>; | ||
| 103 | status = "disabled"; | ||
| 104 | }; | ||
| 105 | }; | ||
| 106 | |||
| 99 | &aips3 { | 107 | &aips3 { |
| 100 | usbotg2: usb@30b20000 { | 108 | usbotg2: usb@30b20000 { |
| 101 | compatible = "fsl,imx7d-usb", "fsl,imx27-usb"; | 109 | compatible = "fsl,imx7d-usb", "fsl,imx27-usb"; |
| @@ -173,6 +181,7 @@ | |||
| 173 | <&src IMX7_RESET_PCIE_CTRL_APPS_EN>, | 181 | <&src IMX7_RESET_PCIE_CTRL_APPS_EN>, |
| 174 | <&src IMX7_RESET_PCIE_CTRL_APPS_TURNOFF>; | 182 | <&src IMX7_RESET_PCIE_CTRL_APPS_TURNOFF>; |
| 175 | reset-names = "pciephy", "apps", "turnoff"; | 183 | reset-names = "pciephy", "apps", "turnoff"; |
| 184 | fsl,imx7d-pcie-phy = <&pcie_phy>; | ||
| 176 | status = "disabled"; | 185 | status = "disabled"; |
| 177 | }; | 186 | }; |
| 178 | }; | 187 | }; |
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi index 0e762ca92558..cb7185014d3a 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi | |||
| @@ -666,6 +666,17 @@ | |||
| 666 | status = "disabled"; | 666 | status = "disabled"; |
| 667 | }; | 667 | }; |
| 668 | 668 | ||
| 669 | pcie_ep@3400000 { | ||
| 670 | compatible = "fsl,ls1046a-pcie-ep","fsl,ls-pcie-ep"; | ||
| 671 | reg = <0x00 0x03400000 0x0 0x00100000 | ||
| 672 | 0x40 0x00000000 0x8 0x00000000>; | ||
| 673 | reg-names = "regs", "addr_space"; | ||
| 674 | num-ib-windows = <6>; | ||
| 675 | num-ob-windows = <8>; | ||
| 676 | num-lanes = <2>; | ||
| 677 | status = "disabled"; | ||
| 678 | }; | ||
| 679 | |||
| 669 | pcie@3500000 { | 680 | pcie@3500000 { |
| 670 | compatible = "fsl,ls1046a-pcie"; | 681 | compatible = "fsl,ls1046a-pcie"; |
| 671 | reg = <0x00 0x03500000 0x0 0x00100000 /* controller registers */ | 682 | reg = <0x00 0x03500000 0x0 0x00100000 /* controller registers */ |
| @@ -693,6 +704,17 @@ | |||
| 693 | status = "disabled"; | 704 | status = "disabled"; |
| 694 | }; | 705 | }; |
| 695 | 706 | ||
| 707 | pcie_ep@3500000 { | ||
| 708 | compatible = "fsl,ls1046a-pcie-ep","fsl,ls-pcie-ep"; | ||
| 709 | reg = <0x00 0x03500000 0x0 0x00100000 | ||
| 710 | 0x48 0x00000000 0x8 0x00000000>; | ||
| 711 | reg-names = "regs", "addr_space"; | ||
| 712 | num-ib-windows = <6>; | ||
| 713 | num-ob-windows = <8>; | ||
| 714 | num-lanes = <2>; | ||
| 715 | status = "disabled"; | ||
| 716 | }; | ||
| 717 | |||
| 696 | pcie@3600000 { | 718 | pcie@3600000 { |
| 697 | compatible = "fsl,ls1046a-pcie"; | 719 | compatible = "fsl,ls1046a-pcie"; |
| 698 | reg = <0x00 0x03600000 0x0 0x00100000 /* controller registers */ | 720 | reg = <0x00 0x03600000 0x0 0x00100000 /* controller registers */ |
| @@ -720,6 +742,17 @@ | |||
| 720 | status = "disabled"; | 742 | status = "disabled"; |
| 721 | }; | 743 | }; |
| 722 | 744 | ||
| 745 | pcie_ep@3600000 { | ||
| 746 | compatible = "fsl,ls1046a-pcie-ep", "fsl,ls-pcie-ep"; | ||
| 747 | reg = <0x00 0x03600000 0x0 0x00100000 | ||
| 748 | 0x50 0x00000000 0x8 0x00000000>; | ||
| 749 | reg-names = "regs", "addr_space"; | ||
| 750 | num-ib-windows = <6>; | ||
| 751 | num-ob-windows = <8>; | ||
| 752 | num-lanes = <2>; | ||
| 753 | status = "disabled"; | ||
| 754 | }; | ||
| 755 | |||
| 723 | qdma: dma-controller@8380000 { | 756 | qdma: dma-controller@8380000 { |
| 724 | compatible = "fsl,ls1046a-qdma", "fsl,ls1021a-qdma"; | 757 | compatible = "fsl,ls1046a-qdma", "fsl,ls1021a-qdma"; |
| 725 | reg = <0x0 0x8380000 0x0 0x1000>, /* Controller regs */ | 758 | reg = <0x0 0x8380000 0x0 0x1000>, /* Controller regs */ |
| @@ -740,7 +773,6 @@ | |||
| 740 | queue-sizes = <64 64>; | 773 | queue-sizes = <64 64>; |
| 741 | big-endian; | 774 | big-endian; |
| 742 | }; | 775 | }; |
| 743 | |||
| 744 | }; | 776 | }; |
| 745 | 777 | ||
| 746 | reserved-memory { | 778 | reserved-memory { |
diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c index 7abb09e2eeb8..7f2eed1fc81b 100644 --- a/arch/x86/hyperv/hv_init.c +++ b/arch/x86/hyperv/hv_init.c | |||
| @@ -96,6 +96,7 @@ void __percpu **hyperv_pcpu_input_arg; | |||
| 96 | EXPORT_SYMBOL_GPL(hyperv_pcpu_input_arg); | 96 | EXPORT_SYMBOL_GPL(hyperv_pcpu_input_arg); |
| 97 | 97 | ||
| 98 | u32 hv_max_vp_index; | 98 | u32 hv_max_vp_index; |
| 99 | EXPORT_SYMBOL_GPL(hv_max_vp_index); | ||
| 99 | 100 | ||
| 100 | static int hv_cpu_init(unsigned int cpu) | 101 | static int hv_cpu_init(unsigned int cpu) |
| 101 | { | 102 | { |
diff --git a/arch/x86/pci/fixup.c b/arch/x86/pci/fixup.c index 30a5111ae5fd..527e69b12002 100644 --- a/arch/x86/pci/fixup.c +++ b/arch/x86/pci/fixup.c | |||
| @@ -635,6 +635,22 @@ static void quirk_no_aersid(struct pci_dev *pdev) | |||
| 635 | DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_INTEL, PCI_ANY_ID, | 635 | DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_INTEL, PCI_ANY_ID, |
| 636 | PCI_CLASS_BRIDGE_PCI, 8, quirk_no_aersid); | 636 | PCI_CLASS_BRIDGE_PCI, 8, quirk_no_aersid); |
| 637 | 637 | ||
| 638 | static void quirk_intel_th_dnv(struct pci_dev *dev) | ||
| 639 | { | ||
| 640 | struct resource *r = &dev->resource[4]; | ||
| 641 | |||
| 642 | /* | ||
| 643 | * Denverton reports 2k of RTIT_BAR (intel_th resource 4), which | ||
| 644 | * appears to be 4 MB in reality. | ||
| 645 | */ | ||
| 646 | if (r->end == r->start + 0x7ff) { | ||
| 647 | r->start = 0; | ||
| 648 | r->end = 0x3fffff; | ||
| 649 | r->flags |= IORESOURCE_UNSET; | ||
| 650 | } | ||
| 651 | } | ||
| 652 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x19e1, quirk_intel_th_dnv); | ||
| 653 | |||
| 638 | #ifdef CONFIG_PHYS_ADDR_T_64BIT | 654 | #ifdef CONFIG_PHYS_ADDR_T_64BIT |
| 639 | 655 | ||
| 640 | #define AMD_141b_MMIO_BASE(x) (0x80 + (x) * 0x8) | 656 | #define AMD_141b_MMIO_BASE(x) (0x80 + (x) * 0x8) |
diff --git a/drivers/dma/pch_dma.c b/drivers/dma/pch_dma.c index afd8f27bda96..538b6e0e17bb 100644 --- a/drivers/dma/pch_dma.c +++ b/drivers/dma/pch_dma.c | |||
| @@ -972,7 +972,6 @@ static void pch_dma_remove(struct pci_dev *pdev) | |||
| 972 | } | 972 | } |
| 973 | 973 | ||
| 974 | /* PCI Device ID of DMA device */ | 974 | /* PCI Device ID of DMA device */ |
| 975 | #define PCI_VENDOR_ID_ROHM 0x10DB | ||
| 976 | #define PCI_DEVICE_ID_EG20T_PCH_DMA_8CH 0x8810 | 975 | #define PCI_DEVICE_ID_EG20T_PCH_DMA_8CH 0x8810 |
| 977 | #define PCI_DEVICE_ID_EG20T_PCH_DMA_4CH 0x8815 | 976 | #define PCI_DEVICE_ID_EG20T_PCH_DMA_4CH 0x8815 |
| 978 | #define PCI_DEVICE_ID_ML7213_DMA1_8CH 0x8026 | 977 | #define PCI_DEVICE_ID_ML7213_DMA1_8CH 0x8026 |
diff --git a/drivers/gpio/gpio-ml-ioh.c b/drivers/gpio/gpio-ml-ioh.c index 51c7d1b84c2e..0c076dce9e17 100644 --- a/drivers/gpio/gpio-ml-ioh.c +++ b/drivers/gpio/gpio-ml-ioh.c | |||
| @@ -31,8 +31,6 @@ | |||
| 31 | 31 | ||
| 32 | #define IOH_IRQ_BASE 0 | 32 | #define IOH_IRQ_BASE 0 |
| 33 | 33 | ||
| 34 | #define PCI_VENDOR_ID_ROHM 0x10DB | ||
| 35 | |||
| 36 | struct ioh_reg_comn { | 34 | struct ioh_reg_comn { |
| 37 | u32 ien; | 35 | u32 ien; |
| 38 | u32 istatus; | 36 | u32 istatus; |
diff --git a/drivers/gpio/gpio-pch.c b/drivers/gpio/gpio-pch.c index ee79e5f88b5a..1d99293096f2 100644 --- a/drivers/gpio/gpio-pch.c +++ b/drivers/gpio/gpio-pch.c | |||
| @@ -437,7 +437,6 @@ static int __maybe_unused pch_gpio_resume(struct device *dev) | |||
| 437 | 437 | ||
| 438 | static SIMPLE_DEV_PM_OPS(pch_gpio_pm_ops, pch_gpio_suspend, pch_gpio_resume); | 438 | static SIMPLE_DEV_PM_OPS(pch_gpio_pm_ops, pch_gpio_suspend, pch_gpio_resume); |
| 439 | 439 | ||
| 440 | #define PCI_VENDOR_ID_ROHM 0x10DB | ||
| 441 | static const struct pci_device_id pch_gpio_pcidev_id[] = { | 440 | static const struct pci_device_id pch_gpio_pcidev_id[] = { |
| 442 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x8803) }, | 441 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x8803) }, |
| 443 | { PCI_DEVICE(PCI_VENDOR_ID_ROHM, 0x8014) }, | 442 | { PCI_DEVICE(PCI_VENDOR_ID_ROHM, 0x8014) }, |
diff --git a/drivers/i2c/busses/i2c-eg20t.c b/drivers/i2c/busses/i2c-eg20t.c index 835d54ac2971..231675b10376 100644 --- a/drivers/i2c/busses/i2c-eg20t.c +++ b/drivers/i2c/busses/i2c-eg20t.c | |||
| @@ -177,7 +177,6 @@ static wait_queue_head_t pch_event; | |||
| 177 | static DEFINE_MUTEX(pch_mutex); | 177 | static DEFINE_MUTEX(pch_mutex); |
| 178 | 178 | ||
| 179 | /* Definition for ML7213 by LAPIS Semiconductor */ | 179 | /* Definition for ML7213 by LAPIS Semiconductor */ |
| 180 | #define PCI_VENDOR_ID_ROHM 0x10DB | ||
| 181 | #define PCI_DEVICE_ID_ML7213_I2C 0x802D | 180 | #define PCI_DEVICE_ID_ML7213_I2C 0x802D |
| 182 | #define PCI_DEVICE_ID_ML7223_I2C 0x8010 | 181 | #define PCI_DEVICE_ID_ML7223_I2C 0x8010 |
| 183 | #define PCI_DEVICE_ID_ML7831_I2C 0x8817 | 182 | #define PCI_DEVICE_ID_ML7831_I2C 0x8817 |
diff --git a/drivers/misc/pch_phub.c b/drivers/misc/pch_phub.c index 540845651b8c..309703e9c42e 100644 --- a/drivers/misc/pch_phub.c +++ b/drivers/misc/pch_phub.c | |||
| @@ -64,7 +64,6 @@ | |||
| 64 | #define CLKCFG_UARTCLKSEL (1 << 18) | 64 | #define CLKCFG_UARTCLKSEL (1 << 18) |
| 65 | 65 | ||
| 66 | /* Macros for ML7213 */ | 66 | /* Macros for ML7213 */ |
| 67 | #define PCI_VENDOR_ID_ROHM 0x10db | ||
| 68 | #define PCI_DEVICE_ID_ROHM_ML7213_PHUB 0x801A | 67 | #define PCI_DEVICE_ID_ROHM_ML7213_PHUB 0x801A |
| 69 | 68 | ||
| 70 | /* Macros for ML7223 */ | 69 | /* Macros for ML7223 */ |
diff --git a/drivers/misc/pci_endpoint_test.c b/drivers/misc/pci_endpoint_test.c index 896e2df9400f..29582fe57151 100644 --- a/drivers/misc/pci_endpoint_test.c +++ b/drivers/misc/pci_endpoint_test.c | |||
| @@ -788,6 +788,7 @@ static void pci_endpoint_test_remove(struct pci_dev *pdev) | |||
| 788 | static const struct pci_device_id pci_endpoint_test_tbl[] = { | 788 | static const struct pci_device_id pci_endpoint_test_tbl[] = { |
| 789 | { PCI_DEVICE(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_DRA74x) }, | 789 | { PCI_DEVICE(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_DRA74x) }, |
| 790 | { PCI_DEVICE(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_DRA72x) }, | 790 | { PCI_DEVICE(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_DRA72x) }, |
| 791 | { PCI_DEVICE(PCI_VENDOR_ID_FREESCALE, 0x81c0) }, | ||
| 791 | { PCI_DEVICE(PCI_VENDOR_ID_SYNOPSYS, 0xedda) }, | 792 | { PCI_DEVICE(PCI_VENDOR_ID_SYNOPSYS, 0xedda) }, |
| 792 | { } | 793 | { } |
| 793 | }; | 794 | }; |
diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c index 552d930e3940..528f6b4fd16a 100644 --- a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c +++ b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c | |||
| @@ -27,7 +27,6 @@ | |||
| 27 | #define DRV_VERSION "1.01" | 27 | #define DRV_VERSION "1.01" |
| 28 | const char pch_driver_version[] = DRV_VERSION; | 28 | const char pch_driver_version[] = DRV_VERSION; |
| 29 | 29 | ||
| 30 | #define PCI_DEVICE_ID_INTEL_IOH1_GBE 0x8802 /* Pci device ID */ | ||
| 31 | #define PCH_GBE_MAR_ENTRIES 16 | 30 | #define PCH_GBE_MAR_ENTRIES 16 |
| 32 | #define PCH_GBE_SHORT_PKT 64 | 31 | #define PCH_GBE_SHORT_PKT 64 |
| 33 | #define DSC_INIT16 0xC000 | 32 | #define DSC_INIT16 0xC000 |
| @@ -37,11 +36,9 @@ const char pch_driver_version[] = DRV_VERSION; | |||
| 37 | #define PCH_GBE_PCI_BAR 1 | 36 | #define PCH_GBE_PCI_BAR 1 |
| 38 | #define PCH_GBE_RESERVE_MEMORY 0x200000 /* 2MB */ | 37 | #define PCH_GBE_RESERVE_MEMORY 0x200000 /* 2MB */ |
| 39 | 38 | ||
| 40 | /* Macros for ML7223 */ | 39 | #define PCI_DEVICE_ID_INTEL_IOH1_GBE 0x8802 |
| 41 | #define PCI_VENDOR_ID_ROHM 0x10db | ||
| 42 | #define PCI_DEVICE_ID_ROHM_ML7223_GBE 0x8013 | ||
| 43 | 40 | ||
| 44 | /* Macros for ML7831 */ | 41 | #define PCI_DEVICE_ID_ROHM_ML7223_GBE 0x8013 |
| 45 | #define PCI_DEVICE_ID_ROHM_ML7831_GBE 0x8802 | 42 | #define PCI_DEVICE_ID_ROHM_ML7831_GBE 0x8802 |
| 46 | 43 | ||
| 47 | #define PCH_GBE_TX_WEIGHT 64 | 44 | #define PCH_GBE_TX_WEIGHT 64 |
diff --git a/drivers/pci/controller/Kconfig b/drivers/pci/controller/Kconfig index 6671946dbf66..6012f3059acd 100644 --- a/drivers/pci/controller/Kconfig +++ b/drivers/pci/controller/Kconfig | |||
| @@ -175,7 +175,7 @@ config PCIE_IPROC_MSI | |||
| 175 | 175 | ||
| 176 | config PCIE_ALTERA | 176 | config PCIE_ALTERA |
| 177 | bool "Altera PCIe controller" | 177 | bool "Altera PCIe controller" |
| 178 | depends on ARM || NIOS2 || COMPILE_TEST | 178 | depends on ARM || NIOS2 || ARM64 || COMPILE_TEST |
| 179 | help | 179 | help |
| 180 | Say Y here if you want to enable PCIe controller support on Altera | 180 | Say Y here if you want to enable PCIe controller support on Altera |
| 181 | FPGA. | 181 | FPGA. |
diff --git a/drivers/pci/controller/dwc/Kconfig b/drivers/pci/controller/dwc/Kconfig index 548c58223868..6ea74b1c0d94 100644 --- a/drivers/pci/controller/dwc/Kconfig +++ b/drivers/pci/controller/dwc/Kconfig | |||
| @@ -89,8 +89,8 @@ config PCI_EXYNOS | |||
| 89 | select PCIE_DW_HOST | 89 | select PCIE_DW_HOST |
| 90 | 90 | ||
| 91 | config PCI_IMX6 | 91 | config PCI_IMX6 |
| 92 | bool "Freescale i.MX6/7 PCIe controller" | 92 | bool "Freescale i.MX6/7/8 PCIe controller" |
| 93 | depends on SOC_IMX6Q || SOC_IMX7D || (ARM && COMPILE_TEST) | 93 | depends on SOC_IMX6Q || SOC_IMX7D || (ARM64 && ARCH_MXC) || COMPILE_TEST |
| 94 | depends on PCI_MSI_IRQ_DOMAIN | 94 | depends on PCI_MSI_IRQ_DOMAIN |
| 95 | select PCIE_DW_HOST | 95 | select PCIE_DW_HOST |
| 96 | 96 | ||
diff --git a/drivers/pci/controller/dwc/Makefile b/drivers/pci/controller/dwc/Makefile index 7bcdcdf5024e..b5f3b83cc2b3 100644 --- a/drivers/pci/controller/dwc/Makefile +++ b/drivers/pci/controller/dwc/Makefile | |||
| @@ -8,7 +8,7 @@ obj-$(CONFIG_PCI_EXYNOS) += pci-exynos.o | |||
| 8 | obj-$(CONFIG_PCI_IMX6) += pci-imx6.o | 8 | obj-$(CONFIG_PCI_IMX6) += pci-imx6.o |
| 9 | obj-$(CONFIG_PCIE_SPEAR13XX) += pcie-spear13xx.o | 9 | obj-$(CONFIG_PCIE_SPEAR13XX) += pcie-spear13xx.o |
| 10 | obj-$(CONFIG_PCI_KEYSTONE) += pci-keystone.o | 10 | obj-$(CONFIG_PCI_KEYSTONE) += pci-keystone.o |
| 11 | obj-$(CONFIG_PCI_LAYERSCAPE) += pci-layerscape.o | 11 | obj-$(CONFIG_PCI_LAYERSCAPE) += pci-layerscape.o pci-layerscape-ep.o |
| 12 | obj-$(CONFIG_PCIE_QCOM) += pcie-qcom.o | 12 | obj-$(CONFIG_PCIE_QCOM) += pcie-qcom.o |
| 13 | obj-$(CONFIG_PCIE_ARMADA_8K) += pcie-armada8k.o | 13 | obj-$(CONFIG_PCIE_ARMADA_8K) += pcie-armada8k.o |
| 14 | obj-$(CONFIG_PCIE_ARTPEC6) += pcie-artpec6.o | 14 | obj-$(CONFIG_PCIE_ARTPEC6) += pcie-artpec6.o |
diff --git a/drivers/pci/controller/dwc/pci-dra7xx.c b/drivers/pci/controller/dwc/pci-dra7xx.c index a32d6dde7a57..ae84a69ae63a 100644 --- a/drivers/pci/controller/dwc/pci-dra7xx.c +++ b/drivers/pci/controller/dwc/pci-dra7xx.c | |||
| @@ -81,6 +81,10 @@ | |||
| 81 | #define MSI_REQ_GRANT BIT(0) | 81 | #define MSI_REQ_GRANT BIT(0) |
| 82 | #define MSI_VECTOR_SHIFT 7 | 82 | #define MSI_VECTOR_SHIFT 7 |
| 83 | 83 | ||
| 84 | #define PCIE_1LANE_2LANE_SELECTION BIT(13) | ||
| 85 | #define PCIE_B1C0_MODE_SEL BIT(2) | ||
| 86 | #define PCIE_B0_B1_TSYNCEN BIT(0) | ||
| 87 | |||
| 84 | struct dra7xx_pcie { | 88 | struct dra7xx_pcie { |
| 85 | struct dw_pcie *pci; | 89 | struct dw_pcie *pci; |
| 86 | void __iomem *base; /* DT ti_conf */ | 90 | void __iomem *base; /* DT ti_conf */ |
| @@ -93,6 +97,7 @@ struct dra7xx_pcie { | |||
| 93 | 97 | ||
| 94 | struct dra7xx_pcie_of_data { | 98 | struct dra7xx_pcie_of_data { |
| 95 | enum dw_pcie_device_mode mode; | 99 | enum dw_pcie_device_mode mode; |
| 100 | u32 b1co_mode_sel_mask; | ||
| 96 | }; | 101 | }; |
| 97 | 102 | ||
| 98 | #define to_dra7xx_pcie(x) dev_get_drvdata((x)->dev) | 103 | #define to_dra7xx_pcie(x) dev_get_drvdata((x)->dev) |
| @@ -389,9 +394,22 @@ static int dra7xx_pcie_raise_irq(struct dw_pcie_ep *ep, u8 func_no, | |||
| 389 | return 0; | 394 | return 0; |
| 390 | } | 395 | } |
| 391 | 396 | ||
| 397 | static const struct pci_epc_features dra7xx_pcie_epc_features = { | ||
| 398 | .linkup_notifier = true, | ||
| 399 | .msi_capable = true, | ||
| 400 | .msix_capable = false, | ||
| 401 | }; | ||
| 402 | |||
| 403 | static const struct pci_epc_features* | ||
| 404 | dra7xx_pcie_get_features(struct dw_pcie_ep *ep) | ||
| 405 | { | ||
| 406 | return &dra7xx_pcie_epc_features; | ||
| 407 | } | ||
| 408 | |||
| 392 | static struct dw_pcie_ep_ops pcie_ep_ops = { | 409 | static struct dw_pcie_ep_ops pcie_ep_ops = { |
| 393 | .ep_init = dra7xx_pcie_ep_init, | 410 | .ep_init = dra7xx_pcie_ep_init, |
| 394 | .raise_irq = dra7xx_pcie_raise_irq, | 411 | .raise_irq = dra7xx_pcie_raise_irq, |
| 412 | .get_features = dra7xx_pcie_get_features, | ||
| 395 | }; | 413 | }; |
| 396 | 414 | ||
| 397 | static int __init dra7xx_add_pcie_ep(struct dra7xx_pcie *dra7xx, | 415 | static int __init dra7xx_add_pcie_ep(struct dra7xx_pcie *dra7xx, |
| @@ -499,6 +517,10 @@ static int dra7xx_pcie_enable_phy(struct dra7xx_pcie *dra7xx) | |||
| 499 | int i; | 517 | int i; |
| 500 | 518 | ||
| 501 | for (i = 0; i < phy_count; i++) { | 519 | for (i = 0; i < phy_count; i++) { |
| 520 | ret = phy_set_mode(dra7xx->phy[i], PHY_MODE_PCIE); | ||
| 521 | if (ret < 0) | ||
| 522 | goto err_phy; | ||
| 523 | |||
| 502 | ret = phy_init(dra7xx->phy[i]); | 524 | ret = phy_init(dra7xx->phy[i]); |
| 503 | if (ret < 0) | 525 | if (ret < 0) |
| 504 | goto err_phy; | 526 | goto err_phy; |
| @@ -529,6 +551,26 @@ static const struct dra7xx_pcie_of_data dra7xx_pcie_ep_of_data = { | |||
| 529 | .mode = DW_PCIE_EP_TYPE, | 551 | .mode = DW_PCIE_EP_TYPE, |
| 530 | }; | 552 | }; |
| 531 | 553 | ||
| 554 | static const struct dra7xx_pcie_of_data dra746_pcie_rc_of_data = { | ||
| 555 | .b1co_mode_sel_mask = BIT(2), | ||
| 556 | .mode = DW_PCIE_RC_TYPE, | ||
| 557 | }; | ||
| 558 | |||
| 559 | static const struct dra7xx_pcie_of_data dra726_pcie_rc_of_data = { | ||
| 560 | .b1co_mode_sel_mask = GENMASK(3, 2), | ||
| 561 | .mode = DW_PCIE_RC_TYPE, | ||
| 562 | }; | ||
| 563 | |||
| 564 | static const struct dra7xx_pcie_of_data dra746_pcie_ep_of_data = { | ||
| 565 | .b1co_mode_sel_mask = BIT(2), | ||
| 566 | .mode = DW_PCIE_EP_TYPE, | ||
| 567 | }; | ||
| 568 | |||
| 569 | static const struct dra7xx_pcie_of_data dra726_pcie_ep_of_data = { | ||
| 570 | .b1co_mode_sel_mask = GENMASK(3, 2), | ||
| 571 | .mode = DW_PCIE_EP_TYPE, | ||
| 572 | }; | ||
| 573 | |||
| 532 | static const struct of_device_id of_dra7xx_pcie_match[] = { | 574 | static const struct of_device_id of_dra7xx_pcie_match[] = { |
| 533 | { | 575 | { |
| 534 | .compatible = "ti,dra7-pcie", | 576 | .compatible = "ti,dra7-pcie", |
| @@ -538,6 +580,22 @@ static const struct of_device_id of_dra7xx_pcie_match[] = { | |||
| 538 | .compatible = "ti,dra7-pcie-ep", | 580 | .compatible = "ti,dra7-pcie-ep", |
| 539 | .data = &dra7xx_pcie_ep_of_data, | 581 | .data = &dra7xx_pcie_ep_of_data, |
| 540 | }, | 582 | }, |
| 583 | { | ||
| 584 | .compatible = "ti,dra746-pcie-rc", | ||
| 585 | .data = &dra746_pcie_rc_of_data, | ||
| 586 | }, | ||
| 587 | { | ||
| 588 | .compatible = "ti,dra726-pcie-rc", | ||
| 589 | .data = &dra726_pcie_rc_of_data, | ||
| 590 | }, | ||
| 591 | { | ||
| 592 | .compatible = "ti,dra746-pcie-ep", | ||
| 593 | .data = &dra746_pcie_ep_of_data, | ||
| 594 | }, | ||
| 595 | { | ||
| 596 | .compatible = "ti,dra726-pcie-ep", | ||
| 597 | .data = &dra726_pcie_ep_of_data, | ||
| 598 | }, | ||
| 541 | {}, | 599 | {}, |
| 542 | }; | 600 | }; |
| 543 | 601 | ||
| @@ -583,6 +641,34 @@ static int dra7xx_pcie_unaligned_memaccess(struct device *dev) | |||
| 583 | return ret; | 641 | return ret; |
| 584 | } | 642 | } |
| 585 | 643 | ||
| 644 | static int dra7xx_pcie_configure_two_lane(struct device *dev, | ||
| 645 | u32 b1co_mode_sel_mask) | ||
| 646 | { | ||
| 647 | struct device_node *np = dev->of_node; | ||
| 648 | struct regmap *pcie_syscon; | ||
| 649 | unsigned int pcie_reg; | ||
| 650 | u32 mask; | ||
| 651 | u32 val; | ||
| 652 | |||
| 653 | pcie_syscon = syscon_regmap_lookup_by_phandle(np, "ti,syscon-lane-sel"); | ||
| 654 | if (IS_ERR(pcie_syscon)) { | ||
| 655 | dev_err(dev, "unable to get ti,syscon-lane-sel\n"); | ||
| 656 | return -EINVAL; | ||
| 657 | } | ||
| 658 | |||
| 659 | if (of_property_read_u32_index(np, "ti,syscon-lane-sel", 1, | ||
| 660 | &pcie_reg)) { | ||
| 661 | dev_err(dev, "couldn't get lane selection reg offset\n"); | ||
| 662 | return -EINVAL; | ||
| 663 | } | ||
| 664 | |||
| 665 | mask = b1co_mode_sel_mask | PCIE_B0_B1_TSYNCEN; | ||
| 666 | val = PCIE_B1C0_MODE_SEL | PCIE_B0_B1_TSYNCEN; | ||
| 667 | regmap_update_bits(pcie_syscon, pcie_reg, mask, val); | ||
| 668 | |||
| 669 | return 0; | ||
| 670 | } | ||
| 671 | |||
| 586 | static int __init dra7xx_pcie_probe(struct platform_device *pdev) | 672 | static int __init dra7xx_pcie_probe(struct platform_device *pdev) |
| 587 | { | 673 | { |
| 588 | u32 reg; | 674 | u32 reg; |
| @@ -603,6 +689,7 @@ static int __init dra7xx_pcie_probe(struct platform_device *pdev) | |||
| 603 | const struct of_device_id *match; | 689 | const struct of_device_id *match; |
| 604 | const struct dra7xx_pcie_of_data *data; | 690 | const struct dra7xx_pcie_of_data *data; |
| 605 | enum dw_pcie_device_mode mode; | 691 | enum dw_pcie_device_mode mode; |
| 692 | u32 b1co_mode_sel_mask; | ||
| 606 | 693 | ||
| 607 | match = of_match_device(of_match_ptr(of_dra7xx_pcie_match), dev); | 694 | match = of_match_device(of_match_ptr(of_dra7xx_pcie_match), dev); |
| 608 | if (!match) | 695 | if (!match) |
| @@ -610,6 +697,7 @@ static int __init dra7xx_pcie_probe(struct platform_device *pdev) | |||
| 610 | 697 | ||
| 611 | data = (struct dra7xx_pcie_of_data *)match->data; | 698 | data = (struct dra7xx_pcie_of_data *)match->data; |
| 612 | mode = (enum dw_pcie_device_mode)data->mode; | 699 | mode = (enum dw_pcie_device_mode)data->mode; |
| 700 | b1co_mode_sel_mask = data->b1co_mode_sel_mask; | ||
| 613 | 701 | ||
| 614 | dra7xx = devm_kzalloc(dev, sizeof(*dra7xx), GFP_KERNEL); | 702 | dra7xx = devm_kzalloc(dev, sizeof(*dra7xx), GFP_KERNEL); |
| 615 | if (!dra7xx) | 703 | if (!dra7xx) |
| @@ -665,6 +753,12 @@ static int __init dra7xx_pcie_probe(struct platform_device *pdev) | |||
| 665 | dra7xx->pci = pci; | 753 | dra7xx->pci = pci; |
| 666 | dra7xx->phy_count = phy_count; | 754 | dra7xx->phy_count = phy_count; |
| 667 | 755 | ||
| 756 | if (phy_count == 2) { | ||
| 757 | ret = dra7xx_pcie_configure_two_lane(dev, b1co_mode_sel_mask); | ||
| 758 | if (ret < 0) | ||
| 759 | dra7xx->phy_count = 1; /* Fallback to x1 lane mode */ | ||
| 760 | } | ||
| 761 | |||
| 668 | ret = dra7xx_pcie_enable_phy(dra7xx); | 762 | ret = dra7xx_pcie_enable_phy(dra7xx); |
| 669 | if (ret) { | 763 | if (ret) { |
| 670 | dev_err(dev, "failed to enable phy\n"); | 764 | dev_err(dev, "failed to enable phy\n"); |
diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c index 80f843030e36..3d627f94a166 100644 --- a/drivers/pci/controller/dwc/pci-imx6.c +++ b/drivers/pci/controller/dwc/pci-imx6.c | |||
| @@ -8,6 +8,7 @@ | |||
| 8 | * Author: Sean Cross <xobs@kosagi.com> | 8 | * Author: Sean Cross <xobs@kosagi.com> |
| 9 | */ | 9 | */ |
| 10 | 10 | ||
| 11 | #include <linux/bitfield.h> | ||
| 11 | #include <linux/clk.h> | 12 | #include <linux/clk.h> |
| 12 | #include <linux/delay.h> | 13 | #include <linux/delay.h> |
| 13 | #include <linux/gpio.h> | 14 | #include <linux/gpio.h> |
| @@ -18,6 +19,7 @@ | |||
| 18 | #include <linux/module.h> | 19 | #include <linux/module.h> |
| 19 | #include <linux/of_gpio.h> | 20 | #include <linux/of_gpio.h> |
| 20 | #include <linux/of_device.h> | 21 | #include <linux/of_device.h> |
| 22 | #include <linux/of_address.h> | ||
| 21 | #include <linux/pci.h> | 23 | #include <linux/pci.h> |
| 22 | #include <linux/platform_device.h> | 24 | #include <linux/platform_device.h> |
| 23 | #include <linux/regmap.h> | 25 | #include <linux/regmap.h> |
| @@ -32,6 +34,12 @@ | |||
| 32 | 34 | ||
| 33 | #include "pcie-designware.h" | 35 | #include "pcie-designware.h" |
| 34 | 36 | ||
| 37 | #define IMX8MQ_GPR_PCIE_REF_USE_PAD BIT(9) | ||
| 38 | #define IMX8MQ_GPR_PCIE_CLK_REQ_OVERRIDE_EN BIT(10) | ||
| 39 | #define IMX8MQ_GPR_PCIE_CLK_REQ_OVERRIDE BIT(11) | ||
| 40 | #define IMX8MQ_GPR12_PCIE2_CTRL_DEVICE_TYPE GENMASK(11, 8) | ||
| 41 | #define IMX8MQ_PCIE2_BASE_ADDR 0x33c00000 | ||
| 42 | |||
| 35 | #define to_imx6_pcie(x) dev_get_drvdata((x)->dev) | 43 | #define to_imx6_pcie(x) dev_get_drvdata((x)->dev) |
| 36 | 44 | ||
| 37 | enum imx6_pcie_variants { | 45 | enum imx6_pcie_variants { |
| @@ -39,6 +47,15 @@ enum imx6_pcie_variants { | |||
| 39 | IMX6SX, | 47 | IMX6SX, |
| 40 | IMX6QP, | 48 | IMX6QP, |
| 41 | IMX7D, | 49 | IMX7D, |
| 50 | IMX8MQ, | ||
| 51 | }; | ||
| 52 | |||
| 53 | #define IMX6_PCIE_FLAG_IMX6_PHY BIT(0) | ||
| 54 | #define IMX6_PCIE_FLAG_IMX6_SPEED_CHANGE BIT(1) | ||
| 55 | |||
| 56 | struct imx6_pcie_drvdata { | ||
| 57 | enum imx6_pcie_variants variant; | ||
| 58 | u32 flags; | ||
| 42 | }; | 59 | }; |
| 43 | 60 | ||
| 44 | struct imx6_pcie { | 61 | struct imx6_pcie { |
| @@ -49,11 +66,12 @@ struct imx6_pcie { | |||
| 49 | struct clk *pcie_phy; | 66 | struct clk *pcie_phy; |
| 50 | struct clk *pcie_inbound_axi; | 67 | struct clk *pcie_inbound_axi; |
| 51 | struct clk *pcie; | 68 | struct clk *pcie; |
| 69 | struct clk *pcie_aux; | ||
| 52 | struct regmap *iomuxc_gpr; | 70 | struct regmap *iomuxc_gpr; |
| 71 | u32 controller_id; | ||
| 53 | struct reset_control *pciephy_reset; | 72 | struct reset_control *pciephy_reset; |
| 54 | struct reset_control *apps_reset; | 73 | struct reset_control *apps_reset; |
| 55 | struct reset_control *turnoff_reset; | 74 | struct reset_control *turnoff_reset; |
| 56 | enum imx6_pcie_variants variant; | ||
| 57 | u32 tx_deemph_gen1; | 75 | u32 tx_deemph_gen1; |
| 58 | u32 tx_deemph_gen2_3p5db; | 76 | u32 tx_deemph_gen2_3p5db; |
| 59 | u32 tx_deemph_gen2_6db; | 77 | u32 tx_deemph_gen2_6db; |
| @@ -61,11 +79,13 @@ struct imx6_pcie { | |||
| 61 | u32 tx_swing_low; | 79 | u32 tx_swing_low; |
| 62 | int link_gen; | 80 | int link_gen; |
| 63 | struct regulator *vpcie; | 81 | struct regulator *vpcie; |
| 82 | void __iomem *phy_base; | ||
| 64 | 83 | ||
| 65 | /* power domain for pcie */ | 84 | /* power domain for pcie */ |
| 66 | struct device *pd_pcie; | 85 | struct device *pd_pcie; |
| 67 | /* power domain for pcie phy */ | 86 | /* power domain for pcie phy */ |
| 68 | struct device *pd_pcie_phy; | 87 | struct device *pd_pcie_phy; |
| 88 | const struct imx6_pcie_drvdata *drvdata; | ||
| 69 | }; | 89 | }; |
| 70 | 90 | ||
| 71 | /* Parameters for the waiting for PCIe PHY PLL to lock on i.MX7 */ | 91 | /* Parameters for the waiting for PCIe PHY PLL to lock on i.MX7 */ |
| @@ -101,7 +121,6 @@ struct imx6_pcie { | |||
| 101 | #define PCIE_PHY_STAT_ACK_LOC 16 | 121 | #define PCIE_PHY_STAT_ACK_LOC 16 |
| 102 | 122 | ||
| 103 | #define PCIE_LINK_WIDTH_SPEED_CONTROL 0x80C | 123 | #define PCIE_LINK_WIDTH_SPEED_CONTROL 0x80C |
| 104 | #define PORT_LOGIC_SPEED_CHANGE (0x1 << 17) | ||
| 105 | 124 | ||
| 106 | /* PHY registers (not memory-mapped) */ | 125 | /* PHY registers (not memory-mapped) */ |
| 107 | #define PCIE_PHY_ATEOVRD 0x10 | 126 | #define PCIE_PHY_ATEOVRD 0x10 |
| @@ -117,6 +136,23 @@ struct imx6_pcie { | |||
| 117 | #define PCIE_PHY_RX_ASIC_OUT 0x100D | 136 | #define PCIE_PHY_RX_ASIC_OUT 0x100D |
| 118 | #define PCIE_PHY_RX_ASIC_OUT_VALID (1 << 0) | 137 | #define PCIE_PHY_RX_ASIC_OUT_VALID (1 << 0) |
| 119 | 138 | ||
| 139 | /* iMX7 PCIe PHY registers */ | ||
| 140 | #define PCIE_PHY_CMN_REG4 0x14 | ||
| 141 | /* These are probably the bits that *aren't* DCC_FB_EN */ | ||
| 142 | #define PCIE_PHY_CMN_REG4_DCC_FB_EN 0x29 | ||
| 143 | |||
| 144 | #define PCIE_PHY_CMN_REG15 0x54 | ||
| 145 | #define PCIE_PHY_CMN_REG15_DLY_4 BIT(2) | ||
| 146 | #define PCIE_PHY_CMN_REG15_PLL_PD BIT(5) | ||
| 147 | #define PCIE_PHY_CMN_REG15_OVRD_PLL_PD BIT(7) | ||
| 148 | |||
| 149 | #define PCIE_PHY_CMN_REG24 0x90 | ||
| 150 | #define PCIE_PHY_CMN_REG24_RX_EQ BIT(6) | ||
| 151 | #define PCIE_PHY_CMN_REG24_RX_EQ_SEL BIT(3) | ||
| 152 | |||
| 153 | #define PCIE_PHY_CMN_REG26 0x98 | ||
| 154 | #define PCIE_PHY_CMN_REG26_ATT_MODE 0xBC | ||
| 155 | |||
| 120 | #define PHY_RX_OVRD_IN_LO 0x1005 | 156 | #define PHY_RX_OVRD_IN_LO 0x1005 |
| 121 | #define PHY_RX_OVRD_IN_LO_RX_DATA_EN (1 << 5) | 157 | #define PHY_RX_OVRD_IN_LO_RX_DATA_EN (1 << 5) |
| 122 | #define PHY_RX_OVRD_IN_LO_RX_PLL_EN (1 << 3) | 158 | #define PHY_RX_OVRD_IN_LO_RX_PLL_EN (1 << 3) |
| @@ -251,6 +287,9 @@ static void imx6_pcie_reset_phy(struct imx6_pcie *imx6_pcie) | |||
| 251 | { | 287 | { |
| 252 | u32 tmp; | 288 | u32 tmp; |
| 253 | 289 | ||
| 290 | if (!(imx6_pcie->drvdata->flags & IMX6_PCIE_FLAG_IMX6_PHY)) | ||
| 291 | return; | ||
| 292 | |||
| 254 | pcie_phy_read(imx6_pcie, PHY_RX_OVRD_IN_LO, &tmp); | 293 | pcie_phy_read(imx6_pcie, PHY_RX_OVRD_IN_LO, &tmp); |
| 255 | tmp |= (PHY_RX_OVRD_IN_LO_RX_DATA_EN | | 294 | tmp |= (PHY_RX_OVRD_IN_LO_RX_DATA_EN | |
| 256 | PHY_RX_OVRD_IN_LO_RX_PLL_EN); | 295 | PHY_RX_OVRD_IN_LO_RX_PLL_EN); |
| @@ -264,6 +303,7 @@ static void imx6_pcie_reset_phy(struct imx6_pcie *imx6_pcie) | |||
| 264 | pcie_phy_write(imx6_pcie, PHY_RX_OVRD_IN_LO, tmp); | 303 | pcie_phy_write(imx6_pcie, PHY_RX_OVRD_IN_LO, tmp); |
| 265 | } | 304 | } |
| 266 | 305 | ||
| 306 | #ifdef CONFIG_ARM | ||
| 267 | /* Added for PCI abort handling */ | 307 | /* Added for PCI abort handling */ |
| 268 | static int imx6q_pcie_abort_handler(unsigned long addr, | 308 | static int imx6q_pcie_abort_handler(unsigned long addr, |
| 269 | unsigned int fsr, struct pt_regs *regs) | 309 | unsigned int fsr, struct pt_regs *regs) |
| @@ -297,6 +337,7 @@ static int imx6q_pcie_abort_handler(unsigned long addr, | |||
| 297 | 337 | ||
| 298 | return 1; | 338 | return 1; |
| 299 | } | 339 | } |
| 340 | #endif | ||
| 300 | 341 | ||
| 301 | static int imx6_pcie_attach_pd(struct device *dev) | 342 | static int imx6_pcie_attach_pd(struct device *dev) |
| 302 | { | 343 | { |
| @@ -342,8 +383,9 @@ static void imx6_pcie_assert_core_reset(struct imx6_pcie *imx6_pcie) | |||
| 342 | { | 383 | { |
| 343 | struct device *dev = imx6_pcie->pci->dev; | 384 | struct device *dev = imx6_pcie->pci->dev; |
| 344 | 385 | ||
| 345 | switch (imx6_pcie->variant) { | 386 | switch (imx6_pcie->drvdata->variant) { |
| 346 | case IMX7D: | 387 | case IMX7D: |
| 388 | case IMX8MQ: | ||
| 347 | reset_control_assert(imx6_pcie->pciephy_reset); | 389 | reset_control_assert(imx6_pcie->pciephy_reset); |
| 348 | reset_control_assert(imx6_pcie->apps_reset); | 390 | reset_control_assert(imx6_pcie->apps_reset); |
| 349 | break; | 391 | break; |
| @@ -378,13 +420,20 @@ static void imx6_pcie_assert_core_reset(struct imx6_pcie *imx6_pcie) | |||
| 378 | } | 420 | } |
| 379 | } | 421 | } |
| 380 | 422 | ||
| 423 | static unsigned int imx6_pcie_grp_offset(const struct imx6_pcie *imx6_pcie) | ||
| 424 | { | ||
| 425 | WARN_ON(imx6_pcie->drvdata->variant != IMX8MQ); | ||
| 426 | return imx6_pcie->controller_id == 1 ? IOMUXC_GPR16 : IOMUXC_GPR14; | ||
| 427 | } | ||
| 428 | |||
| 381 | static int imx6_pcie_enable_ref_clk(struct imx6_pcie *imx6_pcie) | 429 | static int imx6_pcie_enable_ref_clk(struct imx6_pcie *imx6_pcie) |
| 382 | { | 430 | { |
| 383 | struct dw_pcie *pci = imx6_pcie->pci; | 431 | struct dw_pcie *pci = imx6_pcie->pci; |
| 384 | struct device *dev = pci->dev; | 432 | struct device *dev = pci->dev; |
| 433 | unsigned int offset; | ||
| 385 | int ret = 0; | 434 | int ret = 0; |
| 386 | 435 | ||
| 387 | switch (imx6_pcie->variant) { | 436 | switch (imx6_pcie->drvdata->variant) { |
| 388 | case IMX6SX: | 437 | case IMX6SX: |
| 389 | ret = clk_prepare_enable(imx6_pcie->pcie_inbound_axi); | 438 | ret = clk_prepare_enable(imx6_pcie->pcie_inbound_axi); |
| 390 | if (ret) { | 439 | if (ret) { |
| @@ -412,6 +461,25 @@ static int imx6_pcie_enable_ref_clk(struct imx6_pcie *imx6_pcie) | |||
| 412 | break; | 461 | break; |
| 413 | case IMX7D: | 462 | case IMX7D: |
| 414 | break; | 463 | break; |
| 464 | case IMX8MQ: | ||
| 465 | ret = clk_prepare_enable(imx6_pcie->pcie_aux); | ||
| 466 | if (ret) { | ||
| 467 | dev_err(dev, "unable to enable pcie_aux clock\n"); | ||
| 468 | break; | ||
| 469 | } | ||
| 470 | |||
| 471 | offset = imx6_pcie_grp_offset(imx6_pcie); | ||
| 472 | /* | ||
| 473 | * Set the over ride low and enabled | ||
| 474 | * make sure that REF_CLK is turned on. | ||
| 475 | */ | ||
| 476 | regmap_update_bits(imx6_pcie->iomuxc_gpr, offset, | ||
| 477 | IMX8MQ_GPR_PCIE_CLK_REQ_OVERRIDE, | ||
| 478 | 0); | ||
| 479 | regmap_update_bits(imx6_pcie->iomuxc_gpr, offset, | ||
| 480 | IMX8MQ_GPR_PCIE_CLK_REQ_OVERRIDE_EN, | ||
| 481 | IMX8MQ_GPR_PCIE_CLK_REQ_OVERRIDE_EN); | ||
| 482 | break; | ||
| 415 | } | 483 | } |
| 416 | 484 | ||
| 417 | return ret; | 485 | return ret; |
| @@ -487,9 +555,32 @@ static void imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie) | |||
| 487 | !imx6_pcie->gpio_active_high); | 555 | !imx6_pcie->gpio_active_high); |
| 488 | } | 556 | } |
| 489 | 557 | ||
| 490 | switch (imx6_pcie->variant) { | 558 | switch (imx6_pcie->drvdata->variant) { |
| 559 | case IMX8MQ: | ||
| 560 | reset_control_deassert(imx6_pcie->pciephy_reset); | ||
| 561 | break; | ||
| 491 | case IMX7D: | 562 | case IMX7D: |
| 492 | reset_control_deassert(imx6_pcie->pciephy_reset); | 563 | reset_control_deassert(imx6_pcie->pciephy_reset); |
| 564 | |||
| 565 | /* Workaround for ERR010728, failure of PCI-e PLL VCO to | ||
| 566 | * oscillate, especially when cold. This turns off "Duty-cycle | ||
| 567 | * Corrector" and other mysterious undocumented things. | ||
| 568 | */ | ||
| 569 | if (likely(imx6_pcie->phy_base)) { | ||
| 570 | /* De-assert DCC_FB_EN */ | ||
| 571 | writel(PCIE_PHY_CMN_REG4_DCC_FB_EN, | ||
| 572 | imx6_pcie->phy_base + PCIE_PHY_CMN_REG4); | ||
| 573 | /* Assert RX_EQS and RX_EQS_SEL */ | ||
| 574 | writel(PCIE_PHY_CMN_REG24_RX_EQ_SEL | ||
| 575 | | PCIE_PHY_CMN_REG24_RX_EQ, | ||
| 576 | imx6_pcie->phy_base + PCIE_PHY_CMN_REG24); | ||
| 577 | /* Assert ATT_MODE */ | ||
| 578 | writel(PCIE_PHY_CMN_REG26_ATT_MODE, | ||
| 579 | imx6_pcie->phy_base + PCIE_PHY_CMN_REG26); | ||
| 580 | } else { | ||
| 581 | dev_warn(dev, "Unable to apply ERR010728 workaround. DT missing fsl,imx7d-pcie-phy phandle ?\n"); | ||
| 582 | } | ||
| 583 | |||
| 493 | imx7d_pcie_wait_for_phy_pll_lock(imx6_pcie); | 584 | imx7d_pcie_wait_for_phy_pll_lock(imx6_pcie); |
| 494 | break; | 585 | break; |
| 495 | case IMX6SX: | 586 | case IMX6SX: |
| @@ -523,9 +614,37 @@ err_pcie_phy: | |||
| 523 | } | 614 | } |
| 524 | } | 615 | } |
| 525 | 616 | ||
| 617 | static void imx6_pcie_configure_type(struct imx6_pcie *imx6_pcie) | ||
| 618 | { | ||
| 619 | unsigned int mask, val; | ||
| 620 | |||
| 621 | if (imx6_pcie->drvdata->variant == IMX8MQ && | ||
| 622 | imx6_pcie->controller_id == 1) { | ||
| 623 | mask = IMX8MQ_GPR12_PCIE2_CTRL_DEVICE_TYPE; | ||
| 624 | val = FIELD_PREP(IMX8MQ_GPR12_PCIE2_CTRL_DEVICE_TYPE, | ||
| 625 | PCI_EXP_TYPE_ROOT_PORT); | ||
| 626 | } else { | ||
| 627 | mask = IMX6Q_GPR12_DEVICE_TYPE; | ||
| 628 | val = FIELD_PREP(IMX6Q_GPR12_DEVICE_TYPE, | ||
| 629 | PCI_EXP_TYPE_ROOT_PORT); | ||
| 630 | } | ||
| 631 | |||
| 632 | regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, mask, val); | ||
| 633 | } | ||
| 634 | |||
| 526 | static void imx6_pcie_init_phy(struct imx6_pcie *imx6_pcie) | 635 | static void imx6_pcie_init_phy(struct imx6_pcie *imx6_pcie) |
| 527 | { | 636 | { |
| 528 | switch (imx6_pcie->variant) { | 637 | switch (imx6_pcie->drvdata->variant) { |
| 638 | case IMX8MQ: | ||
| 639 | /* | ||
| 640 | * TODO: Currently this code assumes external | ||
| 641 | * oscillator is being used | ||
| 642 | */ | ||
| 643 | regmap_update_bits(imx6_pcie->iomuxc_gpr, | ||
| 644 | imx6_pcie_grp_offset(imx6_pcie), | ||
| 645 | IMX8MQ_GPR_PCIE_REF_USE_PAD, | ||
| 646 | IMX8MQ_GPR_PCIE_REF_USE_PAD); | ||
| 647 | break; | ||
| 529 | case IMX7D: | 648 | case IMX7D: |
| 530 | regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, | 649 | regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, |
| 531 | IMX7D_GPR12_PCIE_PHY_REFCLK_SEL, 0); | 650 | IMX7D_GPR12_PCIE_PHY_REFCLK_SEL, 0); |
| @@ -561,8 +680,7 @@ static void imx6_pcie_init_phy(struct imx6_pcie *imx6_pcie) | |||
| 561 | break; | 680 | break; |
| 562 | } | 681 | } |
| 563 | 682 | ||
| 564 | regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, | 683 | imx6_pcie_configure_type(imx6_pcie); |
| 565 | IMX6Q_GPR12_DEVICE_TYPE, PCI_EXP_TYPE_ROOT_PORT << 12); | ||
| 566 | } | 684 | } |
| 567 | 685 | ||
| 568 | static int imx6_setup_phy_mpll(struct imx6_pcie *imx6_pcie) | 686 | static int imx6_setup_phy_mpll(struct imx6_pcie *imx6_pcie) |
| @@ -571,6 +689,9 @@ static int imx6_setup_phy_mpll(struct imx6_pcie *imx6_pcie) | |||
| 571 | int mult, div; | 689 | int mult, div; |
| 572 | u32 val; | 690 | u32 val; |
| 573 | 691 | ||
| 692 | if (!(imx6_pcie->drvdata->flags & IMX6_PCIE_FLAG_IMX6_PHY)) | ||
| 693 | return 0; | ||
| 694 | |||
| 574 | switch (phy_rate) { | 695 | switch (phy_rate) { |
| 575 | case 125000000: | 696 | case 125000000: |
| 576 | /* | 697 | /* |
| @@ -647,7 +768,7 @@ static void imx6_pcie_ltssm_enable(struct device *dev) | |||
| 647 | { | 768 | { |
| 648 | struct imx6_pcie *imx6_pcie = dev_get_drvdata(dev); | 769 | struct imx6_pcie *imx6_pcie = dev_get_drvdata(dev); |
| 649 | 770 | ||
| 650 | switch (imx6_pcie->variant) { | 771 | switch (imx6_pcie->drvdata->variant) { |
| 651 | case IMX6Q: | 772 | case IMX6Q: |
| 652 | case IMX6SX: | 773 | case IMX6SX: |
| 653 | case IMX6QP: | 774 | case IMX6QP: |
| @@ -656,6 +777,7 @@ static void imx6_pcie_ltssm_enable(struct device *dev) | |||
| 656 | IMX6Q_GPR12_PCIE_CTL_2); | 777 | IMX6Q_GPR12_PCIE_CTL_2); |
| 657 | break; | 778 | break; |
| 658 | case IMX7D: | 779 | case IMX7D: |
| 780 | case IMX8MQ: | ||
| 659 | reset_control_deassert(imx6_pcie->apps_reset); | 781 | reset_control_deassert(imx6_pcie->apps_reset); |
| 660 | break; | 782 | break; |
| 661 | } | 783 | } |
| @@ -700,7 +822,8 @@ static int imx6_pcie_establish_link(struct imx6_pcie *imx6_pcie) | |||
| 700 | tmp |= PORT_LOGIC_SPEED_CHANGE; | 822 | tmp |= PORT_LOGIC_SPEED_CHANGE; |
| 701 | dw_pcie_writel_dbi(pci, PCIE_LINK_WIDTH_SPEED_CONTROL, tmp); | 823 | dw_pcie_writel_dbi(pci, PCIE_LINK_WIDTH_SPEED_CONTROL, tmp); |
| 702 | 824 | ||
| 703 | if (imx6_pcie->variant != IMX7D) { | 825 | if (imx6_pcie->drvdata->flags & |
| 826 | IMX6_PCIE_FLAG_IMX6_SPEED_CHANGE) { | ||
| 704 | /* | 827 | /* |
| 705 | * On i.MX7, DIRECT_SPEED_CHANGE behaves differently | 828 | * On i.MX7, DIRECT_SPEED_CHANGE behaves differently |
| 706 | * from i.MX6 family when no link speed transition | 829 | * from i.MX6 family when no link speed transition |
| @@ -797,7 +920,7 @@ static void imx6_pcie_ltssm_disable(struct device *dev) | |||
| 797 | { | 920 | { |
| 798 | struct imx6_pcie *imx6_pcie = dev_get_drvdata(dev); | 921 | struct imx6_pcie *imx6_pcie = dev_get_drvdata(dev); |
| 799 | 922 | ||
| 800 | switch (imx6_pcie->variant) { | 923 | switch (imx6_pcie->drvdata->variant) { |
| 801 | case IMX6SX: | 924 | case IMX6SX: |
| 802 | case IMX6QP: | 925 | case IMX6QP: |
| 803 | regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, | 926 | regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, |
| @@ -823,7 +946,7 @@ static void imx6_pcie_pm_turnoff(struct imx6_pcie *imx6_pcie) | |||
| 823 | } | 946 | } |
| 824 | 947 | ||
| 825 | /* Others poke directly at IOMUXC registers */ | 948 | /* Others poke directly at IOMUXC registers */ |
| 826 | switch (imx6_pcie->variant) { | 949 | switch (imx6_pcie->drvdata->variant) { |
| 827 | case IMX6SX: | 950 | case IMX6SX: |
| 828 | regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, | 951 | regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, |
| 829 | IMX6SX_GPR12_PCIE_PM_TURN_OFF, | 952 | IMX6SX_GPR12_PCIE_PM_TURN_OFF, |
| @@ -853,7 +976,7 @@ static void imx6_pcie_clk_disable(struct imx6_pcie *imx6_pcie) | |||
| 853 | clk_disable_unprepare(imx6_pcie->pcie_phy); | 976 | clk_disable_unprepare(imx6_pcie->pcie_phy); |
| 854 | clk_disable_unprepare(imx6_pcie->pcie_bus); | 977 | clk_disable_unprepare(imx6_pcie->pcie_bus); |
| 855 | 978 | ||
| 856 | switch (imx6_pcie->variant) { | 979 | switch (imx6_pcie->drvdata->variant) { |
| 857 | case IMX6SX: | 980 | case IMX6SX: |
| 858 | clk_disable_unprepare(imx6_pcie->pcie_inbound_axi); | 981 | clk_disable_unprepare(imx6_pcie->pcie_inbound_axi); |
| 859 | break; | 982 | break; |
| @@ -862,6 +985,9 @@ static void imx6_pcie_clk_disable(struct imx6_pcie *imx6_pcie) | |||
| 862 | IMX7D_GPR12_PCIE_PHY_REFCLK_SEL, | 985 | IMX7D_GPR12_PCIE_PHY_REFCLK_SEL, |
| 863 | IMX7D_GPR12_PCIE_PHY_REFCLK_SEL); | 986 | IMX7D_GPR12_PCIE_PHY_REFCLK_SEL); |
| 864 | break; | 987 | break; |
| 988 | case IMX8MQ: | ||
| 989 | clk_disable_unprepare(imx6_pcie->pcie_aux); | ||
| 990 | break; | ||
| 865 | default: | 991 | default: |
| 866 | break; | 992 | break; |
| 867 | } | 993 | } |
| @@ -869,8 +995,8 @@ static void imx6_pcie_clk_disable(struct imx6_pcie *imx6_pcie) | |||
| 869 | 995 | ||
| 870 | static inline bool imx6_pcie_supports_suspend(struct imx6_pcie *imx6_pcie) | 996 | static inline bool imx6_pcie_supports_suspend(struct imx6_pcie *imx6_pcie) |
| 871 | { | 997 | { |
| 872 | return (imx6_pcie->variant == IMX7D || | 998 | return (imx6_pcie->drvdata->variant == IMX7D || |
| 873 | imx6_pcie->variant == IMX6SX); | 999 | imx6_pcie->drvdata->variant == IMX6SX); |
| 874 | } | 1000 | } |
| 875 | 1001 | ||
| 876 | static int imx6_pcie_suspend_noirq(struct device *dev) | 1002 | static int imx6_pcie_suspend_noirq(struct device *dev) |
| @@ -919,6 +1045,7 @@ static int imx6_pcie_probe(struct platform_device *pdev) | |||
| 919 | struct device *dev = &pdev->dev; | 1045 | struct device *dev = &pdev->dev; |
| 920 | struct dw_pcie *pci; | 1046 | struct dw_pcie *pci; |
| 921 | struct imx6_pcie *imx6_pcie; | 1047 | struct imx6_pcie *imx6_pcie; |
| 1048 | struct device_node *np; | ||
| 922 | struct resource *dbi_base; | 1049 | struct resource *dbi_base; |
| 923 | struct device_node *node = dev->of_node; | 1050 | struct device_node *node = dev->of_node; |
| 924 | int ret; | 1051 | int ret; |
| @@ -936,8 +1063,24 @@ static int imx6_pcie_probe(struct platform_device *pdev) | |||
| 936 | pci->ops = &dw_pcie_ops; | 1063 | pci->ops = &dw_pcie_ops; |
| 937 | 1064 | ||
| 938 | imx6_pcie->pci = pci; | 1065 | imx6_pcie->pci = pci; |
| 939 | imx6_pcie->variant = | 1066 | imx6_pcie->drvdata = of_device_get_match_data(dev); |
| 940 | (enum imx6_pcie_variants)of_device_get_match_data(dev); | 1067 | |
| 1068 | /* Find the PHY if one is defined, only imx7d uses it */ | ||
| 1069 | np = of_parse_phandle(node, "fsl,imx7d-pcie-phy", 0); | ||
| 1070 | if (np) { | ||
| 1071 | struct resource res; | ||
| 1072 | |||
| 1073 | ret = of_address_to_resource(np, 0, &res); | ||
| 1074 | if (ret) { | ||
| 1075 | dev_err(dev, "Unable to map PCIe PHY\n"); | ||
| 1076 | return ret; | ||
| 1077 | } | ||
| 1078 | imx6_pcie->phy_base = devm_ioremap_resource(dev, &res); | ||
| 1079 | if (IS_ERR(imx6_pcie->phy_base)) { | ||
| 1080 | dev_err(dev, "Unable to map PCIe PHY\n"); | ||
| 1081 | return PTR_ERR(imx6_pcie->phy_base); | ||
| 1082 | } | ||
| 1083 | } | ||
| 941 | 1084 | ||
| 942 | dbi_base = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1085 | dbi_base = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 943 | pci->dbi_base = devm_ioremap_resource(dev, dbi_base); | 1086 | pci->dbi_base = devm_ioremap_resource(dev, dbi_base); |
| @@ -981,7 +1124,7 @@ static int imx6_pcie_probe(struct platform_device *pdev) | |||
| 981 | return PTR_ERR(imx6_pcie->pcie); | 1124 | return PTR_ERR(imx6_pcie->pcie); |
| 982 | } | 1125 | } |
| 983 | 1126 | ||
| 984 | switch (imx6_pcie->variant) { | 1127 | switch (imx6_pcie->drvdata->variant) { |
| 985 | case IMX6SX: | 1128 | case IMX6SX: |
| 986 | imx6_pcie->pcie_inbound_axi = devm_clk_get(dev, | 1129 | imx6_pcie->pcie_inbound_axi = devm_clk_get(dev, |
| 987 | "pcie_inbound_axi"); | 1130 | "pcie_inbound_axi"); |
| @@ -990,7 +1133,17 @@ static int imx6_pcie_probe(struct platform_device *pdev) | |||
| 990 | return PTR_ERR(imx6_pcie->pcie_inbound_axi); | 1133 | return PTR_ERR(imx6_pcie->pcie_inbound_axi); |
| 991 | } | 1134 | } |
| 992 | break; | 1135 | break; |
| 1136 | case IMX8MQ: | ||
| 1137 | imx6_pcie->pcie_aux = devm_clk_get(dev, "pcie_aux"); | ||
| 1138 | if (IS_ERR(imx6_pcie->pcie_aux)) { | ||
| 1139 | dev_err(dev, "pcie_aux clock source missing or invalid\n"); | ||
| 1140 | return PTR_ERR(imx6_pcie->pcie_aux); | ||
| 1141 | } | ||
| 1142 | /* fall through */ | ||
| 993 | case IMX7D: | 1143 | case IMX7D: |
| 1144 | if (dbi_base->start == IMX8MQ_PCIE2_BASE_ADDR) | ||
| 1145 | imx6_pcie->controller_id = 1; | ||
| 1146 | |||
| 994 | imx6_pcie->pciephy_reset = devm_reset_control_get_exclusive(dev, | 1147 | imx6_pcie->pciephy_reset = devm_reset_control_get_exclusive(dev, |
| 995 | "pciephy"); | 1148 | "pciephy"); |
| 996 | if (IS_ERR(imx6_pcie->pciephy_reset)) { | 1149 | if (IS_ERR(imx6_pcie->pciephy_reset)) { |
| @@ -1087,11 +1240,36 @@ static void imx6_pcie_shutdown(struct platform_device *pdev) | |||
| 1087 | imx6_pcie_assert_core_reset(imx6_pcie); | 1240 | imx6_pcie_assert_core_reset(imx6_pcie); |
| 1088 | } | 1241 | } |
| 1089 | 1242 | ||
| 1243 | static const struct imx6_pcie_drvdata drvdata[] = { | ||
| 1244 | [IMX6Q] = { | ||
| 1245 | .variant = IMX6Q, | ||
| 1246 | .flags = IMX6_PCIE_FLAG_IMX6_PHY | | ||
| 1247 | IMX6_PCIE_FLAG_IMX6_SPEED_CHANGE, | ||
| 1248 | }, | ||
| 1249 | [IMX6SX] = { | ||
| 1250 | .variant = IMX6SX, | ||
| 1251 | .flags = IMX6_PCIE_FLAG_IMX6_PHY | | ||
| 1252 | IMX6_PCIE_FLAG_IMX6_SPEED_CHANGE, | ||
| 1253 | }, | ||
| 1254 | [IMX6QP] = { | ||
| 1255 | .variant = IMX6QP, | ||
| 1256 | .flags = IMX6_PCIE_FLAG_IMX6_PHY | | ||
| 1257 | IMX6_PCIE_FLAG_IMX6_SPEED_CHANGE, | ||
| 1258 | }, | ||
| 1259 | [IMX7D] = { | ||
| 1260 | .variant = IMX7D, | ||
| 1261 | }, | ||
| 1262 | [IMX8MQ] = { | ||
| 1263 | .variant = IMX8MQ, | ||
| 1264 | }, | ||
| 1265 | }; | ||
| 1266 | |||
| 1090 | static const struct of_device_id imx6_pcie_of_match[] = { | 1267 | static const struct of_device_id imx6_pcie_of_match[] = { |
| 1091 | { .compatible = "fsl,imx6q-pcie", .data = (void *)IMX6Q, }, | 1268 | { .compatible = "fsl,imx6q-pcie", .data = &drvdata[IMX6Q], }, |
| 1092 | { .compatible = "fsl,imx6sx-pcie", .data = (void *)IMX6SX, }, | 1269 | { .compatible = "fsl,imx6sx-pcie", .data = &drvdata[IMX6SX], }, |
| 1093 | { .compatible = "fsl,imx6qp-pcie", .data = (void *)IMX6QP, }, | 1270 | { .compatible = "fsl,imx6qp-pcie", .data = &drvdata[IMX6QP], }, |
| 1094 | { .compatible = "fsl,imx7d-pcie", .data = (void *)IMX7D, }, | 1271 | { .compatible = "fsl,imx7d-pcie", .data = &drvdata[IMX7D], }, |
| 1272 | { .compatible = "fsl,imx8mq-pcie", .data = &drvdata[IMX8MQ], } , | ||
| 1095 | {}, | 1273 | {}, |
| 1096 | }; | 1274 | }; |
| 1097 | 1275 | ||
| @@ -1108,6 +1286,7 @@ static struct platform_driver imx6_pcie_driver = { | |||
| 1108 | 1286 | ||
| 1109 | static int __init imx6_pcie_init(void) | 1287 | static int __init imx6_pcie_init(void) |
| 1110 | { | 1288 | { |
| 1289 | #ifdef CONFIG_ARM | ||
| 1111 | /* | 1290 | /* |
| 1112 | * Since probe() can be deferred we need to make sure that | 1291 | * Since probe() can be deferred we need to make sure that |
| 1113 | * hook_fault_code is not called after __init memory is freed | 1292 | * hook_fault_code is not called after __init memory is freed |
| @@ -1117,6 +1296,7 @@ static int __init imx6_pcie_init(void) | |||
| 1117 | */ | 1296 | */ |
| 1118 | hook_fault_code(8, imx6q_pcie_abort_handler, SIGBUS, 0, | 1297 | hook_fault_code(8, imx6q_pcie_abort_handler, SIGBUS, 0, |
| 1119 | "external abort on non-linefetch"); | 1298 | "external abort on non-linefetch"); |
| 1299 | #endif | ||
| 1120 | 1300 | ||
| 1121 | return platform_driver_register(&imx6_pcie_driver); | 1301 | return platform_driver_register(&imx6_pcie_driver); |
| 1122 | } | 1302 | } |
diff --git a/drivers/pci/controller/dwc/pci-layerscape-ep.c b/drivers/pci/controller/dwc/pci-layerscape-ep.c new file mode 100644 index 000000000000..a42c9c3ae1cc --- /dev/null +++ b/drivers/pci/controller/dwc/pci-layerscape-ep.c | |||
| @@ -0,0 +1,156 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | ||
| 2 | /* | ||
| 3 | * PCIe controller EP driver for Freescale Layerscape SoCs | ||
| 4 | * | ||
| 5 | * Copyright (C) 2018 NXP Semiconductor. | ||
| 6 | * | ||
| 7 | * Author: Xiaowei Bao <xiaowei.bao@nxp.com> | ||
| 8 | */ | ||
| 9 | |||
| 10 | #include <linux/kernel.h> | ||
| 11 | #include <linux/init.h> | ||
| 12 | #include <linux/of_pci.h> | ||
| 13 | #include <linux/of_platform.h> | ||
| 14 | #include <linux/of_address.h> | ||
| 15 | #include <linux/pci.h> | ||
| 16 | #include <linux/platform_device.h> | ||
| 17 | #include <linux/resource.h> | ||
| 18 | |||
| 19 | #include "pcie-designware.h" | ||
| 20 | |||
| 21 | #define PCIE_DBI2_OFFSET 0x1000 /* DBI2 base address*/ | ||
| 22 | |||
| 23 | struct ls_pcie_ep { | ||
| 24 | struct dw_pcie *pci; | ||
| 25 | }; | ||
| 26 | |||
| 27 | #define to_ls_pcie_ep(x) dev_get_drvdata((x)->dev) | ||
| 28 | |||
| 29 | static int ls_pcie_establish_link(struct dw_pcie *pci) | ||
| 30 | { | ||
| 31 | return 0; | ||
| 32 | } | ||
| 33 | |||
| 34 | static const struct dw_pcie_ops ls_pcie_ep_ops = { | ||
| 35 | .start_link = ls_pcie_establish_link, | ||
| 36 | }; | ||
| 37 | |||
| 38 | static const struct of_device_id ls_pcie_ep_of_match[] = { | ||
| 39 | { .compatible = "fsl,ls-pcie-ep",}, | ||
| 40 | { }, | ||
| 41 | }; | ||
| 42 | |||
| 43 | static const struct pci_epc_features ls_pcie_epc_features = { | ||
| 44 | .linkup_notifier = false, | ||
| 45 | .msi_capable = true, | ||
| 46 | .msix_capable = false, | ||
| 47 | }; | ||
| 48 | |||
| 49 | static const struct pci_epc_features* | ||
| 50 | ls_pcie_ep_get_features(struct dw_pcie_ep *ep) | ||
| 51 | { | ||
| 52 | return &ls_pcie_epc_features; | ||
| 53 | } | ||
| 54 | |||
| 55 | static void ls_pcie_ep_init(struct dw_pcie_ep *ep) | ||
| 56 | { | ||
| 57 | struct dw_pcie *pci = to_dw_pcie_from_ep(ep); | ||
| 58 | enum pci_barno bar; | ||
| 59 | |||
| 60 | for (bar = BAR_0; bar <= BAR_5; bar++) | ||
| 61 | dw_pcie_ep_reset_bar(pci, bar); | ||
| 62 | } | ||
| 63 | |||
| 64 | static int ls_pcie_ep_raise_irq(struct dw_pcie_ep *ep, u8 func_no, | ||
| 65 | enum pci_epc_irq_type type, u16 interrupt_num) | ||
| 66 | { | ||
| 67 | struct dw_pcie *pci = to_dw_pcie_from_ep(ep); | ||
| 68 | |||
| 69 | switch (type) { | ||
| 70 | case PCI_EPC_IRQ_LEGACY: | ||
| 71 | return dw_pcie_ep_raise_legacy_irq(ep, func_no); | ||
| 72 | case PCI_EPC_IRQ_MSI: | ||
| 73 | return dw_pcie_ep_raise_msi_irq(ep, func_no, interrupt_num); | ||
| 74 | case PCI_EPC_IRQ_MSIX: | ||
| 75 | return dw_pcie_ep_raise_msix_irq(ep, func_no, interrupt_num); | ||
| 76 | default: | ||
| 77 | dev_err(pci->dev, "UNKNOWN IRQ type\n"); | ||
| 78 | return -EINVAL; | ||
| 79 | } | ||
| 80 | } | ||
| 81 | |||
| 82 | static struct dw_pcie_ep_ops pcie_ep_ops = { | ||
| 83 | .ep_init = ls_pcie_ep_init, | ||
| 84 | .raise_irq = ls_pcie_ep_raise_irq, | ||
| 85 | .get_features = ls_pcie_ep_get_features, | ||
| 86 | }; | ||
| 87 | |||
| 88 | static int __init ls_add_pcie_ep(struct ls_pcie_ep *pcie, | ||
| 89 | struct platform_device *pdev) | ||
| 90 | { | ||
| 91 | struct dw_pcie *pci = pcie->pci; | ||
| 92 | struct device *dev = pci->dev; | ||
| 93 | struct dw_pcie_ep *ep; | ||
| 94 | struct resource *res; | ||
| 95 | int ret; | ||
| 96 | |||
| 97 | ep = &pci->ep; | ||
| 98 | ep->ops = &pcie_ep_ops; | ||
| 99 | |||
| 100 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "addr_space"); | ||
| 101 | if (!res) | ||
| 102 | return -EINVAL; | ||
| 103 | |||
| 104 | ep->phys_base = res->start; | ||
| 105 | ep->addr_size = resource_size(res); | ||
| 106 | |||
| 107 | ret = dw_pcie_ep_init(ep); | ||
| 108 | if (ret) { | ||
| 109 | dev_err(dev, "failed to initialize endpoint\n"); | ||
| 110 | return ret; | ||
| 111 | } | ||
| 112 | |||
| 113 | return 0; | ||
| 114 | } | ||
| 115 | |||
| 116 | static int __init ls_pcie_ep_probe(struct platform_device *pdev) | ||
| 117 | { | ||
| 118 | struct device *dev = &pdev->dev; | ||
| 119 | struct dw_pcie *pci; | ||
| 120 | struct ls_pcie_ep *pcie; | ||
| 121 | struct resource *dbi_base; | ||
| 122 | int ret; | ||
| 123 | |||
| 124 | pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL); | ||
| 125 | if (!pcie) | ||
| 126 | return -ENOMEM; | ||
| 127 | |||
| 128 | pci = devm_kzalloc(dev, sizeof(*pci), GFP_KERNEL); | ||
| 129 | if (!pci) | ||
| 130 | return -ENOMEM; | ||
| 131 | |||
| 132 | dbi_base = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs"); | ||
| 133 | pci->dbi_base = devm_pci_remap_cfg_resource(dev, dbi_base); | ||
| 134 | if (IS_ERR(pci->dbi_base)) | ||
| 135 | return PTR_ERR(pci->dbi_base); | ||
| 136 | |||
| 137 | pci->dbi_base2 = pci->dbi_base + PCIE_DBI2_OFFSET; | ||
| 138 | pci->dev = dev; | ||
| 139 | pci->ops = &ls_pcie_ep_ops; | ||
| 140 | pcie->pci = pci; | ||
| 141 | |||
| 142 | platform_set_drvdata(pdev, pcie); | ||
| 143 | |||
| 144 | ret = ls_add_pcie_ep(pcie, pdev); | ||
| 145 | |||
| 146 | return ret; | ||
| 147 | } | ||
| 148 | |||
| 149 | static struct platform_driver ls_pcie_ep_driver = { | ||
| 150 | .driver = { | ||
| 151 | .name = "layerscape-pcie-ep", | ||
| 152 | .of_match_table = ls_pcie_ep_of_match, | ||
| 153 | .suppress_bind_attrs = true, | ||
| 154 | }, | ||
| 155 | }; | ||
| 156 | builtin_platform_driver_probe(ls_pcie_ep_driver, ls_pcie_ep_probe); | ||
diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c index a543c45c7224..24f5a775ad34 100644 --- a/drivers/pci/controller/dwc/pcie-designware-ep.c +++ b/drivers/pci/controller/dwc/pcie-designware-ep.c | |||
| @@ -355,6 +355,17 @@ static int dw_pcie_ep_start(struct pci_epc *epc) | |||
| 355 | return pci->ops->start_link(pci); | 355 | return pci->ops->start_link(pci); |
| 356 | } | 356 | } |
| 357 | 357 | ||
| 358 | static const struct pci_epc_features* | ||
| 359 | dw_pcie_ep_get_features(struct pci_epc *epc, u8 func_no) | ||
| 360 | { | ||
| 361 | struct dw_pcie_ep *ep = epc_get_drvdata(epc); | ||
| 362 | |||
| 363 | if (!ep->ops->get_features) | ||
| 364 | return NULL; | ||
| 365 | |||
| 366 | return ep->ops->get_features(ep); | ||
| 367 | } | ||
| 368 | |||
| 358 | static const struct pci_epc_ops epc_ops = { | 369 | static const struct pci_epc_ops epc_ops = { |
| 359 | .write_header = dw_pcie_ep_write_header, | 370 | .write_header = dw_pcie_ep_write_header, |
| 360 | .set_bar = dw_pcie_ep_set_bar, | 371 | .set_bar = dw_pcie_ep_set_bar, |
| @@ -368,6 +379,7 @@ static const struct pci_epc_ops epc_ops = { | |||
| 368 | .raise_irq = dw_pcie_ep_raise_irq, | 379 | .raise_irq = dw_pcie_ep_raise_irq, |
| 369 | .start = dw_pcie_ep_start, | 380 | .start = dw_pcie_ep_start, |
| 370 | .stop = dw_pcie_ep_stop, | 381 | .stop = dw_pcie_ep_stop, |
| 382 | .get_features = dw_pcie_ep_get_features, | ||
| 371 | }; | 383 | }; |
| 372 | 384 | ||
| 373 | int dw_pcie_ep_raise_legacy_irq(struct dw_pcie_ep *ep, u8 func_no) | 385 | int dw_pcie_ep_raise_legacy_irq(struct dw_pcie_ep *ep, u8 func_no) |
| @@ -465,8 +477,10 @@ int dw_pcie_ep_raise_msix_irq(struct dw_pcie_ep *ep, u8 func_no, | |||
| 465 | 477 | ||
| 466 | iounmap(msix_tbl); | 478 | iounmap(msix_tbl); |
| 467 | 479 | ||
| 468 | if (vec_ctrl & PCI_MSIX_ENTRY_CTRL_MASKBIT) | 480 | if (vec_ctrl & PCI_MSIX_ENTRY_CTRL_MASKBIT) { |
| 481 | dev_dbg(pci->dev, "MSI-X entry ctrl set\n"); | ||
| 469 | return -EPERM; | 482 | return -EPERM; |
| 483 | } | ||
| 470 | 484 | ||
| 471 | ret = dw_pcie_ep_map_addr(epc, func_no, ep->msi_mem_phys, msg_addr, | 485 | ret = dw_pcie_ep_map_addr(epc, func_no, ep->msi_mem_phys, msg_addr, |
| 472 | epc->mem->page_size); | 486 | epc->mem->page_size); |
diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c index 721d60a5d9e4..25087d3c9a82 100644 --- a/drivers/pci/controller/dwc/pcie-designware-host.c +++ b/drivers/pci/controller/dwc/pcie-designware-host.c | |||
| @@ -120,9 +120,9 @@ static void dw_chained_msi_isr(struct irq_desc *desc) | |||
| 120 | chained_irq_exit(chip, desc); | 120 | chained_irq_exit(chip, desc); |
| 121 | } | 121 | } |
| 122 | 122 | ||
| 123 | static void dw_pci_setup_msi_msg(struct irq_data *data, struct msi_msg *msg) | 123 | static void dw_pci_setup_msi_msg(struct irq_data *d, struct msi_msg *msg) |
| 124 | { | 124 | { |
| 125 | struct pcie_port *pp = irq_data_get_irq_chip_data(data); | 125 | struct pcie_port *pp = irq_data_get_irq_chip_data(d); |
| 126 | struct dw_pcie *pci = to_dw_pcie_from_pp(pp); | 126 | struct dw_pcie *pci = to_dw_pcie_from_pp(pp); |
| 127 | u64 msi_target; | 127 | u64 msi_target; |
| 128 | 128 | ||
| @@ -135,61 +135,61 @@ static void dw_pci_setup_msi_msg(struct irq_data *data, struct msi_msg *msg) | |||
| 135 | msg->address_hi = upper_32_bits(msi_target); | 135 | msg->address_hi = upper_32_bits(msi_target); |
| 136 | 136 | ||
| 137 | if (pp->ops->get_msi_data) | 137 | if (pp->ops->get_msi_data) |
| 138 | msg->data = pp->ops->get_msi_data(pp, data->hwirq); | 138 | msg->data = pp->ops->get_msi_data(pp, d->hwirq); |
| 139 | else | 139 | else |
| 140 | msg->data = data->hwirq; | 140 | msg->data = d->hwirq; |
| 141 | 141 | ||
| 142 | dev_dbg(pci->dev, "msi#%d address_hi %#x address_lo %#x\n", | 142 | dev_dbg(pci->dev, "msi#%d address_hi %#x address_lo %#x\n", |
| 143 | (int)data->hwirq, msg->address_hi, msg->address_lo); | 143 | (int)d->hwirq, msg->address_hi, msg->address_lo); |
| 144 | } | 144 | } |
| 145 | 145 | ||
| 146 | static int dw_pci_msi_set_affinity(struct irq_data *irq_data, | 146 | static int dw_pci_msi_set_affinity(struct irq_data *d, |
| 147 | const struct cpumask *mask, bool force) | 147 | const struct cpumask *mask, bool force) |
| 148 | { | 148 | { |
| 149 | return -EINVAL; | 149 | return -EINVAL; |
| 150 | } | 150 | } |
| 151 | 151 | ||
| 152 | static void dw_pci_bottom_mask(struct irq_data *data) | 152 | static void dw_pci_bottom_mask(struct irq_data *d) |
| 153 | { | 153 | { |
| 154 | struct pcie_port *pp = irq_data_get_irq_chip_data(data); | 154 | struct pcie_port *pp = irq_data_get_irq_chip_data(d); |
| 155 | unsigned int res, bit, ctrl; | 155 | unsigned int res, bit, ctrl; |
| 156 | unsigned long flags; | 156 | unsigned long flags; |
| 157 | 157 | ||
| 158 | raw_spin_lock_irqsave(&pp->lock, flags); | 158 | raw_spin_lock_irqsave(&pp->lock, flags); |
| 159 | 159 | ||
| 160 | if (pp->ops->msi_clear_irq) { | 160 | if (pp->ops->msi_clear_irq) { |
| 161 | pp->ops->msi_clear_irq(pp, data->hwirq); | 161 | pp->ops->msi_clear_irq(pp, d->hwirq); |
| 162 | } else { | 162 | } else { |
| 163 | ctrl = data->hwirq / MAX_MSI_IRQS_PER_CTRL; | 163 | ctrl = d->hwirq / MAX_MSI_IRQS_PER_CTRL; |
| 164 | res = ctrl * MSI_REG_CTRL_BLOCK_SIZE; | 164 | res = ctrl * MSI_REG_CTRL_BLOCK_SIZE; |
| 165 | bit = data->hwirq % MAX_MSI_IRQS_PER_CTRL; | 165 | bit = d->hwirq % MAX_MSI_IRQS_PER_CTRL; |
| 166 | 166 | ||
| 167 | pp->irq_status[ctrl] &= ~(1 << bit); | 167 | pp->irq_mask[ctrl] |= BIT(bit); |
| 168 | dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_MASK + res, 4, | 168 | dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_MASK + res, 4, |
| 169 | ~pp->irq_status[ctrl]); | 169 | pp->irq_mask[ctrl]); |
| 170 | } | 170 | } |
| 171 | 171 | ||
| 172 | raw_spin_unlock_irqrestore(&pp->lock, flags); | 172 | raw_spin_unlock_irqrestore(&pp->lock, flags); |
| 173 | } | 173 | } |
| 174 | 174 | ||
| 175 | static void dw_pci_bottom_unmask(struct irq_data *data) | 175 | static void dw_pci_bottom_unmask(struct irq_data *d) |
| 176 | { | 176 | { |
| 177 | struct pcie_port *pp = irq_data_get_irq_chip_data(data); | 177 | struct pcie_port *pp = irq_data_get_irq_chip_data(d); |
| 178 | unsigned int res, bit, ctrl; | 178 | unsigned int res, bit, ctrl; |
| 179 | unsigned long flags; | 179 | unsigned long flags; |
| 180 | 180 | ||
| 181 | raw_spin_lock_irqsave(&pp->lock, flags); | 181 | raw_spin_lock_irqsave(&pp->lock, flags); |
| 182 | 182 | ||
| 183 | if (pp->ops->msi_set_irq) { | 183 | if (pp->ops->msi_set_irq) { |
| 184 | pp->ops->msi_set_irq(pp, data->hwirq); | 184 | pp->ops->msi_set_irq(pp, d->hwirq); |
| 185 | } else { | 185 | } else { |
| 186 | ctrl = data->hwirq / MAX_MSI_IRQS_PER_CTRL; | 186 | ctrl = d->hwirq / MAX_MSI_IRQS_PER_CTRL; |
| 187 | res = ctrl * MSI_REG_CTRL_BLOCK_SIZE; | 187 | res = ctrl * MSI_REG_CTRL_BLOCK_SIZE; |
| 188 | bit = data->hwirq % MAX_MSI_IRQS_PER_CTRL; | 188 | bit = d->hwirq % MAX_MSI_IRQS_PER_CTRL; |
| 189 | 189 | ||
| 190 | pp->irq_status[ctrl] |= 1 << bit; | 190 | pp->irq_mask[ctrl] &= ~BIT(bit); |
| 191 | dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_MASK + res, 4, | 191 | dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_MASK + res, 4, |
| 192 | ~pp->irq_status[ctrl]); | 192 | pp->irq_mask[ctrl]); |
| 193 | } | 193 | } |
| 194 | 194 | ||
| 195 | raw_spin_unlock_irqrestore(&pp->lock, flags); | 195 | raw_spin_unlock_irqrestore(&pp->lock, flags); |
| @@ -207,7 +207,7 @@ static void dw_pci_bottom_ack(struct irq_data *d) | |||
| 207 | 207 | ||
| 208 | raw_spin_lock_irqsave(&pp->lock, flags); | 208 | raw_spin_lock_irqsave(&pp->lock, flags); |
| 209 | 209 | ||
| 210 | dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_STATUS + res, 4, 1 << bit); | 210 | dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_STATUS + res, 4, BIT(bit)); |
| 211 | 211 | ||
| 212 | if (pp->ops->msi_irq_ack) | 212 | if (pp->ops->msi_irq_ack) |
| 213 | pp->ops->msi_irq_ack(d->hwirq, pp); | 213 | pp->ops->msi_irq_ack(d->hwirq, pp); |
| @@ -255,13 +255,13 @@ static int dw_pcie_irq_domain_alloc(struct irq_domain *domain, | |||
| 255 | static void dw_pcie_irq_domain_free(struct irq_domain *domain, | 255 | static void dw_pcie_irq_domain_free(struct irq_domain *domain, |
| 256 | unsigned int virq, unsigned int nr_irqs) | 256 | unsigned int virq, unsigned int nr_irqs) |
| 257 | { | 257 | { |
| 258 | struct irq_data *data = irq_domain_get_irq_data(domain, virq); | 258 | struct irq_data *d = irq_domain_get_irq_data(domain, virq); |
| 259 | struct pcie_port *pp = irq_data_get_irq_chip_data(data); | 259 | struct pcie_port *pp = irq_data_get_irq_chip_data(d); |
| 260 | unsigned long flags; | 260 | unsigned long flags; |
| 261 | 261 | ||
| 262 | raw_spin_lock_irqsave(&pp->lock, flags); | 262 | raw_spin_lock_irqsave(&pp->lock, flags); |
| 263 | 263 | ||
| 264 | bitmap_release_region(pp->msi_irq_in_use, data->hwirq, | 264 | bitmap_release_region(pp->msi_irq_in_use, d->hwirq, |
| 265 | order_base_2(nr_irqs)); | 265 | order_base_2(nr_irqs)); |
| 266 | 266 | ||
| 267 | raw_spin_unlock_irqrestore(&pp->lock, flags); | 267 | raw_spin_unlock_irqrestore(&pp->lock, flags); |
| @@ -439,7 +439,7 @@ int dw_pcie_host_init(struct pcie_port *pp) | |||
| 439 | if (ret) | 439 | if (ret) |
| 440 | pci->num_viewport = 2; | 440 | pci->num_viewport = 2; |
| 441 | 441 | ||
| 442 | if (IS_ENABLED(CONFIG_PCI_MSI)) { | 442 | if (IS_ENABLED(CONFIG_PCI_MSI) && pci_msi_enabled()) { |
| 443 | /* | 443 | /* |
| 444 | * If a specific SoC driver needs to change the | 444 | * If a specific SoC driver needs to change the |
| 445 | * default number of vectors, it needs to implement | 445 | * default number of vectors, it needs to implement |
| @@ -512,8 +512,9 @@ error: | |||
| 512 | return ret; | 512 | return ret; |
| 513 | } | 513 | } |
| 514 | 514 | ||
| 515 | static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus, | 515 | static int dw_pcie_access_other_conf(struct pcie_port *pp, struct pci_bus *bus, |
| 516 | u32 devfn, int where, int size, u32 *val) | 516 | u32 devfn, int where, int size, u32 *val, |
| 517 | bool write) | ||
| 517 | { | 518 | { |
| 518 | int ret, type; | 519 | int ret, type; |
| 519 | u32 busdev, cfg_size; | 520 | u32 busdev, cfg_size; |
| @@ -521,9 +522,6 @@ static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus, | |||
| 521 | void __iomem *va_cfg_base; | 522 | void __iomem *va_cfg_base; |
| 522 | struct dw_pcie *pci = to_dw_pcie_from_pp(pp); | 523 | struct dw_pcie *pci = to_dw_pcie_from_pp(pp); |
| 523 | 524 | ||
| 524 | if (pp->ops->rd_other_conf) | ||
| 525 | return pp->ops->rd_other_conf(pp, bus, devfn, where, size, val); | ||
| 526 | |||
| 527 | busdev = PCIE_ATU_BUS(bus->number) | PCIE_ATU_DEV(PCI_SLOT(devfn)) | | 525 | busdev = PCIE_ATU_BUS(bus->number) | PCIE_ATU_DEV(PCI_SLOT(devfn)) | |
| 528 | PCIE_ATU_FUNC(PCI_FUNC(devfn)); | 526 | PCIE_ATU_FUNC(PCI_FUNC(devfn)); |
| 529 | 527 | ||
| @@ -542,7 +540,11 @@ static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus, | |||
| 542 | dw_pcie_prog_outbound_atu(pci, PCIE_ATU_REGION_INDEX1, | 540 | dw_pcie_prog_outbound_atu(pci, PCIE_ATU_REGION_INDEX1, |
| 543 | type, cpu_addr, | 541 | type, cpu_addr, |
| 544 | busdev, cfg_size); | 542 | busdev, cfg_size); |
| 545 | ret = dw_pcie_read(va_cfg_base + where, size, val); | 543 | if (write) |
| 544 | ret = dw_pcie_write(va_cfg_base + where, size, *val); | ||
| 545 | else | ||
| 546 | ret = dw_pcie_read(va_cfg_base + where, size, val); | ||
| 547 | |||
| 546 | if (pci->num_viewport <= 2) | 548 | if (pci->num_viewport <= 2) |
| 547 | dw_pcie_prog_outbound_atu(pci, PCIE_ATU_REGION_INDEX1, | 549 | dw_pcie_prog_outbound_atu(pci, PCIE_ATU_REGION_INDEX1, |
| 548 | PCIE_ATU_TYPE_IO, pp->io_base, | 550 | PCIE_ATU_TYPE_IO, pp->io_base, |
| @@ -551,43 +553,26 @@ static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus, | |||
| 551 | return ret; | 553 | return ret; |
| 552 | } | 554 | } |
| 553 | 555 | ||
| 556 | static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus, | ||
| 557 | u32 devfn, int where, int size, u32 *val) | ||
| 558 | { | ||
| 559 | if (pp->ops->rd_other_conf) | ||
| 560 | return pp->ops->rd_other_conf(pp, bus, devfn, where, | ||
| 561 | size, val); | ||
| 562 | |||
| 563 | return dw_pcie_access_other_conf(pp, bus, devfn, where, size, val, | ||
| 564 | false); | ||
| 565 | } | ||
| 566 | |||
| 554 | static int dw_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus, | 567 | static int dw_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus, |
| 555 | u32 devfn, int where, int size, u32 val) | 568 | u32 devfn, int where, int size, u32 val) |
| 556 | { | 569 | { |
| 557 | int ret, type; | ||
| 558 | u32 busdev, cfg_size; | ||
| 559 | u64 cpu_addr; | ||
| 560 | void __iomem *va_cfg_base; | ||
| 561 | struct dw_pcie *pci = to_dw_pcie_from_pp(pp); | ||
| 562 | |||
| 563 | if (pp->ops->wr_other_conf) | 570 | if (pp->ops->wr_other_conf) |
| 564 | return pp->ops->wr_other_conf(pp, bus, devfn, where, size, val); | 571 | return pp->ops->wr_other_conf(pp, bus, devfn, where, |
| 565 | 572 | size, val); | |
| 566 | busdev = PCIE_ATU_BUS(bus->number) | PCIE_ATU_DEV(PCI_SLOT(devfn)) | | ||
| 567 | PCIE_ATU_FUNC(PCI_FUNC(devfn)); | ||
| 568 | 573 | ||
| 569 | if (bus->parent->number == pp->root_bus_nr) { | 574 | return dw_pcie_access_other_conf(pp, bus, devfn, where, size, &val, |
| 570 | type = PCIE_ATU_TYPE_CFG0; | 575 | true); |
| 571 | cpu_addr = pp->cfg0_base; | ||
| 572 | cfg_size = pp->cfg0_size; | ||
| 573 | va_cfg_base = pp->va_cfg0_base; | ||
| 574 | } else { | ||
| 575 | type = PCIE_ATU_TYPE_CFG1; | ||
| 576 | cpu_addr = pp->cfg1_base; | ||
| 577 | cfg_size = pp->cfg1_size; | ||
| 578 | va_cfg_base = pp->va_cfg1_base; | ||
| 579 | } | ||
| 580 | |||
| 581 | dw_pcie_prog_outbound_atu(pci, PCIE_ATU_REGION_INDEX1, | ||
| 582 | type, cpu_addr, | ||
| 583 | busdev, cfg_size); | ||
| 584 | ret = dw_pcie_write(va_cfg_base + where, size, val); | ||
| 585 | if (pci->num_viewport <= 2) | ||
| 586 | dw_pcie_prog_outbound_atu(pci, PCIE_ATU_REGION_INDEX1, | ||
| 587 | PCIE_ATU_TYPE_IO, pp->io_base, | ||
| 588 | pp->io_bus_addr, pp->io_size); | ||
| 589 | |||
| 590 | return ret; | ||
| 591 | } | 576 | } |
| 592 | 577 | ||
| 593 | static int dw_pcie_valid_device(struct pcie_port *pp, struct pci_bus *bus, | 578 | static int dw_pcie_valid_device(struct pcie_port *pp, struct pci_bus *bus, |
| @@ -665,13 +650,13 @@ void dw_pcie_setup_rc(struct pcie_port *pp) | |||
| 665 | 650 | ||
| 666 | /* Initialize IRQ Status array */ | 651 | /* Initialize IRQ Status array */ |
| 667 | for (ctrl = 0; ctrl < num_ctrls; ctrl++) { | 652 | for (ctrl = 0; ctrl < num_ctrls; ctrl++) { |
| 653 | pp->irq_mask[ctrl] = ~0; | ||
| 668 | dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_MASK + | 654 | dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_MASK + |
| 669 | (ctrl * MSI_REG_CTRL_BLOCK_SIZE), | 655 | (ctrl * MSI_REG_CTRL_BLOCK_SIZE), |
| 670 | 4, ~0); | 656 | 4, pp->irq_mask[ctrl]); |
| 671 | dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_ENABLE + | 657 | dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_ENABLE + |
| 672 | (ctrl * MSI_REG_CTRL_BLOCK_SIZE), | 658 | (ctrl * MSI_REG_CTRL_BLOCK_SIZE), |
| 673 | 4, ~0); | 659 | 4, ~0); |
| 674 | pp->irq_status[ctrl] = 0; | ||
| 675 | } | 660 | } |
| 676 | 661 | ||
| 677 | /* Setup RC BARs */ | 662 | /* Setup RC BARs */ |
diff --git a/drivers/pci/controller/dwc/pcie-designware-plat.c b/drivers/pci/controller/dwc/pcie-designware-plat.c index c12bf794d69c..932dbd0b34b6 100644 --- a/drivers/pci/controller/dwc/pcie-designware-plat.c +++ b/drivers/pci/controller/dwc/pcie-designware-plat.c | |||
| @@ -13,11 +13,9 @@ | |||
| 13 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
| 14 | #include <linux/init.h> | 14 | #include <linux/init.h> |
| 15 | #include <linux/of_device.h> | 15 | #include <linux/of_device.h> |
| 16 | #include <linux/of_gpio.h> | ||
| 17 | #include <linux/pci.h> | 16 | #include <linux/pci.h> |
| 18 | #include <linux/platform_device.h> | 17 | #include <linux/platform_device.h> |
| 19 | #include <linux/resource.h> | 18 | #include <linux/resource.h> |
| 20 | #include <linux/signal.h> | ||
| 21 | #include <linux/types.h> | 19 | #include <linux/types.h> |
| 22 | #include <linux/regmap.h> | 20 | #include <linux/regmap.h> |
| 23 | 21 | ||
| @@ -70,14 +68,10 @@ static const struct dw_pcie_ops dw_pcie_ops = { | |||
| 70 | static void dw_plat_pcie_ep_init(struct dw_pcie_ep *ep) | 68 | static void dw_plat_pcie_ep_init(struct dw_pcie_ep *ep) |
| 71 | { | 69 | { |
| 72 | struct dw_pcie *pci = to_dw_pcie_from_ep(ep); | 70 | struct dw_pcie *pci = to_dw_pcie_from_ep(ep); |
| 73 | struct pci_epc *epc = ep->epc; | ||
| 74 | enum pci_barno bar; | 71 | enum pci_barno bar; |
| 75 | 72 | ||
| 76 | for (bar = BAR_0; bar <= BAR_5; bar++) | 73 | for (bar = BAR_0; bar <= BAR_5; bar++) |
| 77 | dw_pcie_ep_reset_bar(pci, bar); | 74 | dw_pcie_ep_reset_bar(pci, bar); |
| 78 | |||
| 79 | epc->features |= EPC_FEATURE_NO_LINKUP_NOTIFIER; | ||
| 80 | epc->features |= EPC_FEATURE_MSIX_AVAILABLE; | ||
| 81 | } | 75 | } |
| 82 | 76 | ||
| 83 | static int dw_plat_pcie_ep_raise_irq(struct dw_pcie_ep *ep, u8 func_no, | 77 | static int dw_plat_pcie_ep_raise_irq(struct dw_pcie_ep *ep, u8 func_no, |
| @@ -100,9 +94,22 @@ static int dw_plat_pcie_ep_raise_irq(struct dw_pcie_ep *ep, u8 func_no, | |||
| 100 | return 0; | 94 | return 0; |
| 101 | } | 95 | } |
| 102 | 96 | ||
| 97 | static const struct pci_epc_features dw_plat_pcie_epc_features = { | ||
| 98 | .linkup_notifier = false, | ||
| 99 | .msi_capable = true, | ||
| 100 | .msix_capable = true, | ||
| 101 | }; | ||
| 102 | |||
| 103 | static const struct pci_epc_features* | ||
| 104 | dw_plat_pcie_get_features(struct dw_pcie_ep *ep) | ||
| 105 | { | ||
| 106 | return &dw_plat_pcie_epc_features; | ||
| 107 | } | ||
| 108 | |||
| 103 | static struct dw_pcie_ep_ops pcie_ep_ops = { | 109 | static struct dw_pcie_ep_ops pcie_ep_ops = { |
| 104 | .ep_init = dw_plat_pcie_ep_init, | 110 | .ep_init = dw_plat_pcie_ep_init, |
| 105 | .raise_irq = dw_plat_pcie_ep_raise_irq, | 111 | .raise_irq = dw_plat_pcie_ep_raise_irq, |
| 112 | .get_features = dw_plat_pcie_get_features, | ||
| 106 | }; | 113 | }; |
| 107 | 114 | ||
| 108 | static int dw_plat_add_pcie_port(struct dw_plat_pcie *dw_plat_pcie, | 115 | static int dw_plat_add_pcie_port(struct dw_plat_pcie *dw_plat_pcie, |
diff --git a/drivers/pci/controller/dwc/pcie-designware.c b/drivers/pci/controller/dwc/pcie-designware.c index 93ef8c31fb39..31f6331ca46f 100644 --- a/drivers/pci/controller/dwc/pcie-designware.c +++ b/drivers/pci/controller/dwc/pcie-designware.c | |||
| @@ -22,7 +22,7 @@ | |||
| 22 | 22 | ||
| 23 | int dw_pcie_read(void __iomem *addr, int size, u32 *val) | 23 | int dw_pcie_read(void __iomem *addr, int size, u32 *val) |
| 24 | { | 24 | { |
| 25 | if ((uintptr_t)addr & (size - 1)) { | 25 | if (!IS_ALIGNED((uintptr_t)addr, size)) { |
| 26 | *val = 0; | 26 | *val = 0; |
| 27 | return PCIBIOS_BAD_REGISTER_NUMBER; | 27 | return PCIBIOS_BAD_REGISTER_NUMBER; |
| 28 | } | 28 | } |
| @@ -43,7 +43,7 @@ int dw_pcie_read(void __iomem *addr, int size, u32 *val) | |||
| 43 | 43 | ||
| 44 | int dw_pcie_write(void __iomem *addr, int size, u32 val) | 44 | int dw_pcie_write(void __iomem *addr, int size, u32 val) |
| 45 | { | 45 | { |
| 46 | if ((uintptr_t)addr & (size - 1)) | 46 | if (!IS_ALIGNED((uintptr_t)addr, size)) |
| 47 | return PCIBIOS_BAD_REGISTER_NUMBER; | 47 | return PCIBIOS_BAD_REGISTER_NUMBER; |
| 48 | 48 | ||
| 49 | if (size == 4) | 49 | if (size == 4) |
| @@ -306,7 +306,7 @@ void dw_pcie_disable_atu(struct dw_pcie *pci, int index, | |||
| 306 | } | 306 | } |
| 307 | 307 | ||
| 308 | dw_pcie_writel_dbi(pci, PCIE_ATU_VIEWPORT, region | index); | 308 | dw_pcie_writel_dbi(pci, PCIE_ATU_VIEWPORT, region | index); |
| 309 | dw_pcie_writel_dbi(pci, PCIE_ATU_CR2, ~PCIE_ATU_ENABLE); | 309 | dw_pcie_writel_dbi(pci, PCIE_ATU_CR2, (u32)~PCIE_ATU_ENABLE); |
| 310 | } | 310 | } |
| 311 | 311 | ||
| 312 | int dw_pcie_wait_for_link(struct dw_pcie *pci) | 312 | int dw_pcie_wait_for_link(struct dw_pcie *pci) |
diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h index 9943d8c68335..377f4c0b52da 100644 --- a/drivers/pci/controller/dwc/pcie-designware.h +++ b/drivers/pci/controller/dwc/pcie-designware.h | |||
| @@ -11,6 +11,7 @@ | |||
| 11 | #ifndef _PCIE_DESIGNWARE_H | 11 | #ifndef _PCIE_DESIGNWARE_H |
| 12 | #define _PCIE_DESIGNWARE_H | 12 | #define _PCIE_DESIGNWARE_H |
| 13 | 13 | ||
| 14 | #include <linux/bitfield.h> | ||
| 14 | #include <linux/dma-mapping.h> | 15 | #include <linux/dma-mapping.h> |
| 15 | #include <linux/irq.h> | 16 | #include <linux/irq.h> |
| 16 | #include <linux/msi.h> | 17 | #include <linux/msi.h> |
| @@ -30,23 +31,25 @@ | |||
| 30 | 31 | ||
| 31 | /* Synopsys-specific PCIe configuration registers */ | 32 | /* Synopsys-specific PCIe configuration registers */ |
| 32 | #define PCIE_PORT_LINK_CONTROL 0x710 | 33 | #define PCIE_PORT_LINK_CONTROL 0x710 |
| 33 | #define PORT_LINK_MODE_MASK (0x3f << 16) | 34 | #define PORT_LINK_MODE_MASK GENMASK(21, 16) |
| 34 | #define PORT_LINK_MODE_1_LANES (0x1 << 16) | 35 | #define PORT_LINK_MODE(n) FIELD_PREP(PORT_LINK_MODE_MASK, n) |
| 35 | #define PORT_LINK_MODE_2_LANES (0x3 << 16) | 36 | #define PORT_LINK_MODE_1_LANES PORT_LINK_MODE(0x1) |
| 36 | #define PORT_LINK_MODE_4_LANES (0x7 << 16) | 37 | #define PORT_LINK_MODE_2_LANES PORT_LINK_MODE(0x3) |
| 37 | #define PORT_LINK_MODE_8_LANES (0xf << 16) | 38 | #define PORT_LINK_MODE_4_LANES PORT_LINK_MODE(0x7) |
| 39 | #define PORT_LINK_MODE_8_LANES PORT_LINK_MODE(0xf) | ||
| 38 | 40 | ||
| 39 | #define PCIE_PORT_DEBUG0 0x728 | 41 | #define PCIE_PORT_DEBUG0 0x728 |
| 40 | #define PORT_LOGIC_LTSSM_STATE_MASK 0x1f | 42 | #define PORT_LOGIC_LTSSM_STATE_MASK 0x1f |
| 41 | #define PORT_LOGIC_LTSSM_STATE_L0 0x11 | 43 | #define PORT_LOGIC_LTSSM_STATE_L0 0x11 |
| 42 | 44 | ||
| 43 | #define PCIE_LINK_WIDTH_SPEED_CONTROL 0x80C | 45 | #define PCIE_LINK_WIDTH_SPEED_CONTROL 0x80C |
| 44 | #define PORT_LOGIC_SPEED_CHANGE (0x1 << 17) | 46 | #define PORT_LOGIC_SPEED_CHANGE BIT(17) |
| 45 | #define PORT_LOGIC_LINK_WIDTH_MASK (0x1f << 8) | 47 | #define PORT_LOGIC_LINK_WIDTH_MASK GENMASK(12, 8) |
| 46 | #define PORT_LOGIC_LINK_WIDTH_1_LANES (0x1 << 8) | 48 | #define PORT_LOGIC_LINK_WIDTH(n) FIELD_PREP(PORT_LOGIC_LINK_WIDTH_MASK, n) |
| 47 | #define PORT_LOGIC_LINK_WIDTH_2_LANES (0x2 << 8) | 49 | #define PORT_LOGIC_LINK_WIDTH_1_LANES PORT_LOGIC_LINK_WIDTH(0x1) |
| 48 | #define PORT_LOGIC_LINK_WIDTH_4_LANES (0x4 << 8) | 50 | #define PORT_LOGIC_LINK_WIDTH_2_LANES PORT_LOGIC_LINK_WIDTH(0x2) |
| 49 | #define PORT_LOGIC_LINK_WIDTH_8_LANES (0x8 << 8) | 51 | #define PORT_LOGIC_LINK_WIDTH_4_LANES PORT_LOGIC_LINK_WIDTH(0x4) |
| 52 | #define PORT_LOGIC_LINK_WIDTH_8_LANES PORT_LOGIC_LINK_WIDTH(0x8) | ||
| 50 | 53 | ||
| 51 | #define PCIE_MSI_ADDR_LO 0x820 | 54 | #define PCIE_MSI_ADDR_LO 0x820 |
| 52 | #define PCIE_MSI_ADDR_HI 0x824 | 55 | #define PCIE_MSI_ADDR_HI 0x824 |
| @@ -55,30 +58,30 @@ | |||
| 55 | #define PCIE_MSI_INTR0_STATUS 0x830 | 58 | #define PCIE_MSI_INTR0_STATUS 0x830 |
| 56 | 59 | ||
| 57 | #define PCIE_ATU_VIEWPORT 0x900 | 60 | #define PCIE_ATU_VIEWPORT 0x900 |
| 58 | #define PCIE_ATU_REGION_INBOUND (0x1 << 31) | 61 | #define PCIE_ATU_REGION_INBOUND BIT(31) |
| 59 | #define PCIE_ATU_REGION_OUTBOUND (0x0 << 31) | 62 | #define PCIE_ATU_REGION_OUTBOUND 0 |
| 60 | #define PCIE_ATU_REGION_INDEX2 (0x2 << 0) | 63 | #define PCIE_ATU_REGION_INDEX2 0x2 |
| 61 | #define PCIE_ATU_REGION_INDEX1 (0x1 << 0) | 64 | #define PCIE_ATU_REGION_INDEX1 0x1 |
| 62 | #define PCIE_ATU_REGION_INDEX0 (0x0 << 0) | 65 | #define PCIE_ATU_REGION_INDEX0 0x0 |
| 63 | #define PCIE_ATU_CR1 0x904 | 66 | #define PCIE_ATU_CR1 0x904 |
| 64 | #define PCIE_ATU_TYPE_MEM (0x0 << 0) | 67 | #define PCIE_ATU_TYPE_MEM 0x0 |
| 65 | #define PCIE_ATU_TYPE_IO (0x2 << 0) | 68 | #define PCIE_ATU_TYPE_IO 0x2 |
| 66 | #define PCIE_ATU_TYPE_CFG0 (0x4 << 0) | 69 | #define PCIE_ATU_TYPE_CFG0 0x4 |
| 67 | #define PCIE_ATU_TYPE_CFG1 (0x5 << 0) | 70 | #define PCIE_ATU_TYPE_CFG1 0x5 |
| 68 | #define PCIE_ATU_CR2 0x908 | 71 | #define PCIE_ATU_CR2 0x908 |
| 69 | #define PCIE_ATU_ENABLE (0x1 << 31) | 72 | #define PCIE_ATU_ENABLE BIT(31) |
| 70 | #define PCIE_ATU_BAR_MODE_ENABLE (0x1 << 30) | 73 | #define PCIE_ATU_BAR_MODE_ENABLE BIT(30) |
| 71 | #define PCIE_ATU_LOWER_BASE 0x90C | 74 | #define PCIE_ATU_LOWER_BASE 0x90C |
| 72 | #define PCIE_ATU_UPPER_BASE 0x910 | 75 | #define PCIE_ATU_UPPER_BASE 0x910 |
| 73 | #define PCIE_ATU_LIMIT 0x914 | 76 | #define PCIE_ATU_LIMIT 0x914 |
| 74 | #define PCIE_ATU_LOWER_TARGET 0x918 | 77 | #define PCIE_ATU_LOWER_TARGET 0x918 |
| 75 | #define PCIE_ATU_BUS(x) (((x) & 0xff) << 24) | 78 | #define PCIE_ATU_BUS(x) FIELD_PREP(GENMASK(31, 24), x) |
| 76 | #define PCIE_ATU_DEV(x) (((x) & 0x1f) << 19) | 79 | #define PCIE_ATU_DEV(x) FIELD_PREP(GENMASK(23, 19), x) |
| 77 | #define PCIE_ATU_FUNC(x) (((x) & 0x7) << 16) | 80 | #define PCIE_ATU_FUNC(x) FIELD_PREP(GENMASK(18, 16), x) |
| 78 | #define PCIE_ATU_UPPER_TARGET 0x91C | 81 | #define PCIE_ATU_UPPER_TARGET 0x91C |
| 79 | 82 | ||
| 80 | #define PCIE_MISC_CONTROL_1_OFF 0x8BC | 83 | #define PCIE_MISC_CONTROL_1_OFF 0x8BC |
| 81 | #define PCIE_DBI_RO_WR_EN (0x1 << 0) | 84 | #define PCIE_DBI_RO_WR_EN BIT(0) |
| 82 | 85 | ||
| 83 | /* | 86 | /* |
| 84 | * iATU Unroll-specific register definitions | 87 | * iATU Unroll-specific register definitions |
| @@ -105,7 +108,7 @@ | |||
| 105 | ((region) << 9) | 108 | ((region) << 9) |
| 106 | 109 | ||
| 107 | #define PCIE_GET_ATU_INB_UNR_REG_OFFSET(region) \ | 110 | #define PCIE_GET_ATU_INB_UNR_REG_OFFSET(region) \ |
| 108 | (((region) << 9) | (0x1 << 8)) | 111 | (((region) << 9) | BIT(8)) |
| 109 | 112 | ||
| 110 | #define MAX_MSI_IRQS 256 | 113 | #define MAX_MSI_IRQS 256 |
| 111 | #define MAX_MSI_IRQS_PER_CTRL 32 | 114 | #define MAX_MSI_IRQS_PER_CTRL 32 |
| @@ -177,7 +180,7 @@ struct pcie_port { | |||
| 177 | struct irq_domain *msi_domain; | 180 | struct irq_domain *msi_domain; |
| 178 | dma_addr_t msi_data; | 181 | dma_addr_t msi_data; |
| 179 | u32 num_vectors; | 182 | u32 num_vectors; |
| 180 | u32 irq_status[MAX_MSI_CTRLS]; | 183 | u32 irq_mask[MAX_MSI_CTRLS]; |
| 181 | raw_spinlock_t lock; | 184 | raw_spinlock_t lock; |
| 182 | DECLARE_BITMAP(msi_irq_in_use, MAX_MSI_IRQS); | 185 | DECLARE_BITMAP(msi_irq_in_use, MAX_MSI_IRQS); |
| 183 | }; | 186 | }; |
| @@ -192,6 +195,7 @@ struct dw_pcie_ep_ops { | |||
| 192 | void (*ep_init)(struct dw_pcie_ep *ep); | 195 | void (*ep_init)(struct dw_pcie_ep *ep); |
| 193 | int (*raise_irq)(struct dw_pcie_ep *ep, u8 func_no, | 196 | int (*raise_irq)(struct dw_pcie_ep *ep, u8 func_no, |
| 194 | enum pci_epc_irq_type type, u16 interrupt_num); | 197 | enum pci_epc_irq_type type, u16 interrupt_num); |
| 198 | const struct pci_epc_features* (*get_features)(struct dw_pcie_ep *ep); | ||
| 195 | }; | 199 | }; |
| 196 | 200 | ||
| 197 | struct dw_pcie_ep { | 201 | struct dw_pcie_ep { |
diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c index d185ea5fe996..a7f703556790 100644 --- a/drivers/pci/controller/dwc/pcie-qcom.c +++ b/drivers/pci/controller/dwc/pcie-qcom.c | |||
| @@ -1228,7 +1228,7 @@ static int qcom_pcie_probe(struct platform_device *pdev) | |||
| 1228 | 1228 | ||
| 1229 | pcie->ops = of_device_get_match_data(dev); | 1229 | pcie->ops = of_device_get_match_data(dev); |
| 1230 | 1230 | ||
| 1231 | pcie->reset = devm_gpiod_get_optional(dev, "perst", GPIOD_OUT_LOW); | 1231 | pcie->reset = devm_gpiod_get_optional(dev, "perst", GPIOD_OUT_HIGH); |
| 1232 | if (IS_ERR(pcie->reset)) { | 1232 | if (IS_ERR(pcie->reset)) { |
| 1233 | ret = PTR_ERR(pcie->reset); | 1233 | ret = PTR_ERR(pcie->reset); |
| 1234 | goto err_pm_runtime_put; | 1234 | goto err_pm_runtime_put; |
diff --git a/drivers/pci/controller/pci-aardvark.c b/drivers/pci/controller/pci-aardvark.c index 750081c1cb48..eb58dfdaba1b 100644 --- a/drivers/pci/controller/pci-aardvark.c +++ b/drivers/pci/controller/pci-aardvark.c | |||
| @@ -466,7 +466,7 @@ advk_pci_bridge_emul_pcie_conf_write(struct pci_bridge_emul *bridge, | |||
| 466 | } | 466 | } |
| 467 | } | 467 | } |
| 468 | 468 | ||
| 469 | struct pci_bridge_emul_ops advk_pci_bridge_emul_ops = { | 469 | static struct pci_bridge_emul_ops advk_pci_bridge_emul_ops = { |
| 470 | .read_pcie = advk_pci_bridge_emul_pcie_conf_read, | 470 | .read_pcie = advk_pci_bridge_emul_pcie_conf_read, |
| 471 | .write_pcie = advk_pci_bridge_emul_pcie_conf_write, | 471 | .write_pcie = advk_pci_bridge_emul_pcie_conf_write, |
| 472 | }; | 472 | }; |
| @@ -499,7 +499,7 @@ static void advk_sw_pci_bridge_init(struct advk_pcie *pcie) | |||
| 499 | bridge->data = pcie; | 499 | bridge->data = pcie; |
| 500 | bridge->ops = &advk_pci_bridge_emul_ops; | 500 | bridge->ops = &advk_pci_bridge_emul_ops; |
| 501 | 501 | ||
| 502 | pci_bridge_emul_init(bridge); | 502 | pci_bridge_emul_init(bridge, 0); |
| 503 | 503 | ||
| 504 | } | 504 | } |
| 505 | 505 | ||
diff --git a/drivers/pci/controller/pci-hyperv.c b/drivers/pci/controller/pci-hyperv.c index 9ba4d12c179c..95441a35eceb 100644 --- a/drivers/pci/controller/pci-hyperv.c +++ b/drivers/pci/controller/pci-hyperv.c | |||
| @@ -391,14 +391,6 @@ struct hv_interrupt_entry { | |||
| 391 | u32 data; | 391 | u32 data; |
| 392 | }; | 392 | }; |
| 393 | 393 | ||
| 394 | #define HV_VP_SET_BANK_COUNT_MAX 5 /* current implementation limit */ | ||
| 395 | |||
| 396 | struct hv_vp_set { | ||
| 397 | u64 format; /* 0 (HvGenericSetSparse4k) */ | ||
| 398 | u64 valid_banks; | ||
| 399 | u64 masks[HV_VP_SET_BANK_COUNT_MAX]; | ||
| 400 | }; | ||
| 401 | |||
| 402 | /* | 394 | /* |
| 403 | * flags for hv_device_interrupt_target.flags | 395 | * flags for hv_device_interrupt_target.flags |
| 404 | */ | 396 | */ |
| @@ -410,7 +402,7 @@ struct hv_device_interrupt_target { | |||
| 410 | u32 flags; | 402 | u32 flags; |
| 411 | union { | 403 | union { |
| 412 | u64 vp_mask; | 404 | u64 vp_mask; |
| 413 | struct hv_vp_set vp_set; | 405 | struct hv_vpset vp_set; |
| 414 | }; | 406 | }; |
| 415 | }; | 407 | }; |
| 416 | 408 | ||
| @@ -420,7 +412,7 @@ struct retarget_msi_interrupt { | |||
| 420 | struct hv_interrupt_entry int_entry; | 412 | struct hv_interrupt_entry int_entry; |
| 421 | u64 reserved2; | 413 | u64 reserved2; |
| 422 | struct hv_device_interrupt_target int_target; | 414 | struct hv_device_interrupt_target int_target; |
| 423 | } __packed; | 415 | } __packed __aligned(8); |
| 424 | 416 | ||
| 425 | /* | 417 | /* |
| 426 | * Driver specific state. | 418 | * Driver specific state. |
| @@ -460,12 +452,16 @@ struct hv_pcibus_device { | |||
| 460 | struct msi_controller msi_chip; | 452 | struct msi_controller msi_chip; |
| 461 | struct irq_domain *irq_domain; | 453 | struct irq_domain *irq_domain; |
| 462 | 454 | ||
| 463 | /* hypercall arg, must not cross page boundary */ | ||
| 464 | struct retarget_msi_interrupt retarget_msi_interrupt_params; | ||
| 465 | |||
| 466 | spinlock_t retarget_msi_interrupt_lock; | 455 | spinlock_t retarget_msi_interrupt_lock; |
| 467 | 456 | ||
| 468 | struct workqueue_struct *wq; | 457 | struct workqueue_struct *wq; |
| 458 | |||
| 459 | /* hypercall arg, must not cross page boundary */ | ||
| 460 | struct retarget_msi_interrupt retarget_msi_interrupt_params; | ||
| 461 | |||
| 462 | /* | ||
| 463 | * Don't put anything here: retarget_msi_interrupt_params must be last | ||
| 464 | */ | ||
| 469 | }; | 465 | }; |
| 470 | 466 | ||
| 471 | /* | 467 | /* |
| @@ -910,12 +906,12 @@ static void hv_irq_unmask(struct irq_data *data) | |||
| 910 | struct retarget_msi_interrupt *params; | 906 | struct retarget_msi_interrupt *params; |
| 911 | struct hv_pcibus_device *hbus; | 907 | struct hv_pcibus_device *hbus; |
| 912 | struct cpumask *dest; | 908 | struct cpumask *dest; |
| 909 | cpumask_var_t tmp; | ||
| 913 | struct pci_bus *pbus; | 910 | struct pci_bus *pbus; |
| 914 | struct pci_dev *pdev; | 911 | struct pci_dev *pdev; |
| 915 | unsigned long flags; | 912 | unsigned long flags; |
| 916 | u32 var_size = 0; | 913 | u32 var_size = 0; |
| 917 | int cpu_vmbus; | 914 | int cpu, nr_bank; |
| 918 | int cpu; | ||
| 919 | u64 res; | 915 | u64 res; |
| 920 | 916 | ||
| 921 | dest = irq_data_get_effective_affinity_mask(data); | 917 | dest = irq_data_get_effective_affinity_mask(data); |
| @@ -955,28 +951,27 @@ static void hv_irq_unmask(struct irq_data *data) | |||
| 955 | */ | 951 | */ |
| 956 | params->int_target.flags |= | 952 | params->int_target.flags |= |
| 957 | HV_DEVICE_INTERRUPT_TARGET_PROCESSOR_SET; | 953 | HV_DEVICE_INTERRUPT_TARGET_PROCESSOR_SET; |
| 958 | params->int_target.vp_set.valid_banks = | ||
| 959 | (1ull << HV_VP_SET_BANK_COUNT_MAX) - 1; | ||
| 960 | 954 | ||
| 961 | /* | 955 | if (!alloc_cpumask_var(&tmp, GFP_ATOMIC)) { |
| 962 | * var-sized hypercall, var-size starts after vp_mask (thus | 956 | res = 1; |
| 963 | * vp_set.format does not count, but vp_set.valid_banks does). | 957 | goto exit_unlock; |
| 964 | */ | 958 | } |
| 965 | var_size = 1 + HV_VP_SET_BANK_COUNT_MAX; | ||
| 966 | 959 | ||
| 967 | for_each_cpu_and(cpu, dest, cpu_online_mask) { | 960 | cpumask_and(tmp, dest, cpu_online_mask); |
| 968 | cpu_vmbus = hv_cpu_number_to_vp_number(cpu); | 961 | nr_bank = cpumask_to_vpset(¶ms->int_target.vp_set, tmp); |
| 962 | free_cpumask_var(tmp); | ||
| 969 | 963 | ||
| 970 | if (cpu_vmbus >= HV_VP_SET_BANK_COUNT_MAX * 64) { | 964 | if (nr_bank <= 0) { |
| 971 | dev_err(&hbus->hdev->device, | 965 | res = 1; |
| 972 | "too high CPU %d", cpu_vmbus); | 966 | goto exit_unlock; |
| 973 | res = 1; | ||
| 974 | goto exit_unlock; | ||
| 975 | } | ||
| 976 | |||
| 977 | params->int_target.vp_set.masks[cpu_vmbus / 64] |= | ||
| 978 | (1ULL << (cpu_vmbus & 63)); | ||
| 979 | } | 967 | } |
| 968 | |||
| 969 | /* | ||
| 970 | * var-sized hypercall, var-size starts after vp_mask (thus | ||
| 971 | * vp_set.format does not count, but vp_set.valid_bank_mask | ||
| 972 | * does). | ||
| 973 | */ | ||
| 974 | var_size = 1 + nr_bank; | ||
| 980 | } else { | 975 | } else { |
| 981 | for_each_cpu_and(cpu, dest, cpu_online_mask) { | 976 | for_each_cpu_and(cpu, dest, cpu_online_mask) { |
| 982 | params->int_target.vp_mask |= | 977 | params->int_target.vp_mask |= |
diff --git a/drivers/pci/controller/pci-mvebu.c b/drivers/pci/controller/pci-mvebu.c index fa0fc46edb0c..d3a0419e42f2 100644 --- a/drivers/pci/controller/pci-mvebu.c +++ b/drivers/pci/controller/pci-mvebu.c | |||
| @@ -583,7 +583,7 @@ static void mvebu_pci_bridge_emul_init(struct mvebu_pcie_port *port) | |||
| 583 | bridge->data = port; | 583 | bridge->data = port; |
| 584 | bridge->ops = &mvebu_pci_bridge_emul_ops; | 584 | bridge->ops = &mvebu_pci_bridge_emul_ops; |
| 585 | 585 | ||
| 586 | pci_bridge_emul_init(bridge); | 586 | pci_bridge_emul_init(bridge, PCI_BRIDGE_EMUL_NO_PREFETCHABLE_BAR); |
| 587 | } | 587 | } |
| 588 | 588 | ||
| 589 | static inline struct mvebu_pcie *sys_to_pcie(struct pci_sys_data *sys) | 589 | static inline struct mvebu_pcie *sys_to_pcie(struct pci_sys_data *sys) |
diff --git a/drivers/pci/controller/pcie-altera.c b/drivers/pci/controller/pcie-altera.c index 7d05e51205b3..27edcebd1726 100644 --- a/drivers/pci/controller/pcie-altera.c +++ b/drivers/pci/controller/pcie-altera.c | |||
| @@ -11,6 +11,7 @@ | |||
| 11 | #include <linux/irqchip/chained_irq.h> | 11 | #include <linux/irqchip/chained_irq.h> |
| 12 | #include <linux/init.h> | 12 | #include <linux/init.h> |
| 13 | #include <linux/of_address.h> | 13 | #include <linux/of_address.h> |
| 14 | #include <linux/of_device.h> | ||
| 14 | #include <linux/of_irq.h> | 15 | #include <linux/of_irq.h> |
| 15 | #include <linux/of_pci.h> | 16 | #include <linux/of_pci.h> |
| 16 | #include <linux/pci.h> | 17 | #include <linux/pci.h> |
| @@ -37,7 +38,12 @@ | |||
| 37 | #define RP_LTSSM_MASK 0x1f | 38 | #define RP_LTSSM_MASK 0x1f |
| 38 | #define LTSSM_L0 0xf | 39 | #define LTSSM_L0 0xf |
| 39 | 40 | ||
| 40 | #define PCIE_CAP_OFFSET 0x80 | 41 | #define S10_RP_TX_CNTRL 0x2004 |
| 42 | #define S10_RP_RXCPL_REG 0x2008 | ||
| 43 | #define S10_RP_RXCPL_STATUS 0x200C | ||
| 44 | #define S10_RP_CFG_ADDR(pcie, reg) \ | ||
| 45 | (((pcie)->hip_base) + (reg) + (1 << 20)) | ||
| 46 | |||
| 41 | /* TLP configuration type 0 and 1 */ | 47 | /* TLP configuration type 0 and 1 */ |
| 42 | #define TLP_FMTTYPE_CFGRD0 0x04 /* Configuration Read Type 0 */ | 48 | #define TLP_FMTTYPE_CFGRD0 0x04 /* Configuration Read Type 0 */ |
| 43 | #define TLP_FMTTYPE_CFGWR0 0x44 /* Configuration Write Type 0 */ | 49 | #define TLP_FMTTYPE_CFGWR0 0x44 /* Configuration Write Type 0 */ |
| @@ -49,18 +55,19 @@ | |||
| 49 | #define RP_DEVFN 0 | 55 | #define RP_DEVFN 0 |
| 50 | #define TLP_REQ_ID(bus, devfn) (((bus) << 8) | (devfn)) | 56 | #define TLP_REQ_ID(bus, devfn) (((bus) << 8) | (devfn)) |
| 51 | #define TLP_CFGRD_DW0(pcie, bus) \ | 57 | #define TLP_CFGRD_DW0(pcie, bus) \ |
| 52 | ((((bus == pcie->root_bus_nr) ? TLP_FMTTYPE_CFGRD0 \ | 58 | ((((bus == pcie->root_bus_nr) ? pcie->pcie_data->cfgrd0 \ |
| 53 | : TLP_FMTTYPE_CFGRD1) << 24) | \ | 59 | : pcie->pcie_data->cfgrd1) << 24) | \ |
| 54 | TLP_PAYLOAD_SIZE) | 60 | TLP_PAYLOAD_SIZE) |
| 55 | #define TLP_CFGWR_DW0(pcie, bus) \ | 61 | #define TLP_CFGWR_DW0(pcie, bus) \ |
| 56 | ((((bus == pcie->root_bus_nr) ? TLP_FMTTYPE_CFGWR0 \ | 62 | ((((bus == pcie->root_bus_nr) ? pcie->pcie_data->cfgwr0 \ |
| 57 | : TLP_FMTTYPE_CFGWR1) << 24) | \ | 63 | : pcie->pcie_data->cfgwr1) << 24) | \ |
| 58 | TLP_PAYLOAD_SIZE) | 64 | TLP_PAYLOAD_SIZE) |
| 59 | #define TLP_CFG_DW1(pcie, tag, be) \ | 65 | #define TLP_CFG_DW1(pcie, tag, be) \ |
| 60 | (((TLP_REQ_ID(pcie->root_bus_nr, RP_DEVFN)) << 16) | (tag << 8) | (be)) | 66 | (((TLP_REQ_ID(pcie->root_bus_nr, RP_DEVFN)) << 16) | (tag << 8) | (be)) |
| 61 | #define TLP_CFG_DW2(bus, devfn, offset) \ | 67 | #define TLP_CFG_DW2(bus, devfn, offset) \ |
| 62 | (((bus) << 24) | ((devfn) << 16) | (offset)) | 68 | (((bus) << 24) | ((devfn) << 16) | (offset)) |
| 63 | #define TLP_COMP_STATUS(s) (((s) >> 13) & 7) | 69 | #define TLP_COMP_STATUS(s) (((s) >> 13) & 7) |
| 70 | #define TLP_BYTE_COUNT(s) (((s) >> 0) & 0xfff) | ||
| 64 | #define TLP_HDR_SIZE 3 | 71 | #define TLP_HDR_SIZE 3 |
| 65 | #define TLP_LOOP 500 | 72 | #define TLP_LOOP 500 |
| 66 | 73 | ||
| @@ -69,14 +76,47 @@ | |||
| 69 | 76 | ||
| 70 | #define DWORD_MASK 3 | 77 | #define DWORD_MASK 3 |
| 71 | 78 | ||
| 79 | #define S10_TLP_FMTTYPE_CFGRD0 0x05 | ||
| 80 | #define S10_TLP_FMTTYPE_CFGRD1 0x04 | ||
| 81 | #define S10_TLP_FMTTYPE_CFGWR0 0x45 | ||
| 82 | #define S10_TLP_FMTTYPE_CFGWR1 0x44 | ||
| 83 | |||
| 84 | enum altera_pcie_version { | ||
| 85 | ALTERA_PCIE_V1 = 0, | ||
| 86 | ALTERA_PCIE_V2, | ||
| 87 | }; | ||
| 88 | |||
| 72 | struct altera_pcie { | 89 | struct altera_pcie { |
| 73 | struct platform_device *pdev; | 90 | struct platform_device *pdev; |
| 74 | void __iomem *cra_base; /* DT Cra */ | 91 | void __iomem *cra_base; |
| 92 | void __iomem *hip_base; | ||
| 75 | int irq; | 93 | int irq; |
| 76 | u8 root_bus_nr; | 94 | u8 root_bus_nr; |
| 77 | struct irq_domain *irq_domain; | 95 | struct irq_domain *irq_domain; |
| 78 | struct resource bus_range; | 96 | struct resource bus_range; |
| 79 | struct list_head resources; | 97 | struct list_head resources; |
| 98 | const struct altera_pcie_data *pcie_data; | ||
| 99 | }; | ||
| 100 | |||
| 101 | struct altera_pcie_ops { | ||
| 102 | int (*tlp_read_pkt)(struct altera_pcie *pcie, u32 *value); | ||
| 103 | void (*tlp_write_pkt)(struct altera_pcie *pcie, u32 *headers, | ||
| 104 | u32 data, bool align); | ||
| 105 | bool (*get_link_status)(struct altera_pcie *pcie); | ||
| 106 | int (*rp_read_cfg)(struct altera_pcie *pcie, int where, | ||
| 107 | int size, u32 *value); | ||
| 108 | int (*rp_write_cfg)(struct altera_pcie *pcie, u8 busno, | ||
| 109 | int where, int size, u32 value); | ||
| 110 | }; | ||
| 111 | |||
| 112 | struct altera_pcie_data { | ||
| 113 | const struct altera_pcie_ops *ops; | ||
| 114 | enum altera_pcie_version version; | ||
| 115 | u32 cap_offset; /* PCIe capability structure register offset */ | ||
| 116 | u32 cfgrd0; | ||
| 117 | u32 cfgrd1; | ||
| 118 | u32 cfgwr0; | ||
| 119 | u32 cfgwr1; | ||
| 80 | }; | 120 | }; |
| 81 | 121 | ||
| 82 | struct tlp_rp_regpair_t { | 122 | struct tlp_rp_regpair_t { |
| @@ -101,6 +141,15 @@ static bool altera_pcie_link_up(struct altera_pcie *pcie) | |||
| 101 | return !!((cra_readl(pcie, RP_LTSSM) & RP_LTSSM_MASK) == LTSSM_L0); | 141 | return !!((cra_readl(pcie, RP_LTSSM) & RP_LTSSM_MASK) == LTSSM_L0); |
| 102 | } | 142 | } |
| 103 | 143 | ||
| 144 | static bool s10_altera_pcie_link_up(struct altera_pcie *pcie) | ||
| 145 | { | ||
| 146 | void __iomem *addr = S10_RP_CFG_ADDR(pcie, | ||
| 147 | pcie->pcie_data->cap_offset + | ||
| 148 | PCI_EXP_LNKSTA); | ||
| 149 | |||
| 150 | return !!(readw(addr) & PCI_EXP_LNKSTA_DLLLA); | ||
| 151 | } | ||
| 152 | |||
| 104 | /* | 153 | /* |
| 105 | * Altera PCIe port uses BAR0 of RC's configuration space as the translation | 154 | * Altera PCIe port uses BAR0 of RC's configuration space as the translation |
| 106 | * from PCI bus to native BUS. Entire DDR region is mapped into PCIe space | 155 | * from PCI bus to native BUS. Entire DDR region is mapped into PCIe space |
| @@ -128,12 +177,18 @@ static void tlp_write_tx(struct altera_pcie *pcie, | |||
| 128 | cra_writel(pcie, tlp_rp_regdata->ctrl, RP_TX_CNTRL); | 177 | cra_writel(pcie, tlp_rp_regdata->ctrl, RP_TX_CNTRL); |
| 129 | } | 178 | } |
| 130 | 179 | ||
| 180 | static void s10_tlp_write_tx(struct altera_pcie *pcie, u32 reg0, u32 ctrl) | ||
| 181 | { | ||
| 182 | cra_writel(pcie, reg0, RP_TX_REG0); | ||
| 183 | cra_writel(pcie, ctrl, S10_RP_TX_CNTRL); | ||
| 184 | } | ||
| 185 | |||
| 131 | static bool altera_pcie_valid_device(struct altera_pcie *pcie, | 186 | static bool altera_pcie_valid_device(struct altera_pcie *pcie, |
| 132 | struct pci_bus *bus, int dev) | 187 | struct pci_bus *bus, int dev) |
| 133 | { | 188 | { |
| 134 | /* If there is no link, then there is no device */ | 189 | /* If there is no link, then there is no device */ |
| 135 | if (bus->number != pcie->root_bus_nr) { | 190 | if (bus->number != pcie->root_bus_nr) { |
| 136 | if (!altera_pcie_link_up(pcie)) | 191 | if (!pcie->pcie_data->ops->get_link_status(pcie)) |
| 137 | return false; | 192 | return false; |
| 138 | } | 193 | } |
| 139 | 194 | ||
| @@ -183,6 +238,53 @@ static int tlp_read_packet(struct altera_pcie *pcie, u32 *value) | |||
| 183 | return PCIBIOS_DEVICE_NOT_FOUND; | 238 | return PCIBIOS_DEVICE_NOT_FOUND; |
| 184 | } | 239 | } |
| 185 | 240 | ||
| 241 | static int s10_tlp_read_packet(struct altera_pcie *pcie, u32 *value) | ||
| 242 | { | ||
| 243 | u32 ctrl; | ||
| 244 | u32 comp_status; | ||
| 245 | u32 dw[4]; | ||
| 246 | u32 count; | ||
| 247 | struct device *dev = &pcie->pdev->dev; | ||
| 248 | |||
| 249 | for (count = 0; count < TLP_LOOP; count++) { | ||
| 250 | ctrl = cra_readl(pcie, S10_RP_RXCPL_STATUS); | ||
| 251 | if (ctrl & RP_RXCPL_SOP) { | ||
| 252 | /* Read first DW */ | ||
| 253 | dw[0] = cra_readl(pcie, S10_RP_RXCPL_REG); | ||
| 254 | break; | ||
| 255 | } | ||
| 256 | |||
| 257 | udelay(5); | ||
| 258 | } | ||
| 259 | |||
| 260 | /* SOP detection failed, return error */ | ||
| 261 | if (count == TLP_LOOP) | ||
| 262 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
| 263 | |||
| 264 | count = 1; | ||
| 265 | |||
| 266 | /* Poll for EOP */ | ||
| 267 | while (count < ARRAY_SIZE(dw)) { | ||
| 268 | ctrl = cra_readl(pcie, S10_RP_RXCPL_STATUS); | ||
| 269 | dw[count++] = cra_readl(pcie, S10_RP_RXCPL_REG); | ||
| 270 | if (ctrl & RP_RXCPL_EOP) { | ||
| 271 | comp_status = TLP_COMP_STATUS(dw[1]); | ||
| 272 | if (comp_status) | ||
| 273 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
| 274 | |||
| 275 | if (value && TLP_BYTE_COUNT(dw[1]) == sizeof(u32) && | ||
| 276 | count == 4) | ||
| 277 | *value = dw[3]; | ||
| 278 | |||
| 279 | return PCIBIOS_SUCCESSFUL; | ||
| 280 | } | ||
| 281 | } | ||
| 282 | |||
| 283 | dev_warn(dev, "Malformed TLP packet\n"); | ||
| 284 | |||
| 285 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
| 286 | } | ||
| 287 | |||
| 186 | static void tlp_write_packet(struct altera_pcie *pcie, u32 *headers, | 288 | static void tlp_write_packet(struct altera_pcie *pcie, u32 *headers, |
| 187 | u32 data, bool align) | 289 | u32 data, bool align) |
| 188 | { | 290 | { |
| @@ -210,6 +312,15 @@ static void tlp_write_packet(struct altera_pcie *pcie, u32 *headers, | |||
| 210 | tlp_write_tx(pcie, &tlp_rp_regdata); | 312 | tlp_write_tx(pcie, &tlp_rp_regdata); |
| 211 | } | 313 | } |
| 212 | 314 | ||
| 315 | static void s10_tlp_write_packet(struct altera_pcie *pcie, u32 *headers, | ||
| 316 | u32 data, bool dummy) | ||
| 317 | { | ||
| 318 | s10_tlp_write_tx(pcie, headers[0], RP_TX_SOP); | ||
| 319 | s10_tlp_write_tx(pcie, headers[1], 0); | ||
| 320 | s10_tlp_write_tx(pcie, headers[2], 0); | ||
| 321 | s10_tlp_write_tx(pcie, data, RP_TX_EOP); | ||
| 322 | } | ||
| 323 | |||
| 213 | static int tlp_cfg_dword_read(struct altera_pcie *pcie, u8 bus, u32 devfn, | 324 | static int tlp_cfg_dword_read(struct altera_pcie *pcie, u8 bus, u32 devfn, |
| 214 | int where, u8 byte_en, u32 *value) | 325 | int where, u8 byte_en, u32 *value) |
| 215 | { | 326 | { |
| @@ -219,9 +330,9 @@ static int tlp_cfg_dword_read(struct altera_pcie *pcie, u8 bus, u32 devfn, | |||
| 219 | headers[1] = TLP_CFG_DW1(pcie, TLP_READ_TAG, byte_en); | 330 | headers[1] = TLP_CFG_DW1(pcie, TLP_READ_TAG, byte_en); |
| 220 | headers[2] = TLP_CFG_DW2(bus, devfn, where); | 331 | headers[2] = TLP_CFG_DW2(bus, devfn, where); |
| 221 | 332 | ||
| 222 | tlp_write_packet(pcie, headers, 0, false); | 333 | pcie->pcie_data->ops->tlp_write_pkt(pcie, headers, 0, false); |
| 223 | 334 | ||
| 224 | return tlp_read_packet(pcie, value); | 335 | return pcie->pcie_data->ops->tlp_read_pkt(pcie, value); |
| 225 | } | 336 | } |
| 226 | 337 | ||
| 227 | static int tlp_cfg_dword_write(struct altera_pcie *pcie, u8 bus, u32 devfn, | 338 | static int tlp_cfg_dword_write(struct altera_pcie *pcie, u8 bus, u32 devfn, |
| @@ -236,11 +347,13 @@ static int tlp_cfg_dword_write(struct altera_pcie *pcie, u8 bus, u32 devfn, | |||
| 236 | 347 | ||
| 237 | /* check alignment to Qword */ | 348 | /* check alignment to Qword */ |
| 238 | if ((where & 0x7) == 0) | 349 | if ((where & 0x7) == 0) |
| 239 | tlp_write_packet(pcie, headers, value, true); | 350 | pcie->pcie_data->ops->tlp_write_pkt(pcie, headers, |
| 351 | value, true); | ||
| 240 | else | 352 | else |
| 241 | tlp_write_packet(pcie, headers, value, false); | 353 | pcie->pcie_data->ops->tlp_write_pkt(pcie, headers, |
| 354 | value, false); | ||
| 242 | 355 | ||
| 243 | ret = tlp_read_packet(pcie, NULL); | 356 | ret = pcie->pcie_data->ops->tlp_read_pkt(pcie, NULL); |
| 244 | if (ret != PCIBIOS_SUCCESSFUL) | 357 | if (ret != PCIBIOS_SUCCESSFUL) |
| 245 | return ret; | 358 | return ret; |
| 246 | 359 | ||
| @@ -254,6 +367,53 @@ static int tlp_cfg_dword_write(struct altera_pcie *pcie, u8 bus, u32 devfn, | |||
| 254 | return PCIBIOS_SUCCESSFUL; | 367 | return PCIBIOS_SUCCESSFUL; |
| 255 | } | 368 | } |
| 256 | 369 | ||
| 370 | static int s10_rp_read_cfg(struct altera_pcie *pcie, int where, | ||
| 371 | int size, u32 *value) | ||
| 372 | { | ||
| 373 | void __iomem *addr = S10_RP_CFG_ADDR(pcie, where); | ||
| 374 | |||
| 375 | switch (size) { | ||
| 376 | case 1: | ||
| 377 | *value = readb(addr); | ||
| 378 | break; | ||
| 379 | case 2: | ||
| 380 | *value = readw(addr); | ||
| 381 | break; | ||
| 382 | default: | ||
| 383 | *value = readl(addr); | ||
| 384 | break; | ||
| 385 | } | ||
| 386 | |||
| 387 | return PCIBIOS_SUCCESSFUL; | ||
| 388 | } | ||
| 389 | |||
| 390 | static int s10_rp_write_cfg(struct altera_pcie *pcie, u8 busno, | ||
| 391 | int where, int size, u32 value) | ||
| 392 | { | ||
| 393 | void __iomem *addr = S10_RP_CFG_ADDR(pcie, where); | ||
| 394 | |||
| 395 | switch (size) { | ||
| 396 | case 1: | ||
| 397 | writeb(value, addr); | ||
| 398 | break; | ||
| 399 | case 2: | ||
| 400 | writew(value, addr); | ||
| 401 | break; | ||
| 402 | default: | ||
| 403 | writel(value, addr); | ||
| 404 | break; | ||
| 405 | } | ||
| 406 | |||
| 407 | /* | ||
| 408 | * Monitor changes to PCI_PRIMARY_BUS register on root port | ||
| 409 | * and update local copy of root bus number accordingly. | ||
| 410 | */ | ||
| 411 | if (busno == pcie->root_bus_nr && where == PCI_PRIMARY_BUS) | ||
| 412 | pcie->root_bus_nr = value & 0xff; | ||
| 413 | |||
| 414 | return PCIBIOS_SUCCESSFUL; | ||
| 415 | } | ||
| 416 | |||
| 257 | static int _altera_pcie_cfg_read(struct altera_pcie *pcie, u8 busno, | 417 | static int _altera_pcie_cfg_read(struct altera_pcie *pcie, u8 busno, |
| 258 | unsigned int devfn, int where, int size, | 418 | unsigned int devfn, int where, int size, |
| 259 | u32 *value) | 419 | u32 *value) |
| @@ -262,6 +422,10 @@ static int _altera_pcie_cfg_read(struct altera_pcie *pcie, u8 busno, | |||
| 262 | u32 data; | 422 | u32 data; |
| 263 | u8 byte_en; | 423 | u8 byte_en; |
| 264 | 424 | ||
| 425 | if (busno == pcie->root_bus_nr && pcie->pcie_data->ops->rp_read_cfg) | ||
| 426 | return pcie->pcie_data->ops->rp_read_cfg(pcie, where, | ||
| 427 | size, value); | ||
| 428 | |||
| 265 | switch (size) { | 429 | switch (size) { |
| 266 | case 1: | 430 | case 1: |
| 267 | byte_en = 1 << (where & 3); | 431 | byte_en = 1 << (where & 3); |
| @@ -302,6 +466,10 @@ static int _altera_pcie_cfg_write(struct altera_pcie *pcie, u8 busno, | |||
| 302 | u32 shift = 8 * (where & 3); | 466 | u32 shift = 8 * (where & 3); |
| 303 | u8 byte_en; | 467 | u8 byte_en; |
| 304 | 468 | ||
| 469 | if (busno == pcie->root_bus_nr && pcie->pcie_data->ops->rp_write_cfg) | ||
| 470 | return pcie->pcie_data->ops->rp_write_cfg(pcie, busno, | ||
| 471 | where, size, value); | ||
| 472 | |||
| 305 | switch (size) { | 473 | switch (size) { |
| 306 | case 1: | 474 | case 1: |
| 307 | data32 = (value & 0xff) << shift; | 475 | data32 = (value & 0xff) << shift; |
| @@ -365,7 +533,8 @@ static int altera_read_cap_word(struct altera_pcie *pcie, u8 busno, | |||
| 365 | int ret; | 533 | int ret; |
| 366 | 534 | ||
| 367 | ret = _altera_pcie_cfg_read(pcie, busno, devfn, | 535 | ret = _altera_pcie_cfg_read(pcie, busno, devfn, |
| 368 | PCIE_CAP_OFFSET + offset, sizeof(*value), | 536 | pcie->pcie_data->cap_offset + offset, |
| 537 | sizeof(*value), | ||
| 369 | &data); | 538 | &data); |
| 370 | *value = data; | 539 | *value = data; |
| 371 | return ret; | 540 | return ret; |
| @@ -375,7 +544,8 @@ static int altera_write_cap_word(struct altera_pcie *pcie, u8 busno, | |||
| 375 | unsigned int devfn, int offset, u16 value) | 544 | unsigned int devfn, int offset, u16 value) |
| 376 | { | 545 | { |
| 377 | return _altera_pcie_cfg_write(pcie, busno, devfn, | 546 | return _altera_pcie_cfg_write(pcie, busno, devfn, |
| 378 | PCIE_CAP_OFFSET + offset, sizeof(value), | 547 | pcie->pcie_data->cap_offset + offset, |
| 548 | sizeof(value), | ||
| 379 | value); | 549 | value); |
| 380 | } | 550 | } |
| 381 | 551 | ||
| @@ -403,7 +573,7 @@ static void altera_wait_link_retrain(struct altera_pcie *pcie) | |||
| 403 | /* Wait for link is up */ | 573 | /* Wait for link is up */ |
| 404 | start_jiffies = jiffies; | 574 | start_jiffies = jiffies; |
| 405 | for (;;) { | 575 | for (;;) { |
| 406 | if (altera_pcie_link_up(pcie)) | 576 | if (pcie->pcie_data->ops->get_link_status(pcie)) |
| 407 | break; | 577 | break; |
| 408 | 578 | ||
| 409 | if (time_after(jiffies, start_jiffies + LINK_UP_TIMEOUT)) { | 579 | if (time_after(jiffies, start_jiffies + LINK_UP_TIMEOUT)) { |
| @@ -418,7 +588,7 @@ static void altera_pcie_retrain(struct altera_pcie *pcie) | |||
| 418 | { | 588 | { |
| 419 | u16 linkcap, linkstat, linkctl; | 589 | u16 linkcap, linkstat, linkctl; |
| 420 | 590 | ||
| 421 | if (!altera_pcie_link_up(pcie)) | 591 | if (!pcie->pcie_data->ops->get_link_status(pcie)) |
| 422 | return; | 592 | return; |
| 423 | 593 | ||
| 424 | /* | 594 | /* |
| @@ -540,12 +710,20 @@ static int altera_pcie_parse_dt(struct altera_pcie *pcie) | |||
| 540 | struct device *dev = &pcie->pdev->dev; | 710 | struct device *dev = &pcie->pdev->dev; |
| 541 | struct platform_device *pdev = pcie->pdev; | 711 | struct platform_device *pdev = pcie->pdev; |
| 542 | struct resource *cra; | 712 | struct resource *cra; |
| 713 | struct resource *hip; | ||
| 543 | 714 | ||
| 544 | cra = platform_get_resource_byname(pdev, IORESOURCE_MEM, "Cra"); | 715 | cra = platform_get_resource_byname(pdev, IORESOURCE_MEM, "Cra"); |
| 545 | pcie->cra_base = devm_ioremap_resource(dev, cra); | 716 | pcie->cra_base = devm_ioremap_resource(dev, cra); |
| 546 | if (IS_ERR(pcie->cra_base)) | 717 | if (IS_ERR(pcie->cra_base)) |
| 547 | return PTR_ERR(pcie->cra_base); | 718 | return PTR_ERR(pcie->cra_base); |
| 548 | 719 | ||
| 720 | if (pcie->pcie_data->version == ALTERA_PCIE_V2) { | ||
| 721 | hip = platform_get_resource_byname(pdev, IORESOURCE_MEM, "Hip"); | ||
| 722 | pcie->hip_base = devm_ioremap_resource(&pdev->dev, hip); | ||
| 723 | if (IS_ERR(pcie->hip_base)) | ||
| 724 | return PTR_ERR(pcie->hip_base); | ||
| 725 | } | ||
| 726 | |||
| 549 | /* setup IRQ */ | 727 | /* setup IRQ */ |
| 550 | pcie->irq = platform_get_irq(pdev, 0); | 728 | pcie->irq = platform_get_irq(pdev, 0); |
| 551 | if (pcie->irq < 0) { | 729 | if (pcie->irq < 0) { |
| @@ -562,6 +740,48 @@ static void altera_pcie_host_init(struct altera_pcie *pcie) | |||
| 562 | altera_pcie_retrain(pcie); | 740 | altera_pcie_retrain(pcie); |
| 563 | } | 741 | } |
| 564 | 742 | ||
| 743 | static const struct altera_pcie_ops altera_pcie_ops_1_0 = { | ||
| 744 | .tlp_read_pkt = tlp_read_packet, | ||
| 745 | .tlp_write_pkt = tlp_write_packet, | ||
| 746 | .get_link_status = altera_pcie_link_up, | ||
| 747 | }; | ||
| 748 | |||
| 749 | static const struct altera_pcie_ops altera_pcie_ops_2_0 = { | ||
| 750 | .tlp_read_pkt = s10_tlp_read_packet, | ||
| 751 | .tlp_write_pkt = s10_tlp_write_packet, | ||
| 752 | .get_link_status = s10_altera_pcie_link_up, | ||
| 753 | .rp_read_cfg = s10_rp_read_cfg, | ||
| 754 | .rp_write_cfg = s10_rp_write_cfg, | ||
| 755 | }; | ||
| 756 | |||
| 757 | static const struct altera_pcie_data altera_pcie_1_0_data = { | ||
| 758 | .ops = &altera_pcie_ops_1_0, | ||
| 759 | .cap_offset = 0x80, | ||
| 760 | .version = ALTERA_PCIE_V1, | ||
| 761 | .cfgrd0 = TLP_FMTTYPE_CFGRD0, | ||
| 762 | .cfgrd1 = TLP_FMTTYPE_CFGRD1, | ||
| 763 | .cfgwr0 = TLP_FMTTYPE_CFGWR0, | ||
| 764 | .cfgwr1 = TLP_FMTTYPE_CFGWR1, | ||
| 765 | }; | ||
| 766 | |||
| 767 | static const struct altera_pcie_data altera_pcie_2_0_data = { | ||
| 768 | .ops = &altera_pcie_ops_2_0, | ||
| 769 | .version = ALTERA_PCIE_V2, | ||
| 770 | .cap_offset = 0x70, | ||
| 771 | .cfgrd0 = S10_TLP_FMTTYPE_CFGRD0, | ||
| 772 | .cfgrd1 = S10_TLP_FMTTYPE_CFGRD1, | ||
| 773 | .cfgwr0 = S10_TLP_FMTTYPE_CFGWR0, | ||
| 774 | .cfgwr1 = S10_TLP_FMTTYPE_CFGWR1, | ||
| 775 | }; | ||
| 776 | |||
| 777 | static const struct of_device_id altera_pcie_of_match[] = { | ||
| 778 | {.compatible = "altr,pcie-root-port-1.0", | ||
| 779 | .data = &altera_pcie_1_0_data }, | ||
| 780 | {.compatible = "altr,pcie-root-port-2.0", | ||
| 781 | .data = &altera_pcie_2_0_data }, | ||
| 782 | {}, | ||
| 783 | }; | ||
| 784 | |||
| 565 | static int altera_pcie_probe(struct platform_device *pdev) | 785 | static int altera_pcie_probe(struct platform_device *pdev) |
| 566 | { | 786 | { |
| 567 | struct device *dev = &pdev->dev; | 787 | struct device *dev = &pdev->dev; |
| @@ -570,6 +790,7 @@ static int altera_pcie_probe(struct platform_device *pdev) | |||
| 570 | struct pci_bus *child; | 790 | struct pci_bus *child; |
| 571 | struct pci_host_bridge *bridge; | 791 | struct pci_host_bridge *bridge; |
| 572 | int ret; | 792 | int ret; |
| 793 | const struct of_device_id *match; | ||
| 573 | 794 | ||
| 574 | bridge = devm_pci_alloc_host_bridge(dev, sizeof(*pcie)); | 795 | bridge = devm_pci_alloc_host_bridge(dev, sizeof(*pcie)); |
| 575 | if (!bridge) | 796 | if (!bridge) |
| @@ -578,6 +799,12 @@ static int altera_pcie_probe(struct platform_device *pdev) | |||
| 578 | pcie = pci_host_bridge_priv(bridge); | 799 | pcie = pci_host_bridge_priv(bridge); |
| 579 | pcie->pdev = pdev; | 800 | pcie->pdev = pdev; |
| 580 | 801 | ||
| 802 | match = of_match_device(altera_pcie_of_match, &pdev->dev); | ||
| 803 | if (!match) | ||
| 804 | return -ENODEV; | ||
| 805 | |||
| 806 | pcie->pcie_data = match->data; | ||
| 807 | |||
| 581 | ret = altera_pcie_parse_dt(pcie); | 808 | ret = altera_pcie_parse_dt(pcie); |
| 582 | if (ret) { | 809 | if (ret) { |
| 583 | dev_err(dev, "Parsing DT failed\n"); | 810 | dev_err(dev, "Parsing DT failed\n"); |
| @@ -628,11 +855,6 @@ static int altera_pcie_probe(struct platform_device *pdev) | |||
| 628 | return ret; | 855 | return ret; |
| 629 | } | 856 | } |
| 630 | 857 | ||
| 631 | static const struct of_device_id altera_pcie_of_match[] = { | ||
| 632 | { .compatible = "altr,pcie-root-port-1.0", }, | ||
| 633 | {}, | ||
| 634 | }; | ||
| 635 | |||
| 636 | static struct platform_driver altera_pcie_driver = { | 858 | static struct platform_driver altera_pcie_driver = { |
| 637 | .probe = altera_pcie_probe, | 859 | .probe = altera_pcie_probe, |
| 638 | .driver = { | 860 | .driver = { |
diff --git a/drivers/pci/controller/pcie-cadence-ep.c b/drivers/pci/controller/pcie-cadence-ep.c index c3a088910f48..def7820cb824 100644 --- a/drivers/pci/controller/pcie-cadence-ep.c +++ b/drivers/pci/controller/pcie-cadence-ep.c | |||
| @@ -396,21 +396,21 @@ static int cdns_pcie_ep_start(struct pci_epc *epc) | |||
| 396 | cfg |= BIT(epf->func_no); | 396 | cfg |= BIT(epf->func_no); |
| 397 | cdns_pcie_writel(pcie, CDNS_PCIE_LM_EP_FUNC_CFG, cfg); | 397 | cdns_pcie_writel(pcie, CDNS_PCIE_LM_EP_FUNC_CFG, cfg); |
| 398 | 398 | ||
| 399 | /* | ||
| 400 | * The PCIe links are automatically established by the controller | ||
| 401 | * once for all at powerup: the software can neither start nor stop | ||
| 402 | * those links later at runtime. | ||
| 403 | * | ||
| 404 | * Then we only have to notify the EP core that our links are already | ||
| 405 | * established. However we don't call directly pci_epc_linkup() because | ||
| 406 | * we've already locked the epc->lock. | ||
| 407 | */ | ||
| 408 | list_for_each_entry(epf, &epc->pci_epf, list) | ||
| 409 | pci_epf_linkup(epf); | ||
| 410 | |||
| 411 | return 0; | 399 | return 0; |
| 412 | } | 400 | } |
| 413 | 401 | ||
| 402 | static const struct pci_epc_features cdns_pcie_epc_features = { | ||
| 403 | .linkup_notifier = false, | ||
| 404 | .msi_capable = true, | ||
| 405 | .msix_capable = false, | ||
| 406 | }; | ||
| 407 | |||
| 408 | static const struct pci_epc_features* | ||
| 409 | cdns_pcie_ep_get_features(struct pci_epc *epc, u8 func_no) | ||
| 410 | { | ||
| 411 | return &cdns_pcie_epc_features; | ||
| 412 | } | ||
| 413 | |||
| 414 | static const struct pci_epc_ops cdns_pcie_epc_ops = { | 414 | static const struct pci_epc_ops cdns_pcie_epc_ops = { |
| 415 | .write_header = cdns_pcie_ep_write_header, | 415 | .write_header = cdns_pcie_ep_write_header, |
| 416 | .set_bar = cdns_pcie_ep_set_bar, | 416 | .set_bar = cdns_pcie_ep_set_bar, |
| @@ -421,6 +421,7 @@ static const struct pci_epc_ops cdns_pcie_epc_ops = { | |||
| 421 | .get_msi = cdns_pcie_ep_get_msi, | 421 | .get_msi = cdns_pcie_ep_get_msi, |
| 422 | .raise_irq = cdns_pcie_ep_raise_irq, | 422 | .raise_irq = cdns_pcie_ep_raise_irq, |
| 423 | .start = cdns_pcie_ep_start, | 423 | .start = cdns_pcie_ep_start, |
| 424 | .get_features = cdns_pcie_ep_get_features, | ||
| 424 | }; | 425 | }; |
| 425 | 426 | ||
| 426 | static const struct of_device_id cdns_pcie_ep_of_match[] = { | 427 | static const struct of_device_id cdns_pcie_ep_of_match[] = { |
diff --git a/drivers/pci/controller/pcie-mediatek.c b/drivers/pci/controller/pcie-mediatek.c index 55e471c18e8d..0b6c72804e03 100644 --- a/drivers/pci/controller/pcie-mediatek.c +++ b/drivers/pci/controller/pcie-mediatek.c | |||
| @@ -90,6 +90,12 @@ | |||
| 90 | #define AHB2PCIE_SIZE(x) ((x) & GENMASK(4, 0)) | 90 | #define AHB2PCIE_SIZE(x) ((x) & GENMASK(4, 0)) |
| 91 | #define PCIE_AXI_WINDOW0 0x448 | 91 | #define PCIE_AXI_WINDOW0 0x448 |
| 92 | #define WIN_ENABLE BIT(7) | 92 | #define WIN_ENABLE BIT(7) |
| 93 | /* | ||
| 94 | * Define PCIe to AHB window size as 2^33 to support max 8GB address space | ||
| 95 | * translate, support least 4GB DRAM size access from EP DMA(physical DRAM | ||
| 96 | * start from 0x40000000). | ||
| 97 | */ | ||
| 98 | #define PCIE2AHB_SIZE 0x21 | ||
| 93 | 99 | ||
| 94 | /* PCIe V2 configuration transaction header */ | 100 | /* PCIe V2 configuration transaction header */ |
| 95 | #define PCIE_CFG_HEADER0 0x460 | 101 | #define PCIE_CFG_HEADER0 0x460 |
| @@ -654,7 +660,6 @@ static int mtk_pcie_startup_port_v2(struct mtk_pcie_port *port) | |||
| 654 | struct resource *mem = &pcie->mem; | 660 | struct resource *mem = &pcie->mem; |
| 655 | const struct mtk_pcie_soc *soc = port->pcie->soc; | 661 | const struct mtk_pcie_soc *soc = port->pcie->soc; |
| 656 | u32 val; | 662 | u32 val; |
| 657 | size_t size; | ||
| 658 | int err; | 663 | int err; |
| 659 | 664 | ||
| 660 | /* MT7622 platforms need to enable LTSSM and ASPM from PCIe subsys */ | 665 | /* MT7622 platforms need to enable LTSSM and ASPM from PCIe subsys */ |
| @@ -706,15 +711,15 @@ static int mtk_pcie_startup_port_v2(struct mtk_pcie_port *port) | |||
| 706 | mtk_pcie_enable_msi(port); | 711 | mtk_pcie_enable_msi(port); |
| 707 | 712 | ||
| 708 | /* Set AHB to PCIe translation windows */ | 713 | /* Set AHB to PCIe translation windows */ |
| 709 | size = mem->end - mem->start; | 714 | val = lower_32_bits(mem->start) | |
| 710 | val = lower_32_bits(mem->start) | AHB2PCIE_SIZE(fls(size)); | 715 | AHB2PCIE_SIZE(fls(resource_size(mem))); |
| 711 | writel(val, port->base + PCIE_AHB_TRANS_BASE0_L); | 716 | writel(val, port->base + PCIE_AHB_TRANS_BASE0_L); |
| 712 | 717 | ||
| 713 | val = upper_32_bits(mem->start); | 718 | val = upper_32_bits(mem->start); |
| 714 | writel(val, port->base + PCIE_AHB_TRANS_BASE0_H); | 719 | writel(val, port->base + PCIE_AHB_TRANS_BASE0_H); |
| 715 | 720 | ||
| 716 | /* Set PCIe to AXI translation memory space.*/ | 721 | /* Set PCIe to AXI translation memory space.*/ |
| 717 | val = fls(0xffffffff) | WIN_ENABLE; | 722 | val = PCIE2AHB_SIZE | WIN_ENABLE; |
| 718 | writel(val, port->base + PCIE_AXI_WINDOW0); | 723 | writel(val, port->base + PCIE_AXI_WINDOW0); |
| 719 | 724 | ||
| 720 | return 0; | 725 | return 0; |
diff --git a/drivers/pci/controller/pcie-rockchip-ep.c b/drivers/pci/controller/pcie-rockchip-ep.c index b8163c56a142..a5d799e2dff2 100644 --- a/drivers/pci/controller/pcie-rockchip-ep.c +++ b/drivers/pci/controller/pcie-rockchip-ep.c | |||
| @@ -499,12 +499,21 @@ static int rockchip_pcie_ep_start(struct pci_epc *epc) | |||
| 499 | 499 | ||
| 500 | rockchip_pcie_write(rockchip, cfg, PCIE_CORE_PHY_FUNC_CFG); | 500 | rockchip_pcie_write(rockchip, cfg, PCIE_CORE_PHY_FUNC_CFG); |
| 501 | 501 | ||
| 502 | list_for_each_entry(epf, &epc->pci_epf, list) | ||
| 503 | pci_epf_linkup(epf); | ||
| 504 | |||
| 505 | return 0; | 502 | return 0; |
| 506 | } | 503 | } |
| 507 | 504 | ||
| 505 | static const struct pci_epc_features rockchip_pcie_epc_features = { | ||
| 506 | .linkup_notifier = false, | ||
| 507 | .msi_capable = true, | ||
| 508 | .msix_capable = false, | ||
| 509 | }; | ||
| 510 | |||
| 511 | static const struct pci_epc_features* | ||
| 512 | rockchip_pcie_ep_get_features(struct pci_epc *epc, u8 func_no) | ||
| 513 | { | ||
| 514 | return &rockchip_pcie_epc_features; | ||
| 515 | } | ||
| 516 | |||
| 508 | static const struct pci_epc_ops rockchip_pcie_epc_ops = { | 517 | static const struct pci_epc_ops rockchip_pcie_epc_ops = { |
| 509 | .write_header = rockchip_pcie_ep_write_header, | 518 | .write_header = rockchip_pcie_ep_write_header, |
| 510 | .set_bar = rockchip_pcie_ep_set_bar, | 519 | .set_bar = rockchip_pcie_ep_set_bar, |
| @@ -515,6 +524,7 @@ static const struct pci_epc_ops rockchip_pcie_epc_ops = { | |||
| 515 | .get_msi = rockchip_pcie_ep_get_msi, | 524 | .get_msi = rockchip_pcie_ep_get_msi, |
| 516 | .raise_irq = rockchip_pcie_ep_raise_irq, | 525 | .raise_irq = rockchip_pcie_ep_raise_irq, |
| 517 | .start = rockchip_pcie_ep_start, | 526 | .start = rockchip_pcie_ep_start, |
| 527 | .get_features = rockchip_pcie_ep_get_features, | ||
| 518 | }; | 528 | }; |
| 519 | 529 | ||
| 520 | static int rockchip_pcie_parse_ep_dt(struct rockchip_pcie *rockchip, | 530 | static int rockchip_pcie_parse_ep_dt(struct rockchip_pcie *rockchip, |
diff --git a/drivers/pci/controller/vmd.c b/drivers/pci/controller/vmd.c index 3890812cdf87..cf6816b55b5e 100644 --- a/drivers/pci/controller/vmd.c +++ b/drivers/pci/controller/vmd.c | |||
| @@ -571,6 +571,7 @@ static int vmd_enable_domain(struct vmd_dev *vmd, unsigned long features) | |||
| 571 | LIST_HEAD(resources); | 571 | LIST_HEAD(resources); |
| 572 | resource_size_t offset[2] = {0}; | 572 | resource_size_t offset[2] = {0}; |
| 573 | resource_size_t membar2_offset = 0x2000, busn_start = 0; | 573 | resource_size_t membar2_offset = 0x2000, busn_start = 0; |
| 574 | struct pci_bus *child; | ||
| 574 | 575 | ||
| 575 | /* | 576 | /* |
| 576 | * Shadow registers may exist in certain VMD device ids which allow | 577 | * Shadow registers may exist in certain VMD device ids which allow |
| @@ -698,7 +699,19 @@ static int vmd_enable_domain(struct vmd_dev *vmd, unsigned long features) | |||
| 698 | vmd_attach_resources(vmd); | 699 | vmd_attach_resources(vmd); |
| 699 | vmd_setup_dma_ops(vmd); | 700 | vmd_setup_dma_ops(vmd); |
| 700 | dev_set_msi_domain(&vmd->bus->dev, vmd->irq_domain); | 701 | dev_set_msi_domain(&vmd->bus->dev, vmd->irq_domain); |
| 701 | pci_rescan_bus(vmd->bus); | 702 | |
| 703 | pci_scan_child_bus(vmd->bus); | ||
| 704 | pci_assign_unassigned_bus_resources(vmd->bus); | ||
| 705 | |||
| 706 | /* | ||
| 707 | * VMD root buses are virtual and don't return true on pci_is_pcie() | ||
| 708 | * and will fail pcie_bus_configure_settings() early. It can instead be | ||
| 709 | * run on each of the real root ports. | ||
| 710 | */ | ||
| 711 | list_for_each_entry(child, &vmd->bus->children, node) | ||
| 712 | pcie_bus_configure_settings(child); | ||
| 713 | |||
| 714 | pci_bus_add_devices(vmd->bus); | ||
| 702 | 715 | ||
| 703 | WARN(sysfs_create_link(&vmd->dev->dev.kobj, &vmd->bus->dev.kobj, | 716 | WARN(sysfs_create_link(&vmd->dev->dev.kobj, &vmd->bus->dev.kobj, |
| 704 | "domain"), "Can't create symlink to domain\n"); | 717 | "domain"), "Can't create symlink to domain\n"); |
diff --git a/drivers/pci/endpoint/functions/pci-epf-test.c b/drivers/pci/endpoint/functions/pci-epf-test.c index 3e86fa3c7da3..d0b91da49bf4 100644 --- a/drivers/pci/endpoint/functions/pci-epf-test.c +++ b/drivers/pci/endpoint/functions/pci-epf-test.c | |||
| @@ -47,9 +47,8 @@ struct pci_epf_test { | |||
| 47 | void *reg[6]; | 47 | void *reg[6]; |
| 48 | struct pci_epf *epf; | 48 | struct pci_epf *epf; |
| 49 | enum pci_barno test_reg_bar; | 49 | enum pci_barno test_reg_bar; |
| 50 | bool linkup_notifier; | ||
| 51 | bool msix_available; | ||
| 52 | struct delayed_work cmd_handler; | 50 | struct delayed_work cmd_handler; |
| 51 | const struct pci_epc_features *epc_features; | ||
| 53 | }; | 52 | }; |
| 54 | 53 | ||
| 55 | struct pci_epf_test_reg { | 54 | struct pci_epf_test_reg { |
| @@ -71,11 +70,6 @@ static struct pci_epf_header test_header = { | |||
| 71 | .interrupt_pin = PCI_INTERRUPT_INTA, | 70 | .interrupt_pin = PCI_INTERRUPT_INTA, |
| 72 | }; | 71 | }; |
| 73 | 72 | ||
| 74 | struct pci_epf_test_data { | ||
| 75 | enum pci_barno test_reg_bar; | ||
| 76 | bool linkup_notifier; | ||
| 77 | }; | ||
| 78 | |||
| 79 | static size_t bar_size[] = { 512, 512, 1024, 16384, 131072, 1048576 }; | 73 | static size_t bar_size[] = { 512, 512, 1024, 16384, 131072, 1048576 }; |
| 80 | 74 | ||
| 81 | static int pci_epf_test_copy(struct pci_epf_test *epf_test) | 75 | static int pci_epf_test_copy(struct pci_epf_test *epf_test) |
| @@ -175,7 +169,7 @@ static int pci_epf_test_read(struct pci_epf_test *epf_test) | |||
| 175 | goto err_map_addr; | 169 | goto err_map_addr; |
| 176 | } | 170 | } |
| 177 | 171 | ||
| 178 | memcpy(buf, src_addr, reg->size); | 172 | memcpy_fromio(buf, src_addr, reg->size); |
| 179 | 173 | ||
| 180 | crc32 = crc32_le(~0, buf, reg->size); | 174 | crc32 = crc32_le(~0, buf, reg->size); |
| 181 | if (crc32 != reg->checksum) | 175 | if (crc32 != reg->checksum) |
| @@ -230,7 +224,7 @@ static int pci_epf_test_write(struct pci_epf_test *epf_test) | |||
| 230 | get_random_bytes(buf, reg->size); | 224 | get_random_bytes(buf, reg->size); |
| 231 | reg->checksum = crc32_le(~0, buf, reg->size); | 225 | reg->checksum = crc32_le(~0, buf, reg->size); |
| 232 | 226 | ||
| 233 | memcpy(dst_addr, buf, reg->size); | 227 | memcpy_toio(dst_addr, buf, reg->size); |
| 234 | 228 | ||
| 235 | /* | 229 | /* |
| 236 | * wait 1ms inorder for the write to complete. Without this delay L3 | 230 | * wait 1ms inorder for the write to complete. Without this delay L3 |
| @@ -402,13 +396,15 @@ static int pci_epf_test_set_bar(struct pci_epf *epf) | |||
| 402 | struct device *dev = &epf->dev; | 396 | struct device *dev = &epf->dev; |
| 403 | struct pci_epf_test *epf_test = epf_get_drvdata(epf); | 397 | struct pci_epf_test *epf_test = epf_get_drvdata(epf); |
| 404 | enum pci_barno test_reg_bar = epf_test->test_reg_bar; | 398 | enum pci_barno test_reg_bar = epf_test->test_reg_bar; |
| 399 | const struct pci_epc_features *epc_features; | ||
| 400 | |||
| 401 | epc_features = epf_test->epc_features; | ||
| 405 | 402 | ||
| 406 | for (bar = BAR_0; bar <= BAR_5; bar++) { | 403 | for (bar = BAR_0; bar <= BAR_5; bar++) { |
| 407 | epf_bar = &epf->bar[bar]; | 404 | epf_bar = &epf->bar[bar]; |
| 408 | 405 | ||
| 409 | epf_bar->flags |= upper_32_bits(epf_bar->size) ? | 406 | if (!!(epc_features->reserved_bar & (1 << bar))) |
| 410 | PCI_BASE_ADDRESS_MEM_TYPE_64 : | 407 | continue; |
| 411 | PCI_BASE_ADDRESS_MEM_TYPE_32; | ||
| 412 | 408 | ||
| 413 | ret = pci_epc_set_bar(epc, epf->func_no, epf_bar); | 409 | ret = pci_epc_set_bar(epc, epf->func_no, epf_bar); |
| 414 | if (ret) { | 410 | if (ret) { |
| @@ -433,9 +429,13 @@ static int pci_epf_test_alloc_space(struct pci_epf *epf) | |||
| 433 | { | 429 | { |
| 434 | struct pci_epf_test *epf_test = epf_get_drvdata(epf); | 430 | struct pci_epf_test *epf_test = epf_get_drvdata(epf); |
| 435 | struct device *dev = &epf->dev; | 431 | struct device *dev = &epf->dev; |
| 432 | struct pci_epf_bar *epf_bar; | ||
| 436 | void *base; | 433 | void *base; |
| 437 | int bar; | 434 | int bar; |
| 438 | enum pci_barno test_reg_bar = epf_test->test_reg_bar; | 435 | enum pci_barno test_reg_bar = epf_test->test_reg_bar; |
| 436 | const struct pci_epc_features *epc_features; | ||
| 437 | |||
| 438 | epc_features = epf_test->epc_features; | ||
| 439 | 439 | ||
| 440 | base = pci_epf_alloc_space(epf, sizeof(struct pci_epf_test_reg), | 440 | base = pci_epf_alloc_space(epf, sizeof(struct pci_epf_test_reg), |
| 441 | test_reg_bar); | 441 | test_reg_bar); |
| @@ -446,37 +446,69 @@ static int pci_epf_test_alloc_space(struct pci_epf *epf) | |||
| 446 | epf_test->reg[test_reg_bar] = base; | 446 | epf_test->reg[test_reg_bar] = base; |
| 447 | 447 | ||
| 448 | for (bar = BAR_0; bar <= BAR_5; bar++) { | 448 | for (bar = BAR_0; bar <= BAR_5; bar++) { |
| 449 | epf_bar = &epf->bar[bar]; | ||
| 449 | if (bar == test_reg_bar) | 450 | if (bar == test_reg_bar) |
| 450 | continue; | 451 | continue; |
| 452 | |||
| 453 | if (!!(epc_features->reserved_bar & (1 << bar))) | ||
| 454 | continue; | ||
| 455 | |||
| 451 | base = pci_epf_alloc_space(epf, bar_size[bar], bar); | 456 | base = pci_epf_alloc_space(epf, bar_size[bar], bar); |
| 452 | if (!base) | 457 | if (!base) |
| 453 | dev_err(dev, "Failed to allocate space for BAR%d\n", | 458 | dev_err(dev, "Failed to allocate space for BAR%d\n", |
| 454 | bar); | 459 | bar); |
| 455 | epf_test->reg[bar] = base; | 460 | epf_test->reg[bar] = base; |
| 461 | if (epf_bar->flags & PCI_BASE_ADDRESS_MEM_TYPE_64) | ||
| 462 | bar++; | ||
| 456 | } | 463 | } |
| 457 | 464 | ||
| 458 | return 0; | 465 | return 0; |
| 459 | } | 466 | } |
| 460 | 467 | ||
| 468 | static void pci_epf_configure_bar(struct pci_epf *epf, | ||
| 469 | const struct pci_epc_features *epc_features) | ||
| 470 | { | ||
| 471 | struct pci_epf_bar *epf_bar; | ||
| 472 | bool bar_fixed_64bit; | ||
| 473 | int i; | ||
| 474 | |||
| 475 | for (i = BAR_0; i <= BAR_5; i++) { | ||
| 476 | epf_bar = &epf->bar[i]; | ||
| 477 | bar_fixed_64bit = !!(epc_features->bar_fixed_64bit & (1 << i)); | ||
| 478 | if (bar_fixed_64bit) | ||
| 479 | epf_bar->flags |= PCI_BASE_ADDRESS_MEM_TYPE_64; | ||
| 480 | if (epc_features->bar_fixed_size[i]) | ||
| 481 | bar_size[i] = epc_features->bar_fixed_size[i]; | ||
| 482 | } | ||
| 483 | } | ||
| 484 | |||
| 461 | static int pci_epf_test_bind(struct pci_epf *epf) | 485 | static int pci_epf_test_bind(struct pci_epf *epf) |
| 462 | { | 486 | { |
| 463 | int ret; | 487 | int ret; |
| 464 | struct pci_epf_test *epf_test = epf_get_drvdata(epf); | 488 | struct pci_epf_test *epf_test = epf_get_drvdata(epf); |
| 465 | struct pci_epf_header *header = epf->header; | 489 | struct pci_epf_header *header = epf->header; |
| 490 | const struct pci_epc_features *epc_features; | ||
| 491 | enum pci_barno test_reg_bar = BAR_0; | ||
| 466 | struct pci_epc *epc = epf->epc; | 492 | struct pci_epc *epc = epf->epc; |
| 467 | struct device *dev = &epf->dev; | 493 | struct device *dev = &epf->dev; |
| 494 | bool linkup_notifier = false; | ||
| 495 | bool msix_capable = false; | ||
| 496 | bool msi_capable = true; | ||
| 468 | 497 | ||
| 469 | if (WARN_ON_ONCE(!epc)) | 498 | if (WARN_ON_ONCE(!epc)) |
| 470 | return -EINVAL; | 499 | return -EINVAL; |
| 471 | 500 | ||
| 472 | if (epc->features & EPC_FEATURE_NO_LINKUP_NOTIFIER) | 501 | epc_features = pci_epc_get_features(epc, epf->func_no); |
| 473 | epf_test->linkup_notifier = false; | 502 | if (epc_features) { |
| 474 | else | 503 | linkup_notifier = epc_features->linkup_notifier; |
| 475 | epf_test->linkup_notifier = true; | 504 | msix_capable = epc_features->msix_capable; |
| 476 | 505 | msi_capable = epc_features->msi_capable; | |
| 477 | epf_test->msix_available = epc->features & EPC_FEATURE_MSIX_AVAILABLE; | 506 | test_reg_bar = pci_epc_get_first_free_bar(epc_features); |
| 507 | pci_epf_configure_bar(epf, epc_features); | ||
| 508 | } | ||
| 478 | 509 | ||
| 479 | epf_test->test_reg_bar = EPC_FEATURE_GET_BAR(epc->features); | 510 | epf_test->test_reg_bar = test_reg_bar; |
| 511 | epf_test->epc_features = epc_features; | ||
| 480 | 512 | ||
| 481 | ret = pci_epc_write_header(epc, epf->func_no, header); | 513 | ret = pci_epc_write_header(epc, epf->func_no, header); |
| 482 | if (ret) { | 514 | if (ret) { |
| @@ -492,13 +524,15 @@ static int pci_epf_test_bind(struct pci_epf *epf) | |||
| 492 | if (ret) | 524 | if (ret) |
| 493 | return ret; | 525 | return ret; |
| 494 | 526 | ||
| 495 | ret = pci_epc_set_msi(epc, epf->func_no, epf->msi_interrupts); | 527 | if (msi_capable) { |
| 496 | if (ret) { | 528 | ret = pci_epc_set_msi(epc, epf->func_no, epf->msi_interrupts); |
| 497 | dev_err(dev, "MSI configuration failed\n"); | 529 | if (ret) { |
| 498 | return ret; | 530 | dev_err(dev, "MSI configuration failed\n"); |
| 531 | return ret; | ||
| 532 | } | ||
| 499 | } | 533 | } |
| 500 | 534 | ||
| 501 | if (epf_test->msix_available) { | 535 | if (msix_capable) { |
| 502 | ret = pci_epc_set_msix(epc, epf->func_no, epf->msix_interrupts); | 536 | ret = pci_epc_set_msix(epc, epf->func_no, epf->msix_interrupts); |
| 503 | if (ret) { | 537 | if (ret) { |
| 504 | dev_err(dev, "MSI-X configuration failed\n"); | 538 | dev_err(dev, "MSI-X configuration failed\n"); |
| @@ -506,7 +540,7 @@ static int pci_epf_test_bind(struct pci_epf *epf) | |||
| 506 | } | 540 | } |
| 507 | } | 541 | } |
| 508 | 542 | ||
| 509 | if (!epf_test->linkup_notifier) | 543 | if (!linkup_notifier) |
| 510 | queue_work(kpcitest_workqueue, &epf_test->cmd_handler.work); | 544 | queue_work(kpcitest_workqueue, &epf_test->cmd_handler.work); |
| 511 | 545 | ||
| 512 | return 0; | 546 | return 0; |
| @@ -523,17 +557,6 @@ static int pci_epf_test_probe(struct pci_epf *epf) | |||
| 523 | { | 557 | { |
| 524 | struct pci_epf_test *epf_test; | 558 | struct pci_epf_test *epf_test; |
| 525 | struct device *dev = &epf->dev; | 559 | struct device *dev = &epf->dev; |
| 526 | const struct pci_epf_device_id *match; | ||
| 527 | struct pci_epf_test_data *data; | ||
| 528 | enum pci_barno test_reg_bar = BAR_0; | ||
| 529 | bool linkup_notifier = true; | ||
| 530 | |||
| 531 | match = pci_epf_match_device(pci_epf_test_ids, epf); | ||
| 532 | data = (struct pci_epf_test_data *)match->driver_data; | ||
| 533 | if (data) { | ||
| 534 | test_reg_bar = data->test_reg_bar; | ||
| 535 | linkup_notifier = data->linkup_notifier; | ||
| 536 | } | ||
| 537 | 560 | ||
| 538 | epf_test = devm_kzalloc(dev, sizeof(*epf_test), GFP_KERNEL); | 561 | epf_test = devm_kzalloc(dev, sizeof(*epf_test), GFP_KERNEL); |
| 539 | if (!epf_test) | 562 | if (!epf_test) |
| @@ -541,8 +564,6 @@ static int pci_epf_test_probe(struct pci_epf *epf) | |||
| 541 | 564 | ||
| 542 | epf->header = &test_header; | 565 | epf->header = &test_header; |
| 543 | epf_test->epf = epf; | 566 | epf_test->epf = epf; |
| 544 | epf_test->test_reg_bar = test_reg_bar; | ||
| 545 | epf_test->linkup_notifier = linkup_notifier; | ||
| 546 | 567 | ||
| 547 | INIT_DELAYED_WORK(&epf_test->cmd_handler, pci_epf_test_cmd_handler); | 568 | INIT_DELAYED_WORK(&epf_test->cmd_handler, pci_epf_test_cmd_handler); |
| 548 | 569 | ||
diff --git a/drivers/pci/endpoint/pci-epc-core.c b/drivers/pci/endpoint/pci-epc-core.c index 094dcc3203b8..e4712a0f249c 100644 --- a/drivers/pci/endpoint/pci-epc-core.c +++ b/drivers/pci/endpoint/pci-epc-core.c | |||
| @@ -84,6 +84,59 @@ err: | |||
| 84 | EXPORT_SYMBOL_GPL(pci_epc_get); | 84 | EXPORT_SYMBOL_GPL(pci_epc_get); |
| 85 | 85 | ||
| 86 | /** | 86 | /** |
| 87 | * pci_epc_get_first_free_bar() - helper to get first unreserved BAR | ||
| 88 | * @epc_features: pci_epc_features structure that holds the reserved bar bitmap | ||
| 89 | * | ||
| 90 | * Invoke to get the first unreserved BAR that can be used for endpoint | ||
| 91 | * function. For any incorrect value in reserved_bar return '0'. | ||
| 92 | */ | ||
| 93 | unsigned int pci_epc_get_first_free_bar(const struct pci_epc_features | ||
| 94 | *epc_features) | ||
| 95 | { | ||
| 96 | int free_bar; | ||
| 97 | |||
| 98 | if (!epc_features) | ||
| 99 | return 0; | ||
| 100 | |||
| 101 | free_bar = ffz(epc_features->reserved_bar); | ||
| 102 | if (free_bar > 5) | ||
| 103 | return 0; | ||
| 104 | |||
| 105 | return free_bar; | ||
| 106 | } | ||
| 107 | EXPORT_SYMBOL_GPL(pci_epc_get_first_free_bar); | ||
| 108 | |||
| 109 | /** | ||
| 110 | * pci_epc_get_features() - get the features supported by EPC | ||
| 111 | * @epc: the features supported by *this* EPC device will be returned | ||
| 112 | * @func_no: the features supported by the EPC device specific to the | ||
| 113 | * endpoint function with func_no will be returned | ||
| 114 | * | ||
| 115 | * Invoke to get the features provided by the EPC which may be | ||
| 116 | * specific to an endpoint function. Returns pci_epc_features on success | ||
| 117 | * and NULL for any failures. | ||
| 118 | */ | ||
| 119 | const struct pci_epc_features *pci_epc_get_features(struct pci_epc *epc, | ||
| 120 | u8 func_no) | ||
| 121 | { | ||
| 122 | const struct pci_epc_features *epc_features; | ||
| 123 | unsigned long flags; | ||
| 124 | |||
| 125 | if (IS_ERR_OR_NULL(epc) || func_no >= epc->max_functions) | ||
| 126 | return NULL; | ||
| 127 | |||
| 128 | if (!epc->ops->get_features) | ||
| 129 | return NULL; | ||
| 130 | |||
| 131 | spin_lock_irqsave(&epc->lock, flags); | ||
| 132 | epc_features = epc->ops->get_features(epc, func_no); | ||
| 133 | spin_unlock_irqrestore(&epc->lock, flags); | ||
| 134 | |||
| 135 | return epc_features; | ||
| 136 | } | ||
| 137 | EXPORT_SYMBOL_GPL(pci_epc_get_features); | ||
| 138 | |||
| 139 | /** | ||
| 87 | * pci_epc_stop() - stop the PCI link | 140 | * pci_epc_stop() - stop the PCI link |
| 88 | * @epc: the link of the EPC device that has to be stopped | 141 | * @epc: the link of the EPC device that has to be stopped |
| 89 | * | 142 | * |
diff --git a/drivers/pci/endpoint/pci-epf-core.c b/drivers/pci/endpoint/pci-epf-core.c index 825fa24427a3..8bfdcd291196 100644 --- a/drivers/pci/endpoint/pci-epf-core.c +++ b/drivers/pci/endpoint/pci-epf-core.c | |||
| @@ -131,7 +131,9 @@ void *pci_epf_alloc_space(struct pci_epf *epf, size_t size, enum pci_barno bar) | |||
| 131 | epf->bar[bar].phys_addr = phys_addr; | 131 | epf->bar[bar].phys_addr = phys_addr; |
| 132 | epf->bar[bar].size = size; | 132 | epf->bar[bar].size = size; |
| 133 | epf->bar[bar].barno = bar; | 133 | epf->bar[bar].barno = bar; |
| 134 | epf->bar[bar].flags = PCI_BASE_ADDRESS_SPACE_MEMORY; | 134 | epf->bar[bar].flags |= upper_32_bits(size) ? |
| 135 | PCI_BASE_ADDRESS_MEM_TYPE_64 : | ||
| 136 | PCI_BASE_ADDRESS_MEM_TYPE_32; | ||
| 135 | 137 | ||
| 136 | return space; | 138 | return space; |
| 137 | } | 139 | } |
diff --git a/drivers/pci/hotplug/ibmphp.h b/drivers/pci/hotplug/ibmphp.h index b89f850c3a4e..e90a4ebf6550 100644 --- a/drivers/pci/hotplug/ibmphp.h +++ b/drivers/pci/hotplug/ibmphp.h | |||
| @@ -378,7 +378,6 @@ int ibmphp_add_pfmem_from_mem(struct resource_node *); | |||
| 378 | struct bus_node *ibmphp_find_res_bus(u8); | 378 | struct bus_node *ibmphp_find_res_bus(u8); |
| 379 | void ibmphp_print_test(void); /* for debugging purposes */ | 379 | void ibmphp_print_test(void); /* for debugging purposes */ |
| 380 | 380 | ||
| 381 | void ibmphp_hpc_initvars(void); | ||
| 382 | int ibmphp_hpc_readslot(struct slot *, u8, u8 *); | 381 | int ibmphp_hpc_readslot(struct slot *, u8, u8 *); |
| 383 | int ibmphp_hpc_writeslot(struct slot *, u8); | 382 | int ibmphp_hpc_writeslot(struct slot *, u8); |
| 384 | void ibmphp_lock_operations(void); | 383 | void ibmphp_lock_operations(void); |
diff --git a/drivers/pci/hotplug/ibmphp_core.c b/drivers/pci/hotplug/ibmphp_core.c index 08a58e911fc2..17124254d897 100644 --- a/drivers/pci/hotplug/ibmphp_core.c +++ b/drivers/pci/hotplug/ibmphp_core.c | |||
| @@ -1277,8 +1277,6 @@ static int __init ibmphp_init(void) | |||
| 1277 | 1277 | ||
| 1278 | ibmphp_debug = debug; | 1278 | ibmphp_debug = debug; |
| 1279 | 1279 | ||
| 1280 | ibmphp_hpc_initvars(); | ||
| 1281 | |||
| 1282 | for (i = 0; i < 16; i++) | 1280 | for (i = 0; i < 16; i++) |
| 1283 | irqs[i] = 0; | 1281 | irqs[i] = 0; |
| 1284 | 1282 | ||
diff --git a/drivers/pci/hotplug/ibmphp_hpc.c b/drivers/pci/hotplug/ibmphp_hpc.c index 752c384cbd4c..508a62a6b5f9 100644 --- a/drivers/pci/hotplug/ibmphp_hpc.c +++ b/drivers/pci/hotplug/ibmphp_hpc.c | |||
| @@ -15,13 +15,13 @@ | |||
| 15 | 15 | ||
| 16 | #include <linux/wait.h> | 16 | #include <linux/wait.h> |
| 17 | #include <linux/time.h> | 17 | #include <linux/time.h> |
| 18 | #include <linux/completion.h> | ||
| 18 | #include <linux/delay.h> | 19 | #include <linux/delay.h> |
| 19 | #include <linux/module.h> | 20 | #include <linux/module.h> |
| 20 | #include <linux/pci.h> | 21 | #include <linux/pci.h> |
| 21 | #include <linux/init.h> | 22 | #include <linux/init.h> |
| 22 | #include <linux/mutex.h> | 23 | #include <linux/mutex.h> |
| 23 | #include <linux/sched.h> | 24 | #include <linux/sched.h> |
| 24 | #include <linux/semaphore.h> | ||
| 25 | #include <linux/kthread.h> | 25 | #include <linux/kthread.h> |
| 26 | #include "ibmphp.h" | 26 | #include "ibmphp.h" |
| 27 | 27 | ||
| @@ -88,10 +88,10 @@ static int to_debug = 0; | |||
| 88 | //---------------------------------------------------------------------------- | 88 | //---------------------------------------------------------------------------- |
| 89 | // global variables | 89 | // global variables |
| 90 | //---------------------------------------------------------------------------- | 90 | //---------------------------------------------------------------------------- |
| 91 | static struct mutex sem_hpcaccess; // lock access to HPC | 91 | static DEFINE_MUTEX(sem_hpcaccess); // lock access to HPC |
| 92 | static struct semaphore semOperations; // lock all operations and | 92 | static DEFINE_MUTEX(operations_mutex); // lock all operations and |
| 93 | // access to data structures | 93 | // access to data structures |
| 94 | static struct semaphore sem_exit; // make sure polling thread goes away | 94 | static DECLARE_COMPLETION(exit_complete); // make sure polling thread goes away |
| 95 | static struct task_struct *ibmphp_poll_thread; | 95 | static struct task_struct *ibmphp_poll_thread; |
| 96 | //---------------------------------------------------------------------------- | 96 | //---------------------------------------------------------------------------- |
| 97 | // local function prototypes | 97 | // local function prototypes |
| @@ -110,23 +110,6 @@ static int hpc_wait_ctlr_notworking(int, struct controller *, void __iomem *, u8 | |||
| 110 | 110 | ||
| 111 | 111 | ||
| 112 | /*---------------------------------------------------------------------- | 112 | /*---------------------------------------------------------------------- |
| 113 | * Name: ibmphp_hpc_initvars | ||
| 114 | * | ||
| 115 | * Action: initialize semaphores and variables | ||
| 116 | *---------------------------------------------------------------------*/ | ||
| 117 | void __init ibmphp_hpc_initvars(void) | ||
| 118 | { | ||
| 119 | debug("%s - Entry\n", __func__); | ||
| 120 | |||
| 121 | mutex_init(&sem_hpcaccess); | ||
| 122 | sema_init(&semOperations, 1); | ||
| 123 | sema_init(&sem_exit, 0); | ||
| 124 | to_debug = 0; | ||
| 125 | |||
| 126 | debug("%s - Exit\n", __func__); | ||
| 127 | } | ||
| 128 | |||
| 129 | /*---------------------------------------------------------------------- | ||
| 130 | * Name: i2c_ctrl_read | 113 | * Name: i2c_ctrl_read |
| 131 | * | 114 | * |
| 132 | * Action: read from HPC over I2C | 115 | * Action: read from HPC over I2C |
| @@ -780,7 +763,7 @@ void free_hpc_access(void) | |||
| 780 | *---------------------------------------------------------------------*/ | 763 | *---------------------------------------------------------------------*/ |
| 781 | void ibmphp_lock_operations(void) | 764 | void ibmphp_lock_operations(void) |
| 782 | { | 765 | { |
| 783 | down(&semOperations); | 766 | mutex_lock(&operations_mutex); |
| 784 | to_debug = 1; | 767 | to_debug = 1; |
| 785 | } | 768 | } |
| 786 | 769 | ||
| @@ -790,7 +773,7 @@ void ibmphp_lock_operations(void) | |||
| 790 | void ibmphp_unlock_operations(void) | 773 | void ibmphp_unlock_operations(void) |
| 791 | { | 774 | { |
| 792 | debug("%s - Entry\n", __func__); | 775 | debug("%s - Entry\n", __func__); |
| 793 | up(&semOperations); | 776 | mutex_unlock(&operations_mutex); |
| 794 | to_debug = 0; | 777 | to_debug = 0; |
| 795 | debug("%s - Exit\n", __func__); | 778 | debug("%s - Exit\n", __func__); |
| 796 | } | 779 | } |
| @@ -816,7 +799,7 @@ static int poll_hpc(void *data) | |||
| 816 | 799 | ||
| 817 | while (!kthread_should_stop()) { | 800 | while (!kthread_should_stop()) { |
| 818 | /* try to get the lock to do some kind of hardware access */ | 801 | /* try to get the lock to do some kind of hardware access */ |
| 819 | down(&semOperations); | 802 | mutex_lock(&operations_mutex); |
| 820 | 803 | ||
| 821 | switch (poll_state) { | 804 | switch (poll_state) { |
| 822 | case POLL_LATCH_REGISTER: | 805 | case POLL_LATCH_REGISTER: |
| @@ -871,13 +854,13 @@ static int poll_hpc(void *data) | |||
| 871 | break; | 854 | break; |
| 872 | case POLL_SLEEP: | 855 | case POLL_SLEEP: |
| 873 | /* don't sleep with a lock on the hardware */ | 856 | /* don't sleep with a lock on the hardware */ |
| 874 | up(&semOperations); | 857 | mutex_unlock(&operations_mutex); |
| 875 | msleep(POLL_INTERVAL_SEC * 1000); | 858 | msleep(POLL_INTERVAL_SEC * 1000); |
| 876 | 859 | ||
| 877 | if (kthread_should_stop()) | 860 | if (kthread_should_stop()) |
| 878 | goto out_sleep; | 861 | goto out_sleep; |
| 879 | 862 | ||
| 880 | down(&semOperations); | 863 | mutex_lock(&operations_mutex); |
| 881 | 864 | ||
| 882 | if (poll_count >= POLL_LATCH_CNT) { | 865 | if (poll_count >= POLL_LATCH_CNT) { |
| 883 | poll_count = 0; | 866 | poll_count = 0; |
| @@ -887,12 +870,12 @@ static int poll_hpc(void *data) | |||
| 887 | break; | 870 | break; |
| 888 | } | 871 | } |
| 889 | /* give up the hardware semaphore */ | 872 | /* give up the hardware semaphore */ |
| 890 | up(&semOperations); | 873 | mutex_unlock(&operations_mutex); |
| 891 | /* sleep for a short time just for good measure */ | 874 | /* sleep for a short time just for good measure */ |
| 892 | out_sleep: | 875 | out_sleep: |
| 893 | msleep(100); | 876 | msleep(100); |
| 894 | } | 877 | } |
| 895 | up(&sem_exit); | 878 | complete(&exit_complete); |
| 896 | debug("%s - Exit\n", __func__); | 879 | debug("%s - Exit\n", __func__); |
| 897 | return 0; | 880 | return 0; |
| 898 | } | 881 | } |
| @@ -1060,9 +1043,9 @@ void __exit ibmphp_hpc_stop_poll_thread(void) | |||
| 1060 | debug("after locking operations\n"); | 1043 | debug("after locking operations\n"); |
| 1061 | 1044 | ||
| 1062 | // wait for poll thread to exit | 1045 | // wait for poll thread to exit |
| 1063 | debug("before sem_exit down\n"); | 1046 | debug("before exit_complete down\n"); |
| 1064 | down(&sem_exit); | 1047 | wait_for_completion(&exit_complete); |
| 1065 | debug("after sem_exit down\n"); | 1048 | debug("after exit_completion down\n"); |
| 1066 | 1049 | ||
| 1067 | // cleanup | 1050 | // cleanup |
| 1068 | debug("before free_hpc_access\n"); | 1051 | debug("before free_hpc_access\n"); |
| @@ -1070,8 +1053,6 @@ void __exit ibmphp_hpc_stop_poll_thread(void) | |||
| 1070 | debug("after free_hpc_access\n"); | 1053 | debug("after free_hpc_access\n"); |
| 1071 | ibmphp_unlock_operations(); | 1054 | ibmphp_unlock_operations(); |
| 1072 | debug("after unlock operations\n"); | 1055 | debug("after unlock operations\n"); |
| 1073 | up(&sem_exit); | ||
| 1074 | debug("after sem exit up\n"); | ||
| 1075 | 1056 | ||
| 1076 | debug("%s - Exit\n", __func__); | 1057 | debug("%s - Exit\n", __func__); |
| 1077 | } | 1058 | } |
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index 7dd443aea5a5..6a2365cd794e 100644 --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c | |||
| @@ -156,9 +156,9 @@ static void pcie_do_write_cmd(struct controller *ctrl, u16 cmd, | |||
| 156 | slot_ctrl |= (cmd & mask); | 156 | slot_ctrl |= (cmd & mask); |
| 157 | ctrl->cmd_busy = 1; | 157 | ctrl->cmd_busy = 1; |
| 158 | smp_mb(); | 158 | smp_mb(); |
| 159 | ctrl->slot_ctrl = slot_ctrl; | ||
| 159 | pcie_capability_write_word(pdev, PCI_EXP_SLTCTL, slot_ctrl); | 160 | pcie_capability_write_word(pdev, PCI_EXP_SLTCTL, slot_ctrl); |
| 160 | ctrl->cmd_started = jiffies; | 161 | ctrl->cmd_started = jiffies; |
| 161 | ctrl->slot_ctrl = slot_ctrl; | ||
| 162 | 162 | ||
| 163 | /* | 163 | /* |
| 164 | * Controllers with the Intel CF118 and similar errata advertise | 164 | * Controllers with the Intel CF118 and similar errata advertise |
| @@ -736,12 +736,25 @@ void pcie_clear_hotplug_events(struct controller *ctrl) | |||
| 736 | 736 | ||
| 737 | void pcie_enable_interrupt(struct controller *ctrl) | 737 | void pcie_enable_interrupt(struct controller *ctrl) |
| 738 | { | 738 | { |
| 739 | pcie_write_cmd(ctrl, PCI_EXP_SLTCTL_HPIE, PCI_EXP_SLTCTL_HPIE); | 739 | u16 mask; |
| 740 | |||
| 741 | mask = PCI_EXP_SLTCTL_HPIE | PCI_EXP_SLTCTL_DLLSCE; | ||
| 742 | pcie_write_cmd(ctrl, mask, mask); | ||
| 740 | } | 743 | } |
| 741 | 744 | ||
| 742 | void pcie_disable_interrupt(struct controller *ctrl) | 745 | void pcie_disable_interrupt(struct controller *ctrl) |
| 743 | { | 746 | { |
| 744 | pcie_write_cmd(ctrl, 0, PCI_EXP_SLTCTL_HPIE); | 747 | u16 mask; |
| 748 | |||
| 749 | /* | ||
| 750 | * Mask hot-plug interrupt to prevent it triggering immediately | ||
| 751 | * when the link goes inactive (we still get PME when any of the | ||
| 752 | * enabled events is detected). Same goes with Link Layer State | ||
| 753 | * changed event which generates PME immediately when the link goes | ||
| 754 | * inactive so mask it as well. | ||
| 755 | */ | ||
| 756 | mask = PCI_EXP_SLTCTL_HPIE | PCI_EXP_SLTCTL_DLLSCE; | ||
| 757 | pcie_write_cmd(ctrl, 0, mask); | ||
| 745 | } | 758 | } |
| 746 | 759 | ||
| 747 | /* | 760 | /* |
| @@ -920,3 +933,5 @@ DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_QCOM, 0x0400, | |||
| 920 | PCI_CLASS_BRIDGE_PCI, 8, quirk_cmd_compl); | 933 | PCI_CLASS_BRIDGE_PCI, 8, quirk_cmd_compl); |
| 921 | DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_QCOM, 0x0401, | 934 | DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_QCOM, 0x0401, |
| 922 | PCI_CLASS_BRIDGE_PCI, 8, quirk_cmd_compl); | 935 | PCI_CLASS_BRIDGE_PCI, 8, quirk_cmd_compl); |
| 936 | DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_HXT, 0x0401, | ||
| 937 | PCI_CLASS_BRIDGE_PCI, 8, quirk_cmd_compl); | ||
diff --git a/drivers/pci/of.c b/drivers/pci/of.c index 4c4217d0c3f1..3d32da15c215 100644 --- a/drivers/pci/of.c +++ b/drivers/pci/of.c | |||
| @@ -113,7 +113,7 @@ struct device_node *of_pci_find_child_device(struct device_node *parent, | |||
| 113 | * a fake root for all functions of a multi-function | 113 | * a fake root for all functions of a multi-function |
| 114 | * device we go down them as well. | 114 | * device we go down them as well. |
| 115 | */ | 115 | */ |
| 116 | if (!strcmp(node->name, "multifunc-device")) { | 116 | if (of_node_name_eq(node, "multifunc-device")) { |
| 117 | for_each_child_of_node(node, node2) { | 117 | for_each_child_of_node(node, node2) { |
| 118 | if (__of_pci_pci_compare(node2, devfn)) { | 118 | if (__of_pci_pci_compare(node2, devfn)) { |
| 119 | of_node_put(node); | 119 | of_node_put(node); |
diff --git a/drivers/pci/pci-bridge-emul.c b/drivers/pci/pci-bridge-emul.c index 129738362d90..83fb077d0b41 100644 --- a/drivers/pci/pci-bridge-emul.c +++ b/drivers/pci/pci-bridge-emul.c | |||
| @@ -24,29 +24,6 @@ | |||
| 24 | #define PCI_CAP_PCIE_START PCI_BRIDGE_CONF_END | 24 | #define PCI_CAP_PCIE_START PCI_BRIDGE_CONF_END |
| 25 | #define PCI_CAP_PCIE_END (PCI_CAP_PCIE_START + PCI_EXP_SLTSTA2 + 2) | 25 | #define PCI_CAP_PCIE_END (PCI_CAP_PCIE_START + PCI_EXP_SLTSTA2 + 2) |
| 26 | 26 | ||
| 27 | /* | ||
| 28 | * Initialize a pci_bridge_emul structure to represent a fake PCI | ||
| 29 | * bridge configuration space. The caller needs to have initialized | ||
| 30 | * the PCI configuration space with whatever values make sense | ||
| 31 | * (typically at least vendor, device, revision), the ->ops pointer, | ||
| 32 | * and optionally ->data and ->has_pcie. | ||
| 33 | */ | ||
| 34 | void pci_bridge_emul_init(struct pci_bridge_emul *bridge) | ||
| 35 | { | ||
| 36 | bridge->conf.class_revision |= PCI_CLASS_BRIDGE_PCI << 16; | ||
| 37 | bridge->conf.header_type = PCI_HEADER_TYPE_BRIDGE; | ||
| 38 | bridge->conf.cache_line_size = 0x10; | ||
| 39 | bridge->conf.status = PCI_STATUS_CAP_LIST; | ||
| 40 | |||
| 41 | if (bridge->has_pcie) { | ||
| 42 | bridge->conf.capabilities_pointer = PCI_CAP_PCIE_START; | ||
| 43 | bridge->pcie_conf.cap_id = PCI_CAP_ID_EXP; | ||
| 44 | /* Set PCIe v2, root port, slot support */ | ||
| 45 | bridge->pcie_conf.cap = PCI_EXP_TYPE_ROOT_PORT << 4 | 2 | | ||
| 46 | PCI_EXP_FLAGS_SLOT; | ||
| 47 | } | ||
| 48 | } | ||
| 49 | |||
| 50 | struct pci_bridge_reg_behavior { | 27 | struct pci_bridge_reg_behavior { |
| 51 | /* Read-only bits */ | 28 | /* Read-only bits */ |
| 52 | u32 ro; | 29 | u32 ro; |
| @@ -284,6 +261,61 @@ const static struct pci_bridge_reg_behavior pcie_cap_regs_behavior[] = { | |||
| 284 | }; | 261 | }; |
| 285 | 262 | ||
| 286 | /* | 263 | /* |
| 264 | * Initialize a pci_bridge_emul structure to represent a fake PCI | ||
| 265 | * bridge configuration space. The caller needs to have initialized | ||
| 266 | * the PCI configuration space with whatever values make sense | ||
| 267 | * (typically at least vendor, device, revision), the ->ops pointer, | ||
| 268 | * and optionally ->data and ->has_pcie. | ||
| 269 | */ | ||
| 270 | int pci_bridge_emul_init(struct pci_bridge_emul *bridge, | ||
| 271 | unsigned int flags) | ||
| 272 | { | ||
| 273 | bridge->conf.class_revision |= PCI_CLASS_BRIDGE_PCI << 16; | ||
| 274 | bridge->conf.header_type = PCI_HEADER_TYPE_BRIDGE; | ||
| 275 | bridge->conf.cache_line_size = 0x10; | ||
| 276 | bridge->conf.status = PCI_STATUS_CAP_LIST; | ||
| 277 | bridge->pci_regs_behavior = kmemdup(pci_regs_behavior, | ||
| 278 | sizeof(pci_regs_behavior), | ||
| 279 | GFP_KERNEL); | ||
| 280 | if (!bridge->pci_regs_behavior) | ||
| 281 | return -ENOMEM; | ||
| 282 | |||
| 283 | if (bridge->has_pcie) { | ||
| 284 | bridge->conf.capabilities_pointer = PCI_CAP_PCIE_START; | ||
| 285 | bridge->pcie_conf.cap_id = PCI_CAP_ID_EXP; | ||
| 286 | /* Set PCIe v2, root port, slot support */ | ||
| 287 | bridge->pcie_conf.cap = PCI_EXP_TYPE_ROOT_PORT << 4 | 2 | | ||
| 288 | PCI_EXP_FLAGS_SLOT; | ||
| 289 | bridge->pcie_cap_regs_behavior = | ||
| 290 | kmemdup(pcie_cap_regs_behavior, | ||
| 291 | sizeof(pcie_cap_regs_behavior), | ||
| 292 | GFP_KERNEL); | ||
| 293 | if (!bridge->pcie_cap_regs_behavior) { | ||
| 294 | kfree(bridge->pci_regs_behavior); | ||
| 295 | return -ENOMEM; | ||
| 296 | } | ||
| 297 | } | ||
| 298 | |||
| 299 | if (flags & PCI_BRIDGE_EMUL_NO_PREFETCHABLE_BAR) { | ||
| 300 | bridge->pci_regs_behavior[PCI_PREF_MEMORY_BASE / 4].ro = ~0; | ||
| 301 | bridge->pci_regs_behavior[PCI_PREF_MEMORY_BASE / 4].rw = 0; | ||
| 302 | } | ||
| 303 | |||
| 304 | return 0; | ||
| 305 | } | ||
| 306 | |||
| 307 | /* | ||
| 308 | * Cleanup a pci_bridge_emul structure that was previously initilized | ||
| 309 | * using pci_bridge_emul_init(). | ||
| 310 | */ | ||
| 311 | void pci_bridge_emul_cleanup(struct pci_bridge_emul *bridge) | ||
| 312 | { | ||
| 313 | if (bridge->has_pcie) | ||
| 314 | kfree(bridge->pcie_cap_regs_behavior); | ||
| 315 | kfree(bridge->pci_regs_behavior); | ||
| 316 | } | ||
| 317 | |||
| 318 | /* | ||
| 287 | * Should be called by the PCI controller driver when reading the PCI | 319 | * Should be called by the PCI controller driver when reading the PCI |
| 288 | * configuration space of the fake bridge. It will call back the | 320 | * configuration space of the fake bridge. It will call back the |
| 289 | * ->ops->read_base or ->ops->read_pcie operations. | 321 | * ->ops->read_base or ->ops->read_pcie operations. |
| @@ -312,11 +344,11 @@ int pci_bridge_emul_conf_read(struct pci_bridge_emul *bridge, int where, | |||
| 312 | reg -= PCI_CAP_PCIE_START; | 344 | reg -= PCI_CAP_PCIE_START; |
| 313 | read_op = bridge->ops->read_pcie; | 345 | read_op = bridge->ops->read_pcie; |
| 314 | cfgspace = (u32 *) &bridge->pcie_conf; | 346 | cfgspace = (u32 *) &bridge->pcie_conf; |
| 315 | behavior = pcie_cap_regs_behavior; | 347 | behavior = bridge->pcie_cap_regs_behavior; |
| 316 | } else { | 348 | } else { |
| 317 | read_op = bridge->ops->read_base; | 349 | read_op = bridge->ops->read_base; |
| 318 | cfgspace = (u32 *) &bridge->conf; | 350 | cfgspace = (u32 *) &bridge->conf; |
| 319 | behavior = pci_regs_behavior; | 351 | behavior = bridge->pci_regs_behavior; |
| 320 | } | 352 | } |
| 321 | 353 | ||
| 322 | if (read_op) | 354 | if (read_op) |
| @@ -383,11 +415,11 @@ int pci_bridge_emul_conf_write(struct pci_bridge_emul *bridge, int where, | |||
| 383 | reg -= PCI_CAP_PCIE_START; | 415 | reg -= PCI_CAP_PCIE_START; |
| 384 | write_op = bridge->ops->write_pcie; | 416 | write_op = bridge->ops->write_pcie; |
| 385 | cfgspace = (u32 *) &bridge->pcie_conf; | 417 | cfgspace = (u32 *) &bridge->pcie_conf; |
| 386 | behavior = pcie_cap_regs_behavior; | 418 | behavior = bridge->pcie_cap_regs_behavior; |
| 387 | } else { | 419 | } else { |
| 388 | write_op = bridge->ops->write_base; | 420 | write_op = bridge->ops->write_base; |
| 389 | cfgspace = (u32 *) &bridge->conf; | 421 | cfgspace = (u32 *) &bridge->conf; |
| 390 | behavior = pci_regs_behavior; | 422 | behavior = bridge->pci_regs_behavior; |
| 391 | } | 423 | } |
| 392 | 424 | ||
| 393 | /* Keep all bits, except the RW bits */ | 425 | /* Keep all bits, except the RW bits */ |
diff --git a/drivers/pci/pci-bridge-emul.h b/drivers/pci/pci-bridge-emul.h index 9d510ccf738b..e65b1b79899d 100644 --- a/drivers/pci/pci-bridge-emul.h +++ b/drivers/pci/pci-bridge-emul.h | |||
| @@ -107,15 +107,26 @@ struct pci_bridge_emul_ops { | |||
| 107 | u32 old, u32 new, u32 mask); | 107 | u32 old, u32 new, u32 mask); |
| 108 | }; | 108 | }; |
| 109 | 109 | ||
| 110 | struct pci_bridge_reg_behavior; | ||
| 111 | |||
| 110 | struct pci_bridge_emul { | 112 | struct pci_bridge_emul { |
| 111 | struct pci_bridge_emul_conf conf; | 113 | struct pci_bridge_emul_conf conf; |
| 112 | struct pci_bridge_emul_pcie_conf pcie_conf; | 114 | struct pci_bridge_emul_pcie_conf pcie_conf; |
| 113 | struct pci_bridge_emul_ops *ops; | 115 | struct pci_bridge_emul_ops *ops; |
| 116 | struct pci_bridge_reg_behavior *pci_regs_behavior; | ||
| 117 | struct pci_bridge_reg_behavior *pcie_cap_regs_behavior; | ||
| 114 | void *data; | 118 | void *data; |
| 115 | bool has_pcie; | 119 | bool has_pcie; |
| 116 | }; | 120 | }; |
| 117 | 121 | ||
| 118 | void pci_bridge_emul_init(struct pci_bridge_emul *bridge); | 122 | enum { |
| 123 | PCI_BRIDGE_EMUL_NO_PREFETCHABLE_BAR = BIT(0), | ||
| 124 | }; | ||
| 125 | |||
| 126 | int pci_bridge_emul_init(struct pci_bridge_emul *bridge, | ||
| 127 | unsigned int flags); | ||
| 128 | void pci_bridge_emul_cleanup(struct pci_bridge_emul *bridge); | ||
| 129 | |||
| 119 | int pci_bridge_emul_conf_read(struct pci_bridge_emul *bridge, int where, | 130 | int pci_bridge_emul_conf_read(struct pci_bridge_emul *bridge, int where, |
| 120 | int size, u32 *value); | 131 | int size, u32 *value); |
| 121 | int pci_bridge_emul_conf_write(struct pci_bridge_emul *bridge, int where, | 132 | int pci_bridge_emul_conf_write(struct pci_bridge_emul *bridge, int where, |
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index 79b1610a8beb..71853befd435 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c | |||
| @@ -100,7 +100,7 @@ static ssize_t new_id_store(struct device_driver *driver, const char *buf, | |||
| 100 | { | 100 | { |
| 101 | struct pci_driver *pdrv = to_pci_driver(driver); | 101 | struct pci_driver *pdrv = to_pci_driver(driver); |
| 102 | const struct pci_device_id *ids = pdrv->id_table; | 102 | const struct pci_device_id *ids = pdrv->id_table; |
| 103 | __u32 vendor, device, subvendor = PCI_ANY_ID, | 103 | u32 vendor, device, subvendor = PCI_ANY_ID, |
| 104 | subdevice = PCI_ANY_ID, class = 0, class_mask = 0; | 104 | subdevice = PCI_ANY_ID, class = 0, class_mask = 0; |
| 105 | unsigned long driver_data = 0; | 105 | unsigned long driver_data = 0; |
| 106 | int fields = 0; | 106 | int fields = 0; |
| @@ -168,7 +168,7 @@ static ssize_t remove_id_store(struct device_driver *driver, const char *buf, | |||
| 168 | { | 168 | { |
| 169 | struct pci_dynid *dynid, *n; | 169 | struct pci_dynid *dynid, *n; |
| 170 | struct pci_driver *pdrv = to_pci_driver(driver); | 170 | struct pci_driver *pdrv = to_pci_driver(driver); |
| 171 | __u32 vendor, device, subvendor = PCI_ANY_ID, | 171 | u32 vendor, device, subvendor = PCI_ANY_ID, |
| 172 | subdevice = PCI_ANY_ID, class = 0, class_mask = 0; | 172 | subdevice = PCI_ANY_ID, class = 0, class_mask = 0; |
| 173 | int fields = 0; | 173 | int fields = 0; |
| 174 | size_t retval = -ENODEV; | 174 | size_t retval = -ENODEV; |
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index db55acf32a7e..7c1b362f599a 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
| @@ -861,7 +861,7 @@ static int pci_raw_set_power_state(struct pci_dev *dev, pci_power_t state) | |||
| 861 | if ((pmcsr & PCI_PM_CTRL_STATE_MASK) == PCI_D3hot | 861 | if ((pmcsr & PCI_PM_CTRL_STATE_MASK) == PCI_D3hot |
| 862 | && !(pmcsr & PCI_PM_CTRL_NO_SOFT_RESET)) | 862 | && !(pmcsr & PCI_PM_CTRL_NO_SOFT_RESET)) |
| 863 | need_restore = true; | 863 | need_restore = true; |
| 864 | /* Fall-through: force to D0 */ | 864 | /* Fall-through - force to D0 */ |
| 865 | default: | 865 | default: |
| 866 | pmcsr = 0; | 866 | pmcsr = 0; |
| 867 | break; | 867 | break; |
| @@ -1233,7 +1233,6 @@ static void pci_restore_pcie_state(struct pci_dev *dev) | |||
| 1233 | pcie_capability_write_word(dev, PCI_EXP_SLTCTL2, cap[i++]); | 1233 | pcie_capability_write_word(dev, PCI_EXP_SLTCTL2, cap[i++]); |
| 1234 | } | 1234 | } |
| 1235 | 1235 | ||
| 1236 | |||
| 1237 | static int pci_save_pcix_state(struct pci_dev *dev) | 1236 | static int pci_save_pcix_state(struct pci_dev *dev) |
| 1238 | { | 1237 | { |
| 1239 | int pos; | 1238 | int pos; |
| @@ -1270,6 +1269,45 @@ static void pci_restore_pcix_state(struct pci_dev *dev) | |||
| 1270 | pci_write_config_word(dev, pos + PCI_X_CMD, cap[i++]); | 1269 | pci_write_config_word(dev, pos + PCI_X_CMD, cap[i++]); |
| 1271 | } | 1270 | } |
| 1272 | 1271 | ||
| 1272 | static void pci_save_ltr_state(struct pci_dev *dev) | ||
| 1273 | { | ||
| 1274 | int ltr; | ||
| 1275 | struct pci_cap_saved_state *save_state; | ||
| 1276 | u16 *cap; | ||
| 1277 | |||
| 1278 | if (!pci_is_pcie(dev)) | ||
| 1279 | return; | ||
| 1280 | |||
| 1281 | ltr = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_LTR); | ||
| 1282 | if (!ltr) | ||
| 1283 | return; | ||
| 1284 | |||
| 1285 | save_state = pci_find_saved_ext_cap(dev, PCI_EXT_CAP_ID_LTR); | ||
| 1286 | if (!save_state) { | ||
| 1287 | pci_err(dev, "no suspend buffer for LTR; ASPM issues possible after resume\n"); | ||
| 1288 | return; | ||
| 1289 | } | ||
| 1290 | |||
| 1291 | cap = (u16 *)&save_state->cap.data[0]; | ||
| 1292 | pci_read_config_word(dev, ltr + PCI_LTR_MAX_SNOOP_LAT, cap++); | ||
| 1293 | pci_read_config_word(dev, ltr + PCI_LTR_MAX_NOSNOOP_LAT, cap++); | ||
| 1294 | } | ||
| 1295 | |||
| 1296 | static void pci_restore_ltr_state(struct pci_dev *dev) | ||
| 1297 | { | ||
| 1298 | struct pci_cap_saved_state *save_state; | ||
| 1299 | int ltr; | ||
| 1300 | u16 *cap; | ||
| 1301 | |||
| 1302 | save_state = pci_find_saved_ext_cap(dev, PCI_EXT_CAP_ID_LTR); | ||
| 1303 | ltr = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_LTR); | ||
| 1304 | if (!save_state || !ltr) | ||
| 1305 | return; | ||
| 1306 | |||
| 1307 | cap = (u16 *)&save_state->cap.data[0]; | ||
| 1308 | pci_write_config_word(dev, ltr + PCI_LTR_MAX_SNOOP_LAT, *cap++); | ||
| 1309 | pci_write_config_word(dev, ltr + PCI_LTR_MAX_NOSNOOP_LAT, *cap++); | ||
| 1310 | } | ||
| 1273 | 1311 | ||
| 1274 | /** | 1312 | /** |
| 1275 | * pci_save_state - save the PCI configuration space of a device before suspending | 1313 | * pci_save_state - save the PCI configuration space of a device before suspending |
| @@ -1291,6 +1329,7 @@ int pci_save_state(struct pci_dev *dev) | |||
| 1291 | if (i != 0) | 1329 | if (i != 0) |
| 1292 | return i; | 1330 | return i; |
| 1293 | 1331 | ||
| 1332 | pci_save_ltr_state(dev); | ||
| 1294 | pci_save_dpc_state(dev); | 1333 | pci_save_dpc_state(dev); |
| 1295 | return pci_save_vc_state(dev); | 1334 | return pci_save_vc_state(dev); |
| 1296 | } | 1335 | } |
| @@ -1390,7 +1429,12 @@ void pci_restore_state(struct pci_dev *dev) | |||
| 1390 | if (!dev->state_saved) | 1429 | if (!dev->state_saved) |
| 1391 | return; | 1430 | return; |
| 1392 | 1431 | ||
| 1393 | /* PCI Express register must be restored first */ | 1432 | /* |
| 1433 | * Restore max latencies (in the LTR capability) before enabling | ||
| 1434 | * LTR itself (in the PCIe capability). | ||
| 1435 | */ | ||
| 1436 | pci_restore_ltr_state(dev); | ||
| 1437 | |||
| 1394 | pci_restore_pcie_state(dev); | 1438 | pci_restore_pcie_state(dev); |
| 1395 | pci_restore_pasid_state(dev); | 1439 | pci_restore_pasid_state(dev); |
| 1396 | pci_restore_pri_state(dev); | 1440 | pci_restore_pri_state(dev); |
| @@ -2260,7 +2304,7 @@ static pci_power_t pci_target_state(struct pci_dev *dev, bool wakeup) | |||
| 2260 | case PCI_D2: | 2304 | case PCI_D2: |
| 2261 | if (pci_no_d1d2(dev)) | 2305 | if (pci_no_d1d2(dev)) |
| 2262 | break; | 2306 | break; |
| 2263 | /* else: fall through */ | 2307 | /* else, fall through */ |
| 2264 | default: | 2308 | default: |
| 2265 | target_state = state; | 2309 | target_state = state; |
| 2266 | } | 2310 | } |
| @@ -2501,6 +2545,25 @@ void pci_config_pm_runtime_put(struct pci_dev *pdev) | |||
| 2501 | pm_runtime_put_sync(parent); | 2545 | pm_runtime_put_sync(parent); |
| 2502 | } | 2546 | } |
| 2503 | 2547 | ||
| 2548 | static const struct dmi_system_id bridge_d3_blacklist[] = { | ||
| 2549 | #ifdef CONFIG_X86 | ||
| 2550 | { | ||
| 2551 | /* | ||
| 2552 | * Gigabyte X299 root port is not marked as hotplug capable | ||
| 2553 | * which allows Linux to power manage it. However, this | ||
| 2554 | * confuses the BIOS SMI handler so don't power manage root | ||
| 2555 | * ports on that system. | ||
| 2556 | */ | ||
| 2557 | .ident = "X299 DESIGNARE EX-CF", | ||
| 2558 | .matches = { | ||
| 2559 | DMI_MATCH(DMI_BOARD_VENDOR, "Gigabyte Technology Co., Ltd."), | ||
| 2560 | DMI_MATCH(DMI_BOARD_NAME, "X299 DESIGNARE EX-CF"), | ||
| 2561 | }, | ||
| 2562 | }, | ||
| 2563 | #endif | ||
| 2564 | { } | ||
| 2565 | }; | ||
| 2566 | |||
| 2504 | /** | 2567 | /** |
| 2505 | * pci_bridge_d3_possible - Is it possible to put the bridge into D3 | 2568 | * pci_bridge_d3_possible - Is it possible to put the bridge into D3 |
| 2506 | * @bridge: Bridge to check | 2569 | * @bridge: Bridge to check |
| @@ -2546,6 +2609,9 @@ bool pci_bridge_d3_possible(struct pci_dev *bridge) | |||
| 2546 | if (bridge->is_hotplug_bridge) | 2609 | if (bridge->is_hotplug_bridge) |
| 2547 | return false; | 2610 | return false; |
| 2548 | 2611 | ||
| 2612 | if (dmi_check_system(bridge_d3_blacklist)) | ||
| 2613 | return false; | ||
| 2614 | |||
| 2549 | /* | 2615 | /* |
| 2550 | * It should be safe to put PCIe ports from 2015 or newer | 2616 | * It should be safe to put PCIe ports from 2015 or newer |
| 2551 | * to D3. | 2617 | * to D3. |
| @@ -2998,6 +3064,11 @@ void pci_allocate_cap_save_buffers(struct pci_dev *dev) | |||
| 2998 | if (error) | 3064 | if (error) |
| 2999 | pci_err(dev, "unable to preallocate PCI-X save buffer\n"); | 3065 | pci_err(dev, "unable to preallocate PCI-X save buffer\n"); |
| 3000 | 3066 | ||
| 3067 | error = pci_add_ext_cap_save_buffer(dev, PCI_EXT_CAP_ID_LTR, | ||
| 3068 | 2 * sizeof(u16)); | ||
| 3069 | if (error) | ||
| 3070 | pci_err(dev, "unable to allocate suspend buffer for LTR\n"); | ||
| 3071 | |||
| 3001 | pci_allocate_vc_save_buffers(dev); | 3072 | pci_allocate_vc_save_buffers(dev); |
| 3002 | } | 3073 | } |
| 3003 | 3074 | ||
| @@ -5058,39 +5129,42 @@ unlock: | |||
| 5058 | return 0; | 5129 | return 0; |
| 5059 | } | 5130 | } |
| 5060 | 5131 | ||
| 5061 | /* Save and disable devices from the top of the tree down */ | 5132 | /* |
| 5062 | static void pci_bus_save_and_disable(struct pci_bus *bus) | 5133 | * Save and disable devices from the top of the tree down while holding |
| 5134 | * the @dev mutex lock for the entire tree. | ||
| 5135 | */ | ||
| 5136 | static void pci_bus_save_and_disable_locked(struct pci_bus *bus) | ||
| 5063 | { | 5137 | { |
| 5064 | struct pci_dev *dev; | 5138 | struct pci_dev *dev; |
| 5065 | 5139 | ||
| 5066 | list_for_each_entry(dev, &bus->devices, bus_list) { | 5140 | list_for_each_entry(dev, &bus->devices, bus_list) { |
| 5067 | pci_dev_lock(dev); | ||
| 5068 | pci_dev_save_and_disable(dev); | 5141 | pci_dev_save_and_disable(dev); |
| 5069 | pci_dev_unlock(dev); | ||
| 5070 | if (dev->subordinate) | 5142 | if (dev->subordinate) |
| 5071 | pci_bus_save_and_disable(dev->subordinate); | 5143 | pci_bus_save_and_disable_locked(dev->subordinate); |
| 5072 | } | 5144 | } |
| 5073 | } | 5145 | } |
| 5074 | 5146 | ||
| 5075 | /* | 5147 | /* |
| 5076 | * Restore devices from top of the tree down - parent bridges need to be | 5148 | * Restore devices from top of the tree down while holding @dev mutex lock |
| 5077 | * restored before we can get to subordinate devices. | 5149 | * for the entire tree. Parent bridges need to be restored before we can |
| 5150 | * get to subordinate devices. | ||
| 5078 | */ | 5151 | */ |
| 5079 | static void pci_bus_restore(struct pci_bus *bus) | 5152 | static void pci_bus_restore_locked(struct pci_bus *bus) |
| 5080 | { | 5153 | { |
| 5081 | struct pci_dev *dev; | 5154 | struct pci_dev *dev; |
| 5082 | 5155 | ||
| 5083 | list_for_each_entry(dev, &bus->devices, bus_list) { | 5156 | list_for_each_entry(dev, &bus->devices, bus_list) { |
| 5084 | pci_dev_lock(dev); | ||
| 5085 | pci_dev_restore(dev); | 5157 | pci_dev_restore(dev); |
| 5086 | pci_dev_unlock(dev); | ||
| 5087 | if (dev->subordinate) | 5158 | if (dev->subordinate) |
| 5088 | pci_bus_restore(dev->subordinate); | 5159 | pci_bus_restore_locked(dev->subordinate); |
| 5089 | } | 5160 | } |
| 5090 | } | 5161 | } |
| 5091 | 5162 | ||
| 5092 | /* Save and disable devices from the top of the tree down */ | 5163 | /* |
| 5093 | static void pci_slot_save_and_disable(struct pci_slot *slot) | 5164 | * Save and disable devices from the top of the tree down while holding |
| 5165 | * the @dev mutex lock for the entire tree. | ||
| 5166 | */ | ||
| 5167 | static void pci_slot_save_and_disable_locked(struct pci_slot *slot) | ||
| 5094 | { | 5168 | { |
| 5095 | struct pci_dev *dev; | 5169 | struct pci_dev *dev; |
| 5096 | 5170 | ||
| @@ -5099,26 +5173,25 @@ static void pci_slot_save_and_disable(struct pci_slot *slot) | |||
| 5099 | continue; | 5173 | continue; |
| 5100 | pci_dev_save_and_disable(dev); | 5174 | pci_dev_save_and_disable(dev); |
| 5101 | if (dev->subordinate) | 5175 | if (dev->subordinate) |
| 5102 | pci_bus_save_and_disable(dev->subordinate); | 5176 | pci_bus_save_and_disable_locked(dev->subordinate); |
| 5103 | } | 5177 | } |
| 5104 | } | 5178 | } |
| 5105 | 5179 | ||
| 5106 | /* | 5180 | /* |
| 5107 | * Restore devices from top of the tree down - parent bridges need to be | 5181 | * Restore devices from top of the tree down while holding @dev mutex lock |
| 5108 | * restored before we can get to subordinate devices. | 5182 | * for the entire tree. Parent bridges need to be restored before we can |
| 5183 | * get to subordinate devices. | ||
| 5109 | */ | 5184 | */ |
| 5110 | static void pci_slot_restore(struct pci_slot *slot) | 5185 | static void pci_slot_restore_locked(struct pci_slot *slot) |
| 5111 | { | 5186 | { |
| 5112 | struct pci_dev *dev; | 5187 | struct pci_dev *dev; |
| 5113 | 5188 | ||
| 5114 | list_for_each_entry(dev, &slot->bus->devices, bus_list) { | 5189 | list_for_each_entry(dev, &slot->bus->devices, bus_list) { |
| 5115 | if (!dev->slot || dev->slot != slot) | 5190 | if (!dev->slot || dev->slot != slot) |
| 5116 | continue; | 5191 | continue; |
| 5117 | pci_dev_lock(dev); | ||
| 5118 | pci_dev_restore(dev); | 5192 | pci_dev_restore(dev); |
| 5119 | pci_dev_unlock(dev); | ||
| 5120 | if (dev->subordinate) | 5193 | if (dev->subordinate) |
| 5121 | pci_bus_restore(dev->subordinate); | 5194 | pci_bus_restore_locked(dev->subordinate); |
| 5122 | } | 5195 | } |
| 5123 | } | 5196 | } |
| 5124 | 5197 | ||
| @@ -5177,17 +5250,15 @@ static int __pci_reset_slot(struct pci_slot *slot) | |||
| 5177 | if (rc) | 5250 | if (rc) |
| 5178 | return rc; | 5251 | return rc; |
| 5179 | 5252 | ||
| 5180 | pci_slot_save_and_disable(slot); | ||
| 5181 | |||
| 5182 | if (pci_slot_trylock(slot)) { | 5253 | if (pci_slot_trylock(slot)) { |
| 5254 | pci_slot_save_and_disable_locked(slot); | ||
| 5183 | might_sleep(); | 5255 | might_sleep(); |
| 5184 | rc = pci_reset_hotplug_slot(slot->hotplug, 0); | 5256 | rc = pci_reset_hotplug_slot(slot->hotplug, 0); |
| 5257 | pci_slot_restore_locked(slot); | ||
| 5185 | pci_slot_unlock(slot); | 5258 | pci_slot_unlock(slot); |
| 5186 | } else | 5259 | } else |
| 5187 | rc = -EAGAIN; | 5260 | rc = -EAGAIN; |
| 5188 | 5261 | ||
| 5189 | pci_slot_restore(slot); | ||
| 5190 | |||
| 5191 | return rc; | 5262 | return rc; |
| 5192 | } | 5263 | } |
| 5193 | 5264 | ||
| @@ -5273,17 +5344,15 @@ static int __pci_reset_bus(struct pci_bus *bus) | |||
| 5273 | if (rc) | 5344 | if (rc) |
| 5274 | return rc; | 5345 | return rc; |
| 5275 | 5346 | ||
| 5276 | pci_bus_save_and_disable(bus); | ||
| 5277 | |||
| 5278 | if (pci_bus_trylock(bus)) { | 5347 | if (pci_bus_trylock(bus)) { |
| 5348 | pci_bus_save_and_disable_locked(bus); | ||
| 5279 | might_sleep(); | 5349 | might_sleep(); |
| 5280 | rc = pci_bridge_secondary_bus_reset(bus->self); | 5350 | rc = pci_bridge_secondary_bus_reset(bus->self); |
| 5351 | pci_bus_restore_locked(bus); | ||
| 5281 | pci_bus_unlock(bus); | 5352 | pci_bus_unlock(bus); |
| 5282 | } else | 5353 | } else |
| 5283 | rc = -EAGAIN; | 5354 | rc = -EAGAIN; |
| 5284 | 5355 | ||
| 5285 | pci_bus_restore(bus); | ||
| 5286 | |||
| 5287 | return rc; | 5356 | return rc; |
| 5288 | } | 5357 | } |
| 5289 | 5358 | ||
| @@ -6000,8 +6069,7 @@ void pci_reassigndev_resource_alignment(struct pci_dev *dev) | |||
| 6000 | * to enable the kernel to reassign new resource | 6069 | * to enable the kernel to reassign new resource |
| 6001 | * window later on. | 6070 | * window later on. |
| 6002 | */ | 6071 | */ |
| 6003 | if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE && | 6072 | if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) { |
| 6004 | (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) { | ||
| 6005 | for (i = PCI_BRIDGE_RESOURCES; i < PCI_NUM_RESOURCES; i++) { | 6073 | for (i = PCI_BRIDGE_RESOURCES; i < PCI_NUM_RESOURCES; i++) { |
| 6006 | r = &dev->resource[i]; | 6074 | r = &dev->resource[i]; |
| 6007 | if (!(r->flags & IORESOURCE_MEM)) | 6075 | if (!(r->flags & IORESOURCE_MEM)) |
diff --git a/drivers/pci/pcie/Kconfig b/drivers/pci/pcie/Kconfig index 44742b2e1126..5cbdbca904ac 100644 --- a/drivers/pci/pcie/Kconfig +++ b/drivers/pci/pcie/Kconfig | |||
| @@ -6,10 +6,9 @@ config PCIEPORTBUS | |||
| 6 | bool "PCI Express Port Bus support" | 6 | bool "PCI Express Port Bus support" |
| 7 | depends on PCI | 7 | depends on PCI |
| 8 | help | 8 | help |
| 9 | This automatically enables PCI Express Port Bus support. Users can | 9 | This enables PCI Express Port Bus support. Users can then enable |
| 10 | choose Native Hot-Plug support, Advanced Error Reporting support, | 10 | support for Native Hot-Plug, Advanced Error Reporting, Power |
| 11 | Power Management Event support and Virtual Channel support to run | 11 | Management Events, and Downstream Port Containment. |
| 12 | on PCI Express Ports (Root or Switch). | ||
| 13 | 12 | ||
| 14 | # | 13 | # |
| 15 | # Include service Kconfig here | 14 | # Include service Kconfig here |
diff --git a/drivers/pci/pcie/Makefile b/drivers/pci/pcie/Makefile index ab514083d5d4..f1d7bc1e5efa 100644 --- a/drivers/pci/pcie/Makefile +++ b/drivers/pci/pcie/Makefile | |||
| @@ -3,6 +3,7 @@ | |||
| 3 | # Makefile for PCI Express features and port driver | 3 | # Makefile for PCI Express features and port driver |
| 4 | 4 | ||
| 5 | pcieportdrv-y := portdrv_core.o portdrv_pci.o err.o | 5 | pcieportdrv-y := portdrv_core.o portdrv_pci.o err.o |
| 6 | pcieportdrv-y += bw_notification.o | ||
| 6 | 7 | ||
| 7 | obj-$(CONFIG_PCIEPORTBUS) += pcieportdrv.o | 8 | obj-$(CONFIG_PCIEPORTBUS) += pcieportdrv.o |
| 8 | 9 | ||
diff --git a/drivers/pci/pcie/aer.c b/drivers/pci/pcie/aer.c index fed29de783e0..f8fc2114ad39 100644 --- a/drivers/pci/pcie/aer.c +++ b/drivers/pci/pcie/aer.c | |||
| @@ -117,7 +117,7 @@ bool pci_aer_available(void) | |||
| 117 | 117 | ||
| 118 | static int ecrc_policy = ECRC_POLICY_DEFAULT; | 118 | static int ecrc_policy = ECRC_POLICY_DEFAULT; |
| 119 | 119 | ||
| 120 | static const char *ecrc_policy_str[] = { | 120 | static const char * const ecrc_policy_str[] = { |
| 121 | [ECRC_POLICY_DEFAULT] = "bios", | 121 | [ECRC_POLICY_DEFAULT] = "bios", |
| 122 | [ECRC_POLICY_OFF] = "off", | 122 | [ECRC_POLICY_OFF] = "off", |
| 123 | [ECRC_POLICY_ON] = "on" | 123 | [ECRC_POLICY_ON] = "on" |
| @@ -203,11 +203,8 @@ void pcie_ecrc_get_policy(char *str) | |||
| 203 | { | 203 | { |
| 204 | int i; | 204 | int i; |
| 205 | 205 | ||
| 206 | for (i = 0; i < ARRAY_SIZE(ecrc_policy_str); i++) | 206 | i = match_string(ecrc_policy_str, ARRAY_SIZE(ecrc_policy_str), str); |
| 207 | if (!strncmp(str, ecrc_policy_str[i], | 207 | if (i < 0) |
| 208 | strlen(ecrc_policy_str[i]))) | ||
| 209 | break; | ||
| 210 | if (i >= ARRAY_SIZE(ecrc_policy_str)) | ||
| 211 | return; | 208 | return; |
| 212 | 209 | ||
| 213 | ecrc_policy = i; | 210 | ecrc_policy = i; |
diff --git a/drivers/pci/pcie/bw_notification.c b/drivers/pci/pcie/bw_notification.c new file mode 100644 index 000000000000..d2eae3b7cc0f --- /dev/null +++ b/drivers/pci/pcie/bw_notification.c | |||
| @@ -0,0 +1,110 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0+ | ||
| 2 | /* | ||
| 3 | * PCI Express Link Bandwidth Notification services driver | ||
| 4 | * Author: Alexandru Gagniuc <mr.nuke.me@gmail.com> | ||
| 5 | * | ||
| 6 | * Copyright (C) 2019, Dell Inc | ||
| 7 | * | ||
| 8 | * The PCIe Link Bandwidth Notification provides a way to notify the | ||
| 9 | * operating system when the link width or data rate changes. This | ||
| 10 | * capability is required for all root ports and downstream ports | ||
| 11 | * supporting links wider than x1 and/or multiple link speeds. | ||
| 12 | * | ||
| 13 | * This service port driver hooks into the bandwidth notification interrupt | ||
| 14 | * and warns when links become degraded in operation. | ||
| 15 | */ | ||
| 16 | |||
| 17 | #include "../pci.h" | ||
| 18 | #include "portdrv.h" | ||
| 19 | |||
| 20 | static bool pcie_link_bandwidth_notification_supported(struct pci_dev *dev) | ||
| 21 | { | ||
| 22 | int ret; | ||
| 23 | u32 lnk_cap; | ||
| 24 | |||
| 25 | ret = pcie_capability_read_dword(dev, PCI_EXP_LNKCAP, &lnk_cap); | ||
| 26 | return (ret == PCIBIOS_SUCCESSFUL) && (lnk_cap & PCI_EXP_LNKCAP_LBNC); | ||
| 27 | } | ||
| 28 | |||
| 29 | static void pcie_enable_link_bandwidth_notification(struct pci_dev *dev) | ||
| 30 | { | ||
| 31 | u16 lnk_ctl; | ||
| 32 | |||
| 33 | pcie_capability_read_word(dev, PCI_EXP_LNKCTL, &lnk_ctl); | ||
| 34 | lnk_ctl |= PCI_EXP_LNKCTL_LBMIE; | ||
| 35 | pcie_capability_write_word(dev, PCI_EXP_LNKCTL, lnk_ctl); | ||
| 36 | } | ||
| 37 | |||
| 38 | static void pcie_disable_link_bandwidth_notification(struct pci_dev *dev) | ||
| 39 | { | ||
| 40 | u16 lnk_ctl; | ||
| 41 | |||
| 42 | pcie_capability_read_word(dev, PCI_EXP_LNKCTL, &lnk_ctl); | ||
| 43 | lnk_ctl &= ~PCI_EXP_LNKCTL_LBMIE; | ||
| 44 | pcie_capability_write_word(dev, PCI_EXP_LNKCTL, lnk_ctl); | ||
| 45 | } | ||
| 46 | |||
| 47 | static irqreturn_t pcie_bw_notification_handler(int irq, void *context) | ||
| 48 | { | ||
| 49 | struct pcie_device *srv = context; | ||
| 50 | struct pci_dev *port = srv->port; | ||
| 51 | struct pci_dev *dev; | ||
| 52 | u16 link_status, events; | ||
| 53 | int ret; | ||
| 54 | |||
| 55 | ret = pcie_capability_read_word(port, PCI_EXP_LNKSTA, &link_status); | ||
| 56 | events = link_status & PCI_EXP_LNKSTA_LBMS; | ||
| 57 | |||
| 58 | if (ret != PCIBIOS_SUCCESSFUL || !events) | ||
| 59 | return IRQ_NONE; | ||
| 60 | |||
| 61 | /* | ||
| 62 | * Print status from downstream devices, not this root port or | ||
| 63 | * downstream switch port. | ||
| 64 | */ | ||
| 65 | down_read(&pci_bus_sem); | ||
| 66 | list_for_each_entry(dev, &port->subordinate->devices, bus_list) | ||
| 67 | __pcie_print_link_status(dev, false); | ||
| 68 | up_read(&pci_bus_sem); | ||
| 69 | |||
| 70 | pcie_update_link_speed(port->subordinate, link_status); | ||
| 71 | pcie_capability_write_word(port, PCI_EXP_LNKSTA, events); | ||
| 72 | return IRQ_HANDLED; | ||
| 73 | } | ||
| 74 | |||
| 75 | static int pcie_bandwidth_notification_probe(struct pcie_device *srv) | ||
| 76 | { | ||
| 77 | int ret; | ||
| 78 | |||
| 79 | /* Single-width or single-speed ports do not have to support this. */ | ||
| 80 | if (!pcie_link_bandwidth_notification_supported(srv->port)) | ||
| 81 | return -ENODEV; | ||
| 82 | |||
| 83 | ret = request_threaded_irq(srv->irq, NULL, pcie_bw_notification_handler, | ||
| 84 | IRQF_SHARED, "PCIe BW notif", srv); | ||
| 85 | if (ret) | ||
| 86 | return ret; | ||
| 87 | |||
| 88 | pcie_enable_link_bandwidth_notification(srv->port); | ||
| 89 | |||
| 90 | return 0; | ||
| 91 | } | ||
| 92 | |||
| 93 | static void pcie_bandwidth_notification_remove(struct pcie_device *srv) | ||
| 94 | { | ||
| 95 | pcie_disable_link_bandwidth_notification(srv->port); | ||
| 96 | free_irq(srv->irq, srv); | ||
| 97 | } | ||
| 98 | |||
| 99 | static struct pcie_port_service_driver pcie_bandwidth_notification_driver = { | ||
| 100 | .name = "pcie_bw_notification", | ||
| 101 | .port_type = PCIE_ANY_PORT, | ||
| 102 | .service = PCIE_PORT_SERVICE_BWNOTIF, | ||
| 103 | .probe = pcie_bandwidth_notification_probe, | ||
| 104 | .remove = pcie_bandwidth_notification_remove, | ||
| 105 | }; | ||
| 106 | |||
| 107 | int __init pcie_bandwidth_notification_init(void) | ||
| 108 | { | ||
| 109 | return pcie_port_service_register(&pcie_bandwidth_notification_driver); | ||
| 110 | } | ||
diff --git a/drivers/pci/pcie/dpc.c b/drivers/pci/pcie/dpc.c index e435d12e61a0..7b77754a82de 100644 --- a/drivers/pci/pcie/dpc.c +++ b/drivers/pci/pcie/dpc.c | |||
| @@ -202,6 +202,28 @@ static void dpc_process_rp_pio_error(struct dpc_dev *dpc) | |||
| 202 | pci_write_config_dword(pdev, cap + PCI_EXP_DPC_RP_PIO_STATUS, status); | 202 | pci_write_config_dword(pdev, cap + PCI_EXP_DPC_RP_PIO_STATUS, status); |
| 203 | } | 203 | } |
| 204 | 204 | ||
| 205 | static int dpc_get_aer_uncorrect_severity(struct pci_dev *dev, | ||
| 206 | struct aer_err_info *info) | ||
| 207 | { | ||
| 208 | int pos = dev->aer_cap; | ||
| 209 | u32 status, mask, sev; | ||
| 210 | |||
| 211 | pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, &status); | ||
| 212 | pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_MASK, &mask); | ||
| 213 | status &= ~mask; | ||
| 214 | if (!status) | ||
| 215 | return 0; | ||
| 216 | |||
| 217 | pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_SEVER, &sev); | ||
| 218 | status &= sev; | ||
| 219 | if (status) | ||
| 220 | info->severity = AER_FATAL; | ||
| 221 | else | ||
| 222 | info->severity = AER_NONFATAL; | ||
| 223 | |||
| 224 | return 1; | ||
| 225 | } | ||
| 226 | |||
| 205 | static irqreturn_t dpc_handler(int irq, void *context) | 227 | static irqreturn_t dpc_handler(int irq, void *context) |
| 206 | { | 228 | { |
| 207 | struct aer_err_info info; | 229 | struct aer_err_info info; |
| @@ -229,9 +251,12 @@ static irqreturn_t dpc_handler(int irq, void *context) | |||
| 229 | /* show RP PIO error detail information */ | 251 | /* show RP PIO error detail information */ |
| 230 | if (dpc->rp_extensions && reason == 3 && ext_reason == 0) | 252 | if (dpc->rp_extensions && reason == 3 && ext_reason == 0) |
| 231 | dpc_process_rp_pio_error(dpc); | 253 | dpc_process_rp_pio_error(dpc); |
| 232 | else if (reason == 0 && aer_get_device_error_info(pdev, &info)) { | 254 | else if (reason == 0 && |
| 255 | dpc_get_aer_uncorrect_severity(pdev, &info) && | ||
| 256 | aer_get_device_error_info(pdev, &info)) { | ||
| 233 | aer_print_error(pdev, &info); | 257 | aer_print_error(pdev, &info); |
| 234 | pci_cleanup_aer_uncorrect_error_status(pdev); | 258 | pci_cleanup_aer_uncorrect_error_status(pdev); |
| 259 | pci_aer_clear_fatal_status(pdev); | ||
| 235 | } | 260 | } |
| 236 | 261 | ||
| 237 | /* We configure DPC so it only triggers on ERR_FATAL */ | 262 | /* We configure DPC so it only triggers on ERR_FATAL */ |
diff --git a/drivers/pci/pcie/pme.c b/drivers/pci/pcie/pme.c index 0dbcf429089f..54d593d10396 100644 --- a/drivers/pci/pcie/pme.c +++ b/drivers/pci/pcie/pme.c | |||
| @@ -363,6 +363,16 @@ static bool pcie_pme_check_wakeup(struct pci_bus *bus) | |||
| 363 | return false; | 363 | return false; |
| 364 | } | 364 | } |
| 365 | 365 | ||
| 366 | static void pcie_pme_disable_interrupt(struct pci_dev *port, | ||
| 367 | struct pcie_pme_service_data *data) | ||
| 368 | { | ||
| 369 | spin_lock_irq(&data->lock); | ||
| 370 | pcie_pme_interrupt_enable(port, false); | ||
| 371 | pcie_clear_root_pme_status(port); | ||
| 372 | data->noirq = true; | ||
| 373 | spin_unlock_irq(&data->lock); | ||
| 374 | } | ||
| 375 | |||
| 366 | /** | 376 | /** |
| 367 | * pcie_pme_suspend - Suspend PCIe PME service device. | 377 | * pcie_pme_suspend - Suspend PCIe PME service device. |
| 368 | * @srv: PCIe service device to suspend. | 378 | * @srv: PCIe service device to suspend. |
| @@ -387,11 +397,7 @@ static int pcie_pme_suspend(struct pcie_device *srv) | |||
| 387 | return 0; | 397 | return 0; |
| 388 | } | 398 | } |
| 389 | 399 | ||
| 390 | spin_lock_irq(&data->lock); | 400 | pcie_pme_disable_interrupt(port, data); |
| 391 | pcie_pme_interrupt_enable(port, false); | ||
| 392 | pcie_clear_root_pme_status(port); | ||
| 393 | data->noirq = true; | ||
| 394 | spin_unlock_irq(&data->lock); | ||
| 395 | 401 | ||
| 396 | synchronize_irq(srv->irq); | 402 | synchronize_irq(srv->irq); |
| 397 | 403 | ||
| @@ -427,34 +433,12 @@ static int pcie_pme_resume(struct pcie_device *srv) | |||
| 427 | */ | 433 | */ |
| 428 | static void pcie_pme_remove(struct pcie_device *srv) | 434 | static void pcie_pme_remove(struct pcie_device *srv) |
| 429 | { | 435 | { |
| 430 | pcie_pme_suspend(srv); | ||
| 431 | free_irq(srv->irq, srv); | ||
| 432 | kfree(get_service_data(srv)); | ||
| 433 | } | ||
| 434 | |||
| 435 | static int pcie_pme_runtime_suspend(struct pcie_device *srv) | ||
| 436 | { | ||
| 437 | struct pcie_pme_service_data *data = get_service_data(srv); | ||
| 438 | |||
| 439 | spin_lock_irq(&data->lock); | ||
| 440 | pcie_pme_interrupt_enable(srv->port, false); | ||
| 441 | pcie_clear_root_pme_status(srv->port); | ||
| 442 | data->noirq = true; | ||
| 443 | spin_unlock_irq(&data->lock); | ||
| 444 | |||
| 445 | return 0; | ||
| 446 | } | ||
| 447 | |||
| 448 | static int pcie_pme_runtime_resume(struct pcie_device *srv) | ||
| 449 | { | ||
| 450 | struct pcie_pme_service_data *data = get_service_data(srv); | 436 | struct pcie_pme_service_data *data = get_service_data(srv); |
| 451 | 437 | ||
| 452 | spin_lock_irq(&data->lock); | 438 | pcie_pme_disable_interrupt(srv->port, data); |
| 453 | pcie_pme_interrupt_enable(srv->port, true); | 439 | free_irq(srv->irq, srv); |
| 454 | data->noirq = false; | 440 | cancel_work_sync(&data->work); |
| 455 | spin_unlock_irq(&data->lock); | 441 | kfree(data); |
| 456 | |||
| 457 | return 0; | ||
| 458 | } | 442 | } |
| 459 | 443 | ||
| 460 | static struct pcie_port_service_driver pcie_pme_driver = { | 444 | static struct pcie_port_service_driver pcie_pme_driver = { |
| @@ -464,8 +448,6 @@ static struct pcie_port_service_driver pcie_pme_driver = { | |||
| 464 | 448 | ||
| 465 | .probe = pcie_pme_probe, | 449 | .probe = pcie_pme_probe, |
| 466 | .suspend = pcie_pme_suspend, | 450 | .suspend = pcie_pme_suspend, |
| 467 | .runtime_suspend = pcie_pme_runtime_suspend, | ||
| 468 | .runtime_resume = pcie_pme_runtime_resume, | ||
| 469 | .resume = pcie_pme_resume, | 451 | .resume = pcie_pme_resume, |
| 470 | .remove = pcie_pme_remove, | 452 | .remove = pcie_pme_remove, |
| 471 | }; | 453 | }; |
diff --git a/drivers/pci/pcie/portdrv.h b/drivers/pci/pcie/portdrv.h index fbbf00b0992e..1d50dc58ac40 100644 --- a/drivers/pci/pcie/portdrv.h +++ b/drivers/pci/pcie/portdrv.h | |||
| @@ -20,8 +20,10 @@ | |||
| 20 | #define PCIE_PORT_SERVICE_HP (1 << PCIE_PORT_SERVICE_HP_SHIFT) | 20 | #define PCIE_PORT_SERVICE_HP (1 << PCIE_PORT_SERVICE_HP_SHIFT) |
| 21 | #define PCIE_PORT_SERVICE_DPC_SHIFT 3 /* Downstream Port Containment */ | 21 | #define PCIE_PORT_SERVICE_DPC_SHIFT 3 /* Downstream Port Containment */ |
| 22 | #define PCIE_PORT_SERVICE_DPC (1 << PCIE_PORT_SERVICE_DPC_SHIFT) | 22 | #define PCIE_PORT_SERVICE_DPC (1 << PCIE_PORT_SERVICE_DPC_SHIFT) |
| 23 | #define PCIE_PORT_SERVICE_BWNOTIF_SHIFT 4 /* Bandwidth notification */ | ||
| 24 | #define PCIE_PORT_SERVICE_BWNOTIF (1 << PCIE_PORT_SERVICE_BWNOTIF_SHIFT) | ||
| 23 | 25 | ||
| 24 | #define PCIE_PORT_DEVICE_MAXSERVICES 4 | 26 | #define PCIE_PORT_DEVICE_MAXSERVICES 5 |
| 25 | 27 | ||
| 26 | #ifdef CONFIG_PCIEAER | 28 | #ifdef CONFIG_PCIEAER |
| 27 | int pcie_aer_init(void); | 29 | int pcie_aer_init(void); |
| @@ -47,6 +49,8 @@ int pcie_dpc_init(void); | |||
| 47 | static inline int pcie_dpc_init(void) { return 0; } | 49 | static inline int pcie_dpc_init(void) { return 0; } |
| 48 | #endif | 50 | #endif |
| 49 | 51 | ||
| 52 | int pcie_bandwidth_notification_init(void); | ||
| 53 | |||
| 50 | /* Port Type */ | 54 | /* Port Type */ |
| 51 | #define PCIE_ANY_PORT (~0) | 55 | #define PCIE_ANY_PORT (~0) |
| 52 | 56 | ||
diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c index f458ac9cb70c..7d04f9d087a6 100644 --- a/drivers/pci/pcie/portdrv_core.c +++ b/drivers/pci/pcie/portdrv_core.c | |||
| @@ -99,7 +99,7 @@ static int pcie_message_numbers(struct pci_dev *dev, int mask, | |||
| 99 | */ | 99 | */ |
| 100 | static int pcie_port_enable_irq_vec(struct pci_dev *dev, int *irqs, int mask) | 100 | static int pcie_port_enable_irq_vec(struct pci_dev *dev, int *irqs, int mask) |
| 101 | { | 101 | { |
| 102 | int nr_entries, nvec; | 102 | int nr_entries, nvec, pcie_irq; |
| 103 | u32 pme = 0, aer = 0, dpc = 0; | 103 | u32 pme = 0, aer = 0, dpc = 0; |
| 104 | 104 | ||
| 105 | /* Allocate the maximum possible number of MSI/MSI-X vectors */ | 105 | /* Allocate the maximum possible number of MSI/MSI-X vectors */ |
| @@ -135,10 +135,13 @@ static int pcie_port_enable_irq_vec(struct pci_dev *dev, int *irqs, int mask) | |||
| 135 | return nr_entries; | 135 | return nr_entries; |
| 136 | } | 136 | } |
| 137 | 137 | ||
| 138 | /* PME and hotplug share an MSI/MSI-X vector */ | 138 | /* PME, hotplug and bandwidth notification share an MSI/MSI-X vector */ |
| 139 | if (mask & (PCIE_PORT_SERVICE_PME | PCIE_PORT_SERVICE_HP)) { | 139 | if (mask & (PCIE_PORT_SERVICE_PME | PCIE_PORT_SERVICE_HP | |
| 140 | irqs[PCIE_PORT_SERVICE_PME_SHIFT] = pci_irq_vector(dev, pme); | 140 | PCIE_PORT_SERVICE_BWNOTIF)) { |
| 141 | irqs[PCIE_PORT_SERVICE_HP_SHIFT] = pci_irq_vector(dev, pme); | 141 | pcie_irq = pci_irq_vector(dev, pme); |
| 142 | irqs[PCIE_PORT_SERVICE_PME_SHIFT] = pcie_irq; | ||
| 143 | irqs[PCIE_PORT_SERVICE_HP_SHIFT] = pcie_irq; | ||
| 144 | irqs[PCIE_PORT_SERVICE_BWNOTIF_SHIFT] = pcie_irq; | ||
| 142 | } | 145 | } |
| 143 | 146 | ||
| 144 | if (mask & PCIE_PORT_SERVICE_AER) | 147 | if (mask & PCIE_PORT_SERVICE_AER) |
| @@ -250,6 +253,10 @@ static int get_port_device_capability(struct pci_dev *dev) | |||
| 250 | pci_aer_available() && services & PCIE_PORT_SERVICE_AER) | 253 | pci_aer_available() && services & PCIE_PORT_SERVICE_AER) |
| 251 | services |= PCIE_PORT_SERVICE_DPC; | 254 | services |= PCIE_PORT_SERVICE_DPC; |
| 252 | 255 | ||
| 256 | if (pci_pcie_type(dev) == PCI_EXP_TYPE_DOWNSTREAM || | ||
| 257 | pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT) | ||
| 258 | services |= PCIE_PORT_SERVICE_BWNOTIF; | ||
| 259 | |||
| 253 | return services; | 260 | return services; |
| 254 | } | 261 | } |
| 255 | 262 | ||
diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c index 0acca3596807..0a87091a0800 100644 --- a/drivers/pci/pcie/portdrv_pci.c +++ b/drivers/pci/pcie/portdrv_pci.c | |||
| @@ -182,10 +182,12 @@ static void pcie_portdrv_err_resume(struct pci_dev *dev) | |||
| 182 | /* | 182 | /* |
| 183 | * LINUX Device Driver Model | 183 | * LINUX Device Driver Model |
| 184 | */ | 184 | */ |
| 185 | static const struct pci_device_id port_pci_ids[] = { { | 185 | static const struct pci_device_id port_pci_ids[] = { |
| 186 | /* handle any PCI-Express port */ | 186 | /* handle any PCI-Express port */ |
| 187 | PCI_DEVICE_CLASS(((PCI_CLASS_BRIDGE_PCI << 8) | 0x00), ~0), | 187 | { PCI_DEVICE_CLASS(((PCI_CLASS_BRIDGE_PCI << 8) | 0x00), ~0) }, |
| 188 | }, { /* end: all zeroes */ } | 188 | /* subtractive decode PCI-to-PCI bridge, class type is 060401h */ |
| 189 | { PCI_DEVICE_CLASS(((PCI_CLASS_BRIDGE_PCI << 8) | 0x01), ~0) }, | ||
| 190 | { }, | ||
| 189 | }; | 191 | }; |
| 190 | 192 | ||
| 191 | static const struct pci_error_handlers pcie_portdrv_err_handler = { | 193 | static const struct pci_error_handlers pcie_portdrv_err_handler = { |
| @@ -238,6 +240,7 @@ static void __init pcie_init_services(void) | |||
| 238 | pcie_pme_init(); | 240 | pcie_pme_init(); |
| 239 | pcie_dpc_init(); | 241 | pcie_dpc_init(); |
| 240 | pcie_hp_init(); | 242 | pcie_hp_init(); |
| 243 | pcie_bandwidth_notification_init(); | ||
| 241 | } | 244 | } |
| 242 | 245 | ||
| 243 | static int __init pcie_portdrv_init(void) | 246 | static int __init pcie_portdrv_init(void) |
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 257b9f6f2ebb..2ec0df04e0dc 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c | |||
| @@ -121,13 +121,13 @@ static u64 pci_size(u64 base, u64 maxbase, u64 mask) | |||
| 121 | * Get the lowest of them to find the decode size, and from that | 121 | * Get the lowest of them to find the decode size, and from that |
| 122 | * the extent. | 122 | * the extent. |
| 123 | */ | 123 | */ |
| 124 | size = (size & ~(size-1)) - 1; | 124 | size = size & ~(size-1); |
| 125 | 125 | ||
| 126 | /* | 126 | /* |
| 127 | * base == maxbase can be valid only if the BAR has already been | 127 | * base == maxbase can be valid only if the BAR has already been |
| 128 | * programmed with all 1s. | 128 | * programmed with all 1s. |
| 129 | */ | 129 | */ |
| 130 | if (base == maxbase && ((base | size) & mask) != mask) | 130 | if (base == maxbase && ((base | (size - 1)) & mask) != mask) |
| 131 | return 0; | 131 | return 0; |
| 132 | 132 | ||
| 133 | return size; | 133 | return size; |
| @@ -278,7 +278,7 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, | |||
| 278 | /* Above 32-bit boundary; try to reallocate */ | 278 | /* Above 32-bit boundary; try to reallocate */ |
| 279 | res->flags |= IORESOURCE_UNSET; | 279 | res->flags |= IORESOURCE_UNSET; |
| 280 | res->start = 0; | 280 | res->start = 0; |
| 281 | res->end = sz64; | 281 | res->end = sz64 - 1; |
| 282 | pci_info(dev, "reg 0x%x: can't handle BAR above 4GB (bus address %#010llx)\n", | 282 | pci_info(dev, "reg 0x%x: can't handle BAR above 4GB (bus address %#010llx)\n", |
| 283 | pos, (unsigned long long)l64); | 283 | pos, (unsigned long long)l64); |
| 284 | goto out; | 284 | goto out; |
| @@ -286,7 +286,7 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, | |||
| 286 | } | 286 | } |
| 287 | 287 | ||
| 288 | region.start = l64; | 288 | region.start = l64; |
| 289 | region.end = l64 + sz64; | 289 | region.end = l64 + sz64 - 1; |
| 290 | 290 | ||
| 291 | pcibios_bus_to_resource(dev->bus, res, ®ion); | 291 | pcibios_bus_to_resource(dev->bus, res, ®ion); |
| 292 | pcibios_resource_to_bus(dev->bus, &inverted_region, res); | 292 | pcibios_resource_to_bus(dev->bus, &inverted_region, res); |
| @@ -348,6 +348,57 @@ static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom) | |||
| 348 | } | 348 | } |
| 349 | } | 349 | } |
| 350 | 350 | ||
| 351 | static void pci_read_bridge_windows(struct pci_dev *bridge) | ||
| 352 | { | ||
| 353 | u16 io; | ||
| 354 | u32 pmem, tmp; | ||
| 355 | |||
| 356 | pci_read_config_word(bridge, PCI_IO_BASE, &io); | ||
| 357 | if (!io) { | ||
| 358 | pci_write_config_word(bridge, PCI_IO_BASE, 0xe0f0); | ||
| 359 | pci_read_config_word(bridge, PCI_IO_BASE, &io); | ||
| 360 | pci_write_config_word(bridge, PCI_IO_BASE, 0x0); | ||
| 361 | } | ||
| 362 | if (io) | ||
| 363 | bridge->io_window = 1; | ||
| 364 | |||
| 365 | /* | ||
| 366 | * DECchip 21050 pass 2 errata: the bridge may miss an address | ||
| 367 | * disconnect boundary by one PCI data phase. Workaround: do not | ||
| 368 | * use prefetching on this device. | ||
| 369 | */ | ||
| 370 | if (bridge->vendor == PCI_VENDOR_ID_DEC && bridge->device == 0x0001) | ||
| 371 | return; | ||
| 372 | |||
| 373 | pci_read_config_dword(bridge, PCI_PREF_MEMORY_BASE, &pmem); | ||
| 374 | if (!pmem) { | ||
| 375 | pci_write_config_dword(bridge, PCI_PREF_MEMORY_BASE, | ||
| 376 | 0xffe0fff0); | ||
| 377 | pci_read_config_dword(bridge, PCI_PREF_MEMORY_BASE, &pmem); | ||
| 378 | pci_write_config_dword(bridge, PCI_PREF_MEMORY_BASE, 0x0); | ||
| 379 | } | ||
| 380 | if (!pmem) | ||
| 381 | return; | ||
| 382 | |||
| 383 | bridge->pref_window = 1; | ||
| 384 | |||
| 385 | if ((pmem & PCI_PREF_RANGE_TYPE_MASK) == PCI_PREF_RANGE_TYPE_64) { | ||
| 386 | |||
| 387 | /* | ||
| 388 | * Bridge claims to have a 64-bit prefetchable memory | ||
| 389 | * window; verify that the upper bits are actually | ||
| 390 | * writable. | ||
| 391 | */ | ||
| 392 | pci_read_config_dword(bridge, PCI_PREF_BASE_UPPER32, &pmem); | ||
| 393 | pci_write_config_dword(bridge, PCI_PREF_BASE_UPPER32, | ||
| 394 | 0xffffffff); | ||
| 395 | pci_read_config_dword(bridge, PCI_PREF_BASE_UPPER32, &tmp); | ||
| 396 | pci_write_config_dword(bridge, PCI_PREF_BASE_UPPER32, pmem); | ||
| 397 | if (tmp) | ||
| 398 | bridge->pref_64_window = 1; | ||
| 399 | } | ||
| 400 | } | ||
| 401 | |||
| 351 | static void pci_read_bridge_io(struct pci_bus *child) | 402 | static void pci_read_bridge_io(struct pci_bus *child) |
| 352 | { | 403 | { |
| 353 | struct pci_dev *dev = child->self; | 404 | struct pci_dev *dev = child->self; |
| @@ -1728,9 +1779,6 @@ int pci_setup_device(struct pci_dev *dev) | |||
| 1728 | break; | 1779 | break; |
| 1729 | 1780 | ||
| 1730 | case PCI_HEADER_TYPE_BRIDGE: /* bridge header */ | 1781 | case PCI_HEADER_TYPE_BRIDGE: /* bridge header */ |
| 1731 | if (class != PCI_CLASS_BRIDGE_PCI) | ||
| 1732 | goto bad; | ||
| 1733 | |||
| 1734 | /* | 1782 | /* |
| 1735 | * The PCI-to-PCI bridge spec requires that subtractive | 1783 | * The PCI-to-PCI bridge spec requires that subtractive |
| 1736 | * decoding (i.e. transparent) bridge must have programming | 1784 | * decoding (i.e. transparent) bridge must have programming |
| @@ -1739,6 +1787,7 @@ int pci_setup_device(struct pci_dev *dev) | |||
| 1739 | pci_read_irq(dev); | 1787 | pci_read_irq(dev); |
| 1740 | dev->transparent = ((dev->class & 0xff) == 1); | 1788 | dev->transparent = ((dev->class & 0xff) == 1); |
| 1741 | pci_read_bases(dev, 2, PCI_ROM_ADDRESS1); | 1789 | pci_read_bases(dev, 2, PCI_ROM_ADDRESS1); |
| 1790 | pci_read_bridge_windows(dev); | ||
| 1742 | set_pcie_hotplug_bridge(dev); | 1791 | set_pcie_hotplug_bridge(dev); |
| 1743 | pos = pci_find_capability(dev, PCI_CAP_ID_SSVID); | 1792 | pos = pci_find_capability(dev, PCI_CAP_ID_SSVID); |
| 1744 | if (pos) { | 1793 | if (pos) { |
| @@ -1856,8 +1905,6 @@ static void program_hpp_type0(struct pci_dev *dev, struct hpp_type0 *hpp) | |||
| 1856 | pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER, | 1905 | pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER, |
| 1857 | hpp->latency_timer); | 1906 | hpp->latency_timer); |
| 1858 | pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &pci_bctl); | 1907 | pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &pci_bctl); |
| 1859 | if (hpp->enable_serr) | ||
| 1860 | pci_bctl |= PCI_BRIDGE_CTL_SERR; | ||
| 1861 | if (hpp->enable_perr) | 1908 | if (hpp->enable_perr) |
| 1862 | pci_bctl |= PCI_BRIDGE_CTL_PARITY; | 1909 | pci_bctl |= PCI_BRIDGE_CTL_PARITY; |
| 1863 | pci_write_config_word(dev, PCI_BRIDGE_CONTROL, pci_bctl); | 1910 | pci_write_config_word(dev, PCI_BRIDGE_CONTROL, pci_bctl); |
| @@ -2071,11 +2118,8 @@ static void pci_configure_ltr(struct pci_dev *dev) | |||
| 2071 | { | 2118 | { |
| 2072 | #ifdef CONFIG_PCIEASPM | 2119 | #ifdef CONFIG_PCIEASPM |
| 2073 | struct pci_host_bridge *host = pci_find_host_bridge(dev->bus); | 2120 | struct pci_host_bridge *host = pci_find_host_bridge(dev->bus); |
| 2074 | u32 cap; | ||
| 2075 | struct pci_dev *bridge; | 2121 | struct pci_dev *bridge; |
| 2076 | 2122 | u32 cap, ctl; | |
| 2077 | if (!host->native_ltr) | ||
| 2078 | return; | ||
| 2079 | 2123 | ||
| 2080 | if (!pci_is_pcie(dev)) | 2124 | if (!pci_is_pcie(dev)) |
| 2081 | return; | 2125 | return; |
| @@ -2084,22 +2128,35 @@ static void pci_configure_ltr(struct pci_dev *dev) | |||
| 2084 | if (!(cap & PCI_EXP_DEVCAP2_LTR)) | 2128 | if (!(cap & PCI_EXP_DEVCAP2_LTR)) |
| 2085 | return; | 2129 | return; |
| 2086 | 2130 | ||
| 2087 | /* | 2131 | pcie_capability_read_dword(dev, PCI_EXP_DEVCTL2, &ctl); |
| 2088 | * Software must not enable LTR in an Endpoint unless the Root | 2132 | if (ctl & PCI_EXP_DEVCTL2_LTR_EN) { |
| 2089 | * Complex and all intermediate Switches indicate support for LTR. | 2133 | if (pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT) { |
| 2090 | * PCIe r3.1, sec 6.18. | 2134 | dev->ltr_path = 1; |
| 2091 | */ | 2135 | return; |
| 2092 | if (pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT) | 2136 | } |
| 2093 | dev->ltr_path = 1; | 2137 | |
| 2094 | else { | ||
| 2095 | bridge = pci_upstream_bridge(dev); | 2138 | bridge = pci_upstream_bridge(dev); |
| 2096 | if (bridge && bridge->ltr_path) | 2139 | if (bridge && bridge->ltr_path) |
| 2097 | dev->ltr_path = 1; | 2140 | dev->ltr_path = 1; |
| 2141 | |||
| 2142 | return; | ||
| 2098 | } | 2143 | } |
| 2099 | 2144 | ||
| 2100 | if (dev->ltr_path) | 2145 | if (!host->native_ltr) |
| 2146 | return; | ||
| 2147 | |||
| 2148 | /* | ||
| 2149 | * Software must not enable LTR in an Endpoint unless the Root | ||
| 2150 | * Complex and all intermediate Switches indicate support for LTR. | ||
| 2151 | * PCIe r4.0, sec 6.18. | ||
| 2152 | */ | ||
| 2153 | if (pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT || | ||
| 2154 | ((bridge = pci_upstream_bridge(dev)) && | ||
| 2155 | bridge->ltr_path)) { | ||
| 2101 | pcie_capability_set_word(dev, PCI_EXP_DEVCTL2, | 2156 | pcie_capability_set_word(dev, PCI_EXP_DEVCTL2, |
| 2102 | PCI_EXP_DEVCTL2_LTR_EN); | 2157 | PCI_EXP_DEVCTL2_LTR_EN); |
| 2158 | dev->ltr_path = 1; | ||
| 2159 | } | ||
| 2103 | #endif | 2160 | #endif |
| 2104 | } | 2161 | } |
| 2105 | 2162 | ||
| @@ -2129,6 +2186,24 @@ static void pci_configure_eetlp_prefix(struct pci_dev *dev) | |||
| 2129 | #endif | 2186 | #endif |
| 2130 | } | 2187 | } |
| 2131 | 2188 | ||
| 2189 | static void pci_configure_serr(struct pci_dev *dev) | ||
| 2190 | { | ||
| 2191 | u16 control; | ||
| 2192 | |||
| 2193 | if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) { | ||
| 2194 | |||
| 2195 | /* | ||
| 2196 | * A bridge will not forward ERR_ messages coming from an | ||
| 2197 | * endpoint unless SERR# forwarding is enabled. | ||
| 2198 | */ | ||
| 2199 | pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &control); | ||
| 2200 | if (!(control & PCI_BRIDGE_CTL_SERR)) { | ||
| 2201 | control |= PCI_BRIDGE_CTL_SERR; | ||
| 2202 | pci_write_config_word(dev, PCI_BRIDGE_CONTROL, control); | ||
| 2203 | } | ||
| 2204 | } | ||
| 2205 | } | ||
| 2206 | |||
| 2132 | static void pci_configure_device(struct pci_dev *dev) | 2207 | static void pci_configure_device(struct pci_dev *dev) |
| 2133 | { | 2208 | { |
| 2134 | struct hotplug_params hpp; | 2209 | struct hotplug_params hpp; |
| @@ -2139,6 +2214,7 @@ static void pci_configure_device(struct pci_dev *dev) | |||
| 2139 | pci_configure_relaxed_ordering(dev); | 2214 | pci_configure_relaxed_ordering(dev); |
| 2140 | pci_configure_ltr(dev); | 2215 | pci_configure_ltr(dev); |
| 2141 | pci_configure_eetlp_prefix(dev); | 2216 | pci_configure_eetlp_prefix(dev); |
| 2217 | pci_configure_serr(dev); | ||
| 2142 | 2218 | ||
| 2143 | memset(&hpp, 0, sizeof(hpp)); | 2219 | memset(&hpp, 0, sizeof(hpp)); |
| 2144 | ret = pci_get_hp_params(dev, &hpp); | 2220 | ret = pci_get_hp_params(dev, &hpp); |
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index e2a879e93d86..a59ad09ce911 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
| @@ -2139,7 +2139,7 @@ static void quirk_netmos(struct pci_dev *dev) | |||
| 2139 | if (dev->subsystem_vendor == PCI_VENDOR_ID_IBM && | 2139 | if (dev->subsystem_vendor == PCI_VENDOR_ID_IBM && |
| 2140 | dev->subsystem_device == 0x0299) | 2140 | dev->subsystem_device == 0x0299) |
| 2141 | return; | 2141 | return; |
| 2142 | /* else: fall through */ | 2142 | /* else, fall through */ |
| 2143 | case PCI_DEVICE_ID_NETMOS_9735: | 2143 | case PCI_DEVICE_ID_NETMOS_9735: |
| 2144 | case PCI_DEVICE_ID_NETMOS_9745: | 2144 | case PCI_DEVICE_ID_NETMOS_9745: |
| 2145 | case PCI_DEVICE_ID_NETMOS_9845: | 2145 | case PCI_DEVICE_ID_NETMOS_9845: |
| @@ -4520,6 +4520,8 @@ static const struct pci_dev_acs_enabled { | |||
| 4520 | /* QCOM QDF2xxx root ports */ | 4520 | /* QCOM QDF2xxx root ports */ |
| 4521 | { PCI_VENDOR_ID_QCOM, 0x0400, pci_quirk_qcom_rp_acs }, | 4521 | { PCI_VENDOR_ID_QCOM, 0x0400, pci_quirk_qcom_rp_acs }, |
| 4522 | { PCI_VENDOR_ID_QCOM, 0x0401, pci_quirk_qcom_rp_acs }, | 4522 | { PCI_VENDOR_ID_QCOM, 0x0401, pci_quirk_qcom_rp_acs }, |
| 4523 | /* HXT SD4800 root ports. The ACS design is same as QCOM QDF2xxx */ | ||
| 4524 | { PCI_VENDOR_ID_HXT, 0x0401, pci_quirk_qcom_rp_acs }, | ||
| 4523 | /* Intel PCH root ports */ | 4525 | /* Intel PCH root ports */ |
| 4524 | { PCI_VENDOR_ID_INTEL, PCI_ANY_ID, pci_quirk_intel_pch_acs }, | 4526 | { PCI_VENDOR_ID_INTEL, PCI_ANY_ID, pci_quirk_intel_pch_acs }, |
| 4525 | { PCI_VENDOR_ID_INTEL, PCI_ANY_ID, pci_quirk_intel_spt_pch_acs }, | 4527 | { PCI_VENDOR_ID_INTEL, PCI_ANY_ID, pci_quirk_intel_spt_pch_acs }, |
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index ed960436df5e..ec44a0f3a7ac 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c | |||
| @@ -735,58 +735,21 @@ int pci_claim_bridge_resource(struct pci_dev *bridge, int i) | |||
| 735 | base/limit registers must be read-only and read as 0. */ | 735 | base/limit registers must be read-only and read as 0. */ |
| 736 | static void pci_bridge_check_ranges(struct pci_bus *bus) | 736 | static void pci_bridge_check_ranges(struct pci_bus *bus) |
| 737 | { | 737 | { |
| 738 | u16 io; | ||
| 739 | u32 pmem; | ||
| 740 | struct pci_dev *bridge = bus->self; | 738 | struct pci_dev *bridge = bus->self; |
| 741 | struct resource *b_res; | 739 | struct resource *b_res = &bridge->resource[PCI_BRIDGE_RESOURCES]; |
| 742 | 740 | ||
| 743 | b_res = &bridge->resource[PCI_BRIDGE_RESOURCES]; | ||
| 744 | b_res[1].flags |= IORESOURCE_MEM; | 741 | b_res[1].flags |= IORESOURCE_MEM; |
| 745 | 742 | ||
| 746 | pci_read_config_word(bridge, PCI_IO_BASE, &io); | 743 | if (bridge->io_window) |
| 747 | if (!io) { | ||
| 748 | pci_write_config_word(bridge, PCI_IO_BASE, 0xe0f0); | ||
| 749 | pci_read_config_word(bridge, PCI_IO_BASE, &io); | ||
| 750 | pci_write_config_word(bridge, PCI_IO_BASE, 0x0); | ||
| 751 | } | ||
| 752 | if (io) | ||
| 753 | b_res[0].flags |= IORESOURCE_IO; | 744 | b_res[0].flags |= IORESOURCE_IO; |
| 754 | 745 | ||
| 755 | /* DECchip 21050 pass 2 errata: the bridge may miss an address | 746 | if (bridge->pref_window) { |
| 756 | disconnect boundary by one PCI data phase. | ||
| 757 | Workaround: do not use prefetching on this device. */ | ||
| 758 | if (bridge->vendor == PCI_VENDOR_ID_DEC && bridge->device == 0x0001) | ||
| 759 | return; | ||
| 760 | |||
| 761 | pci_read_config_dword(bridge, PCI_PREF_MEMORY_BASE, &pmem); | ||
| 762 | if (!pmem) { | ||
| 763 | pci_write_config_dword(bridge, PCI_PREF_MEMORY_BASE, | ||
| 764 | 0xffe0fff0); | ||
| 765 | pci_read_config_dword(bridge, PCI_PREF_MEMORY_BASE, &pmem); | ||
| 766 | pci_write_config_dword(bridge, PCI_PREF_MEMORY_BASE, 0x0); | ||
| 767 | } | ||
| 768 | if (pmem) { | ||
| 769 | b_res[2].flags |= IORESOURCE_MEM | IORESOURCE_PREFETCH; | 747 | b_res[2].flags |= IORESOURCE_MEM | IORESOURCE_PREFETCH; |
| 770 | if ((pmem & PCI_PREF_RANGE_TYPE_MASK) == | 748 | if (bridge->pref_64_window) { |
| 771 | PCI_PREF_RANGE_TYPE_64) { | ||
| 772 | b_res[2].flags |= IORESOURCE_MEM_64; | 749 | b_res[2].flags |= IORESOURCE_MEM_64; |
| 773 | b_res[2].flags |= PCI_PREF_RANGE_TYPE_64; | 750 | b_res[2].flags |= PCI_PREF_RANGE_TYPE_64; |
| 774 | } | 751 | } |
| 775 | } | 752 | } |
| 776 | |||
| 777 | /* double check if bridge does support 64 bit pref */ | ||
| 778 | if (b_res[2].flags & IORESOURCE_MEM_64) { | ||
| 779 | u32 mem_base_hi, tmp; | ||
| 780 | pci_read_config_dword(bridge, PCI_PREF_BASE_UPPER32, | ||
| 781 | &mem_base_hi); | ||
| 782 | pci_write_config_dword(bridge, PCI_PREF_BASE_UPPER32, | ||
| 783 | 0xffffffff); | ||
| 784 | pci_read_config_dword(bridge, PCI_PREF_BASE_UPPER32, &tmp); | ||
| 785 | if (!tmp) | ||
| 786 | b_res[2].flags &= ~IORESOURCE_MEM_64; | ||
| 787 | pci_write_config_dword(bridge, PCI_PREF_BASE_UPPER32, | ||
| 788 | mem_base_hi); | ||
| 789 | } | ||
| 790 | } | 753 | } |
| 791 | 754 | ||
| 792 | /* Helper function for sizing routines: find first available | 755 | /* Helper function for sizing routines: find first available |
| @@ -1223,12 +1186,12 @@ void __pci_bus_size_bridges(struct pci_bus *bus, struct list_head *realloc_head) | |||
| 1223 | if (!b) | 1186 | if (!b) |
| 1224 | continue; | 1187 | continue; |
| 1225 | 1188 | ||
| 1226 | switch (dev->class >> 8) { | 1189 | switch (dev->hdr_type) { |
| 1227 | case PCI_CLASS_BRIDGE_CARDBUS: | 1190 | case PCI_HEADER_TYPE_CARDBUS: |
| 1228 | pci_bus_size_cardbus(b, realloc_head); | 1191 | pci_bus_size_cardbus(b, realloc_head); |
| 1229 | break; | 1192 | break; |
| 1230 | 1193 | ||
| 1231 | case PCI_CLASS_BRIDGE_PCI: | 1194 | case PCI_HEADER_TYPE_BRIDGE: |
| 1232 | default: | 1195 | default: |
| 1233 | __pci_bus_size_bridges(b, realloc_head); | 1196 | __pci_bus_size_bridges(b, realloc_head); |
| 1234 | break; | 1197 | break; |
| @@ -1239,12 +1202,12 @@ void __pci_bus_size_bridges(struct pci_bus *bus, struct list_head *realloc_head) | |||
| 1239 | if (pci_is_root_bus(bus)) | 1202 | if (pci_is_root_bus(bus)) |
| 1240 | return; | 1203 | return; |
| 1241 | 1204 | ||
| 1242 | switch (bus->self->class >> 8) { | 1205 | switch (bus->self->hdr_type) { |
| 1243 | case PCI_CLASS_BRIDGE_CARDBUS: | 1206 | case PCI_HEADER_TYPE_CARDBUS: |
| 1244 | /* don't size cardbuses yet. */ | 1207 | /* don't size cardbuses yet. */ |
| 1245 | break; | 1208 | break; |
| 1246 | 1209 | ||
| 1247 | case PCI_CLASS_BRIDGE_PCI: | 1210 | case PCI_HEADER_TYPE_BRIDGE: |
| 1248 | pci_bridge_check_ranges(bus); | 1211 | pci_bridge_check_ranges(bus); |
| 1249 | if (bus->self->is_hotplug_bridge) { | 1212 | if (bus->self->is_hotplug_bridge) { |
| 1250 | additional_io_size = pci_hotplug_io_size; | 1213 | additional_io_size = pci_hotplug_io_size; |
| @@ -1393,13 +1356,13 @@ void __pci_bus_assign_resources(const struct pci_bus *bus, | |||
| 1393 | 1356 | ||
| 1394 | __pci_bus_assign_resources(b, realloc_head, fail_head); | 1357 | __pci_bus_assign_resources(b, realloc_head, fail_head); |
| 1395 | 1358 | ||
| 1396 | switch (dev->class >> 8) { | 1359 | switch (dev->hdr_type) { |
| 1397 | case PCI_CLASS_BRIDGE_PCI: | 1360 | case PCI_HEADER_TYPE_BRIDGE: |
| 1398 | if (!pci_is_enabled(dev)) | 1361 | if (!pci_is_enabled(dev)) |
| 1399 | pci_setup_bridge(b); | 1362 | pci_setup_bridge(b); |
| 1400 | break; | 1363 | break; |
| 1401 | 1364 | ||
| 1402 | case PCI_CLASS_BRIDGE_CARDBUS: | 1365 | case PCI_HEADER_TYPE_CARDBUS: |
| 1403 | pci_setup_cardbus(b); | 1366 | pci_setup_cardbus(b); |
| 1404 | break; | 1367 | break; |
| 1405 | 1368 | ||
diff --git a/drivers/spi/spi-topcliff-pch.c b/drivers/spi/spi-topcliff-pch.c index e7e8ea1edcce..fba3f180f233 100644 --- a/drivers/spi/spi-topcliff-pch.c +++ b/drivers/spi/spi-topcliff-pch.c | |||
| @@ -92,7 +92,6 @@ | |||
| 92 | #define PCH_MAX_SPBR 1023 | 92 | #define PCH_MAX_SPBR 1023 |
| 93 | 93 | ||
| 94 | /* Definition for ML7213/ML7223/ML7831 by LAPIS Semiconductor */ | 94 | /* Definition for ML7213/ML7223/ML7831 by LAPIS Semiconductor */ |
| 95 | #define PCI_VENDOR_ID_ROHM 0x10DB | ||
| 96 | #define PCI_DEVICE_ID_ML7213_SPI 0x802c | 95 | #define PCI_DEVICE_ID_ML7213_SPI 0x802c |
| 97 | #define PCI_DEVICE_ID_ML7223_SPI 0x800F | 96 | #define PCI_DEVICE_ID_ML7223_SPI 0x800F |
| 98 | #define PCI_DEVICE_ID_ML7831_SPI 0x8816 | 97 | #define PCI_DEVICE_ID_ML7831_SPI 0x8816 |
diff --git a/drivers/tty/serial/pch_uart.c b/drivers/tty/serial/pch_uart.c index 9ed121f08a54..6157213a8359 100644 --- a/drivers/tty/serial/pch_uart.c +++ b/drivers/tty/serial/pch_uart.c | |||
| @@ -192,8 +192,6 @@ enum { | |||
| 192 | #define PCH_UART_HAL_LOOP (PCH_UART_MCR_LOOP) | 192 | #define PCH_UART_HAL_LOOP (PCH_UART_MCR_LOOP) |
| 193 | #define PCH_UART_HAL_AFE (PCH_UART_MCR_AFE) | 193 | #define PCH_UART_HAL_AFE (PCH_UART_MCR_AFE) |
| 194 | 194 | ||
| 195 | #define PCI_VENDOR_ID_ROHM 0x10DB | ||
| 196 | |||
| 197 | #define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE) | 195 | #define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE) |
| 198 | 196 | ||
| 199 | #define DEFAULT_UARTCLK 1843200 /* 1.8432 MHz */ | 197 | #define DEFAULT_UARTCLK 1843200 /* 1.8432 MHz */ |
diff --git a/drivers/usb/gadget/udc/pch_udc.c b/drivers/usb/gadget/udc/pch_udc.c index 55c8c8abeacd..cded51f36fc1 100644 --- a/drivers/usb/gadget/udc/pch_udc.c +++ b/drivers/usb/gadget/udc/pch_udc.c | |||
| @@ -368,7 +368,6 @@ struct pch_udc_dev { | |||
| 368 | #define PCI_DEVICE_ID_INTEL_QUARK_X1000_UDC 0x0939 | 368 | #define PCI_DEVICE_ID_INTEL_QUARK_X1000_UDC 0x0939 |
| 369 | #define PCI_DEVICE_ID_INTEL_EG20T_UDC 0x8808 | 369 | #define PCI_DEVICE_ID_INTEL_EG20T_UDC 0x8808 |
| 370 | 370 | ||
| 371 | #define PCI_VENDOR_ID_ROHM 0x10DB | ||
| 372 | #define PCI_DEVICE_ID_ML7213_IOH_UDC 0x801D | 371 | #define PCI_DEVICE_ID_ML7213_IOH_UDC 0x801D |
| 373 | #define PCI_DEVICE_ID_ML7831_IOH_UDC 0x8808 | 372 | #define PCI_DEVICE_ID_ML7831_IOH_UDC 0x8808 |
| 374 | 373 | ||
diff --git a/include/linux/msi.h b/include/linux/msi.h index 784fb52b9900..7e9b81c3b50d 100644 --- a/include/linux/msi.h +++ b/include/linux/msi.h | |||
| @@ -83,12 +83,12 @@ struct msi_desc { | |||
| 83 | struct { | 83 | struct { |
| 84 | u32 masked; | 84 | u32 masked; |
| 85 | struct { | 85 | struct { |
| 86 | __u8 is_msix : 1; | 86 | u8 is_msix : 1; |
| 87 | __u8 multiple : 3; | 87 | u8 multiple : 3; |
| 88 | __u8 multi_cap : 3; | 88 | u8 multi_cap : 3; |
| 89 | __u8 maskbit : 1; | 89 | u8 maskbit : 1; |
| 90 | __u8 is_64 : 1; | 90 | u8 is_64 : 1; |
| 91 | __u16 entry_nr; | 91 | u16 entry_nr; |
| 92 | unsigned default_irq; | 92 | unsigned default_irq; |
| 93 | } msi_attrib; | 93 | } msi_attrib; |
| 94 | union { | 94 | union { |
diff --git a/include/linux/pci-epc.h b/include/linux/pci-epc.h index 37dab8116901..c3ffa3917f88 100644 --- a/include/linux/pci-epc.h +++ b/include/linux/pci-epc.h | |||
| @@ -59,6 +59,8 @@ struct pci_epc_ops { | |||
| 59 | enum pci_epc_irq_type type, u16 interrupt_num); | 59 | enum pci_epc_irq_type type, u16 interrupt_num); |
| 60 | int (*start)(struct pci_epc *epc); | 60 | int (*start)(struct pci_epc *epc); |
| 61 | void (*stop)(struct pci_epc *epc); | 61 | void (*stop)(struct pci_epc *epc); |
| 62 | const struct pci_epc_features* (*get_features)(struct pci_epc *epc, | ||
| 63 | u8 func_no); | ||
| 62 | struct module *owner; | 64 | struct module *owner; |
| 63 | }; | 65 | }; |
| 64 | 66 | ||
| @@ -97,16 +99,25 @@ struct pci_epc { | |||
| 97 | struct config_group *group; | 99 | struct config_group *group; |
| 98 | /* spinlock to protect against concurrent access of EP controller */ | 100 | /* spinlock to protect against concurrent access of EP controller */ |
| 99 | spinlock_t lock; | 101 | spinlock_t lock; |
| 100 | unsigned int features; | ||
| 101 | }; | 102 | }; |
| 102 | 103 | ||
| 103 | #define EPC_FEATURE_NO_LINKUP_NOTIFIER BIT(0) | 104 | /** |
| 104 | #define EPC_FEATURE_BAR_MASK (BIT(1) | BIT(2) | BIT(3)) | 105 | * struct pci_epc_features - features supported by a EPC device per function |
| 105 | #define EPC_FEATURE_MSIX_AVAILABLE BIT(4) | 106 | * @linkup_notifier: indicate if the EPC device can notify EPF driver on link up |
| 106 | #define EPC_FEATURE_SET_BAR(features, bar) \ | 107 | * @msi_capable: indicate if the endpoint function has MSI capability |
| 107 | (features |= (EPC_FEATURE_BAR_MASK & (bar << 1))) | 108 | * @msix_capable: indicate if the endpoint function has MSI-X capability |
| 108 | #define EPC_FEATURE_GET_BAR(features) \ | 109 | * @reserved_bar: bitmap to indicate reserved BAR unavailable to function driver |
| 109 | ((features & EPC_FEATURE_BAR_MASK) >> 1) | 110 | * @bar_fixed_64bit: bitmap to indicate fixed 64bit BARs |
| 111 | * @bar_fixed_size: Array specifying the size supported by each BAR | ||
| 112 | */ | ||
| 113 | struct pci_epc_features { | ||
| 114 | unsigned int linkup_notifier : 1; | ||
| 115 | unsigned int msi_capable : 1; | ||
| 116 | unsigned int msix_capable : 1; | ||
| 117 | u8 reserved_bar; | ||
| 118 | u8 bar_fixed_64bit; | ||
| 119 | u64 bar_fixed_size[BAR_5 + 1]; | ||
| 120 | }; | ||
| 110 | 121 | ||
| 111 | #define to_pci_epc(device) container_of((device), struct pci_epc, dev) | 122 | #define to_pci_epc(device) container_of((device), struct pci_epc, dev) |
| 112 | 123 | ||
| @@ -158,6 +169,10 @@ int pci_epc_raise_irq(struct pci_epc *epc, u8 func_no, | |||
| 158 | enum pci_epc_irq_type type, u16 interrupt_num); | 169 | enum pci_epc_irq_type type, u16 interrupt_num); |
| 159 | int pci_epc_start(struct pci_epc *epc); | 170 | int pci_epc_start(struct pci_epc *epc); |
| 160 | void pci_epc_stop(struct pci_epc *epc); | 171 | void pci_epc_stop(struct pci_epc *epc); |
| 172 | const struct pci_epc_features *pci_epc_get_features(struct pci_epc *epc, | ||
| 173 | u8 func_no); | ||
| 174 | unsigned int pci_epc_get_first_free_bar(const struct pci_epc_features | ||
| 175 | *epc_features); | ||
| 161 | struct pci_epc *pci_epc_get(const char *epc_name); | 176 | struct pci_epc *pci_epc_get(const char *epc_name); |
| 162 | void pci_epc_put(struct pci_epc *epc); | 177 | void pci_epc_put(struct pci_epc *epc); |
| 163 | 178 | ||
diff --git a/include/linux/pci.h b/include/linux/pci.h index e7c51b00cdfe..4eca42cf611b 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h | |||
| @@ -373,6 +373,9 @@ struct pci_dev { | |||
| 373 | bool match_driver; /* Skip attaching driver */ | 373 | bool match_driver; /* Skip attaching driver */ |
| 374 | 374 | ||
| 375 | unsigned int transparent:1; /* Subtractive decode bridge */ | 375 | unsigned int transparent:1; /* Subtractive decode bridge */ |
| 376 | unsigned int io_window:1; /* Bridge has I/O window */ | ||
| 377 | unsigned int pref_window:1; /* Bridge has pref mem window */ | ||
| 378 | unsigned int pref_64_window:1; /* Pref mem window is 64-bit */ | ||
| 376 | unsigned int multifunction:1; /* Multi-function device */ | 379 | unsigned int multifunction:1; /* Multi-function device */ |
| 377 | 380 | ||
| 378 | unsigned int is_busmaster:1; /* Is busmaster */ | 381 | unsigned int is_busmaster:1; /* Is busmaster */ |
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 5eaf39dbc388..70e86148cb1e 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h | |||
| @@ -1140,6 +1140,8 @@ | |||
| 1140 | #define PCI_VENDOR_ID_TCONRAD 0x10da | 1140 | #define PCI_VENDOR_ID_TCONRAD 0x10da |
| 1141 | #define PCI_DEVICE_ID_TCONRAD_TOKENRING 0x0508 | 1141 | #define PCI_DEVICE_ID_TCONRAD_TOKENRING 0x0508 |
| 1142 | 1142 | ||
| 1143 | #define PCI_VENDOR_ID_ROHM 0x10db | ||
| 1144 | |||
| 1143 | #define PCI_VENDOR_ID_NVIDIA 0x10de | 1145 | #define PCI_VENDOR_ID_NVIDIA 0x10de |
| 1144 | #define PCI_DEVICE_ID_NVIDIA_TNT 0x0020 | 1146 | #define PCI_DEVICE_ID_NVIDIA_TNT 0x0020 |
| 1145 | #define PCI_DEVICE_ID_NVIDIA_TNT2 0x0028 | 1147 | #define PCI_DEVICE_ID_NVIDIA_TNT2 0x0028 |
| @@ -2573,6 +2575,8 @@ | |||
| 2573 | 2575 | ||
| 2574 | #define PCI_VENDOR_ID_HYGON 0x1d94 | 2576 | #define PCI_VENDOR_ID_HYGON 0x1d94 |
| 2575 | 2577 | ||
| 2578 | #define PCI_VENDOR_ID_HXT 0x1dbf | ||
| 2579 | |||
| 2576 | #define PCI_VENDOR_ID_TEKRAM 0x1de1 | 2580 | #define PCI_VENDOR_ID_TEKRAM 0x1de1 |
| 2577 | #define PCI_DEVICE_ID_TEKRAM_DC290 0xdc29 | 2581 | #define PCI_DEVICE_ID_TEKRAM_DC290 0xdc29 |
| 2578 | 2582 | ||
