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