Message ID | 20240326-alpha-pll-fix-stromer-set-rate-v2-1-48ae83af71c8@gmail.com |
---|---|
State | New |
Headers | show |
Series | [v2] clk: qcom: clk-alpha-pll: fix rate setting for Stromer PLLs | expand |
2024. 03. 26. 21:51 keltezéssel, Konrad Dybcio írta: ... >> diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c >> index 8a412ef47e163..8e98198d4b4b6 100644 >> --- a/drivers/clk/qcom/clk-alpha-pll.c >> +++ b/drivers/clk/qcom/clk-alpha-pll.c >> @@ -2490,6 +2490,10 @@ static int clk_alpha_pll_stromer_set_rate(struct clk_hw *hw, unsigned long rate, >> rate = alpha_pll_round_rate(rate, prate, &l, &a, ALPHA_REG_BITWIDTH); >> >> regmap_write(pll->clkr.regmap, PLL_L_VAL(pll), l); >> + >> + if (ALPHA_REG_BITWIDTH > ALPHA_BITWIDTH) >> + a <<= ALPHA_REG_BITWIDTH - ALPHA_BITWIDTH; > > Uh.. that's not right, this is comparing two constants > > Did you mean to use pll_alpha_width()? No, not in this patch at least. The clk_alpha_pll_stromer_set_rate() function assumes that the alpha register is 40 bits wide, and currently it does not use pll_alpha_width() at all. Originally, I have converted the function to use it, but that made the change unnecessarily complex since it was a mix of a fix and of a rework. The current patch is a simplified version of that, but i forgot to drop the comparison at the end of the process. In order to keep this fix as simple as possible and backportable to stable kernels, I would rather remove the comparison to reduce the change to a single-line addition. Then modifying the code to use pll_alpha_width() can be done in a separate change. Regards, Gabor
diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c index 8a412ef47e163..8e98198d4b4b6 100644 --- a/drivers/clk/qcom/clk-alpha-pll.c +++ b/drivers/clk/qcom/clk-alpha-pll.c @@ -2490,6 +2490,10 @@ static int clk_alpha_pll_stromer_set_rate(struct clk_hw *hw, unsigned long rate, rate = alpha_pll_round_rate(rate, prate, &l, &a, ALPHA_REG_BITWIDTH); regmap_write(pll->clkr.regmap, PLL_L_VAL(pll), l); + + if (ALPHA_REG_BITWIDTH > ALPHA_BITWIDTH) + a <<= ALPHA_REG_BITWIDTH - ALPHA_BITWIDTH; + regmap_write(pll->clkr.regmap, PLL_ALPHA_VAL(pll), a); regmap_write(pll->clkr.regmap, PLL_ALPHA_VAL_U(pll), a >> ALPHA_BITWIDTH);
The clk_alpha_pll_stromer_set_rate() function writes inproper values into the ALPHA_VAL{,_U} registers which results in wrong clock rates when the alpha value is used. The broken behaviour can be seen on IPQ5018 for example, when dynamic scaling sets the CPU frequency to 800000 KHz. In this case the CPU cores are running only at 792031 KHz: # cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq 800000 # cat /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_cur_freq 792031 This happens because the function ignores the fact that the alpha value calculated by the alpha_pll_round_rate() function is only 32 bits wide which must be extended to 40 bits if it is used on a hardware which supports 40 bits wide values. Extend the clk_alpha_pll_stromer_set_rate() function to convert the alpha value to 40 bits before wrinting that into the registers in order to ensure that the hardware really uses the requested rate. After the change the CPU frequency is correct: # cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq 800000 # cat /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_cur_freq 800000 Cc: stable@vger.kernel.org Fixes: e47a4f55f240 ("clk: qcom: clk-alpha-pll: Add support for Stromer PLLs") Signed-off-by: Gabor Juhos <j4g8y7@gmail.com> --- Changes in v2: - fix subject prefix - rebase on v6.9-rc1 - Link to v1: https://lore.kernel.org/r/20240324-alpha-pll-fix-stromer-set-rate-v1-1-335b0b157219@gmail.com Depends on the following patch: https://lore.kernel.org/r/20240315-apss-ipq-pll-ipq5018-hang-v2-1-6fe30ada2009@gmail.com --- drivers/clk/qcom/clk-alpha-pll.c | 4 ++++ 1 file changed, 4 insertions(+) --- base-commit: 5eab983c5e31e5f0bf2d583731e320e21814d1b7 change-id: 20240324-alpha-pll-fix-stromer-set-rate-472376e624f0 Best regards,