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.bur...@imgtec.com>
Cc: Daniel Schwierzeck <daniel.schwierz...@gmail.com>
Cc: u-boot@lists.denx.de
Signed-off-by: Paul Burton <paul.bur...@mips.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 57112f5333..877087d4f1 100644
--- a/drivers/pci/pcie_xilinx.c
+++ b/drivers/pci/pcie_xilinx.c
@@ -21,8 +21,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
@@ -159,6 +165,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,
@@ -175,5 +206,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.15.0

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot

Reply via email to