* [PATCH v2 0/5] Add quirks to proceed PME handshake in DWC PM
@ 2025-06-18 2:41 Richard Zhu
2025-06-18 2:41 ` [PATCH v2 1/5] PCI: imx6: Don't poll LTSSM state of i.MX6QP PCIe in PM operations Richard Zhu
` (4 more replies)
0 siblings, 5 replies; 11+ messages in thread
From: Richard Zhu @ 2025-06-18 2:41 UTC (permalink / raw)
To: frank.li, 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 chenages 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/
[PATCH v2 1/5] PCI: imx6: Don't poll LTSSM state of i.MX6QP PCIe in
[PATCH v2 2/5] PCI: imx6: Don't poll LTSSM state of i.MX7D PCIe in PM
[PATCH v2 3/5] PCI: dwc: Don't poll L2 if QUIRK_NOL2POLL_IN_PM is
[PATCH v2 4/5] PCI: dwc: Skip PME_Turn_Off message if there is no
[PATCH v2 5/5] PCI: dwc: Don't return error when wait for link up
drivers/pci/controller/dwc/pci-imx6.c | 4 ++++
drivers/pci/controller/dwc/pcie-designware-host.c | 50 +++++++++++++++++++++++++++++++-------------------
drivers/pci/controller/dwc/pcie-designware.h | 4 ++++
3 files changed, 39 insertions(+), 19 deletions(-)
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH v2 1/5] PCI: imx6: Don't poll LTSSM state of i.MX6QP PCIe in PM operations
2025-06-18 2:41 [PATCH v2 0/5] Add quirks to proceed PME handshake in DWC PM Richard Zhu
@ 2025-06-18 2:41 ` Richard Zhu
2025-06-18 18:36 ` Frank Li
2025-06-18 2:41 ` [PATCH v2 2/5] PCI: imx6: Don't poll LTSSM state of i.MX7D " Richard Zhu
` (3 subsequent siblings)
4 siblings, 1 reply; 11+ messages in thread
From: Richard Zhu @ 2025-06-18 2:41 UTC (permalink / raw)
To: frank.li, l.stach, lpieralisi, kwilczynski, mani, robh, bhelgaas,
shawnguo, s.hauer, kernel, festevam
Cc: linux-pci, linux-arm-kernel, imx, linux-kernel, Richard Zhu
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.
Signed-off-by: Richard Zhu <hongxing.zhu@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 5a38cfaf989b..8b7daaf36fef 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;
@@ -1759,6 +1760,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);
@@ -1837,6 +1839,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] 11+ messages in thread
* [PATCH v2 2/5] PCI: imx6: Don't poll LTSSM state of i.MX7D PCIe in PM operations
2025-06-18 2:41 [PATCH v2 0/5] Add quirks to proceed PME handshake in DWC PM Richard Zhu
2025-06-18 2:41 ` [PATCH v2 1/5] PCI: imx6: Don't poll LTSSM state of i.MX6QP PCIe in PM operations Richard Zhu
@ 2025-06-18 2:41 ` Richard Zhu
2025-06-18 18:34 ` Frank Li
2025-06-18 2:41 ` [PATCH v2 3/5] PCI: dwc: Don't poll L2 if QUIRK_NOL2POLL_IN_PM is existing in suspend Richard Zhu
` (2 subsequent siblings)
4 siblings, 1 reply; 11+ messages in thread
From: Richard Zhu @ 2025-06-18 2:41 UTC (permalink / raw)
To: frank.li, l.stach, lpieralisi, kwilczynski, mani, robh, bhelgaas,
shawnguo, s.hauer, kernel, festevam
Cc: linux-pci, linux-arm-kernel, imx, linux-kernel, Richard Zhu
Add a quirk flag(QUIRK_NOL2POLL_IN_PM) for i.MX7D PCIe. Don't poll the
LTSSM states after issuing the PME_Turn_Off message.
Signed-off-by: Richard Zhu <hongxing.zhu@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 8b7daaf36fef..f084a9ad1001 100644
--- a/drivers/pci/controller/dwc/pci-imx6.c
+++ b/drivers/pci/controller/dwc/pci-imx6.c
@@ -1851,6 +1851,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] 11+ messages in thread
* [PATCH v2 3/5] PCI: dwc: Don't poll L2 if QUIRK_NOL2POLL_IN_PM is existing in suspend
2025-06-18 2:41 [PATCH v2 0/5] Add quirks to proceed PME handshake in DWC PM Richard Zhu
2025-06-18 2:41 ` [PATCH v2 1/5] PCI: imx6: Don't poll LTSSM state of i.MX6QP PCIe in PM operations Richard Zhu
2025-06-18 2:41 ` [PATCH v2 2/5] PCI: imx6: Don't poll LTSSM state of i.MX7D " Richard Zhu
@ 2025-06-18 2:41 ` Richard Zhu
2025-06-18 18:32 ` Frank Li
2025-06-18 2:41 ` [PATCH v2 4/5] PCI: dwc: Skip PME_Turn_Off message if there is no endpoint connected Richard Zhu
2025-06-18 2:41 ` [PATCH v2 5/5] PCI: dwc: Don't return error when wait for link up Richard Zhu
4 siblings, 1 reply; 11+ messages in thread
From: Richard Zhu @ 2025-06-18 2:41 UTC (permalink / raw)
To: frank.li, l.stach, lpieralisi, kwilczynski, mani, robh, bhelgaas,
shawnguo, s.hauer, kernel, festevam
Cc: linux-pci, linux-arm-kernel, imx, linux-kernel, Richard Zhu
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 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>
---
.../pci/controller/dwc/pcie-designware-host.c | 31 +++++++++++++------
drivers/pci/controller/dwc/pcie-designware.h | 4 +++
2 files changed, 25 insertions(+), 10 deletions(-)
diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
index 906277f9ffaf..2d58a3eb94a1 100644
--- a/drivers/pci/controller/dwc/pcie-designware-host.c
+++ b/drivers/pci/controller/dwc/pcie-designware-host.c
@@ -1026,7 +1026,7 @@ int dw_pcie_suspend_noirq(struct dw_pcie *pci)
{
u8 offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);
u32 val;
- int ret;
+ int ret = 0;
/*
* If L1SS is supported, then do not put the link into L2 as some
@@ -1043,15 +1043,26 @@ 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)) {
+ /*
+ * 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;
+ }
}
/*
diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
index ce9e18554e42..e35b19cbd8bf 100644
--- a/drivers/pci/controller/dwc/pcie-designware.h
+++ b/drivers/pci/controller/dwc/pcie-designware.h
@@ -299,6 +299,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;
@@ -509,6 +512,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] 11+ messages in thread
* [PATCH v2 4/5] PCI: dwc: Skip PME_Turn_Off message if there is no endpoint connected
2025-06-18 2:41 [PATCH v2 0/5] Add quirks to proceed PME handshake in DWC PM Richard Zhu
` (2 preceding siblings ...)
2025-06-18 2:41 ` [PATCH v2 3/5] PCI: dwc: Don't poll L2 if QUIRK_NOL2POLL_IN_PM is existing in suspend Richard Zhu
@ 2025-06-18 2:41 ` Richard Zhu
2025-06-18 18:19 ` Frank Li
2025-06-18 2:41 ` [PATCH v2 5/5] PCI: dwc: Don't return error when wait for link up Richard Zhu
4 siblings, 1 reply; 11+ messages in thread
From: Richard Zhu @ 2025-06-18 2:41 UTC (permalink / raw)
To: frank.li, l.stach, lpieralisi, kwilczynski, mani, robh, bhelgaas,
shawnguo, s.hauer, kernel, festevam
Cc: linux-pci, linux-arm-kernel, imx, linux-kernel, Richard Zhu
Skip PME_Turn_Off message if there is no endpoint connected.
Signed-off-by: Richard Zhu <hongxing.zhu@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 2d58a3eb94a1..228484e3ea4a 100644
--- a/drivers/pci/controller/dwc/pcie-designware-host.c
+++ b/drivers/pci/controller/dwc/pcie-designware-host.c
@@ -1035,12 +1035,15 @@ int dw_pcie_suspend_noirq(struct dw_pcie *pci)
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 {
- 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] 11+ messages in thread
* [PATCH v2 5/5] PCI: dwc: Don't return error when wait for link up
2025-06-18 2:41 [PATCH v2 0/5] Add quirks to proceed PME handshake in DWC PM Richard Zhu
` (3 preceding siblings ...)
2025-06-18 2:41 ` [PATCH v2 4/5] PCI: dwc: Skip PME_Turn_Off message if there is no endpoint connected Richard Zhu
@ 2025-06-18 2:41 ` Richard Zhu
2025-06-18 18:24 ` Frank Li
4 siblings, 1 reply; 11+ messages in thread
From: Richard Zhu @ 2025-06-18 2:41 UTC (permalink / raw)
To: frank.li, l.stach, lpieralisi, kwilczynski, mani, robh, bhelgaas,
shawnguo, s.hauer, kernel, festevam
Cc: linux-pci, linux-arm-kernel, imx, linux-kernel, Richard Zhu
When wait for link up, both the link up and link down are normal
results, not mistakes.
Don't return error, since the results had been notified.
Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com>
---
drivers/pci/controller/dwc/pcie-designware-host.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
index 228484e3ea4a..fe6997c9c1d5 100644
--- a/drivers/pci/controller/dwc/pcie-designware-host.c
+++ b/drivers/pci/controller/dwc/pcie-designware-host.c
@@ -1108,9 +1108,7 @@ int dw_pcie_resume_noirq(struct dw_pcie *pci)
if (ret)
return ret;
- ret = dw_pcie_wait_for_link(pci);
- if (ret)
- return ret;
+ dw_pcie_wait_for_link(pci);
return ret;
}
--
2.37.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH v2 4/5] PCI: dwc: Skip PME_Turn_Off message if there is no endpoint connected
2025-06-18 2:41 ` [PATCH v2 4/5] PCI: dwc: Skip PME_Turn_Off message if there is no endpoint connected Richard Zhu
@ 2025-06-18 18:19 ` Frank Li
0 siblings, 0 replies; 11+ messages in thread
From: Frank Li @ 2025-06-18 18:19 UTC (permalink / raw)
To: Richard Zhu
Cc: l.stach, lpieralisi, kwilczynski, mani, robh, bhelgaas, shawnguo,
s.hauer, kernel, festevam, linux-pci, linux-arm-kernel, imx,
linux-kernel
On Wed, Jun 18, 2025 at 10:41:15AM +0800, Richard Zhu wrote:
> 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 2d58a3eb94a1..228484e3ea4a 100644
> --- a/drivers/pci/controller/dwc/pcie-designware-host.c
> +++ b/drivers/pci/controller/dwc/pcie-designware-host.c
> @@ -1035,12 +1035,15 @@ int dw_pcie_suspend_noirq(struct dw_pcie *pci)
> 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 {
> - 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 [flat|nested] 11+ messages in thread
* Re: [PATCH v2 5/5] PCI: dwc: Don't return error when wait for link up
2025-06-18 2:41 ` [PATCH v2 5/5] PCI: dwc: Don't return error when wait for link up Richard Zhu
@ 2025-06-18 18:24 ` Frank Li
0 siblings, 0 replies; 11+ messages in thread
From: Frank Li @ 2025-06-18 18:24 UTC (permalink / raw)
To: Richard Zhu
Cc: l.stach, lpieralisi, kwilczynski, mani, robh, bhelgaas, shawnguo,
s.hauer, kernel, festevam, linux-pci, linux-arm-kernel, imx,
linux-kernel
On Wed, Jun 18, 2025 at 10:41:16AM +0800, Richard Zhu wrote:
> When wait for link up, both the link up and link down are normal
> results, not mistakes.
> Don't return error, since the results had been notified.
When waiting for the PCIe link to come up, both link up and link down are
valid results depending on the device state. Do not return an error, as
the outcome has already been reported in dw_pcie_wait_for_link().
Reviewed-by: Frank Li <Frank.Li@nxp.com>
>
> Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com>
> ---
> drivers/pci/controller/dwc/pcie-designware-host.c | 4 +---
> 1 file changed, 1 insertion(+), 3 deletions(-)
>
> diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
> index 228484e3ea4a..fe6997c9c1d5 100644
> --- a/drivers/pci/controller/dwc/pcie-designware-host.c
> +++ b/drivers/pci/controller/dwc/pcie-designware-host.c
> @@ -1108,9 +1108,7 @@ int dw_pcie_resume_noirq(struct dw_pcie *pci)
> if (ret)
> return ret;
>
> - ret = dw_pcie_wait_for_link(pci);
> - if (ret)
> - return ret;
> + dw_pcie_wait_for_link(pci);
>
> return ret;
> }
> --
> 2.37.1
>
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v2 3/5] PCI: dwc: Don't poll L2 if QUIRK_NOL2POLL_IN_PM is existing in suspend
2025-06-18 2:41 ` [PATCH v2 3/5] PCI: dwc: Don't poll L2 if QUIRK_NOL2POLL_IN_PM is existing in suspend Richard Zhu
@ 2025-06-18 18:32 ` Frank Li
0 siblings, 0 replies; 11+ messages in thread
From: Frank Li @ 2025-06-18 18:32 UTC (permalink / raw)
To: Richard Zhu
Cc: l.stach, lpieralisi, kwilczynski, mani, robh, bhelgaas, shawnguo,
s.hauer, kernel, festevam, linux-pci, linux-arm-kernel, imx,
linux-kernel
On Wed, Jun 18, 2025 at 10:41:14AM +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
^ needn't ,
> PME_Turn_Off is sent out.
>
> 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.
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.
Reviewed-by: Frank Li <Frank.Li@nxp.com>
>
> Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com>
> ---
> .../pci/controller/dwc/pcie-designware-host.c | 31 +++++++++++++------
> drivers/pci/controller/dwc/pcie-designware.h | 4 +++
> 2 files changed, 25 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
> index 906277f9ffaf..2d58a3eb94a1 100644
> --- a/drivers/pci/controller/dwc/pcie-designware-host.c
> +++ b/drivers/pci/controller/dwc/pcie-designware-host.c
> @@ -1026,7 +1026,7 @@ int dw_pcie_suspend_noirq(struct dw_pcie *pci)
> {
> u8 offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);
> u32 val;
> - int ret;
> + int ret = 0;
>
> /*
> * If L1SS is supported, then do not put the link into L2 as some
> @@ -1043,15 +1043,26 @@ 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)) {
> + /*
> + * 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;
> + }
> }
>
> /*
> diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
> index ce9e18554e42..e35b19cbd8bf 100644
> --- a/drivers/pci/controller/dwc/pcie-designware.h
> +++ b/drivers/pci/controller/dwc/pcie-designware.h
> @@ -299,6 +299,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;
> @@ -509,6 +512,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 [flat|nested] 11+ messages in thread
* Re: [PATCH v2 2/5] PCI: imx6: Don't poll LTSSM state of i.MX7D PCIe in PM operations
2025-06-18 2:41 ` [PATCH v2 2/5] PCI: imx6: Don't poll LTSSM state of i.MX7D " Richard Zhu
@ 2025-06-18 18:34 ` Frank Li
0 siblings, 0 replies; 11+ messages in thread
From: Frank Li @ 2025-06-18 18:34 UTC (permalink / raw)
To: Richard Zhu
Cc: l.stach, lpieralisi, kwilczynski, mani, robh, bhelgaas, shawnguo,
s.hauer, kernel, festevam, linux-pci, linux-arm-kernel, imx,
linux-kernel
On Wed, Jun 18, 2025 at 10:41:13AM +0800, Richard Zhu wrote:
> Add a quirk flag(QUIRK_NOL2POLL_IN_PM) for i.MX7D PCIe. Don't poll the
> LTSSM states after issuing the PME_Turn_Off message.
s/issuing/issue
>
> Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com>
> ---
This patch should after
PCI: dwc: Don't poll L2 if QUIRK_NOL2POLL_IN_PM is existing in suspend
Frank
> 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 8b7daaf36fef..f084a9ad1001 100644
> --- a/drivers/pci/controller/dwc/pci-imx6.c
> +++ b/drivers/pci/controller/dwc/pci-imx6.c
> @@ -1851,6 +1851,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 [flat|nested] 11+ messages in thread
* Re: [PATCH v2 1/5] PCI: imx6: Don't poll LTSSM state of i.MX6QP PCIe in PM operations
2025-06-18 2:41 ` [PATCH v2 1/5] PCI: imx6: Don't poll LTSSM state of i.MX6QP PCIe in PM operations Richard Zhu
@ 2025-06-18 18:36 ` Frank Li
0 siblings, 0 replies; 11+ messages in thread
From: Frank Li @ 2025-06-18 18:36 UTC (permalink / raw)
To: Richard Zhu
Cc: l.stach, lpieralisi, kwilczynski, mani, robh, bhelgaas, shawnguo,
s.hauer, kernel, festevam, linux-pci, linux-arm-kernel, imx,
linux-kernel
On Wed, Jun 18, 2025 at 10:41:12AM +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 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.
>
> Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com>
> ---
This patch should be after you add QUIRK_NOL2POLL_IN_PM to avoid build
break.
Frank
> 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 5a38cfaf989b..8b7daaf36fef 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;
> @@ -1759,6 +1760,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);
> @@ -1837,6 +1839,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 [flat|nested] 11+ messages in thread
end of thread, other threads:[~2025-06-18 18:36 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-06-18 2:41 [PATCH v2 0/5] Add quirks to proceed PME handshake in DWC PM Richard Zhu
2025-06-18 2:41 ` [PATCH v2 1/5] PCI: imx6: Don't poll LTSSM state of i.MX6QP PCIe in PM operations Richard Zhu
2025-06-18 18:36 ` Frank Li
2025-06-18 2:41 ` [PATCH v2 2/5] PCI: imx6: Don't poll LTSSM state of i.MX7D " Richard Zhu
2025-06-18 18:34 ` Frank Li
2025-06-18 2:41 ` [PATCH v2 3/5] PCI: dwc: Don't poll L2 if QUIRK_NOL2POLL_IN_PM is existing in suspend Richard Zhu
2025-06-18 18:32 ` Frank Li
2025-06-18 2:41 ` [PATCH v2 4/5] PCI: dwc: Skip PME_Turn_Off message if there is no endpoint connected Richard Zhu
2025-06-18 18:19 ` Frank Li
2025-06-18 2:41 ` [PATCH v2 5/5] PCI: dwc: Don't return error when wait for link up Richard Zhu
2025-06-18 18:24 ` Frank Li
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).