]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/arm64/rockchip/clk/rk3328_cru.c
arm64: rockchip: rl3399: Remove the ability to put the PLL in normal mode at boot
[FreeBSD/FreeBSD.git] / sys / arm64 / rockchip / clk / rk3328_cru.c
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3  *
4  * Copyright (c) 2018 Emmanuel Vadot <manu@freebsd.org>
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  *
28  * $FreeBSD$
29  */
30
31 #include <sys/cdefs.h>
32 __FBSDID("$FreeBSD$");
33
34 #include <sys/param.h>
35 #include <sys/systm.h>
36 #include <sys/bus.h>
37 #include <sys/rman.h>
38 #include <sys/kernel.h>
39 #include <sys/module.h>
40 #include <machine/bus.h>
41
42 #include <dev/fdt/simplebus.h>
43
44 #include <dev/ofw/ofw_bus.h>
45 #include <dev/ofw/ofw_bus_subr.h>
46
47 #include <dev/extres/clk/clk_div.h>
48 #include <dev/extres/clk/clk_fixed.h>
49 #include <dev/extres/clk/clk_mux.h>
50
51 #include <arm64/rockchip/clk/rk_cru.h>
52
53 /* GATES */
54
55 #define ACLK_PERI               153
56 #define PCLK_GPIO0              200
57 #define PCLK_GPIO1              201
58 #define PCLK_GPIO2              202
59 #define PCLK_GPIO3              203
60 #define PCLK_I2C0               205
61 #define PCLK_I2C1               206
62 #define PCLK_I2C2               207
63 #define PCLK_I2C3               208
64 #define PCLK_TSADC              213
65 #define HCLK_SDMMC              317
66 #define HCLK_SDIO               318
67 #define HCLK_EMMC               319
68 #define HCLK_SDMMC_EXT          320
69
70 static struct rk_cru_gate rk3328_gates[] = {
71         /* CRU_CLKGATE_CON0 */
72         CRU_GATE(0, "apll_core", "apll", 0x200, 0)
73         CRU_GATE(0, "dpll_core", "dpll", 0x200, 1)
74         CRU_GATE(0, "gpll_core", "gpll", 0x200, 2)
75         CRU_GATE(0, "npll_core", "npll", 0x200, 12)
76
77         /* CRU_CLKGATE_CON4 */
78         CRU_GATE(0, "gpll_peri", "gpll", 0x210, 0)
79         CRU_GATE(0, "cpll_peri", "cpll", 0x210, 1)
80
81         /* CRU_CLKGATE_CON8 */
82         CRU_GATE(0, "pclk_bus", "pclk_bus_pre", 0x220, 3)
83         CRU_GATE(0, "pclk_phy_pre", "pclk_bus_pre", 0x220, 4)
84
85         /* CRU_CLKGATE_CON10 */
86         CRU_GATE(ACLK_PERI, "aclk_peri", "aclk_peri_pre", 0x228, 0)
87
88         /* CRU_CLKGATE_CON15*/
89         CRU_GATE(PCLK_I2C0, "pclk_i2c0", "pclk_bus", 0x23C, 10)
90
91         /* CRU_CLKGATE_CON16 */
92         CRU_GATE(PCLK_I2C1, "pclk_i2c1", "pclk_bus", 0x23C, 0)
93         CRU_GATE(PCLK_I2C2, "pclk_i2c2", "pclk_bus", 0x23C, 1)
94         CRU_GATE(PCLK_I2C3, "pclk_i2c3", "pclk_bus", 0x23C, 2)
95         CRU_GATE(PCLK_TSADC, "pclk_tsadc", "pclk_bus", 0x23C, 14)
96
97         CRU_GATE(PCLK_GPIO0, "pclk_gpio0", "pclk_bus", 0x240, 7)
98         CRU_GATE(PCLK_GPIO1, "pclk_gpio1", "pclk_bus", 0x240, 8)
99         CRU_GATE(PCLK_GPIO2, "pclk_gpio2", "pclk_bus", 0x240, 9)
100         CRU_GATE(PCLK_GPIO3, "pclk_gpio3", "pclk_bus", 0x240, 10)
101
102         /* CRU_CLKGATE_CON19 */
103         CRU_GATE(HCLK_SDMMC, "hclk_sdmmc", "hclk_peri", 0x24C, 0)
104         CRU_GATE(HCLK_SDIO, "hclk_sdio", "hclk_peri", 0x24C, 1)
105         CRU_GATE(HCLK_EMMC, "hclk_emmc", "hclk_peri", 0x24C, 2)
106         CRU_GATE(HCLK_SDMMC_EXT, "hclk_sdmmc_ext", "hclk_peri", 0x24C, 15)
107 };
108
109 /*
110  * PLLs
111  */
112
113 #define PLL_APLL                1
114 #define PLL_DPLL                2
115 #define PLL_CPLL                3
116 #define PLL_GPLL                4
117 #define PLL_NPLL                5
118
119 static struct rk_clk_pll_rate rk3328_pll_rates[] = {
120         {
121                 .freq = 1608000000,
122                 .refdiv = 1,
123                 .fbdiv = 67,
124                 .postdiv1 = 1,
125                 .postdiv2 = 1,
126                 .dsmpd = 1,
127         },
128         {
129                 .freq = 1584000000,
130                 .refdiv = 1,
131                 .fbdiv = 66,
132                 .postdiv1 = 1,
133                 .postdiv2 = 1,
134                 .dsmpd = 1,
135         },
136         {
137                 .freq = 1560000000,
138                 .refdiv = 1,
139                 .fbdiv = 65,
140                 .postdiv1 = 1,
141                 .postdiv2 = 1,
142                 .dsmpd = 1,
143         },
144         {
145                 .freq = 1536000000,
146                 .refdiv = 1,
147                 .fbdiv = 64,
148                 .postdiv1 = 1,
149                 .postdiv2 = 1,
150                 .dsmpd = 1,
151         },
152         {
153                 .freq = 1512000000,
154                 .refdiv = 1,
155                 .fbdiv = 63,
156                 .postdiv1 = 1,
157                 .postdiv2 = 1,
158                 .dsmpd = 1,
159         },
160         {
161                 .freq = 1488000000,
162                 .refdiv = 1,
163                 .fbdiv = 62,
164                 .postdiv1 = 1,
165                 .postdiv2 = 1,
166                 .dsmpd = 1,
167         },
168         {
169                 .freq = 1464000000,
170                 .refdiv = 1,
171                 .fbdiv = 61,
172                 .postdiv1 = 1,
173                 .postdiv2 = 1,
174                 .dsmpd = 1,
175         },
176         {
177                 .freq = 1440000000,
178                 .refdiv = 1,
179                 .fbdiv = 60,
180                 .postdiv1 = 1,
181                 .postdiv2 = 1,
182                 .dsmpd = 1,
183         },
184         {
185                 .freq = 1416000000,
186                 .refdiv = 1,
187                 .fbdiv = 59,
188                 .postdiv1 = 1,
189                 .postdiv2 = 1,
190                 .dsmpd = 1,
191         },
192         {
193                 .freq = 1392000000,
194                 .refdiv = 1,
195                 .fbdiv = 58,
196                 .postdiv1 = 1,
197                 .postdiv2 = 1,
198                 .dsmpd = 1,
199         },
200         {
201                 .freq = 1368000000,
202                 .refdiv = 1,
203                 .fbdiv = 57,
204                 .postdiv1 = 1,
205                 .postdiv2 = 1,
206                 .dsmpd = 1,
207         },
208         {
209                 .freq = 1344000000,
210                 .refdiv = 1,
211                 .fbdiv = 56,
212                 .postdiv1 = 1,
213                 .postdiv2 = 1,
214                 .dsmpd = 1,
215         },
216         {
217                 .freq = 1320000000,
218                 .refdiv = 1,
219                 .fbdiv = 55,
220                 .postdiv1 = 1,
221                 .postdiv2 = 1,
222                 .dsmpd = 1,
223         },
224         {
225                 .freq = 1296000000,
226                 .refdiv = 1,
227                 .fbdiv = 54,
228                 .postdiv1 = 1,
229                 .postdiv2 = 1,
230                 .dsmpd = 1,
231         },
232         {
233                 .freq = 1272000000,
234                 .refdiv = 1,
235                 .fbdiv = 53,
236                 .postdiv1 = 1,
237                 .postdiv2 = 1,
238                 .dsmpd = 1,
239         },
240         {
241                 .freq = 1248000000,
242                 .refdiv = 1,
243                 .fbdiv = 52,
244                 .postdiv1 = 1,
245                 .postdiv2 = 1,
246                 .dsmpd = 1,
247         },
248         {
249                 .freq = 1200000000,
250                 .refdiv = 1,
251                 .fbdiv = 50,
252                 .postdiv1 = 1,
253                 .postdiv2 = 1,
254                 .dsmpd = 1,
255         },
256         {
257                 .freq = 1188000000,
258                 .refdiv = 2,
259                 .fbdiv = 99,
260                 .postdiv1 = 1,
261                 .postdiv2 = 1,
262                 .dsmpd = 1,
263         },
264         {
265                 .freq = 1104000000,
266                 .refdiv = 1,
267                 .fbdiv = 46,
268                 .postdiv1 = 1,
269                 .postdiv2 = 1,
270                 .dsmpd = 1,
271         },
272         {
273                 .freq = 1100000000,
274                 .refdiv = 12,
275                 .fbdiv = 550,
276                 .postdiv1 = 1,
277                 .postdiv2 = 1,
278                 .dsmpd = 1,
279         },
280         {
281                 .freq = 1008000000,
282                 .refdiv = 1,
283                 .fbdiv = 84,
284                 .postdiv1 = 2,
285                 .postdiv2 = 1,
286                 .dsmpd = 1,
287         },
288         {
289                 .freq = 1000000000,
290                 .refdiv = 6,
291                 .fbdiv = 500,
292                 .postdiv1 = 2,
293                 .postdiv2 = 1,
294                 .dsmpd = 1,
295         },
296         {
297                 .freq = 984000000,
298                 .refdiv = 1,
299                 .fbdiv = 82,
300                 .postdiv1 = 2,
301                 .postdiv2 = 1,
302                 .dsmpd = 1,
303         },
304         {
305                 .freq = 960000000,
306                 .refdiv = 1,
307                 .fbdiv = 80,
308                 .postdiv1 = 2,
309                 .postdiv2 = 1,
310                 .dsmpd = 1,
311         },
312         {
313                 .freq = 936000000,
314                 .refdiv = 1,
315                 .fbdiv = 78,
316                 .postdiv1 = 2,
317                 .postdiv2 = 1,
318                 .dsmpd = 1,
319         },
320         {
321                 .freq = 912000000,
322                 .refdiv = 1,
323                 .fbdiv = 76,
324                 .postdiv1 = 2,
325                 .postdiv2 = 1,
326                 .dsmpd = 1,
327         },
328         {
329                 .freq = 900000000,
330                 .refdiv = 4,
331                 .fbdiv = 300,
332                 .postdiv1 = 2,
333                 .postdiv2 = 1,
334                 .dsmpd = 1,
335         },
336         {
337                 .freq = 888000000,
338                 .refdiv = 1,
339                 .fbdiv = 74,
340                 .postdiv1 = 2,
341                 .postdiv2 = 1,
342                 .dsmpd = 1,
343         },
344         {
345                 .freq = 864000000,
346                 .refdiv = 1,
347                 .fbdiv = 72,
348                 .postdiv1 = 2,
349                 .postdiv2 = 1,
350                 .dsmpd = 1,
351         },
352         {
353                 .freq = 840000000,
354                 .refdiv = 1,
355                 .fbdiv = 70,
356                 .postdiv1 = 2,
357                 .postdiv2 = 1,
358                 .dsmpd = 1,
359         },
360         {
361                 .freq = 816000000,
362                 .refdiv = 1,
363                 .fbdiv = 68,
364                 .postdiv1 = 2,
365                 .postdiv2 = 1,
366                 .dsmpd = 1,
367         },
368         {
369                 .freq = 800000000,
370                 .refdiv = 6,
371                 .fbdiv = 400,
372                 .postdiv1 = 2,
373                 .postdiv2 = 1,
374                 .dsmpd = 1,
375         },
376         {
377                 .freq = 700000000,
378                 .refdiv = 6,
379                 .fbdiv = 350,
380                 .postdiv1 = 2,
381                 .postdiv2 = 1,
382                 .dsmpd = 1,
383         },
384         {
385                 .freq = 696000000,
386                 .refdiv = 1,
387                 .fbdiv = 58,
388                 .postdiv1 = 2,
389                 .postdiv2 = 1,
390                 .dsmpd = 1,
391         },
392         {
393                 .freq = 600000000,
394                 .refdiv = 1,
395                 .fbdiv = 75,
396                 .postdiv1 = 3,
397                 .postdiv2 = 1,
398                 .dsmpd = 1,
399         },
400         {
401                 .freq = 594000000,
402                 .refdiv = 2,
403                 .fbdiv = 99,
404                 .postdiv1 = 2,
405                 .postdiv2 = 1,
406                 .dsmpd = 1,
407         },
408         {
409                 .freq = 504000000,
410                 .refdiv = 1,
411                 .fbdiv = 63,
412                 .postdiv1 = 3,
413                 .postdiv2 = 1,
414                 .dsmpd = 1,
415         },
416         {
417                 .freq = 500000000,
418                 .refdiv = 6,
419                 .fbdiv = 250,
420                 .postdiv1 = 2,
421                 .postdiv2 = 1,
422                 .dsmpd = 1,
423         },
424         {
425                 .freq = 408000000,
426                 .refdiv = 1,
427                 .fbdiv = 68,
428                 .postdiv1 = 2,
429                 .postdiv2 = 2,
430                 .dsmpd = 1,
431         },
432         {
433                 .freq = 312000000,
434                 .refdiv = 1,
435                 .fbdiv = 52,
436                 .postdiv1 = 2,
437                 .postdiv2 = 2,
438                 .dsmpd = 1,
439         },
440         {
441                 .freq = 216000000,
442                 .refdiv = 1,
443                 .fbdiv = 72,
444                 .postdiv1 = 4,
445                 .postdiv2 = 2,
446                 .dsmpd = 1,
447         },
448         {
449                 .freq = 96000000,
450                 .refdiv = 1,
451                 .fbdiv = 64,
452                 .postdiv1 = 4,
453                 .postdiv2 = 4,
454                 .dsmpd = 1,
455         },
456         {},
457 };
458
459 static struct rk_clk_pll_rate rk3328_pll_frac_rates[] = {
460         {
461                 .freq = 1016064000,
462                 .refdiv = 3,
463                 .fbdiv = 127,
464                 .postdiv1 = 1,
465                 .postdiv2 = 1,
466                 .dsmpd = 0,
467                 .frac = 134217,
468         },
469         {
470                 .freq = 983040000,
471                 .refdiv = 24,
472                 .fbdiv = 983,
473                 .postdiv1 = 1,
474                 .postdiv2 = 1,
475                 .dsmpd = 0,
476                 .frac = 671088,
477         },
478         {
479                 .freq = 491520000,
480                 .refdiv = 24,
481                 .fbdiv = 983,
482                 .postdiv1 = 2,
483                 .postdiv2 = 1,
484                 .dsmpd = 0,
485                 .frac = 671088,
486         },
487         {
488                 .freq = 61440000,
489                 .refdiv = 6,
490                 .fbdiv = 215,
491                 .postdiv1 = 7,
492                 .postdiv2 = 2,
493                 .dsmpd = 0,
494                 .frac = 671088,
495         },
496         {
497                 .freq = 56448000,
498                 .refdiv = 12,
499                 .fbdiv = 451,
500                 .postdiv1 = 4,
501                 .postdiv2 = 4,
502                 .dsmpd = 0,
503                 .frac = 9797894,
504         },
505         {
506                 .freq = 40960000,
507                 .refdiv = 12,
508                 .fbdiv = 409,
509                 .postdiv1 = 4,
510                 .postdiv2 = 5,
511                 .dsmpd = 0,
512                 .frac = 10066329,
513         },
514         {},
515 };
516
517 static const char *pll_parents[] = {"xin24m"};
518 static struct rk_clk_pll_def apll = {
519         .clkdef = {
520                 .id = PLL_APLL,
521                 .name = "apll",
522                 .parent_names = pll_parents,
523                 .parent_cnt = nitems(pll_parents),
524         },
525         .base_offset = 0x00,
526         .gate_offset = 0x200,
527         .gate_shift = 0,
528         .mode_reg = 0x80,
529         .mode_shift = 1,
530         .flags = RK_CLK_PLL_HAVE_GATE,
531         .frac_rates = rk3328_pll_frac_rates,
532 };
533
534 static struct rk_clk_pll_def dpll = {
535         .clkdef = {
536                 .id = PLL_DPLL,
537                 .name = "dpll",
538                 .parent_names = pll_parents,
539                 .parent_cnt = nitems(pll_parents),
540         },
541         .base_offset = 0x20,
542         .gate_offset = 0x200,
543         .gate_shift = 1,
544         .mode_reg = 0x80,
545         .mode_shift = 4,
546         .flags = RK_CLK_PLL_HAVE_GATE,
547 };
548
549 static struct rk_clk_pll_def cpll = {
550         .clkdef = {
551                 .id = PLL_CPLL,
552                 .name = "cpll",
553                 .parent_names = pll_parents,
554                 .parent_cnt = nitems(pll_parents),
555         },
556         .base_offset = 0x40,
557         .mode_reg = 0x80,
558         .mode_shift = 8,
559         .rates = rk3328_pll_rates,
560 };
561
562 static struct rk_clk_pll_def gpll = {
563         .clkdef = {
564                 .id = PLL_GPLL,
565                 .name = "gpll",
566                 .parent_names = pll_parents,
567                 .parent_cnt = nitems(pll_parents),
568         },
569         .base_offset = 0x60,
570         .gate_offset = 0x200,
571         .gate_shift = 2,
572         .mode_reg = 0x80,
573         .mode_shift = 12,
574         .flags = RK_CLK_PLL_HAVE_GATE,
575         .frac_rates = rk3328_pll_frac_rates,
576 };
577
578 static struct rk_clk_pll_def npll = {
579         .clkdef = {
580                 .id = PLL_NPLL,
581                 .name = "npll",
582                 .parent_names = pll_parents,
583                 .parent_cnt = nitems(pll_parents),
584         },
585         .base_offset = 0xa0,
586         .gate_offset = 0x200,
587         .gate_shift = 12,
588         .mode_reg = 0x80,
589         .mode_shift = 1,
590         .flags = RK_CLK_PLL_HAVE_GATE,
591         .rates = rk3328_pll_rates,
592 };
593
594 /* CRU_CLKSEL_CON0 */
595 #define ACLK_BUS_PRE            136
596
597 /* Needs hdmiphy as parent too*/
598 static const char *aclk_bus_pre_parents[] = {"cpll", "gpll"};
599 static struct rk_clk_composite_def aclk_bus_pre = {
600         .clkdef = {
601                 .id = ACLK_BUS_PRE,
602                 .name = "aclk_bus_pre",
603                 .parent_names = aclk_bus_pre_parents,
604                 .parent_cnt = nitems(aclk_bus_pre_parents),
605         },
606         .muxdiv_offset = 0x100,
607         .mux_shift = 13,
608         .mux_width = 2,
609
610         .div_shift = 8,
611         .div_width = 5,
612
613         .gate_offset = 0x220,
614         .gate_shift = 0,
615
616         .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE,
617 };
618
619 static struct rk_clk_armclk_rates rk3328_armclk_rates[] = {
620         {
621                 .freq = 1296000000,
622                 .div = 1,
623         },
624         {
625                 .freq = 1200000000,
626                 .div = 1,
627         },
628         {
629                 .freq = 1104000000,
630                 .div = 1,
631         },
632         {
633                 .freq = 1008000000,
634                 .div = 1,
635         },
636         {
637                 .freq = 912000000,
638                 .div = 1,
639         },
640         {
641                 .freq = 816000000,
642                 .div = 1,
643         },
644         {
645                 .freq = 696000000,
646                 .div = 1,
647         },
648         {
649                 .freq = 600000000,
650                 .div = 1,
651         },
652         {
653                 .freq = 408000000,
654                 .div = 1,
655         },
656         {
657                 .freq = 312000000,
658                 .div = 1,
659         },
660         {
661                 .freq = 216000000,
662                 .div = 1,
663         },
664         {
665                 .freq = 96000000,
666                 .div = 1,
667         },
668 };
669
670 #define ARMCLK  6
671 static const char *armclk_parents[] = {"apll", "gpll", "dpll", "npll" };
672 static struct rk_clk_armclk_def armclk = {
673         .clkdef = {
674                 .id = ARMCLK,
675                 .name = "armclk",
676                 .parent_names = armclk_parents,
677                 .parent_cnt = nitems(armclk_parents),
678         },
679         .muxdiv_offset = 0x100,
680         .mux_shift = 6,
681         .mux_width = 2,
682
683         .div_shift = 0,
684         .div_width = 5,
685
686         .flags = RK_CLK_COMPOSITE_HAVE_MUX,
687         .main_parent = 3, /* npll */
688         .alt_parent = 0, /* apll */
689
690         .rates = rk3328_armclk_rates,
691         .nrates = nitems(rk3328_armclk_rates),
692 };
693
694 /* CRU_CLKSEL_CON1 */
695
696 #define PCLK_BUS_PRE            216
697 #define HCLK_BUS_PRE            328
698
699 static const char *hclk_bus_pre_parents[] = {"aclk_bus_pre"};
700 static struct rk_clk_composite_def hclk_bus_pre = {
701         .clkdef = {
702                 .id = HCLK_BUS_PRE,
703                 .name = "hclk_bus_pre",
704                 .parent_names = hclk_bus_pre_parents,
705                 .parent_cnt = nitems(hclk_bus_pre_parents),
706         },
707         .muxdiv_offset = 0x104,
708
709         .div_shift = 8,
710         .div_width = 2,
711
712         .gate_offset = 0x220,
713         .gate_shift = 1,
714
715         .flags = RK_CLK_COMPOSITE_HAVE_GATE,
716 };
717
718 static const char *pclk_bus_pre_parents[] = {"aclk_bus_pre"};
719 static struct rk_clk_composite_def pclk_bus_pre = {
720         .clkdef = {
721                 .id = PCLK_BUS_PRE,
722                 .name = "pclk_bus_pre",
723                 .parent_names = pclk_bus_pre_parents,
724                 .parent_cnt = nitems(pclk_bus_pre_parents),
725         },
726         .muxdiv_offset = 0x104,
727
728         .div_shift = 12,
729         .div_width = 3,
730
731         .gate_offset = 0x220,
732         .gate_shift = 2,
733
734         .flags = RK_CLK_COMPOSITE_HAVE_GATE,
735 };
736
737 /* CRU_CLKSEL_CON22 */
738
739 #define SCLK_TSADC              36
740
741 static const char *clk_tsadc_parents[] = {"xin24m"};
742 static struct rk_clk_composite_def clk_tsadc = {
743         .clkdef = {
744                 .id = SCLK_TSADC,
745                 .name = "clk_tsadc",
746                 .parent_names = clk_tsadc_parents,
747                 .parent_cnt = nitems(clk_tsadc_parents),
748         },
749         .div_shift = 0,
750         .div_width = 9,
751 };
752
753 /* CRU_CLKSEL_CON28 */
754
755 #define ACLK_PERI_PRE           137
756
757 static const char *aclk_peri_pre_parents[] = {"cpll", "gpll"/* , "hdmiphy" */};
758 static struct rk_clk_composite_def aclk_peri_pre = {
759         .clkdef = {
760                 .id = ACLK_PERI_PRE,
761                 .name = "aclk_peri_pre",
762                 .parent_names = aclk_peri_pre_parents,
763                 .parent_cnt = nitems(aclk_peri_pre_parents),
764         },
765         .muxdiv_offset = 0x170,
766
767         .mux_shift = 6,
768         .mux_width = 2,
769
770         .div_shift = 0,
771         .div_width = 5,
772
773         .flags = RK_CLK_COMPOSITE_HAVE_MUX,
774 };
775
776 /* CRU_CLKSEL_CON29 */
777
778 #define PCLK_PERI               230
779 #define HCLK_PERI               308
780
781 static const char *phclk_peri_parents[] = {"aclk_peri_pre"};
782 static struct rk_clk_composite_def pclk_peri = {
783         .clkdef = {
784                 .id = PCLK_PERI,
785                 .name = "pclk_peri",
786                 .parent_names = phclk_peri_parents,
787                 .parent_cnt = nitems(phclk_peri_parents),
788         },
789
790         .div_shift = 0,
791         .div_width = 2,
792
793         /* CRU_CLKGATE_CON10 */
794         .gate_offset = 0x228,
795         .gate_shift = 2,
796
797         .flags = RK_CLK_COMPOSITE_HAVE_GATE,
798 };
799
800 static struct rk_clk_composite_def hclk_peri = {
801         .clkdef = {
802                 .id = HCLK_PERI,
803                 .name = "hclk_peri",
804                 .parent_names = phclk_peri_parents,
805                 .parent_cnt = nitems(phclk_peri_parents),
806         },
807
808         .div_shift = 4,
809         .div_width = 3,
810
811         /* CRU_CLKGATE_CON10 */
812         .gate_offset = 0x228,
813         .gate_shift = 1,
814
815         .flags = RK_CLK_COMPOSITE_HAVE_GATE,
816 };
817
818 /* CRU_CLKSEL_CON30 */
819
820 #define SCLK_SDMMC              33
821
822 static const char *mmc_parents[] = {"cpll", "gpll", "xin24m"/* , "usb480m" */};
823 static struct rk_clk_composite_def sdmmc = {
824         .clkdef = {
825                 .id = SCLK_SDMMC,
826                 .name = "clk_sdmmc",
827                 .parent_names = mmc_parents,
828                 .parent_cnt = nitems(mmc_parents),
829         },
830         .muxdiv_offset = 0x178,
831
832         .mux_shift = 8,
833         .mux_width = 2,
834
835         .div_shift = 0,
836         .div_width = 8,
837
838         /* CRU_CLKGATE_CON4 */
839         .gate_offset = 0x210,
840         .gate_shift = 3,
841
842         .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE,
843 };
844
845 /* CRU_CLKSEL_CON31 */
846 #define SCLK_SDIO               34
847
848 static struct rk_clk_composite_def sdio = {
849         .clkdef = {
850                 .id = SCLK_SDIO,
851                 .name = "clk_sdio",
852                 .parent_names = mmc_parents,
853                 .parent_cnt = nitems(mmc_parents),
854         },
855         .muxdiv_offset = 0x17C,
856
857         .mux_shift = 8,
858         .mux_width = 2,
859
860         .div_shift = 0,
861         .div_width = 8,
862
863         /* CRU_CLKGATE_CON4 */
864         .gate_offset = 0x210,
865         .gate_shift = 4,
866
867         .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE,
868 };
869
870 /* CRU_CLKSEL_CON32 */
871 #define SCLK_EMMC               35
872
873 static struct rk_clk_composite_def emmc = {
874         .clkdef = {
875                 .id = SCLK_EMMC,
876                 .name = "clk_emmc",
877                 .parent_names = mmc_parents,
878                 .parent_cnt = nitems(mmc_parents),
879         },
880         .muxdiv_offset = 0x180,
881
882         .mux_shift = 8,
883         .mux_width = 2,
884
885         .div_shift = 0,
886         .div_width = 8,
887
888         /* CRU_CLKGATE_CON4 */
889         .gate_offset = 0x210,
890         .gate_shift = 5,
891
892         .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE,
893 };
894
895 /* CRU_CLKSEL_CON34 */
896 #define SCLK_I2C0       55
897 #define SCLK_I2C1       56
898
899 static const char *i2c_parents[] = {"cpll", "gpll"};
900
901 static struct rk_clk_composite_def i2c0 = {
902         .clkdef = {
903                 .id = SCLK_I2C0,
904                 .name = "clk_i2c0",
905                 .parent_names = i2c_parents,
906                 .parent_cnt = nitems(i2c_parents),
907         },
908         .muxdiv_offset = 0x188,
909
910         .mux_shift = 7,
911         .mux_width = 1,
912
913         .div_shift = 0,
914         .div_width = 6,
915
916         /* CRU_CLKGATE_CON2 */
917         .gate_offset = 0x208,
918         .gate_shift = 9,
919
920         .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE,
921 };
922
923 static struct rk_clk_composite_def i2c1 = {
924         .clkdef = {
925                 .id = SCLK_I2C1,
926                 .name = "clk_i2c1",
927                 .parent_names = i2c_parents,
928                 .parent_cnt = nitems(i2c_parents),
929         },
930         .muxdiv_offset = 0x188,
931
932         .mux_shift = 15,
933         .mux_width = 1,
934
935         .div_shift = 8,
936         .div_width = 6,
937
938         /* CRU_CLKGATE_CON2 */
939         .gate_offset = 0x208,
940         .gate_shift = 10,
941
942         .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE,
943 };
944
945 /* CRU_CLKSEL_CON35 */
946 #define SCLK_I2C2       57
947 #define SCLK_I2C3       58
948
949 static struct rk_clk_composite_def i2c2 = {
950         .clkdef = {
951                 .id = SCLK_I2C2,
952                 .name = "clk_i2c2",
953                 .parent_names = i2c_parents,
954                 .parent_cnt = nitems(i2c_parents),
955         },
956         .muxdiv_offset = 0x18C,
957
958         .mux_shift = 7,
959         .mux_width = 1,
960
961         .div_shift = 0,
962         .div_width = 6,
963
964         /* CRU_CLKGATE_CON2 */
965         .gate_offset = 0x208,
966         .gate_shift = 11,
967
968         .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE,
969 };
970
971 static struct rk_clk_composite_def i2c3 = {
972         .clkdef = {
973                 .id = SCLK_I2C3,
974                 .name = "clk_i2c3",
975                 .parent_names = i2c_parents,
976                 .parent_cnt = nitems(i2c_parents),
977         },
978         .muxdiv_offset = 0x18C,
979
980         .mux_shift = 15,
981         .mux_width = 1,
982
983         .div_shift = 8,
984         .div_width = 6,
985
986         /* CRU_CLKGATE_CON2 */
987         .gate_offset = 0x208,
988         .gate_shift = 12,
989
990         .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE,
991 };
992
993 static struct rk_clk rk3328_clks[] = {
994         {
995                 .type = RK3328_CLK_PLL,
996                 .clk.pll = &apll
997         },
998         {
999                 .type = RK3328_CLK_PLL,
1000                 .clk.pll = &dpll
1001         },
1002         {
1003                 .type = RK3328_CLK_PLL,
1004                 .clk.pll = &cpll
1005         },
1006         {
1007                 .type = RK3328_CLK_PLL,
1008                 .clk.pll = &gpll
1009         },
1010         {
1011                 .type = RK3328_CLK_PLL,
1012                 .clk.pll = &npll
1013         },
1014
1015         {
1016                 .type = RK_CLK_COMPOSITE,
1017                 .clk.composite = &aclk_bus_pre
1018         },
1019         {
1020                 .type = RK_CLK_COMPOSITE,
1021                 .clk.composite = &hclk_bus_pre
1022         },
1023         {
1024                 .type = RK_CLK_COMPOSITE,
1025                 .clk.composite = &pclk_bus_pre
1026         },
1027
1028         {
1029                 .type = RK_CLK_ARMCLK,
1030                 .clk.armclk = &armclk,
1031         },
1032
1033         {
1034                 .type = RK_CLK_COMPOSITE,
1035                 .clk.composite = &clk_tsadc,
1036         },
1037         {
1038                 .type = RK_CLK_COMPOSITE,
1039                 .clk.composite = &aclk_peri_pre,
1040         },
1041         {
1042                 .type = RK_CLK_COMPOSITE,
1043                 .clk.composite = &pclk_peri,
1044         },
1045         {
1046                 .type = RK_CLK_COMPOSITE,
1047                 .clk.composite = &hclk_peri,
1048         },
1049         {
1050                 .type = RK_CLK_COMPOSITE,
1051                 .clk.composite = &sdmmc
1052         },
1053         {
1054                 .type = RK_CLK_COMPOSITE,
1055                 .clk.composite = &sdio
1056         },
1057         {
1058                 .type = RK_CLK_COMPOSITE,
1059                 .clk.composite = &emmc
1060         },
1061
1062         {
1063                 .type = RK_CLK_COMPOSITE,
1064                 .clk.composite = &i2c0
1065         },
1066         {
1067                 .type = RK_CLK_COMPOSITE,
1068                 .clk.composite = &i2c1
1069         },
1070         {
1071                 .type = RK_CLK_COMPOSITE,
1072                 .clk.composite = &i2c2
1073         },
1074         {
1075                 .type = RK_CLK_COMPOSITE,
1076                 .clk.composite = &i2c3
1077         },
1078 };
1079
1080 static int
1081 rk3328_cru_probe(device_t dev)
1082 {
1083
1084         if (!ofw_bus_status_okay(dev))
1085                 return (ENXIO);
1086
1087         if (ofw_bus_is_compatible(dev, "rockchip,rk3328-cru")) {
1088                 device_set_desc(dev, "Rockchip RK3328 Clock and Reset Unit");
1089                 return (BUS_PROBE_DEFAULT);
1090         }
1091
1092         return (ENXIO);
1093 }
1094
1095 static int
1096 rk3328_cru_attach(device_t dev)
1097 {
1098         struct rk_cru_softc *sc;
1099
1100         sc = device_get_softc(dev);
1101         sc->dev = dev;
1102
1103         sc->gates = rk3328_gates;
1104         sc->ngates = nitems(rk3328_gates);
1105
1106         sc->clks = rk3328_clks;
1107         sc->nclks = nitems(rk3328_clks);
1108
1109         sc->reset_offset = 0x300;
1110         sc->reset_num = 184;
1111
1112         return (rk_cru_attach(dev));
1113 }
1114
1115 static device_method_t rk3328_cru_methods[] = {
1116         /* Device interface */
1117         DEVMETHOD(device_probe,         rk3328_cru_probe),
1118         DEVMETHOD(device_attach,        rk3328_cru_attach),
1119
1120         DEVMETHOD_END
1121 };
1122
1123 static devclass_t rk3328_cru_devclass;
1124
1125 DEFINE_CLASS_1(rk3328_cru, rk3328_cru_driver, rk3328_cru_methods,
1126   sizeof(struct rk_cru_softc), rk_cru_driver);
1127
1128 EARLY_DRIVER_MODULE(rk3328_cru, simplebus, rk3328_cru_driver,
1129     rk3328_cru_devclass, 0, 0, BUS_PASS_BUS + BUS_PASS_ORDER_MIDDLE);