Merge tag 's390-5.18-2' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
[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_with_accuracy(NULL, parent_names[0],
475                                                            NULL, 0, 32768,
476                                                            93750000);
477         if (IS_ERR(slow_rc))
478                 return;
479
480         xtal_name = of_clk_get_parent_name(np, 0);
481         if (!xtal_name)
482                 goto unregister_slow_rc;
483
484         bypass = of_property_read_bool(np, "atmel,osc-bypass");
485         slow_osc = at91_clk_register_slow_osc(regbase, parent_names[1],
486                                               xtal_name, 5000000, bypass,
487                                               &at91sam9x60_bits);
488         if (IS_ERR(slow_osc))
489                 goto unregister_slow_rc;
490
491         clk_data = kzalloc(struct_size(clk_data, hws, 2), GFP_KERNEL);
492         if (!clk_data)
493                 goto unregister_slow_osc;
494
495         /* MD_SLCK and TD_SLCK. */
496         clk_data->num = 2;
497         clk_data->hws[0] = clk_hw_register_fixed_rate(NULL, "md_slck",
498                                                       parent_names[0],
499                                                       0, 32768);
500         if (IS_ERR(clk_data->hws[0]))
501                 goto clk_data_free;
502
503         clk_data->hws[1] = at91_clk_register_sam9x5_slow(regbase, "td_slck",
504                                                          parent_names, 2,
505                                                          &at91sam9x60_bits);
506         if (IS_ERR(clk_data->hws[1]))
507                 goto unregister_md_slck;
508
509         ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_data);
510         if (WARN_ON(ret))
511                 goto unregister_td_slck;
512
513         return;
514
515 unregister_td_slck:
516         at91_clk_unregister_sam9x5_slow(clk_data->hws[1]);
517 unregister_md_slck:
518         clk_hw_unregister(clk_data->hws[0]);
519 clk_data_free:
520         kfree(clk_data);
521 unregister_slow_osc:
522         at91_clk_unregister_slow_osc(slow_osc);
523 unregister_slow_rc:
524         clk_hw_unregister(slow_rc);
525 }
526 CLK_OF_DECLARE(sam9x60_clk_sckc, "microchip,sam9x60-sckc",
527                of_sam9x60_sckc_setup);
528
529 static int clk_sama5d4_slow_osc_prepare(struct clk_hw *hw)
530 {
531         struct clk_sama5d4_slow_osc *osc = to_clk_sama5d4_slow_osc(hw);
532
533         if (osc->prepared)
534                 return 0;
535
536         /*
537          * Assume that if it has already been selected (for example by the
538          * bootloader), enough time has already passed.
539          */
540         if ((readl(osc->sckcr) & osc->bits->cr_oscsel)) {
541                 osc->prepared = true;
542                 return 0;
543         }
544
545         if (system_state < SYSTEM_RUNNING)
546                 udelay(osc->startup_usec);
547         else
548                 usleep_range(osc->startup_usec, osc->startup_usec + 1);
549         osc->prepared = true;
550
551         return 0;
552 }
553
554 static int clk_sama5d4_slow_osc_is_prepared(struct clk_hw *hw)
555 {
556         struct clk_sama5d4_slow_osc *osc = to_clk_sama5d4_slow_osc(hw);
557
558         return osc->prepared;
559 }
560
561 static const struct clk_ops sama5d4_slow_osc_ops = {
562         .prepare = clk_sama5d4_slow_osc_prepare,
563         .is_prepared = clk_sama5d4_slow_osc_is_prepared,
564 };
565
566 static const struct clk_slow_bits at91sama5d4_bits = {
567         .cr_oscsel = BIT(3),
568 };
569
570 static void __init of_sama5d4_sckc_setup(struct device_node *np)
571 {
572         void __iomem *regbase = of_iomap(np, 0);
573         struct clk_hw *slow_rc, *slowck;
574         struct clk_sama5d4_slow_osc *osc;
575         struct clk_init_data init;
576         const char *xtal_name;
577         const char *parent_names[2] = { "slow_rc_osc", "slow_osc" };
578         int ret;
579
580         if (!regbase)
581                 return;
582
583         slow_rc = clk_hw_register_fixed_rate_with_accuracy(NULL,
584                                                            parent_names[0],
585                                                            NULL, 0, 32768,
586                                                            250000000);
587         if (IS_ERR(slow_rc))
588                 return;
589
590         xtal_name = of_clk_get_parent_name(np, 0);
591
592         osc = kzalloc(sizeof(*osc), GFP_KERNEL);
593         if (!osc)
594                 goto unregister_slow_rc;
595
596         init.name = parent_names[1];
597         init.ops = &sama5d4_slow_osc_ops;
598         init.parent_names = &xtal_name;
599         init.num_parents = 1;
600         init.flags = CLK_IGNORE_UNUSED;
601
602         osc->hw.init = &init;
603         osc->sckcr = regbase;
604         osc->startup_usec = 1200000;
605         osc->bits = &at91sama5d4_bits;
606
607         ret = clk_hw_register(NULL, &osc->hw);
608         if (ret)
609                 goto free_slow_osc_data;
610
611         slowck = at91_clk_register_sam9x5_slow(regbase, "slowck",
612                                                parent_names, 2,
613                                                &at91sama5d4_bits);
614         if (IS_ERR(slowck))
615                 goto unregister_slow_osc;
616
617         ret = of_clk_add_hw_provider(np, of_clk_hw_simple_get, slowck);
618         if (WARN_ON(ret))
619                 goto unregister_slowck;
620
621         return;
622
623 unregister_slowck:
624         at91_clk_unregister_sam9x5_slow(slowck);
625 unregister_slow_osc:
626         clk_hw_unregister(&osc->hw);
627 free_slow_osc_data:
628         kfree(osc);
629 unregister_slow_rc:
630         clk_hw_unregister(slow_rc);
631 }
632 CLK_OF_DECLARE(sama5d4_clk_sckc, "atmel,sama5d4-sckc",
633                of_sama5d4_sckc_setup);