GNU Linux-libre 6.8.9-gnu
[releases.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 struct clk_parent_data *parent_data,
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_data)
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_data = parent_data;
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         .determine_rate = clk_hw_determine_rate_no_reparent,
314         .set_parent = clk_sam9x5_slow_set_parent,
315         .get_parent = clk_sam9x5_slow_get_parent,
316 };
317
318 static struct clk_hw * __init
319 at91_clk_register_sam9x5_slow(void __iomem *sckcr,
320                               const char *name,
321                               const struct clk_hw **parent_hws,
322                               int num_parents,
323                               const struct clk_slow_bits *bits)
324 {
325         struct clk_sam9x5_slow *slowck;
326         struct clk_hw *hw;
327         struct clk_init_data init = {};
328         int ret;
329
330         if (!sckcr || !name || !parent_hws || !num_parents)
331                 return ERR_PTR(-EINVAL);
332
333         slowck = kzalloc(sizeof(*slowck), GFP_KERNEL);
334         if (!slowck)
335                 return ERR_PTR(-ENOMEM);
336
337         init.name = name;
338         init.ops = &sam9x5_slow_ops;
339         init.parent_hws = parent_hws;
340         init.num_parents = num_parents;
341         init.flags = 0;
342
343         slowck->hw.init = &init;
344         slowck->sckcr = sckcr;
345         slowck->bits = bits;
346         slowck->parent = !!(readl(sckcr) & slowck->bits->cr_oscsel);
347
348         hw = &slowck->hw;
349         ret = clk_hw_register(NULL, &slowck->hw);
350         if (ret) {
351                 kfree(slowck);
352                 hw = ERR_PTR(ret);
353         }
354
355         return hw;
356 }
357
358 static void at91_clk_unregister_sam9x5_slow(struct clk_hw *hw)
359 {
360         struct clk_sam9x5_slow *slowck = to_clk_sam9x5_slow(hw);
361
362         clk_hw_unregister(hw);
363         kfree(slowck);
364 }
365
366 static void __init at91sam9x5_sckc_register(struct device_node *np,
367                                             unsigned int rc_osc_startup_us,
368                                             const struct clk_slow_bits *bits)
369 {
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         static struct clk_parent_data parent_data = {
375                 .name = "slow_xtal",
376         };
377         const struct clk_hw *parent_hws[2];
378         bool bypass;
379         int ret;
380
381         if (!regbase)
382                 return;
383
384         slow_rc = at91_clk_register_slow_rc_osc(regbase, "slow_rc_osc",
385                                                 32768, 50000000,
386                                                 rc_osc_startup_us, bits);
387         if (IS_ERR(slow_rc))
388                 return;
389
390         xtal_name = of_clk_get_parent_name(np, 0);
391         if (!xtal_name) {
392                 /* DT backward compatibility */
393                 child = of_get_compatible_child(np, "atmel,at91sam9x5-clk-slow-osc");
394                 if (!child)
395                         goto unregister_slow_rc;
396
397                 xtal_name = of_clk_get_parent_name(child, 0);
398                 bypass = of_property_read_bool(child, "atmel,osc-bypass");
399
400                 child =  of_get_compatible_child(np, "atmel,at91sam9x5-clk-slow");
401         } else {
402                 bypass = of_property_read_bool(np, "atmel,osc-bypass");
403         }
404
405         if (!xtal_name)
406                 goto unregister_slow_rc;
407
408         parent_data.fw_name = xtal_name;
409
410         slow_osc = at91_clk_register_slow_osc(regbase, "slow_osc",
411                                               &parent_data, 1200000, bypass, bits);
412         if (IS_ERR(slow_osc))
413                 goto unregister_slow_rc;
414
415         parent_hws[0] = slow_rc;
416         parent_hws[1] = slow_osc;
417         slowck = at91_clk_register_sam9x5_slow(regbase, "slowck", parent_hws,
418                                                2, bits);
419         if (IS_ERR(slowck))
420                 goto unregister_slow_osc;
421
422         /* DT backward compatibility */
423         if (child)
424                 ret = of_clk_add_hw_provider(child, of_clk_hw_simple_get,
425                                              slowck);
426         else
427                 ret = of_clk_add_hw_provider(np, of_clk_hw_simple_get, slowck);
428
429         if (WARN_ON(ret))
430                 goto unregister_slowck;
431
432         return;
433
434 unregister_slowck:
435         at91_clk_unregister_sam9x5_slow(slowck);
436 unregister_slow_osc:
437         at91_clk_unregister_slow_osc(slow_osc);
438 unregister_slow_rc:
439         at91_clk_unregister_slow_rc_osc(slow_rc);
440 }
441
442 static const struct clk_slow_bits at91sam9x5_bits = {
443         .cr_rcen = BIT(0),
444         .cr_osc32en = BIT(1),
445         .cr_osc32byp = BIT(2),
446         .cr_oscsel = BIT(3),
447 };
448
449 static void __init of_at91sam9x5_sckc_setup(struct device_node *np)
450 {
451         at91sam9x5_sckc_register(np, 75, &at91sam9x5_bits);
452 }
453 CLK_OF_DECLARE(at91sam9x5_clk_sckc, "atmel,at91sam9x5-sckc",
454                of_at91sam9x5_sckc_setup);
455
456 static void __init of_sama5d3_sckc_setup(struct device_node *np)
457 {
458         at91sam9x5_sckc_register(np, 500, &at91sam9x5_bits);
459 }
460 CLK_OF_DECLARE(sama5d3_clk_sckc, "atmel,sama5d3-sckc",
461                of_sama5d3_sckc_setup);
462
463 static const struct clk_slow_bits at91sam9x60_bits = {
464         .cr_osc32en = BIT(1),
465         .cr_osc32byp = BIT(2),
466         .cr_oscsel = BIT(24),
467 };
468
469 static void __init of_sam9x60_sckc_setup(struct device_node *np)
470 {
471         void __iomem *regbase = of_iomap(np, 0);
472         struct clk_hw_onecell_data *clk_data;
473         struct clk_hw *slow_rc, *slow_osc;
474         const char *xtal_name;
475         const struct clk_hw *parent_hws[2];
476         static struct clk_parent_data parent_data = {
477                 .name = "slow_xtal",
478         };
479         bool bypass;
480         int ret;
481
482         if (!regbase)
483                 return;
484
485         slow_rc = clk_hw_register_fixed_rate_with_accuracy(NULL, "slow_rc_osc",
486                                                            NULL, 0, 32768,
487                                                            93750000);
488         if (IS_ERR(slow_rc))
489                 return;
490
491         xtal_name = of_clk_get_parent_name(np, 0);
492         if (!xtal_name)
493                 goto unregister_slow_rc;
494
495         parent_data.fw_name = xtal_name;
496         bypass = of_property_read_bool(np, "atmel,osc-bypass");
497         slow_osc = at91_clk_register_slow_osc(regbase, "slow_osc",
498                                               &parent_data, 5000000, bypass,
499                                               &at91sam9x60_bits);
500         if (IS_ERR(slow_osc))
501                 goto unregister_slow_rc;
502
503         clk_data = kzalloc(struct_size(clk_data, hws, 2), GFP_KERNEL);
504         if (!clk_data)
505                 goto unregister_slow_osc;
506
507         /* MD_SLCK and TD_SLCK. */
508         clk_data->num = 2;
509         clk_data->hws[0] = clk_hw_register_fixed_rate_parent_hw(NULL, "md_slck",
510                                                                 slow_rc,
511                                                                 0, 32768);
512         if (IS_ERR(clk_data->hws[0]))
513                 goto clk_data_free;
514
515         parent_hws[0] = slow_rc;
516         parent_hws[1] = slow_osc;
517         clk_data->hws[1] = at91_clk_register_sam9x5_slow(regbase, "td_slck",
518                                                          parent_hws, 2,
519                                                          &at91sam9x60_bits);
520         if (IS_ERR(clk_data->hws[1]))
521                 goto unregister_md_slck;
522
523         ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_data);
524         if (WARN_ON(ret))
525                 goto unregister_td_slck;
526
527         return;
528
529 unregister_td_slck:
530         at91_clk_unregister_sam9x5_slow(clk_data->hws[1]);
531 unregister_md_slck:
532         clk_hw_unregister(clk_data->hws[0]);
533 clk_data_free:
534         kfree(clk_data);
535 unregister_slow_osc:
536         at91_clk_unregister_slow_osc(slow_osc);
537 unregister_slow_rc:
538         clk_hw_unregister(slow_rc);
539 }
540 CLK_OF_DECLARE(sam9x60_clk_sckc, "microchip,sam9x60-sckc",
541                of_sam9x60_sckc_setup);
542
543 static int clk_sama5d4_slow_osc_prepare(struct clk_hw *hw)
544 {
545         struct clk_sama5d4_slow_osc *osc = to_clk_sama5d4_slow_osc(hw);
546
547         if (osc->prepared)
548                 return 0;
549
550         /*
551          * Assume that if it has already been selected (for example by the
552          * bootloader), enough time has already passed.
553          */
554         if ((readl(osc->sckcr) & osc->bits->cr_oscsel)) {
555                 osc->prepared = true;
556                 return 0;
557         }
558
559         if (system_state < SYSTEM_RUNNING)
560                 udelay(osc->startup_usec);
561         else
562                 usleep_range(osc->startup_usec, osc->startup_usec + 1);
563         osc->prepared = true;
564
565         return 0;
566 }
567
568 static int clk_sama5d4_slow_osc_is_prepared(struct clk_hw *hw)
569 {
570         struct clk_sama5d4_slow_osc *osc = to_clk_sama5d4_slow_osc(hw);
571
572         return osc->prepared;
573 }
574
575 static const struct clk_ops sama5d4_slow_osc_ops = {
576         .prepare = clk_sama5d4_slow_osc_prepare,
577         .is_prepared = clk_sama5d4_slow_osc_is_prepared,
578 };
579
580 static const struct clk_slow_bits at91sama5d4_bits = {
581         .cr_oscsel = BIT(3),
582 };
583
584 static void __init of_sama5d4_sckc_setup(struct device_node *np)
585 {
586         void __iomem *regbase = of_iomap(np, 0);
587         struct clk_hw *slow_rc, *slowck;
588         struct clk_sama5d4_slow_osc *osc;
589         struct clk_init_data init = {};
590         const char *xtal_name;
591         const struct clk_hw *parent_hws[2];
592         static struct clk_parent_data parent_data = {
593                 .name = "slow_xtal",
594         };
595         int ret;
596
597         if (!regbase)
598                 return;
599
600         slow_rc = clk_hw_register_fixed_rate_with_accuracy(NULL,
601                                                            "slow_rc_osc",
602                                                            NULL, 0, 32768,
603                                                            250000000);
604         if (IS_ERR(slow_rc))
605                 return;
606
607         xtal_name = of_clk_get_parent_name(np, 0);
608         if (!xtal_name)
609                 goto unregister_slow_rc;
610         parent_data.fw_name = xtal_name;
611
612         osc = kzalloc(sizeof(*osc), GFP_KERNEL);
613         if (!osc)
614                 goto unregister_slow_rc;
615
616         init.name = "slow_osc";
617         init.ops = &sama5d4_slow_osc_ops;
618         init.parent_data = &parent_data;
619         init.num_parents = 1;
620         init.flags = CLK_IGNORE_UNUSED;
621
622         osc->hw.init = &init;
623         osc->sckcr = regbase;
624         osc->startup_usec = 1200000;
625         osc->bits = &at91sama5d4_bits;
626
627         ret = clk_hw_register(NULL, &osc->hw);
628         if (ret)
629                 goto free_slow_osc_data;
630
631         parent_hws[0] = slow_rc;
632         parent_hws[1] = &osc->hw;
633         slowck = at91_clk_register_sam9x5_slow(regbase, "slowck",
634                                                parent_hws, 2,
635                                                &at91sama5d4_bits);
636         if (IS_ERR(slowck))
637                 goto unregister_slow_osc;
638
639         ret = of_clk_add_hw_provider(np, of_clk_hw_simple_get, slowck);
640         if (WARN_ON(ret))
641                 goto unregister_slowck;
642
643         return;
644
645 unregister_slowck:
646         at91_clk_unregister_sam9x5_slow(slowck);
647 unregister_slow_osc:
648         clk_hw_unregister(&osc->hw);
649 free_slow_osc_data:
650         kfree(osc);
651 unregister_slow_rc:
652         clk_hw_unregister(slow_rc);
653 }
654 CLK_OF_DECLARE(sama5d4_clk_sckc, "atmel,sama5d4-sckc",
655                of_sama5d4_sckc_setup);