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
6 While the rational library works great, it doesn't really allow us to add
7 more constraints, like the minimum.
9 Remove that in order to be able to deal with the constraints we'll need.
11 Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
12 Acked-by: Chen-Yu Tsai <wens@csie.org>
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(-)
20 --- a/drivers/clk/sunxi-ng/Kconfig
21 +++ b/drivers/clk/sunxi-ng/Kconfig
22 @@ -36,17 +36,14 @@ config SUNXI_CCU_NK
40 --- a/drivers/clk/sunxi-ng/ccu_nkm.c
41 +++ b/drivers/clk/sunxi-ng/ccu_nkm.c
45 #include <linux/clk-provider.h>
46 -#include <linux/rational.h>
50 @@ -28,21 +27,21 @@ static void ccu_nkm_find_best(unsigned l
51 unsigned long _n, _k, _m;
53 for (_k = 1; _k <= nkm->max_k; _k++) {
54 - unsigned long tmp_rate;
56 - rational_best_approximation(rate / _k, parent,
57 - nkm->max_n, nkm->max_m, &_n, &_m);
59 - tmp_rate = parent * _n * _k / _m;
61 - if (tmp_rate > rate)
64 - if ((rate - tmp_rate) < (rate - best_rate)) {
65 - best_rate = tmp_rate;
69 + for (_n = 1; _n <= nkm->max_n; _n++) {
70 + for (_m = 1; _n <= nkm->max_m; _m++) {
71 + unsigned long tmp_rate;
73 + tmp_rate = parent * _n * _k / _m;
75 + if (tmp_rate > rate)
77 + if ((rate - tmp_rate) < (rate - best_rate)) {
78 + best_rate = tmp_rate;
87 --- a/drivers/clk/sunxi-ng/ccu_nkmp.c
88 +++ b/drivers/clk/sunxi-ng/ccu_nkmp.c
92 #include <linux/clk-provider.h>
93 -#include <linux/rational.h>
97 @@ -29,24 +28,24 @@ static void ccu_nkmp_find_best(unsigned
98 unsigned long _n, _k, _m, _p;
100 for (_k = 1; _k <= nkmp->max_k; _k++) {
101 - for (_p = 1; _p <= nkmp->max_p; _p <<= 1) {
102 - unsigned long tmp_rate;
104 - rational_best_approximation(rate / _k, parent / _p,
105 - nkmp->max_n, nkmp->max_m,
108 - tmp_rate = parent * _n * _k / (_m * _p);
110 - if (tmp_rate > rate)
113 - if ((rate - tmp_rate) < (rate - best_rate)) {
114 - best_rate = tmp_rate;
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;
124 + tmp_rate = parent * _n * _k / (_m * _p);
126 + if (tmp_rate > rate)
129 + if ((rate - tmp_rate) < (rate - best_rate)) {
130 + best_rate = tmp_rate;
140 --- a/drivers/clk/sunxi-ng/ccu_nm.c
141 +++ b/drivers/clk/sunxi-ng/ccu_nm.c
145 #include <linux/clk-provider.h>
146 -#include <linux/rational.h>
148 #include "ccu_frac.h"
149 #include "ccu_gate.h"
153 + unsigned long n, max_n;
154 + unsigned long m, max_m;
157 +static void ccu_nm_find_best(unsigned long parent, unsigned long rate,
158 + struct _ccu_nm *nm)
160 + unsigned long best_rate = 0;
161 + unsigned long best_n = 0, best_m = 0;
162 + unsigned long _n, _m;
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;
168 + if (tmp_rate > rate)
171 + if ((rate - tmp_rate) < (rate - best_rate)) {
172 + best_rate = tmp_rate;
183 static void ccu_nm_disable(struct clk_hw *hw)
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)
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;
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;
199 - rational_best_approximation(rate, *parent_rate, max_n, max_m, &n, &m);
200 + ccu_nm_find_best(*parent_rate, rate, &_nm);
202 - return *parent_rate * n / m;
203 + return *parent_rate * _nm.n / _nm.m;
206 static int ccu_nm_set_rate(struct clk_hw *hw, unsigned long rate,
207 unsigned long parent_rate)
209 struct ccu_nm *nm = hw_to_ccu_nm(hw);
210 + struct _ccu_nm _nm;
212 - unsigned long max_n, max_m;
213 - unsigned long n, m;
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
219 ccu_frac_helper_disable(&nm->common, &nm->frac);
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;
226 - rational_best_approximation(rate, parent_rate, max_n, max_m, &n, &m);
227 + ccu_nm_find_best(parent_rate, rate, &_nm);
229 spin_lock_irqsave(nm->common.lock, flags);
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);
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);
239 spin_unlock_irqrestore(nm->common.lock, flags);