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 
sama7g5_pmc_setup(struct device_node * np)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);
1254