[PATCH 4/8] pci: pcie_dw_rockchip: Hide BARs of the root complex
Jonas Karlman
jonas at kwiboo.se
Sat Apr 22 20:19:50 CEST 2023
PCI Autoconfig read the Root Complex BARs and try to claim the entire
1 GiB memory region on RK3568, leaving no space for any attached device.
Return an invalid value during config read of Root Complex BARs during
autoconfig to work around such issue.
Signed-off-by: Jonas Karlman <jonas at kwiboo.se>
---
drivers/pci/pcie_dw_rockchip.c | 28 +++++++++++++++++++++++++++-
1 file changed, 27 insertions(+), 1 deletion(-)
diff --git a/drivers/pci/pcie_dw_rockchip.c b/drivers/pci/pcie_dw_rockchip.c
index fd3da47272b3..924ecb93e963 100644
--- a/drivers/pci/pcie_dw_rockchip.c
+++ b/drivers/pci/pcie_dw_rockchip.c
@@ -146,6 +146,32 @@ static inline void rk_pcie_writel_apb(struct rk_pcie *rk_pcie, u32 reg,
__rk_pcie_write_apb(rk_pcie, rk_pcie->apb_base, reg, 0x4, val);
}
+/**
+ * The BARs of bridge should be hidden during enumeration to avoid
+ * allocation of the entire memory region by PCIe core on RK3568.
+ */
+static bool rk_pcie_hide_rc_bar(struct pcie_dw *pcie, pci_dev_t bdf,
+ uint offset)
+{
+ int bus = PCI_BUS(bdf) - pcie->first_busno;
+
+ return bus == 0 && PCI_DEV(bdf) == 0 && PCI_FUNC(bdf) == 0 &&
+ offset >= PCI_BASE_ADDRESS_0 && offset <= PCI_BASE_ADDRESS_1;
+}
+
+static int rk_pcie_read_config(const struct udevice *bus, pci_dev_t bdf,
+ uint offset, ulong *valuep,
+ enum pci_size_t size)
+{
+ struct pcie_dw *pcie = dev_get_priv(bus);
+ int ret = pcie_dw_read_config(bus, bdf, offset, valuep, size);
+
+ if (!ret && rk_pcie_hide_rc_bar(pcie, bdf, offset))
+ *valuep = pci_get_ff(size);
+
+ return ret;
+}
+
/**
* rk_pcie_configure() - Configure link capabilities and speed
*
@@ -476,7 +502,7 @@ rockchip_pcie_probe_err_init_port:
}
static const struct dm_pci_ops rockchip_pcie_ops = {
- .read_config = pcie_dw_read_config,
+ .read_config = rk_pcie_read_config,
.write_config = pcie_dw_write_config,
};
--
2.40.0
More information about the U-Boot
mailing list