From b9cbc06049cb6b7a322d708c2098195fb9fdcc4c Mon Sep 17 00:00:00 2001 From: Manivannan Sadhasivam Date: Tue, 27 Jun 2023 19:40:36 +0530 Subject: PCI: qcom-ep: Switch MHI bus master clock off during L1SS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently, as part of the qcom_pcie_perst_deassert() function, instead of writing the updated value to clear PARF_MSTR_AXI_CLK_EN, the variable "val" is re-read. This must be fixed to ensure that the master clock supplied to the MHI bus is correctly gated during L1.1/L1.2 to save power. Thus, replace the line that re-reads "val" with a line that writes the updated value to the register to clear PARF_MSTR_AXI_CLK_EN. [kwilczynski: commit log] Fixes: c457ac029e44 ("PCI: qcom-ep: Gate Master AXI clock to MHI bus during L1SS") Link: https://lore.kernel.org/linux-pci/20230627141036.11600-1-manivannan.sadhasivam@linaro.org Reported-by: Krzysztof Wilczyński Signed-off-by: Manivannan Sadhasivam Signed-off-by: Krzysztof Wilczyński --- drivers/pci/controller/dwc/pcie-qcom-ep.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/pci/controller/dwc') diff --git a/drivers/pci/controller/dwc/pcie-qcom-ep.c b/drivers/pci/controller/dwc/pcie-qcom-ep.c index 0fe7f06f2102..267e1247d548 100644 --- a/drivers/pci/controller/dwc/pcie-qcom-ep.c +++ b/drivers/pci/controller/dwc/pcie-qcom-ep.c @@ -415,7 +415,7 @@ static int qcom_pcie_perst_deassert(struct dw_pcie *pci) /* Gate Master AXI clock to MHI bus during L1SS */ val = readl_relaxed(pcie_ep->parf + PARF_MHI_CLOCK_RESET_CTRL); val &= ~PARF_MSTR_AXI_CLK_EN; - val = readl_relaxed(pcie_ep->parf + PARF_MHI_CLOCK_RESET_CTRL); + writel_relaxed(val, pcie_ep->parf + PARF_MHI_CLOCK_RESET_CTRL); dw_pcie_ep_init_notify(&pcie_ep->pci.ep); -- cgit v1.2.3 From 188f46cac267b9b8f3201ed21d719a51946e1e34 Mon Sep 17 00:00:00 2001 From: Yang Li Date: Thu, 23 Mar 2023 15:45:53 +0800 Subject: PCI: imx6: Use devm_platform_get_and_ioremap_resource() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Convert calls to platform_get_resource() and devm_ioremap_resource() into a single call to devm_platform_get_and_ioremap_resource(), to simplify the code. This new helper added in commit 890cc39a8799 ("drivers: provide devm_platform_get_and_ioremap_resource()") does what both of the other separate functions do. [kwilczynski: commit log] Link: https://lore.kernel.org/linux-pci/20230323074553.90372-1-yang.lee@linux.alibaba.com Signed-off-by: Yang Li Signed-off-by: Krzysztof Wilczyński Reviewed-by: Richard Zhu --- drivers/pci/controller/dwc/pci-imx6.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/pci/controller/dwc') diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c index 27aaa2a6bf39..6bf7ad2f7b48 100644 --- a/drivers/pci/controller/dwc/pci-imx6.c +++ b/drivers/pci/controller/dwc/pci-imx6.c @@ -1282,8 +1282,7 @@ static int imx6_pcie_probe(struct platform_device *pdev) return PTR_ERR(imx6_pcie->phy_base); } - dbi_base = platform_get_resource(pdev, IORESOURCE_MEM, 0); - pci->dbi_base = devm_ioremap_resource(dev, dbi_base); + pci->dbi_base = devm_platform_get_and_ioremap_resource(pdev, 0, &dbi_base); if (IS_ERR(pci->dbi_base)) return PTR_ERR(pci->dbi_base); -- cgit v1.2.3 From 1a8bf351ccde7527ca0427151b5fe43f64fa1eac Mon Sep 17 00:00:00 2001 From: Krzysztof Wilczyński Date: Thu, 29 Jun 2023 16:59:54 +0000 Subject: PCI: meson: Remove cast between incompatible function type MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rather than casting void(*)(struct clk *) to void (*)(void *), that forces conversion to an incompatible function type, replace the cast with a small local stub function with a signature that matches what the devm_add_action_or_reset() function expects. The sub function takes a void *, then passes it directly to clk_disable_unprepare(), which handles the more specific type. Reported by clang when building with warnings enabled: drivers/pci/controller/dwc/pci-meson.c:191:6: warning: cast from 'void (*)(struct clk *)' to 'void (*)(void *)' converts to incompatible function type [-Wcast-function-type-strict] (void (*) (void *))clk_disable_unprepare, ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ No functional changes are intended. Fixes: 9c0ef6d34fdb ("PCI: amlogic: Add the Amlogic Meson PCIe controller driver") Link: https://lore.kernel.org/linux-pci/20230629165956.237832-1-kwilczynski@kernel.org Reviewed-by: Neil Armstrong Signed-off-by: Krzysztof Wilczyński --- drivers/pci/controller/dwc/pci-meson.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'drivers/pci/controller/dwc') diff --git a/drivers/pci/controller/dwc/pci-meson.c b/drivers/pci/controller/dwc/pci-meson.c index c1527693bed9..34990a6363d0 100644 --- a/drivers/pci/controller/dwc/pci-meson.c +++ b/drivers/pci/controller/dwc/pci-meson.c @@ -163,6 +163,13 @@ static int meson_pcie_reset(struct meson_pcie *mp) return 0; } +static inline void meson_pcie_disable_clock(void *data) +{ + struct clk *clk = data; + + clk_disable_unprepare(clk); +} + static inline struct clk *meson_pcie_probe_clock(struct device *dev, const char *id, u64 rate) { @@ -187,9 +194,7 @@ static inline struct clk *meson_pcie_probe_clock(struct device *dev, return ERR_PTR(ret); } - devm_add_action_or_reset(dev, - (void (*) (void *))clk_disable_unprepare, - clk); + devm_add_action_or_reset(dev, meson_pcie_disable_clock, clk); return clk; } -- cgit v1.2.3 From 7a6531696668f1c9251f6b7219c02519f652be3d Mon Sep 17 00:00:00 2001 From: Krzysztof Wilczyński Date: Thu, 29 Jun 2023 16:59:55 +0000 Subject: PCI: keembay: Remove cast between incompatible function type MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rather than casting void(*)(struct clk *) to void (*)(void *), that forces conversion to an incompatible function type, replace the cast with a small local stub function with a signature that matches what the devm_add_action_or_reset() function expects. The sub function takes a void *, then passes it directly to clk_disable_unprepare(), which handles the more specific type. Reported by clang when building with warnings enabled: drivers/pci/controller/dwc/pcie-keembay.c:172:12: warning: cast from 'void (*)(struct clk *)' to 'void (*)(void *)' converts to incompatible function type [-Wcast-function-type-strict] (void(*)(void *))clk_disable_unprepare, ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ No functional changes are intended. Fixes: 0c87f90b4c13 ("PCI: keembay: Add support for Intel Keem Bay") Link: https://lore.kernel.org/linux-pci/20230629165956.237832-2-kwilczynski@kernel.org Acked-by: Srikanth Thokala Signed-off-by: Krzysztof Wilczyński --- drivers/pci/controller/dwc/pcie-keembay.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'drivers/pci/controller/dwc') diff --git a/drivers/pci/controller/dwc/pcie-keembay.c b/drivers/pci/controller/dwc/pcie-keembay.c index f90f36bac018..289bff99d762 100644 --- a/drivers/pci/controller/dwc/pcie-keembay.c +++ b/drivers/pci/controller/dwc/pcie-keembay.c @@ -148,6 +148,13 @@ static const struct dw_pcie_ops keembay_pcie_ops = { .stop_link = keembay_pcie_stop_link, }; +static inline void keembay_pcie_disable_clock(void *data) +{ + struct clk *clk = data; + + clk_disable_unprepare(clk); +} + static inline struct clk *keembay_pcie_probe_clock(struct device *dev, const char *id, u64 rate) { @@ -168,9 +175,7 @@ static inline struct clk *keembay_pcie_probe_clock(struct device *dev, if (ret) return ERR_PTR(ret); - ret = devm_add_action_or_reset(dev, - (void(*)(void *))clk_disable_unprepare, - clk); + ret = devm_add_action_or_reset(dev, keembay_pcie_disable_clock, clk); if (ret) return ERR_PTR(ret); -- cgit v1.2.3 From c925cfaf0992f151c02f239e035ca9316224f224 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Fri, 14 Jul 2023 11:48:25 -0600 Subject: PCI: Explicitly include correct DT includes The DT of_device.h and of_platform.h date back to the separate of_platform_bus_type before it as merged into the regular platform bus. As part of that merge prepping Arm DT support 13 years ago, they "temporarily" include each other. They also include platform_device.h and of.h. As a result, there's a pretty much random mix of those include files used throughout the tree. In order to detangle these headers and replace the implicit includes with struct declarations, users need to explicitly include the correct includes. Link: https://lore.kernel.org/r/20230714174827.4061572-1-robh@kernel.org Signed-off-by: Rob Herring Signed-off-by: Bjorn Helgaas --- drivers/pci/controller/cadence/pci-j721e.c | 2 +- drivers/pci/controller/cadence/pcie-cadence-plat.c | 3 +-- drivers/pci/controller/cadence/pcie-cadence.c | 1 + drivers/pci/controller/dwc/pci-dra7xx.c | 2 +- drivers/pci/controller/dwc/pci-exynos.c | 2 +- drivers/pci/controller/dwc/pci-imx6.c | 2 +- drivers/pci/controller/dwc/pci-keystone.c | 1 - drivers/pci/controller/dwc/pci-meson.c | 2 +- drivers/pci/controller/dwc/pcie-artpec6.c | 2 +- drivers/pci/controller/dwc/pcie-designware-plat.c | 2 +- drivers/pci/controller/dwc/pcie-designware.c | 2 +- drivers/pci/controller/dwc/pcie-dw-rockchip.c | 2 +- drivers/pci/controller/dwc/pcie-intel-gw.c | 2 ++ drivers/pci/controller/dwc/pcie-kirin.c | 3 +-- drivers/pci/controller/dwc/pcie-qcom.c | 2 +- drivers/pci/controller/dwc/pcie-tegra194.c | 1 - drivers/pci/controller/dwc/pcie-uniphier-ep.c | 2 +- drivers/pci/controller/mobiveil/pcie-mobiveil-host.c | 3 --- drivers/pci/controller/pci-ftpci100.c | 3 +-- drivers/pci/controller/pci-host-common.c | 2 +- drivers/pci/controller/pci-ixp4xx.c | 3 +-- drivers/pci/controller/pci-loongson.c | 2 +- drivers/pci/controller/pci-v3-semi.c | 3 +-- drivers/pci/controller/pcie-altera.c | 5 ++--- drivers/pci/controller/pcie-rockchip-host.c | 4 +--- drivers/pci/controller/pcie-rockchip.c | 1 + drivers/pci/endpoint/pci-epc-core.c | 1 - drivers/pci/probe.c | 1 - 28 files changed, 25 insertions(+), 36 deletions(-) (limited to 'drivers/pci/controller/dwc') diff --git a/drivers/pci/controller/cadence/pci-j721e.c b/drivers/pci/controller/cadence/pci-j721e.c index e70213c9060a..2c87e7728a65 100644 --- a/drivers/pci/controller/cadence/pci-j721e.c +++ b/drivers/pci/controller/cadence/pci-j721e.c @@ -14,8 +14,8 @@ #include #include #include -#include #include +#include #include #include diff --git a/drivers/pci/controller/cadence/pcie-cadence-plat.c b/drivers/pci/controller/cadence/pcie-cadence-plat.c index bac0541317c1..371ffc1f00f8 100644 --- a/drivers/pci/controller/cadence/pcie-cadence-plat.c +++ b/drivers/pci/controller/cadence/pcie-cadence-plat.c @@ -6,11 +6,10 @@ * Author: Tom Joseph */ #include -#include +#include #include #include #include -#include #include "pcie-cadence.h" #define CDNS_PLAT_CPU_TO_BUS_ADDR 0x0FFFFFFF diff --git a/drivers/pci/controller/cadence/pcie-cadence.c b/drivers/pci/controller/cadence/pcie-cadence.c index 13c4032ca379..4251fac5e310 100644 --- a/drivers/pci/controller/cadence/pcie-cadence.c +++ b/drivers/pci/controller/cadence/pcie-cadence.c @@ -4,6 +4,7 @@ // Author: Cyrille Pitchen #include +#include #include "pcie-cadence.h" diff --git a/drivers/pci/controller/dwc/pci-dra7xx.c b/drivers/pci/controller/dwc/pci-dra7xx.c index 4ae807e7cf79..b445ffe95e3f 100644 --- a/drivers/pci/controller/dwc/pci-dra7xx.c +++ b/drivers/pci/controller/dwc/pci-dra7xx.c @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/pci/controller/dwc/pci-exynos.c b/drivers/pci/controller/dwc/pci-exynos.c index ec5611005566..6319082301d6 100644 --- a/drivers/pci/controller/dwc/pci-exynos.c +++ b/drivers/pci/controller/dwc/pci-exynos.c @@ -14,11 +14,11 @@ #include #include #include -#include #include #include #include #include +#include #include #include "pcie-designware.h" diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c index 27aaa2a6bf39..d123797a06a2 100644 --- a/drivers/pci/controller/dwc/pci-imx6.c +++ b/drivers/pci/controller/dwc/pci-imx6.c @@ -17,8 +17,8 @@ #include #include #include +#include #include -#include #include #include #include diff --git a/drivers/pci/controller/dwc/pci-keystone.c b/drivers/pci/controller/dwc/pci-keystone.c index 78818853af9e..49aea6ce3e87 100644 --- a/drivers/pci/controller/dwc/pci-keystone.c +++ b/drivers/pci/controller/dwc/pci-keystone.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/pci/controller/dwc/pci-meson.c b/drivers/pci/controller/dwc/pci-meson.c index c1527693bed9..973b0fc81315 100644 --- a/drivers/pci/controller/dwc/pci-meson.c +++ b/drivers/pci/controller/dwc/pci-meson.c @@ -9,7 +9,6 @@ #include #include #include -#include #include #include #include @@ -17,6 +16,7 @@ #include #include #include +#include #include #include "pcie-designware.h" diff --git a/drivers/pci/controller/dwc/pcie-artpec6.c b/drivers/pci/controller/dwc/pcie-artpec6.c index 98102079e26d..9b572a2b2c9a 100644 --- a/drivers/pci/controller/dwc/pcie-artpec6.c +++ b/drivers/pci/controller/dwc/pcie-artpec6.c @@ -10,7 +10,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/pci/controller/dwc/pcie-designware-plat.c b/drivers/pci/controller/dwc/pcie-designware-plat.c index 1fcfb840f238..b625841e98aa 100644 --- a/drivers/pci/controller/dwc/pcie-designware-plat.c +++ b/drivers/pci/controller/dwc/pcie-designware-plat.c @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/pci/controller/dwc/pcie-designware.c b/drivers/pci/controller/dwc/pcie-designware.c index c87848cd8686..2459f2a61b9b 100644 --- a/drivers/pci/controller/dwc/pcie-designware.c +++ b/drivers/pci/controller/dwc/pcie-designware.c @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include #include diff --git a/drivers/pci/controller/dwc/pcie-dw-rockchip.c b/drivers/pci/controller/dwc/pcie-dw-rockchip.c index c1e7653e508e..2fe42c70097f 100644 --- a/drivers/pci/controller/dwc/pcie-dw-rockchip.c +++ b/drivers/pci/controller/dwc/pcie-dw-rockchip.c @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/pci/controller/dwc/pcie-intel-gw.c b/drivers/pci/controller/dwc/pcie-intel-gw.c index 9c7caed9e706..c9c93524e01d 100644 --- a/drivers/pci/controller/dwc/pcie-intel-gw.c +++ b/drivers/pci/controller/dwc/pcie-intel-gw.c @@ -9,9 +9,11 @@ #include #include #include +#include #include #include #include +#include #include #include "../../pci.h" diff --git a/drivers/pci/controller/dwc/pcie-kirin.c b/drivers/pci/controller/dwc/pcie-kirin.c index d09507f822a7..d93bc2906950 100644 --- a/drivers/pci/controller/dwc/pcie-kirin.c +++ b/drivers/pci/controller/dwc/pcie-kirin.c @@ -16,8 +16,7 @@ #include #include #include -#include -#include +#include #include #include #include diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c index 7a87a47eb7ed..cee4e400a695 100644 --- a/drivers/pci/controller/dwc/pcie-qcom.c +++ b/drivers/pci/controller/dwc/pcie-qcom.c @@ -19,7 +19,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/pci/controller/dwc/pcie-tegra194.c b/drivers/pci/controller/dwc/pcie-tegra194.c index e1db909f53ec..383ba71d1e8f 100644 --- a/drivers/pci/controller/dwc/pcie-tegra194.c +++ b/drivers/pci/controller/dwc/pcie-tegra194.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/pci/controller/dwc/pcie-uniphier-ep.c b/drivers/pci/controller/dwc/pcie-uniphier-ep.c index 4d0a587c0ba5..cba3c88fcf39 100644 --- a/drivers/pci/controller/dwc/pcie-uniphier-ep.c +++ b/drivers/pci/controller/dwc/pcie-uniphier-ep.c @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c b/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c index 31a7bdebe540..45b97a4b14db 100644 --- a/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c +++ b/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c @@ -17,9 +17,6 @@ #include #include #include -#include -#include -#include #include #include #include diff --git a/drivers/pci/controller/pci-ftpci100.c b/drivers/pci/controller/pci-ftpci100.c index 6e7981d2ed5e..ffdeed25e961 100644 --- a/drivers/pci/controller/pci-ftpci100.c +++ b/drivers/pci/controller/pci-ftpci100.c @@ -15,8 +15,7 @@ #include #include #include -#include -#include +#include #include #include #include diff --git a/drivers/pci/controller/pci-host-common.c b/drivers/pci/controller/pci-host-common.c index d3924a44db02..6be3266cd7b5 100644 --- a/drivers/pci/controller/pci-host-common.c +++ b/drivers/pci/controller/pci-host-common.c @@ -9,8 +9,8 @@ #include #include +#include #include -#include #include #include #include diff --git a/drivers/pci/controller/pci-ixp4xx.c b/drivers/pci/controller/pci-ixp4xx.c index e44252db6085..acb85e0d5675 100644 --- a/drivers/pci/controller/pci-ixp4xx.c +++ b/drivers/pci/controller/pci-ixp4xx.c @@ -19,8 +19,7 @@ #include #include #include -#include -#include +#include #include #include #include diff --git a/drivers/pci/controller/pci-loongson.c b/drivers/pci/controller/pci-loongson.c index fe0f732f6e43..d45e7b8dc530 100644 --- a/drivers/pci/controller/pci-loongson.c +++ b/drivers/pci/controller/pci-loongson.c @@ -5,7 +5,7 @@ * Copyright (C) 2020 Jiaxun Yang */ -#include +#include #include #include #include diff --git a/drivers/pci/controller/pci-v3-semi.c b/drivers/pci/controller/pci-v3-semi.c index ca44b0c83d1b..0917f571bb6d 100644 --- a/drivers/pci/controller/pci-v3-semi.c +++ b/drivers/pci/controller/pci-v3-semi.c @@ -20,8 +20,7 @@ #include #include #include -#include -#include +#include #include #include #include diff --git a/drivers/pci/controller/pcie-altera.c b/drivers/pci/controller/pcie-altera.c index c95a29fff8bf..a9536dc4bf96 100644 --- a/drivers/pci/controller/pcie-altera.c +++ b/drivers/pci/controller/pcie-altera.c @@ -9,11 +9,10 @@ #include #include #include +#include #include #include -#include -#include -#include +#include #include #include #include diff --git a/drivers/pci/controller/pcie-rockchip-host.c b/drivers/pci/controller/pcie-rockchip-host.c index 2438bc9b3a1a..afbbdccd195d 100644 --- a/drivers/pci/controller/pcie-rockchip-host.c +++ b/drivers/pci/controller/pcie-rockchip-host.c @@ -24,10 +24,8 @@ #include #include #include -#include -#include +#include #include -#include #include #include #include diff --git a/drivers/pci/controller/pcie-rockchip.c b/drivers/pci/controller/pcie-rockchip.c index 1aa84035a8bc..0ef2e622d36e 100644 --- a/drivers/pci/controller/pcie-rockchip.c +++ b/drivers/pci/controller/pcie-rockchip.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/pci/endpoint/pci-epc-core.c b/drivers/pci/endpoint/pci-epc-core.c index 6c54fa5684d2..5a4a8b0be626 100644 --- a/drivers/pci/endpoint/pci-epc-core.c +++ b/drivers/pci/endpoint/pci-epc-core.c @@ -9,7 +9,6 @@ #include #include #include -#include #include #include diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 8bac3ce02609..31fb02fbb2cc 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -8,7 +8,6 @@ #include #include #include -#include #include #include #include -- cgit v1.2.3 From c5097b9869a136349d8404715dc8aabb7570a762 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Thu, 6 Jul 2023 10:26:10 +0200 Subject: Revert "PCI: dwc: Wait for link up only if link is started" This reverts commit da56a1bfbab55189595e588f1d984bdfb5cf5924. Bjorn Andersson, Fabio Estevam, Xiaolei Wang, and Jon Hunter reported that da56a1bfbab5 ("PCI: dwc: Wait for link up only if link is started") broke controller probing by returning an error in case the link does not come up during host initialisation, for example when the slot is empty. As explained in commit 886a9c134755 ("PCI: dwc: Move link handling into common code") and as indicated by the comment "Ignore errors, the link may come up later" in the code, waiting for link up and ignoring errors is the intended behaviour: Let's standardize this to succeed as there are usecases where devices (and the link) appear later even without hotplug. For example, a reconfigured FPGA device. Reverting the offending commit specifically fixes a regression on Qualcomm platforms like the Lenovo ThinkPad X13s which no longer reach the interconnect sync state if a slot does not have a device populated (e.g. an optional modem). Note that enabling asynchronous probing by default as was done for Qualcomm platforms by commit c0e1eb441b1d ("PCI: qcom: Enable async probe by default"), should take care of any related boot time concerns. Finally, note that the intel-gw driver is the only driver currently not providing a .start_link() callback and instead starts the link in its .host_init() callback, which may avoid an additional one-second timeout during probe by making the link-up wait conditional. If anyone cares, that can be done in a follow-up patch with a proper motivation. [bhelgaas: add Fabio Estevam, Xiaolei Wang, Jon Hunter reports] Fixes: da56a1bfbab5 ("PCI: dwc: Wait for link up only if link is started") Link: https://lore.kernel.org/r/20230706082610.26584-1-johan+linaro@kernel.org Reported-by: Bjorn Andersson Signed-off-by: Johan Hovold Reported-by: Fabio Estevam Link: https://lore.kernel.org/r/20230704122635.1362156-1-festevam@gmail.com/ Reported-by: Xiaolei Wang Link: https://lore.kernel.org/r/20230705010624.3912934-1-xiaolei.wang@windriver.com/ Reported-by: Jon Hunter Link: https://lore.kernel.org/r/6ca287a1-6c7c-7b90-9022-9e73fb82b564@nvidia.com Signed-off-by: Bjorn Helgaas Reviewed-by: Manivannan Sadhasivam Cc: Sajid Dalvi Cc: Ajay Agarwal --- drivers/pci/controller/dwc/pcie-designware-host.c | 13 ++++--------- drivers/pci/controller/dwc/pcie-designware.c | 20 +++++++------------- drivers/pci/controller/dwc/pcie-designware.h | 1 - 3 files changed, 11 insertions(+), 23 deletions(-) (limited to 'drivers/pci/controller/dwc') diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c index cf61733bf78d..9952057c8819 100644 --- a/drivers/pci/controller/dwc/pcie-designware-host.c +++ b/drivers/pci/controller/dwc/pcie-designware-host.c @@ -485,20 +485,15 @@ int dw_pcie_host_init(struct dw_pcie_rp *pp) if (ret) goto err_remove_edma; - if (dw_pcie_link_up(pci)) { - dw_pcie_print_link_status(pci); - } else { + if (!dw_pcie_link_up(pci)) { ret = dw_pcie_start_link(pci); if (ret) goto err_remove_edma; - - if (pci->ops && pci->ops->start_link) { - ret = dw_pcie_wait_for_link(pci); - if (ret) - goto err_stop_link; - } } + /* Ignore errors, the link may come up later */ + dw_pcie_wait_for_link(pci); + bridge->sysdata = pp; ret = pci_host_probe(bridge); diff --git a/drivers/pci/controller/dwc/pcie-designware.c b/drivers/pci/controller/dwc/pcie-designware.c index c87848cd8686..1f2ee71da4da 100644 --- a/drivers/pci/controller/dwc/pcie-designware.c +++ b/drivers/pci/controller/dwc/pcie-designware.c @@ -644,20 +644,9 @@ void dw_pcie_disable_atu(struct dw_pcie *pci, u32 dir, int index) dw_pcie_writel_atu(pci, dir, index, PCIE_ATU_REGION_CTRL2, 0); } -void dw_pcie_print_link_status(struct dw_pcie *pci) -{ - u32 offset, val; - - offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP); - val = dw_pcie_readw_dbi(pci, offset + PCI_EXP_LNKSTA); - - dev_info(pci->dev, "PCIe Gen.%u x%u link up\n", - FIELD_GET(PCI_EXP_LNKSTA_CLS, val), - FIELD_GET(PCI_EXP_LNKSTA_NLW, val)); -} - int dw_pcie_wait_for_link(struct dw_pcie *pci) { + u32 offset, val; int retries; /* Check if the link is up or not */ @@ -673,7 +662,12 @@ int dw_pcie_wait_for_link(struct dw_pcie *pci) return -ETIMEDOUT; } - dw_pcie_print_link_status(pci); + offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP); + val = dw_pcie_readw_dbi(pci, offset + PCI_EXP_LNKSTA); + + dev_info(pci->dev, "PCIe Gen.%u x%u link up\n", + FIELD_GET(PCI_EXP_LNKSTA_CLS, val), + FIELD_GET(PCI_EXP_LNKSTA_NLW, val)); return 0; } diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h index 615660640801..79713ce075cc 100644 --- a/drivers/pci/controller/dwc/pcie-designware.h +++ b/drivers/pci/controller/dwc/pcie-designware.h @@ -429,7 +429,6 @@ void dw_pcie_setup(struct dw_pcie *pci); void dw_pcie_iatu_detect(struct dw_pcie *pci); int dw_pcie_edma_detect(struct dw_pcie *pci); void dw_pcie_edma_remove(struct dw_pcie *pci); -void dw_pcie_print_link_status(struct dw_pcie *pci); static inline void dw_pcie_writel_dbi(struct dw_pcie *pci, u32 reg, u32 val) { -- cgit v1.2.3 From ebfde1584d9f037b6309fc682c96e22dac7bcb7a Mon Sep 17 00:00:00 2001 From: Vidya Sagar Date: Mon, 19 Jun 2023 15:56:04 +0530 Subject: Revert "PCI: tegra194: Enable support for 256 Byte payload" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After commit 4fb8e46c1bc4 ("PCI: tegra194: Enable support for 256 Byte payload"), we initialize MPS=256 for tegra194 Root Ports before enumerating the hierarchy. Consider an Endpoint that supports only MPS=128. In the default situation (CONFIG_PCIE_BUS_DEFAULT set and no "pci=pcie_bus_*" parameter), Linux tries to configure the MPS of every device to match the upstream bridge. If the Endpoint is directly below the Root Port, Linux can reduce the Root Port MPS to 128 to match the Endpoint. But if there's a switch in the middle, Linux doesn't reduce the Root Port MPS because other devices below the switch may already be configured with MPS larger than 128. This scenario results in uncorrectable Malformed TLP errors if the Root Port sends TLPs with payloads larger than 128 bytes. These errors can be avoided by using the "pci=pcie_bus_safe" parameter, but it doesn't seem to be a good idea to always have this parameter even for basic functionality to work. Revert commit 4fb8e46c1bc4 ("PCI: tegra194: Enable support for 256 Byte payload") so the Root Ports default to MPS=128, which all devices support. If peer-to-peer DMA is not required, one can use "pci=pcie_bus_perf" to get the benefit of larger MPS settings. [bhelgaas: commit log; kwilczynski: retain "u16 val_16" declaration at the top, add missing acked by tag] Fixes: 4fb8e46c1bc4 ("PCI: tegra194: Enable support for 256 Byte payload") Link: https://lore.kernel.org/linux-pci/20230619102604.3735001-1-vidyas@nvidia.com Signed-off-by: Vidya Sagar Signed-off-by: Krzysztof Wilczyński Acked-by: Jon Hunter Cc: stable@vger.kernel.org # v6.0-rc1+ --- drivers/pci/controller/dwc/pcie-tegra194.c | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'drivers/pci/controller/dwc') diff --git a/drivers/pci/controller/dwc/pcie-tegra194.c b/drivers/pci/controller/dwc/pcie-tegra194.c index e1db909f53ec..ccff8cde5cff 100644 --- a/drivers/pci/controller/dwc/pcie-tegra194.c +++ b/drivers/pci/controller/dwc/pcie-tegra194.c @@ -900,11 +900,6 @@ static int tegra_pcie_dw_host_init(struct dw_pcie_rp *pp) pcie->pcie_cap_base = dw_pcie_find_capability(&pcie->pci, PCI_CAP_ID_EXP); - val_16 = dw_pcie_readw_dbi(pci, pcie->pcie_cap_base + PCI_EXP_DEVCTL); - val_16 &= ~PCI_EXP_DEVCTL_PAYLOAD; - val_16 |= PCI_EXP_DEVCTL_PAYLOAD_256B; - dw_pcie_writew_dbi(pci, pcie->pcie_cap_base + PCI_EXP_DEVCTL, val_16); - val = dw_pcie_readl_dbi(pci, PCI_IO_BASE); val &= ~(IO_BASE_IO_DECODE | IO_BASE_IO_DECODE_BIT8); dw_pcie_writel_dbi(pci, PCI_IO_BASE, val); @@ -1887,11 +1882,6 @@ static void pex_ep_event_pex_rst_deassert(struct tegra_pcie_dw *pcie) pcie->pcie_cap_base = dw_pcie_find_capability(&pcie->pci, PCI_CAP_ID_EXP); - val_16 = dw_pcie_readw_dbi(pci, pcie->pcie_cap_base + PCI_EXP_DEVCTL); - val_16 &= ~PCI_EXP_DEVCTL_PAYLOAD; - val_16 |= PCI_EXP_DEVCTL_PAYLOAD_256B; - dw_pcie_writew_dbi(pci, pcie->pcie_cap_base + PCI_EXP_DEVCTL, val_16); - /* Clear Slot Clock Configuration bit if SRNS configuration */ if (pcie->enable_srns) { val_16 = dw_pcie_readw_dbi(pci, pcie->pcie_cap_base + -- cgit v1.2.3 From fc8b24c28bec19fc0621d108b9ee81ddfdedb25a Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 31 Jul 2023 12:55:01 +0100 Subject: PCI: dwc: Provide deinit callback for i.MX The i.MX integration for the DesignWare PCI controller has a _host_exit() operation which undoes everything that the _host_init() operation does but does not wire this up as the host_deinit callback for the core, or call it in any path other than suspend. This means that if we ever unwind the initial probe of the device, for example because it fails, the regulator core complains that the regulators for the device were left enabled: imx6q-pcie 33800000.pcie: iATU: unroll T, 4 ob, 4 ib, align 64K, limit 16G imx6q-pcie 33800000.pcie: Phy link never came up imx6q-pcie 33800000.pcie: Phy link never came up imx6q-pcie: probe of 33800000.pcie failed with error -110 ------------[ cut here ]------------ WARNING: CPU: 2 PID: 46 at drivers/regulator/core.c:2396 _regulator_put+0x110/0x128 Wire up the callback so that the core can clean up after itself. Link: https://lore.kernel.org/r/20230731-pci-imx-regulator-cleanup-v2-1-fc8fa5c9893d@kernel.org Tested-by: Fabio Estevam Signed-off-by: Mark Brown Signed-off-by: Lorenzo Pieralisi Reviewed-by: Richard Zhu Acked-by: Manivannan Sadhasivam --- drivers/pci/controller/dwc/pci-imx6.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/pci/controller/dwc') diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c index 27aaa2a6bf39..a18c20085e94 100644 --- a/drivers/pci/controller/dwc/pci-imx6.c +++ b/drivers/pci/controller/dwc/pci-imx6.c @@ -1040,6 +1040,7 @@ static void imx6_pcie_host_exit(struct dw_pcie_rp *pp) static const struct dw_pcie_host_ops imx6_pcie_host_ops = { .host_init = imx6_pcie_host_init, + .host_deinit = imx6_pcie_host_exit, }; static const struct dw_pcie_ops dw_pcie_ops = { -- cgit v1.2.3 From 551a60e1225e71fff8efd9390204c505b0870e0f Mon Sep 17 00:00:00 2001 From: Yong-Xuan Wang Date: Mon, 7 Aug 2023 05:56:21 +0000 Subject: PCI: fu740: Set the number of MSI vectors The iMSI-RX module of the DW PCIe controller provides multiple sets of MSI_CTRL_INT_i_* registers, and each set is capable of handling 32 MSI interrupts. However, the fu740 PCIe controller driver only enabled one set of MSI_CTRL_INT_i_* registers, as the total number of supported interrupts was not specified. Set the supported number of MSI vectors to enable all the MSI_CTRL_INT_i_* registers on the fu740 PCIe core, allowing the system to fully utilize the available MSI interrupts. Link: https://lore.kernel.org/r/20230807055621.2431-1-yongxuan.wang@sifive.com Signed-off-by: Yong-Xuan Wang Signed-off-by: Lorenzo Pieralisi Reviewed-by: Serge Semin --- drivers/pci/controller/dwc/pcie-fu740.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/pci/controller/dwc') diff --git a/drivers/pci/controller/dwc/pcie-fu740.c b/drivers/pci/controller/dwc/pcie-fu740.c index 0c90583c078b..1e9b44b8bba4 100644 --- a/drivers/pci/controller/dwc/pcie-fu740.c +++ b/drivers/pci/controller/dwc/pcie-fu740.c @@ -299,6 +299,7 @@ static int fu740_pcie_probe(struct platform_device *pdev) pci->dev = dev; pci->ops = &dw_pcie_ops; pci->pp.ops = &fu740_pcie_host_ops; + pci->pp.num_vectors = MAX_MSI_IRQS; /* SiFive specific region: mgmt */ afp->mgmt_base = devm_platform_ioremap_resource_byname(pdev, "mgmt"); -- cgit v1.2.3 From d28c0d84ca40e8cbc5c9f4e94f4ec78469d6c07b Mon Sep 17 00:00:00 2001 From: Frank Li Date: Thu, 20 Jul 2023 09:58:33 -0400 Subject: PCI: layerscape: Add support for link-down notification Add support to pass link-down notification to the endpoint function driver so that it can process the LINK_DOWN event. Link: https://lore.kernel.org/r/20230720135834.1977616-1-Frank.Li@nxp.com Signed-off-by: Frank Li Signed-off-by: Lorenzo Pieralisi Acked-by: Manivannan Sadhasivam --- drivers/pci/controller/dwc/pci-layerscape-ep.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/pci/controller/dwc') diff --git a/drivers/pci/controller/dwc/pci-layerscape-ep.c b/drivers/pci/controller/dwc/pci-layerscape-ep.c index de4c1758a6c3..e0969ff2ddf7 100644 --- a/drivers/pci/controller/dwc/pci-layerscape-ep.c +++ b/drivers/pci/controller/dwc/pci-layerscape-ep.c @@ -89,6 +89,7 @@ static irqreturn_t ls_pcie_ep_event_handler(int irq, void *dev_id) dev_dbg(pci->dev, "Link up\n"); } else if (val & PEX_PF0_PME_MES_DR_LDD) { dev_dbg(pci->dev, "Link down\n"); + pci_epc_linkdown(pci->ep.epc); } else if (val & PEX_PF0_PME_MES_DR_HRD) { dev_dbg(pci->dev, "Hot reset\n"); } -- cgit v1.2.3 From 17cf8661ee0f065c08152e611a568dd1fb0285f1 Mon Sep 17 00:00:00 2001 From: Xiaowei Bao Date: Thu, 20 Jul 2023 09:58:34 -0400 Subject: PCI: layerscape: Add workaround for lost link capabilities during reset The endpoint controller loses the Maximum Link Width and Supported Link Speed value from the Link Capabilities Register - initially configured by the Reset Configuration Word (RCW) - during a link-down or hot reset event. Address this issue in the endpoint event handler. Link: https://lore.kernel.org/r/20230720135834.1977616-2-Frank.Li@nxp.com Fixes: a805770d8a22 ("PCI: layerscape: Add EP mode support") Signed-off-by: Xiaowei Bao Signed-off-by: Hou Zhiqiang Signed-off-by: Frank Li Signed-off-by: Lorenzo Pieralisi Acked-by: Manivannan Sadhasivam --- drivers/pci/controller/dwc/pci-layerscape-ep.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'drivers/pci/controller/dwc') diff --git a/drivers/pci/controller/dwc/pci-layerscape-ep.c b/drivers/pci/controller/dwc/pci-layerscape-ep.c index e0969ff2ddf7..b1faf41a2fae 100644 --- a/drivers/pci/controller/dwc/pci-layerscape-ep.c +++ b/drivers/pci/controller/dwc/pci-layerscape-ep.c @@ -45,6 +45,7 @@ struct ls_pcie_ep { struct pci_epc_features *ls_epc; const struct ls_pcie_ep_drvdata *drvdata; int irq; + u32 lnkcap; bool big_endian; }; @@ -73,6 +74,7 @@ static irqreturn_t ls_pcie_ep_event_handler(int irq, void *dev_id) struct ls_pcie_ep *pcie = dev_id; struct dw_pcie *pci = pcie->pci; u32 val, cfg; + u8 offset; val = ls_lut_readl(pcie, PEX_PF0_PME_MES_DR); ls_lut_writel(pcie, PEX_PF0_PME_MES_DR, val); @@ -81,6 +83,19 @@ static irqreturn_t ls_pcie_ep_event_handler(int irq, void *dev_id) return IRQ_NONE; if (val & PEX_PF0_PME_MES_DR_LUD) { + + offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP); + + /* + * The values of the Maximum Link Width and Supported Link + * Speed from the Link Capabilities Register will be lost + * during link down or hot reset. Restore initial value + * that configured by the Reset Configuration Word (RCW). + */ + dw_pcie_dbi_ro_wr_en(pci); + dw_pcie_writel_dbi(pci, offset + PCI_EXP_LNKCAP, pcie->lnkcap); + dw_pcie_dbi_ro_wr_dis(pci); + cfg = ls_lut_readl(pcie, PEX_PF0_CONFIG); cfg |= PEX_PF0_CFG_READY; ls_lut_writel(pcie, PEX_PF0_CONFIG, cfg); @@ -216,6 +231,7 @@ static int __init ls_pcie_ep_probe(struct platform_device *pdev) struct ls_pcie_ep *pcie; struct pci_epc_features *ls_epc; struct resource *dbi_base; + u8 offset; int ret; pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL); @@ -252,6 +268,9 @@ static int __init ls_pcie_ep_probe(struct platform_device *pdev) platform_set_drvdata(pdev, pcie); + offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP); + pcie->lnkcap = dw_pcie_readl_dbi(pci, offset + PCI_EXP_LNKCAP); + ret = dw_pcie_ep_init(&pci->ep); if (ret) return ret; -- cgit v1.2.3 From 4774faf854f53461fd22daa73f3881fe11b6b755 Mon Sep 17 00:00:00 2001 From: Frank Li Date: Mon, 21 Aug 2023 14:48:14 -0400 Subject: PCI: dwc: Implement generic suspend/resume functionality Introduce an helper function (dw_pcie_get_ltssm()) to retrieve SMLH_LTSS_STATE. Add common dw_pcie_suspend(resume)_noirq() API to implement the DWC controller generic suspend/resume functionality. Add a controller specific callback to send the PME_Turn_Off message (ie .pme_turn_off) for controller platform specific PME handling. Link: https://lore.kernel.org/r/20230821184815.2167131-3-Frank.Li@nxp.com Signed-off-by: Frank Li [lpieralisi@kernel.org: commit log] Signed-off-by: Lorenzo Pieralisi Acked-by: Manivannan Sadhasivam --- drivers/pci/controller/dwc/pcie-designware-host.c | 71 +++++++++++++++++++++++ drivers/pci/controller/dwc/pcie-designware.h | 28 +++++++++ 2 files changed, 99 insertions(+) (limited to 'drivers/pci/controller/dwc') diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c index cf61733bf78d..5c8cbc3afae4 100644 --- a/drivers/pci/controller/dwc/pcie-designware-host.c +++ b/drivers/pci/controller/dwc/pcie-designware-host.c @@ -8,6 +8,7 @@ * Author: Jingoo Han */ +#include #include #include #include @@ -16,6 +17,7 @@ #include #include +#include "../../pci.h" #include "pcie-designware.h" static struct pci_ops dw_pcie_ops; @@ -812,3 +814,72 @@ int dw_pcie_setup_rc(struct dw_pcie_rp *pp) return 0; } EXPORT_SYMBOL_GPL(dw_pcie_setup_rc); + +int dw_pcie_suspend_noirq(struct dw_pcie *pci) +{ + u8 offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP); + u32 val; + int ret; + + /* + * If L1SS is supported, then do not put the link into L2 as some + * devices such as NVMe expect low resume latency. + */ + if (dw_pcie_readw_dbi(pci, offset + PCI_EXP_LNKCTL) & PCI_EXP_LNKCTL_ASPM_L1) + return 0; + + if (dw_pcie_get_ltssm(pci) <= DW_PCIE_LTSSM_DETECT_ACT) + return 0; + + if (!pci->pp.ops->pme_turn_off) + return 0; + + pci->pp.ops->pme_turn_off(&pci->pp); + + ret = read_poll_timeout(dw_pcie_get_ltssm, val, val == DW_PCIE_LTSSM_L2_IDLE, + PCIE_PME_TO_L2_TIMEOUT_US/10, + PCIE_PME_TO_L2_TIMEOUT_US, false, pci); + if (ret) { + dev_err(pci->dev, "Timeout waiting for L2 entry! LTSSM: 0x%x\n", val); + return ret; + } + + if (pci->pp.ops->host_deinit) + pci->pp.ops->host_deinit(&pci->pp); + + pci->suspended = true; + + return ret; +} +EXPORT_SYMBOL_GPL(dw_pcie_suspend_noirq); + +int dw_pcie_resume_noirq(struct dw_pcie *pci) +{ + int ret; + + if (!pci->suspended) + return 0; + + pci->suspended = false; + + if (pci->pp.ops->host_init) { + ret = pci->pp.ops->host_init(&pci->pp); + if (ret) { + dev_err(pci->dev, "Host init failed: %d\n", ret); + return ret; + } + } + + dw_pcie_setup_rc(&pci->pp); + + ret = dw_pcie_start_link(pci); + if (ret) + return ret; + + ret = dw_pcie_wait_for_link(pci); + if (ret) + return ret; + + return ret; +} +EXPORT_SYMBOL_GPL(dw_pcie_resume_noirq); diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h index 615660640801..91d13f9b21b1 100644 --- a/drivers/pci/controller/dwc/pcie-designware.h +++ b/drivers/pci/controller/dwc/pcie-designware.h @@ -288,10 +288,21 @@ enum dw_pcie_core_rst { DW_PCIE_NUM_CORE_RSTS }; +enum dw_pcie_ltssm { + /* Need to align with PCIE_PORT_DEBUG0 bits 0:5 */ + DW_PCIE_LTSSM_DETECT_QUIET = 0x0, + DW_PCIE_LTSSM_DETECT_ACT = 0x1, + DW_PCIE_LTSSM_L0 = 0x11, + DW_PCIE_LTSSM_L2_IDLE = 0x15, + + DW_PCIE_LTSSM_UNKNOWN = 0xFFFFFFFF, +}; + struct dw_pcie_host_ops { int (*host_init)(struct dw_pcie_rp *pp); void (*host_deinit)(struct dw_pcie_rp *pp); int (*msi_host_init)(struct dw_pcie_rp *pp); + void (*pme_turn_off)(struct dw_pcie_rp *pp); }; struct dw_pcie_rp { @@ -364,6 +375,7 @@ struct dw_pcie_ops { void (*write_dbi2)(struct dw_pcie *pcie, void __iomem *base, u32 reg, size_t size, u32 val); int (*link_up)(struct dw_pcie *pcie); + enum dw_pcie_ltssm (*get_ltssm)(struct dw_pcie *pcie); int (*start_link)(struct dw_pcie *pcie); void (*stop_link)(struct dw_pcie *pcie); }; @@ -393,6 +405,7 @@ struct dw_pcie { struct reset_control_bulk_data app_rsts[DW_PCIE_NUM_APP_RSTS]; struct reset_control_bulk_data core_rsts[DW_PCIE_NUM_CORE_RSTS]; struct gpio_desc *pe_rst; + bool suspended; }; #define to_dw_pcie_from_pp(port) container_of((port), struct dw_pcie, pp) @@ -431,6 +444,9 @@ int dw_pcie_edma_detect(struct dw_pcie *pci); void dw_pcie_edma_remove(struct dw_pcie *pci); void dw_pcie_print_link_status(struct dw_pcie *pci); +int dw_pcie_suspend_noirq(struct dw_pcie *pci); +int dw_pcie_resume_noirq(struct dw_pcie *pci); + static inline void dw_pcie_writel_dbi(struct dw_pcie *pci, u32 reg, u32 val) { dw_pcie_write_dbi(pci, reg, 0x4, val); @@ -502,6 +518,18 @@ static inline void dw_pcie_stop_link(struct dw_pcie *pci) pci->ops->stop_link(pci); } +static inline enum dw_pcie_ltssm dw_pcie_get_ltssm(struct dw_pcie *pci) +{ + u32 val; + + if (pci->ops && pci->ops->get_ltssm) + return pci->ops->get_ltssm(pci); + + val = dw_pcie_readl_dbi(pci, PCIE_PORT_DEBUG0); + + return (enum dw_pcie_ltssm)FIELD_GET(PORT_LOGIC_LTSSM_STATE_MASK, val); +} + #ifdef CONFIG_PCIE_DW_HOST irqreturn_t dw_handle_msi_irq(struct dw_pcie_rp *pp); int dw_pcie_setup_rc(struct dw_pcie_rp *pp); -- cgit v1.2.3 From 9fda4d09905db9ecae17ad741924a7530aa3c96e Mon Sep 17 00:00:00 2001 From: Hou Zhiqiang Date: Mon, 21 Aug 2023 14:48:15 -0400 Subject: PCI: layerscape: Add power management support for ls1028a Add PME_Turn_off/PME_TO_Ack handshake sequence for ls1028a platform. Implemented on top of common dwc dw_pcie_suspend(resume)_noirq() functions to handle system enter/exit suspend states. Link: https://lore.kernel.org/r/20230821184815.2167131-4-Frank.Li@nxp.com Signed-off-by: Hou Zhiqiang Signed-off-by: Frank Li Signed-off-by: Lorenzo Pieralisi Acked-by: Manivannan Sadhasivam --- drivers/pci/controller/dwc/pci-layerscape.c | 140 ++++++++++++++++++++++++++-- 1 file changed, 131 insertions(+), 9 deletions(-) (limited to 'drivers/pci/controller/dwc') diff --git a/drivers/pci/controller/dwc/pci-layerscape.c b/drivers/pci/controller/dwc/pci-layerscape.c index ed5fb492fe08..b931d597656f 100644 --- a/drivers/pci/controller/dwc/pci-layerscape.c +++ b/drivers/pci/controller/dwc/pci-layerscape.c @@ -8,9 +8,11 @@ * Author: Minghuan Lian */ +#include #include #include #include +#include #include #include #include @@ -20,6 +22,7 @@ #include #include +#include "../../pci.h" #include "pcie-designware.h" /* PEX Internal Configuration Registers */ @@ -27,12 +30,26 @@ #define PCIE_ABSERR 0x8d0 /* Bridge Slave Error Response Register */ #define PCIE_ABSERR_SETTING 0x9401 /* Forward error of non-posted request */ +/* PF Message Command Register */ +#define LS_PCIE_PF_MCR 0x2c +#define PF_MCR_PTOMR BIT(0) +#define PF_MCR_EXL2S BIT(1) + #define PCIE_IATU_NUM 6 +struct ls_pcie_drvdata { + const u32 pf_off; + bool pm_support; +}; + struct ls_pcie { struct dw_pcie *pci; + const struct ls_pcie_drvdata *drvdata; + void __iomem *pf_base; + bool big_endian; }; +#define ls_pcie_pf_readl_addr(addr) ls_pcie_pf_readl(pcie, addr) #define to_ls_pcie(x) dev_get_drvdata((x)->dev) static bool ls_pcie_is_bridge(struct ls_pcie *pcie) @@ -73,6 +90,68 @@ static void ls_pcie_fix_error_response(struct ls_pcie *pcie) iowrite32(PCIE_ABSERR_SETTING, pci->dbi_base + PCIE_ABSERR); } +static u32 ls_pcie_pf_readl(struct ls_pcie *pcie, u32 off) +{ + if (pcie->big_endian) + return ioread32be(pcie->pf_base + off); + + return ioread32(pcie->pf_base + off); +} + +static void ls_pcie_pf_writel(struct ls_pcie *pcie, u32 off, u32 val) +{ + if (pcie->big_endian) + iowrite32be(val, pcie->pf_base + off); + else + iowrite32(val, pcie->pf_base + off); +} + +static void ls_pcie_send_turnoff_msg(struct dw_pcie_rp *pp) +{ + struct dw_pcie *pci = to_dw_pcie_from_pp(pp); + struct ls_pcie *pcie = to_ls_pcie(pci); + u32 val; + int ret; + + val = ls_pcie_pf_readl(pcie, LS_PCIE_PF_MCR); + val |= PF_MCR_PTOMR; + ls_pcie_pf_writel(pcie, LS_PCIE_PF_MCR, val); + + ret = readx_poll_timeout(ls_pcie_pf_readl_addr, LS_PCIE_PF_MCR, + val, !(val & PF_MCR_PTOMR), + PCIE_PME_TO_L2_TIMEOUT_US/10, + PCIE_PME_TO_L2_TIMEOUT_US); + if (ret) + dev_err(pcie->pci->dev, "PME_Turn_off timeout\n"); +} + +static void ls_pcie_exit_from_l2(struct dw_pcie_rp *pp) +{ + struct dw_pcie *pci = to_dw_pcie_from_pp(pp); + struct ls_pcie *pcie = to_ls_pcie(pci); + u32 val; + int ret; + + /* + * Set PF_MCR_EXL2S bit in LS_PCIE_PF_MCR register for the link + * to exit L2 state. + */ + val = ls_pcie_pf_readl(pcie, LS_PCIE_PF_MCR); + val |= PF_MCR_EXL2S; + ls_pcie_pf_writel(pcie, LS_PCIE_PF_MCR, val); + + /* + * L2 exit timeout of 10ms is not defined in the specifications, + * it was chosen based on empirical observations. + */ + ret = readx_poll_timeout(ls_pcie_pf_readl_addr, LS_PCIE_PF_MCR, + val, !(val & PF_MCR_EXL2S), + 1000, + 10000); + if (ret) + dev_err(pcie->pci->dev, "L2 exit timeout\n"); +} + static int ls_pcie_host_init(struct dw_pcie_rp *pp) { struct dw_pcie *pci = to_dw_pcie_from_pp(pp); @@ -91,18 +170,28 @@ static int ls_pcie_host_init(struct dw_pcie_rp *pp) static const struct dw_pcie_host_ops ls_pcie_host_ops = { .host_init = ls_pcie_host_init, + .pme_turn_off = ls_pcie_send_turnoff_msg, +}; + +static const struct ls_pcie_drvdata ls1021a_drvdata = { + .pm_support = false, +}; + +static const struct ls_pcie_drvdata layerscape_drvdata = { + .pf_off = 0xc0000, + .pm_support = true, }; static const struct of_device_id ls_pcie_of_match[] = { - { .compatible = "fsl,ls1012a-pcie", }, - { .compatible = "fsl,ls1021a-pcie", }, - { .compatible = "fsl,ls1028a-pcie", }, - { .compatible = "fsl,ls1043a-pcie", }, - { .compatible = "fsl,ls1046a-pcie", }, - { .compatible = "fsl,ls2080a-pcie", }, - { .compatible = "fsl,ls2085a-pcie", }, - { .compatible = "fsl,ls2088a-pcie", }, - { .compatible = "fsl,ls1088a-pcie", }, + { .compatible = "fsl,ls1012a-pcie", .data = &layerscape_drvdata }, + { .compatible = "fsl,ls1021a-pcie", .data = &ls1021a_drvdata }, + { .compatible = "fsl,ls1028a-pcie", .data = &layerscape_drvdata }, + { .compatible = "fsl,ls1043a-pcie", .data = &ls1021a_drvdata }, + { .compatible = "fsl,ls1046a-pcie", .data = &layerscape_drvdata }, + { .compatible = "fsl,ls2080a-pcie", .data = &layerscape_drvdata }, + { .compatible = "fsl,ls2085a-pcie", .data = &layerscape_drvdata }, + { .compatible = "fsl,ls2088a-pcie", .data = &layerscape_drvdata }, + { .compatible = "fsl,ls1088a-pcie", .data = &layerscape_drvdata }, { }, }; @@ -121,6 +210,8 @@ static int ls_pcie_probe(struct platform_device *pdev) if (!pci) return -ENOMEM; + pcie->drvdata = of_device_get_match_data(dev); + pci->dev = dev; pci->pp.ops = &ls_pcie_host_ops; @@ -131,6 +222,10 @@ static int ls_pcie_probe(struct platform_device *pdev) if (IS_ERR(pci->dbi_base)) return PTR_ERR(pci->dbi_base); + pcie->big_endian = of_property_read_bool(dev->of_node, "big-endian"); + + pcie->pf_base = pci->dbi_base + pcie->drvdata->pf_off; + if (!ls_pcie_is_bridge(pcie)) return -ENODEV; @@ -139,12 +234,39 @@ static int ls_pcie_probe(struct platform_device *pdev) return dw_pcie_host_init(&pci->pp); } +static int ls_pcie_suspend_noirq(struct device *dev) +{ + struct ls_pcie *pcie = dev_get_drvdata(dev); + + if (!pcie->drvdata->pm_support) + return 0; + + return dw_pcie_suspend_noirq(pcie->pci); +} + +static int ls_pcie_resume_noirq(struct device *dev) +{ + struct ls_pcie *pcie = dev_get_drvdata(dev); + + if (!pcie->drvdata->pm_support) + return 0; + + ls_pcie_exit_from_l2(&pcie->pci->pp); + + return dw_pcie_resume_noirq(pcie->pci); +} + +static const struct dev_pm_ops ls_pcie_pm_ops = { + NOIRQ_SYSTEM_SLEEP_PM_OPS(ls_pcie_suspend_noirq, ls_pcie_resume_noirq) +}; + static struct platform_driver ls_pcie_driver = { .probe = ls_pcie_probe, .driver = { .name = "layerscape-pcie", .of_match_table = ls_pcie_of_match, .suppress_bind_attrs = true, + .pm = &ls_pcie_pm_ops, }, }; builtin_platform_driver(ls_pcie_driver); -- cgit v1.2.3 From 8cd2b8ce48e52bfda76a04be9aef8c1b176693d9 Mon Sep 17 00:00:00 2001 From: Manivannan Sadhasivam Date: Mon, 17 Jul 2023 12:24:53 +0530 Subject: PCI: qcom-ep: Pass alignment restriction to the EPF core MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Qcom PCIe EP controllers have 4K alignment restriction for the outbound window address. Hence, pass this info to the EPF core so that the EPF drivers can make use of this info. Link: https://lore.kernel.org/linux-pci/20230717065459.14138-2-manivannan.sadhasivam@linaro.org Signed-off-by: Manivannan Sadhasivam Signed-off-by: Krzysztof Wilczyński --- drivers/pci/controller/dwc/pcie-qcom-ep.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/pci/controller/dwc') diff --git a/drivers/pci/controller/dwc/pcie-qcom-ep.c b/drivers/pci/controller/dwc/pcie-qcom-ep.c index 0fe7f06f2102..736be5bee458 100644 --- a/drivers/pci/controller/dwc/pcie-qcom-ep.c +++ b/drivers/pci/controller/dwc/pcie-qcom-ep.c @@ -706,6 +706,7 @@ static const struct pci_epc_features qcom_pcie_epc_features = { .core_init_notifier = true, .msi_capable = true, .msix_capable = false, + .align = SZ_4K, }; static const struct pci_epc_features * -- cgit v1.2.3 From d60379d65d2b908818d99541753d74f99645da51 Mon Sep 17 00:00:00 2001 From: Mrinmay Sarkar Date: Fri, 21 Jul 2023 22:54:33 +0530 Subject: PCI: qcom: Add support for sa8775p SoC MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add support for sa8775p SoC that uses controller version 5.90 reusing the 1.9.0 config. Link: https://lore.kernel.org/linux-pci/1689960276-29266-3-git-send-email-quic_msarkar@quicinc.com Signed-off-by: Mrinmay Sarkar Signed-off-by: Krzysztof Wilczyński Reviewed-by: Bjorn Andersson Reviewed-by: Manivannan Sadhasivam --- drivers/pci/controller/dwc/pcie-qcom.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/pci/controller/dwc') diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c index 7a87a47eb7ed..3c3de787f5a3 100644 --- a/drivers/pci/controller/dwc/pcie-qcom.c +++ b/drivers/pci/controller/dwc/pcie-qcom.c @@ -1613,6 +1613,7 @@ static const struct of_device_id qcom_pcie_match[] = { { .compatible = "qcom,pcie-msm8996", .data = &cfg_2_3_2 }, { .compatible = "qcom,pcie-qcs404", .data = &cfg_2_4_0 }, { .compatible = "qcom,pcie-sa8540p", .data = &cfg_1_9_0 }, + { .compatible = "qcom,pcie-sa8775p", .data = &cfg_1_9_0}, { .compatible = "qcom,pcie-sc7280", .data = &cfg_1_9_0 }, { .compatible = "qcom,pcie-sc8180x", .data = &cfg_1_9_0 }, { .compatible = "qcom,pcie-sc8280xp", .data = &cfg_1_9_0 }, -- cgit v1.2.3 From ff8d92038cf92c886873c0e0628ba1272e6a087c Mon Sep 17 00:00:00 2001 From: Manivannan Sadhasivam Date: Mon, 17 Jul 2023 12:24:55 +0530 Subject: PCI: qcom-ep: Add eDMA support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Qualcomm PCIe Endpoint controllers have the in-built Embedded DMA (eDMA) peripheral for offloading the data transfer between the PCIe bus and memory. Let's add support for it by enabling the eDMA IRQ in the driver. The eDMA DMA Engine driver will handle the rest of the functionality. Since the eDMA on Qualcomm platforms only uses a single IRQ for all channels, use 1 for edma.nr_irqs. [kwilczynski: commit log] Link: https://lore.kernel.org/linux-pci/20230717065459.14138-4-manivannan.sadhasivam@linaro.org Signed-off-by: Manivannan Sadhasivam Signed-off-by: Krzysztof Wilczyński --- drivers/pci/controller/dwc/pcie-qcom-ep.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/pci/controller/dwc') diff --git a/drivers/pci/controller/dwc/pcie-qcom-ep.c b/drivers/pci/controller/dwc/pcie-qcom-ep.c index 736be5bee458..1baec81183b6 100644 --- a/drivers/pci/controller/dwc/pcie-qcom-ep.c +++ b/drivers/pci/controller/dwc/pcie-qcom-ep.c @@ -74,6 +74,7 @@ #define PARF_INT_ALL_PLS_ERR BIT(15) #define PARF_INT_ALL_PME_LEGACY BIT(16) #define PARF_INT_ALL_PLS_PME BIT(17) +#define PARF_INT_ALL_EDMA BIT(22) /* PARF_BDF_TO_SID_CFG register fields */ #define PARF_BDF_TO_SID_BYPASS BIT(0) @@ -395,7 +396,7 @@ static int qcom_pcie_perst_deassert(struct dw_pcie *pci) writel_relaxed(0, pcie_ep->parf + PARF_INT_ALL_MASK); val = PARF_INT_ALL_LINK_DOWN | PARF_INT_ALL_BME | PARF_INT_ALL_PM_TURNOFF | PARF_INT_ALL_DSTATE_CHANGE | - PARF_INT_ALL_LINK_UP; + PARF_INT_ALL_LINK_UP | PARF_INT_ALL_EDMA; writel_relaxed(val, pcie_ep->parf + PARF_INT_ALL_MASK); ret = dw_pcie_ep_init_complete(&pcie_ep->pci.ep); @@ -744,6 +745,7 @@ static int qcom_pcie_ep_probe(struct platform_device *pdev) pcie_ep->pci.dev = dev; pcie_ep->pci.ops = &pci_ops; pcie_ep->pci.ep.ops = &pci_ep_ops; + pcie_ep->pci.edma.nr_irqs = 1; platform_set_drvdata(pdev, pcie_ep); ret = qcom_pcie_ep_get_resources(pdev, pcie_ep); -- cgit v1.2.3 From 823de40c94d680ec8d57a660ac96a653acadb0a5 Mon Sep 17 00:00:00 2001 From: Manivannan Sadhasivam Date: Wed, 26 Jul 2023 20:59:31 +0530 Subject: PCI: qcom-ep: Treat unknown IRQ events as an error MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sometimes, the Qcom PCIe EP controller can receive some interrupts unknown to the driver, like safety interrupts in newer SoCs. In those cases, if the driver doesn't clear the interrupts, it will end up in an interrupt storm. However, the users will not know about it because the log is treated as a debug message. So let's treat the unknown event log as an error so that it at least makes the user aware, thereby getting fixed eventually. [kwilczynski: commit log] Link: https://lore.kernel.org/linux-pci/20230726152931.18134-1-manivannan.sadhasivam@linaro.org Signed-off-by: Manivannan Sadhasivam Signed-off-by: Krzysztof Wilczyński --- drivers/pci/controller/dwc/pcie-qcom-ep.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/pci/controller/dwc') diff --git a/drivers/pci/controller/dwc/pcie-qcom-ep.c b/drivers/pci/controller/dwc/pcie-qcom-ep.c index 0fe7f06f2102..86929a7a104e 100644 --- a/drivers/pci/controller/dwc/pcie-qcom-ep.c +++ b/drivers/pci/controller/dwc/pcie-qcom-ep.c @@ -593,7 +593,7 @@ static irqreturn_t qcom_pcie_ep_global_irq_thread(int irq, void *data) dw_pcie_ep_linkup(&pci->ep); pcie_ep->link_status = QCOM_PCIE_EP_LINK_UP; } else { - dev_dbg(dev, "Received unknown event: %d\n", status); + dev_err(dev, "Received unknown event: %d\n", status); } return IRQ_HANDLED; -- cgit v1.2.3 From 01794236666abef69a07b48fa0948c4157d7ca70 Mon Sep 17 00:00:00 2001 From: Krishna chaitanya chundru Date: Wed, 19 Jul 2023 12:50:18 +0530 Subject: PCI: qcom-ep: Add ICC bandwidth voting support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add support for voting interconnect (ICC) bandwidth based on the link speed and width. This commit is inspired from the basic interconnect support added to pcie-qcom driver in commit c4860af88d0c ("PCI: qcom: Add basic interconnect support"). The interconnect support is kept optional to be backward compatible with legacy device trees. [kwilczynski: add missing kernel-doc for the icc_mem variable] Link: https://lore.kernel.org/linux-pci/1689751218-24492-5-git-send-email-quic_krichai@quicinc.com Signed-off-by: Krishna chaitanya chundru Signed-off-by: Krzysztof Wilczyński Reviewed-by: Manivannan Sadhasivam --- drivers/pci/controller/dwc/pcie-qcom-ep.c | 72 +++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) (limited to 'drivers/pci/controller/dwc') diff --git a/drivers/pci/controller/dwc/pcie-qcom-ep.c b/drivers/pci/controller/dwc/pcie-qcom-ep.c index 86929a7a104e..38f1a1b75039 100644 --- a/drivers/pci/controller/dwc/pcie-qcom-ep.c +++ b/drivers/pci/controller/dwc/pcie-qcom-ep.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -133,6 +134,11 @@ #define CORE_RESET_TIME_US_MAX 1005 #define WAKE_DELAY_US 2000 /* 2 ms */ +#define PCIE_GEN1_BW_MBPS 250 +#define PCIE_GEN2_BW_MBPS 500 +#define PCIE_GEN3_BW_MBPS 985 +#define PCIE_GEN4_BW_MBPS 1969 + #define to_pcie_ep(x) dev_get_drvdata((x)->dev) enum qcom_pcie_ep_link_status { @@ -155,6 +161,7 @@ enum qcom_pcie_ep_link_status { * @wake: WAKE# GPIO * @phy: PHY controller block * @debugfs: PCIe Endpoint Debugfs directory + * @icc_mem: Handle to an interconnect path between PCIe and MEM * @clks: PCIe clocks * @num_clks: PCIe clocks count * @perst_en: Flag for PERST enable @@ -178,6 +185,8 @@ struct qcom_pcie_ep { struct phy *phy; struct dentry *debugfs; + struct icc_path *icc_mem; + struct clk_bulk_data *clks; int num_clks; @@ -253,8 +262,49 @@ static void qcom_pcie_dw_stop_link(struct dw_pcie *pci) disable_irq(pcie_ep->perst_irq); } +static void qcom_pcie_ep_icc_update(struct qcom_pcie_ep *pcie_ep) +{ + struct dw_pcie *pci = &pcie_ep->pci; + u32 offset, status, bw; + int speed, width; + int ret; + + if (!pcie_ep->icc_mem) + return; + + offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP); + status = readw(pci->dbi_base + offset + PCI_EXP_LNKSTA); + + speed = FIELD_GET(PCI_EXP_LNKSTA_CLS, status); + width = FIELD_GET(PCI_EXP_LNKSTA_NLW, status); + + switch (speed) { + case 1: + bw = MBps_to_icc(PCIE_GEN1_BW_MBPS); + break; + case 2: + bw = MBps_to_icc(PCIE_GEN2_BW_MBPS); + break; + case 3: + bw = MBps_to_icc(PCIE_GEN3_BW_MBPS); + break; + default: + dev_warn(pci->dev, "using default GEN4 bandwidth\n"); + fallthrough; + case 4: + bw = MBps_to_icc(PCIE_GEN4_BW_MBPS); + break; + } + + ret = icc_set_bw(pcie_ep->icc_mem, 0, width * bw); + if (ret) + dev_err(pci->dev, "failed to set interconnect bandwidth: %d\n", + ret); +} + static int qcom_pcie_enable_resources(struct qcom_pcie_ep *pcie_ep) { + struct dw_pcie *pci = &pcie_ep->pci; int ret; ret = clk_bulk_prepare_enable(pcie_ep->num_clks, pcie_ep->clks); @@ -277,8 +327,24 @@ static int qcom_pcie_enable_resources(struct qcom_pcie_ep *pcie_ep) if (ret) goto err_phy_exit; + /* + * Some Qualcomm platforms require interconnect bandwidth constraints + * to be set before enabling interconnect clocks. + * + * Set an initial peak bandwidth corresponding to single-lane Gen 1 + * for the pcie-mem path. + */ + ret = icc_set_bw(pcie_ep->icc_mem, 0, MBps_to_icc(PCIE_GEN1_BW_MBPS)); + if (ret) { + dev_err(pci->dev, "failed to set interconnect bandwidth: %d\n", + ret); + goto err_phy_off; + } + return 0; +err_phy_off: + phy_power_off(pcie_ep->phy); err_phy_exit: phy_exit(pcie_ep->phy); err_disable_clk: @@ -289,6 +355,7 @@ err_disable_clk: static void qcom_pcie_disable_resources(struct qcom_pcie_ep *pcie_ep) { + icc_set_bw(pcie_ep->icc_mem, 0, 0); phy_power_off(pcie_ep->phy); phy_exit(pcie_ep->phy); clk_bulk_disable_unprepare(pcie_ep->num_clks, pcie_ep->clks); @@ -550,6 +617,10 @@ static int qcom_pcie_ep_get_resources(struct platform_device *pdev, if (IS_ERR(pcie_ep->phy)) ret = PTR_ERR(pcie_ep->phy); + pcie_ep->icc_mem = devm_of_icc_get(dev, "pcie-mem"); + if (IS_ERR(pcie_ep->icc_mem)) + ret = PTR_ERR(pcie_ep->icc_mem); + return ret; } @@ -573,6 +644,7 @@ static irqreturn_t qcom_pcie_ep_global_irq_thread(int irq, void *data) } else if (FIELD_GET(PARF_INT_ALL_BME, status)) { dev_dbg(dev, "Received BME event. Link is enabled!\n"); pcie_ep->link_status = QCOM_PCIE_EP_LINK_ENABLED; + qcom_pcie_ep_icc_update(pcie_ep); pci_epc_bme_notify(pci->ep.epc); } else if (FIELD_GET(PARF_INT_ALL_PM_TURNOFF, status)) { dev_dbg(dev, "Received PM Turn-off event! Entering L23\n"); -- cgit v1.2.3