* [PATCH v5 0/6] Add quirks to proceed PME handshake in DWC PM
@ 2025-09-02 8:01 Richard Zhu
2025-09-02 8:01 ` [PATCH v5 1/6] PCI: dwc: Remove the L1SS check before putting the link into L2 Richard Zhu
` (5 more replies)
0 siblings, 6 replies; 7+ messages in thread
From: Richard Zhu @ 2025-09-02 8:01 UTC (permalink / raw)
To: frank.li, jingoohan1, l.stach, lpieralisi, kwilczynski, mani,
robh, bhelgaas, shawnguo, s.hauer, kernel, festevam
Cc: linux-pci, linux-arm-kernel, imx, linux-kernel
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 of i.MX6QP PCIe is inaccessible after the PME_Turn_Off
is kicked off. To handle this case, don't poll L2 state and add one max
10ms delay if QUIRK_NOL2POLL_IN_PM flag is existing in suspend.
Main changes in v5:
- Fix build warning caused by 6-1 patch.
v4:https://patchwork.kernel.org/project/linux-pci/cover/20250822084341.3160738-1-hongxing.zhu@nxp.com/
Main changes in v4:
- Add one patch[1/6] to remove the L1SS check during L2 entry.
- Update the code comments of 2/6 patch and commit description of 6/6 patch.
- Add background to 5/6 to describe why skip PME_Turn_off message when no
endpoint device is connected.
v3:https://patchwork.kernel.org/project/linux-pci/cover/20250818073205.1412507-1-hongxing.zhu@nxp.com/
Main changes in v3:
- Adjust the patch sequence to avoid the build break.
- Update the commit message.
v2:https://patchwork.kernel.org/project/linux-pci/cover/20250618024116.3704579-1-hongxing.zhu@nxp.com/
Main changes in v2:
Add the following two patches.
- Skip PME_Turn_Off message if there is no endpoint connected.
- Don't return error when wait for link up.
v1:https://patchwork.kernel.org/project/linux-pci/cover/20250408065221.1941928-1-hongxing.zhu@nxp.com/
drivers/pci/controller/dwc/pcie-designware-host.c
[PATCH v5 1/6] PCI: dwc: Remove the L1SS check before putting the
[PATCH v5 2/6] PCI: dwc: Don't poll L2 if QUIRK_NOL2POLL_IN_PM is
[PATCH v5 3/6] PCI: imx6: Don't poll LTSSM state of i.MX6QP PCIe in
[PATCH v5 4/6] PCI: imx6: Don't poll LTSSM state of i.MX7D PCIe in PM
[PATCH v5 5/6] PCI: dwc: Skip PME_Turn_Off message if there is no
[PATCH v5 6/6] PCI: dwc: Don't return error when wait for link up in
drivers/pci/controller/dwc/pci-imx6.c | 4 ++++
drivers/pci/controller/dwc/pcie-designware-host.c | 62 +++++++++++++++++++++++++++++++++++---------------------------
drivers/pci/controller/dwc/pcie-designware.h | 4 ++++
3 files changed, 43 insertions(+), 27 deletions(-)
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v5 1/6] PCI: dwc: Remove the L1SS check before putting the link into L2
2025-09-02 8:01 [PATCH v5 0/6] Add quirks to proceed PME handshake in DWC PM Richard Zhu
@ 2025-09-02 8:01 ` Richard Zhu
2025-09-02 8:01 ` [PATCH v5 2/6] PCI: dwc: Don't poll L2 if QUIRK_NOL2POLL_IN_PM is existing in suspend Richard Zhu
` (4 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Richard Zhu @ 2025-09-02 8:01 UTC (permalink / raw)
To: frank.li, jingoohan1, l.stach, lpieralisi, kwilczynski, mani,
robh, bhelgaas, shawnguo, s.hauer, kernel, festevam
Cc: linux-pci, linux-arm-kernel, imx, linux-kernel, Richard Zhu
Since this L1SS check is just an encapsulation problem, and the ASPM
shouldn't leak out here. Remove the L1SS check during L2 entry.
Fixes: 4774faf854f5 ("PCI: dwc: Implement generic suspend/resume functionality")
Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com>
---
drivers/pci/controller/dwc/pcie-designware-host.c | 8 --------
1 file changed, 8 deletions(-)
diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
index 952f8594b501..9d46d1f0334b 100644
--- a/drivers/pci/controller/dwc/pcie-designware-host.c
+++ b/drivers/pci/controller/dwc/pcie-designware-host.c
@@ -1005,17 +1005,9 @@ static int dw_pcie_pme_turn_off(struct dw_pcie *pci)
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 (pci->pp.ops->pme_turn_off) {
pci->pp.ops->pme_turn_off(&pci->pp);
} else {
--
2.37.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH v5 2/6] PCI: dwc: Don't poll L2 if QUIRK_NOL2POLL_IN_PM is existing in suspend
2025-09-02 8:01 [PATCH v5 0/6] Add quirks to proceed PME handshake in DWC PM Richard Zhu
2025-09-02 8:01 ` [PATCH v5 1/6] PCI: dwc: Remove the L1SS check before putting the link into L2 Richard Zhu
@ 2025-09-02 8:01 ` Richard Zhu
2025-09-02 8:01 ` [PATCH v5 3/6] PCI: imx6: Don't poll LTSSM state of i.MX6QP PCIe in PM operations Richard Zhu
` (3 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Richard Zhu @ 2025-09-02 8:01 UTC (permalink / raw)
To: frank.li, jingoohan1, l.stach, lpieralisi, kwilczynski, mani,
robh, bhelgaas, shawnguo, s.hauer, kernel, festevam
Cc: linux-pci, linux-arm-kernel, imx, linux-kernel, Richard Zhu,
Frank Li
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 QUIRK_NOL2POLL_IN_PM flag is set
in suspend.
Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
---
.../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)
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);
- return ret;
+ if (dwc_quirk(pci, QUIRK_NOL2POLL_IN_PM)) {
+ /*
+ * Add the QUIRK_NOL2_POLL_IN_PM case 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.
+ */
+ 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);
+ 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
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH v5 3/6] PCI: imx6: Don't poll LTSSM state of i.MX6QP PCIe in PM operations
2025-09-02 8:01 [PATCH v5 0/6] Add quirks to proceed PME handshake in DWC PM Richard Zhu
2025-09-02 8:01 ` [PATCH v5 1/6] PCI: dwc: Remove the L1SS check before putting the link into L2 Richard Zhu
2025-09-02 8:01 ` [PATCH v5 2/6] PCI: dwc: Don't poll L2 if QUIRK_NOL2POLL_IN_PM is existing in suspend Richard Zhu
@ 2025-09-02 8:01 ` Richard Zhu
2025-09-02 8:01 ` [PATCH v5 4/6] PCI: imx6: Don't poll LTSSM state of i.MX7D " Richard Zhu
` (2 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Richard Zhu @ 2025-09-02 8:01 UTC (permalink / raw)
To: frank.li, jingoohan1, l.stach, lpieralisi, kwilczynski, mani,
robh, bhelgaas, shawnguo, s.hauer, kernel, festevam
Cc: linux-pci, linux-arm-kernel, imx, linux-kernel, Richard Zhu,
Frank Li
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 of i.MX6QP PCIe are inaccessible after the PME_Turn_Off
is kicked off. To handle this case, don't poll L2 state and add one max
10ms delay if QUIRK_NOL2POLL_IN_PM flag is existing in suspend.
Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
---
drivers/pci/controller/dwc/pci-imx6.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
index 80e48746bbaf..18b97bd0462b 100644
--- a/drivers/pci/controller/dwc/pci-imx6.c
+++ b/drivers/pci/controller/dwc/pci-imx6.c
@@ -125,6 +125,7 @@ struct imx_pcie_drvdata {
enum imx_pcie_variants variant;
enum dw_pcie_device_mode mode;
u32 flags;
+ u32 quirk;
int dbi_length;
const char *gpr;
const u32 ltssm_off;
@@ -1765,6 +1766,7 @@ static int imx_pcie_probe(struct platform_device *pdev)
if (ret)
return ret;
+ pci->quirk_flag = imx_pcie->drvdata->quirk;
pci->use_parent_dt_ranges = true;
if (imx_pcie->drvdata->mode == DW_PCIE_EP_TYPE) {
ret = imx_add_pcie_ep(imx_pcie, pdev);
@@ -1849,6 +1851,7 @@ static const struct imx_pcie_drvdata drvdata[] = {
.enable_ref_clk = imx6q_pcie_enable_ref_clk,
.core_reset = imx6qp_pcie_core_reset,
.ops = &imx_pcie_host_ops,
+ .quirk = QUIRK_NOL2POLL_IN_PM,
},
[IMX7D] = {
.variant = IMX7D,
--
2.37.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH v5 4/6] PCI: imx6: Don't poll LTSSM state of i.MX7D PCIe in PM operations
2025-09-02 8:01 [PATCH v5 0/6] Add quirks to proceed PME handshake in DWC PM Richard Zhu
` (2 preceding siblings ...)
2025-09-02 8:01 ` [PATCH v5 3/6] PCI: imx6: Don't poll LTSSM state of i.MX6QP PCIe in PM operations Richard Zhu
@ 2025-09-02 8:01 ` Richard Zhu
2025-09-02 8:01 ` [PATCH v5 5/6] PCI: dwc: Skip PME_Turn_Off message if there is no endpoint connected Richard Zhu
2025-09-02 8:01 ` [PATCH v5 6/6] PCI: dwc: Don't return error when wait for link up in dw_pcie_resume_noirq() Richard Zhu
5 siblings, 0 replies; 7+ messages in thread
From: Richard Zhu @ 2025-09-02 8:01 UTC (permalink / raw)
To: frank.li, jingoohan1, l.stach, lpieralisi, kwilczynski, mani,
robh, bhelgaas, shawnguo, s.hauer, kernel, festevam
Cc: linux-pci, linux-arm-kernel, imx, linux-kernel, Richard Zhu,
Frank Li
Add a quirk flag(QUIRK_NOL2POLL_IN_PM) for i.MX7D PCIe. Don't poll the
LTSSM states after issue the PME_Turn_Off message.
Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
---
drivers/pci/controller/dwc/pci-imx6.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
index 18b97bd0462b..a59b5282c3cc 100644
--- a/drivers/pci/controller/dwc/pci-imx6.c
+++ b/drivers/pci/controller/dwc/pci-imx6.c
@@ -1863,6 +1863,7 @@ static const struct imx_pcie_drvdata drvdata[] = {
.mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
.enable_ref_clk = imx7d_pcie_enable_ref_clk,
.core_reset = imx7d_pcie_core_reset,
+ .quirk = QUIRK_NOL2POLL_IN_PM,
},
[IMX8MQ] = {
.variant = IMX8MQ,
--
2.37.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH v5 5/6] PCI: dwc: Skip PME_Turn_Off message if there is no endpoint connected
2025-09-02 8:01 [PATCH v5 0/6] Add quirks to proceed PME handshake in DWC PM Richard Zhu
` (3 preceding siblings ...)
2025-09-02 8:01 ` [PATCH v5 4/6] PCI: imx6: Don't poll LTSSM state of i.MX7D " Richard Zhu
@ 2025-09-02 8:01 ` Richard Zhu
2025-09-02 8:01 ` [PATCH v5 6/6] PCI: dwc: Don't return error when wait for link up in dw_pcie_resume_noirq() Richard Zhu
5 siblings, 0 replies; 7+ messages in thread
From: Richard Zhu @ 2025-09-02 8:01 UTC (permalink / raw)
To: frank.li, jingoohan1, l.stach, lpieralisi, kwilczynski, mani,
robh, bhelgaas, shawnguo, s.hauer, kernel, festevam
Cc: linux-pci, linux-arm-kernel, imx, linux-kernel, Richard Zhu,
Frank Li
A chip freeze is observed on i.MX7D when PCIe RC kicks off the PM_PME
message and no any devices are connected on the port.
To workaroud such kind of issue, skip PME_Turn_Off message if there is
no endpoint connected.
Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
---
drivers/pci/controller/dwc/pcie-designware-host.c | 15 +++++++++------
1 file changed, 9 insertions(+), 6 deletions(-)
diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
index 57a1ba08c427..b303a74b0fd7 100644
--- a/drivers/pci/controller/dwc/pcie-designware-host.c
+++ b/drivers/pci/controller/dwc/pcie-designware-host.c
@@ -1008,12 +1008,15 @@ int dw_pcie_suspend_noirq(struct dw_pcie *pci)
u32 val;
int ret;
- if (pci->pp.ops->pme_turn_off) {
- pci->pp.ops->pme_turn_off(&pci->pp);
- } else {
- ret = dw_pcie_pme_turn_off(pci);
- if (ret)
- return ret;
+ /* Skip PME_Turn_Off message if there is no endpoint connected */
+ if (dw_pcie_get_ltssm(pci) > DW_PCIE_LTSSM_DETECT_WAIT) {
+ if (pci->pp.ops->pme_turn_off) {
+ pci->pp.ops->pme_turn_off(&pci->pp);
+ } else {
+ ret = dw_pcie_pme_turn_off(pci);
+ if (ret)
+ return ret;
+ }
}
if (dwc_quirk(pci, QUIRK_NOL2POLL_IN_PM)) {
--
2.37.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH v5 6/6] PCI: dwc: Don't return error when wait for link up in dw_pcie_resume_noirq()
2025-09-02 8:01 [PATCH v5 0/6] Add quirks to proceed PME handshake in DWC PM Richard Zhu
` (4 preceding siblings ...)
2025-09-02 8:01 ` [PATCH v5 5/6] PCI: dwc: Skip PME_Turn_Off message if there is no endpoint connected Richard Zhu
@ 2025-09-02 8:01 ` Richard Zhu
5 siblings, 0 replies; 7+ messages in thread
From: Richard Zhu @ 2025-09-02 8:01 UTC (permalink / raw)
To: frank.li, jingoohan1, l.stach, lpieralisi, kwilczynski, mani,
robh, bhelgaas, shawnguo, s.hauer, kernel, festevam
Cc: linux-pci, linux-arm-kernel, imx, linux-kernel, Richard Zhu,
Frank Li
When waiting for the PCIe link to come up, both link up and link down
are valid results depending on the device state.
Since the link may come up later and to get rid of the following
mis-reported PM errors. Do not return an -ETIMEDOUT error, as the
outcome has already been reported in dw_pcie_wait_for_link().
PM error logs introduced by the -ETIMEDOUT error return.
imx6q-pcie 33800000.pcie: Phy link never came up
imx6q-pcie 33800000.pcie: PM: dpm_run_callback(): genpd_resume_noirq returns -110
imx6q-pcie 33800000.pcie: PM: failed to resume noirq: error -110
Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
---
drivers/pci/controller/dwc/pcie-designware-host.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
index b303a74b0fd7..c4386be38a07 100644
--- a/drivers/pci/controller/dwc/pcie-designware-host.c
+++ b/drivers/pci/controller/dwc/pcie-designware-host.c
@@ -1084,10 +1084,9 @@ int dw_pcie_resume_noirq(struct dw_pcie *pci)
if (ret)
return ret;
- ret = dw_pcie_wait_for_link(pci);
- if (ret)
- return ret;
+ /* Ignore errors, the link may come up later */
+ dw_pcie_wait_for_link(pci);
- return ret;
+ return 0;
}
EXPORT_SYMBOL_GPL(dw_pcie_resume_noirq);
--
2.37.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
end of thread, other threads:[~2025-09-02 8:03 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-09-02 8:01 [PATCH v5 0/6] Add quirks to proceed PME handshake in DWC PM Richard Zhu
2025-09-02 8:01 ` [PATCH v5 1/6] PCI: dwc: Remove the L1SS check before putting the link into L2 Richard Zhu
2025-09-02 8:01 ` [PATCH v5 2/6] PCI: dwc: Don't poll L2 if QUIRK_NOL2POLL_IN_PM is existing in suspend Richard Zhu
2025-09-02 8:01 ` [PATCH v5 3/6] PCI: imx6: Don't poll LTSSM state of i.MX6QP PCIe in PM operations Richard Zhu
2025-09-02 8:01 ` [PATCH v5 4/6] PCI: imx6: Don't poll LTSSM state of i.MX7D " Richard Zhu
2025-09-02 8:01 ` [PATCH v5 5/6] PCI: dwc: Skip PME_Turn_Off message if there is no endpoint connected Richard Zhu
2025-09-02 8:01 ` [PATCH v5 6/6] PCI: dwc: Don't return error when wait for link up in dw_pcie_resume_noirq() Richard Zhu
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).