xref: /optee_os/core/drivers/clk/sam/sama7g5_clk.c (revision e6b19839e65a107ae4832f93bd801c10b3e8c3c5)
1943d822aSTony Han // SPDX-License-Identifier: BSD-2-Clause
2943d822aSTony Han /*
3943d822aSTony Han  * Copyright (c) 2024, Microchip
4943d822aSTony Han  */
5943d822aSTony Han 
6943d822aSTony Han #include <assert.h>
7943d822aSTony Han #include <dt-bindings/clock/at91.h>
8943d822aSTony Han #include <io.h>
9943d822aSTony Han #include <kernel/boot.h>
10943d822aSTony Han #include <kernel/dt.h>
11943d822aSTony Han #include <kernel/panic.h>
12943d822aSTony Han #include <libfdt.h>
13943d822aSTony Han #include <matrix.h>
14943d822aSTony Han #include <sama7g5.h>
15943d822aSTony Han #include <stdint.h>
16943d822aSTony Han #include <util.h>
17943d822aSTony Han #include "at91_clk.h"
18943d822aSTony Han 
19943d822aSTony Han #define CLK_IS_CRITICAL 0
20943d822aSTony Han 
21943d822aSTony Han /* PLL clocks identifiers */
22943d822aSTony Han enum pll_ids {
23943d822aSTony Han 	PLL_ID_CPU,
24943d822aSTony Han 	PLL_ID_SYS,
25943d822aSTony Han 	PLL_ID_DDR,
26943d822aSTony Han 	PLL_ID_IMG,
27943d822aSTony Han 	PLL_ID_BAUD,
28943d822aSTony Han 	PLL_ID_AUDIO,
29943d822aSTony Han 	PLL_ID_ETH,
30943d822aSTony Han 	PLL_ID_MAX,
31943d822aSTony Han };
32943d822aSTony Han 
33943d822aSTony Han /* PLL type identifiers */
34943d822aSTony Han enum pll_type {
35943d822aSTony Han 	PLL_TYPE_FRAC,
36943d822aSTony Han 	PLL_TYPE_DIV,
37943d822aSTony Han 	PLL_TYPE_CNT,
38943d822aSTony Han };
39943d822aSTony Han 
40943d822aSTony Han /* Layout for fractional PLLs */
41943d822aSTony Han static const struct clk_pll_layout pll_layout_frac = {
42943d822aSTony Han 	.mul_mask	= GENMASK_32(31, 24),
43943d822aSTony Han 	.frac_mask	= GENMASK_32(21, 0),
44943d822aSTony Han 	.mul_shift	= 24,
45943d822aSTony Han 	.frac_shift	= 0,
46943d822aSTony Han };
47943d822aSTony Han 
48943d822aSTony Han /* Layout for DIVPMC dividers */
49943d822aSTony Han static const struct clk_pll_layout pll_layout_divpmc = {
50943d822aSTony Han 	.div_mask	= GENMASK_32(7, 0),
51943d822aSTony Han 	.endiv_mask	= BIT(29),
52943d822aSTony Han 	.div_shift	= 0,
53943d822aSTony Han 	.endiv_shift	= 29,
54943d822aSTony Han };
55943d822aSTony Han 
56943d822aSTony Han /* Layout for DIVIO dividers */
57943d822aSTony Han static const struct clk_pll_layout pll_layout_divio = {
58943d822aSTony Han 	.div_mask	= GENMASK_32(19, 12),
59943d822aSTony Han 	.endiv_mask	= BIT(30),
60943d822aSTony Han 	.div_shift	= 12,
61943d822aSTony Han 	.endiv_shift	= 30,
62943d822aSTony Han };
63943d822aSTony Han 
64943d822aSTony Han /*
65943d822aSTony Han  * CPU PLL output range
66943d822aSTony Han  * Notice: The upper limit has been setup to 1000000002 due to hardware
67943d822aSTony Han  * block which cannot output exactly 1GHz.
68943d822aSTony Han  */
69943d822aSTony Han static const struct clk_range cpu_pll_output[] = {
70943d822aSTony Han 	{ .min = 2343750, .max = 1000000002 },
71943d822aSTony Han };
72943d822aSTony Han 
73943d822aSTony Han /* PLL output range */
74943d822aSTony Han static const struct clk_range pll_output[] = {
75943d822aSTony Han 	{ .min = 2343750, .max = 1200000000 },
76943d822aSTony Han };
77943d822aSTony Han 
78943d822aSTony Han /* CPU PLL characteristics */
79943d822aSTony Han static const struct clk_pll_charac cpu_pll_characteristics = {
80943d822aSTony Han 	.input = { .min = 12000000, .max = 50000000 },
81943d822aSTony Han 	.num_output = ARRAY_SIZE(cpu_pll_output),
82943d822aSTony Han 	.output = cpu_pll_output,
83943d822aSTony Han };
84943d822aSTony Han 
85943d822aSTony Han /* PLL characteristics */
86943d822aSTony Han static const struct clk_pll_charac pll_characteristics = {
87943d822aSTony Han 	.input = { .min = 12000000, .max = 50000000 },
88943d822aSTony Han 	.num_output = ARRAY_SIZE(pll_output),
89943d822aSTony Han 	.output = pll_output,
90943d822aSTony Han };
91943d822aSTony Han 
92943d822aSTony Han /* PLL clocks description */
93943d822aSTony Han struct sama7g5_pll {
94943d822aSTony Han 	const char *name;
95943d822aSTony Han 	const char *parent;
96943d822aSTony Han 	const struct clk_pll_layout *layout;
97943d822aSTony Han 	const struct clk_pll_charac *charac;
98943d822aSTony Han 	unsigned long flags;
99943d822aSTony Han 	uint8_t type;
100943d822aSTony Han 	uint8_t eid; /* export index in sama7g5->chws[] array */
101943d822aSTony Han 	uint8_t safe_div; /* intermediate divider need to be set on
102943d822aSTony Han 			   * PRE_RATE_CHANGE notification
103943d822aSTony Han 			   */
104943d822aSTony Han };
105943d822aSTony Han 
106943d822aSTony Han static const struct sama7g5_pll sama7g5_plls[][PLL_ID_MAX] = {
107943d822aSTony Han 	[PLL_ID_CPU] = {
108943d822aSTony Han 		{
109943d822aSTony Han 			.name = "cpupll_fracck",
110943d822aSTony Han 			.parent = "mainck",
111943d822aSTony Han 			.layout = &pll_layout_frac,
112943d822aSTony Han 			.charac = &cpu_pll_characteristics,
113943d822aSTony Han 			.type = PLL_TYPE_FRAC,
114943d822aSTony Han 			/*
115943d822aSTony Han 			 * This feeds cpupll_divpmcck which feeds CPU. It
116943d822aSTony Han 			 * should not be disabled.
117943d822aSTony Han 			 */
118943d822aSTony Han 			.flags = CLK_IS_CRITICAL,
119943d822aSTony Han 		},
120943d822aSTony Han 		{
121943d822aSTony Han 			.name = "cpupll_divpmcck",
122943d822aSTony Han 			.parent = "cpupll_fracck",
123943d822aSTony Han 			.layout = &pll_layout_divpmc,
124943d822aSTony Han 			.charac = &cpu_pll_characteristics,
125943d822aSTony Han 			.type = PLL_TYPE_DIV,
126943d822aSTony Han 			/* This feeds CPU. It should not be disabled. */
127943d822aSTony Han 			.flags = CLK_IS_CRITICAL,
128943d822aSTony Han 			.eid = PMC_CPUPLL,
129943d822aSTony Han 			/*
130943d822aSTony Han 			 * Safe div=15 should be safe even for switching b/w
131943d822aSTony Han 			 * 1GHz and 90MHz (frac pll might go up to 1.2GHz).
132943d822aSTony Han 			 */
133943d822aSTony Han 			.safe_div = 15,
134943d822aSTony Han 		},
135943d822aSTony Han 	},
136943d822aSTony Han 
137943d822aSTony Han 	[PLL_ID_SYS] = {
138943d822aSTony Han 		{
139943d822aSTony Han 			.name = "syspll_fracck",
140943d822aSTony Han 			.parent = "mainck",
141943d822aSTony Han 			.layout = &pll_layout_frac,
142943d822aSTony Han 			.charac = &pll_characteristics,
143943d822aSTony Han 			.type = PLL_TYPE_FRAC,
144943d822aSTony Han 			/*
145943d822aSTony Han 			 * This feeds syspll_divpmcck which may feed critical
146943d822aSTony Han 			 * parts of the systems like timers. Therefore it
147943d822aSTony Han 			 * should not be disabled.
148943d822aSTony Han 			 */
149943d822aSTony Han 			.flags = CLK_IS_CRITICAL | CLK_SET_RATE_GATE,
150943d822aSTony Han 		},
151943d822aSTony Han 		{
152943d822aSTony Han 			.name = "syspll_divpmcck",
153943d822aSTony Han 			.parent = "syspll_fracck",
154943d822aSTony Han 			.layout = &pll_layout_divpmc,
155943d822aSTony Han 			.charac = &pll_characteristics,
156943d822aSTony Han 			.type = PLL_TYPE_DIV,
157943d822aSTony Han 			/*
158943d822aSTony Han 			 * This may feed critical parts of the systems like
159943d822aSTony Han 			 * timers. Therefore it should not be disabled.
160943d822aSTony Han 			 */
161943d822aSTony Han 			.flags = CLK_IS_CRITICAL | CLK_SET_RATE_GATE,
162943d822aSTony Han 			.eid = PMC_SYSPLL,
163943d822aSTony Han 		},
164943d822aSTony Han 	},
165943d822aSTony Han 
166943d822aSTony Han 	[PLL_ID_DDR] = {
167943d822aSTony Han 		{
168943d822aSTony Han 			.name = "ddrpll_fracck",
169943d822aSTony Han 			.parent = "mainck",
170943d822aSTony Han 			.layout = &pll_layout_frac,
171943d822aSTony Han 			.charac = &pll_characteristics,
172943d822aSTony Han 			.type = PLL_TYPE_FRAC,
173943d822aSTony Han 			/*
174943d822aSTony Han 			 * This feeds ddrpll_divpmcck which feeds DDR. It
175943d822aSTony Han 			 * should not be disabled.
176943d822aSTony Han 			 */
177943d822aSTony Han 			.flags = CLK_IS_CRITICAL | CLK_SET_RATE_GATE,
178943d822aSTony Han 		},
179943d822aSTony Han 		{
180943d822aSTony Han 			.name = "ddrpll_divpmcck",
181943d822aSTony Han 			.parent = "ddrpll_fracck",
182943d822aSTony Han 			.layout = &pll_layout_divpmc,
183943d822aSTony Han 			.charac = &pll_characteristics,
184943d822aSTony Han 			.type = PLL_TYPE_DIV,
185943d822aSTony Han 			/* This feeds DDR. It should not be disabled. */
186943d822aSTony Han 			.flags = CLK_IS_CRITICAL | CLK_SET_RATE_GATE,
187943d822aSTony Han 			.eid = PMC_DDRPLL,
188943d822aSTony Han 		},
189943d822aSTony Han 	},
190943d822aSTony Han 
191943d822aSTony Han 	[PLL_ID_IMG] = {
192943d822aSTony Han 		{
193943d822aSTony Han 			.name = "imgpll_fracck",
194943d822aSTony Han 			.parent = "mainck",
195943d822aSTony Han 			.layout = &pll_layout_frac,
196943d822aSTony Han 			.charac = &pll_characteristics,
197943d822aSTony Han 			.type = PLL_TYPE_FRAC,
198943d822aSTony Han 			.flags = CLK_SET_RATE_GATE,
199943d822aSTony Han 		},
200943d822aSTony Han 		{
201943d822aSTony Han 			.name = "imgpll_divpmcck",
202943d822aSTony Han 			.parent = "imgpll_fracck",
203943d822aSTony Han 			.layout = &pll_layout_divpmc,
204943d822aSTony Han 			.charac = &pll_characteristics,
205943d822aSTony Han 			.type = PLL_TYPE_DIV,
206943d822aSTony Han 			.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE,
207943d822aSTony Han 			.eid = PMC_IMGPLL,
208943d822aSTony Han 		},
209943d822aSTony Han 	},
210943d822aSTony Han 
211943d822aSTony Han 	[PLL_ID_BAUD] = {
212943d822aSTony Han 		{
213943d822aSTony Han 			.name = "baudpll_fracck",
214943d822aSTony Han 			.parent = "mainck",
215943d822aSTony Han 			.layout = &pll_layout_frac,
216943d822aSTony Han 			.charac = &pll_characteristics,
217943d822aSTony Han 			.type = PLL_TYPE_FRAC,
218943d822aSTony Han 			.flags = CLK_SET_RATE_GATE,
219943d822aSTony Han 		},
220943d822aSTony Han 		{
221943d822aSTony Han 			.name = "baudpll_divpmcck",
222943d822aSTony Han 			.parent = "baudpll_fracck",
223943d822aSTony Han 			.layout = &pll_layout_divpmc,
224943d822aSTony Han 			.charac = &pll_characteristics,
225943d822aSTony Han 			.type = PLL_TYPE_DIV,
226943d822aSTony Han 			.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE,
227943d822aSTony Han 			.eid = PMC_BAUDPLL,
228943d822aSTony Han 		},
229943d822aSTony Han 	},
230943d822aSTony Han 
231943d822aSTony Han 	[PLL_ID_AUDIO] = {
232943d822aSTony Han 		{
233943d822aSTony Han 			.name = "audiopll_fracck",
234943d822aSTony Han 			.parent = "main_xtal",
235943d822aSTony Han 			.layout = &pll_layout_frac,
236943d822aSTony Han 			.charac = &pll_characteristics,
237943d822aSTony Han 			.type = PLL_TYPE_FRAC,
238943d822aSTony Han 			.flags = CLK_SET_RATE_GATE,
239943d822aSTony Han 		},
240943d822aSTony Han 		{
241943d822aSTony Han 			.name = "audiopll_divck",
242943d822aSTony Han 			.parent = "audiopll_fracck",
243943d822aSTony Han 			.layout = &pll_layout_divpmc,
244943d822aSTony Han 			.charac = &pll_characteristics,
245943d822aSTony Han 			.type = PLL_TYPE_DIV,
246943d822aSTony Han 			.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE,
247943d822aSTony Han 			.eid = PMC_AUDIOPMCPLL,
248943d822aSTony Han 		},
249943d822aSTony Han 		{
250943d822aSTony Han 			.name = "audiopll_diviock",
251943d822aSTony Han 			.parent = "audiopll_fracck",
252943d822aSTony Han 			.layout = &pll_layout_divio,
253943d822aSTony Han 			.charac = &pll_characteristics,
254943d822aSTony Han 			.type = PLL_TYPE_DIV,
255943d822aSTony Han 			.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE,
256943d822aSTony Han 			.eid = PMC_AUDIOIOPLL,
257943d822aSTony Han 		},
258943d822aSTony Han 	},
259943d822aSTony Han 
260943d822aSTony Han 	[PLL_ID_ETH] = {
261943d822aSTony Han 		{
262943d822aSTony Han 			.name = "ethpll_fracck",
263943d822aSTony Han 			.parent = "main_xtal",
264943d822aSTony Han 			.layout = &pll_layout_frac,
265943d822aSTony Han 			.charac = &pll_characteristics,
266943d822aSTony Han 			.type = PLL_TYPE_FRAC,
267943d822aSTony Han 			.flags = CLK_SET_RATE_GATE,
268943d822aSTony Han 		},
269943d822aSTony Han 		{
270943d822aSTony Han 			.name = "ethpll_divpmcck",
271943d822aSTony Han 			.parent = "ethpll_fracck",
272943d822aSTony Han 			.layout = &pll_layout_divpmc,
273943d822aSTony Han 			.charac = &pll_characteristics,
274943d822aSTony Han 			.type = PLL_TYPE_DIV,
275943d822aSTony Han 			.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE,
276943d822aSTony Han 			.eid = PMC_ETHPLL,
277943d822aSTony Han 		},
278943d822aSTony Han 	},
279943d822aSTony Han };
280943d822aSTony Han 
281943d822aSTony Han /*
282943d822aSTony Han  * Master clock (MCK[1..4]) description
283943d822aSTony Han  * @eparents:		extra parents names array
284943d822aSTony Han  * @eparents_chg_id:	index in parents array that specifies the changeable
285943d822aSTony Han  *			parent
286943d822aSTony Han  * @eparents_count:	extra parents count
287943d822aSTony Han  * @eparents_mux_table:	mux table for extra parents
288943d822aSTony Han  * @id:			clock id
289943d822aSTony Han  * @eid:		export index in sama7g5->chws[] array
290943d822aSTony Han  */
291943d822aSTony Han struct sama7g5_mck {
292943d822aSTony Han 	const char *name;
293943d822aSTony Han 	const char *eparents[4];
294943d822aSTony Han 	int eparents_chg_id;
295943d822aSTony Han 	uint8_t eparents_count;
296943d822aSTony Han 	uint8_t eparents_mux_table[4];
297943d822aSTony Han 	uint8_t id;
298943d822aSTony Han 	uint8_t eid;
299943d822aSTony Han };
300943d822aSTony Han 
301943d822aSTony Han static const struct sama7g5_mck sama7g5_mckx[] = {
302943d822aSTony Han 	{
303943d822aSTony Han 		.name = "mck1",
304943d822aSTony Han 		.id = 1,
305943d822aSTony Han 		.eparents = { "syspll_divpmcck", },
306943d822aSTony Han 		.eparents_mux_table = { 5, },
307943d822aSTony Han 		.eparents_count = 1,
308943d822aSTony Han 		.eparents_chg_id = INT_MIN,
309943d822aSTony Han 		.eid = PMC_MCK1,
310943d822aSTony Han 	},
311943d822aSTony Han 	{
312943d822aSTony Han 		.name = "mck2",
313943d822aSTony Han 		.id = 2,
314943d822aSTony Han 		.eparents = { "ddrpll_divpmcck", },
315943d822aSTony Han 		.eparents_mux_table = { 6, },
316943d822aSTony Han 		.eparents_count = 1,
317943d822aSTony Han 		.eparents_chg_id = INT_MIN,
318943d822aSTony Han 	},
319943d822aSTony Han 	{
320943d822aSTony Han 		.name = "mck3",
321943d822aSTony Han 		.id = 3,
322943d822aSTony Han 		.eparents = { "syspll_divpmcck",
323943d822aSTony Han 			"ddrpll_divpmcck",
324943d822aSTony Han 			"imgpll_divpmcck", },
325943d822aSTony Han 		.eparents_mux_table = { 5, 6, 7, },
326943d822aSTony Han 		.eparents_count = 3,
327943d822aSTony Han 		.eparents_chg_id = 5,
328943d822aSTony Han 	},
329943d822aSTony Han 	{
330943d822aSTony Han 		.name = "mck4",
331943d822aSTony Han 		.id = 4,
332943d822aSTony Han 		.eparents = { "syspll_divpmcck", },
333943d822aSTony Han 		.eparents_mux_table = { 5, },
334943d822aSTony Han 		.eparents_count = 1,
335943d822aSTony Han 		.eparents_chg_id = INT_MIN,
336943d822aSTony Han 	},
337943d822aSTony Han };
338943d822aSTony Han 
339943d822aSTony Han /* System clock description */
340943d822aSTony Han static const struct {
341943d822aSTony Han 	const char *name;
342943d822aSTony Han 	const char *parent;
343943d822aSTony Han 	uint8_t id;
344943d822aSTony Han } sama7g5_systemck[] = {
345943d822aSTony Han 	{ .name = "pck0", .parent = "prog0", .id = 8, },
346943d822aSTony Han 	{ .name = "pck1", .parent = "prog1", .id = 9, },
347943d822aSTony Han 	{ .name = "pck2", .parent = "prog2", .id = 10, },
348943d822aSTony Han 	{ .name = "pck3", .parent = "prog3", .id = 11, },
349943d822aSTony Han 	{ .name = "pck4", .parent = "prog4", .id = 12, },
350943d822aSTony Han 	{ .name = "pck5", .parent = "prog5", .id = 13, },
351943d822aSTony Han 	{ .name = "pck6", .parent = "prog6", .id = 14, },
352943d822aSTony Han 	{ .name = "pck7", .parent = "prog7", .id = 15, },
353943d822aSTony Han };
354943d822aSTony Han 
355943d822aSTony Han /* Peripheral clock description */
356943d822aSTony Han static const struct {
357943d822aSTony Han 	const char *name;
358943d822aSTony Han 	const char *parent;
359943d822aSTony Han 	struct clk_range output;
360943d822aSTony Han 	uint8_t id;
361943d822aSTony Han } peri_clks[] = {
362943d822aSTony Han 	{
363943d822aSTony Han 		.name = "pioA_clk",
364943d822aSTony Han 		.parent = "mck0",
365943d822aSTony Han 		.id = 11,
366943d822aSTony Han 	},
367943d822aSTony Han 	{
368943d822aSTony Han 		.name = "securam_clk",
369943d822aSTony Han 		.parent = "mck0",
370943d822aSTony Han 		.id = 18,
371943d822aSTony Han 	},
372943d822aSTony Han 	{
373943d822aSTony Han 		.name = "sfr_clk",
374943d822aSTony Han 		.parent = "mck1",
375943d822aSTony Han 		.id = 19,
376943d822aSTony Han 	},
377943d822aSTony Han 	{
378943d822aSTony Han 		.name = "hsmc_clk",
379943d822aSTony Han 		.parent = "mck1",
380943d822aSTony Han 		.id = 21,
381943d822aSTony Han 	},
382943d822aSTony Han 	{
383943d822aSTony Han 		.name = "xdmac0_clk",
384943d822aSTony Han 		.parent = "mck1",
385943d822aSTony Han 		.id = 22,
386943d822aSTony Han 	},
387943d822aSTony Han 	{
388943d822aSTony Han 		.name = "xdmac1_clk",
389943d822aSTony Han 		.parent = "mck1",
390943d822aSTony Han 		.id = 23,
391943d822aSTony Han 	},
392943d822aSTony Han 	{
393943d822aSTony Han 		.name = "xdmac2_clk",
394943d822aSTony Han 		.parent = "mck1",
395943d822aSTony Han 		.id = 24,
396943d822aSTony Han 	},
397943d822aSTony Han 	{
398943d822aSTony Han 		.name = "acc_clk",
399943d822aSTony Han 		.parent = "mck1",
400943d822aSTony Han 		.id = 25,
401943d822aSTony Han 	},
402943d822aSTony Han 	{
403943d822aSTony Han 		.name = "aes_clk",
404943d822aSTony Han 		.parent = "mck1",
405943d822aSTony Han 		.id = 27,
406943d822aSTony Han 	},
407943d822aSTony Han 	{
408943d822aSTony Han 		.name = "tzaesbasc_clk",
409943d822aSTony Han 		.parent = "mck1",
410943d822aSTony Han 		.id = 28,
411943d822aSTony Han 	},
412943d822aSTony Han 	{
413943d822aSTony Han 		.name = "asrc_clk",
414943d822aSTony Han 		.parent = "mck1",
415943d822aSTony Han 		.id = 30,
416943d822aSTony Han 		.output = { .max = 200000000, },
417943d822aSTony Han 	},
418943d822aSTony Han 	{
419943d822aSTony Han 		.name = "cpkcc_clk",
420943d822aSTony Han 		.parent = "mck0",
421943d822aSTony Han 		.id = 32,
422943d822aSTony Han 	},
423943d822aSTony Han 	{
424943d822aSTony Han 		.name = "csi_clk",
425943d822aSTony Han 		.parent = "mck3",
426943d822aSTony Han 		.id = 33,
427943d822aSTony Han 		.output = { .max = 266000000, },
428943d822aSTony Han 	},
429943d822aSTony Han 	{
430943d822aSTony Han 		.name = "csi2dc_clk",
431943d822aSTony Han 		.parent = "mck3",
432943d822aSTony Han 		.id = 34,
433943d822aSTony Han 		.output = { .max = 266000000, },
434943d822aSTony Han 	},
435943d822aSTony Han 	{
436943d822aSTony Han 		.name = "eic_clk",
437943d822aSTony Han 		.parent = "mck1",
438943d822aSTony Han 		.id = 37,
439943d822aSTony Han 	},
440943d822aSTony Han 	{
441943d822aSTony Han 		.name = "flex0_clk",
442943d822aSTony Han 		.parent = "mck1",
443943d822aSTony Han 		.id = 38,
444943d822aSTony Han 	},
445943d822aSTony Han 	{
446943d822aSTony Han 		.name = "flex1_clk",
447943d822aSTony Han 		.parent = "mck1",
448943d822aSTony Han 		.id = 39,
449943d822aSTony Han 	},
450943d822aSTony Han 	{
451943d822aSTony Han 		.name = "flex2_clk",
452943d822aSTony Han 		.parent = "mck1",
453943d822aSTony Han 		.id = 40,
454943d822aSTony Han 	},
455943d822aSTony Han 	{
456943d822aSTony Han 		.name = "flex3_clk",
457943d822aSTony Han 		.parent = "mck1",
458943d822aSTony Han 		.id = 41,
459943d822aSTony Han 	},
460943d822aSTony Han 	{
461943d822aSTony Han 		.name = "flex4_clk",
462943d822aSTony Han 		.parent = "mck1",
463943d822aSTony Han 		.id = 42,
464943d822aSTony Han 	},
465943d822aSTony Han 	{
466943d822aSTony Han 		.name = "flex5_clk",
467943d822aSTony Han 		.parent = "mck1",
468943d822aSTony Han 		.id = 43,
469943d822aSTony Han 	},
470943d822aSTony Han 	{
471943d822aSTony Han 		.name = "flex6_clk",
472943d822aSTony Han 		.parent = "mck1",
473943d822aSTony Han 		.id = 44,
474943d822aSTony Han 	},
475943d822aSTony Han 	{
476943d822aSTony Han 		.name = "flex7_clk",
477943d822aSTony Han 		.parent = "mck1",
478943d822aSTony Han 		.id = 45,
479943d822aSTony Han 	},
480943d822aSTony Han 	{
481943d822aSTony Han 		.name = "flex8_clk",
482943d822aSTony Han 		.parent = "mck1",
483943d822aSTony Han 		.id = 46,
484943d822aSTony Han 	},
485943d822aSTony Han 	{
486943d822aSTony Han 		.name = "flex9_clk",
487943d822aSTony Han 		.parent = "mck1",
488943d822aSTony Han 		.id = 47,
489943d822aSTony Han 	},
490943d822aSTony Han 	{
491943d822aSTony Han 		.name = "flex10_clk",
492943d822aSTony Han 		.parent = "mck1",
493943d822aSTony Han 		.id = 48,
494943d822aSTony Han 	},
495943d822aSTony Han 	{
496943d822aSTony Han 		.name = "flex11_clk",
497943d822aSTony Han 		.parent = "mck1",
498943d822aSTony Han 		.id = 49,
499943d822aSTony Han 	},
500943d822aSTony Han 	{
501943d822aSTony Han 		.name = "gmac0_clk",
502943d822aSTony Han 		.parent = "mck1",
503943d822aSTony Han 		.id = 51,
504943d822aSTony Han 	},
505943d822aSTony Han 	{
506943d822aSTony Han 		.name = "gmac1_clk",
507943d822aSTony Han 		.parent = "mck1",
508943d822aSTony Han 		.id = 52,
509943d822aSTony Han 	},
510943d822aSTony Han 	{
511943d822aSTony Han 		.name = "icm_clk",
512943d822aSTony Han 		.parent = "mck1",
513943d822aSTony Han 		.id = 55,
514943d822aSTony Han 	},
515943d822aSTony Han 	{
516943d822aSTony Han 		.name = "isc_clk",
517943d822aSTony Han 		.parent = "mck3",
518943d822aSTony Han 		.id = 56,
519943d822aSTony Han 		.output = { .max = 266000000, },
520943d822aSTony Han 	},
521943d822aSTony Han 	{
522943d822aSTony Han 		.name = "i2smcc0_clk",
523943d822aSTony Han 		.parent = "mck1",
524943d822aSTony Han 		.id = 57,
525943d822aSTony Han 		.output = { .max = 200000000, },
526943d822aSTony Han 	},
527943d822aSTony Han 	{
528943d822aSTony Han 		.name = "i2smcc1_clk",
529943d822aSTony Han 		.parent = "mck1",
530943d822aSTony Han 		.id = 58,
531943d822aSTony Han 		.output = { .max = 200000000, },
532943d822aSTony Han 	},
533943d822aSTony Han 	{
534943d822aSTony Han 		.name = "matrix_clk",
535943d822aSTony Han 		.parent = "mck1",
536943d822aSTony Han 		.id = 60, },
537943d822aSTony Han 	{
538943d822aSTony Han 		.name = "mcan0_clk",
539943d822aSTony Han 		.parent = "mck1",
540943d822aSTony Han 		.id = 61,
541943d822aSTony Han 		.output = { .max = 200000000, },
542943d822aSTony Han 	},
543943d822aSTony Han 	{
544943d822aSTony Han 		.name = "mcan1_clk",
545943d822aSTony Han 		.parent = "mck1",
546943d822aSTony Han 		.id = 62,
547943d822aSTony Han 		.output = { .max = 200000000, },
548943d822aSTony Han 	},
549943d822aSTony Han 	{
550943d822aSTony Han 		.name = "mcan2_clk",
551943d822aSTony Han 		.parent = "mck1",
552943d822aSTony Han 		.id = 63,
553943d822aSTony Han 		.output = { .max = 200000000, },
554943d822aSTony Han 	},
555943d822aSTony Han 	{
556943d822aSTony Han 		.name = "mcan3_clk",
557943d822aSTony Han 		.parent = "mck1",
558943d822aSTony Han 		.id = 64,
559943d822aSTony Han 		.output = { .max = 200000000, },
560943d822aSTony Han 	},
561943d822aSTony Han 	{
562943d822aSTony Han 		.name = "mcan4_clk",
563943d822aSTony Han 		.parent = "mck1",
564943d822aSTony Han 		.id = 65,
565943d822aSTony Han 		.output = { .max = 200000000, },
566943d822aSTony Han 	},
567943d822aSTony Han 	{
568943d822aSTony Han 		.name = "mcan5_clk",
569943d822aSTony Han 		.parent = "mck1",
570943d822aSTony Han 		.id = 66,
571943d822aSTony Han 		.output = { .max = 200000000, },
572943d822aSTony Han 	},
573943d822aSTony Han 	{
574943d822aSTony Han 		.name = "pdmc0_clk",
575943d822aSTony Han 		.parent = "mck1",
576943d822aSTony Han 		.id = 68,
577943d822aSTony Han 		.output = { .max = 200000000, },
578943d822aSTony Han 	},
579943d822aSTony Han 	{
580943d822aSTony Han 		.name = "pdmc1_clk",
581943d822aSTony Han 		.parent = "mck1",
582943d822aSTony Han 		.id = 69,
583943d822aSTony Han 		.output = { .max = 200000000, },
584943d822aSTony Han 	},
585943d822aSTony Han 	{
586943d822aSTony Han 		.name = "pit64b0_clk",
587943d822aSTony Han 		.parent = "mck1",
588943d822aSTony Han 		.id = 70,
589943d822aSTony Han 	},
590943d822aSTony Han 	{
591943d822aSTony Han 		.name = "pit64b1_clk",
592943d822aSTony Han 		.parent = "mck1",
593943d822aSTony Han 		.id = 71,
594943d822aSTony Han 	},
595943d822aSTony Han 	{
596943d822aSTony Han 		.name = "pit64b2_clk",
597943d822aSTony Han 		.parent = "mck1",
598943d822aSTony Han 		.id = 72,
599943d822aSTony Han 	},
600943d822aSTony Han 	{
601943d822aSTony Han 		.name = "pit64b3_clk",
602943d822aSTony Han 		.parent = "mck1",
603943d822aSTony Han 		.id = 73,
604943d822aSTony Han 	},
605943d822aSTony Han 	{
606943d822aSTony Han 		.name = "pit64b4_clk",
607943d822aSTony Han 		.parent = "mck1",
608943d822aSTony Han 		.id = 74,
609943d822aSTony Han 	},
610943d822aSTony Han 	{
611943d822aSTony Han 		.name = "pit64b5_clk",
612943d822aSTony Han 		.parent = "mck1",
613943d822aSTony Han 		.id = 75,
614943d822aSTony Han 	},
615943d822aSTony Han 	{
616943d822aSTony Han 		.name = "pwm_clk",
617943d822aSTony Han 		.parent = "mck1",
618943d822aSTony Han 		.id = 77,
619943d822aSTony Han 	},
620943d822aSTony Han 	{
621943d822aSTony Han 		.name = "qspi0_clk",
622943d822aSTony Han 		.parent = "mck1",
623943d822aSTony Han 		.id = 78,
624943d822aSTony Han 	},
625943d822aSTony Han 	{
626943d822aSTony Han 		.name = "qspi1_clk",
627943d822aSTony Han 		.parent = "mck1",
628943d822aSTony Han 		.id = 79,
629943d822aSTony Han 	},
630943d822aSTony Han 	{
631943d822aSTony Han 		.name = "sdmmc0_clk",
632943d822aSTony Han 		.parent = "mck1",
633943d822aSTony Han 		.id = 80,
634943d822aSTony Han 	},
635943d822aSTony Han 	{
636943d822aSTony Han 		.name = "sdmmc1_clk",
637943d822aSTony Han 		.parent = "mck1",
638943d822aSTony Han 		.id = 81,
639943d822aSTony Han 	},
640943d822aSTony Han 	{
641943d822aSTony Han 		.name = "sdmmc2_clk",
642943d822aSTony Han 		.parent = "mck1",
643943d822aSTony Han 		.id = 82,
644943d822aSTony Han 	},
645943d822aSTony Han 	{
646943d822aSTony Han 		.name = "sha_clk",
647943d822aSTony Han 		.parent = "mck1",
648943d822aSTony Han 		.id = 83,
649943d822aSTony Han 	},
650943d822aSTony Han 	{
651943d822aSTony Han 		.name = "spdifrx_clk",
652943d822aSTony Han 		.parent = "mck1",
653943d822aSTony Han 		.id = 84,
654943d822aSTony Han 		.output = { .max = 200000000, },
655943d822aSTony Han 	},
656943d822aSTony Han 	{
657943d822aSTony Han 		.name = "spdiftx_clk",
658943d822aSTony Han 		.parent = "mck1",
659943d822aSTony Han 		.id = 85,
660943d822aSTony Han 		.output = { .max = 200000000, },
661943d822aSTony Han 	},
662943d822aSTony Han 	{
663943d822aSTony Han 		.name = "ssc0_clk",
664943d822aSTony Han 		.parent = "mck1",
665943d822aSTony Han 		.id = 86,
666943d822aSTony Han 		.output = { .max = 200000000, },
667943d822aSTony Han 	},
668943d822aSTony Han 	{
669943d822aSTony Han 		.name = "ssc1_clk",
670943d822aSTony Han 		.parent = "mck1",
671943d822aSTony Han 		.id = 87,
672943d822aSTony Han 		.output = { .max = 200000000, },
673943d822aSTony Han 	},
674943d822aSTony Han 	{
675943d822aSTony Han 		.name = "tcb0_ch0_clk",
676943d822aSTony Han 		.parent = "mck1",
677943d822aSTony Han 		.id = 88,
678943d822aSTony Han 		.output = { .max = 200000000, },
679943d822aSTony Han 	},
680943d822aSTony Han 	{
681943d822aSTony Han 		.name = "tcb0_ch1_clk",
682943d822aSTony Han 		.parent = "mck1",
683943d822aSTony Han 		.id = 89,
684943d822aSTony Han 		.output = { .max = 200000000, },
685943d822aSTony Han 	},
686943d822aSTony Han 	{
687943d822aSTony Han 		.name = "tcb0_ch2_clk",
688943d822aSTony Han 		.parent = "mck1",
689943d822aSTony Han 		.id = 90,
690943d822aSTony Han 		.output = { .max = 200000000, },
691943d822aSTony Han 	},
692943d822aSTony Han 	{
693943d822aSTony Han 		.name = "tcb1_ch0_clk",
694943d822aSTony Han 		.parent = "mck1",
695943d822aSTony Han 		.id = 91,
696943d822aSTony Han 		.output = { .max = 200000000, },
697943d822aSTony Han 	},
698943d822aSTony Han 	{
699943d822aSTony Han 		.name = "tcb1_ch1_clk",
700943d822aSTony Han 		.parent = "mck1",
701943d822aSTony Han 		.id = 92,
702943d822aSTony Han 		.output = { .max = 200000000, },
703943d822aSTony Han 	},
704943d822aSTony Han 	{
705943d822aSTony Han 		.name = "tcb1_ch2_clk",
706943d822aSTony Han 		.parent = "mck1",
707943d822aSTony Han 		.id = 93,
708943d822aSTony Han 		.output = { .max = 200000000, },
709943d822aSTony Han 	},
710943d822aSTony Han 	{
711943d822aSTony Han 		.name = "tcpca_clk",
712943d822aSTony Han 		.parent = "mck1",
713943d822aSTony Han 		.id = 94,
714943d822aSTony Han 	},
715943d822aSTony Han 	{
716943d822aSTony Han 		.name = "tcpcb_clk",
717943d822aSTony Han 		.parent = "mck1",
718943d822aSTony Han 		.id = 95,
719943d822aSTony Han 	},
720943d822aSTony Han 	{
721943d822aSTony Han 		.name = "tdes_clk",
722943d822aSTony Han 		.parent = "mck1",
723943d822aSTony Han 		.id = 96,
724943d822aSTony Han 	},
725943d822aSTony Han 	{
726943d822aSTony Han 		.name = "trng_clk",
727943d822aSTony Han 		.parent = "mck1",
728943d822aSTony Han 		.id = 97,
729943d822aSTony Han 	},
730943d822aSTony Han 	{
731943d822aSTony Han 		.name = "udphsa_clk",
732943d822aSTony Han 		.parent = "mck1",
733943d822aSTony Han 		.id = 104,
734943d822aSTony Han 	},
735943d822aSTony Han 	{
736943d822aSTony Han 		.name = "udphsb_clk",
737943d822aSTony Han 		.parent = "mck1",
738943d822aSTony Han 		.id = 105,
739943d822aSTony Han 	},
740943d822aSTony Han 	{
741943d822aSTony Han 		.name = "uhphs_clk",
742943d822aSTony Han 		.parent = "mck1",
743943d822aSTony Han 		.id = 106,
744943d822aSTony Han 	},
745943d822aSTony Han };
746943d822aSTony Han 
747943d822aSTony Han /* UTMI clock description */
748943d822aSTony Han static struct {
749943d822aSTony Han 	const char *name;
750943d822aSTony Han 	const char *parent;
751943d822aSTony Han 	uint8_t id;
752943d822aSTony Han } sama7_utmick[] = {
75383aae07dSTony Han 	{ .name = "utmi1ck", .parent = "utmick", .id = 0, },
75483aae07dSTony Han 	{ .name = "utmi2ck", .parent = "utmi1ck", .id = 1, },
75583aae07dSTony Han 	{ .name = "utmi3ck", .parent = "utmi1ck", .id = 2, },
756943d822aSTony Han };
757943d822aSTony Han 
758943d822aSTony Han /* Generic clock description */
759943d822aSTony Han struct sama7g5_gck {
760943d822aSTony Han 	const char *name;
761943d822aSTony Han 	const char *parents[8];
762943d822aSTony Han 	const char parents_mux_table[8];
763943d822aSTony Han 	struct clk_range output;
764943d822aSTony Han 	int parents_chg_id; /* id in parent array of changeable PLL parent */
765943d822aSTony Han 	uint8_t parents_count;
766943d822aSTony Han 	uint8_t id;
767943d822aSTony Han };
768943d822aSTony Han 
769943d822aSTony Han static const struct sama7g5_gck sama7g5_gcks[] = {
770943d822aSTony Han 	{
771943d822aSTony Han 		.name  = "adc_gclk",
772943d822aSTony Han 		.id = 26,
773943d822aSTony Han 		.output = { .max = 100000000, },
774943d822aSTony Han 		.parents = { "syspll_divpmcck",
775943d822aSTony Han 			     "imgpll_divpmcck",
776943d822aSTony Han 			     "audiopll_divck", },
777943d822aSTony Han 		.parents_mux_table = { 5, 7, 9, },
778943d822aSTony Han 		.parents_count = 3,
779943d822aSTony Han 		.parents_chg_id = INT_MIN,
780943d822aSTony Han 	},
781943d822aSTony Han 	{
782943d822aSTony Han 		.name  = "asrc_gclk",
783943d822aSTony Han 		.id = 30,
784943d822aSTony Han 		.output = { .max = 200000000 },
785943d822aSTony Han 		.parents = { "audiopll_divck", },
786943d822aSTony Han 		.parents_mux_table = { 9, },
787943d822aSTony Han 		.parents_count = 1,
788943d822aSTony Han 		.parents_chg_id = INT_MIN,
789943d822aSTony Han 	},
790943d822aSTony Han 	{
791943d822aSTony Han 		.name  = "csi_gclk",
792943d822aSTony Han 		.id = 33,
793943d822aSTony Han 		.output = { .max = 27000000  },
794943d822aSTony Han 		.parents = { "ddrpll_divpmcck", "imgpll_divpmcck", },
795943d822aSTony Han 		.parents_mux_table = { 6, 7, },
796943d822aSTony Han 		.parents_count = 2,
797943d822aSTony Han 		.parents_chg_id = INT_MIN,
798943d822aSTony Han 	},
799943d822aSTony Han 	{
800943d822aSTony Han 		.name  = "flex0_gclk",
801943d822aSTony Han 		.id = 38,
802943d822aSTony Han 		.output = { .max = 200000000 },
803943d822aSTony Han 		.parents = { "syspll_divpmcck", "baudpll_divpmcck", },
804943d822aSTony Han 		.parents_mux_table = { 5, 8, },
805943d822aSTony Han 		.parents_count = 2,
806943d822aSTony Han 		.parents_chg_id = INT_MIN,
807943d822aSTony Han 	},
808943d822aSTony Han 	{
809943d822aSTony Han 		.name  = "flex1_gclk",
810943d822aSTony Han 		.id = 39,
811943d822aSTony Han 		.output = { .max = 200000000 },
812943d822aSTony Han 		.parents = { "syspll_divpmcck", "baudpll_divpmcck", },
813943d822aSTony Han 		.parents_mux_table = { 5, 8, },
814943d822aSTony Han 		.parents_count = 2,
815943d822aSTony Han 		.parents_chg_id = INT_MIN,
816943d822aSTony Han 	},
817943d822aSTony Han 	{
818943d822aSTony Han 		.name  = "flex2_gclk",
819943d822aSTony Han 		.id = 40,
820943d822aSTony Han 		.output = { .max = 200000000 },
821943d822aSTony Han 		.parents = { "syspll_divpmcck", "baudpll_divpmcck", },
822943d822aSTony Han 		.parents_mux_table = { 5, 8, },
823943d822aSTony Han 		.parents_count = 2,
824943d822aSTony Han 		.parents_chg_id = INT_MIN,
825943d822aSTony Han 	},
826943d822aSTony Han 	{
827943d822aSTony Han 		.name  = "flex3_gclk",
828943d822aSTony Han 		.id = 41,
829943d822aSTony Han 		.output = { .max = 200000000 },
830943d822aSTony Han 		.parents = { "syspll_divpmcck", "baudpll_divpmcck", },
831943d822aSTony Han 		.parents_mux_table = { 5, 8, },
832943d822aSTony Han 		.parents_count = 2,
833943d822aSTony Han 		.parents_chg_id = INT_MIN,
834943d822aSTony Han 	},
835943d822aSTony Han 	{
836943d822aSTony Han 		.name  = "flex4_gclk",
837943d822aSTony Han 		.id = 42,
838943d822aSTony Han 		.output = { .max = 200000000 },
839943d822aSTony Han 		.parents = { "syspll_divpmcck", "baudpll_divpmcck", },
840943d822aSTony Han 		.parents_mux_table = { 5, 8, },
841943d822aSTony Han 		.parents_count = 2,
842943d822aSTony Han 		.parents_chg_id = INT_MIN,
843943d822aSTony Han 	},
844943d822aSTony Han 	{
845943d822aSTony Han 		.name  = "flex5_gclk",
846943d822aSTony Han 		.id = 43,
847943d822aSTony Han 		.output = { .max = 200000000 },
848943d822aSTony Han 		.parents = { "syspll_divpmcck", "baudpll_divpmcck", },
849943d822aSTony Han 		.parents_mux_table = { 5, 8, },
850943d822aSTony Han 		.parents_count = 2,
851943d822aSTony Han 		.parents_chg_id = INT_MIN,
852943d822aSTony Han 	},
853943d822aSTony Han 	{
854943d822aSTony Han 		.name  = "flex6_gclk",
855943d822aSTony Han 		.id = 44,
856943d822aSTony Han 		.output = { .max = 200000000 },
857943d822aSTony Han 		.parents = { "syspll_divpmcck", "baudpll_divpmcck", },
858943d822aSTony Han 		.parents_mux_table = { 5, 8, },
859943d822aSTony Han 		.parents_count = 2,
860943d822aSTony Han 		.parents_chg_id = INT_MIN,
861943d822aSTony Han 	},
862943d822aSTony Han 	{
863943d822aSTony Han 		.name  = "flex7_gclk",
864943d822aSTony Han 		.id = 45,
865943d822aSTony Han 		.output = { .max = 200000000 },
866943d822aSTony Han 		.parents = { "syspll_divpmcck", "baudpll_divpmcck", },
867943d822aSTony Han 		.parents_mux_table = { 5, 8, },
868943d822aSTony Han 		.parents_count = 2,
869943d822aSTony Han 		.parents_chg_id = INT_MIN,
870943d822aSTony Han 	},
871943d822aSTony Han 	{
872943d822aSTony Han 		.name  = "flex8_gclk",
873943d822aSTony Han 		.id = 46,
874943d822aSTony Han 		.output = { .max = 200000000 },
875943d822aSTony Han 		.parents = { "syspll_divpmcck", "baudpll_divpmcck", },
876943d822aSTony Han 		.parents_mux_table = { 5, 8, },
877943d822aSTony Han 		.parents_count = 2,
878943d822aSTony Han 		.parents_chg_id = INT_MIN,
879943d822aSTony Han 	},
880943d822aSTony Han 	{
881943d822aSTony Han 		.name  = "flex9_gclk",
882943d822aSTony Han 		.id = 47,
883943d822aSTony Han 		.output = { .max = 200000000 },
884943d822aSTony Han 		.parents = { "syspll_divpmcck", "baudpll_divpmcck", },
885943d822aSTony Han 		.parents_mux_table = { 5, 8, },
886943d822aSTony Han 		.parents_count = 2,
887943d822aSTony Han 		.parents_chg_id = INT_MIN,
888943d822aSTony Han 	},
889943d822aSTony Han 	{
890943d822aSTony Han 		.name  = "flex10_gclk",
891943d822aSTony Han 		.id = 48,
892943d822aSTony Han 		.output = { .max = 200000000 },
893943d822aSTony Han 		.parents = { "syspll_divpmcck", "baudpll_divpmcck", },
894943d822aSTony Han 		.parents_mux_table = { 5, 8, },
895943d822aSTony Han 		.parents_count = 2,
896943d822aSTony Han 		.parents_chg_id = INT_MIN,
897943d822aSTony Han 	},
898943d822aSTony Han 	{
899943d822aSTony Han 		.name  = "flex11_gclk",
900943d822aSTony Han 		.id = 49,
901943d822aSTony Han 		.output = { .max = 200000000 },
902943d822aSTony Han 		.parents = { "syspll_divpmcck", "baudpll_divpmcck", },
903943d822aSTony Han 		.parents_mux_table = { 5, 8, },
904943d822aSTony Han 		.parents_count = 2,
905943d822aSTony Han 		.parents_chg_id = INT_MIN,
906943d822aSTony Han 	},
907943d822aSTony Han 	{
908943d822aSTony Han 		.name  = "gmac0_gclk",
909943d822aSTony Han 		.id = 51,
910943d822aSTony Han 		.output = { .max = 125000000 },
911943d822aSTony Han 		.parents = { "ethpll_divpmcck", },
912943d822aSTony Han 		.parents_mux_table = { 10, },
913943d822aSTony Han 		.parents_count = 1,
914943d822aSTony Han 		.parents_chg_id = 3,
915943d822aSTony Han 	},
916943d822aSTony Han 	{
917943d822aSTony Han 		.name  = "gmac1_gclk",
918943d822aSTony Han 		.id = 52,
919943d822aSTony Han 		.output = { .max = 50000000  },
920943d822aSTony Han 		.parents = { "ethpll_divpmcck", },
921943d822aSTony Han 		.parents_mux_table = { 10, },
922943d822aSTony Han 		.parents_count = 1,
923943d822aSTony Han 		.parents_chg_id = INT_MIN,
924943d822aSTony Han 	},
925943d822aSTony Han 	{
926943d822aSTony Han 		.name  = "gmac0_tsu_gclk",
927943d822aSTony Han 		.id = 53,
928943d822aSTony Han 		.output = { .max = 300000000 },
929943d822aSTony Han 		.parents = { "audiopll_divck", "ethpll_divpmcck", },
930943d822aSTony Han 		.parents_mux_table = { 9, 10, },
931943d822aSTony Han 		.parents_count = 2,
932943d822aSTony Han 		.parents_chg_id = INT_MIN,
933943d822aSTony Han 	},
934943d822aSTony Han 	{
935943d822aSTony Han 		.name  = "gmac1_tsu_gclk",
936943d822aSTony Han 		.id = 54,
937943d822aSTony Han 		.output = { .max = 300000000 },
938943d822aSTony Han 		.parents = { "audiopll_divck", "ethpll_divpmcck", },
939943d822aSTony Han 		.parents_mux_table = { 9, 10, },
940943d822aSTony Han 		.parents_count = 2,
941943d822aSTony Han 		.parents_chg_id = INT_MIN,
942943d822aSTony Han 	},
943943d822aSTony Han 	{
944943d822aSTony Han 		.name  = "i2smcc0_gclk",
945943d822aSTony Han 		.id = 57,
946943d822aSTony Han 		.output = { .max = 100000000 },
947943d822aSTony Han 		.parents = { "syspll_divpmcck", "audiopll_divck", },
948943d822aSTony Han 		.parents_mux_table = { 5, 9, },
949943d822aSTony Han 		.parents_count = 2,
950943d822aSTony Han 		.parents_chg_id = INT_MIN,
951943d822aSTony Han 	},
952943d822aSTony Han 	{
953943d822aSTony Han 		.name  = "i2smcc1_gclk",
954943d822aSTony Han 		.id = 58,
955943d822aSTony Han 		.output = { .max = 100000000 },
956943d822aSTony Han 		.parents = { "syspll_divpmcck", "audiopll_divck", },
957943d822aSTony Han 		.parents_mux_table = { 5, 9, },
958943d822aSTony Han 		.parents_count = 2,
959943d822aSTony Han 		.parents_chg_id = INT_MIN,
960943d822aSTony Han 	},
961943d822aSTony Han 	{
962943d822aSTony Han 		.name  = "mcan0_gclk",
963943d822aSTony Han 		.id = 61,
964943d822aSTony Han 		.output = { .max = 200000000 },
965943d822aSTony Han 		.parents = { "syspll_divpmcck", "baudpll_divpmcck", },
966943d822aSTony Han 		.parents_mux_table = { 5, 8, },
967943d822aSTony Han 		.parents_count = 2,
968943d822aSTony Han 		.parents_chg_id = INT_MIN,
969943d822aSTony Han 	},
970943d822aSTony Han 	{
971943d822aSTony Han 		.name  = "mcan1_gclk",
972943d822aSTony Han 		.id = 62,
973943d822aSTony Han 		.output = { .max = 200000000 },
974943d822aSTony Han 		.parents = { "syspll_divpmcck", "baudpll_divpmcck", },
975943d822aSTony Han 		.parents_mux_table = { 5, 8, },
976943d822aSTony Han 		.parents_count = 2,
977943d822aSTony Han 		.parents_chg_id = INT_MIN,
978943d822aSTony Han 	},
979943d822aSTony Han 	{
980943d822aSTony Han 		.name  = "mcan2_gclk",
981943d822aSTony Han 		.id = 63,
982943d822aSTony Han 		.output = { .max = 200000000 },
983943d822aSTony Han 		.parents = { "syspll_divpmcck", "baudpll_divpmcck", },
984943d822aSTony Han 		.parents_mux_table = { 5, 8, },
985943d822aSTony Han 		.parents_count = 2,
986943d822aSTony Han 		.parents_chg_id = INT_MIN,
987943d822aSTony Han 	},
988943d822aSTony Han 	{
989943d822aSTony Han 		.name  = "mcan3_gclk",
990943d822aSTony Han 		.id = 64,
991943d822aSTony Han 		.output = { .max = 200000000 },
992943d822aSTony Han 		.parents = { "syspll_divpmcck", "baudpll_divpmcck", },
993943d822aSTony Han 		.parents_mux_table = { 5, 8, },
994943d822aSTony Han 		.parents_count = 2,
995943d822aSTony Han 		.parents_chg_id = INT_MIN,
996943d822aSTony Han 	},
997943d822aSTony Han 	{
998943d822aSTony Han 		.name  = "mcan4_gclk",
999943d822aSTony Han 		.id = 65,
1000943d822aSTony Han 		.output = { .max = 200000000 },
1001943d822aSTony Han 		.parents = { "syspll_divpmcck", "baudpll_divpmcck", },
1002943d822aSTony Han 		.parents_mux_table = { 5, 8, },
1003943d822aSTony Han 		.parents_count = 2,
1004943d822aSTony Han 		.parents_chg_id = INT_MIN,
1005943d822aSTony Han 	},
1006943d822aSTony Han 	{
1007943d822aSTony Han 		.name  = "mcan5_gclk",
1008943d822aSTony Han 		.id = 66,
1009943d822aSTony Han 		.output = { .max = 200000000 },
1010943d822aSTony Han 		.parents = { "syspll_divpmcck", "baudpll_divpmcck", },
1011943d822aSTony Han 		.parents_mux_table = { 5, 8, },
1012943d822aSTony Han 		.parents_count = 2,
1013943d822aSTony Han 		.parents_chg_id = INT_MIN,
1014943d822aSTony Han 	},
1015943d822aSTony Han 	{
1016943d822aSTony Han 		.name  = "pdmc0_gclk",
1017943d822aSTony Han 		.id = 68,
1018943d822aSTony Han 		.output = { .max = 50000000  },
1019943d822aSTony Han 		.parents = { "syspll_divpmcck", "audiopll_divck", },
1020943d822aSTony Han 		.parents_mux_table = { 5, 9, },
1021943d822aSTony Han 		.parents_count = 2,
1022943d822aSTony Han 		.parents_chg_id = INT_MIN,
1023943d822aSTony Han 	},
1024943d822aSTony Han 	{
1025943d822aSTony Han 		.name  = "pdmc1_gclk",
1026943d822aSTony Han 		.id = 69,
1027943d822aSTony Han 		.output = { .max = 50000000, },
1028943d822aSTony Han 		.parents = { "syspll_divpmcck", "audiopll_divck", },
1029943d822aSTony Han 		.parents_mux_table = { 5, 9, },
1030943d822aSTony Han 		.parents_count = 2,
1031943d822aSTony Han 		.parents_chg_id = INT_MIN,
1032943d822aSTony Han 	},
1033943d822aSTony Han 	{
1034943d822aSTony Han 		.name  = "pit64b0_gclk",
1035943d822aSTony Han 		.id = 70,
1036943d822aSTony Han 		.output = { .max = 200000000 },
1037943d822aSTony Han 		.parents = { "syspll_divpmcck", "imgpll_divpmcck",
1038943d822aSTony Han 			     "baudpll_divpmcck", "audiopll_divck",
1039943d822aSTony Han 			     "ethpll_divpmcck", },
1040943d822aSTony Han 		.parents_mux_table = { 5, 7, 8, 9, 10, },
1041943d822aSTony Han 		.parents_count = 5,
1042943d822aSTony Han 		.parents_chg_id = INT_MIN,
1043943d822aSTony Han 	},
1044943d822aSTony Han 	{
1045943d822aSTony Han 		.name  = "pit64b1_gclk",
1046943d822aSTony Han 		.id = 71,
1047943d822aSTony Han 		.output = { .max = 200000000 },
1048943d822aSTony Han 		.parents = { "syspll_divpmcck", "imgpll_divpmcck",
1049943d822aSTony Han 			     "baudpll_divpmcck", "audiopll_divck",
1050943d822aSTony Han 			     "ethpll_divpmcck", },
1051943d822aSTony Han 		.parents_mux_table = { 5, 7, 8, 9, 10, },
1052943d822aSTony Han 		.parents_count = 5,
1053943d822aSTony Han 		.parents_chg_id = INT_MIN,
1054943d822aSTony Han 	},
1055943d822aSTony Han 	{
1056943d822aSTony Han 		.name  = "pit64b2_gclk",
1057943d822aSTony Han 		.id = 72,
1058943d822aSTony Han 		.output = { .max = 200000000 },
1059943d822aSTony Han 		.parents = { "syspll_divpmcck", "imgpll_divpmcck",
1060943d822aSTony Han 			     "baudpll_divpmcck", "audiopll_divck",
1061943d822aSTony Han 			     "ethpll_divpmcck", },
1062943d822aSTony Han 		.parents_mux_table = { 5, 7, 8, 9, 10, },
1063943d822aSTony Han 		.parents_count = 5,
1064943d822aSTony Han 		.parents_chg_id = INT_MIN,
1065943d822aSTony Han 	},
1066943d822aSTony Han 	{
1067943d822aSTony Han 		.name  = "pit64b3_gclk",
1068943d822aSTony Han 		.id = 73,
1069943d822aSTony Han 		.output = { .max = 200000000 },
1070943d822aSTony Han 		.parents = { "syspll_divpmcck", "imgpll_divpmcck",
1071943d822aSTony Han 			     "baudpll_divpmcck", "audiopll_divck",
1072943d822aSTony Han 			     "ethpll_divpmcck", },
1073943d822aSTony Han 		.parents_mux_table = { 5, 7, 8, 9, 10, },
1074943d822aSTony Han 		.parents_count = 5,
1075943d822aSTony Han 		.parents_chg_id = INT_MIN,
1076943d822aSTony Han 	},
1077943d822aSTony Han 	{
1078943d822aSTony Han 		.name  = "pit64b4_gclk",
1079943d822aSTony Han 		.id = 74,
1080943d822aSTony Han 		.output = { .max = 200000000 },
1081943d822aSTony Han 		.parents = { "syspll_divpmcck", "imgpll_divpmcck",
1082943d822aSTony Han 			     "baudpll_divpmcck", "audiopll_divck",
1083943d822aSTony Han 			     "ethpll_divpmcck", },
1084943d822aSTony Han 		.parents_mux_table = { 5, 7, 8, 9, 10, },
1085943d822aSTony Han 		.parents_count = 5,
1086943d822aSTony Han 		.parents_chg_id = INT_MIN,
1087943d822aSTony Han 	},
1088943d822aSTony Han 	{
1089943d822aSTony Han 		.name  = "pit64b5_gclk",
1090943d822aSTony Han 		.id = 75,
1091943d822aSTony Han 		.output = { .max = 200000000 },
1092943d822aSTony Han 		.parents = { "syspll_divpmcck", "imgpll_divpmcck",
1093943d822aSTony Han 			     "baudpll_divpmcck", "audiopll_divck",
1094943d822aSTony Han 			     "ethpll_divpmcck", },
1095943d822aSTony Han 		.parents_mux_table = { 5, 7, 8, 9, 10, },
1096943d822aSTony Han 		.parents_count = 5,
1097943d822aSTony Han 		.parents_chg_id = INT_MIN,
1098943d822aSTony Han 	},
1099943d822aSTony Han 	{
1100943d822aSTony Han 		.name  = "qspi0_gclk",
1101943d822aSTony Han 		.id = 78,
1102943d822aSTony Han 		.output = { .max = 200000000 },
1103943d822aSTony Han 		.parents = { "syspll_divpmcck", "baudpll_divpmcck", },
1104943d822aSTony Han 		.parents_mux_table = { 5, 8, },
1105943d822aSTony Han 		.parents_count = 2,
1106943d822aSTony Han 		.parents_chg_id = INT_MIN,
1107943d822aSTony Han 	},
1108943d822aSTony Han 	{
1109943d822aSTony Han 		.name  = "qspi1_gclk",
1110943d822aSTony Han 		.id = 79,
1111943d822aSTony Han 		.output = { .max = 200000000 },
1112943d822aSTony Han 		.parents = { "syspll_divpmcck", "baudpll_divpmcck", },
1113943d822aSTony Han 		.parents_mux_table = { 5, 8, },
1114943d822aSTony Han 		.parents_count = 2,
1115943d822aSTony Han 		.parents_chg_id = INT_MIN,
1116943d822aSTony Han 	},
1117943d822aSTony Han 	{
1118943d822aSTony Han 		.name  = "sdmmc0_gclk",
1119943d822aSTony Han 		.id = 80,
1120943d822aSTony Han 		.output = { .max = 208000000 },
1121943d822aSTony Han 		.parents = { "syspll_divpmcck", "baudpll_divpmcck", },
1122943d822aSTony Han 		.parents_mux_table = { 5, 8, },
1123943d822aSTony Han 		.parents_count = 2,
1124943d822aSTony Han 		.parents_chg_id = 4,
1125943d822aSTony Han 	},
1126943d822aSTony Han 	{
1127943d822aSTony Han 		.name  = "sdmmc1_gclk",
1128943d822aSTony Han 		.id = 81,
1129943d822aSTony Han 		.output = { .max = 208000000 },
1130943d822aSTony Han 		.parents = { "syspll_divpmcck", "baudpll_divpmcck", },
1131943d822aSTony Han 		.parents_mux_table = { 5, 8, },
1132943d822aSTony Han 		.parents_count = 2,
1133943d822aSTony Han 		.parents_chg_id = 4,
1134943d822aSTony Han 	},
1135943d822aSTony Han 	{
1136943d822aSTony Han 		.name  = "sdmmc2_gclk",
1137943d822aSTony Han 		.id = 82,
1138943d822aSTony Han 		.output = { .max = 208000000 },
1139943d822aSTony Han 		.parents = { "syspll_divpmcck", "baudpll_divpmcck", },
1140943d822aSTony Han 		.parents_mux_table = { 5, 8, },
1141943d822aSTony Han 		.parents_count = 2,
1142943d822aSTony Han 		.parents_chg_id = 4,
1143943d822aSTony Han 	},
1144943d822aSTony Han 	{
1145943d822aSTony Han 		.name  = "spdifrx_gclk",
1146943d822aSTony Han 		.id = 84,
1147943d822aSTony Han 		.output = { .max = 150000000 },
1148943d822aSTony Han 		.parents = { "syspll_divpmcck", "audiopll_divck", },
1149943d822aSTony Han 		.parents_mux_table = { 5, 9, },
1150943d822aSTony Han 		.parents_count = 2,
1151943d822aSTony Han 		.parents_chg_id = INT_MIN,
1152943d822aSTony Han 	},
1153943d822aSTony Han 	{
1154943d822aSTony Han 		.name = "spdiftx_gclk",
1155943d822aSTony Han 		.id = 85,
1156943d822aSTony Han 		.output = { .max = 25000000  },
1157943d822aSTony Han 		.parents = { "syspll_divpmcck", "audiopll_divck", },
1158943d822aSTony Han 		.parents_mux_table = { 5, 9, },
1159943d822aSTony Han 		.parents_count = 2,
1160943d822aSTony Han 		.parents_chg_id = INT_MIN,
1161943d822aSTony Han 	},
1162943d822aSTony Han 	{
1163943d822aSTony Han 		.name  = "tcb0_ch0_gclk",
1164943d822aSTony Han 		.id = 88,
1165943d822aSTony Han 		.output = { .max = 200000000 },
1166943d822aSTony Han 		.parents = { "syspll_divpmcck", "imgpll_divpmcck",
1167943d822aSTony Han 			     "baudpll_divpmcck", "audiopll_divck",
1168943d822aSTony Han 			     "ethpll_divpmcck", },
1169943d822aSTony Han 		.parents_mux_table = { 5, 7, 8, 9, 10, },
1170943d822aSTony Han 		.parents_count = 5,
1171943d822aSTony Han 		.parents_chg_id = INT_MIN,
1172943d822aSTony Han 	},
1173943d822aSTony Han 	{
1174943d822aSTony Han 		.name  = "tcb1_ch0_gclk",
1175943d822aSTony Han 		.id = 91,
1176943d822aSTony Han 		.output = { .max = 200000000 },
1177943d822aSTony Han 		.parents = { "syspll_divpmcck", "imgpll_divpmcck",
1178943d822aSTony Han 			     "baudpll_divpmcck", "audiopll_divck",
1179943d822aSTony Han 			     "ethpll_divpmcck", },
1180943d822aSTony Han 		.parents_mux_table = { 5, 7, 8, 9, 10, },
1181943d822aSTony Han 		.parents_count = 5,
1182943d822aSTony Han 		.parents_chg_id = INT_MIN,
1183943d822aSTony Han 	},
1184943d822aSTony Han 	{
1185943d822aSTony Han 		.name  = "tcpca_gclk",
1186943d822aSTony Han 		.id = 94,
1187943d822aSTony Han 		.output = { .max = 32768, },
1188943d822aSTony Han 		.parents_chg_id = INT_MIN,
1189943d822aSTony Han 	},
1190943d822aSTony Han 	{
1191943d822aSTony Han 		.name  = "tcpcb_gclk",
1192943d822aSTony Han 		.id = 95,
1193943d822aSTony Han 		.output = { .max = 32768, },
1194943d822aSTony Han 		.parents_chg_id = INT_MIN,
1195943d822aSTony Han 	},
1196943d822aSTony Han };
1197943d822aSTony Han 
1198943d822aSTony Han /* MCK0 characteristics */
1199943d822aSTony Han static const struct clk_master_charac mck0_characteristics = {
1200943d822aSTony Han 	.output = { .min = 32768, .max = 200000000 },
1201943d822aSTony Han 	.divisors = { 1, 2, 4, 3, 5 },
1202943d822aSTony Han 	.have_div3_pres = 1,
1203943d822aSTony Han };
1204943d822aSTony Han 
1205943d822aSTony Han /* MCK0 layout */
1206943d822aSTony Han static const struct clk_master_layout mck0_layout = {
1207943d822aSTony Han 	.mask = 0x773,
1208943d822aSTony Han 	.pres_shift = 4,
1209943d822aSTony Han 	.offset = 0x28,
1210943d822aSTony Han };
1211943d822aSTony Han 
1212943d822aSTony Han /* Peripheral clock layout */
1213943d822aSTony Han static const struct clk_pcr_layout sama7g5_pcr_layout = {
1214943d822aSTony Han 	.offset = 0x88,
1215943d822aSTony Han 	.cmd = BIT(31),
1216943d822aSTony Han 	.div_mask = GENMASK_32(27, 20),
1217943d822aSTony Han 	.gckcss_mask = GENMASK_32(12, 8),
1218943d822aSTony Han 	.pid_mask = GENMASK_32(6, 0),
1219943d822aSTony Han };
1220943d822aSTony Han 
1221943d822aSTony Han static const struct clk_programmable_layout sama7g5_prog_layout = {
1222943d822aSTony Han 	.pres_mask = 0xff,
1223943d822aSTony Han 	.pres_shift = 8,
1224943d822aSTony Han 	.css_mask = GENMASK_32(4, 0),
1225943d822aSTony Han 	.have_slck_mck = 0,
1226943d822aSTony Han 	.is_pres_direct = 1,
1227943d822aSTony Han };
1228943d822aSTony Han 
1229943d822aSTony Han static const struct {
1230943d822aSTony Han 	const char *name;
1231943d822aSTony Han 	uint8_t id;
1232943d822aSTony Han } sama7g5_progck[] = {
1233943d822aSTony Han 	{ .name = "prog0", .id = 0 },
1234943d822aSTony Han 	{ .name = "prog1", .id = 1 },
1235943d822aSTony Han 	{ .name = "prog2", .id = 2 },
1236943d822aSTony Han 	{ .name = "prog3", .id = 3 },
1237943d822aSTony Han 	{ .name = "prog4", .id = 4 },
1238943d822aSTony Han 	{ .name = "prog5", .id = 5 },
1239943d822aSTony Han 	{ .name = "prog6", .id = 6 },
1240943d822aSTony Han 	{ .name = "prog7", .id = 7 },
1241943d822aSTony Han };
1242943d822aSTony Han 
1243943d822aSTony Han static struct pmc_data *sama7g5_pmc;
1244943d822aSTony Han 
at91_pmc_get_base(void)1245943d822aSTony Han vaddr_t at91_pmc_get_base(void)
1246943d822aSTony Han {
1247943d822aSTony Han 	assert(sama7g5_pmc);
1248943d822aSTony Han 
1249943d822aSTony Han 	return sama7g5_pmc->base;
1250943d822aSTony Han }
1251943d822aSTony Han 
at91_pmc_clk_get(unsigned int type,unsigned int idx,struct clk ** clk)1252943d822aSTony Han TEE_Result at91_pmc_clk_get(unsigned int type, unsigned int idx,
1253943d822aSTony Han 			    struct clk **clk)
1254943d822aSTony Han {
1255943d822aSTony Han 	return pmc_clk_get(sama7g5_pmc, type, idx, clk);
1256943d822aSTony Han }
1257943d822aSTony Han 
pmc_setup_sama7g5(const void * fdt,int nodeoffset,const void * data __unused)1258943d822aSTony Han static TEE_Result pmc_setup_sama7g5(const void *fdt, int nodeoffset,
1259943d822aSTony Han 				    const void *data __unused)
1260943d822aSTony Han {
1261943d822aSTony Han 	struct clk *pll_frac_clk[PLL_ID_MAX] = { };
1262943d822aSTony Han 	struct clk *pll_div_clk[PLL_ID_MAX] = { };
1263943d822aSTony Han 	TEE_Result res = TEE_ERROR_GENERIC;
1264943d822aSTony Han 	const uint32_t *fdt_prop = NULL;
1265943d822aSTony Han 	struct pmc_clk *pmc_clk = NULL;
1266943d822aSTony Han 	struct clk *parents[11] = { };
1267943d822aSTony Han 	struct clk *main_xtal_clk = NULL;
1268943d822aSTony Han 	struct clk *main_rc_osc = NULL;
1269943d822aSTony Han 	struct clk *main_osc = NULL;
1270943d822aSTony Han 	struct clk *mck0_clk = NULL;
1271943d822aSTony Han 	struct clk *main_clk = NULL;
1272943d822aSTony Han 	struct clk *md_slck = NULL;
1273943d822aSTony Han 	struct clk *td_slck = NULL;
1274943d822aSTony Han 	struct clk *parent = NULL;
1275943d822aSTony Han 	struct clk *clk = NULL;
1276943d822aSTony Han 	unsigned int i = 0;
1277943d822aSTony Han 	unsigned int j = 0;
1278943d822aSTony Han 	vaddr_t base = 0;
1279943d822aSTony Han 	size_t size = 0;
1280943d822aSTony Han 	int bypass = 0;
1281943d822aSTony Han 
1282943d822aSTony Han 	if (dt_map_dev(fdt, nodeoffset, &base, &size, DT_MAP_AUTO) < 0)
1283943d822aSTony Han 		panic();
1284943d822aSTony Han 
1285943d822aSTony Han 	if (fdt_get_status(fdt, nodeoffset) == DT_STATUS_OK_SEC)
1286943d822aSTony Han 		matrix_configure_periph_secure(ID_PMC);
1287943d822aSTony Han 
1288943d822aSTony Han 	res = clk_dt_get_by_name(fdt, nodeoffset, "md_slck", &md_slck);
1289943d822aSTony Han 	if (res)
1290943d822aSTony Han 		return res;
1291943d822aSTony Han 
1292943d822aSTony Han 	res = clk_dt_get_by_name(fdt, nodeoffset, "td_slck", &td_slck);
1293943d822aSTony Han 	if (res)
1294943d822aSTony Han 		return res;
1295943d822aSTony Han 
1296943d822aSTony Han 	res = clk_dt_get_by_name(fdt, nodeoffset, "main_xtal", &main_xtal_clk);
1297943d822aSTony Han 	if (res)
1298943d822aSTony Han 		return res;
1299943d822aSTony Han 
1300943d822aSTony Han 	sama7g5_pmc = pmc_data_allocate(PMC_SAMA7G5_CORE_CLK_COUNT,
1301943d822aSTony Han 					ARRAY_SIZE(sama7g5_systemck),
1302943d822aSTony Han 					ARRAY_SIZE(peri_clks),
1303943d822aSTony Han 					ARRAY_SIZE(sama7g5_gcks), 8);
1304943d822aSTony Han 	if (!sama7g5_pmc)
1305943d822aSTony Han 		panic();
1306943d822aSTony Han 
1307943d822aSTony Han 	sama7g5_pmc->base = base;
1308943d822aSTony Han 
1309943d822aSTony Han 	main_rc_osc = pmc_register_main_rc_osc(sama7g5_pmc, "main_rc_osc",
1310943d822aSTony Han 					       12000000);
1311943d822aSTony Han 	if (!main_rc_osc)
1312943d822aSTony Han 		panic();
1313943d822aSTony Han 
1314943d822aSTony Han 	fdt_prop = fdt_getprop(fdt, nodeoffset, "atmel,osc-bypass", NULL);
1315943d822aSTony Han 	if (fdt_prop)
1316943d822aSTony Han 		bypass = fdt32_to_cpu(*fdt_prop);
1317943d822aSTony Han 
1318943d822aSTony Han 	main_osc = pmc_register_main_osc(sama7g5_pmc, "main_osc",
1319943d822aSTony Han 					 main_xtal_clk, bypass);
1320943d822aSTony Han 	if (!main_osc)
1321943d822aSTony Han 		panic();
1322943d822aSTony Han 
1323943d822aSTony Han 	parents[0] = main_rc_osc;
1324943d822aSTony Han 	parents[1] = main_osc;
1325943d822aSTony Han 	main_clk = at91_clk_register_sam9x5_main(sama7g5_pmc, "mainck",
1326943d822aSTony Han 						 parents, 2);
1327943d822aSTony Han 	if (!main_clk)
1328943d822aSTony Han 		panic();
1329943d822aSTony Han 	pmc_clk = &sama7g5_pmc->chws[PMC_MAIN];
1330943d822aSTony Han 	pmc_clk->clk = main_clk;
1331943d822aSTony Han 	pmc_clk->id = PMC_MAIN;
1332943d822aSTony Han 
1333943d822aSTony Han 	for (i = 0; i < PLL_ID_MAX; i++) {
1334943d822aSTony Han 		struct pmc_data *pmc = sama7g5_pmc;
1335943d822aSTony Han 		const struct sama7g5_pll *p = NULL;
1336943d822aSTony Han 
1337943d822aSTony Han 		for (j = 0; j < 3; j++) {
1338943d822aSTony Han 			p = &sama7g5_plls[i][j];
1339943d822aSTony Han 			if (!p->name)
1340943d822aSTony Han 				continue;
1341943d822aSTony Han 
1342943d822aSTony Han 			switch (p->type) {
1343943d822aSTony Han 			case PLL_TYPE_FRAC:
1344943d822aSTony Han 				if (!strcmp(p->parent, "mainck"))
1345943d822aSTony Han 					parent = main_clk;
1346943d822aSTony Han 				else if (!strcmp(p->parent, "main_xtal"))
1347943d822aSTony Han 					parent = main_xtal_clk;
1348943d822aSTony Han 				else
1349943d822aSTony Han 					parent = pmc_clk_get_by_name(pmc->chws,
1350943d822aSTony Han 								     pmc->ncore,
1351943d822aSTony Han 								     p->parent);
1352943d822aSTony Han 				assert(parent);
1353943d822aSTony Han 
1354943d822aSTony Han 				clk = sam9x60_clk_register_frac_pll(sama7g5_pmc,
1355943d822aSTony Han 								    p->name,
1356943d822aSTony Han 								    parent, i,
1357943d822aSTony Han 								    p->charac,
1358943d822aSTony Han 								    p->layout,
1359943d822aSTony Han 								    p->flags);
1360943d822aSTony Han 				pll_frac_clk[i] = clk;
1361943d822aSTony Han 				break;
1362943d822aSTony Han 
1363943d822aSTony Han 			case PLL_TYPE_DIV:
1364943d822aSTony Han 				parent = clk;
1365943d822aSTony Han 				clk = sam9x60_clk_register_div_pll(sama7g5_pmc,
1366943d822aSTony Han 								   p->name,
1367943d822aSTony Han 								   parent, i,
1368943d822aSTony Han 								   p->charac,
1369943d822aSTony Han 								   p->layout,
1370943d822aSTony Han 								   p->flags,
1371943d822aSTony Han 								   p->safe_div);
1372943d822aSTony Han 				break;
1373943d822aSTony Han 
1374943d822aSTony Han 			default:
1375943d822aSTony Han 				continue;
1376943d822aSTony Han 			}
1377943d822aSTony Han 			if (!clk)
1378943d822aSTony Han 				panic();
1379943d822aSTony Han 
1380943d822aSTony Han 			if (p->eid) {
1381943d822aSTony Han 				sama7g5_pmc->chws[p->eid].clk = clk;
1382943d822aSTony Han 				sama7g5_pmc->chws[p->eid].id = p->eid;
1383b71b399eSTony Han 				sam_set_clock_range(PMC_TYPE_CORE, p->eid,
1384b71b399eSTony Han 						    p->charac->output);
1385943d822aSTony Han 			}
1386943d822aSTony Han 		}
1387943d822aSTony Han 		p = &sama7g5_plls[i][PLL_TYPE_DIV];
1388943d822aSTony Han 		pll_div_clk[i] = sama7g5_pmc->chws[p->eid].clk;
1389943d822aSTony Han 	}
1390943d822aSTony Han 
1391943d822aSTony Han 	parents[0] = md_slck;
1392943d822aSTony Han 	parents[1] = main_clk;
1393943d822aSTony Han 	parents[2] = pll_div_clk[PLL_ID_CPU];
1394943d822aSTony Han 	parents[3] = pll_div_clk[PLL_ID_SYS];
1395943d822aSTony Han 	clk = at91_clk_register_master_pres(sama7g5_pmc, "fclk", 4,
1396943d822aSTony Han 					    parents,
1397943d822aSTony Han 					    &mck0_layout,
1398943d822aSTony Han 					    &mck0_characteristics, INT_MIN);
1399943d822aSTony Han 	if (!clk)
1400943d822aSTony Han 		panic();
1401943d822aSTony Han 	pmc_clk = &sama7g5_pmc->chws[PMC_MCK_PRES];
1402943d822aSTony Han 	pmc_clk->clk = clk;
1403943d822aSTony Han 	pmc_clk->id = PMC_MCK_PRES;
1404943d822aSTony Han 
1405943d822aSTony Han 	mck0_clk = at91_clk_register_master_div(sama7g5_pmc, "mck0",
1406943d822aSTony Han 						clk,
1407943d822aSTony Han 						&mck0_layout,
1408943d822aSTony Han 						&mck0_characteristics);
1409943d822aSTony Han 	if (!mck0_clk)
1410943d822aSTony Han 		panic();
1411943d822aSTony Han 	pmc_clk = &sama7g5_pmc->chws[PMC_MCK];
1412943d822aSTony Han 	pmc_clk->clk = mck0_clk;
1413943d822aSTony Han 	pmc_clk->id = PMC_MCK;
1414b71b399eSTony Han 	sam_set_clock_range(PMC_TYPE_SYSTEM, PMC_MCK,
1415b71b399eSTony Han 			    &mck0_characteristics.output);
1416943d822aSTony Han 
1417943d822aSTony Han 	parents[0] = md_slck;
1418943d822aSTony Han 	parents[1] = td_slck;
1419943d822aSTony Han 	parents[2] = main_clk;
1420943d822aSTony Han 	parents[3] = mck0_clk;
1421943d822aSTony Han 	for (i = 0; i < ARRAY_SIZE(sama7g5_mckx); i++) {
1422943d822aSTony Han 		const struct sama7g5_mck *mck = &sama7g5_mckx[i];
1423943d822aSTony Han 		uint8_t num_parents = 4 + mck->eparents_count;
1424943d822aSTony Han 		uint32_t *mux_table = calloc(num_parents, sizeof(*mux_table));
1425943d822aSTony Han 
1426943d822aSTony Han 		if (!mux_table)
1427943d822aSTony Han 			panic();
1428943d822aSTony Han 
1429943d822aSTony Han 		mux_table[0] = 0;
1430943d822aSTony Han 		mux_table[1] = 1;
1431943d822aSTony Han 		mux_table[2] = 2;
1432943d822aSTony Han 		mux_table[3] = 3;
1433943d822aSTony Han 		for (j = 0; j < mck->eparents_count; j++) {
1434943d822aSTony Han 			parents[4 + j] = pmc_clk_get_by_name(sama7g5_pmc->chws,
1435943d822aSTony Han 							     sama7g5_pmc->ncore,
1436943d822aSTony Han 							     mck->eparents[j]);
1437943d822aSTony Han 			assert(parents[4 + j]);
1438943d822aSTony Han 			mux_table[4 + j] = mck->eparents_mux_table[j];
1439943d822aSTony Han 		}
1440943d822aSTony Han 
1441943d822aSTony Han 		clk = at91_clk_sama7g5_register_master(sama7g5_pmc,
1442943d822aSTony Han 						       mck->name,
1443943d822aSTony Han 						       num_parents, parents,
1444943d822aSTony Han 						       mux_table,
1445943d822aSTony Han 						       mck->id,
1446943d822aSTony Han 						       mck->eparents_chg_id);
1447943d822aSTony Han 		if (!clk)
1448943d822aSTony Han 			panic();
1449943d822aSTony Han 
1450943d822aSTony Han 		sama7g5_pmc->chws[PMC_MCK1 + i].clk = clk;
1451943d822aSTony Han 	}
1452943d822aSTony Han 
1453943d822aSTony Han 	clk = at91_clk_sama7g5_register_utmi(sama7g5_pmc, "utmick", main_clk);
1454943d822aSTony Han 	if (!clk)
1455943d822aSTony Han 		panic();
1456943d822aSTony Han 	sama7g5_pmc->chws[PMC_UTMI].clk = clk;
1457943d822aSTony Han 	sama7g5_pmc->chws[PMC_UTMI].id = PMC_UTMI;
1458943d822aSTony Han 
1459943d822aSTony Han 	for (i = 0; i < ARRAY_SIZE(sama7_utmick); i++) {
1460943d822aSTony Han 		if (strcmp("utmick", sama7_utmick[i].parent) == 0)
1461943d822aSTony Han 			parent = clk;
146283aae07dSTony Han 		else if (strcmp("utmi1ck", sama7_utmick[i].parent) == 0)
1463943d822aSTony Han 			parent = sama7g5_pmc->chws[PMC_UTMI1].clk;
1464943d822aSTony Han 		else
1465943d822aSTony Han 			panic();
1466943d822aSTony Han 		clk = sama7_utmi_clk_register(sama7_utmick[i].name, parent,
1467943d822aSTony Han 					      sama7_utmick[i].id);
1468943d822aSTony Han 		if (!clk)
1469943d822aSTony Han 			panic();
1470943d822aSTony Han 
1471943d822aSTony Han 		pmc_clk = &sama7g5_pmc->chws[PMC_UTMI1 + i];
1472943d822aSTony Han 		pmc_clk->clk = clk;
1473943d822aSTony Han 		pmc_clk->id = PMC_UTMI1 + i;
1474943d822aSTony Han 	}
1475943d822aSTony Han 
1476943d822aSTony Han 	parents[0] = md_slck;
1477943d822aSTony Han 	parents[1] = td_slck;
1478943d822aSTony Han 	parents[2] = main_clk;
1479943d822aSTony Han 	parents[3] = pll_div_clk[PLL_ID_SYS];
1480943d822aSTony Han 	parents[4] = pll_div_clk[PLL_ID_DDR];
1481943d822aSTony Han 	parents[5] = pll_div_clk[PLL_ID_IMG];
1482943d822aSTony Han 	parents[6] = pll_div_clk[PLL_ID_BAUD];
1483943d822aSTony Han 	parents[7] = pll_div_clk[PLL_ID_AUDIO];
1484943d822aSTony Han 	parents[8] = pll_div_clk[PLL_ID_ETH];
1485943d822aSTony Han 	for (i = 0; i < ARRAY_SIZE(sama7g5_progck); i++) {
1486943d822aSTony Han 		clk = at91_clk_register_programmable(sama7g5_pmc,
1487943d822aSTony Han 						     sama7g5_progck[i].name,
1488943d822aSTony Han 						     parents, 9, i,
1489943d822aSTony Han 						     &sama7g5_prog_layout);
1490943d822aSTony Han 		if (!clk)
1491943d822aSTony Han 			panic();
1492943d822aSTony Han 
1493943d822aSTony Han 		pmc_clk = &sama7g5_pmc->pchws[i];
1494943d822aSTony Han 		pmc_clk->clk = clk;
1495943d822aSTony Han 		pmc_clk->id = sama7g5_progck[i].id;
1496943d822aSTony Han 	}
1497943d822aSTony Han 
1498943d822aSTony Han 	for (i = 0; i < ARRAY_SIZE(sama7g5_systemck); i++) {
1499943d822aSTony Han 		clk = at91_clk_register_system(sama7g5_pmc,
1500943d822aSTony Han 					       sama7g5_systemck[i].name,
1501943d822aSTony Han 					       sama7g5_pmc->pchws[i].clk,
1502943d822aSTony Han 					       sama7g5_systemck[i].id);
1503943d822aSTony Han 		if (!clk)
1504943d822aSTony Han 			panic();
1505943d822aSTony Han 
1506943d822aSTony Han 		pmc_clk = &sama7g5_pmc->shws[i];
1507943d822aSTony Han 		pmc_clk->clk = clk;
1508943d822aSTony Han 		pmc_clk->id = sama7g5_systemck[i].id;
1509943d822aSTony Han 	}
1510943d822aSTony Han 
1511943d822aSTony Han 	for (i = 0; i < ARRAY_SIZE(peri_clks); i++) {
1512943d822aSTony Han 		parent = pmc_clk_get_by_name(sama7g5_pmc->chws,
1513943d822aSTony Han 					     sama7g5_pmc->ncore,
1514943d822aSTony Han 					     peri_clks[i].parent);
1515943d822aSTony Han 		clk = at91_clk_register_sam9x5_periph(sama7g5_pmc,
1516943d822aSTony Han 						      &sama7g5_pcr_layout,
1517943d822aSTony Han 						      peri_clks[i].name,
1518943d822aSTony Han 						      parent,
1519943d822aSTony Han 						      peri_clks[i].id,
1520943d822aSTony Han 						      &peri_clks[i].output);
1521943d822aSTony Han 		if (!clk)
1522943d822aSTony Han 			panic();
1523943d822aSTony Han 
1524943d822aSTony Han 		pmc_clk = &sama7g5_pmc->phws[i];
1525943d822aSTony Han 		pmc_clk->clk = clk;
1526943d822aSTony Han 		pmc_clk->id = peri_clks[i].id;
1527b71b399eSTony Han 
1528b71b399eSTony Han 		sam_set_clock_range(PMC_TYPE_PERIPHERAL, peri_clks[i].id,
1529b71b399eSTony Han 				    &peri_clks[i].output);
1530943d822aSTony Han 	}
1531943d822aSTony Han 
1532943d822aSTony Han 	parents[0] = md_slck;
1533943d822aSTony Han 	parents[1] = td_slck;
1534943d822aSTony Han 	parents[2] = main_clk;
1535943d822aSTony Han 	for (i = 0; i < ARRAY_SIZE(sama7g5_gcks); i++) {
1536943d822aSTony Han 		const struct sama7g5_gck *gck = sama7g5_gcks + i;
1537943d822aSTony Han 		uint8_t num_parents = 3 + gck->parents_count;
1538943d822aSTony Han 		uint32_t *mux_table = calloc(num_parents, sizeof(*mux_table));
1539943d822aSTony Han 
1540943d822aSTony Han 		if (!mux_table)
1541943d822aSTony Han 			panic();
1542943d822aSTony Han 
1543943d822aSTony Han 		mux_table[0] = 0;
1544943d822aSTony Han 		mux_table[1] = 1;
1545943d822aSTony Han 		mux_table[2] = 2;
1546943d822aSTony Han 		for (j = 0; j < gck->parents_count; j++) {
1547943d822aSTony Han 			parents[3 + j] = pmc_clk_get_by_name(sama7g5_pmc->chws,
1548943d822aSTony Han 							     sama7g5_pmc->ncore,
1549943d822aSTony Han 							     gck->parents[j]);
1550943d822aSTony Han 			assert(parents[3 + j]);
1551943d822aSTony Han 			mux_table[3 + j] = gck->parents_mux_table[j];
1552943d822aSTony Han 		}
1553943d822aSTony Han 
1554943d822aSTony Han 		clk = at91_clk_register_generated(sama7g5_pmc,
1555943d822aSTony Han 						  &sama7g5_pcr_layout,
1556943d822aSTony Han 						  gck->name, parents,
1557943d822aSTony Han 						  mux_table,
1558943d822aSTony Han 						  num_parents, gck->id,
1559943d822aSTony Han 						  &gck->output,
1560943d822aSTony Han 						  gck->parents_chg_id);
1561943d822aSTony Han 		if (!clk)
1562943d822aSTony Han 			panic();
1563943d822aSTony Han 
1564943d822aSTony Han 		pmc_clk = &sama7g5_pmc->ghws[i];
1565943d822aSTony Han 		pmc_clk->clk = clk;
1566943d822aSTony Han 		pmc_clk->id = gck->id;
1567b71b399eSTony Han 
1568b71b399eSTony Han 		sam_set_clock_range(PMC_TYPE_GCK, gck->id, &gck->output);
1569943d822aSTony Han 	}
1570943d822aSTony Han 
1571943d822aSTony Han 	res = clk_set_rate(pll_frac_clk[PLL_ID_ETH], 625000000);
1572943d822aSTony Han 	if (res)
1573943d822aSTony Han 		panic();
1574943d822aSTony Han 
1575943d822aSTony Han 	res = clk_set_rate(pll_div_clk[PLL_ID_ETH], 625000000);
1576943d822aSTony Han 	if (res)
1577943d822aSTony Han 		panic();
1578943d822aSTony Han 
15795d74b835STony Han 	res = clk_set_rate(pll_frac_clk[PLL_ID_AUDIO], 983040000);
15805d74b835STony Han 	if (res)
15815d74b835STony Han 		panic();
15825d74b835STony Han 
15835d74b835STony Han 	res = clk_set_rate(pll_div_clk[PLL_ID_AUDIO], 196608000);
15845d74b835STony Han 	if (res)
15855d74b835STony Han 		panic();
15865d74b835STony Han 
15875d74b835STony Han 	clk = pmc_clk_get_by_name(sama7g5_pmc->ghws, sama7g5_pmc->ngck,
15885d74b835STony Han 				  "pdmc0_gclk");
15895d74b835STony Han 	assert(clk);
15905d74b835STony Han 	res = clk_set_parent(clk, pll_div_clk[PLL_ID_AUDIO]);
15915d74b835STony Han 	if (res)
15925d74b835STony Han 		panic();
15935d74b835STony Han 
1594*e6b19839STony Han 	clk = pmc_clk_get_by_name(sama7g5_pmc->ghws, sama7g5_pmc->ngck,
1595*e6b19839STony Han 				  "i2smcc0_gclk");
1596*e6b19839STony Han 	assert(clk);
1597*e6b19839STony Han 	res = clk_set_parent(clk, pll_div_clk[PLL_ID_AUDIO]);
1598*e6b19839STony Han 	if (res)
1599*e6b19839STony Han 		panic();
1600*e6b19839STony Han 
1601943d822aSTony Han 	res = clk_dt_register_clk_provider(fdt, nodeoffset, clk_dt_pmc_get,
1602943d822aSTony Han 					   sama7g5_pmc);
1603943d822aSTony Han 	if (res)
1604943d822aSTony Han 		panic();
1605943d822aSTony Han 
1606943d822aSTony Han 	pmc_register_pm();
1607943d822aSTony Han 
1608943d822aSTony Han 	return TEE_SUCCESS;
1609943d822aSTony Han }
1610943d822aSTony Han 
1611943d822aSTony Han CLK_DT_DECLARE(sama7g5_clk, "microchip,sama7g5-pmc", pmc_setup_sama7g5);
1612