diff options
author | Christian Lamparter <chunkeey@gmail.com> | 2018-03-11 16:42:29 +0100 |
---|---|---|
committer | Mathias Kresin <dev@kresin.me> | 2018-03-14 19:04:51 +0100 |
commit | a44d435c1dc14ffdfb9b533b32eecd23178af151 (patch) | |
tree | 5846e33ae169c379fdb24d7a5a7272022bcae010 /target/linux/ipq40xx/patches-4.14 | |
parent | 1b906723ebea2319ba428ae708867273805ddd43 (diff) | |
download | upstream-a44d435c1dc14ffdfb9b533b32eecd23178af151.tar.gz upstream-a44d435c1dc14ffdfb9b533b32eecd23178af151.tar.bz2 upstream-a44d435c1dc14ffdfb9b533b32eecd23178af151.zip |
ipq40xx: fix apss cpu overclocking spam
There's an interaction issue between the clk changes:"
clk: qcom: ipq4019: Add the apss cpu pll divider clock node
clk: qcom: ipq4019: remove fixed clocks and add pll clocks
" and the cpufreq-dt.
cpufreq-dt is now spamming the kernel-log with the following:
[ 1099.190658] cpu cpu0: dev_pm_opp_set_rate: failed to find current OPP
for freq 761142857 (-34)
This only happens on certain devices like the Compex WPJ428
and AVM FritzBox!4040. However, other devices like the Asus
RT-AC58U and Meraki MR33 work just fine.
The issue stem from the fact that all higher CPU-Clocks
are achieved by switching the clock-parent to the P_DDRPLLAPSS
(ddrpllapss). Which is set by Qualcomm's proprietary bootcode
as part of the DDR calibration.
For example, the FB4040 uses 256 MiB Nanya NT5CC128M16IP clocked
at round 533 MHz (ddrpllsdcc = 190285714 Hz).
whereas the 128 MiB Nanya NT5CC64M16GP-DI in the ASUS RT-AC58U is
clocked at a slightly higher 537 MHz ( ddrpllsdcc = 192000000 Hz).
Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
Diffstat (limited to 'target/linux/ipq40xx/patches-4.14')
-rw-r--r-- | target/linux/ipq40xx/patches-4.14/017-qcom-ipq4019-add-cpu-operating-points-for-cpufreq-su.patch | 4 | ||||
-rw-r--r-- | target/linux/ipq40xx/patches-4.14/900-clk-fix.patch | 111 |
2 files changed, 113 insertions, 2 deletions
diff --git a/target/linux/ipq40xx/patches-4.14/017-qcom-ipq4019-add-cpu-operating-points-for-cpufreq-su.patch b/target/linux/ipq40xx/patches-4.14/017-qcom-ipq4019-add-cpu-operating-points-for-cpufreq-su.patch index 138a2dd8b2..03e9021a42 100644 --- a/target/linux/ipq40xx/patches-4.14/017-qcom-ipq4019-add-cpu-operating-points-for-cpufreq-su.patch +++ b/target/linux/ipq40xx/patches-4.14/017-qcom-ipq4019-add-cpu-operating-points-for-cpufreq-su.patch @@ -69,8 +69,8 @@ Signed-off-by: Matthew McClintock <mmcclint@codeaurora.org> + opp-hz = /bits/ 64 <500000000>; + clock-latency-ns = <256000>; + }; -+ opp-716800000 { -+ opp-hz = /bits/ 64 <716800000>; ++ opp-716000000 { ++ opp-hz = /bits/ 64 <716000000>; + clock-latency-ns = <256000>; }; }; diff --git a/target/linux/ipq40xx/patches-4.14/900-clk-fix.patch b/target/linux/ipq40xx/patches-4.14/900-clk-fix.patch new file mode 100644 index 0000000000..1c6b8c831d --- /dev/null +++ b/target/linux/ipq40xx/patches-4.14/900-clk-fix.patch @@ -0,0 +1,111 @@ +From 12e9319da1adacac92930c899c99f0e1970cac11 Mon Sep 17 00:00:00 2001 +From: Christian Lamparter <chunkeey@googlemail.com> +Date: Thu, 11 Mar 2018 14:41:31 +0100 +Subject: [PATCH] clk: fix apss cpu overclocking + +There's an interaction issue between the clk changes:" +clk: qcom: ipq4019: Add the apss cpu pll divider clock node +clk: qcom: ipq4019: remove fixed clocks and add pll clocks +" and the cpufreq-dt. + +cpufreq-dt is now spamming the kernel-log with the following: + +[ 1099.190658] cpu cpu0: dev_pm_opp_set_rate: failed to find current OPP +for freq 761142857 (-34) + +This only happens on certain devices like the Compex WPJ428 +and AVM FritzBox!4040. However, other devices like the Asus +RT-AC58U and Meraki MR33 work just fine. + +The issue stem from the fact that all higher CPU-Clocks +are achieved by switching the clock-parent to the P_DDRPLLAPSS +(ddrpllapss). Which is set by Qualcomm's proprietary bootcode +as part of the DDR calibration. + +For example, the FB4040 uses 256 MiB Nanya NT5CC128M16IP clocked +at round 533 MHz (ddrpllsdcc = 190285714 Hz). + +whereas the 128 MiB Nanya NT5CC64M16GP-DI in the ASUS RT-AC58U is +clocked at a slightly higher 537 MHz ( ddrpllsdcc = 192000000 Hz). + +This patch attempts to fix the issue by modifying +clk_cpu_div_round_rate(), clk_cpu_div_set_rate(), clk_cpu_div_recalc_rate() +to use a new qcom_find_freq_close() function, which returns the closest +matching frequency, instead of the next higher. This way, the SoC in +the FB4040 (with its max clock speed of 710.4 MHz) will no longer +try to overclock to 761 MHz. + +Fixes: d83dcacea18 ("clk: qcom: ipq4019: Add the apss cpu pll divider clock node") +Signed-off-by: Christian Lamparter <chunkeey@gmail.com> +--- +--- a/drivers/clk/qcom/gcc-ipq4019.c ++++ b/drivers/clk/qcom/gcc-ipq4019.c +@@ -1253,6 +1253,29 @@ static const struct clk_fepll_vco gcc_fe + .reg = 0x2f020, + }; + ++ ++const struct freq_tbl *qcom_find_freq_close(const struct freq_tbl *f, ++ unsigned long rate) ++{ ++ const struct freq_tbl *last = NULL; ++ ++ for ( ; f->freq; f++) { ++ if (rate == f->freq) ++ return f; ++ ++ if (f->freq > rate) { ++ if (!last || ++ (f->freq - rate) < (rate - last->freq)) ++ return f; ++ else ++ return last; ++ } ++ last = f; ++ } ++ ++ return last; ++} ++ + /* + * Round rate function for APSS CPU PLL Clock divider. + * It looks up the frequency table and returns the next higher frequency +@@ -1265,7 +1288,7 @@ static long clk_cpu_div_round_rate(struc + struct clk_hw *p_hw; + const struct freq_tbl *f; + +- f = qcom_find_freq(pll->freq_tbl, rate); ++ f = qcom_find_freq_close(pll->freq_tbl, rate); + if (!f) + return -EINVAL; + +@@ -1288,7 +1311,7 @@ static int clk_cpu_div_set_rate(struct c + u32 mask; + int ret; + +- f = qcom_find_freq(pll->freq_tbl, rate); ++ f = qcom_find_freq_close(pll->freq_tbl, rate); + if (!f) + return -EINVAL; + +@@ -1315,6 +1338,7 @@ static unsigned long + clk_cpu_div_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) + { ++ const struct freq_tbl *f; + struct clk_fepll *pll = to_clk_fepll(hw); + u32 cdiv, pre_div; + u64 rate; +@@ -1335,7 +1359,11 @@ clk_cpu_div_recalc_rate(struct clk_hw *h + rate = clk_fepll_vco_calc_rate(pll, parent_rate) * 2; + do_div(rate, pre_div); + +- return rate; ++ f = qcom_find_freq_close(pll->freq_tbl, rate); ++ if (!f) ++ return rate; ++ ++ return f->freq; + }; + + static const struct clk_ops clk_regmap_cpu_div_ops = { |