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