diff options
author | Jim Quinlan <james.quinlan@broadcom.com> | 2024-08-16 01:57:19 +0300 |
---|---|---|
committer | Krzysztof Wilczyński <kwilczynski@kernel.org> | 2024-09-04 16:59:28 +0300 |
commit | 8201360218c6a42b3f7ff03d8908bd345e3620f4 (patch) | |
tree | 17dcba33585a1541733915d64dc523878f9f9fbe /drivers/pci/controller | |
parent | 46cb27f671f2148005ee556b895d6372c6608e27 (diff) | |
download | linux-8201360218c6a42b3f7ff03d8908bd345e3620f4.tar.xz |
PCI: brcmstb: Use swinit reset if available
The 7712 SoC adds a software init reset device for the PCIe HW.
If found in the DT node, use it.
Link: https://lore.kernel.org/linux-pci/20240815225731.40276-7-james.quinlan@broadcom.com
Signed-off-by: Jim Quinlan <james.quinlan@broadcom.com>
Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Diffstat (limited to 'drivers/pci/controller')
-rw-r--r-- | drivers/pci/controller/pcie-brcmstb.c | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/drivers/pci/controller/pcie-brcmstb.c b/drivers/pci/controller/pcie-brcmstb.c index f8b6765d2e65..926644eff39d 100644 --- a/drivers/pci/controller/pcie-brcmstb.c +++ b/drivers/pci/controller/pcie-brcmstb.c @@ -266,6 +266,7 @@ struct brcm_pcie { struct reset_control *rescal; struct reset_control *perst_reset; struct reset_control *bridge_reset; + struct reset_control *swinit_reset; int num_memc; u64 memc_size[PCIE_BRCM_MAX_MEMC]; u32 hw_rev; @@ -1635,12 +1636,35 @@ static int brcm_pcie_probe(struct platform_device *pdev) if (IS_ERR(pcie->bridge_reset)) return PTR_ERR(pcie->bridge_reset); + pcie->swinit_reset = devm_reset_control_get_optional_exclusive(&pdev->dev, "swinit"); + if (IS_ERR(pcie->swinit_reset)) + return PTR_ERR(pcie->swinit_reset); + ret = clk_prepare_enable(pcie->clk); if (ret) return dev_err_probe(&pdev->dev, ret, "could not enable clock\n"); pcie->bridge_sw_init_set(pcie, 0); + if (pcie->swinit_reset) { + ret = reset_control_assert(pcie->swinit_reset); + if (ret) { + clk_disable_unprepare(pcie->clk); + return dev_err_probe(&pdev->dev, ret, + "could not assert reset 'swinit'\n"); + } + + /* HW team recommends 1us for proper sync and propagation of reset */ + udelay(1); + + ret = reset_control_deassert(pcie->swinit_reset); + if (ret) { + clk_disable_unprepare(pcie->clk); + return dev_err_probe(&pdev->dev, ret, + "could not de-assert reset 'swinit'\n"); + } + } + ret = reset_control_reset(pcie->rescal); if (ret) { clk_disable_unprepare(pcie->clk); |