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-provider.h>
13 #include <linux/init.h>
14 #include <linux/of_device.h>
15 #include <linux/platform_device.h>
17 #include "clk-regmap.h"
21 #include "meson-eeclk.h"
23 static DEFINE_SPINLOCK(meson_clk_lock
);
25 static struct clk_regmap axg_fixed_pll_dco
= {
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
){
59 .name
= "fixed_pll_dco",
60 .ops
= &meson_clk_pll_ro_ops
,
61 .parent_data
= &(const struct clk_parent_data
) {
68 static struct clk_regmap axg_fixed_pll
= {
69 .data
= &(struct clk_regmap_div_data
){
70 .offset
= HHI_MPLL_CNTL
,
73 .flags
= CLK_DIVIDER_POWER_OF_TWO
,
75 .hw
.init
= &(struct clk_init_data
){
77 .ops
= &clk_regmap_divider_ro_ops
,
78 .parent_hws
= (const struct clk_hw
*[]) {
83 * This clock won't ever change at runtime so
84 * CLK_SET_RATE_PARENT is not required
89 static struct clk_regmap axg_sys_pll_dco
= {
90 .data
= &(struct meson_clk_pll_data
){
92 .reg_off
= HHI_SYS_PLL_CNTL
,
97 .reg_off
= HHI_SYS_PLL_CNTL
,
102 .reg_off
= HHI_SYS_PLL_CNTL
,
107 .reg_off
= HHI_SYS_PLL_CNTL
,
112 .reg_off
= HHI_SYS_PLL_CNTL
,
117 .hw
.init
= &(struct clk_init_data
){
118 .name
= "sys_pll_dco",
119 .ops
= &meson_clk_pll_ro_ops
,
120 .parent_data
= &(const struct clk_parent_data
) {
127 static struct clk_regmap axg_sys_pll
= {
128 .data
= &(struct clk_regmap_div_data
){
129 .offset
= HHI_SYS_PLL_CNTL
,
132 .flags
= CLK_DIVIDER_POWER_OF_TWO
,
134 .hw
.init
= &(struct clk_init_data
){
136 .ops
= &clk_regmap_divider_ro_ops
,
137 .parent_hws
= (const struct clk_hw
*[]) {
141 .flags
= CLK_SET_RATE_PARENT
,
145 static const struct pll_params_table axg_gp0_pll_params_table
[] = {
178 static const struct reg_sequence axg_gp0_init_regs
[] = {
179 { .reg
= HHI_GP0_PLL_CNTL1
, .def
= 0xc084b000 },
180 { .reg
= HHI_GP0_PLL_CNTL2
, .def
= 0xb75020be },
181 { .reg
= HHI_GP0_PLL_CNTL3
, .def
= 0x0a59a288 },
182 { .reg
= HHI_GP0_PLL_CNTL4
, .def
= 0xc000004d },
183 { .reg
= HHI_GP0_PLL_CNTL5
, .def
= 0x00078000 },
186 static struct clk_regmap axg_gp0_pll_dco
= {
187 .data
= &(struct meson_clk_pll_data
){
189 .reg_off
= HHI_GP0_PLL_CNTL
,
194 .reg_off
= HHI_GP0_PLL_CNTL
,
199 .reg_off
= HHI_GP0_PLL_CNTL
,
204 .reg_off
= HHI_GP0_PLL_CNTL1
,
209 .reg_off
= HHI_GP0_PLL_CNTL
,
214 .reg_off
= HHI_GP0_PLL_CNTL
,
218 .table
= axg_gp0_pll_params_table
,
219 .init_regs
= axg_gp0_init_regs
,
220 .init_count
= ARRAY_SIZE(axg_gp0_init_regs
),
222 .hw
.init
= &(struct clk_init_data
){
223 .name
= "gp0_pll_dco",
224 .ops
= &meson_clk_pll_ops
,
225 .parent_data
= &(const struct clk_parent_data
) {
232 static struct clk_regmap axg_gp0_pll
= {
233 .data
= &(struct clk_regmap_div_data
){
234 .offset
= HHI_GP0_PLL_CNTL
,
237 .flags
= CLK_DIVIDER_POWER_OF_TWO
,
239 .hw
.init
= &(struct clk_init_data
){
241 .ops
= &clk_regmap_divider_ops
,
242 .parent_hws
= (const struct clk_hw
*[]) {
246 .flags
= CLK_SET_RATE_PARENT
,
250 static const struct reg_sequence axg_hifi_init_regs
[] = {
251 { .reg
= HHI_HIFI_PLL_CNTL1
, .def
= 0xc084b000 },
252 { .reg
= HHI_HIFI_PLL_CNTL2
, .def
= 0xb75020be },
253 { .reg
= HHI_HIFI_PLL_CNTL3
, .def
= 0x0a6a3a88 },
254 { .reg
= HHI_HIFI_PLL_CNTL4
, .def
= 0xc000004d },
255 { .reg
= HHI_HIFI_PLL_CNTL5
, .def
= 0x00058000 },
258 static struct clk_regmap axg_hifi_pll_dco
= {
259 .data
= &(struct meson_clk_pll_data
){
261 .reg_off
= HHI_HIFI_PLL_CNTL
,
266 .reg_off
= HHI_HIFI_PLL_CNTL
,
271 .reg_off
= HHI_HIFI_PLL_CNTL
,
276 .reg_off
= HHI_HIFI_PLL_CNTL5
,
281 .reg_off
= HHI_HIFI_PLL_CNTL
,
286 .reg_off
= HHI_HIFI_PLL_CNTL
,
290 .table
= axg_gp0_pll_params_table
,
291 .init_regs
= axg_hifi_init_regs
,
292 .init_count
= ARRAY_SIZE(axg_hifi_init_regs
),
293 .flags
= CLK_MESON_PLL_ROUND_CLOSEST
,
295 .hw
.init
= &(struct clk_init_data
){
296 .name
= "hifi_pll_dco",
297 .ops
= &meson_clk_pll_ops
,
298 .parent_data
= &(const struct clk_parent_data
) {
305 static struct clk_regmap axg_hifi_pll
= {
306 .data
= &(struct clk_regmap_div_data
){
307 .offset
= HHI_HIFI_PLL_CNTL
,
310 .flags
= CLK_DIVIDER_POWER_OF_TWO
,
312 .hw
.init
= &(struct clk_init_data
){
314 .ops
= &clk_regmap_divider_ops
,
315 .parent_hws
= (const struct clk_hw
*[]) {
319 .flags
= CLK_SET_RATE_PARENT
,
323 static struct clk_fixed_factor axg_fclk_div2_div
= {
326 .hw
.init
= &(struct clk_init_data
){
327 .name
= "fclk_div2_div",
328 .ops
= &clk_fixed_factor_ops
,
329 .parent_hws
= (const struct clk_hw
*[]) { &axg_fixed_pll
.hw
},
334 static struct clk_regmap axg_fclk_div2
= {
335 .data
= &(struct clk_regmap_gate_data
){
336 .offset
= HHI_MPLL_CNTL6
,
339 .hw
.init
= &(struct clk_init_data
){
341 .ops
= &clk_regmap_gate_ops
,
342 .parent_hws
= (const struct clk_hw
*[]) {
343 &axg_fclk_div2_div
.hw
346 .flags
= CLK_IS_CRITICAL
,
350 static struct clk_fixed_factor axg_fclk_div3_div
= {
353 .hw
.init
= &(struct clk_init_data
){
354 .name
= "fclk_div3_div",
355 .ops
= &clk_fixed_factor_ops
,
356 .parent_hws
= (const struct clk_hw
*[]) { &axg_fixed_pll
.hw
},
361 static struct clk_regmap axg_fclk_div3
= {
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_hws
= (const struct clk_hw
*[]) {
370 &axg_fclk_div3_div
.hw
375 * This clock, as fdiv2, is used by the SCPI FW and is required
376 * by the platform to operate correctly.
377 * Until the following condition are met, we need this clock to
378 * be marked as critical:
379 * a) The SCPI generic driver claims and enable all the clocks
381 * b) CCF has a clock hand-off mechanism to make the sure the
382 * clock stays on until the proper driver comes along
384 .flags
= CLK_IS_CRITICAL
,
388 static struct clk_fixed_factor axg_fclk_div4_div
= {
391 .hw
.init
= &(struct clk_init_data
){
392 .name
= "fclk_div4_div",
393 .ops
= &clk_fixed_factor_ops
,
394 .parent_hws
= (const struct clk_hw
*[]) { &axg_fixed_pll
.hw
},
399 static struct clk_regmap axg_fclk_div4
= {
400 .data
= &(struct clk_regmap_gate_data
){
401 .offset
= HHI_MPLL_CNTL6
,
404 .hw
.init
= &(struct clk_init_data
){
406 .ops
= &clk_regmap_gate_ops
,
407 .parent_hws
= (const struct clk_hw
*[]) {
408 &axg_fclk_div4_div
.hw
414 static struct clk_fixed_factor axg_fclk_div5_div
= {
417 .hw
.init
= &(struct clk_init_data
){
418 .name
= "fclk_div5_div",
419 .ops
= &clk_fixed_factor_ops
,
420 .parent_hws
= (const struct clk_hw
*[]) { &axg_fixed_pll
.hw
},
425 static struct clk_regmap axg_fclk_div5
= {
426 .data
= &(struct clk_regmap_gate_data
){
427 .offset
= HHI_MPLL_CNTL6
,
430 .hw
.init
= &(struct clk_init_data
){
432 .ops
= &clk_regmap_gate_ops
,
433 .parent_hws
= (const struct clk_hw
*[]) {
434 &axg_fclk_div5_div
.hw
440 static struct clk_fixed_factor axg_fclk_div7_div
= {
443 .hw
.init
= &(struct clk_init_data
){
444 .name
= "fclk_div7_div",
445 .ops
= &clk_fixed_factor_ops
,
446 .parent_hws
= (const struct clk_hw
*[]) {
453 static struct clk_regmap axg_fclk_div7
= {
454 .data
= &(struct clk_regmap_gate_data
){
455 .offset
= HHI_MPLL_CNTL6
,
458 .hw
.init
= &(struct clk_init_data
){
460 .ops
= &clk_regmap_gate_ops
,
461 .parent_hws
= (const struct clk_hw
*[]) {
462 &axg_fclk_div7_div
.hw
468 static struct clk_regmap axg_mpll_prediv
= {
469 .data
= &(struct clk_regmap_div_data
){
470 .offset
= HHI_MPLL_CNTL5
,
474 .hw
.init
= &(struct clk_init_data
){
475 .name
= "mpll_prediv",
476 .ops
= &clk_regmap_divider_ro_ops
,
477 .parent_hws
= (const struct clk_hw
*[]) {
484 static struct clk_regmap axg_mpll0_div
= {
485 .data
= &(struct meson_clk_mpll_data
){
487 .reg_off
= HHI_MPLL_CNTL7
,
492 .reg_off
= HHI_MPLL_CNTL7
,
497 .reg_off
= HHI_MPLL_CNTL7
,
502 .reg_off
= HHI_PLL_TOP_MISC
,
506 .lock
= &meson_clk_lock
,
507 .flags
= CLK_MESON_MPLL_ROUND_CLOSEST
,
509 .hw
.init
= &(struct clk_init_data
){
511 .ops
= &meson_clk_mpll_ops
,
512 .parent_hws
= (const struct clk_hw
*[]) {
519 static struct clk_regmap axg_mpll0
= {
520 .data
= &(struct clk_regmap_gate_data
){
521 .offset
= HHI_MPLL_CNTL7
,
524 .hw
.init
= &(struct clk_init_data
){
526 .ops
= &clk_regmap_gate_ops
,
527 .parent_hws
= (const struct clk_hw
*[]) {
531 .flags
= CLK_SET_RATE_PARENT
,
535 static struct clk_regmap axg_mpll1_div
= {
536 .data
= &(struct meson_clk_mpll_data
){
538 .reg_off
= HHI_MPLL_CNTL8
,
543 .reg_off
= HHI_MPLL_CNTL8
,
548 .reg_off
= HHI_MPLL_CNTL8
,
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_hws
= (const struct clk_hw
*[]) {
570 static struct clk_regmap axg_mpll1
= {
571 .data
= &(struct clk_regmap_gate_data
){
572 .offset
= HHI_MPLL_CNTL8
,
575 .hw
.init
= &(struct clk_init_data
){
577 .ops
= &clk_regmap_gate_ops
,
578 .parent_hws
= (const struct clk_hw
*[]) {
582 .flags
= CLK_SET_RATE_PARENT
,
586 static struct clk_regmap axg_mpll2_div
= {
587 .data
= &(struct meson_clk_mpll_data
){
589 .reg_off
= HHI_MPLL_CNTL9
,
594 .reg_off
= HHI_MPLL_CNTL9
,
599 .reg_off
= HHI_MPLL_CNTL9
,
604 .reg_off
= HHI_MPLL_CNTL
,
609 .reg_off
= HHI_PLL_TOP_MISC
,
613 .lock
= &meson_clk_lock
,
614 .flags
= CLK_MESON_MPLL_ROUND_CLOSEST
,
616 .hw
.init
= &(struct clk_init_data
){
618 .ops
= &meson_clk_mpll_ops
,
619 .parent_hws
= (const struct clk_hw
*[]) {
626 static struct clk_regmap axg_mpll2
= {
627 .data
= &(struct clk_regmap_gate_data
){
628 .offset
= HHI_MPLL_CNTL9
,
631 .hw
.init
= &(struct clk_init_data
){
633 .ops
= &clk_regmap_gate_ops
,
634 .parent_hws
= (const struct clk_hw
*[]) {
638 .flags
= CLK_SET_RATE_PARENT
,
642 static struct clk_regmap axg_mpll3_div
= {
643 .data
= &(struct meson_clk_mpll_data
){
645 .reg_off
= HHI_MPLL3_CNTL0
,
650 .reg_off
= HHI_MPLL3_CNTL0
,
655 .reg_off
= HHI_MPLL3_CNTL0
,
660 .reg_off
= HHI_PLL_TOP_MISC
,
664 .lock
= &meson_clk_lock
,
665 .flags
= CLK_MESON_MPLL_ROUND_CLOSEST
,
667 .hw
.init
= &(struct clk_init_data
){
669 .ops
= &meson_clk_mpll_ops
,
670 .parent_hws
= (const struct clk_hw
*[]) {
677 static struct clk_regmap axg_mpll3
= {
678 .data
= &(struct clk_regmap_gate_data
){
679 .offset
= HHI_MPLL3_CNTL0
,
682 .hw
.init
= &(struct clk_init_data
){
684 .ops
= &clk_regmap_gate_ops
,
685 .parent_hws
= (const struct clk_hw
*[]) {
689 .flags
= CLK_SET_RATE_PARENT
,
693 static const struct pll_params_table axg_pcie_pll_params_table
[] = {
701 static const struct reg_sequence axg_pcie_init_regs
[] = {
702 { .reg
= HHI_PCIE_PLL_CNTL1
, .def
= 0x0084a2aa },
703 { .reg
= HHI_PCIE_PLL_CNTL2
, .def
= 0xb75020be },
704 { .reg
= HHI_PCIE_PLL_CNTL3
, .def
= 0x0a47488e },
705 { .reg
= HHI_PCIE_PLL_CNTL4
, .def
= 0xc000004d },
706 { .reg
= HHI_PCIE_PLL_CNTL5
, .def
= 0x00078000 },
707 { .reg
= HHI_PCIE_PLL_CNTL6
, .def
= 0x002323c6 },
708 { .reg
= HHI_PCIE_PLL_CNTL
, .def
= 0x400106c8 },
711 static struct clk_regmap axg_pcie_pll_dco
= {
712 .data
= &(struct meson_clk_pll_data
){
714 .reg_off
= HHI_PCIE_PLL_CNTL
,
719 .reg_off
= HHI_PCIE_PLL_CNTL
,
724 .reg_off
= HHI_PCIE_PLL_CNTL
,
729 .reg_off
= HHI_PCIE_PLL_CNTL1
,
734 .reg_off
= HHI_PCIE_PLL_CNTL
,
739 .reg_off
= HHI_PCIE_PLL_CNTL
,
743 .table
= axg_pcie_pll_params_table
,
744 .init_regs
= axg_pcie_init_regs
,
745 .init_count
= ARRAY_SIZE(axg_pcie_init_regs
),
747 .hw
.init
= &(struct clk_init_data
){
748 .name
= "pcie_pll_dco",
749 .ops
= &meson_clk_pll_ops
,
750 .parent_data
= &(const struct clk_parent_data
) {
757 static struct clk_regmap axg_pcie_pll_od
= {
758 .data
= &(struct clk_regmap_div_data
){
759 .offset
= HHI_PCIE_PLL_CNTL
,
762 .flags
= CLK_DIVIDER_POWER_OF_TWO
,
764 .hw
.init
= &(struct clk_init_data
){
765 .name
= "pcie_pll_od",
766 .ops
= &clk_regmap_divider_ops
,
767 .parent_hws
= (const struct clk_hw
*[]) {
771 .flags
= CLK_SET_RATE_PARENT
,
775 static struct clk_regmap axg_pcie_pll
= {
776 .data
= &(struct clk_regmap_div_data
){
777 .offset
= HHI_PCIE_PLL_CNTL6
,
780 .flags
= CLK_DIVIDER_POWER_OF_TWO
,
782 .hw
.init
= &(struct clk_init_data
){
784 .ops
= &clk_regmap_divider_ops
,
785 .parent_hws
= (const struct clk_hw
*[]) {
789 .flags
= CLK_SET_RATE_PARENT
,
793 static struct clk_regmap axg_pcie_mux
= {
794 .data
= &(struct clk_regmap_mux_data
){
795 .offset
= HHI_PCIE_PLL_CNTL6
,
798 /* skip the parent mpll3, reserved for debug */
799 .table
= (u32
[]){ 1 },
801 .hw
.init
= &(struct clk_init_data
){
803 .ops
= &clk_regmap_mux_ops
,
804 .parent_hws
= (const struct clk_hw
*[]) { &axg_pcie_pll
.hw
},
806 .flags
= CLK_SET_RATE_PARENT
,
810 static struct clk_regmap axg_pcie_ref
= {
811 .data
= &(struct clk_regmap_mux_data
){
812 .offset
= HHI_PCIE_PLL_CNTL6
,
815 /* skip the parent 0, reserved for debug */
816 .table
= (u32
[]){ 1 },
818 .hw
.init
= &(struct clk_init_data
){
820 .ops
= &clk_regmap_mux_ops
,
821 .parent_hws
= (const struct clk_hw
*[]) { &axg_pcie_mux
.hw
},
823 .flags
= CLK_SET_RATE_PARENT
,
827 static struct clk_regmap axg_pcie_cml_en0
= {
828 .data
= &(struct clk_regmap_gate_data
){
829 .offset
= HHI_PCIE_PLL_CNTL6
,
832 .hw
.init
= &(struct clk_init_data
) {
833 .name
= "pcie_cml_en0",
834 .ops
= &clk_regmap_gate_ops
,
835 .parent_hws
= (const struct clk_hw
*[]) { &axg_pcie_ref
.hw
},
837 .flags
= CLK_SET_RATE_PARENT
,
842 static struct clk_regmap axg_pcie_cml_en1
= {
843 .data
= &(struct clk_regmap_gate_data
){
844 .offset
= HHI_PCIE_PLL_CNTL6
,
847 .hw
.init
= &(struct clk_init_data
) {
848 .name
= "pcie_cml_en1",
849 .ops
= &clk_regmap_gate_ops
,
850 .parent_hws
= (const struct clk_hw
*[]) { &axg_pcie_ref
.hw
},
852 .flags
= CLK_SET_RATE_PARENT
,
856 static u32 mux_table_clk81
[] = { 0, 2, 3, 4, 5, 6, 7 };
857 static const struct clk_parent_data clk81_parent_data
[] = {
858 { .fw_name
= "xtal", },
859 { .hw
= &axg_fclk_div7
.hw
},
860 { .hw
= &axg_mpll1
.hw
},
861 { .hw
= &axg_mpll2
.hw
},
862 { .hw
= &axg_fclk_div4
.hw
},
863 { .hw
= &axg_fclk_div3
.hw
},
864 { .hw
= &axg_fclk_div5
.hw
},
867 static struct clk_regmap axg_mpeg_clk_sel
= {
868 .data
= &(struct clk_regmap_mux_data
){
869 .offset
= HHI_MPEG_CLK_CNTL
,
872 .table
= mux_table_clk81
,
874 .hw
.init
= &(struct clk_init_data
){
875 .name
= "mpeg_clk_sel",
876 .ops
= &clk_regmap_mux_ro_ops
,
877 .parent_data
= clk81_parent_data
,
878 .num_parents
= ARRAY_SIZE(clk81_parent_data
),
882 static struct clk_regmap axg_mpeg_clk_div
= {
883 .data
= &(struct clk_regmap_div_data
){
884 .offset
= HHI_MPEG_CLK_CNTL
,
888 .hw
.init
= &(struct clk_init_data
){
889 .name
= "mpeg_clk_div",
890 .ops
= &clk_regmap_divider_ops
,
891 .parent_hws
= (const struct clk_hw
*[]) {
895 .flags
= CLK_SET_RATE_PARENT
,
899 static struct clk_regmap axg_clk81
= {
900 .data
= &(struct clk_regmap_gate_data
){
901 .offset
= HHI_MPEG_CLK_CNTL
,
904 .hw
.init
= &(struct clk_init_data
){
906 .ops
= &clk_regmap_gate_ops
,
907 .parent_hws
= (const struct clk_hw
*[]) {
911 .flags
= (CLK_SET_RATE_PARENT
| CLK_IS_CRITICAL
),
915 static const struct clk_parent_data axg_sd_emmc_clk0_parent_data
[] = {
916 { .fw_name
= "xtal", },
917 { .hw
= &axg_fclk_div2
.hw
},
918 { .hw
= &axg_fclk_div3
.hw
},
919 { .hw
= &axg_fclk_div5
.hw
},
920 { .hw
= &axg_fclk_div7
.hw
},
922 * Following these parent clocks, we should also have had mpll2, mpll3
923 * and gp0_pll but these clocks are too precious to be used here. All
924 * the necessary rates for MMC and NAND operation can be acheived using
925 * xtal or fclk_div clocks
930 static struct clk_regmap axg_sd_emmc_b_clk0_sel
= {
931 .data
= &(struct clk_regmap_mux_data
){
932 .offset
= HHI_SD_EMMC_CLK_CNTL
,
936 .hw
.init
= &(struct clk_init_data
) {
937 .name
= "sd_emmc_b_clk0_sel",
938 .ops
= &clk_regmap_mux_ops
,
939 .parent_data
= axg_sd_emmc_clk0_parent_data
,
940 .num_parents
= ARRAY_SIZE(axg_sd_emmc_clk0_parent_data
),
941 .flags
= CLK_SET_RATE_PARENT
,
945 static struct clk_regmap axg_sd_emmc_b_clk0_div
= {
946 .data
= &(struct clk_regmap_div_data
){
947 .offset
= HHI_SD_EMMC_CLK_CNTL
,
950 .flags
= CLK_DIVIDER_ROUND_CLOSEST
,
952 .hw
.init
= &(struct clk_init_data
) {
953 .name
= "sd_emmc_b_clk0_div",
954 .ops
= &clk_regmap_divider_ops
,
955 .parent_hws
= (const struct clk_hw
*[]) {
956 &axg_sd_emmc_b_clk0_sel
.hw
959 .flags
= CLK_SET_RATE_PARENT
,
963 static struct clk_regmap axg_sd_emmc_b_clk0
= {
964 .data
= &(struct clk_regmap_gate_data
){
965 .offset
= HHI_SD_EMMC_CLK_CNTL
,
968 .hw
.init
= &(struct clk_init_data
){
969 .name
= "sd_emmc_b_clk0",
970 .ops
= &clk_regmap_gate_ops
,
971 .parent_hws
= (const struct clk_hw
*[]) {
972 &axg_sd_emmc_b_clk0_div
.hw
975 .flags
= CLK_SET_RATE_PARENT
,
979 /* EMMC/NAND clock */
980 static struct clk_regmap axg_sd_emmc_c_clk0_sel
= {
981 .data
= &(struct clk_regmap_mux_data
){
982 .offset
= HHI_NAND_CLK_CNTL
,
986 .hw
.init
= &(struct clk_init_data
) {
987 .name
= "sd_emmc_c_clk0_sel",
988 .ops
= &clk_regmap_mux_ops
,
989 .parent_data
= axg_sd_emmc_clk0_parent_data
,
990 .num_parents
= ARRAY_SIZE(axg_sd_emmc_clk0_parent_data
),
991 .flags
= CLK_SET_RATE_PARENT
,
995 static struct clk_regmap axg_sd_emmc_c_clk0_div
= {
996 .data
= &(struct clk_regmap_div_data
){
997 .offset
= HHI_NAND_CLK_CNTL
,
1000 .flags
= CLK_DIVIDER_ROUND_CLOSEST
,
1002 .hw
.init
= &(struct clk_init_data
) {
1003 .name
= "sd_emmc_c_clk0_div",
1004 .ops
= &clk_regmap_divider_ops
,
1005 .parent_hws
= (const struct clk_hw
*[]) {
1006 &axg_sd_emmc_c_clk0_sel
.hw
1009 .flags
= CLK_SET_RATE_PARENT
,
1013 static struct clk_regmap axg_sd_emmc_c_clk0
= {
1014 .data
= &(struct clk_regmap_gate_data
){
1015 .offset
= HHI_NAND_CLK_CNTL
,
1018 .hw
.init
= &(struct clk_init_data
){
1019 .name
= "sd_emmc_c_clk0",
1020 .ops
= &clk_regmap_gate_ops
,
1021 .parent_hws
= (const struct clk_hw
*[]) {
1022 &axg_sd_emmc_c_clk0_div
.hw
1025 .flags
= CLK_SET_RATE_PARENT
,
1029 static u32 mux_table_gen_clk
[] = { 0, 4, 5, 6, 7, 8,
1030 9, 10, 11, 13, 14, };
1031 static const struct clk_parent_data gen_clk_parent_data
[] = {
1032 { .fw_name
= "xtal", },
1033 { .hw
= &axg_hifi_pll
.hw
},
1034 { .hw
= &axg_mpll0
.hw
},
1035 { .hw
= &axg_mpll1
.hw
},
1036 { .hw
= &axg_mpll2
.hw
},
1037 { .hw
= &axg_mpll3
.hw
},
1038 { .hw
= &axg_fclk_div4
.hw
},
1039 { .hw
= &axg_fclk_div3
.hw
},
1040 { .hw
= &axg_fclk_div5
.hw
},
1041 { .hw
= &axg_fclk_div7
.hw
},
1042 { .hw
= &axg_gp0_pll
.hw
},
1045 static struct clk_regmap axg_gen_clk_sel
= {
1046 .data
= &(struct clk_regmap_mux_data
){
1047 .offset
= HHI_GEN_CLK_CNTL
,
1050 .table
= mux_table_gen_clk
,
1052 .hw
.init
= &(struct clk_init_data
){
1053 .name
= "gen_clk_sel",
1054 .ops
= &clk_regmap_mux_ops
,
1056 * bits 15:12 selects from 14 possible parents:
1057 * xtal, [rtc_oscin_i], [sys_cpu_div16], [ddr_dpll_pt],
1058 * hifi_pll, mpll0, mpll1, mpll2, mpll3, fdiv4,
1059 * fdiv3, fdiv5, [cts_msr_clk], fdiv7, gp0_pll
1061 .parent_data
= gen_clk_parent_data
,
1062 .num_parents
= ARRAY_SIZE(gen_clk_parent_data
),
1066 static struct clk_regmap axg_gen_clk_div
= {
1067 .data
= &(struct clk_regmap_div_data
){
1068 .offset
= HHI_GEN_CLK_CNTL
,
1072 .hw
.init
= &(struct clk_init_data
){
1073 .name
= "gen_clk_div",
1074 .ops
= &clk_regmap_divider_ops
,
1075 .parent_hws
= (const struct clk_hw
*[]) {
1079 .flags
= CLK_SET_RATE_PARENT
,
1083 static struct clk_regmap axg_gen_clk
= {
1084 .data
= &(struct clk_regmap_gate_data
){
1085 .offset
= HHI_GEN_CLK_CNTL
,
1088 .hw
.init
= &(struct clk_init_data
){
1090 .ops
= &clk_regmap_gate_ops
,
1091 .parent_hws
= (const struct clk_hw
*[]) {
1095 .flags
= CLK_SET_RATE_PARENT
,
1099 #define MESON_GATE(_name, _reg, _bit) \
1100 MESON_PCLK(_name, _reg, _bit, &axg_clk81.hw)
1102 /* Everything Else (EE) domain gates */
1103 static MESON_GATE(axg_ddr
, HHI_GCLK_MPEG0
, 0);
1104 static MESON_GATE(axg_audio_locker
, HHI_GCLK_MPEG0
, 2);
1105 static MESON_GATE(axg_mipi_dsi_host
, HHI_GCLK_MPEG0
, 3);
1106 static MESON_GATE(axg_isa
, HHI_GCLK_MPEG0
, 5);
1107 static MESON_GATE(axg_pl301
, HHI_GCLK_MPEG0
, 6);
1108 static MESON_GATE(axg_periphs
, HHI_GCLK_MPEG0
, 7);
1109 static MESON_GATE(axg_spicc_0
, HHI_GCLK_MPEG0
, 8);
1110 static MESON_GATE(axg_i2c
, HHI_GCLK_MPEG0
, 9);
1111 static MESON_GATE(axg_rng0
, HHI_GCLK_MPEG0
, 12);
1112 static MESON_GATE(axg_uart0
, HHI_GCLK_MPEG0
, 13);
1113 static MESON_GATE(axg_mipi_dsi_phy
, HHI_GCLK_MPEG0
, 14);
1114 static MESON_GATE(axg_spicc_1
, HHI_GCLK_MPEG0
, 15);
1115 static MESON_GATE(axg_pcie_a
, HHI_GCLK_MPEG0
, 16);
1116 static MESON_GATE(axg_pcie_b
, HHI_GCLK_MPEG0
, 17);
1117 static MESON_GATE(axg_hiu_reg
, HHI_GCLK_MPEG0
, 19);
1118 static MESON_GATE(axg_assist_misc
, HHI_GCLK_MPEG0
, 23);
1119 static MESON_GATE(axg_emmc_b
, HHI_GCLK_MPEG0
, 25);
1120 static MESON_GATE(axg_emmc_c
, HHI_GCLK_MPEG0
, 26);
1121 static MESON_GATE(axg_dma
, HHI_GCLK_MPEG0
, 27);
1122 static MESON_GATE(axg_spi
, HHI_GCLK_MPEG0
, 30);
1124 static MESON_GATE(axg_audio
, HHI_GCLK_MPEG1
, 0);
1125 static MESON_GATE(axg_eth_core
, HHI_GCLK_MPEG1
, 3);
1126 static MESON_GATE(axg_uart1
, HHI_GCLK_MPEG1
, 16);
1127 static MESON_GATE(axg_g2d
, HHI_GCLK_MPEG1
, 20);
1128 static MESON_GATE(axg_usb0
, HHI_GCLK_MPEG1
, 21);
1129 static MESON_GATE(axg_usb1
, HHI_GCLK_MPEG1
, 22);
1130 static MESON_GATE(axg_reset
, HHI_GCLK_MPEG1
, 23);
1131 static MESON_GATE(axg_usb_general
, HHI_GCLK_MPEG1
, 26);
1132 static MESON_GATE(axg_ahb_arb0
, HHI_GCLK_MPEG1
, 29);
1133 static MESON_GATE(axg_efuse
, HHI_GCLK_MPEG1
, 30);
1134 static MESON_GATE(axg_boot_rom
, HHI_GCLK_MPEG1
, 31);
1136 static MESON_GATE(axg_ahb_data_bus
, HHI_GCLK_MPEG2
, 1);
1137 static MESON_GATE(axg_ahb_ctrl_bus
, HHI_GCLK_MPEG2
, 2);
1138 static MESON_GATE(axg_usb1_to_ddr
, HHI_GCLK_MPEG2
, 8);
1139 static MESON_GATE(axg_usb0_to_ddr
, HHI_GCLK_MPEG2
, 9);
1140 static MESON_GATE(axg_mmc_pclk
, HHI_GCLK_MPEG2
, 11);
1141 static MESON_GATE(axg_vpu_intr
, HHI_GCLK_MPEG2
, 25);
1142 static MESON_GATE(axg_sec_ahb_ahb3_bridge
, HHI_GCLK_MPEG2
, 26);
1143 static MESON_GATE(axg_gic
, HHI_GCLK_MPEG2
, 30);
1144 static MESON_GATE(axg_mipi_enable
, HHI_MIPI_CNTL0
, 29);
1146 /* Always On (AO) domain gates */
1148 static MESON_GATE(axg_ao_media_cpu
, HHI_GCLK_AO
, 0);
1149 static MESON_GATE(axg_ao_ahb_sram
, HHI_GCLK_AO
, 1);
1150 static MESON_GATE(axg_ao_ahb_bus
, HHI_GCLK_AO
, 2);
1151 static MESON_GATE(axg_ao_iface
, HHI_GCLK_AO
, 3);
1152 static MESON_GATE(axg_ao_i2c
, HHI_GCLK_AO
, 4);
1154 /* Array of all clocks provided by this provider */
1156 static struct clk_hw_onecell_data axg_hw_onecell_data
= {
1158 [CLKID_SYS_PLL
] = &axg_sys_pll
.hw
,
1159 [CLKID_FIXED_PLL
] = &axg_fixed_pll
.hw
,
1160 [CLKID_FCLK_DIV2
] = &axg_fclk_div2
.hw
,
1161 [CLKID_FCLK_DIV3
] = &axg_fclk_div3
.hw
,
1162 [CLKID_FCLK_DIV4
] = &axg_fclk_div4
.hw
,
1163 [CLKID_FCLK_DIV5
] = &axg_fclk_div5
.hw
,
1164 [CLKID_FCLK_DIV7
] = &axg_fclk_div7
.hw
,
1165 [CLKID_GP0_PLL
] = &axg_gp0_pll
.hw
,
1166 [CLKID_MPEG_SEL
] = &axg_mpeg_clk_sel
.hw
,
1167 [CLKID_MPEG_DIV
] = &axg_mpeg_clk_div
.hw
,
1168 [CLKID_CLK81
] = &axg_clk81
.hw
,
1169 [CLKID_MPLL0
] = &axg_mpll0
.hw
,
1170 [CLKID_MPLL1
] = &axg_mpll1
.hw
,
1171 [CLKID_MPLL2
] = &axg_mpll2
.hw
,
1172 [CLKID_MPLL3
] = &axg_mpll3
.hw
,
1173 [CLKID_DDR
] = &axg_ddr
.hw
,
1174 [CLKID_AUDIO_LOCKER
] = &axg_audio_locker
.hw
,
1175 [CLKID_MIPI_DSI_HOST
] = &axg_mipi_dsi_host
.hw
,
1176 [CLKID_ISA
] = &axg_isa
.hw
,
1177 [CLKID_PL301
] = &axg_pl301
.hw
,
1178 [CLKID_PERIPHS
] = &axg_periphs
.hw
,
1179 [CLKID_SPICC0
] = &axg_spicc_0
.hw
,
1180 [CLKID_I2C
] = &axg_i2c
.hw
,
1181 [CLKID_RNG0
] = &axg_rng0
.hw
,
1182 [CLKID_UART0
] = &axg_uart0
.hw
,
1183 [CLKID_MIPI_DSI_PHY
] = &axg_mipi_dsi_phy
.hw
,
1184 [CLKID_SPICC1
] = &axg_spicc_1
.hw
,
1185 [CLKID_PCIE_A
] = &axg_pcie_a
.hw
,
1186 [CLKID_PCIE_B
] = &axg_pcie_b
.hw
,
1187 [CLKID_HIU_IFACE
] = &axg_hiu_reg
.hw
,
1188 [CLKID_ASSIST_MISC
] = &axg_assist_misc
.hw
,
1189 [CLKID_SD_EMMC_B
] = &axg_emmc_b
.hw
,
1190 [CLKID_SD_EMMC_C
] = &axg_emmc_c
.hw
,
1191 [CLKID_DMA
] = &axg_dma
.hw
,
1192 [CLKID_SPI
] = &axg_spi
.hw
,
1193 [CLKID_AUDIO
] = &axg_audio
.hw
,
1194 [CLKID_ETH
] = &axg_eth_core
.hw
,
1195 [CLKID_UART1
] = &axg_uart1
.hw
,
1196 [CLKID_G2D
] = &axg_g2d
.hw
,
1197 [CLKID_USB0
] = &axg_usb0
.hw
,
1198 [CLKID_USB1
] = &axg_usb1
.hw
,
1199 [CLKID_RESET
] = &axg_reset
.hw
,
1200 [CLKID_USB
] = &axg_usb_general
.hw
,
1201 [CLKID_AHB_ARB0
] = &axg_ahb_arb0
.hw
,
1202 [CLKID_EFUSE
] = &axg_efuse
.hw
,
1203 [CLKID_BOOT_ROM
] = &axg_boot_rom
.hw
,
1204 [CLKID_AHB_DATA_BUS
] = &axg_ahb_data_bus
.hw
,
1205 [CLKID_AHB_CTRL_BUS
] = &axg_ahb_ctrl_bus
.hw
,
1206 [CLKID_USB1_DDR_BRIDGE
] = &axg_usb1_to_ddr
.hw
,
1207 [CLKID_USB0_DDR_BRIDGE
] = &axg_usb0_to_ddr
.hw
,
1208 [CLKID_MMC_PCLK
] = &axg_mmc_pclk
.hw
,
1209 [CLKID_VPU_INTR
] = &axg_vpu_intr
.hw
,
1210 [CLKID_SEC_AHB_AHB3_BRIDGE
] = &axg_sec_ahb_ahb3_bridge
.hw
,
1211 [CLKID_GIC
] = &axg_gic
.hw
,
1212 [CLKID_AO_MEDIA_CPU
] = &axg_ao_media_cpu
.hw
,
1213 [CLKID_AO_AHB_SRAM
] = &axg_ao_ahb_sram
.hw
,
1214 [CLKID_AO_AHB_BUS
] = &axg_ao_ahb_bus
.hw
,
1215 [CLKID_AO_IFACE
] = &axg_ao_iface
.hw
,
1216 [CLKID_AO_I2C
] = &axg_ao_i2c
.hw
,
1217 [CLKID_SD_EMMC_B_CLK0_SEL
] = &axg_sd_emmc_b_clk0_sel
.hw
,
1218 [CLKID_SD_EMMC_B_CLK0_DIV
] = &axg_sd_emmc_b_clk0_div
.hw
,
1219 [CLKID_SD_EMMC_B_CLK0
] = &axg_sd_emmc_b_clk0
.hw
,
1220 [CLKID_SD_EMMC_C_CLK0_SEL
] = &axg_sd_emmc_c_clk0_sel
.hw
,
1221 [CLKID_SD_EMMC_C_CLK0_DIV
] = &axg_sd_emmc_c_clk0_div
.hw
,
1222 [CLKID_SD_EMMC_C_CLK0
] = &axg_sd_emmc_c_clk0
.hw
,
1223 [CLKID_MPLL0_DIV
] = &axg_mpll0_div
.hw
,
1224 [CLKID_MPLL1_DIV
] = &axg_mpll1_div
.hw
,
1225 [CLKID_MPLL2_DIV
] = &axg_mpll2_div
.hw
,
1226 [CLKID_MPLL3_DIV
] = &axg_mpll3_div
.hw
,
1227 [CLKID_HIFI_PLL
] = &axg_hifi_pll
.hw
,
1228 [CLKID_MPLL_PREDIV
] = &axg_mpll_prediv
.hw
,
1229 [CLKID_FCLK_DIV2_DIV
] = &axg_fclk_div2_div
.hw
,
1230 [CLKID_FCLK_DIV3_DIV
] = &axg_fclk_div3_div
.hw
,
1231 [CLKID_FCLK_DIV4_DIV
] = &axg_fclk_div4_div
.hw
,
1232 [CLKID_FCLK_DIV5_DIV
] = &axg_fclk_div5_div
.hw
,
1233 [CLKID_FCLK_DIV7_DIV
] = &axg_fclk_div7_div
.hw
,
1234 [CLKID_PCIE_PLL
] = &axg_pcie_pll
.hw
,
1235 [CLKID_PCIE_MUX
] = &axg_pcie_mux
.hw
,
1236 [CLKID_PCIE_REF
] = &axg_pcie_ref
.hw
,
1237 [CLKID_PCIE_CML_EN0
] = &axg_pcie_cml_en0
.hw
,
1238 [CLKID_PCIE_CML_EN1
] = &axg_pcie_cml_en1
.hw
,
1239 [CLKID_MIPI_ENABLE
] = &axg_mipi_enable
.hw
,
1240 [CLKID_GEN_CLK_SEL
] = &axg_gen_clk_sel
.hw
,
1241 [CLKID_GEN_CLK_DIV
] = &axg_gen_clk_div
.hw
,
1242 [CLKID_GEN_CLK
] = &axg_gen_clk
.hw
,
1243 [CLKID_SYS_PLL_DCO
] = &axg_sys_pll_dco
.hw
,
1244 [CLKID_FIXED_PLL_DCO
] = &axg_fixed_pll_dco
.hw
,
1245 [CLKID_GP0_PLL_DCO
] = &axg_gp0_pll_dco
.hw
,
1246 [CLKID_HIFI_PLL_DCO
] = &axg_hifi_pll_dco
.hw
,
1247 [CLKID_PCIE_PLL_DCO
] = &axg_pcie_pll_dco
.hw
,
1248 [CLKID_PCIE_PLL_OD
] = &axg_pcie_pll_od
.hw
,
1254 /* Convenience table to populate regmap in .probe */
1255 static struct clk_regmap
*const axg_clk_regmaps
[] = {
1294 &axg_sec_ahb_ahb3_bridge
,
1301 &axg_sd_emmc_b_clk0
,
1302 &axg_sd_emmc_c_clk0
,
1304 &axg_sd_emmc_b_clk0_div
,
1305 &axg_sd_emmc_c_clk0_div
,
1307 &axg_sd_emmc_b_clk0_sel
,
1308 &axg_sd_emmc_c_clk0_sel
,
1346 static const struct meson_eeclkc_data axg_clkc_data
= {
1347 .regmap_clks
= axg_clk_regmaps
,
1348 .regmap_clk_num
= ARRAY_SIZE(axg_clk_regmaps
),
1349 .hw_onecell_data
= &axg_hw_onecell_data
,
1353 static const struct of_device_id clkc_match_table
[] = {
1354 { .compatible
= "amlogic,axg-clkc", .data
= &axg_clkc_data
},
1358 static struct platform_driver axg_driver
= {
1359 .probe
= meson_eeclkc_probe
,
1362 .of_match_table
= clkc_match_table
,
1366 builtin_platform_driver(axg_driver
);