1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3  *
4  * Copyright (c) 2018 Emmanuel Vadot <[email protected]>
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
20  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
22  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
23  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  *
27  * $FreeBSD$
28  */
29 
30 #include <sys/cdefs.h>
31 __FBSDID("$FreeBSD$");
32 
33 #include <sys/param.h>
34 #include <sys/systm.h>
35 #include <sys/bus.h>
36 #include <sys/rman.h>
37 #include <sys/kernel.h>
38 #include <sys/module.h>
39 #include <machine/bus.h>
40 
41 #include <dev/fdt/simplebus.h>
42 
43 #include <dev/ofw/ofw_bus.h>
44 #include <dev/ofw/ofw_bus_subr.h>
45 
46 #include <dev/extres/clk/clk_div.h>
47 #include <dev/extres/clk/clk_fixed.h>
48 #include <dev/extres/clk/clk_mux.h>
49 
50 #include <arm64/rockchip/clk/rk_cru.h>
51 
52 /* Registers */
53 #define	RK3328_GRF_SOC_CON4	0x410
54 #define	RK3328_GRF_MAC_CON1	0x904
55 #define	RK3328_GRF_MAC_CON2	0x908
56 
57 /* GATES */
58 
59 #define	SCLK_I2S0		41
60 #define	SCLK_I2S1		42
61 #define	SCLK_I2S2		43
62 #define	SCLK_I2S1_OUT		44
63 #define	SCLK_I2S2_OUT		45
64 #define	SCLK_MAC2PHY_RXTX	83
65 #define	SCLK_MAC2PHY_SRC	84
66 #define	SCLK_MAC2PHY_REF	85
67 #define	SCLK_MAC2PHY_OUT	86
68 #define	SCLK_MAC2IO_RX		87
69 #define	SCLK_MAC2IO_TX		88
70 #define	SCLK_MAC2IO_REFOUT	89
71 #define	SCLK_MAC2IO_REF		90
72 #define	SCLK_MAC2IO_OUT		91
73 #define	SCLK_USB3OTG_REF	96
74 #define	SCLK_MAC2IO_SRC		99
75 #define	SCLK_MAC2IO		100
76 #define	SCLK_MAC2PHY		101
77 #define	SCLK_MAC2IO_EXT		102
78 #define	ACLK_USB3OTG		132
79 #define ACLK_GMAC		146
80 #define ACLK_MAC2PHY		149
81 #define ACLK_MAC2IO		150
82 #define	ACLK_PERI		153
83 #define	PCLK_GPIO0		200
84 #define	PCLK_GPIO1		201
85 #define	PCLK_GPIO2		202
86 #define	PCLK_GPIO3		203
87 #define	PCLK_I2C0		205
88 #define	PCLK_I2C1		206
89 #define	PCLK_I2C2		207
90 #define	PCLK_I2C3		208
91 #define	PCLK_TSADC		213
92 #define PCLK_GMAC		220
93 #define PCLK_MAC2PHY		222
94 #define PCLK_MAC2IO		223
95 #define	PCLK_USB3PHY_OTG	224
96 #define	PCLK_USB3PHY_PIPE	225
97 #define	PCLK_USB3_GRF		226
98 #define	PCLK_ACODECPHY		235
99 #define	HCLK_I2S0_8CH		311
100 #define	HCLK_I2S1_8CH		312
101 #define	HCLK_I2S2_2CH		313
102 #define	HCLK_SDMMC		317
103 #define	HCLK_SDIO		318
104 #define	HCLK_EMMC		319
105 #define	HCLK_SDMMC_EXT		320
106 
107 static struct rk_cru_gate rk3328_gates[] = {
108 	/* CRU_CLKGATE_CON0 */
109 	CRU_GATE(0, "apll_core", "apll", 0x200, 0)
110 	CRU_GATE(0, "dpll_core", "dpll", 0x200, 1)
111 	CRU_GATE(0, "gpll_core", "gpll", 0x200, 2)
112 	CRU_GATE(0, "npll_core", "npll", 0x200, 12)
113 
114 	/* CRU_CLKGATE_CON1 */
115 	CRU_GATE(SCLK_I2S0, "clk_i2s0", "clk_i2s0_mux", 0x204, 3)
116 	CRU_GATE(SCLK_I2S1, "clk_i2s1", "clk_i2s1_mux", 0x204, 6)
117 	CRU_GATE(SCLK_I2S1, "clk_i2s2", "clk_i2s2_mux", 0x204, 10)
118 
119 	/* CRU_CLKGATE_CON4 */
120 	CRU_GATE(0, "gpll_peri", "gpll", 0x210, 0)
121 	CRU_GATE(0, "cpll_peri", "cpll", 0x210, 1)
122 	CRU_GATE(SCLK_USB3OTG_REF, "clk_usb3otg_ref", "xin24m", 0x210, 7)
123 
124 	/* CRU_CLKGATE_CON8 */
125 	CRU_GATE(0, "pclk_bus", "pclk_bus_pre", 0x220, 3)
126 	CRU_GATE(0, "pclk_phy_pre", "pclk_bus_pre", 0x220, 4)
127 
128 	/* CRU_CLKGATE_CON8 */
129 	CRU_GATE(SCLK_MAC2IO_REF, "clk_mac2io_ref", "clk_mac2io", 0x224, 7)
130 	CRU_GATE(SCLK_MAC2IO_REFOUT, "clk_mac2io_refout", "clk_mac2io", 0x224, 6)
131 	CRU_GATE(SCLK_MAC2IO_TX, "clk_mac2io_tx", "clk_mac2io", 0x224, 5)
132 	CRU_GATE(SCLK_MAC2IO_RX, "clk_mac2io_rx", "clk_mac2io", 0x224, 4)
133 	CRU_GATE(SCLK_MAC2PHY_REF, "clk_mac2phy_ref", "clk_mac2phy", 0x224, 3)
134 	CRU_GATE(SCLK_MAC2PHY_RXTX, "clk_mac2phy_rxtx", "clk_mac2phy", 0x224, 1)
135 
136 	/* CRU_CLKGATE_CON10 */
137 	CRU_GATE(ACLK_PERI, "aclk_peri", "aclk_peri_pre", 0x228, 0)
138 
139 	/* CRU_CLKGATE_CON15*/
140 	CRU_GATE(HCLK_I2S0_8CH, "hclk_i2s0_8ch", "hclk_bus_pre", 0x23C, 3)
141 	CRU_GATE(HCLK_I2S1_8CH, "hclk_i2s1_8ch", "hclk_bus_pre", 0x23C, 4)
142 	CRU_GATE(HCLK_I2S2_2CH, "hclk_i2s2_2ch", "hclk_bus_pre", 0x23C, 5)
143 	CRU_GATE(PCLK_I2C0, "pclk_i2c0", "pclk_bus", 0x23C, 10)
144 
145 	/* CRU_CLKGATE_CON16 */
146 	CRU_GATE(PCLK_I2C1, "pclk_i2c1", "pclk_bus", 0x23C, 0)
147 	CRU_GATE(PCLK_I2C2, "pclk_i2c2", "pclk_bus", 0x23C, 1)
148 	CRU_GATE(PCLK_I2C3, "pclk_i2c3", "pclk_bus", 0x23C, 2)
149 	CRU_GATE(PCLK_TSADC, "pclk_tsadc", "pclk_bus", 0x23C, 14)
150 
151 	CRU_GATE(PCLK_GPIO0, "pclk_gpio0", "pclk_bus", 0x240, 7)
152 	CRU_GATE(PCLK_GPIO1, "pclk_gpio1", "pclk_bus", 0x240, 8)
153 	CRU_GATE(PCLK_GPIO2, "pclk_gpio2", "pclk_bus", 0x240, 9)
154 	CRU_GATE(PCLK_GPIO3, "pclk_gpio3", "pclk_bus", 0x240, 10)
155 
156 	/* CRU_CLKGATE_CON17 */
157 	CRU_GATE(PCLK_USB3_GRF, "pclk_usb3_grf", "pclk_phy_pre", 0x244, 2)
158 	CRU_GATE(PCLK_ACODECPHY, "pclk_acodecphy", "pclk_phy_pre", 0x244, 5)
159 
160 	/* CRU_CLKGATE_CON19 */
161 	CRU_GATE(HCLK_SDMMC, "hclk_sdmmc", "hclk_peri", 0x24C, 0)
162 	CRU_GATE(HCLK_SDIO, "hclk_sdio", "hclk_peri", 0x24C, 1)
163 	CRU_GATE(HCLK_EMMC, "hclk_emmc", "hclk_peri", 0x24C, 2)
164 	CRU_GATE(0, "hclk_peri_niu", "hclk_peri", 0x24C, 12)
165 	CRU_GATE(0, "pclk_peri_niu", "hclk_peri", 0x24C, 13)
166 	CRU_GATE(ACLK_USB3OTG, "aclk_usb3otg", "aclk_peri", 0x24C, 14)
167 	CRU_GATE(HCLK_SDMMC_EXT, "hclk_sdmmc_ext", "hclk_peri", 0x24C, 15)
168 
169 	/* CRU_CLKGATE_CON26 */
170 	CRU_GATE(ACLK_MAC2PHY, "aclk_mac2phy", "aclk_gmac", 0x268, 0)
171 	CRU_GATE(PCLK_MAC2PHY, "pclk_mac2phy", "pclk_gmac", 0x268, 1)
172 	CRU_GATE(ACLK_MAC2IO, "aclk_mac2io", "aclk_gmac", 0x268, 2)
173 	CRU_GATE(PCLK_MAC2IO, "pclk_mac2io", "pclk_gmac", 0x268, 3)
174 
175 	/* CRU_CLKGATE_CON28 */
176 	CRU_GATE(PCLK_USB3PHY_OTG, "pclk_usb3phy_otg", "pclk_phy_pre", 0x270, 1)
177 	CRU_GATE(PCLK_USB3PHY_PIPE, "pclk_usb3phy_pipe", "pclk_phy_pre", 0x270, 2)
178 };
179 
180 /*
181  * PLLs
182  */
183 
184 #define PLL_APLL		1
185 #define PLL_DPLL		2
186 #define PLL_CPLL		3
187 #define PLL_GPLL		4
188 #define PLL_NPLL		5
189 
190 static struct rk_clk_pll_rate rk3328_pll_rates[] = {
191 	{
192 		.freq = 1608000000,
193 		.refdiv = 1,
194 		.fbdiv = 67,
195 		.postdiv1 = 1,
196 		.postdiv2 = 1,
197 		.dsmpd = 1,
198 	},
199 	{
200 		.freq = 1584000000,
201 		.refdiv = 1,
202 		.fbdiv = 66,
203 		.postdiv1 = 1,
204 		.postdiv2 = 1,
205 		.dsmpd = 1,
206 	},
207 	{
208 		.freq = 1560000000,
209 		.refdiv = 1,
210 		.fbdiv = 65,
211 		.postdiv1 = 1,
212 		.postdiv2 = 1,
213 		.dsmpd = 1,
214 	},
215 	{
216 		.freq = 1536000000,
217 		.refdiv = 1,
218 		.fbdiv = 64,
219 		.postdiv1 = 1,
220 		.postdiv2 = 1,
221 		.dsmpd = 1,
222 	},
223 	{
224 		.freq = 1512000000,
225 		.refdiv = 1,
226 		.fbdiv = 63,
227 		.postdiv1 = 1,
228 		.postdiv2 = 1,
229 		.dsmpd = 1,
230 	},
231 	{
232 		.freq = 1488000000,
233 		.refdiv = 1,
234 		.fbdiv = 62,
235 		.postdiv1 = 1,
236 		.postdiv2 = 1,
237 		.dsmpd = 1,
238 	},
239 	{
240 		.freq = 1464000000,
241 		.refdiv = 1,
242 		.fbdiv = 61,
243 		.postdiv1 = 1,
244 		.postdiv2 = 1,
245 		.dsmpd = 1,
246 	},
247 	{
248 		.freq = 1440000000,
249 		.refdiv = 1,
250 		.fbdiv = 60,
251 		.postdiv1 = 1,
252 		.postdiv2 = 1,
253 		.dsmpd = 1,
254 	},
255 	{
256 		.freq = 1416000000,
257 		.refdiv = 1,
258 		.fbdiv = 59,
259 		.postdiv1 = 1,
260 		.postdiv2 = 1,
261 		.dsmpd = 1,
262 	},
263 	{
264 		.freq = 1392000000,
265 		.refdiv = 1,
266 		.fbdiv = 58,
267 		.postdiv1 = 1,
268 		.postdiv2 = 1,
269 		.dsmpd = 1,
270 	},
271 	{
272 		.freq = 1368000000,
273 		.refdiv = 1,
274 		.fbdiv = 57,
275 		.postdiv1 = 1,
276 		.postdiv2 = 1,
277 		.dsmpd = 1,
278 	},
279 	{
280 		.freq = 1344000000,
281 		.refdiv = 1,
282 		.fbdiv = 56,
283 		.postdiv1 = 1,
284 		.postdiv2 = 1,
285 		.dsmpd = 1,
286 	},
287 	{
288 		.freq = 1320000000,
289 		.refdiv = 1,
290 		.fbdiv = 55,
291 		.postdiv1 = 1,
292 		.postdiv2 = 1,
293 		.dsmpd = 1,
294 	},
295 	{
296 		.freq = 1296000000,
297 		.refdiv = 1,
298 		.fbdiv = 54,
299 		.postdiv1 = 1,
300 		.postdiv2 = 1,
301 		.dsmpd = 1,
302 	},
303 	{
304 		.freq = 1272000000,
305 		.refdiv = 1,
306 		.fbdiv = 53,
307 		.postdiv1 = 1,
308 		.postdiv2 = 1,
309 		.dsmpd = 1,
310 	},
311 	{
312 		.freq = 1248000000,
313 		.refdiv = 1,
314 		.fbdiv = 52,
315 		.postdiv1 = 1,
316 		.postdiv2 = 1,
317 		.dsmpd = 1,
318 	},
319 	{
320 		.freq = 1200000000,
321 		.refdiv = 1,
322 		.fbdiv = 50,
323 		.postdiv1 = 1,
324 		.postdiv2 = 1,
325 		.dsmpd = 1,
326 	},
327 	{
328 		.freq = 1188000000,
329 		.refdiv = 2,
330 		.fbdiv = 99,
331 		.postdiv1 = 1,
332 		.postdiv2 = 1,
333 		.dsmpd = 1,
334 	},
335 	{
336 		.freq = 1104000000,
337 		.refdiv = 1,
338 		.fbdiv = 46,
339 		.postdiv1 = 1,
340 		.postdiv2 = 1,
341 		.dsmpd = 1,
342 	},
343 	{
344 		.freq = 1100000000,
345 		.refdiv = 12,
346 		.fbdiv = 550,
347 		.postdiv1 = 1,
348 		.postdiv2 = 1,
349 		.dsmpd = 1,
350 	},
351 	{
352 		.freq = 1008000000,
353 		.refdiv = 1,
354 		.fbdiv = 84,
355 		.postdiv1 = 2,
356 		.postdiv2 = 1,
357 		.dsmpd = 1,
358 	},
359 	{
360 		.freq = 1000000000,
361 		.refdiv = 6,
362 		.fbdiv = 500,
363 		.postdiv1 = 2,
364 		.postdiv2 = 1,
365 		.dsmpd = 1,
366 	},
367 	{
368 		.freq = 984000000,
369 		.refdiv = 1,
370 		.fbdiv = 82,
371 		.postdiv1 = 2,
372 		.postdiv2 = 1,
373 		.dsmpd = 1,
374 	},
375 	{
376 		.freq = 960000000,
377 		.refdiv = 1,
378 		.fbdiv = 80,
379 		.postdiv1 = 2,
380 		.postdiv2 = 1,
381 		.dsmpd = 1,
382 	},
383 	{
384 		.freq = 936000000,
385 		.refdiv = 1,
386 		.fbdiv = 78,
387 		.postdiv1 = 2,
388 		.postdiv2 = 1,
389 		.dsmpd = 1,
390 	},
391 	{
392 		.freq = 912000000,
393 		.refdiv = 1,
394 		.fbdiv = 76,
395 		.postdiv1 = 2,
396 		.postdiv2 = 1,
397 		.dsmpd = 1,
398 	},
399 	{
400 		.freq = 900000000,
401 		.refdiv = 4,
402 		.fbdiv = 300,
403 		.postdiv1 = 2,
404 		.postdiv2 = 1,
405 		.dsmpd = 1,
406 	},
407 	{
408 		.freq = 888000000,
409 		.refdiv = 1,
410 		.fbdiv = 74,
411 		.postdiv1 = 2,
412 		.postdiv2 = 1,
413 		.dsmpd = 1,
414 	},
415 	{
416 		.freq = 864000000,
417 		.refdiv = 1,
418 		.fbdiv = 72,
419 		.postdiv1 = 2,
420 		.postdiv2 = 1,
421 		.dsmpd = 1,
422 	},
423 	{
424 		.freq = 840000000,
425 		.refdiv = 1,
426 		.fbdiv = 70,
427 		.postdiv1 = 2,
428 		.postdiv2 = 1,
429 		.dsmpd = 1,
430 	},
431 	{
432 		.freq = 816000000,
433 		.refdiv = 1,
434 		.fbdiv = 68,
435 		.postdiv1 = 2,
436 		.postdiv2 = 1,
437 		.dsmpd = 1,
438 	},
439 	{
440 		.freq = 800000000,
441 		.refdiv = 6,
442 		.fbdiv = 400,
443 		.postdiv1 = 2,
444 		.postdiv2 = 1,
445 		.dsmpd = 1,
446 	},
447 	{
448 		.freq = 700000000,
449 		.refdiv = 6,
450 		.fbdiv = 350,
451 		.postdiv1 = 2,
452 		.postdiv2 = 1,
453 		.dsmpd = 1,
454 	},
455 	{
456 		.freq = 696000000,
457 		.refdiv = 1,
458 		.fbdiv = 58,
459 		.postdiv1 = 2,
460 		.postdiv2 = 1,
461 		.dsmpd = 1,
462 	},
463 	{
464 		.freq = 600000000,
465 		.refdiv = 1,
466 		.fbdiv = 75,
467 		.postdiv1 = 3,
468 		.postdiv2 = 1,
469 		.dsmpd = 1,
470 	},
471 	{
472 		.freq = 594000000,
473 		.refdiv = 2,
474 		.fbdiv = 99,
475 		.postdiv1 = 2,
476 		.postdiv2 = 1,
477 		.dsmpd = 1,
478 	},
479 	{
480 		.freq = 504000000,
481 		.refdiv = 1,
482 		.fbdiv = 63,
483 		.postdiv1 = 3,
484 		.postdiv2 = 1,
485 		.dsmpd = 1,
486 	},
487 	{
488 		.freq = 500000000,
489 		.refdiv = 6,
490 		.fbdiv = 250,
491 		.postdiv1 = 2,
492 		.postdiv2 = 1,
493 		.dsmpd = 1,
494 	},
495 	{
496 		.freq = 408000000,
497 		.refdiv = 1,
498 		.fbdiv = 68,
499 		.postdiv1 = 2,
500 		.postdiv2 = 2,
501 		.dsmpd = 1,
502 	},
503 	{
504 		.freq = 312000000,
505 		.refdiv = 1,
506 		.fbdiv = 52,
507 		.postdiv1 = 2,
508 		.postdiv2 = 2,
509 		.dsmpd = 1,
510 	},
511 	{
512 		.freq = 216000000,
513 		.refdiv = 1,
514 		.fbdiv = 72,
515 		.postdiv1 = 4,
516 		.postdiv2 = 2,
517 		.dsmpd = 1,
518 	},
519 	{
520 		.freq = 96000000,
521 		.refdiv = 1,
522 		.fbdiv = 64,
523 		.postdiv1 = 4,
524 		.postdiv2 = 4,
525 		.dsmpd = 1,
526 	},
527 	{},
528 };
529 
530 static struct rk_clk_pll_rate rk3328_pll_frac_rates[] = {
531 	{
532 		.freq = 1016064000,
533 		.refdiv = 3,
534 		.fbdiv = 127,
535 		.postdiv1 = 1,
536 		.postdiv2 = 1,
537 		.dsmpd = 0,
538 		.frac = 134217,
539 	},
540 	{
541 		.freq = 983040000,
542 		.refdiv = 24,
543 		.fbdiv = 983,
544 		.postdiv1 = 1,
545 		.postdiv2 = 1,
546 		.dsmpd = 0,
547 		.frac = 671088,
548 	},
549 	{
550 		.freq = 491520000,
551 		.refdiv = 24,
552 		.fbdiv = 983,
553 		.postdiv1 = 2,
554 		.postdiv2 = 1,
555 		.dsmpd = 0,
556 		.frac = 671088,
557 	},
558 	{
559 		.freq = 61440000,
560 		.refdiv = 6,
561 		.fbdiv = 215,
562 		.postdiv1 = 7,
563 		.postdiv2 = 2,
564 		.dsmpd = 0,
565 		.frac = 671088,
566 	},
567 	{
568 		.freq = 56448000,
569 		.refdiv = 12,
570 		.fbdiv = 451,
571 		.postdiv1 = 4,
572 		.postdiv2 = 4,
573 		.dsmpd = 0,
574 		.frac = 9797894,
575 	},
576 	{
577 		.freq = 40960000,
578 		.refdiv = 12,
579 		.fbdiv = 409,
580 		.postdiv1 = 4,
581 		.postdiv2 = 5,
582 		.dsmpd = 0,
583 		.frac = 10066329,
584 	},
585 	{},
586 };
587 
588 static const char *pll_parents[] = {"xin24m"};
589 static struct rk_clk_pll_def apll = {
590 	.clkdef = {
591 		.id = PLL_APLL,
592 		.name = "apll",
593 		.parent_names = pll_parents,
594 		.parent_cnt = nitems(pll_parents),
595 	},
596 	.base_offset = 0x00,
597 	.gate_offset = 0x200,
598 	.gate_shift = 0,
599 	.mode_reg = 0x80,
600 	.mode_shift = 1,
601 	.flags = RK_CLK_PLL_HAVE_GATE,
602 	.frac_rates = rk3328_pll_frac_rates,
603 };
604 
605 static struct rk_clk_pll_def dpll = {
606 	.clkdef = {
607 		.id = PLL_DPLL,
608 		.name = "dpll",
609 		.parent_names = pll_parents,
610 		.parent_cnt = nitems(pll_parents),
611 	},
612 	.base_offset = 0x20,
613 	.gate_offset = 0x200,
614 	.gate_shift = 1,
615 	.mode_reg = 0x80,
616 	.mode_shift = 4,
617 	.flags = RK_CLK_PLL_HAVE_GATE,
618 };
619 
620 static struct rk_clk_pll_def cpll = {
621 	.clkdef = {
622 		.id = PLL_CPLL,
623 		.name = "cpll",
624 		.parent_names = pll_parents,
625 		.parent_cnt = nitems(pll_parents),
626 	},
627 	.base_offset = 0x40,
628 	.mode_reg = 0x80,
629 	.mode_shift = 8,
630 	.rates = rk3328_pll_rates,
631 };
632 
633 static struct rk_clk_pll_def gpll = {
634 	.clkdef = {
635 		.id = PLL_GPLL,
636 		.name = "gpll",
637 		.parent_names = pll_parents,
638 		.parent_cnt = nitems(pll_parents),
639 	},
640 	.base_offset = 0x60,
641 	.gate_offset = 0x200,
642 	.gate_shift = 2,
643 	.mode_reg = 0x80,
644 	.mode_shift = 12,
645 	.flags = RK_CLK_PLL_HAVE_GATE,
646 	.frac_rates = rk3328_pll_frac_rates,
647 };
648 
649 static struct rk_clk_pll_def npll = {
650 	.clkdef = {
651 		.id = PLL_NPLL,
652 		.name = "npll",
653 		.parent_names = pll_parents,
654 		.parent_cnt = nitems(pll_parents),
655 	},
656 	.base_offset = 0xa0,
657 	.gate_offset = 0x200,
658 	.gate_shift = 12,
659 	.mode_reg = 0x80,
660 	.mode_shift = 1,
661 	.flags = RK_CLK_PLL_HAVE_GATE,
662 	.rates = rk3328_pll_rates,
663 };
664 
665 /* CRU_CLKSEL_CON0 */
666 #define ACLK_BUS_PRE		136
667 
668 /* Needs hdmiphy as parent too*/
669 static const char *aclk_bus_pre_parents[] = {"cpll", "gpll"};
670 static struct rk_clk_composite_def aclk_bus_pre = {
671 	.clkdef = {
672 		.id = ACLK_BUS_PRE,
673 		.name = "aclk_bus_pre",
674 		.parent_names = aclk_bus_pre_parents,
675 		.parent_cnt = nitems(aclk_bus_pre_parents),
676 	},
677 	.muxdiv_offset = 0x100,
678 	.mux_shift = 13,
679 	.mux_width = 2,
680 
681 	.div_shift = 8,
682 	.div_width = 5,
683 
684 	.gate_offset = 0x220,
685 	.gate_shift = 0,
686 
687 	.flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE,
688 };
689 
690 static struct rk_clk_armclk_rates rk3328_armclk_rates[] = {
691 	{
692 		.freq = 1296000000,
693 		.div = 1,
694 	},
695 	{
696 		.freq = 1200000000,
697 		.div = 1,
698 	},
699 	{
700 		.freq = 1104000000,
701 		.div = 1,
702 	},
703 	{
704 		.freq = 1008000000,
705 		.div = 1,
706 	},
707 	{
708 		.freq = 912000000,
709 		.div = 1,
710 	},
711 	{
712 		.freq = 816000000,
713 		.div = 1,
714 	},
715 	{
716 		.freq = 696000000,
717 		.div = 1,
718 	},
719 	{
720 		.freq = 600000000,
721 		.div = 1,
722 	},
723 	{
724 		.freq = 408000000,
725 		.div = 1,
726 	},
727 	{
728 		.freq = 312000000,
729 		.div = 1,
730 	},
731 	{
732 		.freq = 216000000,
733 		.div = 1,
734 	},
735 	{
736 		.freq = 96000000,
737 		.div = 1,
738 	},
739 };
740 
741 #define	ARMCLK	6
742 static const char *armclk_parents[] = {"apll", "gpll", "dpll", "npll" };
743 static struct rk_clk_armclk_def armclk = {
744 	.clkdef = {
745 		.id = ARMCLK,
746 		.name = "armclk",
747 		.parent_names = armclk_parents,
748 		.parent_cnt = nitems(armclk_parents),
749 	},
750 	.muxdiv_offset = 0x100,
751 	.mux_shift = 6,
752 	.mux_width = 2,
753 
754 	.div_shift = 0,
755 	.div_width = 5,
756 
757 	.flags = RK_CLK_COMPOSITE_HAVE_MUX,
758 	.main_parent = 3, /* npll */
759 	.alt_parent = 0, /* apll */
760 
761 	.rates = rk3328_armclk_rates,
762 	.nrates = nitems(rk3328_armclk_rates),
763 };
764 
765 /* CRU_CLKSEL_CON1 */
766 
767 #define PCLK_BUS_PRE		216
768 #define HCLK_BUS_PRE		328
769 
770 static const char *hclk_bus_pre_parents[] = {"aclk_bus_pre"};
771 static struct rk_clk_composite_def hclk_bus_pre = {
772 	.clkdef = {
773 		.id = HCLK_BUS_PRE,
774 		.name = "hclk_bus_pre",
775 		.parent_names = hclk_bus_pre_parents,
776 		.parent_cnt = nitems(hclk_bus_pre_parents),
777 	},
778 	.muxdiv_offset = 0x104,
779 
780 	.div_shift = 8,
781 	.div_width = 2,
782 
783 	.gate_offset = 0x220,
784 	.gate_shift = 1,
785 
786 	.flags = RK_CLK_COMPOSITE_HAVE_GATE,
787 };
788 
789 static const char *pclk_bus_pre_parents[] = {"aclk_bus_pre"};
790 static struct rk_clk_composite_def pclk_bus_pre = {
791 	.clkdef = {
792 		.id = PCLK_BUS_PRE,
793 		.name = "pclk_bus_pre",
794 		.parent_names = pclk_bus_pre_parents,
795 		.parent_cnt = nitems(pclk_bus_pre_parents),
796 	},
797 	.muxdiv_offset = 0x104,
798 
799 	.div_shift = 12,
800 	.div_width = 3,
801 
802 	.gate_offset = 0x220,
803 	.gate_shift = 2,
804 
805 	.flags = RK_CLK_COMPOSITE_HAVE_GATE,
806 };
807 
808 /* CRU_CLKSEL_CON22 */
809 
810 #define SCLK_TSADC		36
811 
812 static const char *clk_tsadc_parents[] = {"xin24m"};
813 static struct rk_clk_composite_def clk_tsadc = {
814 	.clkdef = {
815 		.id = SCLK_TSADC,
816 		.name = "clk_tsadc",
817 		.parent_names = clk_tsadc_parents,
818 		.parent_cnt = nitems(clk_tsadc_parents),
819 	},
820 	.div_shift = 0,
821 	.div_width = 9,
822 };
823 
824 /* CRU_CLKSEL_CON28 */
825 
826 #define ACLK_PERI_PRE		137
827 
828 static const char *aclk_peri_pre_parents[] = {"cpll", "gpll"/* , "hdmiphy" */};
829 static struct rk_clk_composite_def aclk_peri_pre = {
830 	.clkdef = {
831 		.id = ACLK_PERI_PRE,
832 		.name = "aclk_peri_pre",
833 		.parent_names = aclk_peri_pre_parents,
834 		.parent_cnt = nitems(aclk_peri_pre_parents),
835 	},
836 	.muxdiv_offset = 0x170,
837 
838 	.mux_shift = 6,
839 	.mux_width = 2,
840 
841 	.div_shift = 0,
842 	.div_width = 5,
843 
844 	.flags = RK_CLK_COMPOSITE_HAVE_MUX,
845 };
846 
847 /* CRU_CLKSEL_CON29 */
848 
849 #define PCLK_PERI		230
850 #define HCLK_PERI		308
851 
852 static const char *phclk_peri_parents[] = {"aclk_peri_pre"};
853 static struct rk_clk_composite_def pclk_peri = {
854 	.clkdef = {
855 		.id = PCLK_PERI,
856 		.name = "pclk_peri",
857 		.parent_names = phclk_peri_parents,
858 		.parent_cnt = nitems(phclk_peri_parents),
859 	},
860 
861 	.div_shift = 0,
862 	.div_width = 2,
863 
864 	/* CRU_CLKGATE_CON10 */
865 	.gate_offset = 0x228,
866 	.gate_shift = 2,
867 
868 	.flags = RK_CLK_COMPOSITE_HAVE_GATE,
869 };
870 
871 static struct rk_clk_composite_def hclk_peri = {
872 	.clkdef = {
873 		.id = HCLK_PERI,
874 		.name = "hclk_peri",
875 		.parent_names = phclk_peri_parents,
876 		.parent_cnt = nitems(phclk_peri_parents),
877 	},
878 
879 	.div_shift = 4,
880 	.div_width = 3,
881 
882 	/* CRU_CLKGATE_CON10 */
883 	.gate_offset = 0x228,
884 	.gate_shift = 1,
885 
886 	.flags = RK_CLK_COMPOSITE_HAVE_GATE,
887 };
888 
889 /* CRU_CLKSEL_CON30 */
890 
891 #define SCLK_SDMMC		33
892 
893 static const char *mmc_parents[] = {"cpll", "gpll", "xin24m"/* , "usb480m" */};
894 static struct rk_clk_composite_def sdmmc = {
895 	.clkdef = {
896 		.id = SCLK_SDMMC,
897 		.name = "clk_sdmmc",
898 		.parent_names = mmc_parents,
899 		.parent_cnt = nitems(mmc_parents),
900 	},
901 	.muxdiv_offset = 0x178,
902 
903 	.mux_shift = 8,
904 	.mux_width = 2,
905 
906 	.div_shift = 0,
907 	.div_width = 8,
908 
909 	/* CRU_CLKGATE_CON4 */
910 	.gate_offset = 0x210,
911 	.gate_shift = 3,
912 
913 	.flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE,
914 };
915 
916 /* CRU_CLKSEL_CON31 */
917 #define SCLK_SDIO		34
918 
919 static struct rk_clk_composite_def sdio = {
920 	.clkdef = {
921 		.id = SCLK_SDIO,
922 		.name = "clk_sdio",
923 		.parent_names = mmc_parents,
924 		.parent_cnt = nitems(mmc_parents),
925 	},
926 	.muxdiv_offset = 0x17C,
927 
928 	.mux_shift = 8,
929 	.mux_width = 2,
930 
931 	.div_shift = 0,
932 	.div_width = 8,
933 
934 	/* CRU_CLKGATE_CON4 */
935 	.gate_offset = 0x210,
936 	.gate_shift = 4,
937 
938 	.flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE,
939 };
940 
941 /* CRU_CLKSEL_CON32 */
942 #define SCLK_EMMC		35
943 
944 static struct rk_clk_composite_def emmc = {
945 	.clkdef = {
946 		.id = SCLK_EMMC,
947 		.name = "clk_emmc",
948 		.parent_names = mmc_parents,
949 		.parent_cnt = nitems(mmc_parents),
950 	},
951 	.muxdiv_offset = 0x180,
952 
953 	.mux_shift = 8,
954 	.mux_width = 2,
955 
956 	.div_shift = 0,
957 	.div_width = 8,
958 
959 	/* CRU_CLKGATE_CON4 */
960 	.gate_offset = 0x210,
961 	.gate_shift = 5,
962 
963 	.flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE,
964 };
965 
966 /* CRU_CLKSEL_CON34 */
967 #define	SCLK_I2C0	55
968 #define	SCLK_I2C1	56
969 
970 static const char *i2c_parents[] = {"cpll", "gpll"};
971 
972 static struct rk_clk_composite_def i2c0 = {
973 	.clkdef = {
974 		.id = SCLK_I2C0,
975 		.name = "clk_i2c0",
976 		.parent_names = i2c_parents,
977 		.parent_cnt = nitems(i2c_parents),
978 	},
979 	.muxdiv_offset = 0x188,
980 
981 	.mux_shift = 7,
982 	.mux_width = 1,
983 
984 	.div_shift = 0,
985 	.div_width = 6,
986 
987 	/* CRU_CLKGATE_CON2 */
988 	.gate_offset = 0x208,
989 	.gate_shift = 9,
990 
991 	.flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE,
992 };
993 
994 static struct rk_clk_composite_def i2c1 = {
995 	.clkdef = {
996 		.id = SCLK_I2C1,
997 		.name = "clk_i2c1",
998 		.parent_names = i2c_parents,
999 		.parent_cnt = nitems(i2c_parents),
1000 	},
1001 	.muxdiv_offset = 0x188,
1002 
1003 	.mux_shift = 15,
1004 	.mux_width = 1,
1005 
1006 	.div_shift = 8,
1007 	.div_width = 6,
1008 
1009 	/* CRU_CLKGATE_CON2 */
1010 	.gate_offset = 0x208,
1011 	.gate_shift = 10,
1012 
1013 	.flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE,
1014 };
1015 
1016 /* CRU_CLKSEL_CON35 */
1017 #define	SCLK_I2C2	57
1018 #define	SCLK_I2C3	58
1019 
1020 static struct rk_clk_composite_def i2c2 = {
1021 	.clkdef = {
1022 		.id = SCLK_I2C2,
1023 		.name = "clk_i2c2",
1024 		.parent_names = i2c_parents,
1025 		.parent_cnt = nitems(i2c_parents),
1026 	},
1027 	.muxdiv_offset = 0x18C,
1028 
1029 	.mux_shift = 7,
1030 	.mux_width = 1,
1031 
1032 	.div_shift = 0,
1033 	.div_width = 6,
1034 
1035 	/* CRU_CLKGATE_CON2 */
1036 	.gate_offset = 0x208,
1037 	.gate_shift = 11,
1038 
1039 	.flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE,
1040 };
1041 
1042 static struct rk_clk_composite_def i2c3 = {
1043 	.clkdef = {
1044 		.id = SCLK_I2C3,
1045 		.name = "clk_i2c3",
1046 		.parent_names = i2c_parents,
1047 		.parent_cnt = nitems(i2c_parents),
1048 	},
1049 	.muxdiv_offset = 0x18C,
1050 
1051 	.mux_shift = 15,
1052 	.mux_width = 1,
1053 
1054 	.div_shift = 8,
1055 	.div_width = 6,
1056 
1057 	/* CRU_CLKGATE_CON2 */
1058 	.gate_offset = 0x208,
1059 	.gate_shift = 12,
1060 
1061 	.flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE,
1062 };
1063 
1064 #define	SCLK_USB3_REF		72
1065 #define	SCLK_USB3_SUSPEND	73
1066 #define	SCLK_USB3PHY_REF	94
1067 #define	SCLK_REF_USB3OTG	95
1068 #define	SCLK_USB3OTG_SUSPEND	97
1069 #define	SCLK_REF_USB3OTG_SRC	98
1070 
1071 static const char *ref_usb3otg_parents[] = { "xin24m", "clk_usb3otg_ref" };
1072 
1073 static struct rk_clk_composite_def ref_usb3otg = {
1074 	.clkdef = {
1075 		.id = SCLK_REF_USB3OTG,
1076 		.name = "clk_ref_usb3otg",
1077 		.parent_names = ref_usb3otg_parents,
1078 		.parent_cnt = nitems(ref_usb3otg_parents),
1079 	},
1080 	.muxdiv_offset = 0x1B4,
1081 
1082 	.mux_shift = 8,
1083 	.mux_width = 1,
1084 
1085 	.flags = RK_CLK_COMPOSITE_HAVE_MUX,
1086 };
1087 
1088 static const char *usb3otg_suspend_parents[] = { "xin24m"/*, "clk_rtc32k" */};
1089 
1090 static struct rk_clk_composite_def usb3otg_suspend = {
1091 	.clkdef = {
1092 		.id = SCLK_USB3OTG_SUSPEND,
1093 		.name = "clk_usb3otg_suspend",
1094 		.parent_names = usb3otg_suspend_parents,
1095 		.parent_cnt = nitems(usb3otg_suspend_parents),
1096 	},
1097 	.muxdiv_offset = 0x184,
1098 
1099 	.mux_shift = 15,
1100 	.mux_width = 1,
1101 
1102 	.div_shift = 0,
1103 	.div_width = 10,
1104 
1105 	/* CRU_CLKGATE_CON4 */
1106 	.gate_offset = 0x210,
1107 	.gate_shift = 8,
1108 
1109 	.flags = RK_CLK_COMPOSITE_HAVE_GATE,
1110 };
1111 
1112 static const char *ref_usb3otg_src_parents[] = { "cpll", "gpll" };
1113 
1114 static struct rk_clk_composite_def ref_usb3otg_src = {
1115 	.clkdef = {
1116 		.id = SCLK_REF_USB3OTG_SRC,
1117 		.name = "clk_ref_usb3otg_src",
1118 		.parent_names = ref_usb3otg_src_parents,
1119 		.parent_cnt = nitems(ref_usb3otg_src_parents),
1120 	},
1121 	.muxdiv_offset = 0x1B4,
1122 
1123 	.mux_shift = 7,
1124 	.mux_width = 1,
1125 
1126 	.div_shift = 0,
1127 	.div_width = 7,
1128 
1129 	/* CRU_CLKGATE_CON4 */
1130 	.gate_offset = 0x210,
1131 	.gate_shift = 9,
1132 
1133 	.flags = RK_CLK_COMPOSITE_HAVE_GATE,
1134 };
1135 
1136 /* I2S0 */
1137 static const char *i2s0_div_parents[] = { "cpll", "gpll" };
1138 static struct rk_clk_composite_def i2s0_div = {
1139 	.clkdef = {
1140 		.id = 0,
1141 		.name = "clk_i2s0_div",
1142 		.parent_names = i2s0_div_parents,
1143 		.parent_cnt = nitems(i2s0_div_parents),
1144 	},
1145 	/* CRU_CLKSEL_CON6 */
1146 	.muxdiv_offset = 0x118,
1147 
1148 	.mux_shift = 15,
1149 	.mux_width = 1,
1150 
1151 	.div_shift = 0,
1152 	.div_width = 7,
1153 
1154 	/* CRU_CLKGATE_CON1 */
1155 	.gate_offset = 0x204,
1156 	.gate_shift = 1,
1157 
1158 	.flags = RK_CLK_COMPOSITE_HAVE_GATE,
1159 };
1160 
1161 static const char *i2s0_frac_parents[] = { "clk_i2s0_div" };
1162 static struct rk_clk_fract_def i2s0_frac = {
1163 	.clkdef = {
1164 		.id = 0,
1165 		.name = "clk_i2s0_frac",
1166 		.parent_names = i2s0_frac_parents,
1167 		.parent_cnt = nitems(i2s0_frac_parents),
1168 	},
1169 	/* CRU_CLKSEL_CON7 */
1170 	.offset = 0x11c,
1171 
1172 	/* CRU_CLKGATE_CON1 */
1173 	.gate_offset = 0x204,
1174 	.gate_shift = 2,
1175 
1176 	.flags = RK_CLK_FRACT_HAVE_GATE,
1177 };
1178 
1179 static const char *i2s0_mux_parents[] = { "clk_i2s0_div", "clk_i2s0_frac", "xin12m", "xin12m" };
1180 static struct rk_clk_mux_def i2s0_mux = {
1181 	.clkdef = {
1182 		.id = 0,
1183 		.name = "clk_i2s0_mux",
1184 		.parent_names = i2s0_mux_parents,
1185 		.parent_cnt = nitems(i2s0_mux_parents),
1186 	},
1187 	.offset = 0x118,
1188 
1189 	.shift = 8,
1190 	.width = 2,
1191 
1192 	.mux_flags = RK_CLK_MUX_REPARENT,
1193 };
1194 
1195 /* I2S1 */
1196 static const char *i2s1_div_parents[] = { "cpll", "gpll" };
1197 static struct rk_clk_composite_def i2s1_div = {
1198 	.clkdef = {
1199 		.id = 0,
1200 		.name = "clk_i2s1_div",
1201 		.parent_names = i2s1_div_parents,
1202 		.parent_cnt = nitems(i2s1_div_parents),
1203 	},
1204 	/* CRU_CLKSEL_CON8 */
1205 	.muxdiv_offset = 0x120,
1206 
1207 	.mux_shift = 15,
1208 	.mux_width = 1,
1209 
1210 	.div_shift = 0,
1211 	.div_width = 7,
1212 
1213 	/* CRU_CLKGATE_CON1 */
1214 	.gate_offset = 0x204,
1215 	.gate_shift = 4,
1216 
1217 	.flags = RK_CLK_COMPOSITE_HAVE_GATE,
1218 };
1219 
1220 static const char *i2s1_frac_parents[] = { "clk_i2s1_div" };
1221 static struct rk_clk_fract_def i2s1_frac = {
1222 	.clkdef = {
1223 		.id = 0,
1224 		.name = "clk_i2s1_frac",
1225 		.parent_names = i2s1_frac_parents,
1226 		.parent_cnt = nitems(i2s1_frac_parents),
1227 	},
1228 	/* CRU_CLKSEL_CON9 */
1229 	.offset = 0x124,
1230 
1231 	/* CRU_CLKGATE_CON1 */
1232 	.gate_offset = 0x204,
1233 	.gate_shift = 5,
1234 
1235 	.flags = RK_CLK_FRACT_HAVE_GATE,
1236 };
1237 
1238 static const char *i2s1_mux_parents[] = { "clk_i2s1_div", "clk_i2s1_frac", "clkin_i2s1", "xin12m" };
1239 static struct rk_clk_mux_def i2s1_mux = {
1240 	.clkdef = {
1241 		.id = 0,
1242 		.name = "clk_i2s1_mux",
1243 		.parent_names = i2s1_mux_parents,
1244 		.parent_cnt = nitems(i2s1_mux_parents),
1245 	},
1246 	.offset = 0x120,
1247 
1248 	.shift = 8,
1249 	.width = 2,
1250 	.mux_flags = RK_CLK_MUX_REPARENT,
1251 };
1252 
1253 static struct clk_fixed_def clkin_i2s1 = {
1254 	.clkdef = {
1255 		.id = 0,
1256 		.name = "clkin_i2s1",
1257 		.parent_names = NULL,
1258 		.parent_cnt = 0
1259 	},
1260 
1261 	.freq = 0,
1262 };
1263 
1264 /* I2S2 */
1265 static const char *i2s2_div_parents[] = { "cpll", "gpll" };
1266 static struct rk_clk_composite_def i2s2_div = {
1267 	.clkdef = {
1268 		.id = 0,
1269 		.name = "clk_i2s2_div",
1270 		.parent_names = i2s2_div_parents,
1271 		.parent_cnt = nitems(i2s2_div_parents),
1272 	},
1273 	/* CRU_CLKSEL_CON10 */
1274 	.muxdiv_offset = 0x128,
1275 
1276 	.mux_shift = 15,
1277 	.mux_width = 1,
1278 
1279 	.div_shift = 0,
1280 	.div_width = 7,
1281 
1282 	/* CRU_CLKGATE_CON1 */
1283 	.gate_offset = 0x204,
1284 	.gate_shift = 8,
1285 
1286 	.flags = RK_CLK_COMPOSITE_HAVE_GATE,
1287 };
1288 
1289 static const char *i2s2_frac_parents[] = { "clk_i2s2_div" };
1290 static struct rk_clk_fract_def i2s2_frac = {
1291 	.clkdef = {
1292 		.id = 0,
1293 		.name = "clk_i2s2_frac",
1294 		.parent_names = i2s2_frac_parents,
1295 		.parent_cnt = nitems(i2s2_frac_parents),
1296 	},
1297 	/* CRU_CLKSEL_CON11 */
1298 	.offset = 0x12c,
1299 
1300 	/* CRU_CLKGATE_CON1 */
1301 	.gate_offset = 0x204,
1302 	.gate_shift = 9,
1303 
1304 	.flags = RK_CLK_FRACT_HAVE_GATE,
1305 };
1306 
1307 static const char *i2s2_mux_parents[] = { "clk_i2s2_div", "clk_i2s2_frac", "clkin_i2s2", "xin12m" };
1308 static struct rk_clk_mux_def i2s2_mux = {
1309 	.clkdef = {
1310 		.id = 0,
1311 		.name = "clk_i2s2_mux",
1312 		.parent_names = i2s2_mux_parents,
1313 		.parent_cnt = nitems(i2s2_mux_parents),
1314 	},
1315 	.offset = 0x128,
1316 
1317 	.shift = 8,
1318 	.width = 2,
1319 
1320 	.mux_flags = RK_CLK_MUX_REPARENT,
1321 };
1322 
1323 static struct clk_fixed_def clkin_i2s2 = {
1324 	.clkdef = {
1325 		.id = 0,
1326 		.name = "clkin_i2s2",
1327 		.parent_names = NULL,
1328 		.parent_cnt = 0
1329 	},
1330 
1331 	.freq = 0,
1332 };
1333 
1334 static struct clk_fixed_def xin12m = {
1335 	.clkdef = {
1336 		.id = 0,
1337 		.name = "xin12m",
1338 		.parent_names = NULL,
1339 		.parent_cnt = 0
1340 	},
1341 
1342 	.freq = 12000000,
1343 };
1344 
1345 static const char *mac2io_src_parents[] = { "cpll", "gpll" };
1346 
1347 static struct rk_clk_composite_def mac2io_src = {
1348 	.clkdef = {
1349 		.id = SCLK_MAC2IO_SRC,
1350 		.name = "clk_mac2io_src",
1351 		.parent_names = mac2io_src_parents,
1352 		.parent_cnt = nitems(mac2io_src_parents),
1353 	},
1354 	/* CRU_CLKSEL_CON27 */
1355 	.muxdiv_offset = 0x16c,
1356 
1357 	.mux_shift = 7,
1358 	.mux_width = 1,
1359 
1360 	.div_shift = 0,
1361 	.div_width = 5,
1362 
1363 	/* CRU_CLKGATE_CON3 */
1364 	.gate_offset = 0x20c,
1365 	.gate_shift = 1,
1366 
1367 	.flags = RK_CLK_COMPOSITE_HAVE_GATE | RK_CLK_COMPOSITE_HAVE_MUX,
1368 };
1369 
1370 static const char *mac2io_out_parents[] = { "cpll", "gpll" };
1371 
1372 static struct rk_clk_composite_def mac2io_out = {
1373 	.clkdef = {
1374 		.id = SCLK_MAC2IO_OUT,
1375 		.name = "clk_mac2io_out",
1376 		.parent_names = mac2io_out_parents,
1377 		.parent_cnt = nitems(mac2io_out_parents),
1378 	},
1379 	/* CRU_CLKSEL_CON27 */
1380 	.muxdiv_offset = 0x16c,
1381 
1382 	.mux_shift = 15,
1383 	.mux_width = 1,
1384 
1385 	.div_shift = 8,
1386 	.div_width = 5,
1387 
1388 	/* CRU_CLKGATE_CON3 */
1389 	.gate_offset = 0x20c,
1390 	.gate_shift = 5,
1391 
1392 	.flags = RK_CLK_COMPOSITE_HAVE_GATE | RK_CLK_COMPOSITE_HAVE_MUX,
1393 };
1394 
1395 static const char *mac2io_parents[] = { "clk_mac2io_src", "gmac_clkin" };
1396 
1397 static struct rk_clk_composite_def mac2io = {
1398 	.clkdef = {
1399 		.id = SCLK_MAC2IO,
1400 		.name = "clk_mac2io",
1401 		.parent_names = mac2io_parents,
1402 		.parent_cnt = nitems(mac2io_parents),
1403 	},
1404 	.muxdiv_offset = RK3328_GRF_MAC_CON1,
1405 
1406 	.mux_shift = 10,
1407 	.mux_width = 1,
1408 
1409 	.flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_GRF
1410 };
1411 
1412 static const char *mac2io_ext_parents[] = { "clk_mac2io", "gmac_clkin" };
1413 
1414 static struct rk_clk_composite_def mac2io_ext = {
1415 	.clkdef = {
1416 		.id = SCLK_MAC2IO_EXT,
1417 		.name = "clk_mac2io_ext",
1418 		.parent_names = mac2io_ext_parents,
1419 		.parent_cnt = nitems(mac2io_ext_parents),
1420 	},
1421 	.muxdiv_offset = RK3328_GRF_SOC_CON4,
1422 
1423 	.mux_shift = 14,
1424 	.mux_width = 1,
1425 
1426 	.flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_GRF
1427 };
1428 
1429 static const char *mac2phy_src_parents[] = { "cpll", "gpll" };
1430 
1431 static struct rk_clk_composite_def mac2phy_src = {
1432 	.clkdef = {
1433 		.id = SCLK_MAC2PHY_SRC,
1434 		.name = "clk_mac2phy_src",
1435 		.parent_names = mac2phy_src_parents,
1436 		.parent_cnt = nitems(mac2phy_src_parents),
1437 	},
1438 	/* CRU_CLKSEL_CON26 */
1439 	.muxdiv_offset = 0x168,
1440 
1441 	.mux_shift = 7,
1442 	.mux_width = 1,
1443 
1444 	.div_shift = 0,
1445 	.div_width = 5,
1446 
1447 	/* CRU_CLKGATE_CON3 */
1448 	.gate_offset = 0x20c,
1449 	.gate_shift = 0,
1450 
1451 	.flags = RK_CLK_COMPOSITE_HAVE_GATE | RK_CLK_COMPOSITE_HAVE_MUX,
1452 };
1453 
1454 static const char *mac2phy_parents[] = { "clk_mac2phy_src", "phy_50m_out" };
1455 
1456 static struct rk_clk_composite_def mac2phy = {
1457 	.clkdef = {
1458 		.id = SCLK_MAC2PHY,
1459 		.name = "clk_mac2phy",
1460 		.parent_names = mac2phy_parents,
1461 		.parent_cnt = nitems(mac2phy_parents),
1462 	},
1463 	.muxdiv_offset = RK3328_GRF_MAC_CON2,
1464 
1465 	.mux_shift = 10,
1466 	.mux_width = 1,
1467 
1468 	.flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_GRF
1469 };
1470 
1471 static const char *mac2phy_out_parents[] = { "clk_mac2phy" };
1472 
1473 static struct rk_clk_composite_def mac2phy_out = {
1474 	.clkdef = {
1475 		.id = SCLK_MAC2PHY_OUT,
1476 		.name = "clk_mac2phy_out",
1477 		.parent_names = mac2phy_out_parents,
1478 		.parent_cnt = nitems(mac2phy_out_parents),
1479 	},
1480 	/* CRU_CLKSEL_CON26 */
1481 	.muxdiv_offset = 0x168,
1482 
1483 	.div_shift = 8,
1484 	.div_width = 2,
1485 
1486 	/* CRU_CLKGATE_CON9 */
1487 	.gate_offset = 0x224,
1488 	.gate_shift = 2,
1489 
1490 	.flags = RK_CLK_COMPOSITE_HAVE_GATE
1491 };
1492 
1493 static struct clk_fixed_def phy_50m_out = {
1494 	.clkdef.name = "phy_50m_out",
1495 	.freq = 50000000,
1496 };
1497 
1498 static struct clk_link_def gmac_clkin = {
1499 	.clkdef.name = "gmac_clkin",
1500 };
1501 
1502 static const char *aclk_gmac_parents[] = { "cpll", "gpll" };
1503 
1504 static struct rk_clk_composite_def aclk_gmac = {
1505 	.clkdef = {
1506 		.id = ACLK_GMAC,
1507 		.name = "aclk_gmac",
1508 		.parent_names = aclk_gmac_parents,
1509 		.parent_cnt = nitems(aclk_gmac_parents),
1510 	},
1511 	/* CRU_CLKSEL_CON35 */
1512 	.muxdiv_offset = 0x18c,
1513 
1514 	.mux_shift = 6,
1515 	.mux_width = 2,
1516 
1517 	.div_shift = 0,
1518 	.div_width = 5,
1519 
1520 	/* CRU_CLKGATE_CON3 */
1521 	.gate_offset = 0x20c,
1522 	.gate_shift = 2,
1523 
1524 	.flags = RK_CLK_COMPOSITE_HAVE_GATE | RK_CLK_COMPOSITE_HAVE_MUX,
1525 };
1526 
1527 static const char *pclk_gmac_parents[] = { "aclk_gmac" };
1528 
1529 static struct rk_clk_composite_def pclk_gmac = {
1530 	.clkdef = {
1531 		.id = PCLK_GMAC,
1532 		.name = "pclk_gmac",
1533 		.parent_names = pclk_gmac_parents,
1534 		.parent_cnt = nitems(pclk_gmac_parents),
1535 	},
1536 	/* CRU_CLKSEL_CON25 */
1537 	.muxdiv_offset = 0x164,
1538 
1539 	.div_shift = 8,
1540 	.div_width = 3,
1541 
1542 	/* CRU_CLKGATE_CON9 */
1543 	.gate_offset = 0x224,
1544 	.gate_shift = 0,
1545 
1546 	.flags = RK_CLK_COMPOSITE_HAVE_GATE
1547 };
1548 
1549 static struct rk_clk rk3328_clks[] = {
1550 	{
1551 		.type = RK3328_CLK_PLL,
1552 		.clk.pll = &apll
1553 	},
1554 	{
1555 		.type = RK3328_CLK_PLL,
1556 		.clk.pll = &dpll
1557 	},
1558 	{
1559 		.type = RK3328_CLK_PLL,
1560 		.clk.pll = &cpll
1561 	},
1562 	{
1563 		.type = RK3328_CLK_PLL,
1564 		.clk.pll = &gpll
1565 	},
1566 	{
1567 		.type = RK3328_CLK_PLL,
1568 		.clk.pll = &npll
1569 	},
1570 
1571 	{
1572 		.type = RK_CLK_COMPOSITE,
1573 		.clk.composite = &aclk_bus_pre
1574 	},
1575 	{
1576 		.type = RK_CLK_COMPOSITE,
1577 		.clk.composite = &hclk_bus_pre
1578 	},
1579 	{
1580 		.type = RK_CLK_COMPOSITE,
1581 		.clk.composite = &pclk_bus_pre
1582 	},
1583 
1584 	{
1585 		.type = RK_CLK_ARMCLK,
1586 		.clk.armclk = &armclk,
1587 	},
1588 
1589 	{
1590 		.type = RK_CLK_COMPOSITE,
1591 		.clk.composite = &clk_tsadc,
1592 	},
1593 	{
1594 		.type = RK_CLK_COMPOSITE,
1595 		.clk.composite = &aclk_peri_pre,
1596 	},
1597 	{
1598 		.type = RK_CLK_COMPOSITE,
1599 		.clk.composite = &pclk_peri,
1600 	},
1601 	{
1602 		.type = RK_CLK_COMPOSITE,
1603 		.clk.composite = &hclk_peri,
1604 	},
1605 	{
1606 		.type = RK_CLK_COMPOSITE,
1607 		.clk.composite = &sdmmc
1608 	},
1609 	{
1610 		.type = RK_CLK_COMPOSITE,
1611 		.clk.composite = &sdio
1612 	},
1613 	{
1614 		.type = RK_CLK_COMPOSITE,
1615 		.clk.composite = &emmc
1616 	},
1617 
1618 	{
1619 		.type = RK_CLK_COMPOSITE,
1620 		.clk.composite = &i2c0
1621 	},
1622 	{
1623 		.type = RK_CLK_COMPOSITE,
1624 		.clk.composite = &i2c1
1625 	},
1626 	{
1627 		.type = RK_CLK_COMPOSITE,
1628 		.clk.composite = &i2c2
1629 	},
1630 	{
1631 		.type = RK_CLK_COMPOSITE,
1632 		.clk.composite = &i2c3
1633 	},
1634 
1635 	{
1636 		.type = RK_CLK_COMPOSITE,
1637 		.clk.composite = &ref_usb3otg
1638 	},
1639 	{
1640 		.type = RK_CLK_COMPOSITE,
1641 		.clk.composite = &ref_usb3otg_src
1642 	},
1643 	{
1644 		.type = RK_CLK_COMPOSITE,
1645 		.clk.composite = &usb3otg_suspend
1646 	},
1647 	{
1648 		.type = RK_CLK_COMPOSITE,
1649 		.clk.composite = &i2s0_div
1650 	},
1651 	{
1652 		.type = RK_CLK_FRACT,
1653 		.clk.fract = &i2s0_frac
1654 	},
1655 	{
1656 		.type = RK_CLK_MUX,
1657 		.clk.mux = &i2s0_mux
1658 	},
1659 	{
1660 		.type = RK_CLK_COMPOSITE,
1661 		.clk.composite = &i2s1_div
1662 	},
1663 	{
1664 		.type = RK_CLK_FRACT,
1665 		.clk.fract = &i2s1_frac
1666 	},
1667 	{
1668 		.type = RK_CLK_MUX,
1669 		.clk.mux = &i2s1_mux
1670 	},
1671 	{
1672 		.type = RK_CLK_FIXED,
1673 		.clk.fixed = &clkin_i2s1
1674 	},
1675 	{
1676 		.type = RK_CLK_COMPOSITE,
1677 		.clk.composite = &i2s2_div
1678 	},
1679 	{
1680 		.type = RK_CLK_FRACT,
1681 		.clk.fract = &i2s2_frac
1682 	},
1683 	{
1684 		.type = RK_CLK_MUX,
1685 		.clk.mux = &i2s2_mux
1686 	},
1687 	{
1688 		.type = RK_CLK_FIXED,
1689 		.clk.fixed = &clkin_i2s2
1690 	},
1691 	{
1692 		.type = RK_CLK_FIXED,
1693 		.clk.fixed = &xin12m
1694 	},
1695 	{
1696 		.type = RK_CLK_COMPOSITE,
1697 		.clk.composite = &mac2io_src
1698 	},
1699 	{
1700 		.type = RK_CLK_COMPOSITE,
1701 		.clk.composite = &mac2io
1702 	},
1703 	{
1704 		.type = RK_CLK_COMPOSITE,
1705 		.clk.composite = &mac2io_out
1706 	},
1707 	{
1708 		.type = RK_CLK_COMPOSITE,
1709 		.clk.composite = &mac2io_ext
1710 	},
1711 	{
1712 		.type = RK_CLK_COMPOSITE,
1713 		.clk.composite = &mac2phy_src
1714 	},
1715 	{
1716 		.type = RK_CLK_COMPOSITE,
1717 		.clk.composite = &mac2phy
1718 	},
1719 	{
1720 		.type = RK_CLK_COMPOSITE,
1721 		.clk.composite = &mac2phy_out
1722 	},
1723 	{
1724 		.type = RK_CLK_FIXED,
1725 		.clk.fixed = &phy_50m_out
1726 	},
1727 	{
1728 		.type = RK_CLK_LINK,
1729 		.clk.link = &gmac_clkin
1730 	},
1731 	{
1732 		.type = RK_CLK_COMPOSITE,
1733 		.clk.composite = &aclk_gmac
1734 	},
1735 	{
1736 		.type = RK_CLK_COMPOSITE,
1737 		.clk.composite = &pclk_gmac
1738 	},
1739 };
1740 
1741 static int
rk3328_cru_probe(device_t dev)1742 rk3328_cru_probe(device_t dev)
1743 {
1744 
1745 	if (!ofw_bus_status_okay(dev))
1746 		return (ENXIO);
1747 
1748 	if (ofw_bus_is_compatible(dev, "rockchip,rk3328-cru")) {
1749 		device_set_desc(dev, "Rockchip RK3328 Clock and Reset Unit");
1750 		return (BUS_PROBE_DEFAULT);
1751 	}
1752 
1753 	return (ENXIO);
1754 }
1755 
1756 static int
rk3328_cru_attach(device_t dev)1757 rk3328_cru_attach(device_t dev)
1758 {
1759 	struct rk_cru_softc *sc;
1760 
1761 	sc = device_get_softc(dev);
1762 	sc->dev = dev;
1763 
1764 	sc->gates = rk3328_gates;
1765 	sc->ngates = nitems(rk3328_gates);
1766 
1767 	sc->clks = rk3328_clks;
1768 	sc->nclks = nitems(rk3328_clks);
1769 
1770 	sc->reset_offset = 0x300;
1771 	sc->reset_num = 184;
1772 
1773 	return (rk_cru_attach(dev));
1774 }
1775 
1776 static device_method_t rk3328_cru_methods[] = {
1777 	/* Device interface */
1778 	DEVMETHOD(device_probe,		rk3328_cru_probe),
1779 	DEVMETHOD(device_attach,	rk3328_cru_attach),
1780 
1781 	DEVMETHOD_END
1782 };
1783 
1784 static devclass_t rk3328_cru_devclass;
1785 
1786 DEFINE_CLASS_1(rk3328_cru, rk3328_cru_driver, rk3328_cru_methods,
1787   sizeof(struct rk_cru_softc), rk_cru_driver);
1788 
1789 EARLY_DRIVER_MODULE(rk3328_cru, simplebus, rk3328_cru_driver,
1790     rk3328_cru_devclass, 0, 0, BUS_PASS_BUS + BUS_PASS_ORDER_MIDDLE);
1791