[openwrt/openwrt] ipq40xx: fix apss cpu overclocking spam

LEDE Commits lede-commits at lists.infradead.org
Wed Mar 14 11:40:09 PDT 2018


mkresin pushed a commit to openwrt/openwrt.git, branch master:
https://git.lede-project.org/a44d435c1dc14ffdfb9b533b32eecd23178af151

commit a44d435c1dc14ffdfb9b533b32eecd23178af151
Author: Christian Lamparter <chunkeey at gmail.com>
AuthorDate: Sun Mar 11 16:42:29 2018 +0100

    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 at gmail.com>
---
 ...9-add-cpu-operating-points-for-cpufreq-su.patch |   4 +-
 .../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 138a2dd..03e9021 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 at 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 0000000..1c6b8c8
--- /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 at 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 at 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 = {



More information about the lede-commits mailing list