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_device.h>
16 #include <linux/mfd/syscon.h>
17 #include <linux/platform_device.h>
18 #include <linux/regmap.h>
23 static DEFINE_SPINLOCK(meson_clk_lock
);
25 static struct clk_regmap axg_fixed_pll
= {
26 .data
= &(struct meson_clk_pll_data
){
28 .reg_off
= HHI_MPLL_CNTL
,
33 .reg_off
= HHI_MPLL_CNTL
,
38 .reg_off
= HHI_MPLL_CNTL
,
43 .reg_off
= HHI_MPLL_CNTL2
,
48 .reg_off
= HHI_MPLL_CNTL
,
53 .reg_off
= HHI_MPLL_CNTL
,
58 .hw
.init
= &(struct clk_init_data
){
60 .ops
= &meson_clk_pll_ro_ops
,
61 .parent_names
= (const char *[]){ "xtal" },
66 static struct clk_regmap axg_sys_pll
= {
67 .data
= &(struct meson_clk_pll_data
){
69 .reg_off
= HHI_SYS_PLL_CNTL
,
74 .reg_off
= HHI_SYS_PLL_CNTL
,
79 .reg_off
= HHI_SYS_PLL_CNTL
,
84 .reg_off
= HHI_SYS_PLL_CNTL
,
89 .reg_off
= HHI_SYS_PLL_CNTL
,
94 .hw
.init
= &(struct clk_init_data
){
96 .ops
= &meson_clk_pll_ro_ops
,
97 .parent_names
= (const char *[]){ "xtal" },
99 .flags
= CLK_GET_RATE_NOCACHE
,
103 static const struct pll_rate_table axg_gp0_pll_rate_table
[] = {
104 PLL_RATE(240000000, 40, 1, 2),
105 PLL_RATE(246000000, 41, 1, 2),
106 PLL_RATE(252000000, 42, 1, 2),
107 PLL_RATE(258000000, 43, 1, 2),
108 PLL_RATE(264000000, 44, 1, 2),
109 PLL_RATE(270000000, 45, 1, 2),
110 PLL_RATE(276000000, 46, 1, 2),
111 PLL_RATE(282000000, 47, 1, 2),
112 PLL_RATE(288000000, 48, 1, 2),
113 PLL_RATE(294000000, 49, 1, 2),
114 PLL_RATE(300000000, 50, 1, 2),
115 PLL_RATE(306000000, 51, 1, 2),
116 PLL_RATE(312000000, 52, 1, 2),
117 PLL_RATE(318000000, 53, 1, 2),
118 PLL_RATE(324000000, 54, 1, 2),
119 PLL_RATE(330000000, 55, 1, 2),
120 PLL_RATE(336000000, 56, 1, 2),
121 PLL_RATE(342000000, 57, 1, 2),
122 PLL_RATE(348000000, 58, 1, 2),
123 PLL_RATE(354000000, 59, 1, 2),
124 PLL_RATE(360000000, 60, 1, 2),
125 PLL_RATE(366000000, 61, 1, 2),
126 PLL_RATE(372000000, 62, 1, 2),
127 PLL_RATE(378000000, 63, 1, 2),
128 PLL_RATE(384000000, 64, 1, 2),
129 PLL_RATE(390000000, 65, 1, 3),
130 PLL_RATE(396000000, 66, 1, 3),
131 PLL_RATE(402000000, 67, 1, 3),
132 PLL_RATE(408000000, 68, 1, 3),
133 PLL_RATE(480000000, 40, 1, 1),
134 PLL_RATE(492000000, 41, 1, 1),
135 PLL_RATE(504000000, 42, 1, 1),
136 PLL_RATE(516000000, 43, 1, 1),
137 PLL_RATE(528000000, 44, 1, 1),
138 PLL_RATE(540000000, 45, 1, 1),
139 PLL_RATE(552000000, 46, 1, 1),
140 PLL_RATE(564000000, 47, 1, 1),
141 PLL_RATE(576000000, 48, 1, 1),
142 PLL_RATE(588000000, 49, 1, 1),
143 PLL_RATE(600000000, 50, 1, 1),
144 PLL_RATE(612000000, 51, 1, 1),
145 PLL_RATE(624000000, 52, 1, 1),
146 PLL_RATE(636000000, 53, 1, 1),
147 PLL_RATE(648000000, 54, 1, 1),
148 PLL_RATE(660000000, 55, 1, 1),
149 PLL_RATE(672000000, 56, 1, 1),
150 PLL_RATE(684000000, 57, 1, 1),
151 PLL_RATE(696000000, 58, 1, 1),
152 PLL_RATE(708000000, 59, 1, 1),
153 PLL_RATE(720000000, 60, 1, 1),
154 PLL_RATE(732000000, 61, 1, 1),
155 PLL_RATE(744000000, 62, 1, 1),
156 PLL_RATE(756000000, 63, 1, 1),
157 PLL_RATE(768000000, 64, 1, 1),
158 PLL_RATE(780000000, 65, 1, 1),
159 PLL_RATE(792000000, 66, 1, 1),
160 PLL_RATE(804000000, 67, 1, 1),
161 PLL_RATE(816000000, 68, 1, 1),
162 PLL_RATE(960000000, 40, 1, 0),
163 PLL_RATE(984000000, 41, 1, 0),
164 PLL_RATE(1008000000, 42, 1, 0),
165 PLL_RATE(1032000000, 43, 1, 0),
166 PLL_RATE(1056000000, 44, 1, 0),
167 PLL_RATE(1080000000, 45, 1, 0),
168 PLL_RATE(1104000000, 46, 1, 0),
169 PLL_RATE(1128000000, 47, 1, 0),
170 PLL_RATE(1152000000, 48, 1, 0),
171 PLL_RATE(1176000000, 49, 1, 0),
172 PLL_RATE(1200000000, 50, 1, 0),
173 PLL_RATE(1224000000, 51, 1, 0),
174 PLL_RATE(1248000000, 52, 1, 0),
175 PLL_RATE(1272000000, 53, 1, 0),
176 PLL_RATE(1296000000, 54, 1, 0),
177 PLL_RATE(1320000000, 55, 1, 0),
178 PLL_RATE(1344000000, 56, 1, 0),
179 PLL_RATE(1368000000, 57, 1, 0),
180 PLL_RATE(1392000000, 58, 1, 0),
181 PLL_RATE(1416000000, 59, 1, 0),
182 PLL_RATE(1440000000, 60, 1, 0),
183 PLL_RATE(1464000000, 61, 1, 0),
184 PLL_RATE(1488000000, 62, 1, 0),
185 PLL_RATE(1512000000, 63, 1, 0),
186 PLL_RATE(1536000000, 64, 1, 0),
187 PLL_RATE(1560000000, 65, 1, 0),
188 PLL_RATE(1584000000, 66, 1, 0),
189 PLL_RATE(1608000000, 67, 1, 0),
190 PLL_RATE(1632000000, 68, 1, 0),
194 static const struct reg_sequence axg_gp0_init_regs
[] = {
195 { .reg
= HHI_GP0_PLL_CNTL1
, .def
= 0xc084b000 },
196 { .reg
= HHI_GP0_PLL_CNTL2
, .def
= 0xb75020be },
197 { .reg
= HHI_GP0_PLL_CNTL3
, .def
= 0x0a59a288 },
198 { .reg
= HHI_GP0_PLL_CNTL4
, .def
= 0xc000004d },
199 { .reg
= HHI_GP0_PLL_CNTL5
, .def
= 0x00078000 },
200 { .reg
= HHI_GP0_PLL_CNTL
, .def
= 0x40010250 },
203 static struct clk_regmap axg_gp0_pll
= {
204 .data
= &(struct meson_clk_pll_data
){
206 .reg_off
= HHI_GP0_PLL_CNTL
,
211 .reg_off
= HHI_GP0_PLL_CNTL
,
216 .reg_off
= HHI_GP0_PLL_CNTL
,
221 .reg_off
= HHI_GP0_PLL_CNTL1
,
226 .reg_off
= HHI_GP0_PLL_CNTL
,
231 .reg_off
= HHI_GP0_PLL_CNTL
,
235 .table
= axg_gp0_pll_rate_table
,
236 .init_regs
= axg_gp0_init_regs
,
237 .init_count
= ARRAY_SIZE(axg_gp0_init_regs
),
239 .hw
.init
= &(struct clk_init_data
){
241 .ops
= &meson_clk_pll_ops
,
242 .parent_names
= (const char *[]){ "xtal" },
247 static const struct reg_sequence axg_hifi_init_regs
[] = {
248 { .reg
= HHI_HIFI_PLL_CNTL1
, .def
= 0xc084b000 },
249 { .reg
= HHI_HIFI_PLL_CNTL2
, .def
= 0xb75020be },
250 { .reg
= HHI_HIFI_PLL_CNTL3
, .def
= 0x0a6a3a88 },
251 { .reg
= HHI_HIFI_PLL_CNTL4
, .def
= 0xc000004d },
252 { .reg
= HHI_HIFI_PLL_CNTL5
, .def
= 0x00058000 },
253 { .reg
= HHI_HIFI_PLL_CNTL
, .def
= 0x40010250 },
256 static struct clk_regmap axg_hifi_pll
= {
257 .data
= &(struct meson_clk_pll_data
){
259 .reg_off
= HHI_HIFI_PLL_CNTL
,
264 .reg_off
= HHI_HIFI_PLL_CNTL
,
269 .reg_off
= HHI_HIFI_PLL_CNTL
,
274 .reg_off
= HHI_HIFI_PLL_CNTL5
,
279 .reg_off
= HHI_HIFI_PLL_CNTL
,
284 .reg_off
= HHI_HIFI_PLL_CNTL
,
288 .table
= axg_gp0_pll_rate_table
,
289 .init_regs
= axg_hifi_init_regs
,
290 .init_count
= ARRAY_SIZE(axg_hifi_init_regs
),
291 .flags
= CLK_MESON_PLL_ROUND_CLOSEST
,
293 .hw
.init
= &(struct clk_init_data
){
295 .ops
= &meson_clk_pll_ops
,
296 .parent_names
= (const char *[]){ "xtal" },
301 static struct clk_fixed_factor axg_fclk_div2_div
= {
304 .hw
.init
= &(struct clk_init_data
){
305 .name
= "fclk_div2_div",
306 .ops
= &clk_fixed_factor_ops
,
307 .parent_names
= (const char *[]){ "fixed_pll" },
312 static struct clk_regmap axg_fclk_div2
= {
313 .data
= &(struct clk_regmap_gate_data
){
314 .offset
= HHI_MPLL_CNTL6
,
317 .hw
.init
= &(struct clk_init_data
){
319 .ops
= &clk_regmap_gate_ops
,
320 .parent_names
= (const char *[]){ "fclk_div2_div" },
325 static struct clk_fixed_factor axg_fclk_div3_div
= {
328 .hw
.init
= &(struct clk_init_data
){
329 .name
= "fclk_div3_div",
330 .ops
= &clk_fixed_factor_ops
,
331 .parent_names
= (const char *[]){ "fixed_pll" },
336 static struct clk_regmap axg_fclk_div3
= {
337 .data
= &(struct clk_regmap_gate_data
){
338 .offset
= HHI_MPLL_CNTL6
,
341 .hw
.init
= &(struct clk_init_data
){
343 .ops
= &clk_regmap_gate_ops
,
344 .parent_names
= (const char *[]){ "fclk_div3_div" },
349 static struct clk_fixed_factor axg_fclk_div4_div
= {
352 .hw
.init
= &(struct clk_init_data
){
353 .name
= "fclk_div4_div",
354 .ops
= &clk_fixed_factor_ops
,
355 .parent_names
= (const char *[]){ "fixed_pll" },
360 static struct clk_regmap axg_fclk_div4
= {
361 .data
= &(struct clk_regmap_gate_data
){
362 .offset
= HHI_MPLL_CNTL6
,
365 .hw
.init
= &(struct clk_init_data
){
367 .ops
= &clk_regmap_gate_ops
,
368 .parent_names
= (const char *[]){ "fclk_div4_div" },
373 static struct clk_fixed_factor axg_fclk_div5_div
= {
376 .hw
.init
= &(struct clk_init_data
){
377 .name
= "fclk_div5_div",
378 .ops
= &clk_fixed_factor_ops
,
379 .parent_names
= (const char *[]){ "fixed_pll" },
384 static struct clk_regmap axg_fclk_div5
= {
385 .data
= &(struct clk_regmap_gate_data
){
386 .offset
= HHI_MPLL_CNTL6
,
389 .hw
.init
= &(struct clk_init_data
){
391 .ops
= &clk_regmap_gate_ops
,
392 .parent_names
= (const char *[]){ "fclk_div5_div" },
397 static struct clk_fixed_factor axg_fclk_div7_div
= {
400 .hw
.init
= &(struct clk_init_data
){
401 .name
= "fclk_div7_div",
402 .ops
= &clk_fixed_factor_ops
,
403 .parent_names
= (const char *[]){ "fixed_pll" },
408 static struct clk_regmap axg_fclk_div7
= {
409 .data
= &(struct clk_regmap_gate_data
){
410 .offset
= HHI_MPLL_CNTL6
,
413 .hw
.init
= &(struct clk_init_data
){
415 .ops
= &clk_regmap_gate_ops
,
416 .parent_names
= (const char *[]){ "fclk_div7_div" },
421 static struct clk_regmap axg_mpll_prediv
= {
422 .data
= &(struct clk_regmap_div_data
){
423 .offset
= HHI_MPLL_CNTL5
,
427 .hw
.init
= &(struct clk_init_data
){
428 .name
= "mpll_prediv",
429 .ops
= &clk_regmap_divider_ro_ops
,
430 .parent_names
= (const char *[]){ "fixed_pll" },
435 static struct clk_regmap axg_mpll0_div
= {
436 .data
= &(struct meson_clk_mpll_data
){
438 .reg_off
= HHI_MPLL_CNTL7
,
443 .reg_off
= HHI_MPLL_CNTL7
,
448 .reg_off
= HHI_MPLL_CNTL7
,
453 .reg_off
= HHI_MPLL_CNTL
,
458 .reg_off
= HHI_PLL_TOP_MISC
,
462 .lock
= &meson_clk_lock
,
463 .flags
= CLK_MESON_MPLL_ROUND_CLOSEST
,
465 .hw
.init
= &(struct clk_init_data
){
467 .ops
= &meson_clk_mpll_ops
,
468 .parent_names
= (const char *[]){ "mpll_prediv" },
473 static struct clk_regmap axg_mpll0
= {
474 .data
= &(struct clk_regmap_gate_data
){
475 .offset
= HHI_MPLL_CNTL7
,
478 .hw
.init
= &(struct clk_init_data
){
480 .ops
= &clk_regmap_gate_ops
,
481 .parent_names
= (const char *[]){ "mpll0_div" },
483 .flags
= CLK_SET_RATE_PARENT
,
487 static struct clk_regmap axg_mpll1_div
= {
488 .data
= &(struct meson_clk_mpll_data
){
490 .reg_off
= HHI_MPLL_CNTL8
,
495 .reg_off
= HHI_MPLL_CNTL8
,
500 .reg_off
= HHI_MPLL_CNTL8
,
505 .reg_off
= HHI_PLL_TOP_MISC
,
509 .lock
= &meson_clk_lock
,
510 .flags
= CLK_MESON_MPLL_ROUND_CLOSEST
,
512 .hw
.init
= &(struct clk_init_data
){
514 .ops
= &meson_clk_mpll_ops
,
515 .parent_names
= (const char *[]){ "mpll_prediv" },
520 static struct clk_regmap axg_mpll1
= {
521 .data
= &(struct clk_regmap_gate_data
){
522 .offset
= HHI_MPLL_CNTL8
,
525 .hw
.init
= &(struct clk_init_data
){
527 .ops
= &clk_regmap_gate_ops
,
528 .parent_names
= (const char *[]){ "mpll1_div" },
530 .flags
= CLK_SET_RATE_PARENT
,
534 static struct clk_regmap axg_mpll2_div
= {
535 .data
= &(struct meson_clk_mpll_data
){
537 .reg_off
= HHI_MPLL_CNTL9
,
542 .reg_off
= HHI_MPLL_CNTL9
,
547 .reg_off
= HHI_MPLL_CNTL9
,
552 .reg_off
= HHI_PLL_TOP_MISC
,
556 .lock
= &meson_clk_lock
,
557 .flags
= CLK_MESON_MPLL_ROUND_CLOSEST
,
559 .hw
.init
= &(struct clk_init_data
){
561 .ops
= &meson_clk_mpll_ops
,
562 .parent_names
= (const char *[]){ "mpll_prediv" },
567 static struct clk_regmap axg_mpll2
= {
568 .data
= &(struct clk_regmap_gate_data
){
569 .offset
= HHI_MPLL_CNTL9
,
572 .hw
.init
= &(struct clk_init_data
){
574 .ops
= &clk_regmap_gate_ops
,
575 .parent_names
= (const char *[]){ "mpll2_div" },
577 .flags
= CLK_SET_RATE_PARENT
,
581 static struct clk_regmap axg_mpll3_div
= {
582 .data
= &(struct meson_clk_mpll_data
){
584 .reg_off
= HHI_MPLL3_CNTL0
,
589 .reg_off
= HHI_MPLL3_CNTL0
,
594 .reg_off
= HHI_MPLL3_CNTL0
,
599 .reg_off
= HHI_PLL_TOP_MISC
,
603 .lock
= &meson_clk_lock
,
604 .flags
= CLK_MESON_MPLL_ROUND_CLOSEST
,
606 .hw
.init
= &(struct clk_init_data
){
608 .ops
= &meson_clk_mpll_ops
,
609 .parent_names
= (const char *[]){ "mpll_prediv" },
614 static struct clk_regmap axg_mpll3
= {
615 .data
= &(struct clk_regmap_gate_data
){
616 .offset
= HHI_MPLL3_CNTL0
,
619 .hw
.init
= &(struct clk_init_data
){
621 .ops
= &clk_regmap_gate_ops
,
622 .parent_names
= (const char *[]){ "mpll3_div" },
624 .flags
= CLK_SET_RATE_PARENT
,
628 static const struct pll_rate_table axg_pcie_pll_rate_table
[] = {
639 static const struct reg_sequence axg_pcie_init_regs
[] = {
640 { .reg
= HHI_PCIE_PLL_CNTL
, .def
= 0x400106c8 },
641 { .reg
= HHI_PCIE_PLL_CNTL1
, .def
= 0x0084a2aa },
642 { .reg
= HHI_PCIE_PLL_CNTL2
, .def
= 0xb75020be },
643 { .reg
= HHI_PCIE_PLL_CNTL3
, .def
= 0x0a47488e },
644 { .reg
= HHI_PCIE_PLL_CNTL4
, .def
= 0xc000004d },
645 { .reg
= HHI_PCIE_PLL_CNTL5
, .def
= 0x00078000 },
646 { .reg
= HHI_PCIE_PLL_CNTL6
, .def
= 0x002323c6 },
649 static struct clk_regmap axg_pcie_pll
= {
650 .data
= &(struct meson_clk_pll_data
){
652 .reg_off
= HHI_PCIE_PLL_CNTL
,
657 .reg_off
= HHI_PCIE_PLL_CNTL
,
662 .reg_off
= HHI_PCIE_PLL_CNTL
,
667 .reg_off
= HHI_PCIE_PLL_CNTL6
,
672 .reg_off
= HHI_PCIE_PLL_CNTL1
,
677 .reg_off
= HHI_PCIE_PLL_CNTL
,
682 .reg_off
= HHI_PCIE_PLL_CNTL
,
686 .table
= axg_pcie_pll_rate_table
,
687 .init_regs
= axg_pcie_init_regs
,
688 .init_count
= ARRAY_SIZE(axg_pcie_init_regs
),
690 .hw
.init
= &(struct clk_init_data
){
692 .ops
= &meson_clk_pll_ops
,
693 .parent_names
= (const char *[]){ "xtal" },
698 static struct clk_regmap axg_pcie_mux
= {
699 .data
= &(struct clk_regmap_mux_data
){
700 .offset
= HHI_PCIE_PLL_CNTL6
,
704 .hw
.init
= &(struct clk_init_data
){
706 .ops
= &clk_regmap_mux_ops
,
707 .parent_names
= (const char *[]){ "mpll3", "pcie_pll" },
709 .flags
= CLK_SET_RATE_PARENT
,
713 static struct clk_regmap axg_pcie_ref
= {
714 .data
= &(struct clk_regmap_mux_data
){
715 .offset
= HHI_PCIE_PLL_CNTL6
,
718 /* skip the parent 0, reserved for debug */
719 .table
= (u32
[]){ 1 },
721 .hw
.init
= &(struct clk_init_data
){
723 .ops
= &clk_regmap_mux_ops
,
724 .parent_names
= (const char *[]){ "pcie_mux" },
726 .flags
= CLK_SET_RATE_PARENT
,
730 static struct clk_regmap axg_pcie_cml_en0
= {
731 .data
= &(struct clk_regmap_gate_data
){
732 .offset
= HHI_PCIE_PLL_CNTL6
,
735 .hw
.init
= &(struct clk_init_data
) {
736 .name
= "pcie_cml_en0",
737 .ops
= &clk_regmap_gate_ops
,
738 .parent_names
= (const char *[]){ "pcie_ref" },
740 .flags
= CLK_SET_RATE_PARENT
,
745 static struct clk_regmap axg_pcie_cml_en1
= {
746 .data
= &(struct clk_regmap_gate_data
){
747 .offset
= HHI_PCIE_PLL_CNTL6
,
750 .hw
.init
= &(struct clk_init_data
) {
751 .name
= "pcie_cml_en1",
752 .ops
= &clk_regmap_gate_ops
,
753 .parent_names
= (const char *[]){ "pcie_ref" },
755 .flags
= CLK_SET_RATE_PARENT
,
759 static u32 mux_table_clk81
[] = { 0, 2, 3, 4, 5, 6, 7 };
760 static const char * const clk81_parent_names
[] = {
761 "xtal", "fclk_div7", "mpll1", "mpll2", "fclk_div4",
762 "fclk_div3", "fclk_div5"
765 static struct clk_regmap axg_mpeg_clk_sel
= {
766 .data
= &(struct clk_regmap_mux_data
){
767 .offset
= HHI_MPEG_CLK_CNTL
,
770 .table
= mux_table_clk81
,
772 .hw
.init
= &(struct clk_init_data
){
773 .name
= "mpeg_clk_sel",
774 .ops
= &clk_regmap_mux_ro_ops
,
775 .parent_names
= clk81_parent_names
,
776 .num_parents
= ARRAY_SIZE(clk81_parent_names
),
780 static struct clk_regmap axg_mpeg_clk_div
= {
781 .data
= &(struct clk_regmap_div_data
){
782 .offset
= HHI_MPEG_CLK_CNTL
,
786 .hw
.init
= &(struct clk_init_data
){
787 .name
= "mpeg_clk_div",
788 .ops
= &clk_regmap_divider_ops
,
789 .parent_names
= (const char *[]){ "mpeg_clk_sel" },
791 .flags
= CLK_SET_RATE_PARENT
,
795 static struct clk_regmap axg_clk81
= {
796 .data
= &(struct clk_regmap_gate_data
){
797 .offset
= HHI_MPEG_CLK_CNTL
,
800 .hw
.init
= &(struct clk_init_data
){
802 .ops
= &clk_regmap_gate_ops
,
803 .parent_names
= (const char *[]){ "mpeg_clk_div" },
805 .flags
= (CLK_SET_RATE_PARENT
| CLK_IS_CRITICAL
),
809 static const char * const axg_sd_emmc_clk0_parent_names
[] = {
810 "xtal", "fclk_div2", "fclk_div3", "fclk_div5", "fclk_div7",
813 * Following these parent clocks, we should also have had mpll2, mpll3
814 * and gp0_pll but these clocks are too precious to be used here. All
815 * the necessary rates for MMC and NAND operation can be acheived using
816 * xtal or fclk_div clocks
821 static struct clk_regmap axg_sd_emmc_b_clk0_sel
= {
822 .data
= &(struct clk_regmap_mux_data
){
823 .offset
= HHI_SD_EMMC_CLK_CNTL
,
827 .hw
.init
= &(struct clk_init_data
) {
828 .name
= "sd_emmc_b_clk0_sel",
829 .ops
= &clk_regmap_mux_ops
,
830 .parent_names
= axg_sd_emmc_clk0_parent_names
,
831 .num_parents
= ARRAY_SIZE(axg_sd_emmc_clk0_parent_names
),
832 .flags
= CLK_SET_RATE_PARENT
,
836 static struct clk_regmap axg_sd_emmc_b_clk0_div
= {
837 .data
= &(struct clk_regmap_div_data
){
838 .offset
= HHI_SD_EMMC_CLK_CNTL
,
841 .flags
= CLK_DIVIDER_ROUND_CLOSEST
,
843 .hw
.init
= &(struct clk_init_data
) {
844 .name
= "sd_emmc_b_clk0_div",
845 .ops
= &clk_regmap_divider_ops
,
846 .parent_names
= (const char *[]){ "sd_emmc_b_clk0_sel" },
848 .flags
= CLK_SET_RATE_PARENT
,
852 static struct clk_regmap axg_sd_emmc_b_clk0
= {
853 .data
= &(struct clk_regmap_gate_data
){
854 .offset
= HHI_SD_EMMC_CLK_CNTL
,
857 .hw
.init
= &(struct clk_init_data
){
858 .name
= "sd_emmc_b_clk0",
859 .ops
= &clk_regmap_gate_ops
,
860 .parent_names
= (const char *[]){ "sd_emmc_b_clk0_div" },
862 .flags
= CLK_SET_RATE_PARENT
,
866 /* EMMC/NAND clock */
867 static struct clk_regmap axg_sd_emmc_c_clk0_sel
= {
868 .data
= &(struct clk_regmap_mux_data
){
869 .offset
= HHI_NAND_CLK_CNTL
,
873 .hw
.init
= &(struct clk_init_data
) {
874 .name
= "sd_emmc_c_clk0_sel",
875 .ops
= &clk_regmap_mux_ops
,
876 .parent_names
= axg_sd_emmc_clk0_parent_names
,
877 .num_parents
= ARRAY_SIZE(axg_sd_emmc_clk0_parent_names
),
878 .flags
= CLK_SET_RATE_PARENT
,
882 static struct clk_regmap axg_sd_emmc_c_clk0_div
= {
883 .data
= &(struct clk_regmap_div_data
){
884 .offset
= HHI_NAND_CLK_CNTL
,
887 .flags
= CLK_DIVIDER_ROUND_CLOSEST
,
889 .hw
.init
= &(struct clk_init_data
) {
890 .name
= "sd_emmc_c_clk0_div",
891 .ops
= &clk_regmap_divider_ops
,
892 .parent_names
= (const char *[]){ "sd_emmc_c_clk0_sel" },
894 .flags
= CLK_SET_RATE_PARENT
,
898 static struct clk_regmap axg_sd_emmc_c_clk0
= {
899 .data
= &(struct clk_regmap_gate_data
){
900 .offset
= HHI_NAND_CLK_CNTL
,
903 .hw
.init
= &(struct clk_init_data
){
904 .name
= "sd_emmc_c_clk0",
905 .ops
= &clk_regmap_gate_ops
,
906 .parent_names
= (const char *[]){ "sd_emmc_c_clk0_div" },
908 .flags
= CLK_SET_RATE_PARENT
,
912 static u32 mux_table_gen_clk
[] = { 0, 4, 5, 6, 7, 8,
913 9, 10, 11, 13, 14, };
914 static const char * const gen_clk_parent_names
[] = {
915 "xtal", "hifi_pll", "mpll0", "mpll1", "mpll2", "mpll3",
916 "fclk_div4", "fclk_div3", "fclk_div5", "fclk_div7", "gp0_pll",
919 static struct clk_regmap axg_gen_clk_sel
= {
920 .data
= &(struct clk_regmap_mux_data
){
921 .offset
= HHI_GEN_CLK_CNTL
,
924 .table
= mux_table_gen_clk
,
926 .hw
.init
= &(struct clk_init_data
){
927 .name
= "gen_clk_sel",
928 .ops
= &clk_regmap_mux_ops
,
930 * bits 15:12 selects from 14 possible parents:
931 * xtal, [rtc_oscin_i], [sys_cpu_div16], [ddr_dpll_pt],
932 * hifi_pll, mpll0, mpll1, mpll2, mpll3, fdiv4,
933 * fdiv3, fdiv5, [cts_msr_clk], fdiv7, gp0_pll
935 .parent_names
= gen_clk_parent_names
,
936 .num_parents
= ARRAY_SIZE(gen_clk_parent_names
),
940 static struct clk_regmap axg_gen_clk_div
= {
941 .data
= &(struct clk_regmap_div_data
){
942 .offset
= HHI_GEN_CLK_CNTL
,
946 .hw
.init
= &(struct clk_init_data
){
947 .name
= "gen_clk_div",
948 .ops
= &clk_regmap_divider_ops
,
949 .parent_names
= (const char *[]){ "gen_clk_sel" },
951 .flags
= CLK_SET_RATE_PARENT
,
955 static struct clk_regmap axg_gen_clk
= {
956 .data
= &(struct clk_regmap_gate_data
){
957 .offset
= HHI_GEN_CLK_CNTL
,
960 .hw
.init
= &(struct clk_init_data
){
962 .ops
= &clk_regmap_gate_ops
,
963 .parent_names
= (const char *[]){ "gen_clk_div" },
965 .flags
= CLK_SET_RATE_PARENT
,
969 /* Everything Else (EE) domain gates */
970 static MESON_GATE(axg_ddr
, HHI_GCLK_MPEG0
, 0);
971 static MESON_GATE(axg_audio_locker
, HHI_GCLK_MPEG0
, 2);
972 static MESON_GATE(axg_mipi_dsi_host
, HHI_GCLK_MPEG0
, 3);
973 static MESON_GATE(axg_isa
, HHI_GCLK_MPEG0
, 5);
974 static MESON_GATE(axg_pl301
, HHI_GCLK_MPEG0
, 6);
975 static MESON_GATE(axg_periphs
, HHI_GCLK_MPEG0
, 7);
976 static MESON_GATE(axg_spicc_0
, HHI_GCLK_MPEG0
, 8);
977 static MESON_GATE(axg_i2c
, HHI_GCLK_MPEG0
, 9);
978 static MESON_GATE(axg_rng0
, HHI_GCLK_MPEG0
, 12);
979 static MESON_GATE(axg_uart0
, HHI_GCLK_MPEG0
, 13);
980 static MESON_GATE(axg_mipi_dsi_phy
, HHI_GCLK_MPEG0
, 14);
981 static MESON_GATE(axg_spicc_1
, HHI_GCLK_MPEG0
, 15);
982 static MESON_GATE(axg_pcie_a
, HHI_GCLK_MPEG0
, 16);
983 static MESON_GATE(axg_pcie_b
, HHI_GCLK_MPEG0
, 17);
984 static MESON_GATE(axg_hiu_reg
, HHI_GCLK_MPEG0
, 19);
985 static MESON_GATE(axg_assist_misc
, HHI_GCLK_MPEG0
, 23);
986 static MESON_GATE(axg_emmc_b
, HHI_GCLK_MPEG0
, 25);
987 static MESON_GATE(axg_emmc_c
, HHI_GCLK_MPEG0
, 26);
988 static MESON_GATE(axg_dma
, HHI_GCLK_MPEG0
, 27);
989 static MESON_GATE(axg_spi
, HHI_GCLK_MPEG0
, 30);
991 static MESON_GATE(axg_audio
, HHI_GCLK_MPEG1
, 0);
992 static MESON_GATE(axg_eth_core
, HHI_GCLK_MPEG1
, 3);
993 static MESON_GATE(axg_uart1
, HHI_GCLK_MPEG1
, 16);
994 static MESON_GATE(axg_g2d
, HHI_GCLK_MPEG1
, 20);
995 static MESON_GATE(axg_usb0
, HHI_GCLK_MPEG1
, 21);
996 static MESON_GATE(axg_usb1
, HHI_GCLK_MPEG1
, 22);
997 static MESON_GATE(axg_reset
, HHI_GCLK_MPEG1
, 23);
998 static MESON_GATE(axg_usb_general
, HHI_GCLK_MPEG1
, 26);
999 static MESON_GATE(axg_ahb_arb0
, HHI_GCLK_MPEG1
, 29);
1000 static MESON_GATE(axg_efuse
, HHI_GCLK_MPEG1
, 30);
1001 static MESON_GATE(axg_boot_rom
, HHI_GCLK_MPEG1
, 31);
1003 static MESON_GATE(axg_ahb_data_bus
, HHI_GCLK_MPEG2
, 1);
1004 static MESON_GATE(axg_ahb_ctrl_bus
, HHI_GCLK_MPEG2
, 2);
1005 static MESON_GATE(axg_usb1_to_ddr
, HHI_GCLK_MPEG2
, 8);
1006 static MESON_GATE(axg_usb0_to_ddr
, HHI_GCLK_MPEG2
, 9);
1007 static MESON_GATE(axg_mmc_pclk
, HHI_GCLK_MPEG2
, 11);
1008 static MESON_GATE(axg_vpu_intr
, HHI_GCLK_MPEG2
, 25);
1009 static MESON_GATE(axg_sec_ahb_ahb3_bridge
, HHI_GCLK_MPEG2
, 26);
1010 static MESON_GATE(axg_gic
, HHI_GCLK_MPEG2
, 30);
1011 static MESON_GATE(axg_mipi_enable
, HHI_MIPI_CNTL0
, 29);
1013 /* Always On (AO) domain gates */
1015 static MESON_GATE(axg_ao_media_cpu
, HHI_GCLK_AO
, 0);
1016 static MESON_GATE(axg_ao_ahb_sram
, HHI_GCLK_AO
, 1);
1017 static MESON_GATE(axg_ao_ahb_bus
, HHI_GCLK_AO
, 2);
1018 static MESON_GATE(axg_ao_iface
, HHI_GCLK_AO
, 3);
1019 static MESON_GATE(axg_ao_i2c
, HHI_GCLK_AO
, 4);
1021 /* Array of all clocks provided by this provider */
1023 static struct clk_hw_onecell_data axg_hw_onecell_data
= {
1025 [CLKID_SYS_PLL
] = &axg_sys_pll
.hw
,
1026 [CLKID_FIXED_PLL
] = &axg_fixed_pll
.hw
,
1027 [CLKID_FCLK_DIV2
] = &axg_fclk_div2
.hw
,
1028 [CLKID_FCLK_DIV3
] = &axg_fclk_div3
.hw
,
1029 [CLKID_FCLK_DIV4
] = &axg_fclk_div4
.hw
,
1030 [CLKID_FCLK_DIV5
] = &axg_fclk_div5
.hw
,
1031 [CLKID_FCLK_DIV7
] = &axg_fclk_div7
.hw
,
1032 [CLKID_GP0_PLL
] = &axg_gp0_pll
.hw
,
1033 [CLKID_MPEG_SEL
] = &axg_mpeg_clk_sel
.hw
,
1034 [CLKID_MPEG_DIV
] = &axg_mpeg_clk_div
.hw
,
1035 [CLKID_CLK81
] = &axg_clk81
.hw
,
1036 [CLKID_MPLL0
] = &axg_mpll0
.hw
,
1037 [CLKID_MPLL1
] = &axg_mpll1
.hw
,
1038 [CLKID_MPLL2
] = &axg_mpll2
.hw
,
1039 [CLKID_MPLL3
] = &axg_mpll3
.hw
,
1040 [CLKID_DDR
] = &axg_ddr
.hw
,
1041 [CLKID_AUDIO_LOCKER
] = &axg_audio_locker
.hw
,
1042 [CLKID_MIPI_DSI_HOST
] = &axg_mipi_dsi_host
.hw
,
1043 [CLKID_ISA
] = &axg_isa
.hw
,
1044 [CLKID_PL301
] = &axg_pl301
.hw
,
1045 [CLKID_PERIPHS
] = &axg_periphs
.hw
,
1046 [CLKID_SPICC0
] = &axg_spicc_0
.hw
,
1047 [CLKID_I2C
] = &axg_i2c
.hw
,
1048 [CLKID_RNG0
] = &axg_rng0
.hw
,
1049 [CLKID_UART0
] = &axg_uart0
.hw
,
1050 [CLKID_MIPI_DSI_PHY
] = &axg_mipi_dsi_phy
.hw
,
1051 [CLKID_SPICC1
] = &axg_spicc_1
.hw
,
1052 [CLKID_PCIE_A
] = &axg_pcie_a
.hw
,
1053 [CLKID_PCIE_B
] = &axg_pcie_b
.hw
,
1054 [CLKID_HIU_IFACE
] = &axg_hiu_reg
.hw
,
1055 [CLKID_ASSIST_MISC
] = &axg_assist_misc
.hw
,
1056 [CLKID_SD_EMMC_B
] = &axg_emmc_b
.hw
,
1057 [CLKID_SD_EMMC_C
] = &axg_emmc_c
.hw
,
1058 [CLKID_DMA
] = &axg_dma
.hw
,
1059 [CLKID_SPI
] = &axg_spi
.hw
,
1060 [CLKID_AUDIO
] = &axg_audio
.hw
,
1061 [CLKID_ETH
] = &axg_eth_core
.hw
,
1062 [CLKID_UART1
] = &axg_uart1
.hw
,
1063 [CLKID_G2D
] = &axg_g2d
.hw
,
1064 [CLKID_USB0
] = &axg_usb0
.hw
,
1065 [CLKID_USB1
] = &axg_usb1
.hw
,
1066 [CLKID_RESET
] = &axg_reset
.hw
,
1067 [CLKID_USB
] = &axg_usb_general
.hw
,
1068 [CLKID_AHB_ARB0
] = &axg_ahb_arb0
.hw
,
1069 [CLKID_EFUSE
] = &axg_efuse
.hw
,
1070 [CLKID_BOOT_ROM
] = &axg_boot_rom
.hw
,
1071 [CLKID_AHB_DATA_BUS
] = &axg_ahb_data_bus
.hw
,
1072 [CLKID_AHB_CTRL_BUS
] = &axg_ahb_ctrl_bus
.hw
,
1073 [CLKID_USB1_DDR_BRIDGE
] = &axg_usb1_to_ddr
.hw
,
1074 [CLKID_USB0_DDR_BRIDGE
] = &axg_usb0_to_ddr
.hw
,
1075 [CLKID_MMC_PCLK
] = &axg_mmc_pclk
.hw
,
1076 [CLKID_VPU_INTR
] = &axg_vpu_intr
.hw
,
1077 [CLKID_SEC_AHB_AHB3_BRIDGE
] = &axg_sec_ahb_ahb3_bridge
.hw
,
1078 [CLKID_GIC
] = &axg_gic
.hw
,
1079 [CLKID_AO_MEDIA_CPU
] = &axg_ao_media_cpu
.hw
,
1080 [CLKID_AO_AHB_SRAM
] = &axg_ao_ahb_sram
.hw
,
1081 [CLKID_AO_AHB_BUS
] = &axg_ao_ahb_bus
.hw
,
1082 [CLKID_AO_IFACE
] = &axg_ao_iface
.hw
,
1083 [CLKID_AO_I2C
] = &axg_ao_i2c
.hw
,
1084 [CLKID_SD_EMMC_B_CLK0_SEL
] = &axg_sd_emmc_b_clk0_sel
.hw
,
1085 [CLKID_SD_EMMC_B_CLK0_DIV
] = &axg_sd_emmc_b_clk0_div
.hw
,
1086 [CLKID_SD_EMMC_B_CLK0
] = &axg_sd_emmc_b_clk0
.hw
,
1087 [CLKID_SD_EMMC_C_CLK0_SEL
] = &axg_sd_emmc_c_clk0_sel
.hw
,
1088 [CLKID_SD_EMMC_C_CLK0_DIV
] = &axg_sd_emmc_c_clk0_div
.hw
,
1089 [CLKID_SD_EMMC_C_CLK0
] = &axg_sd_emmc_c_clk0
.hw
,
1090 [CLKID_MPLL0_DIV
] = &axg_mpll0_div
.hw
,
1091 [CLKID_MPLL1_DIV
] = &axg_mpll1_div
.hw
,
1092 [CLKID_MPLL2_DIV
] = &axg_mpll2_div
.hw
,
1093 [CLKID_MPLL3_DIV
] = &axg_mpll3_div
.hw
,
1094 [CLKID_HIFI_PLL
] = &axg_hifi_pll
.hw
,
1095 [CLKID_MPLL_PREDIV
] = &axg_mpll_prediv
.hw
,
1096 [CLKID_FCLK_DIV2_DIV
] = &axg_fclk_div2_div
.hw
,
1097 [CLKID_FCLK_DIV3_DIV
] = &axg_fclk_div3_div
.hw
,
1098 [CLKID_FCLK_DIV4_DIV
] = &axg_fclk_div4_div
.hw
,
1099 [CLKID_FCLK_DIV5_DIV
] = &axg_fclk_div5_div
.hw
,
1100 [CLKID_FCLK_DIV7_DIV
] = &axg_fclk_div7_div
.hw
,
1101 [CLKID_PCIE_PLL
] = &axg_pcie_pll
.hw
,
1102 [CLKID_PCIE_MUX
] = &axg_pcie_mux
.hw
,
1103 [CLKID_PCIE_REF
] = &axg_pcie_ref
.hw
,
1104 [CLKID_PCIE_CML_EN0
] = &axg_pcie_cml_en0
.hw
,
1105 [CLKID_PCIE_CML_EN1
] = &axg_pcie_cml_en1
.hw
,
1106 [CLKID_MIPI_ENABLE
] = &axg_mipi_enable
.hw
,
1107 [CLKID_GEN_CLK_SEL
] = &axg_gen_clk_sel
.hw
,
1108 [CLKID_GEN_CLK_DIV
] = &axg_gen_clk_div
.hw
,
1109 [CLKID_GEN_CLK
] = &axg_gen_clk
.hw
,
1115 /* Convenience table to populate regmap in .probe */
1116 static struct clk_regmap
*const axg_clk_regmaps
[] = {
1155 &axg_sec_ahb_ahb3_bridge
,
1162 &axg_sd_emmc_b_clk0
,
1163 &axg_sd_emmc_c_clk0
,
1165 &axg_sd_emmc_b_clk0_div
,
1166 &axg_sd_emmc_c_clk0_div
,
1168 &axg_sd_emmc_b_clk0_sel
,
1169 &axg_sd_emmc_c_clk0_sel
,
1199 static const struct of_device_id clkc_match_table
[] = {
1200 { .compatible
= "amlogic,axg-clkc" },
1204 static int axg_clkc_probe(struct platform_device
*pdev
)
1206 struct device
*dev
= &pdev
->dev
;
1210 /* Get the hhi system controller node if available */
1211 map
= syscon_node_to_regmap(of_get_parent(dev
->of_node
));
1213 dev_err(dev
, "failed to get HHI regmap\n");
1214 return PTR_ERR(map
);
1217 /* Populate regmap for the regmap backed clocks */
1218 for (i
= 0; i
< ARRAY_SIZE(axg_clk_regmaps
); i
++)
1219 axg_clk_regmaps
[i
]->map
= map
;
1221 for (i
= 0; i
< axg_hw_onecell_data
.num
; i
++) {
1222 /* array might be sparse */
1223 if (!axg_hw_onecell_data
.hws
[i
])
1226 ret
= devm_clk_hw_register(dev
, axg_hw_onecell_data
.hws
[i
]);
1228 dev_err(dev
, "Clock registration failed\n");
1233 return devm_of_clk_add_hw_provider(dev
, of_clk_hw_onecell_get
,
1234 &axg_hw_onecell_data
);
1237 static struct platform_driver axg_driver
= {
1238 .probe
= axg_clkc_probe
,
1241 .of_match_table
= clkc_match_table
,
1245 builtin_platform_driver(axg_driver
);