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