]> git.baikalelectronics.ru Git - kernel.git/commitdiff
PCI: qcom: Set up rev 2.1.0 PARF_PHY before enabling clocks
authorChristian Marangi <ansuelsmth@gmail.com>
Fri, 8 Jul 2022 22:27:43 +0000 (00:27 +0200)
committerBjorn Helgaas <bhelgaas@google.com>
Wed, 13 Jul 2022 19:53:02 +0000 (14:53 -0500)
We currently enable clocks BEFORE we write to PARF_PHY_CTRL reg to enable
clocks and resets. This causes the driver to never set to a ready state
with the error 'Phy link never came up'.

This is caused by the PHY clock getting enabled before setting the required
bits in the PARF regs.

A workaround for this was set but with this new discovery we can drop
the workaround and use a proper solution to the problem by just enabling
the clock only AFTER the PARF_PHY_CTRL bit is set.

This correctly sets up the PCIe link and makes it usable even when a
bootloader leaves the PCIe link in an undefined state.

Fixes: d11a813ae6a6 ("PCI: qcom: Add Qualcomm PCIe controller driver")
Link: https://lore.kernel.org/r/20220708222743.27019-1-ansuelsmth@gmail.com
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
drivers/pci/controller/dwc/pcie-qcom.c

index 2ea13750b4924149fa1c8e962f225291b5fa368c..da13a66ced14600a96ed7ecb49933066c2d92d29 100644 (file)
@@ -337,8 +337,6 @@ static int qcom_pcie_init_2_1_0(struct qcom_pcie *pcie)
        reset_control_assert(res->ext_reset);
        reset_control_assert(res->phy_reset);
 
-       writel(1, pcie->parf + PCIE20_PARF_PHY_CTRL);
-
        ret = regulator_bulk_enable(ARRAY_SIZE(res->supplies), res->supplies);
        if (ret < 0) {
                dev_err(dev, "cannot enable regulators\n");
@@ -381,15 +379,15 @@ static int qcom_pcie_init_2_1_0(struct qcom_pcie *pcie)
                goto err_deassert_axi;
        }
 
-       ret = clk_bulk_prepare_enable(ARRAY_SIZE(res->clks), res->clks);
-       if (ret)
-               goto err_clks;
-
        /* enable PCIe clocks and resets */
        val = readl(pcie->parf + PCIE20_PARF_PHY_CTRL);
        val &= ~BIT(0);
        writel(val, pcie->parf + PCIE20_PARF_PHY_CTRL);
 
+       ret = clk_bulk_prepare_enable(ARRAY_SIZE(res->clks), res->clks);
+       if (ret)
+               goto err_clks;
+
        if (of_device_is_compatible(node, "qcom,pcie-ipq8064") ||
            of_device_is_compatible(node, "qcom,pcie-ipq8064-v2")) {
                writel(PCS_DEEMPH_TX_DEEMPH_GEN1(24) |