Commit 58a17b26 authored by Richard Zhu's avatar Richard Zhu Committed by Manivannan Sadhasivam
Browse files

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: a528d1a7 ("PCI: imx6: Use DWC common suspend resume method")
Signed-off-by: default avatarRichard Zhu <hongxing.zhu@nxp.com>
[mani: renamed flag to skip_l23_ready and reworded description]
Signed-off-by: default avatarManivannan Sadhasivam <mani@kernel.org>
Reviewed-by: default avatarFrank Li <Frank.Li@nxp.com>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260114083300.3689672-2-hongxing.zhu@nxp.com
parent 86cbb7a8
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -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,
+10 −0
Original line number Diff line number Diff line
@@ -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,
+1 −0
Original line number Diff line number Diff line
@@ -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 {