summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Zhu <hongxing.zhu@nxp.com>2026-01-14 11:33:00 +0300
committerManivannan Sadhasivam <mani@kernel.org>2026-01-21 12:37:39 +0300
commit58a17b2647ba5aac47e3ffafd0a9b92bf4a9bcbe (patch)
tree3b595a68d3689743dce452900cd19deea7af13f2
parent86cbb7a81068434fdc1d5afb96d91ab971fb279e (diff)
downloadlinux-58a17b2647ba5aac47e3ffafd0a9b92bf4a9bcbe.tar.xz
PCI: dwc: Skip waiting for L2/L3 Ready if dw_pcie_rp::skip_l23_wait is true
In NXP i.MX6QP and i.MX7D SoCs, LTSSM registers are not accessible once PME_Turn_Off message is broadcasted to the link. So there is no way to verify whether the link has entered L2/L3 Ready state or not. Hence, add a new flag 'dw_pcie_rp::skip_l23_ready' and set it to 'true' for the above mentioned SoCs. This flag when set, will allow the DWC core to skip polling for L2/L3 Ready state and just wait for 10ms as recommended in the PCIe spec r6.0, sec 5.3.3.2.1. Fixes: a528d1a72597 ("PCI: imx6: Use DWC common suspend resume method") Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com> [mani: renamed flag to skip_l23_ready and reworded description] Signed-off-by: Manivannan Sadhasivam <mani@kernel.org> Reviewed-by: Frank Li <Frank.Li@nxp.com> Cc: stable@vger.kernel.org Link: https://patch.msgid.link/20260114083300.3689672-2-hongxing.zhu@nxp.com
-rw-r--r--drivers/pci/controller/dwc/pci-imx6.c5
-rw-r--r--drivers/pci/controller/dwc/pcie-designware-host.c10
-rw-r--r--drivers/pci/controller/dwc/pcie-designware.h1
3 files changed, 16 insertions, 0 deletions
diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
index 4668fc9648bf..dfe814469993 100644
--- a/drivers/pci/controller/dwc/pci-imx6.c
+++ b/drivers/pci/controller/dwc/pci-imx6.c
@@ -114,6 +114,7 @@ enum imx_pcie_variants {
#define IMX_PCIE_FLAG_BROKEN_SUSPEND BIT(9)
#define IMX_PCIE_FLAG_HAS_LUT BIT(10)
#define IMX_PCIE_FLAG_8GT_ECN_ERR051586 BIT(11)
+#define IMX_PCIE_FLAG_SKIP_L23_READY BIT(12)
#define imx_check_flag(pci, val) (pci->drvdata->flags & val)
@@ -1777,6 +1778,8 @@ static int imx_pcie_probe(struct platform_device *pdev)
*/
imx_pcie_add_lut_by_rid(imx_pcie, 0);
} else {
+ if (imx_check_flag(imx_pcie, IMX_PCIE_FLAG_SKIP_L23_READY))
+ pci->pp.skip_l23_ready = true;
pci->pp.use_atu_msg = true;
ret = dw_pcie_host_init(&pci->pp);
if (ret < 0)
@@ -1838,6 +1841,7 @@ static const struct imx_pcie_drvdata drvdata[] = {
.variant = IMX6QP,
.flags = IMX_PCIE_FLAG_IMX_PHY |
IMX_PCIE_FLAG_SPEED_CHANGE_WORKAROUND |
+ IMX_PCIE_FLAG_SKIP_L23_READY |
IMX_PCIE_FLAG_SUPPORTS_SUSPEND,
.dbi_length = 0x200,
.gpr = "fsl,imx6q-iomuxc-gpr",
@@ -1854,6 +1858,7 @@ static const struct imx_pcie_drvdata drvdata[] = {
.variant = IMX7D,
.flags = IMX_PCIE_FLAG_SUPPORTS_SUSPEND |
IMX_PCIE_FLAG_HAS_APP_RESET |
+ IMX_PCIE_FLAG_SKIP_L23_READY |
IMX_PCIE_FLAG_HAS_PHY_RESET,
.gpr = "fsl,imx7d-iomuxc-gpr",
.mode_off[0] = IOMUXC_GPR12,
diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
index a72406ef7e26..a17833dd6f9d 100644
--- a/drivers/pci/controller/dwc/pcie-designware-host.c
+++ b/drivers/pci/controller/dwc/pcie-designware-host.c
@@ -1199,6 +1199,16 @@ int dw_pcie_suspend_noirq(struct dw_pcie *pci)
return ret;
}
+ /*
+ * Some SoCs do not support reading the LTSSM register after
+ * PME_Turn_Off broadcast. For those SoCs, skip waiting for L2/L3 Ready
+ * state and wait 10ms as recommended in PCIe spec r6.0, sec 5.3.3.2.1.
+ */
+ if (pci->pp.skip_l23_ready) {
+ mdelay(PCIE_PME_TO_L2_TIMEOUT_US/1000);
+ goto stop_link;
+ }
+
ret = read_poll_timeout(dw_pcie_get_ltssm, val,
val == DW_PCIE_LTSSM_L2_IDLE ||
val <= DW_PCIE_LTSSM_DETECT_WAIT,
diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
index c1def4d9cf62..ec4b7a689f59 100644
--- a/drivers/pci/controller/dwc/pcie-designware.h
+++ b/drivers/pci/controller/dwc/pcie-designware.h
@@ -442,6 +442,7 @@ struct dw_pcie_rp {
struct pci_config_window *cfg;
bool ecam_enabled;
bool native_ecam;
+ bool skip_l23_ready;
};
struct dw_pcie_ep_ops {