From: Stefan Eichenberger <eichest@gmail.com>
To: hongxing.zhu@nxp.com, l.stach@pengutronix.de,
lpieralisi@kernel.org, kw@linux.com, robh@kernel.org,
bhelgaas@google.com, shawnguo@kernel.org, s.hauer@pengutronix.de,
kernel@pengutronix.de, festevam@gmail.com,
francesco.dolcini@toradex.com
Cc: linux-pci@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
imx@lists.linux.dev, linux-kernel@vger.kernel.org,
Stefan Eichenberger <stefan.eichenberger@toradex.com>
Subject: [PATCH v1 3/3] PCI: imx6: reset link on resume
Date: Mon, 19 Aug 2024 11:03:19 +0200 [thread overview]
Message-ID: <20240819090428.17349-4-eichest@gmail.com> (raw)
In-Reply-To: <20240819090428.17349-1-eichest@gmail.com>
From: Stefan Eichenberger <stefan.eichenberger@toradex.com>
According to the https://www.nxp.com/docs/en/errata/IMX6DQCE.pdf errata,
the i.MX6Q PCIe controller does not support suspend/resume. So suspend
and resume was omitted. However, this does not seem to work because it
looks like the PCIe link is still expecting a reset. If we do not reset
the link, we end up with a frozen system after resume. The last message
we see is:
ath10k_pci 0000:01:00.0: Unable to change power state from D3hot to D0,
device inaccessible
Besides resetting the link, we also need to enable msi again, otherwise
DMA access will not work and we can still end up with a frozen system.
With these changes we can suspend and resume the system properly with a
PCIe device attached. This was tested with a Compex WLE900VX miniPCIe
Wifi module.
Signed-off-by: Stefan Eichenberger <stefan.eichenberger@toradex.com>
---
drivers/pci/controller/dwc/pci-imx6.c | 45 ++++++++++++++++++++++++++-
1 file changed, 44 insertions(+), 1 deletion(-)
diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
index f17561791e35a..751243f4c519e 100644
--- a/drivers/pci/controller/dwc/pci-imx6.c
+++ b/drivers/pci/controller/dwc/pci-imx6.c
@@ -1213,14 +1213,57 @@ static int imx6_pcie_suspend_noirq(struct device *dev)
return 0;
}
+static int imx6_pcie_reset_link(struct imx6_pcie *imx6_pcie)
+{
+ int ret;
+
+ regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
+ IMX6Q_GPR1_PCIE_TEST_PD, 1 << 18);
+ regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
+ IMX6Q_GPR1_PCIE_REF_CLK_EN, 0 << 16);
+
+ /* Reset the PCIe device */
+ gpiod_set_value_cansleep(imx6_pcie->reset_gpiod, 1);
+
+ ret = imx6_pcie_enable_ref_clk(imx6_pcie);
+ if (ret) {
+ dev_err(imx6_pcie->pci->dev, "unable to enable pcie ref clock\n");
+ return ret;
+ }
+
+ imx6_pcie_deassert_reset_gpio(imx6_pcie);
+
+ /*
+ * Setup the root complex again and enable msi. Without this PCIe will
+ * not work in msi mode and drivers will crash if they try to access
+ * the device memory area
+ */
+ dw_pcie_setup_rc(&imx6_pcie->pci->pp);
+ if (pci_msi_enabled()) {
+ u32 val;
+ u8 offset = dw_pcie_find_capability(imx6_pcie->pci, PCI_CAP_ID_MSI);
+
+ val = dw_pcie_readw_dbi(imx6_pcie->pci, offset + PCI_MSI_FLAGS);
+ val |= PCI_MSI_FLAGS_ENABLE;
+ dw_pcie_writew_dbi(imx6_pcie->pci, offset + PCI_MSI_FLAGS, val);
+ }
+
+ return 0;
+}
+
static int imx6_pcie_resume_noirq(struct device *dev)
{
int ret;
struct imx6_pcie *imx6_pcie = dev_get_drvdata(dev);
struct dw_pcie_rp *pp = &imx6_pcie->pci->pp;
+ /*
+ * Even though the i.MX6Q does not support suspend/resume, we need to
+ * reset the link after resume or the memory mapped PCIe I/O space will
+ * be inaccessible. This will cause the system to freeze.
+ */
if (!(imx6_pcie->drvdata->flags & IMX6_PCIE_FLAG_SUPPORTS_SUSPEND))
- return 0;
+ return imx6_pcie_reset_link(imx6_pcie);
ret = imx6_pcie_host_init(pp);
if (ret)
--
2.43.0
next prev parent reply other threads:[~2024-08-19 9:07 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-08-19 9:03 [PATCH v1 0/3] PCI: imx6: reset link after suspend/resume Stefan Eichenberger
2024-08-19 9:03 ` [PATCH v1 1/3] PCI: imx6: Add a function to deassert the reset gpio Stefan Eichenberger
2024-08-19 14:49 ` Frank Li
2024-08-20 7:07 ` Stefan Eichenberger
2024-08-19 9:03 ` [PATCH v1 2/3] PCI: imx6: move the wait for clock stabilization to enable ref clk Stefan Eichenberger
2024-08-19 14:45 ` Frank Li
2024-08-20 7:06 ` Stefan Eichenberger
2024-08-19 9:03 ` Stefan Eichenberger [this message]
2024-08-19 14:39 ` [PATCH v1 3/3] PCI: imx6: reset link on resume Frank Li
2024-08-20 7:05 ` Stefan Eichenberger
2024-08-19 14:30 ` [PATCH v1 0/3] PCI: imx6: reset link after suspend/resume Frank Li
2024-08-20 6:52 ` Stefan Eichenberger
2024-08-21 15:41 ` Stefan Eichenberger
2024-08-21 16:51 ` Frank Li
2024-08-22 7:20 ` Stefan Eichenberger
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240819090428.17349-4-eichest@gmail.com \
--to=eichest@gmail.com \
--cc=bhelgaas@google.com \
--cc=festevam@gmail.com \
--cc=francesco.dolcini@toradex.com \
--cc=hongxing.zhu@nxp.com \
--cc=imx@lists.linux.dev \
--cc=kernel@pengutronix.de \
--cc=kw@linux.com \
--cc=l.stach@pengutronix.de \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=lpieralisi@kernel.org \
--cc=robh@kernel.org \
--cc=s.hauer@pengutronix.de \
--cc=shawnguo@kernel.org \
--cc=stefan.eichenberger@toradex.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).