clk: at91: sama7g5: allow SYS and CPU PLLs to be exported and referenced in DT
[linux-2.6-microblaze.git] / drivers / clk / at91 / sama7g5.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * SAMA7G5 PMC code.
4  *
5  * Copyright (C) 2020 Microchip Technology Inc. and its subsidiaries
6  *
7  * Author: Claudiu Beznea <claudiu.beznea@microchip.com>
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 #define SAMA7G5_INIT_TABLE(_table, _count)              \
20         do {                                            \
21                 u8 _i;                                  \
22                 for (_i = 0; _i < (_count); _i++)       \
23                         (_table)[_i] = _i;              \
24         } while (0)
25
26 #define SAMA7G5_FILL_TABLE(_to, _from, _count)          \
27         do {                                            \
28                 u8 _i;                                  \
29                 for (_i = 0; _i < (_count); _i++) {     \
30                         (_to)[_i] = (_from)[_i];        \
31                 }                                       \
32         } while (0)
33
34 static DEFINE_SPINLOCK(pmc_pll_lock);
35 static DEFINE_SPINLOCK(pmc_mckX_lock);
36
37 /**
38  * PLL clocks identifiers
39  * @PLL_ID_CPU:         CPU PLL identifier
40  * @PLL_ID_SYS:         System PLL identifier
41  * @PLL_ID_DDR:         DDR PLL identifier
42  * @PLL_ID_IMG:         Image subsystem PLL identifier
43  * @PLL_ID_BAUD:        Baud PLL identifier
44  * @PLL_ID_AUDIO:       Audio PLL identifier
45  * @PLL_ID_ETH:         Ethernet PLL identifier
46  */
47 enum pll_ids {
48         PLL_ID_CPU,
49         PLL_ID_SYS,
50         PLL_ID_DDR,
51         PLL_ID_IMG,
52         PLL_ID_BAUD,
53         PLL_ID_AUDIO,
54         PLL_ID_ETH,
55         PLL_ID_MAX,
56 };
57
58 /**
59  * PLL type identifiers
60  * @PLL_TYPE_FRAC:      fractional PLL identifier
61  * @PLL_TYPE_DIV:       divider PLL identifier
62  */
63 enum pll_type {
64         PLL_TYPE_FRAC,
65         PLL_TYPE_DIV,
66 };
67
68 /* Layout for fractional PLLs. */
69 static const struct clk_pll_layout pll_layout_frac = {
70         .mul_mask       = GENMASK(31, 24),
71         .frac_mask      = GENMASK(21, 0),
72         .mul_shift      = 24,
73         .frac_shift     = 0,
74 };
75
76 /* Layout for DIVPMC dividers. */
77 static const struct clk_pll_layout pll_layout_divpmc = {
78         .div_mask       = GENMASK(7, 0),
79         .endiv_mask     = BIT(29),
80         .div_shift      = 0,
81         .endiv_shift    = 29,
82 };
83
84 /* Layout for DIVIO dividers. */
85 static const struct clk_pll_layout pll_layout_divio = {
86         .div_mask       = GENMASK(19, 12),
87         .endiv_mask     = BIT(30),
88         .div_shift      = 12,
89         .endiv_shift    = 30,
90 };
91
92 /**
93  * PLL clocks description
94  * @n:          clock name
95  * @p:          clock parent
96  * @l:          clock layout
97  * @t:          clock type
98  * @f:          true if clock is critical and cannot be disabled
99  * @eid:        export index in sama7g5->chws[] array
100  */
101 static const struct {
102         const char *n;
103         const char *p;
104         const struct clk_pll_layout *l;
105         u8 t;
106         u8 c;
107         u8 eid;
108 } sama7g5_plls[][PLL_ID_MAX] = {
109         [PLL_ID_CPU] = {
110                 { .n = "cpupll_fracck",
111                   .p = "mainck",
112                   .l = &pll_layout_frac,
113                   .t = PLL_TYPE_FRAC,
114                   .c = 1, },
115
116                 { .n = "cpupll_divpmcck",
117                   .p = "cpupll_fracck",
118                   .l = &pll_layout_divpmc,
119                   .t = PLL_TYPE_DIV,
120                   .c = 1,
121                   .eid = PMC_CPUPLL, },
122         },
123
124         [PLL_ID_SYS] = {
125                 { .n = "syspll_fracck",
126                   .p = "mainck",
127                   .l = &pll_layout_frac,
128                   .t = PLL_TYPE_FRAC,
129                   .c = 1, },
130
131                 { .n = "syspll_divpmcck",
132                   .p = "syspll_fracck",
133                   .l = &pll_layout_divpmc,
134                   .t = PLL_TYPE_DIV,
135                   .c = 1,
136                   .eid = PMC_SYSPLL, },
137         },
138
139         [PLL_ID_DDR] = {
140                 { .n = "ddrpll_fracck",
141                   .p = "mainck",
142                   .l = &pll_layout_frac,
143                   .t = PLL_TYPE_FRAC,
144                   .c = 1, },
145
146                 { .n = "ddrpll_divpmcck",
147                   .p = "ddrpll_fracck",
148                   .l = &pll_layout_divpmc,
149                   .t = PLL_TYPE_DIV,
150                   .c = 1, },
151         },
152
153         [PLL_ID_IMG] = {
154                 { .n = "imgpll_fracck",
155                   .p = "mainck",
156                   .l = &pll_layout_frac,
157                   .t = PLL_TYPE_FRAC, },
158
159                 { .n = "imgpll_divpmcck",
160                   .p = "imgpll_fracck",
161                   .l = &pll_layout_divpmc,
162                   .t = PLL_TYPE_DIV, },
163         },
164
165         [PLL_ID_BAUD] = {
166                 { .n = "baudpll_fracck",
167                   .p = "mainck",
168                   .l = &pll_layout_frac,
169                   .t = PLL_TYPE_FRAC, },
170
171                 { .n = "baudpll_divpmcck",
172                   .p = "baudpll_fracck",
173                   .l = &pll_layout_divpmc,
174                   .t = PLL_TYPE_DIV, },
175         },
176
177         [PLL_ID_AUDIO] = {
178                 { .n = "audiopll_fracck",
179                   .p = "main_xtal",
180                   .l = &pll_layout_frac,
181                   .t = PLL_TYPE_FRAC, },
182
183                 { .n = "audiopll_divpmcck",
184                   .p = "audiopll_fracck",
185                   .l = &pll_layout_divpmc,
186                   .t = PLL_TYPE_DIV,
187                   .eid = PMC_AUDIOPMCPLL, },
188
189                 { .n = "audiopll_diviock",
190                   .p = "audiopll_fracck",
191                   .l = &pll_layout_divio,
192                   .t = PLL_TYPE_DIV,
193                   .eid = PMC_AUDIOIOPLL, },
194         },
195
196         [PLL_ID_ETH] = {
197                 { .n = "ethpll_fracck",
198                   .p = "main_xtal",
199                   .l = &pll_layout_frac,
200                   .t = PLL_TYPE_FRAC, },
201
202                 { .n = "ethpll_divpmcck",
203                   .p = "ethpll_fracck",
204                   .l = &pll_layout_divpmc,
205                   .t = PLL_TYPE_DIV, },
206         },
207 };
208
209 /**
210  * Master clock (MCK[1..4]) description
211  * @n:                  clock name
212  * @ep:                 extra parents names array
213  * @ep_chg_chg_id:      index in parents array that specifies the changeable
214  *                      parent
215  * @ep_count:           extra parents count
216  * @ep_mux_table:       mux table for extra parents
217  * @id:                 clock id
218  * @c:                  true if clock is critical and cannot be disabled
219  */
220 static const struct {
221         const char *n;
222         const char *ep[4];
223         int ep_chg_id;
224         u8 ep_count;
225         u8 ep_mux_table[4];
226         u8 id;
227         u8 c;
228 } sama7g5_mckx[] = {
229         { .n = "mck1",
230           .id = 1,
231           .ep = { "syspll_divpmcck", },
232           .ep_mux_table = { 5, },
233           .ep_count = 1,
234           .ep_chg_id = INT_MIN,
235           .c = 1, },
236
237         { .n = "mck2",
238           .id = 2,
239           .ep = { "ddrpll_divpmcck", },
240           .ep_mux_table = { 6, },
241           .ep_count = 1,
242           .ep_chg_id = INT_MIN,
243           .c = 1, },
244
245         { .n = "mck3",
246           .id = 3,
247           .ep = { "syspll_divpmcck", "ddrpll_divpmcck", "imgpll_divpmcck", },
248           .ep_mux_table = { 5, 6, 7, },
249           .ep_count = 3,
250           .ep_chg_id = 6, },
251
252         { .n = "mck4",
253           .id = 4,
254           .ep = { "syspll_divpmcck", },
255           .ep_mux_table = { 5, },
256           .ep_count = 1,
257           .ep_chg_id = INT_MIN,
258           .c = 1, },
259 };
260
261 /**
262  * System clock description
263  * @n:  clock name
264  * @p:  clock parent name
265  * @id: clock id
266  */
267 static const struct {
268         const char *n;
269         const char *p;
270         u8 id;
271 } sama7g5_systemck[] = {
272         { .n = "pck0",          .p = "prog0", .id = 8, },
273         { .n = "pck1",          .p = "prog1", .id = 9, },
274         { .n = "pck2",          .p = "prog2", .id = 10, },
275         { .n = "pck3",          .p = "prog3", .id = 11, },
276         { .n = "pck4",          .p = "prog4", .id = 12, },
277         { .n = "pck5",          .p = "prog5", .id = 13, },
278         { .n = "pck6",          .p = "prog6", .id = 14, },
279         { .n = "pck7",          .p = "prog7", .id = 15, },
280 };
281
282 /* Mux table for programmable clocks. */
283 static u32 sama7g5_prog_mux_table[] = { 0, 1, 2, 3, 5, 6, 7, 8, 9, 10, };
284
285 /**
286  * Peripheral clock description
287  * @n:          clock name
288  * @p:          clock parent name
289  * @r:          clock range values
290  * @id:         clock id
291  * @chgp:       index in parent array of the changeable parent
292  */
293 static const struct {
294         const char *n;
295         const char *p;
296         struct clk_range r;
297         u8 chgp;
298         u8 id;
299 } sama7g5_periphck[] = {
300         { .n = "pioA_clk",      .p = "mck0", .id = 11, },
301         { .n = "sfr_clk",       .p = "mck1", .id = 19, },
302         { .n = "hsmc_clk",      .p = "mck1", .id = 21, },
303         { .n = "xdmac0_clk",    .p = "mck1", .id = 22, },
304         { .n = "xdmac1_clk",    .p = "mck1", .id = 23, },
305         { .n = "xdmac2_clk",    .p = "mck1", .id = 24, },
306         { .n = "acc_clk",       .p = "mck1", .id = 25, },
307         { .n = "aes_clk",       .p = "mck1", .id = 27, },
308         { .n = "tzaesbasc_clk", .p = "mck1", .id = 28, },
309         { .n = "asrc_clk",      .p = "mck1", .id = 30, .r = { .max = 200000000, }, },
310         { .n = "cpkcc_clk",     .p = "mck0", .id = 32, },
311         { .n = "csi_clk",       .p = "mck3", .id = 33, .r = { .max = 266000000, }, .chgp = 1, },
312         { .n = "csi2dc_clk",    .p = "mck3", .id = 34, .r = { .max = 266000000, }, .chgp = 1, },
313         { .n = "eic_clk",       .p = "mck1", .id = 37, },
314         { .n = "flex0_clk",     .p = "mck1", .id = 38, },
315         { .n = "flex1_clk",     .p = "mck1", .id = 39, },
316         { .n = "flex2_clk",     .p = "mck1", .id = 40, },
317         { .n = "flex3_clk",     .p = "mck1", .id = 41, },
318         { .n = "flex4_clk",     .p = "mck1", .id = 42, },
319         { .n = "flex5_clk",     .p = "mck1", .id = 43, },
320         { .n = "flex6_clk",     .p = "mck1", .id = 44, },
321         { .n = "flex7_clk",     .p = "mck1", .id = 45, },
322         { .n = "flex8_clk",     .p = "mck1", .id = 46, },
323         { .n = "flex9_clk",     .p = "mck1", .id = 47, },
324         { .n = "flex10_clk",    .p = "mck1", .id = 48, },
325         { .n = "flex11_clk",    .p = "mck1", .id = 49, },
326         { .n = "gmac0_clk",     .p = "mck1", .id = 51, },
327         { .n = "gmac1_clk",     .p = "mck1", .id = 52, },
328         { .n = "icm_clk",       .p = "mck1", .id = 55, },
329         { .n = "isc_clk",       .p = "mck3", .id = 56, .r = { .max = 266000000, }, .chgp = 1, },
330         { .n = "i2smcc0_clk",   .p = "mck1", .id = 57, .r = { .max = 200000000, }, },
331         { .n = "i2smcc1_clk",   .p = "mck1", .id = 58, .r = { .max = 200000000, }, },
332         { .n = "matrix_clk",    .p = "mck1", .id = 60, },
333         { .n = "mcan0_clk",     .p = "mck1", .id = 61, .r = { .max = 200000000, }, },
334         { .n = "mcan1_clk",     .p = "mck1", .id = 62, .r = { .max = 200000000, }, },
335         { .n = "mcan2_clk",     .p = "mck1", .id = 63, .r = { .max = 200000000, }, },
336         { .n = "mcan3_clk",     .p = "mck1", .id = 64, .r = { .max = 200000000, }, },
337         { .n = "mcan4_clk",     .p = "mck1", .id = 65, .r = { .max = 200000000, }, },
338         { .n = "mcan5_clk",     .p = "mck1", .id = 66, .r = { .max = 200000000, }, },
339         { .n = "pdmc0_clk",     .p = "mck1", .id = 68, .r = { .max = 200000000, }, },
340         { .n = "pdmc1_clk",     .p = "mck1", .id = 69, .r = { .max = 200000000, }, },
341         { .n = "pit64b0_clk",   .p = "mck1", .id = 70, },
342         { .n = "pit64b1_clk",   .p = "mck1", .id = 71, },
343         { .n = "pit64b2_clk",   .p = "mck1", .id = 72, },
344         { .n = "pit64b3_clk",   .p = "mck1", .id = 73, },
345         { .n = "pit64b4_clk",   .p = "mck1", .id = 74, },
346         { .n = "pit64b5_clk",   .p = "mck1", .id = 75, },
347         { .n = "pwm_clk",       .p = "mck1", .id = 77, },
348         { .n = "qspi0_clk",     .p = "mck1", .id = 78, },
349         { .n = "qspi1_clk",     .p = "mck1", .id = 79, },
350         { .n = "sdmmc0_clk",    .p = "mck1", .id = 80, },
351         { .n = "sdmmc1_clk",    .p = "mck1", .id = 81, },
352         { .n = "sdmmc2_clk",    .p = "mck1", .id = 82, },
353         { .n = "sha_clk",       .p = "mck1", .id = 83, },
354         { .n = "spdifrx_clk",   .p = "mck1", .id = 84, .r = { .max = 200000000, }, },
355         { .n = "spdiftx_clk",   .p = "mck1", .id = 85, .r = { .max = 200000000, }, },
356         { .n = "ssc0_clk",      .p = "mck1", .id = 86, .r = { .max = 200000000, }, },
357         { .n = "ssc1_clk",      .p = "mck1", .id = 87, .r = { .max = 200000000, }, },
358         { .n = "tcb0_ch0_clk",  .p = "mck1", .id = 88, .r = { .max = 200000000, }, },
359         { .n = "tcb0_ch1_clk",  .p = "mck1", .id = 89, .r = { .max = 200000000, }, },
360         { .n = "tcb0_ch2_clk",  .p = "mck1", .id = 90, .r = { .max = 200000000, }, },
361         { .n = "tcb1_ch0_clk",  .p = "mck1", .id = 91, .r = { .max = 200000000, }, },
362         { .n = "tcb1_ch1_clk",  .p = "mck1", .id = 92, .r = { .max = 200000000, }, },
363         { .n = "tcb1_ch2_clk",  .p = "mck1", .id = 93, .r = { .max = 200000000, }, },
364         { .n = "tcpca_clk",     .p = "mck1", .id = 94, },
365         { .n = "tcpcb_clk",     .p = "mck1", .id = 95, },
366         { .n = "tdes_clk",      .p = "mck1", .id = 96, },
367         { .n = "trng_clk",      .p = "mck1", .id = 97, },
368         { .n = "udphsa_clk",    .p = "mck1", .id = 104, },
369         { .n = "udphsb_clk",    .p = "mck1", .id = 105, },
370         { .n = "uhphs_clk",     .p = "mck1", .id = 106, },
371 };
372
373 /**
374  * Generic clock description
375  * @n:                  clock name
376  * @pp:                 PLL parents
377  * @pp_mux_table:       PLL parents mux table
378  * @r:                  clock output range
379  * @pp_chg_id:          id in parrent array of changeable PLL parent
380  * @pp_count:           PLL parents count
381  * @id:                 clock id
382  */
383 static const struct {
384         const char *n;
385         const char *pp[8];
386         const char pp_mux_table[8];
387         struct clk_range r;
388         int pp_chg_id;
389         u8 pp_count;
390         u8 id;
391 } sama7g5_gck[] = {
392         { .n  = "adc_gclk",
393           .id = 26,
394           .r = { .max = 100000000, },
395           .pp = { "syspll_divpmcck", "imgpll_divpmcck", "audiopll_divpmcck", },
396           .pp_mux_table = { 5, 7, 9, },
397           .pp_count = 3,
398           .pp_chg_id = INT_MIN, },
399
400         { .n  = "asrc_gclk",
401           .id = 30,
402           .r = { .max = 200000000 },
403           .pp = { "audiopll_divpmcck", },
404           .pp_mux_table = { 9, },
405           .pp_count = 1,
406           .pp_chg_id = 4, },
407
408         { .n  = "csi_gclk",
409           .id = 33,
410           .r = { .max = 27000000  },
411           .pp = { "ddrpll_divpmcck", "imgpll_divpmcck", },
412           .pp_mux_table = { 6, 7, },
413           .pp_count = 2,
414           .pp_chg_id = INT_MIN, },
415
416         { .n  = "flex0_gclk",
417           .id = 38,
418           .r = { .max = 200000000 },
419           .pp = { "syspll_divpmcck", "baudpll_divpmcck", },
420           .pp_mux_table = { 5, 8, },
421           .pp_count = 2,
422           .pp_chg_id = INT_MIN, },
423
424         { .n  = "flex1_gclk",
425           .id = 39,
426           .r = { .max = 200000000 },
427           .pp = { "syspll_divpmcck", "baudpll_divpmcck", },
428           .pp_mux_table = { 5, 8, },
429           .pp_count = 2,
430           .pp_chg_id = INT_MIN, },
431
432         { .n  = "flex2_gclk",
433           .id = 40,
434           .r = { .max = 200000000 },
435           .pp = { "syspll_divpmcck", "baudpll_divpmcck", },
436           .pp_mux_table = { 5, 8, },
437           .pp_count = 2,
438           .pp_chg_id = INT_MIN, },
439
440         { .n  = "flex3_gclk",
441           .id = 41,
442           .r = { .max = 200000000 },
443           .pp = { "syspll_divpmcck", "baudpll_divpmcck", },
444           .pp_mux_table = { 5, 8, },
445           .pp_count = 2,
446           .pp_chg_id = INT_MIN, },
447
448         { .n  = "flex4_gclk",
449           .id = 42,
450           .r = { .max = 200000000 },
451           .pp = { "syspll_divpmcck", "baudpll_divpmcck", },
452           .pp_mux_table = { 5, 8, },
453           .pp_count = 2,
454           .pp_chg_id = INT_MIN, },
455
456         { .n  = "flex5_gclk",
457           .id = 43,
458           .r = { .max = 200000000 },
459           .pp = { "syspll_divpmcck", "baudpll_divpmcck", },
460           .pp_mux_table = { 5, 8, },
461           .pp_count = 2,
462           .pp_chg_id = INT_MIN, },
463
464         { .n  = "flex6_gclk",
465           .id = 44,
466           .r = { .max = 200000000 },
467           .pp = { "syspll_divpmcck", "baudpll_divpmcck", },
468           .pp_mux_table = { 5, 8, },
469           .pp_count = 2,
470           .pp_chg_id = INT_MIN, },
471
472         { .n  = "flex7_gclk",
473           .id = 45,
474           .r = { .max = 200000000 },
475           .pp = { "syspll_divpmcck", "baudpll_divpmcck", },
476           .pp_mux_table = { 5, 8, },
477           .pp_count = 2,
478           .pp_chg_id = INT_MIN, },
479
480         { .n  = "flex8_gclk",
481           .id = 46,
482           .r = { .max = 200000000 },
483           .pp = { "syspll_divpmcck", "baudpll_divpmcck", },
484           .pp_mux_table = { 5, 8, },
485           .pp_count = 2,
486           .pp_chg_id = INT_MIN, },
487
488         { .n  = "flex9_gclk",
489           .id = 47,
490           .r = { .max = 200000000 },
491           .pp = { "syspll_divpmcck", "baudpll_divpmcck", },
492           .pp_mux_table = { 5, 8, },
493           .pp_count = 2,
494           .pp_chg_id = INT_MIN, },
495
496         { .n  = "flex10_gclk",
497           .id = 48,
498           .r = { .max = 200000000 },
499           .pp = { "syspll_divpmcck", "baudpll_divpmcck", },
500           .pp_mux_table = { 5, 8, },
501           .pp_count = 2,
502           .pp_chg_id = INT_MIN, },
503
504         { .n  = "flex11_gclk",
505           .id = 49,
506           .r = { .max = 200000000 },
507           .pp = { "syspll_divpmcck", "baudpll_divpmcck", },
508           .pp_mux_table = { 5, 8, },
509           .pp_count = 2,
510           .pp_chg_id = INT_MIN, },
511
512         { .n  = "gmac0_gclk",
513           .id = 51,
514           .r = { .max = 125000000 },
515           .pp = { "ethpll_divpmcck", },
516           .pp_mux_table = { 10, },
517           .pp_count = 1,
518           .pp_chg_id = 4, },
519
520         { .n  = "gmac1_gclk",
521           .id = 52,
522           .r = { .max = 50000000  },
523           .pp = { "ethpll_divpmcck", },
524           .pp_mux_table = { 10, },
525           .pp_count = 1,
526           .pp_chg_id = INT_MIN, },
527
528         { .n  = "gmac0_tsu_gclk",
529           .id = 53,
530           .r = { .max = 300000000 },
531           .pp = { "audiopll_divpmcck", "ethpll_divpmcck", },
532           .pp_mux_table = { 9, 10, },
533           .pp_count = 2,
534           .pp_chg_id = INT_MIN, },
535
536         { .n  = "gmac1_tsu_gclk",
537           .id = 54,
538           .r = { .max = 300000000 },
539           .pp = { "audiopll_divpmcck", "ethpll_divpmcck", },
540           .pp_mux_table = { 9, 10, },
541           .pp_count = 2,
542           .pp_chg_id = INT_MIN, },
543
544         { .n  = "i2smcc0_gclk",
545           .id = 57,
546           .r = { .max = 100000000 },
547           .pp = { "syspll_divpmcck", "audiopll_divpmcck", },
548           .pp_mux_table = { 5, 9, },
549           .pp_count = 2,
550           .pp_chg_id = 5, },
551
552         { .n  = "i2smcc1_gclk",
553           .id = 58,
554           .r = { .max = 100000000 },
555           .pp = { "syspll_divpmcck", "audiopll_divpmcck", },
556           .pp_mux_table = { 5, 9, },
557           .pp_count = 2,
558           .pp_chg_id = 5, },
559
560         { .n  = "mcan0_gclk",
561           .id = 61,
562           .r = { .max = 200000000 },
563           .pp = { "syspll_divpmcck", "baudpll_divpmcck", },
564           .pp_mux_table = { 5, 8, },
565           .pp_count = 2,
566           .pp_chg_id = INT_MIN, },
567
568         { .n  = "mcan1_gclk",
569           .id = 62,
570           .r = { .max = 200000000 },
571           .pp = { "syspll_divpmcck", "baudpll_divpmcck", },
572           .pp_mux_table = { 5, 8, },
573           .pp_count = 2,
574           .pp_chg_id = INT_MIN, },
575
576         { .n  = "mcan2_gclk",
577           .id = 63,
578           .r = { .max = 200000000 },
579           .pp = { "syspll_divpmcck", "baudpll_divpmcck", },
580           .pp_mux_table = { 5, 8, },
581           .pp_count = 2,
582           .pp_chg_id = INT_MIN, },
583
584         { .n  = "mcan3_gclk",
585           .id = 64,
586           .r = { .max = 200000000 },
587           .pp = { "syspll_divpmcck", "baudpll_divpmcck", },
588           .pp_mux_table = { 5, 8, },
589           .pp_count = 2,
590           .pp_chg_id = INT_MIN, },
591
592         { .n  = "mcan4_gclk",
593           .id = 65,
594           .r = { .max = 200000000 },
595           .pp = { "syspll_divpmcck", "baudpll_divpmcck", },
596           .pp_mux_table = { 5, 8, },
597           .pp_count = 2,
598           .pp_chg_id = INT_MIN, },
599
600         { .n  = "mcan5_gclk",
601           .id = 66,
602           .r = { .max = 200000000 },
603           .pp = { "syspll_divpmcck", "baudpll_divpmcck", },
604           .pp_mux_table = { 5, 8, },
605           .pp_count = 2,
606           .pp_chg_id = INT_MIN, },
607
608         { .n  = "pdmc0_gclk",
609           .id = 68,
610           .r = { .max = 50000000  },
611           .pp = { "syspll_divpmcck", "baudpll_divpmcck", },
612           .pp_mux_table = { 5, 8, },
613           .pp_count = 2,
614           .pp_chg_id = INT_MIN, },
615
616         { .n  = "pdmc1_gclk",
617           .id = 69,
618           .r = { .max = 50000000, },
619           .pp = { "syspll_divpmcck", "baudpll_divpmcck", },
620           .pp_mux_table = { 5, 8, },
621           .pp_count = 2,
622           .pp_chg_id = INT_MIN, },
623
624         { .n  = "pit64b0_gclk",
625           .id = 70,
626           .r = { .max = 200000000 },
627           .pp = { "syspll_divpmcck", "imgpll_divpmcck", "baudpll_divpmcck",
628                   "audiopll_divpmcck", "ethpll_divpmcck", },
629           .pp_mux_table = { 5, 7, 8, 9, 10, },
630           .pp_count = 5,
631           .pp_chg_id = INT_MIN, },
632
633         { .n  = "pit64b1_gclk",
634           .id = 71,
635           .r = { .max = 200000000 },
636           .pp = { "syspll_divpmcck", "imgpll_divpmcck", "baudpll_divpmcck",
637                   "audiopll_divpmcck", "ethpll_divpmcck", },
638           .pp_mux_table = { 5, 7, 8, 9, 10, },
639           .pp_count = 5,
640           .pp_chg_id = INT_MIN, },
641
642         { .n  = "pit64b2_gclk",
643           .id = 72,
644           .r = { .max = 200000000 },
645           .pp = { "syspll_divpmcck", "imgpll_divpmcck", "baudpll_divpmcck",
646                   "audiopll_divpmcck", "ethpll_divpmcck", },
647           .pp_mux_table = { 5, 7, 8, 9, 10, },
648           .pp_count = 5,
649           .pp_chg_id = INT_MIN, },
650
651         { .n  = "pit64b3_gclk",
652           .id = 73,
653           .r = { .max = 200000000 },
654           .pp = { "syspll_divpmcck", "imgpll_divpmcck", "baudpll_divpmcck",
655                   "audiopll_divpmcck", "ethpll_divpmcck", },
656           .pp_mux_table = { 5, 7, 8, 9, 10, },
657           .pp_count = 5,
658           .pp_chg_id = INT_MIN, },
659
660         { .n  = "pit64b4_gclk",
661           .id = 74,
662           .r = { .max = 200000000 },
663           .pp = { "syspll_divpmcck", "imgpll_divpmcck", "baudpll_divpmcck",
664                   "audiopll_divpmcck", "ethpll_divpmcck", },
665           .pp_mux_table = { 5, 7, 8, 9, 10, },
666           .pp_count = 5,
667           .pp_chg_id = INT_MIN, },
668
669         { .n  = "pit64b5_gclk",
670           .id = 75,
671           .r = { .max = 200000000 },
672           .pp = { "syspll_divpmcck", "imgpll_divpmcck", "baudpll_divpmcck",
673                   "audiopll_divpmcck", "ethpll_divpmcck", },
674           .pp_mux_table = { 5, 7, 8, 9, 10, },
675           .pp_count = 5,
676           .pp_chg_id = INT_MIN, },
677
678         { .n  = "qspi0_gclk",
679           .id = 78,
680           .r = { .max = 200000000 },
681           .pp = { "syspll_divpmcck", "baudpll_divpmcck", },
682           .pp_mux_table = { 5, 8, },
683           .pp_count = 2,
684           .pp_chg_id = INT_MIN, },
685
686         { .n  = "qspi1_gclk",
687           .id = 79,
688           .r = { .max = 200000000 },
689           .pp = { "syspll_divpmcck", "baudpll_divpmcck", },
690           .pp_mux_table = { 5, 8, },
691           .pp_count = 2,
692           .pp_chg_id = INT_MIN, },
693
694         { .n  = "sdmmc0_gclk",
695           .id = 80,
696           .r = { .max = 208000000 },
697           .pp = { "syspll_divpmcck", "baudpll_divpmcck", },
698           .pp_mux_table = { 5, 8, },
699           .pp_count = 2,
700           .pp_chg_id = 5, },
701
702         { .n  = "sdmmc1_gclk",
703           .id = 81,
704           .r = { .max = 208000000 },
705           .pp = { "syspll_divpmcck", "baudpll_divpmcck", },
706           .pp_mux_table = { 5, 8, },
707           .pp_count = 2,
708           .pp_chg_id = 5, },
709
710         { .n  = "sdmmc2_gclk",
711           .id = 82,
712           .r = { .max = 208000000 },
713           .pp = { "syspll_divpmcck", "baudpll_divpmcck", },
714           .pp_mux_table = { 5, 8, },
715           .pp_count = 2,
716           .pp_chg_id = 5, },
717
718         { .n  = "spdifrx_gclk",
719           .id = 84,
720           .r = { .max = 150000000 },
721           .pp = { "syspll_divpmcck", "audiopll_divpmcck", },
722           .pp_mux_table = { 5, 9, },
723           .pp_count = 2,
724           .pp_chg_id = 5, },
725
726         { .n = "spdiftx_gclk",
727           .id = 85,
728           .r = { .max = 25000000  },
729           .pp = { "syspll_divpmcck", "audiopll_divpmcck", },
730           .pp_mux_table = { 5, 9, },
731           .pp_count = 2,
732           .pp_chg_id = 5, },
733
734         { .n  = "tcb0_ch0_gclk",
735           .id = 88,
736           .r = { .max = 200000000 },
737           .pp = { "syspll_divpmcck", "imgpll_divpmcck", "baudpll_divpmcck",
738                   "audiopll_divpmcck", "ethpll_divpmcck", },
739           .pp_mux_table = { 5, 7, 8, 9, 10, },
740           .pp_count = 5,
741           .pp_chg_id = INT_MIN, },
742
743         { .n  = "tcb1_ch0_gclk",
744           .id = 91,
745           .r = { .max = 200000000 },
746           .pp = { "syspll_divpmcck", "imgpll_divpmcck", "baudpll_divpmcck",
747                   "audiopll_divpmcck", "ethpll_divpmcck", },
748           .pp_mux_table = { 5, 7, 8, 9, 10, },
749           .pp_count = 5,
750           .pp_chg_id = INT_MIN, },
751
752         { .n  = "tcpca_gclk",
753           .id = 94,
754           .r = { .max = 32768, },
755           .pp_chg_id = INT_MIN, },
756
757         { .n  = "tcpcb_gclk",
758           .id = 95,
759           .r = { .max = 32768, },
760           .pp_chg_id = INT_MIN, },
761 };
762
763 /* PLL output range. */
764 static const struct clk_range pll_outputs[] = {
765         { .min = 2343750, .max = 1200000000 },
766 };
767
768 /* PLL characteristics. */
769 static const struct clk_pll_characteristics pll_characteristics = {
770         .input = { .min = 12000000, .max = 50000000 },
771         .num_output = ARRAY_SIZE(pll_outputs),
772         .output = pll_outputs,
773 };
774
775 /* MCK0 characteristics. */
776 static const struct clk_master_characteristics mck0_characteristics = {
777         .output = { .min = 140000000, .max = 200000000 },
778         .divisors = { 1, 2, 4, 3 },
779         .have_div3_pres = 1,
780 };
781
782 /* MCK0 layout. */
783 static const struct clk_master_layout mck0_layout = {
784         .mask = 0x373,
785         .pres_shift = 4,
786         .offset = 0x28,
787 };
788
789 /* Programmable clock layout. */
790 static const struct clk_programmable_layout programmable_layout = {
791         .pres_mask = 0xff,
792         .pres_shift = 8,
793         .css_mask = 0x1f,
794         .have_slck_mck = 0,
795         .is_pres_direct = 1,
796 };
797
798 /* Peripheral clock layout. */
799 static const struct clk_pcr_layout sama7g5_pcr_layout = {
800         .offset = 0x88,
801         .cmd = BIT(31),
802         .gckcss_mask = GENMASK(12, 8),
803         .pid_mask = GENMASK(6, 0),
804 };
805
806 static void __init sama7g5_pmc_setup(struct device_node *np)
807 {
808         const char *td_slck_name, *md_slck_name, *mainxtal_name;
809         struct pmc_data *sama7g5_pmc;
810         const char *parent_names[10];
811         void **alloc_mem = NULL;
812         int alloc_mem_size = 0;
813         struct regmap *regmap;
814         struct clk_hw *hw;
815         bool bypass;
816         int i, j;
817
818         i = of_property_match_string(np, "clock-names", "td_slck");
819         if (i < 0)
820                 return;
821
822         td_slck_name = of_clk_get_parent_name(np, i);
823
824         i = of_property_match_string(np, "clock-names", "md_slck");
825         if (i < 0)
826                 return;
827
828         md_slck_name = of_clk_get_parent_name(np, i);
829
830         i = of_property_match_string(np, "clock-names", "main_xtal");
831         if (i < 0)
832                 return;
833
834         mainxtal_name = of_clk_get_parent_name(np, i);
835
836         regmap = device_node_to_regmap(np);
837         if (IS_ERR(regmap))
838                 return;
839
840         sama7g5_pmc = pmc_data_allocate(PMC_ETHPLL + 1,
841                                         nck(sama7g5_systemck),
842                                         nck(sama7g5_periphck),
843                                         nck(sama7g5_gck), 8);
844         if (!sama7g5_pmc)
845                 return;
846
847         alloc_mem = kmalloc(sizeof(void *) *
848                             (ARRAY_SIZE(sama7g5_mckx) + ARRAY_SIZE(sama7g5_gck)),
849                             GFP_KERNEL);
850         if (!alloc_mem)
851                 goto err_free;
852
853         hw = at91_clk_register_main_rc_osc(regmap, "main_rc_osc", 12000000,
854                                            50000000);
855         if (IS_ERR(hw))
856                 goto err_free;
857
858         bypass = of_property_read_bool(np, "atmel,osc-bypass");
859
860         hw = at91_clk_register_main_osc(regmap, "main_osc", mainxtal_name,
861                                         bypass);
862         if (IS_ERR(hw))
863                 goto err_free;
864
865         parent_names[0] = "main_rc_osc";
866         parent_names[1] = "main_osc";
867         hw = at91_clk_register_sam9x5_main(regmap, "mainck", parent_names, 2);
868         if (IS_ERR(hw))
869                 goto err_free;
870
871         sama7g5_pmc->chws[PMC_MAIN] = hw;
872
873         for (i = 0; i < PLL_ID_MAX; i++) {
874                 for (j = 0; j < 3; j++) {
875                         struct clk_hw *parent_hw;
876
877                         if (!sama7g5_plls[i][j].n)
878                                 continue;
879
880                         switch (sama7g5_plls[i][j].t) {
881                         case PLL_TYPE_FRAC:
882                                 if (!strcmp(sama7g5_plls[i][j].p, "mainck"))
883                                         parent_hw = sama7g5_pmc->chws[PMC_MAIN];
884                                 else
885                                         parent_hw = __clk_get_hw(of_clk_get_by_name(np,
886                                                 sama7g5_plls[i][j].p));
887
888                                 hw = sam9x60_clk_register_frac_pll(regmap,
889                                         &pmc_pll_lock, sama7g5_plls[i][j].n,
890                                         sama7g5_plls[i][j].p, parent_hw, i,
891                                         &pll_characteristics,
892                                         sama7g5_plls[i][j].l,
893                                         sama7g5_plls[i][j].c);
894                                 break;
895
896                         case PLL_TYPE_DIV:
897                                 hw = sam9x60_clk_register_div_pll(regmap,
898                                         &pmc_pll_lock, sama7g5_plls[i][j].n,
899                                         sama7g5_plls[i][j].p, i,
900                                         &pll_characteristics,
901                                         sama7g5_plls[i][j].l,
902                                         sama7g5_plls[i][j].c);
903                                 break;
904
905                         default:
906                                 continue;
907                         }
908
909                         if (IS_ERR(hw))
910                                 goto err_free;
911
912                         if (sama7g5_plls[i][j].eid)
913                                 sama7g5_pmc->chws[sama7g5_plls[i][j].eid] = hw;
914                 }
915         }
916
917         parent_names[0] = md_slck_name;
918         parent_names[1] = "mainck";
919         parent_names[2] = "cpupll_divpmcck";
920         parent_names[3] = "syspll_divpmcck";
921         hw = at91_clk_register_master(regmap, "mck0", 4, parent_names,
922                                       &mck0_layout, &mck0_characteristics);
923         if (IS_ERR(hw))
924                 goto err_free;
925
926         sama7g5_pmc->chws[PMC_MCK] = hw;
927
928         parent_names[0] = md_slck_name;
929         parent_names[1] = td_slck_name;
930         parent_names[2] = "mainck";
931         parent_names[3] = "mck0";
932         for (i = 0; i < ARRAY_SIZE(sama7g5_mckx); i++) {
933                 u8 num_parents = 4 + sama7g5_mckx[i].ep_count;
934                 u32 *mux_table;
935
936                 mux_table = kmalloc_array(num_parents, sizeof(*mux_table),
937                                           GFP_KERNEL);
938                 if (!mux_table)
939                         goto err_free;
940
941                 SAMA7G5_INIT_TABLE(mux_table, 4);
942                 SAMA7G5_FILL_TABLE(&mux_table[4], sama7g5_mckx[i].ep_mux_table,
943                                    sama7g5_mckx[i].ep_count);
944                 SAMA7G5_FILL_TABLE(&parent_names[4], sama7g5_mckx[i].ep,
945                                    sama7g5_mckx[i].ep_count);
946
947                 hw = at91_clk_sama7g5_register_master(regmap, sama7g5_mckx[i].n,
948                                    num_parents, parent_names, mux_table,
949                                    &pmc_mckX_lock, sama7g5_mckx[i].id,
950                                    sama7g5_mckx[i].c,
951                                    sama7g5_mckx[i].ep_chg_id);
952                 if (IS_ERR(hw))
953                         goto err_free;
954
955                 alloc_mem[alloc_mem_size++] = mux_table;
956         }
957
958         hw = at91_clk_sama7g5_register_utmi(regmap, "utmick", "main_xtal");
959         if (IS_ERR(hw))
960                 goto err_free;
961
962         sama7g5_pmc->chws[PMC_UTMI] = hw;
963
964         parent_names[0] = md_slck_name;
965         parent_names[1] = td_slck_name;
966         parent_names[2] = "mainck";
967         parent_names[3] = "mck0";
968         parent_names[4] = "syspll_divpmcck";
969         parent_names[5] = "ddrpll_divpmcck";
970         parent_names[6] = "imgpll_divpmcck";
971         parent_names[7] = "baudpll_divpmcck";
972         parent_names[8] = "audiopll_divpmcck";
973         parent_names[9] = "ethpll_divpmcck";
974         for (i = 0; i < 8; i++) {
975                 char name[6];
976
977                 snprintf(name, sizeof(name), "prog%d", i);
978
979                 hw = at91_clk_register_programmable(regmap, name, parent_names,
980                                                     10, i,
981                                                     &programmable_layout,
982                                                     sama7g5_prog_mux_table);
983                 if (IS_ERR(hw))
984                         goto err_free;
985
986                 sama7g5_pmc->pchws[i] = hw;
987         }
988
989         for (i = 0; i < ARRAY_SIZE(sama7g5_systemck); i++) {
990                 hw = at91_clk_register_system(regmap, sama7g5_systemck[i].n,
991                                               sama7g5_systemck[i].p,
992                                               sama7g5_systemck[i].id);
993                 if (IS_ERR(hw))
994                         goto err_free;
995
996                 sama7g5_pmc->shws[sama7g5_systemck[i].id] = hw;
997         }
998
999         for (i = 0; i < ARRAY_SIZE(sama7g5_periphck); i++) {
1000                 hw = at91_clk_register_sam9x5_peripheral(regmap, &pmc_pcr_lock,
1001                                                 &sama7g5_pcr_layout,
1002                                                 sama7g5_periphck[i].n,
1003                                                 sama7g5_periphck[i].p,
1004                                                 sama7g5_periphck[i].id,
1005                                                 &sama7g5_periphck[i].r,
1006                                                 sama7g5_periphck[i].chgp ? 0 :
1007                                                 INT_MIN);
1008                 if (IS_ERR(hw))
1009                         goto err_free;
1010
1011                 sama7g5_pmc->phws[sama7g5_periphck[i].id] = hw;
1012         }
1013
1014         parent_names[0] = md_slck_name;
1015         parent_names[1] = td_slck_name;
1016         parent_names[2] = "mainck";
1017         parent_names[3] = "mck0";
1018         for (i = 0; i < ARRAY_SIZE(sama7g5_gck); i++) {
1019                 u8 num_parents = 4 + sama7g5_gck[i].pp_count;
1020                 u32 *mux_table;
1021
1022                 mux_table = kmalloc_array(num_parents, sizeof(*mux_table),
1023                                           GFP_KERNEL);
1024                 if (!mux_table)
1025                         goto err_free;
1026
1027                 SAMA7G5_INIT_TABLE(mux_table, 4);
1028                 SAMA7G5_FILL_TABLE(&mux_table[4], sama7g5_gck[i].pp_mux_table,
1029                                    sama7g5_gck[i].pp_count);
1030                 SAMA7G5_FILL_TABLE(&parent_names[4], sama7g5_gck[i].pp,
1031                                    sama7g5_gck[i].pp_count);
1032
1033                 hw = at91_clk_register_generated(regmap, &pmc_pcr_lock,
1034                                                  &sama7g5_pcr_layout,
1035                                                  sama7g5_gck[i].n,
1036                                                  parent_names, mux_table,
1037                                                  num_parents,
1038                                                  sama7g5_gck[i].id,
1039                                                  &sama7g5_gck[i].r,
1040                                                  sama7g5_gck[i].pp_chg_id);
1041                 if (IS_ERR(hw))
1042                         goto err_free;
1043
1044                 sama7g5_pmc->ghws[sama7g5_gck[i].id] = hw;
1045                 alloc_mem[alloc_mem_size++] = mux_table;
1046         }
1047
1048         of_clk_add_hw_provider(np, of_clk_hw_pmc_get, sama7g5_pmc);
1049
1050         return;
1051
1052 err_free:
1053         if (alloc_mem) {
1054                 for (i = 0; i < alloc_mem_size; i++)
1055                         kfree(alloc_mem[i]);
1056                 kfree(alloc_mem);
1057         }
1058
1059         kfree(sama7g5_pmc);
1060 }
1061
1062 /* Some clks are used for a clocksource */
1063 CLK_OF_DECLARE(sama7g5_pmc, "microchip,sama7g5-pmc", sama7g5_pmc_setup);