diff mbox series

[2/3] clk: qcom: clk-alpha-pll: Add support to reconfigure PLL

Message ID 20250113-support-pll-reconfigure-v1-2-1fae6bc1062d@quicinc.com
State New
Headers show
Series Add support to reconfigure PLL | expand

Commit Message

Taniya Das Jan. 13, 2025, 5:27 p.m. UTC
During boot-up, there is a possibility that the PLL configuration might
be missed even after invoking pll_configure() from the clock controller
probe. This is often due to the PLL being connected to rail or rails
that are in an OFF state and current clock controller also cannot vote
on multiple rails. As a result, the PLL may be enabled with suboptimal
settings, leading to functional issues.

The PLL configuration, now part of clk_alpha_pll, can be reused to
reconfigure the PLL to a known good state before scaling for frequency.
The 'clk_alpha_pll_reconfigure()' can be updated to support more PLLs
in future.

Signed-off-by: Taniya Das <quic_tdas@quicinc.com>
---
 drivers/clk/qcom/clk-alpha-pll.c | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)
diff mbox series

Patch

diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c
index 9a65d14acf71c97912664be4f6f78891cab4afa3..eb27c0992c7f9281dac4f2fc792084292c21a6c1 100644
--- a/drivers/clk/qcom/clk-alpha-pll.c
+++ b/drivers/clk/qcom/clk-alpha-pll.c
@@ -1750,6 +1750,26 @@  static int alpha_pll_lucid_prepare(struct clk_hw *hw)
 	return __alpha_pll_trion_prepare(hw, LUCID_PCAL_DONE);
 }
 
+#define GET_PLL_TYPE(pll)    ((pll->regs - clk_alpha_pll_regs[0]) / PLL_OFF_MAX_REGS)
+static void clk_alpha_pll_reconfigure(struct clk_alpha_pll *pll)
+{
+	if (!pll->config || !pll->regs)
+		return;
+
+	pr_debug("configuring the PLL again!\n");
+
+	switch (GET_PLL_TYPE(pll)) {
+	case CLK_ALPHA_PLL_TYPE_LUCID_OLE:
+		clk_lucid_ole_pll_configure(pll, pll->clkr.regmap, pll->config);
+		break;
+	case CLK_ALPHA_PLL_TYPE_LUCID_EVO:
+		clk_lucid_evo_pll_configure(pll, pll->clkr.regmap, pll->config);
+		break;
+	default:
+		break;
+	}
+}
+
 static int __alpha_pll_trion_set_rate(struct clk_hw *hw, unsigned long rate,
 				      unsigned long prate, u32 latch_bit, u32 latch_ack)
 {
@@ -1765,6 +1785,11 @@  static int __alpha_pll_trion_set_rate(struct clk_hw *hw, unsigned long rate,
 	if (ret < 0)
 		return ret;
 
+	regmap_read(pll->clkr.regmap, PLL_L_VAL(pll), &val);
+	/* Check if the PLL is in good state to accept set rate requests. */
+	if (!(val & LUCID_EVO_PLL_L_VAL_MASK))
+		clk_alpha_pll_reconfigure(pll);
+
 	regmap_update_bits(pll->clkr.regmap, PLL_L_VAL(pll), LUCID_EVO_PLL_L_VAL_MASK,  l);
 	regmap_write(pll->clkr.regmap, PLL_ALPHA_VAL(pll), a);
 
@@ -2372,6 +2397,11 @@  static int alpha_pll_lucid_evo_enable(struct clk_hw *hw)
 	if (trion_pll_is_enabled(pll, regmap))
 		return 0;
 
+	regmap_read(pll->clkr.regmap, PLL_L_VAL(pll), &val);
+	/* Check if the PLL is in good state to accept enable requests */
+	if (!(val & LUCID_EVO_PLL_L_VAL_MASK))
+		clk_alpha_pll_reconfigure(pll);
+
 	ret = regmap_update_bits(regmap, PLL_MODE(pll), PLL_RESET_N, PLL_RESET_N);
 	if (ret)
 		return ret;