Re: [PATCH v2 1/5] clk: qcom: cmnpll: Account for reference clock divider
From: George Moussalem <hidden>
Date: 2026-01-07 13:17:22
Also in:
linux-arm-msm, linux-clk, lkml
On 1/7/26 09:35, Luo Jie wrote:
The clk_cmn_pll_recalc_rate() function must account for the reference clock divider programmed in CMN_PLL_REFCLK_CONFIG. Without this fix, platforms with a reference divider other than 1 calculate incorrect CMN PLL rates. For example, on IPQ5332 where the reference divider is 2, the computed rate becomes twice the actual output. Read CMN_PLL_REFCLK_DIV and divide the parent rate by this value before applying the 2 * FACTOR scaling. This yields the correct rate calculation: rate = (parent_rate / ref_div) * 2 * factor. Maintain backward compatibility with earlier platforms (e.g. IPQ9574, IPQ5424, IPQ5018) that use ref_div = 1.
Just tested this patch and can confirm IPQ5018 also has a ref_div of 2.
With this patch applied, the correct assigned clock rate of 4.8GHz is
also reported:
root@OpenWrt:~# cat /sys/kernel/debug/clk/clk_summary | grep cmn -A 3 -B 3
deviceless
no_connection_id
xo-clk 1 1 0 48000000
0 0 50000 Y deviceless
no_connection_id
ref-96mhz-clk 1 1 0 96000000
0 0 50000 Y deviceless
no_connection_id
cmn_pll 0 0 0
4800000000 0 0 50000 Y deviceless
no_connection_id
eth-50mhz 0 0 0 50000000
0 0 50000 Y deviceless
no_connection_id
sleep-32khz 0 0 0 32000
0 0 50000 Y deviceless
no_connection_id
xo-24mhz 0 0 0 24000000
0 0 50000 Y deviceless
no_connection_id
Once accepted, I will submit a patch to correct the assigned clock rate
from 9.6GHz to 4.8GHz as the ref div is now properly applied.
Thanks Luo!
quoted hunk ↗ jump to hunk
Fixes: f81715a4c87c ("clk: qcom: Add CMN PLL clock controller driver for IPQ SoC") Signed-off-by: Luo Jie <jie.luo@oss.qualcomm.com> --- drivers/clk/qcom/ipq-cmn-pll.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-)diff --git a/drivers/clk/qcom/ipq-cmn-pll.c b/drivers/clk/qcom/ipq-cmn-pll.c index dafbf5732048..369798d1ce42 100644 --- a/drivers/clk/qcom/ipq-cmn-pll.c +++ b/drivers/clk/qcom/ipq-cmn-pll.c@@ -185,7 +185,7 @@ static unsigned long clk_cmn_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { struct clk_cmn_pll *cmn_pll = to_clk_cmn_pll(hw); - u32 val, factor; + u32 val, factor, ref_div; /* * The value of CMN_PLL_DIVIDER_CTRL_FACTOR is automatically adjusted@@ -193,8 +193,15 @@ static unsigned long clk_cmn_pll_recalc_rate(struct clk_hw *hw, */ regmap_read(cmn_pll->regmap, CMN_PLL_DIVIDER_CTRL, &val); factor = FIELD_GET(CMN_PLL_DIVIDER_CTRL_FACTOR, val); + if (WARN_ON(factor == 0)) + factor = 1; - return parent_rate * 2 * factor; + regmap_read(cmn_pll->regmap, CMN_PLL_REFCLK_CONFIG, &val); + ref_div = FIELD_GET(CMN_PLL_REFCLK_DIV, val); + if (WARN_ON(ref_div == 0)) + ref_div = 1; + + return div_u64((u64)parent_rate * 2 * factor, ref_div); } static int clk_cmn_pll_determine_rate(struct clk_hw *hw,
Best regards, George