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