From: Daniel Thompson <daniel.thompson@linaro.org>
To: Minghuan Lian <minghuan.Lian@nxp.com>,
Mingkai Hu <mingkai.hu@nxp.com>, Roy Zang <roy.zang@nxp.com>
Cc: Daniel Thompson <daniel.thompson@linaro.org>,
Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>,
Rob Herring <robh@kernel.org>,
Bjorn Helgaas <bhelgaas@google.com>,
Jon Nettleton <jon@solid-run.com>,
linuxppc-dev@lists.ozlabs.org, linux-pci@vger.kernel.org,
linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, patches@linaro.org
Subject: [RFC HACK PATCH] PCI: dwc: layerscape: Hack around enumeration problems with Honeycomb LX2K
Date: Fri, 11 Dec 2020 12:15:07 +0000 [thread overview]
Message-ID: <20201211121507.28166-1-daniel.thompson@linaro.org> (raw)
I have been chasing down a problem enumerating an NVMe drive on a
Honeycomb LX2K (NXP LX2160A). Specifically the drive can only enumerate
successfully if the we are emitting lots of console messages via a UART.
If the system is booted with `quiet` set then enumeration fails.
I guessed this would be due to the timing impact of printk-to-UART and
tried to find out where a delay could be added to provoke a successful
enumeration.
This patch contains the results. The delay length (1ms) was selected by
binary searching downwards until the delay was not effective for these
devices (Honeycomb LX2K and a Western Digital WD Blue SN550).
I have also included the workaround twice (conditionally compiled). The
first change is the *latest* possible code path that we can deploy a
delay whilst the second is the earliest place I could find.
The summary is that the critical window were we are currently relying on
a call to the console UART code can "mend" the driver runs from calling
dw_pcie_setup_rc() in host init to just before we read the state in the
link up callback.
Signed-off-by: Daniel Thompson <daniel.thompson@linaro.org>
---
Notes:
This patch is RFC (and HACK) because I don't have much clue *why* this
patch works... merely that this is the smallest possible change I need
to replicate the current accidental printk() workaround. Perhaps one
could argue that RFC here stands for request-for-clue. All my
observations and changes here are empirical and I don't know how best to
turn them into something that is not a hack!
BTW I noticed many other pcie-designware drivers take advantage
of a function called dw_pcie_wait_for_link() in their init paths...
but my naive attempts to add it to the layerscape driver results
in non-booting systems so I haven't embarrassed myself by including
that in the patch!
drivers/pci/controller/dwc/pci-layerscape.c | 35 +++++++++++++++++++++
1 file changed, 35 insertions(+)
diff --git a/drivers/pci/controller/dwc/pci-layerscape.c b/drivers/pci/controller/dwc/pci-layerscape.c
index f24f79a70d9a..c354904b90ef 100644
--- a/drivers/pci/controller/dwc/pci-layerscape.c
+++ b/drivers/pci/controller/dwc/pci-layerscape.c
@@ -22,6 +22,8 @@
#include "pcie-designware.h"
+#define WORKAROUND_LATEST_POSSIBLE
+
/* PEX1/2 Misc Ports Status Register */
#define SCFG_PEXMSCPORTSR(pex_idx) (0x94 + (pex_idx) * 4)
#define LTSSM_STATE_SHIFT 20
@@ -113,10 +115,31 @@ static int ls_pcie_link_up(struct dw_pcie *pci)
struct ls_pcie *pcie = to_ls_pcie(pci);
u32 state;
+ /*
+ * Strictly speaking *this* (before the ioread32) is the latest
+ * point a simple delay can be effective. If we move the delay
+ * after the ioread32 then the NVMe does not enumerate.
+ *
+ * However this function appears to be frequently called so an
+ * unconditional delay here causes noticeable delay at boot
+ * time. Hence we implement the workaround by retrying the read
+ * after a short delay if we think we might need to return false.
+ */
+
state = (ioread32(pcie->lut + pcie->drvdata->lut_dbg) >>
pcie->drvdata->ltssm_shift) &
LTSSM_STATE_MASK;
+#ifdef WORKAROUND_LATEST_POSSIBLE
+ if (state < LTSSM_PCIE_L0) {
+ /* see comment above */
+ mdelay(1);
+ state = (ioread32(pcie->lut + pcie->drvdata->lut_dbg) >>
+ pcie->drvdata->ltssm_shift) &
+ LTSSM_STATE_MASK;
+ }
+#endif
+
if (state < LTSSM_PCIE_L0)
return 0;
@@ -152,6 +175,18 @@ static int ls_pcie_host_init(struct pcie_port *pp)
dw_pcie_setup_rc(pp);
+#ifdef WORKAROUND_EARLIEST_POSSIBLE
+ /*
+ * This is the earliest point the delay is effective.
+ * If we move it before dw_pcie_setup_rc() then the
+ * NVMe does not enumerate.
+ *
+ * 500us is too short to reliably work around the issue
+ * hence adopting 1000us here.
+ */
+ mdelay(1);
+#endif
+
return 0;
}
base-commit: 0477e92881850d44910a7e94fc2c46f96faa131f
--
2.29.2
next reply other threads:[~2020-12-11 12:17 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-12-11 12:15 Daniel Thompson [this message]
2020-12-11 14:37 ` [RFC HACK PATCH] PCI: dwc: layerscape: Hack around enumeration problems with Honeycomb LX2K Rob Herring
2020-12-11 17:05 ` Daniel Thompson
2020-12-14 10:43 ` Daniel Thompson
2020-12-14 14:57 ` Rob Herring
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=20201211121507.28166-1-daniel.thompson@linaro.org \
--to=daniel.thompson@linaro.org \
--cc=bhelgaas@google.com \
--cc=jon@solid-run.com \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=linuxppc-dev@lists.ozlabs.org \
--cc=lorenzo.pieralisi@arm.com \
--cc=minghuan.Lian@nxp.com \
--cc=mingkai.hu@nxp.com \
--cc=patches@linaro.org \
--cc=robh@kernel.org \
--cc=roy.zang@nxp.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).