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 / sckc.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * drivers/clk/at91/sckc.c
4  *
5  *  Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
6  */
7
8 #include <linux/clk-provider.h>
9 #include <linux/clkdev.h>
10 #include <linux/delay.h>
11 #include <linux/of.h>
12 #include <linux/of_address.h>
13 #include <linux/io.h>
14
15 #define SLOW_CLOCK_FREQ         32768
16 #define SLOWCK_SW_CYCLES        5
17 #define SLOWCK_SW_TIME_USEC     ((SLOWCK_SW_CYCLES * USEC_PER_SEC) / \
18                                  SLOW_CLOCK_FREQ)
19
20 #define AT91_SCKC_CR                    0x00
21
22 struct clk_slow_bits {
23         u32 cr_rcen;
24         u32 cr_osc32en;
25         u32 cr_osc32byp;
26         u32 cr_oscsel;
27 };
28
29 struct clk_slow_osc {
30         struct clk_hw hw;
31         void __iomem *sckcr;
32         const struct clk_slow_bits *bits;
33         unsigned long startup_usec;
34 };
35
36 #define to_clk_slow_osc(hw) container_of(hw, struct clk_slow_osc, hw)
37
38 struct clk_sama5d4_slow_osc {
39         struct clk_hw hw;
40         void __iomem *sckcr;
41         const struct clk_slow_bits *bits;
42         unsigned long startup_usec;
43         bool prepared;
44 };
45
46 #define to_clk_sama5d4_slow_osc(hw) container_of(hw, struct clk_sama5d4_slow_osc, hw)
47
48 struct clk_slow_rc_osc {
49         struct clk_hw hw;
50         void __iomem *sckcr;
51         const struct clk_slow_bits *bits;
52         unsigned long frequency;
53         unsigned long accuracy;
54         unsigned long startup_usec;
55 };
56
57 #define to_clk_slow_rc_osc(hw) container_of(hw, struct clk_slow_rc_osc, hw)
58
59 struct clk_sam9x5_slow {
60         struct clk_hw hw;
61         void __iomem *sckcr;
62         const struct clk_slow_bits *bits;
63         u8 parent;
64 };
65
66 #define to_clk_sam9x5_slow(hw) container_of(hw, struct clk_sam9x5_slow, hw)
67
68 static int clk_slow_osc_prepare(struct clk_hw *hw)
69 {
70         struct clk_slow_osc *osc = to_clk_slow_osc(hw);
71         void __iomem *sckcr = osc->sckcr;
72         u32 tmp = readl(sckcr);
73
74         if (tmp & (osc->bits->cr_osc32byp | osc->bits->cr_osc32en))
75                 return 0;
76
77         writel(tmp | osc->bits->cr_osc32en, sckcr);
78
79         if (system_state < SYSTEM_RUNNING)
80                 udelay(osc->startup_usec);
81         else
82                 usleep_range(osc->startup_usec, osc->startup_usec + 1);
83
84         return 0;
85 }
86
87 static void clk_slow_osc_unprepare(struct clk_hw *hw)
88 {
89         struct clk_slow_osc *osc = to_clk_slow_osc(hw);
90         void __iomem *sckcr = osc->sckcr;
91         u32 tmp = readl(sckcr);
92
93         if (tmp & osc->bits->cr_osc32byp)
94                 return;
95
96         writel(tmp & ~osc->bits->cr_osc32en, sckcr);
97 }
98
99 static int clk_slow_osc_is_prepared(struct clk_hw *hw)
100 {
101         struct clk_slow_osc *osc = to_clk_slow_osc(hw);
102         void __iomem *sckcr = osc->sckcr;
103         u32 tmp = readl(sckcr);
104
105         if (tmp & osc->bits->cr_osc32byp)
106                 return 1;
107
108         return !!(tmp & osc->bits->cr_osc32en);
109 }
110
111 static const struct clk_ops slow_osc_ops = {
112         .prepare = clk_slow_osc_prepare,
113         .unprepare = clk_slow_osc_unprepare,
114         .is_prepared = clk_slow_osc_is_prepared,
115 };
116
117 static struct clk_hw * __init
118 at91_clk_register_slow_osc(void __iomem *sckcr,
119                            const char *name,
120                            const char *parent_name,
121                            unsigned long startup,
122                            bool bypass,
123                            const struct clk_slow_bits *bits)
124 {
125         struct clk_slow_osc *osc;
126         struct clk_hw *hw;
127         struct clk_init_data init;
128         int ret;
129
130         if (!sckcr || !name || !parent_name)
131                 return ERR_PTR(-EINVAL);
132
133         osc = kzalloc(sizeof(*osc), GFP_KERNEL);
134         if (!osc)
135                 return ERR_PTR(-ENOMEM);
136
137         init.name = name;
138         init.ops = &slow_osc_ops;
139         init.parent_names = &parent_name;
140         init.num_parents = 1;
141         init.flags = CLK_IGNORE_UNUSED;
142
143         osc->hw.init = &init;
144         osc->sckcr = sckcr;
145         osc->startup_usec = startup;
146         osc->bits = bits;
147
148         if (bypass)
149                 writel((readl(sckcr) & ~osc->bits->cr_osc32en) |
150                                         osc->bits->cr_osc32byp, sckcr);
151
152         hw = &osc->hw;
153         ret = clk_hw_register(NULL, &osc->hw);
154         if (ret) {
155                 kfree(osc);
156                 hw = ERR_PTR(ret);
157         }
158
159         return hw;
160 }
161
162 static void at91_clk_unregister_slow_osc(struct clk_hw *hw)
163 {
164         struct clk_slow_osc *osc = to_clk_slow_osc(hw);
165
166         clk_hw_unregister(hw);
167         kfree(osc);
168 }
169
170 static unsigned long clk_slow_rc_osc_recalc_rate(struct clk_hw *hw,
171                                                  unsigned long parent_rate)
172 {
173         struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw);
174
175         return osc->frequency;
176 }
177
178 static unsigned long clk_slow_rc_osc_recalc_accuracy(struct clk_hw *hw,
179                                                      unsigned long parent_acc)
180 {
181         struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw);
182
183         return osc->accuracy;
184 }
185
186 static int clk_slow_rc_osc_prepare(struct clk_hw *hw)
187 {
188         struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw);
189         void __iomem *sckcr = osc->sckcr;
190
191         writel(readl(sckcr) | osc->bits->cr_rcen, sckcr);
192
193         if (system_state < SYSTEM_RUNNING)
194                 udelay(osc->startup_usec);
195         else
196                 usleep_range(osc->startup_usec, osc->startup_usec + 1);
197
198         return 0;
199 }
200
201 static void clk_slow_rc_osc_unprepare(struct clk_hw *hw)
202 {
203         struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw);
204         void __iomem *sckcr = osc->sckcr;
205
206         writel(readl(sckcr) & ~osc->bits->cr_rcen, sckcr);
207 }
208
209 static int clk_slow_rc_osc_is_prepared(struct clk_hw *hw)
210 {
211         struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw);
212
213         return !!(readl(osc->sckcr) & osc->bits->cr_rcen);
214 }
215
216 static const struct clk_ops slow_rc_osc_ops = {
217         .prepare = clk_slow_rc_osc_prepare,
218         .unprepare = clk_slow_rc_osc_unprepare,
219         .is_prepared = clk_slow_rc_osc_is_prepared,
220         .recalc_rate = clk_slow_rc_osc_recalc_rate,
221         .recalc_accuracy = clk_slow_rc_osc_recalc_accuracy,
222 };
223
224 static struct clk_hw * __init
225 at91_clk_register_slow_rc_osc(void __iomem *sckcr,
226                               const char *name,
227                               unsigned long frequency,
228                               unsigned long accuracy,
229                               unsigned long startup,
230                               const struct clk_slow_bits *bits)
231 {
232         struct clk_slow_rc_osc *osc;
233         struct clk_hw *hw;
234         struct clk_init_data init;
235         int ret;
236
237         if (!sckcr || !name)
238                 return ERR_PTR(-EINVAL);
239
240         osc = kzalloc(sizeof(*osc), GFP_KERNEL);
241         if (!osc)
242                 return ERR_PTR(-ENOMEM);
243
244         init.name = name;
245         init.ops = &slow_rc_osc_ops;
246         init.parent_names = NULL;
247         init.num_parents = 0;
248         init.flags = CLK_IGNORE_UNUSED;
249
250         osc->hw.init = &init;
251         osc->sckcr = sckcr;
252         osc->bits = bits;
253         osc->frequency = frequency;
254         osc->accuracy = accuracy;
255         osc->startup_usec = startup;
256
257         hw = &osc->hw;
258         ret = clk_hw_register(NULL, &osc->hw);
259         if (ret) {
260                 kfree(osc);
261                 hw = ERR_PTR(ret);
262         }
263
264         return hw;
265 }
266
267 static void at91_clk_unregister_slow_rc_osc(struct clk_hw *hw)
268 {
269         struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw);
270
271         clk_hw_unregister(hw);
272         kfree(osc);
273 }
274
275 static int clk_sam9x5_slow_set_parent(struct clk_hw *hw, u8 index)
276 {
277         struct clk_sam9x5_slow *slowck = to_clk_sam9x5_slow(hw);
278         void __iomem *sckcr = slowck->sckcr;
279         u32 tmp;
280
281         if (index > 1)
282                 return -EINVAL;
283
284         tmp = readl(sckcr);
285
286         if ((!index && !(tmp & slowck->bits->cr_oscsel)) ||
287             (index && (tmp & slowck->bits->cr_oscsel)))
288                 return 0;
289
290         if (index)
291                 tmp |= slowck->bits->cr_oscsel;
292         else
293                 tmp &= ~slowck->bits->cr_oscsel;
294
295         writel(tmp, sckcr);
296
297         if (system_state < SYSTEM_RUNNING)
298                 udelay(SLOWCK_SW_TIME_USEC);
299         else
300                 usleep_range(SLOWCK_SW_TIME_USEC, SLOWCK_SW_TIME_USEC + 1);
301
302         return 0;
303 }
304
305 static u8 clk_sam9x5_slow_get_parent(struct clk_hw *hw)
306 {
307         struct clk_sam9x5_slow *slowck = to_clk_sam9x5_slow(hw);
308
309         return !!(readl(slowck->sckcr) & slowck->bits->cr_oscsel);
310 }
311
312 static const struct clk_ops sam9x5_slow_ops = {
313         .set_parent = clk_sam9x5_slow_set_parent,
314         .get_parent = clk_sam9x5_slow_get_parent,
315 };
316
317 static struct clk_hw * __init
318 at91_clk_register_sam9x5_slow(void __iomem *sckcr,
319                               const char *name,
320                               const char **parent_names,
321                               int num_parents,
322                               const struct clk_slow_bits *bits)
323 {
324         struct clk_sam9x5_slow *slowck;
325         struct clk_hw *hw;
326         struct clk_init_data init;
327         int ret;
328
329         if (!sckcr || !name || !parent_names || !num_parents)
330                 return ERR_PTR(-EINVAL);
331
332         slowck = kzalloc(sizeof(*slowck), GFP_KERNEL);
333         if (!slowck)
334                 return ERR_PTR(-ENOMEM);
335
336         init.name = name;
337         init.ops = &sam9x5_slow_ops;
338         init.parent_names = parent_names;
339         init.num_parents = num_parents;
340         init.flags = 0;
341
342         slowck->hw.init = &init;
343         slowck->sckcr = sckcr;
344         slowck->bits = bits;
345         slowck->parent = !!(readl(sckcr) & slowck->bits->cr_oscsel);
346
347         hw = &slowck->hw;
348         ret = clk_hw_register(NULL, &slowck->hw);
349         if (ret) {
350                 kfree(slowck);
351                 hw = ERR_PTR(ret);
352         }
353
354         return hw;
355 }
356
357 static void at91_clk_unregister_sam9x5_slow(struct clk_hw *hw)
358 {
359         struct clk_sam9x5_slow *slowck = to_clk_sam9x5_slow(hw);
360
361         clk_hw_unregister(hw);
362         kfree(slowck);
363 }
364
365 static void __init at91sam9x5_sckc_register(struct device_node *np,
366                                             unsigned int rc_osc_startup_us,
367                                             const struct clk_slow_bits *bits)
368 {
369         const char *parent_names[2] = { "slow_rc_osc", "slow_osc" };
370         void __iomem *regbase = of_iomap(np, 0);
371         struct device_node *child = NULL;
372         const char *xtal_name;
373         struct clk_hw *slow_rc, *slow_osc, *slowck;
374         bool bypass;
375         int ret;
376
377         if (!regbase)
378                 return;
379
380         slow_rc = at91_clk_register_slow_rc_osc(regbase, parent_names[0],
381                                                 32768, 50000000,
382                                                 rc_osc_startup_us, bits);
383         if (IS_ERR(slow_rc))
384                 return;
385
386         xtal_name = of_clk_get_parent_name(np, 0);
387         if (!xtal_name) {
388                 /* DT backward compatibility */
389                 child = of_get_compatible_child(np, "atmel,at91sam9x5-clk-slow-osc");
390                 if (!child)
391                         goto unregister_slow_rc;
392
393                 xtal_name = of_clk_get_parent_name(child, 0);
394                 bypass = of_property_read_bool(child, "atmel,osc-bypass");
395
396                 child =  of_get_compatible_child(np, "atmel,at91sam9x5-clk-slow");
397         } else {
398                 bypass = of_property_read_bool(np, "atmel,osc-bypass");
399         }
400
401         if (!xtal_name)
402                 goto unregister_slow_rc;
403
404         slow_osc = at91_clk_register_slow_osc(regbase, parent_names[1],
405                                               xtal_name, 1200000, bypass, bits);
406         if (IS_ERR(slow_osc))
407                 goto unregister_slow_rc;
408
409         slowck = at91_clk_register_sam9x5_slow(regbase, "slowck", parent_names,
410                                                2, bits);
411         if (IS_ERR(slowck))
412                 goto unregister_slow_osc;
413
414         /* DT backward compatibility */
415         if (child)
416                 ret = of_clk_add_hw_provider(child, of_clk_hw_simple_get,
417                                              slowck);
418         else
419                 ret = of_clk_add_hw_provider(np, of_clk_hw_simple_get, slowck);
420
421         if (WARN_ON(ret))
422                 goto unregister_slowck;
423
424         return;
425
426 unregister_slowck:
427         at91_clk_unregister_sam9x5_slow(slowck);
428 unregister_slow_osc:
429         at91_clk_unregister_slow_osc(slow_osc);
430 unregister_slow_rc:
431         at91_clk_unregister_slow_rc_osc(slow_rc);
432 }
433
434 static const struct clk_slow_bits at91sam9x5_bits = {
435         .cr_rcen = BIT(0),
436         .cr_osc32en = BIT(1),
437         .cr_osc32byp = BIT(2),
438         .cr_oscsel = BIT(3),
439 };
440
441 static void __init of_at91sam9x5_sckc_setup(struct device_node *np)
442 {
443         at91sam9x5_sckc_register(np, 75, &at91sam9x5_bits);
444 }
445 CLK_OF_DECLARE(at91sam9x5_clk_sckc, "atmel,at91sam9x5-sckc",
446                of_at91sam9x5_sckc_setup);
447
448 static void __init of_sama5d3_sckc_setup(struct device_node *np)
449 {
450         at91sam9x5_sckc_register(np, 500, &at91sam9x5_bits);
451 }
452 CLK_OF_DECLARE(sama5d3_clk_sckc, "atmel,sama5d3-sckc",
453                of_sama5d3_sckc_setup);
454
455 static const struct clk_slow_bits at91sam9x60_bits = {
456         .cr_osc32en = BIT(1),
457         .cr_osc32byp = BIT(2),
458         .cr_oscsel = BIT(24),
459 };
460
461 static void __init of_sam9x60_sckc_setup(struct device_node *np)
462 {
463         void __iomem *regbase = of_iomap(np, 0);
464         struct clk_hw_onecell_data *clk_data;
465         struct clk_hw *slow_rc, *slow_osc;
466         const char *xtal_name;
467         const char *parent_names[2] = { "slow_rc_osc", "slow_osc" };
468         bool bypass;
469         int ret;
470
471         if (!regbase)
472                 return;
473
474         slow_rc = clk_hw_register_fixed_rate(NULL, parent_names[0], NULL, 0,
475                                              32768);
476         if (IS_ERR(slow_rc))
477                 return;
478
479         xtal_name = of_clk_get_parent_name(np, 0);
480         if (!xtal_name)
481                 goto unregister_slow_rc;
482
483         bypass = of_property_read_bool(np, "atmel,osc-bypass");
484         slow_osc = at91_clk_register_slow_osc(regbase, parent_names[1],
485                                               xtal_name, 5000000, bypass,
486                                               &at91sam9x60_bits);
487         if (IS_ERR(slow_osc))
488                 goto unregister_slow_rc;
489
490         clk_data = kzalloc(struct_size(clk_data, hws, 2), GFP_KERNEL);
491         if (!clk_data)
492                 goto unregister_slow_osc;
493
494         /* MD_SLCK and TD_SLCK. */
495         clk_data->num = 2;
496         clk_data->hws[0] = clk_hw_register_fixed_rate(NULL, "md_slck",
497                                                       parent_names[0],
498                                                       0, 32768);
499         if (IS_ERR(clk_data->hws[0]))
500                 goto clk_data_free;
501
502         clk_data->hws[1] = at91_clk_register_sam9x5_slow(regbase, "td_slck",
503                                                          parent_names, 2,
504                                                          &at91sam9x60_bits);
505         if (IS_ERR(clk_data->hws[1]))
506                 goto unregister_md_slck;
507
508         ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_data);
509         if (WARN_ON(ret))
510                 goto unregister_td_slck;
511
512         return;
513
514 unregister_td_slck:
515         at91_clk_unregister_sam9x5_slow(clk_data->hws[1]);
516 unregister_md_slck:
517         clk_hw_unregister(clk_data->hws[0]);
518 clk_data_free:
519         kfree(clk_data);
520 unregister_slow_osc:
521         at91_clk_unregister_slow_osc(slow_osc);
522 unregister_slow_rc:
523         clk_hw_unregister(slow_rc);
524 }
525 CLK_OF_DECLARE(sam9x60_clk_sckc, "microchip,sam9x60-sckc",
526                of_sam9x60_sckc_setup);
527
528 static int clk_sama5d4_slow_osc_prepare(struct clk_hw *hw)
529 {
530         struct clk_sama5d4_slow_osc *osc = to_clk_sama5d4_slow_osc(hw);
531
532         if (osc->prepared)
533                 return 0;
534
535         /*
536          * Assume that if it has already been selected (for example by the
537          * bootloader), enough time has aready passed.
538          */
539         if ((readl(osc->sckcr) & osc->bits->cr_oscsel)) {
540                 osc->prepared = true;
541                 return 0;
542         }
543
544         if (system_state < SYSTEM_RUNNING)
545                 udelay(osc->startup_usec);
546         else
547                 usleep_range(osc->startup_usec, osc->startup_usec + 1);
548         osc->prepared = true;
549
550         return 0;
551 }
552
553 static int clk_sama5d4_slow_osc_is_prepared(struct clk_hw *hw)
554 {
555         struct clk_sama5d4_slow_osc *osc = to_clk_sama5d4_slow_osc(hw);
556
557         return osc->prepared;
558 }
559
560 static const struct clk_ops sama5d4_slow_osc_ops = {
561         .prepare = clk_sama5d4_slow_osc_prepare,
562         .is_prepared = clk_sama5d4_slow_osc_is_prepared,
563 };
564
565 static const struct clk_slow_bits at91sama5d4_bits = {
566         .cr_oscsel = BIT(3),
567 };
568
569 static void __init of_sama5d4_sckc_setup(struct device_node *np)
570 {
571         void __iomem *regbase = of_iomap(np, 0);
572         struct clk_hw *slow_rc, *slowck;
573         struct clk_sama5d4_slow_osc *osc;
574         struct clk_init_data init;
575         const char *xtal_name;
576         const char *parent_names[2] = { "slow_rc_osc", "slow_osc" };
577         int ret;
578
579         if (!regbase)
580                 return;
581
582         slow_rc = clk_hw_register_fixed_rate_with_accuracy(NULL,
583                                                            parent_names[0],
584                                                            NULL, 0, 32768,
585                                                            250000000);
586         if (IS_ERR(slow_rc))
587                 return;
588
589         xtal_name = of_clk_get_parent_name(np, 0);
590
591         osc = kzalloc(sizeof(*osc), GFP_KERNEL);
592         if (!osc)
593                 goto unregister_slow_rc;
594
595         init.name = parent_names[1];
596         init.ops = &sama5d4_slow_osc_ops;
597         init.parent_names = &xtal_name;
598         init.num_parents = 1;
599         init.flags = CLK_IGNORE_UNUSED;
600
601         osc->hw.init = &init;
602         osc->sckcr = regbase;
603         osc->startup_usec = 1200000;
604         osc->bits = &at91sama5d4_bits;
605
606         ret = clk_hw_register(NULL, &osc->hw);
607         if (ret)
608                 goto free_slow_osc_data;
609
610         slowck = at91_clk_register_sam9x5_slow(regbase, "slowck",
611                                                parent_names, 2,
612                                                &at91sama5d4_bits);
613         if (IS_ERR(slowck))
614                 goto unregister_slow_osc;
615
616         ret = of_clk_add_hw_provider(np, of_clk_hw_simple_get, slowck);
617         if (WARN_ON(ret))
618                 goto unregister_slowck;
619
620         return;
621
622 unregister_slowck:
623         at91_clk_unregister_sam9x5_slow(slowck);
624 unregister_slow_osc:
625         clk_hw_unregister(&osc->hw);
626 free_slow_osc_data:
627         kfree(osc);
628 unregister_slow_rc:
629         clk_hw_unregister(slow_rc);
630 }
631 CLK_OF_DECLARE(sama5d4_clk_sckc, "atmel,sama5d4-sckc",
632                of_sama5d4_sckc_setup);