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