1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3 *
4 * Copyright (c) 2018 Emmanuel Vadot <[email protected]>
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
20 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
22 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
23 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 *
27 * $FreeBSD$
28 */
29
30 #include <sys/cdefs.h>
31 __FBSDID("$FreeBSD$");
32
33 #include <sys/param.h>
34 #include <sys/systm.h>
35 #include <sys/bus.h>
36 #include <sys/rman.h>
37 #include <sys/kernel.h>
38 #include <sys/module.h>
39 #include <machine/bus.h>
40
41 #include <dev/fdt/simplebus.h>
42
43 #include <dev/ofw/ofw_bus.h>
44 #include <dev/ofw/ofw_bus_subr.h>
45
46 #include <dev/extres/clk/clk_div.h>
47 #include <dev/extres/clk/clk_fixed.h>
48 #include <dev/extres/clk/clk_mux.h>
49
50 #include <arm64/rockchip/clk/rk_cru.h>
51
52 /* Registers */
53 #define RK3328_GRF_SOC_CON4 0x410
54 #define RK3328_GRF_MAC_CON1 0x904
55 #define RK3328_GRF_MAC_CON2 0x908
56
57 /* GATES */
58
59 #define SCLK_I2S0 41
60 #define SCLK_I2S1 42
61 #define SCLK_I2S2 43
62 #define SCLK_I2S1_OUT 44
63 #define SCLK_I2S2_OUT 45
64 #define SCLK_MAC2PHY_RXTX 83
65 #define SCLK_MAC2PHY_SRC 84
66 #define SCLK_MAC2PHY_REF 85
67 #define SCLK_MAC2PHY_OUT 86
68 #define SCLK_MAC2IO_RX 87
69 #define SCLK_MAC2IO_TX 88
70 #define SCLK_MAC2IO_REFOUT 89
71 #define SCLK_MAC2IO_REF 90
72 #define SCLK_MAC2IO_OUT 91
73 #define SCLK_USB3OTG_REF 96
74 #define SCLK_MAC2IO_SRC 99
75 #define SCLK_MAC2IO 100
76 #define SCLK_MAC2PHY 101
77 #define SCLK_MAC2IO_EXT 102
78 #define ACLK_USB3OTG 132
79 #define ACLK_GMAC 146
80 #define ACLK_MAC2PHY 149
81 #define ACLK_MAC2IO 150
82 #define ACLK_PERI 153
83 #define PCLK_GPIO0 200
84 #define PCLK_GPIO1 201
85 #define PCLK_GPIO2 202
86 #define PCLK_GPIO3 203
87 #define PCLK_I2C0 205
88 #define PCLK_I2C1 206
89 #define PCLK_I2C2 207
90 #define PCLK_I2C3 208
91 #define PCLK_TSADC 213
92 #define PCLK_GMAC 220
93 #define PCLK_MAC2PHY 222
94 #define PCLK_MAC2IO 223
95 #define PCLK_USB3PHY_OTG 224
96 #define PCLK_USB3PHY_PIPE 225
97 #define PCLK_USB3_GRF 226
98 #define PCLK_ACODECPHY 235
99 #define HCLK_I2S0_8CH 311
100 #define HCLK_I2S1_8CH 312
101 #define HCLK_I2S2_2CH 313
102 #define HCLK_SDMMC 317
103 #define HCLK_SDIO 318
104 #define HCLK_EMMC 319
105 #define HCLK_SDMMC_EXT 320
106
107 static struct rk_cru_gate rk3328_gates[] = {
108 /* CRU_CLKGATE_CON0 */
109 CRU_GATE(0, "apll_core", "apll", 0x200, 0)
110 CRU_GATE(0, "dpll_core", "dpll", 0x200, 1)
111 CRU_GATE(0, "gpll_core", "gpll", 0x200, 2)
112 CRU_GATE(0, "npll_core", "npll", 0x200, 12)
113
114 /* CRU_CLKGATE_CON1 */
115 CRU_GATE(SCLK_I2S0, "clk_i2s0", "clk_i2s0_mux", 0x204, 3)
116 CRU_GATE(SCLK_I2S1, "clk_i2s1", "clk_i2s1_mux", 0x204, 6)
117 CRU_GATE(SCLK_I2S1, "clk_i2s2", "clk_i2s2_mux", 0x204, 10)
118
119 /* CRU_CLKGATE_CON4 */
120 CRU_GATE(0, "gpll_peri", "gpll", 0x210, 0)
121 CRU_GATE(0, "cpll_peri", "cpll", 0x210, 1)
122 CRU_GATE(SCLK_USB3OTG_REF, "clk_usb3otg_ref", "xin24m", 0x210, 7)
123
124 /* CRU_CLKGATE_CON8 */
125 CRU_GATE(0, "pclk_bus", "pclk_bus_pre", 0x220, 3)
126 CRU_GATE(0, "pclk_phy_pre", "pclk_bus_pre", 0x220, 4)
127
128 /* CRU_CLKGATE_CON8 */
129 CRU_GATE(SCLK_MAC2IO_REF, "clk_mac2io_ref", "clk_mac2io", 0x224, 7)
130 CRU_GATE(SCLK_MAC2IO_REFOUT, "clk_mac2io_refout", "clk_mac2io", 0x224, 6)
131 CRU_GATE(SCLK_MAC2IO_TX, "clk_mac2io_tx", "clk_mac2io", 0x224, 5)
132 CRU_GATE(SCLK_MAC2IO_RX, "clk_mac2io_rx", "clk_mac2io", 0x224, 4)
133 CRU_GATE(SCLK_MAC2PHY_REF, "clk_mac2phy_ref", "clk_mac2phy", 0x224, 3)
134 CRU_GATE(SCLK_MAC2PHY_RXTX, "clk_mac2phy_rxtx", "clk_mac2phy", 0x224, 1)
135
136 /* CRU_CLKGATE_CON10 */
137 CRU_GATE(ACLK_PERI, "aclk_peri", "aclk_peri_pre", 0x228, 0)
138
139 /* CRU_CLKGATE_CON15*/
140 CRU_GATE(HCLK_I2S0_8CH, "hclk_i2s0_8ch", "hclk_bus_pre", 0x23C, 3)
141 CRU_GATE(HCLK_I2S1_8CH, "hclk_i2s1_8ch", "hclk_bus_pre", 0x23C, 4)
142 CRU_GATE(HCLK_I2S2_2CH, "hclk_i2s2_2ch", "hclk_bus_pre", 0x23C, 5)
143 CRU_GATE(PCLK_I2C0, "pclk_i2c0", "pclk_bus", 0x23C, 10)
144
145 /* CRU_CLKGATE_CON16 */
146 CRU_GATE(PCLK_I2C1, "pclk_i2c1", "pclk_bus", 0x23C, 0)
147 CRU_GATE(PCLK_I2C2, "pclk_i2c2", "pclk_bus", 0x23C, 1)
148 CRU_GATE(PCLK_I2C3, "pclk_i2c3", "pclk_bus", 0x23C, 2)
149 CRU_GATE(PCLK_TSADC, "pclk_tsadc", "pclk_bus", 0x23C, 14)
150
151 CRU_GATE(PCLK_GPIO0, "pclk_gpio0", "pclk_bus", 0x240, 7)
152 CRU_GATE(PCLK_GPIO1, "pclk_gpio1", "pclk_bus", 0x240, 8)
153 CRU_GATE(PCLK_GPIO2, "pclk_gpio2", "pclk_bus", 0x240, 9)
154 CRU_GATE(PCLK_GPIO3, "pclk_gpio3", "pclk_bus", 0x240, 10)
155
156 /* CRU_CLKGATE_CON17 */
157 CRU_GATE(PCLK_USB3_GRF, "pclk_usb3_grf", "pclk_phy_pre", 0x244, 2)
158 CRU_GATE(PCLK_ACODECPHY, "pclk_acodecphy", "pclk_phy_pre", 0x244, 5)
159
160 /* CRU_CLKGATE_CON19 */
161 CRU_GATE(HCLK_SDMMC, "hclk_sdmmc", "hclk_peri", 0x24C, 0)
162 CRU_GATE(HCLK_SDIO, "hclk_sdio", "hclk_peri", 0x24C, 1)
163 CRU_GATE(HCLK_EMMC, "hclk_emmc", "hclk_peri", 0x24C, 2)
164 CRU_GATE(0, "hclk_peri_niu", "hclk_peri", 0x24C, 12)
165 CRU_GATE(0, "pclk_peri_niu", "hclk_peri", 0x24C, 13)
166 CRU_GATE(ACLK_USB3OTG, "aclk_usb3otg", "aclk_peri", 0x24C, 14)
167 CRU_GATE(HCLK_SDMMC_EXT, "hclk_sdmmc_ext", "hclk_peri", 0x24C, 15)
168
169 /* CRU_CLKGATE_CON26 */
170 CRU_GATE(ACLK_MAC2PHY, "aclk_mac2phy", "aclk_gmac", 0x268, 0)
171 CRU_GATE(PCLK_MAC2PHY, "pclk_mac2phy", "pclk_gmac", 0x268, 1)
172 CRU_GATE(ACLK_MAC2IO, "aclk_mac2io", "aclk_gmac", 0x268, 2)
173 CRU_GATE(PCLK_MAC2IO, "pclk_mac2io", "pclk_gmac", 0x268, 3)
174
175 /* CRU_CLKGATE_CON28 */
176 CRU_GATE(PCLK_USB3PHY_OTG, "pclk_usb3phy_otg", "pclk_phy_pre", 0x270, 1)
177 CRU_GATE(PCLK_USB3PHY_PIPE, "pclk_usb3phy_pipe", "pclk_phy_pre", 0x270, 2)
178 };
179
180 /*
181 * PLLs
182 */
183
184 #define PLL_APLL 1
185 #define PLL_DPLL 2
186 #define PLL_CPLL 3
187 #define PLL_GPLL 4
188 #define PLL_NPLL 5
189
190 static struct rk_clk_pll_rate rk3328_pll_rates[] = {
191 {
192 .freq = 1608000000,
193 .refdiv = 1,
194 .fbdiv = 67,
195 .postdiv1 = 1,
196 .postdiv2 = 1,
197 .dsmpd = 1,
198 },
199 {
200 .freq = 1584000000,
201 .refdiv = 1,
202 .fbdiv = 66,
203 .postdiv1 = 1,
204 .postdiv2 = 1,
205 .dsmpd = 1,
206 },
207 {
208 .freq = 1560000000,
209 .refdiv = 1,
210 .fbdiv = 65,
211 .postdiv1 = 1,
212 .postdiv2 = 1,
213 .dsmpd = 1,
214 },
215 {
216 .freq = 1536000000,
217 .refdiv = 1,
218 .fbdiv = 64,
219 .postdiv1 = 1,
220 .postdiv2 = 1,
221 .dsmpd = 1,
222 },
223 {
224 .freq = 1512000000,
225 .refdiv = 1,
226 .fbdiv = 63,
227 .postdiv1 = 1,
228 .postdiv2 = 1,
229 .dsmpd = 1,
230 },
231 {
232 .freq = 1488000000,
233 .refdiv = 1,
234 .fbdiv = 62,
235 .postdiv1 = 1,
236 .postdiv2 = 1,
237 .dsmpd = 1,
238 },
239 {
240 .freq = 1464000000,
241 .refdiv = 1,
242 .fbdiv = 61,
243 .postdiv1 = 1,
244 .postdiv2 = 1,
245 .dsmpd = 1,
246 },
247 {
248 .freq = 1440000000,
249 .refdiv = 1,
250 .fbdiv = 60,
251 .postdiv1 = 1,
252 .postdiv2 = 1,
253 .dsmpd = 1,
254 },
255 {
256 .freq = 1416000000,
257 .refdiv = 1,
258 .fbdiv = 59,
259 .postdiv1 = 1,
260 .postdiv2 = 1,
261 .dsmpd = 1,
262 },
263 {
264 .freq = 1392000000,
265 .refdiv = 1,
266 .fbdiv = 58,
267 .postdiv1 = 1,
268 .postdiv2 = 1,
269 .dsmpd = 1,
270 },
271 {
272 .freq = 1368000000,
273 .refdiv = 1,
274 .fbdiv = 57,
275 .postdiv1 = 1,
276 .postdiv2 = 1,
277 .dsmpd = 1,
278 },
279 {
280 .freq = 1344000000,
281 .refdiv = 1,
282 .fbdiv = 56,
283 .postdiv1 = 1,
284 .postdiv2 = 1,
285 .dsmpd = 1,
286 },
287 {
288 .freq = 1320000000,
289 .refdiv = 1,
290 .fbdiv = 55,
291 .postdiv1 = 1,
292 .postdiv2 = 1,
293 .dsmpd = 1,
294 },
295 {
296 .freq = 1296000000,
297 .refdiv = 1,
298 .fbdiv = 54,
299 .postdiv1 = 1,
300 .postdiv2 = 1,
301 .dsmpd = 1,
302 },
303 {
304 .freq = 1272000000,
305 .refdiv = 1,
306 .fbdiv = 53,
307 .postdiv1 = 1,
308 .postdiv2 = 1,
309 .dsmpd = 1,
310 },
311 {
312 .freq = 1248000000,
313 .refdiv = 1,
314 .fbdiv = 52,
315 .postdiv1 = 1,
316 .postdiv2 = 1,
317 .dsmpd = 1,
318 },
319 {
320 .freq = 1200000000,
321 .refdiv = 1,
322 .fbdiv = 50,
323 .postdiv1 = 1,
324 .postdiv2 = 1,
325 .dsmpd = 1,
326 },
327 {
328 .freq = 1188000000,
329 .refdiv = 2,
330 .fbdiv = 99,
331 .postdiv1 = 1,
332 .postdiv2 = 1,
333 .dsmpd = 1,
334 },
335 {
336 .freq = 1104000000,
337 .refdiv = 1,
338 .fbdiv = 46,
339 .postdiv1 = 1,
340 .postdiv2 = 1,
341 .dsmpd = 1,
342 },
343 {
344 .freq = 1100000000,
345 .refdiv = 12,
346 .fbdiv = 550,
347 .postdiv1 = 1,
348 .postdiv2 = 1,
349 .dsmpd = 1,
350 },
351 {
352 .freq = 1008000000,
353 .refdiv = 1,
354 .fbdiv = 84,
355 .postdiv1 = 2,
356 .postdiv2 = 1,
357 .dsmpd = 1,
358 },
359 {
360 .freq = 1000000000,
361 .refdiv = 6,
362 .fbdiv = 500,
363 .postdiv1 = 2,
364 .postdiv2 = 1,
365 .dsmpd = 1,
366 },
367 {
368 .freq = 984000000,
369 .refdiv = 1,
370 .fbdiv = 82,
371 .postdiv1 = 2,
372 .postdiv2 = 1,
373 .dsmpd = 1,
374 },
375 {
376 .freq = 960000000,
377 .refdiv = 1,
378 .fbdiv = 80,
379 .postdiv1 = 2,
380 .postdiv2 = 1,
381 .dsmpd = 1,
382 },
383 {
384 .freq = 936000000,
385 .refdiv = 1,
386 .fbdiv = 78,
387 .postdiv1 = 2,
388 .postdiv2 = 1,
389 .dsmpd = 1,
390 },
391 {
392 .freq = 912000000,
393 .refdiv = 1,
394 .fbdiv = 76,
395 .postdiv1 = 2,
396 .postdiv2 = 1,
397 .dsmpd = 1,
398 },
399 {
400 .freq = 900000000,
401 .refdiv = 4,
402 .fbdiv = 300,
403 .postdiv1 = 2,
404 .postdiv2 = 1,
405 .dsmpd = 1,
406 },
407 {
408 .freq = 888000000,
409 .refdiv = 1,
410 .fbdiv = 74,
411 .postdiv1 = 2,
412 .postdiv2 = 1,
413 .dsmpd = 1,
414 },
415 {
416 .freq = 864000000,
417 .refdiv = 1,
418 .fbdiv = 72,
419 .postdiv1 = 2,
420 .postdiv2 = 1,
421 .dsmpd = 1,
422 },
423 {
424 .freq = 840000000,
425 .refdiv = 1,
426 .fbdiv = 70,
427 .postdiv1 = 2,
428 .postdiv2 = 1,
429 .dsmpd = 1,
430 },
431 {
432 .freq = 816000000,
433 .refdiv = 1,
434 .fbdiv = 68,
435 .postdiv1 = 2,
436 .postdiv2 = 1,
437 .dsmpd = 1,
438 },
439 {
440 .freq = 800000000,
441 .refdiv = 6,
442 .fbdiv = 400,
443 .postdiv1 = 2,
444 .postdiv2 = 1,
445 .dsmpd = 1,
446 },
447 {
448 .freq = 700000000,
449 .refdiv = 6,
450 .fbdiv = 350,
451 .postdiv1 = 2,
452 .postdiv2 = 1,
453 .dsmpd = 1,
454 },
455 {
456 .freq = 696000000,
457 .refdiv = 1,
458 .fbdiv = 58,
459 .postdiv1 = 2,
460 .postdiv2 = 1,
461 .dsmpd = 1,
462 },
463 {
464 .freq = 600000000,
465 .refdiv = 1,
466 .fbdiv = 75,
467 .postdiv1 = 3,
468 .postdiv2 = 1,
469 .dsmpd = 1,
470 },
471 {
472 .freq = 594000000,
473 .refdiv = 2,
474 .fbdiv = 99,
475 .postdiv1 = 2,
476 .postdiv2 = 1,
477 .dsmpd = 1,
478 },
479 {
480 .freq = 504000000,
481 .refdiv = 1,
482 .fbdiv = 63,
483 .postdiv1 = 3,
484 .postdiv2 = 1,
485 .dsmpd = 1,
486 },
487 {
488 .freq = 500000000,
489 .refdiv = 6,
490 .fbdiv = 250,
491 .postdiv1 = 2,
492 .postdiv2 = 1,
493 .dsmpd = 1,
494 },
495 {
496 .freq = 408000000,
497 .refdiv = 1,
498 .fbdiv = 68,
499 .postdiv1 = 2,
500 .postdiv2 = 2,
501 .dsmpd = 1,
502 },
503 {
504 .freq = 312000000,
505 .refdiv = 1,
506 .fbdiv = 52,
507 .postdiv1 = 2,
508 .postdiv2 = 2,
509 .dsmpd = 1,
510 },
511 {
512 .freq = 216000000,
513 .refdiv = 1,
514 .fbdiv = 72,
515 .postdiv1 = 4,
516 .postdiv2 = 2,
517 .dsmpd = 1,
518 },
519 {
520 .freq = 96000000,
521 .refdiv = 1,
522 .fbdiv = 64,
523 .postdiv1 = 4,
524 .postdiv2 = 4,
525 .dsmpd = 1,
526 },
527 {},
528 };
529
530 static struct rk_clk_pll_rate rk3328_pll_frac_rates[] = {
531 {
532 .freq = 1016064000,
533 .refdiv = 3,
534 .fbdiv = 127,
535 .postdiv1 = 1,
536 .postdiv2 = 1,
537 .dsmpd = 0,
538 .frac = 134217,
539 },
540 {
541 .freq = 983040000,
542 .refdiv = 24,
543 .fbdiv = 983,
544 .postdiv1 = 1,
545 .postdiv2 = 1,
546 .dsmpd = 0,
547 .frac = 671088,
548 },
549 {
550 .freq = 491520000,
551 .refdiv = 24,
552 .fbdiv = 983,
553 .postdiv1 = 2,
554 .postdiv2 = 1,
555 .dsmpd = 0,
556 .frac = 671088,
557 },
558 {
559 .freq = 61440000,
560 .refdiv = 6,
561 .fbdiv = 215,
562 .postdiv1 = 7,
563 .postdiv2 = 2,
564 .dsmpd = 0,
565 .frac = 671088,
566 },
567 {
568 .freq = 56448000,
569 .refdiv = 12,
570 .fbdiv = 451,
571 .postdiv1 = 4,
572 .postdiv2 = 4,
573 .dsmpd = 0,
574 .frac = 9797894,
575 },
576 {
577 .freq = 40960000,
578 .refdiv = 12,
579 .fbdiv = 409,
580 .postdiv1 = 4,
581 .postdiv2 = 5,
582 .dsmpd = 0,
583 .frac = 10066329,
584 },
585 {},
586 };
587
588 static const char *pll_parents[] = {"xin24m"};
589 static struct rk_clk_pll_def apll = {
590 .clkdef = {
591 .id = PLL_APLL,
592 .name = "apll",
593 .parent_names = pll_parents,
594 .parent_cnt = nitems(pll_parents),
595 },
596 .base_offset = 0x00,
597 .gate_offset = 0x200,
598 .gate_shift = 0,
599 .mode_reg = 0x80,
600 .mode_shift = 1,
601 .flags = RK_CLK_PLL_HAVE_GATE,
602 .frac_rates = rk3328_pll_frac_rates,
603 };
604
605 static struct rk_clk_pll_def dpll = {
606 .clkdef = {
607 .id = PLL_DPLL,
608 .name = "dpll",
609 .parent_names = pll_parents,
610 .parent_cnt = nitems(pll_parents),
611 },
612 .base_offset = 0x20,
613 .gate_offset = 0x200,
614 .gate_shift = 1,
615 .mode_reg = 0x80,
616 .mode_shift = 4,
617 .flags = RK_CLK_PLL_HAVE_GATE,
618 };
619
620 static struct rk_clk_pll_def cpll = {
621 .clkdef = {
622 .id = PLL_CPLL,
623 .name = "cpll",
624 .parent_names = pll_parents,
625 .parent_cnt = nitems(pll_parents),
626 },
627 .base_offset = 0x40,
628 .mode_reg = 0x80,
629 .mode_shift = 8,
630 .rates = rk3328_pll_rates,
631 };
632
633 static struct rk_clk_pll_def gpll = {
634 .clkdef = {
635 .id = PLL_GPLL,
636 .name = "gpll",
637 .parent_names = pll_parents,
638 .parent_cnt = nitems(pll_parents),
639 },
640 .base_offset = 0x60,
641 .gate_offset = 0x200,
642 .gate_shift = 2,
643 .mode_reg = 0x80,
644 .mode_shift = 12,
645 .flags = RK_CLK_PLL_HAVE_GATE,
646 .frac_rates = rk3328_pll_frac_rates,
647 };
648
649 static struct rk_clk_pll_def npll = {
650 .clkdef = {
651 .id = PLL_NPLL,
652 .name = "npll",
653 .parent_names = pll_parents,
654 .parent_cnt = nitems(pll_parents),
655 },
656 .base_offset = 0xa0,
657 .gate_offset = 0x200,
658 .gate_shift = 12,
659 .mode_reg = 0x80,
660 .mode_shift = 1,
661 .flags = RK_CLK_PLL_HAVE_GATE,
662 .rates = rk3328_pll_rates,
663 };
664
665 /* CRU_CLKSEL_CON0 */
666 #define ACLK_BUS_PRE 136
667
668 /* Needs hdmiphy as parent too*/
669 static const char *aclk_bus_pre_parents[] = {"cpll", "gpll"};
670 static struct rk_clk_composite_def aclk_bus_pre = {
671 .clkdef = {
672 .id = ACLK_BUS_PRE,
673 .name = "aclk_bus_pre",
674 .parent_names = aclk_bus_pre_parents,
675 .parent_cnt = nitems(aclk_bus_pre_parents),
676 },
677 .muxdiv_offset = 0x100,
678 .mux_shift = 13,
679 .mux_width = 2,
680
681 .div_shift = 8,
682 .div_width = 5,
683
684 .gate_offset = 0x220,
685 .gate_shift = 0,
686
687 .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE,
688 };
689
690 static struct rk_clk_armclk_rates rk3328_armclk_rates[] = {
691 {
692 .freq = 1296000000,
693 .div = 1,
694 },
695 {
696 .freq = 1200000000,
697 .div = 1,
698 },
699 {
700 .freq = 1104000000,
701 .div = 1,
702 },
703 {
704 .freq = 1008000000,
705 .div = 1,
706 },
707 {
708 .freq = 912000000,
709 .div = 1,
710 },
711 {
712 .freq = 816000000,
713 .div = 1,
714 },
715 {
716 .freq = 696000000,
717 .div = 1,
718 },
719 {
720 .freq = 600000000,
721 .div = 1,
722 },
723 {
724 .freq = 408000000,
725 .div = 1,
726 },
727 {
728 .freq = 312000000,
729 .div = 1,
730 },
731 {
732 .freq = 216000000,
733 .div = 1,
734 },
735 {
736 .freq = 96000000,
737 .div = 1,
738 },
739 };
740
741 #define ARMCLK 6
742 static const char *armclk_parents[] = {"apll", "gpll", "dpll", "npll" };
743 static struct rk_clk_armclk_def armclk = {
744 .clkdef = {
745 .id = ARMCLK,
746 .name = "armclk",
747 .parent_names = armclk_parents,
748 .parent_cnt = nitems(armclk_parents),
749 },
750 .muxdiv_offset = 0x100,
751 .mux_shift = 6,
752 .mux_width = 2,
753
754 .div_shift = 0,
755 .div_width = 5,
756
757 .flags = RK_CLK_COMPOSITE_HAVE_MUX,
758 .main_parent = 3, /* npll */
759 .alt_parent = 0, /* apll */
760
761 .rates = rk3328_armclk_rates,
762 .nrates = nitems(rk3328_armclk_rates),
763 };
764
765 /* CRU_CLKSEL_CON1 */
766
767 #define PCLK_BUS_PRE 216
768 #define HCLK_BUS_PRE 328
769
770 static const char *hclk_bus_pre_parents[] = {"aclk_bus_pre"};
771 static struct rk_clk_composite_def hclk_bus_pre = {
772 .clkdef = {
773 .id = HCLK_BUS_PRE,
774 .name = "hclk_bus_pre",
775 .parent_names = hclk_bus_pre_parents,
776 .parent_cnt = nitems(hclk_bus_pre_parents),
777 },
778 .muxdiv_offset = 0x104,
779
780 .div_shift = 8,
781 .div_width = 2,
782
783 .gate_offset = 0x220,
784 .gate_shift = 1,
785
786 .flags = RK_CLK_COMPOSITE_HAVE_GATE,
787 };
788
789 static const char *pclk_bus_pre_parents[] = {"aclk_bus_pre"};
790 static struct rk_clk_composite_def pclk_bus_pre = {
791 .clkdef = {
792 .id = PCLK_BUS_PRE,
793 .name = "pclk_bus_pre",
794 .parent_names = pclk_bus_pre_parents,
795 .parent_cnt = nitems(pclk_bus_pre_parents),
796 },
797 .muxdiv_offset = 0x104,
798
799 .div_shift = 12,
800 .div_width = 3,
801
802 .gate_offset = 0x220,
803 .gate_shift = 2,
804
805 .flags = RK_CLK_COMPOSITE_HAVE_GATE,
806 };
807
808 /* CRU_CLKSEL_CON22 */
809
810 #define SCLK_TSADC 36
811
812 static const char *clk_tsadc_parents[] = {"xin24m"};
813 static struct rk_clk_composite_def clk_tsadc = {
814 .clkdef = {
815 .id = SCLK_TSADC,
816 .name = "clk_tsadc",
817 .parent_names = clk_tsadc_parents,
818 .parent_cnt = nitems(clk_tsadc_parents),
819 },
820 .div_shift = 0,
821 .div_width = 9,
822 };
823
824 /* CRU_CLKSEL_CON28 */
825
826 #define ACLK_PERI_PRE 137
827
828 static const char *aclk_peri_pre_parents[] = {"cpll", "gpll"/* , "hdmiphy" */};
829 static struct rk_clk_composite_def aclk_peri_pre = {
830 .clkdef = {
831 .id = ACLK_PERI_PRE,
832 .name = "aclk_peri_pre",
833 .parent_names = aclk_peri_pre_parents,
834 .parent_cnt = nitems(aclk_peri_pre_parents),
835 },
836 .muxdiv_offset = 0x170,
837
838 .mux_shift = 6,
839 .mux_width = 2,
840
841 .div_shift = 0,
842 .div_width = 5,
843
844 .flags = RK_CLK_COMPOSITE_HAVE_MUX,
845 };
846
847 /* CRU_CLKSEL_CON29 */
848
849 #define PCLK_PERI 230
850 #define HCLK_PERI 308
851
852 static const char *phclk_peri_parents[] = {"aclk_peri_pre"};
853 static struct rk_clk_composite_def pclk_peri = {
854 .clkdef = {
855 .id = PCLK_PERI,
856 .name = "pclk_peri",
857 .parent_names = phclk_peri_parents,
858 .parent_cnt = nitems(phclk_peri_parents),
859 },
860
861 .div_shift = 0,
862 .div_width = 2,
863
864 /* CRU_CLKGATE_CON10 */
865 .gate_offset = 0x228,
866 .gate_shift = 2,
867
868 .flags = RK_CLK_COMPOSITE_HAVE_GATE,
869 };
870
871 static struct rk_clk_composite_def hclk_peri = {
872 .clkdef = {
873 .id = HCLK_PERI,
874 .name = "hclk_peri",
875 .parent_names = phclk_peri_parents,
876 .parent_cnt = nitems(phclk_peri_parents),
877 },
878
879 .div_shift = 4,
880 .div_width = 3,
881
882 /* CRU_CLKGATE_CON10 */
883 .gate_offset = 0x228,
884 .gate_shift = 1,
885
886 .flags = RK_CLK_COMPOSITE_HAVE_GATE,
887 };
888
889 /* CRU_CLKSEL_CON30 */
890
891 #define SCLK_SDMMC 33
892
893 static const char *mmc_parents[] = {"cpll", "gpll", "xin24m"/* , "usb480m" */};
894 static struct rk_clk_composite_def sdmmc = {
895 .clkdef = {
896 .id = SCLK_SDMMC,
897 .name = "clk_sdmmc",
898 .parent_names = mmc_parents,
899 .parent_cnt = nitems(mmc_parents),
900 },
901 .muxdiv_offset = 0x178,
902
903 .mux_shift = 8,
904 .mux_width = 2,
905
906 .div_shift = 0,
907 .div_width = 8,
908
909 /* CRU_CLKGATE_CON4 */
910 .gate_offset = 0x210,
911 .gate_shift = 3,
912
913 .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE,
914 };
915
916 /* CRU_CLKSEL_CON31 */
917 #define SCLK_SDIO 34
918
919 static struct rk_clk_composite_def sdio = {
920 .clkdef = {
921 .id = SCLK_SDIO,
922 .name = "clk_sdio",
923 .parent_names = mmc_parents,
924 .parent_cnt = nitems(mmc_parents),
925 },
926 .muxdiv_offset = 0x17C,
927
928 .mux_shift = 8,
929 .mux_width = 2,
930
931 .div_shift = 0,
932 .div_width = 8,
933
934 /* CRU_CLKGATE_CON4 */
935 .gate_offset = 0x210,
936 .gate_shift = 4,
937
938 .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE,
939 };
940
941 /* CRU_CLKSEL_CON32 */
942 #define SCLK_EMMC 35
943
944 static struct rk_clk_composite_def emmc = {
945 .clkdef = {
946 .id = SCLK_EMMC,
947 .name = "clk_emmc",
948 .parent_names = mmc_parents,
949 .parent_cnt = nitems(mmc_parents),
950 },
951 .muxdiv_offset = 0x180,
952
953 .mux_shift = 8,
954 .mux_width = 2,
955
956 .div_shift = 0,
957 .div_width = 8,
958
959 /* CRU_CLKGATE_CON4 */
960 .gate_offset = 0x210,
961 .gate_shift = 5,
962
963 .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE,
964 };
965
966 /* CRU_CLKSEL_CON34 */
967 #define SCLK_I2C0 55
968 #define SCLK_I2C1 56
969
970 static const char *i2c_parents[] = {"cpll", "gpll"};
971
972 static struct rk_clk_composite_def i2c0 = {
973 .clkdef = {
974 .id = SCLK_I2C0,
975 .name = "clk_i2c0",
976 .parent_names = i2c_parents,
977 .parent_cnt = nitems(i2c_parents),
978 },
979 .muxdiv_offset = 0x188,
980
981 .mux_shift = 7,
982 .mux_width = 1,
983
984 .div_shift = 0,
985 .div_width = 6,
986
987 /* CRU_CLKGATE_CON2 */
988 .gate_offset = 0x208,
989 .gate_shift = 9,
990
991 .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE,
992 };
993
994 static struct rk_clk_composite_def i2c1 = {
995 .clkdef = {
996 .id = SCLK_I2C1,
997 .name = "clk_i2c1",
998 .parent_names = i2c_parents,
999 .parent_cnt = nitems(i2c_parents),
1000 },
1001 .muxdiv_offset = 0x188,
1002
1003 .mux_shift = 15,
1004 .mux_width = 1,
1005
1006 .div_shift = 8,
1007 .div_width = 6,
1008
1009 /* CRU_CLKGATE_CON2 */
1010 .gate_offset = 0x208,
1011 .gate_shift = 10,
1012
1013 .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE,
1014 };
1015
1016 /* CRU_CLKSEL_CON35 */
1017 #define SCLK_I2C2 57
1018 #define SCLK_I2C3 58
1019
1020 static struct rk_clk_composite_def i2c2 = {
1021 .clkdef = {
1022 .id = SCLK_I2C2,
1023 .name = "clk_i2c2",
1024 .parent_names = i2c_parents,
1025 .parent_cnt = nitems(i2c_parents),
1026 },
1027 .muxdiv_offset = 0x18C,
1028
1029 .mux_shift = 7,
1030 .mux_width = 1,
1031
1032 .div_shift = 0,
1033 .div_width = 6,
1034
1035 /* CRU_CLKGATE_CON2 */
1036 .gate_offset = 0x208,
1037 .gate_shift = 11,
1038
1039 .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE,
1040 };
1041
1042 static struct rk_clk_composite_def i2c3 = {
1043 .clkdef = {
1044 .id = SCLK_I2C3,
1045 .name = "clk_i2c3",
1046 .parent_names = i2c_parents,
1047 .parent_cnt = nitems(i2c_parents),
1048 },
1049 .muxdiv_offset = 0x18C,
1050
1051 .mux_shift = 15,
1052 .mux_width = 1,
1053
1054 .div_shift = 8,
1055 .div_width = 6,
1056
1057 /* CRU_CLKGATE_CON2 */
1058 .gate_offset = 0x208,
1059 .gate_shift = 12,
1060
1061 .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE,
1062 };
1063
1064 #define SCLK_USB3_REF 72
1065 #define SCLK_USB3_SUSPEND 73
1066 #define SCLK_USB3PHY_REF 94
1067 #define SCLK_REF_USB3OTG 95
1068 #define SCLK_USB3OTG_SUSPEND 97
1069 #define SCLK_REF_USB3OTG_SRC 98
1070
1071 static const char *ref_usb3otg_parents[] = { "xin24m", "clk_usb3otg_ref" };
1072
1073 static struct rk_clk_composite_def ref_usb3otg = {
1074 .clkdef = {
1075 .id = SCLK_REF_USB3OTG,
1076 .name = "clk_ref_usb3otg",
1077 .parent_names = ref_usb3otg_parents,
1078 .parent_cnt = nitems(ref_usb3otg_parents),
1079 },
1080 .muxdiv_offset = 0x1B4,
1081
1082 .mux_shift = 8,
1083 .mux_width = 1,
1084
1085 .flags = RK_CLK_COMPOSITE_HAVE_MUX,
1086 };
1087
1088 static const char *usb3otg_suspend_parents[] = { "xin24m"/*, "clk_rtc32k" */};
1089
1090 static struct rk_clk_composite_def usb3otg_suspend = {
1091 .clkdef = {
1092 .id = SCLK_USB3OTG_SUSPEND,
1093 .name = "clk_usb3otg_suspend",
1094 .parent_names = usb3otg_suspend_parents,
1095 .parent_cnt = nitems(usb3otg_suspend_parents),
1096 },
1097 .muxdiv_offset = 0x184,
1098
1099 .mux_shift = 15,
1100 .mux_width = 1,
1101
1102 .div_shift = 0,
1103 .div_width = 10,
1104
1105 /* CRU_CLKGATE_CON4 */
1106 .gate_offset = 0x210,
1107 .gate_shift = 8,
1108
1109 .flags = RK_CLK_COMPOSITE_HAVE_GATE,
1110 };
1111
1112 static const char *ref_usb3otg_src_parents[] = { "cpll", "gpll" };
1113
1114 static struct rk_clk_composite_def ref_usb3otg_src = {
1115 .clkdef = {
1116 .id = SCLK_REF_USB3OTG_SRC,
1117 .name = "clk_ref_usb3otg_src",
1118 .parent_names = ref_usb3otg_src_parents,
1119 .parent_cnt = nitems(ref_usb3otg_src_parents),
1120 },
1121 .muxdiv_offset = 0x1B4,
1122
1123 .mux_shift = 7,
1124 .mux_width = 1,
1125
1126 .div_shift = 0,
1127 .div_width = 7,
1128
1129 /* CRU_CLKGATE_CON4 */
1130 .gate_offset = 0x210,
1131 .gate_shift = 9,
1132
1133 .flags = RK_CLK_COMPOSITE_HAVE_GATE,
1134 };
1135
1136 /* I2S0 */
1137 static const char *i2s0_div_parents[] = { "cpll", "gpll" };
1138 static struct rk_clk_composite_def i2s0_div = {
1139 .clkdef = {
1140 .id = 0,
1141 .name = "clk_i2s0_div",
1142 .parent_names = i2s0_div_parents,
1143 .parent_cnt = nitems(i2s0_div_parents),
1144 },
1145 /* CRU_CLKSEL_CON6 */
1146 .muxdiv_offset = 0x118,
1147
1148 .mux_shift = 15,
1149 .mux_width = 1,
1150
1151 .div_shift = 0,
1152 .div_width = 7,
1153
1154 /* CRU_CLKGATE_CON1 */
1155 .gate_offset = 0x204,
1156 .gate_shift = 1,
1157
1158 .flags = RK_CLK_COMPOSITE_HAVE_GATE,
1159 };
1160
1161 static const char *i2s0_frac_parents[] = { "clk_i2s0_div" };
1162 static struct rk_clk_fract_def i2s0_frac = {
1163 .clkdef = {
1164 .id = 0,
1165 .name = "clk_i2s0_frac",
1166 .parent_names = i2s0_frac_parents,
1167 .parent_cnt = nitems(i2s0_frac_parents),
1168 },
1169 /* CRU_CLKSEL_CON7 */
1170 .offset = 0x11c,
1171
1172 /* CRU_CLKGATE_CON1 */
1173 .gate_offset = 0x204,
1174 .gate_shift = 2,
1175
1176 .flags = RK_CLK_FRACT_HAVE_GATE,
1177 };
1178
1179 static const char *i2s0_mux_parents[] = { "clk_i2s0_div", "clk_i2s0_frac", "xin12m", "xin12m" };
1180 static struct rk_clk_mux_def i2s0_mux = {
1181 .clkdef = {
1182 .id = 0,
1183 .name = "clk_i2s0_mux",
1184 .parent_names = i2s0_mux_parents,
1185 .parent_cnt = nitems(i2s0_mux_parents),
1186 },
1187 .offset = 0x118,
1188
1189 .shift = 8,
1190 .width = 2,
1191
1192 .mux_flags = RK_CLK_MUX_REPARENT,
1193 };
1194
1195 /* I2S1 */
1196 static const char *i2s1_div_parents[] = { "cpll", "gpll" };
1197 static struct rk_clk_composite_def i2s1_div = {
1198 .clkdef = {
1199 .id = 0,
1200 .name = "clk_i2s1_div",
1201 .parent_names = i2s1_div_parents,
1202 .parent_cnt = nitems(i2s1_div_parents),
1203 },
1204 /* CRU_CLKSEL_CON8 */
1205 .muxdiv_offset = 0x120,
1206
1207 .mux_shift = 15,
1208 .mux_width = 1,
1209
1210 .div_shift = 0,
1211 .div_width = 7,
1212
1213 /* CRU_CLKGATE_CON1 */
1214 .gate_offset = 0x204,
1215 .gate_shift = 4,
1216
1217 .flags = RK_CLK_COMPOSITE_HAVE_GATE,
1218 };
1219
1220 static const char *i2s1_frac_parents[] = { "clk_i2s1_div" };
1221 static struct rk_clk_fract_def i2s1_frac = {
1222 .clkdef = {
1223 .id = 0,
1224 .name = "clk_i2s1_frac",
1225 .parent_names = i2s1_frac_parents,
1226 .parent_cnt = nitems(i2s1_frac_parents),
1227 },
1228 /* CRU_CLKSEL_CON9 */
1229 .offset = 0x124,
1230
1231 /* CRU_CLKGATE_CON1 */
1232 .gate_offset = 0x204,
1233 .gate_shift = 5,
1234
1235 .flags = RK_CLK_FRACT_HAVE_GATE,
1236 };
1237
1238 static const char *i2s1_mux_parents[] = { "clk_i2s1_div", "clk_i2s1_frac", "clkin_i2s1", "xin12m" };
1239 static struct rk_clk_mux_def i2s1_mux = {
1240 .clkdef = {
1241 .id = 0,
1242 .name = "clk_i2s1_mux",
1243 .parent_names = i2s1_mux_parents,
1244 .parent_cnt = nitems(i2s1_mux_parents),
1245 },
1246 .offset = 0x120,
1247
1248 .shift = 8,
1249 .width = 2,
1250 .mux_flags = RK_CLK_MUX_REPARENT,
1251 };
1252
1253 static struct clk_fixed_def clkin_i2s1 = {
1254 .clkdef = {
1255 .id = 0,
1256 .name = "clkin_i2s1",
1257 .parent_names = NULL,
1258 .parent_cnt = 0
1259 },
1260
1261 .freq = 0,
1262 };
1263
1264 /* I2S2 */
1265 static const char *i2s2_div_parents[] = { "cpll", "gpll" };
1266 static struct rk_clk_composite_def i2s2_div = {
1267 .clkdef = {
1268 .id = 0,
1269 .name = "clk_i2s2_div",
1270 .parent_names = i2s2_div_parents,
1271 .parent_cnt = nitems(i2s2_div_parents),
1272 },
1273 /* CRU_CLKSEL_CON10 */
1274 .muxdiv_offset = 0x128,
1275
1276 .mux_shift = 15,
1277 .mux_width = 1,
1278
1279 .div_shift = 0,
1280 .div_width = 7,
1281
1282 /* CRU_CLKGATE_CON1 */
1283 .gate_offset = 0x204,
1284 .gate_shift = 8,
1285
1286 .flags = RK_CLK_COMPOSITE_HAVE_GATE,
1287 };
1288
1289 static const char *i2s2_frac_parents[] = { "clk_i2s2_div" };
1290 static struct rk_clk_fract_def i2s2_frac = {
1291 .clkdef = {
1292 .id = 0,
1293 .name = "clk_i2s2_frac",
1294 .parent_names = i2s2_frac_parents,
1295 .parent_cnt = nitems(i2s2_frac_parents),
1296 },
1297 /* CRU_CLKSEL_CON11 */
1298 .offset = 0x12c,
1299
1300 /* CRU_CLKGATE_CON1 */
1301 .gate_offset = 0x204,
1302 .gate_shift = 9,
1303
1304 .flags = RK_CLK_FRACT_HAVE_GATE,
1305 };
1306
1307 static const char *i2s2_mux_parents[] = { "clk_i2s2_div", "clk_i2s2_frac", "clkin_i2s2", "xin12m" };
1308 static struct rk_clk_mux_def i2s2_mux = {
1309 .clkdef = {
1310 .id = 0,
1311 .name = "clk_i2s2_mux",
1312 .parent_names = i2s2_mux_parents,
1313 .parent_cnt = nitems(i2s2_mux_parents),
1314 },
1315 .offset = 0x128,
1316
1317 .shift = 8,
1318 .width = 2,
1319
1320 .mux_flags = RK_CLK_MUX_REPARENT,
1321 };
1322
1323 static struct clk_fixed_def clkin_i2s2 = {
1324 .clkdef = {
1325 .id = 0,
1326 .name = "clkin_i2s2",
1327 .parent_names = NULL,
1328 .parent_cnt = 0
1329 },
1330
1331 .freq = 0,
1332 };
1333
1334 static struct clk_fixed_def xin12m = {
1335 .clkdef = {
1336 .id = 0,
1337 .name = "xin12m",
1338 .parent_names = NULL,
1339 .parent_cnt = 0
1340 },
1341
1342 .freq = 12000000,
1343 };
1344
1345 static const char *mac2io_src_parents[] = { "cpll", "gpll" };
1346
1347 static struct rk_clk_composite_def mac2io_src = {
1348 .clkdef = {
1349 .id = SCLK_MAC2IO_SRC,
1350 .name = "clk_mac2io_src",
1351 .parent_names = mac2io_src_parents,
1352 .parent_cnt = nitems(mac2io_src_parents),
1353 },
1354 /* CRU_CLKSEL_CON27 */
1355 .muxdiv_offset = 0x16c,
1356
1357 .mux_shift = 7,
1358 .mux_width = 1,
1359
1360 .div_shift = 0,
1361 .div_width = 5,
1362
1363 /* CRU_CLKGATE_CON3 */
1364 .gate_offset = 0x20c,
1365 .gate_shift = 1,
1366
1367 .flags = RK_CLK_COMPOSITE_HAVE_GATE | RK_CLK_COMPOSITE_HAVE_MUX,
1368 };
1369
1370 static const char *mac2io_out_parents[] = { "cpll", "gpll" };
1371
1372 static struct rk_clk_composite_def mac2io_out = {
1373 .clkdef = {
1374 .id = SCLK_MAC2IO_OUT,
1375 .name = "clk_mac2io_out",
1376 .parent_names = mac2io_out_parents,
1377 .parent_cnt = nitems(mac2io_out_parents),
1378 },
1379 /* CRU_CLKSEL_CON27 */
1380 .muxdiv_offset = 0x16c,
1381
1382 .mux_shift = 15,
1383 .mux_width = 1,
1384
1385 .div_shift = 8,
1386 .div_width = 5,
1387
1388 /* CRU_CLKGATE_CON3 */
1389 .gate_offset = 0x20c,
1390 .gate_shift = 5,
1391
1392 .flags = RK_CLK_COMPOSITE_HAVE_GATE | RK_CLK_COMPOSITE_HAVE_MUX,
1393 };
1394
1395 static const char *mac2io_parents[] = { "clk_mac2io_src", "gmac_clkin" };
1396
1397 static struct rk_clk_composite_def mac2io = {
1398 .clkdef = {
1399 .id = SCLK_MAC2IO,
1400 .name = "clk_mac2io",
1401 .parent_names = mac2io_parents,
1402 .parent_cnt = nitems(mac2io_parents),
1403 },
1404 .muxdiv_offset = RK3328_GRF_MAC_CON1,
1405
1406 .mux_shift = 10,
1407 .mux_width = 1,
1408
1409 .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_GRF
1410 };
1411
1412 static const char *mac2io_ext_parents[] = { "clk_mac2io", "gmac_clkin" };
1413
1414 static struct rk_clk_composite_def mac2io_ext = {
1415 .clkdef = {
1416 .id = SCLK_MAC2IO_EXT,
1417 .name = "clk_mac2io_ext",
1418 .parent_names = mac2io_ext_parents,
1419 .parent_cnt = nitems(mac2io_ext_parents),
1420 },
1421 .muxdiv_offset = RK3328_GRF_SOC_CON4,
1422
1423 .mux_shift = 14,
1424 .mux_width = 1,
1425
1426 .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_GRF
1427 };
1428
1429 static const char *mac2phy_src_parents[] = { "cpll", "gpll" };
1430
1431 static struct rk_clk_composite_def mac2phy_src = {
1432 .clkdef = {
1433 .id = SCLK_MAC2PHY_SRC,
1434 .name = "clk_mac2phy_src",
1435 .parent_names = mac2phy_src_parents,
1436 .parent_cnt = nitems(mac2phy_src_parents),
1437 },
1438 /* CRU_CLKSEL_CON26 */
1439 .muxdiv_offset = 0x168,
1440
1441 .mux_shift = 7,
1442 .mux_width = 1,
1443
1444 .div_shift = 0,
1445 .div_width = 5,
1446
1447 /* CRU_CLKGATE_CON3 */
1448 .gate_offset = 0x20c,
1449 .gate_shift = 0,
1450
1451 .flags = RK_CLK_COMPOSITE_HAVE_GATE | RK_CLK_COMPOSITE_HAVE_MUX,
1452 };
1453
1454 static const char *mac2phy_parents[] = { "clk_mac2phy_src", "phy_50m_out" };
1455
1456 static struct rk_clk_composite_def mac2phy = {
1457 .clkdef = {
1458 .id = SCLK_MAC2PHY,
1459 .name = "clk_mac2phy",
1460 .parent_names = mac2phy_parents,
1461 .parent_cnt = nitems(mac2phy_parents),
1462 },
1463 .muxdiv_offset = RK3328_GRF_MAC_CON2,
1464
1465 .mux_shift = 10,
1466 .mux_width = 1,
1467
1468 .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_GRF
1469 };
1470
1471 static const char *mac2phy_out_parents[] = { "clk_mac2phy" };
1472
1473 static struct rk_clk_composite_def mac2phy_out = {
1474 .clkdef = {
1475 .id = SCLK_MAC2PHY_OUT,
1476 .name = "clk_mac2phy_out",
1477 .parent_names = mac2phy_out_parents,
1478 .parent_cnt = nitems(mac2phy_out_parents),
1479 },
1480 /* CRU_CLKSEL_CON26 */
1481 .muxdiv_offset = 0x168,
1482
1483 .div_shift = 8,
1484 .div_width = 2,
1485
1486 /* CRU_CLKGATE_CON9 */
1487 .gate_offset = 0x224,
1488 .gate_shift = 2,
1489
1490 .flags = RK_CLK_COMPOSITE_HAVE_GATE
1491 };
1492
1493 static struct clk_fixed_def phy_50m_out = {
1494 .clkdef.name = "phy_50m_out",
1495 .freq = 50000000,
1496 };
1497
1498 static struct clk_link_def gmac_clkin = {
1499 .clkdef.name = "gmac_clkin",
1500 };
1501
1502 static const char *aclk_gmac_parents[] = { "cpll", "gpll" };
1503
1504 static struct rk_clk_composite_def aclk_gmac = {
1505 .clkdef = {
1506 .id = ACLK_GMAC,
1507 .name = "aclk_gmac",
1508 .parent_names = aclk_gmac_parents,
1509 .parent_cnt = nitems(aclk_gmac_parents),
1510 },
1511 /* CRU_CLKSEL_CON35 */
1512 .muxdiv_offset = 0x18c,
1513
1514 .mux_shift = 6,
1515 .mux_width = 2,
1516
1517 .div_shift = 0,
1518 .div_width = 5,
1519
1520 /* CRU_CLKGATE_CON3 */
1521 .gate_offset = 0x20c,
1522 .gate_shift = 2,
1523
1524 .flags = RK_CLK_COMPOSITE_HAVE_GATE | RK_CLK_COMPOSITE_HAVE_MUX,
1525 };
1526
1527 static const char *pclk_gmac_parents[] = { "aclk_gmac" };
1528
1529 static struct rk_clk_composite_def pclk_gmac = {
1530 .clkdef = {
1531 .id = PCLK_GMAC,
1532 .name = "pclk_gmac",
1533 .parent_names = pclk_gmac_parents,
1534 .parent_cnt = nitems(pclk_gmac_parents),
1535 },
1536 /* CRU_CLKSEL_CON25 */
1537 .muxdiv_offset = 0x164,
1538
1539 .div_shift = 8,
1540 .div_width = 3,
1541
1542 /* CRU_CLKGATE_CON9 */
1543 .gate_offset = 0x224,
1544 .gate_shift = 0,
1545
1546 .flags = RK_CLK_COMPOSITE_HAVE_GATE
1547 };
1548
1549 static struct rk_clk rk3328_clks[] = {
1550 {
1551 .type = RK3328_CLK_PLL,
1552 .clk.pll = &apll
1553 },
1554 {
1555 .type = RK3328_CLK_PLL,
1556 .clk.pll = &dpll
1557 },
1558 {
1559 .type = RK3328_CLK_PLL,
1560 .clk.pll = &cpll
1561 },
1562 {
1563 .type = RK3328_CLK_PLL,
1564 .clk.pll = &gpll
1565 },
1566 {
1567 .type = RK3328_CLK_PLL,
1568 .clk.pll = &npll
1569 },
1570
1571 {
1572 .type = RK_CLK_COMPOSITE,
1573 .clk.composite = &aclk_bus_pre
1574 },
1575 {
1576 .type = RK_CLK_COMPOSITE,
1577 .clk.composite = &hclk_bus_pre
1578 },
1579 {
1580 .type = RK_CLK_COMPOSITE,
1581 .clk.composite = &pclk_bus_pre
1582 },
1583
1584 {
1585 .type = RK_CLK_ARMCLK,
1586 .clk.armclk = &armclk,
1587 },
1588
1589 {
1590 .type = RK_CLK_COMPOSITE,
1591 .clk.composite = &clk_tsadc,
1592 },
1593 {
1594 .type = RK_CLK_COMPOSITE,
1595 .clk.composite = &aclk_peri_pre,
1596 },
1597 {
1598 .type = RK_CLK_COMPOSITE,
1599 .clk.composite = &pclk_peri,
1600 },
1601 {
1602 .type = RK_CLK_COMPOSITE,
1603 .clk.composite = &hclk_peri,
1604 },
1605 {
1606 .type = RK_CLK_COMPOSITE,
1607 .clk.composite = &sdmmc
1608 },
1609 {
1610 .type = RK_CLK_COMPOSITE,
1611 .clk.composite = &sdio
1612 },
1613 {
1614 .type = RK_CLK_COMPOSITE,
1615 .clk.composite = &emmc
1616 },
1617
1618 {
1619 .type = RK_CLK_COMPOSITE,
1620 .clk.composite = &i2c0
1621 },
1622 {
1623 .type = RK_CLK_COMPOSITE,
1624 .clk.composite = &i2c1
1625 },
1626 {
1627 .type = RK_CLK_COMPOSITE,
1628 .clk.composite = &i2c2
1629 },
1630 {
1631 .type = RK_CLK_COMPOSITE,
1632 .clk.composite = &i2c3
1633 },
1634
1635 {
1636 .type = RK_CLK_COMPOSITE,
1637 .clk.composite = &ref_usb3otg
1638 },
1639 {
1640 .type = RK_CLK_COMPOSITE,
1641 .clk.composite = &ref_usb3otg_src
1642 },
1643 {
1644 .type = RK_CLK_COMPOSITE,
1645 .clk.composite = &usb3otg_suspend
1646 },
1647 {
1648 .type = RK_CLK_COMPOSITE,
1649 .clk.composite = &i2s0_div
1650 },
1651 {
1652 .type = RK_CLK_FRACT,
1653 .clk.fract = &i2s0_frac
1654 },
1655 {
1656 .type = RK_CLK_MUX,
1657 .clk.mux = &i2s0_mux
1658 },
1659 {
1660 .type = RK_CLK_COMPOSITE,
1661 .clk.composite = &i2s1_div
1662 },
1663 {
1664 .type = RK_CLK_FRACT,
1665 .clk.fract = &i2s1_frac
1666 },
1667 {
1668 .type = RK_CLK_MUX,
1669 .clk.mux = &i2s1_mux
1670 },
1671 {
1672 .type = RK_CLK_FIXED,
1673 .clk.fixed = &clkin_i2s1
1674 },
1675 {
1676 .type = RK_CLK_COMPOSITE,
1677 .clk.composite = &i2s2_div
1678 },
1679 {
1680 .type = RK_CLK_FRACT,
1681 .clk.fract = &i2s2_frac
1682 },
1683 {
1684 .type = RK_CLK_MUX,
1685 .clk.mux = &i2s2_mux
1686 },
1687 {
1688 .type = RK_CLK_FIXED,
1689 .clk.fixed = &clkin_i2s2
1690 },
1691 {
1692 .type = RK_CLK_FIXED,
1693 .clk.fixed = &xin12m
1694 },
1695 {
1696 .type = RK_CLK_COMPOSITE,
1697 .clk.composite = &mac2io_src
1698 },
1699 {
1700 .type = RK_CLK_COMPOSITE,
1701 .clk.composite = &mac2io
1702 },
1703 {
1704 .type = RK_CLK_COMPOSITE,
1705 .clk.composite = &mac2io_out
1706 },
1707 {
1708 .type = RK_CLK_COMPOSITE,
1709 .clk.composite = &mac2io_ext
1710 },
1711 {
1712 .type = RK_CLK_COMPOSITE,
1713 .clk.composite = &mac2phy_src
1714 },
1715 {
1716 .type = RK_CLK_COMPOSITE,
1717 .clk.composite = &mac2phy
1718 },
1719 {
1720 .type = RK_CLK_COMPOSITE,
1721 .clk.composite = &mac2phy_out
1722 },
1723 {
1724 .type = RK_CLK_FIXED,
1725 .clk.fixed = &phy_50m_out
1726 },
1727 {
1728 .type = RK_CLK_LINK,
1729 .clk.link = &gmac_clkin
1730 },
1731 {
1732 .type = RK_CLK_COMPOSITE,
1733 .clk.composite = &aclk_gmac
1734 },
1735 {
1736 .type = RK_CLK_COMPOSITE,
1737 .clk.composite = &pclk_gmac
1738 },
1739 };
1740
1741 static int
rk3328_cru_probe(device_t dev)1742 rk3328_cru_probe(device_t dev)
1743 {
1744
1745 if (!ofw_bus_status_okay(dev))
1746 return (ENXIO);
1747
1748 if (ofw_bus_is_compatible(dev, "rockchip,rk3328-cru")) {
1749 device_set_desc(dev, "Rockchip RK3328 Clock and Reset Unit");
1750 return (BUS_PROBE_DEFAULT);
1751 }
1752
1753 return (ENXIO);
1754 }
1755
1756 static int
rk3328_cru_attach(device_t dev)1757 rk3328_cru_attach(device_t dev)
1758 {
1759 struct rk_cru_softc *sc;
1760
1761 sc = device_get_softc(dev);
1762 sc->dev = dev;
1763
1764 sc->gates = rk3328_gates;
1765 sc->ngates = nitems(rk3328_gates);
1766
1767 sc->clks = rk3328_clks;
1768 sc->nclks = nitems(rk3328_clks);
1769
1770 sc->reset_offset = 0x300;
1771 sc->reset_num = 184;
1772
1773 return (rk_cru_attach(dev));
1774 }
1775
1776 static device_method_t rk3328_cru_methods[] = {
1777 /* Device interface */
1778 DEVMETHOD(device_probe, rk3328_cru_probe),
1779 DEVMETHOD(device_attach, rk3328_cru_attach),
1780
1781 DEVMETHOD_END
1782 };
1783
1784 static devclass_t rk3328_cru_devclass;
1785
1786 DEFINE_CLASS_1(rk3328_cru, rk3328_cru_driver, rk3328_cru_methods,
1787 sizeof(struct rk_cru_softc), rk_cru_driver);
1788
1789 EARLY_DRIVER_MODULE(rk3328_cru, simplebus, rk3328_cru_driver,
1790 rk3328_cru_devclass, 0, 0, BUS_PASS_BUS + BUS_PASS_ORDER_MIDDLE);
1791