Thread (17 messages) 17 messages, 2 authors, 2025-09-23

RE: [PATCH v5 2/6] PCI: dwc: Don't poll L2 if QUIRK_NOL2POLL_IN_PM is existing in suspend

From: Hongxing Zhu <hongxing.zhu@nxp.com>
Date: 2025-09-23 09:11:41
Also in: imx, linux-pci, lkml

-----Original Message-----
From: Manivannan Sadhasivam <mani@kernel.org>
Sent: 2025年9月22日 19:26
To: Hongxing Zhu <hongxing.zhu@nxp.com>
Cc: Frank Li <frank.li@nxp.com>; jingoohan1@gmail.com;
l.stach@pengutronix.de; lpieralisi@kernel.org; kwilczynski@kernel.org;
robh@kernel.org; bhelgaas@google.com; shawnguo@kernel.org;
s.hauer@pengutronix.de; kernel@pengutronix.de; festevam@gmail.com;
linux-pci@vger.kernel.org; linux-arm-kernel@lists.infradead.org;
imx@lists.linux.dev; linux-kernel@vger.kernel.org
Subject: Re: [PATCH v5 2/6] PCI: dwc: Don't poll L2 if QUIRK_NOL2POLL_IN_PM
is existing in suspend

On Mon, Sep 22, 2025 at 09:18:20AM +0000, Hongxing Zhu wrote:
quoted
quoted
-----Original Message-----
From: Manivannan Sadhasivam <mani@kernel.org>
Sent: 2025年9月20日 14:29
To: Hongxing Zhu <hongxing.zhu@nxp.com>
Cc: Frank Li <frank.li@nxp.com>; jingoohan1@gmail.com;
l.stach@pengutronix.de; lpieralisi@kernel.org;
kwilczynski@kernel.org; robh@kernel.org; bhelgaas@google.com;
shawnguo@kernel.org; s.hauer@pengutronix.de; kernel@pengutronix.de;
festevam@gmail.com; linux-pci@vger.kernel.org;
linux-arm-kernel@lists.infradead.org;
imx@lists.linux.dev; linux-kernel@vger.kernel.org
Subject: Re: [PATCH v5 2/6] PCI: dwc: Don't poll L2 if
QUIRK_NOL2POLL_IN_PM is existing in suspend

On Tue, Sep 02, 2025 at 04:01:47PM +0800, Richard Zhu wrote:
quoted
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.
quoted
quoted
quoted
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.
This statement is not accurate. A single register read cannot cause hang
AFAIK.
quoted
quoted
I'm guessing that the link down (LDn) happens after initiating
PME_Turn_Off and the access to CSR register (LTSSM) causes hang.

Is my understanding correct?
The access of LTSSM is not relied on the link is up or not. For
example,  the LTSSM stats can be accessed when the link is in the
training  and not up yet.

Per to the discussion with Bjorn, the most possible reason is that the
LTSSM isn't powered anymore on i.MX6/7 when PME_Turn_Off is kicked off.
https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Flore
.kernel.org%2Fimx%2F20250819192838.GA526045%40bhelgaas%2F&data=0
5%7C02
quoted
%7Chongxing.zhu%40nxp.com%7C7e4ed6203e054843384408ddf9cadf68%7C
686ea1d
quoted
3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C638941371899547091%7CUnkno
wn%7CTWF
quoted
pbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4z
MiIsI
quoted
kFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=nwP942sszX532
DftK4o
quoted
zdJ8vHL2klzsRhDbZbj%2BnSLk%3D&reserved=0
I'm not sure though. Could you try to read any DBI register at this point and see
if the hang is observed or not?

LTSSM states are expressed through the DBI registers. So as per my
understanding, unless the whole DBI register space is inaccessible, LTSSM
registers should be accessible.[Richard Zhu] 
Hi Mani:
Re-confirmed in tests, the other DBI registers can't be accessible either.

Best Regards
Richard Zhu
- Mani
quoted
Best Regards
Richard Zhu
quoted
quoted
To support this case, don't poll L2 state and apply a simple delay
of
PCIE_PME_TO_L2_TIMEOUT_US(10ms) if the QUIRK_NOL2POLL_IN_PM
flag
quoted
quoted
is
quoted
set in suspend.

Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
We need Fixes tag also and you do need to set the flag in relevant
glue driver in this patch itself so that it can cleanly be backported.

- Mani
quoted
---
 .../pci/controller/dwc/pcie-designware-host.c | 34
+++++++++++++------  drivers/pci/controller/dwc/pcie-designware.h
+++++++++++++|
4 +++
 2 files changed, 28 insertions(+), 10 deletions(-)
diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c
b/drivers/pci/controller/dwc/pcie-designware-host.c
index 9d46d1f0334b..57a1ba08c427 100644
--- a/drivers/pci/controller/dwc/pcie-designware-host.c
+++ b/drivers/pci/controller/dwc/pcie-designware-host.c
@@ -1016,15 +1016,29 @@ int dw_pcie_suspend_noirq(struct dw_pcie
*pci)
quoted
quoted
quoted
 			return ret;
 	}

-	ret = read_poll_timeout(dw_pcie_get_ltssm, val,
-				val == DW_PCIE_LTSSM_L2_IDLE ||
-				val <= DW_PCIE_LTSSM_DETECT_WAIT,
-				PCIE_PME_TO_L2_TIMEOUT_US/10,
-				PCIE_PME_TO_L2_TIMEOUT_US, false, pci);
-	if (ret) {
-		/* Only log message when LTSSM isn't in DETECT or POLL */
-		dev_err(pci->dev, "Timeout waiting for L2 entry! LTSSM: 0x%x\n",
val);
quoted
-		return ret;
+	if (dwc_quirk(pci, QUIRK_NOL2POLL_IN_PM)) {
+		/*
+		 * Add the QUIRK_NOL2_POLL_IN_PM case to avoid the read
hang,
quoted
quoted
quoted
+		 * 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.
+		 */
+		mdelay(PCIE_PME_TO_L2_TIMEOUT_US/1000);
+	} else {
+		ret = read_poll_timeout(dw_pcie_get_ltssm, val,
+					val == DW_PCIE_LTSSM_L2_IDLE ||
+					val <= DW_PCIE_LTSSM_DETECT_WAIT,
+					PCIE_PME_TO_L2_TIMEOUT_US/10,
+					PCIE_PME_TO_L2_TIMEOUT_US, false, pci);
+		if (ret) {
+			/* Only log message when LTSSM isn't in DETECT or POLL */
+			dev_err(pci->dev, "Timeout waiting for L2 entry! LTSSM:
+0x%x\n",
val);
quoted
+			return ret;
+		}
 	}

 	/*
@@ -1040,7 +1054,7 @@ int dw_pcie_suspend_noirq(struct dw_pcie
*pci)

 	pci->suspended = true;

-	return ret;
+	return 0;
 }
 EXPORT_SYMBOL_GPL(dw_pcie_suspend_noirq);
diff --git a/drivers/pci/controller/dwc/pcie-designware.h
b/drivers/pci/controller/dwc/pcie-designware.h
index 00f52d472dcd..4e5bf6cb6ce8 100644
--- a/drivers/pci/controller/dwc/pcie-designware.h
+++ b/drivers/pci/controller/dwc/pcie-designware.h
@@ -295,6 +295,9 @@
 /* Default eDMA LLP memory size */
 #define DMA_LLP_MEM_SIZE		PAGE_SIZE

+#define QUIRK_NOL2POLL_IN_PM		BIT(0)
+#define dwc_quirk(pci, val)		(pci->quirk_flag & val)
+
 struct dw_pcie;
 struct dw_pcie_rp;
 struct dw_pcie_ep;
@@ -504,6 +507,7 @@ struct dw_pcie {
 	const struct dw_pcie_ops *ops;
 	u32			version;
 	u32			type;
+	u32			quirk_flag;
 	unsigned long		caps;
 	int			num_lanes;
 	int			max_link_speed;
--
2.37.1
--
மணிவண்ணன் சதாசிவம்
--
மணிவண்ணன் சதாசிவம்
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help