xref: /linux/drivers/clk/at91/sam9x7.c (revision 3a39d672e7f48b8d6b91a09afa4b55352773b4b5)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * SAM9X7 PMC code.
4  *
5  * Copyright (C) 2023 Microchip Technology Inc. and its subsidiaries
6  *
7  * Author: Varshini Rajendran <varshini.rajendran@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 static DEFINE_SPINLOCK(pmc_pll_lock);
20 static DEFINE_SPINLOCK(mck_lock);
21 
22 /**
23  * enum pll_ids - PLL clocks identifiers
24  * @PLL_ID_PLLA:	PLLA identifier
25  * @PLL_ID_UPLL:	UPLL identifier
26  * @PLL_ID_AUDIO:	Audio PLL identifier
27  * @PLL_ID_LVDS:	LVDS PLL identifier
28  * @PLL_ID_PLLA_DIV2:	PLLA DIV2 identifier
29  * @PLL_ID_MAX:		Max PLL Identifier
30  */
31 enum pll_ids {
32 	PLL_ID_PLLA,
33 	PLL_ID_UPLL,
34 	PLL_ID_AUDIO,
35 	PLL_ID_LVDS,
36 	PLL_ID_PLLA_DIV2,
37 	PLL_ID_MAX,
38 };
39 
40 /**
41  * enum pll_type - PLL type identifiers
42  * @PLL_TYPE_FRAC:	fractional PLL identifier
43  * @PLL_TYPE_DIV:	divider PLL identifier
44  */
45 enum pll_type {
46 	PLL_TYPE_FRAC,
47 	PLL_TYPE_DIV,
48 };
49 
50 static const struct clk_master_characteristics mck_characteristics = {
51 	.output = { .min = 32000000, .max = 266666667 },
52 	.divisors = { 1, 2, 4, 3, 5},
53 	.have_div3_pres = 1,
54 };
55 
56 static const struct clk_master_layout sam9x7_master_layout = {
57 	.mask = 0x373,
58 	.pres_shift = 4,
59 	.offset = 0x28,
60 };
61 
62 /* Fractional PLL core output range. */
63 static const struct clk_range plla_core_outputs[] = {
64 	{ .min = 375000000, .max = 1600000000 },
65 };
66 
67 static const struct clk_range upll_core_outputs[] = {
68 	{ .min = 600000000, .max = 1200000000 },
69 };
70 
71 static const struct clk_range lvdspll_core_outputs[] = {
72 	{ .min = 400000000, .max = 800000000 },
73 };
74 
75 static const struct clk_range audiopll_core_outputs[] = {
76 	{ .min = 400000000, .max = 800000000 },
77 };
78 
79 static const struct clk_range plladiv2_core_outputs[] = {
80 	{ .min = 375000000, .max = 1600000000 },
81 };
82 
83 /* Fractional PLL output range. */
84 static const struct clk_range plla_outputs[] = {
85 	{ .min = 732421, .max = 800000000 },
86 };
87 
88 static const struct clk_range upll_outputs[] = {
89 	{ .min = 300000000, .max = 600000000 },
90 };
91 
92 static const struct clk_range lvdspll_outputs[] = {
93 	{ .min = 10000000, .max = 800000000 },
94 };
95 
96 static const struct clk_range audiopll_outputs[] = {
97 	{ .min = 10000000, .max = 800000000 },
98 };
99 
100 static const struct clk_range plladiv2_outputs[] = {
101 	{ .min = 366210, .max = 400000000 },
102 };
103 
104 /* PLL characteristics. */
105 static const struct clk_pll_characteristics plla_characteristics = {
106 	.input = { .min = 20000000, .max = 50000000 },
107 	.num_output = ARRAY_SIZE(plla_outputs),
108 	.output = plla_outputs,
109 	.core_output = plla_core_outputs,
110 };
111 
112 static const struct clk_pll_characteristics upll_characteristics = {
113 	.input = { .min = 20000000, .max = 50000000 },
114 	.num_output = ARRAY_SIZE(upll_outputs),
115 	.output = upll_outputs,
116 	.core_output = upll_core_outputs,
117 	.upll = true,
118 };
119 
120 static const struct clk_pll_characteristics lvdspll_characteristics = {
121 	.input = { .min = 20000000, .max = 50000000 },
122 	.num_output = ARRAY_SIZE(lvdspll_outputs),
123 	.output = lvdspll_outputs,
124 	.core_output = lvdspll_core_outputs,
125 };
126 
127 static const struct clk_pll_characteristics audiopll_characteristics = {
128 	.input = { .min = 20000000, .max = 50000000 },
129 	.num_output = ARRAY_SIZE(audiopll_outputs),
130 	.output = audiopll_outputs,
131 	.core_output = audiopll_core_outputs,
132 };
133 
134 static const struct clk_pll_characteristics plladiv2_characteristics = {
135 	.input = { .min = 20000000, .max = 50000000 },
136 	.num_output = ARRAY_SIZE(plladiv2_outputs),
137 	.output = plladiv2_outputs,
138 	.core_output = plladiv2_core_outputs,
139 };
140 
141 /* Layout for fractional PLL ID PLLA. */
142 static const struct clk_pll_layout plla_frac_layout = {
143 	.mul_mask = GENMASK(31, 24),
144 	.frac_mask = GENMASK(21, 0),
145 	.mul_shift = 24,
146 	.frac_shift = 0,
147 	.div2 = 1,
148 };
149 
150 /* Layout for fractional PLLs. */
151 static const struct clk_pll_layout pll_frac_layout = {
152 	.mul_mask = GENMASK(31, 24),
153 	.frac_mask = GENMASK(21, 0),
154 	.mul_shift = 24,
155 	.frac_shift = 0,
156 };
157 
158 /* Layout for DIV PLLs. */
159 static const struct clk_pll_layout pll_divpmc_layout = {
160 	.div_mask = GENMASK(7, 0),
161 	.endiv_mask = BIT(29),
162 	.div_shift = 0,
163 	.endiv_shift = 29,
164 };
165 
166 /* Layout for DIV PLL ID PLLADIV2. */
167 static const struct clk_pll_layout plladiv2_divpmc_layout = {
168 	.div_mask = GENMASK(7, 0),
169 	.endiv_mask = BIT(29),
170 	.div_shift = 0,
171 	.endiv_shift = 29,
172 	.div2 = 1,
173 };
174 
175 /* Layout for DIVIO dividers. */
176 static const struct clk_pll_layout pll_divio_layout = {
177 	.div_mask	= GENMASK(19, 12),
178 	.endiv_mask	= BIT(30),
179 	.div_shift	= 12,
180 	.endiv_shift	= 30,
181 };
182 
183 /*
184  * PLL clocks description
185  * @n:		clock name
186  * @p:		clock parent
187  * @l:		clock layout
188  * @t:		clock type
189  * @c:		pll characteristics
190  * @f:		clock flags
191  * @eid:	export index in sam9x7->chws[] array
192  */
193 static const struct {
194 	const char *n;
195 	const char *p;
196 	const struct clk_pll_layout *l;
197 	u8 t;
198 	const struct clk_pll_characteristics *c;
199 	unsigned long f;
200 	u8 eid;
201 } sam9x7_plls[][3] = {
202 	[PLL_ID_PLLA] = {
203 		{
204 			.n = "plla_fracck",
205 			.p = "mainck",
206 			.l = &plla_frac_layout,
207 			.t = PLL_TYPE_FRAC,
208 			/*
209 			 * This feeds plla_divpmcck which feeds CPU. It should
210 			 * not be disabled.
211 			 */
212 			.f = CLK_IS_CRITICAL | CLK_SET_RATE_GATE,
213 			.c = &plla_characteristics,
214 		},
215 
216 		{
217 			.n = "plla_divpmcck",
218 			.p = "plla_fracck",
219 			.l = &pll_divpmc_layout,
220 			.t = PLL_TYPE_DIV,
221 			/* This feeds CPU. It should not be disabled */
222 			.f = CLK_IS_CRITICAL | CLK_SET_RATE_GATE,
223 			.eid = PMC_PLLACK,
224 			.c = &plla_characteristics,
225 		},
226 	},
227 
228 	[PLL_ID_UPLL] = {
229 		{
230 			.n = "upll_fracck",
231 			.p = "main_osc",
232 			.l = &pll_frac_layout,
233 			.t = PLL_TYPE_FRAC,
234 			.f = CLK_SET_RATE_GATE,
235 			.c = &upll_characteristics,
236 		},
237 
238 		{
239 			.n = "upll_divpmcck",
240 			.p = "upll_fracck",
241 			.l = &pll_divpmc_layout,
242 			.t = PLL_TYPE_DIV,
243 			.f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE |
244 			     CLK_SET_RATE_PARENT,
245 			.eid = PMC_UTMI,
246 			.c = &upll_characteristics,
247 		},
248 	},
249 
250 	[PLL_ID_AUDIO] = {
251 		{
252 			.n = "audiopll_fracck",
253 			.p = "main_osc",
254 			.l = &pll_frac_layout,
255 			.f = CLK_SET_RATE_GATE,
256 			.c = &audiopll_characteristics,
257 			.t = PLL_TYPE_FRAC,
258 		},
259 
260 		{
261 			.n = "audiopll_divpmcck",
262 			.p = "audiopll_fracck",
263 			.l = &pll_divpmc_layout,
264 			.f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE |
265 			     CLK_SET_RATE_PARENT,
266 			.c = &audiopll_characteristics,
267 			.eid = PMC_AUDIOPMCPLL,
268 			.t = PLL_TYPE_DIV,
269 		},
270 
271 		{
272 			.n = "audiopll_diviock",
273 			.p = "audiopll_fracck",
274 			.l = &pll_divio_layout,
275 			.f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE |
276 			     CLK_SET_RATE_PARENT,
277 			.c = &audiopll_characteristics,
278 			.eid = PMC_AUDIOIOPLL,
279 			.t = PLL_TYPE_DIV,
280 		},
281 	},
282 
283 	[PLL_ID_LVDS] = {
284 		{
285 			.n = "lvdspll_fracck",
286 			.p = "main_osc",
287 			.l = &pll_frac_layout,
288 			.f = CLK_SET_RATE_GATE,
289 			.c = &lvdspll_characteristics,
290 			.t = PLL_TYPE_FRAC,
291 		},
292 
293 		{
294 			.n = "lvdspll_divpmcck",
295 			.p = "lvdspll_fracck",
296 			.l = &pll_divpmc_layout,
297 			.f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE |
298 			     CLK_SET_RATE_PARENT,
299 			.c = &lvdspll_characteristics,
300 			.eid = PMC_LVDSPLL,
301 			.t = PLL_TYPE_DIV,
302 		},
303 	},
304 
305 	[PLL_ID_PLLA_DIV2] = {
306 		{
307 			.n = "plla_div2pmcck",
308 			.p = "plla_fracck",
309 			.l = &plladiv2_divpmc_layout,
310 			/*
311 			 * This may feed critical parts of the system like timers.
312 			 * It should not be disabled.
313 			 */
314 			.f = CLK_IS_CRITICAL | CLK_SET_RATE_GATE,
315 			.c = &plladiv2_characteristics,
316 			.eid = PMC_PLLADIV2,
317 			.t = PLL_TYPE_DIV,
318 		},
319 	},
320 };
321 
322 static const struct clk_programmable_layout sam9x7_programmable_layout = {
323 	.pres_mask = 0xff,
324 	.pres_shift = 8,
325 	.css_mask = 0x1f,
326 	.have_slck_mck = 0,
327 	.is_pres_direct = 1,
328 };
329 
330 static const struct clk_pcr_layout sam9x7_pcr_layout = {
331 	.offset = 0x88,
332 	.cmd = BIT(31),
333 	.gckcss_mask = GENMASK(12, 8),
334 	.pid_mask = GENMASK(6, 0),
335 };
336 
337 static const struct {
338 	char *n;
339 	char *p;
340 	u8 id;
341 	unsigned long flags;
342 } sam9x7_systemck[] = {
343 	/*
344 	 * ddrck feeds DDR controller and is enabled by bootloader thus we need
345 	 * to keep it enabled in case there is no Linux consumer for it.
346 	 */
347 	{ .n = "ddrck",		.p = "masterck_div",	.id = 2,	.flags = CLK_IS_CRITICAL },
348 	{ .n = "uhpck",		.p = "usbck",		.id = 6 },
349 	{ .n = "pck0",		.p = "prog0",		.id = 8 },
350 	{ .n = "pck1",		.p = "prog1",		.id = 9 },
351 };
352 
353 /*
354  * Peripheral clocks description
355  * @n:		clock name
356  * @f:		clock flags
357  * @id:		peripheral id
358  */
359 static const struct {
360 	char *n;
361 	unsigned long f;
362 	u8 id;
363 } sam9x7_periphck[] = {
364 	{ .n = "pioA_clk",	.id = 2, },
365 	{ .n = "pioB_clk",	.id = 3, },
366 	{ .n = "pioC_clk",	.id = 4, },
367 	{ .n = "flex0_clk",	.id = 5, },
368 	{ .n = "flex1_clk",	.id = 6, },
369 	{ .n = "flex2_clk",	.id = 7, },
370 	{ .n = "flex3_clk",	.id = 8, },
371 	{ .n = "flex6_clk",	.id = 9, },
372 	{ .n = "flex7_clk",	.id = 10, },
373 	{ .n = "flex8_clk",	.id = 11, },
374 	{ .n = "sdmmc0_clk",	.id = 12, },
375 	{ .n = "flex4_clk",	.id = 13, },
376 	{ .n = "flex5_clk",	.id = 14, },
377 	{ .n = "flex9_clk",	.id = 15, },
378 	{ .n = "flex10_clk",	.id = 16, },
379 	{ .n = "tcb0_clk",	.id = 17, },
380 	{ .n = "pwm_clk",	.id = 18, },
381 	{ .n = "adc_clk",	.id = 19, },
382 	{ .n = "dma0_clk",	.id = 20, },
383 	{ .n = "uhphs_clk",	.id = 22, },
384 	{ .n = "udphs_clk",	.id = 23, },
385 	{ .n = "macb0_clk",	.id = 24, },
386 	{ .n = "lcd_clk",	.id = 25, },
387 	{ .n = "sdmmc1_clk",	.id = 26, },
388 	{ .n = "ssc_clk",	.id = 28, },
389 	{ .n = "can0_clk",	.id = 29, },
390 	{ .n = "can1_clk",	.id = 30, },
391 	{ .n = "flex11_clk",	.id = 32, },
392 	{ .n = "flex12_clk",	.id = 33, },
393 	{ .n = "i2s_clk",	.id = 34, },
394 	{ .n = "qspi_clk",	.id = 35, },
395 	{ .n = "gfx2d_clk",	.id = 36, },
396 	{ .n = "pit64b0_clk",	.id = 37, },
397 	{ .n = "trng_clk",	.id = 38, },
398 	{ .n = "aes_clk",	.id = 39, },
399 	{ .n = "tdes_clk",	.id = 40, },
400 	{ .n = "sha_clk",	.id = 41, },
401 	{ .n = "classd_clk",	.id = 42, },
402 	{ .n = "isi_clk",	.id = 43, },
403 	{ .n = "pioD_clk",	.id = 44, },
404 	{ .n = "tcb1_clk",	.id = 45, },
405 	{ .n = "dbgu_clk",	.id = 47, },
406 	/*
407 	 * mpddr_clk feeds DDR controller and is enabled by bootloader thus we
408 	 * need to keep it enabled in case there is no Linux consumer for it.
409 	 */
410 	{ .n = "mpddr_clk",	.id = 49,	.f = CLK_IS_CRITICAL },
411 	{ .n = "csi2dc_clk",	.id = 52, },
412 	{ .n = "csi4l_clk",	.id = 53, },
413 	{ .n = "dsi4l_clk",	.id = 54, },
414 	{ .n = "lvdsc_clk",	.id = 56, },
415 	{ .n = "pit64b1_clk",	.id = 58, },
416 	{ .n = "puf_clk",	.id = 59, },
417 	{ .n = "gmactsu_clk",	.id = 67, },
418 };
419 
420 /*
421  * Generic clock description
422  * @n:			clock name
423  * @pp:			PLL parents
424  * @pp_mux_table:	PLL parents mux table
425  * @r:			clock output range
426  * @pp_chg_id:		id in parent array of changeable PLL parent
427  * @pp_count:		PLL parents count
428  * @id:			clock id
429  */
430 static const struct {
431 	const char *n;
432 	const char *pp[8];
433 	const char pp_mux_table[8];
434 	struct clk_range r;
435 	int pp_chg_id;
436 	u8 pp_count;
437 	u8 id;
438 } sam9x7_gck[] = {
439 	{
440 		.n = "flex0_gclk",
441 		.id = 5,
442 		.pp = { "plla_div2pmcck", },
443 		.pp_mux_table = { 8, },
444 		.pp_count = 1,
445 		.pp_chg_id = INT_MIN,
446 	},
447 
448 	{
449 		.n = "flex1_gclk",
450 		.id = 6,
451 		.pp = { "plla_div2pmcck", },
452 		.pp_mux_table = { 8, },
453 		.pp_count = 1,
454 		.pp_chg_id = INT_MIN,
455 	},
456 
457 	{
458 		.n = "flex2_gclk",
459 		.id = 7,
460 		.pp = { "plla_div2pmcck", },
461 		.pp_mux_table = { 8, },
462 		.pp_count = 1,
463 		.pp_chg_id = INT_MIN,
464 	},
465 
466 	{
467 		.n = "flex3_gclk",
468 		.id = 8,
469 		.pp = { "plla_div2pmcck", },
470 		.pp_mux_table = { 8, },
471 		.pp_count = 1,
472 		.pp_chg_id = INT_MIN,
473 	},
474 
475 	{
476 		.n = "flex6_gclk",
477 		.id = 9,
478 		.pp = { "plla_div2pmcck", },
479 		.pp_mux_table = { 8, },
480 		.pp_count = 1,
481 		.pp_chg_id = INT_MIN,
482 	},
483 
484 	{
485 		.n = "flex7_gclk",
486 		.id = 10,
487 		.pp = { "plla_div2pmcck", },
488 		.pp_mux_table = { 8, },
489 		.pp_count = 1,
490 		.pp_chg_id = INT_MIN,
491 	},
492 
493 	{
494 		.n = "flex8_gclk",
495 		.id = 11,
496 		.pp = { "plla_div2pmcck", },
497 		.pp_mux_table = { 8, },
498 		.pp_count = 1,
499 		.pp_chg_id = INT_MIN,
500 	},
501 
502 	{
503 		.n = "sdmmc0_gclk",
504 		.id = 12,
505 		.r = { .max = 105000000 },
506 		.pp = { "audiopll_divpmcck", "plla_div2pmcck", },
507 		.pp_mux_table = { 6, 8, },
508 		.pp_count = 2,
509 		.pp_chg_id = INT_MIN,
510 	},
511 
512 	{
513 		.n = "flex4_gclk",
514 		.id = 13,
515 		.pp = { "plla_div2pmcck", },
516 		.pp_mux_table = { 8, },
517 		.pp_count = 1,
518 		.pp_chg_id = INT_MIN,
519 	},
520 
521 	{
522 		.n = "flex5_gclk",
523 		.id = 14,
524 		.pp = { "plla_div2pmcck", },
525 		.pp_mux_table = { 8, },
526 		.pp_count = 1,
527 		.pp_chg_id = INT_MIN,
528 	},
529 
530 	{
531 		.n = "flex9_gclk",
532 		.id = 15,
533 		.pp = { "plla_div2pmcck", },
534 		.pp_mux_table = { 8, },
535 		.pp_count = 1,
536 		.pp_chg_id = INT_MIN,
537 	},
538 
539 	{
540 		.n = "flex10_gclk",
541 		.id = 16,
542 		.pp = { "plla_div2pmcck", },
543 		.pp_mux_table = { 8, },
544 		.pp_count = 1,
545 		.pp_chg_id = INT_MIN,
546 	},
547 
548 	{
549 		.n = "tcb0_gclk",
550 		.id = 17,
551 		.pp = { "audiopll_divpmcck", "plla_div2pmcck", },
552 		.pp_mux_table = { 6, 8, },
553 		.pp_count = 2,
554 		.pp_chg_id = INT_MIN,
555 	},
556 
557 	{
558 		.n = "adc_gclk",
559 		.id = 19,
560 		.pp = { "upll_divpmcck", "plla_div2pmcck", },
561 		.pp_mux_table = { 5, 8, },
562 		.pp_count = 2,
563 		.pp_chg_id = INT_MIN,
564 	},
565 
566 	{
567 		.n = "lcd_gclk",
568 		.id = 25,
569 		.r = { .max = 75000000 },
570 		.pp = { "audiopll_divpmcck", "plla_div2pmcck", },
571 		.pp_mux_table = { 6, 8, },
572 		.pp_count = 2,
573 		.pp_chg_id = INT_MIN,
574 	},
575 
576 	{
577 		.n = "sdmmc1_gclk",
578 		.id = 26,
579 		.r = { .max = 105000000 },
580 		.pp = { "audiopll_divpmcck", "plla_div2pmcck", },
581 		.pp_mux_table = { 6, 8, },
582 		.pp_count = 2,
583 		.pp_chg_id = INT_MIN,
584 	},
585 
586 	{
587 		.n = "mcan0_gclk",
588 		.id = 29,
589 		.r = { .max = 80000000 },
590 		.pp = { "upll_divpmcck", "plla_div2pmcck", },
591 		.pp_mux_table = { 5, 8, },
592 		.pp_count = 2,
593 		.pp_chg_id = INT_MIN,
594 	},
595 
596 	{
597 		.n = "mcan1_gclk",
598 		.id = 30,
599 		.r = { .max = 80000000 },
600 		.pp = { "upll_divpmcck", "plla_div2pmcck", },
601 		.pp_mux_table = { 5, 8, },
602 		.pp_count = 2,
603 		.pp_chg_id = INT_MIN,
604 	},
605 
606 	{
607 		.n = "flex11_gclk",
608 		.id = 32,
609 		.pp = { "plla_div2pmcck", },
610 		.pp_mux_table = { 8, },
611 		.pp_count = 1,
612 		.pp_chg_id = INT_MIN,
613 	},
614 
615 	{
616 		.n = "flex12_gclk",
617 		.id = 33,
618 		.pp = { "plla_div2pmcck", },
619 		.pp_mux_table = { 8, },
620 		.pp_count = 1,
621 		.pp_chg_id = INT_MIN,
622 	},
623 
624 	{
625 		.n = "i2s_gclk",
626 		.id = 34,
627 		.r = { .max = 100000000 },
628 		.pp = { "audiopll_divpmcck", "plla_div2pmcck", },
629 		.pp_mux_table = { 6, 8, },
630 		.pp_count = 2,
631 		.pp_chg_id = INT_MIN,
632 	},
633 
634 	{
635 		.n = "qspi_gclk",
636 		.id = 35,
637 		.r = { .max = 200000000 },
638 		.pp = { "audiopll_divpmcck", "plla_div2pmcck", },
639 		.pp_mux_table = { 6, 8, },
640 		.pp_count = 2,
641 		.pp_chg_id = INT_MIN,
642 	},
643 
644 	{
645 		.n = "pit64b0_gclk",
646 		.id = 37,
647 		.pp = { "plla_div2pmcck", },
648 		.pp_mux_table = { 8, },
649 		.pp_count = 1,
650 		.pp_chg_id = INT_MIN,
651 	},
652 
653 	{
654 		.n = "classd_gclk",
655 		.id = 42,
656 		.r = { .max = 100000000 },
657 		.pp = { "audiopll_divpmcck", "plla_div2pmcck", },
658 		.pp_mux_table = { 6, 8, },
659 		.pp_count = 2,
660 		.pp_chg_id = INT_MIN,
661 	},
662 
663 	{
664 		.n = "tcb1_gclk",
665 		.id = 45,
666 		.pp = { "audiopll_divpmcck", "plla_div2pmcck", },
667 		.pp_mux_table = { 6, 8, },
668 		.pp_count = 2,
669 		.pp_chg_id = INT_MIN,
670 	},
671 
672 	{
673 		.n = "dbgu_gclk",
674 		.id = 47,
675 		.pp = { "plla_div2pmcck", },
676 		.pp_mux_table = { 8, },
677 		.pp_count = 1,
678 		.pp_chg_id = INT_MIN,
679 	},
680 
681 	{
682 		.n = "mipiphy_gclk",
683 		.id = 55,
684 		.r = { .max = 27000000 },
685 		.pp = { "plla_div2pmcck", },
686 		.pp_mux_table = { 8, },
687 		.pp_count = 1,
688 		.pp_chg_id = INT_MIN,
689 	},
690 
691 	{
692 		.n = "pit64b1_gclk",
693 		.id = 58,
694 		.pp = { "plla_div2pmcck", },
695 		.pp_mux_table = { 8, },
696 		.pp_count = 1,
697 		.pp_chg_id = INT_MIN,
698 	},
699 
700 	{
701 		.n = "gmac_gclk",
702 		.id = 67,
703 		.pp = { "audiopll_divpmcck", "plla_div2pmcck", },
704 		.pp_mux_table = { 6, 8, },
705 		.pp_count = 2,
706 		.pp_chg_id = INT_MIN,
707 	},
708 };
709 
sam9x7_pmc_setup(struct device_node * np)710 static void __init sam9x7_pmc_setup(struct device_node *np)
711 {
712 	struct clk_range range = CLK_RANGE(0, 0);
713 	const char *td_slck_name, *md_slck_name, *mainxtal_name;
714 	struct pmc_data *sam9x7_pmc;
715 	const char *parent_names[9];
716 	void **clk_mux_buffer = NULL;
717 	int clk_mux_buffer_size = 0;
718 	struct clk_hw *main_osc_hw;
719 	struct regmap *regmap;
720 	struct clk_hw *hw;
721 	int i, j;
722 
723 	i = of_property_match_string(np, "clock-names", "td_slck");
724 	if (i < 0)
725 		return;
726 
727 	td_slck_name = of_clk_get_parent_name(np, i);
728 
729 	i = of_property_match_string(np, "clock-names", "md_slck");
730 	if (i < 0)
731 		return;
732 
733 	md_slck_name = of_clk_get_parent_name(np, i);
734 
735 	i = of_property_match_string(np, "clock-names", "main_xtal");
736 	if (i < 0)
737 		return;
738 	mainxtal_name = of_clk_get_parent_name(np, i);
739 
740 	regmap = device_node_to_regmap(np);
741 	if (IS_ERR(regmap))
742 		return;
743 
744 	sam9x7_pmc = pmc_data_allocate(PMC_LVDSPLL + 1,
745 				       nck(sam9x7_systemck),
746 				       nck(sam9x7_periphck),
747 				       nck(sam9x7_gck), 8);
748 	if (!sam9x7_pmc)
749 		return;
750 
751 	clk_mux_buffer = kmalloc(sizeof(void *) *
752 				 (ARRAY_SIZE(sam9x7_gck)),
753 				 GFP_KERNEL);
754 	if (!clk_mux_buffer)
755 		goto err_free;
756 
757 	hw = at91_clk_register_main_rc_osc(regmap, "main_rc_osc", 12000000,
758 					   50000000);
759 	if (IS_ERR(hw))
760 		goto err_free;
761 
762 	hw = at91_clk_register_main_osc(regmap, "main_osc", mainxtal_name, NULL, 0);
763 	if (IS_ERR(hw))
764 		goto err_free;
765 	main_osc_hw = hw;
766 
767 	parent_names[0] = "main_rc_osc";
768 	parent_names[1] = "main_osc";
769 	hw = at91_clk_register_sam9x5_main(regmap, "mainck", parent_names, NULL, 2);
770 	if (IS_ERR(hw))
771 		goto err_free;
772 
773 	sam9x7_pmc->chws[PMC_MAIN] = hw;
774 
775 	for (i = 0; i < PLL_ID_MAX; i++) {
776 		for (j = 0; j < 3; j++) {
777 			struct clk_hw *parent_hw;
778 
779 			if (!sam9x7_plls[i][j].n)
780 				continue;
781 
782 			switch (sam9x7_plls[i][j].t) {
783 			case PLL_TYPE_FRAC:
784 				if (!strcmp(sam9x7_plls[i][j].p, "mainck"))
785 					parent_hw = sam9x7_pmc->chws[PMC_MAIN];
786 				else if (!strcmp(sam9x7_plls[i][j].p, "main_osc"))
787 					parent_hw = main_osc_hw;
788 				else
789 					parent_hw = __clk_get_hw(of_clk_get_by_name
790 								 (np, sam9x7_plls[i][j].p));
791 
792 				hw = sam9x60_clk_register_frac_pll(regmap,
793 								   &pmc_pll_lock,
794 								   sam9x7_plls[i][j].n,
795 								   sam9x7_plls[i][j].p,
796 								   parent_hw, i,
797 								   sam9x7_plls[i][j].c,
798 								   sam9x7_plls[i][j].l,
799 								   sam9x7_plls[i][j].f);
800 				break;
801 
802 			case PLL_TYPE_DIV:
803 				hw = sam9x60_clk_register_div_pll(regmap,
804 								  &pmc_pll_lock,
805 								  sam9x7_plls[i][j].n,
806 								  sam9x7_plls[i][j].p, NULL, i,
807 								  sam9x7_plls[i][j].c,
808 								  sam9x7_plls[i][j].l,
809 								  sam9x7_plls[i][j].f, 0);
810 				break;
811 
812 			default:
813 				continue;
814 			}
815 
816 			if (IS_ERR(hw))
817 				goto err_free;
818 
819 			if (sam9x7_plls[i][j].eid)
820 				sam9x7_pmc->chws[sam9x7_plls[i][j].eid] = hw;
821 		}
822 	}
823 
824 	parent_names[0] = md_slck_name;
825 	parent_names[1] = "mainck";
826 	parent_names[2] = "plla_divpmcck";
827 	parent_names[3] = "upll_divpmcck";
828 	hw = at91_clk_register_master_pres(regmap, "masterck_pres", 4,
829 					   parent_names, NULL, &sam9x7_master_layout,
830 					   &mck_characteristics, &mck_lock);
831 	if (IS_ERR(hw))
832 		goto err_free;
833 
834 	hw = at91_clk_register_master_div(regmap, "masterck_div",
835 					  "masterck_pres", NULL, &sam9x7_master_layout,
836 					  &mck_characteristics, &mck_lock,
837 					  CLK_SET_RATE_GATE, 0);
838 	if (IS_ERR(hw))
839 		goto err_free;
840 
841 	sam9x7_pmc->chws[PMC_MCK] = hw;
842 
843 	parent_names[0] = "plla_divpmcck";
844 	parent_names[1] = "upll_divpmcck";
845 	parent_names[2] = "main_osc";
846 	hw = sam9x60_clk_register_usb(regmap, "usbck", parent_names, 3);
847 	if (IS_ERR(hw))
848 		goto err_free;
849 
850 	parent_names[0] = md_slck_name;
851 	parent_names[1] = td_slck_name;
852 	parent_names[2] = "mainck";
853 	parent_names[3] = "masterck_div";
854 	parent_names[4] = "plla_divpmcck";
855 	parent_names[5] = "upll_divpmcck";
856 	parent_names[6] = "audiopll_divpmcck";
857 	for (i = 0; i < 2; i++) {
858 		char name[6];
859 
860 		snprintf(name, sizeof(name), "prog%d", i);
861 
862 		hw = at91_clk_register_programmable(regmap, name,
863 						    parent_names, NULL, 7, i,
864 						    &sam9x7_programmable_layout,
865 						    NULL);
866 		if (IS_ERR(hw))
867 			goto err_free;
868 
869 		sam9x7_pmc->pchws[i] = hw;
870 	}
871 
872 	for (i = 0; i < ARRAY_SIZE(sam9x7_systemck); i++) {
873 		hw = at91_clk_register_system(regmap, sam9x7_systemck[i].n,
874 					      sam9x7_systemck[i].p, NULL,
875 					      sam9x7_systemck[i].id,
876 					      sam9x7_systemck[i].flags);
877 		if (IS_ERR(hw))
878 			goto err_free;
879 
880 		sam9x7_pmc->shws[sam9x7_systemck[i].id] = hw;
881 	}
882 
883 	for (i = 0; i < ARRAY_SIZE(sam9x7_periphck); i++) {
884 		hw = at91_clk_register_sam9x5_peripheral(regmap, &pmc_pcr_lock,
885 							 &sam9x7_pcr_layout,
886 							 sam9x7_periphck[i].n,
887 							 "masterck_div", NULL,
888 							 sam9x7_periphck[i].id,
889 							 &range, INT_MIN,
890 							 sam9x7_periphck[i].f);
891 		if (IS_ERR(hw))
892 			goto err_free;
893 
894 		sam9x7_pmc->phws[sam9x7_periphck[i].id] = hw;
895 	}
896 
897 	parent_names[0] = md_slck_name;
898 	parent_names[1] = td_slck_name;
899 	parent_names[2] = "mainck";
900 	parent_names[3] = "masterck_div";
901 	for (i = 0; i < ARRAY_SIZE(sam9x7_gck); i++) {
902 		u8 num_parents = 4 + sam9x7_gck[i].pp_count;
903 		u32 *mux_table;
904 
905 		mux_table = kmalloc_array(num_parents, sizeof(*mux_table),
906 					  GFP_KERNEL);
907 		if (!mux_table)
908 			goto err_free;
909 
910 		PMC_INIT_TABLE(mux_table, 4);
911 		PMC_FILL_TABLE(&mux_table[4], sam9x7_gck[i].pp_mux_table,
912 			       sam9x7_gck[i].pp_count);
913 		PMC_FILL_TABLE(&parent_names[4], sam9x7_gck[i].pp,
914 			       sam9x7_gck[i].pp_count);
915 
916 		hw = at91_clk_register_generated(regmap, &pmc_pcr_lock,
917 						 &sam9x7_pcr_layout,
918 						 sam9x7_gck[i].n,
919 						 parent_names, NULL, mux_table,
920 						 num_parents,
921 						 sam9x7_gck[i].id,
922 						 &sam9x7_gck[i].r,
923 						 sam9x7_gck[i].pp_chg_id);
924 		if (IS_ERR(hw))
925 			goto err_free;
926 
927 		sam9x7_pmc->ghws[sam9x7_gck[i].id] = hw;
928 		clk_mux_buffer[clk_mux_buffer_size++] = mux_table;
929 	}
930 
931 	of_clk_add_hw_provider(np, of_clk_hw_pmc_get, sam9x7_pmc);
932 	kfree(clk_mux_buffer);
933 
934 	return;
935 
936 err_free:
937 	if (clk_mux_buffer) {
938 		for (i = 0; i < clk_mux_buffer_size; i++)
939 			kfree(clk_mux_buffer[i]);
940 		kfree(clk_mux_buffer);
941 	}
942 	kfree(sam9x7_pmc);
943 }
944 
945 /* Some clks are used for a clocksource */
946 CLK_OF_DECLARE(sam9x7_pmc, "microchip,sam9x7-pmc", sam9x7_pmc_setup);
947