[PATCH u-boot-marvell 7/9] pci: pci_mvebu: Wait 100ms for Link Up in mvebu_pcie_probe()

Pali Rohár pali at kernel.org
Tue Dec 21 12:20:17 CET 2021


After function mvebu_pcie_probe() returns U-Boot DM expects that PCIe link
is already up. In followup patches link initialization will be moved from
SPL to proper and therefore explicitly link up delay is required.

Delay mvebu_pcie_probe() for 100ms to ensure that PCIe link is up after
function finish. In the case when no card is connected to the PCIe slot,
this will delay probe time by 100ms, which should not be problematic.

This change fixes detection and initialization of some QCA98xx cards on
the first serdes when configured in x1 mode. Default configuration of
the first serdes on A385 is x4 mode, so it looks as if some delay is
required when x4 is changed to x1 and card correctly links with A385.
Other PCIe serdes ports on A385 are x1-only, and so they don't have this
problem.

Signed-off-by: Pali Rohár <pali at kernel.org>
---
 drivers/pci/pci_mvebu.c | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/drivers/pci/pci_mvebu.c b/drivers/pci/pci_mvebu.c
index 504ff501aa2e..b5b0897b2124 100644
--- a/drivers/pci/pci_mvebu.c
+++ b/drivers/pci/pci_mvebu.c
@@ -22,6 +22,7 @@
 #include <asm/arch/cpu.h>
 #include <asm/arch/soc.h>
 #include <linux/bitops.h>
+#include <linux/delay.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
 #include <linux/mbus.h>
@@ -69,6 +70,9 @@
 #define PCIE_DEBUG_CTRL			0x1a60
 #define  PCIE_DEBUG_SOFT_RESET		BIT(20)
 
+#define LINK_WAIT_RETRIES	100
+#define LINK_WAIT_TIMEOUT	1000
+
 struct mvebu_pcie {
 	struct pci_controller hose;
 	void __iomem *base;
@@ -98,6 +102,23 @@ static inline bool mvebu_pcie_link_up(struct mvebu_pcie *pcie)
 	return !(val & PCIE_STAT_LINK_DOWN);
 }
 
+static void mvebu_pcie_wait_for_link(struct mvebu_pcie *pcie)
+{
+	int retries;
+
+	/* check if the link is up or not */
+	for (retries = 0; retries < LINK_WAIT_RETRIES; retries++) {
+		if (mvebu_pcie_link_up(pcie)) {
+			printf("%s: Link up\n", pcie->name);
+			return;
+		}
+
+		udelay(LINK_WAIT_TIMEOUT);
+	}
+
+	printf("%s: Link down\n", pcie->name);
+}
+
 static void mvebu_pcie_set_local_bus_nr(struct mvebu_pcie *pcie, int busno)
 {
 	u32 stat;
@@ -501,6 +522,8 @@ static int mvebu_pcie_probe(struct udevice *dev)
 	pcie->cfgcache[(PCI_PREF_MEMORY_BASE - 0x10) / 4] =
 		PCI_PREF_RANGE_TYPE_64 | (PCI_PREF_RANGE_TYPE_64 << 16);
 
+	mvebu_pcie_wait_for_link(pcie);
+
 	return 0;
 }
 
-- 
2.20.1



More information about the U-Boot mailing list