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