]> Git Repo - J-u-boot.git/blob - drivers/clk/at91/sam9x60.c
Merge tag 'u-boot-imx-master-20250127' of https://gitlab.denx.de/u-boot/custodians...
[J-u-boot.git] / drivers / clk / at91 / sam9x60.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) 2020 Microchip Technology Inc. and its subsidiaries
4  *
5  * Author: Claudiu Beznea <[email protected]>
6  *
7  * Based on sam9x60.c on Linux.
8  */
9
10 #include <clk-uclass.h>
11 #include <dm.h>
12 #include <dt-bindings/clk/at91.h>
13 #include <linux/clk-provider.h>
14
15 #include "pmc.h"
16
17 /**
18  * Clock identifiers to be used in conjunction with macros like
19  * AT91_TO_CLK_ID()
20  *
21  * @ID_MD_SLCK:                 TD slow clock identifier
22  * @ID_TD_SLCK:                 MD slow clock identifier
23  * @ID_MAIN_XTAL:               Main Xtal clock identifier
24  * @ID_MAIN_RC:                 Main RC clock identifier
25  * @ID_MAIN_RC_OSC:             Main RC Oscillator clock identifier
26  * @ID_MAIN_OSC:                Main Oscillator clock identifier
27  * @ID_MAINCK:                  MAINCK clock identifier
28  * @ID_PLL_U_FRAC:              UPLL fractional clock identifier
29  * @ID_PLL_U_DIV:               UPLL divider clock identifier
30  * @ID_PLL_A_FRAC:              APLL fractional clock identifier
31  * @ID_PLL_A_DIV:               APLL divider clock identifier
32
33  * @ID_MCK_DIV:                 MCK DIV clock identifier
34
35  * @ID_UTMI:                    UTMI clock identifier
36
37  * @ID_PROG0:                   Programmable 0 clock identifier
38  * @ID_PROG1:                   Programmable 1 clock identifier
39
40  * @ID_PCK0:                    PCK0 system clock identifier
41  * @ID_PCK1:                    PCK1 system clock identifier
42  * @ID_DDR:                     DDR system clock identifier
43  * @ID_QSPI:                    QSPI system clock identifier
44  *
45  * @ID_MCK_PRES:                MCK PRES clock identifier
46  *
47  * Note: if changing the values of this enums please sync them with
48  *       device tree
49  */
50 enum pmc_clk_ids {
51         ID_MD_SLCK              = 0,
52         ID_TD_SLCK              = 1,
53         ID_MAIN_XTAL            = 2,
54         ID_MAIN_RC              = 3,
55         ID_MAIN_RC_OSC          = 4,
56         ID_MAIN_OSC             = 5,
57         ID_MAINCK               = 6,
58
59         ID_PLL_U_FRAC           = 7,
60         ID_PLL_U_DIV            = 8,
61         ID_PLL_A_FRAC           = 9,
62         ID_PLL_A_DIV            = 10,
63
64         ID_MCK_DIV              = 11,
65
66         ID_UTMI                 = 12,
67
68         ID_PROG0                = 13,
69         ID_PROG1                = 14,
70
71         ID_PCK0                 = 15,
72         ID_PCK1                 = 16,
73
74         ID_DDR                  = 17,
75         ID_QSPI                 = 18,
76
77         ID_MCK_PRES             = 19,
78         ID_USBCK                = 20,
79         ID_UHPCK                = 21,
80
81         ID_MAX,
82 };
83
84 /**
85  * PLL type identifiers
86  * @PLL_TYPE_FRAC:      fractional PLL identifier
87  * @PLL_TYPE_DIV:       divider PLL identifier
88  */
89 enum pll_type {
90         PLL_TYPE_FRAC,
91         PLL_TYPE_DIV,
92 };
93
94 /* Clock names used as parents for multiple clocks. */
95 static const char *clk_names[] = {
96         [ID_MAIN_RC_OSC]        = "main_rc_osc",
97         [ID_MAIN_OSC]           = "main_osc",
98         [ID_MAINCK]             = "mainck",
99         [ID_PLL_U_DIV]          = "upll_divpmcck",
100         [ID_PLL_A_DIV]          = "plla_divpmcck",
101         [ID_MCK_PRES]           = "mck_pres",
102         [ID_MCK_DIV]            = "mck_div",
103         [ID_USBCK]              = "usbck",
104 };
105
106 /* Fractional PLL output range. */
107 static const struct clk_range plla_outputs[] = {
108         { .min = 2343750, .max = 1200000000 },
109 };
110
111 static const struct clk_range upll_outputs[] = {
112         { .min = 300000000, .max = 500000000 },
113 };
114
115 /* PLL characteristics. */
116 static const struct clk_pll_characteristics apll_characteristics = {
117         .input = { .min = 12000000, .max = 48000000 },
118         .num_output = ARRAY_SIZE(plla_outputs),
119         .output = plla_outputs,
120 };
121
122 static const struct clk_pll_characteristics upll_characteristics = {
123         .input = { .min = 12000000, .max = 48000000 },
124         .num_output = ARRAY_SIZE(upll_outputs),
125         .output = upll_outputs,
126         .upll = true,
127 };
128
129 /* Layout for fractional PLLs. */
130 static const struct clk_pll_layout pll_layout_frac = {
131         .mul_mask = GENMASK(31, 24),
132         .frac_mask = GENMASK(21, 0),
133         .mul_shift = 24,
134         .frac_shift = 0,
135 };
136
137 /* Layout for DIV PLLs. */
138 static const struct clk_pll_layout pll_layout_div = {
139         .div_mask = GENMASK(7, 0),
140         .endiv_mask = BIT(29),
141         .div_shift = 0,
142         .endiv_shift = 29,
143 };
144
145 /* MCK characteristics. */
146 static const struct clk_master_characteristics mck_characteristics = {
147         .output = { .min = 140000000, .max = 200000000 },
148         .divisors = { 1, 2, 4, 3 },
149         .have_div3_pres = 1,
150 };
151
152 /* MCK layout. */
153 static const struct clk_master_layout mck_layout = {
154         .mask = 0x373,
155         .pres_shift = 4,
156         .offset = 0x28,
157 };
158
159 /* Programmable clock layout. */
160 static const struct clk_programmable_layout programmable_layout = {
161         .pres_mask = 0xff,
162         .pres_shift = 8,
163         .css_mask = 0x1f,
164         .have_slck_mck = 0,
165         .is_pres_direct = 1,
166 };
167
168 /* Peripheral clock layout. */
169 static const struct clk_pcr_layout pcr_layout = {
170         .offset = 0x88,
171         .cmd = BIT(31),
172         .gckcss_mask = GENMASK(12, 8),
173         .pid_mask = GENMASK(6, 0),
174 };
175
176 /* USB clock layout */
177 static const struct clk_usbck_layout usbck_layout = {
178         .offset = 0x38,
179         .usbs_mask = GENMASK(1, 0),
180         .usbdiv_mask = GENMASK(11, 8),
181 };
182
183 /**
184  * PLL clocks description
185  * @n:          clock name
186  * @p:          clock parent
187  * @l:          clock layout
188  * @t:          clock type
189  * @f:          true if clock is fixed and not changeable by driver
190  * @id:         clock id corresponding to PLL driver
191  * @cid:        clock id corresponding to clock subsystem
192  */
193 static const struct {
194         const char *n;
195         const char *p;
196         const struct clk_pll_layout *l;
197         const struct clk_pll_characteristics *c;
198         u8 t;
199         u8 f;
200         u8 id;
201         u8 cid;
202 } sam9x60_plls[] = {
203         {
204                 .n = "plla_fracck",
205                 .p = "mainck",
206                 .l = &pll_layout_frac,
207                 .c = &apll_characteristics,
208                 .t = PLL_TYPE_FRAC,
209                 .f = 1,
210                 .id = 0,
211                 .cid = ID_PLL_A_FRAC,
212         },
213
214         {
215                 .n = "plla_divpmcck",
216                 .p = "plla_fracck",
217                 .l = &pll_layout_div,
218                 .c = &apll_characteristics,
219                 .t = PLL_TYPE_DIV,
220                 .f = 1,
221                 .id = 0,
222                 .cid = ID_PLL_A_DIV,
223         },
224
225         {
226                 .n = "upll_fracck",
227                 .p = "main_osc",
228                 .l = &pll_layout_frac,
229                 .c = &upll_characteristics,
230                 .t = PLL_TYPE_FRAC,
231                 .f = 1,
232                 .id = 1,
233                 .cid = ID_PLL_U_FRAC,
234         },
235
236         {
237                 .n = "upll_divpmcck",
238                 .p = "upll_fracck",
239                 .l = &pll_layout_div,
240                 .c = &upll_characteristics,
241                 .t = PLL_TYPE_DIV,
242                 .f = 1,
243                 .id = 1,
244                 .cid = ID_PLL_U_DIV,
245         },
246 };
247
248 /**
249  * Programmable clock description
250  * @n:                  clock name
251  * @cid:                clock id corresponding to clock subsystem
252  */
253 static const struct {
254         const char *n;
255         u8 cid;
256 } sam9x60_prog[] = {
257         { .n = "prog0", .cid = ID_PROG0, },
258         { .n = "prog1", .cid = ID_PROG1, },
259 };
260
261 /* Mux table for programmable clocks. */
262 static u32 sam9x60_prog_mux_table[] = { 0, 1, 2, 3, 4, 5, };
263
264 /**
265  * System clock description
266  * @n:                  clock name
267  * @p:                  parent clock name
268  * @id:                 clock id corresponding to system clock driver
269  * @cid:                clock id corresponding to clock subsystem
270  */
271 static const struct {
272         const char *n;
273         const char *p;
274         u8 id;
275         u8 cid;
276 } sam9x60_systemck[] = {
277         { .n = "ddrck",         .p = "mck_div",  .id = 2, .cid = ID_DDR, },
278         { .n = "uhpck",         .p = "usbck",    .id = 6, .cid = ID_UHPCK },
279         { .n = "pck0",          .p = "prog0",    .id = 8, .cid = ID_PCK0, },
280         { .n = "pck1",          .p = "prog1",    .id = 9, .cid = ID_PCK1, },
281         { .n = "qspick",        .p = "mck_div",  .id = 19, .cid = ID_QSPI, },
282 };
283
284 /**
285  * Peripheral clock description
286  * @n:          clock name
287  * @id:         clock id
288  */
289 static const struct {
290         const char *n;
291         u8 id;
292 } sam9x60_periphck[] = {
293         { .n = "pioA_clk",   .id = 2, },
294         { .n = "pioB_clk",   .id = 3, },
295         { .n = "pioC_clk",   .id = 4, },
296         { .n = "flex0_clk",  .id = 5, },
297         { .n = "flex1_clk",  .id = 6, },
298         { .n = "flex2_clk",  .id = 7, },
299         { .n = "flex3_clk",  .id = 8, },
300         { .n = "flex6_clk",  .id = 9, },
301         { .n = "flex7_clk",  .id = 10, },
302         { .n = "flex8_clk",  .id = 11, },
303         { .n = "sdmmc0_clk", .id = 12, },
304         { .n = "flex4_clk",  .id = 13, },
305         { .n = "flex5_clk",  .id = 14, },
306         { .n = "flex9_clk",  .id = 15, },
307         { .n = "flex10_clk", .id = 16, },
308         { .n = "tcb0_clk",   .id = 17, },
309         { .n = "pwm_clk",    .id = 18, },
310         { .n = "adc_clk",    .id = 19, },
311         { .n = "dma0_clk",   .id = 20, },
312         { .n = "matrix_clk", .id = 21, },
313         { .n = "uhphs_clk",  .id = 22, },
314         { .n = "udphs_clk",  .id = 23, },
315         { .n = "macb0_clk",  .id = 24, },
316         { .n = "lcd_clk",    .id = 25, },
317         { .n = "sdmmc1_clk", .id = 26, },
318         { .n = "macb1_clk",  .id = 27, },
319         { .n = "ssc_clk",    .id = 28, },
320         { .n = "can0_clk",   .id = 29, },
321         { .n = "can1_clk",   .id = 30, },
322         { .n = "flex11_clk", .id = 32, },
323         { .n = "flex12_clk", .id = 33, },
324         { .n = "i2s_clk",    .id = 34, },
325         { .n = "qspi_clk",   .id = 35, },
326         { .n = "gfx2d_clk",  .id = 36, },
327         { .n = "pit64b_clk", .id = 37, },
328         { .n = "trng_clk",   .id = 38, },
329         { .n = "aes_clk",    .id = 39, },
330         { .n = "tdes_clk",   .id = 40, },
331         { .n = "sha_clk",    .id = 41, },
332         { .n = "classd_clk", .id = 42, },
333         { .n = "isi_clk",    .id = 43, },
334         { .n = "pioD_clk",   .id = 44, },
335         { .n = "tcb1_clk",   .id = 45, },
336         { .n = "dbgu_clk",   .id = 47, },
337         { .n = "mpddr_clk",  .id = 49, },
338 };
339
340 /**
341  * Generic clock description
342  * @n:                  clock name
343  * @ep:                 extra parents parents names
344  * @ep_mux_table:       extra parents mux table
345  * @ep_clk_mux_table:   extra parents clock mux table (for CCF)
346  * @r:                  clock output range
347  * @ep_count:           extra parents count
348  * @id:                 clock id
349  */
350 static const struct {
351         const char *n;
352         struct clk_range r;
353         u8 id;
354 } sam9x60_gck[] = {
355         { .n = "flex0_gclk",  .id = 5, },
356         { .n = "flex1_gclk",  .id = 6, },
357         { .n = "flex2_gclk",  .id = 7, },
358         { .n = "flex3_gclk",  .id = 8, },
359         { .n = "flex6_gclk",  .id = 9, },
360         { .n = "flex7_gclk",  .id = 10, },
361         { .n = "flex8_gclk",  .id = 11, },
362         { .n = "sdmmc0_gclk", .id = 12, .r = { .min = 0, .max = 105000000 }, },
363         { .n = "flex4_gclk",  .id = 13, },
364         { .n = "flex5_gclk",  .id = 14, },
365         { .n = "flex9_gclk",  .id = 15, },
366         { .n = "flex10_gclk", .id = 16, },
367         { .n = "tcb0_gclk",   .id = 17, },
368         { .n = "adc_gclk",    .id = 19, },
369         { .n = "lcd_gclk",    .id = 25, .r = { .min = 0, .max = 140000000 }, },
370         { .n = "sdmmc1_gclk", .id = 26, .r = { .min = 0, .max = 105000000 }, },
371         { .n = "flex11_gclk", .id = 32, },
372         { .n = "flex12_gclk", .id = 33, },
373         { .n = "i2s_gclk",    .id = 34, .r = { .min = 0, .max = 105000000 }, },
374         { .n = "pit64b_gclk", .id = 37, },
375         { .n = "classd_gclk", .id = 42, .r = { .min = 0, .max = 100000000 }, },
376         { .n = "tcb1_gclk",   .id = 45, },
377         { .n = "dbgu_gclk",   .id = 47, },
378 };
379
380 /**
381  * Clock setup description
382  * @cid:        clock id corresponding to clock subsystem
383  * @pid:        parent clock id corresponding to clock subsystem
384  * @rate:       clock rate
385  * @prate:      parent rate
386  */
387 static const struct pmc_clk_setup sam9x60_clk_setup[] = {
388         {
389                 .cid = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_U_FRAC),
390                 .rate = 960000000,
391         },
392
393         {
394                 .cid = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_U_DIV),
395                 .rate = 480000000,
396         },
397
398         {
399                 .cid = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_USBCK),
400                 .pid = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_U_DIV),
401                 .rate = 48000000,
402         },
403 };
404
405 #define prepare_mux_table(_allocs, _index, _dst, _src, _num, _label)    \
406         do {                                                            \
407                 int _i;                                                 \
408                 (_dst) = kzalloc(sizeof(*(_dst)) * (_num), GFP_KERNEL); \
409                 if (!(_dst)) {                                          \
410                         ret = -ENOMEM;                                  \
411                         goto _label;                                    \
412                 }                                                       \
413                 (_allocs)[(_index)++] = (_dst);                         \
414                 for (_i = 0; _i < (_num); _i++)                         \
415                         (_dst)[_i] = (_src)[_i];                        \
416         } while (0)
417
418 static int sam9x60_clk_probe(struct udevice *dev)
419 {
420         void __iomem *base = (void *)devfdt_get_addr_ptr(dev);
421         unsigned int *clkmuxallocs[64], *muxallocs[64];
422         const char *p[10];
423         unsigned int cm[10], m[10], *tmpclkmux, *tmpmux;
424         struct clk clk, *c;
425         int ret, muxallocindex = 0, clkmuxallocindex = 0, i;
426         static const struct clk_range r = { 0, 0 };
427
428         if (!base)
429                 return -EINVAL;
430
431         memset(muxallocs,    0, sizeof(muxallocs));
432         memset(clkmuxallocs, 0, sizeof(clkmuxallocs));
433
434         ret = clk_get_by_index(dev, 0, &clk);
435         if (ret)
436                 return ret;
437
438         ret = clk_get_by_id(clk.id, &c);
439         if (ret)
440                 return ret;
441
442         clk_names[ID_TD_SLCK] = kmemdup(clk_hw_get_name(c),
443                                         strlen(clk_hw_get_name(c)) + 1,
444                                         GFP_KERNEL);
445         if (!clk_names[ID_TD_SLCK])
446                 return -ENOMEM;
447
448         ret = clk_get_by_index(dev, 1, &clk);
449         if (ret)
450                 return ret;
451
452         ret = clk_get_by_id(clk.id, &c);
453         if (ret)
454                 return ret;
455
456         clk_names[ID_MD_SLCK] = kmemdup(clk_hw_get_name(c),
457                                         strlen(clk_hw_get_name(c)) + 1,
458                                         GFP_KERNEL);
459         if (!clk_names[ID_MD_SLCK])
460                 return -ENOMEM;
461
462         ret = clk_get_by_index(dev, 2, &clk);
463         if (ret)
464                 return ret;
465
466         clk_names[ID_MAIN_XTAL] = kmemdup(clk_hw_get_name(&clk),
467                                           strlen(clk_hw_get_name(&clk)) + 1,
468                                           GFP_KERNEL);
469         if (!clk_names[ID_MAIN_XTAL])
470                 return -ENOMEM;
471
472         ret = clk_get_by_index(dev, 3, &clk);
473         if (ret)
474                 goto fail;
475
476         clk_names[ID_MAIN_RC] = kmemdup(clk_hw_get_name(&clk),
477                                         strlen(clk_hw_get_name(&clk)) + 1,
478                                         GFP_KERNEL);
479         if (ret)
480                 goto fail;
481
482         /* Register main rc oscillator. */
483         c = at91_clk_main_rc(base, clk_names[ID_MAIN_RC_OSC],
484                              clk_names[ID_MAIN_RC]);
485         if (IS_ERR(c)) {
486                 ret = PTR_ERR(c);
487                 goto fail;
488         }
489         clk_dm(AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MAIN_RC_OSC), c);
490
491         /* Register main oscillator. */
492         c = at91_clk_main_osc(base, clk_names[ID_MAIN_OSC],
493                               clk_names[ID_MAIN_XTAL], false);
494         if (IS_ERR(c)) {
495                 ret = PTR_ERR(c);
496                 goto fail;
497         }
498         clk_dm(AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MAIN_OSC), c);
499
500         /* Register mainck. */
501         p[0] = clk_names[ID_MAIN_RC_OSC];
502         p[1] = clk_names[ID_MAIN_OSC];
503         cm[0] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MAIN_RC_OSC);
504         cm[1] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MAIN_OSC);
505         prepare_mux_table(clkmuxallocs, clkmuxallocindex, tmpclkmux, cm, 2,
506                           fail);
507         c = at91_clk_sam9x5_main(base, clk_names[ID_MAINCK], p,
508                                  2, tmpclkmux, PMC_TYPE_CORE);
509         if (IS_ERR(c)) {
510                 ret = PTR_ERR(c);
511                 goto fail;
512         }
513         clk_dm(AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MAINCK), c);
514
515         /* Register PLL fracs clocks. */
516         for (i = 0; i < ARRAY_SIZE(sam9x60_plls); i++) {
517                 if (sam9x60_plls[i].t != PLL_TYPE_FRAC)
518                         continue;
519
520                 c = sam9x60_clk_register_frac_pll(base, sam9x60_plls[i].n,
521                                                   sam9x60_plls[i].p,
522                                                   sam9x60_plls[i].id,
523                                                   sam9x60_plls[i].c,
524                                                   sam9x60_plls[i].l,
525                                                   sam9x60_plls[i].f);
526                 if (IS_ERR(c)) {
527                         ret = PTR_ERR(c);
528                         goto fail;
529                 }
530                 clk_dm(AT91_TO_CLK_ID(PMC_TYPE_CORE, sam9x60_plls[i].cid), c);
531         }
532
533         /* Register PLL div clocks. */
534         for (i = 0; i < ARRAY_SIZE(sam9x60_plls); i++) {
535                 if (sam9x60_plls[i].t != PLL_TYPE_DIV)
536                         continue;
537
538                 c = sam9x60_clk_register_div_pll(base, sam9x60_plls[i].n,
539                                                  sam9x60_plls[i].p,
540                                                  sam9x60_plls[i].id,
541                                                  sam9x60_plls[i].c,
542                                                  sam9x60_plls[i].l,
543                                                  sam9x60_plls[i].f);
544                 if (IS_ERR(c)) {
545                         ret = PTR_ERR(c);
546                         goto fail;
547                 }
548                 clk_dm(AT91_TO_CLK_ID(PMC_TYPE_CORE, sam9x60_plls[i].cid), c);
549         }
550
551         /* Register MCK pres clock. */
552         p[0] = clk_names[ID_MD_SLCK];
553         p[1] = clk_names[ID_MAINCK];
554         p[2] = clk_names[ID_PLL_A_DIV];
555         p[3] = clk_names[ID_PLL_U_DIV];
556         cm[0] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MD_SLCK);
557         cm[1] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MAINCK);
558         cm[2] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_A_DIV);
559         cm[3] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_U_DIV);
560         prepare_mux_table(clkmuxallocs, clkmuxallocindex, tmpclkmux, cm, 4,
561                           fail);
562         c = at91_clk_register_master_pres(base, clk_names[ID_MCK_PRES], p, 4,
563                                           &mck_layout, &mck_characteristics,
564                                           tmpclkmux);
565         if (IS_ERR(c)) {
566                 ret = PTR_ERR(c);
567                 goto fail;
568         }
569         clk_dm(AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MCK_PRES), c);
570
571         /* Register MCK div clock. */
572         c = at91_clk_register_master_div(base, clk_names[ID_MCK_DIV],
573                                          clk_names[ID_MCK_PRES],
574                                          &mck_layout, &mck_characteristics);
575         if (IS_ERR(c)) {
576                 ret = PTR_ERR(c);
577                 goto fail;
578         }
579         clk_dm(AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MCK_DIV), c);
580
581         /* Register usbck. */
582         p[0] = clk_names[ID_PLL_A_DIV];
583         p[1] = clk_names[ID_PLL_U_DIV];
584         p[2] = clk_names[ID_MAIN_XTAL];
585         m[0] = 0;
586         m[1] = 1;
587         m[2] = 2;
588         cm[0] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_A_DIV);
589         cm[1] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_U_DIV);
590         cm[2] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MAIN_XTAL);
591         prepare_mux_table(clkmuxallocs, clkmuxallocindex, tmpclkmux, cm,
592                           3, fail);
593         prepare_mux_table(muxallocs, muxallocindex, tmpmux, m, 3, fail);
594         c = sam9x60_clk_register_usb(base, clk_names[ID_USBCK], p, 3,
595                                      &usbck_layout, tmpclkmux, tmpmux,
596                                      ID_USBCK);
597         if (IS_ERR(c)) {
598                 ret = PTR_ERR(c);
599                 goto fail;
600         }
601         clk_dm(AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_USBCK), c);
602
603         /* Register programmable clocks. */
604         p[0] = clk_names[ID_MD_SLCK];
605         p[1] = clk_names[ID_TD_SLCK];
606         p[2] = clk_names[ID_MAINCK];
607         p[3] = clk_names[ID_MCK_DIV];
608         p[4] = clk_names[ID_PLL_A_DIV];
609         p[5] = clk_names[ID_PLL_U_DIV];
610         cm[0] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MD_SLCK);
611         cm[1] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_TD_SLCK);
612         cm[2] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MAINCK);
613         cm[3] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MCK_DIV);
614         cm[4] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_A_DIV);
615         cm[5] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_U_DIV);
616         for (i = 0; i < ARRAY_SIZE(sam9x60_prog); i++) {
617                 prepare_mux_table(clkmuxallocs, clkmuxallocindex, tmpclkmux, cm,
618                                   6, fail);
619
620                 c = at91_clk_register_programmable(base, sam9x60_prog[i].n, p,
621                                                    10, i, &programmable_layout,
622                                                    tmpclkmux,
623                                                    sam9x60_prog_mux_table);
624                 if (IS_ERR(c)) {
625                         ret = PTR_ERR(c);
626                         goto fail;
627                 }
628                 clk_dm(AT91_TO_CLK_ID(PMC_TYPE_CORE, sam9x60_prog[i].cid), c);
629         }
630
631         /* System clocks. */
632         for (i = 0; i < ARRAY_SIZE(sam9x60_systemck); i++) {
633                 c = at91_clk_register_system(base, sam9x60_systemck[i].n,
634                                              sam9x60_systemck[i].p,
635                                              sam9x60_systemck[i].id);
636                 if (IS_ERR(c)) {
637                         ret = PTR_ERR(c);
638                         goto fail;
639                 }
640                 clk_dm(AT91_TO_CLK_ID(PMC_TYPE_SYSTEM, sam9x60_systemck[i].cid),
641                        c);
642         }
643
644         /* Peripheral clocks. */
645         for (i = 0; i < ARRAY_SIZE(sam9x60_periphck); i++) {
646                 c = at91_clk_register_sam9x5_peripheral(base, &pcr_layout,
647                                                         sam9x60_periphck[i].n,
648                                                         clk_names[ID_MCK_DIV],
649                                                         sam9x60_periphck[i].id,
650                                                         &r);
651                 if (IS_ERR(c)) {
652                         ret = PTR_ERR(c);
653                         goto fail;
654                 }
655                 clk_dm(AT91_TO_CLK_ID(PMC_TYPE_PERIPHERAL,
656                                       sam9x60_periphck[i].id), c);
657         }
658
659         /* Generic clocks. */
660         p[0] = clk_names[ID_MD_SLCK];
661         p[1] = clk_names[ID_TD_SLCK];
662         p[2] = clk_names[ID_MAINCK];
663         p[3] = clk_names[ID_MCK_DIV];
664         p[4] = clk_names[ID_PLL_A_DIV];
665         p[5] = clk_names[ID_PLL_U_DIV];
666         m[0] = 0;
667         m[1] = 1;
668         m[2] = 2;
669         m[3] = 3;
670         m[4] = 4;
671         m[5] = 5;
672         cm[0] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MD_SLCK);
673         cm[1] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_TD_SLCK);
674         cm[2] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MAINCK);
675         cm[3] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MCK_DIV);
676         cm[4] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_A_DIV);
677         cm[5] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_U_DIV);
678         for (i = 0; i < ARRAY_SIZE(sam9x60_gck); i++) {
679                 prepare_mux_table(clkmuxallocs, clkmuxallocindex, tmpclkmux, cm,
680                                   6, fail);
681                 prepare_mux_table(muxallocs, muxallocindex, tmpmux, m,
682                                   6, fail);
683
684                 c = at91_clk_register_generic(base, &pcr_layout,
685                                               sam9x60_gck[i].n, p, tmpclkmux,
686                                               tmpmux, 6, sam9x60_gck[i].id,
687                                               &sam9x60_gck[i].r);
688                 if (IS_ERR(c)) {
689                         ret = PTR_ERR(c);
690                         goto fail;
691                 }
692                 clk_dm(AT91_TO_CLK_ID(PMC_TYPE_GCK, sam9x60_gck[i].id), c);
693         }
694
695         /* Setup clocks. */
696         ret = at91_clk_setup(sam9x60_clk_setup, ARRAY_SIZE(sam9x60_clk_setup));
697         if (ret)
698                 goto fail;
699
700         return 0;
701
702 fail:
703         for (i = 0; i < ARRAY_SIZE(muxallocs); i++)
704                 kfree(muxallocs[i]);
705
706         for (i = 0; i < ARRAY_SIZE(clkmuxallocs); i++)
707                 kfree(clkmuxallocs[i]);
708
709         return ret;
710 }
711
712 static const struct udevice_id sam9x60_clk_ids[] = {
713         { .compatible = "microchip,sam9x60-pmc" },
714         { /* Sentinel. */ },
715 };
716
717 U_BOOT_DRIVER(at91_sam9x60_pmc) = {
718         .name = "at91-sam9x60-pmc",
719         .id = UCLASS_CLK,
720         .of_match = sam9x60_clk_ids,
721         .ops = &at91_clk_ops,
722         .probe = sam9x60_clk_probe,
723         .flags = DM_FLAG_PRE_RELOC,
724 };
This page took 0.068349 seconds and 4 git commands to generate.