6b8f46eae0f84384993a52d1425b42eddbdcbefe
[openwrt/openwrt.git] / target / linux / sunxi / patches-4.9 / 0003-clk-sunxi-ng-Remove-the-use-of-rational-computations.patch
1 From ee28648cb2b4d4ab5c2eb8199ea86675fe19016b Mon Sep 17 00:00:00 2001
2 From: Maxime Ripard <maxime.ripard@free-electrons.com>
3 Date: Thu, 29 Sep 2016 22:53:12 +0200
4 Subject: clk: sunxi-ng: Remove the use of rational computations
5
6 While the rational library works great, it doesn't really allow us to add
7 more constraints, like the minimum.
8
9 Remove that in order to be able to deal with the constraints we'll need.
10
11 Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
12 Acked-by: Chen-Yu Tsai <wens@csie.org>
13 ---
14 drivers/clk/sunxi-ng/Kconfig | 3 ---
15 drivers/clk/sunxi-ng/ccu_nkm.c | 31 ++++++++++++-----------
16 drivers/clk/sunxi-ng/ccu_nkmp.c | 37 ++++++++++++++--------------
17 drivers/clk/sunxi-ng/ccu_nm.c | 54 +++++++++++++++++++++++++++++++----------
18 4 files changed, 74 insertions(+), 51 deletions(-)
19
20 --- a/drivers/clk/sunxi-ng/Kconfig
21 +++ b/drivers/clk/sunxi-ng/Kconfig
22 @@ -35,17 +35,14 @@ config SUNXI_CCU_NK
23
24 config SUNXI_CCU_NKM
25 bool
26 - select RATIONAL
27 select SUNXI_CCU_GATE
28
29 config SUNXI_CCU_NKMP
30 bool
31 - select RATIONAL
32 select SUNXI_CCU_GATE
33
34 config SUNXI_CCU_NM
35 bool
36 - select RATIONAL
37 select SUNXI_CCU_FRAC
38 select SUNXI_CCU_GATE
39
40 --- a/drivers/clk/sunxi-ng/ccu_nkm.c
41 +++ b/drivers/clk/sunxi-ng/ccu_nkm.c
42 @@ -9,7 +9,6 @@
43 */
44
45 #include <linux/clk-provider.h>
46 -#include <linux/rational.h>
47
48 #include "ccu_gate.h"
49 #include "ccu_nkm.h"
50 @@ -28,21 +27,21 @@ static void ccu_nkm_find_best(unsigned l
51 unsigned long _n, _k, _m;
52
53 for (_k = 1; _k <= nkm->max_k; _k++) {
54 - unsigned long tmp_rate;
55 -
56 - rational_best_approximation(rate / _k, parent,
57 - nkm->max_n, nkm->max_m, &_n, &_m);
58 -
59 - tmp_rate = parent * _n * _k / _m;
60 -
61 - if (tmp_rate > rate)
62 - continue;
63 -
64 - if ((rate - tmp_rate) < (rate - best_rate)) {
65 - best_rate = tmp_rate;
66 - best_n = _n;
67 - best_k = _k;
68 - best_m = _m;
69 + for (_n = 1; _n <= nkm->max_n; _n++) {
70 + for (_m = 1; _n <= nkm->max_m; _m++) {
71 + unsigned long tmp_rate;
72 +
73 + tmp_rate = parent * _n * _k / _m;
74 +
75 + if (tmp_rate > rate)
76 + continue;
77 + if ((rate - tmp_rate) < (rate - best_rate)) {
78 + best_rate = tmp_rate;
79 + best_n = _n;
80 + best_k = _k;
81 + best_m = _m;
82 + }
83 + }
84 }
85 }
86
87 --- a/drivers/clk/sunxi-ng/ccu_nkmp.c
88 +++ b/drivers/clk/sunxi-ng/ccu_nkmp.c
89 @@ -9,7 +9,6 @@
90 */
91
92 #include <linux/clk-provider.h>
93 -#include <linux/rational.h>
94
95 #include "ccu_gate.h"
96 #include "ccu_nkmp.h"
97 @@ -29,24 +28,24 @@ static void ccu_nkmp_find_best(unsigned
98 unsigned long _n, _k, _m, _p;
99
100 for (_k = 1; _k <= nkmp->max_k; _k++) {
101 - for (_p = 1; _p <= nkmp->max_p; _p <<= 1) {
102 - unsigned long tmp_rate;
103 -
104 - rational_best_approximation(rate / _k, parent / _p,
105 - nkmp->max_n, nkmp->max_m,
106 - &_n, &_m);
107 -
108 - tmp_rate = parent * _n * _k / (_m * _p);
109 -
110 - if (tmp_rate > rate)
111 - continue;
112 -
113 - if ((rate - tmp_rate) < (rate - best_rate)) {
114 - best_rate = tmp_rate;
115 - best_n = _n;
116 - best_k = _k;
117 - best_m = _m;
118 - best_p = _p;
119 + for (_n = 1; _n <= nkmp->max_n; _n++) {
120 + for (_m = 1; _n <= nkmp->max_m; _m++) {
121 + for (_p = 1; _p <= nkmp->max_p; _p <<= 1) {
122 + unsigned long tmp_rate;
123 +
124 + tmp_rate = parent * _n * _k / (_m * _p);
125 +
126 + if (tmp_rate > rate)
127 + continue;
128 +
129 + if ((rate - tmp_rate) < (rate - best_rate)) {
130 + best_rate = tmp_rate;
131 + best_n = _n;
132 + best_k = _k;
133 + best_m = _m;
134 + best_p = _p;
135 + }
136 + }
137 }
138 }
139 }
140 --- a/drivers/clk/sunxi-ng/ccu_nm.c
141 +++ b/drivers/clk/sunxi-ng/ccu_nm.c
142 @@ -9,12 +9,42 @@
143 */
144
145 #include <linux/clk-provider.h>
146 -#include <linux/rational.h>
147
148 #include "ccu_frac.h"
149 #include "ccu_gate.h"
150 #include "ccu_nm.h"
151
152 +struct _ccu_nm {
153 + unsigned long n, max_n;
154 + unsigned long m, max_m;
155 +};
156 +
157 +static void ccu_nm_find_best(unsigned long parent, unsigned long rate,
158 + struct _ccu_nm *nm)
159 +{
160 + unsigned long best_rate = 0;
161 + unsigned long best_n = 0, best_m = 0;
162 + unsigned long _n, _m;
163 +
164 + for (_n = 1; _n <= nm->max_n; _n++) {
165 + for (_m = 1; _n <= nm->max_m; _m++) {
166 + unsigned long tmp_rate = parent * _n / _m;
167 +
168 + if (tmp_rate > rate)
169 + continue;
170 +
171 + if ((rate - tmp_rate) < (rate - best_rate)) {
172 + best_rate = tmp_rate;
173 + best_n = _n;
174 + best_m = _m;
175 + }
176 + }
177 + }
178 +
179 + nm->n = best_n;
180 + nm->m = best_m;
181 +}
182 +
183 static void ccu_nm_disable(struct clk_hw *hw)
184 {
185 struct ccu_nm *nm = hw_to_ccu_nm(hw);
186 @@ -61,24 +91,22 @@ static long ccu_nm_round_rate(struct clk
187 unsigned long *parent_rate)
188 {
189 struct ccu_nm *nm = hw_to_ccu_nm(hw);
190 - unsigned long max_n, max_m;
191 - unsigned long n, m;
192 + struct _ccu_nm _nm;
193
194 - max_n = 1 << nm->n.width;
195 - max_m = nm->m.max ?: 1 << nm->m.width;
196 + _nm.max_n = 1 << nm->n.width;
197 + _nm.max_m = nm->m.max ?: 1 << nm->m.width;
198
199 - rational_best_approximation(rate, *parent_rate, max_n, max_m, &n, &m);
200 + ccu_nm_find_best(*parent_rate, rate, &_nm);
201
202 - return *parent_rate * n / m;
203 + return *parent_rate * _nm.n / _nm.m;
204 }
205
206 static int ccu_nm_set_rate(struct clk_hw *hw, unsigned long rate,
207 unsigned long parent_rate)
208 {
209 struct ccu_nm *nm = hw_to_ccu_nm(hw);
210 + struct _ccu_nm _nm;
211 unsigned long flags;
212 - unsigned long max_n, max_m;
213 - unsigned long n, m;
214 u32 reg;
215
216 if (ccu_frac_helper_has_rate(&nm->common, &nm->frac, rate))
217 @@ -86,10 +114,10 @@ static int ccu_nm_set_rate(struct clk_hw
218 else
219 ccu_frac_helper_disable(&nm->common, &nm->frac);
220
221 - max_n = 1 << nm->n.width;
222 - max_m = nm->m.max ?: 1 << nm->m.width;
223 + _nm.max_n = 1 << nm->n.width;
224 + _nm.max_m = nm->m.max ?: 1 << nm->m.width;
225
226 - rational_best_approximation(rate, parent_rate, max_n, max_m, &n, &m);
227 + ccu_nm_find_best(parent_rate, rate, &_nm);
228
229 spin_lock_irqsave(nm->common.lock, flags);
230
231 @@ -97,7 +125,7 @@ static int ccu_nm_set_rate(struct clk_hw
232 reg &= ~GENMASK(nm->n.width + nm->n.shift - 1, nm->n.shift);
233 reg &= ~GENMASK(nm->m.width + nm->m.shift - 1, nm->m.shift);
234
235 - writel(reg | ((m - 1) << nm->m.shift) | ((n - 1) << nm->n.shift),
236 + writel(reg | ((_nm.m - 1) << nm->m.shift) | ((_nm.n - 1) << nm->n.shift),
237 nm->common.base + nm->common.reg);
238
239 spin_unlock_irqrestore(nm->common.lock, flags);