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