1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * SAMA7G5 PMC clock support.
4  *
5  * Copyright (C) 2020 Microchip Technology Inc. and its subsidiaries
6  *
7  * Author: Claudiu Beznea <claudiu.beznea@microchip.com>
8  *
9  * Based on drivers/clk/at91/sama7g5.c from Linux.
10  */
11 
12 #include <common.h>
13 #include <clk-uclass.h>
14 #include <dm.h>
15 #include <dt-bindings/clk/at91.h>
16 #include <linux/clk-provider.h>
17 
18 #include "pmc.h"
19 
20 /**
21  * Clock identifiers to be used in conjunction with macros like
22  * AT91_TO_CLK_ID()
23  *
24  * @ID_MD_SLCK:			TD slow clock identifier
25  * @ID_TD_SLCK:			MD slow clock identifier
26  * @ID_MAIN_XTAL:		Main Xtal clock identifier
27  * @ID_MAIN_RC:			Main RC clock identifier
28  * @ID_MAIN_RC_OSC:		Main RC Oscillator clock identifier
29  * @ID_MAIN_OSC:		Main Oscillator clock identifier
30  * @ID_MAINCK:			MAINCK clock identifier
31  * @ID_PLL_CPU_FRAC:		CPU PLL fractional clock identifier
32  * @ID_PLL_CPU_DIV:		CPU PLL divider clock identifier
33  * @ID_PLL_SYS_FRAC:		SYS PLL fractional clock identifier
34  * @ID_PLL_SYS_DIV:		SYS PLL divider clock identifier
35  * @ID_PLL_DDR_FRAC:		DDR PLL fractional clock identifier
36  * @ID_PLL_DDR_DIV:		DDR PLL divider clock identifier
37  * @ID_PLL_IMG_FRAC:		IMC PLL fractional clock identifier
38  * @ID_PLL_IMG_DIV:		IMG PLL divider clock identifier
39  * @ID_PLL_BAUD_FRAC:		Baud PLL fractional clock identifier
40  * @ID_PLL_BAUD_DIV:		Baud PLL divider clock identifier
41  * @ID_PLL_AUDIO_FRAC:		Audio PLL fractional clock identifier
42  * @ID_PLL_AUDIO_DIVPMC:	Audio PLL PMC divider clock identifier
43  * @ID_PLL_AUDIO_DIVIO:		Audio PLL IO divider clock identifier
44  * @ID_PLL_ETH_FRAC:		Ethernet PLL fractional clock identifier
45  * @ID_PLL_ETH_DIV:		Ethernet PLL divider clock identifier
46 
47  * @ID_MCK0:			MCK0 clock identifier
48  * @ID_MCK1:			MCK1 clock identifier
49  * @ID_MCK2:			MCK2 clock identifier
50  * @ID_MCK3:			MCK3 clock identifier
51  * @ID_MCK4:			MCK4 clock identifier
52 
53  * @ID_UTMI:			UTMI clock identifier
54 
55  * @ID_PROG0:			Programmable 0 clock identifier
56  * @ID_PROG1:			Programmable 1 clock identifier
57  * @ID_PROG2:			Programmable 2 clock identifier
58  * @ID_PROG3:			Programmable 3 clock identifier
59  * @ID_PROG4:			Programmable 4 clock identifier
60  * @ID_PROG5:			Programmable 5 clock identifier
61  * @ID_PROG6:			Programmable 6 clock identifier
62  * @ID_PROG7:			Programmable 7 clock identifier
63 
64  * @ID_PCK0:			System clock 0 clock identifier
65  * @ID_PCK1:			System clock 1 clock identifier
66  * @ID_PCK2:			System clock 2 clock identifier
67  * @ID_PCK3:			System clock 3 clock identifier
68  * @ID_PCK4:			System clock 4 clock identifier
69  * @ID_PCK5:			System clock 5 clock identifier
70  * @ID_PCK6:			System clock 6 clock identifier
71  * @ID_PCK7:			System clock 7 clock identifier
72  */
73 enum pmc_clk_ids {
74 	ID_MD_SLCK		= 0,
75 	ID_TD_SLCK		= 1,
76 	ID_MAIN_XTAL		= 2,
77 	ID_MAIN_RC		= 3,
78 	ID_MAIN_RC_OSC		= 4,
79 	ID_MAIN_OSC		= 5,
80 	ID_MAINCK		= 6,
81 
82 	ID_PLL_CPU_FRAC		= 7,
83 	ID_PLL_CPU_DIV		= 8,
84 	ID_PLL_SYS_FRAC		= 9,
85 	ID_PLL_SYS_DIV		= 10,
86 	ID_PLL_DDR_FRAC		= 11,
87 	ID_PLL_DDR_DIV		= 12,
88 	ID_PLL_IMG_FRAC		= 13,
89 	ID_PLL_IMG_DIV		= 14,
90 	ID_PLL_BAUD_FRAC	= 15,
91 	ID_PLL_BAUD_DIV		= 16,
92 	ID_PLL_AUDIO_FRAC	= 17,
93 	ID_PLL_AUDIO_DIVPMC	= 18,
94 	ID_PLL_AUDIO_DIVIO	= 19,
95 	ID_PLL_ETH_FRAC		= 20,
96 	ID_PLL_ETH_DIV		= 21,
97 
98 	ID_MCK0			= 22,
99 	ID_MCK1			= 23,
100 	ID_MCK2			= 24,
101 	ID_MCK3			= 25,
102 	ID_MCK4			= 26,
103 
104 	ID_UTMI			= 27,
105 
106 	ID_PROG0		= 28,
107 	ID_PROG1		= 29,
108 	ID_PROG2		= 30,
109 	ID_PROG3		= 31,
110 	ID_PROG4		= 32,
111 	ID_PROG5		= 33,
112 	ID_PROG6		= 34,
113 	ID_PROG7		= 35,
114 
115 	ID_PCK0			= 36,
116 	ID_PCK1			= 37,
117 	ID_PCK2			= 38,
118 	ID_PCK3			= 39,
119 	ID_PCK4			= 40,
120 	ID_PCK5			= 41,
121 	ID_PCK6			= 42,
122 	ID_PCK7			= 43,
123 
124 	ID_MAX,
125 };
126 
127 /**
128  * PLL type identifiers
129  * @PLL_TYPE_FRAC:	fractional PLL identifier
130  * @PLL_TYPE_DIV:	divider PLL identifier
131  */
132 enum pll_type {
133 	PLL_TYPE_FRAC,
134 	PLL_TYPE_DIV,
135 };
136 
137 /* Clock names used as parents for multiple clocks. */
138 static const char *clk_names[] = {
139 	[ID_MAIN_RC_OSC]	= "main_rc_osc",
140 	[ID_MAIN_OSC]		= "main_osc",
141 	[ID_MAINCK]		= "mainck",
142 	[ID_PLL_CPU_DIV]	= "cpupll_divpmcck",
143 	[ID_PLL_SYS_DIV]	= "syspll_divpmcck",
144 	[ID_PLL_DDR_DIV]	= "ddrpll_divpmcck",
145 	[ID_PLL_IMG_DIV]	= "imgpll_divpmcck",
146 	[ID_PLL_BAUD_DIV]	= "baudpll_divpmcck",
147 	[ID_PLL_AUDIO_DIVPMC]	= "audiopll_divpmcck",
148 	[ID_PLL_AUDIO_DIVIO]	= "audiopll_diviock",
149 	[ID_PLL_ETH_DIV]	= "ethpll_divpmcck",
150 	[ID_MCK0]		= "mck0",
151 };
152 
153 /* Fractional PLL output range. */
154 static const struct clk_range pll_outputs[] = {
155 	{ .min = 2343750, .max = 1200000000 },
156 };
157 
158 /* PLL characteristics. */
159 static const struct clk_pll_characteristics pll_characteristics = {
160 	.input = { .min = 12000000, .max = 50000000 },
161 	.num_output = ARRAY_SIZE(pll_outputs),
162 	.output = pll_outputs,
163 };
164 
165 /* Layout for fractional PLLs. */
166 static const struct clk_pll_layout pll_layout_frac = {
167 	.mul_mask	= GENMASK(31, 24),
168 	.frac_mask	= GENMASK(21, 0),
169 	.mul_shift	= 24,
170 	.frac_shift	= 0,
171 };
172 
173 /* Layout for DIVPMC dividers. */
174 static const struct clk_pll_layout pll_layout_divpmc = {
175 	.div_mask	= GENMASK(7, 0),
176 	.endiv_mask	= BIT(29),
177 	.div_shift	= 0,
178 	.endiv_shift	= 29,
179 };
180 
181 /* Layout for DIVIO dividers. */
182 static const struct clk_pll_layout pll_layout_divio = {
183 	.div_mask	= GENMASK(19, 12),
184 	.endiv_mask	= BIT(30),
185 	.div_shift	= 12,
186 	.endiv_shift	= 30,
187 };
188 
189 /* MCK0 characteristics. */
190 static const struct clk_master_characteristics mck0_characteristics = {
191 	.output = { .min = 140000000, .max = 200000000 },
192 	.divisors = { 1, 2, 4, 3, 5 },
193 	.have_div3_pres = 1,
194 };
195 
196 /* MCK0 layout. */
197 static const struct clk_master_layout mck0_layout = {
198 	.mask = 0x773,
199 	.pres_shift = 4,
200 	.offset = 0x28,
201 };
202 
203 /* Programmable clock layout. */
204 static const struct clk_programmable_layout programmable_layout = {
205 	.pres_mask = 0xff,
206 	.pres_shift = 8,
207 	.css_mask = 0x1f,
208 	.have_slck_mck = 0,
209 	.is_pres_direct = 1,
210 };
211 
212 /* Peripheral clock layout. */
213 static const struct clk_pcr_layout sama7g5_pcr_layout = {
214 	.offset = 0x88,
215 	.cmd = BIT(31),
216 	.gckcss_mask = GENMASK(12, 8),
217 	.pid_mask = GENMASK(6, 0),
218 	.div_mask = GENMASK(15, 14),
219 };
220 
221 /**
222  * PLL clocks description
223  * @n:		clock name
224  * @p:		clock parent
225  * @l:		clock layout
226  * @t:		clock type
227  * @c:		true if clock is critical and cannot be disabled
228  * @id:		clock id corresponding to PLL driver
229  * @cid:	clock id corresponding to clock subsystem
230  */
231 static const struct {
232 	const char *n;
233 	const char *p;
234 	const struct clk_pll_layout *l;
235 	u8 t;
236 	u8 c;
237 	u8 id;
238 	u8 cid;
239 } sama7g5_plls[] = {
240 	{
241 		.n = "cpupll_fracck",
242 		.p = "mainck",
243 		.l = &pll_layout_frac,
244 		.t = PLL_TYPE_FRAC,
245 		.c = 1,
246 		.id = 0,
247 		.cid = ID_PLL_CPU_FRAC,
248 	},
249 
250 	{
251 		.n = "cpupll_divpmcck",
252 		.p = "cpupll_fracck",
253 		.l = &pll_layout_divpmc,
254 		.t = PLL_TYPE_DIV,
255 		.c = 1,
256 		.id = 0,
257 		.cid = ID_PLL_CPU_DIV,
258 	},
259 
260 	{
261 		.n = "syspll_fracck",
262 		.p = "mainck",
263 		.l = &pll_layout_frac,
264 		.t = PLL_TYPE_FRAC,
265 		.c = 1,
266 		.id = 1,
267 		.cid = ID_PLL_SYS_FRAC,
268 	},
269 
270 	{
271 		.n = "syspll_divpmcck",
272 		.p = "syspll_fracck",
273 		.l = &pll_layout_divpmc,
274 		.t = PLL_TYPE_DIV,
275 		.c = 1,
276 		.id = 1,
277 		.cid = ID_PLL_SYS_DIV,
278 	},
279 
280 	{
281 		.n = "ddrpll_fracck",
282 		.p = "mainck",
283 		.l = &pll_layout_frac,
284 		.t = PLL_TYPE_FRAC,
285 		.c = 1,
286 		.id = 2,
287 		.cid = ID_PLL_DDR_FRAC,
288 	},
289 
290 	{
291 		.n = "ddrpll_divpmcck",
292 		.p = "ddrpll_fracck",
293 		.l = &pll_layout_divpmc,
294 		.t = PLL_TYPE_DIV,
295 		.c = 1,
296 		.id = 2,
297 		.cid = ID_PLL_DDR_DIV,
298 	},
299 
300 	{
301 		.n = "imgpll_fracck",
302 		.p = "mainck",
303 		.l = &pll_layout_frac,
304 		.t = PLL_TYPE_FRAC,
305 		.id = 3,
306 		.cid = ID_PLL_IMG_FRAC,
307 	},
308 
309 	{
310 		.n = "imgpll_divpmcck",
311 		.p = "imgpll_fracck",
312 		.l = &pll_layout_divpmc,
313 		.t = PLL_TYPE_DIV,
314 		.id = 3,
315 		.cid = ID_PLL_IMG_DIV
316 	},
317 
318 	{
319 		.n = "baudpll_fracck",
320 		.p = "mainck",
321 		.l = &pll_layout_frac,
322 		.t = PLL_TYPE_FRAC,
323 		.id = 4,
324 		.cid = ID_PLL_BAUD_FRAC,
325 	},
326 
327 	{
328 		.n = "baudpll_divpmcck",
329 		.p = "baudpll_fracck",
330 		.l = &pll_layout_divpmc,
331 		.t = PLL_TYPE_DIV,
332 		.id = 4,
333 		.cid = ID_PLL_BAUD_DIV,
334 	},
335 
336 	{
337 		.n = "audiopll_fracck",
338 		.p = "main_osc",
339 		.l = &pll_layout_frac,
340 		.t = PLL_TYPE_FRAC,
341 		.id = 5,
342 		.cid = ID_PLL_AUDIO_FRAC,
343 	},
344 
345 	{
346 		.n = "audiopll_divpmcck",
347 		.p = "audiopll_fracck",
348 		.l = &pll_layout_divpmc,
349 		.t = PLL_TYPE_DIV,
350 		.id = 5,
351 		.cid = ID_PLL_AUDIO_DIVPMC,
352 	},
353 
354 	{
355 		.n = "audiopll_diviock",
356 		.p = "audiopll_fracck",
357 		.l = &pll_layout_divio,
358 		.t = PLL_TYPE_DIV,
359 		.id = 5,
360 		.cid = ID_PLL_AUDIO_DIVIO,
361 	},
362 
363 	{
364 		.n = "ethpll_fracck",
365 		.p = "main_osc",
366 		.l = &pll_layout_frac,
367 		.t = PLL_TYPE_FRAC,
368 		.id = 6,
369 		.cid = ID_PLL_ETH_FRAC,
370 	},
371 
372 	{
373 		.n = "ethpll_divpmcck",
374 		.p = "ethpll_fracck",
375 		.l = &pll_layout_divpmc,
376 		.t = PLL_TYPE_DIV,
377 		.id = 6,
378 		.cid = ID_PLL_ETH_DIV,
379 	},
380 };
381 
382 /**
383  * Master clock (MCK[1..4]) description
384  * @n:			clock name
385  * @ep:			extra parents names array
386  * @ep_chg_chg_id:	index in parents array that specifies the changeable
387  *			parent
388  * @ep_count:		extra parents count
389  * @ep_mux_table:	mux table for extra parents
390  * @ep_clk_mux_table:	mux table to deal with subsystem clock ids
391  * @id:			clock id corresponding to MCK driver
392  * @cid:		clock id corresponding to clock subsystem
393  * @c:			true if clock is critical and cannot be disabled
394  */
395 static const struct {
396 	const char *n;
397 	const char *ep[4];
398 	u8 ep_count;
399 	u8 ep_mux_table[4];
400 	u8 ep_clk_mux_table[4];
401 	u8 id;
402 	u8 cid;
403 	u8 c;
404 } sama7g5_mckx[] = {
405 	{
406 		.n = "mck1",
407 		.id = 1,
408 		.cid = ID_MCK1,
409 		.ep = { "syspll_divpmcck", },
410 		.ep_mux_table = { 5, },
411 		.ep_clk_mux_table = { ID_PLL_SYS_DIV, },
412 		.ep_count = 1,
413 		.c = 1,
414 	},
415 
416 	{
417 		.n = "mck2",
418 		.id = 2,
419 		.cid = ID_MCK2,
420 		.ep = { "ddrpll_divpmcck", },
421 		.ep_mux_table = { 6, },
422 		.ep_clk_mux_table = { ID_PLL_DDR_DIV, },
423 		.ep_count = 1,
424 		.c = 1,
425 	},
426 
427 	{
428 		.n = "mck3",
429 		.id = 3,
430 		.cid = ID_MCK3,
431 		.ep = { "syspll_divpmcck", "ddrpll_divpmcck", "imgpll_divpmcck", },
432 		.ep_mux_table = { 5, 6, 7, },
433 		.ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_DDR_DIV, ID_PLL_IMG_DIV, },
434 		.ep_count = 3,
435 	},
436 
437 	{
438 		.n = "mck4",
439 		.id = 4,
440 		.cid = ID_MCK4,
441 		.ep = { "syspll_divpmcck", },
442 		.ep_mux_table = { 5, },
443 		.ep_clk_mux_table = { ID_PLL_SYS_DIV, },
444 		.ep_count = 1,
445 		.c = 1,
446 	},
447 };
448 
449 /**
450  * Programmable clock description
451  * @n:			clock name
452  * @cid:		clock id corresponding to clock subsystem
453  */
454 static const struct {
455 	const char *n;
456 	u8 cid;
457 } sama7g5_prog[] = {
458 	{ .n = "prog0", .cid = ID_PROG0, },
459 	{ .n = "prog1", .cid = ID_PROG1, },
460 	{ .n = "prog2", .cid = ID_PROG2, },
461 	{ .n = "prog3", .cid = ID_PROG3, },
462 	{ .n = "prog4", .cid = ID_PROG4, },
463 	{ .n = "prog5", .cid = ID_PROG5, },
464 	{ .n = "prog6", .cid = ID_PROG6, },
465 	{ .n = "prog7", .cid = ID_PROG7, },
466 };
467 
468 /* Mux table for programmable clocks. */
469 static u32 sama7g5_prog_mux_table[] = { 0, 1, 2, 3, 5, 6, 7, 8, 9, 10, };
470 
471 /**
472  * System clock description
473  * @n:			clock name
474  * @p:			parent clock name
475  * @id:			clock id corresponding to system clock driver
476  * @cid:		clock id corresponding to clock subsystem
477  */
478 static const struct {
479 	const char *n;
480 	const char *p;
481 	u8 id;
482 	u8 cid;
483 } sama7g5_systemck[] = {
484 	{ .n = "pck0", .p = "prog0", .id = 8, .cid = ID_PCK0, },
485 	{ .n = "pck1", .p = "prog1", .id = 9, .cid = ID_PCK1, },
486 	{ .n = "pck2", .p = "prog2", .id = 10, .cid = ID_PCK2, },
487 	{ .n = "pck3", .p = "prog3", .id = 11, .cid = ID_PCK3, },
488 	{ .n = "pck4", .p = "prog4", .id = 12, .cid = ID_PCK4, },
489 	{ .n = "pck5", .p = "prog5", .id = 13, .cid = ID_PCK5, },
490 	{ .n = "pck6", .p = "prog6", .id = 14, .cid = ID_PCK6, },
491 	{ .n = "pck7", .p = "prog7", .id = 15, .cid = ID_PCK7, },
492 };
493 
494 /**
495  * Peripheral clock description
496  * @n:		clock name
497  * @p:		clock parent name
498  * @r:		clock range values
499  * @id:		clock id
500  */
501 static const struct {
502 	const char *n;
503 	const char *p;
504 	struct clk_range r;
505 	u8 id;
506 } sama7g5_periphck[] = {
507 	{ .n = "pioA_clk",	.p = "mck0", .id = 11, },
508 	{ .n = "sfr_clk",	.p = "mck1", .id = 19, },
509 	{ .n = "hsmc_clk",	.p = "mck1", .id = 21, },
510 	{ .n = "xdmac0_clk",	.p = "mck1", .id = 22, },
511 	{ .n = "xdmac1_clk",	.p = "mck1", .id = 23, },
512 	{ .n = "xdmac2_clk",	.p = "mck1", .id = 24, },
513 	{ .n = "acc_clk",	.p = "mck1", .id = 25, },
514 	{ .n = "aes_clk",	.p = "mck1", .id = 27, },
515 	{ .n = "tzaesbasc_clk",	.p = "mck1", .id = 28, },
516 	{ .n = "asrc_clk",	.p = "mck1", .id = 30, .r = { .max = 200000000, }, },
517 	{ .n = "cpkcc_clk",	.p = "mck0", .id = 32, },
518 	{ .n = "csi_clk",	.p = "mck3", .id = 33, .r = { .max = 266000000, }, },
519 	{ .n = "csi2dc_clk",	.p = "mck3", .id = 34, .r = { .max = 266000000, }, },
520 	{ .n = "eic_clk",	.p = "mck1", .id = 37, },
521 	{ .n = "flex0_clk",	.p = "mck1", .id = 38, },
522 	{ .n = "flex1_clk",	.p = "mck1", .id = 39, },
523 	{ .n = "flex2_clk",	.p = "mck1", .id = 40, },
524 	{ .n = "flex3_clk",	.p = "mck1", .id = 41, },
525 	{ .n = "flex4_clk",	.p = "mck1", .id = 42, },
526 	{ .n = "flex5_clk",	.p = "mck1", .id = 43, },
527 	{ .n = "flex6_clk",	.p = "mck1", .id = 44, },
528 	{ .n = "flex7_clk",	.p = "mck1", .id = 45, },
529 	{ .n = "flex8_clk",	.p = "mck1", .id = 46, },
530 	{ .n = "flex9_clk",	.p = "mck1", .id = 47, },
531 	{ .n = "flex10_clk",	.p = "mck1", .id = 48, },
532 	{ .n = "flex11_clk",	.p = "mck1", .id = 49, },
533 	{ .n = "gmac0_clk",	.p = "mck1", .id = 51, },
534 	{ .n = "gmac1_clk",	.p = "mck1", .id = 52, },
535 	{ .n = "gmac0_tsu_clk",	.p = "mck1", .id = 53, },
536 	{ .n = "gmac1_tsu_clk",	.p = "mck1", .id = 54, },
537 	{ .n = "icm_clk",	.p = "mck1", .id = 55, },
538 	{ .n = "isc_clk",	.p = "mck3", .id = 56, .r = { .max = 266000000, }, },
539 	{ .n = "i2smcc0_clk",	.p = "mck1", .id = 57, .r = { .max = 200000000, }, },
540 	{ .n = "i2smcc1_clk",	.p = "mck1", .id = 58, .r = { .max = 200000000, }, },
541 	{ .n = "matrix_clk",	.p = "mck1", .id = 60, },
542 	{ .n = "mcan0_clk",	.p = "mck1", .id = 61, .r = { .max = 200000000, }, },
543 	{ .n = "mcan1_clk",	.p = "mck1", .id = 62, .r = { .max = 200000000, }, },
544 	{ .n = "mcan2_clk",	.p = "mck1", .id = 63, .r = { .max = 200000000, }, },
545 	{ .n = "mcan3_clk",	.p = "mck1", .id = 64, .r = { .max = 200000000, }, },
546 	{ .n = "mcan4_clk",	.p = "mck1", .id = 65, .r = { .max = 200000000, }, },
547 	{ .n = "mcan5_clk",	.p = "mck1", .id = 66, .r = { .max = 200000000, }, },
548 	{ .n = "pdmc0_clk",	.p = "mck1", .id = 68, .r = { .max = 200000000, }, },
549 	{ .n = "pdmc1_clk",	.p = "mck1", .id = 69, .r = { .max = 200000000, }, },
550 	{ .n = "pit64b0_clk",	.p = "mck1", .id = 70, },
551 	{ .n = "pit64b1_clk",	.p = "mck1", .id = 71, },
552 	{ .n = "pit64b2_clk",	.p = "mck1", .id = 72, },
553 	{ .n = "pit64b3_clk",	.p = "mck1", .id = 73, },
554 	{ .n = "pit64b4_clk",	.p = "mck1", .id = 74, },
555 	{ .n = "pit64b5_clk",	.p = "mck1", .id = 75, },
556 	{ .n = "pwm_clk",	.p = "mck1", .id = 77, },
557 	{ .n = "qspi0_clk",	.p = "mck1", .id = 78, },
558 	{ .n = "qspi1_clk",	.p = "mck1", .id = 79, },
559 	{ .n = "sdmmc0_clk",	.p = "mck1", .id = 80, },
560 	{ .n = "sdmmc1_clk",	.p = "mck1", .id = 81, },
561 	{ .n = "sdmmc2_clk",	.p = "mck1", .id = 82, },
562 	{ .n = "sha_clk",	.p = "mck1", .id = 83, },
563 	{ .n = "spdifrx_clk",	.p = "mck1", .id = 84, .r = { .max = 200000000, }, },
564 	{ .n = "spdiftx_clk",	.p = "mck1", .id = 85, .r = { .max = 200000000, }, },
565 	{ .n = "ssc0_clk",	.p = "mck1", .id = 86, .r = { .max = 200000000, }, },
566 	{ .n = "ssc1_clk",	.p = "mck1", .id = 87, .r = { .max = 200000000, }, },
567 	{ .n = "tcb0_ch0_clk",	.p = "mck1", .id = 88, .r = { .max = 200000000, }, },
568 	{ .n = "tcb0_ch1_clk",	.p = "mck1", .id = 89, .r = { .max = 200000000, }, },
569 	{ .n = "tcb0_ch2_clk",	.p = "mck1", .id = 90, .r = { .max = 200000000, }, },
570 	{ .n = "tcb1_ch0_clk",	.p = "mck1", .id = 91, .r = { .max = 200000000, }, },
571 	{ .n = "tcb1_ch1_clk",	.p = "mck1", .id = 92, .r = { .max = 200000000, }, },
572 	{ .n = "tcb1_ch2_clk",	.p = "mck1", .id = 93, .r = { .max = 200000000, }, },
573 	{ .n = "tcpca_clk",	.p = "mck1", .id = 94, },
574 	{ .n = "tcpcb_clk",	.p = "mck1", .id = 95, },
575 	{ .n = "tdes_clk",	.p = "mck1", .id = 96, },
576 	{ .n = "trng_clk",	.p = "mck1", .id = 97, },
577 	{ .n = "udphsa_clk",	.p = "mck1", .id = 104, },
578 	{ .n = "udphsb_clk",	.p = "mck1", .id = 105, },
579 	{ .n = "uhphs_clk",	.p = "mck1", .id = 106, },
580 };
581 
582 /**
583  * Generic clock description
584  * @n:			clock name
585  * @ep:			extra parents names
586  * @ep_mux_table:	extra parents mux table
587  * @ep_clk_mux_table:	extra parents clock mux table (for CCF)
588  * @r:			clock output range
589  * @ep_count:		extra parents count
590  * @id:			clock id
591  */
592 static const struct {
593 	const char *n;
594 	const char *ep[8];
595 	const char ep_mux_table[8];
596 	const char ep_clk_mux_table[8];
597 	struct clk_range r;
598 	u8 ep_count;
599 	u8 id;
600 } sama7g5_gck[] = {
601 	{
602 		.n  = "adc_gclk",
603 		.id = 26,
604 		.r = { .max = 100000000, },
605 		.ep = { "syspll_divpmcck", "imgpll_divpmcck", "audiopll_divpmcck", },
606 		.ep_mux_table = { 5, 7, 9, },
607 		.ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_IMG_DIV,
608 				      ID_PLL_AUDIO_DIVPMC, },
609 		.ep_count = 3,
610 	},
611 
612 	{
613 		.n  = "asrc_gclk",
614 		.id = 30,
615 		.r = { .max = 200000000 },
616 		.ep = { "audiopll_divpmcck", },
617 		.ep_mux_table = { 9, },
618 		.ep_clk_mux_table = { ID_PLL_AUDIO_DIVPMC, },
619 		.ep_count = 1,
620 	},
621 
622 	{
623 		.n  = "csi_gclk",
624 		.id = 33,
625 		.r = { .max = 27000000  },
626 		.ep = { "ddrpll_divpmcck", "imgpll_divpmcck", },
627 		.ep_clk_mux_table = { ID_PLL_DDR_DIV, ID_PLL_IMG_DIV, },
628 		.ep_mux_table = { 6, 7, },
629 		.ep_count = 2,
630 	},
631 
632 	{
633 		.n  = "flex0_gclk",
634 		.id = 38,
635 		.r = { .max = 200000000 },
636 		.ep = { "syspll_divpmcck", "baudpll_divpmcck", },
637 		.ep_mux_table = { 5, 8, },
638 		.ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, },
639 		.ep_count = 2,
640 	},
641 
642 	{
643 		.n  = "flex1_gclk",
644 		.id = 39,
645 		.r = { .max = 200000000 },
646 		.ep = { "syspll_divpmcck", "baudpll_divpmcck", },
647 		.ep_mux_table = { 5, 8, },
648 		.ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, },
649 		.ep_count = 2,
650 	},
651 
652 	{
653 		.n  = "flex2_gclk",
654 		.id = 40,
655 		.r = { .max = 200000000 },
656 		.ep = { "syspll_divpmcck", "baudpll_divpmcck", },
657 		.ep_mux_table = { 5, 8, },
658 		.ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, },
659 		.ep_count = 2,
660 	},
661 
662 	{
663 		.n  = "flex3_gclk",
664 		.id = 41,
665 		.r = { .max = 200000000 },
666 		.ep = { "syspll_divpmcck", "baudpll_divpmcck", },
667 		.ep_mux_table = { 5, 8, },
668 		.ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, },
669 		.ep_count = 2,
670 	},
671 
672 	{
673 		.n  = "flex4_gclk",
674 		.id = 42,
675 		.r = { .max = 200000000 },
676 		.ep = { "syspll_divpmcck", "baudpll_divpmcck", },
677 		.ep_mux_table = { 5, 8, },
678 		.ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, },
679 		.ep_count = 2,
680 	},
681 
682 	{
683 		.n  = "flex5_gclk",
684 		.id = 43,
685 		.r = { .max = 200000000 },
686 		.ep = { "syspll_divpmcck", "baudpll_divpmcck", },
687 		.ep_mux_table = { 5, 8, },
688 		.ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, },
689 		.ep_count = 2,
690 	},
691 
692 	{
693 		.n  = "flex6_gclk",
694 		.id = 44,
695 		.r = { .max = 200000000 },
696 		.ep = { "syspll_divpmcck", "baudpll_divpmcck", },
697 		.ep_mux_table = { 5, 8, },
698 		.ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, },
699 		.ep_count = 2,
700 	},
701 
702 	{
703 		.n  = "flex7_gclk",
704 		.id = 45,
705 		.r = { .max = 200000000 },
706 		.ep = { "syspll_divpmcck", "baudpll_divpmcck", },
707 		.ep_mux_table = { 5, 8, },
708 		.ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, },
709 		.ep_count = 2,
710 	},
711 
712 	{
713 		.n  = "flex8_gclk",
714 		.id = 46,
715 		.r = { .max = 200000000 },
716 		.ep = { "syspll_divpmcck", "baudpll_divpmcck", },
717 		.ep_mux_table = { 5, 8, },
718 		.ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, },
719 		.ep_count = 2,
720 	},
721 
722 	{
723 		.n  = "flex9_gclk",
724 		.id = 47,
725 		.r = { .max = 200000000 },
726 		.ep = { "syspll_divpmcck", "baudpll_divpmcck", },
727 		.ep_mux_table = { 5, 8, },
728 		.ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, },
729 		.ep_count = 2,
730 	},
731 
732 	{
733 		.n  = "flex10_gclk",
734 		.id = 48,
735 		.r = { .max = 200000000 },
736 		.ep = { "syspll_divpmcck", "baudpll_divpmcck", },
737 		.ep_mux_table = { 5, 8, },
738 		.ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, },
739 		.ep_count = 2,
740 	},
741 
742 	{
743 		.n  = "flex11_gclk",
744 		.id = 49,
745 		.r = { .max = 200000000 },
746 		.ep = { "syspll_divpmcck", "baudpll_divpmcck", },
747 		.ep_mux_table = { 5, 8, },
748 		.ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, },
749 		.ep_count = 2,
750 	},
751 
752 	{
753 		.n  = "gmac0_gclk",
754 		.id = 51,
755 		.r = { .max = 125000000 },
756 		.ep = { "ethpll_divpmcck", },
757 		.ep_clk_mux_table = { ID_PLL_ETH_DIV, },
758 		.ep_mux_table = { 10, },
759 		.ep_count = 1,
760 	},
761 
762 	{
763 		.n  = "gmac1_gclk",
764 		.id = 52,
765 		.r = { .max = 50000000  },
766 		.ep = { "ethpll_divpmcck", },
767 		.ep_mux_table = { 10, },
768 		.ep_clk_mux_table = { ID_PLL_ETH_DIV, },
769 		.ep_count = 1,
770 	},
771 
772 	{
773 		.n  = "gmac0_tsu_gclk",
774 		.id = 53,
775 		.r = { .max = 300000000 },
776 		.ep = { "audiopll_divpmcck", "ethpll_divpmcck", },
777 		.ep_mux_table = { 9, 10, },
778 		.ep_clk_mux_table = { ID_PLL_AUDIO_DIVPMC, ID_PLL_ETH_DIV, },
779 		.ep_count = 2,
780 	},
781 
782 	{
783 		.n  = "gmac1_tsu_gclk",
784 		.id = 54,
785 		.r = { .max = 300000000 },
786 		.ep = { "audiopll_divpmcck", "ethpll_divpmcck", },
787 		.ep_mux_table = { 9, 10, },
788 		.ep_clk_mux_table = { ID_PLL_AUDIO_DIVPMC, ID_PLL_ETH_DIV, },
789 		.ep_count = 2,
790 	},
791 
792 	{
793 		.n  = "i2smcc0_gclk",
794 		.id = 57,
795 		.r = { .max = 100000000 },
796 		.ep = { "syspll_divpmcck", "audiopll_divpmcck", },
797 		.ep_mux_table = { 5, 9, },
798 		.ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_AUDIO_DIVPMC, },
799 		.ep_count = 2,
800 	},
801 
802 	{
803 		.n  = "i2smcc1_gclk",
804 		.id = 58,
805 		.r = { .max = 100000000 },
806 		.ep = { "syspll_divpmcck", "audiopll_divpmcck", },
807 		.ep_mux_table = { 5, 9, },
808 		.ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_AUDIO_DIVPMC, },
809 		.ep_count = 2,
810 	},
811 
812 	{
813 		.n  = "mcan0_gclk",
814 		.id = 61,
815 		.r = { .max = 200000000 },
816 		.ep = { "syspll_divpmcck", "baudpll_divpmcck", },
817 		.ep_mux_table = { 5, 8, },
818 		.ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, },
819 		.ep_count = 2,
820 	},
821 
822 	{
823 		.n  = "mcan1_gclk",
824 		.id = 62,
825 		.r = { .max = 200000000 },
826 		.ep = { "syspll_divpmcck", "baudpll_divpmcck", },
827 		.ep_mux_table = { 5, 8, },
828 		.ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, },
829 		.ep_count = 2,
830 	},
831 
832 	{
833 		.n  = "mcan2_gclk",
834 		.id = 63,
835 		.r = { .max = 200000000 },
836 		.ep = { "syspll_divpmcck", "baudpll_divpmcck", },
837 		.ep_mux_table = { 5, 8, },
838 		.ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, },
839 		.ep_count = 2,
840 	},
841 
842 	{
843 		.n  = "mcan3_gclk",
844 		.id = 64,
845 		.r = { .max = 200000000 },
846 		.ep = { "syspll_divpmcck", "baudpll_divpmcck", },
847 		.ep_mux_table = { 5, 8, },
848 		.ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, },
849 		.ep_count = 2,
850 	},
851 
852 	{
853 		.n  = "mcan4_gclk",
854 		.id = 65,
855 		.r = { .max = 200000000 },
856 		.ep = { "syspll_divpmcck", "baudpll_divpmcck", },
857 		.ep_mux_table = { 5, 8, },
858 		.ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, },
859 		.ep_count = 2,
860 	},
861 
862 	{
863 		.n  = "mcan5_gclk",
864 		.id = 66,
865 		.r = { .max = 200000000 },
866 		.ep = { "syspll_divpmcck", "baudpll_divpmcck", },
867 		.ep_mux_table = { 5, 8, },
868 		.ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, },
869 		.ep_count = 2,
870 	},
871 
872 	{
873 		.n  = "pdmc0_gclk",
874 		.id = 68,
875 		.r = { .max = 50000000  },
876 		.ep = { "syspll_divpmcck", "baudpll_divpmcck", },
877 		.ep_mux_table = { 5, 8, },
878 		.ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, },
879 		.ep_count = 2,
880 	},
881 
882 	{
883 		.n  = "pdmc1_gclk",
884 		.id = 69,
885 		.r = { .max = 50000000, },
886 		.ep = { "syspll_divpmcck", "baudpll_divpmcck", },
887 		.ep_mux_table = { 5, 8, },
888 		.ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, },
889 		.ep_count = 2,
890 	},
891 
892 	{
893 		.n  = "pit64b0_gclk",
894 		.id = 70,
895 		.r = { .max = 200000000 },
896 		.ep = { "syspll_divpmcck", "imgpll_divpmcck", "baudpll_divpmcck",
897 			"audiopll_divpmcck", "ethpll_divpmcck", },
898 		.ep_mux_table = { 5, 7, 8, 9, 10, },
899 		.ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_IMG_DIV,
900 				      ID_PLL_BAUD_DIV, ID_PLL_AUDIO_DIVPMC,
901 				      ID_PLL_ETH_DIV, },
902 		.ep_count = 5,
903 	},
904 
905 	{
906 		.n  = "pit64b1_gclk",
907 		.id = 71,
908 		.r = { .max = 200000000 },
909 		.ep = { "syspll_divpmcck", "imgpll_divpmcck", "baudpll_divpmcck",
910 			"audiopll_divpmcck", "ethpll_divpmcck", },
911 		.ep_mux_table = { 5, 7, 8, 9, 10, },
912 		.ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_IMG_DIV,
913 				      ID_PLL_BAUD_DIV, ID_PLL_AUDIO_DIVPMC,
914 				      ID_PLL_ETH_DIV, },
915 		.ep_count = 5,
916 	},
917 
918 	{
919 		.n  = "pit64b2_gclk",
920 		.id = 72,
921 		.r = { .max = 200000000 },
922 		.ep = { "syspll_divpmcck", "imgpll_divpmcck", "baudpll_divpmcck",
923 			"audiopll_divpmcck", "ethpll_divpmcck", },
924 		.ep_mux_table = { 5, 7, 8, 9, 10, },
925 		.ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_IMG_DIV,
926 				      ID_PLL_BAUD_DIV, ID_PLL_AUDIO_DIVPMC,
927 				      ID_PLL_ETH_DIV, },
928 		.ep_count = 5,
929 	},
930 
931 	{
932 		.n  = "pit64b3_gclk",
933 		.id = 73,
934 		.r = { .max = 200000000 },
935 		.ep = { "syspll_divpmcck", "imgpll_divpmcck", "baudpll_divpmcck",
936 			"audiopll_divpmcck", "ethpll_divpmcck", },
937 		.ep_mux_table = { 5, 7, 8, 9, 10, },
938 		.ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_IMG_DIV,
939 				      ID_PLL_BAUD_DIV, ID_PLL_AUDIO_DIVPMC,
940 				      ID_PLL_ETH_DIV, },
941 		.ep_count = 5,
942 	},
943 
944 	{
945 		.n  = "pit64b4_gclk",
946 		.id = 74,
947 		.r = { .max = 200000000 },
948 		.ep = { "syspll_divpmcck", "imgpll_divpmcck", "baudpll_divpmcck",
949 			"audiopll_divpmcck", "ethpll_divpmcck", },
950 		.ep_mux_table = { 5, 7, 8, 9, 10, },
951 		.ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_IMG_DIV,
952 				      ID_PLL_BAUD_DIV, ID_PLL_AUDIO_DIVPMC,
953 				      ID_PLL_ETH_DIV, },
954 		.ep_count = 5,
955 	},
956 
957 	{
958 		.n  = "pit64b5_gclk",
959 		.id = 75,
960 		.r = { .max = 200000000 },
961 		.ep = { "syspll_divpmcck", "imgpll_divpmcck", "baudpll_divpmcck",
962 			"audiopll_divpmcck", "ethpll_divpmcck", },
963 		.ep_mux_table = { 5, 7, 8, 9, 10, },
964 		.ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_IMG_DIV,
965 				      ID_PLL_BAUD_DIV, ID_PLL_AUDIO_DIVPMC,
966 				      ID_PLL_ETH_DIV, },
967 		.ep_count = 5,
968 	},
969 
970 	{
971 		.n  = "qspi0_gclk",
972 		.id = 78,
973 		.r = { .max = 200000000 },
974 		.ep = { "syspll_divpmcck", "baudpll_divpmcck", },
975 		.ep_mux_table = { 5, 8, },
976 		.ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_IMG_DIV,
977 				      ID_PLL_BAUD_DIV, ID_PLL_AUDIO_DIVPMC,
978 				      ID_PLL_ETH_DIV, },
979 		.ep_count = 2,
980 	},
981 
982 	{
983 		.n  = "qspi1_gclk",
984 		.id = 79,
985 		.r = { .max = 200000000 },
986 		.ep = { "syspll_divpmcck", "baudpll_divpmcck", },
987 		.ep_mux_table = { 5, 8, },
988 		.ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, },
989 		.ep_count = 2,
990 	},
991 
992 	{
993 		.n  = "sdmmc0_gclk",
994 		.id = 80,
995 		.r = { .max = 208000000 },
996 		.ep = { "syspll_divpmcck", "baudpll_divpmcck", },
997 		.ep_mux_table = { 5, 8, },
998 		.ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, },
999 		.ep_count = 2,
1000 	},
1001 
1002 	{
1003 		.n  = "sdmmc1_gclk",
1004 		.id = 81,
1005 		.r = { .max = 208000000 },
1006 		.ep = { "syspll_divpmcck", "baudpll_divpmcck", },
1007 		.ep_mux_table = { 5, 8, },
1008 		.ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, },
1009 		.ep_count = 2,
1010 	},
1011 
1012 	{
1013 		.n  = "sdmmc2_gclk",
1014 		.id = 82,
1015 		.r = { .max = 208000000 },
1016 		.ep = { "syspll_divpmcck", "baudpll_divpmcck", },
1017 		.ep_mux_table = { 5, 8, },
1018 		.ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, },
1019 		.ep_count = 2,
1020 	},
1021 
1022 	{
1023 		.n  = "spdifrx_gclk",
1024 		.id = 84,
1025 		.r = { .max = 150000000 },
1026 		.ep = { "syspll_divpmcck", "audiopll_divpmcck", },
1027 		.ep_mux_table = { 5, 9, },
1028 		.ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_AUDIO_DIVPMC, },
1029 		.ep_count = 2,
1030 	},
1031 
1032 	{
1033 		.n = "spdiftx_gclk",
1034 		.id = 85,
1035 		.r = { .max = 25000000  },
1036 		.ep = { "syspll_divpmcck", "audiopll_divpmcck", },
1037 		.ep_mux_table = { 5, 9, },
1038 		.ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_AUDIO_DIVPMC, },
1039 		.ep_count = 2,
1040 	},
1041 
1042 	{
1043 		.n  = "tcb0_ch0_gclk",
1044 		.id = 88,
1045 		.r = { .max = 200000000 },
1046 		.ep = { "syspll_divpmcck", "imgpll_divpmcck", "baudpll_divpmcck",
1047 			"audiopll_divpmcck", "ethpll_divpmcck", },
1048 		.ep_mux_table = { 5, 7, 8, 9, 10, },
1049 		.ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_IMG_DIV,
1050 				      ID_PLL_BAUD_DIV, ID_PLL_AUDIO_DIVPMC,
1051 				      ID_PLL_ETH_DIV, },
1052 		.ep_count = 5,
1053 	},
1054 
1055 	{
1056 		.n  = "tcb1_ch0_gclk",
1057 		.id = 91,
1058 		.r = { .max = 200000000 },
1059 		.ep = { "syspll_divpmcck", "imgpll_divpmcck", "baudpll_divpmcck",
1060 			"audiopll_divpmcck", "ethpll_divpmcck", },
1061 		.ep_mux_table = { 5, 7, 8, 9, 10, },
1062 		.ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_IMG_DIV,
1063 				      ID_PLL_BAUD_DIV, ID_PLL_AUDIO_DIVPMC,
1064 				      ID_PLL_ETH_DIV, },
1065 		.ep_count = 5,
1066 	},
1067 };
1068 
1069 /**
1070  * Clock setup description
1071  * @cid:	clock id corresponding to clock subsystem
1072  * @pid:	parent clock id corresponding to clock subsystem
1073  * @rate:	clock rate
1074  * @prate:	parent rate
1075  */
1076 static const struct pmc_clk_setup {
1077 	unsigned int cid;
1078 	unsigned int pid;
1079 	unsigned long rate;
1080 	unsigned long prate;
1081 } sama7g5_clk_setup[] = {
1082 	{
1083 		.cid = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_ETH_FRAC),
1084 		.rate = 625000000,
1085 	},
1086 
1087 	{
1088 		.cid = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_ETH_DIV),
1089 		.rate = 625000000,
1090 	},
1091 };
1092 
1093 #define SAMA7G5_MAX_MUX_ALLOCS		(64)
1094 
1095 #define prepare_mux_table(_allocs, _index, _dst, _src, _num, _label)	\
1096 	do {								\
1097 		int _i;							\
1098 		if ((_index) >= SAMA7G5_MAX_MUX_ALLOCS) {		\
1099 			debug("%s(): AT91: MUX: insufficient space\n",	\
1100 			      __func__);				\
1101 			goto _label;					\
1102 		}							\
1103 		(_dst) = kzalloc(sizeof(*(_dst)) * (_num), GFP_KERNEL);	\
1104 		if (!(_dst))						\
1105 			goto _label;					\
1106 		(_allocs)[(_index)++] = (_dst);				\
1107 		for (_i = 0; _i < (_num); _i++)				\
1108 			(_dst)[_i] = (_src)[_i];			\
1109 	} while (0)
1110 
sama7g5_clk_probe(struct udevice * dev)1111 static int sama7g5_clk_probe(struct udevice *dev)
1112 {
1113 	void __iomem *base = (void *)devfdt_get_addr(dev);
1114 	unsigned int *clkmuxallocs[SAMA7G5_MAX_MUX_ALLOCS];
1115 	unsigned int *muxallocs[SAMA7G5_MAX_MUX_ALLOCS];
1116 	const char *p[10];
1117 	unsigned int cm[10], m[10], *tmpclkmux, *tmpmux;
1118 	struct clk clk, *c, *parent;
1119 	bool main_osc_bypass;
1120 	int ret, muxallocindex = 0, clkmuxallocindex = 0, i, j;
1121 
1122 	if (IS_ERR(base))
1123 		return PTR_ERR(base);
1124 
1125 	memset(muxallocs,    0, ARRAY_SIZE(muxallocs));
1126 	memset(clkmuxallocs, 0, ARRAY_SIZE(clkmuxallocs));
1127 
1128 	ret = clk_get_by_index(dev, 0, &clk);
1129 	if (ret)
1130 		return ret;
1131 	ret = clk_get_by_id(clk.id, &c);
1132 	if (ret)
1133 		return ret;
1134 	clk_names[ID_TD_SLCK] = kmemdup(clk_hw_get_name(c),
1135 		strlen(clk_hw_get_name(c)) + 1, GFP_KERNEL);
1136 	if (!clk_names[ID_TD_SLCK])
1137 		return -ENOMEM;
1138 
1139 	ret = clk_get_by_index(dev, 1, &clk);
1140 	if (ret)
1141 		return ret;
1142 	ret = clk_get_by_id(clk.id, &c);
1143 	if (ret)
1144 		return ret;
1145 	clk_names[ID_MD_SLCK] = kmemdup(clk_hw_get_name(c),
1146 		strlen(clk_hw_get_name(c)) + 1, GFP_KERNEL);
1147 	if (!clk_names[ID_MD_SLCK])
1148 		return -ENOMEM;
1149 
1150 	ret = clk_get_by_index(dev, 2, &clk);
1151 	if (ret)
1152 		return ret;
1153 	clk_names[ID_MAIN_XTAL] = kmemdup(clk_hw_get_name(&clk),
1154 		strlen(clk_hw_get_name(&clk)) + 1, GFP_KERNEL);
1155 	if (!clk_names[ID_MAIN_XTAL])
1156 		return -ENOMEM;
1157 
1158 	ret = clk_get_by_index(dev, 3, &clk);
1159 	if (ret)
1160 		goto fail;
1161 	clk_names[ID_MAIN_RC] = kmemdup(clk_hw_get_name(&clk),
1162 		strlen(clk_hw_get_name(&clk)) + 1, GFP_KERNEL);
1163 	if (ret)
1164 		goto fail;
1165 
1166 	main_osc_bypass = dev_read_bool(dev, "atmel,main-osc-bypass");
1167 
1168 	/* Register main rc oscillator. */
1169 	clk_dm(AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MAIN_RC_OSC),
1170 		at91_clk_main_rc(base, clk_names[ID_MAIN_RC_OSC],
1171 		clk_names[ID_MAIN_RC]));
1172 
1173 	/* Register main oscillator. */
1174 	clk_dm(AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MAIN_OSC),
1175 		at91_clk_main_osc(base, clk_names[ID_MAIN_OSC],
1176 		clk_names[ID_MAIN_XTAL], main_osc_bypass));
1177 
1178 	/* Register mainck. */
1179 	p[0] = clk_names[ID_MAIN_RC_OSC];
1180 	p[1] = clk_names[ID_MAIN_OSC];
1181 	cm[0] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MAIN_RC_OSC);
1182 	cm[1] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MAIN_OSC);
1183 	prepare_mux_table(clkmuxallocs, clkmuxallocindex, tmpclkmux, cm, 2,
1184 			  fail);
1185 	clk_dm(AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MAINCK),
1186 		at91_clk_sam9x5_main(base, clk_names[ID_MAINCK], p,
1187 		2, tmpclkmux, PMC_TYPE_CORE));
1188 
1189 	/* Register PLL fracs clocks. */
1190 	for (i = 0; i < ARRAY_SIZE(sama7g5_plls); i++) {
1191 		if (sama7g5_plls[i].t != PLL_TYPE_FRAC)
1192 			continue;
1193 
1194 		clk_dm(AT91_TO_CLK_ID(PMC_TYPE_CORE, sama7g5_plls[i].cid),
1195 			sam9x60_clk_register_frac_pll(base, sama7g5_plls[i].n,
1196 			sama7g5_plls[i].p, sama7g5_plls[i].id,
1197 			&pll_characteristics, sama7g5_plls[i].l,
1198 			sama7g5_plls[i].c));
1199 	}
1200 
1201 	/* Register PLL div clocks. */
1202 	for (i = 0; i < ARRAY_SIZE(sama7g5_plls); i++) {
1203 		if (sama7g5_plls[i].t != PLL_TYPE_DIV)
1204 			continue;
1205 
1206 		clk_dm(AT91_TO_CLK_ID(PMC_TYPE_CORE, sama7g5_plls[i].cid),
1207 			sam9x60_clk_register_div_pll(base, sama7g5_plls[i].n,
1208 			sama7g5_plls[i].p, sama7g5_plls[i].id,
1209 			&pll_characteristics, sama7g5_plls[i].l,
1210 			sama7g5_plls[i].c));
1211 	}
1212 
1213 	/* Register MCK0 clock. */
1214 	p[0] = clk_names[ID_MD_SLCK];
1215 	p[1] = clk_names[ID_MAINCK];
1216 	p[2] = clk_names[ID_PLL_CPU_DIV];
1217 	p[3] = clk_names[ID_PLL_SYS_DIV];
1218 	cm[0] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MD_SLCK);
1219 	cm[1] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MAINCK);
1220 	cm[2] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_CPU_DIV);
1221 	cm[3] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_SYS_DIV);
1222 	prepare_mux_table(clkmuxallocs, clkmuxallocindex, tmpclkmux, cm, 2,
1223 			  fail);
1224 	clk_dm(AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MCK0),
1225 		at91_clk_register_master(base, clk_names[ID_MCK0], p,
1226 		4, &mck0_layout, &mck0_characteristics, tmpclkmux));
1227 
1228 	/* Register MCK1-4 clocks. */
1229 	p[0] = clk_names[ID_MD_SLCK];
1230 	p[1] = clk_names[ID_TD_SLCK];
1231 	p[2] = clk_names[ID_MAINCK];
1232 	p[3] = clk_names[ID_MCK0];
1233 	m[0] = 0;
1234 	m[1] = 1;
1235 	m[2] = 2;
1236 	m[3] = 3;
1237 	cm[0] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MD_SLCK);
1238 	cm[1] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_TD_SLCK);
1239 	cm[2] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MAINCK);
1240 	cm[3] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MCK0);
1241 	for (i = 0; i < ARRAY_SIZE(sama7g5_mckx); i++) {
1242 		for (j = 0; j < sama7g5_mckx[i].ep_count; j++) {
1243 			p[4 + j] = sama7g5_mckx[i].ep[j];
1244 			m[4 + j] = sama7g5_mckx[i].ep_mux_table[j];
1245 			cm[4 + j] = AT91_TO_CLK_ID(PMC_TYPE_CORE,
1246 					sama7g5_mckx[i].ep_clk_mux_table[j]);
1247 		}
1248 
1249 		prepare_mux_table(clkmuxallocs, clkmuxallocindex, tmpclkmux, cm,
1250 			4 + sama7g5_mckx[i].ep_count, fail);
1251 		prepare_mux_table(muxallocs, muxallocindex, tmpmux, m,
1252 			4 + sama7g5_mckx[i].ep_count, fail);
1253 
1254 		clk_dm(AT91_TO_CLK_ID(PMC_TYPE_CORE, sama7g5_mckx[i].cid),
1255 			at91_clk_sama7g5_register_master(base,
1256 			sama7g5_mckx[i].n, p, 4 + sama7g5_mckx[i].ep_count,
1257 			tmpmux, tmpclkmux, sama7g5_mckx[i].c,
1258 			sama7g5_mckx[i].id));
1259 	}
1260 
1261 	/* Register UTMI clock. */
1262 	clk_dm(AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_UTMI),
1263 		at91_clk_sama7g5_register_utmi(base, "utmick",
1264 		clk_names[ID_MAIN_XTAL]));
1265 
1266 	/* Register programmable clocks. */
1267 	p[0] = clk_names[ID_MD_SLCK];
1268 	p[1] = clk_names[ID_TD_SLCK];
1269 	p[2] = clk_names[ID_MAINCK];
1270 	p[3] = clk_names[ID_MCK0];
1271 	p[4] = clk_names[ID_PLL_SYS_DIV];
1272 	p[5] = clk_names[ID_PLL_DDR_DIV];
1273 	p[6] = clk_names[ID_PLL_IMG_DIV];
1274 	p[7] = clk_names[ID_PLL_BAUD_DIV];
1275 	p[8] = clk_names[ID_PLL_AUDIO_DIVPMC];
1276 	p[9] = clk_names[ID_PLL_ETH_DIV];
1277 	cm[0] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MD_SLCK);
1278 	cm[1] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_TD_SLCK);
1279 	cm[2] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MAINCK);
1280 	cm[3] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MCK0);
1281 	cm[4] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_SYS_DIV);
1282 	cm[5] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_DDR_DIV);
1283 	cm[6] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_IMG_DIV);
1284 	cm[7] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_BAUD_DIV);
1285 	cm[8] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_AUDIO_DIVPMC);
1286 	cm[9] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_ETH_DIV);
1287 	for (i = 0; i < ARRAY_SIZE(sama7g5_prog); i++) {
1288 		prepare_mux_table(clkmuxallocs, clkmuxallocindex, tmpclkmux, cm,
1289 			10, fail);
1290 
1291 		clk_dm(AT91_TO_CLK_ID(PMC_TYPE_CORE, sama7g5_prog[i].cid),
1292 			at91_clk_register_programmable(base, sama7g5_prog[i].n,
1293 			p, 10, i, &programmable_layout, tmpclkmux,
1294 			sama7g5_prog_mux_table));
1295 	}
1296 
1297 	/* System clocks. */
1298 	for (i = 0; i < ARRAY_SIZE(sama7g5_systemck); i++) {
1299 		clk_dm(AT91_TO_CLK_ID(PMC_TYPE_SYSTEM, sama7g5_systemck[i].cid),
1300 			at91_clk_register_system(base, sama7g5_systemck[i].n,
1301 			sama7g5_systemck[i].p, sama7g5_systemck[i].id));
1302 	}
1303 
1304 	/* Peripheral clocks. */
1305 	for (i = 0; i < ARRAY_SIZE(sama7g5_periphck); i++) {
1306 		clk_dm(AT91_TO_CLK_ID(PMC_TYPE_PERIPHERAL,
1307 			sama7g5_periphck[i].id),
1308 			at91_clk_register_sam9x5_peripheral(base,
1309 			&sama7g5_pcr_layout, sama7g5_periphck[i].n,
1310 			sama7g5_periphck[i].p, sama7g5_periphck[i].id,
1311 			&sama7g5_periphck[i].r));
1312 	}
1313 
1314 	/* Generic clocks. */
1315 	p[0] = clk_names[ID_MD_SLCK];
1316 	p[1] = clk_names[ID_TD_SLCK];
1317 	p[2] = clk_names[ID_MAINCK];
1318 	p[3] = clk_names[ID_MCK0];
1319 	m[0] = 0;
1320 	m[1] = 1;
1321 	m[2] = 2;
1322 	m[3] = 3;
1323 	cm[0] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MD_SLCK);
1324 	cm[1] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_TD_SLCK);
1325 	cm[2] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MAINCK);
1326 	cm[3] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MCK0);
1327 	for (i = 0; i < ARRAY_SIZE(sama7g5_gck); i++) {
1328 		for (j = 0; j < sama7g5_gck[i].ep_count; j++) {
1329 			p[4 + j] = sama7g5_gck[i].ep[j];
1330 			m[4 + j] = sama7g5_gck[i].ep_mux_table[j];
1331 			cm[4 + j] = AT91_TO_CLK_ID(PMC_TYPE_CORE,
1332 					sama7g5_gck[i].ep_clk_mux_table[j]);
1333 		}
1334 
1335 		prepare_mux_table(clkmuxallocs, clkmuxallocindex, tmpclkmux, cm,
1336 			4 + sama7g5_gck[i].ep_count, fail);
1337 		prepare_mux_table(muxallocs, muxallocindex, tmpmux, m,
1338 			4 + sama7g5_gck[i].ep_count, fail);
1339 
1340 		clk_dm(AT91_TO_CLK_ID(PMC_TYPE_GCK, sama7g5_gck[i].id),
1341 			at91_clk_register_generic(base, &sama7g5_pcr_layout,
1342 			sama7g5_gck[i].n, p, tmpclkmux, tmpmux,
1343 			4 + sama7g5_gck[i].ep_count, sama7g5_gck[i].id,
1344 			&sama7g5_gck[i].r));
1345 	}
1346 
1347 	/* Setup clocks. */
1348 	for (i = 0; i < ARRAY_SIZE(sama7g5_clk_setup); i++) {
1349 		ret = clk_get_by_id(sama7g5_clk_setup[i].cid, &c);
1350 		if (ret)
1351 			goto fail;
1352 
1353 		if (sama7g5_clk_setup[i].pid) {
1354 			ret = clk_get_by_id(sama7g5_clk_setup[i].pid, &parent);
1355 			if (ret)
1356 				goto fail;
1357 
1358 			ret = clk_set_parent(c, parent);
1359 			if (ret)
1360 				goto fail;
1361 
1362 			if (sama7g5_clk_setup[i].prate) {
1363 				ret = clk_set_rate(parent,
1364 					sama7g5_clk_setup[i].prate);
1365 				if (ret < 0)
1366 					goto fail;
1367 			}
1368 		}
1369 
1370 		if (sama7g5_clk_setup[i].rate) {
1371 			ret = clk_set_rate(c, sama7g5_clk_setup[i].rate);
1372 			if (ret < 0)
1373 				goto fail;
1374 		}
1375 	}
1376 
1377 	return 0;
1378 
1379 fail:
1380 	for (i = 0; i < ARRAY_SIZE(muxallocs); i++)
1381 		kfree(muxallocs[i]);
1382 
1383 	for (i = 0; i < ARRAY_SIZE(clkmuxallocs); i++)
1384 		kfree(clkmuxallocs[i]);
1385 
1386 	return -ENOMEM;
1387 }
1388 
1389 static const struct udevice_id sama7g5_clk_ids[] = {
1390 	{ .compatible = "microchip,sama7g5-pmc" },
1391 	{ /* Sentinel. */ },
1392 };
1393 
1394 U_BOOT_DRIVER(at91_sama7g5_pmc) = {
1395 	.name = "at91-sama7g5-pmc",
1396 	.id = UCLASS_CLK,
1397 	.of_match = sama7g5_clk_ids,
1398 	.ops = &at91_clk_ops,
1399 	.probe = sama7g5_clk_probe,
1400 	.flags = DM_FLAG_PRE_RELOC,
1401 };
1402