[PATCH v2 -next 05/11] PCI: brcmstb: Restore CRS in RootCtl after prstn_n

From: Stanimir Varbanov
Date: Tue Sep 10 2024 - 11:21:04 EST


RootCtl bits might reset by perst_n during probe, re-enable
CRS SVE here in pcie_start_link.

Signed-off-by: Stanimir Varbanov <svarbanov@xxxxxxx>
---
drivers/pci/controller/pcie-brcmstb.c | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/controller/pcie-brcmstb.c b/drivers/pci/controller/pcie-brcmstb.c
index 7bd85566c242..f2a7a8e93a74 100644
--- a/drivers/pci/controller/pcie-brcmstb.c
+++ b/drivers/pci/controller/pcie-brcmstb.c
@@ -1271,7 +1271,7 @@ static int brcm_pcie_start_link(struct brcm_pcie *pcie)
{
struct device *dev = pcie->dev;
void __iomem *base = pcie->base;
- u16 nlw, cls, lnksta;
+ u16 nlw, cls, lnksta, tmp16;
bool ssc_good = false;
int ret, i;

@@ -1319,6 +1319,17 @@ static int brcm_pcie_start_link(struct brcm_pcie *pcie)
pci_speed_string(pcie_link_speed[cls]), nlw,
ssc_good ? "(SSC)" : "(!SSC)");

+ /*
+ * RootCtl bits are reset by perst_n, which undoes pci_enable_crs()
+ * called prior to pci_add_new_bus() during probe. Re-enable here.
+ */
+ tmp16 = readw(base + BRCM_PCIE_CAP_REGS + PCI_EXP_RTCAP);
+ if (tmp16 & PCI_EXP_RTCAP_CRSVIS) {
+ tmp16 = readw(base + BRCM_PCIE_CAP_REGS + PCI_EXP_RTCTL);
+ u16p_replace_bits(&tmp16, 1, PCI_EXP_RTCTL_CRSSVE);
+ writew(tmp16, base + BRCM_PCIE_CAP_REGS + PCI_EXP_RTCTL);
+ }
+
return 0;
}

--
2.35.3