[PATCH v4 04/12] clk: qcom: ipq-cmn-pll: Register CMN PLL /2 clock
From: Luo Jie
Date: Sun Sep 06 2026 - 10:19:39 EST
Most CMN PLL output clocks are derived from the 12 GHz PLL output
through a shared, physical /2 stage, ahead of any further per-clock
processing: a gated fixed rate (PCS/ETH0/ETH1/ETH2/EPHY/ETH), a
configurable divider (NSS/PPE/PON), or a rate-select bit (EPHY-RAW).
This /2 stage is present in the CMN PLL block on every SoC supported
by this driver.
Register this /2 stage once as a fixed-factor clock, "cmn_pll_div2",
and store it on struct clk_cmn_pll so the output clock types can parent
on it. The two plain fixed-rate outputs, xo-24mhz and sleep-32khz, are
the exception on IPQ5210 SoC: they stay parented directly on the main
PLL clock.
On SoCs other than IPQ5210, every output clock is a plain fixed-rate
clock (CMN_PLL_CLK_FIXED_RATE) whose rate is a hardcoded absolute
value rather than one computed from the parent rate, so this /2 clock
is registered there but currently has no consumers; IPQ5210 is simply
the first SoC in this driver whose output clocks are modeled as
depending on parent_rate, which is what makes the /2 stage significant.
Signed-off-by: Luo Jie <jie.luo@xxxxxxxxxxxxxxxx>
---
drivers/clk/qcom/ipq-cmn-pll.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/drivers/clk/qcom/ipq-cmn-pll.c b/drivers/clk/qcom/ipq-cmn-pll.c
index 4fdf78f6829e..c86f7982607c 100644
--- a/drivers/clk/qcom/ipq-cmn-pll.c
+++ b/drivers/clk/qcom/ipq-cmn-pll.c
@@ -96,10 +96,13 @@ struct cmn_pll_fixed_output_clk {
* struct clk_cmn_pll - CMN PLL hardware specific data
* @regmap: hardware regmap.
* @hw: handle between common and hardware-specific interfaces
+ * @div2_hw: fixed /2 clock derived from the CMN PLL output; present on
+ * every supported SoC.
*/
struct clk_cmn_pll {
struct regmap *regmap;
struct clk_hw hw;
+ struct clk_hw *div2_hw;
};
#define CLK_PLL_OUTPUT(_id, _name, _rate) { \
@@ -362,6 +365,7 @@ static int ipq_cmn_pll_register_clks(struct platform_device *pdev)
const struct cmn_pll_fixed_output_clk *p, *fixed_clk;
struct clk_hw_onecell_data *hw_data;
struct device *dev = &pdev->dev;
+ struct clk_cmn_pll *cmn_pll;
struct clk_hw *cmn_pll_hw;
unsigned int num_clks;
struct clk_hw *hw;
@@ -388,6 +392,14 @@ static int ipq_cmn_pll_register_clks(struct platform_device *pdev)
if (IS_ERR(cmn_pll_hw))
return PTR_ERR(cmn_pll_hw);
+ cmn_pll = to_clk_cmn_pll(cmn_pll_hw);
+ cmn_pll->div2_hw = devm_clk_hw_register_fixed_factor_parent_hw(dev,
+ "cmn_pll_div2",
+ cmn_pll_hw,
+ 0, 1, 2);
+ if (IS_ERR(cmn_pll->div2_hw))
+ return PTR_ERR(cmn_pll->div2_hw);
+
/* Register the fixed rate output clocks. */
for (i = 0; i < num_clks; i++) {
struct clk_parent_data pdata = { .hw = cmn_pll_hw };
--
2.43.0