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_PMU		20
56 #define	PCLK_GPIO0_PMU		23
57 #define	PCLK_GPIO1_PMU		24
58 #define	PCLK_I2C0_PMU		27
59 #define	PCLK_I2C4_PMU		28
60 #define	PCLK_I2C8_PMU		29
61 #define	PCLK_RKPWM_PMU		30
62 
63 static struct rk_cru_gate rk3399_pmu_gates[] = {
64 	/* PMUCRU_CLKGATE_CON1 */
65 	CRU_GATE(PCLK_PMU, "pclk_pmu", "pclk_pmu_src", 0x104, 0)
66 	CRU_GATE(PCLK_GPIO0_PMU, "pclk_gpio0_pmu", "pclk_pmu_src", 0x104, 3)
67 	CRU_GATE(PCLK_GPIO1_PMU, "pclk_gpio1_pmu", "pclk_pmu_src", 0x104, 4)
68 	CRU_GATE(PCLK_I2C0_PMU, "pclk_i2c0_pmu", "pclk_pmu_src", 0x104, 7)
69 	CRU_GATE(PCLK_I2C4_PMU, "pclk_i2c4_pmu", "pclk_pmu_src", 0x104, 8)
70 	CRU_GATE(PCLK_I2C8_PMU, "pclk_i2c8_pmu", "pclk_pmu_src", 0x104, 9)
71 	CRU_GATE(PCLK_RKPWM_PMU, "pclk_rkpwm_pmu", "pclk_pmu_src", 0x104, 10)
72 };
73 
74 /*
75  * PLLs
76  */
77 
78 #define PLL_PPLL	1
79 
80 static struct rk_clk_pll_rate rk3399_pll_rates[] = {
81 	{
82 		.freq = 2208000000,
83 		.refdiv = 1,
84 		.fbdiv = 92,
85 		.postdiv1 = 1,
86 		.postdiv2 = 1,
87 		.dsmpd = 1,
88 	},
89 	{
90 		.freq = 2184000000,
91 		.refdiv = 1,
92 		.fbdiv = 91,
93 		.postdiv1 = 1,
94 		.postdiv2 = 1,
95 		.dsmpd = 1,
96 	},
97 	{
98 		.freq = 2160000000,
99 		.refdiv = 1,
100 		.fbdiv = 90,
101 		.postdiv1 = 1,
102 		.postdiv2 = 1,
103 		.dsmpd = 1,
104 	},
105 	{
106 		.freq = 2136000000,
107 		.refdiv = 1,
108 		.fbdiv = 89,
109 		.postdiv1 = 1,
110 		.postdiv2 = 1,
111 		.dsmpd = 1,
112 	},
113 	{
114 		.freq = 2112000000,
115 		.refdiv = 1,
116 		.fbdiv = 88,
117 		.postdiv1 = 1,
118 		.postdiv2 = 1,
119 		.dsmpd = 1,
120 	},
121 	{
122 		.freq = 2088000000,
123 		.refdiv = 1,
124 		.fbdiv = 87,
125 		.postdiv1 = 1,
126 		.postdiv2 = 1,
127 		.dsmpd = 1,
128 	},
129 	{
130 		.freq = 2064000000,
131 		.refdiv = 1,
132 		.fbdiv = 86,
133 		.postdiv1 = 1,
134 		.postdiv2 = 1,
135 		.dsmpd = 1,
136 	},
137 	{
138 		.freq = 2040000000,
139 		.refdiv = 1,
140 		.fbdiv = 85,
141 		.postdiv1 = 1,
142 		.postdiv2 = 1,
143 		.dsmpd = 1,
144 	},
145 	{
146 		.freq = 2016000000,
147 		.refdiv = 1,
148 		.fbdiv = 84,
149 		.postdiv1 = 1,
150 		.postdiv2 = 1,
151 		.dsmpd = 1,
152 	},
153 	{
154 		.freq = 1992000000,
155 		.refdiv = 1,
156 		.fbdiv = 83,
157 		.postdiv1 = 1,
158 		.postdiv2 = 1,
159 		.dsmpd = 1,
160 	},
161 	{
162 		.freq = 1968000000,
163 		.refdiv = 1,
164 		.fbdiv = 82,
165 		.postdiv1 = 1,
166 		.postdiv2 = 1,
167 		.dsmpd = 1,
168 	},
169 	{
170 		.freq = 1944000000,
171 		.refdiv = 1,
172 		.fbdiv = 81,
173 		.postdiv1 = 1,
174 		.postdiv2 = 1,
175 		.dsmpd = 1,
176 	},
177 	{
178 		.freq = 1920000000,
179 		.refdiv = 1,
180 		.fbdiv = 80,
181 		.postdiv1 = 1,
182 		.postdiv2 = 1,
183 		.dsmpd = 1,
184 	},
185 	{
186 		.freq = 1896000000,
187 		.refdiv = 1,
188 		.fbdiv = 79,
189 		.postdiv1 = 1,
190 		.postdiv2 = 1,
191 		.dsmpd = 1,
192 	},
193 	{
194 		.freq = 1872000000,
195 		.refdiv = 1,
196 		.fbdiv = 78,
197 		.postdiv1 = 1,
198 		.postdiv2 = 1,
199 		.dsmpd = 1,
200 	},
201 	{
202 		.freq = 1848000000,
203 		.refdiv = 1,
204 		.fbdiv = 77,
205 		.postdiv1 = 1,
206 		.postdiv2 = 1,
207 		.dsmpd = 1,
208 	},
209 	{
210 		.freq = 1824000000,
211 		.refdiv = 1,
212 		.fbdiv = 76,
213 		.postdiv1 = 1,
214 		.postdiv2 = 1,
215 		.dsmpd = 1,
216 	},
217 	{
218 		.freq = 1800000000,
219 		.refdiv = 1,
220 		.fbdiv = 75,
221 		.postdiv1 = 1,
222 		.postdiv2 = 1,
223 		.dsmpd = 1,
224 	},
225 	{
226 		.freq = 1776000000,
227 		.refdiv = 1,
228 		.fbdiv = 74,
229 		.postdiv1 = 1,
230 		.postdiv2 = 1,
231 		.dsmpd = 1,
232 	},
233 	{
234 		.freq = 1752000000,
235 		.refdiv = 1,
236 		.fbdiv = 73,
237 		.postdiv1 = 1,
238 		.postdiv2 = 1,
239 		.dsmpd = 1,
240 	},
241 	{
242 		.freq = 1728000000,
243 		.refdiv = 1,
244 		.fbdiv = 72,
245 		.postdiv1 = 1,
246 		.postdiv2 = 1,
247 		.dsmpd = 1,
248 	},
249 	{
250 		.freq = 1704000000,
251 		.refdiv = 1,
252 		.fbdiv = 71,
253 		.postdiv1 = 1,
254 		.postdiv2 = 1,
255 		.dsmpd = 1,
256 	},
257 	{
258 		.freq = 1680000000,
259 		.refdiv = 1,
260 		.fbdiv = 70,
261 		.postdiv1 = 1,
262 		.postdiv2 = 1,
263 		.dsmpd = 1,
264 	},
265 	{
266 		.freq = 1656000000,
267 		.refdiv = 1,
268 		.fbdiv = 69,
269 		.postdiv1 = 1,
270 		.postdiv2 = 1,
271 		.dsmpd = 1,
272 	},
273 	{
274 		.freq = 1632000000,
275 		.refdiv = 1,
276 		.fbdiv = 68,
277 		.postdiv1 = 1,
278 		.postdiv2 = 1,
279 		.dsmpd = 1,
280 	},
281 	{
282 		.freq = 1608000000,
283 		.refdiv = 1,
284 		.fbdiv = 67,
285 		.postdiv1 = 1,
286 		.postdiv2 = 1,
287 		.dsmpd = 1,
288 	},
289 	{
290 		.freq = 1600000000,
291 		.refdiv = 3,
292 		.fbdiv = 200,
293 		.postdiv1 = 1,
294 		.postdiv2 = 1,
295 		.dsmpd = 1,
296 	},
297 	{
298 		.freq = 1584000000,
299 		.refdiv = 1,
300 		.fbdiv = 66,
301 		.postdiv1 = 1,
302 		.postdiv2 = 1,
303 		.dsmpd = 1,
304 	},
305 	{
306 		.freq = 1560000000,
307 		.refdiv = 1,
308 		.fbdiv = 65,
309 		.postdiv1 = 1,
310 		.postdiv2 = 1,
311 		.dsmpd = 1,
312 	},
313 	{
314 		.freq = 1536000000,
315 		.refdiv = 1,
316 		.fbdiv = 64,
317 		.postdiv1 = 1,
318 		.postdiv2 = 1,
319 		.dsmpd = 1,
320 	},
321 	{
322 		.freq = 1512000000,
323 		.refdiv = 1,
324 		.fbdiv = 63,
325 		.postdiv1 = 1,
326 		.postdiv2 = 1,
327 		.dsmpd = 1,
328 	},
329 	{
330 		.freq = 1488000000,
331 		.refdiv = 1,
332 		.fbdiv = 62,
333 		.postdiv1 = 1,
334 		.postdiv2 = 1,
335 		.dsmpd = 1,
336 	},
337 	{
338 		.freq = 1464000000,
339 		.refdiv = 1,
340 		.fbdiv = 61,
341 		.postdiv1 = 1,
342 		.postdiv2 = 1,
343 		.dsmpd = 1,
344 	},
345 	{
346 		.freq = 1440000000,
347 		.refdiv = 1,
348 		.fbdiv = 60,
349 		.postdiv1 = 1,
350 		.postdiv2 = 1,
351 		.dsmpd = 1,
352 	},
353 	{
354 		.freq = 1416000000,
355 		.refdiv = 1,
356 		.fbdiv = 59,
357 		.postdiv1 = 1,
358 		.postdiv2 = 1,
359 		.dsmpd = 1,
360 	},
361 	{
362 		.freq = 1392000000,
363 		.refdiv = 1,
364 		.fbdiv = 58,
365 		.postdiv1 = 1,
366 		.postdiv2 = 1,
367 		.dsmpd = 1,
368 	},
369 	{
370 		.freq = 1368000000,
371 		.refdiv = 1,
372 		.fbdiv = 57,
373 		.postdiv1 = 1,
374 		.postdiv2 = 1,
375 		.dsmpd = 1,
376 	},
377 	{
378 		.freq = 1344000000,
379 		.refdiv = 1,
380 		.fbdiv = 56,
381 		.postdiv1 = 1,
382 		.postdiv2 = 1,
383 		.dsmpd = 1,
384 	},
385 	{
386 		.freq = 1320000000,
387 		.refdiv = 1,
388 		.fbdiv = 55,
389 		.postdiv1 = 1,
390 		.postdiv2 = 1,
391 		.dsmpd = 1,
392 	},
393 	{
394 		.freq = 1296000000,
395 		.refdiv = 1,
396 		.fbdiv = 54,
397 		.postdiv1 = 1,
398 		.postdiv2 = 1,
399 		.dsmpd = 1,
400 	},
401 	{
402 		.freq = 1272000000,
403 		.refdiv = 1,
404 		.fbdiv = 53,
405 		.postdiv1 = 1,
406 		.postdiv2 = 1,
407 		.dsmpd = 1,
408 	},
409 	{
410 		.freq = 1248000000,
411 		.refdiv = 1,
412 		.fbdiv = 52,
413 		.postdiv1 = 1,
414 		.postdiv2 = 1,
415 		.dsmpd = 1,
416 	},
417 	{
418 		.freq = 1200000000,
419 		.refdiv = 1,
420 		.fbdiv = 50,
421 		.postdiv1 = 1,
422 		.postdiv2 = 1,
423 		.dsmpd = 1,
424 	},
425 	{
426 		.freq = 1188000000,
427 		.refdiv = 2,
428 		.fbdiv = 99,
429 		.postdiv1 = 1,
430 		.postdiv2 = 1,
431 		.dsmpd = 1,
432 	},
433 	{
434 		.freq = 1104000000,
435 		.refdiv = 1,
436 		.fbdiv = 46,
437 		.postdiv1 = 1,
438 		.postdiv2 = 1,
439 		.dsmpd = 1,
440 	},
441 	{
442 		.freq = 1100000000,
443 		.refdiv = 12,
444 		.fbdiv = 550,
445 		.postdiv1 = 1,
446 		.postdiv2 = 1,
447 		.dsmpd = 1,
448 	},
449 	{
450 		.freq = 1008000000,
451 		.refdiv = 1,
452 		.fbdiv = 84,
453 		.postdiv1 = 2,
454 		.postdiv2 = 1,
455 		.dsmpd = 1,
456 	},
457 	{
458 		.freq = 1000000000,
459 		.refdiv = 1,
460 		.fbdiv = 125,
461 		.postdiv1 = 3,
462 		.postdiv2 = 1,
463 		.dsmpd = 1,
464 	},
465 	{
466 		.freq = 984000000,
467 		.refdiv = 1,
468 		.fbdiv = 82,
469 		.postdiv1 = 2,
470 		.postdiv2 = 1,
471 		.dsmpd = 1,
472 	},
473 	{
474 		.freq = 960000000,
475 		.refdiv = 1,
476 		.fbdiv = 80,
477 		.postdiv1 = 2,
478 		.postdiv2 = 1,
479 		.dsmpd = 1,
480 	},
481 	{
482 		.freq = 936000000,
483 		.refdiv = 1,
484 		.fbdiv = 78,
485 		.postdiv1 = 2,
486 		.postdiv2 = 1,
487 		.dsmpd = 1,
488 	},
489 	{
490 		.freq = 912000000,
491 		.refdiv = 1,
492 		.fbdiv = 76,
493 		.postdiv1 = 2,
494 		.postdiv2 = 1,
495 		.dsmpd = 1,
496 	},
497 	{
498 		.freq = 900000000,
499 		.refdiv = 4,
500 		.fbdiv = 300,
501 		.postdiv1 = 2,
502 		.postdiv2 = 1,
503 		.dsmpd = 1,
504 	},
505 	{
506 		.freq = 888000000,
507 		.refdiv = 1,
508 		.fbdiv = 74,
509 		.postdiv1 = 2,
510 		.postdiv2 = 1,
511 		.dsmpd = 1,
512 	},
513 	{
514 		.freq = 864000000,
515 		.refdiv = 1,
516 		.fbdiv = 72,
517 		.postdiv1 = 2,
518 		.postdiv2 = 1,
519 		.dsmpd = 1,
520 	},
521 	{
522 		.freq = 840000000,
523 		.refdiv = 1,
524 		.fbdiv = 70,
525 		.postdiv1 = 2,
526 		.postdiv2 = 1,
527 		.dsmpd = 1,
528 	},
529 	{
530 		.freq = 816000000,
531 		.refdiv = 1,
532 		.fbdiv = 68,
533 		.postdiv1 = 2,
534 		.postdiv2 = 1,
535 		.dsmpd = 1,
536 	},
537 	{
538 		.freq = 800000000,
539 		.refdiv = 1,
540 		.fbdiv = 100,
541 		.postdiv1 = 3,
542 		.postdiv2 = 1,
543 		.dsmpd = 1,
544 	},
545 	{
546 		.freq = 700000000,
547 		.refdiv = 6,
548 		.fbdiv = 350,
549 		.postdiv1 = 2,
550 		.postdiv2 = 1,
551 		.dsmpd = 1,
552 	},
553 	{
554 		.freq = 696000000,
555 		.refdiv = 1,
556 		.fbdiv = 58,
557 		.postdiv1 = 2,
558 		.postdiv2 = 1,
559 		.dsmpd = 1,
560 	},
561 	{
562 		.freq = 676000000,
563 		.refdiv = 3,
564 		.fbdiv = 169,
565 		.postdiv1 = 2,
566 		.postdiv2 = 1,
567 		.dsmpd = 1,
568 	},
569 	{
570 		.freq = 600000000,
571 		.refdiv = 1,
572 		.fbdiv = 75,
573 		.postdiv1 = 3,
574 		.postdiv2 = 1,
575 		.dsmpd = 1,
576 	},
577 	{
578 		.freq = 594000000,
579 		.refdiv = 1,
580 		.fbdiv = 99,
581 		.postdiv1 = 4,
582 		.postdiv2 = 1,
583 		.dsmpd = 1,
584 	},
585 	{
586 		.freq = 533250000,
587 		.refdiv = 8,
588 		.fbdiv = 711,
589 		.postdiv1 = 4,
590 		.postdiv2 = 1,
591 		.dsmpd = 1,
592 	},
593 	{
594 		.freq = 504000000,
595 		.refdiv = 1,
596 		.fbdiv = 63,
597 		.postdiv1 = 3,
598 		.postdiv2 = 1,
599 		.dsmpd = 1,
600 	},
601 	{
602 		.freq = 500000000,
603 		.refdiv = 6,
604 		.fbdiv = 250,
605 		.postdiv1 = 2,
606 		.postdiv2 = 1,
607 		.dsmpd = 1,
608 	},
609 	{
610 		.freq = 408000000,
611 		.refdiv = 1,
612 		.fbdiv = 68,
613 		.postdiv1 = 2,
614 		.postdiv2 = 2,
615 		.dsmpd = 1,
616 	},
617 	{
618 		.freq = 312000000,
619 		.refdiv = 1,
620 		.fbdiv = 52,
621 		.postdiv1 = 2,
622 		.postdiv2 = 2,
623 		.dsmpd = 1,
624 	},
625 	{
626 		.freq = 297000000,
627 		.refdiv = 1,
628 		.fbdiv = 99,
629 		.postdiv1 = 4,
630 		.postdiv2 = 2,
631 		.dsmpd = 1,
632 	},
633 	{
634 		.freq = 216000000,
635 		.refdiv = 1,
636 		.fbdiv = 72,
637 		.postdiv1 = 4,
638 		.postdiv2 = 2,
639 		.dsmpd = 1,
640 	},
641 	{
642 		.freq = 148500000,
643 		.refdiv = 1,
644 		.fbdiv = 99,
645 		.postdiv1 = 4,
646 		.postdiv2 = 4,
647 		.dsmpd = 1,
648 	},
649 	{
650 		.freq = 106500000,
651 		.refdiv = 1,
652 		.fbdiv = 71,
653 		.postdiv1 = 4,
654 		.postdiv2 = 4,
655 		.dsmpd = 1,
656 	},
657 	{
658 		.freq = 96000000,
659 		.refdiv = 1,
660 		.fbdiv = 64,
661 		.postdiv1 = 4,
662 		.postdiv2 = 4,
663 		.dsmpd = 1,
664 	},
665 	{
666 		.freq = 74250000,
667 		.refdiv = 2,
668 		.fbdiv = 99,
669 		.postdiv1 = 4,
670 		.postdiv2 = 4,
671 		.dsmpd = 1,
672 	},
673 	{
674 		.freq = 65000000,
675 		.refdiv = 1,
676 		.fbdiv = 65,
677 		.postdiv1 = 6,
678 		.postdiv2 = 4,
679 		.dsmpd = 1,
680 	},
681 	{
682 		.freq = 54000000,
683 		.refdiv = 1,
684 		.fbdiv = 54,
685 		.postdiv1 = 6,
686 		.postdiv2 = 4,
687 		.dsmpd = 1,
688 	},
689 	{
690 		.freq = 27000000,
691 		.refdiv = 1,
692 		.fbdiv = 27,
693 		.postdiv1 = 6,
694 		.postdiv2 = 4,
695 		.dsmpd = 1,
696 	},
697 	{},
698 };
699 
700 static const char *pll_parents[] = {"xin24m"};
701 
702 static struct rk_clk_pll_def ppll = {
703 	.clkdef = {
704 		.id = PLL_PPLL,
705 		.name = "ppll",
706 		.parent_names = pll_parents,
707 		.parent_cnt = nitems(pll_parents),
708 	},
709 	.base_offset = 0x00,
710 
711 	.rates = rk3399_pll_rates,
712 };
713 
714 static const char *pmu_parents[] = {"ppll"};
715 
716 #define	PCLK_PMU_SRC			19
717 
718 static struct rk_clk_composite_def pclk_pmu_src = {
719 	.clkdef = {
720 		.id = PCLK_PMU_SRC,
721 		.name = "pclk_pmu_src",
722 		.parent_names = pmu_parents,
723 		.parent_cnt = nitems(pmu_parents),
724 	},
725 	/* PMUCRU_CLKSEL_CON0 */
726 	.muxdiv_offset = 0x80,
727 
728 	.div_shift = 0,
729 	.div_width = 5,
730 };
731 
732 #define	SCLK_I2C0_PMU	9
733 #define	SCLK_I2C4_PMU	10
734 #define	SCLK_I2C8_PMU	11
735 
736 static struct rk_clk_composite_def i2c0 = {
737 	.clkdef = {
738 		.id = SCLK_I2C0_PMU,
739 		.name = "clk_i2c0_pmu",
740 		.parent_names = pmu_parents,
741 		.parent_cnt = nitems(pmu_parents),
742 	},
743 	/* PMUCRU_CLKSEL_CON2 */
744 	.muxdiv_offset = 0x88,
745 
746 	.div_shift = 0,
747 	.div_width = 7,
748 
749 	/* PMUCRU_CLKGATE_CON0 */
750 	.gate_offset = 0x100,
751 	.gate_shift = 9,
752 
753 	.flags = RK_CLK_COMPOSITE_HAVE_GATE,
754 };
755 
756 static struct rk_clk_composite_def i2c8 = {
757 	.clkdef = {
758 		.id = SCLK_I2C8_PMU,
759 		.name = "clk_i2c8_pmu",
760 		.parent_names = pmu_parents,
761 		.parent_cnt = nitems(pmu_parents),
762 	},
763 	/* PMUCRU_CLKSEL_CON2 */
764 	.muxdiv_offset = 0x88,
765 
766 	.div_shift = 8,
767 	.div_width = 7,
768 
769 	/* PMUCRU_CLKGATE_CON0 */
770 	.gate_offset = 0x100,
771 	.gate_shift = 11,
772 
773 	.flags = RK_CLK_COMPOSITE_HAVE_GATE,
774 };
775 
776 static struct rk_clk_composite_def i2c4 = {
777 	.clkdef = {
778 		.id = SCLK_I2C4_PMU,
779 		.name = "clk_i2c4_pmu",
780 		.parent_names = pmu_parents,
781 		.parent_cnt = nitems(pmu_parents),
782 	},
783 	/* PMUCRU_CLKSEL_CON3 */
784 	.muxdiv_offset = 0x8c,
785 
786 	.div_shift = 0,
787 	.div_width = 7,
788 
789 	/* PMUCRU_CLKGATE_CON0 */
790 	.gate_offset = 0x100,
791 	.gate_shift = 10,
792 
793 	.flags = RK_CLK_COMPOSITE_HAVE_GATE,
794 };
795 
796 static struct rk_clk rk3399_pmu_clks[] = {
797 	{
798 		.type = RK3399_CLK_PLL,
799 		.clk.pll = &ppll
800 	},
801 
802 	{
803 		.type = RK_CLK_COMPOSITE,
804 		.clk.composite = &pclk_pmu_src
805 	},
806 	{
807 		.type = RK_CLK_COMPOSITE,
808 		.clk.composite = &i2c0
809 	},
810 	{
811 		.type = RK_CLK_COMPOSITE,
812 		.clk.composite = &i2c4
813 	},
814 	{
815 		.type = RK_CLK_COMPOSITE,
816 		.clk.composite = &i2c8
817 	},
818 };
819 
820 static int
rk3399_pmucru_probe(device_t dev)821 rk3399_pmucru_probe(device_t dev)
822 {
823 
824 	if (!ofw_bus_status_okay(dev))
825 		return (ENXIO);
826 
827 	if (ofw_bus_is_compatible(dev, "rockchip,rk3399-pmucru")) {
828 		device_set_desc(dev, "Rockchip RK3399 PMU Clock and Reset Unit");
829 		return (BUS_PROBE_DEFAULT);
830 	}
831 
832 	return (ENXIO);
833 }
834 
835 static int
rk3399_pmucru_attach(device_t dev)836 rk3399_pmucru_attach(device_t dev)
837 {
838 	struct rk_cru_softc *sc;
839 
840 	sc = device_get_softc(dev);
841 	sc->dev = dev;
842 
843 	sc->gates = rk3399_pmu_gates;
844 	sc->ngates = nitems(rk3399_pmu_gates);
845 
846 	sc->clks = rk3399_pmu_clks;
847 	sc->nclks = nitems(rk3399_pmu_clks);
848 
849 	sc->reset_offset = 0x110;
850 	sc->reset_num = 30;
851 
852 	return (rk_cru_attach(dev));
853 }
854 
855 static device_method_t rk3399_pmucru_methods[] = {
856 	/* Device interface */
857 	DEVMETHOD(device_probe,		rk3399_pmucru_probe),
858 	DEVMETHOD(device_attach,	rk3399_pmucru_attach),
859 
860 	DEVMETHOD_END
861 };
862 
863 static devclass_t rk3399_pmucru_devclass;
864 
865 DEFINE_CLASS_1(rk3399_pmucru, rk3399_pmucru_driver, rk3399_pmucru_methods,
866   sizeof(struct rk_cru_softc), rk_cru_driver);
867 
868 EARLY_DRIVER_MODULE(rk3399_pmucru, simplebus, rk3399_pmucru_driver,
869     rk3399_pmucru_devclass, 0, 0, BUS_PASS_BUS + BUS_PASS_ORDER_MIDDLE);
870