b56c01f3b06f07333828f7003ae632efc0198985
[platform/kernel/u-boot.git] / drivers / clk / at91 / compat.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Compatible code for non CCF AT91 platforms.
4  *
5  * Copyright (C) 2020 Microchip Technology Inc. and its subsidiaries
6  *
7  * Author: Claudiu Beznea <claudiu.beznea@microchip.com>
8  */
9 #include <common.h>
10 #include <clk-uclass.h>
11 #include <dm.h>
12 #include <dm/device_compat.h>
13 #include <dm/lists.h>
14 #include <dm/util.h>
15 #include <mach/at91_pmc.h>
16 #include <mach/at91_sfr.h>
17 #include <regmap.h>
18 #include <syscon.h>
19
20 #include "pmc.h"
21
22 DECLARE_GLOBAL_DATA_PTR;
23
24 struct pmc_platdata {
25         struct at91_pmc *reg_base;
26         struct regmap *regmap_sfr;
27 };
28
29 static const struct udevice_id at91_pmc_match[] = {
30         { .compatible = "atmel,at91rm9200-pmc" },
31         { .compatible = "atmel,at91sam9260-pmc" },
32         { .compatible = "atmel,at91sam9g45-pmc" },
33         { .compatible = "atmel,at91sam9n12-pmc" },
34         { .compatible = "atmel,at91sam9x5-pmc" },
35         { .compatible = "atmel,sama5d3-pmc" },
36         { .compatible = "atmel,sama5d2-pmc" },
37         {}
38 };
39
40 U_BOOT_DRIVER(at91_pmc) = {
41         .name = "at91-pmc",
42         .id = UCLASS_SIMPLE_BUS,
43         .of_match = at91_pmc_match,
44 };
45
46 static int at91_pmc_core_probe(struct udevice *dev)
47 {
48         struct pmc_platdata *plat = dev_get_platdata(dev);
49
50         dev = dev_get_parent(dev);
51
52         plat->reg_base = dev_read_addr_ptr(dev);
53
54         return 0;
55 }
56
57 /**
58  * at91_clk_sub_device_bind() - for the at91 clock driver
59  * Recursively bind its children as clk devices.
60  *
61  * @return: 0 on success, or negative error code on failure
62  */
63 int at91_clk_sub_device_bind(struct udevice *dev, const char *drv_name)
64 {
65         ofnode parent = dev_ofnode(dev);
66         ofnode node;
67         bool pre_reloc_only = !(gd->flags & GD_FLG_RELOC);
68         const char *name;
69         int ret;
70
71         ofnode_for_each_subnode(node, parent) {
72                 if (pre_reloc_only && !ofnode_pre_reloc(node))
73                         continue;
74                 /*
75                  * If this node has "compatible" property, this is not
76                  * a clock sub-node, but a normal device. skip.
77                  */
78                 if (ofnode_read_prop(node, "compatible", NULL))
79                         continue;
80
81                 if (ret != -FDT_ERR_NOTFOUND)
82                         return ret;
83
84                 name = ofnode_get_name(node);
85                 if (!name)
86                         return -EINVAL;
87                 ret = device_bind_driver_to_node(dev, drv_name, name, node,
88                                                  NULL);
89                 if (ret)
90                         return ret;
91         }
92
93         return 0;
94 }
95
96 int at91_clk_of_xlate(struct clk *clk, struct ofnode_phandle_args *args)
97 {
98         int periph;
99
100         if (args->args_count) {
101                 debug("Invalid args_count: %d\n", args->args_count);
102                 return -EINVAL;
103         }
104
105         periph = fdtdec_get_uint(gd->fdt_blob, dev_of_offset(clk->dev), "reg",
106                                  -1);
107         if (periph < 0)
108                 return -EINVAL;
109
110         clk->id = periph;
111
112         return 0;
113 }
114
115 int at91_clk_probe(struct udevice *dev)
116 {
117         struct udevice *dev_periph_container, *dev_pmc;
118         struct pmc_platdata *plat = dev_get_platdata(dev);
119
120         dev_periph_container = dev_get_parent(dev);
121         dev_pmc = dev_get_parent(dev_periph_container);
122
123         plat->reg_base = dev_read_addr_ptr(dev_pmc);
124
125         return 0;
126 }
127
128 /* SCKC specific code. */
129 static const struct udevice_id at91_sckc_match[] = {
130         { .compatible = "atmel,at91sam9x5-sckc" },
131         {}
132 };
133
134 U_BOOT_DRIVER(at91_sckc) = {
135         .name = "at91-sckc",
136         .id = UCLASS_SIMPLE_BUS,
137         .of_match = at91_sckc_match,
138 };
139
140 /* Slow clock specific code. */
141 static int at91_slow_clk_enable(struct clk *clk)
142 {
143         return 0;
144 }
145
146 static ulong at91_slow_clk_get_rate(struct clk *clk)
147 {
148         return CONFIG_SYS_AT91_SLOW_CLOCK;
149 }
150
151 static struct clk_ops at91_slow_clk_ops = {
152         .enable = at91_slow_clk_enable,
153         .get_rate = at91_slow_clk_get_rate,
154 };
155
156 static const struct udevice_id at91_slow_clk_match[] = {
157         { .compatible = "atmel,at91sam9x5-clk-slow" },
158         {}
159 };
160
161 U_BOOT_DRIVER(at91_slow_clk) = {
162         .name = "at91-slow-clk",
163         .id = UCLASS_CLK,
164         .of_match = at91_slow_clk_match,
165         .ops = &at91_slow_clk_ops,
166 };
167
168 /* Master clock specific code. */
169 static ulong at91_master_clk_get_rate(struct clk *clk)
170 {
171         return gd->arch.mck_rate_hz;
172 }
173
174 static struct clk_ops at91_master_clk_ops = {
175         .get_rate = at91_master_clk_get_rate,
176 };
177
178 static const struct udevice_id at91_master_clk_match[] = {
179         { .compatible = "atmel,at91rm9200-clk-master" },
180         { .compatible = "atmel,at91sam9x5-clk-master" },
181         {}
182 };
183
184 U_BOOT_DRIVER(at91_master_clk) = {
185         .name = "at91-master-clk",
186         .id = UCLASS_CLK,
187         .of_match = at91_master_clk_match,
188         .ops = &at91_master_clk_ops,
189 };
190
191 /* Main osc clock specific code. */
192 static int main_osc_clk_enable(struct clk *clk)
193 {
194         struct pmc_platdata *plat = dev_get_platdata(clk->dev);
195         struct at91_pmc *pmc = plat->reg_base;
196
197         if (readl(&pmc->sr) & AT91_PMC_MOSCSELS)
198                 return 0;
199
200         return -EINVAL;
201 }
202
203 static ulong main_osc_clk_get_rate(struct clk *clk)
204 {
205         return gd->arch.main_clk_rate_hz;
206 }
207
208 static struct clk_ops main_osc_clk_ops = {
209         .enable = main_osc_clk_enable,
210         .get_rate = main_osc_clk_get_rate,
211 };
212
213 static int main_osc_clk_probe(struct udevice *dev)
214 {
215         return at91_pmc_core_probe(dev);
216 }
217
218 static const struct udevice_id main_osc_clk_match[] = {
219         { .compatible = "atmel,at91sam9x5-clk-main" },
220         {}
221 };
222
223 U_BOOT_DRIVER(at91sam9x5_main_osc_clk) = {
224         .name = "at91sam9x5-main-osc-clk",
225         .id = UCLASS_CLK,
226         .of_match = main_osc_clk_match,
227         .probe = main_osc_clk_probe,
228         .plat_auto      = sizeof(struct pmc_platdata),
229         .ops = &main_osc_clk_ops,
230 };
231
232 /* PLLA clock specific code. */
233 static int plla_clk_enable(struct clk *clk)
234 {
235         struct pmc_platdata *plat = dev_get_platdata(clk->dev);
236         struct at91_pmc *pmc = plat->reg_base;
237
238         if (readl(&pmc->sr) & AT91_PMC_LOCKA)
239                 return 0;
240
241         return -EINVAL;
242 }
243
244 static ulong plla_clk_get_rate(struct clk *clk)
245 {
246         return gd->arch.plla_rate_hz;
247 }
248
249 static struct clk_ops plla_clk_ops = {
250         .enable = plla_clk_enable,
251         .get_rate = plla_clk_get_rate,
252 };
253
254 static int plla_clk_probe(struct udevice *dev)
255 {
256         return at91_pmc_core_probe(dev);
257 }
258
259 static const struct udevice_id plla_clk_match[] = {
260         { .compatible = "atmel,sama5d3-clk-pll" },
261         {}
262 };
263
264 U_BOOT_DRIVER(at91_plla_clk) = {
265         .name = "at91-plla-clk",
266         .id = UCLASS_CLK,
267         .of_match = plla_clk_match,
268         .probe = plla_clk_probe,
269         .plat_auto      = sizeof(struct pmc_platdata),
270         .ops = &plla_clk_ops,
271 };
272
273 /* PLLA DIV clock specific code. */
274 static int at91_plladiv_clk_enable(struct clk *clk)
275 {
276         return 0;
277 }
278
279 static ulong at91_plladiv_clk_get_rate(struct clk *clk)
280 {
281         struct pmc_platdata *plat = dev_get_platdata(clk->dev);
282         struct at91_pmc *pmc = plat->reg_base;
283         struct clk source;
284         ulong clk_rate;
285         int ret;
286
287         ret = clk_get_by_index(clk->dev, 0, &source);
288         if (ret)
289                 return -EINVAL;
290
291         clk_rate = clk_get_rate(&source);
292         if (readl(&pmc->mckr) & AT91_PMC_MCKR_PLLADIV_2)
293                 clk_rate /= 2;
294
295         return clk_rate;
296 }
297
298 static ulong at91_plladiv_clk_set_rate(struct clk *clk, ulong rate)
299 {
300         struct pmc_platdata *plat = dev_get_platdata(clk->dev);
301         struct at91_pmc *pmc = plat->reg_base;
302         struct clk source;
303         ulong parent_rate;
304         int ret;
305
306         ret = clk_get_by_index(clk->dev, 0, &source);
307         if (ret)
308                 return -EINVAL;
309
310         parent_rate = clk_get_rate(&source);
311         if ((parent_rate != rate) && ((parent_rate) / 2 != rate))
312                 return -EINVAL;
313
314         if (parent_rate != rate) {
315                 writel((readl(&pmc->mckr) | AT91_PMC_MCKR_PLLADIV_2),
316                        &pmc->mckr);
317         }
318
319         return 0;
320 }
321
322 static struct clk_ops at91_plladiv_clk_ops = {
323         .enable = at91_plladiv_clk_enable,
324         .get_rate = at91_plladiv_clk_get_rate,
325         .set_rate = at91_plladiv_clk_set_rate,
326 };
327
328 static int at91_plladiv_clk_probe(struct udevice *dev)
329 {
330         return at91_pmc_core_probe(dev);
331 }
332
333 static const struct udevice_id at91_plladiv_clk_match[] = {
334         { .compatible = "atmel,at91sam9x5-clk-plldiv" },
335         {}
336 };
337
338 U_BOOT_DRIVER(at91_plladiv_clk) = {
339         .name = "at91-plladiv-clk",
340         .id = UCLASS_CLK,
341         .of_match = at91_plladiv_clk_match,
342         .probe = at91_plladiv_clk_probe,
343         .plat_auto      = sizeof(struct pmc_platdata),
344         .ops = &at91_plladiv_clk_ops,
345 };
346
347 /* System clock specific code. */
348 #define SYSTEM_MAX_ID           31
349
350 /**
351  * at91_system_clk_bind() - for the system clock driver
352  * Recursively bind its children as clk devices.
353  *
354  * @return: 0 on success, or negative error code on failure
355  */
356 static int at91_system_clk_bind(struct udevice *dev)
357 {
358         return at91_clk_sub_device_bind(dev, "system-clk");
359 }
360
361 static const struct udevice_id at91_system_clk_match[] = {
362         { .compatible = "atmel,at91rm9200-clk-system" },
363         {}
364 };
365
366 U_BOOT_DRIVER(at91_system_clk) = {
367         .name = "at91-system-clk",
368         .id = UCLASS_MISC,
369         .of_match = at91_system_clk_match,
370         .bind = at91_system_clk_bind,
371 };
372
373 static inline int is_pck(int id)
374 {
375         return (id >= 8) && (id <= 15);
376 }
377
378 static ulong system_clk_get_rate(struct clk *clk)
379 {
380         struct clk clk_dev;
381         int ret;
382
383         ret = clk_get_by_index(clk->dev, 0, &clk_dev);
384         if (ret)
385                 return -EINVAL;
386
387         return clk_get_rate(&clk_dev);
388 }
389
390 static ulong system_clk_set_rate(struct clk *clk, ulong rate)
391 {
392         struct clk clk_dev;
393         int ret;
394
395         ret = clk_get_by_index(clk->dev, 0, &clk_dev);
396         if (ret)
397                 return -EINVAL;
398
399         return clk_set_rate(&clk_dev, rate);
400 }
401
402 static int system_clk_enable(struct clk *clk)
403 {
404         struct pmc_platdata *plat = dev_get_platdata(clk->dev);
405         struct at91_pmc *pmc = plat->reg_base;
406         u32 mask;
407
408         if (clk->id > SYSTEM_MAX_ID)
409                 return -EINVAL;
410
411         mask = BIT(clk->id);
412
413         writel(mask, &pmc->scer);
414
415         /**
416          * For the programmable clocks the Ready status in the PMC
417          * status register should be checked after enabling.
418          * For other clocks this is unnecessary.
419          */
420         if (!is_pck(clk->id))
421                 return 0;
422
423         while (!(readl(&pmc->sr) & mask))
424                 ;
425
426         return 0;
427 }
428
429 static struct clk_ops system_clk_ops = {
430         .of_xlate = at91_clk_of_xlate,
431         .get_rate = system_clk_get_rate,
432         .set_rate = system_clk_set_rate,
433         .enable = system_clk_enable,
434 };
435
436 U_BOOT_DRIVER(system_clk) = {
437         .name = "system-clk",
438         .id = UCLASS_CLK,
439         .probe = at91_clk_probe,
440         .plat_auto      = sizeof(struct pmc_platdata),
441         .ops = &system_clk_ops,
442 };
443
444 /* Peripheral clock specific code. */
445 #define PERIPHERAL_ID_MIN       2
446 #define PERIPHERAL_ID_MAX       31
447 #define PERIPHERAL_MASK(id)     (1 << ((id) & PERIPHERAL_ID_MAX))
448
449 enum periph_clk_type {
450         CLK_PERIPH_AT91RM9200 = 0,
451         CLK_PERIPH_AT91SAM9X5,
452 };
453
454 /**
455  * sam9x5_periph_clk_bind() - for the periph clock driver
456  * Recursively bind its children as clk devices.
457  *
458  * @return: 0 on success, or negative error code on failure
459  */
460 static int sam9x5_periph_clk_bind(struct udevice *dev)
461 {
462         return at91_clk_sub_device_bind(dev, "periph-clk");
463 }
464
465 static const struct udevice_id sam9x5_periph_clk_match[] = {
466         {
467                 .compatible = "atmel,at91rm9200-clk-peripheral",
468                 .data = CLK_PERIPH_AT91RM9200,
469         },
470         {
471                 .compatible = "atmel,at91sam9x5-clk-peripheral",
472                 .data = CLK_PERIPH_AT91SAM9X5,
473         },
474         {}
475 };
476
477 U_BOOT_DRIVER(sam9x5_periph_clk) = {
478         .name = "sam9x5-periph-clk",
479         .id = UCLASS_MISC,
480         .of_match = sam9x5_periph_clk_match,
481         .bind = sam9x5_periph_clk_bind,
482 };
483
484 static int periph_clk_enable(struct clk *clk)
485 {
486         struct pmc_platdata *plat = dev_get_platdata(clk->dev);
487         struct at91_pmc *pmc = plat->reg_base;
488         enum periph_clk_type clk_type;
489         void *addr;
490
491         if (clk->id < PERIPHERAL_ID_MIN)
492                 return -1;
493
494         clk_type = dev_get_driver_data(dev_get_parent(clk->dev));
495         if (clk_type == CLK_PERIPH_AT91RM9200) {
496                 addr = &pmc->pcer;
497                 if (clk->id > PERIPHERAL_ID_MAX)
498                         addr = &pmc->pcer1;
499
500                 setbits_le32(addr, PERIPHERAL_MASK(clk->id));
501         } else {
502                 writel(clk->id & AT91_PMC_PCR_PID_MASK, &pmc->pcr);
503                 setbits_le32(&pmc->pcr,
504                              AT91_PMC_PCR_CMD_WRITE | AT91_PMC_PCR_EN);
505         }
506
507         return 0;
508 }
509
510 static ulong periph_get_rate(struct clk *clk)
511 {
512         struct udevice *dev;
513         struct clk clk_dev;
514         ulong clk_rate;
515         int ret;
516
517         dev = dev_get_parent(clk->dev);
518
519         ret = clk_get_by_index(dev, 0, &clk_dev);
520         if (ret)
521                 return ret;
522
523         clk_rate = clk_get_rate(&clk_dev);
524
525         clk_free(&clk_dev);
526
527         return clk_rate;
528 }
529
530 static struct clk_ops periph_clk_ops = {
531         .of_xlate = at91_clk_of_xlate,
532         .enable = periph_clk_enable,
533         .get_rate = periph_get_rate,
534 };
535
536 U_BOOT_DRIVER(clk_periph) = {
537         .name   = "periph-clk",
538         .id     = UCLASS_CLK,
539         .plat_auto      = sizeof(struct pmc_platdata),
540         .probe = at91_clk_probe,
541         .ops    = &periph_clk_ops,
542 };
543
544 /* UTMI clock specific code. */
545 #ifdef CONFIG_AT91_UTMI
546
547 /*
548  * The purpose of this clock is to generate a 480 MHz signal. A different
549  * rate can't be configured.
550  */
551 #define UTMI_RATE       480000000
552
553 static int utmi_clk_enable(struct clk *clk)
554 {
555         struct pmc_platdata *plat = dev_get_platdata(clk->dev);
556         struct at91_pmc *pmc = plat->reg_base;
557         struct clk clk_dev;
558         ulong clk_rate;
559         u32 utmi_ref_clk_freq;
560         u32 tmp;
561         int err;
562         int timeout = 2000000;
563
564         if (readl(&pmc->sr) & AT91_PMC_LOCKU)
565                 return 0;
566
567         /*
568          * If mainck rate is different from 12 MHz, we have to configure the
569          * FREQ field of the SFR_UTMICKTRIM register to generate properly
570          * the utmi clock.
571          */
572         err = clk_get_by_index(clk->dev, 0, &clk_dev);
573         if (err)
574                 return -EINVAL;
575
576         clk_rate = clk_get_rate(&clk_dev);
577         switch (clk_rate) {
578         case 12000000:
579                 utmi_ref_clk_freq = 0;
580                 break;
581         case 16000000:
582                 utmi_ref_clk_freq = 1;
583                 break;
584         case 24000000:
585                 utmi_ref_clk_freq = 2;
586                 break;
587         /*
588          * Not supported on SAMA5D2 but it's not an issue since MAINCK
589          * maximum value is 24 MHz.
590          */
591         case 48000000:
592                 utmi_ref_clk_freq = 3;
593                 break;
594         default:
595                 printf("UTMICK: unsupported mainck rate\n");
596                 return -EINVAL;
597         }
598
599         if (plat->regmap_sfr) {
600                 err = regmap_read(plat->regmap_sfr, AT91_SFR_UTMICKTRIM, &tmp);
601                 if (err)
602                         return -EINVAL;
603
604                 tmp &= ~AT91_UTMICKTRIM_FREQ;
605                 tmp |= utmi_ref_clk_freq;
606                 err = regmap_write(plat->regmap_sfr, AT91_SFR_UTMICKTRIM, tmp);
607                 if (err)
608                         return -EINVAL;
609         } else if (utmi_ref_clk_freq) {
610                 printf("UTMICK: sfr node required\n");
611                 return -EINVAL;
612         }
613
614         tmp = readl(&pmc->uckr);
615         tmp |= AT91_PMC_UPLLEN |
616                AT91_PMC_UPLLCOUNT |
617                AT91_PMC_BIASEN;
618         writel(tmp, &pmc->uckr);
619
620         while ((--timeout) && !(readl(&pmc->sr) & AT91_PMC_LOCKU))
621                 ;
622         if (!timeout) {
623                 printf("UTMICK: timeout waiting for UPLL lock\n");
624                 return -ETIMEDOUT;
625         }
626
627         return 0;
628 }
629
630 static ulong utmi_clk_get_rate(struct clk *clk)
631 {
632         /* UTMI clk rate is fixed. */
633         return UTMI_RATE;
634 }
635
636 static struct clk_ops utmi_clk_ops = {
637         .enable = utmi_clk_enable,
638         .get_rate = utmi_clk_get_rate,
639 };
640
641 static int utmi_clk_ofdata_to_platdata(struct udevice *dev)
642 {
643         struct pmc_platdata *plat = dev_get_platdata(dev);
644         struct udevice *syscon;
645
646         uclass_get_device_by_phandle(UCLASS_SYSCON, dev,
647                                      "regmap-sfr", &syscon);
648
649         if (syscon)
650                 plat->regmap_sfr = syscon_get_regmap(syscon);
651
652         return 0;
653 }
654
655 static int utmi_clk_probe(struct udevice *dev)
656 {
657         return at91_pmc_core_probe(dev);
658 }
659
660 static const struct udevice_id utmi_clk_match[] = {
661         { .compatible = "atmel,at91sam9x5-clk-utmi" },
662         {}
663 };
664
665 U_BOOT_DRIVER(at91sam9x5_utmi_clk) = {
666         .name = "at91sam9x5-utmi-clk",
667         .id = UCLASS_CLK,
668         .of_match = utmi_clk_match,
669         .probe = utmi_clk_probe,
670         .ofdata_to_platdata = utmi_clk_ofdata_to_platdata,
671         .plat_auto      = sizeof(struct pmc_platdata),
672         .ops = &utmi_clk_ops,
673 };
674
675 #endif /* CONFIG_AT91_UTMI */
676
677 /* H32MX clock specific code. */
678 #ifdef CONFIG_AT91_H32MX
679
680 #define H32MX_MAX_FREQ  90000000
681
682 static ulong sama5d4_h32mx_clk_get_rate(struct clk *clk)
683 {
684         struct pmc_platdata *plat = dev_get_platdata(clk->dev);
685         struct at91_pmc *pmc = plat->reg_base;
686         ulong rate = gd->arch.mck_rate_hz;
687
688         if (readl(&pmc->mckr) & AT91_PMC_MCKR_H32MXDIV)
689                 rate /= 2;
690
691         if (rate > H32MX_MAX_FREQ)
692                 dev_dbg(clk->dev, "H32MX clock is too fast\n");
693
694         return rate;
695 }
696
697 static struct clk_ops sama5d4_h32mx_clk_ops = {
698         .get_rate = sama5d4_h32mx_clk_get_rate,
699 };
700
701 static int sama5d4_h32mx_clk_probe(struct udevice *dev)
702 {
703         return at91_pmc_core_probe(dev);
704 }
705
706 static const struct udevice_id sama5d4_h32mx_clk_match[] = {
707         { .compatible = "atmel,sama5d4-clk-h32mx" },
708         {}
709 };
710
711 U_BOOT_DRIVER(sama5d4_h32mx_clk) = {
712         .name = "sama5d4-h32mx-clk",
713         .id = UCLASS_CLK,
714         .of_match = sama5d4_h32mx_clk_match,
715         .probe = sama5d4_h32mx_clk_probe,
716         .plat_auto      = sizeof(struct pmc_platdata),
717         .ops = &sama5d4_h32mx_clk_ops,
718 };
719
720 #endif /* CONFIG_AT91_H32MX */
721
722 /* Generic clock specific code. */
723 #ifdef CONFIG_AT91_GENERIC_CLK
724
725 #define GENERATED_SOURCE_MAX    6
726 #define GENERATED_MAX_DIV       255
727
728 /**
729  * generated_clk_bind() - for the generated clock driver
730  * Recursively bind its children as clk devices.
731  *
732  * @return: 0 on success, or negative error code on failure
733  */
734 static int generated_clk_bind(struct udevice *dev)
735 {
736         return at91_clk_sub_device_bind(dev, "generic-clk");
737 }
738
739 static const struct udevice_id generated_clk_match[] = {
740         { .compatible = "atmel,sama5d2-clk-generated" },
741         {}
742 };
743
744 U_BOOT_DRIVER(generated_clk) = {
745         .name = "generated-clk",
746         .id = UCLASS_MISC,
747         .of_match = generated_clk_match,
748         .bind = generated_clk_bind,
749 };
750
751 struct generic_clk_priv {
752         u32 num_parents;
753 };
754
755 static ulong generic_clk_get_rate(struct clk *clk)
756 {
757         struct pmc_platdata *plat = dev_get_platdata(clk->dev);
758         struct at91_pmc *pmc = plat->reg_base;
759         struct clk parent;
760         ulong clk_rate;
761         u32 tmp, gckdiv;
762         u8 clock_source, parent_index;
763         int ret;
764
765         writel(clk->id & AT91_PMC_PCR_PID_MASK, &pmc->pcr);
766         tmp = readl(&pmc->pcr);
767         clock_source = (tmp >> AT91_PMC_PCR_GCKCSS_OFFSET) &
768                     AT91_PMC_PCR_GCKCSS_MASK;
769         gckdiv = (tmp >> AT91_PMC_PCR_GCKDIV_OFFSET) & AT91_PMC_PCR_GCKDIV_MASK;
770
771         parent_index = clock_source - 1;
772         ret = clk_get_by_index(dev_get_parent(clk->dev), parent_index, &parent);
773         if (ret)
774                 return 0;
775
776         clk_rate = clk_get_rate(&parent) / (gckdiv + 1);
777
778         clk_free(&parent);
779
780         return clk_rate;
781 }
782
783 static ulong generic_clk_set_rate(struct clk *clk, ulong rate)
784 {
785         struct pmc_platdata *plat = dev_get_platdata(clk->dev);
786         struct at91_pmc *pmc = plat->reg_base;
787         struct generic_clk_priv *priv = dev_get_priv(clk->dev);
788         struct clk parent, best_parent;
789         ulong tmp_rate, best_rate = rate, parent_rate;
790         int tmp_diff, best_diff = -1;
791         u32 div, best_div = 0;
792         u8 best_parent_index, best_clock_source = 0;
793         u8 i;
794         u32 tmp;
795         int ret;
796
797         for (i = 0; i < priv->num_parents; i++) {
798                 ret = clk_get_by_index(dev_get_parent(clk->dev), i, &parent);
799                 if (ret)
800                         return ret;
801
802                 parent_rate = clk_get_rate(&parent);
803                 if (IS_ERR_VALUE(parent_rate))
804                         return parent_rate;
805
806                 for (div = 1; div < GENERATED_MAX_DIV + 2; div++) {
807                         tmp_rate = DIV_ROUND_CLOSEST(parent_rate, div);
808                         tmp_diff = abs(rate - tmp_rate);
809
810                         if (best_diff < 0 || best_diff > tmp_diff) {
811                                 best_rate = tmp_rate;
812                                 best_diff = tmp_diff;
813
814                                 best_div = div - 1;
815                                 best_parent = parent;
816                                 best_parent_index = i;
817                                 best_clock_source = best_parent_index + 1;
818                         }
819
820                         if (!best_diff || tmp_rate < rate)
821                                 break;
822                 }
823
824                 if (!best_diff)
825                         break;
826         }
827
828         debug("GCK: best parent: %s, best_rate = %ld, best_div = %d\n",
829               best_parent.dev->name, best_rate, best_div);
830
831         ret = clk_enable(&best_parent);
832         if (ret)
833                 return ret;
834
835         writel(clk->id & AT91_PMC_PCR_PID_MASK, &pmc->pcr);
836         tmp = readl(&pmc->pcr);
837         tmp &= ~(AT91_PMC_PCR_GCKDIV | AT91_PMC_PCR_GCKCSS);
838         tmp |= AT91_PMC_PCR_GCKCSS_(best_clock_source) |
839                AT91_PMC_PCR_CMD_WRITE |
840                AT91_PMC_PCR_GCKDIV_(best_div) |
841                AT91_PMC_PCR_GCKEN;
842         writel(tmp, &pmc->pcr);
843
844         while (!(readl(&pmc->sr) & AT91_PMC_GCKRDY))
845                 ;
846
847         return 0;
848 }
849
850 static struct clk_ops generic_clk_ops = {
851         .of_xlate = at91_clk_of_xlate,
852         .get_rate = generic_clk_get_rate,
853         .set_rate = generic_clk_set_rate,
854 };
855
856 static int generic_clk_ofdata_to_platdata(struct udevice *dev)
857 {
858         struct generic_clk_priv *priv = dev_get_priv(dev);
859         u32 cells[GENERATED_SOURCE_MAX];
860         u32 num_parents;
861
862         num_parents = fdtdec_get_int_array_count(gd->fdt_blob,
863                         dev_of_offset(dev_get_parent(dev)), "clocks", cells,
864                         GENERATED_SOURCE_MAX);
865
866         if (!num_parents)
867                 return -1;
868
869         priv->num_parents = num_parents;
870
871         return 0;
872 }
873
874 U_BOOT_DRIVER(generic_clk) = {
875         .name = "generic-clk",
876         .id = UCLASS_CLK,
877         .probe = at91_clk_probe,
878         .ofdata_to_platdata = generic_clk_ofdata_to_platdata,
879         .priv_auto      = sizeof(struct generic_clk_priv),
880         .plat_auto      = sizeof(struct pmc_platdata),
881         .ops = &generic_clk_ops,
882 };
883
884 #endif /* CONFIG_AT91_GENERIC_CLK */
885
886 /* USB clock specific code. */
887 #ifdef CONFIG_AT91_USB_CLK
888
889 #define AT91_USB_CLK_SOURCE_MAX 2
890 #define AT91_USB_CLK_MAX_DIV    15
891
892 struct at91_usb_clk_priv {
893         u32 num_clksource;
894 };
895
896 static ulong at91_usb_clk_get_rate(struct clk *clk)
897 {
898         struct pmc_platdata *plat = dev_get_platdata(clk->dev);
899         struct at91_pmc *pmc = plat->reg_base;
900         struct clk source;
901         u32 tmp, usbdiv;
902         u8 source_index;
903         int ret;
904
905         tmp = readl(&pmc->pcr);
906         source_index = (tmp >> AT91_PMC_USB_USBS_OFFSET) &
907                         AT91_PMC_USB_USBS_MASK;
908         usbdiv = (tmp >> AT91_PMC_USB_DIV_OFFSET) & AT91_PMC_USB_DIV_MASK;
909
910         ret = clk_get_by_index(clk->dev, source_index, &source);
911         if (ret)
912                 return 0;
913
914         return clk_get_rate(&source) / (usbdiv + 1);
915 }
916
917 static ulong at91_usb_clk_set_rate(struct clk *clk, ulong rate)
918 {
919         struct pmc_platdata *plat = dev_get_platdata(clk->dev);
920         struct at91_pmc *pmc = plat->reg_base;
921         struct at91_usb_clk_priv *priv = dev_get_priv(clk->dev);
922         struct clk source, best_source;
923         ulong tmp_rate, best_rate = rate, source_rate;
924         int tmp_diff, best_diff = -1;
925         u32 div, best_div = 0;
926         u8 best_source_index = 0;
927         u8 i;
928         u32 tmp;
929         int ret;
930
931         for (i = 0; i < priv->num_clksource; i++) {
932                 ret = clk_get_by_index(clk->dev, i, &source);
933                 if (ret)
934                         return ret;
935
936                 source_rate = clk_get_rate(&source);
937                 if (IS_ERR_VALUE(source_rate))
938                         return source_rate;
939
940                 for (div = 1; div < AT91_USB_CLK_MAX_DIV + 2; div++) {
941                         tmp_rate = DIV_ROUND_CLOSEST(source_rate, div);
942                         tmp_diff = abs(rate - tmp_rate);
943
944                         if (best_diff < 0 || best_diff > tmp_diff) {
945                                 best_rate = tmp_rate;
946                                 best_diff = tmp_diff;
947
948                                 best_div = div - 1;
949                                 best_source = source;
950                                 best_source_index = i;
951                         }
952
953                         if (!best_diff || tmp_rate < rate)
954                                 break;
955                 }
956
957                 if (!best_diff)
958                         break;
959         }
960
961         debug("AT91 USB: best sourc: %s, best_rate = %ld, best_div = %d\n",
962               best_source.dev->name, best_rate, best_div);
963
964         ret = clk_enable(&best_source);
965         if (ret)
966                 return ret;
967
968         tmp = AT91_PMC_USB_USBS_(best_source_index) |
969               AT91_PMC_USB_DIV_(best_div);
970         writel(tmp, &pmc->usb);
971
972         return 0;
973 }
974
975 static struct clk_ops at91_usb_clk_ops = {
976         .get_rate = at91_usb_clk_get_rate,
977         .set_rate = at91_usb_clk_set_rate,
978 };
979
980 static int at91_usb_clk_ofdata_to_platdata(struct udevice *dev)
981 {
982         struct at91_usb_clk_priv *priv = dev_get_priv(dev);
983         u32 cells[AT91_USB_CLK_SOURCE_MAX];
984         u32 num_clksource;
985
986         num_clksource = fdtdec_get_int_array_count(gd->fdt_blob,
987                                                    dev_of_offset(dev),
988                                                    "clocks", cells,
989                                                    AT91_USB_CLK_SOURCE_MAX);
990
991         if (!num_clksource)
992                 return -1;
993
994         priv->num_clksource = num_clksource;
995
996         return 0;
997 }
998
999 static int at91_usb_clk_probe(struct udevice *dev)
1000 {
1001         return at91_pmc_core_probe(dev);
1002 }
1003
1004 static const struct udevice_id at91_usb_clk_match[] = {
1005         { .compatible = "atmel,at91sam9x5-clk-usb" },
1006         {}
1007 };
1008
1009 U_BOOT_DRIVER(at91_usb_clk) = {
1010         .name = "at91-usb-clk",
1011         .id = UCLASS_CLK,
1012         .of_match = at91_usb_clk_match,
1013         .probe = at91_usb_clk_probe,
1014         .ofdata_to_platdata = at91_usb_clk_ofdata_to_platdata,
1015         .priv_auto      = sizeof(struct at91_usb_clk_priv),
1016         .plat_auto      = sizeof(struct pmc_platdata),
1017         .ops = &at91_usb_clk_ops,
1018 };
1019
1020 #endif /* CONFIG_AT91_USB_CLK */