GNU Linux-libre 6.8.9-gnu
[releases.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_mck0_lock);
36 static DEFINE_SPINLOCK(pmc_mckX_lock);
37
38 /*
39  * PLL clocks identifiers
40  * @PLL_ID_CPU:         CPU PLL identifier
41  * @PLL_ID_SYS:         System PLL identifier
42  * @PLL_ID_DDR:         DDR PLL identifier
43  * @PLL_ID_IMG:         Image subsystem PLL identifier
44  * @PLL_ID_BAUD:        Baud PLL identifier
45  * @PLL_ID_AUDIO:       Audio PLL identifier
46  * @PLL_ID_ETH:         Ethernet PLL identifier
47  */
48 enum pll_ids {
49         PLL_ID_CPU,
50         PLL_ID_SYS,
51         PLL_ID_DDR,
52         PLL_ID_IMG,
53         PLL_ID_BAUD,
54         PLL_ID_AUDIO,
55         PLL_ID_ETH,
56         PLL_ID_MAX,
57 };
58
59 /*
60  * PLL component identifier
61  * @PLL_COMPID_FRAC: Fractional PLL component identifier
62  * @PLL_COMPID_DIV0: 1st PLL divider component identifier
63  * @PLL_COMPID_DIV1: 2nd PLL divider component identifier
64  */
65 enum pll_component_id {
66         PLL_COMPID_FRAC,
67         PLL_COMPID_DIV0,
68         PLL_COMPID_DIV1,
69 };
70
71 /*
72  * PLL type identifiers
73  * @PLL_TYPE_FRAC:      fractional PLL identifier
74  * @PLL_TYPE_DIV:       divider PLL identifier
75  */
76 enum pll_type {
77         PLL_TYPE_FRAC,
78         PLL_TYPE_DIV,
79 };
80
81 /* Layout for fractional PLLs. */
82 static const struct clk_pll_layout pll_layout_frac = {
83         .mul_mask       = GENMASK(31, 24),
84         .frac_mask      = GENMASK(21, 0),
85         .mul_shift      = 24,
86         .frac_shift     = 0,
87 };
88
89 /* Layout for DIVPMC dividers. */
90 static const struct clk_pll_layout pll_layout_divpmc = {
91         .div_mask       = GENMASK(7, 0),
92         .endiv_mask     = BIT(29),
93         .div_shift      = 0,
94         .endiv_shift    = 29,
95 };
96
97 /* Layout for DIVIO dividers. */
98 static const struct clk_pll_layout pll_layout_divio = {
99         .div_mask       = GENMASK(19, 12),
100         .endiv_mask     = BIT(30),
101         .div_shift      = 12,
102         .endiv_shift    = 30,
103 };
104
105 /*
106  * CPU PLL output range.
107  * Notice: The upper limit has been setup to 1000000002 due to hardware
108  * block which cannot output exactly 1GHz.
109  */
110 static const struct clk_range cpu_pll_outputs[] = {
111         { .min = 2343750, .max = 1000000002 },
112 };
113
114 /* PLL output range. */
115 static const struct clk_range pll_outputs[] = {
116         { .min = 2343750, .max = 1200000000 },
117 };
118
119 /* CPU PLL characteristics. */
120 static const struct clk_pll_characteristics cpu_pll_characteristics = {
121         .input = { .min = 12000000, .max = 50000000 },
122         .num_output = ARRAY_SIZE(cpu_pll_outputs),
123         .output = cpu_pll_outputs,
124 };
125
126 /* PLL characteristics. */
127 static const struct clk_pll_characteristics pll_characteristics = {
128         .input = { .min = 12000000, .max = 50000000 },
129         .num_output = ARRAY_SIZE(pll_outputs),
130         .output = pll_outputs,
131 };
132
133 /*
134  * SAMA7G5 PLL possible parents
135  * @SAMA7G5_PLL_PARENT_MAINCK: MAINCK is PLL a parent
136  * @SAMA7G5_PLL_PARENT_MAIN_XTAL: MAIN XTAL is a PLL parent
137  * @SAMA7G5_PLL_PARENT_FRACCK: Frac PLL is a PLL parent (for PLL dividers)
138  */
139 enum sama7g5_pll_parent {
140         SAMA7G5_PLL_PARENT_MAINCK,
141         SAMA7G5_PLL_PARENT_MAIN_XTAL,
142         SAMA7G5_PLL_PARENT_FRACCK,
143 };
144
145 /*
146  * PLL clocks description
147  * @n:          clock name
148  * @l:          clock layout
149  * @c:          clock characteristics
150  * @hw:         pointer to clk_hw
151  * @t:          clock type
152  * @f:          clock flags
153  * @p:          clock parent
154  * @eid:        export index in sama7g5->chws[] array
155  * @safe_div:   intermediate divider need to be set on PRE_RATE_CHANGE
156  *              notification
157  */
158 static struct sama7g5_pll {
159         const char *n;
160         const struct clk_pll_layout *l;
161         const struct clk_pll_characteristics *c;
162         struct clk_hw *hw;
163         unsigned long f;
164         enum sama7g5_pll_parent p;
165         u8 t;
166         u8 eid;
167         u8 safe_div;
168 } sama7g5_plls[][PLL_ID_MAX] = {
169         [PLL_ID_CPU] = {
170                 [PLL_COMPID_FRAC] = {
171                         .n = "cpupll_fracck",
172                         .p = SAMA7G5_PLL_PARENT_MAINCK,
173                         .l = &pll_layout_frac,
174                         .c = &cpu_pll_characteristics,
175                         .t = PLL_TYPE_FRAC,
176                         /*
177                          * This feeds cpupll_divpmcck which feeds CPU. It should
178                          * not be disabled.
179                          */
180                         .f = CLK_IS_CRITICAL,
181                 },
182
183                 [PLL_COMPID_DIV0] = {
184                         .n = "cpupll_divpmcck",
185                         .p = SAMA7G5_PLL_PARENT_FRACCK,
186                         .l = &pll_layout_divpmc,
187                         .c = &cpu_pll_characteristics,
188                         .t = PLL_TYPE_DIV,
189                         /* This feeds CPU. It should not be disabled. */
190                         .f = CLK_IS_CRITICAL | CLK_SET_RATE_PARENT,
191                         .eid = PMC_CPUPLL,
192                         /*
193                          * Safe div=15 should be safe even for switching b/w 1GHz and
194                          * 90MHz (frac pll might go up to 1.2GHz).
195                          */
196                         .safe_div = 15,
197                 },
198         },
199
200         [PLL_ID_SYS] = {
201                 [PLL_COMPID_FRAC] = {
202                         .n = "syspll_fracck",
203                         .p = SAMA7G5_PLL_PARENT_MAINCK,
204                         .l = &pll_layout_frac,
205                         .c = &pll_characteristics,
206                         .t = PLL_TYPE_FRAC,
207                         /*
208                          * This feeds syspll_divpmcck which may feed critical parts
209                          * of the systems like timers. Therefore it should not be
210                          * disabled.
211                          */
212                         .f = CLK_IS_CRITICAL | CLK_SET_RATE_GATE,
213                 },
214
215                 [PLL_COMPID_DIV0] = {
216                         .n = "syspll_divpmcck",
217                         .p = SAMA7G5_PLL_PARENT_FRACCK,
218                         .l = &pll_layout_divpmc,
219                         .c = &pll_characteristics,
220                         .t = PLL_TYPE_DIV,
221                         /*
222                          * This may feed critical parts of the systems like timers.
223                          * Therefore it should not be disabled.
224                          */
225                         .f = CLK_IS_CRITICAL | CLK_SET_RATE_GATE,
226                         .eid = PMC_SYSPLL,
227                 },
228         },
229
230         [PLL_ID_DDR] = {
231                 [PLL_COMPID_FRAC] = {
232                         .n = "ddrpll_fracck",
233                         .p = SAMA7G5_PLL_PARENT_MAINCK,
234                         .l = &pll_layout_frac,
235                         .c = &pll_characteristics,
236                         .t = PLL_TYPE_FRAC,
237                         /*
238                          * This feeds ddrpll_divpmcck which feeds DDR. It should not
239                          * be disabled.
240                          */
241                         .f = CLK_IS_CRITICAL | CLK_SET_RATE_GATE,
242                 },
243
244                 [PLL_COMPID_DIV0] = {
245                         .n = "ddrpll_divpmcck",
246                         .p = SAMA7G5_PLL_PARENT_FRACCK,
247                         .l = &pll_layout_divpmc,
248                         .c = &pll_characteristics,
249                         .t = PLL_TYPE_DIV,
250                         /* This feeds DDR. It should not be disabled. */
251                         .f = CLK_IS_CRITICAL | CLK_SET_RATE_GATE,
252                 },
253         },
254
255         [PLL_ID_IMG] = {
256                 [PLL_COMPID_FRAC] = {
257                         .n = "imgpll_fracck",
258                         .p = SAMA7G5_PLL_PARENT_MAINCK,
259                         .l = &pll_layout_frac,
260                         .c = &pll_characteristics,
261                         .t = PLL_TYPE_FRAC,
262                         .f = CLK_SET_RATE_GATE,
263                 },
264
265                 [PLL_COMPID_DIV0] = {
266                         .n = "imgpll_divpmcck",
267                         .p = SAMA7G5_PLL_PARENT_FRACCK,
268                         .l = &pll_layout_divpmc,
269                         .c = &pll_characteristics,
270                         .t = PLL_TYPE_DIV,
271                         .f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE |
272                              CLK_SET_RATE_PARENT,
273                 },
274         },
275
276         [PLL_ID_BAUD] = {
277                 [PLL_COMPID_FRAC] = {
278                         .n = "baudpll_fracck",
279                         .p = SAMA7G5_PLL_PARENT_MAINCK,
280                         .l = &pll_layout_frac,
281                         .c = &pll_characteristics,
282                         .t = PLL_TYPE_FRAC,
283                         .f = CLK_SET_RATE_GATE, },
284
285                 [PLL_COMPID_DIV0] = {
286                         .n = "baudpll_divpmcck",
287                         .p = SAMA7G5_PLL_PARENT_FRACCK,
288                         .l = &pll_layout_divpmc,
289                         .c = &pll_characteristics,
290                         .t = PLL_TYPE_DIV,
291                         .f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE |
292                              CLK_SET_RATE_PARENT,
293                 },
294         },
295
296         [PLL_ID_AUDIO] = {
297                 [PLL_COMPID_FRAC] = {
298                         .n = "audiopll_fracck",
299                         .p = SAMA7G5_PLL_PARENT_MAIN_XTAL,
300                         .l = &pll_layout_frac,
301                         .c = &pll_characteristics,
302                         .t = PLL_TYPE_FRAC,
303                         .f = CLK_SET_RATE_GATE,
304                 },
305
306                 [PLL_COMPID_DIV0] = {
307                         .n = "audiopll_divpmcck",
308                         .p = SAMA7G5_PLL_PARENT_FRACCK,
309                         .l = &pll_layout_divpmc,
310                         .c = &pll_characteristics,
311                         .t = PLL_TYPE_DIV,
312                         .f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE |
313                              CLK_SET_RATE_PARENT,
314                         .eid = PMC_AUDIOPMCPLL,
315                 },
316
317                 [PLL_COMPID_DIV1] = {
318                         .n = "audiopll_diviock",
319                         .p = SAMA7G5_PLL_PARENT_FRACCK,
320                         .l = &pll_layout_divio,
321                         .c = &pll_characteristics,
322                         .t = PLL_TYPE_DIV,
323                         .f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE |
324                              CLK_SET_RATE_PARENT,
325                         .eid = PMC_AUDIOIOPLL,
326                 },
327         },
328
329         [PLL_ID_ETH] = {
330                 [PLL_COMPID_FRAC] = {
331                         .n = "ethpll_fracck",
332                         .p = SAMA7G5_PLL_PARENT_MAIN_XTAL,
333                         .l = &pll_layout_frac,
334                         .c = &pll_characteristics,
335                         .t = PLL_TYPE_FRAC,
336                         .f = CLK_SET_RATE_GATE,
337                 },
338
339                 [PLL_COMPID_DIV0] = {
340                         .n = "ethpll_divpmcck",
341                         .p = SAMA7G5_PLL_PARENT_FRACCK,
342                         .l = &pll_layout_divpmc,
343                         .c = &pll_characteristics,
344                         .t = PLL_TYPE_DIV,
345                         .f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE |
346                              CLK_SET_RATE_PARENT,
347                 },
348         },
349 };
350
351 /* Used to create an array entry identifying a PLL by its components. */
352 #define PLL_IDS_TO_ARR_ENTRY(_id, _comp) { PLL_ID_##_id, PLL_COMPID_##_comp}
353
354 /*
355  * Master clock (MCK[1..4]) description
356  * @n:                  clock name
357  * @ep:                 extra parents names array (entry formed by PLL components
358  *                      identifiers (see enum pll_component_id))
359  * @hw:                 pointer to clk_hw
360  * @ep_chg_id:          index in parents array that specifies the changeable
361  *                      parent
362  * @ep_count:           extra parents count
363  * @ep_mux_table:       mux table for extra parents
364  * @id:                 clock id
365  * @eid:                export index in sama7g5->chws[] array
366  * @c:                  true if clock is critical and cannot be disabled
367  */
368 static struct {
369         const char *n;
370         struct {
371                 int pll_id;
372                 int pll_compid;
373         } ep[4];
374         struct clk_hw *hw;
375         int ep_chg_id;
376         u8 ep_count;
377         u8 ep_mux_table[4];
378         u8 id;
379         u8 eid;
380         u8 c;
381 } sama7g5_mckx[] = {
382         { .n = "mck0", }, /* Dummy entry for MCK0 to store hw in probe. */
383         { .n = "mck1",
384           .id = 1,
385           .ep = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), },
386           .ep_mux_table = { 5, },
387           .ep_count = 1,
388           .ep_chg_id = INT_MIN,
389           .eid = PMC_MCK1,
390           .c = 1, },
391
392         { .n = "mck2",
393           .id = 2,
394           .ep = { PLL_IDS_TO_ARR_ENTRY(DDR, DIV0), },
395           .ep_mux_table = { 6, },
396           .ep_count = 1,
397           .ep_chg_id = INT_MIN,
398           .c = 1, },
399
400         { .n = "mck3",
401           .id = 3,
402           .ep = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), PLL_IDS_TO_ARR_ENTRY(DDR, DIV0),
403                   PLL_IDS_TO_ARR_ENTRY(IMG, DIV0), },
404           .ep_mux_table = { 5, 6, 7, },
405           .ep_count = 3,
406           .ep_chg_id = 5, },
407
408         { .n = "mck4",
409           .id = 4,
410           .ep = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), },
411           .ep_mux_table = { 5, },
412           .ep_count = 1,
413           .ep_chg_id = INT_MIN,
414           .c = 1, },
415 };
416
417 /*
418  * System clock description
419  * @n:  clock name
420  * @id: clock id
421  */
422 static const struct {
423         const char *n;
424         u8 id;
425 } sama7g5_systemck[] = {
426         { .n = "pck0", .id = 8, },
427         { .n = "pck1", .id = 9, },
428         { .n = "pck2", .id = 10, },
429         { .n = "pck3", .id = 11, },
430         { .n = "pck4", .id = 12, },
431         { .n = "pck5", .id = 13, },
432         { .n = "pck6", .id = 14, },
433         { .n = "pck7", .id = 15, },
434 };
435
436 /* Mux table for programmable clocks. */
437 static u32 sama7g5_prog_mux_table[] = { 0, 1, 2, 5, 6, 7, 8, 9, 10, };
438
439 /*
440  * Peripheral clock parent hw identifier (used to index in sama7g5_mckx[])
441  * @PCK_PARENT_HW_MCK0: pck parent hw identifier is MCK0
442  * @PCK_PARENT_HW_MCK1: pck parent hw identifier is MCK1
443  * @PCK_PARENT_HW_MCK2: pck parent hw identifier is MCK2
444  * @PCK_PARENT_HW_MCK3: pck parent hw identifier is MCK3
445  * @PCK_PARENT_HW_MCK4: pck parent hw identifier is MCK4
446  * @PCK_PARENT_HW_MAX: max identifier
447  */
448 enum sama7g5_pck_parent_hw_id {
449         PCK_PARENT_HW_MCK0,
450         PCK_PARENT_HW_MCK1,
451         PCK_PARENT_HW_MCK2,
452         PCK_PARENT_HW_MCK3,
453         PCK_PARENT_HW_MCK4,
454         PCK_PARENT_HW_MAX,
455 };
456
457 /*
458  * Peripheral clock description
459  * @n:          clock name
460  * @p:          clock parent hw id
461  * @r:          clock range values
462  * @id:         clock id
463  * @chgp:       index in parent array of the changeable parent
464  */
465 static struct {
466         const char *n;
467         enum sama7g5_pck_parent_hw_id p;
468         struct clk_range r;
469         u8 chgp;
470         u8 id;
471 } sama7g5_periphck[] = {
472         { .n = "pioA_clk",      .p = PCK_PARENT_HW_MCK0, .id = 11, },
473         { .n = "securam_clk",   .p = PCK_PARENT_HW_MCK0, .id = 18, },
474         { .n = "sfr_clk",       .p = PCK_PARENT_HW_MCK1, .id = 19, },
475         { .n = "hsmc_clk",      .p = PCK_PARENT_HW_MCK1, .id = 21, },
476         { .n = "xdmac0_clk",    .p = PCK_PARENT_HW_MCK1, .id = 22, },
477         { .n = "xdmac1_clk",    .p = PCK_PARENT_HW_MCK1, .id = 23, },
478         { .n = "xdmac2_clk",    .p = PCK_PARENT_HW_MCK1, .id = 24, },
479         { .n = "acc_clk",       .p = PCK_PARENT_HW_MCK1, .id = 25, },
480         { .n = "aes_clk",       .p = PCK_PARENT_HW_MCK1, .id = 27, },
481         { .n = "tzaesbasc_clk", .p = PCK_PARENT_HW_MCK1, .id = 28, },
482         { .n = "asrc_clk",      .p = PCK_PARENT_HW_MCK1, .id = 30, .r = { .max = 200000000, }, },
483         { .n = "cpkcc_clk",     .p = PCK_PARENT_HW_MCK0, .id = 32, },
484         { .n = "csi_clk",       .p = PCK_PARENT_HW_MCK3, .id = 33, .r = { .max = 266000000, }, .chgp = 1, },
485         { .n = "csi2dc_clk",    .p = PCK_PARENT_HW_MCK3, .id = 34, .r = { .max = 266000000, }, .chgp = 1, },
486         { .n = "eic_clk",       .p = PCK_PARENT_HW_MCK1, .id = 37, },
487         { .n = "flex0_clk",     .p = PCK_PARENT_HW_MCK1, .id = 38, },
488         { .n = "flex1_clk",     .p = PCK_PARENT_HW_MCK1, .id = 39, },
489         { .n = "flex2_clk",     .p = PCK_PARENT_HW_MCK1, .id = 40, },
490         { .n = "flex3_clk",     .p = PCK_PARENT_HW_MCK1, .id = 41, },
491         { .n = "flex4_clk",     .p = PCK_PARENT_HW_MCK1, .id = 42, },
492         { .n = "flex5_clk",     .p = PCK_PARENT_HW_MCK1, .id = 43, },
493         { .n = "flex6_clk",     .p = PCK_PARENT_HW_MCK1, .id = 44, },
494         { .n = "flex7_clk",     .p = PCK_PARENT_HW_MCK1, .id = 45, },
495         { .n = "flex8_clk",     .p = PCK_PARENT_HW_MCK1, .id = 46, },
496         { .n = "flex9_clk",     .p = PCK_PARENT_HW_MCK1, .id = 47, },
497         { .n = "flex10_clk",    .p = PCK_PARENT_HW_MCK1, .id = 48, },
498         { .n = "flex11_clk",    .p = PCK_PARENT_HW_MCK1, .id = 49, },
499         { .n = "gmac0_clk",     .p = PCK_PARENT_HW_MCK1, .id = 51, },
500         { .n = "gmac1_clk",     .p = PCK_PARENT_HW_MCK1, .id = 52, },
501         { .n = "icm_clk",       .p = PCK_PARENT_HW_MCK1, .id = 55, },
502         { .n = "isc_clk",       .p = PCK_PARENT_HW_MCK3, .id = 56, .r = { .max = 266000000, }, .chgp = 1, },
503         { .n = "i2smcc0_clk",   .p = PCK_PARENT_HW_MCK1, .id = 57, .r = { .max = 200000000, }, },
504         { .n = "i2smcc1_clk",   .p = PCK_PARENT_HW_MCK1, .id = 58, .r = { .max = 200000000, }, },
505         { .n = "matrix_clk",    .p = PCK_PARENT_HW_MCK1, .id = 60, },
506         { .n = "mcan0_clk",     .p = PCK_PARENT_HW_MCK1, .id = 61, .r = { .max = 200000000, }, },
507         { .n = "mcan1_clk",     .p = PCK_PARENT_HW_MCK1, .id = 62, .r = { .max = 200000000, }, },
508         { .n = "mcan2_clk",     .p = PCK_PARENT_HW_MCK1, .id = 63, .r = { .max = 200000000, }, },
509         { .n = "mcan3_clk",     .p = PCK_PARENT_HW_MCK1, .id = 64, .r = { .max = 200000000, }, },
510         { .n = "mcan4_clk",     .p = PCK_PARENT_HW_MCK1, .id = 65, .r = { .max = 200000000, }, },
511         { .n = "mcan5_clk",     .p = PCK_PARENT_HW_MCK1, .id = 66, .r = { .max = 200000000, }, },
512         { .n = "pdmc0_clk",     .p = PCK_PARENT_HW_MCK1, .id = 68, .r = { .max = 200000000, }, },
513         { .n = "pdmc1_clk",     .p = PCK_PARENT_HW_MCK1, .id = 69, .r = { .max = 200000000, }, },
514         { .n = "pit64b0_clk",   .p = PCK_PARENT_HW_MCK1, .id = 70, },
515         { .n = "pit64b1_clk",   .p = PCK_PARENT_HW_MCK1, .id = 71, },
516         { .n = "pit64b2_clk",   .p = PCK_PARENT_HW_MCK1, .id = 72, },
517         { .n = "pit64b3_clk",   .p = PCK_PARENT_HW_MCK1, .id = 73, },
518         { .n = "pit64b4_clk",   .p = PCK_PARENT_HW_MCK1, .id = 74, },
519         { .n = "pit64b5_clk",   .p = PCK_PARENT_HW_MCK1, .id = 75, },
520         { .n = "pwm_clk",       .p = PCK_PARENT_HW_MCK1, .id = 77, },
521         { .n = "qspi0_clk",     .p = PCK_PARENT_HW_MCK1, .id = 78, },
522         { .n = "qspi1_clk",     .p = PCK_PARENT_HW_MCK1, .id = 79, },
523         { .n = "sdmmc0_clk",    .p = PCK_PARENT_HW_MCK1, .id = 80, },
524         { .n = "sdmmc1_clk",    .p = PCK_PARENT_HW_MCK1, .id = 81, },
525         { .n = "sdmmc2_clk",    .p = PCK_PARENT_HW_MCK1, .id = 82, },
526         { .n = "sha_clk",       .p = PCK_PARENT_HW_MCK1, .id = 83, },
527         { .n = "spdifrx_clk",   .p = PCK_PARENT_HW_MCK1, .id = 84, .r = { .max = 200000000, }, },
528         { .n = "spdiftx_clk",   .p = PCK_PARENT_HW_MCK1, .id = 85, .r = { .max = 200000000, }, },
529         { .n = "ssc0_clk",      .p = PCK_PARENT_HW_MCK1, .id = 86, .r = { .max = 200000000, }, },
530         { .n = "ssc1_clk",      .p = PCK_PARENT_HW_MCK1, .id = 87, .r = { .max = 200000000, }, },
531         { .n = "tcb0_ch0_clk",  .p = PCK_PARENT_HW_MCK1, .id = 88, .r = { .max = 200000000, }, },
532         { .n = "tcb0_ch1_clk",  .p = PCK_PARENT_HW_MCK1, .id = 89, .r = { .max = 200000000, }, },
533         { .n = "tcb0_ch2_clk",  .p = PCK_PARENT_HW_MCK1, .id = 90, .r = { .max = 200000000, }, },
534         { .n = "tcb1_ch0_clk",  .p = PCK_PARENT_HW_MCK1, .id = 91, .r = { .max = 200000000, }, },
535         { .n = "tcb1_ch1_clk",  .p = PCK_PARENT_HW_MCK1, .id = 92, .r = { .max = 200000000, }, },
536         { .n = "tcb1_ch2_clk",  .p = PCK_PARENT_HW_MCK1, .id = 93, .r = { .max = 200000000, }, },
537         { .n = "tcpca_clk",     .p = PCK_PARENT_HW_MCK1, .id = 94, },
538         { .n = "tcpcb_clk",     .p = PCK_PARENT_HW_MCK1, .id = 95, },
539         { .n = "tdes_clk",      .p = PCK_PARENT_HW_MCK1, .id = 96, },
540         { .n = "trng_clk",      .p = PCK_PARENT_HW_MCK1, .id = 97, },
541         { .n = "udphsa_clk",    .p = PCK_PARENT_HW_MCK1, .id = 104, },
542         { .n = "udphsb_clk",    .p = PCK_PARENT_HW_MCK1, .id = 105, },
543         { .n = "uhphs_clk",     .p = PCK_PARENT_HW_MCK1, .id = 106, },
544 };
545
546 /*
547  * Generic clock description
548  * @n:                  clock name
549  * @pp:                 PLL parents (entry formed by PLL components identifiers
550  *                      (see enum pll_component_id))
551  * @pp_mux_table:       PLL parents mux table
552  * @r:                  clock output range
553  * @pp_chg_id:          id in parent array of changeable PLL parent
554  * @pp_count:           PLL parents count
555  * @id:                 clock id
556  */
557 static const struct {
558         const char *n;
559         struct {
560                 int pll_id;
561                 int pll_compid;
562         } pp[8];
563         const char pp_mux_table[8];
564         struct clk_range r;
565         int pp_chg_id;
566         u8 pp_count;
567         u8 id;
568 } sama7g5_gck[] = {
569         { .n  = "adc_gclk",
570           .id = 26,
571           .r = { .max = 100000000, },
572           .pp = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), PLL_IDS_TO_ARR_ENTRY(IMG, DIV0),
573                   PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0), },
574           .pp_mux_table = { 5, 7, 9, },
575           .pp_count = 3,
576           .pp_chg_id = INT_MIN, },
577
578         { .n  = "asrc_gclk",
579           .id = 30,
580           .r = { .max = 200000000 },
581           .pp = { PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0), },
582           .pp_mux_table = { 9, },
583           .pp_count = 1,
584           .pp_chg_id = 3, },
585
586         { .n  = "csi_gclk",
587           .id = 33,
588           .r = { .max = 27000000  },
589           .pp = { PLL_IDS_TO_ARR_ENTRY(DDR, DIV0), PLL_IDS_TO_ARR_ENTRY(IMG, DIV0), },
590           .pp_mux_table = { 6, 7, },
591           .pp_count = 2,
592           .pp_chg_id = INT_MIN, },
593
594         { .n  = "flex0_gclk",
595           .id = 38,
596           .r = { .max = 200000000 },
597           .pp = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), },
598           .pp_mux_table = { 5, 8, },
599           .pp_count = 2,
600           .pp_chg_id = INT_MIN, },
601
602         { .n  = "flex1_gclk",
603           .id = 39,
604           .r = { .max = 200000000 },
605           .pp = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), },
606           .pp_mux_table = { 5, 8, },
607           .pp_count = 2,
608           .pp_chg_id = INT_MIN, },
609
610         { .n  = "flex2_gclk",
611           .id = 40,
612           .r = { .max = 200000000 },
613           .pp = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), },
614           .pp_mux_table = { 5, 8, },
615           .pp_count = 2,
616           .pp_chg_id = INT_MIN, },
617
618         { .n  = "flex3_gclk",
619           .id = 41,
620           .r = { .max = 200000000 },
621           .pp = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), },
622           .pp_mux_table = { 5, 8, },
623           .pp_count = 2,
624           .pp_chg_id = INT_MIN, },
625
626         { .n  = "flex4_gclk",
627           .id = 42,
628           .r = { .max = 200000000 },
629           .pp = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), },
630           .pp_mux_table = { 5, 8, },
631           .pp_count = 2,
632           .pp_chg_id = INT_MIN, },
633
634         { .n  = "flex5_gclk",
635           .id = 43,
636           .r = { .max = 200000000 },
637           .pp = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), },
638           .pp_mux_table = { 5, 8, },
639           .pp_count = 2,
640           .pp_chg_id = INT_MIN, },
641
642         { .n  = "flex6_gclk",
643           .id = 44,
644           .r = { .max = 200000000 },
645           .pp = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), },
646           .pp_mux_table = { 5, 8, },
647           .pp_count = 2,
648           .pp_chg_id = INT_MIN, },
649
650         { .n  = "flex7_gclk",
651           .id = 45,
652           .r = { .max = 200000000 },
653           .pp = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), },
654           .pp_mux_table = { 5, 8, },
655           .pp_count = 2,
656           .pp_chg_id = INT_MIN, },
657
658         { .n  = "flex8_gclk",
659           .id = 46,
660           .r = { .max = 200000000 },
661           .pp = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), },
662           .pp_mux_table = { 5, 8, },
663           .pp_count = 2,
664           .pp_chg_id = INT_MIN, },
665
666         { .n  = "flex9_gclk",
667           .id = 47,
668           .r = { .max = 200000000 },
669           .pp = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), },
670           .pp_mux_table = { 5, 8, },
671           .pp_count = 2,
672           .pp_chg_id = INT_MIN, },
673
674         { .n  = "flex10_gclk",
675           .id = 48,
676           .r = { .max = 200000000 },
677           .pp = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), },
678           .pp_mux_table = { 5, 8, },
679           .pp_count = 2,
680           .pp_chg_id = INT_MIN, },
681
682         { .n  = "flex11_gclk",
683           .id = 49,
684           .r = { .max = 200000000 },
685           .pp = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), },
686           .pp_mux_table = { 5, 8, },
687           .pp_count = 2,
688           .pp_chg_id = INT_MIN, },
689
690         { .n  = "gmac0_gclk",
691           .id = 51,
692           .r = { .max = 125000000 },
693           .pp = { PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), },
694           .pp_mux_table = { 10, },
695           .pp_count = 1,
696           .pp_chg_id = 3, },
697
698         { .n  = "gmac1_gclk",
699           .id = 52,
700           .r = { .max = 50000000  },
701           .pp = { PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), },
702           .pp_mux_table = { 10, },
703           .pp_count = 1,
704           .pp_chg_id = INT_MIN, },
705
706         { .n  = "gmac0_tsu_gclk",
707           .id = 53,
708           .r = { .max = 300000000 },
709           .pp = { PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0), PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), },
710           .pp_mux_table = { 9, 10, },
711           .pp_count = 2,
712           .pp_chg_id = INT_MIN, },
713
714         { .n  = "gmac1_tsu_gclk",
715           .id = 54,
716           .r = { .max = 300000000 },
717           .pp = { PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0), PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), },
718           .pp_mux_table = { 9, 10, },
719           .pp_count = 2,
720           .pp_chg_id = INT_MIN, },
721
722         { .n  = "i2smcc0_gclk",
723           .id = 57,
724           .r = { .max = 100000000 },
725           .pp = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0), },
726           .pp_mux_table = { 5, 9, },
727           .pp_count = 2,
728           .pp_chg_id = 4, },
729
730         { .n  = "i2smcc1_gclk",
731           .id = 58,
732           .r = { .max = 100000000 },
733           .pp = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0), },
734           .pp_mux_table = { 5, 9, },
735           .pp_count = 2,
736           .pp_chg_id = 4, },
737
738         { .n  = "mcan0_gclk",
739           .id = 61,
740           .r = { .max = 200000000 },
741           .pp = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), },
742           .pp_mux_table = { 5, 8, },
743           .pp_count = 2,
744           .pp_chg_id = INT_MIN, },
745
746         { .n  = "mcan1_gclk",
747           .id = 62,
748           .r = { .max = 200000000 },
749           .pp = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), },
750           .pp_mux_table = { 5, 8, },
751           .pp_count = 2,
752           .pp_chg_id = INT_MIN, },
753
754         { .n  = "mcan2_gclk",
755           .id = 63,
756           .r = { .max = 200000000 },
757           .pp = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), },
758           .pp_mux_table = { 5, 8, },
759           .pp_count = 2,
760           .pp_chg_id = INT_MIN, },
761
762         { .n  = "mcan3_gclk",
763           .id = 64,
764           .r = { .max = 200000000 },
765           .pp = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), },
766           .pp_mux_table = { 5, 8, },
767           .pp_count = 2,
768           .pp_chg_id = INT_MIN, },
769
770         { .n  = "mcan4_gclk",
771           .id = 65,
772           .r = { .max = 200000000 },
773           .pp = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), },
774           .pp_mux_table = { 5, 8, },
775           .pp_count = 2,
776           .pp_chg_id = INT_MIN, },
777
778         { .n  = "mcan5_gclk",
779           .id = 66,
780           .r = { .max = 200000000 },
781           .pp = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), },
782           .pp_mux_table = { 5, 8, },
783           .pp_count = 2,
784           .pp_chg_id = INT_MIN, },
785
786         { .n  = "pdmc0_gclk",
787           .id = 68,
788           .r = { .max = 50000000  },
789           .pp = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0), },
790           .pp_mux_table = { 5, 9, },
791           .pp_count = 2,
792           .pp_chg_id = INT_MIN, },
793
794         { .n  = "pdmc1_gclk",
795           .id = 69,
796           .r = { .max = 50000000, },
797           .pp = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0), },
798           .pp_mux_table = { 5, 9, },
799           .pp_count = 2,
800           .pp_chg_id = INT_MIN, },
801
802         { .n  = "pit64b0_gclk",
803           .id = 70,
804           .r = { .max = 200000000 },
805           .pp = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), PLL_IDS_TO_ARR_ENTRY(IMG, DIV0),
806                   PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0),
807                   PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), },
808           .pp_mux_table = { 5, 7, 8, 9, 10, },
809           .pp_count = 5,
810           .pp_chg_id = INT_MIN, },
811
812         { .n  = "pit64b1_gclk",
813           .id = 71,
814           .r = { .max = 200000000 },
815           .pp = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), PLL_IDS_TO_ARR_ENTRY(IMG, DIV0),
816                   PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0),
817                   PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), },
818           .pp_mux_table = { 5, 7, 8, 9, 10, },
819           .pp_count = 5,
820           .pp_chg_id = INT_MIN, },
821
822         { .n  = "pit64b2_gclk",
823           .id = 72,
824           .r = { .max = 200000000 },
825           .pp = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), PLL_IDS_TO_ARR_ENTRY(IMG, DIV0),
826                   PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0),
827                   PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), },
828           .pp_mux_table = { 5, 7, 8, 9, 10, },
829           .pp_count = 5,
830           .pp_chg_id = INT_MIN, },
831
832         { .n  = "pit64b3_gclk",
833           .id = 73,
834           .r = { .max = 200000000 },
835           .pp = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), PLL_IDS_TO_ARR_ENTRY(IMG, DIV0),
836                   PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0),
837                   PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), },
838           .pp_mux_table = { 5, 7, 8, 9, 10, },
839           .pp_count = 5,
840           .pp_chg_id = INT_MIN, },
841
842         { .n  = "pit64b4_gclk",
843           .id = 74,
844           .r = { .max = 200000000 },
845           .pp = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), PLL_IDS_TO_ARR_ENTRY(IMG, DIV0),
846                   PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0),
847                   PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), },
848           .pp_mux_table = { 5, 7, 8, 9, 10, },
849           .pp_count = 5,
850           .pp_chg_id = INT_MIN, },
851
852         { .n  = "pit64b5_gclk",
853           .id = 75,
854           .r = { .max = 200000000 },
855           .pp = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), PLL_IDS_TO_ARR_ENTRY(IMG, DIV0),
856                   PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0),
857                   PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), },
858           .pp_mux_table = { 5, 7, 8, 9, 10, },
859           .pp_count = 5,
860           .pp_chg_id = INT_MIN, },
861
862         { .n  = "qspi0_gclk",
863           .id = 78,
864           .r = { .max = 200000000 },
865           .pp = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), },
866           .pp_mux_table = { 5, 8, },
867           .pp_count = 2,
868           .pp_chg_id = INT_MIN, },
869
870         { .n  = "qspi1_gclk",
871           .id = 79,
872           .r = { .max = 200000000 },
873           .pp = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), },
874           .pp_mux_table = { 5, 8, },
875           .pp_count = 2,
876           .pp_chg_id = INT_MIN, },
877
878         { .n  = "sdmmc0_gclk",
879           .id = 80,
880           .r = { .max = 208000000 },
881           .pp = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), },
882           .pp_mux_table = { 5, 8, },
883           .pp_count = 2,
884           .pp_chg_id = 4, },
885
886         { .n  = "sdmmc1_gclk",
887           .id = 81,
888           .r = { .max = 208000000 },
889           .pp = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), },
890           .pp_mux_table = { 5, 8, },
891           .pp_count = 2,
892           .pp_chg_id = 4, },
893
894         { .n  = "sdmmc2_gclk",
895           .id = 82,
896           .r = { .max = 208000000 },
897           .pp = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), },
898           .pp_mux_table = { 5, 8, },
899           .pp_count = 2,
900           .pp_chg_id = 4, },
901
902         { .n  = "spdifrx_gclk",
903           .id = 84,
904           .r = { .max = 150000000 },
905           .pp = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0), },
906           .pp_mux_table = { 5, 9, },
907           .pp_count = 2,
908           .pp_chg_id = 4, },
909
910         { .n = "spdiftx_gclk",
911           .id = 85,
912           .r = { .max = 25000000  },
913           .pp = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0), },
914           .pp_mux_table = { 5, 9, },
915           .pp_count = 2,
916           .pp_chg_id = 4, },
917
918         { .n  = "tcb0_ch0_gclk",
919           .id = 88,
920           .r = { .max = 200000000 },
921           .pp = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), PLL_IDS_TO_ARR_ENTRY(IMG, DIV0),
922                   PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0),
923                   PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), },
924           .pp_mux_table = { 5, 7, 8, 9, 10, },
925           .pp_count = 5,
926           .pp_chg_id = INT_MIN, },
927
928         { .n  = "tcb1_ch0_gclk",
929           .id = 91,
930           .r = { .max = 200000000 },
931           .pp = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), PLL_IDS_TO_ARR_ENTRY(IMG, DIV0),
932                   PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0),
933                   PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), },
934           .pp_mux_table = { 5, 7, 8, 9, 10, },
935           .pp_count = 5,
936           .pp_chg_id = INT_MIN, },
937
938         { .n  = "tcpca_gclk",
939           .id = 94,
940           .r = { .max = 32768, },
941           .pp_chg_id = INT_MIN, },
942
943         { .n  = "tcpcb_gclk",
944           .id = 95,
945           .r = { .max = 32768, },
946           .pp_chg_id = INT_MIN, },
947 };
948
949 /* MCK0 characteristics. */
950 static const struct clk_master_characteristics mck0_characteristics = {
951         .output = { .min = 32768, .max = 200000000 },
952         .divisors = { 1, 2, 4, 3, 5 },
953         .have_div3_pres = 1,
954 };
955
956 /* MCK0 layout. */
957 static const struct clk_master_layout mck0_layout = {
958         .mask = 0x773,
959         .pres_shift = 4,
960         .offset = 0x28,
961 };
962
963 /* Programmable clock layout. */
964 static const struct clk_programmable_layout programmable_layout = {
965         .pres_mask = 0xff,
966         .pres_shift = 8,
967         .css_mask = 0x1f,
968         .have_slck_mck = 0,
969         .is_pres_direct = 1,
970 };
971
972 /* Peripheral clock layout. */
973 static const struct clk_pcr_layout sama7g5_pcr_layout = {
974         .offset = 0x88,
975         .cmd = BIT(31),
976         .gckcss_mask = GENMASK(12, 8),
977         .pid_mask = GENMASK(6, 0),
978 };
979
980 static void __init sama7g5_pmc_setup(struct device_node *np)
981 {
982         const char *main_xtal_name = "main_xtal";
983         struct pmc_data *sama7g5_pmc;
984         void **alloc_mem = NULL;
985         int alloc_mem_size = 0;
986         struct regmap *regmap;
987         struct clk_hw *hw, *main_rc_hw, *main_osc_hw, *main_xtal_hw;
988         struct clk_hw *td_slck_hw, *md_slck_hw;
989         static struct clk_parent_data parent_data;
990         struct clk_hw *parent_hws[10];
991         bool bypass;
992         int i, j;
993
994         td_slck_hw = __clk_get_hw(of_clk_get_by_name(np, "td_slck"));
995         md_slck_hw = __clk_get_hw(of_clk_get_by_name(np, "md_slck"));
996         main_xtal_hw = __clk_get_hw(of_clk_get_by_name(np, main_xtal_name));
997
998         if (!td_slck_hw || !md_slck_hw || !main_xtal_hw)
999                 return;
1000
1001         regmap = device_node_to_regmap(np);
1002         if (IS_ERR(regmap))
1003                 return;
1004
1005         sama7g5_pmc = pmc_data_allocate(PMC_MCK1 + 1,
1006                                         nck(sama7g5_systemck),
1007                                         nck(sama7g5_periphck),
1008                                         nck(sama7g5_gck), 8);
1009         if (!sama7g5_pmc)
1010                 return;
1011
1012         alloc_mem = kmalloc(sizeof(void *) *
1013                             (ARRAY_SIZE(sama7g5_mckx) + ARRAY_SIZE(sama7g5_gck)),
1014                             GFP_KERNEL);
1015         if (!alloc_mem)
1016                 goto err_free;
1017
1018         main_rc_hw = at91_clk_register_main_rc_osc(regmap, "main_rc_osc", 12000000,
1019                                                    50000000);
1020         if (IS_ERR(main_rc_hw))
1021                 goto err_free;
1022
1023         bypass = of_property_read_bool(np, "atmel,osc-bypass");
1024
1025         parent_data.name = main_xtal_name;
1026         parent_data.fw_name = main_xtal_name;
1027         main_osc_hw = at91_clk_register_main_osc(regmap, "main_osc", NULL,
1028                                                  &parent_data, bypass);
1029         if (IS_ERR(main_osc_hw))
1030                 goto err_free;
1031
1032         parent_hws[0] = main_rc_hw;
1033         parent_hws[1] = main_osc_hw;
1034         hw = at91_clk_register_sam9x5_main(regmap, "mainck", NULL, parent_hws, 2);
1035         if (IS_ERR(hw))
1036                 goto err_free;
1037
1038         sama7g5_pmc->chws[PMC_MAIN] = hw;
1039
1040         for (i = 0; i < PLL_ID_MAX; i++) {
1041                 for (j = 0; j < 3; j++) {
1042                         struct clk_hw *parent_hw;
1043
1044                         if (!sama7g5_plls[i][j].n)
1045                                 continue;
1046
1047                         switch (sama7g5_plls[i][j].t) {
1048                         case PLL_TYPE_FRAC:
1049                                 switch (sama7g5_plls[i][j].p) {
1050                                 case SAMA7G5_PLL_PARENT_MAINCK:
1051                                         parent_hw = sama7g5_pmc->chws[PMC_MAIN];
1052                                         break;
1053                                 case SAMA7G5_PLL_PARENT_MAIN_XTAL:
1054                                         parent_hw = main_xtal_hw;
1055                                         break;
1056                                 default:
1057                                         /* Should not happen. */
1058                                         parent_hw = NULL;
1059                                         break;
1060                                 }
1061
1062                                 hw = sam9x60_clk_register_frac_pll(regmap,
1063                                         &pmc_pll_lock, sama7g5_plls[i][j].n,
1064                                         NULL, parent_hw, i,
1065                                         sama7g5_plls[i][j].c,
1066                                         sama7g5_plls[i][j].l,
1067                                         sama7g5_plls[i][j].f);
1068                                 break;
1069
1070                         case PLL_TYPE_DIV:
1071                                 hw = sam9x60_clk_register_div_pll(regmap,
1072                                         &pmc_pll_lock, sama7g5_plls[i][j].n,
1073                                         NULL, sama7g5_plls[i][0].hw, i,
1074                                         sama7g5_plls[i][j].c,
1075                                         sama7g5_plls[i][j].l,
1076                                         sama7g5_plls[i][j].f,
1077                                         sama7g5_plls[i][j].safe_div);
1078                                 break;
1079
1080                         default:
1081                                 continue;
1082                         }
1083
1084                         if (IS_ERR(hw))
1085                                 goto err_free;
1086
1087                         sama7g5_plls[i][j].hw = hw;
1088                         if (sama7g5_plls[i][j].eid)
1089                                 sama7g5_pmc->chws[sama7g5_plls[i][j].eid] = hw;
1090                 }
1091         }
1092
1093         hw = at91_clk_register_master_div(regmap, "mck0", NULL,
1094                                           sama7g5_plls[PLL_ID_CPU][1].hw,
1095                                           &mck0_layout, &mck0_characteristics,
1096                                           &pmc_mck0_lock, CLK_GET_RATE_NOCACHE, 5);
1097         if (IS_ERR(hw))
1098                 goto err_free;
1099
1100         sama7g5_mckx[PCK_PARENT_HW_MCK0].hw = sama7g5_pmc->chws[PMC_MCK] = hw;
1101
1102         parent_hws[0] = md_slck_hw;
1103         parent_hws[1] = td_slck_hw;
1104         parent_hws[2] = sama7g5_pmc->chws[PMC_MAIN];
1105         for (i = PCK_PARENT_HW_MCK1; i < ARRAY_SIZE(sama7g5_mckx); i++) {
1106                 u8 num_parents = 3 + sama7g5_mckx[i].ep_count;
1107                 struct clk_hw *tmp_parent_hws[8];
1108                 u32 *mux_table;
1109
1110                 mux_table = kmalloc_array(num_parents, sizeof(*mux_table),
1111                                           GFP_KERNEL);
1112                 if (!mux_table)
1113                         goto err_free;
1114
1115                 SAMA7G5_INIT_TABLE(mux_table, 3);
1116                 SAMA7G5_FILL_TABLE(&mux_table[3], sama7g5_mckx[i].ep_mux_table,
1117                                    sama7g5_mckx[i].ep_count);
1118                 for (j = 0; j < sama7g5_mckx[i].ep_count; j++) {
1119                         u8 pll_id = sama7g5_mckx[i].ep[j].pll_id;
1120                         u8 pll_compid = sama7g5_mckx[i].ep[j].pll_compid;
1121
1122                         tmp_parent_hws[j] = sama7g5_plls[pll_id][pll_compid].hw;
1123                 }
1124                 SAMA7G5_FILL_TABLE(&parent_hws[3], tmp_parent_hws,
1125                                    sama7g5_mckx[i].ep_count);
1126
1127                 hw = at91_clk_sama7g5_register_master(regmap, sama7g5_mckx[i].n,
1128                                    num_parents, NULL, parent_hws, mux_table,
1129                                    &pmc_mckX_lock, sama7g5_mckx[i].id,
1130                                    sama7g5_mckx[i].c,
1131                                    sama7g5_mckx[i].ep_chg_id);
1132                 if (IS_ERR(hw))
1133                         goto err_free;
1134
1135                 alloc_mem[alloc_mem_size++] = mux_table;
1136
1137                 sama7g5_mckx[i].hw = hw;
1138                 if (sama7g5_mckx[i].eid)
1139                         sama7g5_pmc->chws[sama7g5_mckx[i].eid] = hw;
1140         }
1141
1142         hw = at91_clk_sama7g5_register_utmi(regmap, "utmick", NULL, main_xtal_hw);
1143         if (IS_ERR(hw))
1144                 goto err_free;
1145
1146         sama7g5_pmc->chws[PMC_UTMI] = hw;
1147
1148         parent_hws[0] = md_slck_hw;
1149         parent_hws[1] = td_slck_hw;
1150         parent_hws[2] = sama7g5_pmc->chws[PMC_MAIN];
1151         parent_hws[3] = sama7g5_plls[PLL_ID_SYS][PLL_COMPID_DIV0].hw;
1152         parent_hws[4] = sama7g5_plls[PLL_ID_DDR][PLL_COMPID_DIV0].hw;
1153         parent_hws[5] = sama7g5_plls[PLL_ID_IMG][PLL_COMPID_DIV0].hw;
1154         parent_hws[6] = sama7g5_plls[PLL_ID_BAUD][PLL_COMPID_DIV0].hw;
1155         parent_hws[7] = sama7g5_plls[PLL_ID_AUDIO][PLL_COMPID_DIV0].hw;
1156         parent_hws[8] = sama7g5_plls[PLL_ID_ETH][PLL_COMPID_DIV0].hw;
1157         for (i = 0; i < 8; i++) {
1158                 char name[6];
1159
1160                 snprintf(name, sizeof(name), "prog%d", i);
1161
1162                 hw = at91_clk_register_programmable(regmap, name, NULL, parent_hws,
1163                                                     9, i,
1164                                                     &programmable_layout,
1165                                                     sama7g5_prog_mux_table);
1166                 if (IS_ERR(hw))
1167                         goto err_free;
1168
1169                 sama7g5_pmc->pchws[i] = hw;
1170         }
1171
1172         for (i = 0; i < ARRAY_SIZE(sama7g5_systemck); i++) {
1173                 hw = at91_clk_register_system(regmap, sama7g5_systemck[i].n,
1174                                               NULL, sama7g5_pmc->pchws[i],
1175                                               sama7g5_systemck[i].id, 0);
1176                 if (IS_ERR(hw))
1177                         goto err_free;
1178
1179                 sama7g5_pmc->shws[sama7g5_systemck[i].id] = hw;
1180         }
1181
1182         for (i = 0; i < ARRAY_SIZE(sama7g5_periphck); i++) {
1183                 hw = at91_clk_register_sam9x5_peripheral(regmap, &pmc_pcr_lock,
1184                                                 &sama7g5_pcr_layout,
1185                                                 sama7g5_periphck[i].n,
1186                                                 NULL,
1187                                                 sama7g5_mckx[sama7g5_periphck[i].p].hw,
1188                                                 sama7g5_periphck[i].id,
1189                                                 &sama7g5_periphck[i].r,
1190                                                 sama7g5_periphck[i].chgp ? 0 :
1191                                                 INT_MIN, 0);
1192                 if (IS_ERR(hw))
1193                         goto err_free;
1194
1195                 sama7g5_pmc->phws[sama7g5_periphck[i].id] = hw;
1196         }
1197
1198         parent_hws[0] = md_slck_hw;
1199         parent_hws[1] = td_slck_hw;
1200         parent_hws[2] = sama7g5_pmc->chws[PMC_MAIN];
1201         for (i = 0; i < ARRAY_SIZE(sama7g5_gck); i++) {
1202                 u8 num_parents = 3 + sama7g5_gck[i].pp_count;
1203                 struct clk_hw *tmp_parent_hws[8];
1204                 u32 *mux_table;
1205
1206                 mux_table = kmalloc_array(num_parents, sizeof(*mux_table),
1207                                           GFP_KERNEL);
1208                 if (!mux_table)
1209                         goto err_free;
1210
1211                 SAMA7G5_INIT_TABLE(mux_table, 3);
1212                 SAMA7G5_FILL_TABLE(&mux_table[3], sama7g5_gck[i].pp_mux_table,
1213                                    sama7g5_gck[i].pp_count);
1214                 for (j = 0; j < sama7g5_gck[i].pp_count; j++) {
1215                         u8 pll_id = sama7g5_gck[i].pp[j].pll_id;
1216                         u8 pll_compid = sama7g5_gck[i].pp[j].pll_compid;
1217
1218                         tmp_parent_hws[j] = sama7g5_plls[pll_id][pll_compid].hw;
1219                 }
1220                 SAMA7G5_FILL_TABLE(&parent_hws[3], tmp_parent_hws,
1221                                    sama7g5_gck[i].pp_count);
1222
1223                 hw = at91_clk_register_generated(regmap, &pmc_pcr_lock,
1224                                                  &sama7g5_pcr_layout,
1225                                                  sama7g5_gck[i].n, NULL,
1226                                                  parent_hws, mux_table,
1227                                                  num_parents,
1228                                                  sama7g5_gck[i].id,
1229                                                  &sama7g5_gck[i].r,
1230                                                  sama7g5_gck[i].pp_chg_id);
1231                 if (IS_ERR(hw))
1232                         goto err_free;
1233
1234                 sama7g5_pmc->ghws[sama7g5_gck[i].id] = hw;
1235                 alloc_mem[alloc_mem_size++] = mux_table;
1236         }
1237
1238         of_clk_add_hw_provider(np, of_clk_hw_pmc_get, sama7g5_pmc);
1239
1240         return;
1241
1242 err_free:
1243         if (alloc_mem) {
1244                 for (i = 0; i < alloc_mem_size; i++)
1245                         kfree(alloc_mem[i]);
1246                 kfree(alloc_mem);
1247         }
1248
1249         kfree(sama7g5_pmc);
1250 }
1251
1252 /* Some clks are used for a clocksource */
1253 CLK_OF_DECLARE(sama7g5_pmc, "microchip,sama7g5-pmc", sama7g5_pmc_setup);