v1.5 branch refresh based upon upstream master @ c8677ca89e53e3be7988d54280fce166cc894a7e
[librecmc/librecmc.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 @@ -36,17 +36,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);