[U-Boot] [PATCH 04/23] pci: xilinx: Initialise the root bridge during probe

Paul Burton paul.burton at imgtec.com
Mon Sep 26 20:28:58 CEST 2016


Whilst the pcie_xilinx driver was sufficient to run under QEMU, it was
failing on FPGA because it wasn't configuring the root bridge, and
access from the PCI auto-configuration code to subordinate busses would
lead to data bus errors. Fix this by configuring the root bridge to
allow access to all possible subordinate busses based upon the size of
the ECAM region, and disable interrupts since U-Boot isn't using them.

Signed-off-by: Paul Burton <paul.burton at imgtec.com>
---

 drivers/pci/pcie_xilinx.c | 36 ++++++++++++++++++++++++++++++++++--
 1 file changed, 34 insertions(+), 2 deletions(-)

diff --git a/drivers/pci/pcie_xilinx.c b/drivers/pci/pcie_xilinx.c
index 5216001..9059c41 100644
--- a/drivers/pci/pcie_xilinx.c
+++ b/drivers/pci/pcie_xilinx.c
@@ -23,8 +23,14 @@ struct xilinx_pcie {
 };
 
 /* Register definitions */
-#define XILINX_PCIE_REG_PSCR		0x144
-#define XILINX_PCIE_REG_PSCR_LNKUP	BIT(11)
+#define XILINX_PCIE_REG_BRIDGE_INFO			0x130
+#define  XILINX_PCIE_REG_BRIDGE_INFO_ECAMSZ_SHIFT	16
+#define  XILINX_PCIE_REG_BRIDGE_INFO_ECAMSZ_MASK	(0x7 << 16)
+#define XILINX_PCIE_REG_INT_MASK			0x13c
+#define XILINX_PCIE_REG_PSCR				0x144
+#define  XILINX_PCIE_REG_PSCR_LNKUP			BIT(11)
+#define XILINX_PCIE_REG_RPSC				0x148
+#define  XILINX_PCIE_REG_RPSC_BRIDGEEN			BIT(0)
 
 /**
  * pcie_xilinx_link_up() - Check whether the PCIe link is up
@@ -200,6 +206,31 @@ static int pcie_xilinx_ofdata_to_platdata(struct udevice *dev)
 	return 0;
 }
 
+static int pcie_xilinx_probe(struct udevice *dev)
+{
+	struct xilinx_pcie *pcie = dev_get_priv(dev);
+	u32 bridge_info, ecam_sz, rpsc;
+
+	/* Disable all interrupts */
+	writel(0, pcie->cfg_base + XILINX_PCIE_REG_INT_MASK);
+
+	/* Enable the bridge */
+	rpsc = readl(pcie->cfg_base + XILINX_PCIE_REG_RPSC);
+	rpsc |= XILINX_PCIE_REG_RPSC_BRIDGEEN;
+	writel(rpsc, pcie->cfg_base + XILINX_PCIE_REG_RPSC);
+
+	/* Discover the size of the ECAM region */
+	bridge_info = readl(pcie->cfg_base + XILINX_PCIE_REG_BRIDGE_INFO);
+	ecam_sz = bridge_info & XILINX_PCIE_REG_BRIDGE_INFO_ECAMSZ_MASK;
+	ecam_sz >>= XILINX_PCIE_REG_BRIDGE_INFO_ECAMSZ_SHIFT;
+
+	/* Enable access to all possible subordinate buses */
+	writel((0 << 0) | (1 << 8) | (GENMASK(ecam_sz - 1, 0) << 16),
+	       pcie->cfg_base + PCI_PRIMARY_BUS);
+
+	return 0;
+}
+
 static const struct dm_pci_ops pcie_xilinx_ops = {
 	.read_config	= pcie_xilinx_read_config,
 	.write_config	= pcie_xilinx_write_config,
@@ -216,5 +247,6 @@ U_BOOT_DRIVER(pcie_xilinx) = {
 	.of_match		= pcie_xilinx_ids,
 	.ops			= &pcie_xilinx_ops,
 	.ofdata_to_platdata	= pcie_xilinx_ofdata_to_platdata,
+	.probe			= pcie_xilinx_probe,
 	.priv_auto_alloc_size	= sizeof(struct xilinx_pcie),
 };
-- 
2.10.0



More information about the U-Boot mailing list