[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <drqhmcl5vzuk7dx5g4fjhrsfstu2tssmmotychgyf3vcus2tz5@rqsrsrbpjc2o>
Date: Wed, 21 Jan 2026 13:23:57 +0530
From: Manivannan Sadhasivam <mani@...nel.org>
To: Richard Zhu <hongxing.zhu@....com>
Cc: frank.li@....com, jingoohan1@...il.com, l.stach@...gutronix.de,
lpieralisi@...nel.org, kwilczynski@...nel.org, robh@...nel.org, bhelgaas@...gle.com,
shawnguo@...nel.org, s.hauer@...gutronix.de, kernel@...gutronix.de,
festevam@...il.com, linux-pci@...r.kernel.org, linux-arm-kernel@...ts.infradead.org,
imx@...ts.linux.dev, linux-kernel@...r.kernel.org, stable@...r.kernel.org
Subject: Re: [PATCH v9] PCI: dwc: Don't poll L2 if skip_l23_wait is true
On Wed, Jan 14, 2026 at 04:33:00PM +0800, Richard Zhu wrote:
> Refer to PCIe r6.0, sec 5.2, fig 5-1 Link Power Management State Flow
> Diagram. Both L0 and L2/L3 Ready can be transferred to LDn directly.
>
> It's harmless to let dw_pcie_suspend_noirq() proceed suspend after the
> PME_Turn_Off is sent out, whatever the LTSSM state is in L2 or L3 after
> a recommended 10ms max wait refer to PCIe r6.0, sec 5.3.3.2.1 PME
> Synchronization.
>
> The LTSSM states are inaccessible on i.MX6QP and i.MX7D after the
> PME_Turn_Off is sent out.
>
> To support this case, don't poll L2 state and apply a simple delay of
> PCIE_PME_TO_L2_TIMEOUT_US(10ms) if the skip_l23_wait flag is true in
> suspend.
>
I think this patch should simply say:
"In i.MX6QP and i.MX7D SoCs, LTSSM registers are not accessible once
PME_Turn_Off is broadcasted to the link. So there is no way to verify whether
the link has entered L2/L3 state or not.
Hence, add a new flag 'dw_pcie_rp::skip_l23_wait' and set it for the above
mentioned SoCs. This flag when set, will allow the DWC core to skip the L23 poll
and just wait for 10ms as per the delay mentioned in PCIe spec r6.0 sec
5.3.3.2.1."
Does it look good?
- Mani
> Cc: stable@...r.kernel.org
> Fixes: 4774faf854f5 ("PCI: dwc: Implement generic suspend/resume functionality")
> Fixes: a528d1a72597 ("PCI: imx6: Use DWC common suspend resume method")
> Signed-off-by: Richard Zhu <hongxing.zhu@....com>
> Reviewed-by: Frank Li <Frank.Li@....com>
> ---
> drivers/pci/controller/dwc/pci-imx6.c | 5 +++++
> drivers/pci/controller/dwc/pcie-designware-host.c | 15 +++++++++++++++
> drivers/pci/controller/dwc/pcie-designware.h | 1 +
> 3 files changed, 21 insertions(+)
>
> diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
> index 4668fc9648bf..cbe98824427b 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_WAIT 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_WAIT))
> + pci->pp.skip_l23_wait = 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_WAIT |
> 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_WAIT |
> 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 fad0cbedefbc..5aa7f23bb58e 100644
> --- a/drivers/pci/controller/dwc/pcie-designware-host.c
> +++ b/drivers/pci/controller/dwc/pcie-designware-host.c
> @@ -1194,6 +1194,21 @@ int dw_pcie_suspend_noirq(struct dw_pcie *pci)
> return ret;
> }
>
> + /*
> + * Skip L23 poll and wait to avoid the read hang, when LTSSM is
> + * not powered in L2/L3/LDn properly.
> + *
> + * Refer to PCIe r6.0, sec 5.2, fig 5-1 Link Power Management
> + * State Flow Diagram. Both L0 and L2/L3 Ready can be
> + * transferred to LDn directly. On the LTSSM states poll broken
> + * platforms, add a max 10ms delay refer to PCIe r6.0,
> + * sec 5.3.3.2.1 PME Synchronization.
> + */
> + if (pci->pp.skip_l23_wait) {
> + 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 f87c67a7a482..b31f8061f23a 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_wait;
> };
>
> struct dw_pcie_ep_ops {
> --
> 2.37.1
>
--
மணிவண்ணன் சதாசிவம்
Powered by blists - more mailing lists