@@ -900,27 +900,27 @@ static int qcom_pcie_init_2_7_0(struct qcom_pcie *pcie)
return ret;
}
- ret = clk_bulk_prepare_enable(res->num_clks, res->clks);
- if (ret < 0)
- goto err_disable_regulators;
-
+ /* Assert the reset to hold the RC in a known state */
ret = reset_control_assert(res->rst);
if (ret) {
dev_err(dev, "reset assert failed (%d)\n", ret);
- goto err_disable_clocks;
+ goto err_disable_regulators;
}
-
usleep_range(1000, 1500);
+ /* GCC_PCIE_n_AUX_CLK won't come up if the reset is asserted */
ret = reset_control_deassert(res->rst);
if (ret) {
dev_err(dev, "reset deassert failed (%d)\n", ret);
- goto err_disable_clocks;
+ goto err_disable_regulators;
}
-
/* Wait for reset to complete, required on SM8450 */
usleep_range(1000, 1500);
+ ret = clk_bulk_prepare_enable(res->num_clks, res->clks);
+ if (ret < 0)
+ goto err_assert_reset;
+
/* configure PCIe to RC mode */
writel(DEVICE_TYPE_RC, pcie->parf + PARF_DEVICE_TYPE);
@@ -951,8 +951,9 @@ static int qcom_pcie_init_2_7_0(struct qcom_pcie *pcie)
writel(val, pcie->parf + PARF_AXI_MSTR_WR_ADDR_HALT_V2);
return 0;
-err_disable_clocks:
- clk_bulk_disable_unprepare(res->num_clks, res->clks);
+
+err_assert_reset:
+ reset_control_assert(res->rst);
err_disable_regulators:
regulator_bulk_disable(ARRAY_SIZE(res->supplies), res->supplies);
At least on SC8280XP, if the PCIe reset is asserted, the corresponding AUX_CLK will be stuck at 'off'. Assert the reset (which may end up being a NOP if it was previously asserted) and de-assert it back *before* turning on the clocks to avoid such cases. In addition to that, in case the clock bulk enable fails, assert the RC reset back, as the hardware is in an unknown state at best. Fixes: ed8cc3b1fc84 ("PCI: qcom: Add support for SDM845 PCIe controller") Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org> --- drivers/pci/controller/dwc/pcie-qcom.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-)