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/module.h>
9 #include <linux/of_address.h>
10 #include <linux/platform_device.h>
11
12 #include "ccu_common.h"
13 #include "ccu_reset.h"
14
15 #include "ccu_div.h"
16 #include "ccu_gate.h"
17 #include "ccu_mp.h"
18 #include "ccu_mult.h"
19 #include "ccu_nk.h"
20 #include "ccu_nkm.h"
21 #include "ccu_nkmp.h"
22 #include "ccu_nm.h"
23
24 #include "ccu-sun50iw10.h"
25
26 /*
27 * The CPU PLL is actually NP clock, with P being /1, /2 or /4. However
28 * P should only be used for output frequencies lower than 288 MHz.
29 *
30 * For now we can just model it as a multiplier clock, and force P to /1.
31 *
32 * The M factor is present in the register's description, but not in the
33 * frequency formula, and it's documented as "M is only used for backdoor
34 * testing", so it's not modelled and then force to 0.
35 */
36 #define SUN50IW10_PLL_CPUX_REG 0x000
37 static struct ccu_mult pll_cpux_clk = {
38 .enable = BIT(27),
39 .lock = BIT(28),
40 .mult = _SUNXI_CCU_MULT_MIN(8, 8, 12),
41 .common = {
42 .reg = 0x000,
43 .hw.init = CLK_HW_INIT("pll-cpux", "dcxo24M",
44 &ccu_mult_ops,
45 CLK_SET_RATE_UNGATE),
46 },
47 };
48
49 /* Some PLLs are input * N / div1 / P. Model them as NKMP with no K */
50 #define SUN50IW10_PLL_DDR0_REG 0x010
51 static struct ccu_nkmp pll_ddr0_clk = {
52 .enable = BIT(27),
53 .lock = BIT(28),
54 .n = _SUNXI_CCU_MULT_MIN(8, 8, 12),
55 .m = _SUNXI_CCU_DIV(1, 1), /* input divider */
56 .p = _SUNXI_CCU_DIV(0, 1), /* output divider */
57 .common = {
58 .reg = 0x010,
59 .hw.init = CLK_HW_INIT("pll-ddr0", "dcxo24M",
60 &ccu_nkmp_ops,
61 CLK_SET_RATE_UNGATE |
62 CLK_IS_CRITICAL),
63 },
64 };
65
66 #define SUN50IW10_PLL_PERIPH0_REG 0x020
67 static struct ccu_nkmp pll_periph0_clk = {
68 .enable = BIT(27),
69 .lock = BIT(28),
70 .n = _SUNXI_CCU_MULT_MIN(8, 8, 12),
71 .m = _SUNXI_CCU_DIV(1, 1), /* input divider */
72 .p = _SUNXI_CCU_DIV(0, 1), /* output divider */
73 .fixed_post_div = 2,
74 .common = {
75 .reg = 0x020,
76 .features = CCU_FEATURE_FIXED_POSTDIV,
77 .hw.init = CLK_HW_INIT("pll-periph0", "dcxo24M",
78 &ccu_nkmp_ops,
79 CLK_SET_RATE_UNGATE),
80 },
81 };
82
83 #define SUN50IW10_PLL_PERIPH1_REG 0x028
84 static struct ccu_nkmp pll_periph1_clk = {
85 .enable = BIT(27),
86 .lock = BIT(28),
87 .n = _SUNXI_CCU_MULT_MIN(8, 8, 12),
88 .m = _SUNXI_CCU_DIV(1, 1), /* input divider */
89 .p = _SUNXI_CCU_DIV(0, 1), /* output divider */
90 .fixed_post_div = 2,
91 .common = {
92 .reg = 0x028,
93 .features = CCU_FEATURE_FIXED_POSTDIV,
94 .hw.init = CLK_HW_INIT("pll-periph1", "dcxo24M",
95 &ccu_nkmp_ops,
96 CLK_SET_RATE_UNGATE),
97 },
98 };
99
100 #define SUN50IW10_PLL_GPU_REG 0x030
101 static struct ccu_nkmp pll_gpu_clk = {
102 .enable = BIT(27),
103 .lock = BIT(28),
104 .n = _SUNXI_CCU_MULT_MIN(8, 8, 12),
105 .m = _SUNXI_CCU_DIV(1, 1), /* input divider */
106 .p = _SUNXI_CCU_DIV(0, 1), /* output divider */
107 .common = {
108 .reg = 0x030,
109 .hw.init = CLK_HW_INIT("pll-gpu", "dcxo24M",
110 &ccu_nkmp_ops,
111 CLK_SET_RATE_UNGATE),
112 },
113 };
114
115 /*
116 * For Video PLLs, the output divider is described as "used for testing"
117 * in the user manual. So it's not modelled and forced to 0.
118 */
119 #define SUN50IW10_PLL_VIDEO0_REG 0x040
120 static struct ccu_nm pll_video0_clk = {
121 .enable = BIT(27),
122 .lock = BIT(28),
123 .n = _SUNXI_CCU_MULT_MIN(8, 8, 12),
124 .m = _SUNXI_CCU_DIV(1, 1), /* input divider */
125 .fixed_post_div = 4,
126 .min_rate = 288000000,
127 .max_rate = 2400000000UL,
128 .common = {
129 .reg = 0x040,
130 .features = CCU_FEATURE_FIXED_POSTDIV,
131 .hw.init = CLK_HW_INIT("pll-video0", "dcxo24M",
132 &ccu_nm_ops,
133 CLK_SET_RATE_UNGATE),
134 },
135 };
136
137 #define SUN50IW10_PLL_VIDEO1_REG 0x048
138 static struct ccu_nm pll_video1_clk = {
139 .enable = BIT(27),
140 .lock = BIT(28),
141 .n = _SUNXI_CCU_MULT_MIN(8, 8, 12),
142 .m = _SUNXI_CCU_DIV(1, 1), /* input divider */
143 .fixed_post_div = 4,
144 .min_rate = 288000000,
145 .max_rate = 2400000000UL,
146 .common = {
147 .reg = 0x048,
148 .features = CCU_FEATURE_FIXED_POSTDIV,
149 .hw.init = CLK_HW_INIT("pll-video1", "dcxo24M",
150 &ccu_nm_ops,
151 CLK_SET_RATE_UNGATE),
152 },
153 };
154
155 #define SUN50IW10_PLL_VIDEO2_REG 0x050
156 static struct ccu_nm pll_video2_clk = {
157 .enable = BIT(27),
158 .lock = BIT(28),
159 .n = _SUNXI_CCU_MULT_MIN(8, 8, 12),
160 .m = _SUNXI_CCU_DIV(1, 1), /* input divider */
161 .fixed_post_div = 4,
162 .min_rate = 288000000,
163 .max_rate = 2400000000UL,
164 .common = {
165 .reg = 0x050,
166 .features = CCU_FEATURE_FIXED_POSTDIV,
167 .hw.init = CLK_HW_INIT("pll-video2", "dcxo24M",
168 &ccu_nm_ops,
169 CLK_SET_RATE_UNGATE),
170 },
171 };
172
173 #define SUN50IW10_PLL_VE_REG 0x058
174 static struct ccu_nkmp pll_ve_clk = {
175 .enable = BIT(27),
176 .lock = BIT(28),
177 .n = _SUNXI_CCU_MULT_MIN(8, 8, 12),
178 .m = _SUNXI_CCU_DIV(1, 1), /* input divider */
179 .p = _SUNXI_CCU_DIV(0, 1), /* output divider */
180 .common = {
181 .reg = 0x058,
182 .hw.init = CLK_HW_INIT("pll-ve", "dcxo24M",
183 &ccu_nkmp_ops,
184 CLK_SET_RATE_UNGATE),
185 },
186 };
187
188 /*
189 * The COM PLL has m0 dividers in addition to the usual N, M
190 * factors. Since we only need 1 frequencies from this PLL: 45.1584 MHz,
191 * ignore it for now.
192 */
193 #define SUN50IW10_PLL_COM_REG 0x060
194 static struct ccu_sdm_setting pll_com_sdm_table[] = {
195 { .rate = 451584000, .pattern = 0xc0014396, .m = 2, .n = 37 },
196 };
197
198 static struct ccu_nm pll_com_clk = {
199 .enable = BIT(27),
200 .lock = BIT(28),
201 .n = _SUNXI_CCU_MULT_MIN(8, 8, 12),
202 .m = _SUNXI_CCU_DIV(0, 1),
203 .sdm = _SUNXI_CCU_SDM(pll_com_sdm_table, BIT(24),
204 0x160, BIT(31)),
205 .common = {
206 .reg = 0x060,
207 .features = CCU_FEATURE_SIGMA_DELTA_MOD,
208 .hw.init = CLK_HW_INIT("pll-com", "dcxo24M",
209 &ccu_nm_ops,
210 CLK_SET_RATE_UNGATE),
211 },
212 };
213
214 #define SUN50IW10_PLL_VIDEO3_REG 0x068
215 static struct ccu_nm pll_video3_clk = {
216 .enable = BIT(27),
217 .lock = BIT(28),
218 .n = _SUNXI_CCU_MULT_MIN(8, 8, 12),
219 .m = _SUNXI_CCU_DIV(1, 1), /* input divider */
220 .fixed_post_div = 4,
221 .min_rate = 288000000,
222 .max_rate = 2400000000UL,
223 .common = {
224 .reg = 0x068,
225 .features = CCU_FEATURE_FIXED_POSTDIV,
226 .hw.init = CLK_HW_INIT("pll-video3", "dcxo24M",
227 &ccu_nm_ops,
228 CLK_SET_RATE_UNGATE),
229 },
230 };
231
232 /* for pm resume */
233 #define SUN50IW10_PLL_PERIPH1_PATTERN0_REG 0x128
234 struct ccu_common pll_periph1_pattern0_common = {
235 .reg = 0x128,
236 };
237
238 /*
239 * The Audio PLL has m0, m1 dividers in addition to the usual N, M
240 * factors. Since we only need 4 frequencies from this PLL: 22.5792 MHz,
241 * 24.576 MHz, 90.3168MHz and 98.304MHz ignore them for now.
242 * Enforce the default for them, which is m0 = 1, m1 = 0.
243 */
244 #define SUN50IW10_PLL_AUDIO_REG 0x078
245 static struct ccu_sdm_setting pll_audio_sdm_table[] = {
246 { .rate = 45158400, .pattern = 0xc001bcd3, .m = 18, .n = 33 },
247 { .rate = 49152000, .pattern = 0xc001eb85, .m = 20, .n = 40 },
248 { .rate = 180633600, .pattern = 0xc001288d, .m = 3, .n = 22 },
249 { .rate = 196608000, .pattern = 0xc001eb85, .m = 5, .n = 40 },
250 };
251
252 static struct ccu_nm pll_audio_clk = {
253 .enable = BIT(27),
254 .lock = BIT(28),
255 .n = _SUNXI_CCU_MULT_MIN(8, 8, 12),
256 .m = _SUNXI_CCU_DIV(16, 6),
257 .fixed_post_div = 2,
258 .sdm = _SUNXI_CCU_SDM(pll_audio_sdm_table, BIT(24),
259 0x178, BIT(31)),
260 .common = {
261 .reg = 0x078,
262 .features = CCU_FEATURE_FIXED_POSTDIV |
263 CCU_FEATURE_SIGMA_DELTA_MOD,
264 .hw.init = CLK_HW_INIT("pll-audio", "dcxo24M",
265 &ccu_nm_ops,
266 CLK_SET_RATE_UNGATE),
267 },
268 };
269
270 static const char * const cpux_parents[] = { "dcxo24M", "osc32k",
271 "iosc", "pll-cpux",
272 "pll-periph0" };
273 static SUNXI_CCU_MUX(cpux_clk, "cpux", cpux_parents,
274 0x500, 24, 3, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL);
275 static SUNXI_CCU_M(axi_clk, "axi", "cpux", 0x500, 0, 2, 0);
276 static SUNXI_CCU_M(cpux_apb_clk, "cpux-apb", "cpux", 0x500, 8, 2, 0);
277
278 static const char * const psi_ahb1_ahb2_parents[] = { "dcxo24M", "osc32k",
279 "iosc", "pll-periph0",
280 "pll-periph0-2x" };
281 static SUNXI_CCU_MP_WITH_MUX(psi_ahb1_ahb2_clk, "psi-ahb1-ahb2",
282 psi_ahb1_ahb2_parents,
283 0x510,
284 0, 2, /* M */
285 8, 2, /* P */
286 24, 3, /* mux */
287 0);
288
289 static const char * const ahb3_apb1_apb2_parents[] = { "dcxo24M", "osc32k",
290 "psi-ahb1-ahb2",
291 "pll-periph0",
292 "pll-periph0-2x" };
293 static SUNXI_CCU_MP_WITH_MUX(ahb3_clk, "ahb3", ahb3_apb1_apb2_parents, 0x51c,
294 0, 2, /* M */
295 8, 2, /* P */
296 24, 3, /* mux */
297 0);
298
299 static SUNXI_CCU_MP_WITH_MUX(apb1_clk, "apb1", ahb3_apb1_apb2_parents, 0x520,
300 0, 2, /* M */
301 8, 2, /* P */
302 24, 3, /* mux */
303 0);
304
305 static SUNXI_CCU_MP_WITH_MUX(apb2_clk, "apb2", ahb3_apb1_apb2_parents, 0x524,
306 0, 2, /* M */
307 8, 2, /* P */
308 24, 3, /* mux */
309 0);
310
311 static const char * const mbus_parents[] = { "dcxo24M", "pll-ddr0",
312 "pll-periph0",
313 "pll-periph0-2x" };
314 static SUNXI_CCU_M_WITH_MUX_GATE(mbus_clk, "mbus", mbus_parents, 0x540,
315 0, 3, /* M */
316 24, 2, /* mux */
317 BIT(31), /* gate */
318 CLK_IS_CRITICAL);
319
320 static const char * const de_parents[] = { "pll-com", "pll-periph0-2x" };
321 static SUNXI_CCU_M_WITH_MUX_GATE(de0_clk, "de0", de_parents, 0x600,
322 0, 4, /* M */
323 24, 1, /* mux */
324 BIT(31), /* gate */
325 CLK_SET_RATE_NO_REPARENT);
326
327 static SUNXI_CCU_M_WITH_MUX_GATE(de1_clk, "de1", de_parents, 0x604,
328 0, 4, /* M */
329 24, 1, /* mux */
330 BIT(31), /* gate */
331 CLK_SET_RATE_NO_REPARENT);
332
333 static SUNXI_CCU_GATE(bus_de0_clk, "bus-de0", "psi-ahb1-ahb2",
334 0x60c, BIT(0), 0);
335 static SUNXI_CCU_GATE(bus_de1_clk, "bus-de1", "psi-ahb1-ahb2",
336 0x60c, BIT(1), 0);
337
338 static const char * const eink_parents[] = { "pll-com", "pll-periph0-2x",
339 "pll-video0", "pll-video1",
340 "pll-video2"};
341 static SUNXI_CCU_M_WITH_MUX_GATE(eink_clk, "eink",
342 eink_parents,
343 0x610,
344 0, 4, /* M */
345 24, 3, /* mux */
346 BIT(31), /* gate */
347 0);
348
349 static SUNXI_CCU_GATE(bus_eink_clk, "bus-eink", "psi-ahb1-ahb2",
350 0x61c, BIT(0), 0);
351
352 static const char * const g2d_parents[] = { "pll-com", "pll-periph0-2x",
353 "pll-video0-2x", "pll-video1-2x",
354 "pll-video2-2x"};
355 static SUNXI_CCU_M_WITH_MUX_GATE(g2d_clk, "g2d",
356 g2d_parents,
357 0x630,
358 0, 4, /* M */
359 24, 3, /* mux */
360 BIT(31), /* gate */
361 0);
362
363 static SUNXI_CCU_GATE(bus_g2d_clk, "bus-g2d", "psi-ahb1-ahb2",
364 0x63c, BIT(0), 0);
365
366 static const char * const eink_panel_parents[] = { "pll-video0",
367 "pll-video1",
368 "pll-video2",
369 "pll-video3" };
370 static SUNXI_CCU_M_WITH_MUX_GATE(eink_panel_clk, "eink-panel",
371 eink_panel_parents,
372 0x640,
373 0, 5, /* M */
374 24, 2, /* mux */
375 BIT(31), /* gate */
376 0);
377
378 static const char * const gpu_parents[] = { "pll-gpu" };
379 static SUNXI_CCU_M_WITH_MUX_GATE(gpu_clk, "gpu", gpu_parents, 0x670,
380 0, 2, /* M */
381 24, 1, /* mux */
382 BIT(31), /* gate */
383 0);
384
385 static SUNXI_CCU_GATE(bus_gpu_clk, "bus-gpu", "psi-ahb1-ahb2",
386 0x67c, BIT(0), 0);
387
388 static const char * const ce_parents[] = { "dcxo24M", "pll-periph0-2x" };
389 static SUNXI_CCU_MP_WITH_MUX_GATE(ce_clk, "ce", ce_parents, 0x680,
390 0, 4, /* M */
391 8, 2, /* N */
392 24, 1, /* mux */
393 BIT(31), /* gate */
394 0);
395
396 static SUNXI_CCU_GATE(bus_ce_clk, "bus-ce", "psi-ahb1-ahb2",
397 0x68c, BIT(0), 0);
398
399 static const char * const ve_parents[] = { "pll-ve" };
400 static SUNXI_CCU_M_WITH_MUX_GATE(ve_clk, "ve", ve_parents, 0x690,
401 0, 3, /* M */
402 24, 1, /* mux */
403 BIT(31), /* gate */
404 CLK_SET_RATE_PARENT);
405
406 static SUNXI_CCU_GATE(bus_ve_clk, "bus-ve", "psi-ahb1-ahb2",
407 0x69c, BIT(0), 0);
408
409 static SUNXI_CCU_GATE(bus_dma_clk, "bus-dma", "psi-ahb1-ahb2",
410 0x70c, BIT(0), 0);
411
412 static SUNXI_CCU_GATE(bus_msgbox_clk, "bus-msgbox", "psi-ahb1-ahb2",
413 0x71c, BIT(0), 0);
414
415 static SUNXI_CCU_GATE(bus_spinlock_clk, "bus-spinlock", "psi-ahb1-ahb2",
416 0x72c, BIT(0), 0);
417
418 static SUNXI_CCU_GATE(bus_hstimer_clk, "bus-hstimer", "psi-ahb1-ahb2",
419 0x73c, BIT(0), 0);
420
421 static SUNXI_CCU_GATE(avs_clk, "avs", "dcxo24M", 0x740, BIT(31), 0);
422
423 static SUNXI_CCU_GATE(bus_dbg_clk, "bus-dbg", "psi-ahb1-ahb2",
424 0x78c, BIT(0), 0);
425
426 static SUNXI_CCU_GATE(bus_psi_clk, "bus-psi", "psi-ahb1-ahb2",
427 0x79c, BIT(0), 0);
428
429 static SUNXI_CCU_GATE(bus_pwm_clk, "bus-pwm", "apb1", 0x7ac, BIT(0), 0);
430
431 static SUNXI_CCU_GATE(bus_iommu_clk, "bus-iommu", "apb1", 0x7bc, BIT(0), 0);
432
433 static SUNXI_CCU_GATE(mbus_dma_clk, "mbus-dma", "mbus",
434 0x804, BIT(0), 0);
435 static SUNXI_CCU_GATE(mbus_ve_clk, "mbus-ve", "mbus",
436 0x804, BIT(1), 0);
437 static SUNXI_CCU_GATE(mbus_ce_clk, "mbus-ce", "mbus",
438 0x804, BIT(2), 0);
439 static SUNXI_CCU_GATE(mbus_nand_clk, "mbus-nand", "mbus",
440 0x804, BIT(5), 0);
441 static SUNXI_CCU_GATE(mbus_csi_clk, "mbus-csi", "mbus",
442 0x804, BIT(8), 0);
443 static SUNXI_CCU_GATE(mbus_isp_clk, "mbus-isp", "mbus",
444 0x804, BIT(9), 0);
445 static SUNXI_CCU_GATE(mbus_g2d_clk, "mbus-g2d", "mbus",
446 0x804, BIT(10), 0);
447
448 static SUNXI_CCU_GATE(bus_dram_clk, "bus-dram", "psi-ahb1-ahb2",
449 0x80c, BIT(0), CLK_IS_CRITICAL);
450
451 static const char * const nand_spi_parents[] = { "dcxo24M",
452 "pll-periph0",
453 "pll-periph1",
454 "pll-periph0-2x",
455 "pll-periph1-2x" };
456 static SUNXI_CCU_MP_WITH_MUX_GATE(nand0_clk, "nand0", nand_spi_parents, 0x810,
457 0, 4, /* M */
458 8, 2, /* N */
459 24, 3, /* mux */
460 BIT(31), /* gate */
461 0);
462
463 static SUNXI_CCU_MP_WITH_MUX_GATE(nand1_clk, "nand1", nand_spi_parents, 0x814,
464 0, 4, /* M */
465 8, 2, /* N */
466 24, 3, /* mux */
467 BIT(31), /* gate */
468 0);
469
470 static SUNXI_CCU_GATE(bus_nand_clk, "bus-nand", "ahb3", 0x82c, BIT(0), 0);
471
472 /* don't use postdiv for bsp kernel */
473 static const char * const mmc_parents[] = { "dcxo24M", "pll-periph0-2x",
474 "pll-periph1-2x" };
475 static SUNXI_CCU_MP_WITH_MUX_GATE(mmc0_clk, "mmc0", mmc_parents, 0x830,
476 0, 4, /* M */
477 8, 2, /* N */
478 24, 2, /* mux */
479 BIT(31), /* gate */
480 CLK_SET_RATE_NO_REPARENT);
481
482 static SUNXI_CCU_MP_WITH_MUX_GATE(mmc1_clk, "mmc1", mmc_parents, 0x834,
483 0, 4, /* M */
484 8, 2, /* N */
485 24, 2, /* mux */
486 BIT(31), /* gate */
487 CLK_SET_RATE_NO_REPARENT);
488
489 static SUNXI_CCU_MP_WITH_MUX_GATE(mmc2_clk, "mmc2", mmc_parents, 0x838,
490 0, 4, /* M */
491 8, 2, /* N */
492 24, 2, /* mux */
493 BIT(31), /* gate */
494 CLK_SET_RATE_NO_REPARENT);
495
496 static SUNXI_CCU_MP_WITH_MUX_GATE(mmc3_clk, "mmc3", mmc_parents, 0x83c,
497 0, 4, /* M */
498 8, 2, /* N */
499 24, 2, /* mux */
500 BIT(31), /* gate */
501 CLK_SET_RATE_NO_REPARENT);
502
503 static SUNXI_CCU_GATE(bus_mmc0_clk, "bus-mmc0", "ahb3", 0x84c, BIT(0), 0);
504 static SUNXI_CCU_GATE(bus_mmc1_clk, "bus-mmc1", "ahb3", 0x84c, BIT(1), 0);
505 static SUNXI_CCU_GATE(bus_mmc2_clk, "bus-mmc2", "ahb3", 0x84c, BIT(2), 0);
506 static SUNXI_CCU_GATE(bus_mmc3_clk, "bus-mmc3", "ahb3", 0x84c, BIT(3), 0);
507
508 static SUNXI_CCU_GATE(bus_uart0_clk, "bus-uart0", "apb2", 0x90c, BIT(0), 0);
509 static SUNXI_CCU_GATE(bus_uart1_clk, "bus-uart1", "apb2", 0x90c, BIT(1), 0);
510 static SUNXI_CCU_GATE(bus_uart2_clk, "bus-uart2", "apb2", 0x90c, BIT(2), 0);
511 static SUNXI_CCU_GATE(bus_uart3_clk, "bus-uart3", "apb2", 0x90c, BIT(3), 0);
512 static SUNXI_CCU_GATE(bus_uart4_clk, "bus-uart4", "apb2", 0x90c, BIT(4), 0);
513 static SUNXI_CCU_GATE(bus_uart5_clk, "bus-uart5", "apb2", 0x90c, BIT(5), 0);
514 static SUNXI_CCU_GATE(bus_uart6_clk, "bus-uart6", "apb2", 0x90c, BIT(6), 0);
515
516 static SUNXI_CCU_GATE(bus_i2c0_clk, "bus-i2c0", "apb2", 0x91c, BIT(0), 0);
517 static SUNXI_CCU_GATE(bus_i2c1_clk, "bus-i2c1", "apb2", 0x91c, BIT(1), 0);
518 static SUNXI_CCU_GATE(bus_i2c2_clk, "bus-i2c2", "apb2", 0x91c, BIT(2), 0);
519 static SUNXI_CCU_GATE(bus_i2c3_clk, "bus-i2c3", "apb2", 0x91c, BIT(3), 0);
520 static SUNXI_CCU_GATE(bus_i2c4_clk, "bus-i2c4", "apb2", 0x91c, BIT(4), 0);
521 static SUNXI_CCU_GATE(bus_i2c5_clk, "bus-i2c5", "apb2", 0x91c, BIT(5), 0);
522
523 static SUNXI_CCU_MP_WITH_MUX_GATE(spi0_clk, "spi0", nand_spi_parents, 0x940,
524 0, 4, /* M */
525 8, 2, /* N */
526 24, 3, /* mux */
527 BIT(31), /* gate */
528 0);
529
530 static SUNXI_CCU_MP_WITH_MUX_GATE(spi1_clk, "spi1", nand_spi_parents, 0x944,
531 0, 4, /* M */
532 8, 2, /* N */
533 24, 3, /* mux */
534 BIT(31), /* gate */
535 0);
536
537 static SUNXI_CCU_MP_WITH_MUX_GATE(spi2_clk, "spi2", nand_spi_parents, 0x948,
538 0, 4, /* M */
539 8, 2, /* N */
540 24, 3, /* mux */
541 BIT(31), /* gate */
542 0);
543
544 static SUNXI_CCU_GATE(bus_spi0_clk, "bus-spi0", "ahb3", 0x96c, BIT(0), 0);
545 static SUNXI_CCU_GATE(bus_spi1_clk, "bus-spi1", "ahb3", 0x96c, BIT(1), 0);
546 static SUNXI_CCU_GATE(bus_spi2_clk, "bus-spi2", "ahb3", 0x96c, BIT(2), 0);
547
548 static SUNXI_CCU_GATE(emac0_25m_clk, "emac0-25m", "ahb3", 0x970,
549 BIT(31) | BIT(30), 0);
550
551 static SUNXI_CCU_GATE(emac1_25m_clk, "emac1-25m", "ahb3", 0x974,
552 BIT(31) | BIT(30), 0);
553
554 static SUNXI_CCU_GATE(bus_emac0_clk, "bus-emac0", "ahb3", 0x97c, BIT(0), 0);
555 static SUNXI_CCU_GATE(bus_emac1_clk, "bus-emac1", "ahb3", 0x97c, BIT(1), 0);
556
557 static const char * const ir_parents[] = { "osc32k", "dcxo24M",
558 "pll-periph0", "pll-periph1" };
559 static SUNXI_CCU_MP_WITH_MUX_GATE(ir_rx_clk, "ir-rx", ir_parents, 0x990,
560 0, 4, /* M */
561 8, 2, /* N */
562 24, 3, /* mux */
563 BIT(31), /* gate */
564 0);
565
566 static SUNXI_CCU_GATE(bus_ir_rx_clk, "bus-ir-rx", "ahb3", 0x99c, BIT(0), 0);
567
568 static SUNXI_CCU_MP_WITH_MUX_GATE(ir_tx_clk, "ir-tx", ir_parents, 0x9c0,
569 0, 4, /* M */
570 8, 2, /* N */
571 24, 3, /* mux */
572 BIT(31), /* gate */
573 0);
574
575 static SUNXI_CCU_GATE(bus_ir_tx_clk, "bus-ir-tx", "apb1", 0x9cc, BIT(0), 0);
576
577 static SUNXI_CCU_GATE(bus_gpadc_clk, "bus-gpadc", "apb1", 0x9ec, BIT(0), 0);
578
579 static SUNXI_CCU_GATE(bus_ths_clk, "bus-ths", "apb1", 0x9fc, BIT(0), 0);
580
581 static const char * const audio_parents[] = { "pll-audio", "pll-com-audio" };
582 static struct ccu_div i2s0_clk = {
583 .enable = BIT(31),
584 .div = _SUNXI_CCU_DIV_FLAGS(8, 2, CLK_DIVIDER_POWER_OF_TWO),
585 .mux = _SUNXI_CCU_MUX(24, 2),
586 .common = {
587 .reg = 0xa10,
588 .hw.init = CLK_HW_INIT_PARENTS("i2s0",
589 audio_parents,
590 &ccu_div_ops,
591 CLK_SET_RATE_PARENT),
592 },
593 };
594
595 static struct ccu_div i2s1_clk = {
596 .enable = BIT(31),
597 .div = _SUNXI_CCU_DIV_FLAGS(8, 2, CLK_DIVIDER_POWER_OF_TWO),
598 .mux = _SUNXI_CCU_MUX(24, 2),
599 .common = {
600 .reg = 0xa14,
601 .hw.init = CLK_HW_INIT_PARENTS("i2s1",
602 audio_parents,
603 &ccu_div_ops,
604 CLK_SET_RATE_PARENT),
605 },
606 };
607
608 static struct ccu_div i2s2_clk = {
609 .enable = BIT(31),
610 .div = _SUNXI_CCU_DIV_FLAGS(8, 2, CLK_DIVIDER_POWER_OF_TWO),
611 .mux = _SUNXI_CCU_MUX(24, 2),
612 .common = {
613 .reg = 0xa18,
614 .hw.init = CLK_HW_INIT_PARENTS("i2s2",
615 audio_parents,
616 &ccu_div_ops,
617 CLK_SET_RATE_PARENT),
618 },
619 };
620
621 static struct ccu_div i2s3_clk = {
622 .enable = BIT(31),
623 .div = _SUNXI_CCU_DIV_FLAGS(8, 2, CLK_DIVIDER_POWER_OF_TWO),
624 .mux = _SUNXI_CCU_MUX(24, 2),
625 .common = {
626 .reg = 0xa1c,
627 .hw.init = CLK_HW_INIT_PARENTS("i2s3",
628 audio_parents,
629 &ccu_div_ops,
630 CLK_SET_RATE_PARENT),
631 },
632 };
633
634 static SUNXI_CCU_GATE(bus_i2s0_clk, "bus-i2s0", "apb1", 0xa20, BIT(0), 0);
635 static SUNXI_CCU_GATE(bus_i2s1_clk, "bus-i2s1", "apb1", 0xa20, BIT(1), 0);
636 static SUNXI_CCU_GATE(bus_i2s2_clk, "bus-i2s2", "apb1", 0xa20, BIT(2), 0);
637 static SUNXI_CCU_GATE(bus_i2s3_clk, "bus-i2s3", "apb1", 0xa20, BIT(3), 0);
638
639 static struct ccu_div spdif_clk = {
640 .enable = BIT(31),
641 .div = _SUNXI_CCU_DIV_FLAGS(8, 2, CLK_DIVIDER_POWER_OF_TWO),
642 .mux = _SUNXI_CCU_MUX(24, 2),
643 .common = {
644 .reg = 0xa24,
645 .hw.init = CLK_HW_INIT_PARENTS("spdif",
646 audio_parents,
647 &ccu_div_ops,
648 0),
649 },
650 };
651
652 static SUNXI_CCU_GATE(bus_spdif_clk, "bus-spdif", "apb1", 0xa2c, BIT(0), 0);
653
654 static struct ccu_div dmic_clk = {
655 .enable = BIT(31),
656 .div = _SUNXI_CCU_DIV_FLAGS(8, 2, CLK_DIVIDER_POWER_OF_TWO),
657 .mux = _SUNXI_CCU_MUX(24, 2),
658 .common = {
659 .reg = 0xa40,
660 .hw.init = CLK_HW_INIT_PARENTS("dmic",
661 audio_parents,
662 &ccu_div_ops,
663 0),
664 },
665 };
666
667 static SUNXI_CCU_GATE(bus_dmic_clk, "bus-dmic", "apb1", 0xa4c, BIT(0), 0);
668
669 static SUNXI_CCU_M_WITH_MUX_GATE(audio_codec_dac_clk, "audio-codec-dac",
670 audio_parents, 0xa50,
671 0, 4, /* M */
672 24, 2, /* mux */
673 BIT(31), /* gate */
674 0);
675
676 static SUNXI_CCU_M_WITH_MUX_GATE(audio_codec_adc_clk, "audio-codec-adc",
677 audio_parents, 0xa54,
678 0, 4, /* M */
679 24, 2, /* mux */
680 BIT(31), /* gate */
681 0);
682
683 static SUNXI_CCU_M_WITH_MUX_GATE(audio_codec_4x_clk, "audio-codec-4x",
684 audio_parents, 0xa58,
685 0, 4, /* M */
686 24, 2, /* mux */
687 BIT(31), /* gate */
688 0);
689
690 static SUNXI_CCU_GATE(bus_audio_codec_clk, "bus-audio-codec", "apb1", 0xa5c, BIT(0), 0);
691
692 /*
693 * There are OHCI 12M clock source selection bits for 2 USB 2.0 ports.
694 * We will force them to 0 (12M divided from 48M).
695 */
696 #define SUN50IW10_USB0_CLK_REG 0xa70
697 #define SUN50IW10_USB1_CLK_REG 0xa74
698
699 static SUNXI_CCU_GATE(usb_ohci0_clk, "usb-ohci0", "osc12M", 0xa70, BIT(31), 0);
700 static SUNXI_CCU_GATE(usb_phy0_clk, "usb-phy0", "dcxo24M", 0xa70, BIT(29), 0);
701
702 static SUNXI_CCU_GATE(usb_ohci1_clk, "usb-ohci1", "osc12M", 0xa74, BIT(31), 0);
703 static SUNXI_CCU_GATE(usb_phy1_clk, "usb-phy1", "dcxo24M", 0xa74, BIT(29), 0);
704
705 static SUNXI_CCU_GATE(bus_ohci0_clk, "bus-ohci0", "ahb3", 0xa8c, BIT(0), 0);
706 static SUNXI_CCU_GATE(bus_ohci1_clk, "bus-ohci1", "ahb3", 0xa8c, BIT(1), 0);
707 static SUNXI_CCU_GATE(bus_ehci0_clk, "bus-ehci0", "ahb3", 0xa8c, BIT(4), 0);
708 static SUNXI_CCU_GATE(bus_ehci1_clk, "bus-ehci1", "ahb3", 0xa8c, BIT(5), 0);
709 static SUNXI_CCU_GATE(bus_otg_clk, "bus-otg", "ahb3", 0xa8c, BIT(8), 0);
710
711 static SUNXI_CCU_GATE(bus_lradc_clk, "bus-lradc", "ahb3", 0xa9c, BIT(0), 0);
712
713 static SUNXI_CCU_GATE(bus_dpss_top0_clk, "bus-dpss-top0", "ahb3",
714 0xabc, BIT(0), 0);
715
716 static SUNXI_CCU_GATE(bus_dpss_top1_clk, "bus-dpss-top1", "ahb3",
717 0xacc, BIT(0), 0);
718
719 static const char * const mipi_dsi_parents[] = { "dcxo24M", "pll-periph0-2x",
720 "pll-periph0" };
721 static SUNXI_CCU_M_WITH_MUX_GATE(mipi_dsi_clk, "mipi-dsi",
722 mipi_dsi_parents,
723 0xb24,
724 0, 4, /* M */
725 24, 2, /* mux */
726 BIT(31), /* gate */
727 CLK_SET_RATE_NO_REPARENT);
728
729 static SUNXI_CCU_GATE(bus_mipi_dsi_clk, "bus-mipi-dsi", "ahb3",
730 0xb4c, BIT(0), 0);
731
732 static const char * const tcon_lcd0_parents[] = { "pll-video0-4x",
733 "pll-video1-4x",
734 "pll-video2-4x",
735 "pll-video3-4x",
736 "pll-periph0-2x" };
737 static SUNXI_CCU_MP_WITH_MUX_GATE(tcon_lcd0_clk, "tcon-lcd0",
738 tcon_lcd0_parents, 0xb60,
739 0, 4, /* M */
740 8, 2, /* N */
741 24, 3, /* mux */
742 BIT(31), /* gate */
743 CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT);
744
745 static const char * const tcon_lcd1_parents[] = { "pll-video1-4x",
746 "pll-video2-4x",
747 "pll-video3-4x",
748 "pll-video0-4x",
749 "pll-periph0-2x" };
750 static SUNXI_CCU_MP_WITH_MUX_GATE(tcon_lcd1_clk, "tcon-lcd1",
751 tcon_lcd1_parents, 0xb64,
752 0, 4, /* M */
753 8, 2, /* N */
754 24, 3, /* mux */
755 BIT(31), /* gate */
756 CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT);
757
758 static SUNXI_CCU_GATE(bus_tcon_lcd0_clk, "bus-tcon-lcd0", "ahb3",
759 0xb7c, BIT(0), 0);
760 static SUNXI_CCU_GATE(bus_tcon_lcd1_clk, "bus-tcon-lcd1", "ahb3",
761 0xb7c, BIT(1), 0);
762
763 static const char * const ledc_parents[] = { "dcxo24M",
764 "pll-periph0" };
765 static SUNXI_CCU_MP_WITH_MUX_GATE(ledc_clk, "ledc",
766 ledc_parents, 0xbf0,
767 0, 4, /* M */
768 8, 2, /* N */
769 24, 3, /* mux */
770 BIT(31), /* gate */
771 0);
772
773 static SUNXI_CCU_GATE(bus_ledc_clk, "bus-ledc", "ahb3", 0xbfc, BIT(0), 0);
774
775 static const char * const csi_top_parents[] = { "pll-periph0-2x",
776 "pll-video0-2x",
777 "pll-video1-2x",
778 "pll-video2-2x",
779 "pll-video3-2x" };
780 static SUNXI_CCU_M_WITH_MUX_GATE(csi_top_clk, "csi-top",
781 csi_top_parents, 0xc04,
782 0, 4, /* M */
783 24, 3, /* mux */
784 BIT(31), /* gate */
785 0);
786
787 static const char * const csi0_mclk_parents[] = { "dcxo24M", "pll-video2",
788 "pll-video3", "pll-video0",
789 "pll-video1" };
790 static SUNXI_CCU_M_WITH_MUX_GATE(csi0_mclk_clk, "csi0-mclk",
791 csi0_mclk_parents, 0xc08,
792 0, 5, /* M */
793 24, 3, /* mux */
794 BIT(31), /* gate */
795 0);
796
797 static const char * const csi1_mclk_parents[] = { "dcxo24M", "pll-video3",
798 "pll-video0", "pll-video1",
799 "pll-video2" };
800 static SUNXI_CCU_M_WITH_MUX_GATE(csi1_mclk_clk, "csi1-mclk",
801 csi1_mclk_parents, 0xc0c,
802 0, 5, /* M */
803 24, 3, /* mux */
804 BIT(31), /* gate */
805 0);
806
807 static SUNXI_CCU_GATE(bus_csi_clk, "bus-csi", "ahb3", 0xc1c, BIT(0), 0);
808
809 static const char * const csi_isp_parents[] = { "pll-periph0-2x",
810 "pll-video0-2x",
811 "pll-video1-2x",
812 "pll-video2-2x",
813 "pll-video3-2x" };
814 static SUNXI_CCU_M_WITH_MUX_GATE(csi_isp_clk, "csi-isp",
815 csi_isp_parents, 0xc20,
816 0, 5, /* M */
817 24, 3, /* mux */
818 BIT(31), /* gate */
819 0);
820
821 /* Fixed factor clocks */
822 static CLK_FIXED_FACTOR_FW_NAME(osc12M_clk, "osc12M", "hosc", 2, 1, 0);
823
824 static CLK_FIXED_FACTOR_HW(pll_com_audio_clk, "pll-com-audio",
825 &pll_com_clk.common.hw,
826 5, 1, CLK_SET_RATE_PARENT);
827
828 static CLK_FIXED_FACTOR_HW(pll_periph0_2x_clk, "pll-periph0-2x",
829 &pll_periph0_clk.common.hw,
830 1, 2, 0);
831
832 static CLK_FIXED_FACTOR_HW(pll_periph1_2x_clk, "pll-periph1-2x",
833 &pll_periph1_clk.common.hw,
834 1, 2, 0);
835
836 static const struct clk_hw *pll_video0_parents[] = {
837 &pll_video0_clk.common.hw
838 };
839 static CLK_FIXED_FACTOR_HWS(pll_video0_4x_clk, "pll-video0-4x",
840 pll_video0_parents,
841 1, 4, CLK_SET_RATE_PARENT);
842 static CLK_FIXED_FACTOR_HWS(pll_video0_2x_clk, "pll-video0-2x",
843 pll_video0_parents,
844 1, 2, CLK_SET_RATE_PARENT);
845
846 static const struct clk_hw *pll_video1_parents[] = {
847 &pll_video1_clk.common.hw
848 };
849 static CLK_FIXED_FACTOR_HWS(pll_video1_4x_clk, "pll-video1-4x",
850 pll_video1_parents,
851 1, 4, CLK_SET_RATE_PARENT);
852 static CLK_FIXED_FACTOR_HWS(pll_video1_2x_clk, "pll-video1-2x",
853 pll_video1_parents,
854 1, 2, CLK_SET_RATE_PARENT);
855
856 static const struct clk_hw *pll_video2_parents[] = {
857 &pll_video2_clk.common.hw
858 };
859 static CLK_FIXED_FACTOR_HWS(pll_video2_4x_clk, "pll-video2-4x",
860 pll_video2_parents,
861 1, 4, CLK_SET_RATE_PARENT);
862 static CLK_FIXED_FACTOR_HWS(pll_video2_2x_clk, "pll-video2-2x",
863 pll_video2_parents,
864 1, 2, CLK_SET_RATE_PARENT);
865
866 static const struct clk_hw *pll_video3_parents[] = {
867 &pll_video3_clk.common.hw
868 };
869 static CLK_FIXED_FACTOR_HWS(pll_video3_4x_clk, "pll-video3-4x",
870 pll_video3_parents,
871 1, 4, CLK_SET_RATE_PARENT);
872 static CLK_FIXED_FACTOR_HWS(pll_video3_2x_clk, "pll-video3-2x",
873 pll_video3_parents,
874 1, 2, CLK_SET_RATE_PARENT);
875
876 /* for save sdm register when suspend */
877 #ifdef CONFIG_PM_SLEEP
878 static struct ccu_nm pll_audio_sdm_clk = {
879 .common = {
880 .reg = 0x178,
881 },
882 };
883
884 static struct ccu_nm pll_com_sdm_clk = {
885 .common = {
886 .reg = 0x160,
887 },
888 };
889 #endif
890
891 static struct ccu_common *sun50iw10_ccu_clks[] = {
892 &pll_cpux_clk.common,
893 &pll_ddr0_clk.common,
894 &pll_periph0_clk.common,
895 &pll_periph1_pattern0_common, /* for pm resume */
896 &pll_periph1_clk.common,
897 &pll_gpu_clk.common,
898 &pll_video0_clk.common,
899 &pll_video1_clk.common,
900 &pll_video2_clk.common,
901 &pll_video3_clk.common,
902 &pll_ve_clk.common,
903 &pll_com_clk.common,
904 &pll_audio_clk.common,
905 &cpux_clk.common,
906 &axi_clk.common,
907 &cpux_apb_clk.common,
908 &psi_ahb1_ahb2_clk.common,
909 &ahb3_clk.common,
910 &apb1_clk.common,
911 &apb2_clk.common,
912 &mbus_clk.common,
913 &de0_clk.common,
914 &de1_clk.common,
915 &bus_de0_clk.common,
916 &bus_de1_clk.common,
917 &eink_clk.common,
918 &bus_eink_clk.common,
919 &g2d_clk.common,
920 &bus_g2d_clk.common,
921 &eink_panel_clk.common,
922 &gpu_clk.common,
923 &bus_gpu_clk.common,
924 &ce_clk.common,
925 &bus_ce_clk.common,
926 &ve_clk.common,
927 &bus_ve_clk.common,
928 &bus_dma_clk.common,
929 &bus_msgbox_clk.common,
930 &bus_spinlock_clk.common,
931 &bus_hstimer_clk.common,
932 &avs_clk.common,
933 &bus_dbg_clk.common,
934 &bus_psi_clk.common,
935 &bus_pwm_clk.common,
936 &bus_iommu_clk.common,
937 &mbus_dma_clk.common,
938 &mbus_ve_clk.common,
939 &mbus_ce_clk.common,
940 &mbus_nand_clk.common,
941 &mbus_csi_clk.common,
942 &mbus_isp_clk.common,
943 &mbus_g2d_clk.common,
944 &bus_dram_clk.common,
945 &nand0_clk.common,
946 &nand1_clk.common,
947 &bus_nand_clk.common,
948 &mmc0_clk.common,
949 &mmc1_clk.common,
950 &mmc2_clk.common,
951 &mmc3_clk.common,
952 &bus_mmc0_clk.common,
953 &bus_mmc1_clk.common,
954 &bus_mmc2_clk.common,
955 &bus_mmc3_clk.common,
956 &bus_uart0_clk.common,
957 &bus_uart1_clk.common,
958 &bus_uart2_clk.common,
959 &bus_uart3_clk.common,
960 &bus_uart4_clk.common,
961 &bus_uart5_clk.common,
962 &bus_uart6_clk.common,
963 &bus_i2c0_clk.common,
964 &bus_i2c1_clk.common,
965 &bus_i2c2_clk.common,
966 &bus_i2c3_clk.common,
967 &bus_i2c4_clk.common,
968 &bus_i2c5_clk.common,
969 &spi0_clk.common,
970 &spi1_clk.common,
971 &spi2_clk.common,
972 &bus_spi0_clk.common,
973 &bus_spi1_clk.common,
974 &bus_spi2_clk.common,
975 &emac0_25m_clk.common,
976 &emac1_25m_clk.common,
977 &bus_emac0_clk.common,
978 &bus_emac1_clk.common,
979 &ir_rx_clk.common,
980 &bus_ir_rx_clk.common,
981 &ir_tx_clk.common,
982 &bus_ir_tx_clk.common,
983 &bus_gpadc_clk.common,
984 &bus_ths_clk.common,
985 &i2s0_clk.common,
986 &i2s1_clk.common,
987 &i2s2_clk.common,
988 &i2s3_clk.common,
989 &bus_i2s0_clk.common,
990 &bus_i2s1_clk.common,
991 &bus_i2s2_clk.common,
992 &bus_i2s3_clk.common,
993 &spdif_clk.common,
994 &bus_spdif_clk.common,
995 &dmic_clk.common,
996 &bus_dmic_clk.common,
997 &audio_codec_dac_clk.common,
998 &audio_codec_adc_clk.common,
999 &audio_codec_4x_clk.common,
1000 &bus_audio_codec_clk.common,
1001 &usb_ohci0_clk.common,
1002 &usb_phy0_clk.common,
1003 &usb_ohci1_clk.common,
1004 &usb_phy1_clk.common,
1005 &bus_ohci0_clk.common,
1006 &bus_ohci1_clk.common,
1007 &bus_ehci0_clk.common,
1008 &bus_ehci1_clk.common,
1009 &bus_otg_clk.common,
1010 &bus_lradc_clk.common,
1011 &bus_dpss_top0_clk.common,
1012 &bus_dpss_top1_clk.common,
1013 &mipi_dsi_clk.common,
1014 &bus_mipi_dsi_clk.common,
1015 &tcon_lcd0_clk.common,
1016 &tcon_lcd1_clk.common,
1017 &bus_tcon_lcd0_clk.common,
1018 &bus_tcon_lcd1_clk.common,
1019 &ledc_clk.common,
1020 &bus_ledc_clk.common,
1021 &csi_top_clk.common,
1022 &csi0_mclk_clk.common,
1023 &csi1_mclk_clk.common,
1024 &bus_csi_clk.common,
1025 &csi_isp_clk.common,
1026 #ifdef CONFIG_PM_SLEEP
1027 &pll_audio_sdm_clk.common,
1028 &pll_com_sdm_clk.common,
1029 #endif
1030 };
1031
1032 static struct clk_hw_onecell_data sun50iw10_hw_clks = {
1033 .hws = {
1034 [CLK_OSC12M] = &osc12M_clk.hw,
1035 [CLK_PLL_CPUX] = &pll_cpux_clk.common.hw,
1036 [CLK_PLL_DDR0] = &pll_ddr0_clk.common.hw,
1037 [CLK_PLL_PERIPH0] = &pll_periph0_clk.common.hw,
1038 [CLK_PLL_PERIPH0_2X] = &pll_periph0_2x_clk.hw,
1039 [CLK_PLL_PERIPH1] = &pll_periph1_clk.common.hw,
1040 [CLK_PLL_PERIPH1_2X] = &pll_periph1_2x_clk.hw,
1041 [CLK_PLL_GPU] = &pll_gpu_clk.common.hw,
1042 [CLK_PLL_VIDEO0] = &pll_video0_clk.common.hw,
1043 [CLK_PLL_VIDEO0_2X] = &pll_video0_2x_clk.hw,
1044 [CLK_PLL_VIDEO0_4X] = &pll_video0_4x_clk.hw,
1045 [CLK_PLL_VIDEO1] = &pll_video1_clk.common.hw,
1046 [CLK_PLL_VIDEO1_2X] = &pll_video1_2x_clk.hw,
1047 [CLK_PLL_VIDEO1_4X] = &pll_video1_4x_clk.hw,
1048 [CLK_PLL_VIDEO2] = &pll_video2_clk.common.hw,
1049 [CLK_PLL_VIDEO2_2X] = &pll_video2_2x_clk.hw,
1050 [CLK_PLL_VIDEO2_4X] = &pll_video2_4x_clk.hw,
1051 [CLK_PLL_VIDEO3] = &pll_video3_clk.common.hw,
1052 [CLK_PLL_VIDEO3_2X] = &pll_video3_2x_clk.hw,
1053 [CLK_PLL_VIDEO3_4X] = &pll_video3_4x_clk.hw,
1054 [CLK_PLL_VE] = &pll_ve_clk.common.hw,
1055 [CLK_PLL_COM] = &pll_com_clk.common.hw,
1056 [CLK_PLL_COM_AUDIO] = &pll_com_audio_clk.hw,
1057 [CLK_PLL_AUDIO] = &pll_audio_clk.common.hw,
1058 [CLK_CPUX] = &cpux_clk.common.hw,
1059 [CLK_AXI] = &axi_clk.common.hw,
1060 [CLK_CPUX_APB] = &cpux_apb_clk.common.hw,
1061 [CLK_PSI_AHB1_AHB2] = &psi_ahb1_ahb2_clk.common.hw,
1062 [CLK_AHB3] = &ahb3_clk.common.hw,
1063 [CLK_APB1] = &apb1_clk.common.hw,
1064 [CLK_APB2] = &apb2_clk.common.hw,
1065 [CLK_MBUS] = &mbus_clk.common.hw,
1066 [CLK_DE0] = &de0_clk.common.hw,
1067 [CLK_DE1] = &de1_clk.common.hw,
1068 [CLK_BUS_DE0] = &bus_de0_clk.common.hw,
1069 [CLK_BUS_DE1] = &bus_de1_clk.common.hw,
1070 [CLK_EINK] = &eink_clk.common.hw,
1071 [CLK_BUS_EINK] = &bus_eink_clk.common.hw,
1072 [CLK_G2D] = &g2d_clk.common.hw,
1073 [CLK_BUS_G2D] = &bus_g2d_clk.common.hw,
1074 [CLK_EINK_PANEL] = &eink_panel_clk.common.hw,
1075 [CLK_GPU] = &gpu_clk.common.hw,
1076 [CLK_BUS_GPU] = &bus_gpu_clk.common.hw,
1077 [CLK_CE] = &ce_clk.common.hw,
1078 [CLK_BUS_CE] = &bus_ce_clk.common.hw,
1079 [CLK_VE] = &ve_clk.common.hw,
1080 [CLK_BUS_VE] = &bus_ve_clk.common.hw,
1081 [CLK_BUS_DMA] = &bus_dma_clk.common.hw,
1082 [CLK_BUS_MSGBOX] = &bus_msgbox_clk.common.hw,
1083 [CLK_BUS_SPINLOCK] = &bus_spinlock_clk.common.hw,
1084 [CLK_BUS_HSTIMER] = &bus_hstimer_clk.common.hw,
1085 [CLK_AVS] = &avs_clk.common.hw,
1086 [CLK_BUS_DBG] = &bus_dbg_clk.common.hw,
1087 [CLK_BUS_PSI] = &bus_psi_clk.common.hw,
1088 [CLK_BUS_PWM] = &bus_pwm_clk.common.hw,
1089 [CLK_BUS_IOMMU] = &bus_iommu_clk.common.hw,
1090 [CLK_MBUS_DMA] = &mbus_dma_clk.common.hw,
1091 [CLK_MBUS_VE] = &mbus_ve_clk.common.hw,
1092 [CLK_MBUS_CE] = &mbus_ce_clk.common.hw,
1093 [CLK_MBUS_NAND] = &mbus_nand_clk.common.hw,
1094 [CLK_MBUS_CSI] = &mbus_csi_clk.common.hw,
1095 [CLK_MBUS_ISP] = &mbus_isp_clk.common.hw,
1096 [CLK_MBUS_G2D] = &mbus_g2d_clk.common.hw,
1097 [CLK_BUS_DRAM] = &bus_dram_clk.common.hw,
1098 [CLK_NAND0] = &nand0_clk.common.hw,
1099 [CLK_NAND1] = &nand1_clk.common.hw,
1100 [CLK_BUS_NAND] = &bus_nand_clk.common.hw,
1101 [CLK_MMC0] = &mmc0_clk.common.hw,
1102 [CLK_MMC1] = &mmc1_clk.common.hw,
1103 [CLK_MMC2] = &mmc2_clk.common.hw,
1104 [CLK_MMC3] = &mmc3_clk.common.hw,
1105 [CLK_BUS_MMC0] = &bus_mmc0_clk.common.hw,
1106 [CLK_BUS_MMC1] = &bus_mmc1_clk.common.hw,
1107 [CLK_BUS_MMC2] = &bus_mmc2_clk.common.hw,
1108 [CLK_BUS_MMC3] = &bus_mmc3_clk.common.hw,
1109 [CLK_BUS_UART0] = &bus_uart0_clk.common.hw,
1110 [CLK_BUS_UART1] = &bus_uart1_clk.common.hw,
1111 [CLK_BUS_UART2] = &bus_uart2_clk.common.hw,
1112 [CLK_BUS_UART3] = &bus_uart3_clk.common.hw,
1113 [CLK_BUS_UART4] = &bus_uart4_clk.common.hw,
1114 [CLK_BUS_UART5] = &bus_uart5_clk.common.hw,
1115 [CLK_BUS_UART6] = &bus_uart6_clk.common.hw,
1116 [CLK_BUS_I2C0] = &bus_i2c0_clk.common.hw,
1117 [CLK_BUS_I2C1] = &bus_i2c1_clk.common.hw,
1118 [CLK_BUS_I2C2] = &bus_i2c2_clk.common.hw,
1119 [CLK_BUS_I2C3] = &bus_i2c3_clk.common.hw,
1120 [CLK_BUS_I2C4] = &bus_i2c4_clk.common.hw,
1121 [CLK_BUS_I2C5] = &bus_i2c5_clk.common.hw,
1122 [CLK_SPI0] = &spi0_clk.common.hw,
1123 [CLK_SPI1] = &spi1_clk.common.hw,
1124 [CLK_SPI2] = &spi2_clk.common.hw,
1125 [CLK_BUS_SPI0] = &bus_spi0_clk.common.hw,
1126 [CLK_BUS_SPI1] = &bus_spi1_clk.common.hw,
1127 [CLK_BUS_SPI2] = &bus_spi2_clk.common.hw,
1128 [CLK_EMAC0_25M] = &emac0_25m_clk.common.hw,
1129 [CLK_EMAC1_25M] = &emac1_25m_clk.common.hw,
1130 [CLK_BUS_EMAC0] = &bus_emac0_clk.common.hw,
1131 [CLK_BUS_EMAC1] = &bus_emac1_clk.common.hw,
1132 [CLK_IR_RX] = &ir_rx_clk.common.hw,
1133 [CLK_BUS_IR_RX] = &bus_ir_rx_clk.common.hw,
1134 [CLK_IR_TX] = &ir_tx_clk.common.hw,
1135 [CLK_BUS_IR_TX] = &bus_ir_tx_clk.common.hw,
1136 [CLK_BUS_GPADC] = &bus_gpadc_clk.common.hw,
1137 [CLK_BUS_THS] = &bus_ths_clk.common.hw,
1138 [CLK_I2S0] = &i2s0_clk.common.hw,
1139 [CLK_I2S1] = &i2s1_clk.common.hw,
1140 [CLK_I2S2] = &i2s2_clk.common.hw,
1141 [CLK_I2S3] = &i2s3_clk.common.hw,
1142 [CLK_BUS_I2S0] = &bus_i2s0_clk.common.hw,
1143 [CLK_BUS_I2S1] = &bus_i2s1_clk.common.hw,
1144 [CLK_BUS_I2S2] = &bus_i2s2_clk.common.hw,
1145 [CLK_BUS_I2S3] = &bus_i2s3_clk.common.hw,
1146 [CLK_SPDIF] = &spdif_clk.common.hw,
1147 [CLK_BUS_SPDIF] = &bus_spdif_clk.common.hw,
1148 [CLK_DMIC] = &dmic_clk.common.hw,
1149 [CLK_BUS_DMIC] = &bus_dmic_clk.common.hw,
1150 [CLK_AUDIO_DAC] = &audio_codec_dac_clk.common.hw,
1151 [CLK_AUDIO_ADC] = &audio_codec_adc_clk.common.hw,
1152 [CLK_AUDIO_4X] = &audio_codec_4x_clk.common.hw,
1153 [CLK_BUS_AUDIO_CODEC] = &bus_audio_codec_clk.common.hw,
1154 [CLK_USB_OHCI0] = &usb_ohci0_clk.common.hw,
1155 [CLK_USB_PHY0] = &usb_phy0_clk.common.hw,
1156 [CLK_USB_OHCI1] = &usb_ohci1_clk.common.hw,
1157 [CLK_USB_PHY1] = &usb_phy1_clk.common.hw,
1158 [CLK_BUS_OHCI0] = &bus_ohci0_clk.common.hw,
1159 [CLK_BUS_OHCI1] = &bus_ohci1_clk.common.hw,
1160 [CLK_BUS_EHCI0] = &bus_ehci0_clk.common.hw,
1161 [CLK_BUS_EHCI1] = &bus_ehci1_clk.common.hw,
1162 [CLK_BUS_OTG] = &bus_otg_clk.common.hw,
1163 [CLK_BUS_LRADC] = &bus_lradc_clk.common.hw,
1164 [CLK_BUS_DPSS_TOP0] = &bus_dpss_top0_clk.common.hw,
1165 [CLK_BUS_DPSS_TOP1] = &bus_dpss_top1_clk.common.hw,
1166 [CLK_MIPI_DSI] = &mipi_dsi_clk.common.hw,
1167 [CLK_BUS_MIPI_DSI] = &bus_mipi_dsi_clk.common.hw,
1168 [CLK_TCON_LCD0] = &tcon_lcd0_clk.common.hw,
1169 [CLK_TCON_LCD1] = &tcon_lcd1_clk.common.hw,
1170 [CLK_BUS_TCON_LCD0] = &bus_tcon_lcd0_clk.common.hw,
1171 [CLK_BUS_TCON_LCD1] = &bus_tcon_lcd1_clk.common.hw,
1172 [CLK_LEDC] = &ledc_clk.common.hw,
1173 [CLK_BUS_LEDC] = &bus_ledc_clk.common.hw,
1174 [CLK_CSI_TOP] = &csi_top_clk.common.hw,
1175 [CLK_CSI0_MCLK] = &csi0_mclk_clk.common.hw,
1176 [CLK_CSI1_MCLK] = &csi1_mclk_clk.common.hw,
1177 [CLK_BUS_CSI] = &bus_csi_clk.common.hw,
1178 [CLK_CSI_ISP] = &csi_isp_clk.common.hw,
1179 },
1180 .num = CLK_NUMBER,
1181 };
1182
1183 static struct ccu_reset_map sun50iw10_ccu_resets[] = {
1184 [RST_MBUS] = { 0x540, BIT(30) },
1185
1186 [RST_BUS_DE0] = { 0x60c, BIT(16) },
1187 [RST_BUS_DE1] = { 0x60c, BIT(17) },
1188 [RST_BUS_EINK] = { 0x61c, BIT(16) },
1189 [RST_BUS_G2D] = { 0x63c, BIT(16) },
1190 [RST_BUS_GPU] = { 0x67c, BIT(16) },
1191 [RST_BUS_CE] = { 0x68c, BIT(16) },
1192 [RST_BUS_VE] = { 0x69c, BIT(16) },
1193 [RST_BUS_DMA] = { 0x70c, BIT(16) },
1194 [RST_BUS_MSGBOX] = { 0x71c, BIT(16) },
1195 [RST_BUS_SPINLOCK] = { 0x72c, BIT(16) },
1196 [RST_BUS_HSTIMER] = { 0x73c, BIT(16) },
1197 [RST_BUS_DBG] = { 0x78c, BIT(16) },
1198 [RST_BUS_PSI] = { 0x79c, BIT(16) },
1199 [RST_BUS_PWM] = { 0x7ac, BIT(16) },
1200 [RST_BUS_DRAM] = { 0x80c, BIT(16) },
1201 [RST_BUS_NAND] = { 0x82c, BIT(16) },
1202 [RST_BUS_MMC0] = { 0x84c, BIT(16) },
1203 [RST_BUS_MMC1] = { 0x84c, BIT(17) },
1204 [RST_BUS_MMC2] = { 0x84c, BIT(18) },
1205 [RST_BUS_MMC3] = { 0x84c, BIT(19) },
1206 [RST_BUS_UART0] = { 0x90c, BIT(16) },
1207 [RST_BUS_UART1] = { 0x90c, BIT(17) },
1208 [RST_BUS_UART2] = { 0x90c, BIT(18) },
1209 [RST_BUS_UART3] = { 0x90c, BIT(19) },
1210 [RST_BUS_UART4] = { 0x90c, BIT(20) },
1211 [RST_BUS_UART5] = { 0x90c, BIT(21) },
1212 [RST_BUS_UART6] = { 0x90c, BIT(22) },
1213 [RST_BUS_I2C0] = { 0x91c, BIT(16) },
1214 [RST_BUS_I2C1] = { 0x91c, BIT(17) },
1215 [RST_BUS_I2C2] = { 0x91c, BIT(18) },
1216 [RST_BUS_I2C3] = { 0x91c, BIT(19) },
1217 [RST_BUS_I2C4] = { 0x91c, BIT(20) },
1218 [RST_BUS_I2C5] = { 0x91c, BIT(21) },
1219 [RST_BUS_SPI0] = { 0x96c, BIT(16) },
1220 [RST_BUS_SPI1] = { 0x96c, BIT(17) },
1221 [RST_BUS_SPI2] = { 0x96c, BIT(18) },
1222 [RST_BUS_EMAC0] = { 0x97c, BIT(16) },
1223 [RST_BUS_EMAC1] = { 0x97c, BIT(17) },
1224 [RST_BUS_IR_RX] = { 0x99c, BIT(16) },
1225 [RST_BUS_IR_TX] = { 0x9cc, BIT(16) },
1226 [RST_BUS_GPADC] = { 0x9ec, BIT(16) },
1227 [RST_BUS_THS] = { 0x9fc, BIT(16) },
1228 [RST_BUS_I2S0] = { 0xa20, BIT(16) },
1229 [RST_BUS_I2S1] = { 0xa20, BIT(17) },
1230 [RST_BUS_I2S2] = { 0xa20, BIT(18) },
1231 [RST_BUS_I2S3] = { 0xa20, BIT(19) },
1232 [RST_BUS_SPDIF] = { 0xa2c, BIT(16) },
1233 [RST_BUS_DMIC] = { 0xa4c, BIT(16) },
1234 [RST_BUS_AUDIO_CODEC] = { 0xa5c, BIT(16) },
1235
1236 [RST_USB_PHY0] = { 0xa70, BIT(30) },
1237 [RST_USB_PHY1] = { 0xa74, BIT(30) },
1238
1239 [RST_BUS_OHCI0] = { 0xa8c, BIT(16) },
1240 [RST_BUS_OHCI1] = { 0xa8c, BIT(17) },
1241 [RST_BUS_EHCI0] = { 0xa8c, BIT(20) },
1242 [RST_BUS_EHCI1] = { 0xa8c, BIT(21) },
1243 [RST_BUS_OTG] = { 0xa8c, BIT(24) },
1244
1245 [RST_BUS_LRADC] = { 0xa9c, BIT(16) },
1246 [RST_BUS_DPSS_TOP0] = { 0xabc, BIT(16) },
1247 [RST_BUS_DPSS_TOP1] = { 0xacc, BIT(16) },
1248 [RST_BUS_MIPI_DSI] = { 0xb4c, BIT(16) },
1249 [RST_BUS_TCON_LCD0] = { 0xb7c, BIT(16) },
1250 [RST_BUS_TCON_LCD1] = { 0xb7c, BIT(17) },
1251 [RST_BUS_LVDS0] = { 0xbac, BIT(16) },
1252 [RST_BUS_LVDS1] = { 0xbac, BIT(17) },
1253 [RST_BUS_LEDC] = { 0xbfc, BIT(16) },
1254 [RST_BUS_CSI] = { 0xc1c, BIT(16) },
1255 [RST_BUS_CSI_ISP] = { 0xc2c, BIT(16) },
1256 };
1257
1258 static const struct sunxi_ccu_desc sun50iw10_ccu_desc = {
1259 .ccu_clks = sun50iw10_ccu_clks,
1260 .num_ccu_clks = ARRAY_SIZE(sun50iw10_ccu_clks),
1261
1262 .hw_clks = &sun50iw10_hw_clks,
1263
1264 .resets = sun50iw10_ccu_resets,
1265 .num_resets = ARRAY_SIZE(sun50iw10_ccu_resets),
1266 };
1267
1268 static const u32 pll_regs[] = {
1269 SUN50IW10_PLL_CPUX_REG,
1270 SUN50IW10_PLL_DDR0_REG,
1271 SUN50IW10_PLL_PERIPH0_REG,
1272 SUN50IW10_PLL_PERIPH1_REG,
1273 SUN50IW10_PLL_GPU_REG,
1274 SUN50IW10_PLL_VIDEO0_REG,
1275 SUN50IW10_PLL_VIDEO1_REG,
1276 SUN50IW10_PLL_VIDEO2_REG,
1277 SUN50IW10_PLL_VIDEO3_REG,
1278 SUN50IW10_PLL_VE_REG,
1279 SUN50IW10_PLL_COM_REG,
1280 SUN50IW10_PLL_AUDIO_REG,
1281 };
1282
1283 static const u32 pll_video_regs[] = {
1284 SUN50IW10_PLL_VIDEO0_REG,
1285 SUN50IW10_PLL_VIDEO1_REG,
1286 SUN50IW10_PLL_VIDEO2_REG,
1287 SUN50IW10_PLL_VIDEO3_REG,
1288 };
1289
1290 static const u32 usb2_clk_regs[] = {
1291 SUN50IW10_USB0_CLK_REG,
1292 SUN50IW10_USB1_CLK_REG,
1293 };
1294
1295 static struct ccu_pll_nb sun50iw10_pll_cpu_nb = {
1296 .common = &pll_cpux_clk.common,
1297 /* copy from pll_cpux_clk */
1298 .enable = BIT(27),
1299 .lock = BIT(28),
1300 };
1301
1302 static struct ccu_mux_nb sun50iw10_cpu_nb = {
1303 .common = &cpux_clk.common,
1304 .cm = &cpux_clk.mux,
1305 .delay_us = 1,
1306 .bypass_index = 4, /* index of pll periph0 */
1307 };
1308
sun50iw10_ccu_probe(struct platform_device * pdev)1309 static int sun50iw10_ccu_probe(struct platform_device *pdev)
1310 {
1311 void __iomem *reg;
1312 u32 val;
1313 int i, ret;
1314
1315 reg = devm_platform_ioremap_resource(pdev, 0);
1316 if (IS_ERR(reg))
1317 return PTR_ERR(reg);
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 /*
1327 * In order to pass the EMI certification, the SDM function of
1328 * the peripheral 1 bus is enabled, and the frequency is still
1329 * calculated using the previous division factor.
1330 */
1331 writel(0xd1303333, reg + SUN50IW10_PLL_PERIPH1_PATTERN0_REG);
1332
1333 val = readl(reg + SUN50IW10_PLL_PERIPH1_REG);
1334 val |= BIT(24);
1335 writel(val, reg + SUN50IW10_PLL_PERIPH1_REG);
1336
1337 /*
1338 * Force the output divider of video PLLs to 0.
1339 *
1340 * See the comment before pll-video0 definition for the reason.
1341 */
1342 for (i = 0; i < ARRAY_SIZE(pll_video_regs); i++) {
1343 val = readl(reg + pll_video_regs[i]);
1344 val &= ~BIT(0);
1345 writel(val, reg + pll_video_regs[i]);
1346 }
1347
1348 /* Enforce m1 = 0, m0 = 1 for Audio PLL */
1349 val = readl(reg + SUN50IW10_PLL_AUDIO_REG);
1350 val &= ~BIT(1);
1351 val |= BIT(0);
1352 writel(val, reg + SUN50IW10_PLL_AUDIO_REG);
1353
1354 /*
1355 * Force OHCI 12M clock sources to 00 (12MHz divided from 48MHz)
1356 *
1357 * This clock mux is still mysterious, and the code just enforces
1358 * it to have a valid clock parent.
1359 */
1360 for (i = 0; i < ARRAY_SIZE(usb2_clk_regs); i++) {
1361 val = readl(reg + usb2_clk_regs[i]);
1362 val &= ~GENMASK(25, 24);
1363 writel (val, reg + usb2_clk_regs[i]);
1364 }
1365
1366 ret = sunxi_ccu_probe(pdev->dev.of_node, reg, &sun50iw10_ccu_desc);
1367 if (ret)
1368 return ret;
1369
1370 /* Gate then ungate PLL CPU after any rate changes */
1371 ccu_pll_notifier_register(&sun50iw10_pll_cpu_nb);
1372
1373 /* Reparent CPU during PLL CPU rate changes */
1374 ccu_mux_notifier_register(pll_cpux_clk.common.hw.clk,
1375 &sun50iw10_cpu_nb);
1376
1377 sunxi_ccu_sleep_init(reg, sun50iw10_ccu_clks,
1378 ARRAY_SIZE(sun50iw10_ccu_clks),
1379 NULL, 0);
1380
1381 printk("Sunxi ccu sun50iw10 init OK\n");
1382
1383 return 0;
1384 }
1385
1386 static const struct of_device_id sun50iw10_ccu_ids[] = {
1387 { .compatible = "allwinner,sun50iw10-ccu" },
1388 { }
1389 };
1390
1391 static struct platform_driver sun50iw10_ccu_driver = {
1392 .probe = sun50iw10_ccu_probe,
1393 .driver = {
1394 .name = "sun50iw10-ccu",
1395 .of_match_table = sun50iw10_ccu_ids,
1396 },
1397 };
1398
sunxi_ccu_sun50iw10_init(void)1399 static int __init sunxi_ccu_sun50iw10_init(void)
1400 {
1401 int ret;
1402
1403 ret = platform_driver_register(&sun50iw10_ccu_driver);
1404 if (ret)
1405 pr_err("register ccu sun50iw10 failed\n");
1406
1407 return ret;
1408 }
1409 core_initcall(sunxi_ccu_sun50iw10_init);
1410
sunxi_ccu_sun50iw10_exit(void)1411 static void __exit sunxi_ccu_sun50iw10_exit(void)
1412 {
1413 return platform_driver_unregister(&sun50iw10_ccu_driver);
1414 }
1415 module_exit(sunxi_ccu_sun50iw10_exit);
1416
1417 MODULE_DESCRIPTION("Allwinner sun50iw10 clk driver");
1418 MODULE_LICENSE("GPL v2");
1419 MODULE_VERSION("1.0.6");
1420