Merge tag 'gvt-next-fixes-2021-04-21' of https://github.com/intel/gvt-linux into...
[linux-2.6-microblaze.git] / drivers / clk / at91 / clk-main.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  *  Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
4  */
5
6 #include <linux/clk-provider.h>
7 #include <linux/clkdev.h>
8 #include <linux/clk/at91_pmc.h>
9 #include <linux/delay.h>
10 #include <linux/mfd/syscon.h>
11 #include <linux/regmap.h>
12
13 #include "pmc.h"
14
15 #define SLOW_CLOCK_FREQ         32768
16 #define MAINF_DIV               16
17 #define MAINFRDY_TIMEOUT        (((MAINF_DIV + 1) * USEC_PER_SEC) / \
18                                  SLOW_CLOCK_FREQ)
19 #define MAINF_LOOP_MIN_WAIT     (USEC_PER_SEC / SLOW_CLOCK_FREQ)
20 #define MAINF_LOOP_MAX_WAIT     MAINFRDY_TIMEOUT
21
22 #define MOR_KEY_MASK            (0xff << 16)
23
24 #define clk_main_parent_select(s)       (((s) & \
25                                         (AT91_PMC_MOSCEN | \
26                                         AT91_PMC_OSCBYPASS)) ? 1 : 0)
27
28 struct clk_main_osc {
29         struct clk_hw hw;
30         struct regmap *regmap;
31 };
32
33 #define to_clk_main_osc(hw) container_of(hw, struct clk_main_osc, hw)
34
35 struct clk_main_rc_osc {
36         struct clk_hw hw;
37         struct regmap *regmap;
38         unsigned long frequency;
39         unsigned long accuracy;
40 };
41
42 #define to_clk_main_rc_osc(hw) container_of(hw, struct clk_main_rc_osc, hw)
43
44 struct clk_rm9200_main {
45         struct clk_hw hw;
46         struct regmap *regmap;
47 };
48
49 #define to_clk_rm9200_main(hw) container_of(hw, struct clk_rm9200_main, hw)
50
51 struct clk_sam9x5_main {
52         struct clk_hw hw;
53         struct regmap *regmap;
54         u8 parent;
55 };
56
57 #define to_clk_sam9x5_main(hw) container_of(hw, struct clk_sam9x5_main, hw)
58
59 static inline bool clk_main_osc_ready(struct regmap *regmap)
60 {
61         unsigned int status;
62
63         regmap_read(regmap, AT91_PMC_SR, &status);
64
65         return status & AT91_PMC_MOSCS;
66 }
67
68 static int clk_main_osc_prepare(struct clk_hw *hw)
69 {
70         struct clk_main_osc *osc = to_clk_main_osc(hw);
71         struct regmap *regmap = osc->regmap;
72         u32 tmp;
73
74         regmap_read(regmap, AT91_CKGR_MOR, &tmp);
75         tmp &= ~MOR_KEY_MASK;
76
77         if (tmp & AT91_PMC_OSCBYPASS)
78                 return 0;
79
80         if (!(tmp & AT91_PMC_MOSCEN)) {
81                 tmp |= AT91_PMC_MOSCEN | AT91_PMC_KEY;
82                 regmap_write(regmap, AT91_CKGR_MOR, tmp);
83         }
84
85         while (!clk_main_osc_ready(regmap))
86                 cpu_relax();
87
88         return 0;
89 }
90
91 static void clk_main_osc_unprepare(struct clk_hw *hw)
92 {
93         struct clk_main_osc *osc = to_clk_main_osc(hw);
94         struct regmap *regmap = osc->regmap;
95         u32 tmp;
96
97         regmap_read(regmap, AT91_CKGR_MOR, &tmp);
98         if (tmp & AT91_PMC_OSCBYPASS)
99                 return;
100
101         if (!(tmp & AT91_PMC_MOSCEN))
102                 return;
103
104         tmp &= ~(AT91_PMC_KEY | AT91_PMC_MOSCEN);
105         regmap_write(regmap, AT91_CKGR_MOR, tmp | AT91_PMC_KEY);
106 }
107
108 static int clk_main_osc_is_prepared(struct clk_hw *hw)
109 {
110         struct clk_main_osc *osc = to_clk_main_osc(hw);
111         struct regmap *regmap = osc->regmap;
112         u32 tmp, status;
113
114         regmap_read(regmap, AT91_CKGR_MOR, &tmp);
115         if (tmp & AT91_PMC_OSCBYPASS)
116                 return 1;
117
118         regmap_read(regmap, AT91_PMC_SR, &status);
119
120         return (status & AT91_PMC_MOSCS) && clk_main_parent_select(tmp);
121 }
122
123 static const struct clk_ops main_osc_ops = {
124         .prepare = clk_main_osc_prepare,
125         .unprepare = clk_main_osc_unprepare,
126         .is_prepared = clk_main_osc_is_prepared,
127 };
128
129 struct clk_hw * __init
130 at91_clk_register_main_osc(struct regmap *regmap,
131                            const char *name,
132                            const char *parent_name,
133                            bool bypass)
134 {
135         struct clk_main_osc *osc;
136         struct clk_init_data init;
137         struct clk_hw *hw;
138         int ret;
139
140         if (!name || !parent_name)
141                 return ERR_PTR(-EINVAL);
142
143         osc = kzalloc(sizeof(*osc), GFP_KERNEL);
144         if (!osc)
145                 return ERR_PTR(-ENOMEM);
146
147         init.name = name;
148         init.ops = &main_osc_ops;
149         init.parent_names = &parent_name;
150         init.num_parents = 1;
151         init.flags = CLK_IGNORE_UNUSED;
152
153         osc->hw.init = &init;
154         osc->regmap = regmap;
155
156         if (bypass)
157                 regmap_update_bits(regmap,
158                                    AT91_CKGR_MOR, MOR_KEY_MASK |
159                                    AT91_PMC_OSCBYPASS,
160                                    AT91_PMC_OSCBYPASS | AT91_PMC_KEY);
161
162         hw = &osc->hw;
163         ret = clk_hw_register(NULL, &osc->hw);
164         if (ret) {
165                 kfree(osc);
166                 hw = ERR_PTR(ret);
167         }
168
169         return hw;
170 }
171
172 static bool clk_main_rc_osc_ready(struct regmap *regmap)
173 {
174         unsigned int status;
175
176         regmap_read(regmap, AT91_PMC_SR, &status);
177
178         return !!(status & AT91_PMC_MOSCRCS);
179 }
180
181 static int clk_main_rc_osc_prepare(struct clk_hw *hw)
182 {
183         struct clk_main_rc_osc *osc = to_clk_main_rc_osc(hw);
184         struct regmap *regmap = osc->regmap;
185         unsigned int mor;
186
187         regmap_read(regmap, AT91_CKGR_MOR, &mor);
188
189         if (!(mor & AT91_PMC_MOSCRCEN))
190                 regmap_update_bits(regmap, AT91_CKGR_MOR,
191                                    MOR_KEY_MASK | AT91_PMC_MOSCRCEN,
192                                    AT91_PMC_MOSCRCEN | AT91_PMC_KEY);
193
194         while (!clk_main_rc_osc_ready(regmap))
195                 cpu_relax();
196
197         return 0;
198 }
199
200 static void clk_main_rc_osc_unprepare(struct clk_hw *hw)
201 {
202         struct clk_main_rc_osc *osc = to_clk_main_rc_osc(hw);
203         struct regmap *regmap = osc->regmap;
204         unsigned int mor;
205
206         regmap_read(regmap, AT91_CKGR_MOR, &mor);
207
208         if (!(mor & AT91_PMC_MOSCRCEN))
209                 return;
210
211         regmap_update_bits(regmap, AT91_CKGR_MOR,
212                            MOR_KEY_MASK | AT91_PMC_MOSCRCEN, AT91_PMC_KEY);
213 }
214
215 static int clk_main_rc_osc_is_prepared(struct clk_hw *hw)
216 {
217         struct clk_main_rc_osc *osc = to_clk_main_rc_osc(hw);
218         struct regmap *regmap = osc->regmap;
219         unsigned int mor, status;
220
221         regmap_read(regmap, AT91_CKGR_MOR, &mor);
222         regmap_read(regmap, AT91_PMC_SR, &status);
223
224         return (mor & AT91_PMC_MOSCRCEN) && (status & AT91_PMC_MOSCRCS);
225 }
226
227 static unsigned long clk_main_rc_osc_recalc_rate(struct clk_hw *hw,
228                                                  unsigned long parent_rate)
229 {
230         struct clk_main_rc_osc *osc = to_clk_main_rc_osc(hw);
231
232         return osc->frequency;
233 }
234
235 static unsigned long clk_main_rc_osc_recalc_accuracy(struct clk_hw *hw,
236                                                      unsigned long parent_acc)
237 {
238         struct clk_main_rc_osc *osc = to_clk_main_rc_osc(hw);
239
240         return osc->accuracy;
241 }
242
243 static const struct clk_ops main_rc_osc_ops = {
244         .prepare = clk_main_rc_osc_prepare,
245         .unprepare = clk_main_rc_osc_unprepare,
246         .is_prepared = clk_main_rc_osc_is_prepared,
247         .recalc_rate = clk_main_rc_osc_recalc_rate,
248         .recalc_accuracy = clk_main_rc_osc_recalc_accuracy,
249 };
250
251 struct clk_hw * __init
252 at91_clk_register_main_rc_osc(struct regmap *regmap,
253                               const char *name,
254                               u32 frequency, u32 accuracy)
255 {
256         struct clk_main_rc_osc *osc;
257         struct clk_init_data init;
258         struct clk_hw *hw;
259         int ret;
260
261         if (!name || !frequency)
262                 return ERR_PTR(-EINVAL);
263
264         osc = kzalloc(sizeof(*osc), GFP_KERNEL);
265         if (!osc)
266                 return ERR_PTR(-ENOMEM);
267
268         init.name = name;
269         init.ops = &main_rc_osc_ops;
270         init.parent_names = NULL;
271         init.num_parents = 0;
272         init.flags = CLK_IGNORE_UNUSED;
273
274         osc->hw.init = &init;
275         osc->regmap = regmap;
276         osc->frequency = frequency;
277         osc->accuracy = accuracy;
278
279         hw = &osc->hw;
280         ret = clk_hw_register(NULL, hw);
281         if (ret) {
282                 kfree(osc);
283                 hw = ERR_PTR(ret);
284         }
285
286         return hw;
287 }
288
289 static int clk_main_probe_frequency(struct regmap *regmap)
290 {
291         unsigned long prep_time, timeout;
292         unsigned int mcfr;
293
294         timeout = jiffies + usecs_to_jiffies(MAINFRDY_TIMEOUT);
295         do {
296                 prep_time = jiffies;
297                 regmap_read(regmap, AT91_CKGR_MCFR, &mcfr);
298                 if (mcfr & AT91_PMC_MAINRDY)
299                         return 0;
300                 if (system_state < SYSTEM_RUNNING)
301                         udelay(MAINF_LOOP_MIN_WAIT);
302                 else
303                         usleep_range(MAINF_LOOP_MIN_WAIT, MAINF_LOOP_MAX_WAIT);
304         } while (time_before(prep_time, timeout));
305
306         return -ETIMEDOUT;
307 }
308
309 static unsigned long clk_main_recalc_rate(struct regmap *regmap,
310                                           unsigned long parent_rate)
311 {
312         unsigned int mcfr;
313
314         if (parent_rate)
315                 return parent_rate;
316
317         pr_warn("Main crystal frequency not set, using approximate value\n");
318         regmap_read(regmap, AT91_CKGR_MCFR, &mcfr);
319         if (!(mcfr & AT91_PMC_MAINRDY))
320                 return 0;
321
322         return ((mcfr & AT91_PMC_MAINF) * SLOW_CLOCK_FREQ) / MAINF_DIV;
323 }
324
325 static int clk_rm9200_main_prepare(struct clk_hw *hw)
326 {
327         struct clk_rm9200_main *clkmain = to_clk_rm9200_main(hw);
328
329         return clk_main_probe_frequency(clkmain->regmap);
330 }
331
332 static int clk_rm9200_main_is_prepared(struct clk_hw *hw)
333 {
334         struct clk_rm9200_main *clkmain = to_clk_rm9200_main(hw);
335         unsigned int status;
336
337         regmap_read(clkmain->regmap, AT91_CKGR_MCFR, &status);
338
339         return !!(status & AT91_PMC_MAINRDY);
340 }
341
342 static unsigned long clk_rm9200_main_recalc_rate(struct clk_hw *hw,
343                                                  unsigned long parent_rate)
344 {
345         struct clk_rm9200_main *clkmain = to_clk_rm9200_main(hw);
346
347         return clk_main_recalc_rate(clkmain->regmap, parent_rate);
348 }
349
350 static const struct clk_ops rm9200_main_ops = {
351         .prepare = clk_rm9200_main_prepare,
352         .is_prepared = clk_rm9200_main_is_prepared,
353         .recalc_rate = clk_rm9200_main_recalc_rate,
354 };
355
356 struct clk_hw * __init
357 at91_clk_register_rm9200_main(struct regmap *regmap,
358                               const char *name,
359                               const char *parent_name)
360 {
361         struct clk_rm9200_main *clkmain;
362         struct clk_init_data init;
363         struct clk_hw *hw;
364         int ret;
365
366         if (!name)
367                 return ERR_PTR(-EINVAL);
368
369         if (!parent_name)
370                 return ERR_PTR(-EINVAL);
371
372         clkmain = kzalloc(sizeof(*clkmain), GFP_KERNEL);
373         if (!clkmain)
374                 return ERR_PTR(-ENOMEM);
375
376         init.name = name;
377         init.ops = &rm9200_main_ops;
378         init.parent_names = &parent_name;
379         init.num_parents = 1;
380         init.flags = 0;
381
382         clkmain->hw.init = &init;
383         clkmain->regmap = regmap;
384
385         hw = &clkmain->hw;
386         ret = clk_hw_register(NULL, &clkmain->hw);
387         if (ret) {
388                 kfree(clkmain);
389                 hw = ERR_PTR(ret);
390         }
391
392         return hw;
393 }
394
395 static inline bool clk_sam9x5_main_ready(struct regmap *regmap)
396 {
397         unsigned int status;
398
399         regmap_read(regmap, AT91_PMC_SR, &status);
400
401         return !!(status & AT91_PMC_MOSCSELS);
402 }
403
404 static int clk_sam9x5_main_prepare(struct clk_hw *hw)
405 {
406         struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw);
407         struct regmap *regmap = clkmain->regmap;
408
409         while (!clk_sam9x5_main_ready(regmap))
410                 cpu_relax();
411
412         return clk_main_probe_frequency(regmap);
413 }
414
415 static int clk_sam9x5_main_is_prepared(struct clk_hw *hw)
416 {
417         struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw);
418
419         return clk_sam9x5_main_ready(clkmain->regmap);
420 }
421
422 static unsigned long clk_sam9x5_main_recalc_rate(struct clk_hw *hw,
423                                                  unsigned long parent_rate)
424 {
425         struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw);
426
427         return clk_main_recalc_rate(clkmain->regmap, parent_rate);
428 }
429
430 static int clk_sam9x5_main_set_parent(struct clk_hw *hw, u8 index)
431 {
432         struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw);
433         struct regmap *regmap = clkmain->regmap;
434         unsigned int tmp;
435
436         if (index > 1)
437                 return -EINVAL;
438
439         regmap_read(regmap, AT91_CKGR_MOR, &tmp);
440
441         if (index && !(tmp & AT91_PMC_MOSCSEL))
442                 tmp = AT91_PMC_MOSCSEL;
443         else if (!index && (tmp & AT91_PMC_MOSCSEL))
444                 tmp = 0;
445         else
446                 return 0;
447
448         regmap_update_bits(regmap, AT91_CKGR_MOR,
449                            AT91_PMC_MOSCSEL | MOR_KEY_MASK,
450                            tmp | AT91_PMC_KEY);
451
452         while (!clk_sam9x5_main_ready(regmap))
453                 cpu_relax();
454
455         return 0;
456 }
457
458 static u8 clk_sam9x5_main_get_parent(struct clk_hw *hw)
459 {
460         struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw);
461         unsigned int status;
462
463         regmap_read(clkmain->regmap, AT91_CKGR_MOR, &status);
464
465         return clk_main_parent_select(status);
466 }
467
468 static const struct clk_ops sam9x5_main_ops = {
469         .prepare = clk_sam9x5_main_prepare,
470         .is_prepared = clk_sam9x5_main_is_prepared,
471         .recalc_rate = clk_sam9x5_main_recalc_rate,
472         .set_parent = clk_sam9x5_main_set_parent,
473         .get_parent = clk_sam9x5_main_get_parent,
474 };
475
476 struct clk_hw * __init
477 at91_clk_register_sam9x5_main(struct regmap *regmap,
478                               const char *name,
479                               const char **parent_names,
480                               int num_parents)
481 {
482         struct clk_sam9x5_main *clkmain;
483         struct clk_init_data init;
484         unsigned int status;
485         struct clk_hw *hw;
486         int ret;
487
488         if (!name)
489                 return ERR_PTR(-EINVAL);
490
491         if (!parent_names || !num_parents)
492                 return ERR_PTR(-EINVAL);
493
494         clkmain = kzalloc(sizeof(*clkmain), GFP_KERNEL);
495         if (!clkmain)
496                 return ERR_PTR(-ENOMEM);
497
498         init.name = name;
499         init.ops = &sam9x5_main_ops;
500         init.parent_names = parent_names;
501         init.num_parents = num_parents;
502         init.flags = CLK_SET_PARENT_GATE;
503
504         clkmain->hw.init = &init;
505         clkmain->regmap = regmap;
506         regmap_read(clkmain->regmap, AT91_CKGR_MOR, &status);
507         clkmain->parent = clk_main_parent_select(status);
508
509         hw = &clkmain->hw;
510         ret = clk_hw_register(NULL, &clkmain->hw);
511         if (ret) {
512                 kfree(clkmain);
513                 hw = ERR_PTR(ret);
514         }
515
516         return hw;
517 }