1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3  *
4  * Copyright (c) 2018 Emmanuel Vadot <[email protected]>
5  * Copyright (c) 2018 Greg V <[email protected]>
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  *
28  * $FreeBSD$
29  */
30 
31 #include <sys/cdefs.h>
32 __FBSDID("$FreeBSD$");
33 
34 #include <sys/param.h>
35 #include <sys/systm.h>
36 #include <sys/bus.h>
37 #include <sys/rman.h>
38 #include <sys/kernel.h>
39 #include <sys/module.h>
40 #include <machine/bus.h>
41 
42 #include <dev/fdt/simplebus.h>
43 
44 #include <dev/ofw/ofw_bus.h>
45 #include <dev/ofw/ofw_bus_subr.h>
46 
47 #include <dev/extres/clk/clk_div.h>
48 #include <dev/extres/clk/clk_fixed.h>
49 #include <dev/extres/clk/clk_mux.h>
50 
51 #include <arm64/rockchip/clk/rk_cru.h>
52 
53 /* GATES */
54 
55 #define	PCLK_GPIO2		336
56 #define	PCLK_GPIO3		337
57 #define	PCLK_GPIO4		338
58 #define	PCLK_I2C1		341
59 #define	PCLK_I2C2		342
60 #define	PCLK_I2C3		343
61 #define	PCLK_I2C5		344
62 #define	PCLK_I2C6		345
63 #define	PCLK_I2C7		346
64 #define	HCLK_SDMMC		462
65 
66 static struct rk_cru_gate rk3399_gates[] = {
67 	/* CRU_CLKGATE_CON0 */
68 	CRU_GATE(0, "clk_core_l_lpll_src", "lpll", 0x300, 0)
69 	CRU_GATE(0, "clk_core_l_bpll_src", "bpll", 0x300, 1)
70 	CRU_GATE(0, "clk_core_l_dpll_src", "dpll", 0x300, 2)
71 	CRU_GATE(0, "clk_core_l_gpll_src", "gpll", 0x300, 3)
72 
73 	/* CRU_CLKGATE_CON1 */
74 	CRU_GATE(0, "clk_core_b_lpll_src", "lpll", 0x304, 0)
75 	CRU_GATE(0, "clk_core_b_bpll_src", "bpll", 0x304, 1)
76 	CRU_GATE(0, "clk_core_b_dpll_src", "dpll", 0x304, 2)
77 	CRU_GATE(0, "clk_core_b_gpll_src", "gpll", 0x304, 3)
78 
79 	/* CRU_CLKGATE_CON5 */
80 	CRU_GATE(0, "cpll_aclk_perihp_src", "cpll", 0x314, 0)
81 	CRU_GATE(0, "gpll_aclk_perihp_src", "gpll", 0x314, 1)
82 
83 	/* CRU_CLKGATE_CON7 */
84 	CRU_GATE(0, "gpll_aclk_perilp0_src", "gpll", 0x31C, 0)
85 	CRU_GATE(0, "cpll_aclk_perilp0_src", "cpll", 0x31C, 1)
86 
87 	/* CRU_CLKGATE_CON8 */
88 	CRU_GATE(0, "hclk_perilp1_cpll_src", "cpll", 0x320, 1)
89 	CRU_GATE(0, "hclk_perilp1_gpll_src", "gpll", 0x320, 0)
90 
91 	/* CRU_CLKGATE_CON22 */
92 	CRU_GATE(PCLK_I2C7, "pclk_rki2c7", "pclk_perilp1", 0x358, 5)
93 	CRU_GATE(PCLK_I2C1, "pclk_rki2c1", "pclk_perilp1", 0x358, 6)
94 	CRU_GATE(PCLK_I2C5, "pclk_rki2c5", "pclk_perilp1", 0x358, 7)
95 	CRU_GATE(PCLK_I2C6, "pclk_rki2c6", "pclk_perilp1", 0x358, 8)
96 	CRU_GATE(PCLK_I2C2, "pclk_rki2c2", "pclk_perilp1", 0x358, 9)
97 	CRU_GATE(PCLK_I2C3, "pclk_rki2c3", "pclk_perilp1", 0x358, 10)
98 
99 	/* CRU_CLKGATE_CON31 */
100 	CRU_GATE(PCLK_GPIO2, "pclk_gpio2", "pclk_alive", 0x37c, 3)
101 	CRU_GATE(PCLK_GPIO3, "pclk_gpio3", "pclk_alive", 0x37c, 4)
102 	CRU_GATE(PCLK_GPIO4, "pclk_gpio4", "pclk_alive", 0x37c, 5)
103 
104 	/* CRU_CLKGATE_CON33 */
105 	CRU_GATE(HCLK_SDMMC, "hclk_sdmmc", "hclk_sd", 0x384, 8)
106 };
107 
108 
109 /*
110  * PLLs
111  */
112 
113 #define PLL_APLLL			1
114 #define PLL_APLLB			2
115 #define PLL_DPLL			3
116 #define PLL_CPLL			4
117 #define PLL_GPLL			5
118 #define PLL_NPLL			6
119 #define PLL_VPLL			7
120 
121 static struct rk_clk_pll_rate rk3399_pll_rates[] = {
122 	{
123 		.freq = 2208000000,
124 		.refdiv = 1,
125 		.fbdiv = 92,
126 		.postdiv1 = 1,
127 		.postdiv2 = 1,
128 		.dsmpd = 1,
129 	},
130 	{
131 		.freq = 2184000000,
132 		.refdiv = 1,
133 		.fbdiv = 91,
134 		.postdiv1 = 1,
135 		.postdiv2 = 1,
136 		.dsmpd = 1,
137 	},
138 	{
139 		.freq = 2160000000,
140 		.refdiv = 1,
141 		.fbdiv = 90,
142 		.postdiv1 = 1,
143 		.postdiv2 = 1,
144 		.dsmpd = 1,
145 	},
146 	{
147 		.freq = 2136000000,
148 		.refdiv = 1,
149 		.fbdiv = 89,
150 		.postdiv1 = 1,
151 		.postdiv2 = 1,
152 		.dsmpd = 1,
153 	},
154 	{
155 		.freq = 2112000000,
156 		.refdiv = 1,
157 		.fbdiv = 88,
158 		.postdiv1 = 1,
159 		.postdiv2 = 1,
160 		.dsmpd = 1,
161 	},
162 	{
163 		.freq = 2088000000,
164 		.refdiv = 1,
165 		.fbdiv = 87,
166 		.postdiv1 = 1,
167 		.postdiv2 = 1,
168 		.dsmpd = 1,
169 	},
170 	{
171 		.freq = 2064000000,
172 		.refdiv = 1,
173 		.fbdiv = 86,
174 		.postdiv1 = 1,
175 		.postdiv2 = 1,
176 		.dsmpd = 1,
177 	},
178 	{
179 		.freq = 2040000000,
180 		.refdiv = 1,
181 		.fbdiv = 85,
182 		.postdiv1 = 1,
183 		.postdiv2 = 1,
184 		.dsmpd = 1,
185 	},
186 	{
187 		.freq = 2016000000,
188 		.refdiv = 1,
189 		.fbdiv = 84,
190 		.postdiv1 = 1,
191 		.postdiv2 = 1,
192 		.dsmpd = 1,
193 	},
194 	{
195 		.freq = 1992000000,
196 		.refdiv = 1,
197 		.fbdiv = 83,
198 		.postdiv1 = 1,
199 		.postdiv2 = 1,
200 		.dsmpd = 1,
201 	},
202 	{
203 		.freq = 1968000000,
204 		.refdiv = 1,
205 		.fbdiv = 82,
206 		.postdiv1 = 1,
207 		.postdiv2 = 1,
208 		.dsmpd = 1,
209 	},
210 	{
211 		.freq = 1944000000,
212 		.refdiv = 1,
213 		.fbdiv = 81,
214 		.postdiv1 = 1,
215 		.postdiv2 = 1,
216 		.dsmpd = 1,
217 	},
218 	{
219 		.freq = 1920000000,
220 		.refdiv = 1,
221 		.fbdiv = 80,
222 		.postdiv1 = 1,
223 		.postdiv2 = 1,
224 		.dsmpd = 1,
225 	},
226 	{
227 		.freq = 1896000000,
228 		.refdiv = 1,
229 		.fbdiv = 79,
230 		.postdiv1 = 1,
231 		.postdiv2 = 1,
232 		.dsmpd = 1,
233 	},
234 	{
235 		.freq = 1872000000,
236 		.refdiv = 1,
237 		.fbdiv = 78,
238 		.postdiv1 = 1,
239 		.postdiv2 = 1,
240 		.dsmpd = 1,
241 	},
242 	{
243 		.freq = 1848000000,
244 		.refdiv = 1,
245 		.fbdiv = 77,
246 		.postdiv1 = 1,
247 		.postdiv2 = 1,
248 		.dsmpd = 1,
249 	},
250 	{
251 		.freq = 1824000000,
252 		.refdiv = 1,
253 		.fbdiv = 76,
254 		.postdiv1 = 1,
255 		.postdiv2 = 1,
256 		.dsmpd = 1,
257 	},
258 	{
259 		.freq = 1800000000,
260 		.refdiv = 1,
261 		.fbdiv = 75,
262 		.postdiv1 = 1,
263 		.postdiv2 = 1,
264 		.dsmpd = 1,
265 	},
266 	{
267 		.freq = 1776000000,
268 		.refdiv = 1,
269 		.fbdiv = 74,
270 		.postdiv1 = 1,
271 		.postdiv2 = 1,
272 		.dsmpd = 1,
273 	},
274 	{
275 		.freq = 1752000000,
276 		.refdiv = 1,
277 		.fbdiv = 73,
278 		.postdiv1 = 1,
279 		.postdiv2 = 1,
280 		.dsmpd = 1,
281 	},
282 	{
283 		.freq = 1728000000,
284 		.refdiv = 1,
285 		.fbdiv = 72,
286 		.postdiv1 = 1,
287 		.postdiv2 = 1,
288 		.dsmpd = 1,
289 	},
290 	{
291 		.freq = 1704000000,
292 		.refdiv = 1,
293 		.fbdiv = 71,
294 		.postdiv1 = 1,
295 		.postdiv2 = 1,
296 		.dsmpd = 1,
297 	},
298 	{
299 		.freq = 1680000000,
300 		.refdiv = 1,
301 		.fbdiv = 70,
302 		.postdiv1 = 1,
303 		.postdiv2 = 1,
304 		.dsmpd = 1,
305 	},
306 	{
307 		.freq = 1656000000,
308 		.refdiv = 1,
309 		.fbdiv = 69,
310 		.postdiv1 = 1,
311 		.postdiv2 = 1,
312 		.dsmpd = 1,
313 	},
314 	{
315 		.freq = 1632000000,
316 		.refdiv = 1,
317 		.fbdiv = 68,
318 		.postdiv1 = 1,
319 		.postdiv2 = 1,
320 		.dsmpd = 1,
321 	},
322 	{
323 		.freq = 1608000000,
324 		.refdiv = 1,
325 		.fbdiv = 67,
326 		.postdiv1 = 1,
327 		.postdiv2 = 1,
328 		.dsmpd = 1,
329 	},
330 	{
331 		.freq = 1600000000,
332 		.refdiv = 3,
333 		.fbdiv = 200,
334 		.postdiv1 = 1,
335 		.postdiv2 = 1,
336 		.dsmpd = 1,
337 	},
338 	{
339 		.freq = 1584000000,
340 		.refdiv = 1,
341 		.fbdiv = 66,
342 		.postdiv1 = 1,
343 		.postdiv2 = 1,
344 		.dsmpd = 1,
345 	},
346 	{
347 		.freq = 1560000000,
348 		.refdiv = 1,
349 		.fbdiv = 65,
350 		.postdiv1 = 1,
351 		.postdiv2 = 1,
352 		.dsmpd = 1,
353 	},
354 	{
355 		.freq = 1536000000,
356 		.refdiv = 1,
357 		.fbdiv = 64,
358 		.postdiv1 = 1,
359 		.postdiv2 = 1,
360 		.dsmpd = 1,
361 	},
362 	{
363 		.freq = 1512000000,
364 		.refdiv = 1,
365 		.fbdiv = 63,
366 		.postdiv1 = 1,
367 		.postdiv2 = 1,
368 		.dsmpd = 1,
369 	},
370 	{
371 		.freq = 1488000000,
372 		.refdiv = 1,
373 		.fbdiv = 62,
374 		.postdiv1 = 1,
375 		.postdiv2 = 1,
376 		.dsmpd = 1,
377 	},
378 	{
379 		.freq = 1464000000,
380 		.refdiv = 1,
381 		.fbdiv = 61,
382 		.postdiv1 = 1,
383 		.postdiv2 = 1,
384 		.dsmpd = 1,
385 	},
386 	{
387 		.freq = 1440000000,
388 		.refdiv = 1,
389 		.fbdiv = 60,
390 		.postdiv1 = 1,
391 		.postdiv2 = 1,
392 		.dsmpd = 1,
393 	},
394 	{
395 		.freq = 1416000000,
396 		.refdiv = 1,
397 		.fbdiv = 59,
398 		.postdiv1 = 1,
399 		.postdiv2 = 1,
400 		.dsmpd = 1,
401 	},
402 	{
403 		.freq = 1392000000,
404 		.refdiv = 1,
405 		.fbdiv = 58,
406 		.postdiv1 = 1,
407 		.postdiv2 = 1,
408 		.dsmpd = 1,
409 	},
410 	{
411 		.freq = 1368000000,
412 		.refdiv = 1,
413 		.fbdiv = 57,
414 		.postdiv1 = 1,
415 		.postdiv2 = 1,
416 		.dsmpd = 1,
417 	},
418 	{
419 		.freq = 1344000000,
420 		.refdiv = 1,
421 		.fbdiv = 56,
422 		.postdiv1 = 1,
423 		.postdiv2 = 1,
424 		.dsmpd = 1,
425 	},
426 	{
427 		.freq = 1320000000,
428 		.refdiv = 1,
429 		.fbdiv = 55,
430 		.postdiv1 = 1,
431 		.postdiv2 = 1,
432 		.dsmpd = 1,
433 	},
434 	{
435 		.freq = 1296000000,
436 		.refdiv = 1,
437 		.fbdiv = 54,
438 		.postdiv1 = 1,
439 		.postdiv2 = 1,
440 		.dsmpd = 1,
441 	},
442 	{
443 		.freq = 1272000000,
444 		.refdiv = 1,
445 		.fbdiv = 53,
446 		.postdiv1 = 1,
447 		.postdiv2 = 1,
448 		.dsmpd = 1,
449 	},
450 	{
451 		.freq = 1248000000,
452 		.refdiv = 1,
453 		.fbdiv = 52,
454 		.postdiv1 = 1,
455 		.postdiv2 = 1,
456 		.dsmpd = 1,
457 	},
458 	{
459 		.freq = 1200000000,
460 		.refdiv = 1,
461 		.fbdiv = 50,
462 		.postdiv1 = 1,
463 		.postdiv2 = 1,
464 		.dsmpd = 1,
465 	},
466 	{
467 		.freq = 1188000000,
468 		.refdiv = 2,
469 		.fbdiv = 99,
470 		.postdiv1 = 1,
471 		.postdiv2 = 1,
472 		.dsmpd = 1,
473 	},
474 	{
475 		.freq = 1104000000,
476 		.refdiv = 1,
477 		.fbdiv = 46,
478 		.postdiv1 = 1,
479 		.postdiv2 = 1,
480 		.dsmpd = 1,
481 	},
482 	{
483 		.freq = 1100000000,
484 		.refdiv = 12,
485 		.fbdiv = 550,
486 		.postdiv1 = 1,
487 		.postdiv2 = 1,
488 		.dsmpd = 1,
489 	},
490 	{
491 		.freq = 1008000000,
492 		.refdiv = 1,
493 		.fbdiv = 84,
494 		.postdiv1 = 2,
495 		.postdiv2 = 1,
496 		.dsmpd = 1,
497 	},
498 	{
499 		.freq = 1000000000,
500 		.refdiv = 1,
501 		.fbdiv = 125,
502 		.postdiv1 = 3,
503 		.postdiv2 = 1,
504 		.dsmpd = 1,
505 	},
506 	{
507 		.freq = 984000000,
508 		.refdiv = 1,
509 		.fbdiv = 82,
510 		.postdiv1 = 2,
511 		.postdiv2 = 1,
512 		.dsmpd = 1,
513 	},
514 	{
515 		.freq = 960000000,
516 		.refdiv = 1,
517 		.fbdiv = 80,
518 		.postdiv1 = 2,
519 		.postdiv2 = 1,
520 		.dsmpd = 1,
521 	},
522 	{
523 		.freq = 936000000,
524 		.refdiv = 1,
525 		.fbdiv = 78,
526 		.postdiv1 = 2,
527 		.postdiv2 = 1,
528 		.dsmpd = 1,
529 	},
530 	{
531 		.freq = 912000000,
532 		.refdiv = 1,
533 		.fbdiv = 76,
534 		.postdiv1 = 2,
535 		.postdiv2 = 1,
536 		.dsmpd = 1,
537 	},
538 	{
539 		.freq = 900000000,
540 		.refdiv = 4,
541 		.fbdiv = 300,
542 		.postdiv1 = 2,
543 		.postdiv2 = 1,
544 		.dsmpd = 1,
545 	},
546 	{
547 		.freq = 888000000,
548 		.refdiv = 1,
549 		.fbdiv = 74,
550 		.postdiv1 = 2,
551 		.postdiv2 = 1,
552 		.dsmpd = 1,
553 	},
554 	{
555 		.freq = 864000000,
556 		.refdiv = 1,
557 		.fbdiv = 72,
558 		.postdiv1 = 2,
559 		.postdiv2 = 1,
560 		.dsmpd = 1,
561 	},
562 	{
563 		.freq = 840000000,
564 		.refdiv = 1,
565 		.fbdiv = 70,
566 		.postdiv1 = 2,
567 		.postdiv2 = 1,
568 		.dsmpd = 1,
569 	},
570 	{
571 		.freq = 816000000,
572 		.refdiv = 1,
573 		.fbdiv = 68,
574 		.postdiv1 = 2,
575 		.postdiv2 = 1,
576 		.dsmpd = 1,
577 	},
578 	{
579 		.freq = 800000000,
580 		.refdiv = 1,
581 		.fbdiv = 100,
582 		.postdiv1 = 3,
583 		.postdiv2 = 1,
584 		.dsmpd = 1,
585 	},
586 	{
587 		.freq = 700000000,
588 		.refdiv = 6,
589 		.fbdiv = 350,
590 		.postdiv1 = 2,
591 		.postdiv2 = 1,
592 		.dsmpd = 1,
593 	},
594 	{
595 		.freq = 696000000,
596 		.refdiv = 1,
597 		.fbdiv = 58,
598 		.postdiv1 = 2,
599 		.postdiv2 = 1,
600 		.dsmpd = 1,
601 	},
602 	{
603 		.freq = 676000000,
604 		.refdiv = 3,
605 		.fbdiv = 169,
606 		.postdiv1 = 2,
607 		.postdiv2 = 1,
608 		.dsmpd = 1,
609 	},
610 	{
611 		.freq = 600000000,
612 		.refdiv = 1,
613 		.fbdiv = 75,
614 		.postdiv1 = 3,
615 		.postdiv2 = 1,
616 		.dsmpd = 1,
617 	},
618 	{
619 		.freq = 594000000,
620 		.refdiv = 1,
621 		.fbdiv = 99,
622 		.postdiv1 = 4,
623 		.postdiv2 = 1,
624 		.dsmpd = 1,
625 	},
626 	{
627 		.freq = 533250000,
628 		.refdiv = 8,
629 		.fbdiv = 711,
630 		.postdiv1 = 4,
631 		.postdiv2 = 1,
632 		.dsmpd = 1,
633 	},
634 	{
635 		.freq = 504000000,
636 		.refdiv = 1,
637 		.fbdiv = 63,
638 		.postdiv1 = 3,
639 		.postdiv2 = 1,
640 		.dsmpd = 1,
641 	},
642 	{
643 		.freq = 500000000,
644 		.refdiv = 6,
645 		.fbdiv = 250,
646 		.postdiv1 = 2,
647 		.postdiv2 = 1,
648 		.dsmpd = 1,
649 	},
650 	{
651 		.freq = 408000000,
652 		.refdiv = 1,
653 		.fbdiv = 68,
654 		.postdiv1 = 2,
655 		.postdiv2 = 2,
656 		.dsmpd = 1,
657 	},
658 	{
659 		.freq = 312000000,
660 		.refdiv = 1,
661 		.fbdiv = 52,
662 		.postdiv1 = 2,
663 		.postdiv2 = 2,
664 		.dsmpd = 1,
665 	},
666 	{
667 		.freq = 297000000,
668 		.refdiv = 1,
669 		.fbdiv = 99,
670 		.postdiv1 = 4,
671 		.postdiv2 = 2,
672 		.dsmpd = 1,
673 	},
674 	{
675 		.freq = 216000000,
676 		.refdiv = 1,
677 		.fbdiv = 72,
678 		.postdiv1 = 4,
679 		.postdiv2 = 2,
680 		.dsmpd = 1,
681 	},
682 	{
683 		.freq = 148500000,
684 		.refdiv = 1,
685 		.fbdiv = 99,
686 		.postdiv1 = 4,
687 		.postdiv2 = 4,
688 		.dsmpd = 1,
689 	},
690 	{
691 		.freq = 106500000,
692 		.refdiv = 1,
693 		.fbdiv = 71,
694 		.postdiv1 = 4,
695 		.postdiv2 = 4,
696 		.dsmpd = 1,
697 	},
698 	{
699 		.freq = 96000000,
700 		.refdiv = 1,
701 		.fbdiv = 64,
702 		.postdiv1 = 4,
703 		.postdiv2 = 4,
704 		.dsmpd = 1,
705 	},
706 	{
707 		.freq = 74250000,
708 		.refdiv = 2,
709 		.fbdiv = 99,
710 		.postdiv1 = 4,
711 		.postdiv2 = 4,
712 		.dsmpd = 1,
713 	},
714 	{
715 		.freq = 65000000,
716 		.refdiv = 1,
717 		.fbdiv = 65,
718 		.postdiv1 = 6,
719 		.postdiv2 = 4,
720 		.dsmpd = 1,
721 	},
722 	{
723 		.freq = 54000000,
724 		.refdiv = 1,
725 		.fbdiv = 54,
726 		.postdiv1 = 6,
727 		.postdiv2 = 4,
728 		.dsmpd = 1,
729 	},
730 	{
731 		.freq = 27000000,
732 		.refdiv = 1,
733 		.fbdiv = 27,
734 		.postdiv1 = 6,
735 		.postdiv2 = 4,
736 		.dsmpd = 1,
737 	},
738 	{},
739 };
740 
741 static const char *pll_parents[] = {"xin24m"};
742 
743 static struct rk_clk_pll_def lpll = {
744 	.clkdef = {
745 		.id = PLL_APLLL,
746 		.name = "lpll",
747 		.parent_names = pll_parents,
748 		.parent_cnt = nitems(pll_parents),
749 	},
750 	.base_offset = 0x00,
751 	.gate_offset = 0x300,
752 	.gate_shift = 0,
753 	.flags = RK_CLK_PLL_HAVE_GATE,
754 	.rates = rk3399_pll_rates,
755 	.normal_mode = true,
756 };
757 
758 static struct rk_clk_pll_def bpll = {
759 	.clkdef = {
760 		.id = PLL_APLLB,
761 		.name = "bpll",
762 		.parent_names = pll_parents,
763 		.parent_cnt = nitems(pll_parents),
764 	},
765 	.base_offset = 0x20,
766 	.gate_offset = 0x300,
767 	.gate_shift = 1,
768 	.flags = RK_CLK_PLL_HAVE_GATE,
769 	.rates = rk3399_pll_rates,
770 	.normal_mode = true,
771 };
772 
773 static struct rk_clk_pll_def dpll = {
774 	.clkdef = {
775 		.id = PLL_DPLL,
776 		.name = "dpll",
777 		.parent_names = pll_parents,
778 		.parent_cnt = nitems(pll_parents),
779 	},
780 	.base_offset = 0x40,
781 	.gate_offset = 0x300,
782 	.gate_shift = 2,
783 	.flags = RK_CLK_PLL_HAVE_GATE,
784 	.rates = rk3399_pll_rates,
785 };
786 
787 
788 static struct rk_clk_pll_def cpll = {
789 	.clkdef = {
790 		.id = PLL_CPLL,
791 		.name = "cpll",
792 		.parent_names = pll_parents,
793 		.parent_cnt = nitems(pll_parents),
794 	},
795 	.base_offset = 0x60,
796 	.rates = rk3399_pll_rates,
797 };
798 
799 static struct rk_clk_pll_def gpll = {
800 	.clkdef = {
801 		.id = PLL_GPLL,
802 		.name = "gpll",
803 		.parent_names = pll_parents,
804 		.parent_cnt = nitems(pll_parents),
805 	},
806 	.base_offset = 0x80,
807 	.gate_offset = 0x300,
808 	.gate_shift = 3,
809 	.flags = RK_CLK_PLL_HAVE_GATE,
810 	.rates = rk3399_pll_rates,
811 };
812 
813 static struct rk_clk_pll_def npll = {
814 	.clkdef = {
815 		.id = PLL_NPLL,
816 		.name = "npll",
817 		.parent_names = pll_parents,
818 		.parent_cnt = nitems(pll_parents),
819 	},
820 	.base_offset = 0xa0,
821 	.rates = rk3399_pll_rates,
822 };
823 
824 static struct rk_clk_pll_def vpll = {
825 	.clkdef = {
826 		.id = PLL_VPLL,
827 		.name = "vpll",
828 		.parent_names = pll_parents,
829 		.parent_cnt = nitems(pll_parents),
830 	},
831 	.base_offset = 0xc0,
832 	.rates = rk3399_pll_rates,
833 };
834 
835 #define	ACLK_PERIHP	192
836 #define	HCLK_PERIHP	448
837 #define	PCLK_PERIHP	320
838 
839 static const char *aclk_perihp_parents[] = {"cpll_aclk_perihp_src", "gpll_aclk_perihp_src"};
840 
841 static struct rk_clk_composite_def aclk_perihp = {
842 	.clkdef = {
843 		.id = ACLK_PERIHP,
844 		.name = "aclk_perihp",
845 		.parent_names = aclk_perihp_parents,
846 		.parent_cnt = nitems(aclk_perihp_parents),
847 	},
848 	/* CRU_CLKSEL_CON14 */
849 	.muxdiv_offset = 0x138,
850 
851 	.mux_shift = 7,
852 	.mux_width = 1,
853 
854 	.div_shift = 0,
855 	.div_width = 5,
856 
857 	/* CRU_CLKGATE_CON5 */
858 	.gate_offset = 0x314,
859 	.gate_shift = 2,
860 
861 	.flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE,
862 };
863 
864 static const char *hclk_pclk_perihp_parents[] = {"aclk_perihp"};
865 
866 static struct rk_clk_composite_def hclk_perihp = {
867 	.clkdef = {
868 		.id = HCLK_PERIHP,
869 		.name = "hclk_perihp",
870 		.parent_names = hclk_pclk_perihp_parents,
871 		.parent_cnt = nitems(hclk_pclk_perihp_parents),
872 	},
873 	/* CRU_CLKSEL_CON14 */
874 	.muxdiv_offset = 0x138,
875 
876 	.div_shift = 8,
877 	.div_width = 2,
878 
879 	/* CRU_CLKGATE_CON5 */
880 	.gate_offset = 0x314,
881 	.gate_shift = 3,
882 
883 	.flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE,
884 };
885 
886 static struct rk_clk_composite_def pclk_perihp = {
887 	.clkdef = {
888 		.id = PCLK_PERIHP,
889 		.name = "pclk_perihp",
890 		.parent_names = hclk_pclk_perihp_parents,
891 		.parent_cnt = nitems(hclk_pclk_perihp_parents),
892 	},
893 	/* CRU_CLKSEL_CON14 */
894 	.muxdiv_offset = 0x138,
895 
896 	.div_shift = 12,
897 	.div_width = 3,
898 
899 	/* CRU_CLKGATE_CON5 */
900 	.gate_offset = 0x314,
901 	.gate_shift = 4,
902 
903 	.flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE,
904 };
905 
906 #define	ACLK_PERILP0	194
907 #define	HCLK_PERILP0	449
908 #define	PCLK_PERILP0	322
909 
910 static const char *aclk_perilp0_parents[] = {"cpll_aclk_perilp0_src", "gpll_aclk_perilp0_src"};
911 
912 static struct rk_clk_composite_def aclk_perilp0 = {
913 	.clkdef = {
914 		.id = ACLK_PERILP0,
915 		.name = "aclk_perilp0",
916 		.parent_names = aclk_perilp0_parents,
917 		.parent_cnt = nitems(aclk_perilp0_parents),
918 	},
919 	/* CRU_CLKSEL_CON14 */
920 	.muxdiv_offset = 0x15C,
921 
922 	.mux_shift = 7,
923 	.mux_width = 1,
924 
925 	.div_shift = 0,
926 	.div_width = 5,
927 
928 	/* CRU_CLKGATE_CON7 */
929 	.gate_offset = 0x31C,
930 	.gate_shift = 2,
931 
932 	.flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE,
933 };
934 
935 static const char *hclk_pclk_perilp0_parents[] = {"aclk_perilp0"};
936 
937 static struct rk_clk_composite_def hclk_perilp0 = {
938 	.clkdef = {
939 		.id = HCLK_PERILP0,
940 		.name = "hclk_perilp0",
941 		.parent_names = hclk_pclk_perilp0_parents,
942 		.parent_cnt = nitems(hclk_pclk_perilp0_parents),
943 	},
944 	/* CRU_CLKSEL_CON23 */
945 	.muxdiv_offset = 0x15C,
946 
947 	.div_shift = 8,
948 	.div_width = 2,
949 
950 	/* CRU_CLKGATE_CON7 */
951 	.gate_offset = 0x31C,
952 	.gate_shift = 3,
953 
954 	.flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE,
955 };
956 
957 static struct rk_clk_composite_def pclk_perilp0 = {
958 	.clkdef = {
959 		.id = PCLK_PERILP0,
960 		.name = "pclk_perilp0",
961 		.parent_names = hclk_pclk_perilp0_parents,
962 		.parent_cnt = nitems(hclk_pclk_perilp0_parents),
963 	},
964 	/* CRU_CLKSEL_CON23 */
965 	.muxdiv_offset = 0x15C,
966 
967 	.div_shift = 12,
968 	.div_width = 3,
969 
970 	/* CRU_CLKGATE_CON7 */
971 	.gate_offset = 0x31C,
972 	.gate_shift = 4,
973 
974 	.flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE,
975 };
976 
977 /*
978  * misc
979  */
980 #define	PCLK_ALIVE		390
981 
982 static const char *alive_parents[] = {"gpll"};
983 
984 static struct rk_clk_composite_def pclk_alive = {
985 	.clkdef = {
986 		.id = PCLK_ALIVE,
987 		.name = "pclk_alive",
988 		.parent_names = alive_parents,
989 		.parent_cnt = nitems(alive_parents),
990 	},
991 	/* CRU_CLKSEL_CON57 */
992 	.muxdiv_offset = 0x01e4,
993 
994 	.div_shift = 0,
995 	.div_width = 5,
996 };
997 
998 #define	HCLK_PERILP1		450
999 #define	PCLK_PERILP1		323
1000 
1001 static const char *hclk_perilp1_parents[] = {"cpll", "gpll"};
1002 
1003 static struct rk_clk_composite_def hclk_perilp1 = {
1004 	.clkdef = {
1005 		.id = HCLK_PERILP1,
1006 		.name = "hclk_perilp1",
1007 		.parent_names = hclk_perilp1_parents,
1008 		.parent_cnt = nitems(hclk_perilp1_parents),
1009 	},
1010 	/* CRU_CLKSEL_CON25 */
1011 	.muxdiv_offset = 0x164,
1012 	.mux_shift = 7,
1013 	.mux_width = 1,
1014 
1015 	.div_shift = 0,
1016 	.div_width = 5,
1017 
1018 	.flags = RK_CLK_COMPOSITE_HAVE_MUX,
1019 };
1020 
1021 static const char *pclk_perilp1_parents[] = {"hclk_perilp1"};
1022 
1023 static struct rk_clk_composite_def pclk_perilp1 = {
1024 	.clkdef = {
1025 		.id = PCLK_PERILP1,
1026 		.name = "pclk_perilp1",
1027 		.parent_names = pclk_perilp1_parents,
1028 		.parent_cnt = nitems(pclk_perilp1_parents),
1029 	},
1030 	/* CRU_CLKSEL_CON25 */
1031 	.muxdiv_offset = 0x164,
1032 
1033 	.div_shift = 8,
1034 	.div_width = 3,
1035 
1036 	/* CRU_CLKGATE_CON8 */
1037 	.gate_offset = 0x320,
1038 	.gate_shift = 2,
1039 
1040 	.flags = RK_CLK_COMPOSITE_HAVE_GATE,
1041 };
1042 
1043 /*
1044  * i2c
1045  */
1046 static const char *i2c_parents[] = {"cpll", "gpll"};
1047 
1048 #define	SCLK_I2C1	65
1049 #define	SCLK_I2C2	66
1050 #define	SCLK_I2C3	67
1051 #define	SCLK_I2C5	68
1052 #define	SCLK_I2C6	69
1053 #define	SCLK_I2C7	70
1054 
1055 static struct rk_clk_composite_def i2c1 = {
1056 	.clkdef = {
1057 		.id = SCLK_I2C1,
1058 		.name = "clk_i2c1",
1059 		.parent_names = i2c_parents,
1060 		.parent_cnt = nitems(i2c_parents),
1061 	},
1062 	/* CRU_CLKSEL_CON61 */
1063 	.muxdiv_offset = 0x01f4,
1064 	.mux_shift = 7,
1065 	.mux_width = 1,
1066 
1067 	.div_shift = 0,
1068 	.div_width = 7,
1069 
1070 	/* CRU_CLKGATE_CON10 */
1071 	.gate_offset = 0x0328,
1072 	.gate_shift = 0,
1073 
1074 	.flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE,
1075 };
1076 
1077 static struct rk_clk_composite_def i2c2 = {
1078 	.clkdef = {
1079 		.id = SCLK_I2C2,
1080 		.name = "clk_i2c2",
1081 		.parent_names = i2c_parents,
1082 		.parent_cnt = nitems(i2c_parents),
1083 	},
1084 	/* CRU_CLKSEL_CON62 */
1085 	.muxdiv_offset = 0x01f8,
1086 	.mux_shift = 7,
1087 	.mux_width = 1,
1088 
1089 	.div_shift = 0,
1090 	.div_width = 7,
1091 
1092 	/* CRU_CLKGATE_CON10 */
1093 	.gate_offset = 0x0328,
1094 	.gate_shift = 2,
1095 
1096 	.flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE,
1097 };
1098 
1099 static struct rk_clk_composite_def i2c3 = {
1100 	.clkdef = {
1101 		.id = SCLK_I2C3,
1102 		.name = "clk_i2c3",
1103 		.parent_names = i2c_parents,
1104 		.parent_cnt = nitems(i2c_parents),
1105 	},
1106 	/* CRU_CLKSEL_CON63 */
1107 	.muxdiv_offset = 0x01fc,
1108 	.mux_shift = 7,
1109 	.mux_width = 1,
1110 
1111 	.div_shift = 0,
1112 	.div_width = 7,
1113 
1114 	/* CRU_CLKGATE_CON10 */
1115 	.gate_offset = 0x0328,
1116 	.gate_shift = 4,
1117 
1118 	.flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE,
1119 };
1120 
1121 static struct rk_clk_composite_def i2c5 = {
1122 	.clkdef = {
1123 		.id = SCLK_I2C5,
1124 		.name = "clk_i2c5",
1125 		.parent_names = i2c_parents,
1126 		.parent_cnt = nitems(i2c_parents),
1127 	},
1128 	/* CRU_CLKSEL_CON61 */
1129 	.muxdiv_offset = 0x01f4,
1130 	.mux_shift = 15,
1131 	.mux_width = 1,
1132 
1133 	.div_shift = 8,
1134 	.div_width = 7,
1135 
1136 	/* CRU_CLKGATE_CON10 */
1137 	.gate_offset = 0x0328,
1138 	.gate_shift = 1,
1139 
1140 	.flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE,
1141 };
1142 
1143 static struct rk_clk_composite_def i2c6 = {
1144 	.clkdef = {
1145 		.id = SCLK_I2C6,
1146 		.name = "clk_i2c6",
1147 		.parent_names = i2c_parents,
1148 		.parent_cnt = nitems(i2c_parents),
1149 	},
1150 	/* CRU_CLKSEL_CON62 */
1151 	.muxdiv_offset = 0x01f8,
1152 	.mux_shift = 15,
1153 	.mux_width = 1,
1154 
1155 	.div_shift = 8,
1156 	.div_width = 7,
1157 
1158 	/* CRU_CLKGATE_CON10 */
1159 	.gate_offset = 0x0328,
1160 	.gate_shift = 3,
1161 
1162 	.flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE,
1163 };
1164 
1165 static struct rk_clk_composite_def i2c7 = {
1166 	.clkdef = {
1167 		.id = SCLK_I2C7,
1168 		.name = "clk_i2c7",
1169 		.parent_names = i2c_parents,
1170 		.parent_cnt = nitems(i2c_parents),
1171 	},
1172 	/* CRU_CLKSEL_CON63 */
1173 	.muxdiv_offset = 0x01fc,
1174 	.mux_shift = 15,
1175 	.mux_width = 1,
1176 
1177 	.div_shift = 8,
1178 	.div_width = 7,
1179 
1180 	/* CRU_CLKGATE_CON10 */
1181 	.gate_offset = 0x0328,
1182 	.gate_shift = 5,
1183 
1184 	.flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE,
1185 };
1186 
1187 /*
1188  * ARM CPU clocks (LITTLE and big)
1189  */
1190 #define ARMCLKL				8
1191 #define ARMCLKB				9
1192 
1193 static const char *armclk_parents[] = {"lpll", "bpll", "dpll", "gpll"};
1194 
1195 static struct rk_clk_armclk_rates rk3399_armclkl_rates[] = {
1196 	{
1197 		.freq = 1800000000,
1198 		.div = 1,
1199 	},
1200 	{
1201 		.freq = 1704000000,
1202 		.div = 1,
1203 	},
1204 	{
1205 		.freq = 1608000000,
1206 		.div = 1,
1207 	},
1208 	{
1209 		.freq = 1512000000,
1210 		.div = 1,
1211 	},
1212 	{
1213 		.freq = 1488000000,
1214 		.div = 1,
1215 	},
1216 	{
1217 		.freq = 1416000000,
1218 		.div = 1,
1219 	},
1220 	{
1221 		.freq = 1200000000,
1222 		.div = 1,
1223 	},
1224 	{
1225 		.freq = 1008000000,
1226 		.div = 1,
1227 	},
1228 	{
1229 		.freq = 816000000,
1230 		.div = 1,
1231 	},
1232 	{
1233 		.freq = 696000000,
1234 		.div = 1,
1235 	},
1236 	{
1237 		.freq = 600000000,
1238 		.div = 1,
1239 	},
1240 	{
1241 		.freq = 408000000,
1242 		.div = 1,
1243 	},
1244 	{
1245 		.freq = 312000000,
1246 		.div = 1,
1247 	},
1248 	{
1249 		.freq = 216000000,
1250 		.div = 1,
1251 	},
1252 	{
1253 		.freq = 96000000,
1254 		.div = 1,
1255 	},
1256 };
1257 
1258 static struct rk_clk_armclk_def armclk_l = {
1259 	.clkdef = {
1260 		.id = ARMCLKL,
1261 		.name = "armclkl",
1262 		.parent_names = armclk_parents,
1263 		.parent_cnt = nitems(armclk_parents),
1264 	},
1265 	/* CRU_CLKSEL_CON0 */
1266 	.muxdiv_offset = 0x100,
1267 	.mux_shift = 6,
1268 	.mux_width = 2,
1269 
1270 	.div_shift = 0,
1271 	.div_width = 5,
1272 
1273 	.flags = RK_CLK_COMPOSITE_HAVE_MUX,
1274 	.main_parent = 0,
1275 	.alt_parent = 3,
1276 
1277 	.rates = rk3399_armclkl_rates,
1278 	.nrates = nitems(rk3399_armclkl_rates),
1279 };
1280 
1281 static struct rk_clk_armclk_rates rk3399_armclkb_rates[] = {
1282 	{
1283 		.freq = 2208000000,
1284 		.div = 1,
1285 	},
1286 	{
1287 		.freq = 2184000000,
1288 		.div = 1,
1289 	},
1290 	{
1291 		.freq = 2088000000,
1292 		.div = 1,
1293 	},
1294 	{
1295 		.freq = 2040000000,
1296 		.div = 1,
1297 	},
1298 	{
1299 		.freq = 2016000000,
1300 		.div = 1,
1301 	},
1302 	{
1303 		.freq = 1992000000,
1304 		.div = 1,
1305 	},
1306 	{
1307 		.freq = 1896000000,
1308 		.div = 1,
1309 	},
1310 	{
1311 		.freq = 1800000000,
1312 		.div = 1,
1313 	},
1314 	{
1315 		.freq = 1704000000,
1316 		.div = 1,
1317 	},
1318 	{
1319 		.freq = 1608000000,
1320 		.div = 1,
1321 	},
1322 	{
1323 		.freq = 1512000000,
1324 		.div = 1,
1325 	},
1326 	{
1327 		.freq = 1488000000,
1328 		.div = 1,
1329 	},
1330 	{
1331 		.freq = 1416000000,
1332 		.div = 1,
1333 	},
1334 	{
1335 		.freq = 1200000000,
1336 		.div = 1,
1337 	},
1338 	{
1339 		.freq = 1008000000,
1340 		.div = 1,
1341 	},
1342 	{
1343 		.freq = 816000000,
1344 		.div = 1,
1345 	},
1346 	{
1347 		.freq = 696000000,
1348 		.div = 1,
1349 	},
1350 	{
1351 		.freq = 600000000,
1352 		.div = 1,
1353 	},
1354 	{
1355 		.freq = 408000000,
1356 		.div = 1,
1357 	},
1358 	{
1359 		.freq = 312000000,
1360 		.div = 1,
1361 	},
1362 	{
1363 		.freq = 216000000,
1364 		.div = 1,
1365 	},
1366 	{
1367 		.freq = 96000000,
1368 		.div = 1,
1369 	},
1370 };
1371 
1372 static struct rk_clk_armclk_def armclk_b = {
1373 	.clkdef = {
1374 		.id = ARMCLKB,
1375 		.name = "armclkb",
1376 		.parent_names = armclk_parents,
1377 		.parent_cnt = nitems(armclk_parents),
1378 	},
1379 	.muxdiv_offset = 0x108,
1380 	.mux_shift = 6,
1381 	.mux_width = 2,
1382 
1383 	.div_shift = 0,
1384 	.div_width = 5,
1385 
1386 	.flags = RK_CLK_COMPOSITE_HAVE_MUX,
1387 	.main_parent = 1,
1388 	.alt_parent = 3,
1389 
1390 	.rates = rk3399_armclkb_rates,
1391 	.nrates = nitems(rk3399_armclkb_rates),
1392 };
1393 
1394 /*
1395  * sdmmc
1396  */
1397 
1398 #define	HCLK_SD		461
1399 
1400 static const char *hclk_sd_parents[] = {"cpll", "gpll"};
1401 
1402 static struct rk_clk_composite_def hclk_sd = {
1403 	.clkdef = {
1404 		.id = HCLK_SD,
1405 		.name = "hclk_sd",
1406 		.parent_names = hclk_sd_parents,
1407 		.parent_cnt = nitems(hclk_sd_parents),
1408 	},
1409 
1410 	.muxdiv_offset = 0x134,
1411 	.mux_shift = 15,
1412 	.mux_width = 1,
1413 
1414 	.div_shift = 8,
1415 	.div_width = 5,
1416 
1417 	.gate_offset = 0x330,
1418 	.gate_shift = 13,
1419 
1420 	.flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE,
1421 };
1422 
1423 #define	SCLK_SDMMC		76
1424 
1425 static const char *sclk_sdmmc_parents[] = {"cpll", "gpll", "npll", "ppll"};
1426 
1427 static struct rk_clk_composite_def sclk_sdmmc = {
1428 	.clkdef = {
1429 		.id = SCLK_SDMMC,
1430 		.name = "sclk_sdmmc",
1431 		.parent_names = sclk_sdmmc_parents,
1432 		.parent_cnt = nitems(sclk_sdmmc_parents),
1433 	},
1434 
1435 	.muxdiv_offset = 0x140,
1436 	.mux_shift = 8,
1437 	.mux_width = 3,
1438 
1439 	.div_shift = 0,
1440 	.div_width = 7,
1441 
1442 	.gate_offset = 0x318,
1443 	.gate_shift = 1,
1444 
1445 	.flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE,
1446 };
1447 
1448 static struct rk_clk rk3399_clks[] = {
1449 	{
1450 		.type = RK3399_CLK_PLL,
1451 		.clk.pll = &lpll
1452 	},
1453 	{
1454 		.type = RK3399_CLK_PLL,
1455 		.clk.pll = &bpll
1456 	},
1457 	{
1458 		.type = RK3399_CLK_PLL,
1459 		.clk.pll = &dpll
1460 	},
1461 	{
1462 		.type = RK3399_CLK_PLL,
1463 		.clk.pll = &cpll
1464 	},
1465 	{
1466 		.type = RK3399_CLK_PLL,
1467 		.clk.pll = &gpll
1468 	},
1469 	{
1470 		.type = RK3399_CLK_PLL,
1471 		.clk.pll = &npll
1472 	},
1473 	{
1474 		.type = RK3399_CLK_PLL,
1475 		.clk.pll = &vpll
1476 	},
1477 
1478 	{
1479 		.type = RK_CLK_COMPOSITE,
1480 		.clk.composite = &aclk_perihp,
1481 	},
1482 	{
1483 		.type = RK_CLK_COMPOSITE,
1484 		.clk.composite = &hclk_perihp,
1485 	},
1486 	{
1487 		.type = RK_CLK_COMPOSITE,
1488 		.clk.composite = &pclk_perihp,
1489 	},
1490 	{
1491 		.type = RK_CLK_COMPOSITE,
1492 		.clk.composite = &aclk_perilp0,
1493 	},
1494 	{
1495 		.type = RK_CLK_COMPOSITE,
1496 		.clk.composite = &hclk_perilp0,
1497 	},
1498 	{
1499 		.type = RK_CLK_COMPOSITE,
1500 		.clk.composite = &pclk_perilp0,
1501 	},
1502 	{
1503 		.type = RK_CLK_COMPOSITE,
1504 		.clk.composite = &pclk_alive,
1505 	},
1506 	{
1507 		.type = RK_CLK_COMPOSITE,
1508 		.clk.composite = &hclk_perilp1,
1509 	},
1510 	{
1511 		.type = RK_CLK_COMPOSITE,
1512 		.clk.composite = &pclk_perilp1,
1513 	},
1514 	{
1515 		.type = RK_CLK_COMPOSITE,
1516 		.clk.composite = &i2c1,
1517 	},
1518 	{
1519 		.type = RK_CLK_COMPOSITE,
1520 		.clk.composite = &i2c2,
1521 	},
1522 	{
1523 		.type = RK_CLK_COMPOSITE,
1524 		.clk.composite = &i2c3,
1525 	},
1526 	{
1527 		.type = RK_CLK_COMPOSITE,
1528 		.clk.composite = &i2c5,
1529 	},
1530 	{
1531 		.type = RK_CLK_COMPOSITE,
1532 		.clk.composite = &i2c6,
1533 	},
1534 	{
1535 		.type = RK_CLK_COMPOSITE,
1536 		.clk.composite = &i2c7,
1537 	},
1538 
1539 	{
1540 		.type = RK_CLK_ARMCLK,
1541 		.clk.armclk = &armclk_l,
1542 	},
1543 	{
1544 		.type = RK_CLK_ARMCLK,
1545 		.clk.armclk = &armclk_b,
1546 	},
1547 
1548 	{
1549 		.type = RK_CLK_COMPOSITE,
1550 		.clk.composite = &hclk_sd,
1551 	},
1552 	{
1553 		.type = RK_CLK_COMPOSITE,
1554 		.clk.composite = &sclk_sdmmc,
1555 	},
1556 };
1557 
1558 static int
rk3399_cru_probe(device_t dev)1559 rk3399_cru_probe(device_t dev)
1560 {
1561 
1562 	if (!ofw_bus_status_okay(dev))
1563 		return (ENXIO);
1564 
1565 	if (ofw_bus_is_compatible(dev, "rockchip,rk3399-cru")) {
1566 		device_set_desc(dev, "Rockchip RK3399 Clock and Reset Unit");
1567 		return (BUS_PROBE_DEFAULT);
1568 	}
1569 
1570 	return (ENXIO);
1571 }
1572 
1573 static int
rk3399_cru_attach(device_t dev)1574 rk3399_cru_attach(device_t dev)
1575 {
1576 	struct rk_cru_softc *sc;
1577 
1578 	sc = device_get_softc(dev);
1579 	sc->dev = dev;
1580 
1581 	sc->gates = rk3399_gates;
1582 	sc->ngates = nitems(rk3399_gates);
1583 
1584 	sc->clks = rk3399_clks;
1585 	sc->nclks = nitems(rk3399_clks);
1586 
1587 	return (rk_cru_attach(dev));
1588 }
1589 
1590 static device_method_t rk3399_cru_methods[] = {
1591 	/* Device interface */
1592 	DEVMETHOD(device_probe,		rk3399_cru_probe),
1593 	DEVMETHOD(device_attach,	rk3399_cru_attach),
1594 
1595 	DEVMETHOD_END
1596 };
1597 
1598 static devclass_t rk3399_cru_devclass;
1599 
1600 DEFINE_CLASS_1(rk3399_cru, rk3399_cru_driver, rk3399_cru_methods,
1601   sizeof(struct rk_cru_softc), rk_cru_driver);
1602 
1603 EARLY_DRIVER_MODULE(rk3399_cru, simplebus, rk3399_cru_driver,
1604     rk3399_cru_devclass, 0, 0, BUS_PASS_BUS + BUS_PASS_ORDER_MIDDLE);
1605