Merge tag 'riscv/for-v5.5-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/riscv...
[linux-2.6-microblaze.git] / drivers / clk / at91 / clk-sam9x60-pll.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  *  Copyright (C) 2019 Microchip Technology Inc.
4  *
5  */
6
7 #include <linux/bitfield.h>
8 #include <linux/clk-provider.h>
9 #include <linux/clkdev.h>
10 #include <linux/clk/at91_pmc.h>
11 #include <linux/of.h>
12 #include <linux/mfd/syscon.h>
13 #include <linux/regmap.h>
14
15 #include "pmc.h"
16
17 #define PMC_PLL_CTRL0   0xc
18 #define         PMC_PLL_CTRL0_DIV_MSK           GENMASK(7, 0)
19 #define         PMC_PLL_CTRL0_ENPLL             BIT(28)
20 #define         PMC_PLL_CTRL0_ENPLLCK           BIT(29)
21 #define         PMC_PLL_CTRL0_ENLOCK            BIT(31)
22
23 #define PMC_PLL_CTRL1   0x10
24 #define         PMC_PLL_CTRL1_FRACR_MSK         GENMASK(21, 0)
25 #define         PMC_PLL_CTRL1_MUL_MSK           GENMASK(30, 24)
26
27 #define PMC_PLL_ACR     0x18
28 #define         PMC_PLL_ACR_DEFAULT             0x1b040010UL
29 #define         PMC_PLL_ACR_UTMIVR              BIT(12)
30 #define         PMC_PLL_ACR_UTMIBG              BIT(13)
31 #define         PMC_PLL_ACR_LOOP_FILTER_MSK     GENMASK(31, 24)
32
33 #define PMC_PLL_UPDT    0x1c
34 #define         PMC_PLL_UPDT_UPDATE             BIT(8)
35
36 #define PMC_PLL_ISR0    0xec
37
38 #define PLL_DIV_MAX             (FIELD_GET(PMC_PLL_CTRL0_DIV_MSK, UINT_MAX) + 1)
39 #define UPLL_DIV                2
40 #define PLL_MUL_MAX             (FIELD_GET(PMC_PLL_CTRL1_MUL_MSK, UINT_MAX) + 1)
41
42 #define PLL_MAX_ID              1
43
44 struct sam9x60_pll {
45         struct clk_hw hw;
46         struct regmap *regmap;
47         spinlock_t *lock;
48         const struct clk_pll_characteristics *characteristics;
49         u32 frac;
50         u8 id;
51         u8 div;
52         u16 mul;
53 };
54
55 #define to_sam9x60_pll(hw) container_of(hw, struct sam9x60_pll, hw)
56
57 static inline bool sam9x60_pll_ready(struct regmap *regmap, int id)
58 {
59         unsigned int status;
60
61         regmap_read(regmap, PMC_PLL_ISR0, &status);
62
63         return !!(status & BIT(id));
64 }
65
66 static int sam9x60_pll_prepare(struct clk_hw *hw)
67 {
68         struct sam9x60_pll *pll = to_sam9x60_pll(hw);
69         struct regmap *regmap = pll->regmap;
70         unsigned long flags;
71         u8 div;
72         u16 mul;
73         u32 val;
74
75         spin_lock_irqsave(pll->lock, flags);
76         regmap_write(regmap, PMC_PLL_UPDT, pll->id);
77
78         regmap_read(regmap, PMC_PLL_CTRL0, &val);
79         div = FIELD_GET(PMC_PLL_CTRL0_DIV_MSK, val);
80
81         regmap_read(regmap, PMC_PLL_CTRL1, &val);
82         mul = FIELD_GET(PMC_PLL_CTRL1_MUL_MSK, val);
83
84         if (sam9x60_pll_ready(regmap, pll->id) &&
85             (div == pll->div && mul == pll->mul)) {
86                 spin_unlock_irqrestore(pll->lock, flags);
87                 return 0;
88         }
89
90         /* Recommended value for PMC_PLL_ACR */
91         val = PMC_PLL_ACR_DEFAULT;
92         regmap_write(regmap, PMC_PLL_ACR, val);
93
94         regmap_write(regmap, PMC_PLL_CTRL1,
95                      FIELD_PREP(PMC_PLL_CTRL1_MUL_MSK, pll->mul));
96
97         if (pll->characteristics->upll) {
98                 /* Enable the UTMI internal bandgap */
99                 val |= PMC_PLL_ACR_UTMIBG;
100                 regmap_write(regmap, PMC_PLL_ACR, val);
101
102                 udelay(10);
103
104                 /* Enable the UTMI internal regulator */
105                 val |= PMC_PLL_ACR_UTMIVR;
106                 regmap_write(regmap, PMC_PLL_ACR, val);
107
108                 udelay(10);
109         }
110
111         regmap_update_bits(regmap, PMC_PLL_UPDT,
112                            PMC_PLL_UPDT_UPDATE, PMC_PLL_UPDT_UPDATE);
113
114         regmap_write(regmap, PMC_PLL_CTRL0,
115                      PMC_PLL_CTRL0_ENLOCK | PMC_PLL_CTRL0_ENPLL |
116                      PMC_PLL_CTRL0_ENPLLCK | pll->div);
117
118         regmap_update_bits(regmap, PMC_PLL_UPDT,
119                            PMC_PLL_UPDT_UPDATE, PMC_PLL_UPDT_UPDATE);
120
121         while (!sam9x60_pll_ready(regmap, pll->id))
122                 cpu_relax();
123
124         spin_unlock_irqrestore(pll->lock, flags);
125
126         return 0;
127 }
128
129 static int sam9x60_pll_is_prepared(struct clk_hw *hw)
130 {
131         struct sam9x60_pll *pll = to_sam9x60_pll(hw);
132
133         return sam9x60_pll_ready(pll->regmap, pll->id);
134 }
135
136 static void sam9x60_pll_unprepare(struct clk_hw *hw)
137 {
138         struct sam9x60_pll *pll = to_sam9x60_pll(hw);
139         unsigned long flags;
140
141         spin_lock_irqsave(pll->lock, flags);
142
143         regmap_write(pll->regmap, PMC_PLL_UPDT, pll->id);
144
145         regmap_update_bits(pll->regmap, PMC_PLL_CTRL0,
146                            PMC_PLL_CTRL0_ENPLLCK, 0);
147
148         regmap_update_bits(pll->regmap, PMC_PLL_UPDT,
149                            PMC_PLL_UPDT_UPDATE, PMC_PLL_UPDT_UPDATE);
150
151         regmap_update_bits(pll->regmap, PMC_PLL_CTRL0, PMC_PLL_CTRL0_ENPLL, 0);
152
153         if (pll->characteristics->upll)
154                 regmap_update_bits(pll->regmap, PMC_PLL_ACR,
155                                    PMC_PLL_ACR_UTMIBG | PMC_PLL_ACR_UTMIVR, 0);
156
157         regmap_update_bits(pll->regmap, PMC_PLL_UPDT,
158                            PMC_PLL_UPDT_UPDATE, PMC_PLL_UPDT_UPDATE);
159
160         spin_unlock_irqrestore(pll->lock, flags);
161 }
162
163 static unsigned long sam9x60_pll_recalc_rate(struct clk_hw *hw,
164                                              unsigned long parent_rate)
165 {
166         struct sam9x60_pll *pll = to_sam9x60_pll(hw);
167
168         return (parent_rate * (pll->mul + 1)) / (pll->div + 1);
169 }
170
171 static long sam9x60_pll_get_best_div_mul(struct sam9x60_pll *pll,
172                                          unsigned long rate,
173                                          unsigned long parent_rate,
174                                          bool update)
175 {
176         const struct clk_pll_characteristics *characteristics =
177                                                         pll->characteristics;
178         unsigned long bestremainder = ULONG_MAX;
179         unsigned long maxdiv, mindiv, tmpdiv;
180         long bestrate = -ERANGE;
181         unsigned long bestdiv = 0;
182         unsigned long bestmul = 0;
183         unsigned long bestfrac = 0;
184
185         if (rate < characteristics->output[0].min ||
186             rate > characteristics->output[0].max)
187                 return -ERANGE;
188
189         if (!pll->characteristics->upll) {
190                 mindiv = parent_rate / rate;
191                 if (mindiv < 2)
192                         mindiv = 2;
193
194                 maxdiv = DIV_ROUND_UP(parent_rate * PLL_MUL_MAX, rate);
195                 if (maxdiv > PLL_DIV_MAX)
196                         maxdiv = PLL_DIV_MAX;
197         } else {
198                 mindiv = maxdiv = UPLL_DIV;
199         }
200
201         for (tmpdiv = mindiv; tmpdiv <= maxdiv; tmpdiv++) {
202                 unsigned long remainder;
203                 unsigned long tmprate;
204                 unsigned long tmpmul;
205                 unsigned long tmpfrac = 0;
206
207                 /*
208                  * Calculate the multiplier associated with the current
209                  * divider that provide the closest rate to the requested one.
210                  */
211                 tmpmul = mult_frac(rate, tmpdiv, parent_rate);
212                 tmprate = mult_frac(parent_rate, tmpmul, tmpdiv);
213                 remainder = rate - tmprate;
214
215                 if (remainder) {
216                         tmpfrac = DIV_ROUND_CLOSEST_ULL((u64)remainder * tmpdiv * (1 << 22),
217                                                         parent_rate);
218
219                         tmprate += DIV_ROUND_CLOSEST_ULL((u64)tmpfrac * parent_rate,
220                                                          tmpdiv * (1 << 22));
221
222                         if (tmprate > rate)
223                                 remainder = tmprate - rate;
224                         else
225                                 remainder = rate - tmprate;
226                 }
227
228                 /*
229                  * Compare the remainder with the best remainder found until
230                  * now and elect a new best multiplier/divider pair if the
231                  * current remainder is smaller than the best one.
232                  */
233                 if (remainder < bestremainder) {
234                         bestremainder = remainder;
235                         bestdiv = tmpdiv;
236                         bestmul = tmpmul;
237                         bestrate = tmprate;
238                         bestfrac = tmpfrac;
239                 }
240
241                 /* We've found a perfect match!  */
242                 if (!remainder)
243                         break;
244         }
245
246         /* Check if bestrate is a valid output rate  */
247         if (bestrate < characteristics->output[0].min &&
248             bestrate > characteristics->output[0].max)
249                 return -ERANGE;
250
251         if (update) {
252                 pll->div = bestdiv - 1;
253                 pll->mul = bestmul - 1;
254                 pll->frac = bestfrac;
255         }
256
257         return bestrate;
258 }
259
260 static long sam9x60_pll_round_rate(struct clk_hw *hw, unsigned long rate,
261                                    unsigned long *parent_rate)
262 {
263         struct sam9x60_pll *pll = to_sam9x60_pll(hw);
264
265         return sam9x60_pll_get_best_div_mul(pll, rate, *parent_rate, false);
266 }
267
268 static int sam9x60_pll_set_rate(struct clk_hw *hw, unsigned long rate,
269                                 unsigned long parent_rate)
270 {
271         struct sam9x60_pll *pll = to_sam9x60_pll(hw);
272
273         return sam9x60_pll_get_best_div_mul(pll, rate, parent_rate, true);
274 }
275
276 static const struct clk_ops pll_ops = {
277         .prepare = sam9x60_pll_prepare,
278         .unprepare = sam9x60_pll_unprepare,
279         .is_prepared = sam9x60_pll_is_prepared,
280         .recalc_rate = sam9x60_pll_recalc_rate,
281         .round_rate = sam9x60_pll_round_rate,
282         .set_rate = sam9x60_pll_set_rate,
283 };
284
285 struct clk_hw * __init
286 sam9x60_clk_register_pll(struct regmap *regmap, spinlock_t *lock,
287                          const char *name, const char *parent_name, u8 id,
288                          const struct clk_pll_characteristics *characteristics)
289 {
290         struct sam9x60_pll *pll;
291         struct clk_hw *hw;
292         struct clk_init_data init;
293         unsigned int pllr;
294         int ret;
295
296         if (id > PLL_MAX_ID)
297                 return ERR_PTR(-EINVAL);
298
299         pll = kzalloc(sizeof(*pll), GFP_KERNEL);
300         if (!pll)
301                 return ERR_PTR(-ENOMEM);
302
303         init.name = name;
304         init.ops = &pll_ops;
305         init.parent_names = &parent_name;
306         init.num_parents = 1;
307         init.flags = CLK_SET_RATE_GATE;
308
309         pll->id = id;
310         pll->hw.init = &init;
311         pll->characteristics = characteristics;
312         pll->regmap = regmap;
313         pll->lock = lock;
314
315         regmap_write(regmap, PMC_PLL_UPDT, id);
316         regmap_read(regmap, PMC_PLL_CTRL0, &pllr);
317         pll->div = FIELD_GET(PMC_PLL_CTRL0_DIV_MSK, pllr);
318         regmap_read(regmap, PMC_PLL_CTRL1, &pllr);
319         pll->mul = FIELD_GET(PMC_PLL_CTRL1_MUL_MSK, pllr);
320
321         hw = &pll->hw;
322         ret = clk_hw_register(NULL, hw);
323         if (ret) {
324                 kfree(pll);
325                 hw = ERR_PTR(ret);
326         }
327
328         return hw;
329 }
330