]> Git Repo - J-linux.git/blob - drivers/clk/at91/sam9x7.c
Merge tag 'vfs-6.13-rc7.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs
[J-linux.git] / drivers / clk / at91 / sam9x7.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * SAM9X7 PMC code.
4  *
5  * Copyright (C) 2023 Microchip Technology Inc. and its subsidiaries
6  *
7  * Author: Varshini Rajendran <[email protected]>
8  *
9  */
10 #include <linux/clk.h>
11 #include <linux/clk-provider.h>
12 #include <linux/mfd/syscon.h>
13 #include <linux/slab.h>
14
15 #include <dt-bindings/clock/at91.h>
16
17 #include "pmc.h"
18
19 static DEFINE_SPINLOCK(pmc_pll_lock);
20 static DEFINE_SPINLOCK(mck_lock);
21
22 /**
23  * enum pll_ids - PLL clocks identifiers
24  * @PLL_ID_PLLA:        PLLA identifier
25  * @PLL_ID_UPLL:        UPLL identifier
26  * @PLL_ID_AUDIO:       Audio PLL identifier
27  * @PLL_ID_LVDS:        LVDS PLL identifier
28  * @PLL_ID_PLLA_DIV2:   PLLA DIV2 identifier
29  * @PLL_ID_MAX:         Max PLL Identifier
30  */
31 enum pll_ids {
32         PLL_ID_PLLA,
33         PLL_ID_UPLL,
34         PLL_ID_AUDIO,
35         PLL_ID_LVDS,
36         PLL_ID_PLLA_DIV2,
37         PLL_ID_MAX,
38 };
39
40 /**
41  * enum pll_type - PLL type identifiers
42  * @PLL_TYPE_FRAC:      fractional PLL identifier
43  * @PLL_TYPE_DIV:       divider PLL identifier
44  */
45 enum pll_type {
46         PLL_TYPE_FRAC,
47         PLL_TYPE_DIV,
48 };
49
50 static const struct clk_master_characteristics mck_characteristics = {
51         .output = { .min = 32000000, .max = 266666667 },
52         .divisors = { 1, 2, 4, 3, 5},
53         .have_div3_pres = 1,
54 };
55
56 static const struct clk_master_layout sam9x7_master_layout = {
57         .mask = 0x373,
58         .pres_shift = 4,
59         .offset = 0x28,
60 };
61
62 /* Fractional PLL core output range. */
63 static const struct clk_range plla_core_outputs[] = {
64         { .min = 375000000, .max = 1600000000 },
65 };
66
67 static const struct clk_range upll_core_outputs[] = {
68         { .min = 600000000, .max = 1200000000 },
69 };
70
71 static const struct clk_range lvdspll_core_outputs[] = {
72         { .min = 400000000, .max = 800000000 },
73 };
74
75 static const struct clk_range audiopll_core_outputs[] = {
76         { .min = 400000000, .max = 800000000 },
77 };
78
79 static const struct clk_range plladiv2_core_outputs[] = {
80         { .min = 375000000, .max = 1600000000 },
81 };
82
83 /* Fractional PLL output range. */
84 static const struct clk_range plla_outputs[] = {
85         { .min = 732421, .max = 800000000 },
86 };
87
88 static const struct clk_range upll_outputs[] = {
89         { .min = 300000000, .max = 600000000 },
90 };
91
92 static const struct clk_range lvdspll_outputs[] = {
93         { .min = 10000000, .max = 800000000 },
94 };
95
96 static const struct clk_range audiopll_outputs[] = {
97         { .min = 10000000, .max = 800000000 },
98 };
99
100 static const struct clk_range plladiv2_outputs[] = {
101         { .min = 366210, .max = 400000000 },
102 };
103
104 /* PLL characteristics. */
105 static const struct clk_pll_characteristics plla_characteristics = {
106         .input = { .min = 20000000, .max = 50000000 },
107         .num_output = ARRAY_SIZE(plla_outputs),
108         .output = plla_outputs,
109         .core_output = plla_core_outputs,
110 };
111
112 static const struct clk_pll_characteristics upll_characteristics = {
113         .input = { .min = 20000000, .max = 50000000 },
114         .num_output = ARRAY_SIZE(upll_outputs),
115         .output = upll_outputs,
116         .core_output = upll_core_outputs,
117         .upll = true,
118 };
119
120 static const struct clk_pll_characteristics lvdspll_characteristics = {
121         .input = { .min = 20000000, .max = 50000000 },
122         .num_output = ARRAY_SIZE(lvdspll_outputs),
123         .output = lvdspll_outputs,
124         .core_output = lvdspll_core_outputs,
125 };
126
127 static const struct clk_pll_characteristics audiopll_characteristics = {
128         .input = { .min = 20000000, .max = 50000000 },
129         .num_output = ARRAY_SIZE(audiopll_outputs),
130         .output = audiopll_outputs,
131         .core_output = audiopll_core_outputs,
132 };
133
134 static const struct clk_pll_characteristics plladiv2_characteristics = {
135         .input = { .min = 20000000, .max = 50000000 },
136         .num_output = ARRAY_SIZE(plladiv2_outputs),
137         .output = plladiv2_outputs,
138         .core_output = plladiv2_core_outputs,
139 };
140
141 /* Layout for fractional PLL ID PLLA. */
142 static const struct clk_pll_layout plla_frac_layout = {
143         .mul_mask = GENMASK(31, 24),
144         .frac_mask = GENMASK(21, 0),
145         .mul_shift = 24,
146         .frac_shift = 0,
147         .div2 = 1,
148 };
149
150 /* Layout for fractional PLLs. */
151 static const struct clk_pll_layout pll_frac_layout = {
152         .mul_mask = GENMASK(31, 24),
153         .frac_mask = GENMASK(21, 0),
154         .mul_shift = 24,
155         .frac_shift = 0,
156 };
157
158 /* Layout for DIV PLLs. */
159 static const struct clk_pll_layout pll_divpmc_layout = {
160         .div_mask = GENMASK(7, 0),
161         .endiv_mask = BIT(29),
162         .div_shift = 0,
163         .endiv_shift = 29,
164 };
165
166 /* Layout for DIV PLL ID PLLADIV2. */
167 static const struct clk_pll_layout plladiv2_divpmc_layout = {
168         .div_mask = GENMASK(7, 0),
169         .endiv_mask = BIT(29),
170         .div_shift = 0,
171         .endiv_shift = 29,
172         .div2 = 1,
173 };
174
175 /* Layout for DIVIO dividers. */
176 static const struct clk_pll_layout pll_divio_layout = {
177         .div_mask       = GENMASK(19, 12),
178         .endiv_mask     = BIT(30),
179         .div_shift      = 12,
180         .endiv_shift    = 30,
181 };
182
183 /*
184  * PLL clocks description
185  * @n:          clock name
186  * @p:          clock parent
187  * @l:          clock layout
188  * @t:          clock type
189  * @c:          pll characteristics
190  * @f:          clock flags
191  * @eid:        export index in sam9x7->chws[] array
192  */
193 static const struct {
194         const char *n;
195         const char *p;
196         const struct clk_pll_layout *l;
197         u8 t;
198         const struct clk_pll_characteristics *c;
199         unsigned long f;
200         u8 eid;
201 } sam9x7_plls[][3] = {
202         [PLL_ID_PLLA] = {
203                 {
204                         .n = "plla_fracck",
205                         .p = "mainck",
206                         .l = &plla_frac_layout,
207                         .t = PLL_TYPE_FRAC,
208                         /*
209                          * This feeds plla_divpmcck which feeds CPU. It should
210                          * not be disabled.
211                          */
212                         .f = CLK_IS_CRITICAL | CLK_SET_RATE_GATE,
213                         .c = &plla_characteristics,
214                 },
215
216                 {
217                         .n = "plla_divpmcck",
218                         .p = "plla_fracck",
219                         .l = &pll_divpmc_layout,
220                         .t = PLL_TYPE_DIV,
221                         /* This feeds CPU. It should not be disabled */
222                         .f = CLK_IS_CRITICAL | CLK_SET_RATE_GATE,
223                         .eid = PMC_PLLACK,
224                         .c = &plla_characteristics,
225                 },
226         },
227
228         [PLL_ID_UPLL] = {
229                 {
230                         .n = "upll_fracck",
231                         .p = "main_osc",
232                         .l = &pll_frac_layout,
233                         .t = PLL_TYPE_FRAC,
234                         .f = CLK_SET_RATE_GATE,
235                         .c = &upll_characteristics,
236                 },
237
238                 {
239                         .n = "upll_divpmcck",
240                         .p = "upll_fracck",
241                         .l = &pll_divpmc_layout,
242                         .t = PLL_TYPE_DIV,
243                         .f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE |
244                              CLK_SET_RATE_PARENT,
245                         .eid = PMC_UTMI,
246                         .c = &upll_characteristics,
247                 },
248         },
249
250         [PLL_ID_AUDIO] = {
251                 {
252                         .n = "audiopll_fracck",
253                         .p = "main_osc",
254                         .l = &pll_frac_layout,
255                         .f = CLK_SET_RATE_GATE,
256                         .c = &audiopll_characteristics,
257                         .t = PLL_TYPE_FRAC,
258                 },
259
260                 {
261                         .n = "audiopll_divpmcck",
262                         .p = "audiopll_fracck",
263                         .l = &pll_divpmc_layout,
264                         .f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE |
265                              CLK_SET_RATE_PARENT,
266                         .c = &audiopll_characteristics,
267                         .eid = PMC_AUDIOPMCPLL,
268                         .t = PLL_TYPE_DIV,
269                 },
270
271                 {
272                         .n = "audiopll_diviock",
273                         .p = "audiopll_fracck",
274                         .l = &pll_divio_layout,
275                         .f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE |
276                              CLK_SET_RATE_PARENT,
277                         .c = &audiopll_characteristics,
278                         .eid = PMC_AUDIOIOPLL,
279                         .t = PLL_TYPE_DIV,
280                 },
281         },
282
283         [PLL_ID_LVDS] = {
284                 {
285                         .n = "lvdspll_fracck",
286                         .p = "main_osc",
287                         .l = &pll_frac_layout,
288                         .f = CLK_SET_RATE_GATE,
289                         .c = &lvdspll_characteristics,
290                         .t = PLL_TYPE_FRAC,
291                 },
292
293                 {
294                         .n = "lvdspll_divpmcck",
295                         .p = "lvdspll_fracck",
296                         .l = &pll_divpmc_layout,
297                         .f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE |
298                              CLK_SET_RATE_PARENT,
299                         .c = &lvdspll_characteristics,
300                         .eid = PMC_LVDSPLL,
301                         .t = PLL_TYPE_DIV,
302                 },
303         },
304
305         [PLL_ID_PLLA_DIV2] = {
306                 {
307                         .n = "plla_div2pmcck",
308                         .p = "plla_fracck",
309                         .l = &plladiv2_divpmc_layout,
310                         /*
311                          * This may feed critical parts of the system like timers.
312                          * It should not be disabled.
313                          */
314                         .f = CLK_IS_CRITICAL | CLK_SET_RATE_GATE,
315                         .c = &plladiv2_characteristics,
316                         .eid = PMC_PLLADIV2,
317                         .t = PLL_TYPE_DIV,
318                 },
319         },
320 };
321
322 static const struct clk_programmable_layout sam9x7_programmable_layout = {
323         .pres_mask = 0xff,
324         .pres_shift = 8,
325         .css_mask = 0x1f,
326         .have_slck_mck = 0,
327         .is_pres_direct = 1,
328 };
329
330 static const struct clk_pcr_layout sam9x7_pcr_layout = {
331         .offset = 0x88,
332         .cmd = BIT(31),
333         .gckcss_mask = GENMASK(12, 8),
334         .pid_mask = GENMASK(6, 0),
335 };
336
337 static const struct {
338         char *n;
339         char *p;
340         u8 id;
341         unsigned long flags;
342 } sam9x7_systemck[] = {
343         /*
344          * ddrck feeds DDR controller and is enabled by bootloader thus we need
345          * to keep it enabled in case there is no Linux consumer for it.
346          */
347         { .n = "ddrck",         .p = "masterck_div",    .id = 2,        .flags = CLK_IS_CRITICAL },
348         { .n = "uhpck",         .p = "usbck",           .id = 6 },
349         { .n = "pck0",          .p = "prog0",           .id = 8 },
350         { .n = "pck1",          .p = "prog1",           .id = 9 },
351 };
352
353 /*
354  * Peripheral clocks description
355  * @n:          clock name
356  * @f:          clock flags
357  * @id:         peripheral id
358  */
359 static const struct {
360         char *n;
361         unsigned long f;
362         u8 id;
363 } sam9x7_periphck[] = {
364         { .n = "pioA_clk",      .id = 2, },
365         { .n = "pioB_clk",      .id = 3, },
366         { .n = "pioC_clk",      .id = 4, },
367         { .n = "flex0_clk",     .id = 5, },
368         { .n = "flex1_clk",     .id = 6, },
369         { .n = "flex2_clk",     .id = 7, },
370         { .n = "flex3_clk",     .id = 8, },
371         { .n = "flex6_clk",     .id = 9, },
372         { .n = "flex7_clk",     .id = 10, },
373         { .n = "flex8_clk",     .id = 11, },
374         { .n = "sdmmc0_clk",    .id = 12, },
375         { .n = "flex4_clk",     .id = 13, },
376         { .n = "flex5_clk",     .id = 14, },
377         { .n = "flex9_clk",     .id = 15, },
378         { .n = "flex10_clk",    .id = 16, },
379         { .n = "tcb0_clk",      .id = 17, },
380         { .n = "pwm_clk",       .id = 18, },
381         { .n = "adc_clk",       .id = 19, },
382         { .n = "dma0_clk",      .id = 20, },
383         { .n = "uhphs_clk",     .id = 22, },
384         { .n = "udphs_clk",     .id = 23, },
385         { .n = "macb0_clk",     .id = 24, },
386         { .n = "lcd_clk",       .id = 25, },
387         { .n = "sdmmc1_clk",    .id = 26, },
388         { .n = "ssc_clk",       .id = 28, },
389         { .n = "can0_clk",      .id = 29, },
390         { .n = "can1_clk",      .id = 30, },
391         { .n = "flex11_clk",    .id = 32, },
392         { .n = "flex12_clk",    .id = 33, },
393         { .n = "i2s_clk",       .id = 34, },
394         { .n = "qspi_clk",      .id = 35, },
395         { .n = "gfx2d_clk",     .id = 36, },
396         { .n = "pit64b0_clk",   .id = 37, },
397         { .n = "trng_clk",      .id = 38, },
398         { .n = "aes_clk",       .id = 39, },
399         { .n = "tdes_clk",      .id = 40, },
400         { .n = "sha_clk",       .id = 41, },
401         { .n = "classd_clk",    .id = 42, },
402         { .n = "isi_clk",       .id = 43, },
403         { .n = "pioD_clk",      .id = 44, },
404         { .n = "tcb1_clk",      .id = 45, },
405         { .n = "dbgu_clk",      .id = 47, },
406         /*
407          * mpddr_clk feeds DDR controller and is enabled by bootloader thus we
408          * need to keep it enabled in case there is no Linux consumer for it.
409          */
410         { .n = "mpddr_clk",     .id = 49,       .f = CLK_IS_CRITICAL },
411         { .n = "csi2dc_clk",    .id = 52, },
412         { .n = "csi4l_clk",     .id = 53, },
413         { .n = "dsi4l_clk",     .id = 54, },
414         { .n = "lvdsc_clk",     .id = 56, },
415         { .n = "pit64b1_clk",   .id = 58, },
416         { .n = "puf_clk",       .id = 59, },
417         { .n = "gmactsu_clk",   .id = 67, },
418 };
419
420 /*
421  * Generic clock description
422  * @n:                  clock name
423  * @pp:                 PLL parents
424  * @pp_mux_table:       PLL parents mux table
425  * @r:                  clock output range
426  * @pp_chg_id:          id in parent array of changeable PLL parent
427  * @pp_count:           PLL parents count
428  * @id:                 clock id
429  */
430 static const struct {
431         const char *n;
432         const char *pp[8];
433         const char pp_mux_table[8];
434         struct clk_range r;
435         int pp_chg_id;
436         u8 pp_count;
437         u8 id;
438 } sam9x7_gck[] = {
439         {
440                 .n = "flex0_gclk",
441                 .id = 5,
442                 .pp = { "plla_div2pmcck", },
443                 .pp_mux_table = { 8, },
444                 .pp_count = 1,
445                 .pp_chg_id = INT_MIN,
446         },
447
448         {
449                 .n = "flex1_gclk",
450                 .id = 6,
451                 .pp = { "plla_div2pmcck", },
452                 .pp_mux_table = { 8, },
453                 .pp_count = 1,
454                 .pp_chg_id = INT_MIN,
455         },
456
457         {
458                 .n = "flex2_gclk",
459                 .id = 7,
460                 .pp = { "plla_div2pmcck", },
461                 .pp_mux_table = { 8, },
462                 .pp_count = 1,
463                 .pp_chg_id = INT_MIN,
464         },
465
466         {
467                 .n = "flex3_gclk",
468                 .id = 8,
469                 .pp = { "plla_div2pmcck", },
470                 .pp_mux_table = { 8, },
471                 .pp_count = 1,
472                 .pp_chg_id = INT_MIN,
473         },
474
475         {
476                 .n = "flex6_gclk",
477                 .id = 9,
478                 .pp = { "plla_div2pmcck", },
479                 .pp_mux_table = { 8, },
480                 .pp_count = 1,
481                 .pp_chg_id = INT_MIN,
482         },
483
484         {
485                 .n = "flex7_gclk",
486                 .id = 10,
487                 .pp = { "plla_div2pmcck", },
488                 .pp_mux_table = { 8, },
489                 .pp_count = 1,
490                 .pp_chg_id = INT_MIN,
491         },
492
493         {
494                 .n = "flex8_gclk",
495                 .id = 11,
496                 .pp = { "plla_div2pmcck", },
497                 .pp_mux_table = { 8, },
498                 .pp_count = 1,
499                 .pp_chg_id = INT_MIN,
500         },
501
502         {
503                 .n = "sdmmc0_gclk",
504                 .id = 12,
505                 .r = { .max = 105000000 },
506                 .pp = { "audiopll_divpmcck", "plla_div2pmcck", },
507                 .pp_mux_table = { 6, 8, },
508                 .pp_count = 2,
509                 .pp_chg_id = INT_MIN,
510         },
511
512         {
513                 .n = "flex4_gclk",
514                 .id = 13,
515                 .pp = { "plla_div2pmcck", },
516                 .pp_mux_table = { 8, },
517                 .pp_count = 1,
518                 .pp_chg_id = INT_MIN,
519         },
520
521         {
522                 .n = "flex5_gclk",
523                 .id = 14,
524                 .pp = { "plla_div2pmcck", },
525                 .pp_mux_table = { 8, },
526                 .pp_count = 1,
527                 .pp_chg_id = INT_MIN,
528         },
529
530         {
531                 .n = "flex9_gclk",
532                 .id = 15,
533                 .pp = { "plla_div2pmcck", },
534                 .pp_mux_table = { 8, },
535                 .pp_count = 1,
536                 .pp_chg_id = INT_MIN,
537         },
538
539         {
540                 .n = "flex10_gclk",
541                 .id = 16,
542                 .pp = { "plla_div2pmcck", },
543                 .pp_mux_table = { 8, },
544                 .pp_count = 1,
545                 .pp_chg_id = INT_MIN,
546         },
547
548         {
549                 .n = "tcb0_gclk",
550                 .id = 17,
551                 .pp = { "audiopll_divpmcck", "plla_div2pmcck", },
552                 .pp_mux_table = { 6, 8, },
553                 .pp_count = 2,
554                 .pp_chg_id = INT_MIN,
555         },
556
557         {
558                 .n = "adc_gclk",
559                 .id = 19,
560                 .pp = { "upll_divpmcck", "plla_div2pmcck", },
561                 .pp_mux_table = { 5, 8, },
562                 .pp_count = 2,
563                 .pp_chg_id = INT_MIN,
564         },
565
566         {
567                 .n = "lcd_gclk",
568                 .id = 25,
569                 .r = { .max = 75000000 },
570                 .pp = { "audiopll_divpmcck", "plla_div2pmcck", },
571                 .pp_mux_table = { 6, 8, },
572                 .pp_count = 2,
573                 .pp_chg_id = INT_MIN,
574         },
575
576         {
577                 .n = "sdmmc1_gclk",
578                 .id = 26,
579                 .r = { .max = 105000000 },
580                 .pp = { "audiopll_divpmcck", "plla_div2pmcck", },
581                 .pp_mux_table = { 6, 8, },
582                 .pp_count = 2,
583                 .pp_chg_id = INT_MIN,
584         },
585
586         {
587                 .n = "mcan0_gclk",
588                 .id = 29,
589                 .r = { .max = 80000000 },
590                 .pp = { "upll_divpmcck", "plla_div2pmcck", },
591                 .pp_mux_table = { 5, 8, },
592                 .pp_count = 2,
593                 .pp_chg_id = INT_MIN,
594         },
595
596         {
597                 .n = "mcan1_gclk",
598                 .id = 30,
599                 .r = { .max = 80000000 },
600                 .pp = { "upll_divpmcck", "plla_div2pmcck", },
601                 .pp_mux_table = { 5, 8, },
602                 .pp_count = 2,
603                 .pp_chg_id = INT_MIN,
604         },
605
606         {
607                 .n = "flex11_gclk",
608                 .id = 32,
609                 .pp = { "plla_div2pmcck", },
610                 .pp_mux_table = { 8, },
611                 .pp_count = 1,
612                 .pp_chg_id = INT_MIN,
613         },
614
615         {
616                 .n = "flex12_gclk",
617                 .id = 33,
618                 .pp = { "plla_div2pmcck", },
619                 .pp_mux_table = { 8, },
620                 .pp_count = 1,
621                 .pp_chg_id = INT_MIN,
622         },
623
624         {
625                 .n = "i2s_gclk",
626                 .id = 34,
627                 .r = { .max = 100000000 },
628                 .pp = { "audiopll_divpmcck", "plla_div2pmcck", },
629                 .pp_mux_table = { 6, 8, },
630                 .pp_count = 2,
631                 .pp_chg_id = INT_MIN,
632         },
633
634         {
635                 .n = "qspi_gclk",
636                 .id = 35,
637                 .r = { .max = 200000000 },
638                 .pp = { "audiopll_divpmcck", "plla_div2pmcck", },
639                 .pp_mux_table = { 6, 8, },
640                 .pp_count = 2,
641                 .pp_chg_id = INT_MIN,
642         },
643
644         {
645                 .n = "pit64b0_gclk",
646                 .id = 37,
647                 .pp = { "plla_div2pmcck", },
648                 .pp_mux_table = { 8, },
649                 .pp_count = 1,
650                 .pp_chg_id = INT_MIN,
651         },
652
653         {
654                 .n = "classd_gclk",
655                 .id = 42,
656                 .r = { .max = 100000000 },
657                 .pp = { "audiopll_divpmcck", "plla_div2pmcck", },
658                 .pp_mux_table = { 6, 8, },
659                 .pp_count = 2,
660                 .pp_chg_id = INT_MIN,
661         },
662
663         {
664                 .n = "tcb1_gclk",
665                 .id = 45,
666                 .pp = { "audiopll_divpmcck", "plla_div2pmcck", },
667                 .pp_mux_table = { 6, 8, },
668                 .pp_count = 2,
669                 .pp_chg_id = INT_MIN,
670         },
671
672         {
673                 .n = "dbgu_gclk",
674                 .id = 47,
675                 .pp = { "plla_div2pmcck", },
676                 .pp_mux_table = { 8, },
677                 .pp_count = 1,
678                 .pp_chg_id = INT_MIN,
679         },
680
681         {
682                 .n = "mipiphy_gclk",
683                 .id = 55,
684                 .r = { .max = 27000000 },
685                 .pp = { "plla_div2pmcck", },
686                 .pp_mux_table = { 8, },
687                 .pp_count = 1,
688                 .pp_chg_id = INT_MIN,
689         },
690
691         {
692                 .n = "pit64b1_gclk",
693                 .id = 58,
694                 .pp = { "plla_div2pmcck", },
695                 .pp_mux_table = { 8, },
696                 .pp_count = 1,
697                 .pp_chg_id = INT_MIN,
698         },
699
700         {
701                 .n = "gmac_gclk",
702                 .id = 67,
703                 .pp = { "audiopll_divpmcck", "plla_div2pmcck", },
704                 .pp_mux_table = { 6, 8, },
705                 .pp_count = 2,
706                 .pp_chg_id = INT_MIN,
707         },
708 };
709
710 static void __init sam9x7_pmc_setup(struct device_node *np)
711 {
712         struct clk_range range = CLK_RANGE(0, 0);
713         const char *td_slck_name, *md_slck_name, *mainxtal_name;
714         struct pmc_data *sam9x7_pmc;
715         const char *parent_names[9];
716         void **clk_mux_buffer = NULL;
717         int clk_mux_buffer_size = 0;
718         struct clk_hw *main_osc_hw;
719         struct regmap *regmap;
720         struct clk_hw *hw;
721         int i, j;
722
723         i = of_property_match_string(np, "clock-names", "td_slck");
724         if (i < 0)
725                 return;
726
727         td_slck_name = of_clk_get_parent_name(np, i);
728
729         i = of_property_match_string(np, "clock-names", "md_slck");
730         if (i < 0)
731                 return;
732
733         md_slck_name = of_clk_get_parent_name(np, i);
734
735         i = of_property_match_string(np, "clock-names", "main_xtal");
736         if (i < 0)
737                 return;
738         mainxtal_name = of_clk_get_parent_name(np, i);
739
740         regmap = device_node_to_regmap(np);
741         if (IS_ERR(regmap))
742                 return;
743
744         sam9x7_pmc = pmc_data_allocate(PMC_LVDSPLL + 1,
745                                        nck(sam9x7_systemck),
746                                        nck(sam9x7_periphck),
747                                        nck(sam9x7_gck), 8);
748         if (!sam9x7_pmc)
749                 return;
750
751         clk_mux_buffer = kmalloc(sizeof(void *) *
752                                  (ARRAY_SIZE(sam9x7_gck)),
753                                  GFP_KERNEL);
754         if (!clk_mux_buffer)
755                 goto err_free;
756
757         hw = at91_clk_register_main_rc_osc(regmap, "main_rc_osc", 12000000,
758                                            50000000);
759         if (IS_ERR(hw))
760                 goto err_free;
761
762         hw = at91_clk_register_main_osc(regmap, "main_osc", mainxtal_name, NULL, 0);
763         if (IS_ERR(hw))
764                 goto err_free;
765         main_osc_hw = hw;
766
767         parent_names[0] = "main_rc_osc";
768         parent_names[1] = "main_osc";
769         hw = at91_clk_register_sam9x5_main(regmap, "mainck", parent_names, NULL, 2);
770         if (IS_ERR(hw))
771                 goto err_free;
772
773         sam9x7_pmc->chws[PMC_MAIN] = hw;
774
775         for (i = 0; i < PLL_ID_MAX; i++) {
776                 for (j = 0; j < 3; j++) {
777                         struct clk_hw *parent_hw;
778
779                         if (!sam9x7_plls[i][j].n)
780                                 continue;
781
782                         switch (sam9x7_plls[i][j].t) {
783                         case PLL_TYPE_FRAC:
784                                 if (!strcmp(sam9x7_plls[i][j].p, "mainck"))
785                                         parent_hw = sam9x7_pmc->chws[PMC_MAIN];
786                                 else if (!strcmp(sam9x7_plls[i][j].p, "main_osc"))
787                                         parent_hw = main_osc_hw;
788                                 else
789                                         parent_hw = __clk_get_hw(of_clk_get_by_name
790                                                                  (np, sam9x7_plls[i][j].p));
791
792                                 hw = sam9x60_clk_register_frac_pll(regmap,
793                                                                    &pmc_pll_lock,
794                                                                    sam9x7_plls[i][j].n,
795                                                                    sam9x7_plls[i][j].p,
796                                                                    parent_hw, i,
797                                                                    sam9x7_plls[i][j].c,
798                                                                    sam9x7_plls[i][j].l,
799                                                                    sam9x7_plls[i][j].f);
800                                 break;
801
802                         case PLL_TYPE_DIV:
803                                 hw = sam9x60_clk_register_div_pll(regmap,
804                                                                   &pmc_pll_lock,
805                                                                   sam9x7_plls[i][j].n,
806                                                                   sam9x7_plls[i][j].p, NULL, i,
807                                                                   sam9x7_plls[i][j].c,
808                                                                   sam9x7_plls[i][j].l,
809                                                                   sam9x7_plls[i][j].f, 0);
810                                 break;
811
812                         default:
813                                 continue;
814                         }
815
816                         if (IS_ERR(hw))
817                                 goto err_free;
818
819                         if (sam9x7_plls[i][j].eid)
820                                 sam9x7_pmc->chws[sam9x7_plls[i][j].eid] = hw;
821                 }
822         }
823
824         parent_names[0] = md_slck_name;
825         parent_names[1] = "mainck";
826         parent_names[2] = "plla_divpmcck";
827         parent_names[3] = "upll_divpmcck";
828         hw = at91_clk_register_master_pres(regmap, "masterck_pres", 4,
829                                            parent_names, NULL, &sam9x7_master_layout,
830                                            &mck_characteristics, &mck_lock);
831         if (IS_ERR(hw))
832                 goto err_free;
833
834         hw = at91_clk_register_master_div(regmap, "masterck_div",
835                                           "masterck_pres", NULL, &sam9x7_master_layout,
836                                           &mck_characteristics, &mck_lock,
837                                           CLK_SET_RATE_GATE, 0);
838         if (IS_ERR(hw))
839                 goto err_free;
840
841         sam9x7_pmc->chws[PMC_MCK] = hw;
842
843         parent_names[0] = "plla_divpmcck";
844         parent_names[1] = "upll_divpmcck";
845         parent_names[2] = "main_osc";
846         hw = sam9x60_clk_register_usb(regmap, "usbck", parent_names, 3);
847         if (IS_ERR(hw))
848                 goto err_free;
849
850         parent_names[0] = md_slck_name;
851         parent_names[1] = td_slck_name;
852         parent_names[2] = "mainck";
853         parent_names[3] = "masterck_div";
854         parent_names[4] = "plla_divpmcck";
855         parent_names[5] = "upll_divpmcck";
856         parent_names[6] = "audiopll_divpmcck";
857         for (i = 0; i < 2; i++) {
858                 char name[6];
859
860                 snprintf(name, sizeof(name), "prog%d", i);
861
862                 hw = at91_clk_register_programmable(regmap, name,
863                                                     parent_names, NULL, 7, i,
864                                                     &sam9x7_programmable_layout,
865                                                     NULL);
866                 if (IS_ERR(hw))
867                         goto err_free;
868
869                 sam9x7_pmc->pchws[i] = hw;
870         }
871
872         for (i = 0; i < ARRAY_SIZE(sam9x7_systemck); i++) {
873                 hw = at91_clk_register_system(regmap, sam9x7_systemck[i].n,
874                                               sam9x7_systemck[i].p, NULL,
875                                               sam9x7_systemck[i].id,
876                                               sam9x7_systemck[i].flags);
877                 if (IS_ERR(hw))
878                         goto err_free;
879
880                 sam9x7_pmc->shws[sam9x7_systemck[i].id] = hw;
881         }
882
883         for (i = 0; i < ARRAY_SIZE(sam9x7_periphck); i++) {
884                 hw = at91_clk_register_sam9x5_peripheral(regmap, &pmc_pcr_lock,
885                                                          &sam9x7_pcr_layout,
886                                                          sam9x7_periphck[i].n,
887                                                          "masterck_div", NULL,
888                                                          sam9x7_periphck[i].id,
889                                                          &range, INT_MIN,
890                                                          sam9x7_periphck[i].f);
891                 if (IS_ERR(hw))
892                         goto err_free;
893
894                 sam9x7_pmc->phws[sam9x7_periphck[i].id] = hw;
895         }
896
897         parent_names[0] = md_slck_name;
898         parent_names[1] = td_slck_name;
899         parent_names[2] = "mainck";
900         parent_names[3] = "masterck_div";
901         for (i = 0; i < ARRAY_SIZE(sam9x7_gck); i++) {
902                 u8 num_parents = 4 + sam9x7_gck[i].pp_count;
903                 u32 *mux_table;
904
905                 mux_table = kmalloc_array(num_parents, sizeof(*mux_table),
906                                           GFP_KERNEL);
907                 if (!mux_table)
908                         goto err_free;
909
910                 PMC_INIT_TABLE(mux_table, 4);
911                 PMC_FILL_TABLE(&mux_table[4], sam9x7_gck[i].pp_mux_table,
912                                sam9x7_gck[i].pp_count);
913                 PMC_FILL_TABLE(&parent_names[4], sam9x7_gck[i].pp,
914                                sam9x7_gck[i].pp_count);
915
916                 hw = at91_clk_register_generated(regmap, &pmc_pcr_lock,
917                                                  &sam9x7_pcr_layout,
918                                                  sam9x7_gck[i].n,
919                                                  parent_names, NULL, mux_table,
920                                                  num_parents,
921                                                  sam9x7_gck[i].id,
922                                                  &sam9x7_gck[i].r,
923                                                  sam9x7_gck[i].pp_chg_id);
924                 if (IS_ERR(hw))
925                         goto err_free;
926
927                 sam9x7_pmc->ghws[sam9x7_gck[i].id] = hw;
928                 clk_mux_buffer[clk_mux_buffer_size++] = mux_table;
929         }
930
931         of_clk_add_hw_provider(np, of_clk_hw_pmc_get, sam9x7_pmc);
932         kfree(clk_mux_buffer);
933
934         return;
935
936 err_free:
937         if (clk_mux_buffer) {
938                 for (i = 0; i < clk_mux_buffer_size; i++)
939                         kfree(clk_mux_buffer[i]);
940                 kfree(clk_mux_buffer);
941         }
942         kfree(sam9x7_pmc);
943 }
944
945 /* Some clks are used for a clocksource */
946 CLK_OF_DECLARE(sam9x7_pmc, "microchip,sam9x7-pmc", sam9x7_pmc_setup);
This page took 0.081964 seconds and 4 git commands to generate.