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