1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * SAMA7G5 PMC clock support.
4 *
5 * Copyright (C) 2020 Microchip Technology Inc. and its subsidiaries
6 *
7 * Author: Claudiu Beznea <claudiu.beznea@microchip.com>
8 *
9 * Based on drivers/clk/at91/sama7g5.c from Linux.
10 */
11
12#include <common.h>
13#include <clk-uclass.h>
14#include <dm.h>
15#include <dt-bindings/clk/at91.h>
16#include <linux/clk-provider.h>
17
18#include "pmc.h"
19
20/**
21 * Clock identifiers to be used in conjunction with macros like
22 * AT91_TO_CLK_ID()
23 *
24 * @ID_MD_SLCK:			TD slow clock identifier
25 * @ID_TD_SLCK:			MD slow clock identifier
26 * @ID_MAIN_XTAL:		Main Xtal clock identifier
27 * @ID_MAIN_RC:			Main RC clock identifier
28 * @ID_MAIN_RC_OSC:		Main RC Oscillator clock identifier
29 * @ID_MAIN_OSC:		Main Oscillator clock identifier
30 * @ID_MAINCK:			MAINCK clock identifier
31 * @ID_PLL_CPU_FRAC:		CPU PLL fractional clock identifier
32 * @ID_PLL_CPU_DIV:		CPU PLL divider clock identifier
33 * @ID_PLL_SYS_FRAC:		SYS PLL fractional clock identifier
34 * @ID_PLL_SYS_DIV:		SYS PLL divider clock identifier
35 * @ID_PLL_DDR_FRAC:		DDR PLL fractional clock identifier
36 * @ID_PLL_DDR_DIV:		DDR PLL divider clock identifier
37 * @ID_PLL_IMG_FRAC:		IMC PLL fractional clock identifier
38 * @ID_PLL_IMG_DIV:		IMG PLL divider clock identifier
39 * @ID_PLL_BAUD_FRAC:		Baud PLL fractional clock identifier
40 * @ID_PLL_BAUD_DIV:		Baud PLL divider clock identifier
41 * @ID_PLL_AUDIO_FRAC:		Audio PLL fractional clock identifier
42 * @ID_PLL_AUDIO_DIVPMC:	Audio PLL PMC divider clock identifier
43 * @ID_PLL_AUDIO_DIVIO:		Audio PLL IO divider clock identifier
44 * @ID_PLL_ETH_FRAC:		Ethernet PLL fractional clock identifier
45 * @ID_PLL_ETH_DIV:		Ethernet PLL divider clock identifier
46
47 * @ID_MCK0_PRES:		MCK0 PRES clock identifier
48 * @ID_MCK0_DIV:		MCK0 DIV clock identifier
49 * @ID_MCK1:			MCK1 clock identifier
50 * @ID_MCK2:			MCK2 clock identifier
51 * @ID_MCK3:			MCK3 clock identifier
52 * @ID_MCK4:			MCK4 clock identifier
53
54 * @ID_UTMI:			UTMI clock identifier
55
56 * @ID_PROG0:			Programmable 0 clock identifier
57 * @ID_PROG1:			Programmable 1 clock identifier
58 * @ID_PROG2:			Programmable 2 clock identifier
59 * @ID_PROG3:			Programmable 3 clock identifier
60 * @ID_PROG4:			Programmable 4 clock identifier
61 * @ID_PROG5:			Programmable 5 clock identifier
62 * @ID_PROG6:			Programmable 6 clock identifier
63 * @ID_PROG7:			Programmable 7 clock identifier
64
65 * @ID_PCK0:			System clock 0 clock identifier
66 * @ID_PCK1:			System clock 1 clock identifier
67 * @ID_PCK2:			System clock 2 clock identifier
68 * @ID_PCK3:			System clock 3 clock identifier
69 * @ID_PCK4:			System clock 4 clock identifier
70 * @ID_PCK5:			System clock 5 clock identifier
71 * @ID_PCK6:			System clock 6 clock identifier
72 * @ID_PCK7:			System clock 7 clock identifier
73 */
74enum pmc_clk_ids {
75	ID_MD_SLCK		= 0,
76	ID_TD_SLCK		= 1,
77	ID_MAIN_XTAL		= 2,
78	ID_MAIN_RC		= 3,
79	ID_MAIN_RC_OSC		= 4,
80	ID_MAIN_OSC		= 5,
81	ID_MAINCK		= 6,
82
83	ID_PLL_CPU_FRAC		= 7,
84	ID_PLL_CPU_DIV		= 8,
85	ID_PLL_SYS_FRAC		= 9,
86	ID_PLL_SYS_DIV		= 10,
87	ID_PLL_DDR_FRAC		= 11,
88	ID_PLL_DDR_DIV		= 12,
89	ID_PLL_IMG_FRAC		= 13,
90	ID_PLL_IMG_DIV		= 14,
91	ID_PLL_BAUD_FRAC	= 15,
92	ID_PLL_BAUD_DIV		= 16,
93	ID_PLL_AUDIO_FRAC	= 17,
94	ID_PLL_AUDIO_DIVPMC	= 18,
95	ID_PLL_AUDIO_DIVIO	= 19,
96	ID_PLL_ETH_FRAC		= 20,
97	ID_PLL_ETH_DIV		= 21,
98
99	ID_MCK0_DIV		= 22,
100	ID_MCK1			= 23,
101	ID_MCK2			= 24,
102	ID_MCK3			= 25,
103	ID_MCK4			= 26,
104
105	ID_UTMI			= 27,
106
107	ID_PROG0		= 28,
108	ID_PROG1		= 29,
109	ID_PROG2		= 30,
110	ID_PROG3		= 31,
111	ID_PROG4		= 32,
112	ID_PROG5		= 33,
113	ID_PROG6		= 34,
114	ID_PROG7		= 35,
115
116	ID_PCK0			= 36,
117	ID_PCK1			= 37,
118	ID_PCK2			= 38,
119	ID_PCK3			= 39,
120	ID_PCK4			= 40,
121	ID_PCK5			= 41,
122	ID_PCK6			= 42,
123	ID_PCK7			= 43,
124
125	ID_MCK0_PRES		= 44,
126
127	ID_MAX,
128};
129
130/**
131 * PLL type identifiers
132 * @PLL_TYPE_FRAC:	fractional PLL identifier
133 * @PLL_TYPE_DIV:	divider PLL identifier
134 */
135enum pll_type {
136	PLL_TYPE_FRAC,
137	PLL_TYPE_DIV,
138};
139
140/* Clock names used as parents for multiple clocks. */
141static const char *clk_names[] = {
142	[ID_MAIN_RC_OSC]	= "main_rc_osc",
143	[ID_MAIN_OSC]		= "main_osc",
144	[ID_MAINCK]		= "mainck",
145	[ID_PLL_CPU_DIV]	= "cpupll_divpmcck",
146	[ID_PLL_SYS_DIV]	= "syspll_divpmcck",
147	[ID_PLL_DDR_DIV]	= "ddrpll_divpmcck",
148	[ID_PLL_IMG_DIV]	= "imgpll_divpmcck",
149	[ID_PLL_BAUD_DIV]	= "baudpll_divpmcck",
150	[ID_PLL_AUDIO_DIVPMC]	= "audiopll_divpmcck",
151	[ID_PLL_AUDIO_DIVIO]	= "audiopll_diviock",
152	[ID_PLL_ETH_DIV]	= "ethpll_divpmcck",
153	[ID_MCK0_DIV]		= "mck0_div",
154	[ID_MCK0_PRES]		= "mck0_pres",
155};
156
157/* Fractional PLL output range. */
158static const struct clk_range pll_outputs[] = {
159	{ .min = 2343750, .max = 1200000000 },
160};
161
162/* PLL characteristics. */
163static const struct clk_pll_characteristics pll_characteristics = {
164	.input = { .min = 12000000, .max = 50000000 },
165	.num_output = ARRAY_SIZE(pll_outputs),
166	.output = pll_outputs,
167};
168
169/* Layout for fractional PLLs. */
170static const struct clk_pll_layout pll_layout_frac = {
171	.mul_mask	= GENMASK(31, 24),
172	.frac_mask	= GENMASK(21, 0),
173	.mul_shift	= 24,
174	.frac_shift	= 0,
175};
176
177/* Layout for DIVPMC dividers. */
178static const struct clk_pll_layout pll_layout_divpmc = {
179	.div_mask	= GENMASK(7, 0),
180	.endiv_mask	= BIT(29),
181	.div_shift	= 0,
182	.endiv_shift	= 29,
183};
184
185/* Layout for DIVIO dividers. */
186static const struct clk_pll_layout pll_layout_divio = {
187	.div_mask	= GENMASK(19, 12),
188	.endiv_mask	= BIT(30),
189	.div_shift	= 12,
190	.endiv_shift	= 30,
191};
192
193/* MCK0 characteristics. */
194static const struct clk_master_characteristics mck0_characteristics = {
195	.output = { .min = 140000000, .max = 200000000 },
196	.divisors = { 1, 2, 4, 3, 5 },
197	.have_div3_pres = 1,
198};
199
200/* MCK0 layout. */
201static const struct clk_master_layout mck0_layout = {
202	.mask = 0x773,
203	.pres_shift = 4,
204	.offset = 0x28,
205};
206
207/* Programmable clock layout. */
208static const struct clk_programmable_layout programmable_layout = {
209	.pres_mask = 0xff,
210	.pres_shift = 8,
211	.css_mask = 0x1f,
212	.have_slck_mck = 0,
213	.is_pres_direct = 1,
214};
215
216/* Peripheral clock layout. */
217static const struct clk_pcr_layout sama7g5_pcr_layout = {
218	.offset = 0x88,
219	.cmd = BIT(31),
220	.gckcss_mask = GENMASK(12, 8),
221	.pid_mask = GENMASK(6, 0),
222	.div_mask = GENMASK(15, 14),
223};
224
225/**
226 * PLL clocks description
227 * @n:		clock name
228 * @p:		clock parent
229 * @l:		clock layout
230 * @t:		clock type
231 * @c:		true if clock is critical and cannot be disabled
232 * @id:		clock id corresponding to PLL driver
233 * @cid:	clock id corresponding to clock subsystem
234 */
235static const struct {
236	const char *n;
237	const char *p;
238	const struct clk_pll_layout *l;
239	u8 t;
240	u8 c;
241	u8 id;
242	u8 cid;
243} sama7g5_plls[] = {
244	{
245		.n = "cpupll_fracck",
246		.p = "mainck",
247		.l = &pll_layout_frac,
248		.t = PLL_TYPE_FRAC,
249		.c = 1,
250		.id = 0,
251		.cid = ID_PLL_CPU_FRAC,
252	},
253
254	{
255		.n = "cpupll_divpmcck",
256		.p = "cpupll_fracck",
257		.l = &pll_layout_divpmc,
258		.t = PLL_TYPE_DIV,
259		.c = 1,
260		.id = 0,
261		.cid = ID_PLL_CPU_DIV,
262	},
263
264	{
265		.n = "syspll_fracck",
266		.p = "mainck",
267		.l = &pll_layout_frac,
268		.t = PLL_TYPE_FRAC,
269		.c = 1,
270		.id = 1,
271		.cid = ID_PLL_SYS_FRAC,
272	},
273
274	{
275		.n = "syspll_divpmcck",
276		.p = "syspll_fracck",
277		.l = &pll_layout_divpmc,
278		.t = PLL_TYPE_DIV,
279		.c = 1,
280		.id = 1,
281		.cid = ID_PLL_SYS_DIV,
282	},
283
284	{
285		.n = "ddrpll_fracck",
286		.p = "mainck",
287		.l = &pll_layout_frac,
288		.t = PLL_TYPE_FRAC,
289		.c = 1,
290		.id = 2,
291		.cid = ID_PLL_DDR_FRAC,
292	},
293
294	{
295		.n = "ddrpll_divpmcck",
296		.p = "ddrpll_fracck",
297		.l = &pll_layout_divpmc,
298		.t = PLL_TYPE_DIV,
299		.c = 1,
300		.id = 2,
301		.cid = ID_PLL_DDR_DIV,
302	},
303
304	{
305		.n = "imgpll_fracck",
306		.p = "mainck",
307		.l = &pll_layout_frac,
308		.t = PLL_TYPE_FRAC,
309		.id = 3,
310		.cid = ID_PLL_IMG_FRAC,
311	},
312
313	{
314		.n = "imgpll_divpmcck",
315		.p = "imgpll_fracck",
316		.l = &pll_layout_divpmc,
317		.t = PLL_TYPE_DIV,
318		.id = 3,
319		.cid = ID_PLL_IMG_DIV
320	},
321
322	{
323		.n = "baudpll_fracck",
324		.p = "mainck",
325		.l = &pll_layout_frac,
326		.t = PLL_TYPE_FRAC,
327		.id = 4,
328		.cid = ID_PLL_BAUD_FRAC,
329	},
330
331	{
332		.n = "baudpll_divpmcck",
333		.p = "baudpll_fracck",
334		.l = &pll_layout_divpmc,
335		.t = PLL_TYPE_DIV,
336		.id = 4,
337		.cid = ID_PLL_BAUD_DIV,
338	},
339
340	{
341		.n = "audiopll_fracck",
342		.p = "main_osc",
343		.l = &pll_layout_frac,
344		.t = PLL_TYPE_FRAC,
345		.id = 5,
346		.cid = ID_PLL_AUDIO_FRAC,
347	},
348
349	{
350		.n = "audiopll_divpmcck",
351		.p = "audiopll_fracck",
352		.l = &pll_layout_divpmc,
353		.t = PLL_TYPE_DIV,
354		.id = 5,
355		.cid = ID_PLL_AUDIO_DIVPMC,
356	},
357
358	{
359		.n = "audiopll_diviock",
360		.p = "audiopll_fracck",
361		.l = &pll_layout_divio,
362		.t = PLL_TYPE_DIV,
363		.id = 5,
364		.cid = ID_PLL_AUDIO_DIVIO,
365	},
366
367	{
368		.n = "ethpll_fracck",
369		.p = "main_osc",
370		.l = &pll_layout_frac,
371		.t = PLL_TYPE_FRAC,
372		.id = 6,
373		.cid = ID_PLL_ETH_FRAC,
374	},
375
376	{
377		.n = "ethpll_divpmcck",
378		.p = "ethpll_fracck",
379		.l = &pll_layout_divpmc,
380		.t = PLL_TYPE_DIV,
381		.id = 6,
382		.cid = ID_PLL_ETH_DIV,
383	},
384};
385
386/**
387 * Master clock (MCK[1..4]) description
388 * @n:			clock name
389 * @ep:			extra parents names array
390 * @ep_chg_chg_id:	index in parents array that specifies the changeable
391 *			parent
392 * @ep_count:		extra parents count
393 * @ep_mux_table:	mux table for extra parents
394 * @ep_clk_mux_table:	mux table to deal with subsystem clock ids
395 * @id:			clock id corresponding to MCK driver
396 * @cid:		clock id corresponding to clock subsystem
397 * @c:			true if clock is critical and cannot be disabled
398 */
399static const struct {
400	const char *n;
401	const char *ep[4];
402	u8 ep_count;
403	u8 ep_mux_table[4];
404	u8 ep_clk_mux_table[4];
405	u8 id;
406	u8 cid;
407	u8 c;
408} sama7g5_mckx[] = {
409	{
410		.n = "mck1",
411		.id = 1,
412		.cid = ID_MCK1,
413		.ep = { "syspll_divpmcck", },
414		.ep_mux_table = { 5, },
415		.ep_clk_mux_table = { ID_PLL_SYS_DIV, },
416		.ep_count = 1,
417		.c = 1,
418	},
419
420	{
421		.n = "mck2",
422		.id = 2,
423		.cid = ID_MCK2,
424		.ep = { "ddrpll_divpmcck", },
425		.ep_mux_table = { 6, },
426		.ep_clk_mux_table = { ID_PLL_DDR_DIV, },
427		.ep_count = 1,
428		.c = 1,
429	},
430
431	{
432		.n = "mck3",
433		.id = 3,
434		.cid = ID_MCK3,
435		.ep = { "syspll_divpmcck", "ddrpll_divpmcck", "imgpll_divpmcck", },
436		.ep_mux_table = { 5, 6, 7, },
437		.ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_DDR_DIV, ID_PLL_IMG_DIV, },
438		.ep_count = 3,
439	},
440
441	{
442		.n = "mck4",
443		.id = 4,
444		.cid = ID_MCK4,
445		.ep = { "syspll_divpmcck", },
446		.ep_mux_table = { 5, },
447		.ep_clk_mux_table = { ID_PLL_SYS_DIV, },
448		.ep_count = 1,
449		.c = 1,
450	},
451};
452
453/**
454 * Programmable clock description
455 * @n:			clock name
456 * @cid:		clock id corresponding to clock subsystem
457 */
458static const struct {
459	const char *n;
460	u8 cid;
461} sama7g5_prog[] = {
462	{ .n = "prog0", .cid = ID_PROG0, },
463	{ .n = "prog1", .cid = ID_PROG1, },
464	{ .n = "prog2", .cid = ID_PROG2, },
465	{ .n = "prog3", .cid = ID_PROG3, },
466	{ .n = "prog4", .cid = ID_PROG4, },
467	{ .n = "prog5", .cid = ID_PROG5, },
468	{ .n = "prog6", .cid = ID_PROG6, },
469	{ .n = "prog7", .cid = ID_PROG7, },
470};
471
472/* Mux table for programmable clocks. */
473static u32 sama7g5_prog_mux_table[] = { 0, 1, 2, 3, 5, 6, 7, 8, 9, 10, };
474
475/**
476 * System clock description
477 * @n:			clock name
478 * @p:			parent clock name
479 * @id:			clock id corresponding to system clock driver
480 * @cid:		clock id corresponding to clock subsystem
481 */
482static const struct {
483	const char *n;
484	const char *p;
485	u8 id;
486	u8 cid;
487} sama7g5_systemck[] = {
488	{ .n = "pck0", .p = "prog0", .id = 8, .cid = ID_PCK0, },
489	{ .n = "pck1", .p = "prog1", .id = 9, .cid = ID_PCK1, },
490	{ .n = "pck2", .p = "prog2", .id = 10, .cid = ID_PCK2, },
491	{ .n = "pck3", .p = "prog3", .id = 11, .cid = ID_PCK3, },
492	{ .n = "pck4", .p = "prog4", .id = 12, .cid = ID_PCK4, },
493	{ .n = "pck5", .p = "prog5", .id = 13, .cid = ID_PCK5, },
494	{ .n = "pck6", .p = "prog6", .id = 14, .cid = ID_PCK6, },
495	{ .n = "pck7", .p = "prog7", .id = 15, .cid = ID_PCK7, },
496};
497
498/**
499 * Peripheral clock description
500 * @n:		clock name
501 * @p:		clock parent name
502 * @r:		clock range values
503 * @id:		clock id
504 */
505static const struct {
506	const char *n;
507	const char *p;
508	struct clk_range r;
509	u8 id;
510} sama7g5_periphck[] = {
511	{ .n = "pioA_clk",	.p = "mck0_div", .id = 11, },
512	{ .n = "sfr_clk",	.p = "mck1", .id = 19, },
513	{ .n = "hsmc_clk",	.p = "mck1", .id = 21, },
514	{ .n = "xdmac0_clk",	.p = "mck1", .id = 22, },
515	{ .n = "xdmac1_clk",	.p = "mck1", .id = 23, },
516	{ .n = "xdmac2_clk",	.p = "mck1", .id = 24, },
517	{ .n = "acc_clk",	.p = "mck1", .id = 25, },
518	{ .n = "aes_clk",	.p = "mck1", .id = 27, },
519	{ .n = "tzaesbasc_clk",	.p = "mck1", .id = 28, },
520	{ .n = "asrc_clk",	.p = "mck1", .id = 30, .r = { .max = 200000000, }, },
521	{ .n = "cpkcc_clk",	.p = "mck0_div", .id = 32, },
522	{ .n = "csi_clk",	.p = "mck3", .id = 33, .r = { .max = 266000000, }, },
523	{ .n = "csi2dc_clk",	.p = "mck3", .id = 34, .r = { .max = 266000000, }, },
524	{ .n = "eic_clk",	.p = "mck1", .id = 37, },
525	{ .n = "flex0_clk",	.p = "mck1", .id = 38, },
526	{ .n = "flex1_clk",	.p = "mck1", .id = 39, },
527	{ .n = "flex2_clk",	.p = "mck1", .id = 40, },
528	{ .n = "flex3_clk",	.p = "mck1", .id = 41, },
529	{ .n = "flex4_clk",	.p = "mck1", .id = 42, },
530	{ .n = "flex5_clk",	.p = "mck1", .id = 43, },
531	{ .n = "flex6_clk",	.p = "mck1", .id = 44, },
532	{ .n = "flex7_clk",	.p = "mck1", .id = 45, },
533	{ .n = "flex8_clk",	.p = "mck1", .id = 46, },
534	{ .n = "flex9_clk",	.p = "mck1", .id = 47, },
535	{ .n = "flex10_clk",	.p = "mck1", .id = 48, },
536	{ .n = "flex11_clk",	.p = "mck1", .id = 49, },
537	{ .n = "gmac0_clk",	.p = "mck1", .id = 51, },
538	{ .n = "gmac1_clk",	.p = "mck1", .id = 52, },
539	{ .n = "gmac0_tsu_clk",	.p = "mck1", .id = 53, },
540	{ .n = "gmac1_tsu_clk",	.p = "mck1", .id = 54, },
541	{ .n = "icm_clk",	.p = "mck1", .id = 55, },
542	{ .n = "isc_clk",	.p = "mck3", .id = 56, .r = { .max = 266000000, }, },
543	{ .n = "i2smcc0_clk",	.p = "mck1", .id = 57, .r = { .max = 200000000, }, },
544	{ .n = "i2smcc1_clk",	.p = "mck1", .id = 58, .r = { .max = 200000000, }, },
545	{ .n = "matrix_clk",	.p = "mck1", .id = 60, },
546	{ .n = "mcan0_clk",	.p = "mck1", .id = 61, .r = { .max = 200000000, }, },
547	{ .n = "mcan1_clk",	.p = "mck1", .id = 62, .r = { .max = 200000000, }, },
548	{ .n = "mcan2_clk",	.p = "mck1", .id = 63, .r = { .max = 200000000, }, },
549	{ .n = "mcan3_clk",	.p = "mck1", .id = 64, .r = { .max = 200000000, }, },
550	{ .n = "mcan4_clk",	.p = "mck1", .id = 65, .r = { .max = 200000000, }, },
551	{ .n = "mcan5_clk",	.p = "mck1", .id = 66, .r = { .max = 200000000, }, },
552	{ .n = "pdmc0_clk",	.p = "mck1", .id = 68, .r = { .max = 200000000, }, },
553	{ .n = "pdmc1_clk",	.p = "mck1", .id = 69, .r = { .max = 200000000, }, },
554	{ .n = "pit64b0_clk",	.p = "mck1", .id = 70, },
555	{ .n = "pit64b1_clk",	.p = "mck1", .id = 71, },
556	{ .n = "pit64b2_clk",	.p = "mck1", .id = 72, },
557	{ .n = "pit64b3_clk",	.p = "mck1", .id = 73, },
558	{ .n = "pit64b4_clk",	.p = "mck1", .id = 74, },
559	{ .n = "pit64b5_clk",	.p = "mck1", .id = 75, },
560	{ .n = "pwm_clk",	.p = "mck1", .id = 77, },
561	{ .n = "qspi0_clk",	.p = "mck1", .id = 78, },
562	{ .n = "qspi1_clk",	.p = "mck1", .id = 79, },
563	{ .n = "sdmmc0_clk",	.p = "mck1", .id = 80, },
564	{ .n = "sdmmc1_clk",	.p = "mck1", .id = 81, },
565	{ .n = "sdmmc2_clk",	.p = "mck1", .id = 82, },
566	{ .n = "sha_clk",	.p = "mck1", .id = 83, },
567	{ .n = "spdifrx_clk",	.p = "mck1", .id = 84, .r = { .max = 200000000, }, },
568	{ .n = "spdiftx_clk",	.p = "mck1", .id = 85, .r = { .max = 200000000, }, },
569	{ .n = "ssc0_clk",	.p = "mck1", .id = 86, .r = { .max = 200000000, }, },
570	{ .n = "ssc1_clk",	.p = "mck1", .id = 87, .r = { .max = 200000000, }, },
571	{ .n = "tcb0_ch0_clk",	.p = "mck1", .id = 88, .r = { .max = 200000000, }, },
572	{ .n = "tcb0_ch1_clk",	.p = "mck1", .id = 89, .r = { .max = 200000000, }, },
573	{ .n = "tcb0_ch2_clk",	.p = "mck1", .id = 90, .r = { .max = 200000000, }, },
574	{ .n = "tcb1_ch0_clk",	.p = "mck1", .id = 91, .r = { .max = 200000000, }, },
575	{ .n = "tcb1_ch1_clk",	.p = "mck1", .id = 92, .r = { .max = 200000000, }, },
576	{ .n = "tcb1_ch2_clk",	.p = "mck1", .id = 93, .r = { .max = 200000000, }, },
577	{ .n = "tcpca_clk",	.p = "mck1", .id = 94, },
578	{ .n = "tcpcb_clk",	.p = "mck1", .id = 95, },
579	{ .n = "tdes_clk",	.p = "mck1", .id = 96, },
580	{ .n = "trng_clk",	.p = "mck1", .id = 97, },
581	{ .n = "udphsa_clk",	.p = "mck1", .id = 104, },
582	{ .n = "udphsb_clk",	.p = "mck1", .id = 105, },
583	{ .n = "uhphs_clk",	.p = "mck1", .id = 106, },
584};
585
586/**
587 * Generic clock description
588 * @n:			clock name
589 * @ep:			extra parents names
590 * @ep_mux_table:	extra parents mux table
591 * @ep_clk_mux_table:	extra parents clock mux table (for CCF)
592 * @r:			clock output range
593 * @ep_count:		extra parents count
594 * @id:			clock id
595 */
596static const struct {
597	const char *n;
598	const char *ep[8];
599	const char ep_mux_table[8];
600	const char ep_clk_mux_table[8];
601	struct clk_range r;
602	u8 ep_count;
603	u8 id;
604} sama7g5_gck[] = {
605	{
606		.n  = "adc_gclk",
607		.id = 26,
608		.r = { .max = 100000000, },
609		.ep = { "syspll_divpmcck", "imgpll_divpmcck", "audiopll_divpmcck", },
610		.ep_mux_table = { 5, 7, 9, },
611		.ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_IMG_DIV,
612				      ID_PLL_AUDIO_DIVPMC, },
613		.ep_count = 3,
614	},
615
616	{
617		.n  = "asrc_gclk",
618		.id = 30,
619		.r = { .max = 200000000 },
620		.ep = { "audiopll_divpmcck", },
621		.ep_mux_table = { 9, },
622		.ep_clk_mux_table = { ID_PLL_AUDIO_DIVPMC, },
623		.ep_count = 1,
624	},
625
626	{
627		.n  = "csi_gclk",
628		.id = 33,
629		.r = { .max = 27000000  },
630		.ep = { "ddrpll_divpmcck", "imgpll_divpmcck", },
631		.ep_clk_mux_table = { ID_PLL_DDR_DIV, ID_PLL_IMG_DIV, },
632		.ep_mux_table = { 6, 7, },
633		.ep_count = 2,
634	},
635
636	{
637		.n  = "flex0_gclk",
638		.id = 38,
639		.r = { .max = 200000000 },
640		.ep = { "syspll_divpmcck", "baudpll_divpmcck", },
641		.ep_mux_table = { 5, 8, },
642		.ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, },
643		.ep_count = 2,
644	},
645
646	{
647		.n  = "flex1_gclk",
648		.id = 39,
649		.r = { .max = 200000000 },
650		.ep = { "syspll_divpmcck", "baudpll_divpmcck", },
651		.ep_mux_table = { 5, 8, },
652		.ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, },
653		.ep_count = 2,
654	},
655
656	{
657		.n  = "flex2_gclk",
658		.id = 40,
659		.r = { .max = 200000000 },
660		.ep = { "syspll_divpmcck", "baudpll_divpmcck", },
661		.ep_mux_table = { 5, 8, },
662		.ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, },
663		.ep_count = 2,
664	},
665
666	{
667		.n  = "flex3_gclk",
668		.id = 41,
669		.r = { .max = 200000000 },
670		.ep = { "syspll_divpmcck", "baudpll_divpmcck", },
671		.ep_mux_table = { 5, 8, },
672		.ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, },
673		.ep_count = 2,
674	},
675
676	{
677		.n  = "flex4_gclk",
678		.id = 42,
679		.r = { .max = 200000000 },
680		.ep = { "syspll_divpmcck", "baudpll_divpmcck", },
681		.ep_mux_table = { 5, 8, },
682		.ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, },
683		.ep_count = 2,
684	},
685
686	{
687		.n  = "flex5_gclk",
688		.id = 43,
689		.r = { .max = 200000000 },
690		.ep = { "syspll_divpmcck", "baudpll_divpmcck", },
691		.ep_mux_table = { 5, 8, },
692		.ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, },
693		.ep_count = 2,
694	},
695
696	{
697		.n  = "flex6_gclk",
698		.id = 44,
699		.r = { .max = 200000000 },
700		.ep = { "syspll_divpmcck", "baudpll_divpmcck", },
701		.ep_mux_table = { 5, 8, },
702		.ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, },
703		.ep_count = 2,
704	},
705
706	{
707		.n  = "flex7_gclk",
708		.id = 45,
709		.r = { .max = 200000000 },
710		.ep = { "syspll_divpmcck", "baudpll_divpmcck", },
711		.ep_mux_table = { 5, 8, },
712		.ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, },
713		.ep_count = 2,
714	},
715
716	{
717		.n  = "flex8_gclk",
718		.id = 46,
719		.r = { .max = 200000000 },
720		.ep = { "syspll_divpmcck", "baudpll_divpmcck", },
721		.ep_mux_table = { 5, 8, },
722		.ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, },
723		.ep_count = 2,
724	},
725
726	{
727		.n  = "flex9_gclk",
728		.id = 47,
729		.r = { .max = 200000000 },
730		.ep = { "syspll_divpmcck", "baudpll_divpmcck", },
731		.ep_mux_table = { 5, 8, },
732		.ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, },
733		.ep_count = 2,
734	},
735
736	{
737		.n  = "flex10_gclk",
738		.id = 48,
739		.r = { .max = 200000000 },
740		.ep = { "syspll_divpmcck", "baudpll_divpmcck", },
741		.ep_mux_table = { 5, 8, },
742		.ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, },
743		.ep_count = 2,
744	},
745
746	{
747		.n  = "flex11_gclk",
748		.id = 49,
749		.r = { .max = 200000000 },
750		.ep = { "syspll_divpmcck", "baudpll_divpmcck", },
751		.ep_mux_table = { 5, 8, },
752		.ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, },
753		.ep_count = 2,
754	},
755
756	{
757		.n  = "gmac0_gclk",
758		.id = 51,
759		.r = { .max = 125000000 },
760		.ep = { "ethpll_divpmcck", },
761		.ep_clk_mux_table = { ID_PLL_ETH_DIV, },
762		.ep_mux_table = { 10, },
763		.ep_count = 1,
764	},
765
766	{
767		.n  = "gmac1_gclk",
768		.id = 52,
769		.r = { .max = 50000000  },
770		.ep = { "ethpll_divpmcck", },
771		.ep_mux_table = { 10, },
772		.ep_clk_mux_table = { ID_PLL_ETH_DIV, },
773		.ep_count = 1,
774	},
775
776	{
777		.n  = "gmac0_tsu_gclk",
778		.id = 53,
779		.r = { .max = 300000000 },
780		.ep = { "audiopll_divpmcck", "ethpll_divpmcck", },
781		.ep_mux_table = { 9, 10, },
782		.ep_clk_mux_table = { ID_PLL_AUDIO_DIVPMC, ID_PLL_ETH_DIV, },
783		.ep_count = 2,
784	},
785
786	{
787		.n  = "gmac1_tsu_gclk",
788		.id = 54,
789		.r = { .max = 300000000 },
790		.ep = { "audiopll_divpmcck", "ethpll_divpmcck", },
791		.ep_mux_table = { 9, 10, },
792		.ep_clk_mux_table = { ID_PLL_AUDIO_DIVPMC, ID_PLL_ETH_DIV, },
793		.ep_count = 2,
794	},
795
796	{
797		.n  = "i2smcc0_gclk",
798		.id = 57,
799		.r = { .max = 100000000 },
800		.ep = { "syspll_divpmcck", "audiopll_divpmcck", },
801		.ep_mux_table = { 5, 9, },
802		.ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_AUDIO_DIVPMC, },
803		.ep_count = 2,
804	},
805
806	{
807		.n  = "i2smcc1_gclk",
808		.id = 58,
809		.r = { .max = 100000000 },
810		.ep = { "syspll_divpmcck", "audiopll_divpmcck", },
811		.ep_mux_table = { 5, 9, },
812		.ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_AUDIO_DIVPMC, },
813		.ep_count = 2,
814	},
815
816	{
817		.n  = "mcan0_gclk",
818		.id = 61,
819		.r = { .max = 200000000 },
820		.ep = { "syspll_divpmcck", "baudpll_divpmcck", },
821		.ep_mux_table = { 5, 8, },
822		.ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, },
823		.ep_count = 2,
824	},
825
826	{
827		.n  = "mcan1_gclk",
828		.id = 62,
829		.r = { .max = 200000000 },
830		.ep = { "syspll_divpmcck", "baudpll_divpmcck", },
831		.ep_mux_table = { 5, 8, },
832		.ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, },
833		.ep_count = 2,
834	},
835
836	{
837		.n  = "mcan2_gclk",
838		.id = 63,
839		.r = { .max = 200000000 },
840		.ep = { "syspll_divpmcck", "baudpll_divpmcck", },
841		.ep_mux_table = { 5, 8, },
842		.ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, },
843		.ep_count = 2,
844	},
845
846	{
847		.n  = "mcan3_gclk",
848		.id = 64,
849		.r = { .max = 200000000 },
850		.ep = { "syspll_divpmcck", "baudpll_divpmcck", },
851		.ep_mux_table = { 5, 8, },
852		.ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, },
853		.ep_count = 2,
854	},
855
856	{
857		.n  = "mcan4_gclk",
858		.id = 65,
859		.r = { .max = 200000000 },
860		.ep = { "syspll_divpmcck", "baudpll_divpmcck", },
861		.ep_mux_table = { 5, 8, },
862		.ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, },
863		.ep_count = 2,
864	},
865
866	{
867		.n  = "mcan5_gclk",
868		.id = 66,
869		.r = { .max = 200000000 },
870		.ep = { "syspll_divpmcck", "baudpll_divpmcck", },
871		.ep_mux_table = { 5, 8, },
872		.ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, },
873		.ep_count = 2,
874	},
875
876	{
877		.n  = "pdmc0_gclk",
878		.id = 68,
879		.r = { .max = 50000000  },
880		.ep = { "syspll_divpmcck", "baudpll_divpmcck", },
881		.ep_mux_table = { 5, 8, },
882		.ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, },
883		.ep_count = 2,
884	},
885
886	{
887		.n  = "pdmc1_gclk",
888		.id = 69,
889		.r = { .max = 50000000, },
890		.ep = { "syspll_divpmcck", "baudpll_divpmcck", },
891		.ep_mux_table = { 5, 8, },
892		.ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, },
893		.ep_count = 2,
894	},
895
896	{
897		.n  = "pit64b0_gclk",
898		.id = 70,
899		.r = { .max = 200000000 },
900		.ep = { "syspll_divpmcck", "imgpll_divpmcck", "baudpll_divpmcck",
901			"audiopll_divpmcck", "ethpll_divpmcck", },
902		.ep_mux_table = { 5, 7, 8, 9, 10, },
903		.ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_IMG_DIV,
904				      ID_PLL_BAUD_DIV, ID_PLL_AUDIO_DIVPMC,
905				      ID_PLL_ETH_DIV, },
906		.ep_count = 5,
907	},
908
909	{
910		.n  = "pit64b1_gclk",
911		.id = 71,
912		.r = { .max = 200000000 },
913		.ep = { "syspll_divpmcck", "imgpll_divpmcck", "baudpll_divpmcck",
914			"audiopll_divpmcck", "ethpll_divpmcck", },
915		.ep_mux_table = { 5, 7, 8, 9, 10, },
916		.ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_IMG_DIV,
917				      ID_PLL_BAUD_DIV, ID_PLL_AUDIO_DIVPMC,
918				      ID_PLL_ETH_DIV, },
919		.ep_count = 5,
920	},
921
922	{
923		.n  = "pit64b2_gclk",
924		.id = 72,
925		.r = { .max = 200000000 },
926		.ep = { "syspll_divpmcck", "imgpll_divpmcck", "baudpll_divpmcck",
927			"audiopll_divpmcck", "ethpll_divpmcck", },
928		.ep_mux_table = { 5, 7, 8, 9, 10, },
929		.ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_IMG_DIV,
930				      ID_PLL_BAUD_DIV, ID_PLL_AUDIO_DIVPMC,
931				      ID_PLL_ETH_DIV, },
932		.ep_count = 5,
933	},
934
935	{
936		.n  = "pit64b3_gclk",
937		.id = 73,
938		.r = { .max = 200000000 },
939		.ep = { "syspll_divpmcck", "imgpll_divpmcck", "baudpll_divpmcck",
940			"audiopll_divpmcck", "ethpll_divpmcck", },
941		.ep_mux_table = { 5, 7, 8, 9, 10, },
942		.ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_IMG_DIV,
943				      ID_PLL_BAUD_DIV, ID_PLL_AUDIO_DIVPMC,
944				      ID_PLL_ETH_DIV, },
945		.ep_count = 5,
946	},
947
948	{
949		.n  = "pit64b4_gclk",
950		.id = 74,
951		.r = { .max = 200000000 },
952		.ep = { "syspll_divpmcck", "imgpll_divpmcck", "baudpll_divpmcck",
953			"audiopll_divpmcck", "ethpll_divpmcck", },
954		.ep_mux_table = { 5, 7, 8, 9, 10, },
955		.ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_IMG_DIV,
956				      ID_PLL_BAUD_DIV, ID_PLL_AUDIO_DIVPMC,
957				      ID_PLL_ETH_DIV, },
958		.ep_count = 5,
959	},
960
961	{
962		.n  = "pit64b5_gclk",
963		.id = 75,
964		.r = { .max = 200000000 },
965		.ep = { "syspll_divpmcck", "imgpll_divpmcck", "baudpll_divpmcck",
966			"audiopll_divpmcck", "ethpll_divpmcck", },
967		.ep_mux_table = { 5, 7, 8, 9, 10, },
968		.ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_IMG_DIV,
969				      ID_PLL_BAUD_DIV, ID_PLL_AUDIO_DIVPMC,
970				      ID_PLL_ETH_DIV, },
971		.ep_count = 5,
972	},
973
974	{
975		.n  = "qspi0_gclk",
976		.id = 78,
977		.r = { .max = 200000000 },
978		.ep = { "syspll_divpmcck", "baudpll_divpmcck", },
979		.ep_mux_table = { 5, 8, },
980		.ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_IMG_DIV,
981				      ID_PLL_BAUD_DIV, ID_PLL_AUDIO_DIVPMC,
982				      ID_PLL_ETH_DIV, },
983		.ep_count = 2,
984	},
985
986	{
987		.n  = "qspi1_gclk",
988		.id = 79,
989		.r = { .max = 200000000 },
990		.ep = { "syspll_divpmcck", "baudpll_divpmcck", },
991		.ep_mux_table = { 5, 8, },
992		.ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, },
993		.ep_count = 2,
994	},
995
996	{
997		.n  = "sdmmc0_gclk",
998		.id = 80,
999		.r = { .max = 208000000 },
1000		.ep = { "syspll_divpmcck", "baudpll_divpmcck", },
1001		.ep_mux_table = { 5, 8, },
1002		.ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, },
1003		.ep_count = 2,
1004	},
1005
1006	{
1007		.n  = "sdmmc1_gclk",
1008		.id = 81,
1009		.r = { .max = 208000000 },
1010		.ep = { "syspll_divpmcck", "baudpll_divpmcck", },
1011		.ep_mux_table = { 5, 8, },
1012		.ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, },
1013		.ep_count = 2,
1014	},
1015
1016	{
1017		.n  = "sdmmc2_gclk",
1018		.id = 82,
1019		.r = { .max = 208000000 },
1020		.ep = { "syspll_divpmcck", "baudpll_divpmcck", },
1021		.ep_mux_table = { 5, 8, },
1022		.ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, },
1023		.ep_count = 2,
1024	},
1025
1026	{
1027		.n  = "spdifrx_gclk",
1028		.id = 84,
1029		.r = { .max = 150000000 },
1030		.ep = { "syspll_divpmcck", "audiopll_divpmcck", },
1031		.ep_mux_table = { 5, 9, },
1032		.ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_AUDIO_DIVPMC, },
1033		.ep_count = 2,
1034	},
1035
1036	{
1037		.n = "spdiftx_gclk",
1038		.id = 85,
1039		.r = { .max = 25000000  },
1040		.ep = { "syspll_divpmcck", "audiopll_divpmcck", },
1041		.ep_mux_table = { 5, 9, },
1042		.ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_AUDIO_DIVPMC, },
1043		.ep_count = 2,
1044	},
1045
1046	{
1047		.n  = "tcb0_ch0_gclk",
1048		.id = 88,
1049		.r = { .max = 200000000 },
1050		.ep = { "syspll_divpmcck", "imgpll_divpmcck", "baudpll_divpmcck",
1051			"audiopll_divpmcck", "ethpll_divpmcck", },
1052		.ep_mux_table = { 5, 7, 8, 9, 10, },
1053		.ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_IMG_DIV,
1054				      ID_PLL_BAUD_DIV, ID_PLL_AUDIO_DIVPMC,
1055				      ID_PLL_ETH_DIV, },
1056		.ep_count = 5,
1057	},
1058
1059	{
1060		.n  = "tcb1_ch0_gclk",
1061		.id = 91,
1062		.r = { .max = 200000000 },
1063		.ep = { "syspll_divpmcck", "imgpll_divpmcck", "baudpll_divpmcck",
1064			"audiopll_divpmcck", "ethpll_divpmcck", },
1065		.ep_mux_table = { 5, 7, 8, 9, 10, },
1066		.ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_IMG_DIV,
1067				      ID_PLL_BAUD_DIV, ID_PLL_AUDIO_DIVPMC,
1068				      ID_PLL_ETH_DIV, },
1069		.ep_count = 5,
1070	},
1071};
1072
1073/* Clock setup description */
1074static const struct pmc_clk_setup sama7g5_clk_setup[] = {
1075	{
1076		.cid = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_ETH_FRAC),
1077		.rate = 625000000,
1078	},
1079
1080	{
1081		.cid = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_ETH_DIV),
1082		.rate = 625000000,
1083	},
1084};
1085
1086#define SAMA7G5_MAX_MUX_ALLOCS		(64)
1087
1088#define prepare_mux_table(_allocs, _index, _dst, _src, _num, _label)	\
1089	do {								\
1090		int _i;							\
1091		if ((_index) >= SAMA7G5_MAX_MUX_ALLOCS) {		\
1092			debug("%s(): AT91: MUX: insufficient space\n",	\
1093			      __func__);				\
1094			goto _label;					\
1095		}							\
1096		(_dst) = kzalloc(sizeof(*(_dst)) * (_num), GFP_KERNEL);	\
1097		if (!(_dst))						\
1098			goto _label;					\
1099		(_allocs)[(_index)++] = (_dst);				\
1100		for (_i = 0; _i < (_num); _i++)				\
1101			(_dst)[_i] = (_src)[_i];			\
1102	} while (0)
1103
1104static int sama7g5_clk_probe(struct udevice *dev)
1105{
1106	void __iomem *base = devfdt_get_addr_ptr(dev);
1107	unsigned int *clkmuxallocs[SAMA7G5_MAX_MUX_ALLOCS];
1108	unsigned int *muxallocs[SAMA7G5_MAX_MUX_ALLOCS];
1109	const char *p[10];
1110	unsigned int cm[10], m[10], *tmpclkmux, *tmpmux;
1111	struct clk clk, *c;
1112	bool main_osc_bypass;
1113	int ret, muxallocindex = 0, clkmuxallocindex = 0, i, j;
1114
1115	if (IS_ERR(base))
1116		return PTR_ERR(base);
1117
1118	memset(muxallocs,    0, sizeof(muxallocs));
1119	memset(clkmuxallocs, 0, sizeof(clkmuxallocs));
1120
1121	ret = clk_get_by_index(dev, 0, &clk);
1122	if (ret)
1123		return ret;
1124	ret = clk_get_by_id(clk.id, &c);
1125	if (ret)
1126		return ret;
1127	clk_names[ID_TD_SLCK] = kmemdup(clk_hw_get_name(c),
1128		strlen(clk_hw_get_name(c)) + 1, GFP_KERNEL);
1129	if (!clk_names[ID_TD_SLCK])
1130		return -ENOMEM;
1131
1132	ret = clk_get_by_index(dev, 1, &clk);
1133	if (ret)
1134		return ret;
1135	ret = clk_get_by_id(clk.id, &c);
1136	if (ret)
1137		return ret;
1138	clk_names[ID_MD_SLCK] = kmemdup(clk_hw_get_name(c),
1139		strlen(clk_hw_get_name(c)) + 1, GFP_KERNEL);
1140	if (!clk_names[ID_MD_SLCK])
1141		return -ENOMEM;
1142
1143	ret = clk_get_by_index(dev, 2, &clk);
1144	if (ret)
1145		return ret;
1146	clk_names[ID_MAIN_XTAL] = kmemdup(clk_hw_get_name(&clk),
1147		strlen(clk_hw_get_name(&clk)) + 1, GFP_KERNEL);
1148	if (!clk_names[ID_MAIN_XTAL])
1149		return -ENOMEM;
1150
1151	ret = clk_get_by_index(dev, 3, &clk);
1152	if (ret)
1153		goto fail;
1154	clk_names[ID_MAIN_RC] = kmemdup(clk_hw_get_name(&clk),
1155		strlen(clk_hw_get_name(&clk)) + 1, GFP_KERNEL);
1156	if (ret)
1157		goto fail;
1158
1159	main_osc_bypass = dev_read_bool(dev, "atmel,main-osc-bypass");
1160
1161	/* Register main rc oscillator. */
1162	clk_dm(AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MAIN_RC_OSC),
1163		at91_clk_main_rc(base, clk_names[ID_MAIN_RC_OSC],
1164		clk_names[ID_MAIN_RC]));
1165
1166	/* Register main oscillator. */
1167	clk_dm(AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MAIN_OSC),
1168		at91_clk_main_osc(base, clk_names[ID_MAIN_OSC],
1169		clk_names[ID_MAIN_XTAL], main_osc_bypass));
1170
1171	/* Register mainck. */
1172	p[0] = clk_names[ID_MAIN_RC_OSC];
1173	p[1] = clk_names[ID_MAIN_OSC];
1174	cm[0] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MAIN_RC_OSC);
1175	cm[1] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MAIN_OSC);
1176	prepare_mux_table(clkmuxallocs, clkmuxallocindex, tmpclkmux, cm, 2,
1177			  fail);
1178	clk_dm(AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MAINCK),
1179		at91_clk_sam9x5_main(base, clk_names[ID_MAINCK], p,
1180		2, tmpclkmux, PMC_TYPE_CORE));
1181
1182	/* Register PLL fracs clocks. */
1183	for (i = 0; i < ARRAY_SIZE(sama7g5_plls); i++) {
1184		if (sama7g5_plls[i].t != PLL_TYPE_FRAC)
1185			continue;
1186
1187		clk_dm(AT91_TO_CLK_ID(PMC_TYPE_CORE, sama7g5_plls[i].cid),
1188			sam9x60_clk_register_frac_pll(base, sama7g5_plls[i].n,
1189			sama7g5_plls[i].p, sama7g5_plls[i].id,
1190			&pll_characteristics, sama7g5_plls[i].l,
1191			sama7g5_plls[i].c));
1192	}
1193
1194	/* Register PLL div clocks. */
1195	for (i = 0; i < ARRAY_SIZE(sama7g5_plls); i++) {
1196		if (sama7g5_plls[i].t != PLL_TYPE_DIV)
1197			continue;
1198
1199		clk_dm(AT91_TO_CLK_ID(PMC_TYPE_CORE, sama7g5_plls[i].cid),
1200			sam9x60_clk_register_div_pll(base, sama7g5_plls[i].n,
1201			sama7g5_plls[i].p, sama7g5_plls[i].id,
1202			&pll_characteristics, sama7g5_plls[i].l,
1203			sama7g5_plls[i].c));
1204	}
1205
1206	/* Register MCK0_PRES clock. */
1207	p[0] = clk_names[ID_MD_SLCK];
1208	p[1] = clk_names[ID_MAINCK];
1209	p[2] = clk_names[ID_PLL_CPU_DIV];
1210	p[3] = clk_names[ID_PLL_SYS_DIV];
1211	cm[0] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MD_SLCK);
1212	cm[1] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MAINCK);
1213	cm[2] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_CPU_DIV);
1214	cm[3] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_SYS_DIV);
1215	prepare_mux_table(clkmuxallocs, clkmuxallocindex, tmpclkmux, cm, 2,
1216			  fail);
1217	clk_dm(AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MCK0_PRES),
1218		at91_clk_register_master_pres(base, clk_names[ID_MCK0_PRES], p,
1219		4, &mck0_layout, &mck0_characteristics, tmpclkmux));
1220
1221	clk_dm(AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MCK0_DIV),
1222		at91_clk_register_master_div(base, clk_names[ID_MCK0_DIV],
1223		clk_names[ID_MCK0_PRES], &mck0_layout, &mck0_characteristics));
1224
1225	/* Register MCK1-4 clocks. */
1226	p[0] = clk_names[ID_MD_SLCK];
1227	p[1] = clk_names[ID_TD_SLCK];
1228	p[2] = clk_names[ID_MAINCK];
1229	p[3] = clk_names[ID_MCK0_DIV];
1230	m[0] = 0;
1231	m[1] = 1;
1232	m[2] = 2;
1233	m[3] = 3;
1234	cm[0] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MD_SLCK);
1235	cm[1] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_TD_SLCK);
1236	cm[2] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MAINCK);
1237	cm[3] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MCK0_DIV);
1238	for (i = 0; i < ARRAY_SIZE(sama7g5_mckx); i++) {
1239		for (j = 0; j < sama7g5_mckx[i].ep_count; j++) {
1240			p[4 + j] = sama7g5_mckx[i].ep[j];
1241			m[4 + j] = sama7g5_mckx[i].ep_mux_table[j];
1242			cm[4 + j] = AT91_TO_CLK_ID(PMC_TYPE_CORE,
1243					sama7g5_mckx[i].ep_clk_mux_table[j]);
1244		}
1245
1246		prepare_mux_table(clkmuxallocs, clkmuxallocindex, tmpclkmux, cm,
1247			4 + sama7g5_mckx[i].ep_count, fail);
1248		prepare_mux_table(muxallocs, muxallocindex, tmpmux, m,
1249			4 + sama7g5_mckx[i].ep_count, fail);
1250
1251		clk_dm(AT91_TO_CLK_ID(PMC_TYPE_CORE, sama7g5_mckx[i].cid),
1252			at91_clk_sama7g5_register_master(base,
1253			sama7g5_mckx[i].n, p, 4 + sama7g5_mckx[i].ep_count,
1254			tmpmux, tmpclkmux, sama7g5_mckx[i].c,
1255			sama7g5_mckx[i].id));
1256	}
1257
1258	/* Register UTMI clock. */
1259	clk_dm(AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_UTMI),
1260		at91_clk_sama7g5_register_utmi(base, "utmick",
1261		clk_names[ID_MAIN_XTAL]));
1262
1263	/* Register programmable clocks. */
1264	p[0] = clk_names[ID_MD_SLCK];
1265	p[1] = clk_names[ID_TD_SLCK];
1266	p[2] = clk_names[ID_MAINCK];
1267	p[3] = clk_names[ID_MCK0_DIV];
1268	p[4] = clk_names[ID_PLL_SYS_DIV];
1269	p[5] = clk_names[ID_PLL_DDR_DIV];
1270	p[6] = clk_names[ID_PLL_IMG_DIV];
1271	p[7] = clk_names[ID_PLL_BAUD_DIV];
1272	p[8] = clk_names[ID_PLL_AUDIO_DIVPMC];
1273	p[9] = clk_names[ID_PLL_ETH_DIV];
1274	cm[0] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MD_SLCK);
1275	cm[1] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_TD_SLCK);
1276	cm[2] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MAINCK);
1277	cm[3] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MCK0_DIV);
1278	cm[4] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_SYS_DIV);
1279	cm[5] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_DDR_DIV);
1280	cm[6] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_IMG_DIV);
1281	cm[7] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_BAUD_DIV);
1282	cm[8] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_AUDIO_DIVPMC);
1283	cm[9] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_ETH_DIV);
1284	for (i = 0; i < ARRAY_SIZE(sama7g5_prog); i++) {
1285		prepare_mux_table(clkmuxallocs, clkmuxallocindex, tmpclkmux, cm,
1286			10, fail);
1287
1288		clk_dm(AT91_TO_CLK_ID(PMC_TYPE_CORE, sama7g5_prog[i].cid),
1289			at91_clk_register_programmable(base, sama7g5_prog[i].n,
1290			p, 10, i, &programmable_layout, tmpclkmux,
1291			sama7g5_prog_mux_table));
1292	}
1293
1294	/* System clocks. */
1295	for (i = 0; i < ARRAY_SIZE(sama7g5_systemck); i++) {
1296		clk_dm(AT91_TO_CLK_ID(PMC_TYPE_SYSTEM, sama7g5_systemck[i].cid),
1297			at91_clk_register_system(base, sama7g5_systemck[i].n,
1298			sama7g5_systemck[i].p, sama7g5_systemck[i].id));
1299	}
1300
1301	/* Peripheral clocks. */
1302	for (i = 0; i < ARRAY_SIZE(sama7g5_periphck); i++) {
1303		clk_dm(AT91_TO_CLK_ID(PMC_TYPE_PERIPHERAL,
1304			sama7g5_periphck[i].id),
1305			at91_clk_register_sam9x5_peripheral(base,
1306			&sama7g5_pcr_layout, sama7g5_periphck[i].n,
1307			sama7g5_periphck[i].p, sama7g5_periphck[i].id,
1308			&sama7g5_periphck[i].r));
1309	}
1310
1311	/* Generic clocks. */
1312	p[0] = clk_names[ID_MD_SLCK];
1313	p[1] = clk_names[ID_TD_SLCK];
1314	p[2] = clk_names[ID_MAINCK];
1315	p[3] = clk_names[ID_MCK0_DIV];
1316	m[0] = 0;
1317	m[1] = 1;
1318	m[2] = 2;
1319	m[3] = 3;
1320	cm[0] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MD_SLCK);
1321	cm[1] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_TD_SLCK);
1322	cm[2] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MAINCK);
1323	cm[3] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MCK0_DIV);
1324	for (i = 0; i < ARRAY_SIZE(sama7g5_gck); i++) {
1325		for (j = 0; j < sama7g5_gck[i].ep_count; j++) {
1326			p[4 + j] = sama7g5_gck[i].ep[j];
1327			m[4 + j] = sama7g5_gck[i].ep_mux_table[j];
1328			cm[4 + j] = AT91_TO_CLK_ID(PMC_TYPE_CORE,
1329					sama7g5_gck[i].ep_clk_mux_table[j]);
1330		}
1331
1332		prepare_mux_table(clkmuxallocs, clkmuxallocindex, tmpclkmux, cm,
1333			4 + sama7g5_gck[i].ep_count, fail);
1334		prepare_mux_table(muxallocs, muxallocindex, tmpmux, m,
1335			4 + sama7g5_gck[i].ep_count, fail);
1336
1337		clk_dm(AT91_TO_CLK_ID(PMC_TYPE_GCK, sama7g5_gck[i].id),
1338			at91_clk_register_generic(base, &sama7g5_pcr_layout,
1339			sama7g5_gck[i].n, p, tmpclkmux, tmpmux,
1340			4 + sama7g5_gck[i].ep_count, sama7g5_gck[i].id,
1341			&sama7g5_gck[i].r));
1342	}
1343
1344	/* Setup clocks. */
1345	ret = at91_clk_setup(sama7g5_clk_setup, ARRAY_SIZE(sama7g5_clk_setup));
1346	if (ret)
1347		goto fail;
1348
1349	return 0;
1350
1351fail:
1352	for (i = 0; i < ARRAY_SIZE(muxallocs); i++)
1353		kfree(muxallocs[i]);
1354
1355	for (i = 0; i < ARRAY_SIZE(clkmuxallocs); i++)
1356		kfree(clkmuxallocs[i]);
1357
1358	return -ENOMEM;
1359}
1360
1361static const struct udevice_id sama7g5_clk_ids[] = {
1362	{ .compatible = "microchip,sama7g5-pmc" },
1363	{ /* Sentinel. */ },
1364};
1365
1366U_BOOT_DRIVER(at91_sama7g5_pmc) = {
1367	.name = "at91-sama7g5-pmc",
1368	.id = UCLASS_CLK,
1369	.of_match = sama7g5_clk_ids,
1370	.ops = &at91_clk_ops,
1371	.probe = sama7g5_clk_probe,
1372	.flags = DM_FLAG_PRE_RELOC,
1373};
1374