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