On Mon, Jan 20, 2025 at 8:01 AM Stanimir Varbanov <svarbanov@xxxxxxx> wrote: > > Add bare minimum amount of changes in order to support PCIe RC hardware > IP found on RPi5. The PCIe controller on bcm2712 is based on bcm7712 and > as such it inherits register offsets, perst, bridge_reset ops and inbound > windows count. > Although, the implementation for bcm2712 needs a workaround related to the > control of the bridge_reset where turning off of the root port must not > shutdown the bridge_reset and this must be avoided. To implement this > workaround a quirks field is introduced in pcie_cfg_data struct. > > Signed-off-by: Stanimir Varbanov <svarbanov@xxxxxxx> > Reviewed-by: Florian Fainelli <florian.fainelli@xxxxxxxxxxxx> > --- > v4 -> v5: > - No changes. > > drivers/pci/controller/pcie-brcmstb.c | 25 +++++++++++++++++++++++-- > 1 file changed, 23 insertions(+), 2 deletions(-) > > diff --git a/drivers/pci/controller/pcie-brcmstb.c b/drivers/pci/controller/pcie-brcmstb.c > index 59190d8be0fb..50607df34a66 100644 > --- a/drivers/pci/controller/pcie-brcmstb.c > +++ b/drivers/pci/controller/pcie-brcmstb.c > @@ -234,10 +234,20 @@ struct inbound_win { > u64 cpu_addr; > }; > > +/* > + * The RESCAL block is tied to PCIe controller #1, regardless of the number of > + * controllers, and turning off PCIe controller #1 prevents access to the RESCAL > + * register blocks, therefore no other controller can access this register > + * space, and depending upon the bus fabric we may get a timeout (UBUS/GISB), > + * or a hang (AXI). > + */ > +#define CFG_QUIRK_AVOID_BRIDGE_SHUTDOWN BIT(0) > + > struct pcie_cfg_data { > const int *offsets; > const enum pcie_soc_base soc_base; > const bool has_phy; > + const u32 quirks; > u8 num_inbound_wins; > int (*perst_set)(struct brcm_pcie *pcie, u32 val); > int (*bridge_sw_init_set)(struct brcm_pcie *pcie, u32 val); > @@ -1488,8 +1498,9 @@ static int brcm_pcie_turn_off(struct brcm_pcie *pcie) > u32p_replace_bits(&tmp, 1, PCIE_MISC_HARD_PCIE_HARD_DEBUG_SERDES_IDDQ_MASK); > writel(tmp, base + HARD_DEBUG(pcie)); > > - /* Shutdown PCIe bridge */ > - ret = pcie->bridge_sw_init_set(pcie, 1); > + if (!(pcie->cfg->quirks & CFG_QUIRK_AVOID_BRIDGE_SHUTDOWN)) > + /* Shutdown PCIe bridge */ > + ret = pcie->cfg->bridge_sw_init_set(pcie, 1); > > return ret; > } > @@ -1699,6 +1710,15 @@ static const struct pcie_cfg_data bcm2711_cfg = { > .num_inbound_wins = 3, > }; > > +static const struct pcie_cfg_data bcm2712_cfg = { > + .offsets = pcie_offsets_bcm7712, > + .soc_base = BCM7712, > + .perst_set = brcm_pcie_perst_set_7278, > + .bridge_sw_init_set = brcm_pcie_bridge_sw_init_set_generic, > + .quirks = CFG_QUIRK_AVOID_BRIDGE_SHUTDOWN, > + .num_inbound_wins = 10, > +}; > + > static const struct pcie_cfg_data bcm4908_cfg = { > .offsets = pcie_offsets, > .soc_base = BCM4908, > @@ -1750,6 +1770,7 @@ static const struct pcie_cfg_data bcm7712_cfg = { > > static const struct of_device_id brcm_pcie_match[] = { > { .compatible = "brcm,bcm2711-pcie", .data = &bcm2711_cfg }, > + { .compatible = "brcm,bcm2712-pcie", .data = &bcm2712_cfg }, > { .compatible = "brcm,bcm4908-pcie", .data = &bcm4908_cfg }, > { .compatible = "brcm,bcm7211-pcie", .data = &generic_cfg }, > { .compatible = "brcm,bcm7216-pcie", .data = &bcm7216_cfg }, Reviewed-by: Jim Quinlan <james.quinlan@xxxxxxxxxxxx> > -- > 2.47.0 >