Re: [PATCH v1] PCI: dwc: Add force_l2 flag for platforms requiring L2 entry without D3cold

From: Manivannan Sadhasivam

Date: Wed Jul 15 2026 - 13:00:05 EST


On Mon, Jul 06, 2026 at 10:47:52AM +0800, hongxing.zhu@xxxxxxxxxxx wrote:
> From: Richard Zhu <hongxing.zhu@xxxxxxx>
>
> Some platforms like i.MX have their PCIe RC controllers powered off
> during system suspend, requiring full re-initialization on resume.
> These platforms need to enter L2 state to properly notify endpoints
> before power loss, even when D3cold is not supported.
>

So during suspend, RC goes down but the EP stays powered ON? And due to RC
suddenly going down, EP is observing LDn?

Can you control RC power during suspend from pci-imx6 driver? I guess not.

Also, is this behavior applicable to all i.MX6 platforms? If so, how the suspend
worked before?

> Add a force_l2 flag to allow platform drivers to request L2 entry
> during suspend regardless of D3cold capability, and enable it for
> i.MX PCIe controllers.
>

PCIe base spec r7.0, sec 5.2, mentions that the system software should
transition the device into D3Hot before broadcasing the PME_Turn_Off message.
So here we'd be violating that section of the spec if the endpoint is in
non-D3Hot state.

But honestly, I don't have a better solution than intiating L2 entry sequence
forcefully. Atleast, it should be documented in the comments and patch
description.

> Signed-off-by: Richard Zhu <hongxing.zhu@xxxxxxx>
> ---
> drivers/pci/controller/dwc/pci-imx6.c | 5 +++++
> drivers/pci/controller/dwc/pcie-designware-host.c | 8 ++++++--
> drivers/pci/controller/dwc/pcie-designware.h | 5 +++++
> 3 files changed, 16 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
> index f55a68f60eea9..ea0b4eb03c1d0 100644
> --- a/drivers/pci/controller/dwc/pci-imx6.c
> +++ b/drivers/pci/controller/dwc/pci-imx6.c
> @@ -1966,6 +1966,11 @@ static int imx_pcie_probe(struct platform_device *pdev)
> */
> imx_pcie_add_lut_by_rid(imx_pcie, 0);
> } else {
> + /*
> + * i.MX RC is powered off during suspend, force L2 entry to
> + * ensure proper endpoint notification before power loss.
> + */
> + pci->pp.force_l2 = true;
> if (imx_check_flag(imx_pcie, IMX_PCIE_FLAG_SKIP_L23_READY))
> pci->pp.skip_l23_ready = true;
> if (imx_check_flag(imx_pcie, IMX_PCIE_FLAG_KEEP_MSI_CAP))
> diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
> index 06722259d2e37..e3f022d2d453a 100644
> --- a/drivers/pci/controller/dwc/pcie-designware-host.c
> +++ b/drivers/pci/controller/dwc/pcie-designware-host.c
> @@ -1222,14 +1222,18 @@ static int dw_pcie_pme_turn_off(struct dw_pcie *pci)
>
> int dw_pcie_suspend_noirq(struct dw_pcie *pci)
> {
> - bool pme_capable = false;
> + bool d3cold, pme_capable = false;
> int ret = 0;
> u32 val;
>
> if (!dw_pcie_link_up(pci))
> goto stop_link;
>
> - if (!pci_host_common_d3cold_possible(pci->pp.bridge, &pme_capable))
> + d3cold = pci_host_common_d3cold_possible(pci->pp.bridge, &pme_capable);
> + /*
> + * Enter L2 if D3cold is possible or platform requires forced L2 entry
> + */
> + if (!d3cold && !pci->pp.force_l2)
> return 0;
>
> if (pci->pp.ops->pme_turn_off) {
> diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
> index de4b245b1758c..5e88459e0cfa0 100644
> --- a/drivers/pci/controller/dwc/pcie-designware.h
> +++ b/drivers/pci/controller/dwc/pcie-designware.h
> @@ -471,6 +471,11 @@ struct dw_pcie_rp {
> bool native_ecam;
> bool skip_l23_ready;
> bool skip_pwrctrl_off;
> + /*
> + * Force L2 entry even if D3cold not possible (e.g., when RC loses
> + * power).
> + */
> + bool force_l2;

Can it be called, 'suspend_poweroff' to indicate the actual quirk?

- Mani

--
மணிவண்ணன் சதாசிவம்