OpenWrt – Blame information for rev 2
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | From f2b87dc1028b710ec8ce25808b9d21f92b376184 Mon Sep 17 00:00:00 2001 |
2 | From: Christian Lamparter <chunkeey@googlemail.com> |
||
3 | Date: Sun, 11 Mar 2018 14:41:31 +0100 |
||
4 | Subject: [PATCH 2/2] clk: fix apss cpu overclocking |
||
5 | |||
6 | There's an interaction issue between the clk changes:" |
||
7 | clk: qcom: ipq4019: Add the apss cpu pll divider clock node |
||
8 | clk: qcom: ipq4019: remove fixed clocks and add pll clocks |
||
9 | " and the cpufreq-dt. |
||
10 | |||
11 | cpufreq-dt is now spamming the kernel-log with the following: |
||
12 | |||
13 | [ 1099.190658] cpu cpu0: dev_pm_opp_set_rate: failed to find current OPP |
||
14 | for freq 761142857 (-34) |
||
15 | |||
16 | This only happens on certain devices like the Compex WPJ428 |
||
17 | and AVM FritzBox!4040. However, other devices like the Asus |
||
18 | RT-AC58U and Meraki MR33 work just fine. |
||
19 | |||
20 | The issue stem from the fact that all higher CPU-Clocks |
||
21 | are achieved by switching the clock-parent to the P_DDRPLLAPSS |
||
22 | (ddrpllapss). Which is set by Qualcomm's proprietary bootcode |
||
23 | as part of the DDR calibration. |
||
24 | |||
25 | For example, the FB4040 uses 256 MiB Nanya NT5CC128M16IP clocked |
||
26 | at round 533 MHz (ddrpllsdcc = 190285714 Hz). |
||
27 | |||
28 | whereas the 128 MiB Nanya NT5CC64M16GP-DI in the ASUS RT-AC58U is |
||
29 | clocked at a slightly higher 537 MHz ( ddrpllsdcc = 192000000 Hz). |
||
30 | |||
31 | This patch attempts to fix the issue by modifying |
||
32 | clk_cpu_div_round_rate(), clk_cpu_div_set_rate(), clk_cpu_div_recalc_rate() |
||
33 | to use a new qcom_find_freq_close() function, which returns the closest |
||
34 | matching frequency, instead of the next higher. This way, the SoC in |
||
35 | the FB4040 (with its max clock speed of 710.4 MHz) will no longer |
||
36 | try to overclock to 761 MHz. |
||
37 | |||
38 | Fixes: d83dcacea18 ("clk: qcom: ipq4019: Add the apss cpu pll divider clock node") |
||
39 | Signed-off-by: Christian Lamparter <chunkeey@gmail.com> |
||
40 | Signed-off-by: John Crispin <john@phrozen.org> |
||
41 | --- |
||
42 | drivers/clk/qcom/gcc-ipq4019.c | 34 +++++++++++++++++++++++++++++++--- |
||
43 | 1 file changed, 31 insertions(+), 3 deletions(-) |
||
44 | |||
45 | --- a/drivers/clk/qcom/gcc-ipq4019.c |
||
46 | +++ b/drivers/clk/qcom/gcc-ipq4019.c |
||
47 | @@ -1253,6 +1253,29 @@ static const struct clk_fepll_vco gcc_fe |
||
48 | .reg = 0x2f020, |
||
49 | }; |
||
50 | |||
51 | + |
||
52 | +const struct freq_tbl *qcom_find_freq_close(const struct freq_tbl *f, |
||
53 | + unsigned long rate) |
||
54 | +{ |
||
55 | + const struct freq_tbl *last = NULL; |
||
56 | + |
||
57 | + for ( ; f->freq; f++) { |
||
58 | + if (rate == f->freq) |
||
59 | + return f; |
||
60 | + |
||
61 | + if (f->freq > rate) { |
||
62 | + if (!last || |
||
63 | + (f->freq - rate) < (rate - last->freq)) |
||
64 | + return f; |
||
65 | + else |
||
66 | + return last; |
||
67 | + } |
||
68 | + last = f; |
||
69 | + } |
||
70 | + |
||
71 | + return last; |
||
72 | +} |
||
73 | + |
||
74 | /* |
||
75 | * Round rate function for APSS CPU PLL Clock divider. |
||
76 | * It looks up the frequency table and returns the next higher frequency |
||
77 | @@ -1265,7 +1288,7 @@ static long clk_cpu_div_round_rate(struc |
||
78 | struct clk_hw *p_hw; |
||
79 | const struct freq_tbl *f; |
||
80 | |||
81 | - f = qcom_find_freq(pll->freq_tbl, rate); |
||
82 | + f = qcom_find_freq_close(pll->freq_tbl, rate); |
||
83 | if (!f) |
||
84 | return -EINVAL; |
||
85 | |||
86 | @@ -1288,7 +1311,7 @@ static int clk_cpu_div_set_rate(struct c |
||
87 | u32 mask; |
||
88 | int ret; |
||
89 | |||
90 | - f = qcom_find_freq(pll->freq_tbl, rate); |
||
91 | + f = qcom_find_freq_close(pll->freq_tbl, rate); |
||
92 | if (!f) |
||
93 | return -EINVAL; |
||
94 | |||
95 | @@ -1315,6 +1338,7 @@ static unsigned long |
||
96 | clk_cpu_div_recalc_rate(struct clk_hw *hw, |
||
97 | unsigned long parent_rate) |
||
98 | { |
||
99 | + const struct freq_tbl *f; |
||
100 | struct clk_fepll *pll = to_clk_fepll(hw); |
||
101 | u32 cdiv, pre_div; |
||
102 | u64 rate; |
||
103 | @@ -1335,7 +1359,11 @@ clk_cpu_div_recalc_rate(struct clk_hw *h |
||
104 | rate = clk_fepll_vco_calc_rate(pll, parent_rate) * 2; |
||
105 | do_div(rate, pre_div); |
||
106 | |||
107 | - return rate; |
||
108 | + f = qcom_find_freq_close(pll->freq_tbl, rate); |
||
109 | + if (!f) |
||
110 | + return rate; |
||
111 | + |
||
112 | + return f->freq; |
||
113 | }; |
||
114 | |||
115 | static const struct clk_ops clk_regmap_cpu_div_ops = { |