1 // SPDX-License-Identifier: GPL-2.0+
3 * AmLogic Meson-AXG Clock Controller Driver
5 * Copyright (c) 2016 Baylibre SAS.
6 * Author: Michael Turquette <mturquette@baylibre.com>
8 * Copyright (c) 2017 Amlogic, inc.
9 * Author: Qiufang Dai <qiufang.dai@amlogic.com>
12 #include <linux/clk.h>
13 #include <linux/clk-provider.h>
14 #include <linux/init.h>
15 #include <linux/of_address.h>
16 #include <linux/of_device.h>
17 #include <linux/mfd/syscon.h>
18 #include <linux/platform_device.h>
19 #include <linux/regmap.h>
24 static DEFINE_SPINLOCK(meson_clk_lock
);
26 static struct clk_regmap axg_fixed_pll
= {
27 .data
= &(struct meson_clk_pll_data
){
29 .reg_off
= HHI_MPLL_CNTL
,
34 .reg_off
= HHI_MPLL_CNTL
,
39 .reg_off
= HHI_MPLL_CNTL
,
44 .reg_off
= HHI_MPLL_CNTL2
,
49 .reg_off
= HHI_MPLL_CNTL
,
54 .reg_off
= HHI_MPLL_CNTL
,
59 .hw
.init
= &(struct clk_init_data
){
61 .ops
= &meson_clk_pll_ro_ops
,
62 .parent_names
= (const char *[]){ "xtal" },
67 static struct clk_regmap axg_sys_pll
= {
68 .data
= &(struct meson_clk_pll_data
){
70 .reg_off
= HHI_SYS_PLL_CNTL
,
75 .reg_off
= HHI_SYS_PLL_CNTL
,
80 .reg_off
= HHI_SYS_PLL_CNTL
,
85 .reg_off
= HHI_SYS_PLL_CNTL
,
90 .reg_off
= HHI_SYS_PLL_CNTL
,
95 .hw
.init
= &(struct clk_init_data
){
97 .ops
= &meson_clk_pll_ro_ops
,
98 .parent_names
= (const char *[]){ "xtal" },
100 .flags
= CLK_GET_RATE_NOCACHE
,
104 static const struct pll_rate_table axg_gp0_pll_rate_table
[] = {
105 PLL_RATE(240000000, 40, 1, 2),
106 PLL_RATE(246000000, 41, 1, 2),
107 PLL_RATE(252000000, 42, 1, 2),
108 PLL_RATE(258000000, 43, 1, 2),
109 PLL_RATE(264000000, 44, 1, 2),
110 PLL_RATE(270000000, 45, 1, 2),
111 PLL_RATE(276000000, 46, 1, 2),
112 PLL_RATE(282000000, 47, 1, 2),
113 PLL_RATE(288000000, 48, 1, 2),
114 PLL_RATE(294000000, 49, 1, 2),
115 PLL_RATE(300000000, 50, 1, 2),
116 PLL_RATE(306000000, 51, 1, 2),
117 PLL_RATE(312000000, 52, 1, 2),
118 PLL_RATE(318000000, 53, 1, 2),
119 PLL_RATE(324000000, 54, 1, 2),
120 PLL_RATE(330000000, 55, 1, 2),
121 PLL_RATE(336000000, 56, 1, 2),
122 PLL_RATE(342000000, 57, 1, 2),
123 PLL_RATE(348000000, 58, 1, 2),
124 PLL_RATE(354000000, 59, 1, 2),
125 PLL_RATE(360000000, 60, 1, 2),
126 PLL_RATE(366000000, 61, 1, 2),
127 PLL_RATE(372000000, 62, 1, 2),
128 PLL_RATE(378000000, 63, 1, 2),
129 PLL_RATE(384000000, 64, 1, 2),
130 PLL_RATE(390000000, 65, 1, 3),
131 PLL_RATE(396000000, 66, 1, 3),
132 PLL_RATE(402000000, 67, 1, 3),
133 PLL_RATE(408000000, 68, 1, 3),
134 PLL_RATE(480000000, 40, 1, 1),
135 PLL_RATE(492000000, 41, 1, 1),
136 PLL_RATE(504000000, 42, 1, 1),
137 PLL_RATE(516000000, 43, 1, 1),
138 PLL_RATE(528000000, 44, 1, 1),
139 PLL_RATE(540000000, 45, 1, 1),
140 PLL_RATE(552000000, 46, 1, 1),
141 PLL_RATE(564000000, 47, 1, 1),
142 PLL_RATE(576000000, 48, 1, 1),
143 PLL_RATE(588000000, 49, 1, 1),
144 PLL_RATE(600000000, 50, 1, 1),
145 PLL_RATE(612000000, 51, 1, 1),
146 PLL_RATE(624000000, 52, 1, 1),
147 PLL_RATE(636000000, 53, 1, 1),
148 PLL_RATE(648000000, 54, 1, 1),
149 PLL_RATE(660000000, 55, 1, 1),
150 PLL_RATE(672000000, 56, 1, 1),
151 PLL_RATE(684000000, 57, 1, 1),
152 PLL_RATE(696000000, 58, 1, 1),
153 PLL_RATE(708000000, 59, 1, 1),
154 PLL_RATE(720000000, 60, 1, 1),
155 PLL_RATE(732000000, 61, 1, 1),
156 PLL_RATE(744000000, 62, 1, 1),
157 PLL_RATE(756000000, 63, 1, 1),
158 PLL_RATE(768000000, 64, 1, 1),
159 PLL_RATE(780000000, 65, 1, 1),
160 PLL_RATE(792000000, 66, 1, 1),
161 PLL_RATE(804000000, 67, 1, 1),
162 PLL_RATE(816000000, 68, 1, 1),
163 PLL_RATE(960000000, 40, 1, 0),
164 PLL_RATE(984000000, 41, 1, 0),
165 PLL_RATE(1008000000, 42, 1, 0),
166 PLL_RATE(1032000000, 43, 1, 0),
167 PLL_RATE(1056000000, 44, 1, 0),
168 PLL_RATE(1080000000, 45, 1, 0),
169 PLL_RATE(1104000000, 46, 1, 0),
170 PLL_RATE(1128000000, 47, 1, 0),
171 PLL_RATE(1152000000, 48, 1, 0),
172 PLL_RATE(1176000000, 49, 1, 0),
173 PLL_RATE(1200000000, 50, 1, 0),
174 PLL_RATE(1224000000, 51, 1, 0),
175 PLL_RATE(1248000000, 52, 1, 0),
176 PLL_RATE(1272000000, 53, 1, 0),
177 PLL_RATE(1296000000, 54, 1, 0),
178 PLL_RATE(1320000000, 55, 1, 0),
179 PLL_RATE(1344000000, 56, 1, 0),
180 PLL_RATE(1368000000, 57, 1, 0),
181 PLL_RATE(1392000000, 58, 1, 0),
182 PLL_RATE(1416000000, 59, 1, 0),
183 PLL_RATE(1440000000, 60, 1, 0),
184 PLL_RATE(1464000000, 61, 1, 0),
185 PLL_RATE(1488000000, 62, 1, 0),
186 PLL_RATE(1512000000, 63, 1, 0),
187 PLL_RATE(1536000000, 64, 1, 0),
188 PLL_RATE(1560000000, 65, 1, 0),
189 PLL_RATE(1584000000, 66, 1, 0),
190 PLL_RATE(1608000000, 67, 1, 0),
191 PLL_RATE(1632000000, 68, 1, 0),
195 static const struct reg_sequence axg_gp0_init_regs
[] = {
196 { .reg
= HHI_GP0_PLL_CNTL1
, .def
= 0xc084b000 },
197 { .reg
= HHI_GP0_PLL_CNTL2
, .def
= 0xb75020be },
198 { .reg
= HHI_GP0_PLL_CNTL3
, .def
= 0x0a59a288 },
199 { .reg
= HHI_GP0_PLL_CNTL4
, .def
= 0xc000004d },
200 { .reg
= HHI_GP0_PLL_CNTL5
, .def
= 0x00078000 },
201 { .reg
= HHI_GP0_PLL_CNTL
, .def
= 0x40010250 },
204 static struct clk_regmap axg_gp0_pll
= {
205 .data
= &(struct meson_clk_pll_data
){
207 .reg_off
= HHI_GP0_PLL_CNTL
,
212 .reg_off
= HHI_GP0_PLL_CNTL
,
217 .reg_off
= HHI_GP0_PLL_CNTL
,
222 .reg_off
= HHI_GP0_PLL_CNTL1
,
227 .reg_off
= HHI_GP0_PLL_CNTL
,
232 .reg_off
= HHI_GP0_PLL_CNTL
,
236 .table
= axg_gp0_pll_rate_table
,
237 .init_regs
= axg_gp0_init_regs
,
238 .init_count
= ARRAY_SIZE(axg_gp0_init_regs
),
240 .hw
.init
= &(struct clk_init_data
){
242 .ops
= &meson_clk_pll_ops
,
243 .parent_names
= (const char *[]){ "xtal" },
248 static const struct reg_sequence axg_hifi_init_regs
[] = {
249 { .reg
= HHI_HIFI_PLL_CNTL1
, .def
= 0xc084b000 },
250 { .reg
= HHI_HIFI_PLL_CNTL2
, .def
= 0xb75020be },
251 { .reg
= HHI_HIFI_PLL_CNTL3
, .def
= 0x0a6a3a88 },
252 { .reg
= HHI_HIFI_PLL_CNTL4
, .def
= 0xc000004d },
253 { .reg
= HHI_HIFI_PLL_CNTL5
, .def
= 0x00058000 },
254 { .reg
= HHI_HIFI_PLL_CNTL
, .def
= 0x40010250 },
257 static struct clk_regmap axg_hifi_pll
= {
258 .data
= &(struct meson_clk_pll_data
){
260 .reg_off
= HHI_HIFI_PLL_CNTL
,
265 .reg_off
= HHI_HIFI_PLL_CNTL
,
270 .reg_off
= HHI_HIFI_PLL_CNTL
,
275 .reg_off
= HHI_HIFI_PLL_CNTL5
,
280 .reg_off
= HHI_HIFI_PLL_CNTL
,
285 .reg_off
= HHI_HIFI_PLL_CNTL
,
289 .table
= axg_gp0_pll_rate_table
,
290 .init_regs
= axg_hifi_init_regs
,
291 .init_count
= ARRAY_SIZE(axg_hifi_init_regs
),
292 .flags
= CLK_MESON_PLL_ROUND_CLOSEST
,
294 .hw
.init
= &(struct clk_init_data
){
296 .ops
= &meson_clk_pll_ops
,
297 .parent_names
= (const char *[]){ "xtal" },
302 static struct clk_fixed_factor axg_fclk_div2_div
= {
305 .hw
.init
= &(struct clk_init_data
){
306 .name
= "fclk_div2_div",
307 .ops
= &clk_fixed_factor_ops
,
308 .parent_names
= (const char *[]){ "fixed_pll" },
313 static struct clk_regmap axg_fclk_div2
= {
314 .data
= &(struct clk_regmap_gate_data
){
315 .offset
= HHI_MPLL_CNTL6
,
318 .hw
.init
= &(struct clk_init_data
){
320 .ops
= &clk_regmap_gate_ops
,
321 .parent_names
= (const char *[]){ "fclk_div2_div" },
326 static struct clk_fixed_factor axg_fclk_div3_div
= {
329 .hw
.init
= &(struct clk_init_data
){
330 .name
= "fclk_div3_div",
331 .ops
= &clk_fixed_factor_ops
,
332 .parent_names
= (const char *[]){ "fixed_pll" },
337 static struct clk_regmap axg_fclk_div3
= {
338 .data
= &(struct clk_regmap_gate_data
){
339 .offset
= HHI_MPLL_CNTL6
,
342 .hw
.init
= &(struct clk_init_data
){
344 .ops
= &clk_regmap_gate_ops
,
345 .parent_names
= (const char *[]){ "fclk_div3_div" },
350 static struct clk_fixed_factor axg_fclk_div4_div
= {
353 .hw
.init
= &(struct clk_init_data
){
354 .name
= "fclk_div4_div",
355 .ops
= &clk_fixed_factor_ops
,
356 .parent_names
= (const char *[]){ "fixed_pll" },
361 static struct clk_regmap axg_fclk_div4
= {
362 .data
= &(struct clk_regmap_gate_data
){
363 .offset
= HHI_MPLL_CNTL6
,
366 .hw
.init
= &(struct clk_init_data
){
368 .ops
= &clk_regmap_gate_ops
,
369 .parent_names
= (const char *[]){ "fclk_div4_div" },
374 static struct clk_fixed_factor axg_fclk_div5_div
= {
377 .hw
.init
= &(struct clk_init_data
){
378 .name
= "fclk_div5_div",
379 .ops
= &clk_fixed_factor_ops
,
380 .parent_names
= (const char *[]){ "fixed_pll" },
385 static struct clk_regmap axg_fclk_div5
= {
386 .data
= &(struct clk_regmap_gate_data
){
387 .offset
= HHI_MPLL_CNTL6
,
390 .hw
.init
= &(struct clk_init_data
){
392 .ops
= &clk_regmap_gate_ops
,
393 .parent_names
= (const char *[]){ "fclk_div5_div" },
398 static struct clk_fixed_factor axg_fclk_div7_div
= {
401 .hw
.init
= &(struct clk_init_data
){
402 .name
= "fclk_div7_div",
403 .ops
= &clk_fixed_factor_ops
,
404 .parent_names
= (const char *[]){ "fixed_pll" },
409 static struct clk_regmap axg_fclk_div7
= {
410 .data
= &(struct clk_regmap_gate_data
){
411 .offset
= HHI_MPLL_CNTL6
,
414 .hw
.init
= &(struct clk_init_data
){
416 .ops
= &clk_regmap_gate_ops
,
417 .parent_names
= (const char *[]){ "fclk_div7_div" },
422 static struct clk_regmap axg_mpll_prediv
= {
423 .data
= &(struct clk_regmap_div_data
){
424 .offset
= HHI_MPLL_CNTL5
,
428 .hw
.init
= &(struct clk_init_data
){
429 .name
= "mpll_prediv",
430 .ops
= &clk_regmap_divider_ro_ops
,
431 .parent_names
= (const char *[]){ "fixed_pll" },
436 static struct clk_regmap axg_mpll0_div
= {
437 .data
= &(struct meson_clk_mpll_data
){
439 .reg_off
= HHI_MPLL_CNTL7
,
444 .reg_off
= HHI_MPLL_CNTL7
,
449 .reg_off
= HHI_MPLL_CNTL7
,
454 .reg_off
= HHI_MPLL_CNTL
,
459 .reg_off
= HHI_PLL_TOP_MISC
,
463 .lock
= &meson_clk_lock
,
464 .flags
= CLK_MESON_MPLL_ROUND_CLOSEST
,
466 .hw
.init
= &(struct clk_init_data
){
468 .ops
= &meson_clk_mpll_ops
,
469 .parent_names
= (const char *[]){ "mpll_prediv" },
474 static struct clk_regmap axg_mpll0
= {
475 .data
= &(struct clk_regmap_gate_data
){
476 .offset
= HHI_MPLL_CNTL7
,
479 .hw
.init
= &(struct clk_init_data
){
481 .ops
= &clk_regmap_gate_ops
,
482 .parent_names
= (const char *[]){ "mpll0_div" },
484 .flags
= CLK_SET_RATE_PARENT
,
488 static struct clk_regmap axg_mpll1_div
= {
489 .data
= &(struct meson_clk_mpll_data
){
491 .reg_off
= HHI_MPLL_CNTL8
,
496 .reg_off
= HHI_MPLL_CNTL8
,
501 .reg_off
= HHI_MPLL_CNTL8
,
506 .reg_off
= HHI_PLL_TOP_MISC
,
510 .lock
= &meson_clk_lock
,
511 .flags
= CLK_MESON_MPLL_ROUND_CLOSEST
,
513 .hw
.init
= &(struct clk_init_data
){
515 .ops
= &meson_clk_mpll_ops
,
516 .parent_names
= (const char *[]){ "mpll_prediv" },
521 static struct clk_regmap axg_mpll1
= {
522 .data
= &(struct clk_regmap_gate_data
){
523 .offset
= HHI_MPLL_CNTL8
,
526 .hw
.init
= &(struct clk_init_data
){
528 .ops
= &clk_regmap_gate_ops
,
529 .parent_names
= (const char *[]){ "mpll1_div" },
531 .flags
= CLK_SET_RATE_PARENT
,
535 static struct clk_regmap axg_mpll2_div
= {
536 .data
= &(struct meson_clk_mpll_data
){
538 .reg_off
= HHI_MPLL_CNTL9
,
543 .reg_off
= HHI_MPLL_CNTL9
,
548 .reg_off
= HHI_MPLL_CNTL9
,
553 .reg_off
= HHI_PLL_TOP_MISC
,
557 .lock
= &meson_clk_lock
,
558 .flags
= CLK_MESON_MPLL_ROUND_CLOSEST
,
560 .hw
.init
= &(struct clk_init_data
){
562 .ops
= &meson_clk_mpll_ops
,
563 .parent_names
= (const char *[]){ "mpll_prediv" },
568 static struct clk_regmap axg_mpll2
= {
569 .data
= &(struct clk_regmap_gate_data
){
570 .offset
= HHI_MPLL_CNTL9
,
573 .hw
.init
= &(struct clk_init_data
){
575 .ops
= &clk_regmap_gate_ops
,
576 .parent_names
= (const char *[]){ "mpll2_div" },
578 .flags
= CLK_SET_RATE_PARENT
,
582 static struct clk_regmap axg_mpll3_div
= {
583 .data
= &(struct meson_clk_mpll_data
){
585 .reg_off
= HHI_MPLL3_CNTL0
,
590 .reg_off
= HHI_MPLL3_CNTL0
,
595 .reg_off
= HHI_MPLL3_CNTL0
,
600 .reg_off
= HHI_PLL_TOP_MISC
,
604 .lock
= &meson_clk_lock
,
605 .flags
= CLK_MESON_MPLL_ROUND_CLOSEST
,
607 .hw
.init
= &(struct clk_init_data
){
609 .ops
= &meson_clk_mpll_ops
,
610 .parent_names
= (const char *[]){ "mpll_prediv" },
615 static struct clk_regmap axg_mpll3
= {
616 .data
= &(struct clk_regmap_gate_data
){
617 .offset
= HHI_MPLL3_CNTL0
,
620 .hw
.init
= &(struct clk_init_data
){
622 .ops
= &clk_regmap_gate_ops
,
623 .parent_names
= (const char *[]){ "mpll3_div" },
625 .flags
= CLK_SET_RATE_PARENT
,
629 static u32 mux_table_clk81
[] = { 0, 2, 3, 4, 5, 6, 7 };
630 static const char * const clk81_parent_names
[] = {
631 "xtal", "fclk_div7", "mpll1", "mpll2", "fclk_div4",
632 "fclk_div3", "fclk_div5"
635 static struct clk_regmap axg_mpeg_clk_sel
= {
636 .data
= &(struct clk_regmap_mux_data
){
637 .offset
= HHI_MPEG_CLK_CNTL
,
640 .table
= mux_table_clk81
,
642 .hw
.init
= &(struct clk_init_data
){
643 .name
= "mpeg_clk_sel",
644 .ops
= &clk_regmap_mux_ro_ops
,
645 .parent_names
= clk81_parent_names
,
646 .num_parents
= ARRAY_SIZE(clk81_parent_names
),
650 static struct clk_regmap axg_mpeg_clk_div
= {
651 .data
= &(struct clk_regmap_div_data
){
652 .offset
= HHI_MPEG_CLK_CNTL
,
656 .hw
.init
= &(struct clk_init_data
){
657 .name
= "mpeg_clk_div",
658 .ops
= &clk_regmap_divider_ops
,
659 .parent_names
= (const char *[]){ "mpeg_clk_sel" },
661 .flags
= CLK_SET_RATE_PARENT
,
665 static struct clk_regmap axg_clk81
= {
666 .data
= &(struct clk_regmap_gate_data
){
667 .offset
= HHI_MPEG_CLK_CNTL
,
670 .hw
.init
= &(struct clk_init_data
){
672 .ops
= &clk_regmap_gate_ops
,
673 .parent_names
= (const char *[]){ "mpeg_clk_div" },
675 .flags
= (CLK_SET_RATE_PARENT
| CLK_IS_CRITICAL
),
679 static const char * const axg_sd_emmc_clk0_parent_names
[] = {
680 "xtal", "fclk_div2", "fclk_div3", "fclk_div5", "fclk_div7",
683 * Following these parent clocks, we should also have had mpll2, mpll3
684 * and gp0_pll but these clocks are too precious to be used here. All
685 * the necessary rates for MMC and NAND operation can be acheived using
686 * xtal or fclk_div clocks
691 static struct clk_regmap axg_sd_emmc_b_clk0_sel
= {
692 .data
= &(struct clk_regmap_mux_data
){
693 .offset
= HHI_SD_EMMC_CLK_CNTL
,
697 .hw
.init
= &(struct clk_init_data
) {
698 .name
= "sd_emmc_b_clk0_sel",
699 .ops
= &clk_regmap_mux_ops
,
700 .parent_names
= axg_sd_emmc_clk0_parent_names
,
701 .num_parents
= ARRAY_SIZE(axg_sd_emmc_clk0_parent_names
),
702 .flags
= CLK_SET_RATE_PARENT
,
706 static struct clk_regmap axg_sd_emmc_b_clk0_div
= {
707 .data
= &(struct clk_regmap_div_data
){
708 .offset
= HHI_SD_EMMC_CLK_CNTL
,
711 .flags
= CLK_DIVIDER_ROUND_CLOSEST
,
713 .hw
.init
= &(struct clk_init_data
) {
714 .name
= "sd_emmc_b_clk0_div",
715 .ops
= &clk_regmap_divider_ops
,
716 .parent_names
= (const char *[]){ "sd_emmc_b_clk0_sel" },
718 .flags
= CLK_SET_RATE_PARENT
,
722 static struct clk_regmap axg_sd_emmc_b_clk0
= {
723 .data
= &(struct clk_regmap_gate_data
){
724 .offset
= HHI_SD_EMMC_CLK_CNTL
,
727 .hw
.init
= &(struct clk_init_data
){
728 .name
= "sd_emmc_b_clk0",
729 .ops
= &clk_regmap_gate_ops
,
730 .parent_names
= (const char *[]){ "sd_emmc_b_clk0_div" },
732 .flags
= CLK_SET_RATE_PARENT
,
736 /* EMMC/NAND clock */
737 static struct clk_regmap axg_sd_emmc_c_clk0_sel
= {
738 .data
= &(struct clk_regmap_mux_data
){
739 .offset
= HHI_NAND_CLK_CNTL
,
743 .hw
.init
= &(struct clk_init_data
) {
744 .name
= "sd_emmc_c_clk0_sel",
745 .ops
= &clk_regmap_mux_ops
,
746 .parent_names
= axg_sd_emmc_clk0_parent_names
,
747 .num_parents
= ARRAY_SIZE(axg_sd_emmc_clk0_parent_names
),
748 .flags
= CLK_SET_RATE_PARENT
,
752 static struct clk_regmap axg_sd_emmc_c_clk0_div
= {
753 .data
= &(struct clk_regmap_div_data
){
754 .offset
= HHI_NAND_CLK_CNTL
,
757 .flags
= CLK_DIVIDER_ROUND_CLOSEST
,
759 .hw
.init
= &(struct clk_init_data
) {
760 .name
= "sd_emmc_c_clk0_div",
761 .ops
= &clk_regmap_divider_ops
,
762 .parent_names
= (const char *[]){ "sd_emmc_c_clk0_sel" },
764 .flags
= CLK_SET_RATE_PARENT
,
768 static struct clk_regmap axg_sd_emmc_c_clk0
= {
769 .data
= &(struct clk_regmap_gate_data
){
770 .offset
= HHI_NAND_CLK_CNTL
,
773 .hw
.init
= &(struct clk_init_data
){
774 .name
= "sd_emmc_c_clk0",
775 .ops
= &clk_regmap_gate_ops
,
776 .parent_names
= (const char *[]){ "sd_emmc_c_clk0_div" },
778 .flags
= CLK_SET_RATE_PARENT
,
782 /* Everything Else (EE) domain gates */
783 static MESON_GATE(axg_ddr
, HHI_GCLK_MPEG0
, 0);
784 static MESON_GATE(axg_audio_locker
, HHI_GCLK_MPEG0
, 2);
785 static MESON_GATE(axg_mipi_dsi_host
, HHI_GCLK_MPEG0
, 3);
786 static MESON_GATE(axg_isa
, HHI_GCLK_MPEG0
, 5);
787 static MESON_GATE(axg_pl301
, HHI_GCLK_MPEG0
, 6);
788 static MESON_GATE(axg_periphs
, HHI_GCLK_MPEG0
, 7);
789 static MESON_GATE(axg_spicc_0
, HHI_GCLK_MPEG0
, 8);
790 static MESON_GATE(axg_i2c
, HHI_GCLK_MPEG0
, 9);
791 static MESON_GATE(axg_rng0
, HHI_GCLK_MPEG0
, 12);
792 static MESON_GATE(axg_uart0
, HHI_GCLK_MPEG0
, 13);
793 static MESON_GATE(axg_mipi_dsi_phy
, HHI_GCLK_MPEG0
, 14);
794 static MESON_GATE(axg_spicc_1
, HHI_GCLK_MPEG0
, 15);
795 static MESON_GATE(axg_pcie_a
, HHI_GCLK_MPEG0
, 16);
796 static MESON_GATE(axg_pcie_b
, HHI_GCLK_MPEG0
, 17);
797 static MESON_GATE(axg_hiu_reg
, HHI_GCLK_MPEG0
, 19);
798 static MESON_GATE(axg_assist_misc
, HHI_GCLK_MPEG0
, 23);
799 static MESON_GATE(axg_emmc_b
, HHI_GCLK_MPEG0
, 25);
800 static MESON_GATE(axg_emmc_c
, HHI_GCLK_MPEG0
, 26);
801 static MESON_GATE(axg_dma
, HHI_GCLK_MPEG0
, 27);
802 static MESON_GATE(axg_spi
, HHI_GCLK_MPEG0
, 30);
804 static MESON_GATE(axg_audio
, HHI_GCLK_MPEG1
, 0);
805 static MESON_GATE(axg_eth_core
, HHI_GCLK_MPEG1
, 3);
806 static MESON_GATE(axg_uart1
, HHI_GCLK_MPEG1
, 16);
807 static MESON_GATE(axg_g2d
, HHI_GCLK_MPEG1
, 20);
808 static MESON_GATE(axg_usb0
, HHI_GCLK_MPEG1
, 21);
809 static MESON_GATE(axg_usb1
, HHI_GCLK_MPEG1
, 22);
810 static MESON_GATE(axg_reset
, HHI_GCLK_MPEG1
, 23);
811 static MESON_GATE(axg_usb_general
, HHI_GCLK_MPEG1
, 26);
812 static MESON_GATE(axg_ahb_arb0
, HHI_GCLK_MPEG1
, 29);
813 static MESON_GATE(axg_efuse
, HHI_GCLK_MPEG1
, 30);
814 static MESON_GATE(axg_boot_rom
, HHI_GCLK_MPEG1
, 31);
816 static MESON_GATE(axg_ahb_data_bus
, HHI_GCLK_MPEG2
, 1);
817 static MESON_GATE(axg_ahb_ctrl_bus
, HHI_GCLK_MPEG2
, 2);
818 static MESON_GATE(axg_usb1_to_ddr
, HHI_GCLK_MPEG2
, 8);
819 static MESON_GATE(axg_usb0_to_ddr
, HHI_GCLK_MPEG2
, 9);
820 static MESON_GATE(axg_mmc_pclk
, HHI_GCLK_MPEG2
, 11);
821 static MESON_GATE(axg_vpu_intr
, HHI_GCLK_MPEG2
, 25);
822 static MESON_GATE(axg_sec_ahb_ahb3_bridge
, HHI_GCLK_MPEG2
, 26);
823 static MESON_GATE(axg_gic
, HHI_GCLK_MPEG2
, 30);
825 /* Always On (AO) domain gates */
827 static MESON_GATE(axg_ao_media_cpu
, HHI_GCLK_AO
, 0);
828 static MESON_GATE(axg_ao_ahb_sram
, HHI_GCLK_AO
, 1);
829 static MESON_GATE(axg_ao_ahb_bus
, HHI_GCLK_AO
, 2);
830 static MESON_GATE(axg_ao_iface
, HHI_GCLK_AO
, 3);
831 static MESON_GATE(axg_ao_i2c
, HHI_GCLK_AO
, 4);
833 /* Array of all clocks provided by this provider */
835 static struct clk_hw_onecell_data axg_hw_onecell_data
= {
837 [CLKID_SYS_PLL
] = &axg_sys_pll
.hw
,
838 [CLKID_FIXED_PLL
] = &axg_fixed_pll
.hw
,
839 [CLKID_FCLK_DIV2
] = &axg_fclk_div2
.hw
,
840 [CLKID_FCLK_DIV3
] = &axg_fclk_div3
.hw
,
841 [CLKID_FCLK_DIV4
] = &axg_fclk_div4
.hw
,
842 [CLKID_FCLK_DIV5
] = &axg_fclk_div5
.hw
,
843 [CLKID_FCLK_DIV7
] = &axg_fclk_div7
.hw
,
844 [CLKID_GP0_PLL
] = &axg_gp0_pll
.hw
,
845 [CLKID_MPEG_SEL
] = &axg_mpeg_clk_sel
.hw
,
846 [CLKID_MPEG_DIV
] = &axg_mpeg_clk_div
.hw
,
847 [CLKID_CLK81
] = &axg_clk81
.hw
,
848 [CLKID_MPLL0
] = &axg_mpll0
.hw
,
849 [CLKID_MPLL1
] = &axg_mpll1
.hw
,
850 [CLKID_MPLL2
] = &axg_mpll2
.hw
,
851 [CLKID_MPLL3
] = &axg_mpll3
.hw
,
852 [CLKID_DDR
] = &axg_ddr
.hw
,
853 [CLKID_AUDIO_LOCKER
] = &axg_audio_locker
.hw
,
854 [CLKID_MIPI_DSI_HOST
] = &axg_mipi_dsi_host
.hw
,
855 [CLKID_ISA
] = &axg_isa
.hw
,
856 [CLKID_PL301
] = &axg_pl301
.hw
,
857 [CLKID_PERIPHS
] = &axg_periphs
.hw
,
858 [CLKID_SPICC0
] = &axg_spicc_0
.hw
,
859 [CLKID_I2C
] = &axg_i2c
.hw
,
860 [CLKID_RNG0
] = &axg_rng0
.hw
,
861 [CLKID_UART0
] = &axg_uart0
.hw
,
862 [CLKID_MIPI_DSI_PHY
] = &axg_mipi_dsi_phy
.hw
,
863 [CLKID_SPICC1
] = &axg_spicc_1
.hw
,
864 [CLKID_PCIE_A
] = &axg_pcie_a
.hw
,
865 [CLKID_PCIE_B
] = &axg_pcie_b
.hw
,
866 [CLKID_HIU_IFACE
] = &axg_hiu_reg
.hw
,
867 [CLKID_ASSIST_MISC
] = &axg_assist_misc
.hw
,
868 [CLKID_SD_EMMC_B
] = &axg_emmc_b
.hw
,
869 [CLKID_SD_EMMC_C
] = &axg_emmc_c
.hw
,
870 [CLKID_DMA
] = &axg_dma
.hw
,
871 [CLKID_SPI
] = &axg_spi
.hw
,
872 [CLKID_AUDIO
] = &axg_audio
.hw
,
873 [CLKID_ETH
] = &axg_eth_core
.hw
,
874 [CLKID_UART1
] = &axg_uart1
.hw
,
875 [CLKID_G2D
] = &axg_g2d
.hw
,
876 [CLKID_USB0
] = &axg_usb0
.hw
,
877 [CLKID_USB1
] = &axg_usb1
.hw
,
878 [CLKID_RESET
] = &axg_reset
.hw
,
879 [CLKID_USB
] = &axg_usb_general
.hw
,
880 [CLKID_AHB_ARB0
] = &axg_ahb_arb0
.hw
,
881 [CLKID_EFUSE
] = &axg_efuse
.hw
,
882 [CLKID_BOOT_ROM
] = &axg_boot_rom
.hw
,
883 [CLKID_AHB_DATA_BUS
] = &axg_ahb_data_bus
.hw
,
884 [CLKID_AHB_CTRL_BUS
] = &axg_ahb_ctrl_bus
.hw
,
885 [CLKID_USB1_DDR_BRIDGE
] = &axg_usb1_to_ddr
.hw
,
886 [CLKID_USB0_DDR_BRIDGE
] = &axg_usb0_to_ddr
.hw
,
887 [CLKID_MMC_PCLK
] = &axg_mmc_pclk
.hw
,
888 [CLKID_VPU_INTR
] = &axg_vpu_intr
.hw
,
889 [CLKID_SEC_AHB_AHB3_BRIDGE
] = &axg_sec_ahb_ahb3_bridge
.hw
,
890 [CLKID_GIC
] = &axg_gic
.hw
,
891 [CLKID_AO_MEDIA_CPU
] = &axg_ao_media_cpu
.hw
,
892 [CLKID_AO_AHB_SRAM
] = &axg_ao_ahb_sram
.hw
,
893 [CLKID_AO_AHB_BUS
] = &axg_ao_ahb_bus
.hw
,
894 [CLKID_AO_IFACE
] = &axg_ao_iface
.hw
,
895 [CLKID_AO_I2C
] = &axg_ao_i2c
.hw
,
896 [CLKID_SD_EMMC_B_CLK0_SEL
] = &axg_sd_emmc_b_clk0_sel
.hw
,
897 [CLKID_SD_EMMC_B_CLK0_DIV
] = &axg_sd_emmc_b_clk0_div
.hw
,
898 [CLKID_SD_EMMC_B_CLK0
] = &axg_sd_emmc_b_clk0
.hw
,
899 [CLKID_SD_EMMC_C_CLK0_SEL
] = &axg_sd_emmc_c_clk0_sel
.hw
,
900 [CLKID_SD_EMMC_C_CLK0_DIV
] = &axg_sd_emmc_c_clk0_div
.hw
,
901 [CLKID_SD_EMMC_C_CLK0
] = &axg_sd_emmc_c_clk0
.hw
,
902 [CLKID_MPLL0_DIV
] = &axg_mpll0_div
.hw
,
903 [CLKID_MPLL1_DIV
] = &axg_mpll1_div
.hw
,
904 [CLKID_MPLL2_DIV
] = &axg_mpll2_div
.hw
,
905 [CLKID_MPLL3_DIV
] = &axg_mpll3_div
.hw
,
906 [CLKID_HIFI_PLL
] = &axg_hifi_pll
.hw
,
907 [CLKID_MPLL_PREDIV
] = &axg_mpll_prediv
.hw
,
908 [CLKID_FCLK_DIV2_DIV
] = &axg_fclk_div2_div
.hw
,
909 [CLKID_FCLK_DIV3_DIV
] = &axg_fclk_div3_div
.hw
,
910 [CLKID_FCLK_DIV4_DIV
] = &axg_fclk_div4_div
.hw
,
911 [CLKID_FCLK_DIV5_DIV
] = &axg_fclk_div5_div
.hw
,
912 [CLKID_FCLK_DIV7_DIV
] = &axg_fclk_div7_div
.hw
,
918 /* Convenience table to populate regmap in .probe */
919 static struct clk_regmap
*const axg_clk_regmaps
[] = {
958 &axg_sec_ahb_ahb3_bridge
,
968 &axg_sd_emmc_b_clk0_div
,
969 &axg_sd_emmc_c_clk0_div
,
971 &axg_sd_emmc_b_clk0_sel
,
972 &axg_sd_emmc_c_clk0_sel
,
993 static const struct of_device_id clkc_match_table
[] = {
994 { .compatible
= "amlogic,axg-clkc" },
998 static const struct regmap_config clkc_regmap_config
= {
1004 static int axg_clkc_probe(struct platform_device
*pdev
)
1006 struct device
*dev
= &pdev
->dev
;
1007 struct resource
*res
;
1008 void __iomem
*clk_base
= NULL
;
1012 /* Get the hhi system controller node if available */
1013 map
= syscon_node_to_regmap(of_get_parent(dev
->of_node
));
1016 "failed to get HHI regmap - Trying obsolete regs\n");
1019 * FIXME: HHI registers should be accessed through
1020 * the appropriate system controller. This is required because
1021 * there is more than just clocks in this register space
1023 * This fallback method is only provided temporarily until
1024 * all the platform DTs are properly using the syscon node
1026 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
1031 clk_base
= devm_ioremap(dev
, res
->start
, resource_size(res
));
1033 dev_err(dev
, "Unable to map clk base\n");
1037 map
= devm_regmap_init_mmio(dev
, clk_base
,
1038 &clkc_regmap_config
);
1040 return PTR_ERR(map
);
1043 /* Populate regmap for the regmap backed clocks */
1044 for (i
= 0; i
< ARRAY_SIZE(axg_clk_regmaps
); i
++)
1045 axg_clk_regmaps
[i
]->map
= map
;
1047 for (i
= 0; i
< axg_hw_onecell_data
.num
; i
++) {
1048 /* array might be sparse */
1049 if (!axg_hw_onecell_data
.hws
[i
])
1052 ret
= devm_clk_hw_register(dev
, axg_hw_onecell_data
.hws
[i
]);
1054 dev_err(dev
, "Clock registration failed\n");
1059 return devm_of_clk_add_hw_provider(dev
, of_clk_hw_onecell_get
,
1060 &axg_hw_onecell_data
);
1063 static struct platform_driver axg_driver
= {
1064 .probe
= axg_clkc_probe
,
1067 .of_match_table
= clkc_match_table
,
1071 builtin_platform_driver(axg_driver
);