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