BRCM PCIe controller has different means of accessing to its own
config space and to device's config space. To support this quirk,
its driver uses simple heuristic:
when PCI subsystem probes Bus 0, the driver assumes
that the subsystem tries to accesses PCIe controller config space,
when PCI subsystem probes other busses, the driver uses mechanism
for device config space access. This heuristic works well when
there is only one PCIe controller in the system.
But U-Boot does not support concept of "PCI Segment", so when there
are more than one PCI controller:
- first one gets Bus address 0,
- second one - Bus address 2 and so on.
This breaks the brcm driver, because it tries to access second PCIe
controller config space as if it is device. To fix this, we introduce
additional property bus_base that holds a PCIe controller own Bus
address.
We use this property to calculate "real" Bus address for
underlying devices.
Please note that this fix may not support a case when we have
PCI-to-PCI bridges behind the second PCIe controller.

Signed-off-by: Oleksii Moisieiev <[email protected]>
Reviewed-by: Volodymyr Babchuk <[email protected]>
---

 drivers/pci/pcie_brcmstb.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/pci/pcie_brcmstb.c b/drivers/pci/pcie_brcmstb.c
index 9de5c0e980..2e58ea453e 100644
--- a/drivers/pci/pcie_brcmstb.c
+++ b/drivers/pci/pcie_brcmstb.c
@@ -202,6 +202,7 @@ struct brcm_pcie {
        struct reset_ctl        rescal;
        struct reset_ctl        bridge_reset;
        const struct brcm_pcie_cfg_data *pcie_cfg;
+       uint16_t                bus_base;
 };
 
 /**
@@ -313,6 +314,7 @@ static int brcm_pcie_config_address(const struct udevice 
*dev, pci_dev_t bdf,
         * Busses 0 (host PCIe bridge) and 1 (its immediate child)
         * are limited to a single device each
         */
+       pci_bus -= pcie->bus_base;
        if (pci_bus < 2 && pci_dev > 0)
                return -EINVAL;
 
@@ -631,6 +633,8 @@ static int brcm_pcie_probe(struct udevice *dev)
        u16 nlw, cls, lnksta;
        u32 tmp;
 
+       pcie->bus_base = hose->first_busno;
+
        /*
         * Deassert rescal reset for BCM2712.
         */
-- 
2.34.1

Reply via email to