1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * Copyright 2013 Freescale Semiconductor, Inc. |
4 | * Copyright 2021 NXP |
5 | * |
6 | * clock driver for Freescale QorIQ SoCs. |
7 | */ |
8 | |
9 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
10 | |
11 | #include <dt-bindings/clock/fsl,qoriq-clockgen.h> |
12 | #include <linux/clk.h> |
13 | #include <linux/clk-provider.h> |
14 | #include <linux/clkdev.h> |
15 | #include <linux/fsl/guts.h> |
16 | #include <linux/io.h> |
17 | #include <linux/kernel.h> |
18 | #include <linux/module.h> |
19 | #include <linux/of_address.h> |
20 | #include <linux/of.h> |
21 | #include <linux/platform_device.h> |
22 | #include <linux/slab.h> |
23 | |
24 | #define PLL_DIV1 0 |
25 | #define PLL_DIV2 1 |
26 | #define PLL_DIV3 2 |
27 | #define PLL_DIV4 3 |
28 | |
29 | #define PLATFORM_PLL 0 |
30 | #define CGA_PLL1 1 |
31 | #define CGA_PLL2 2 |
32 | #define CGA_PLL3 3 |
33 | #define CGA_PLL4 4 /* only on clockgen-1.0, which lacks CGB */ |
34 | #define CGB_PLL1 4 |
35 | #define CGB_PLL2 5 |
36 | #define MAX_PLL_DIV 32 |
37 | |
38 | struct clockgen_pll_div { |
39 | struct clk *clk; |
40 | char name[32]; |
41 | }; |
42 | |
43 | struct clockgen_pll { |
44 | struct clockgen_pll_div div[MAX_PLL_DIV]; |
45 | }; |
46 | |
47 | #define CLKSEL_VALID 1 |
48 | #define CLKSEL_80PCT 2 /* Only allowed if PLL <= 80% of max cpu freq */ |
49 | |
50 | struct clockgen_sourceinfo { |
51 | u32 flags; /* CLKSEL_xxx */ |
52 | int pll; /* CGx_PLLn */ |
53 | int div; /* PLL_DIVn */ |
54 | }; |
55 | |
56 | #define NUM_MUX_PARENTS 16 |
57 | |
58 | struct clockgen_muxinfo { |
59 | struct clockgen_sourceinfo clksel[NUM_MUX_PARENTS]; |
60 | }; |
61 | |
62 | #define NUM_HWACCEL 5 |
63 | #define NUM_CMUX 8 |
64 | |
65 | struct clockgen; |
66 | |
67 | /* |
68 | * cmux freq must be >= platform pll. |
69 | * If not set, cmux freq must be >= platform pll/2 |
70 | */ |
71 | #define CG_CMUX_GE_PLAT 1 |
72 | |
73 | #define CG_PLL_8BIT 2 /* PLLCnGSR[CFG] is 8 bits, not 6 */ |
74 | #define CG_VER3 4 /* version 3 cg: reg layout different */ |
75 | #define CG_LITTLE_ENDIAN 8 |
76 | |
77 | struct clockgen_chipinfo { |
78 | const char *compat, *guts_compat; |
79 | const struct clockgen_muxinfo *cmux_groups[2]; |
80 | const struct clockgen_muxinfo *hwaccel[NUM_HWACCEL]; |
81 | void (*init_periph)(struct clockgen *cg); |
82 | int cmux_to_group[NUM_CMUX + 1]; /* array should be -1 terminated */ |
83 | u32 pll_mask; /* 1 << n bit set if PLL n is valid */ |
84 | u32 flags; /* CG_xxx */ |
85 | }; |
86 | |
87 | struct clockgen { |
88 | struct device_node *node; |
89 | void __iomem *regs; |
90 | struct clockgen_chipinfo info; /* mutable copy */ |
91 | struct clk *sysclk, *coreclk; |
92 | struct clockgen_pll pll[6]; |
93 | struct clk *cmux[NUM_CMUX]; |
94 | struct clk *hwaccel[NUM_HWACCEL]; |
95 | struct clk *fman[2]; |
96 | struct ccsr_guts __iomem *guts; |
97 | }; |
98 | |
99 | static struct clockgen clockgen; |
100 | static bool add_cpufreq_dev __initdata; |
101 | |
102 | static void cg_out(struct clockgen *cg, u32 val, u32 __iomem *reg) |
103 | { |
104 | if (cg->info.flags & CG_LITTLE_ENDIAN) |
105 | iowrite32(val, reg); |
106 | else |
107 | iowrite32be(val, reg); |
108 | } |
109 | |
110 | static u32 cg_in(struct clockgen *cg, u32 __iomem *reg) |
111 | { |
112 | u32 val; |
113 | |
114 | if (cg->info.flags & CG_LITTLE_ENDIAN) |
115 | val = ioread32(reg); |
116 | else |
117 | val = ioread32be(reg); |
118 | |
119 | return val; |
120 | } |
121 | |
122 | static const struct clockgen_muxinfo p2041_cmux_grp1 = { |
123 | { |
124 | [0] = { CLKSEL_VALID, CGA_PLL1, PLL_DIV1 }, |
125 | [1] = { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 }, |
126 | [4] = { CLKSEL_VALID, CGA_PLL2, PLL_DIV1 }, |
127 | } |
128 | }; |
129 | |
130 | static const struct clockgen_muxinfo p2041_cmux_grp2 = { |
131 | { |
132 | [0] = { CLKSEL_VALID, CGA_PLL1, PLL_DIV1 }, |
133 | [4] = { CLKSEL_VALID, CGA_PLL2, PLL_DIV1 }, |
134 | [5] = { CLKSEL_VALID, CGA_PLL2, PLL_DIV2 }, |
135 | } |
136 | }; |
137 | |
138 | static const struct clockgen_muxinfo p5020_cmux_grp1 = { |
139 | { |
140 | [0] = { CLKSEL_VALID, CGA_PLL1, PLL_DIV1 }, |
141 | [1] = { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 }, |
142 | [4] = { CLKSEL_VALID | CLKSEL_80PCT, CGA_PLL2, PLL_DIV1 }, |
143 | } |
144 | }; |
145 | |
146 | static const struct clockgen_muxinfo p5020_cmux_grp2 = { |
147 | { |
148 | [0] = { CLKSEL_VALID | CLKSEL_80PCT, CGA_PLL1, PLL_DIV1 }, |
149 | [4] = { CLKSEL_VALID, CGA_PLL2, PLL_DIV1 }, |
150 | [5] = { CLKSEL_VALID, CGA_PLL2, PLL_DIV2 }, |
151 | } |
152 | }; |
153 | |
154 | static const struct clockgen_muxinfo p5040_cmux_grp1 = { |
155 | { |
156 | [0] = { CLKSEL_VALID, CGA_PLL1, PLL_DIV1 }, |
157 | [1] = { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 }, |
158 | [4] = { CLKSEL_VALID | CLKSEL_80PCT, CGA_PLL2, PLL_DIV1 }, |
159 | [5] = { CLKSEL_VALID | CLKSEL_80PCT, CGA_PLL2, PLL_DIV2 }, |
160 | } |
161 | }; |
162 | |
163 | static const struct clockgen_muxinfo p5040_cmux_grp2 = { |
164 | { |
165 | [0] = { CLKSEL_VALID | CLKSEL_80PCT, CGA_PLL1, PLL_DIV1 }, |
166 | [1] = { CLKSEL_VALID | CLKSEL_80PCT, CGA_PLL1, PLL_DIV2 }, |
167 | [4] = { CLKSEL_VALID, CGA_PLL2, PLL_DIV1 }, |
168 | [5] = { CLKSEL_VALID, CGA_PLL2, PLL_DIV2 }, |
169 | } |
170 | }; |
171 | |
172 | static const struct clockgen_muxinfo p4080_cmux_grp1 = { |
173 | { |
174 | [0] = { CLKSEL_VALID, CGA_PLL1, PLL_DIV1 }, |
175 | [1] = { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 }, |
176 | [4] = { CLKSEL_VALID, CGA_PLL2, PLL_DIV1 }, |
177 | [5] = { CLKSEL_VALID, CGA_PLL2, PLL_DIV2 }, |
178 | [8] = { CLKSEL_VALID | CLKSEL_80PCT, CGA_PLL3, PLL_DIV1 }, |
179 | } |
180 | }; |
181 | |
182 | static const struct clockgen_muxinfo p4080_cmux_grp2 = { |
183 | { |
184 | [0] = { CLKSEL_VALID | CLKSEL_80PCT, CGA_PLL1, PLL_DIV1 }, |
185 | [8] = { CLKSEL_VALID, CGA_PLL3, PLL_DIV1 }, |
186 | [9] = { CLKSEL_VALID, CGA_PLL3, PLL_DIV2 }, |
187 | [12] = { CLKSEL_VALID, CGA_PLL4, PLL_DIV1 }, |
188 | [13] = { CLKSEL_VALID, CGA_PLL4, PLL_DIV2 }, |
189 | } |
190 | }; |
191 | |
192 | static const struct clockgen_muxinfo t1023_cmux = { |
193 | { |
194 | [0] = { CLKSEL_VALID, CGA_PLL1, PLL_DIV1 }, |
195 | [1] = { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 }, |
196 | } |
197 | }; |
198 | |
199 | static const struct clockgen_muxinfo t1040_cmux = { |
200 | { |
201 | [0] = { CLKSEL_VALID, CGA_PLL1, PLL_DIV1 }, |
202 | [1] = { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 }, |
203 | [4] = { CLKSEL_VALID, CGA_PLL2, PLL_DIV1 }, |
204 | [5] = { CLKSEL_VALID, CGA_PLL2, PLL_DIV2 }, |
205 | } |
206 | }; |
207 | |
208 | |
209 | static const struct clockgen_muxinfo clockgen2_cmux_cga = { |
210 | { |
211 | { CLKSEL_VALID, CGA_PLL1, PLL_DIV1 }, |
212 | { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 }, |
213 | { CLKSEL_VALID, CGA_PLL1, PLL_DIV4 }, |
214 | {}, |
215 | { CLKSEL_VALID, CGA_PLL2, PLL_DIV1 }, |
216 | { CLKSEL_VALID, CGA_PLL2, PLL_DIV2 }, |
217 | { CLKSEL_VALID, CGA_PLL2, PLL_DIV4 }, |
218 | {}, |
219 | { CLKSEL_VALID, CGA_PLL3, PLL_DIV1 }, |
220 | { CLKSEL_VALID, CGA_PLL3, PLL_DIV2 }, |
221 | { CLKSEL_VALID, CGA_PLL3, PLL_DIV4 }, |
222 | }, |
223 | }; |
224 | |
225 | static const struct clockgen_muxinfo clockgen2_cmux_cga12 = { |
226 | { |
227 | { CLKSEL_VALID, CGA_PLL1, PLL_DIV1 }, |
228 | { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 }, |
229 | { CLKSEL_VALID, CGA_PLL1, PLL_DIV4 }, |
230 | {}, |
231 | { CLKSEL_VALID, CGA_PLL2, PLL_DIV1 }, |
232 | { CLKSEL_VALID, CGA_PLL2, PLL_DIV2 }, |
233 | { CLKSEL_VALID, CGA_PLL2, PLL_DIV4 }, |
234 | }, |
235 | }; |
236 | |
237 | static const struct clockgen_muxinfo clockgen2_cmux_cgb = { |
238 | { |
239 | { CLKSEL_VALID, CGB_PLL1, PLL_DIV1 }, |
240 | { CLKSEL_VALID, CGB_PLL1, PLL_DIV2 }, |
241 | { CLKSEL_VALID, CGB_PLL1, PLL_DIV4 }, |
242 | {}, |
243 | { CLKSEL_VALID, CGB_PLL2, PLL_DIV1 }, |
244 | { CLKSEL_VALID, CGB_PLL2, PLL_DIV2 }, |
245 | { CLKSEL_VALID, CGB_PLL2, PLL_DIV4 }, |
246 | }, |
247 | }; |
248 | |
249 | static const struct clockgen_muxinfo ls1021a_cmux = { |
250 | { |
251 | { CLKSEL_VALID, CGA_PLL1, PLL_DIV1 }, |
252 | { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 }, |
253 | { CLKSEL_VALID, CGA_PLL1, PLL_DIV4 }, |
254 | } |
255 | }; |
256 | |
257 | static const struct clockgen_muxinfo ls1028a_hwa1 = { |
258 | { |
259 | { CLKSEL_VALID, PLATFORM_PLL, PLL_DIV1 }, |
260 | { CLKSEL_VALID, CGA_PLL1, PLL_DIV1 }, |
261 | { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 }, |
262 | { CLKSEL_VALID, CGA_PLL1, PLL_DIV3 }, |
263 | { CLKSEL_VALID, CGA_PLL1, PLL_DIV4 }, |
264 | {}, |
265 | { CLKSEL_VALID, CGA_PLL2, PLL_DIV2 }, |
266 | { CLKSEL_VALID, CGA_PLL2, PLL_DIV3 }, |
267 | }, |
268 | }; |
269 | |
270 | static const struct clockgen_muxinfo ls1028a_hwa2 = { |
271 | { |
272 | { CLKSEL_VALID, PLATFORM_PLL, PLL_DIV1 }, |
273 | { CLKSEL_VALID, CGA_PLL2, PLL_DIV1 }, |
274 | { CLKSEL_VALID, CGA_PLL2, PLL_DIV2 }, |
275 | { CLKSEL_VALID, CGA_PLL2, PLL_DIV3 }, |
276 | { CLKSEL_VALID, CGA_PLL2, PLL_DIV4 }, |
277 | {}, |
278 | { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 }, |
279 | { CLKSEL_VALID, CGA_PLL1, PLL_DIV3 }, |
280 | }, |
281 | }; |
282 | |
283 | static const struct clockgen_muxinfo ls1028a_hwa3 = { |
284 | { |
285 | { CLKSEL_VALID, PLATFORM_PLL, PLL_DIV1 }, |
286 | { CLKSEL_VALID, CGA_PLL1, PLL_DIV1 }, |
287 | { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 }, |
288 | { CLKSEL_VALID, CGA_PLL1, PLL_DIV3 }, |
289 | { CLKSEL_VALID, CGA_PLL1, PLL_DIV4 }, |
290 | {}, |
291 | { CLKSEL_VALID, CGA_PLL2, PLL_DIV2 }, |
292 | { CLKSEL_VALID, CGA_PLL2, PLL_DIV3 }, |
293 | }, |
294 | }; |
295 | |
296 | static const struct clockgen_muxinfo ls1028a_hwa4 = { |
297 | { |
298 | { CLKSEL_VALID, PLATFORM_PLL, PLL_DIV1 }, |
299 | { CLKSEL_VALID, CGA_PLL2, PLL_DIV1 }, |
300 | { CLKSEL_VALID, CGA_PLL2, PLL_DIV2 }, |
301 | { CLKSEL_VALID, CGA_PLL2, PLL_DIV3 }, |
302 | { CLKSEL_VALID, CGA_PLL2, PLL_DIV4 }, |
303 | {}, |
304 | { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 }, |
305 | { CLKSEL_VALID, CGA_PLL1, PLL_DIV3 }, |
306 | }, |
307 | }; |
308 | |
309 | static const struct clockgen_muxinfo ls1043a_hwa1 = { |
310 | { |
311 | {}, |
312 | {}, |
313 | { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 }, |
314 | { CLKSEL_VALID, CGA_PLL1, PLL_DIV3 }, |
315 | {}, |
316 | {}, |
317 | { CLKSEL_VALID, CGA_PLL2, PLL_DIV2 }, |
318 | { CLKSEL_VALID, CGA_PLL2, PLL_DIV3 }, |
319 | }, |
320 | }; |
321 | |
322 | static const struct clockgen_muxinfo ls1043a_hwa2 = { |
323 | { |
324 | {}, |
325 | { CLKSEL_VALID, CGA_PLL2, PLL_DIV1 }, |
326 | {}, |
327 | { CLKSEL_VALID, CGA_PLL2, PLL_DIV3 }, |
328 | }, |
329 | }; |
330 | |
331 | static const struct clockgen_muxinfo ls1046a_hwa1 = { |
332 | { |
333 | {}, |
334 | {}, |
335 | { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 }, |
336 | { CLKSEL_VALID, CGA_PLL1, PLL_DIV3 }, |
337 | { CLKSEL_VALID, CGA_PLL1, PLL_DIV4 }, |
338 | { CLKSEL_VALID, PLATFORM_PLL, PLL_DIV1 }, |
339 | { CLKSEL_VALID, CGA_PLL2, PLL_DIV2 }, |
340 | { CLKSEL_VALID, CGA_PLL2, PLL_DIV3 }, |
341 | }, |
342 | }; |
343 | |
344 | static const struct clockgen_muxinfo ls1046a_hwa2 = { |
345 | { |
346 | {}, |
347 | { CLKSEL_VALID, CGA_PLL2, PLL_DIV1 }, |
348 | { CLKSEL_VALID, CGA_PLL2, PLL_DIV2 }, |
349 | { CLKSEL_VALID, CGA_PLL2, PLL_DIV3 }, |
350 | {}, |
351 | {}, |
352 | { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 }, |
353 | }, |
354 | }; |
355 | |
356 | static const struct clockgen_muxinfo ls1088a_hwa1 = { |
357 | { |
358 | {}, |
359 | { CLKSEL_VALID, CGA_PLL1, PLL_DIV1 }, |
360 | { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 }, |
361 | { CLKSEL_VALID, CGA_PLL1, PLL_DIV3 }, |
362 | { CLKSEL_VALID, CGA_PLL1, PLL_DIV4 }, |
363 | {}, |
364 | { CLKSEL_VALID, CGA_PLL2, PLL_DIV2 }, |
365 | { CLKSEL_VALID, CGA_PLL2, PLL_DIV3 }, |
366 | }, |
367 | }; |
368 | |
369 | static const struct clockgen_muxinfo ls1088a_hwa2 = { |
370 | { |
371 | {}, |
372 | { CLKSEL_VALID, CGA_PLL2, PLL_DIV1 }, |
373 | { CLKSEL_VALID, CGA_PLL2, PLL_DIV2 }, |
374 | { CLKSEL_VALID, CGA_PLL2, PLL_DIV3 }, |
375 | { CLKSEL_VALID, CGA_PLL2, PLL_DIV4 }, |
376 | {}, |
377 | { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 }, |
378 | { CLKSEL_VALID, CGA_PLL1, PLL_DIV3 }, |
379 | }, |
380 | }; |
381 | |
382 | static const struct clockgen_muxinfo ls1012a_cmux = { |
383 | { |
384 | [0] = { CLKSEL_VALID, CGA_PLL1, PLL_DIV1 }, |
385 | {}, |
386 | [2] = { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 }, |
387 | } |
388 | }; |
389 | |
390 | static const struct clockgen_muxinfo t1023_hwa1 = { |
391 | { |
392 | {}, |
393 | { CLKSEL_VALID, CGA_PLL1, PLL_DIV1 }, |
394 | { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 }, |
395 | { CLKSEL_VALID, CGA_PLL1, PLL_DIV3 }, |
396 | }, |
397 | }; |
398 | |
399 | static const struct clockgen_muxinfo t1023_hwa2 = { |
400 | { |
401 | [6] = { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 }, |
402 | }, |
403 | }; |
404 | |
405 | static const struct clockgen_muxinfo t2080_hwa1 = { |
406 | { |
407 | {}, |
408 | { CLKSEL_VALID, CGA_PLL1, PLL_DIV1 }, |
409 | { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 }, |
410 | { CLKSEL_VALID, CGA_PLL1, PLL_DIV3 }, |
411 | { CLKSEL_VALID, CGA_PLL1, PLL_DIV4 }, |
412 | { CLKSEL_VALID, PLATFORM_PLL, PLL_DIV1 }, |
413 | { CLKSEL_VALID, CGA_PLL2, PLL_DIV2 }, |
414 | { CLKSEL_VALID, CGA_PLL2, PLL_DIV3 }, |
415 | }, |
416 | }; |
417 | |
418 | static const struct clockgen_muxinfo t2080_hwa2 = { |
419 | { |
420 | {}, |
421 | { CLKSEL_VALID, CGA_PLL2, PLL_DIV1 }, |
422 | { CLKSEL_VALID, CGA_PLL2, PLL_DIV2 }, |
423 | { CLKSEL_VALID, CGA_PLL2, PLL_DIV3 }, |
424 | { CLKSEL_VALID, CGA_PLL2, PLL_DIV4 }, |
425 | { CLKSEL_VALID, PLATFORM_PLL, PLL_DIV1 }, |
426 | { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 }, |
427 | { CLKSEL_VALID, CGA_PLL1, PLL_DIV3 }, |
428 | }, |
429 | }; |
430 | |
431 | static const struct clockgen_muxinfo t4240_hwa1 = { |
432 | { |
433 | { CLKSEL_VALID, PLATFORM_PLL, PLL_DIV2 }, |
434 | { CLKSEL_VALID, CGA_PLL1, PLL_DIV1 }, |
435 | { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 }, |
436 | { CLKSEL_VALID, CGA_PLL1, PLL_DIV3 }, |
437 | { CLKSEL_VALID, CGA_PLL1, PLL_DIV4 }, |
438 | {}, |
439 | { CLKSEL_VALID, CGA_PLL2, PLL_DIV2 }, |
440 | { CLKSEL_VALID, CGA_PLL2, PLL_DIV3 }, |
441 | }, |
442 | }; |
443 | |
444 | static const struct clockgen_muxinfo t4240_hwa4 = { |
445 | { |
446 | [2] = { CLKSEL_VALID, CGB_PLL1, PLL_DIV2 }, |
447 | [3] = { CLKSEL_VALID, CGB_PLL1, PLL_DIV3 }, |
448 | [4] = { CLKSEL_VALID, CGB_PLL1, PLL_DIV4 }, |
449 | [5] = { CLKSEL_VALID, PLATFORM_PLL, PLL_DIV1 }, |
450 | [6] = { CLKSEL_VALID, CGB_PLL2, PLL_DIV2 }, |
451 | }, |
452 | }; |
453 | |
454 | static const struct clockgen_muxinfo t4240_hwa5 = { |
455 | { |
456 | [2] = { CLKSEL_VALID, CGB_PLL2, PLL_DIV2 }, |
457 | [3] = { CLKSEL_VALID, CGB_PLL2, PLL_DIV3 }, |
458 | [4] = { CLKSEL_VALID, CGB_PLL2, PLL_DIV4 }, |
459 | [5] = { CLKSEL_VALID, PLATFORM_PLL, PLL_DIV1 }, |
460 | [6] = { CLKSEL_VALID, CGB_PLL1, PLL_DIV2 }, |
461 | [7] = { CLKSEL_VALID, CGB_PLL1, PLL_DIV3 }, |
462 | }, |
463 | }; |
464 | |
465 | #define RCWSR7_FM1_CLK_SEL 0x40000000 |
466 | #define RCWSR7_FM2_CLK_SEL 0x20000000 |
467 | #define RCWSR7_HWA_ASYNC_DIV 0x04000000 |
468 | |
469 | static void __init p2041_init_periph(struct clockgen *cg) |
470 | { |
471 | u32 reg; |
472 | |
473 | reg = ioread32be(&cg->guts->rcwsr[7]); |
474 | |
475 | if (reg & RCWSR7_FM1_CLK_SEL) |
476 | cg->fman[0] = cg->pll[CGA_PLL2].div[PLL_DIV2].clk; |
477 | else |
478 | cg->fman[0] = cg->pll[PLATFORM_PLL].div[PLL_DIV2].clk; |
479 | } |
480 | |
481 | static void __init p4080_init_periph(struct clockgen *cg) |
482 | { |
483 | u32 reg; |
484 | |
485 | reg = ioread32be(&cg->guts->rcwsr[7]); |
486 | |
487 | if (reg & RCWSR7_FM1_CLK_SEL) |
488 | cg->fman[0] = cg->pll[CGA_PLL3].div[PLL_DIV2].clk; |
489 | else |
490 | cg->fman[0] = cg->pll[PLATFORM_PLL].div[PLL_DIV2].clk; |
491 | |
492 | if (reg & RCWSR7_FM2_CLK_SEL) |
493 | cg->fman[1] = cg->pll[CGA_PLL3].div[PLL_DIV2].clk; |
494 | else |
495 | cg->fman[1] = cg->pll[PLATFORM_PLL].div[PLL_DIV2].clk; |
496 | } |
497 | |
498 | static void __init p5020_init_periph(struct clockgen *cg) |
499 | { |
500 | u32 reg; |
501 | int div = PLL_DIV2; |
502 | |
503 | reg = ioread32be(&cg->guts->rcwsr[7]); |
504 | if (reg & RCWSR7_HWA_ASYNC_DIV) |
505 | div = PLL_DIV4; |
506 | |
507 | if (reg & RCWSR7_FM1_CLK_SEL) |
508 | cg->fman[0] = cg->pll[CGA_PLL2].div[div].clk; |
509 | else |
510 | cg->fman[0] = cg->pll[PLATFORM_PLL].div[PLL_DIV2].clk; |
511 | } |
512 | |
513 | static void __init p5040_init_periph(struct clockgen *cg) |
514 | { |
515 | u32 reg; |
516 | int div = PLL_DIV2; |
517 | |
518 | reg = ioread32be(&cg->guts->rcwsr[7]); |
519 | if (reg & RCWSR7_HWA_ASYNC_DIV) |
520 | div = PLL_DIV4; |
521 | |
522 | if (reg & RCWSR7_FM1_CLK_SEL) |
523 | cg->fman[0] = cg->pll[CGA_PLL3].div[div].clk; |
524 | else |
525 | cg->fman[0] = cg->pll[PLATFORM_PLL].div[PLL_DIV2].clk; |
526 | |
527 | if (reg & RCWSR7_FM2_CLK_SEL) |
528 | cg->fman[1] = cg->pll[CGA_PLL3].div[div].clk; |
529 | else |
530 | cg->fman[1] = cg->pll[PLATFORM_PLL].div[PLL_DIV2].clk; |
531 | } |
532 | |
533 | static void __init t1023_init_periph(struct clockgen *cg) |
534 | { |
535 | cg->fman[0] = cg->hwaccel[1]; |
536 | } |
537 | |
538 | static void __init t1040_init_periph(struct clockgen *cg) |
539 | { |
540 | cg->fman[0] = cg->pll[PLATFORM_PLL].div[PLL_DIV1].clk; |
541 | } |
542 | |
543 | static void __init t2080_init_periph(struct clockgen *cg) |
544 | { |
545 | cg->fman[0] = cg->hwaccel[0]; |
546 | } |
547 | |
548 | static void __init t4240_init_periph(struct clockgen *cg) |
549 | { |
550 | cg->fman[0] = cg->hwaccel[3]; |
551 | cg->fman[1] = cg->hwaccel[4]; |
552 | } |
553 | |
554 | static const struct clockgen_chipinfo chipinfo[] = { |
555 | { |
556 | .compat = "fsl,b4420-clockgen" , |
557 | .guts_compat = "fsl,b4860-device-config" , |
558 | .init_periph = t2080_init_periph, |
559 | .cmux_groups = { |
560 | &clockgen2_cmux_cga12, &clockgen2_cmux_cgb |
561 | }, |
562 | .hwaccel = { |
563 | &t2080_hwa1 |
564 | }, |
565 | .cmux_to_group = { |
566 | 0, 1, 1, 1, -1 |
567 | }, |
568 | .pll_mask = BIT(PLATFORM_PLL) | |
569 | BIT(CGA_PLL1) | BIT(CGA_PLL2) | BIT(CGA_PLL3) | |
570 | BIT(CGB_PLL1) | BIT(CGB_PLL2), |
571 | .flags = CG_PLL_8BIT, |
572 | }, |
573 | { |
574 | .compat = "fsl,b4860-clockgen" , |
575 | .guts_compat = "fsl,b4860-device-config" , |
576 | .init_periph = t2080_init_periph, |
577 | .cmux_groups = { |
578 | &clockgen2_cmux_cga12, &clockgen2_cmux_cgb |
579 | }, |
580 | .hwaccel = { |
581 | &t2080_hwa1 |
582 | }, |
583 | .cmux_to_group = { |
584 | 0, 1, 1, 1, -1 |
585 | }, |
586 | .pll_mask = BIT(PLATFORM_PLL) | |
587 | BIT(CGA_PLL1) | BIT(CGA_PLL2) | BIT(CGA_PLL3) | |
588 | BIT(CGB_PLL1) | BIT(CGB_PLL2), |
589 | .flags = CG_PLL_8BIT, |
590 | }, |
591 | { |
592 | .compat = "fsl,ls1021a-clockgen" , |
593 | .cmux_groups = { |
594 | &ls1021a_cmux |
595 | }, |
596 | .cmux_to_group = { |
597 | 0, -1 |
598 | }, |
599 | .pll_mask = BIT(PLATFORM_PLL) | |
600 | BIT(CGA_PLL1) | BIT(CGA_PLL2), |
601 | }, |
602 | { |
603 | .compat = "fsl,ls1028a-clockgen" , |
604 | .cmux_groups = { |
605 | &clockgen2_cmux_cga12 |
606 | }, |
607 | .hwaccel = { |
608 | &ls1028a_hwa1, &ls1028a_hwa2, |
609 | &ls1028a_hwa3, &ls1028a_hwa4 |
610 | }, |
611 | .cmux_to_group = { |
612 | 0, 0, 0, 0, -1 |
613 | }, |
614 | .pll_mask = BIT(PLATFORM_PLL) | |
615 | BIT(CGA_PLL1) | BIT(CGA_PLL2), |
616 | .flags = CG_VER3 | CG_LITTLE_ENDIAN, |
617 | }, |
618 | { |
619 | .compat = "fsl,ls1043a-clockgen" , |
620 | .init_periph = t2080_init_periph, |
621 | .cmux_groups = { |
622 | &t1040_cmux |
623 | }, |
624 | .hwaccel = { |
625 | &ls1043a_hwa1, &ls1043a_hwa2 |
626 | }, |
627 | .cmux_to_group = { |
628 | 0, -1 |
629 | }, |
630 | .pll_mask = BIT(PLATFORM_PLL) | |
631 | BIT(CGA_PLL1) | BIT(CGA_PLL2), |
632 | .flags = CG_PLL_8BIT, |
633 | }, |
634 | { |
635 | .compat = "fsl,ls1046a-clockgen" , |
636 | .init_periph = t2080_init_periph, |
637 | .cmux_groups = { |
638 | &t1040_cmux |
639 | }, |
640 | .hwaccel = { |
641 | &ls1046a_hwa1, &ls1046a_hwa2 |
642 | }, |
643 | .cmux_to_group = { |
644 | 0, -1 |
645 | }, |
646 | .pll_mask = BIT(PLATFORM_PLL) | |
647 | BIT(CGA_PLL1) | BIT(CGA_PLL2), |
648 | .flags = CG_PLL_8BIT, |
649 | }, |
650 | { |
651 | .compat = "fsl,ls1088a-clockgen" , |
652 | .cmux_groups = { |
653 | &clockgen2_cmux_cga12 |
654 | }, |
655 | .hwaccel = { |
656 | &ls1088a_hwa1, &ls1088a_hwa2 |
657 | }, |
658 | .cmux_to_group = { |
659 | 0, 0, -1 |
660 | }, |
661 | .pll_mask = BIT(PLATFORM_PLL) | |
662 | BIT(CGA_PLL1) | BIT(CGA_PLL2), |
663 | .flags = CG_VER3 | CG_LITTLE_ENDIAN, |
664 | }, |
665 | { |
666 | .compat = "fsl,ls1012a-clockgen" , |
667 | .cmux_groups = { |
668 | &ls1012a_cmux |
669 | }, |
670 | .cmux_to_group = { |
671 | 0, -1 |
672 | }, |
673 | .pll_mask = BIT(PLATFORM_PLL) | BIT(CGA_PLL1), |
674 | }, |
675 | { |
676 | .compat = "fsl,ls2080a-clockgen" , |
677 | .cmux_groups = { |
678 | &clockgen2_cmux_cga12, &clockgen2_cmux_cgb |
679 | }, |
680 | .cmux_to_group = { |
681 | 0, 0, 1, 1, -1 |
682 | }, |
683 | .pll_mask = BIT(PLATFORM_PLL) | |
684 | BIT(CGA_PLL1) | BIT(CGA_PLL2) | |
685 | BIT(CGB_PLL1) | BIT(CGB_PLL2), |
686 | .flags = CG_VER3 | CG_LITTLE_ENDIAN, |
687 | }, |
688 | { |
689 | .compat = "fsl,lx2160a-clockgen" , |
690 | .cmux_groups = { |
691 | &clockgen2_cmux_cga12, &clockgen2_cmux_cgb |
692 | }, |
693 | .cmux_to_group = { |
694 | 0, 0, 0, 0, 1, 1, 1, 1, -1 |
695 | }, |
696 | .pll_mask = BIT(PLATFORM_PLL) | |
697 | BIT(CGA_PLL1) | BIT(CGA_PLL2) | |
698 | BIT(CGB_PLL1) | BIT(CGB_PLL2), |
699 | .flags = CG_VER3 | CG_LITTLE_ENDIAN, |
700 | }, |
701 | { |
702 | .compat = "fsl,p2041-clockgen" , |
703 | .guts_compat = "fsl,qoriq-device-config-1.0" , |
704 | .init_periph = p2041_init_periph, |
705 | .cmux_groups = { |
706 | &p2041_cmux_grp1, &p2041_cmux_grp2 |
707 | }, |
708 | .cmux_to_group = { |
709 | 0, 0, 1, 1, -1 |
710 | }, |
711 | .pll_mask = BIT(PLATFORM_PLL) | |
712 | BIT(CGA_PLL1) | BIT(CGA_PLL2), |
713 | }, |
714 | { |
715 | .compat = "fsl,p3041-clockgen" , |
716 | .guts_compat = "fsl,qoriq-device-config-1.0" , |
717 | .init_periph = p2041_init_periph, |
718 | .cmux_groups = { |
719 | &p2041_cmux_grp1, &p2041_cmux_grp2 |
720 | }, |
721 | .cmux_to_group = { |
722 | 0, 0, 1, 1, -1 |
723 | }, |
724 | .pll_mask = BIT(PLATFORM_PLL) | |
725 | BIT(CGA_PLL1) | BIT(CGA_PLL2), |
726 | }, |
727 | { |
728 | .compat = "fsl,p4080-clockgen" , |
729 | .guts_compat = "fsl,qoriq-device-config-1.0" , |
730 | .init_periph = p4080_init_periph, |
731 | .cmux_groups = { |
732 | &p4080_cmux_grp1, &p4080_cmux_grp2 |
733 | }, |
734 | .cmux_to_group = { |
735 | 0, 0, 0, 0, 1, 1, 1, 1, -1 |
736 | }, |
737 | .pll_mask = BIT(PLATFORM_PLL) | |
738 | BIT(CGA_PLL1) | BIT(CGA_PLL2) | |
739 | BIT(CGA_PLL3) | BIT(CGA_PLL4), |
740 | }, |
741 | { |
742 | .compat = "fsl,p5020-clockgen" , |
743 | .guts_compat = "fsl,qoriq-device-config-1.0" , |
744 | .init_periph = p5020_init_periph, |
745 | .cmux_groups = { |
746 | &p5020_cmux_grp1, &p5020_cmux_grp2 |
747 | }, |
748 | .cmux_to_group = { |
749 | 0, 1, -1 |
750 | }, |
751 | .pll_mask = BIT(PLATFORM_PLL) | |
752 | BIT(CGA_PLL1) | BIT(CGA_PLL2), |
753 | }, |
754 | { |
755 | .compat = "fsl,p5040-clockgen" , |
756 | .guts_compat = "fsl,p5040-device-config" , |
757 | .init_periph = p5040_init_periph, |
758 | .cmux_groups = { |
759 | &p5040_cmux_grp1, &p5040_cmux_grp2 |
760 | }, |
761 | .cmux_to_group = { |
762 | 0, 0, 1, 1, -1 |
763 | }, |
764 | .pll_mask = BIT(PLATFORM_PLL) | |
765 | BIT(CGA_PLL1) | BIT(CGA_PLL2) | BIT(CGA_PLL3), |
766 | }, |
767 | { |
768 | .compat = "fsl,t1023-clockgen" , |
769 | .guts_compat = "fsl,t1023-device-config" , |
770 | .init_periph = t1023_init_periph, |
771 | .cmux_groups = { |
772 | &t1023_cmux |
773 | }, |
774 | .hwaccel = { |
775 | &t1023_hwa1, &t1023_hwa2 |
776 | }, |
777 | .cmux_to_group = { |
778 | 0, 0, -1 |
779 | }, |
780 | .pll_mask = BIT(PLATFORM_PLL) | BIT(CGA_PLL1), |
781 | .flags = CG_PLL_8BIT, |
782 | }, |
783 | { |
784 | .compat = "fsl,t1040-clockgen" , |
785 | .guts_compat = "fsl,t1040-device-config" , |
786 | .init_periph = t1040_init_periph, |
787 | .cmux_groups = { |
788 | &t1040_cmux |
789 | }, |
790 | .cmux_to_group = { |
791 | 0, 0, 0, 0, -1 |
792 | }, |
793 | .pll_mask = BIT(PLATFORM_PLL) | |
794 | BIT(CGA_PLL1) | BIT(CGA_PLL2), |
795 | .flags = CG_PLL_8BIT, |
796 | }, |
797 | { |
798 | .compat = "fsl,t2080-clockgen" , |
799 | .guts_compat = "fsl,t2080-device-config" , |
800 | .init_periph = t2080_init_periph, |
801 | .cmux_groups = { |
802 | &clockgen2_cmux_cga12 |
803 | }, |
804 | .hwaccel = { |
805 | &t2080_hwa1, &t2080_hwa2 |
806 | }, |
807 | .cmux_to_group = { |
808 | 0, -1 |
809 | }, |
810 | .pll_mask = BIT(PLATFORM_PLL) | |
811 | BIT(CGA_PLL1) | BIT(CGA_PLL2), |
812 | .flags = CG_PLL_8BIT, |
813 | }, |
814 | { |
815 | .compat = "fsl,t4240-clockgen" , |
816 | .guts_compat = "fsl,t4240-device-config" , |
817 | .init_periph = t4240_init_periph, |
818 | .cmux_groups = { |
819 | &clockgen2_cmux_cga, &clockgen2_cmux_cgb |
820 | }, |
821 | .hwaccel = { |
822 | &t4240_hwa1, NULL, NULL, &t4240_hwa4, &t4240_hwa5 |
823 | }, |
824 | .cmux_to_group = { |
825 | 0, 0, 1, -1 |
826 | }, |
827 | .pll_mask = BIT(PLATFORM_PLL) | |
828 | BIT(CGA_PLL1) | BIT(CGA_PLL2) | BIT(CGA_PLL3) | |
829 | BIT(CGB_PLL1) | BIT(CGB_PLL2), |
830 | .flags = CG_PLL_8BIT, |
831 | }, |
832 | {}, |
833 | }; |
834 | |
835 | struct mux_hwclock { |
836 | struct clk_hw hw; |
837 | struct clockgen *cg; |
838 | const struct clockgen_muxinfo *info; |
839 | u32 __iomem *reg; |
840 | u8 parent_to_clksel[NUM_MUX_PARENTS]; |
841 | s8 clksel_to_parent[NUM_MUX_PARENTS]; |
842 | int num_parents; |
843 | }; |
844 | |
845 | #define to_mux_hwclock(p) container_of(p, struct mux_hwclock, hw) |
846 | #define CLKSEL_MASK 0x78000000 |
847 | #define CLKSEL_SHIFT 27 |
848 | |
849 | static int mux_set_parent(struct clk_hw *hw, u8 idx) |
850 | { |
851 | struct mux_hwclock *hwc = to_mux_hwclock(hw); |
852 | u32 clksel; |
853 | |
854 | if (idx >= hwc->num_parents) |
855 | return -EINVAL; |
856 | |
857 | clksel = hwc->parent_to_clksel[idx]; |
858 | cg_out(cg: hwc->cg, val: (clksel << CLKSEL_SHIFT) & CLKSEL_MASK, reg: hwc->reg); |
859 | |
860 | return 0; |
861 | } |
862 | |
863 | static u8 mux_get_parent(struct clk_hw *hw) |
864 | { |
865 | struct mux_hwclock *hwc = to_mux_hwclock(hw); |
866 | u32 clksel; |
867 | s8 ret; |
868 | |
869 | clksel = (cg_in(cg: hwc->cg, reg: hwc->reg) & CLKSEL_MASK) >> CLKSEL_SHIFT; |
870 | |
871 | ret = hwc->clksel_to_parent[clksel]; |
872 | if (ret < 0) { |
873 | pr_err("%s: mux at %p has bad clksel\n" , __func__, hwc->reg); |
874 | return 0; |
875 | } |
876 | |
877 | return ret; |
878 | } |
879 | |
880 | static const struct clk_ops cmux_ops = { |
881 | .determine_rate = clk_hw_determine_rate_no_reparent, |
882 | .get_parent = mux_get_parent, |
883 | .set_parent = mux_set_parent, |
884 | }; |
885 | |
886 | /* |
887 | * Don't allow setting for now, as the clock options haven't been |
888 | * sanitized for additional restrictions. |
889 | */ |
890 | static const struct clk_ops hwaccel_ops = { |
891 | .get_parent = mux_get_parent, |
892 | }; |
893 | |
894 | static const struct clockgen_pll_div *get_pll_div(struct clockgen *cg, |
895 | struct mux_hwclock *hwc, |
896 | int idx) |
897 | { |
898 | int pll, div; |
899 | |
900 | if (!(hwc->info->clksel[idx].flags & CLKSEL_VALID)) |
901 | return NULL; |
902 | |
903 | pll = hwc->info->clksel[idx].pll; |
904 | div = hwc->info->clksel[idx].div; |
905 | |
906 | return &cg->pll[pll].div[div]; |
907 | } |
908 | |
909 | static struct clk * __init create_mux_common(struct clockgen *cg, |
910 | struct mux_hwclock *hwc, |
911 | const struct clk_ops *ops, |
912 | unsigned long min_rate, |
913 | unsigned long max_rate, |
914 | unsigned long pct80_rate, |
915 | const char *fmt, int idx) |
916 | { |
917 | struct clk_init_data init = {}; |
918 | struct clk *clk; |
919 | const struct clockgen_pll_div *div; |
920 | const char *parent_names[NUM_MUX_PARENTS]; |
921 | char name[32]; |
922 | int i, j; |
923 | |
924 | snprintf(buf: name, size: sizeof(name), fmt, idx); |
925 | |
926 | for (i = 0, j = 0; i < NUM_MUX_PARENTS; i++) { |
927 | unsigned long rate; |
928 | |
929 | hwc->clksel_to_parent[i] = -1; |
930 | |
931 | div = get_pll_div(cg, hwc, idx: i); |
932 | if (!div) |
933 | continue; |
934 | |
935 | rate = clk_get_rate(clk: div->clk); |
936 | |
937 | if (hwc->info->clksel[i].flags & CLKSEL_80PCT && |
938 | rate > pct80_rate) |
939 | continue; |
940 | if (rate < min_rate) |
941 | continue; |
942 | if (rate > max_rate) |
943 | continue; |
944 | |
945 | parent_names[j] = div->name; |
946 | hwc->parent_to_clksel[j] = i; |
947 | hwc->clksel_to_parent[i] = j; |
948 | j++; |
949 | } |
950 | |
951 | init.name = name; |
952 | init.ops = ops; |
953 | init.parent_names = parent_names; |
954 | init.num_parents = hwc->num_parents = j; |
955 | init.flags = 0; |
956 | hwc->hw.init = &init; |
957 | hwc->cg = cg; |
958 | |
959 | clk = clk_register(NULL, hw: &hwc->hw); |
960 | if (IS_ERR(ptr: clk)) { |
961 | pr_err("%s: Couldn't register %s: %ld\n" , __func__, name, |
962 | PTR_ERR(clk)); |
963 | kfree(objp: hwc); |
964 | return NULL; |
965 | } |
966 | |
967 | return clk; |
968 | } |
969 | |
970 | static struct clk * __init create_one_cmux(struct clockgen *cg, int idx) |
971 | { |
972 | struct mux_hwclock *hwc; |
973 | const struct clockgen_pll_div *div; |
974 | unsigned long plat_rate, min_rate; |
975 | u64 max_rate, pct80_rate; |
976 | u32 clksel; |
977 | |
978 | hwc = kzalloc(size: sizeof(*hwc), GFP_KERNEL); |
979 | if (!hwc) |
980 | return NULL; |
981 | |
982 | if (cg->info.flags & CG_VER3) |
983 | hwc->reg = cg->regs + 0x70000 + 0x20 * idx; |
984 | else |
985 | hwc->reg = cg->regs + 0x20 * idx; |
986 | |
987 | hwc->info = cg->info.cmux_groups[cg->info.cmux_to_group[idx]]; |
988 | |
989 | /* |
990 | * Find the rate for the default clksel, and treat it as the |
991 | * maximum rated core frequency. If this is an incorrect |
992 | * assumption, certain clock options (possibly including the |
993 | * default clksel) may be inappropriately excluded on certain |
994 | * chips. |
995 | */ |
996 | clksel = (cg_in(cg, reg: hwc->reg) & CLKSEL_MASK) >> CLKSEL_SHIFT; |
997 | div = get_pll_div(cg, hwc, idx: clksel); |
998 | if (!div) { |
999 | kfree(objp: hwc); |
1000 | return NULL; |
1001 | } |
1002 | |
1003 | max_rate = clk_get_rate(clk: div->clk); |
1004 | pct80_rate = max_rate * 8; |
1005 | do_div(pct80_rate, 10); |
1006 | |
1007 | plat_rate = clk_get_rate(clk: cg->pll[PLATFORM_PLL].div[PLL_DIV1].clk); |
1008 | |
1009 | if (cg->info.flags & CG_CMUX_GE_PLAT) |
1010 | min_rate = plat_rate; |
1011 | else |
1012 | min_rate = plat_rate / 2; |
1013 | |
1014 | return create_mux_common(cg, hwc, ops: &cmux_ops, min_rate, max_rate, |
1015 | pct80_rate, fmt: "cg-cmux%d" , idx); |
1016 | } |
1017 | |
1018 | static struct clk * __init create_one_hwaccel(struct clockgen *cg, int idx) |
1019 | { |
1020 | struct mux_hwclock *hwc; |
1021 | |
1022 | hwc = kzalloc(size: sizeof(*hwc), GFP_KERNEL); |
1023 | if (!hwc) |
1024 | return NULL; |
1025 | |
1026 | hwc->reg = cg->regs + 0x20 * idx + 0x10; |
1027 | hwc->info = cg->info.hwaccel[idx]; |
1028 | |
1029 | return create_mux_common(cg, hwc, ops: &hwaccel_ops, min_rate: 0, ULONG_MAX, pct80_rate: 0, |
1030 | fmt: "cg-hwaccel%d" , idx); |
1031 | } |
1032 | |
1033 | static void __init create_muxes(struct clockgen *cg) |
1034 | { |
1035 | int i; |
1036 | |
1037 | for (i = 0; i < ARRAY_SIZE(cg->cmux); i++) { |
1038 | if (cg->info.cmux_to_group[i] < 0) |
1039 | break; |
1040 | if (cg->info.cmux_to_group[i] >= |
1041 | ARRAY_SIZE(cg->info.cmux_groups)) { |
1042 | WARN_ON_ONCE(1); |
1043 | continue; |
1044 | } |
1045 | |
1046 | cg->cmux[i] = create_one_cmux(cg, idx: i); |
1047 | } |
1048 | |
1049 | for (i = 0; i < ARRAY_SIZE(cg->hwaccel); i++) { |
1050 | if (!cg->info.hwaccel[i]) |
1051 | continue; |
1052 | |
1053 | cg->hwaccel[i] = create_one_hwaccel(cg, idx: i); |
1054 | } |
1055 | } |
1056 | |
1057 | static void __init _clockgen_init(struct device_node *np, bool legacy); |
1058 | |
1059 | /* |
1060 | * Legacy nodes may get probed before the parent clockgen node. |
1061 | * It is assumed that device trees with legacy nodes will not |
1062 | * contain a "clocks" property -- otherwise the input clocks may |
1063 | * not be initialized at this point. |
1064 | */ |
1065 | static void __init legacy_init_clockgen(struct device_node *np) |
1066 | { |
1067 | if (!clockgen.node) { |
1068 | struct device_node *parent_np; |
1069 | |
1070 | parent_np = of_get_parent(node: np); |
1071 | _clockgen_init(np: parent_np, legacy: true); |
1072 | of_node_put(node: parent_np); |
1073 | } |
1074 | } |
1075 | |
1076 | /* Legacy node */ |
1077 | static void __init core_mux_init(struct device_node *np) |
1078 | { |
1079 | struct clk *clk; |
1080 | struct resource res; |
1081 | int idx, rc; |
1082 | |
1083 | legacy_init_clockgen(np); |
1084 | |
1085 | if (of_address_to_resource(dev: np, index: 0, r: &res)) |
1086 | return; |
1087 | |
1088 | idx = (res.start & 0xf0) >> 5; |
1089 | clk = clockgen.cmux[idx]; |
1090 | |
1091 | rc = of_clk_add_provider(np, clk_src_get: of_clk_src_simple_get, data: clk); |
1092 | if (rc) { |
1093 | pr_err("%s: Couldn't register clk provider for node %pOFn: %d\n" , |
1094 | __func__, np, rc); |
1095 | return; |
1096 | } |
1097 | } |
1098 | |
1099 | static struct clk __init |
1100 | *sysclk_from_fixed(struct device_node *node, const char *name) |
1101 | { |
1102 | u32 rate; |
1103 | |
1104 | if (of_property_read_u32(np: node, propname: "clock-frequency" , out_value: &rate)) |
1105 | return ERR_PTR(error: -ENODEV); |
1106 | |
1107 | return clk_register_fixed_rate(NULL, name, NULL, flags: 0, fixed_rate: rate); |
1108 | } |
1109 | |
1110 | static struct clk __init *input_clock(const char *name, struct clk *clk) |
1111 | { |
1112 | const char *input_name; |
1113 | |
1114 | /* Register the input clock under the desired name. */ |
1115 | input_name = __clk_get_name(clk); |
1116 | clk = clk_register_fixed_factor(NULL, name, parent_name: input_name, |
1117 | flags: 0, mult: 1, div: 1); |
1118 | if (IS_ERR(ptr: clk)) |
1119 | pr_err("%s: Couldn't register %s: %ld\n" , __func__, name, |
1120 | PTR_ERR(clk)); |
1121 | |
1122 | return clk; |
1123 | } |
1124 | |
1125 | static struct clk __init *input_clock_by_name(const char *name, |
1126 | const char *dtname) |
1127 | { |
1128 | struct clk *clk; |
1129 | |
1130 | clk = of_clk_get_by_name(np: clockgen.node, name: dtname); |
1131 | if (IS_ERR(ptr: clk)) |
1132 | return clk; |
1133 | |
1134 | return input_clock(name, clk); |
1135 | } |
1136 | |
1137 | static struct clk __init *input_clock_by_index(const char *name, int idx) |
1138 | { |
1139 | struct clk *clk; |
1140 | |
1141 | clk = of_clk_get(np: clockgen.node, index: 0); |
1142 | if (IS_ERR(ptr: clk)) |
1143 | return clk; |
1144 | |
1145 | return input_clock(name, clk); |
1146 | } |
1147 | |
1148 | static struct clk * __init create_sysclk(const char *name) |
1149 | { |
1150 | struct device_node *sysclk; |
1151 | struct clk *clk; |
1152 | |
1153 | clk = sysclk_from_fixed(node: clockgen.node, name); |
1154 | if (!IS_ERR(ptr: clk)) |
1155 | return clk; |
1156 | |
1157 | clk = input_clock_by_name(name, dtname: "sysclk" ); |
1158 | if (!IS_ERR(ptr: clk)) |
1159 | return clk; |
1160 | |
1161 | clk = input_clock_by_index(name, idx: 0); |
1162 | if (!IS_ERR(ptr: clk)) |
1163 | return clk; |
1164 | |
1165 | sysclk = of_get_child_by_name(node: clockgen.node, name: "sysclk" ); |
1166 | if (sysclk) { |
1167 | clk = sysclk_from_fixed(node: sysclk, name); |
1168 | of_node_put(node: sysclk); |
1169 | if (!IS_ERR(ptr: clk)) |
1170 | return clk; |
1171 | } |
1172 | |
1173 | pr_err("%s: No input sysclk\n" , __func__); |
1174 | return NULL; |
1175 | } |
1176 | |
1177 | static struct clk * __init create_coreclk(const char *name) |
1178 | { |
1179 | struct clk *clk; |
1180 | |
1181 | clk = input_clock_by_name(name, dtname: "coreclk" ); |
1182 | if (!IS_ERR(ptr: clk)) |
1183 | return clk; |
1184 | |
1185 | /* |
1186 | * This indicates a mix of legacy nodes with the new coreclk |
1187 | * mechanism, which should never happen. If this error occurs, |
1188 | * don't use the wrong input clock just because coreclk isn't |
1189 | * ready yet. |
1190 | */ |
1191 | if (WARN_ON(PTR_ERR(clk) == -EPROBE_DEFER)) |
1192 | return clk; |
1193 | |
1194 | return NULL; |
1195 | } |
1196 | |
1197 | /* Legacy node */ |
1198 | static void __init sysclk_init(struct device_node *node) |
1199 | { |
1200 | struct clk *clk; |
1201 | |
1202 | legacy_init_clockgen(np: node); |
1203 | |
1204 | clk = clockgen.sysclk; |
1205 | if (clk) |
1206 | of_clk_add_provider(np: node, clk_src_get: of_clk_src_simple_get, data: clk); |
1207 | } |
1208 | |
1209 | #define PLL_KILL BIT(31) |
1210 | |
1211 | static void __init create_one_pll(struct clockgen *cg, int idx) |
1212 | { |
1213 | u32 __iomem *reg; |
1214 | u32 mult; |
1215 | struct clockgen_pll *pll = &cg->pll[idx]; |
1216 | const char *input = "cg-sysclk" ; |
1217 | int i; |
1218 | |
1219 | if (!(cg->info.pll_mask & (1 << idx))) |
1220 | return; |
1221 | |
1222 | if (cg->coreclk && idx != PLATFORM_PLL) { |
1223 | if (IS_ERR(ptr: cg->coreclk)) |
1224 | return; |
1225 | |
1226 | input = "cg-coreclk" ; |
1227 | } |
1228 | |
1229 | if (cg->info.flags & CG_VER3) { |
1230 | switch (idx) { |
1231 | case PLATFORM_PLL: |
1232 | reg = cg->regs + 0x60080; |
1233 | break; |
1234 | case CGA_PLL1: |
1235 | reg = cg->regs + 0x80; |
1236 | break; |
1237 | case CGA_PLL2: |
1238 | reg = cg->regs + 0xa0; |
1239 | break; |
1240 | case CGB_PLL1: |
1241 | reg = cg->regs + 0x10080; |
1242 | break; |
1243 | case CGB_PLL2: |
1244 | reg = cg->regs + 0x100a0; |
1245 | break; |
1246 | default: |
1247 | WARN_ONCE(1, "index %d\n" , idx); |
1248 | return; |
1249 | } |
1250 | } else { |
1251 | if (idx == PLATFORM_PLL) |
1252 | reg = cg->regs + 0xc00; |
1253 | else |
1254 | reg = cg->regs + 0x800 + 0x20 * (idx - 1); |
1255 | } |
1256 | |
1257 | /* Get the multiple of PLL */ |
1258 | mult = cg_in(cg, reg); |
1259 | |
1260 | /* Check if this PLL is disabled */ |
1261 | if (mult & PLL_KILL) { |
1262 | pr_debug("%s(): pll %p disabled\n" , __func__, reg); |
1263 | return; |
1264 | } |
1265 | |
1266 | if ((cg->info.flags & CG_VER3) || |
1267 | ((cg->info.flags & CG_PLL_8BIT) && idx != PLATFORM_PLL)) |
1268 | mult = (mult & GENMASK(8, 1)) >> 1; |
1269 | else |
1270 | mult = (mult & GENMASK(6, 1)) >> 1; |
1271 | |
1272 | for (i = 0; i < ARRAY_SIZE(pll->div); i++) { |
1273 | struct clk *clk; |
1274 | int ret; |
1275 | |
1276 | /* |
1277 | * For platform PLL, there are MAX_PLL_DIV divider clocks. |
1278 | * For core PLL, there are 4 divider clocks at most. |
1279 | */ |
1280 | if (idx != PLATFORM_PLL && i >= 4) |
1281 | break; |
1282 | |
1283 | snprintf(buf: pll->div[i].name, size: sizeof(pll->div[i].name), |
1284 | fmt: "cg-pll%d-div%d" , idx, i + 1); |
1285 | |
1286 | clk = clk_register_fixed_factor(NULL, |
1287 | name: pll->div[i].name, parent_name: input, flags: 0, mult, div: i + 1); |
1288 | if (IS_ERR(ptr: clk)) { |
1289 | pr_err("%s: %s: register failed %ld\n" , |
1290 | __func__, pll->div[i].name, PTR_ERR(clk)); |
1291 | continue; |
1292 | } |
1293 | |
1294 | pll->div[i].clk = clk; |
1295 | ret = clk_register_clkdev(clk, pll->div[i].name, NULL); |
1296 | if (ret != 0) |
1297 | pr_err("%s: %s: register to lookup table failed %d\n" , |
1298 | __func__, pll->div[i].name, ret); |
1299 | |
1300 | } |
1301 | } |
1302 | |
1303 | static void __init create_plls(struct clockgen *cg) |
1304 | { |
1305 | int i; |
1306 | |
1307 | for (i = 0; i < ARRAY_SIZE(cg->pll); i++) |
1308 | create_one_pll(cg, idx: i); |
1309 | } |
1310 | |
1311 | static void __init legacy_pll_init(struct device_node *np, int idx) |
1312 | { |
1313 | struct clockgen_pll *pll; |
1314 | struct clk_onecell_data *onecell_data; |
1315 | struct clk **subclks; |
1316 | int count, rc; |
1317 | |
1318 | legacy_init_clockgen(np); |
1319 | |
1320 | pll = &clockgen.pll[idx]; |
1321 | count = of_property_count_strings(np, propname: "clock-output-names" ); |
1322 | |
1323 | BUILD_BUG_ON(ARRAY_SIZE(pll->div) < 4); |
1324 | subclks = kcalloc(n: 4, size: sizeof(struct clk *), GFP_KERNEL); |
1325 | if (!subclks) |
1326 | return; |
1327 | |
1328 | onecell_data = kmalloc(size: sizeof(*onecell_data), GFP_KERNEL); |
1329 | if (!onecell_data) |
1330 | goto err_clks; |
1331 | |
1332 | if (count <= 3) { |
1333 | subclks[0] = pll->div[0].clk; |
1334 | subclks[1] = pll->div[1].clk; |
1335 | subclks[2] = pll->div[3].clk; |
1336 | } else { |
1337 | subclks[0] = pll->div[0].clk; |
1338 | subclks[1] = pll->div[1].clk; |
1339 | subclks[2] = pll->div[2].clk; |
1340 | subclks[3] = pll->div[3].clk; |
1341 | } |
1342 | |
1343 | onecell_data->clks = subclks; |
1344 | onecell_data->clk_num = count; |
1345 | |
1346 | rc = of_clk_add_provider(np, clk_src_get: of_clk_src_onecell_get, data: onecell_data); |
1347 | if (rc) { |
1348 | pr_err("%s: Couldn't register clk provider for node %pOFn: %d\n" , |
1349 | __func__, np, rc); |
1350 | goto err_cell; |
1351 | } |
1352 | |
1353 | return; |
1354 | err_cell: |
1355 | kfree(objp: onecell_data); |
1356 | err_clks: |
1357 | kfree(objp: subclks); |
1358 | } |
1359 | |
1360 | /* Legacy node */ |
1361 | static void __init pltfrm_pll_init(struct device_node *np) |
1362 | { |
1363 | legacy_pll_init(np, PLATFORM_PLL); |
1364 | } |
1365 | |
1366 | /* Legacy node */ |
1367 | static void __init core_pll_init(struct device_node *np) |
1368 | { |
1369 | struct resource res; |
1370 | int idx; |
1371 | |
1372 | if (of_address_to_resource(dev: np, index: 0, r: &res)) |
1373 | return; |
1374 | |
1375 | if ((res.start & 0xfff) == 0xc00) { |
1376 | /* |
1377 | * ls1021a devtree labels the platform PLL |
1378 | * with the core PLL compatible |
1379 | */ |
1380 | pltfrm_pll_init(np); |
1381 | } else { |
1382 | idx = (res.start & 0xf0) >> 5; |
1383 | legacy_pll_init(np, CGA_PLL1 + idx); |
1384 | } |
1385 | } |
1386 | |
1387 | static struct clk *clockgen_clk_get(struct of_phandle_args *clkspec, void *data) |
1388 | { |
1389 | struct clockgen *cg = data; |
1390 | struct clk *clk; |
1391 | struct clockgen_pll *pll; |
1392 | u32 type, idx; |
1393 | |
1394 | if (clkspec->args_count < 2) { |
1395 | pr_err("%s: insufficient phandle args\n" , __func__); |
1396 | return ERR_PTR(error: -EINVAL); |
1397 | } |
1398 | |
1399 | type = clkspec->args[0]; |
1400 | idx = clkspec->args[1]; |
1401 | |
1402 | switch (type) { |
1403 | case QORIQ_CLK_SYSCLK: |
1404 | if (idx != 0) |
1405 | goto bad_args; |
1406 | clk = cg->sysclk; |
1407 | break; |
1408 | case QORIQ_CLK_CMUX: |
1409 | if (idx >= ARRAY_SIZE(cg->cmux)) |
1410 | goto bad_args; |
1411 | clk = cg->cmux[idx]; |
1412 | break; |
1413 | case QORIQ_CLK_HWACCEL: |
1414 | if (idx >= ARRAY_SIZE(cg->hwaccel)) |
1415 | goto bad_args; |
1416 | clk = cg->hwaccel[idx]; |
1417 | break; |
1418 | case QORIQ_CLK_FMAN: |
1419 | if (idx >= ARRAY_SIZE(cg->fman)) |
1420 | goto bad_args; |
1421 | clk = cg->fman[idx]; |
1422 | break; |
1423 | case QORIQ_CLK_PLATFORM_PLL: |
1424 | pll = &cg->pll[PLATFORM_PLL]; |
1425 | if (idx >= ARRAY_SIZE(pll->div)) |
1426 | goto bad_args; |
1427 | clk = pll->div[idx].clk; |
1428 | break; |
1429 | case QORIQ_CLK_CORECLK: |
1430 | if (idx != 0) |
1431 | goto bad_args; |
1432 | clk = cg->coreclk; |
1433 | if (IS_ERR(ptr: clk)) |
1434 | clk = NULL; |
1435 | break; |
1436 | default: |
1437 | goto bad_args; |
1438 | } |
1439 | |
1440 | if (!clk) |
1441 | return ERR_PTR(error: -ENOENT); |
1442 | return clk; |
1443 | |
1444 | bad_args: |
1445 | pr_err("%s: Bad phandle args %u %u\n" , __func__, type, idx); |
1446 | return ERR_PTR(error: -EINVAL); |
1447 | } |
1448 | |
1449 | #ifdef CONFIG_PPC |
1450 | #include <asm/mpc85xx.h> |
1451 | |
1452 | static const u32 a4510_svrs[] __initconst = { |
1453 | (SVR_P2040 << 8) | 0x10, /* P2040 1.0 */ |
1454 | (SVR_P2040 << 8) | 0x11, /* P2040 1.1 */ |
1455 | (SVR_P2041 << 8) | 0x10, /* P2041 1.0 */ |
1456 | (SVR_P2041 << 8) | 0x11, /* P2041 1.1 */ |
1457 | (SVR_P3041 << 8) | 0x10, /* P3041 1.0 */ |
1458 | (SVR_P3041 << 8) | 0x11, /* P3041 1.1 */ |
1459 | (SVR_P4040 << 8) | 0x20, /* P4040 2.0 */ |
1460 | (SVR_P4080 << 8) | 0x20, /* P4080 2.0 */ |
1461 | (SVR_P5010 << 8) | 0x10, /* P5010 1.0 */ |
1462 | (SVR_P5010 << 8) | 0x20, /* P5010 2.0 */ |
1463 | (SVR_P5020 << 8) | 0x10, /* P5020 1.0 */ |
1464 | (SVR_P5021 << 8) | 0x10, /* P5021 1.0 */ |
1465 | (SVR_P5040 << 8) | 0x10, /* P5040 1.0 */ |
1466 | }; |
1467 | |
1468 | #define SVR_SECURITY 0x80000 /* The Security (E) bit */ |
1469 | |
1470 | static bool __init has_erratum_a4510(void) |
1471 | { |
1472 | u32 svr = mfspr(SPRN_SVR); |
1473 | int i; |
1474 | |
1475 | svr &= ~SVR_SECURITY; |
1476 | |
1477 | for (i = 0; i < ARRAY_SIZE(a4510_svrs); i++) { |
1478 | if (svr == a4510_svrs[i]) |
1479 | return true; |
1480 | } |
1481 | |
1482 | return false; |
1483 | } |
1484 | #else |
1485 | static bool __init has_erratum_a4510(void) |
1486 | { |
1487 | return false; |
1488 | } |
1489 | #endif |
1490 | |
1491 | static void __init _clockgen_init(struct device_node *np, bool legacy) |
1492 | { |
1493 | int i, ret; |
1494 | bool is_old_ls1021a = false; |
1495 | |
1496 | /* May have already been called by a legacy probe */ |
1497 | if (clockgen.node) |
1498 | return; |
1499 | |
1500 | clockgen.node = np; |
1501 | clockgen.regs = of_iomap(node: np, index: 0); |
1502 | if (!clockgen.regs && |
1503 | of_device_is_compatible(device: of_root, "fsl,ls1021a" )) { |
1504 | /* Compatibility hack for old, broken device trees */ |
1505 | clockgen.regs = ioremap(offset: 0x1ee1000, size: 0x1000); |
1506 | is_old_ls1021a = true; |
1507 | } |
1508 | if (!clockgen.regs) { |
1509 | pr_err("%s(): %pOFn: of_iomap() failed\n" , __func__, np); |
1510 | return; |
1511 | } |
1512 | |
1513 | for (i = 0; i < ARRAY_SIZE(chipinfo); i++) { |
1514 | if (of_device_is_compatible(device: np, chipinfo[i].compat)) |
1515 | break; |
1516 | if (is_old_ls1021a && |
1517 | !strcmp(chipinfo[i].compat, "fsl,ls1021a-clockgen" )) |
1518 | break; |
1519 | } |
1520 | |
1521 | if (i == ARRAY_SIZE(chipinfo)) { |
1522 | pr_err("%s: unknown clockgen node %pOF\n" , __func__, np); |
1523 | goto err; |
1524 | } |
1525 | clockgen.info = chipinfo[i]; |
1526 | |
1527 | if (clockgen.info.guts_compat) { |
1528 | struct device_node *guts; |
1529 | |
1530 | guts = of_find_compatible_node(NULL, NULL, |
1531 | compat: clockgen.info.guts_compat); |
1532 | if (guts) { |
1533 | clockgen.guts = of_iomap(node: guts, index: 0); |
1534 | if (!clockgen.guts) { |
1535 | pr_err("%s: Couldn't map %pOF regs\n" , __func__, |
1536 | guts); |
1537 | } |
1538 | of_node_put(node: guts); |
1539 | } |
1540 | |
1541 | } |
1542 | |
1543 | if (has_erratum_a4510()) |
1544 | clockgen.info.flags |= CG_CMUX_GE_PLAT; |
1545 | |
1546 | clockgen.sysclk = create_sysclk(name: "cg-sysclk" ); |
1547 | clockgen.coreclk = create_coreclk(name: "cg-coreclk" ); |
1548 | create_plls(cg: &clockgen); |
1549 | create_muxes(cg: &clockgen); |
1550 | |
1551 | if (clockgen.info.init_periph) |
1552 | clockgen.info.init_periph(&clockgen); |
1553 | |
1554 | ret = of_clk_add_provider(np, clk_src_get: clockgen_clk_get, data: &clockgen); |
1555 | if (ret) { |
1556 | pr_err("%s: Couldn't register clk provider for node %pOFn: %d\n" , |
1557 | __func__, np, ret); |
1558 | } |
1559 | |
1560 | /* Don't create cpufreq device for legacy clockgen blocks */ |
1561 | add_cpufreq_dev = !legacy; |
1562 | |
1563 | return; |
1564 | err: |
1565 | iounmap(addr: clockgen.regs); |
1566 | clockgen.regs = NULL; |
1567 | } |
1568 | |
1569 | static void __init clockgen_init(struct device_node *np) |
1570 | { |
1571 | _clockgen_init(np, legacy: false); |
1572 | } |
1573 | |
1574 | static int __init clockgen_cpufreq_init(void) |
1575 | { |
1576 | struct platform_device *pdev; |
1577 | |
1578 | if (add_cpufreq_dev) { |
1579 | pdev = platform_device_register_simple(name: "qoriq-cpufreq" , id: -1, |
1580 | NULL, num: 0); |
1581 | if (IS_ERR(ptr: pdev)) |
1582 | pr_err("Couldn't register qoriq-cpufreq err=%ld\n" , |
1583 | PTR_ERR(pdev)); |
1584 | } |
1585 | return 0; |
1586 | } |
1587 | device_initcall(clockgen_cpufreq_init); |
1588 | |
1589 | CLK_OF_DECLARE(qoriq_clockgen_1, "fsl,qoriq-clockgen-1.0" , clockgen_init); |
1590 | CLK_OF_DECLARE(qoriq_clockgen_2, "fsl,qoriq-clockgen-2.0" , clockgen_init); |
1591 | CLK_OF_DECLARE(qoriq_clockgen_b4420, "fsl,b4420-clockgen" , clockgen_init); |
1592 | CLK_OF_DECLARE(qoriq_clockgen_b4860, "fsl,b4860-clockgen" , clockgen_init); |
1593 | CLK_OF_DECLARE(qoriq_clockgen_ls1012a, "fsl,ls1012a-clockgen" , clockgen_init); |
1594 | CLK_OF_DECLARE(qoriq_clockgen_ls1021a, "fsl,ls1021a-clockgen" , clockgen_init); |
1595 | CLK_OF_DECLARE(qoriq_clockgen_ls1028a, "fsl,ls1028a-clockgen" , clockgen_init); |
1596 | CLK_OF_DECLARE(qoriq_clockgen_ls1043a, "fsl,ls1043a-clockgen" , clockgen_init); |
1597 | CLK_OF_DECLARE(qoriq_clockgen_ls1046a, "fsl,ls1046a-clockgen" , clockgen_init); |
1598 | CLK_OF_DECLARE(qoriq_clockgen_ls1088a, "fsl,ls1088a-clockgen" , clockgen_init); |
1599 | CLK_OF_DECLARE(qoriq_clockgen_ls2080a, "fsl,ls2080a-clockgen" , clockgen_init); |
1600 | CLK_OF_DECLARE(qoriq_clockgen_lx2160a, "fsl,lx2160a-clockgen" , clockgen_init); |
1601 | CLK_OF_DECLARE(qoriq_clockgen_p2041, "fsl,p2041-clockgen" , clockgen_init); |
1602 | CLK_OF_DECLARE(qoriq_clockgen_p3041, "fsl,p3041-clockgen" , clockgen_init); |
1603 | CLK_OF_DECLARE(qoriq_clockgen_p4080, "fsl,p4080-clockgen" , clockgen_init); |
1604 | CLK_OF_DECLARE(qoriq_clockgen_p5020, "fsl,p5020-clockgen" , clockgen_init); |
1605 | CLK_OF_DECLARE(qoriq_clockgen_p5040, "fsl,p5040-clockgen" , clockgen_init); |
1606 | CLK_OF_DECLARE(qoriq_clockgen_t1023, "fsl,t1023-clockgen" , clockgen_init); |
1607 | CLK_OF_DECLARE(qoriq_clockgen_t1040, "fsl,t1040-clockgen" , clockgen_init); |
1608 | CLK_OF_DECLARE(qoriq_clockgen_t2080, "fsl,t2080-clockgen" , clockgen_init); |
1609 | CLK_OF_DECLARE(qoriq_clockgen_t4240, "fsl,t4240-clockgen" , clockgen_init); |
1610 | |
1611 | /* Legacy nodes */ |
1612 | CLK_OF_DECLARE(qoriq_sysclk_1, "fsl,qoriq-sysclk-1.0" , sysclk_init); |
1613 | CLK_OF_DECLARE(qoriq_sysclk_2, "fsl,qoriq-sysclk-2.0" , sysclk_init); |
1614 | CLK_OF_DECLARE(qoriq_core_pll_1, "fsl,qoriq-core-pll-1.0" , core_pll_init); |
1615 | CLK_OF_DECLARE(qoriq_core_pll_2, "fsl,qoriq-core-pll-2.0" , core_pll_init); |
1616 | CLK_OF_DECLARE(qoriq_core_mux_1, "fsl,qoriq-core-mux-1.0" , core_mux_init); |
1617 | CLK_OF_DECLARE(qoriq_core_mux_2, "fsl,qoriq-core-mux-2.0" , core_mux_init); |
1618 | CLK_OF_DECLARE(qoriq_pltfrm_pll_1, "fsl,qoriq-platform-pll-1.0" , pltfrm_pll_init); |
1619 | CLK_OF_DECLARE(qoriq_pltfrm_pll_2, "fsl,qoriq-platform-pll-2.0" , pltfrm_pll_init); |
1620 | |