1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * Copyright (c) 2017 Icenowy Zheng <icenowy@aosc.io> |
4 | */ |
5 | |
6 | #include <linux/clk-provider.h> |
7 | #include <linux/io.h> |
8 | #include <linux/module.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-sun50i-h6.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 SUN50I_H6_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" , "osc24M" , |
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 SUN50I_H6_PLL_DDR0_REG 0x010 |
50 | static struct ccu_nkmp pll_ddr0_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-ddr0" , "osc24M" , |
59 | &ccu_nkmp_ops, |
60 | CLK_SET_RATE_UNGATE), |
61 | }, |
62 | }; |
63 | |
64 | #define SUN50I_H6_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 = 4, |
72 | .common = { |
73 | .reg = 0x020, |
74 | .features = CCU_FEATURE_FIXED_POSTDIV, |
75 | .hw.init = CLK_HW_INIT("pll-periph0" , "osc24M" , |
76 | &ccu_nkmp_ops, |
77 | CLK_SET_RATE_UNGATE), |
78 | }, |
79 | }; |
80 | |
81 | #define SUN50I_H6_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 = 4, |
89 | .common = { |
90 | .reg = 0x028, |
91 | .features = CCU_FEATURE_FIXED_POSTDIV, |
92 | .hw.init = CLK_HW_INIT("pll-periph1" , "osc24M" , |
93 | &ccu_nkmp_ops, |
94 | CLK_SET_RATE_UNGATE), |
95 | }, |
96 | }; |
97 | |
98 | /* For GPU PLL, using an output divider for DFS causes system to fail */ |
99 | #define SUN50I_H6_PLL_GPU_REG 0x030 |
100 | static struct ccu_nkmp pll_gpu_clk = { |
101 | .enable = BIT(31), |
102 | .lock = BIT(28), |
103 | .n = _SUNXI_CCU_MULT_MIN(8, 8, 12), |
104 | .m = _SUNXI_CCU_DIV(1, 1), /* input divider */ |
105 | .common = { |
106 | .reg = 0x030, |
107 | .hw.init = CLK_HW_INIT("pll-gpu" , "osc24M" , |
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 SUN50I_H6_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" , "osc24M" , |
130 | &ccu_nm_ops, |
131 | CLK_SET_RATE_UNGATE), |
132 | }, |
133 | }; |
134 | |
135 | #define SUN50I_H6_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" , "osc24M" , |
148 | &ccu_nm_ops, |
149 | CLK_SET_RATE_UNGATE), |
150 | }, |
151 | }; |
152 | |
153 | #define SUN50I_H6_PLL_VE_REG 0x058 |
154 | static struct ccu_nkmp pll_ve_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 | .p = _SUNXI_CCU_DIV(0, 1), /* output divider */ |
160 | .common = { |
161 | .reg = 0x058, |
162 | .hw.init = CLK_HW_INIT("pll-ve" , "osc24M" , |
163 | &ccu_nkmp_ops, |
164 | CLK_SET_RATE_UNGATE), |
165 | }, |
166 | }; |
167 | |
168 | #define SUN50I_H6_PLL_DE_REG 0x060 |
169 | static struct ccu_nkmp pll_de_clk = { |
170 | .enable = BIT(31), |
171 | .lock = BIT(28), |
172 | .n = _SUNXI_CCU_MULT_MIN(8, 8, 12), |
173 | .m = _SUNXI_CCU_DIV(1, 1), /* input divider */ |
174 | .p = _SUNXI_CCU_DIV(0, 1), /* output divider */ |
175 | .common = { |
176 | .reg = 0x060, |
177 | .hw.init = CLK_HW_INIT("pll-de" , "osc24M" , |
178 | &ccu_nkmp_ops, |
179 | CLK_SET_RATE_UNGATE), |
180 | }, |
181 | }; |
182 | |
183 | #define SUN50I_H6_PLL_HSIC_REG 0x070 |
184 | static struct ccu_nkmp pll_hsic_clk = { |
185 | .enable = BIT(31), |
186 | .lock = BIT(28), |
187 | .n = _SUNXI_CCU_MULT_MIN(8, 8, 12), |
188 | .m = _SUNXI_CCU_DIV(1, 1), /* input divider */ |
189 | .p = _SUNXI_CCU_DIV(0, 1), /* output divider */ |
190 | .common = { |
191 | .reg = 0x070, |
192 | .hw.init = CLK_HW_INIT("pll-hsic" , "osc24M" , |
193 | &ccu_nkmp_ops, |
194 | CLK_SET_RATE_UNGATE), |
195 | }, |
196 | }; |
197 | |
198 | /* |
199 | * The Audio PLL is supposed to have 3 outputs: 2 fixed factors from |
200 | * the base (2x and 4x), and one variable divider (the one true pll audio). |
201 | * |
202 | * We don't have any need for the variable divider for now, so we just |
203 | * hardcode it to match with the clock names. |
204 | */ |
205 | #define SUN50I_H6_PLL_AUDIO_REG 0x078 |
206 | |
207 | static struct ccu_sdm_setting pll_audio_sdm_table[] = { |
208 | { .rate = 541900800, .pattern = 0xc001288d, .m = 1, .n = 22 }, |
209 | { .rate = 589824000, .pattern = 0xc00126e9, .m = 1, .n = 24 }, |
210 | }; |
211 | |
212 | static struct ccu_nm pll_audio_base_clk = { |
213 | .enable = BIT(31), |
214 | .lock = BIT(28), |
215 | .n = _SUNXI_CCU_MULT_MIN(8, 8, 12), |
216 | .m = _SUNXI_CCU_DIV(1, 1), /* input divider */ |
217 | .sdm = _SUNXI_CCU_SDM(pll_audio_sdm_table, |
218 | BIT(24), 0x178, BIT(31)), |
219 | .common = { |
220 | .features = CCU_FEATURE_SIGMA_DELTA_MOD, |
221 | .reg = 0x078, |
222 | .hw.init = CLK_HW_INIT("pll-audio-base" , "osc24M" , |
223 | &ccu_nm_ops, |
224 | CLK_SET_RATE_UNGATE), |
225 | }, |
226 | }; |
227 | |
228 | static const char * const cpux_parents[] = { "osc24M" , "osc32k" , |
229 | "iosc" , "pll-cpux" }; |
230 | static SUNXI_CCU_MUX(cpux_clk, "cpux" , cpux_parents, |
231 | 0x500, 24, 2, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL); |
232 | static SUNXI_CCU_M(axi_clk, "axi" , "cpux" , 0x500, 0, 2, 0); |
233 | static SUNXI_CCU_M(cpux_apb_clk, "cpux-apb" , "cpux" , 0x500, 8, 2, 0); |
234 | |
235 | static const char * const psi_ahb1_ahb2_parents[] = { "osc24M" , "osc32k" , |
236 | "iosc" , "pll-periph0" }; |
237 | static SUNXI_CCU_MP_WITH_MUX(psi_ahb1_ahb2_clk, "psi-ahb1-ahb2" , |
238 | psi_ahb1_ahb2_parents, |
239 | 0x510, |
240 | 0, 2, /* M */ |
241 | 8, 2, /* P */ |
242 | 24, 2, /* mux */ |
243 | 0); |
244 | |
245 | static const char * const ahb3_apb1_apb2_parents[] = { "osc24M" , "osc32k" , |
246 | "psi-ahb1-ahb2" , |
247 | "pll-periph0" }; |
248 | static SUNXI_CCU_MP_WITH_MUX(ahb3_clk, "ahb3" , ahb3_apb1_apb2_parents, 0x51c, |
249 | 0, 2, /* M */ |
250 | 8, 2, /* P */ |
251 | 24, 2, /* mux */ |
252 | 0); |
253 | |
254 | static SUNXI_CCU_MP_WITH_MUX(apb1_clk, "apb1" , ahb3_apb1_apb2_parents, 0x520, |
255 | 0, 2, /* M */ |
256 | 8, 2, /* P */ |
257 | 24, 2, /* mux */ |
258 | 0); |
259 | |
260 | static SUNXI_CCU_MP_WITH_MUX(apb2_clk, "apb2" , ahb3_apb1_apb2_parents, 0x524, |
261 | 0, 2, /* M */ |
262 | 8, 2, /* P */ |
263 | 24, 2, /* mux */ |
264 | 0); |
265 | |
266 | static const char * const mbus_parents[] = { "osc24M" , "pll-periph0-2x" , |
267 | "pll-ddr0" , "pll-periph0-4x" }; |
268 | static SUNXI_CCU_M_WITH_MUX_GATE(mbus_clk, "mbus" , mbus_parents, 0x540, |
269 | 0, 3, /* M */ |
270 | 24, 2, /* mux */ |
271 | BIT(31), /* gate */ |
272 | CLK_IS_CRITICAL); |
273 | |
274 | static const char * const de_parents[] = { "pll-de" , "pll-periph0-2x" }; |
275 | static SUNXI_CCU_M_WITH_MUX_GATE(de_clk, "de" , de_parents, 0x600, |
276 | 0, 4, /* M */ |
277 | 24, 1, /* mux */ |
278 | BIT(31), /* gate */ |
279 | CLK_SET_RATE_PARENT); |
280 | |
281 | static SUNXI_CCU_GATE(bus_de_clk, "bus-de" , "psi-ahb1-ahb2" , |
282 | 0x60c, BIT(0), 0); |
283 | |
284 | static const char * const deinterlace_parents[] = { "pll-periph0" , |
285 | "pll-periph1" }; |
286 | static SUNXI_CCU_M_WITH_MUX_GATE(deinterlace_clk, "deinterlace" , |
287 | deinterlace_parents, |
288 | 0x620, |
289 | 0, 4, /* M */ |
290 | 24, 1, /* mux */ |
291 | BIT(31), /* gate */ |
292 | 0); |
293 | |
294 | static SUNXI_CCU_GATE(bus_deinterlace_clk, "bus-deinterlace" , "psi-ahb1-ahb2" , |
295 | 0x62c, BIT(0), 0); |
296 | |
297 | /* Keep GPU_CLK divider const to avoid DFS instability. */ |
298 | static const char * const gpu_parents[] = { "pll-gpu" }; |
299 | static SUNXI_CCU_MUX_WITH_GATE(gpu_clk, "gpu" , gpu_parents, 0x670, |
300 | 24, 1, /* mux */ |
301 | BIT(31), /* gate */ |
302 | CLK_SET_RATE_PARENT); |
303 | |
304 | static SUNXI_CCU_GATE(bus_gpu_clk, "bus-gpu" , "psi-ahb1-ahb2" , |
305 | 0x67c, BIT(0), 0); |
306 | |
307 | /* Also applies to EMCE */ |
308 | static const char * const ce_parents[] = { "osc24M" , "pll-periph0-2x" }; |
309 | static SUNXI_CCU_MP_WITH_MUX_GATE(ce_clk, "ce" , ce_parents, 0x680, |
310 | 0, 4, /* M */ |
311 | 8, 2, /* N */ |
312 | 24, 1, /* mux */ |
313 | BIT(31),/* gate */ |
314 | 0); |
315 | |
316 | static SUNXI_CCU_GATE(bus_ce_clk, "bus-ce" , "psi-ahb1-ahb2" , |
317 | 0x68c, BIT(0), 0); |
318 | |
319 | static const char * const ve_parents[] = { "pll-ve" }; |
320 | static SUNXI_CCU_M_WITH_MUX_GATE(ve_clk, "ve" , ve_parents, 0x690, |
321 | 0, 3, /* M */ |
322 | 24, 1, /* mux */ |
323 | BIT(31), /* gate */ |
324 | CLK_SET_RATE_PARENT); |
325 | |
326 | static SUNXI_CCU_GATE(bus_ve_clk, "bus-ve" , "psi-ahb1-ahb2" , |
327 | 0x69c, BIT(0), 0); |
328 | |
329 | static SUNXI_CCU_MP_WITH_MUX_GATE(emce_clk, "emce" , ce_parents, 0x6b0, |
330 | 0, 4, /* M */ |
331 | 8, 2, /* N */ |
332 | 24, 1, /* mux */ |
333 | BIT(31),/* gate */ |
334 | 0); |
335 | |
336 | static SUNXI_CCU_GATE(bus_emce_clk, "bus-emce" , "psi-ahb1-ahb2" , |
337 | 0x6bc, BIT(0), 0); |
338 | |
339 | static const char * const vp9_parents[] = { "pll-ve" , "pll-periph0-2x" }; |
340 | static SUNXI_CCU_M_WITH_MUX_GATE(vp9_clk, "vp9" , vp9_parents, 0x6c0, |
341 | 0, 3, /* M */ |
342 | 24, 1, /* mux */ |
343 | BIT(31), /* gate */ |
344 | 0); |
345 | |
346 | static SUNXI_CCU_GATE(bus_vp9_clk, "bus-vp9" , "psi-ahb1-ahb2" , |
347 | 0x6cc, BIT(0), 0); |
348 | |
349 | static SUNXI_CCU_GATE(bus_dma_clk, "bus-dma" , "psi-ahb1-ahb2" , |
350 | 0x70c, BIT(0), 0); |
351 | |
352 | static SUNXI_CCU_GATE(bus_msgbox_clk, "bus-msgbox" , "psi-ahb1-ahb2" , |
353 | 0x71c, BIT(0), 0); |
354 | |
355 | static SUNXI_CCU_GATE(bus_spinlock_clk, "bus-spinlock" , "psi-ahb1-ahb2" , |
356 | 0x72c, BIT(0), 0); |
357 | |
358 | static SUNXI_CCU_GATE(bus_hstimer_clk, "bus-hstimer" , "psi-ahb1-ahb2" , |
359 | 0x73c, BIT(0), 0); |
360 | |
361 | static SUNXI_CCU_GATE(avs_clk, "avs" , "osc24M" , 0x740, BIT(31), 0); |
362 | |
363 | static SUNXI_CCU_GATE(bus_dbg_clk, "bus-dbg" , "psi-ahb1-ahb2" , |
364 | 0x78c, BIT(0), 0); |
365 | |
366 | static SUNXI_CCU_GATE(bus_psi_clk, "bus-psi" , "psi-ahb1-ahb2" , |
367 | 0x79c, BIT(0), 0); |
368 | |
369 | static SUNXI_CCU_GATE(bus_pwm_clk, "bus-pwm" , "apb1" , 0x7ac, BIT(0), 0); |
370 | |
371 | static SUNXI_CCU_GATE(bus_iommu_clk, "bus-iommu" , "apb1" , 0x7bc, BIT(0), 0); |
372 | |
373 | static const char * const dram_parents[] = { "pll-ddr0" }; |
374 | static struct ccu_div dram_clk = { |
375 | .div = _SUNXI_CCU_DIV(0, 2), |
376 | .mux = _SUNXI_CCU_MUX(24, 2), |
377 | .common = { |
378 | .reg = 0x800, |
379 | .hw.init = CLK_HW_INIT_PARENTS("dram" , |
380 | dram_parents, |
381 | &ccu_div_ops, |
382 | CLK_IS_CRITICAL), |
383 | }, |
384 | }; |
385 | |
386 | static SUNXI_CCU_GATE(mbus_dma_clk, "mbus-dma" , "mbus" , |
387 | 0x804, BIT(0), 0); |
388 | static SUNXI_CCU_GATE(mbus_ve_clk, "mbus-ve" , "mbus" , |
389 | 0x804, BIT(1), 0); |
390 | static SUNXI_CCU_GATE(mbus_ce_clk, "mbus-ce" , "mbus" , |
391 | 0x804, BIT(2), 0); |
392 | static SUNXI_CCU_GATE(mbus_ts_clk, "mbus-ts" , "mbus" , |
393 | 0x804, BIT(3), 0); |
394 | static SUNXI_CCU_GATE(mbus_nand_clk, "mbus-nand" , "mbus" , |
395 | 0x804, BIT(5), 0); |
396 | static SUNXI_CCU_GATE(mbus_csi_clk, "mbus-csi" , "mbus" , |
397 | 0x804, BIT(8), 0); |
398 | static SUNXI_CCU_GATE(mbus_deinterlace_clk, "mbus-deinterlace" , "mbus" , |
399 | 0x804, BIT(11), 0); |
400 | |
401 | static SUNXI_CCU_GATE(bus_dram_clk, "bus-dram" , "psi-ahb1-ahb2" , |
402 | 0x80c, BIT(0), CLK_IS_CRITICAL); |
403 | |
404 | static const char * const nand_spi_parents[] = { "osc24M" , "pll-periph0" , |
405 | "pll-periph1" , "pll-periph0-2x" , |
406 | "pll-periph1-2x" }; |
407 | static SUNXI_CCU_MP_WITH_MUX_GATE(nand0_clk, "nand0" , nand_spi_parents, 0x810, |
408 | 0, 4, /* M */ |
409 | 8, 2, /* N */ |
410 | 24, 3, /* mux */ |
411 | BIT(31),/* gate */ |
412 | 0); |
413 | |
414 | static SUNXI_CCU_MP_WITH_MUX_GATE(nand1_clk, "nand1" , nand_spi_parents, 0x814, |
415 | 0, 4, /* M */ |
416 | 8, 2, /* N */ |
417 | 24, 3, /* mux */ |
418 | BIT(31),/* gate */ |
419 | 0); |
420 | |
421 | static SUNXI_CCU_GATE(bus_nand_clk, "bus-nand" , "ahb3" , 0x82c, BIT(0), 0); |
422 | |
423 | static const char * const mmc_parents[] = { "osc24M" , "pll-periph0-2x" , |
424 | "pll-periph1-2x" }; |
425 | static SUNXI_CCU_MP_WITH_MUX_GATE_POSTDIV(mmc0_clk, "mmc0" , mmc_parents, 0x830, |
426 | 0, 4, /* M */ |
427 | 8, 2, /* N */ |
428 | 24, 2, /* mux */ |
429 | BIT(31), /* gate */ |
430 | 2, /* post-div */ |
431 | 0); |
432 | |
433 | static SUNXI_CCU_MP_WITH_MUX_GATE_POSTDIV(mmc1_clk, "mmc1" , mmc_parents, 0x834, |
434 | 0, 4, /* M */ |
435 | 8, 2, /* N */ |
436 | 24, 2, /* mux */ |
437 | BIT(31), /* gate */ |
438 | 2, /* post-div */ |
439 | 0); |
440 | |
441 | static SUNXI_CCU_MP_WITH_MUX_GATE_POSTDIV(mmc2_clk, "mmc2" , mmc_parents, 0x838, |
442 | 0, 4, /* M */ |
443 | 8, 2, /* N */ |
444 | 24, 2, /* mux */ |
445 | BIT(31), /* gate */ |
446 | 2, /* post-div */ |
447 | 0); |
448 | |
449 | static SUNXI_CCU_GATE(bus_mmc0_clk, "bus-mmc0" , "ahb3" , 0x84c, BIT(0), 0); |
450 | static SUNXI_CCU_GATE(bus_mmc1_clk, "bus-mmc1" , "ahb3" , 0x84c, BIT(1), 0); |
451 | static SUNXI_CCU_GATE(bus_mmc2_clk, "bus-mmc2" , "ahb3" , 0x84c, BIT(2), 0); |
452 | |
453 | static SUNXI_CCU_GATE(bus_uart0_clk, "bus-uart0" , "apb2" , 0x90c, BIT(0), 0); |
454 | static SUNXI_CCU_GATE(bus_uart1_clk, "bus-uart1" , "apb2" , 0x90c, BIT(1), 0); |
455 | static SUNXI_CCU_GATE(bus_uart2_clk, "bus-uart2" , "apb2" , 0x90c, BIT(2), 0); |
456 | static SUNXI_CCU_GATE(bus_uart3_clk, "bus-uart3" , "apb2" , 0x90c, BIT(3), 0); |
457 | |
458 | static SUNXI_CCU_GATE(bus_i2c0_clk, "bus-i2c0" , "apb2" , 0x91c, BIT(0), 0); |
459 | static SUNXI_CCU_GATE(bus_i2c1_clk, "bus-i2c1" , "apb2" , 0x91c, BIT(1), 0); |
460 | static SUNXI_CCU_GATE(bus_i2c2_clk, "bus-i2c2" , "apb2" , 0x91c, BIT(2), 0); |
461 | static SUNXI_CCU_GATE(bus_i2c3_clk, "bus-i2c3" , "apb2" , 0x91c, BIT(3), 0); |
462 | |
463 | static SUNXI_CCU_GATE(bus_scr0_clk, "bus-scr0" , "apb2" , 0x93c, BIT(0), 0); |
464 | static SUNXI_CCU_GATE(bus_scr1_clk, "bus-scr1" , "apb2" , 0x93c, BIT(1), 0); |
465 | |
466 | static SUNXI_CCU_MP_WITH_MUX_GATE(spi0_clk, "spi0" , nand_spi_parents, 0x940, |
467 | 0, 4, /* M */ |
468 | 8, 2, /* N */ |
469 | 24, 3, /* mux */ |
470 | BIT(31),/* gate */ |
471 | 0); |
472 | |
473 | static SUNXI_CCU_MP_WITH_MUX_GATE(spi1_clk, "spi1" , nand_spi_parents, 0x944, |
474 | 0, 4, /* M */ |
475 | 8, 2, /* N */ |
476 | 24, 3, /* mux */ |
477 | BIT(31),/* gate */ |
478 | 0); |
479 | |
480 | static SUNXI_CCU_GATE(bus_spi0_clk, "bus-spi0" , "ahb3" , 0x96c, BIT(0), 0); |
481 | static SUNXI_CCU_GATE(bus_spi1_clk, "bus-spi1" , "ahb3" , 0x96c, BIT(1), 0); |
482 | |
483 | static SUNXI_CCU_GATE(bus_emac_clk, "bus-emac" , "ahb3" , 0x97c, BIT(0), 0); |
484 | |
485 | static const char * const ts_parents[] = { "osc24M" , "pll-periph0" }; |
486 | static SUNXI_CCU_MP_WITH_MUX_GATE(ts_clk, "ts" , ts_parents, 0x9b0, |
487 | 0, 4, /* M */ |
488 | 8, 2, /* N */ |
489 | 24, 1, /* mux */ |
490 | BIT(31),/* gate */ |
491 | 0); |
492 | |
493 | static SUNXI_CCU_GATE(bus_ts_clk, "bus-ts" , "ahb3" , 0x9bc, BIT(0), 0); |
494 | |
495 | static const char * const ir_tx_parents[] = { "osc32k" , "osc24M" }; |
496 | static SUNXI_CCU_MP_WITH_MUX_GATE(ir_tx_clk, "ir-tx" , ir_tx_parents, 0x9c0, |
497 | 0, 4, /* M */ |
498 | 8, 2, /* N */ |
499 | 24, 1, /* mux */ |
500 | BIT(31),/* gate */ |
501 | 0); |
502 | |
503 | static SUNXI_CCU_GATE(bus_ir_tx_clk, "bus-ir-tx" , "apb1" , 0x9cc, BIT(0), 0); |
504 | |
505 | static SUNXI_CCU_GATE(bus_ths_clk, "bus-ths" , "apb1" , 0x9fc, BIT(0), 0); |
506 | |
507 | static const char * const audio_parents[] = { "pll-audio" , "pll-audio-2x" , "pll-audio-4x" }; |
508 | static struct ccu_div i2s3_clk = { |
509 | .enable = BIT(31), |
510 | .div = _SUNXI_CCU_DIV_FLAGS(8, 2, CLK_DIVIDER_POWER_OF_TWO), |
511 | .mux = _SUNXI_CCU_MUX(24, 2), |
512 | .common = { |
513 | .reg = 0xa0c, |
514 | .hw.init = CLK_HW_INIT_PARENTS("i2s3" , |
515 | audio_parents, |
516 | &ccu_div_ops, |
517 | CLK_SET_RATE_PARENT), |
518 | }, |
519 | }; |
520 | |
521 | static struct ccu_div i2s0_clk = { |
522 | .enable = BIT(31), |
523 | .div = _SUNXI_CCU_DIV_FLAGS(8, 2, CLK_DIVIDER_POWER_OF_TWO), |
524 | .mux = _SUNXI_CCU_MUX(24, 2), |
525 | .common = { |
526 | .reg = 0xa10, |
527 | .hw.init = CLK_HW_INIT_PARENTS("i2s0" , |
528 | audio_parents, |
529 | &ccu_div_ops, |
530 | CLK_SET_RATE_PARENT), |
531 | }, |
532 | }; |
533 | |
534 | static struct ccu_div i2s1_clk = { |
535 | .enable = BIT(31), |
536 | .div = _SUNXI_CCU_DIV_FLAGS(8, 2, CLK_DIVIDER_POWER_OF_TWO), |
537 | .mux = _SUNXI_CCU_MUX(24, 2), |
538 | .common = { |
539 | .reg = 0xa14, |
540 | .hw.init = CLK_HW_INIT_PARENTS("i2s1" , |
541 | audio_parents, |
542 | &ccu_div_ops, |
543 | CLK_SET_RATE_PARENT), |
544 | }, |
545 | }; |
546 | |
547 | static struct ccu_div i2s2_clk = { |
548 | .enable = BIT(31), |
549 | .div = _SUNXI_CCU_DIV_FLAGS(8, 2, CLK_DIVIDER_POWER_OF_TWO), |
550 | .mux = _SUNXI_CCU_MUX(24, 2), |
551 | .common = { |
552 | .reg = 0xa18, |
553 | .hw.init = CLK_HW_INIT_PARENTS("i2s2" , |
554 | audio_parents, |
555 | &ccu_div_ops, |
556 | CLK_SET_RATE_PARENT), |
557 | }, |
558 | }; |
559 | |
560 | static SUNXI_CCU_GATE(bus_i2s0_clk, "bus-i2s0" , "apb1" , 0xa1c, BIT(0), 0); |
561 | static SUNXI_CCU_GATE(bus_i2s1_clk, "bus-i2s1" , "apb1" , 0xa1c, BIT(1), 0); |
562 | static SUNXI_CCU_GATE(bus_i2s2_clk, "bus-i2s2" , "apb1" , 0xa1c, BIT(2), 0); |
563 | static SUNXI_CCU_GATE(bus_i2s3_clk, "bus-i2s3" , "apb1" , 0xa1c, BIT(3), 0); |
564 | |
565 | static struct ccu_div spdif_clk = { |
566 | .enable = BIT(31), |
567 | .div = _SUNXI_CCU_DIV_FLAGS(8, 2, CLK_DIVIDER_POWER_OF_TWO), |
568 | .mux = _SUNXI_CCU_MUX(24, 2), |
569 | .common = { |
570 | .reg = 0xa20, |
571 | .hw.init = CLK_HW_INIT_PARENTS("spdif" , |
572 | audio_parents, |
573 | &ccu_div_ops, |
574 | 0), |
575 | }, |
576 | }; |
577 | |
578 | static SUNXI_CCU_GATE(bus_spdif_clk, "bus-spdif" , "apb1" , 0xa2c, BIT(0), 0); |
579 | |
580 | static struct ccu_div dmic_clk = { |
581 | .enable = BIT(31), |
582 | .div = _SUNXI_CCU_DIV_FLAGS(8, 2, CLK_DIVIDER_POWER_OF_TWO), |
583 | .mux = _SUNXI_CCU_MUX(24, 2), |
584 | .common = { |
585 | .reg = 0xa40, |
586 | .hw.init = CLK_HW_INIT_PARENTS("dmic" , |
587 | audio_parents, |
588 | &ccu_div_ops, |
589 | 0), |
590 | }, |
591 | }; |
592 | |
593 | static SUNXI_CCU_GATE(bus_dmic_clk, "bus-dmic" , "apb1" , 0xa4c, BIT(0), 0); |
594 | |
595 | static struct ccu_div audio_hub_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 = 0xa60, |
601 | .hw.init = CLK_HW_INIT_PARENTS("audio-hub" , |
602 | audio_parents, |
603 | &ccu_div_ops, |
604 | 0), |
605 | }, |
606 | }; |
607 | |
608 | static SUNXI_CCU_GATE(bus_audio_hub_clk, "bus-audio-hub" , "apb1" , 0xa6c, BIT(0), 0); |
609 | |
610 | /* |
611 | * There are OHCI 12M clock source selection bits for 2 USB 2.0 ports. |
612 | * We will force them to 0 (12M divided from 48M). |
613 | */ |
614 | #define SUN50I_H6_USB0_CLK_REG 0xa70 |
615 | #define SUN50I_H6_USB3_CLK_REG 0xa7c |
616 | |
617 | static SUNXI_CCU_GATE(usb_ohci0_clk, "usb-ohci0" , "osc12M" , 0xa70, BIT(31), 0); |
618 | static SUNXI_CCU_GATE(usb_phy0_clk, "usb-phy0" , "osc24M" , 0xa70, BIT(29), 0); |
619 | |
620 | static SUNXI_CCU_GATE(usb_phy1_clk, "usb-phy1" , "osc24M" , 0xa74, BIT(29), 0); |
621 | |
622 | static SUNXI_CCU_GATE(usb_ohci3_clk, "usb-ohci3" , "osc12M" , 0xa7c, BIT(31), 0); |
623 | static SUNXI_CCU_GATE(usb_phy3_clk, "usb-phy3" , "osc12M" , 0xa7c, BIT(29), 0); |
624 | static SUNXI_CCU_GATE(usb_hsic_12m_clk, "usb-hsic-12M" , "osc12M" , 0xa7c, BIT(27), 0); |
625 | static SUNXI_CCU_GATE(usb_hsic_clk, "usb-hsic" , "pll-hsic" , 0xa7c, BIT(26), 0); |
626 | |
627 | static SUNXI_CCU_GATE(bus_ohci0_clk, "bus-ohci0" , "ahb3" , 0xa8c, BIT(0), 0); |
628 | static SUNXI_CCU_GATE(bus_ohci3_clk, "bus-ohci3" , "ahb3" , 0xa8c, BIT(3), 0); |
629 | static SUNXI_CCU_GATE(bus_ehci0_clk, "bus-ehci0" , "ahb3" , 0xa8c, BIT(4), 0); |
630 | static SUNXI_CCU_GATE(bus_xhci_clk, "bus-xhci" , "ahb3" , 0xa8c, BIT(5), 0); |
631 | static SUNXI_CCU_GATE(bus_ehci3_clk, "bus-ehci3" , "ahb3" , 0xa8c, BIT(7), 0); |
632 | static SUNXI_CCU_GATE(bus_otg_clk, "bus-otg" , "ahb3" , 0xa8c, BIT(8), 0); |
633 | |
634 | static struct clk_fixed_factor pll_periph0_4x_clk; |
635 | static CLK_FIXED_FACTOR_HW(pcie_ref_100m_clk, "pcie-ref-100M" , |
636 | &pll_periph0_4x_clk.hw, 24, 1, 0); |
637 | static SUNXI_CCU_GATE(pcie_ref_clk, "pcie-ref" , "pcie-ref-100M" , |
638 | 0xab0, BIT(31), 0); |
639 | static SUNXI_CCU_GATE(pcie_ref_out_clk, "pcie-ref-out" , "pcie-ref" , |
640 | 0xab0, BIT(30), 0); |
641 | |
642 | static SUNXI_CCU_M_WITH_GATE(pcie_maxi_clk, "pcie-maxi" , |
643 | "pll-periph0" , 0xab4, |
644 | 0, 4, /* M */ |
645 | BIT(31), /* gate */ |
646 | 0); |
647 | |
648 | static SUNXI_CCU_M_WITH_GATE(pcie_aux_clk, "pcie-aux" , "osc24M" , 0xab8, |
649 | 0, 5, /* M */ |
650 | BIT(31), /* gate */ |
651 | 0); |
652 | |
653 | static SUNXI_CCU_GATE(bus_pcie_clk, "bus-pcie" , "psi-ahb1-ahb2" , |
654 | 0xabc, BIT(0), 0); |
655 | |
656 | static const char * const hdmi_parents[] = { "pll-video0" , "pll-video1" , |
657 | "pll-video1-4x" }; |
658 | static SUNXI_CCU_M_WITH_MUX_GATE(hdmi_clk, "hdmi" , hdmi_parents, 0xb00, |
659 | 0, 4, /* M */ |
660 | 24, 2, /* mux */ |
661 | BIT(31), /* gate */ |
662 | 0); |
663 | |
664 | static SUNXI_CCU_GATE(hdmi_slow_clk, "hdmi-slow" , "osc24M" , 0xb04, BIT(31), 0); |
665 | |
666 | static const char * const hdmi_cec_parents[] = { "osc32k" , "pll-periph0-2x" }; |
667 | static const struct ccu_mux_fixed_prediv hdmi_cec_predivs[] = { |
668 | { .index = 1, .div = 36621 }, |
669 | }; |
670 | |
671 | #define SUN50I_H6_HDMI_CEC_CLK_REG 0xb10 |
672 | static struct ccu_mux hdmi_cec_clk = { |
673 | .enable = BIT(31), |
674 | |
675 | .mux = { |
676 | .shift = 24, |
677 | .width = 2, |
678 | |
679 | .fixed_predivs = hdmi_cec_predivs, |
680 | .n_predivs = ARRAY_SIZE(hdmi_cec_predivs), |
681 | }, |
682 | |
683 | .common = { |
684 | .reg = 0xb10, |
685 | .features = CCU_FEATURE_FIXED_PREDIV, |
686 | .hw.init = CLK_HW_INIT_PARENTS("hdmi-cec" , |
687 | hdmi_cec_parents, |
688 | &ccu_mux_ops, |
689 | 0), |
690 | }, |
691 | }; |
692 | |
693 | static SUNXI_CCU_GATE(bus_hdmi_clk, "bus-hdmi" , "ahb3" , 0xb1c, BIT(0), 0); |
694 | |
695 | static SUNXI_CCU_GATE(bus_tcon_top_clk, "bus-tcon-top" , "ahb3" , |
696 | 0xb5c, BIT(0), 0); |
697 | |
698 | static const char * const tcon_lcd0_parents[] = { "pll-video0" , |
699 | "pll-video0-4x" , |
700 | "pll-video1" }; |
701 | static SUNXI_CCU_MUX_WITH_GATE(tcon_lcd0_clk, "tcon-lcd0" , |
702 | tcon_lcd0_parents, 0xb60, |
703 | 24, 3, /* mux */ |
704 | BIT(31), /* gate */ |
705 | CLK_SET_RATE_PARENT); |
706 | |
707 | static SUNXI_CCU_GATE(bus_tcon_lcd0_clk, "bus-tcon-lcd0" , "ahb3" , |
708 | 0xb7c, BIT(0), 0); |
709 | |
710 | static const char * const tcon_tv0_parents[] = { "pll-video0" , |
711 | "pll-video0-4x" , |
712 | "pll-video1" , |
713 | "pll-video1-4x" }; |
714 | static SUNXI_CCU_MP_WITH_MUX_GATE(tcon_tv0_clk, "tcon-tv0" , |
715 | tcon_tv0_parents, 0xb80, |
716 | 0, 4, /* M */ |
717 | 8, 2, /* P */ |
718 | 24, 3, /* mux */ |
719 | BIT(31), /* gate */ |
720 | CLK_SET_RATE_PARENT); |
721 | |
722 | static SUNXI_CCU_GATE(bus_tcon_tv0_clk, "bus-tcon-tv0" , "ahb3" , |
723 | 0xb9c, BIT(0), 0); |
724 | |
725 | static SUNXI_CCU_GATE(csi_cci_clk, "csi-cci" , "osc24M" , 0xc00, BIT(0), 0); |
726 | |
727 | static const char * const csi_top_parents[] = { "pll-video0" , "pll-ve" , |
728 | "pll-periph0" }; |
729 | static const u8 csi_top_table[] = { 0, 2, 3 }; |
730 | static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(csi_top_clk, "csi-top" , |
731 | csi_top_parents, csi_top_table, 0xc04, |
732 | 0, 4, /* M */ |
733 | 24, 3, /* mux */ |
734 | BIT(31), /* gate */ |
735 | 0); |
736 | |
737 | static const char * const csi_mclk_parents[] = { "osc24M" , "pll-video0" , |
738 | "pll-periph0" , "pll-periph1" }; |
739 | static SUNXI_CCU_M_WITH_MUX_GATE(csi_mclk_clk, "csi-mclk" , |
740 | csi_mclk_parents, 0xc08, |
741 | 0, 5, /* M */ |
742 | 24, 3, /* mux */ |
743 | BIT(31), /* gate */ |
744 | 0); |
745 | |
746 | static SUNXI_CCU_GATE(bus_csi_clk, "bus-csi" , "ahb3" , 0xc2c, BIT(0), 0); |
747 | |
748 | static const char * const hdcp_parents[] = { "pll-periph0" , "pll-periph1" }; |
749 | static SUNXI_CCU_M_WITH_MUX_GATE(hdcp_clk, "hdcp" , hdcp_parents, 0xc40, |
750 | 0, 4, /* M */ |
751 | 24, 2, /* mux */ |
752 | BIT(31), /* gate */ |
753 | 0); |
754 | |
755 | static SUNXI_CCU_GATE(bus_hdcp_clk, "bus-hdcp" , "ahb3" , 0xc4c, BIT(0), 0); |
756 | |
757 | /* Fixed factor clocks */ |
758 | static CLK_FIXED_FACTOR_FW_NAME(osc12M_clk, "osc12M" , "hosc" , 2, 1, 0); |
759 | |
760 | static const struct clk_hw *clk_parent_pll_audio[] = { |
761 | &pll_audio_base_clk.common.hw |
762 | }; |
763 | |
764 | /* |
765 | * The divider of pll-audio is fixed to 24 for now, so 24576000 and 22579200 |
766 | * rates can be set exactly in conjunction with sigma-delta modulation. |
767 | */ |
768 | static CLK_FIXED_FACTOR_HWS(pll_audio_clk, "pll-audio" , |
769 | clk_parent_pll_audio, |
770 | 24, 1, CLK_SET_RATE_PARENT); |
771 | static CLK_FIXED_FACTOR_HWS(pll_audio_2x_clk, "pll-audio-2x" , |
772 | clk_parent_pll_audio, |
773 | 4, 1, CLK_SET_RATE_PARENT); |
774 | static CLK_FIXED_FACTOR_HWS(pll_audio_4x_clk, "pll-audio-4x" , |
775 | clk_parent_pll_audio, |
776 | 2, 1, CLK_SET_RATE_PARENT); |
777 | |
778 | static const struct clk_hw *pll_periph0_parents[] = { |
779 | &pll_periph0_clk.common.hw |
780 | }; |
781 | static CLK_FIXED_FACTOR_HWS(pll_periph0_4x_clk, "pll-periph0-4x" , |
782 | pll_periph0_parents, |
783 | 1, 4, 0); |
784 | static CLK_FIXED_FACTOR_HWS(pll_periph0_2x_clk, "pll-periph0-2x" , |
785 | pll_periph0_parents, |
786 | 1, 2, 0); |
787 | |
788 | static const struct clk_hw *pll_periph1_parents[] = { |
789 | &pll_periph1_clk.common.hw |
790 | }; |
791 | static CLK_FIXED_FACTOR_HWS(pll_periph1_4x_clk, "pll-periph1-4x" , |
792 | pll_periph1_parents, |
793 | 1, 4, 0); |
794 | static CLK_FIXED_FACTOR_HWS(pll_periph1_2x_clk, "pll-periph1-2x" , |
795 | pll_periph1_parents, |
796 | 1, 2, 0); |
797 | |
798 | static CLK_FIXED_FACTOR_HW(pll_video0_4x_clk, "pll-video0-4x" , |
799 | &pll_video0_clk.common.hw, |
800 | 1, 4, CLK_SET_RATE_PARENT); |
801 | static CLK_FIXED_FACTOR_HW(pll_video1_4x_clk, "pll-video1-4x" , |
802 | &pll_video1_clk.common.hw, |
803 | 1, 4, CLK_SET_RATE_PARENT); |
804 | |
805 | static struct ccu_common *sun50i_h6_ccu_clks[] = { |
806 | &pll_cpux_clk.common, |
807 | &pll_ddr0_clk.common, |
808 | &pll_periph0_clk.common, |
809 | &pll_periph1_clk.common, |
810 | &pll_gpu_clk.common, |
811 | &pll_video0_clk.common, |
812 | &pll_video1_clk.common, |
813 | &pll_ve_clk.common, |
814 | &pll_de_clk.common, |
815 | &pll_hsic_clk.common, |
816 | &pll_audio_base_clk.common, |
817 | &cpux_clk.common, |
818 | &axi_clk.common, |
819 | &cpux_apb_clk.common, |
820 | &psi_ahb1_ahb2_clk.common, |
821 | &ahb3_clk.common, |
822 | &apb1_clk.common, |
823 | &apb2_clk.common, |
824 | &mbus_clk.common, |
825 | &de_clk.common, |
826 | &bus_de_clk.common, |
827 | &deinterlace_clk.common, |
828 | &bus_deinterlace_clk.common, |
829 | &gpu_clk.common, |
830 | &bus_gpu_clk.common, |
831 | &ce_clk.common, |
832 | &bus_ce_clk.common, |
833 | &ve_clk.common, |
834 | &bus_ve_clk.common, |
835 | &emce_clk.common, |
836 | &bus_emce_clk.common, |
837 | &vp9_clk.common, |
838 | &bus_vp9_clk.common, |
839 | &bus_dma_clk.common, |
840 | &bus_msgbox_clk.common, |
841 | &bus_spinlock_clk.common, |
842 | &bus_hstimer_clk.common, |
843 | &avs_clk.common, |
844 | &bus_dbg_clk.common, |
845 | &bus_psi_clk.common, |
846 | &bus_pwm_clk.common, |
847 | &bus_iommu_clk.common, |
848 | &dram_clk.common, |
849 | &mbus_dma_clk.common, |
850 | &mbus_ve_clk.common, |
851 | &mbus_ce_clk.common, |
852 | &mbus_ts_clk.common, |
853 | &mbus_nand_clk.common, |
854 | &mbus_csi_clk.common, |
855 | &mbus_deinterlace_clk.common, |
856 | &bus_dram_clk.common, |
857 | &nand0_clk.common, |
858 | &nand1_clk.common, |
859 | &bus_nand_clk.common, |
860 | &mmc0_clk.common, |
861 | &mmc1_clk.common, |
862 | &mmc2_clk.common, |
863 | &bus_mmc0_clk.common, |
864 | &bus_mmc1_clk.common, |
865 | &bus_mmc2_clk.common, |
866 | &bus_uart0_clk.common, |
867 | &bus_uart1_clk.common, |
868 | &bus_uart2_clk.common, |
869 | &bus_uart3_clk.common, |
870 | &bus_i2c0_clk.common, |
871 | &bus_i2c1_clk.common, |
872 | &bus_i2c2_clk.common, |
873 | &bus_i2c3_clk.common, |
874 | &bus_scr0_clk.common, |
875 | &bus_scr1_clk.common, |
876 | &spi0_clk.common, |
877 | &spi1_clk.common, |
878 | &bus_spi0_clk.common, |
879 | &bus_spi1_clk.common, |
880 | &bus_emac_clk.common, |
881 | &ts_clk.common, |
882 | &bus_ts_clk.common, |
883 | &ir_tx_clk.common, |
884 | &bus_ir_tx_clk.common, |
885 | &bus_ths_clk.common, |
886 | &i2s3_clk.common, |
887 | &i2s0_clk.common, |
888 | &i2s1_clk.common, |
889 | &i2s2_clk.common, |
890 | &bus_i2s0_clk.common, |
891 | &bus_i2s1_clk.common, |
892 | &bus_i2s2_clk.common, |
893 | &bus_i2s3_clk.common, |
894 | &spdif_clk.common, |
895 | &bus_spdif_clk.common, |
896 | &dmic_clk.common, |
897 | &bus_dmic_clk.common, |
898 | &audio_hub_clk.common, |
899 | &bus_audio_hub_clk.common, |
900 | &usb_ohci0_clk.common, |
901 | &usb_phy0_clk.common, |
902 | &usb_phy1_clk.common, |
903 | &usb_ohci3_clk.common, |
904 | &usb_phy3_clk.common, |
905 | &usb_hsic_12m_clk.common, |
906 | &usb_hsic_clk.common, |
907 | &bus_ohci0_clk.common, |
908 | &bus_ohci3_clk.common, |
909 | &bus_ehci0_clk.common, |
910 | &bus_xhci_clk.common, |
911 | &bus_ehci3_clk.common, |
912 | &bus_otg_clk.common, |
913 | &pcie_ref_clk.common, |
914 | &pcie_ref_out_clk.common, |
915 | &pcie_maxi_clk.common, |
916 | &pcie_aux_clk.common, |
917 | &bus_pcie_clk.common, |
918 | &hdmi_clk.common, |
919 | &hdmi_slow_clk.common, |
920 | &hdmi_cec_clk.common, |
921 | &bus_hdmi_clk.common, |
922 | &bus_tcon_top_clk.common, |
923 | &tcon_lcd0_clk.common, |
924 | &bus_tcon_lcd0_clk.common, |
925 | &tcon_tv0_clk.common, |
926 | &bus_tcon_tv0_clk.common, |
927 | &csi_cci_clk.common, |
928 | &csi_top_clk.common, |
929 | &csi_mclk_clk.common, |
930 | &bus_csi_clk.common, |
931 | &hdcp_clk.common, |
932 | &bus_hdcp_clk.common, |
933 | }; |
934 | |
935 | static struct clk_hw_onecell_data sun50i_h6_hw_clks = { |
936 | .hws = { |
937 | [CLK_OSC12M] = &osc12M_clk.hw, |
938 | [CLK_PLL_CPUX] = &pll_cpux_clk.common.hw, |
939 | [CLK_PLL_DDR0] = &pll_ddr0_clk.common.hw, |
940 | [CLK_PLL_PERIPH0] = &pll_periph0_clk.common.hw, |
941 | [CLK_PLL_PERIPH0_2X] = &pll_periph0_2x_clk.hw, |
942 | [CLK_PLL_PERIPH0_4X] = &pll_periph0_4x_clk.hw, |
943 | [CLK_PLL_PERIPH1] = &pll_periph1_clk.common.hw, |
944 | [CLK_PLL_PERIPH1_2X] = &pll_periph1_2x_clk.hw, |
945 | [CLK_PLL_PERIPH1_4X] = &pll_periph1_4x_clk.hw, |
946 | [CLK_PLL_GPU] = &pll_gpu_clk.common.hw, |
947 | [CLK_PLL_VIDEO0] = &pll_video0_clk.common.hw, |
948 | [CLK_PLL_VIDEO0_4X] = &pll_video0_4x_clk.hw, |
949 | [CLK_PLL_VIDEO1] = &pll_video1_clk.common.hw, |
950 | [CLK_PLL_VIDEO1_4X] = &pll_video1_4x_clk.hw, |
951 | [CLK_PLL_VE] = &pll_ve_clk.common.hw, |
952 | [CLK_PLL_DE] = &pll_de_clk.common.hw, |
953 | [CLK_PLL_HSIC] = &pll_hsic_clk.common.hw, |
954 | [CLK_PLL_AUDIO_BASE] = &pll_audio_base_clk.common.hw, |
955 | [CLK_PLL_AUDIO] = &pll_audio_clk.hw, |
956 | [CLK_PLL_AUDIO_2X] = &pll_audio_2x_clk.hw, |
957 | [CLK_PLL_AUDIO_4X] = &pll_audio_4x_clk.hw, |
958 | [CLK_CPUX] = &cpux_clk.common.hw, |
959 | [CLK_AXI] = &axi_clk.common.hw, |
960 | [CLK_CPUX_APB] = &cpux_apb_clk.common.hw, |
961 | [CLK_PSI_AHB1_AHB2] = &psi_ahb1_ahb2_clk.common.hw, |
962 | [CLK_AHB3] = &ahb3_clk.common.hw, |
963 | [CLK_APB1] = &apb1_clk.common.hw, |
964 | [CLK_APB2] = &apb2_clk.common.hw, |
965 | [CLK_MBUS] = &mbus_clk.common.hw, |
966 | [CLK_DE] = &de_clk.common.hw, |
967 | [CLK_BUS_DE] = &bus_de_clk.common.hw, |
968 | [CLK_DEINTERLACE] = &deinterlace_clk.common.hw, |
969 | [CLK_BUS_DEINTERLACE] = &bus_deinterlace_clk.common.hw, |
970 | [CLK_GPU] = &gpu_clk.common.hw, |
971 | [CLK_BUS_GPU] = &bus_gpu_clk.common.hw, |
972 | [CLK_CE] = &ce_clk.common.hw, |
973 | [CLK_BUS_CE] = &bus_ce_clk.common.hw, |
974 | [CLK_VE] = &ve_clk.common.hw, |
975 | [CLK_BUS_VE] = &bus_ve_clk.common.hw, |
976 | [CLK_EMCE] = &emce_clk.common.hw, |
977 | [CLK_BUS_EMCE] = &bus_emce_clk.common.hw, |
978 | [CLK_VP9] = &vp9_clk.common.hw, |
979 | [CLK_BUS_VP9] = &bus_vp9_clk.common.hw, |
980 | [CLK_BUS_DMA] = &bus_dma_clk.common.hw, |
981 | [CLK_BUS_MSGBOX] = &bus_msgbox_clk.common.hw, |
982 | [CLK_BUS_SPINLOCK] = &bus_spinlock_clk.common.hw, |
983 | [CLK_BUS_HSTIMER] = &bus_hstimer_clk.common.hw, |
984 | [CLK_AVS] = &avs_clk.common.hw, |
985 | [CLK_BUS_DBG] = &bus_dbg_clk.common.hw, |
986 | [CLK_BUS_PSI] = &bus_psi_clk.common.hw, |
987 | [CLK_BUS_PWM] = &bus_pwm_clk.common.hw, |
988 | [CLK_BUS_IOMMU] = &bus_iommu_clk.common.hw, |
989 | [CLK_DRAM] = &dram_clk.common.hw, |
990 | [CLK_MBUS_DMA] = &mbus_dma_clk.common.hw, |
991 | [CLK_MBUS_VE] = &mbus_ve_clk.common.hw, |
992 | [CLK_MBUS_CE] = &mbus_ce_clk.common.hw, |
993 | [CLK_MBUS_TS] = &mbus_ts_clk.common.hw, |
994 | [CLK_MBUS_NAND] = &mbus_nand_clk.common.hw, |
995 | [CLK_MBUS_CSI] = &mbus_csi_clk.common.hw, |
996 | [CLK_MBUS_DEINTERLACE] = &mbus_deinterlace_clk.common.hw, |
997 | [CLK_BUS_DRAM] = &bus_dram_clk.common.hw, |
998 | [CLK_NAND0] = &nand0_clk.common.hw, |
999 | [CLK_NAND1] = &nand1_clk.common.hw, |
1000 | [CLK_BUS_NAND] = &bus_nand_clk.common.hw, |
1001 | [CLK_MMC0] = &mmc0_clk.common.hw, |
1002 | [CLK_MMC1] = &mmc1_clk.common.hw, |
1003 | [CLK_MMC2] = &mmc2_clk.common.hw, |
1004 | [CLK_BUS_MMC0] = &bus_mmc0_clk.common.hw, |
1005 | [CLK_BUS_MMC1] = &bus_mmc1_clk.common.hw, |
1006 | [CLK_BUS_MMC2] = &bus_mmc2_clk.common.hw, |
1007 | [CLK_BUS_UART0] = &bus_uart0_clk.common.hw, |
1008 | [CLK_BUS_UART1] = &bus_uart1_clk.common.hw, |
1009 | [CLK_BUS_UART2] = &bus_uart2_clk.common.hw, |
1010 | [CLK_BUS_UART3] = &bus_uart3_clk.common.hw, |
1011 | [CLK_BUS_I2C0] = &bus_i2c0_clk.common.hw, |
1012 | [CLK_BUS_I2C1] = &bus_i2c1_clk.common.hw, |
1013 | [CLK_BUS_I2C2] = &bus_i2c2_clk.common.hw, |
1014 | [CLK_BUS_I2C3] = &bus_i2c3_clk.common.hw, |
1015 | [CLK_BUS_SCR0] = &bus_scr0_clk.common.hw, |
1016 | [CLK_BUS_SCR1] = &bus_scr1_clk.common.hw, |
1017 | [CLK_SPI0] = &spi0_clk.common.hw, |
1018 | [CLK_SPI1] = &spi1_clk.common.hw, |
1019 | [CLK_BUS_SPI0] = &bus_spi0_clk.common.hw, |
1020 | [CLK_BUS_SPI1] = &bus_spi1_clk.common.hw, |
1021 | [CLK_BUS_EMAC] = &bus_emac_clk.common.hw, |
1022 | [CLK_TS] = &ts_clk.common.hw, |
1023 | [CLK_BUS_TS] = &bus_ts_clk.common.hw, |
1024 | [CLK_IR_TX] = &ir_tx_clk.common.hw, |
1025 | [CLK_BUS_IR_TX] = &bus_ir_tx_clk.common.hw, |
1026 | [CLK_BUS_THS] = &bus_ths_clk.common.hw, |
1027 | [CLK_I2S3] = &i2s3_clk.common.hw, |
1028 | [CLK_I2S0] = &i2s0_clk.common.hw, |
1029 | [CLK_I2S1] = &i2s1_clk.common.hw, |
1030 | [CLK_I2S2] = &i2s2_clk.common.hw, |
1031 | [CLK_BUS_I2S0] = &bus_i2s0_clk.common.hw, |
1032 | [CLK_BUS_I2S1] = &bus_i2s1_clk.common.hw, |
1033 | [CLK_BUS_I2S2] = &bus_i2s2_clk.common.hw, |
1034 | [CLK_BUS_I2S3] = &bus_i2s3_clk.common.hw, |
1035 | [CLK_SPDIF] = &spdif_clk.common.hw, |
1036 | [CLK_BUS_SPDIF] = &bus_spdif_clk.common.hw, |
1037 | [CLK_DMIC] = &dmic_clk.common.hw, |
1038 | [CLK_BUS_DMIC] = &bus_dmic_clk.common.hw, |
1039 | [CLK_AUDIO_HUB] = &audio_hub_clk.common.hw, |
1040 | [CLK_BUS_AUDIO_HUB] = &bus_audio_hub_clk.common.hw, |
1041 | [CLK_USB_OHCI0] = &usb_ohci0_clk.common.hw, |
1042 | [CLK_USB_PHY0] = &usb_phy0_clk.common.hw, |
1043 | [CLK_USB_PHY1] = &usb_phy1_clk.common.hw, |
1044 | [CLK_USB_OHCI3] = &usb_ohci3_clk.common.hw, |
1045 | [CLK_USB_PHY3] = &usb_phy3_clk.common.hw, |
1046 | [CLK_USB_HSIC_12M] = &usb_hsic_12m_clk.common.hw, |
1047 | [CLK_USB_HSIC] = &usb_hsic_clk.common.hw, |
1048 | [CLK_BUS_OHCI0] = &bus_ohci0_clk.common.hw, |
1049 | [CLK_BUS_OHCI3] = &bus_ohci3_clk.common.hw, |
1050 | [CLK_BUS_EHCI0] = &bus_ehci0_clk.common.hw, |
1051 | [CLK_BUS_XHCI] = &bus_xhci_clk.common.hw, |
1052 | [CLK_BUS_EHCI3] = &bus_ehci3_clk.common.hw, |
1053 | [CLK_BUS_OTG] = &bus_otg_clk.common.hw, |
1054 | [CLK_PCIE_REF_100M] = &pcie_ref_100m_clk.hw, |
1055 | [CLK_PCIE_REF] = &pcie_ref_clk.common.hw, |
1056 | [CLK_PCIE_REF_OUT] = &pcie_ref_out_clk.common.hw, |
1057 | [CLK_PCIE_MAXI] = &pcie_maxi_clk.common.hw, |
1058 | [CLK_PCIE_AUX] = &pcie_aux_clk.common.hw, |
1059 | [CLK_BUS_PCIE] = &bus_pcie_clk.common.hw, |
1060 | [CLK_HDMI] = &hdmi_clk.common.hw, |
1061 | [CLK_HDMI_SLOW] = &hdmi_slow_clk.common.hw, |
1062 | [CLK_HDMI_CEC] = &hdmi_cec_clk.common.hw, |
1063 | [CLK_BUS_HDMI] = &bus_hdmi_clk.common.hw, |
1064 | [CLK_BUS_TCON_TOP] = &bus_tcon_top_clk.common.hw, |
1065 | [CLK_TCON_LCD0] = &tcon_lcd0_clk.common.hw, |
1066 | [CLK_BUS_TCON_LCD0] = &bus_tcon_lcd0_clk.common.hw, |
1067 | [CLK_TCON_TV0] = &tcon_tv0_clk.common.hw, |
1068 | [CLK_BUS_TCON_TV0] = &bus_tcon_tv0_clk.common.hw, |
1069 | [CLK_CSI_CCI] = &csi_cci_clk.common.hw, |
1070 | [CLK_CSI_TOP] = &csi_top_clk.common.hw, |
1071 | [CLK_CSI_MCLK] = &csi_mclk_clk.common.hw, |
1072 | [CLK_BUS_CSI] = &bus_csi_clk.common.hw, |
1073 | [CLK_HDCP] = &hdcp_clk.common.hw, |
1074 | [CLK_BUS_HDCP] = &bus_hdcp_clk.common.hw, |
1075 | }, |
1076 | .num = CLK_NUMBER, |
1077 | }; |
1078 | |
1079 | static struct ccu_reset_map sun50i_h6_ccu_resets[] = { |
1080 | [RST_MBUS] = { 0x540, BIT(30) }, |
1081 | |
1082 | [RST_BUS_DE] = { 0x60c, BIT(16) }, |
1083 | [RST_BUS_DEINTERLACE] = { 0x62c, BIT(16) }, |
1084 | [RST_BUS_GPU] = { 0x67c, BIT(16) }, |
1085 | [RST_BUS_CE] = { 0x68c, BIT(16) }, |
1086 | [RST_BUS_VE] = { 0x69c, BIT(16) }, |
1087 | [RST_BUS_EMCE] = { 0x6bc, BIT(16) }, |
1088 | [RST_BUS_VP9] = { 0x6cc, BIT(16) }, |
1089 | [RST_BUS_DMA] = { 0x70c, BIT(16) }, |
1090 | [RST_BUS_MSGBOX] = { 0x71c, BIT(16) }, |
1091 | [RST_BUS_SPINLOCK] = { 0x72c, BIT(16) }, |
1092 | [RST_BUS_HSTIMER] = { 0x73c, BIT(16) }, |
1093 | [RST_BUS_DBG] = { 0x78c, BIT(16) }, |
1094 | [RST_BUS_PSI] = { 0x79c, BIT(16) }, |
1095 | [RST_BUS_PWM] = { 0x7ac, BIT(16) }, |
1096 | [RST_BUS_IOMMU] = { 0x7bc, BIT(16) }, |
1097 | [RST_BUS_DRAM] = { 0x80c, BIT(16) }, |
1098 | [RST_BUS_NAND] = { 0x82c, BIT(16) }, |
1099 | [RST_BUS_MMC0] = { 0x84c, BIT(16) }, |
1100 | [RST_BUS_MMC1] = { 0x84c, BIT(17) }, |
1101 | [RST_BUS_MMC2] = { 0x84c, BIT(18) }, |
1102 | [RST_BUS_UART0] = { 0x90c, BIT(16) }, |
1103 | [RST_BUS_UART1] = { 0x90c, BIT(17) }, |
1104 | [RST_BUS_UART2] = { 0x90c, BIT(18) }, |
1105 | [RST_BUS_UART3] = { 0x90c, BIT(19) }, |
1106 | [RST_BUS_I2C0] = { 0x91c, BIT(16) }, |
1107 | [RST_BUS_I2C1] = { 0x91c, BIT(17) }, |
1108 | [RST_BUS_I2C2] = { 0x91c, BIT(18) }, |
1109 | [RST_BUS_I2C3] = { 0x91c, BIT(19) }, |
1110 | [RST_BUS_SCR0] = { 0x93c, BIT(16) }, |
1111 | [RST_BUS_SCR1] = { 0x93c, BIT(17) }, |
1112 | [RST_BUS_SPI0] = { 0x96c, BIT(16) }, |
1113 | [RST_BUS_SPI1] = { 0x96c, BIT(17) }, |
1114 | [RST_BUS_EMAC] = { 0x97c, BIT(16) }, |
1115 | [RST_BUS_TS] = { 0x9bc, BIT(16) }, |
1116 | [RST_BUS_IR_TX] = { 0x9cc, BIT(16) }, |
1117 | [RST_BUS_THS] = { 0x9fc, BIT(16) }, |
1118 | [RST_BUS_I2S0] = { 0xa1c, BIT(16) }, |
1119 | [RST_BUS_I2S1] = { 0xa1c, BIT(17) }, |
1120 | [RST_BUS_I2S2] = { 0xa1c, BIT(18) }, |
1121 | [RST_BUS_I2S3] = { 0xa1c, BIT(19) }, |
1122 | [RST_BUS_SPDIF] = { 0xa2c, BIT(16) }, |
1123 | [RST_BUS_DMIC] = { 0xa4c, BIT(16) }, |
1124 | [RST_BUS_AUDIO_HUB] = { 0xa6c, BIT(16) }, |
1125 | |
1126 | [RST_USB_PHY0] = { 0xa70, BIT(30) }, |
1127 | [RST_USB_PHY1] = { 0xa74, BIT(30) }, |
1128 | [RST_USB_PHY3] = { 0xa7c, BIT(30) }, |
1129 | [RST_USB_HSIC] = { 0xa7c, BIT(28) }, |
1130 | |
1131 | [RST_BUS_OHCI0] = { 0xa8c, BIT(16) }, |
1132 | [RST_BUS_OHCI3] = { 0xa8c, BIT(19) }, |
1133 | [RST_BUS_EHCI0] = { 0xa8c, BIT(20) }, |
1134 | [RST_BUS_XHCI] = { 0xa8c, BIT(21) }, |
1135 | [RST_BUS_EHCI3] = { 0xa8c, BIT(23) }, |
1136 | [RST_BUS_OTG] = { 0xa8c, BIT(24) }, |
1137 | [RST_BUS_PCIE] = { 0xabc, BIT(16) }, |
1138 | |
1139 | [RST_PCIE_POWERUP] = { 0xabc, BIT(17) }, |
1140 | |
1141 | [RST_BUS_HDMI] = { 0xb1c, BIT(16) }, |
1142 | [RST_BUS_HDMI_SUB] = { 0xb1c, BIT(17) }, |
1143 | [RST_BUS_TCON_TOP] = { 0xb5c, BIT(16) }, |
1144 | [RST_BUS_TCON_LCD0] = { 0xb7c, BIT(16) }, |
1145 | [RST_BUS_TCON_TV0] = { 0xb9c, BIT(16) }, |
1146 | [RST_BUS_CSI] = { 0xc2c, BIT(16) }, |
1147 | [RST_BUS_HDCP] = { 0xc4c, BIT(16) }, |
1148 | }; |
1149 | |
1150 | static const struct sunxi_ccu_desc sun50i_h6_ccu_desc = { |
1151 | .ccu_clks = sun50i_h6_ccu_clks, |
1152 | .num_ccu_clks = ARRAY_SIZE(sun50i_h6_ccu_clks), |
1153 | |
1154 | .hw_clks = &sun50i_h6_hw_clks, |
1155 | |
1156 | .resets = sun50i_h6_ccu_resets, |
1157 | .num_resets = ARRAY_SIZE(sun50i_h6_ccu_resets), |
1158 | }; |
1159 | |
1160 | static const u32 pll_regs[] = { |
1161 | SUN50I_H6_PLL_CPUX_REG, |
1162 | SUN50I_H6_PLL_DDR0_REG, |
1163 | SUN50I_H6_PLL_PERIPH0_REG, |
1164 | SUN50I_H6_PLL_PERIPH1_REG, |
1165 | SUN50I_H6_PLL_GPU_REG, |
1166 | SUN50I_H6_PLL_VIDEO0_REG, |
1167 | SUN50I_H6_PLL_VIDEO1_REG, |
1168 | SUN50I_H6_PLL_VE_REG, |
1169 | SUN50I_H6_PLL_DE_REG, |
1170 | SUN50I_H6_PLL_HSIC_REG, |
1171 | SUN50I_H6_PLL_AUDIO_REG, |
1172 | }; |
1173 | |
1174 | static const u32 pll_video_regs[] = { |
1175 | SUN50I_H6_PLL_VIDEO0_REG, |
1176 | SUN50I_H6_PLL_VIDEO1_REG, |
1177 | }; |
1178 | |
1179 | static const u32 usb2_clk_regs[] = { |
1180 | SUN50I_H6_USB0_CLK_REG, |
1181 | SUN50I_H6_USB3_CLK_REG, |
1182 | }; |
1183 | |
1184 | static int sun50i_h6_ccu_probe(struct platform_device *pdev) |
1185 | { |
1186 | void __iomem *reg; |
1187 | u32 val; |
1188 | int i; |
1189 | |
1190 | reg = devm_platform_ioremap_resource(pdev, index: 0); |
1191 | if (IS_ERR(ptr: reg)) |
1192 | return PTR_ERR(ptr: reg); |
1193 | |
1194 | /* |
1195 | * Force PLL_GPU output divider bits to 0 and adjust |
1196 | * multiplier to sensible default value of 432 MHz. |
1197 | */ |
1198 | val = readl(addr: reg + SUN50I_H6_PLL_GPU_REG); |
1199 | val &= ~(GENMASK(15, 8) | BIT(0)); |
1200 | val |= 17 << 8; |
1201 | writel(val, addr: reg + SUN50I_H6_PLL_GPU_REG); |
1202 | |
1203 | /* Force GPU_CLK divider bits to 0 */ |
1204 | val = readl(addr: reg + gpu_clk.common.reg); |
1205 | val &= ~GENMASK(3, 0); |
1206 | writel(val, addr: reg + gpu_clk.common.reg); |
1207 | |
1208 | /* Enable the lock bits on all PLLs */ |
1209 | for (i = 0; i < ARRAY_SIZE(pll_regs); i++) { |
1210 | val = readl(addr: reg + pll_regs[i]); |
1211 | val |= BIT(29); |
1212 | writel(val, addr: reg + pll_regs[i]); |
1213 | } |
1214 | |
1215 | /* |
1216 | * Force the output divider of video PLLs to 0. |
1217 | * |
1218 | * See the comment before pll-video0 definition for the reason. |
1219 | */ |
1220 | for (i = 0; i < ARRAY_SIZE(pll_video_regs); i++) { |
1221 | val = readl(addr: reg + pll_video_regs[i]); |
1222 | val &= ~BIT(0); |
1223 | writel(val, addr: reg + pll_video_regs[i]); |
1224 | } |
1225 | |
1226 | /* |
1227 | * Force OHCI 12M clock sources to 00 (12MHz divided from 48MHz) |
1228 | * |
1229 | * This clock mux is still mysterious, and the code just enforces |
1230 | * it to have a valid clock parent. |
1231 | */ |
1232 | for (i = 0; i < ARRAY_SIZE(usb2_clk_regs); i++) { |
1233 | val = readl(addr: reg + usb2_clk_regs[i]); |
1234 | val &= ~GENMASK(25, 24); |
1235 | writel (val, addr: reg + usb2_clk_regs[i]); |
1236 | } |
1237 | |
1238 | /* |
1239 | * Force the post-divider of pll-audio to 12 and the output divider |
1240 | * of it to 2, so 24576000 and 22579200 rates can be set exactly. |
1241 | */ |
1242 | val = readl(addr: reg + SUN50I_H6_PLL_AUDIO_REG); |
1243 | val &= ~(GENMASK(21, 16) | BIT(0)); |
1244 | writel(val: val | (11 << 16) | BIT(0), addr: reg + SUN50I_H6_PLL_AUDIO_REG); |
1245 | |
1246 | /* |
1247 | * First clock parent (osc32K) is unusable for CEC. But since there |
1248 | * is no good way to force parent switch (both run with same frequency), |
1249 | * just set second clock parent here. |
1250 | */ |
1251 | val = readl(addr: reg + SUN50I_H6_HDMI_CEC_CLK_REG); |
1252 | val |= BIT(24); |
1253 | writel(val, addr: reg + SUN50I_H6_HDMI_CEC_CLK_REG); |
1254 | |
1255 | return devm_sunxi_ccu_probe(dev: &pdev->dev, reg, desc: &sun50i_h6_ccu_desc); |
1256 | } |
1257 | |
1258 | static const struct of_device_id sun50i_h6_ccu_ids[] = { |
1259 | { .compatible = "allwinner,sun50i-h6-ccu" }, |
1260 | { } |
1261 | }; |
1262 | |
1263 | static struct platform_driver sun50i_h6_ccu_driver = { |
1264 | .probe = sun50i_h6_ccu_probe, |
1265 | .driver = { |
1266 | .name = "sun50i-h6-ccu" , |
1267 | .suppress_bind_attrs = true, |
1268 | .of_match_table = sun50i_h6_ccu_ids, |
1269 | }, |
1270 | }; |
1271 | module_platform_driver(sun50i_h6_ccu_driver); |
1272 | |
1273 | MODULE_IMPORT_NS(SUNXI_CCU); |
1274 | MODULE_LICENSE("GPL" ); |
1275 | |