1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Copyright (c) 2020 frank@allwinnertech.com
4 */
5
6 #include <linux/clk-provider.h>
7 #include <linux/io.h>
8 #include <linux/of_address.h>
9 #include <linux/platform_device.h>
10
11 #include "ccu_common.h"
12 #include "ccu_reset.h"
13
14 #include "ccu_div.h"
15 #include "ccu_gate.h"
16 #include "ccu_mp.h"
17 #include "ccu_mult.h"
18 #include "ccu_nk.h"
19 #include "ccu_nkm.h"
20 #include "ccu_nkmp.h"
21 #include "ccu_nm.h"
22
23 #include "ccu-sun50iw12.h"
24
25 /*
26 * The CPU PLL is actually NP clock, with P being /1, /2 or /4. However
27 * P should only be used for output frequencies lower than 288 MHz.
28 *
29 * For now we can just model it as a multiplier clock, and force P to /1.
30 *
31 * The M factor is present in the register's description, but not in the
32 * frequency formula, and it's documented as "M is only used for backdoor
33 * testing", so it's not modelled and then force to 0.
34 */
35 #define SUN50IW12_PLL_CPUX_REG 0x000
36 static struct ccu_mult pll_cpux_clk = {
37 .enable = BIT(31),
38 .lock = BIT(28),
39 .mult = _SUNXI_CCU_MULT_MIN(8, 8, 12),
40 .common = {
41 .reg = 0x000,
42 .hw.init = CLK_HW_INIT("pll-cpux", "dcxo24M",
43 &ccu_mult_ops,
44 CLK_SET_RATE_UNGATE),
45 },
46 };
47
48 /* Some PLLs are input * N / div1 / P. Model them as NKMP with no K */
49 #define SUN50IW12_PLL_DDR_REG 0x010
50 static struct ccu_nkmp pll_ddr_clk = {
51 .enable = BIT(31),
52 .lock = BIT(28),
53 .n = _SUNXI_CCU_MULT_MIN(8, 8, 12),
54 .m = _SUNXI_CCU_DIV(1, 1), /* input divider */
55 .p = _SUNXI_CCU_DIV(0, 1), /* output divider */
56 .common = {
57 .reg = 0x010,
58 .hw.init = CLK_HW_INIT("pll-ddr", "dcxo24M",
59 &ccu_nkmp_ops,
60 CLK_SET_RATE_UNGATE),
61 },
62 };
63
64 #define SUN50IW12_PLL_PERIPH0_REG 0x020
65 static struct ccu_nkmp pll_periph0_clk = {
66 .enable = BIT(31),
67 .lock = BIT(28),
68 .n = _SUNXI_CCU_MULT_MIN(8, 8, 12),
69 .m = _SUNXI_CCU_DIV(1, 1), /* input divider */
70 .p = _SUNXI_CCU_DIV(0, 1), /* output divider */
71 .fixed_post_div = 2,
72 .common = {
73 .reg = 0x020,
74 .features = CCU_FEATURE_FIXED_POSTDIV,
75 .hw.init = CLK_HW_INIT("pll-periph0", "dcxo24M",
76 &ccu_nkmp_ops,
77 CLK_SET_RATE_UNGATE),
78 },
79 };
80
81 #define SUN50IW12_PLL_PERIPH1_REG 0x028
82 static struct ccu_nkmp pll_periph1_clk = {
83 .enable = BIT(31),
84 .lock = BIT(28),
85 .n = _SUNXI_CCU_MULT_MIN(8, 8, 12),
86 .m = _SUNXI_CCU_DIV(1, 1), /* input divider */
87 .p = _SUNXI_CCU_DIV(0, 1), /* output divider */
88 .fixed_post_div = 2,
89 .common = {
90 .reg = 0x028,
91 .features = CCU_FEATURE_FIXED_POSTDIV,
92 .hw.init = CLK_HW_INIT("pll-periph1", "dcxo24M",
93 &ccu_nkmp_ops,
94 CLK_SET_RATE_UNGATE),
95 },
96 };
97
98 #define SUN50IW12_PLL_GPU_REG 0x030
99 static struct ccu_nkmp pll_gpu_clk = {
100 .enable = BIT(31),
101 .lock = BIT(28),
102 .n = _SUNXI_CCU_MULT_MIN(8, 8, 12),
103 .m = _SUNXI_CCU_DIV(1, 1), /* input divider */
104 .p = _SUNXI_CCU_DIV(0, 1), /* output divider */
105 .common = {
106 .reg = 0x030,
107 .hw.init = CLK_HW_INIT("pll-gpu", "dcxo24M",
108 &ccu_nkmp_ops,
109 CLK_SET_RATE_UNGATE),
110 },
111 };
112
113 /*
114 * For Video PLLs, the output divider is described as "used for testing"
115 * in the user manual. So it's not modelled and forced to 0.
116 */
117 #define SUN50IW12_PLL_VIDEO0_REG 0x040
118 static struct ccu_nm pll_video0_clk = {
119 .enable = BIT(31),
120 .lock = BIT(28),
121 .n = _SUNXI_CCU_MULT_MIN(8, 8, 12),
122 .m = _SUNXI_CCU_DIV(1, 1), /* input divider */
123 .fixed_post_div = 4,
124 .min_rate = 288000000,
125 .max_rate = 2400000000UL,
126 .common = {
127 .reg = 0x040,
128 .features = CCU_FEATURE_FIXED_POSTDIV,
129 .hw.init = CLK_HW_INIT("pll-video0", "dcxo24M",
130 &ccu_nm_ops,
131 CLK_SET_RATE_UNGATE),
132 },
133 };
134
135 #define SUN50IW12_PLL_VIDEO1_REG 0x048
136 static struct ccu_nm pll_video1_clk = {
137 .enable = BIT(31),
138 .lock = BIT(28),
139 .n = _SUNXI_CCU_MULT_MIN(8, 8, 12),
140 .m = _SUNXI_CCU_DIV(1, 1), /* input divider */
141 .fixed_post_div = 4,
142 .min_rate = 288000000,
143 .max_rate = 2400000000UL,
144 .common = {
145 .reg = 0x048,
146 .features = CCU_FEATURE_FIXED_POSTDIV,
147 .hw.init = CLK_HW_INIT("pll-video1", "dcxo24M",
148 &ccu_nm_ops,
149 CLK_SET_RATE_UNGATE),
150 },
151 };
152
153 #define SUN50IW12_PLL_VIDEO2_REG 0x050
154 static struct ccu_nm pll_video2_clk = {
155 .enable = BIT(31),
156 .lock = BIT(28),
157 .n = _SUNXI_CCU_MULT_MIN(8, 8, 12),
158 .m = _SUNXI_CCU_DIV(1, 1), /* input divider */
159 .fixed_post_div = 4,
160 .min_rate = 288000000,
161 .max_rate = 2400000000UL,
162 .common = {
163 .reg = 0x050,
164 .features = CCU_FEATURE_FIXED_POSTDIV,
165 .hw.init = CLK_HW_INIT("pll-video2", "dcxo24M",
166 &ccu_nm_ops,
167 CLK_SET_RATE_UNGATE),
168 },
169 };
170
171 #define SUN50IW12_PLL_VE_REG 0x058
172 static struct ccu_nkmp pll_ve_clk = {
173 .enable = BIT(31),
174 .lock = BIT(28),
175 .n = _SUNXI_CCU_MULT_MIN(8, 8, 12),
176 .m = _SUNXI_CCU_DIV(1, 1), /* input divider */
177 .p = _SUNXI_CCU_DIV(0, 1), /* output divider */
178 .common = {
179 .reg = 0x058,
180 .hw.init = CLK_HW_INIT("pll-ve", "dcxo24M",
181 &ccu_nkmp_ops,
182 CLK_SET_RATE_UNGATE),
183 },
184 };
185
186 #define SUN50IW12_PLL_ADC_REG 0x060
187 static struct ccu_nkmp pll_adc_clk = {
188 .enable = BIT(31),
189 .lock = BIT(28),
190 .n = _SUNXI_CCU_MULT_MIN(8, 8, 12),
191 .m = _SUNXI_CCU_DIV(1, 1), /* input divider */
192 .p = _SUNXI_CCU_DIV(0, 1), /* output divider */
193 .common = {
194 .reg = 0x060,
195 .hw.init = CLK_HW_INIT("pll-adc", "dcxo24M",
196 &ccu_nkmp_ops,
197 CLK_SET_RATE_UNGATE),
198 },
199 };
200
201 #define SUN50IW12_PLL_VIDEO3_REG 0x068
202 static struct ccu_nm pll_video3_clk = {
203 .enable = BIT(31),
204 .lock = BIT(28),
205 .n = _SUNXI_CCU_MULT_MIN(8, 8, 12),
206 .m = _SUNXI_CCU_DIV(1, 1), /* input divider */
207 .fixed_post_div = 4,
208 .min_rate = 288000000,
209 .max_rate = 2400000000UL,
210 .common = {
211 .reg = 0x068,
212 .features = CCU_FEATURE_FIXED_POSTDIV,
213 .hw.init = CLK_HW_INIT("pll-video3", "dcxo24M",
214 &ccu_nm_ops,
215 CLK_SET_RATE_UNGATE),
216 },
217 };
218
219 /*
220 * We don't have any need for the variable divider for now, so we just
221 * hardcode it to match with the clock names.
222 */
223 #define SUN50IW12_PLL_AUDIO_REG 0x078
224 static struct ccu_nm pll_audio_clk = {
225 .enable = BIT(31),
226 .lock = BIT(28),
227 .n = _SUNXI_CCU_MULT_MIN(8, 8, 12),
228 .m = _SUNXI_CCU_DIV(1, 1), /* input divider */
229 .common = {
230 .reg = 0x078,
231 .hw.init = CLK_HW_INIT("pll-audio", "dcxo24M",
232 &ccu_nm_ops,
233 CLK_SET_RATE_UNGATE),
234 },
235 };
236
237 /*
238 * When pll_cpux is selected as the clock source for cpux, there is
239 * an additional frequency division factor m, which we will ignore here.
240 */
241 static const char * const cpux_parents[] = { "dcxo24M", "osc32k",
242 "iosc", "pll-cpux",
243 "pll-periph0",
244 "pll-periph0-2x" };
245 static SUNXI_CCU_MUX(cpux_clk, "cpux", cpux_parents,
246 0x500, 24, 3, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL);
247 static SUNXI_CCU_M(axi_clk, "axi", "cpux", 0x500, 0, 2, 0);
248 static SUNXI_CCU_M(cpux_apb_clk, "cpux-apb", "cpux", 0x500, 8, 2, 0);
249
250 static const char * const ahb_apb0_apb1_parents[] = { "dcxo24M", "osc32k",
251 "iosc", "pll-periph0",
252 "pll-periph0-2x" };
253 static SUNXI_CCU_MP_WITH_MUX(ahb_clk, "ahb",
254 ahb_apb0_apb1_parents,
255 0x510,
256 0, 2, /* M */
257 8, 2, /* P */
258 24, 3, /* mux */
259 0);
260
261 static SUNXI_CCU_MP_WITH_MUX(apb0_clk, "apb0", ahb_apb0_apb1_parents, 0x520,
262 0, 2, /* M */
263 8, 2, /* P */
264 24, 3, /* mux */
265 0);
266
267 static SUNXI_CCU_MP_WITH_MUX(apb1_clk, "apb1", ahb_apb0_apb1_parents, 0x524,
268 0, 2, /* M */
269 8, 2, /* P */
270 24, 3, /* mux */
271 0);
272
273 static const char * const mbus_parents[] = { "dcxo24M", "pll-ddr",
274 "pll-periph0", "pll-periph0-2x" };
275 static SUNXI_CCU_M_WITH_MUX_GATE(mbus_clk, "mbus", mbus_parents, 0x540,
276 0, 5, /* M */
277 24, 2, /* mux */
278 BIT(31), /* gate */
279 CLK_IS_CRITICAL);
280
281 static const char * const mips_parents[] = { "pll-periph0-2x", "pll-video0-4x",
282 "dcxo24M" };
283 static SUNXI_CCU_M_WITH_MUX_GATE(mips_clk, "mips", mips_parents, 0x600,
284 0, 3, /* M */
285 24, 2, /* mux */
286 BIT(31), /* gate */
287 CLK_SET_RATE_PARENT);
288
289 static SUNXI_CCU_GATE(bus_mips_clk, "bus-mips", "ahb",
290 0x60c, BIT(0), 0);
291
292 static SUNXI_CCU_M_WITH_GATE(gpu_clk, "gpu", "pll-gpu",
293 0x670, 0, 5, BIT(31), 0);
294
295 static SUNXI_CCU_GATE(bus_gpu_clk, "bus-gpu", "ahb",
296 0x67c, BIT(0), 0);
297
298 static const char * const ce_parents[] = { "dcxo24M", "pll-periph0-2x" };
299 static SUNXI_CCU_MP_WITH_MUX_GATE(ce_clk, "ce", ce_parents, 0x680,
300 0, 4, /* M */
301 8, 2, /* N */
302 24, 1, /* mux */
303 BIT(31), /* gate */
304 0);
305
306 static SUNXI_CCU_GATE(bus_ce_clk, "bus-ce", "ahb",
307 0x68c, BIT(0), 0);
308
309 static SUNXI_CCU_GATE(bus_ce_sys_clk, "bus-ce-sys", "ahb",
310 0x68c, BIT(1), 0);
311
312 static const char * const ve_core_parents[] = { "pll-ve",
313 "pll-periph0-2x" };
314 static SUNXI_CCU_M_WITH_MUX_GATE(ve_core_clk, "ve-core", ve_core_parents,
315 0x690,
316 0, 3, /* M */
317 24, 1, /* mux */
318 BIT(31), /* gate */
319 0);
320
321 static SUNXI_CCU_GATE(bus_ve_clk, "bus-ve", "ahb",
322 0x69c, BIT(0), 0);
323 static SUNXI_CCU_GATE(bus_av1_clk, "bus-av1", "ahb",
324 0x69c, BIT(1), 0);
325 static SUNXI_CCU_GATE(bus_ve3_clk, "bus-ve3", "ahb",
326 0x69c, BIT(2), 0);
327
328 static SUNXI_CCU_GATE(bus_dma_clk, "bus-dma", "ahb",
329 0x70c, BIT(0), 0);
330
331 static SUNXI_CCU_GATE(bus_msgbox_clk, "bus-msgbox", "ahb",
332 0x71c, BIT(0), 0);
333
334 static SUNXI_CCU_GATE(bus_spinlock_clk, "bus-spinlock", "ahb",
335 0x72c, BIT(0), 0);
336
337 static const struct ccu_mux_var_prediv ahb_predivs[] = {
338 { .index = 3, .shift = 0, .width = 5 },
339 };
340
341 static const char * const timer_parents[] = {"dcxo24M", "iosc",
342 "osc32k", "ahb"};
343
344 static struct ccu_div timer0_clk = {
345 .enable = BIT(0),
346 .div = _SUNXI_CCU_DIV_FLAGS(1, 3, CLK_DIVIDER_POWER_OF_TWO),
347 .mux = {
348 .shift = 4,
349 .width = 2,
350
351 .var_predivs = ahb_predivs,
352 .n_var_predivs = ARRAY_SIZE(ahb_predivs),
353 },
354 .common = {
355 .reg = 0x730,
356 .features = CCU_FEATURE_VARIABLE_PREDIV,
357 .hw.init = CLK_HW_INIT_PARENTS("timer0",
358 timer_parents,
359 &ccu_div_ops,
360 0),
361 },
362 };
363
364 static struct ccu_div timer1_clk = {
365 .enable = BIT(0),
366 .div = _SUNXI_CCU_DIV_FLAGS(1, 3, CLK_DIVIDER_POWER_OF_TWO),
367 .mux = {
368 .shift = 4,
369 .width = 2,
370
371 .var_predivs = ahb_predivs,
372 .n_var_predivs = ARRAY_SIZE(ahb_predivs),
373 },
374 .common = {
375 .reg = 0x734,
376 .features = CCU_FEATURE_VARIABLE_PREDIV,
377 .hw.init = CLK_HW_INIT_PARENTS("timer1",
378 timer_parents,
379 &ccu_div_ops,
380 0),
381 },
382 };
383
384 static struct ccu_div timer2_clk = {
385 .enable = BIT(0),
386 .div = _SUNXI_CCU_DIV_FLAGS(1, 3, CLK_DIVIDER_POWER_OF_TWO),
387 .mux = {
388 .shift = 4,
389 .width = 2,
390
391 .var_predivs = ahb_predivs,
392 .n_var_predivs = ARRAY_SIZE(ahb_predivs),
393 },
394 .common = {
395 .reg = 0x738,
396 .features = CCU_FEATURE_VARIABLE_PREDIV,
397 .hw.init = CLK_HW_INIT_PARENTS("timer2",
398 timer_parents,
399 &ccu_div_ops,
400 0),
401 },
402 };
403
404 static struct ccu_div timer3_clk = {
405 .enable = BIT(0),
406 .div = _SUNXI_CCU_DIV_FLAGS(1, 3, CLK_DIVIDER_POWER_OF_TWO),
407 .mux = {
408 .shift = 4,
409 .width = 2,
410
411 .var_predivs = ahb_predivs,
412 .n_var_predivs = ARRAY_SIZE(ahb_predivs),
413 },
414 .common = {
415 .reg = 0x73c,
416 .features = CCU_FEATURE_VARIABLE_PREDIV,
417 .hw.init = CLK_HW_INIT_PARENTS("timer3",
418 timer_parents,
419 &ccu_div_ops,
420 0),
421 },
422 };
423
424 static struct ccu_div timer4_clk = {
425 .enable = BIT(0),
426 .div = _SUNXI_CCU_DIV_FLAGS(1, 3, CLK_DIVIDER_POWER_OF_TWO),
427 .mux = {
428 .shift = 4,
429 .width = 2,
430
431 .var_predivs = ahb_predivs,
432 .n_var_predivs = ARRAY_SIZE(ahb_predivs),
433 },
434 .common = {
435 .reg = 0x740,
436 .features = CCU_FEATURE_VARIABLE_PREDIV,
437 .hw.init = CLK_HW_INIT_PARENTS("timer4",
438 timer_parents,
439 &ccu_div_ops,
440 0),
441 },
442 };
443
444 static struct ccu_div timer5_clk = {
445 .enable = BIT(0),
446 .div = _SUNXI_CCU_DIV_FLAGS(1, 3, CLK_DIVIDER_POWER_OF_TWO),
447 .mux = {
448 .shift = 4,
449 .width = 2,
450
451 .var_predivs = ahb_predivs,
452 .n_var_predivs = ARRAY_SIZE(ahb_predivs),
453 },
454 .common = {
455 .reg = 0x744,
456 .features = CCU_FEATURE_VARIABLE_PREDIV,
457 .hw.init = CLK_HW_INIT_PARENTS("timer5",
458 timer_parents,
459 &ccu_div_ops,
460 0),
461 },
462 };
463
464 static SUNXI_CCU_GATE(bus_timer0_clk, "bus-timer0", "ahb",
465 0x750, BIT(0), 0);
466
467 static SUNXI_CCU_GATE(bus_dbg_clk, "bus-dbg", "ahb",
468 0x78c, BIT(0), 0);
469
470 static SUNXI_CCU_GATE(bus_pwm_clk, "bus-pwm", "apb0",
471 0x7ac, BIT(0), 0);
472
473 static SUNXI_CCU_GATE(bus_iommu_clk, "bus-iommu", "apb0",
474 0x7bc, BIT(0), 0);
475
476 static const char * const dram_parents[] = { "pll-ddr",
477 "pll-periph1-2x" };
478 static SUNXI_CCU_MP_WITH_MUX_GATE(dram_clk, "dram",
479 dram_parents,
480 0x800,
481 0, 5, /* M */
482 8, 2, /* N */
483 24, 2, /* mux */
484 BIT(31), /* gate */
485 CLK_IS_CRITICAL);
486
487 static SUNXI_CCU_GATE(mbus_dma_clk, "mbus-dma", "mbus",
488 0x804, BIT(0), 0);
489 static SUNXI_CCU_GATE(mbus_ve3_clk, "mbus-ve3", "mbus",
490 0x804, BIT(1), 0);
491 static SUNXI_CCU_GATE(mbus_ce_clk, "mbus-ce", "mbus",
492 0x804, BIT(2), 0);
493 static SUNXI_CCU_GATE(mbus_av1_clk, "mbus-av1", "mbus",
494 0x804, BIT(3), 0);
495 static SUNXI_CCU_GATE(mbus_nand_clk, "mbus-nand", "mbus",
496 0x804, BIT(5), 0);
497
498 static SUNXI_CCU_GATE(bus_dram_clk, "bus-dram", "ahb",
499 0x80c, BIT(0), CLK_IS_CRITICAL);
500
501 static const char * const nand_spi_parents[] = { "dcxo24M", "pll-periph0",
502 "pll-periph1", "pll-periph0-2x",
503 "pll-periph1-2x" };
504 static SUNXI_CCU_MP_WITH_MUX_GATE(nand0_clk, "nand0", nand_spi_parents, 0x810,
505 0, 4, /* M */
506 8, 2, /* P */
507 24, 3, /* mux */
508 BIT(31), /* gate */
509 0);
510
511 static SUNXI_CCU_MP_WITH_MUX_GATE(nand1_clk, "nand1", nand_spi_parents, 0x814,
512 0, 4, /* M */
513 8, 2, /* P */
514 24, 3, /* mux */
515 BIT(31), /* gate */
516 0);
517
518 static SUNXI_CCU_GATE(bus_nand_clk, "bus-nand", "ahb", 0x82c, BIT(0), 0);
519
520 /* XXX: don't use POSTDIV for BSP kernel */
521 static const char * const mmc_parents[] = { "dcxo24M", "pll-periph0-2x",
522 "pll-periph1-2x" };
523 static SUNXI_CCU_MP_WITH_MUX_GATE(mmc0_clk, "mmc0", mmc_parents, 0x830,
524 0, 4, /* M */
525 8, 2, /* P */
526 24, 3, /* mux */
527 BIT(31), /* gate */
528 0);
529
530 static SUNXI_CCU_MP_WITH_MUX_GATE(mmc1_clk, "mmc1", mmc_parents, 0x834,
531 0, 4, /* M */
532 8, 2, /* P */
533 24, 3, /* mux */
534 BIT(31), /* gate */
535 0);
536
537 static SUNXI_CCU_MP_WITH_MUX_GATE(mmc2_clk, "mmc2", mmc_parents, 0x838,
538 0, 4, /* M */
539 8, 2, /* P */
540 24, 3, /* mux */
541 BIT(31), /* gate */
542 0);
543
544 static SUNXI_CCU_GATE(bus_mmc0_clk, "bus-mmc0", "ahb", 0x84c, BIT(0), 0);
545 static SUNXI_CCU_GATE(bus_mmc1_clk, "bus-mmc1", "ahb", 0x84c, BIT(1), 0);
546 static SUNXI_CCU_GATE(bus_mmc2_clk, "bus-mmc2", "ahb", 0x84c, BIT(2), 0);
547
548 static SUNXI_CCU_GATE(bus_uart0_clk, "bus-uart0", "apb1", 0x90c, BIT(0), 0);
549 static SUNXI_CCU_GATE(bus_uart1_clk, "bus-uart1", "apb1", 0x90c, BIT(1), 0);
550 static SUNXI_CCU_GATE(bus_uart2_clk, "bus-uart2", "apb1", 0x90c, BIT(2), 0);
551 static SUNXI_CCU_GATE(bus_uart3_clk, "bus-uart3", "apb1", 0x90c, BIT(3), 0);
552
553 static SUNXI_CCU_GATE(bus_i2c0_clk, "bus-i2c0", "apb1", 0x91c, BIT(0), 0);
554 static SUNXI_CCU_GATE(bus_i2c1_clk, "bus-i2c1", "apb1", 0x91c, BIT(1), 0);
555 static SUNXI_CCU_GATE(bus_i2c2_clk, "bus-i2c2", "apb1", 0x91c, BIT(2), 0);
556 static SUNXI_CCU_GATE(bus_i2c3_clk, "bus-i2c3", "apb1", 0x91c, BIT(3), 0);
557
558 static SUNXI_CCU_MP_WITH_MUX_GATE(spi0_clk, "spi0", nand_spi_parents, 0x940,
559 0, 4, /* M */
560 8, 2, /* P */
561 24, 3, /* mux */
562 BIT(31),/* gate */
563 0);
564
565 static SUNXI_CCU_MP_WITH_MUX_GATE(spi1_clk, "spi1", nand_spi_parents, 0x944,
566 0, 4, /* M */
567 8, 2, /* P */
568 24, 3, /* mux */
569 BIT(31),/* gate */
570 0);
571
572 static SUNXI_CCU_GATE(bus_spi0_clk, "bus-spi0", "ahb", 0x96c, BIT(0), 0);
573 static SUNXI_CCU_GATE(bus_spi1_clk, "bus-spi1", "ahb", 0x96c, BIT(1), 0);
574
575 static SUNXI_CCU_GATE(emac_25M_clk, "emac-25M", "ahb",
576 0x970, BIT(30) | BIT(31), 0);
577 static SUNXI_CCU_GATE(bus_emac_clk, "bus-emac", "ahb", 0x97c, BIT(0), 0);
578
579 static SUNXI_CCU_GATE(bus_gpadc_clk, "bus-gpadc", "apb1", 0x9ec, BIT(0), 0);
580
581 static SUNXI_CCU_GATE(bus_ths_clk, "bus-ths", "apb1", 0x9fc, BIT(0), 0);
582
583 static const char * const i2s_spdif_tx_parents[] = { "pll-audio"};
584 static SUNXI_CCU_MP_WITH_MUX_GATE(i2s0_clk, "i2s0", i2s_spdif_tx_parents,
585 0xa10,
586 0, 5,
587 8, 2,
588 24, 3,
589 BIT(31),
590 0);
591
592 static SUNXI_CCU_MP_WITH_MUX_GATE(i2s1_clk, "i2s1", i2s_spdif_tx_parents,
593 0xa14,
594 0, 5,
595 8, 2,
596 24, 3,
597 BIT(31),
598 0);
599
600 static SUNXI_CCU_MP_WITH_MUX_GATE(i2s2_clk, "i2s2", i2s_spdif_tx_parents,
601 0xa14,
602 0, 5,
603 8, 2,
604 24, 3,
605 BIT(31),
606 0);
607
608 static SUNXI_CCU_GATE(bus_i2s0_clk, "bus-i2s0", "apb1", 0xa20, BIT(0), 0);
609 static SUNXI_CCU_GATE(bus_i2s1_clk, "bus-i2s1", "apb1", 0xa20, BIT(1), 0);
610 static SUNXI_CCU_GATE(bus_i2s2_clk, "bus-i2s2", "apb1", 0xa20, BIT(2), 0);
611
612 static const char * const spdif_rx_parents[] = {"pll-periph0-2x",
613 "pll-audio"};
614 static SUNXI_CCU_MP_WITH_MUX_GATE(spdif0_rx_clk, "spdif0-rx",
615 spdif_rx_parents,
616 0xa30,
617 0, 5, /* m */
618 8, 2, /* p */
619 24, 3, /* mux */
620 BIT(31),
621 0);
622
623 static SUNXI_CCU_MP_WITH_MUX_GATE(spdif0_tx_clk, "spdif0-tx",
624 i2s_spdif_tx_parents,
625 0xa34,
626 0, 5, /* m */
627 8, 2, /* p */
628 24, 1, /* mux */
629 BIT(31),
630 0);
631
632 static SUNXI_CCU_MP_WITH_MUX_GATE(spdif1_rx_clk, "spdif1-rx",
633 spdif_rx_parents,
634 0xa40,
635 0, 5, /* m */
636 8, 2, /* p */
637 24, 3, /* mux */
638 BIT(31),
639 0);
640
641 static SUNXI_CCU_MP_WITH_MUX_GATE(spdif1_tx_clk, "spdif1-tx",
642 i2s_spdif_tx_parents,
643 0xa44,
644 0, 5, /* m */
645 8, 2, /* p */
646 24, 1, /* mux */
647 BIT(31),
648 0);
649
650 static SUNXI_CCU_GATE(bus_spdif0_clk, "bus-spdif0", "apb1", 0xa2c, BIT(0), 0);
651 static SUNXI_CCU_GATE(bus_spdif1_clk, "bus-spdif1", "apb1", 0xa2c, BIT(1), 0);
652
653 static const char * const audio_hub_parents[] = { "pll-audio"};
654
655 static SUNXI_CCU_MP_WITH_MUX_GATE(audio_hub_clk, "audio-hub",
656 audio_hub_parents,
657 0xa50,
658 0, 5, /* m */
659 8, 2, /* p */
660 24, 3, /* mux */
661 BIT(31),
662 0);
663
664 static SUNXI_CCU_GATE(bus_audio_hub_clk, "bus-audio_hub", "apb1", 0xa5c, BIT(0), 0);
665
666 static SUNXI_CCU_MP_WITH_MUX_GATE(audio_codec_dac_clk, "audio-codec-dac",
667 audio_hub_parents,
668 0xa60,
669 0, 5, /* m */
670 8, 2, /* p */
671 24, 3, /* mux */
672 BIT(31),
673 0);
674
675 static SUNXI_CCU_MP_WITH_MUX_GATE(audio_codec_adc_clk, "audio-codec-adc",
676 audio_hub_parents,
677 0xa64,
678 0, 5, /* m */
679 8, 2, /* p */
680 24, 3, /* mux */
681 BIT(31),
682 0);
683
684 static SUNXI_CCU_GATE(bus_audio_codec_clk, "bus-audio-codec", "apb1",
685 0xa6c, BIT(0), 0);
686
687 static SUNXI_CCU_GATE(usb_ohci0_clk, "usb-ohci0", "osc12M", 0xa70, BIT(31), 0);
688 static SUNXI_CCU_GATE(usb_ohci1_clk, "usb-ohci1", "osc12M", 0xa78, BIT(31), 0);
689 static SUNXI_CCU_GATE(usb_ohci2_clk, "usb-ohci2", "osc12M", 0xa80, BIT(31), 0);
690
691 /*
692 * There are OHCI 12M clock source selection bits for 3 USB 2.0 ports.
693 * We will force them to 0 (12M divided from 48M).
694 */
695 static SUNXI_CCU_GATE(bus_ohci0_clk, "bus-ohci0", "osc12M", 0xa8c, BIT(0), 0);
696 static SUNXI_CCU_GATE(bus_ohci1_clk, "bus-ohci1", "osc12M", 0xa8c, BIT(1), 0);
697 static SUNXI_CCU_GATE(bus_ohci2_clk, "bus-ohci2", "osc12M", 0xa8c, BIT(2), 0);
698 static SUNXI_CCU_GATE(bus_ehci0_clk, "bus-ehci0", "ahb", 0xa8c, BIT(4), 0);
699 static SUNXI_CCU_GATE(bus_ehci1_clk, "bus-ehci1", "ahb", 0xa8c, BIT(5), 0);
700 static SUNXI_CCU_GATE(bus_ehci2_clk, "bus-ehci2", "ahb", 0xa8c, BIT(6), 0);
701 static SUNXI_CCU_GATE(bus_otg0_clk, "bus-otg0", "ahb", 0xa8c, BIT(8), 0);
702
703 static SUNXI_CCU_GATE(bus_lradc_clk, "bus-lradc", "ahb", 0xa9c, BIT(8), 0);
704
705 static const char *const adc_parents[] = {"pll-adc", "pll-video0"};
706
707 static SUNXI_CCU_MP_WITH_MUX_GATE(adc_clk, "adc",
708 adc_parents,
709 0xd10,
710 0, 5, /* m */
711 8, 2, /* p */
712 24, 1, /* mux */
713 BIT(31),
714 0);
715
716 static const char * const dtmb_120M_parents[] = { "pll-adc", "pll-periph0" };
717
718 static SUNXI_CCU_MP_WITH_MUX_GATE(dtmb_120M_clk, "dtmb-120M",
719 dtmb_120M_parents,
720 0xd18,
721 0, 2, /* m */
722 8, 2, /* p */
723 24, 1, /* mux */
724 BIT(31),
725 0);
726
727 static const char * const tvfe_1296M_parents[] = { "pll-video0-4x", "pll-adc" };
728
729 static SUNXI_CCU_MP_WITH_MUX_GATE(tvfe_1296M_clk, "tvfe_1296M_clk",
730 tvfe_1296M_parents,
731 0xd18,
732 0, 2, /* m */
733 8, 2, /* p */
734 24, 1, /* mux */
735 BIT(31),
736 0);
737
738 static const char * const i2h_parents[] = { "pll-video0-4x",
739 "pll-periph0-2x",
740 "pll-periph1-2x"};
741
742 static SUNXI_CCU_M_WITH_MUX_GATE(i2h_clk, "i2h", i2h_parents, 0xd24,
743 0, 5, /* M */
744 24, 3, /* mux */
745 BIT(31), /* gate */
746 0);
747
748 static const char * const cip_tsx_parents[] = { "pll-periph0",
749 "pll-periph1"};
750
751 static SUNXI_CCU_M_WITH_MUX_GATE(cip_tsx_clk, "cip-tsx", cip_tsx_parents, 0xd28,
752 0, 3,
753 24, 1,
754 BIT(31),
755 0);
756
757 static SUNXI_CCU_M_WITH_MUX_GATE(cip_mcx_clk, "cip-mcx", cip_tsx_parents, 0xd2c,
758 0, 3,
759 24, 1,
760 BIT(31),
761 0);
762
763 static const char * const cip_tsp_parents[] = { "pll-video0-4x",
764 "pll-adc"};
765
766 static SUNXI_CCU_M_WITH_MUX_GATE(cip_tsp_clk, "cip-tsp", cip_tsp_parents, 0xd30,
767 0, 3,
768 24, 1,
769 BIT(31),
770 0);
771
772 static SUNXI_CCU_M_WITH_MUX_GATE(tsa_tsp_clk, "tsa-tsp", cip_tsp_parents, 0xd34,
773 0, 3,
774 24, 1,
775 BIT(31),
776 0);
777
778 static const char * const cip27_parents[] = { "pll-video0",
779 "pll-adc" };
780
781 static SUNXI_CCU_MP_WITH_MUX_GATE(cip27_clk, "cip27",
782 cip27_parents,
783 0xd38,
784 0, 4, /* m */
785 8, 2, /* p */
786 24, 1, /* mux */
787 BIT(31),
788 0);
789
790 static const char *const cip_mts0_parents[] = { "pll-video1-4x", "pll-video0-4x",
791 "pll-video3-4x", "pll-adc",
792 "pll-periph0-2x"};
793
794 static SUNXI_CCU_MP_WITH_MUX_GATE(cip_mts0_clk, "cip-mts",
795 cip_mts0_parents,
796 0xd40,
797 0, 5, /* m */
798 8, 2, /* p */
799 24, 3, /* mux */
800 BIT(31),
801 0);
802
803 static const char * const audio_cpu_parents[] = { "pll-periph0-2x",
804 "pll-periph1-2x"};
805
806 static SUNXI_CCU_M_WITH_MUX_GATE(audio_cpu_clk, "audio_cpu", audio_cpu_parents, 0xd48,
807 0, 3,
808 24, 1,
809 BIT(31),
810 0);
811
812 static const char * const audio_umac_parents[] = { "pll-periph0",
813 "pll-periph1"};
814
815 static SUNXI_CCU_M_WITH_MUX_GATE(audio_umac_clk, "audio_umac", audio_umac_parents, 0xd4c,
816 0, 3,
817 24, 1,
818 BIT(31),
819 0);
820
821 static const char * const audio_ihb_parents[] = { "pll-video0-4x",
822 "pll-periph0",
823 "pll-periph1"};
824
825 static SUNXI_CCU_M_WITH_MUX_GATE(audio_ihb_clk, "audio_ihb", audio_ihb_parents, 0xd50,
826 0, 4,
827 24, 3,
828 BIT(31),
829 0);
830
831 static const char * const tsa432_parents[] = { "pll-video0-4x",
832 "pll-adc"};
833
834 static SUNXI_CCU_M_WITH_MUX_GATE(tsa432_clk, "tsa432", tsa432_parents, 0xd58,
835 0, 3,
836 24, 1,
837 BIT(31),
838 0);
839
840 static const char *const mpg_parents[] = { "pll-video1-4x", "dcxo24M",
841 "pll-adc"};
842
843 static SUNXI_CCU_MP_WITH_MUX_GATE(mpg0_clk, "mpg0",
844 mpg_parents,
845 0xd5c,
846 0, 4, /* m */
847 8, 2, /* p */
848 24, 3, /* mux */
849 BIT(31),
850 0);
851
852 static SUNXI_CCU_MP_WITH_MUX_GATE(mpg1_clk, "mpg1",
853 mpg_parents,
854 0xd60,
855 0, 4, /* m */
856 8, 2, /* p */
857 24, 3, /* mux */
858 BIT(31),
859 0);
860
861 static SUNXI_CCU_GATE(bus_demod_clk, "bus-demod", "pll-video0-4x",
862 0xd64, BIT(0), 0);
863
864 static const char *const tcd3_parents[] = { "pll-video0-4x", "pll-adc"};
865
866 static SUNXI_CCU_MP_WITH_MUX_GATE(tcd3_clk, "tcd3",
867 tcd3_parents,
868 0xd6c,
869 0, 3, /* m */
870 8, 2, /* p */
871 24, 1, /* mux */
872 BIT(31),
873 0);
874
875 static const char *const vincap_dma_parents[] = { "pll-video2-4x", "pll-periph0"};
876 static SUNXI_CCU_M_WITH_MUX_GATE(vincap_dma_clk, "vincap-dma", vincap_dma_parents,
877 0xd74,
878 0, 5, /* M */
879 24, 1, /* mux */
880 BIT(31), /* gate */
881 0);
882 static SUNXI_CCU_GATE(bus_hdmi_audio_clk, "bus-hdmi-audio", "ahb",
883 0xd80, BIT(31), 0);
884 static SUNXI_CCU_GATE(bus_cap_300M_clk, "bus-cap-300M", "ahb",
885 0xd80, BIT(30), 0);
886
887 static const char *const hdmi_audio_parents[] = { "pll-video3-4x", "pll-periph0-2x"};
888 static SUNXI_CCU_M_WITH_MUX_GATE(hdmi_audio_clk, "hdmi-audio", hdmi_audio_parents,
889 0xd84,
890 0, 5, /* M */
891 24, 1, /* mux */
892 BIT(31), /* gate */
893 0);
894
895 static SUNXI_CCU_GATE(bus_tvcap_clk, "bus-tvcap", "ahb",
896 0xd88, BIT(0), 0);
897
898 static SUNXI_CCU_M_WITH_GATE(deint_clk, "deint", "pll-video2-4x",
899 0xdb0, 0, 5, BIT(31), 0);
900
901 static const char * const svp_dtl_parents[] = { "pll-periph0-2x",
902 "pll-video0-4x",
903 "pll-periph1-2x"};
904 static SUNXI_CCU_M_WITH_MUX_GATE(svp_dtl_clk, "svp-dtl", svp_dtl_parents,
905 0xdb8,
906 0, 5, /* M */
907 24, 3, /* mux */
908 BIT(31) | BIT(30), /* gate */
909 0);
910
911 static const char * const afbd_parents[] = { "pll-periph0-2x",
912 "pll-periph0",
913 "pll-video0-4x",
914 "pll-adc"};
915 static SUNXI_CCU_M_WITH_MUX_GATE(afbd_clk, "afbd", afbd_parents,
916 0xdc0,
917 0, 4, /* M */
918 24, 3, /* mux */
919 BIT(31), /* gate */
920 0);
921
922 static SUNXI_CCU_GATE(bus_disp_clk, "bus-disp", "apb1",
923 0xdd8, BIT(0), 0);
924
925 /* Fixed factor clocks */
926 static CLK_FIXED_FACTOR_FW_NAME(osc12M_clk, "osc12M", "hosc", 2, 1, 0);
927
928 static CLK_FIXED_FACTOR_HW(pll_periph0_2x_clk, "pll-periph0-2x",
929 &pll_periph0_clk.common.hw,
930 1, 2, 0);
931
932 static CLK_FIXED_FACTOR_HW(pll_periph1_2x_clk, "pll-periph1-2x",
933 &pll_periph1_clk.common.hw,
934 1, 2, 0);
935
936 static CLK_FIXED_FACTOR_HW(pll_video0_4x_clk, "pll-video0-4x",
937 &pll_video0_clk.common.hw,
938 1, 4, CLK_SET_RATE_PARENT);
939 static CLK_FIXED_FACTOR_HW(pll_video1_4x_clk, "pll-video1-4x",
940 &pll_video1_clk.common.hw,
941 1, 4, CLK_SET_RATE_PARENT);
942 static CLK_FIXED_FACTOR_HW(pll_video2_4x_clk, "pll-video2-4x",
943 &pll_video2_clk.common.hw,
944 1, 4, CLK_SET_RATE_PARENT);
945 static CLK_FIXED_FACTOR_HW(pll_video3_4x_clk, "pll-video3-4x",
946 &pll_video3_clk.common.hw,
947 1, 4, CLK_SET_RATE_PARENT);
948
949 static struct ccu_common *sun50iw12_ccu_clks[] = {
950 &pll_cpux_clk.common,
951 &pll_ddr_clk.common,
952 &pll_periph0_clk.common,
953 &pll_periph1_clk.common,
954 &pll_gpu_clk.common,
955 &pll_video0_clk.common,
956 &pll_video1_clk.common,
957 &pll_video2_clk.common,
958 &pll_ve_clk.common,
959 &pll_adc_clk.common,
960 &pll_video3_clk.common,
961 &pll_audio_clk.common,
962 &cpux_clk.common,
963 &axi_clk.common,
964 &cpux_apb_clk.common,
965 &ahb_clk.common,
966 &apb0_clk.common,
967 &apb1_clk.common,
968 &mbus_clk.common,
969 &mips_clk.common,
970 &bus_mips_clk.common,
971 &gpu_clk.common,
972 &bus_gpu_clk.common,
973 &ce_clk.common,
974 &bus_ce_clk.common,
975 &bus_ce_sys_clk.common,
976 &ve_core_clk.common,
977 &bus_ve_clk.common,
978 &bus_av1_clk.common,
979 &bus_ve3_clk.common,
980 &bus_dma_clk.common,
981 &bus_msgbox_clk.common,
982 &bus_spinlock_clk.common,
983 &timer0_clk.common,
984 &timer1_clk.common,
985 &timer2_clk.common,
986 &timer3_clk.common,
987 &timer4_clk.common,
988 &timer5_clk.common,
989 &bus_timer0_clk.common,
990 &bus_dbg_clk.common,
991 &bus_pwm_clk.common,
992 &bus_iommu_clk.common,
993 &dram_clk.common,
994 &mbus_dma_clk.common,
995 &mbus_ve3_clk.common,
996 &mbus_ce_clk.common,
997 &mbus_av1_clk.common,
998 &mbus_nand_clk.common,
999 &bus_dram_clk.common,
1000 &nand0_clk.common,
1001 &nand1_clk.common,
1002 &bus_nand_clk.common,
1003 &mmc0_clk.common,
1004 &mmc1_clk.common,
1005 &mmc2_clk.common,
1006 &bus_mmc0_clk.common,
1007 &bus_mmc1_clk.common,
1008 &bus_mmc2_clk.common,
1009 &bus_uart0_clk.common,
1010 &bus_uart1_clk.common,
1011 &bus_uart2_clk.common,
1012 &bus_uart3_clk.common,
1013 &bus_i2c0_clk.common,
1014 &bus_i2c1_clk.common,
1015 &bus_i2c2_clk.common,
1016 &bus_i2c3_clk.common,
1017 &spi0_clk.common,
1018 &spi1_clk.common,
1019 &bus_spi0_clk.common,
1020 &bus_spi1_clk.common,
1021 &emac_25M_clk.common,
1022 &bus_emac_clk.common,
1023 &bus_gpadc_clk.common,
1024 &bus_ths_clk.common,
1025 &i2s0_clk.common,
1026 &i2s1_clk.common,
1027 &i2s2_clk.common,
1028 &bus_i2s0_clk.common,
1029 &bus_i2s1_clk.common,
1030 &bus_i2s2_clk.common,
1031 &spdif0_rx_clk.common,
1032 &spdif0_tx_clk.common,
1033 &spdif1_rx_clk.common,
1034 &spdif1_tx_clk.common,
1035 &bus_spdif0_clk.common,
1036 &bus_spdif1_clk.common,
1037 &audio_hub_clk.common,
1038 &bus_audio_hub_clk.common,
1039 &audio_codec_dac_clk.common,
1040 &audio_codec_adc_clk.common,
1041 &bus_audio_codec_clk.common,
1042 &usb_ohci0_clk.common,
1043 &usb_ohci1_clk.common,
1044 &usb_ohci2_clk.common,
1045 &bus_ohci0_clk.common,
1046 &bus_ohci1_clk.common,
1047 &bus_ohci2_clk.common,
1048 &bus_ehci0_clk.common,
1049 &bus_ehci1_clk.common,
1050 &bus_ehci2_clk.common,
1051 &bus_otg0_clk.common,
1052 &bus_lradc_clk.common,
1053 &adc_clk.common,
1054 &dtmb_120M_clk.common,
1055 &tvfe_1296M_clk.common,
1056 &i2h_clk.common,
1057 &cip_tsx_clk.common,
1058 &cip_mcx_clk.common,
1059 &cip_tsp_clk.common,
1060 &tsa_tsp_clk.common,
1061 &cip27_clk.common,
1062 &cip_mts0_clk.common,
1063 &audio_cpu_clk.common,
1064 &audio_umac_clk.common,
1065 &audio_ihb_clk.common,
1066 &tsa432_clk.common,
1067 &mpg0_clk.common,
1068 &mpg1_clk.common,
1069 &bus_demod_clk.common,
1070 &tcd3_clk.common,
1071 &vincap_dma_clk.common,
1072 &bus_hdmi_audio_clk.common,
1073 &bus_cap_300M_clk.common,
1074 &hdmi_audio_clk.common,
1075 &bus_tvcap_clk.common,
1076 &deint_clk.common,
1077 &svp_dtl_clk.common,
1078 &afbd_clk.common,
1079 &bus_disp_clk.common,
1080 };
1081
1082 static struct clk_hw_onecell_data sun50iw12_hw_clks = {
1083 .hws = {
1084 [CLK_OSC12M] = &osc12M_clk.hw,
1085 [CLK_PLL_CPUX] = &pll_cpux_clk.common.hw,
1086 [CLK_PLL_DDR0] = &pll_ddr_clk.common.hw,
1087 [CLK_PLL_PERIPH0] = &pll_periph0_clk.common.hw,
1088 [CLK_PLL_PERIPH0_2X] = &pll_periph0_2x_clk.hw,
1089 [CLK_PLL_PERIPH1] = &pll_periph1_clk.common.hw,
1090 [CLK_PLL_PERIPH1_2X] = &pll_periph1_2x_clk.hw,
1091 [CLK_PLL_GPU] = &pll_gpu_clk.common.hw,
1092 [CLK_PLL_VIDEO0] = &pll_video0_clk.common.hw,
1093 [CLK_PLL_VIDEO0_4X] = &pll_video0_4x_clk.hw,
1094 [CLK_PLL_VIDEO1] = &pll_video1_clk.common.hw,
1095 [CLK_PLL_VIDEO1_4X] = &pll_video1_4x_clk.hw,
1096 [CLK_PLL_VIDEO2] = &pll_video2_clk.common.hw,
1097 [CLK_PLL_VIDEO2_4X] = &pll_video2_4x_clk.hw,
1098 [CLK_PLL_VE] = &pll_ve_clk.common.hw,
1099 [CLK_PLL_ADC] = &pll_adc_clk.common.hw,
1100 [CLK_PLL_VIDEO3] = &pll_video3_clk.common.hw,
1101 [CLK_PLL_VIDEO3_4X] = &pll_video3_4x_clk.hw,
1102 [CLK_PLL_AUDIO] = &pll_audio_clk.common.hw,
1103 [CLK_CPUX] = &cpux_clk.common.hw,
1104 [CLK_AXI] = &axi_clk.common.hw,
1105 [CLK_CPUX_APB] = &cpux_apb_clk.common.hw,
1106 [CLK_AHB] = &ahb_clk.common.hw,
1107 [CLK_APB0] = &apb0_clk.common.hw,
1108 [CLK_APB1] = &apb1_clk.common.hw,
1109 [CLK_MBUS] = &mbus_clk.common.hw,
1110 [CLK_MIPS] = &mips_clk.common.hw,
1111 [CLK_BUS_MIPS] = &bus_mips_clk.common.hw,
1112 [CLK_GPU] = &gpu_clk.common.hw,
1113 [CLK_BUS_GPU] = &bus_gpu_clk.common.hw,
1114 [CLK_CE] = &ce_clk.common.hw,
1115 [CLK_BUS_CE] = &bus_ce_clk.common.hw,
1116 [CLK_VE_CORE] = &ve_core_clk.common.hw,
1117 [CLK_BUS_VE] = &bus_ve_clk.common.hw,
1118 [CLK_BUS_AV1] = &bus_av1_clk.common.hw,
1119 [CLK_BUS_VE3] = &bus_ve3_clk.common.hw,
1120 [CLK_BUS_DMA] = &bus_dma_clk.common.hw,
1121 [CLK_MSGBOX] = &bus_msgbox_clk.common.hw,
1122 [CLK_SPINLOCK] = &bus_spinlock_clk.common.hw,
1123 [CLK_TIMER0] = &timer0_clk.common.hw,
1124 [CLK_TIMER1] = &timer1_clk.common.hw,
1125 [CLK_TIMER2] = &timer2_clk.common.hw,
1126 [CLK_TIMER3] = &timer3_clk.common.hw,
1127 [CLK_TIMER4] = &timer4_clk.common.hw,
1128 [CLK_TIMER5] = &timer5_clk.common.hw,
1129 [CLK_BUS_TIMER0] = &bus_timer0_clk.common.hw,
1130 [CLK_BUS_DBG] = &bus_dbg_clk.common.hw,
1131 [CLK_BUS_PWM] = &bus_pwm_clk.common.hw,
1132 [CLK_BUS_IOMMU] = &bus_iommu_clk.common.hw,
1133 [CLK_DRAM] = &dram_clk.common.hw,
1134 [CLK_MBUS_DMA] = &mbus_dma_clk.common.hw,
1135 [CLK_MBUS_VE3] = &mbus_ve3_clk.common.hw,
1136 [CLK_MBUS_CE] = &mbus_ce_clk.common.hw,
1137 [CLK_MBUS_AV1] = &mbus_av1_clk.common.hw,
1138 [CLK_MBUS_NAND] = &mbus_nand_clk.common.hw,
1139 [CLK_BUS_DRAM] = &bus_dram_clk.common.hw,
1140 [CLK_NAND0] = &nand0_clk.common.hw,
1141 [CLK_NAND1] = &nand1_clk.common.hw,
1142 [CLK_BUS_NAND] = &bus_nand_clk.common.hw,
1143 [CLK_MMC0] = &mmc0_clk.common.hw,
1144 [CLK_MMC1] = &mmc1_clk.common.hw,
1145 [CLK_MMC2] = &mmc2_clk.common.hw,
1146 [CLK_BUS_MMC0] = &bus_mmc0_clk.common.hw,
1147 [CLK_BUS_MMC1] = &bus_mmc1_clk.common.hw,
1148 [CLK_BUS_MMC2] = &bus_mmc2_clk.common.hw,
1149 [CLK_BUS_UART0] = &bus_uart0_clk.common.hw,
1150 [CLK_BUS_UART1] = &bus_uart1_clk.common.hw,
1151 [CLK_BUS_UART2] = &bus_uart2_clk.common.hw,
1152 [CLK_BUS_UART3] = &bus_uart3_clk.common.hw,
1153 [CLK_BUS_I2C0] = &bus_i2c0_clk.common.hw,
1154 [CLK_BUS_I2C1] = &bus_i2c1_clk.common.hw,
1155 [CLK_BUS_I2C2] = &bus_i2c2_clk.common.hw,
1156 [CLK_BUS_I2C3] = &bus_i2c3_clk.common.hw,
1157 [CLK_SPI0] = &spi0_clk.common.hw,
1158 [CLK_SPI1] = &spi1_clk.common.hw,
1159 [CLK_BUS_SPI0] = &bus_spi0_clk.common.hw,
1160 [CLK_BUS_SPI1] = &bus_spi1_clk.common.hw,
1161 [CLK_EMAC_25M] = &emac_25M_clk.common.hw,
1162 [CLK_BUS_EMAC] = &bus_emac_clk.common.hw,
1163 [CLK_BUS_GPADC] = &bus_gpadc_clk.common.hw,
1164 [CLK_BUS_THS] = &bus_ths_clk.common.hw,
1165 [CLK_I2S0] = &i2s0_clk.common.hw,
1166 [CLK_I2S1] = &i2s1_clk.common.hw,
1167 [CLK_I2S2] = &i2s2_clk.common.hw,
1168 [CLK_BUS_I2S0] = &bus_i2s0_clk.common.hw,
1169 [CLK_BUS_I2S1] = &bus_i2s1_clk.common.hw,
1170 [CLK_BUS_I2S2] = &bus_i2s2_clk.common.hw,
1171 [CLK_SPDIF0_RX] = &spdif0_rx_clk.common.hw,
1172 [CLK_SPDIF0_TX] = &spdif0_tx_clk.common.hw,
1173 [CLK_SPDIF1_RX] = &spdif1_rx_clk.common.hw,
1174 [CLK_SPDIF1_TX] = &spdif1_tx_clk.common.hw,
1175 [CLK_BUS_SPDIF0] = &bus_spdif0_clk.common.hw,
1176 [CLK_BUS_SPDIF1] = &bus_spdif1_clk.common.hw,
1177 [CLK_AUDIO_HUB] = &audio_hub_clk.common.hw,
1178 [CLK_AUDIO_CODEC_DAC] = &audio_codec_dac_clk.common.hw,
1179 [CLK_AUDIO_CODEC_ADC] = &audio_codec_adc_clk.common.hw,
1180 [CLK_BUS_AUDIO_CODEC] = &bus_audio_codec_clk.common.hw,
1181 [CLK_USB_OHCI0] = &usb_ohci0_clk.common.hw,
1182 [CLK_USB_OHCI1] = &usb_ohci1_clk.common.hw,
1183 [CLK_USB_OHCI2] = &usb_ohci2_clk.common.hw,
1184 [CLK_BUS_OHCI0] = &bus_ohci0_clk.common.hw,
1185 [CLK_BUS_OHCI1] = &bus_ohci1_clk.common.hw,
1186 [CLK_BUS_OHCI2] = &bus_ohci2_clk.common.hw,
1187 [CLK_BUS_EHCI0] = &bus_ehci0_clk.common.hw,
1188 [CLK_BUS_EHCI1] = &bus_ehci1_clk.common.hw,
1189 [CLK_BUS_EHCI2] = &bus_ehci2_clk.common.hw,
1190 [CLK_BUS_OTG] = &bus_otg0_clk.common.hw,
1191 [CLK_BUS_LRADC] = &bus_lradc_clk.common.hw,
1192 [CLK_ADC] = &adc_clk.common.hw,
1193 [CLK_DTMB_120M] = &dtmb_120M_clk.common.hw,
1194 [CLK_TVFE_1296M] = &tvfe_1296M_clk.common.hw,
1195 [CLK_I2H] = &i2h_clk.common.hw,
1196 [CLK_CIP_TSX] = &cip_tsx_clk.common.hw,
1197 [CLK_CIP_MCX] = &cip_mcx_clk.common.hw,
1198 [CLK_CIP_TSP] = &cip_tsp_clk.common.hw,
1199 [CLK_TSA_TSP] = &tsa_tsp_clk.common.hw,
1200 [CLK_CIP27] = &cip27_clk.common.hw,
1201 [CLK_CIP_MTS0] = &cip_mts0_clk.common.hw,
1202 [CLK_AUDIO_CPU] = &audio_cpu_clk.common.hw,
1203 [CLK_AUDIO_UMAC] = &audio_umac_clk.common.hw,
1204 [CLK_AUDIO_IHB] = &audio_ihb_clk.common.hw,
1205 [CLK_TSA432] = &tsa432_clk.common.hw,
1206 [CLK_MPG0] = &mpg0_clk.common.hw,
1207 [CLK_MPG1] = &mpg1_clk.common.hw,
1208 [CLK_BUS_DEMOD] = &bus_demod_clk.common.hw,
1209 [CLK_TCD3] = &tcd3_clk.common.hw,
1210 [CLK_VINCAP_DMA] = &vincap_dma_clk.common.hw,
1211 [CLK_BUS_HDMI_AUDIO] = &bus_hdmi_audio_clk.common.hw,
1212 [CLK_BUS_CAP_300M] = &bus_cap_300M_clk.common.hw,
1213 [CLK_HDMI_AUDIO] = &hdmi_audio_clk.common.hw,
1214 [CLK_BUS_TVCAP] = &bus_tvcap_clk.common.hw,
1215 [CLK_DEINT] = &deint_clk.common.hw,
1216 [CLK_SVP_DTL] = &svp_dtl_clk.common.hw,
1217 [CLK_AFBD] = &afbd_clk.common.hw,
1218 [CLK_BUS_DISP] = &bus_disp_clk.common.hw,
1219 },
1220 .num = CLK_NUMBER,
1221 };
1222
1223 static struct ccu_reset_map sun50iw12_ccu_resets[] = {
1224 [RST_MBUS] = { 0x540, BIT(30) },
1225 [RST_BUS_MIPS] = { 0x60c, BIT(16) },
1226 [RST_BUS_MIPS_COLD] = { 0x60c, BIT(17) },
1227 [RST_BUS_MIPS_SOFT] = { 0x60c, BIT(18) },
1228 [RST_BUS_GPU] = { 0x67c, BIT(16) },
1229 [RST_BUS_CE] = { 0x68c, BIT(16) },
1230 [RST_BUS_CE_SYS] = { 0x68c, BIT(17) },
1231 [RST_BUS_VE] = { 0x69c, BIT(16) },
1232 [RST_BUS_AV1] = { 0x69c, BIT(17) },
1233 [RST_BUS_VE3] = { 0x69c, BIT(18) },
1234 [RST_BUS_DMA] = { 0x70c, BIT(16) },
1235 [RST_BUS_MSGBOX] = { 0x71c, BIT(16) },
1236 [RST_BUS_SPINLOCK] = { 0x72c, BIT(16) },
1237 [RST_BUS_TIMER0] = { 0x750, BIT(16) },
1238 [RST_BUS_DBGSYS] = { 0x78c, BIT(16) },
1239 [RST_BUS_PWM] = { 0x7ac, BIT(16) },
1240 [RST_BUS_DRAM_MODULE] = { 0x800, BIT(30) },
1241 [RST_BUS_DRAM] = { 0x80c, BIT(16) },
1242 [RST_BUS_NAND] = { 0x82c, BIT(16) },
1243 [RST_BUS_MMC0] = { 0x84c, BIT(16) },
1244 [RST_BUS_MMC1] = { 0x84c, BIT(17) },
1245 [RST_BUS_MMC2] = { 0x84c, BIT(18) },
1246 [RST_BUS_UART0] = { 0x90c, BIT(16) },
1247 [RST_BUS_UART1] = { 0x90c, BIT(17) },
1248 [RST_BUS_UART2] = { 0x90c, BIT(18) },
1249 [RST_BUS_UART3] = { 0x90c, BIT(19) },
1250 [RST_BUS_UART4] = { 0x90c, BIT(20) },
1251 [RST_BUS_I2C0] = { 0x91c, BIT(16) },
1252 [RST_BUS_I2C1] = { 0x91c, BIT(17) },
1253 [RST_BUS_I2C2] = { 0x91c, BIT(18) },
1254 [RST_BUS_I2C3] = { 0x91c, BIT(19) },
1255 [RST_BUS_SPI0] = { 0x96c, BIT(16) },
1256 [RST_BUS_SPI1] = { 0x96c, BIT(17) },
1257 [RST_BUS_EMAC] = { 0x97c, BIT(16) },
1258 [RST_BUS_GPADC] = { 0x9ec, BIT(16) },
1259 [RST_BUS_THS] = { 0x9fc, BIT(16) },
1260 [RST_BUS_I2S0] = { 0xa20, BIT(16) },
1261 [RST_BUS_I2S1] = { 0xa20, BIT(17) },
1262 [RST_BUS_I2S2] = { 0xa20, BIT(18) },
1263 [RST_BUS_SPDIF0] = { 0xa2c, BIT(16) },
1264 [RST_BUS_SPDIF1] = { 0xa2c, BIT(17) },
1265 [RST_BUS_AUDIO_HUB] = { 0xa5c, BIT(16) },
1266 [RST_BUS_AUDIO_CODEC] = { 0xa6c, BIT(16) },
1267 [RST_USB_PHY0] = { 0xa70, BIT(30) },
1268 [RST_USB_PHY1] = { 0xa78, BIT(30) },
1269 [RST_USB_PHY2] = { 0xa80, BIT(30) },
1270 [RST_BUS_OHCI0] = { 0xa8c, BIT(16) },
1271 [RST_BUS_OHCI1] = { 0xa8c, BIT(17) },
1272 [RST_BUS_OHCI2] = { 0xa8c, BIT(18) },
1273 [RST_BUS_EHCI0] = { 0xa8c, BIT(20) },
1274 [RST_BUS_EHCI1] = { 0xa8c, BIT(21) },
1275 [RST_BUS_EHCI2] = { 0xa8c, BIT(22) },
1276 [RST_BUS_OTG] = { 0xa8c, BIT(24) },
1277 [RST_BUS_LRADC] = { 0xa9c, BIT(16) },
1278 [RST_BUS_LVDS] = { 0xbac, BIT(16) },
1279 [RST_BUS_DEMOD] = { 0xd64, BIT(16) },
1280 [RST_BUS_TVCAP] = { 0xd88, BIT(16) },
1281 [RST_BUS_DISP] = { 0xdd8, BIT(16) },
1282 };
1283
1284 static const struct sunxi_ccu_desc sun50iw12_ccu_desc = {
1285 .ccu_clks = sun50iw12_ccu_clks,
1286 .num_ccu_clks = ARRAY_SIZE(sun50iw12_ccu_clks),
1287
1288 .hw_clks = &sun50iw12_hw_clks,
1289
1290 .resets = sun50iw12_ccu_resets,
1291 .num_resets = ARRAY_SIZE(sun50iw12_ccu_resets),
1292 };
1293
1294 static const u32 pll_regs[] = {
1295 SUN50IW12_PLL_CPUX_REG,
1296 SUN50IW12_PLL_DDR_REG,
1297 SUN50IW12_PLL_PERIPH0_REG,
1298 SUN50IW12_PLL_PERIPH1_REG,
1299 SUN50IW12_PLL_GPU_REG,
1300 SUN50IW12_PLL_VIDEO0_REG,
1301 SUN50IW12_PLL_VIDEO1_REG,
1302 SUN50IW12_PLL_VIDEO2_REG,
1303 SUN50IW12_PLL_VE_REG,
1304 SUN50IW12_PLL_ADC_REG,
1305 SUN50IW12_PLL_VIDEO3_REG,
1306 SUN50IW12_PLL_AUDIO_REG,
1307 };
1308
of_sun50iw12_ccu_init(struct device_node * node)1309 static void __init of_sun50iw12_ccu_init(struct device_node *node)
1310 {
1311 void __iomem *reg;
1312 int i;
1313 u32 val;
1314
1315 reg = of_iomap(node, 0);
1316 if (IS_ERR(reg))
1317 return;
1318
1319 /* Enable the lock bits on all PLLs */
1320 for (i = 0; i < ARRAY_SIZE(pll_regs); i++) {
1321 val = readl(reg + pll_regs[i]);
1322 val |= BIT(29);
1323 writel(val, reg + pll_regs[i]);
1324 }
1325
1326 sunxi_ccu_probe(node, reg, &sun50iw12_ccu_desc);
1327 }
1328
1329 CLK_OF_DECLARE(sun50iw12_ccu_init, "allwinner,sun50iw12-ccu", of_sun50iw12_ccu_init);
1330