• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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