PCI: qcom: Switch pcie_1_pipe_clk_src after PHY init in SC7280
authorPrasad Malisetty <pmaliset@codeaurora.org>
Thu, 7 Oct 2021 17:48:43 +0000 (23:18 +0530)
committerBjorn Helgaas <bhelgaas@google.com>
Thu, 14 Oct 2021 21:54:27 +0000 (16:54 -0500)
On the SC7280, the clock source for gcc_pcie_1_pipe_clk_src must be the
TCXO while gdsc is enabled. After PHY init successful clock source should
switch to pipe clock for gcc_pcie_1_pipe_clk_src.

Link: https://lore.kernel.org/r/1633628923-25047-6-git-send-email-pmaliset@codeaurora.org
Signed-off-by: Prasad Malisetty <pmaliset@codeaurora.org>
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Stephen Boyd <swboyd@chromium.org>
drivers/pci/controller/dwc/pcie-qcom.c

index 1c3c01ccb83189b22d4cff8d356bf0905bc0fa42..c4ff996dc443d810702d504dacfb3dd4518b99b5 100644 (file)
@@ -166,6 +166,9 @@ struct qcom_pcie_resources_2_7_0 {
        struct regulator_bulk_data supplies[2];
        struct reset_control *pci_reset;
        struct clk *pipe_clk;
+       struct clk *pipe_clk_src;
+       struct clk *phy_pipe_clk;
+       struct clk *ref_clk_src;
 };
 
 union qcom_pcie_resources {
@@ -191,6 +194,7 @@ struct qcom_pcie_ops {
 
 struct qcom_pcie_cfg {
        const struct qcom_pcie_ops *ops;
+       unsigned int pipe_clk_need_muxing:1;
 };
 
 struct qcom_pcie {
@@ -201,6 +205,7 @@ struct qcom_pcie {
        struct phy *phy;
        struct gpio_desc *reset;
        const struct qcom_pcie_ops *ops;
+       unsigned int pipe_clk_need_muxing:1;
 };
 
 #define to_qcom_pcie(x)                dev_get_drvdata((x)->dev)
@@ -1171,6 +1176,20 @@ static int qcom_pcie_get_resources_2_7_0(struct qcom_pcie *pcie)
        if (ret < 0)
                return ret;
 
+       if (pcie->pipe_clk_need_muxing) {
+               res->pipe_clk_src = devm_clk_get(dev, "pipe_mux");
+               if (IS_ERR(res->pipe_clk_src))
+                       return PTR_ERR(res->pipe_clk_src);
+
+               res->phy_pipe_clk = devm_clk_get(dev, "phy_pipe");
+               if (IS_ERR(res->phy_pipe_clk))
+                       return PTR_ERR(res->phy_pipe_clk);
+
+               res->ref_clk_src = devm_clk_get(dev, "ref");
+               if (IS_ERR(res->ref_clk_src))
+                       return PTR_ERR(res->ref_clk_src);
+       }
+
        res->pipe_clk = devm_clk_get(dev, "pipe");
        return PTR_ERR_OR_ZERO(res->pipe_clk);
 }
@@ -1189,6 +1208,10 @@ static int qcom_pcie_init_2_7_0(struct qcom_pcie *pcie)
                return ret;
        }
 
+       /* Set TCXO as clock source for pcie_pipe_clk_src */
+       if (pcie->pipe_clk_need_muxing)
+               clk_set_parent(res->pipe_clk_src, res->ref_clk_src);
+
        ret = clk_bulk_prepare_enable(res->num_clks, res->clks);
        if (ret < 0)
                goto err_disable_regulators;
@@ -1260,6 +1283,10 @@ static int qcom_pcie_post_init_2_7_0(struct qcom_pcie *pcie)
 {
        struct qcom_pcie_resources_2_7_0 *res = &pcie->res.v2_7_0;
 
+       /* Set pipe clock as clock source for pcie_pipe_clk_src */
+       if (pcie->pipe_clk_need_muxing)
+               clk_set_parent(res->pipe_clk_src, res->phy_pipe_clk);
+
        return clk_prepare_enable(res->pipe_clk);
 }
 
@@ -1490,6 +1517,7 @@ static const struct qcom_pcie_cfg sm8250_cfg = {
 
 static const struct qcom_pcie_cfg sc7280_cfg = {
        .ops = &ops_1_9_0,
+       .pipe_clk_need_muxing = true,
 };
 
 static const struct dw_pcie_ops dw_pcie_ops = {
@@ -1532,6 +1560,7 @@ static int qcom_pcie_probe(struct platform_device *pdev)
        }
 
        pcie->ops = pcie_cfg->ops;
+       pcie->pipe_clk_need_muxing = pcie_cfg->pipe_clk_need_muxing;
 
        pcie->reset = devm_gpiod_get_optional(dev, "perst", GPIOD_OUT_HIGH);
        if (IS_ERR(pcie->reset)) {