[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