Since the STB PCIe HW will cause a CPU abort on a completion timeout abort, we might as well extend the timeout limit. Further, different devices and systems may requires a larger or smaller amount for L1SS exit. Signed-off-by: Jim Quinlan <jim2101024@xxxxxxxxx> --- drivers/pci/controller/pcie-brcmstb.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/drivers/pci/controller/pcie-brcmstb.c b/drivers/pci/controller/pcie-brcmstb.c index 129eee7bdbc1..92d78f4dfaae 100644 --- a/drivers/pci/controller/pcie-brcmstb.c +++ b/drivers/pci/controller/pcie-brcmstb.c @@ -1080,6 +1080,29 @@ static void brcm_config_clkreq(struct brcm_pcie *pcie) writel(clkreq_set, pcie->base + PCIE_MISC_HARD_PCIE_HARD_DEBUG); } +static void brcm_config_completion_timeout(struct brcm_pcie *pcie) +{ + /* TIMEOUT register is two registers before RGR1_SW_INIT_1 */ + const unsigned int REG_OFFSET = PCIE_RGR1_SW_INIT_1(pcie) - 8; + u32 timeout, timeout_msec = 1000; + u64 tmp64; + int ret; + + ret = of_property_read_u32(pcie->np, "brcm,completion-abort-msecs", + &timeout_msec); + + if (ret && ret != -EINVAL) + dev_err(pcie->dev, "bad 'brcm,completion-abort-msecs' prop\n"); + + /* Each unit in timeout register is 1/216,000,000 seconds */ + tmp64 = (u64)216000 * timeout_msec; + + /* Clamp the requested value before writing it */ + timeout = tmp64 > 0xffffffff ? 0xffffffff : tmp64; + timeout = timeout < 0xffff ? 0xffff : timeout; + writel(timeout, pcie->base + REG_OFFSET); +} + static int brcm_pcie_start_link(struct brcm_pcie *pcie) { struct device *dev = pcie->dev; @@ -1110,6 +1133,7 @@ static int brcm_pcie_start_link(struct brcm_pcie *pcie) return -ENODEV; } + brcm_config_completion_timeout(pcie); brcm_config_clkreq(pcie); if (pcie->gen) -- 2.17.1