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