1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
4 * Author: Jian Hu <jian.hu@amlogic.com>
6 * Copyright (c) 2023, SberDevices. All Rights Reserved.
7 * Author: Dmitry Rokosov <ddrokosov@sberdevices.ru>
10 #include <linux/clk-provider.h>
11 #include <linux/mod_devicetable.h>
12 #include <linux/platform_device.h>
13 #include "a1-peripherals.h"
14 #include "clk-dualdiv.h"
15 #include "clk-regmap.h"
16 #include "meson-clkc-utils.h"
18 #include <dt-bindings/clock/amlogic,a1-peripherals-clkc.h>
20 static struct clk_regmap xtal_in = {
21 .data = &(struct clk_regmap_gate_data){
22 .offset = SYS_OSCIN_CTRL,
25 .hw.init = &(struct clk_init_data) {
27 .ops = &clk_regmap_gate_ro_ops,
28 .parent_data = &(const struct clk_parent_data) {
35 static struct clk_regmap fixpll_in = {
36 .data = &(struct clk_regmap_gate_data){
37 .offset = SYS_OSCIN_CTRL,
40 .hw.init = &(struct clk_init_data) {
42 .ops = &clk_regmap_gate_ro_ops,
43 .parent_data = &(const struct clk_parent_data) {
50 static struct clk_regmap usb_phy_in = {
51 .data = &(struct clk_regmap_gate_data){
52 .offset = SYS_OSCIN_CTRL,
55 .hw.init = &(struct clk_init_data) {
57 .ops = &clk_regmap_gate_ops,
58 .parent_data = &(const struct clk_parent_data) {
65 static struct clk_regmap usb_ctrl_in = {
66 .data = &(struct clk_regmap_gate_data){
67 .offset = SYS_OSCIN_CTRL,
70 .hw.init = &(struct clk_init_data) {
71 .name = "usb_ctrl_in",
72 .ops = &clk_regmap_gate_ops,
73 .parent_data = &(const struct clk_parent_data) {
80 static struct clk_regmap hifipll_in = {
81 .data = &(struct clk_regmap_gate_data){
82 .offset = SYS_OSCIN_CTRL,
85 .hw.init = &(struct clk_init_data) {
87 .ops = &clk_regmap_gate_ops,
88 .parent_data = &(const struct clk_parent_data) {
95 static struct clk_regmap syspll_in = {
96 .data = &(struct clk_regmap_gate_data){
97 .offset = SYS_OSCIN_CTRL,
100 .hw.init = &(struct clk_init_data) {
102 .ops = &clk_regmap_gate_ops,
103 .parent_data = &(const struct clk_parent_data) {
110 static struct clk_regmap dds_in = {
111 .data = &(struct clk_regmap_gate_data){
112 .offset = SYS_OSCIN_CTRL,
115 .hw.init = &(struct clk_init_data) {
117 .ops = &clk_regmap_gate_ops,
118 .parent_data = &(const struct clk_parent_data) {
125 static struct clk_regmap rtc_32k_in = {
126 .data = &(struct clk_regmap_gate_data){
127 .offset = RTC_BY_OSCIN_CTRL0,
130 .hw.init = &(struct clk_init_data) {
131 .name = "rtc_32k_in",
132 .ops = &clk_regmap_gate_ops,
133 .parent_data = &(const struct clk_parent_data) {
140 static const struct meson_clk_dualdiv_param clk_32k_div_table[] = {
151 static struct clk_regmap rtc_32k_div = {
152 .data = &(struct meson_clk_dualdiv_data){
154 .reg_off = RTC_BY_OSCIN_CTRL0,
159 .reg_off = RTC_BY_OSCIN_CTRL0,
164 .reg_off = RTC_BY_OSCIN_CTRL1,
169 .reg_off = RTC_BY_OSCIN_CTRL1,
174 .reg_off = RTC_BY_OSCIN_CTRL0,
178 .table = clk_32k_div_table,
180 .hw.init = &(struct clk_init_data){
181 .name = "rtc_32k_div",
182 .ops = &meson_clk_dualdiv_ops,
183 .parent_hws = (const struct clk_hw *[]) {
190 static struct clk_regmap rtc_32k_xtal = {
191 .data = &(struct clk_regmap_gate_data){
192 .offset = RTC_BY_OSCIN_CTRL1,
195 .hw.init = &(struct clk_init_data) {
196 .name = "rtc_32k_xtal",
197 .ops = &clk_regmap_gate_ops,
198 .parent_hws = (const struct clk_hw *[]) {
205 static struct clk_regmap rtc_32k_sel = {
206 .data = &(struct clk_regmap_mux_data) {
210 .flags = CLK_MUX_ROUND_CLOSEST,
212 .hw.init = &(struct clk_init_data){
213 .name = "rtc_32k_sel",
214 .ops = &clk_regmap_mux_ops,
215 .parent_hws = (const struct clk_hw *[]) {
220 .flags = CLK_SET_RATE_PARENT,
224 static struct clk_regmap rtc = {
225 .data = &(struct clk_regmap_gate_data){
226 .offset = RTC_BY_OSCIN_CTRL0,
229 .hw.init = &(struct clk_init_data){
231 .ops = &clk_regmap_gate_ops,
232 .parent_hws = (const struct clk_hw *[]) {
236 .flags = CLK_SET_RATE_PARENT,
240 static u32 mux_table_sys[] = { 0, 1, 2, 3, 7 };
241 static const struct clk_parent_data sys_parents[] = {
242 { .fw_name = "xtal" },
243 { .fw_name = "fclk_div2" },
244 { .fw_name = "fclk_div3" },
245 { .fw_name = "fclk_div5" },
249 static struct clk_regmap sys_b_sel = {
250 .data = &(struct clk_regmap_mux_data){
251 .offset = SYS_CLK_CTRL0,
254 .table = mux_table_sys,
256 .hw.init = &(struct clk_init_data){
258 .ops = &clk_regmap_mux_ro_ops,
259 .parent_data = sys_parents,
260 .num_parents = ARRAY_SIZE(sys_parents),
264 static struct clk_regmap sys_b_div = {
265 .data = &(struct clk_regmap_div_data){
266 .offset = SYS_CLK_CTRL0,
270 .hw.init = &(struct clk_init_data){
272 .ops = &clk_regmap_divider_ro_ops,
273 .parent_hws = (const struct clk_hw *[]) {
277 .flags = CLK_SET_RATE_PARENT,
281 static struct clk_regmap sys_b = {
282 .data = &(struct clk_regmap_gate_data){
283 .offset = SYS_CLK_CTRL0,
286 .hw.init = &(struct clk_init_data) {
288 .ops = &clk_regmap_gate_ro_ops,
289 .parent_hws = (const struct clk_hw *[]) {
293 .flags = CLK_SET_RATE_PARENT,
297 static struct clk_regmap sys_a_sel = {
298 .data = &(struct clk_regmap_mux_data){
299 .offset = SYS_CLK_CTRL0,
302 .table = mux_table_sys,
304 .hw.init = &(struct clk_init_data){
306 .ops = &clk_regmap_mux_ro_ops,
307 .parent_data = sys_parents,
308 .num_parents = ARRAY_SIZE(sys_parents),
312 static struct clk_regmap sys_a_div = {
313 .data = &(struct clk_regmap_div_data){
314 .offset = SYS_CLK_CTRL0,
318 .hw.init = &(struct clk_init_data){
320 .ops = &clk_regmap_divider_ro_ops,
321 .parent_hws = (const struct clk_hw *[]) {
325 .flags = CLK_SET_RATE_PARENT,
329 static struct clk_regmap sys_a = {
330 .data = &(struct clk_regmap_gate_data){
331 .offset = SYS_CLK_CTRL0,
334 .hw.init = &(struct clk_init_data) {
336 .ops = &clk_regmap_gate_ro_ops,
337 .parent_hws = (const struct clk_hw *[]) {
341 .flags = CLK_SET_RATE_PARENT,
345 static struct clk_regmap sys = {
346 .data = &(struct clk_regmap_mux_data){
347 .offset = SYS_CLK_CTRL0,
351 .hw.init = &(struct clk_init_data){
353 .ops = &clk_regmap_mux_ro_ops,
354 .parent_hws = (const struct clk_hw *[]) {
360 * This clock is used by APB bus which is set in boot ROM code
361 * and is required by the platform to operate correctly.
362 * Until the following condition are met, we need this clock to
363 * be marked as critical:
364 * a) Mark the clock used by a firmware resource, if possible
365 * b) CCF has a clock hand-off mechanism to make the sure the
366 * clock stays on until the proper driver comes along
368 .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL,
372 static u32 mux_table_dsp_ab[] = { 0, 1, 2, 3, 4, 7 };
373 static const struct clk_parent_data dsp_ab_parent_data[] = {
374 { .fw_name = "xtal", },
375 { .fw_name = "fclk_div2", },
376 { .fw_name = "fclk_div3", },
377 { .fw_name = "fclk_div5", },
378 { .fw_name = "hifi_pll", },
382 static struct clk_regmap dspa_a_sel = {
383 .data = &(struct clk_regmap_mux_data){
384 .offset = DSPA_CLK_CTRL0,
387 .table = mux_table_dsp_ab,
389 .hw.init = &(struct clk_init_data){
390 .name = "dspa_a_sel",
391 .ops = &clk_regmap_mux_ops,
392 .parent_data = dsp_ab_parent_data,
393 .num_parents = ARRAY_SIZE(dsp_ab_parent_data),
397 static struct clk_regmap dspa_a_div = {
398 .data = &(struct clk_regmap_div_data){
399 .offset = DSPA_CLK_CTRL0,
403 .hw.init = &(struct clk_init_data){
404 .name = "dspa_a_div",
405 .ops = &clk_regmap_divider_ops,
406 .parent_hws = (const struct clk_hw *[]) {
410 .flags = CLK_SET_RATE_PARENT,
414 static struct clk_regmap dspa_a = {
415 .data = &(struct clk_regmap_gate_data){
416 .offset = DSPA_CLK_CTRL0,
419 .hw.init = &(struct clk_init_data) {
421 .ops = &clk_regmap_gate_ops,
422 .parent_hws = (const struct clk_hw *[]) {
426 .flags = CLK_SET_RATE_PARENT,
430 static struct clk_regmap dspa_b_sel = {
431 .data = &(struct clk_regmap_mux_data){
432 .offset = DSPA_CLK_CTRL0,
435 .table = mux_table_dsp_ab,
437 .hw.init = &(struct clk_init_data){
438 .name = "dspa_b_sel",
439 .ops = &clk_regmap_mux_ops,
440 .parent_data = dsp_ab_parent_data,
441 .num_parents = ARRAY_SIZE(dsp_ab_parent_data),
445 static struct clk_regmap dspa_b_div = {
446 .data = &(struct clk_regmap_div_data){
447 .offset = DSPA_CLK_CTRL0,
451 .hw.init = &(struct clk_init_data){
452 .name = "dspa_b_div",
453 .ops = &clk_regmap_divider_ops,
454 .parent_hws = (const struct clk_hw *[]) {
458 .flags = CLK_SET_RATE_PARENT,
462 static struct clk_regmap dspa_b = {
463 .data = &(struct clk_regmap_gate_data){
464 .offset = DSPA_CLK_CTRL0,
467 .hw.init = &(struct clk_init_data) {
469 .ops = &clk_regmap_gate_ops,
470 .parent_hws = (const struct clk_hw *[]) {
474 .flags = CLK_SET_RATE_PARENT,
478 static struct clk_regmap dspa_sel = {
479 .data = &(struct clk_regmap_mux_data){
480 .offset = DSPA_CLK_CTRL0,
484 .hw.init = &(struct clk_init_data){
486 .ops = &clk_regmap_mux_ops,
487 .parent_hws = (const struct clk_hw *[]) {
492 .flags = CLK_SET_RATE_PARENT,
496 static struct clk_regmap dspa_en = {
497 .data = &(struct clk_regmap_gate_data){
498 .offset = DSPA_CLK_EN,
501 .hw.init = &(struct clk_init_data) {
503 .ops = &clk_regmap_gate_ops,
504 .parent_hws = (const struct clk_hw *[]) {
508 .flags = CLK_SET_RATE_PARENT,
512 static struct clk_regmap dspa_en_nic = {
513 .data = &(struct clk_regmap_gate_data){
514 .offset = DSPA_CLK_EN,
517 .hw.init = &(struct clk_init_data) {
518 .name = "dspa_en_nic",
519 .ops = &clk_regmap_gate_ops,
520 .parent_hws = (const struct clk_hw *[]) {
524 .flags = CLK_SET_RATE_PARENT,
528 static struct clk_regmap dspb_a_sel = {
529 .data = &(struct clk_regmap_mux_data){
530 .offset = DSPB_CLK_CTRL0,
533 .table = mux_table_dsp_ab,
535 .hw.init = &(struct clk_init_data){
536 .name = "dspb_a_sel",
537 .ops = &clk_regmap_mux_ops,
538 .parent_data = dsp_ab_parent_data,
539 .num_parents = ARRAY_SIZE(dsp_ab_parent_data),
543 static struct clk_regmap dspb_a_div = {
544 .data = &(struct clk_regmap_div_data){
545 .offset = DSPB_CLK_CTRL0,
549 .hw.init = &(struct clk_init_data){
550 .name = "dspb_a_div",
551 .ops = &clk_regmap_divider_ops,
552 .parent_hws = (const struct clk_hw *[]) {
556 .flags = CLK_SET_RATE_PARENT,
560 static struct clk_regmap dspb_a = {
561 .data = &(struct clk_regmap_gate_data){
562 .offset = DSPB_CLK_CTRL0,
565 .hw.init = &(struct clk_init_data) {
567 .ops = &clk_regmap_gate_ops,
568 .parent_hws = (const struct clk_hw *[]) {
572 .flags = CLK_SET_RATE_PARENT,
576 static struct clk_regmap dspb_b_sel = {
577 .data = &(struct clk_regmap_mux_data){
578 .offset = DSPB_CLK_CTRL0,
581 .table = mux_table_dsp_ab,
583 .hw.init = &(struct clk_init_data){
584 .name = "dspb_b_sel",
585 .ops = &clk_regmap_mux_ops,
586 .parent_data = dsp_ab_parent_data,
587 .num_parents = ARRAY_SIZE(dsp_ab_parent_data),
591 static struct clk_regmap dspb_b_div = {
592 .data = &(struct clk_regmap_div_data){
593 .offset = DSPB_CLK_CTRL0,
597 .hw.init = &(struct clk_init_data){
598 .name = "dspb_b_div",
599 .ops = &clk_regmap_divider_ops,
600 .parent_hws = (const struct clk_hw *[]) {
604 .flags = CLK_SET_RATE_PARENT,
608 static struct clk_regmap dspb_b = {
609 .data = &(struct clk_regmap_gate_data){
610 .offset = DSPB_CLK_CTRL0,
613 .hw.init = &(struct clk_init_data) {
615 .ops = &clk_regmap_gate_ops,
616 .parent_hws = (const struct clk_hw *[]) {
620 .flags = CLK_SET_RATE_PARENT,
624 static struct clk_regmap dspb_sel = {
625 .data = &(struct clk_regmap_mux_data){
626 .offset = DSPB_CLK_CTRL0,
630 .hw.init = &(struct clk_init_data){
632 .ops = &clk_regmap_mux_ops,
633 .parent_hws = (const struct clk_hw *[]) {
638 .flags = CLK_SET_RATE_PARENT,
642 static struct clk_regmap dspb_en = {
643 .data = &(struct clk_regmap_gate_data){
644 .offset = DSPB_CLK_EN,
647 .hw.init = &(struct clk_init_data) {
649 .ops = &clk_regmap_gate_ops,
650 .parent_hws = (const struct clk_hw *[]) {
654 .flags = CLK_SET_RATE_PARENT,
658 static struct clk_regmap dspb_en_nic = {
659 .data = &(struct clk_regmap_gate_data){
660 .offset = DSPB_CLK_EN,
663 .hw.init = &(struct clk_init_data) {
664 .name = "dspb_en_nic",
665 .ops = &clk_regmap_gate_ops,
666 .parent_hws = (const struct clk_hw *[]) {
670 .flags = CLK_SET_RATE_PARENT,
674 static struct clk_regmap clk_24m = {
675 .data = &(struct clk_regmap_gate_data){
676 .offset = CLK12_24_CTRL,
679 .hw.init = &(struct clk_init_data) {
681 .ops = &clk_regmap_gate_ops,
682 .parent_data = &(const struct clk_parent_data) {
689 static struct clk_fixed_factor clk_24m_div2 = {
692 .hw.init = &(struct clk_init_data){
694 .ops = &clk_fixed_factor_ops,
695 .parent_hws = (const struct clk_hw *[]) {
702 static struct clk_regmap clk_12m = {
703 .data = &(struct clk_regmap_gate_data){
704 .offset = CLK12_24_CTRL,
707 .hw.init = &(struct clk_init_data) {
709 .ops = &clk_regmap_gate_ops,
710 .parent_hws = (const struct clk_hw *[]) {
717 static struct clk_regmap fclk_div2_divn_pre = {
718 .data = &(struct clk_regmap_div_data){
719 .offset = CLK12_24_CTRL,
723 .hw.init = &(struct clk_init_data){
724 .name = "fclk_div2_divn_pre",
725 .ops = &clk_regmap_divider_ops,
726 .parent_data = &(const struct clk_parent_data) {
727 .fw_name = "fclk_div2",
733 static struct clk_regmap fclk_div2_divn = {
734 .data = &(struct clk_regmap_gate_data){
735 .offset = CLK12_24_CTRL,
738 .hw.init = &(struct clk_init_data){
739 .name = "fclk_div2_divn",
740 .ops = &clk_regmap_gate_ops,
741 .parent_hws = (const struct clk_hw *[]) {
742 &fclk_div2_divn_pre.hw
745 .flags = CLK_SET_RATE_PARENT,
750 * the index 2 is sys_pll_div16, it will be implemented in the CPU clock driver,
751 * the index 4 is the clock measurement source, it's not supported yet
753 static u32 gen_table[] = { 0, 1, 3, 5, 6, 7, 8 };
754 static const struct clk_parent_data gen_parent_data[] = {
755 { .fw_name = "xtal", },
757 { .fw_name = "hifi_pll", },
758 { .fw_name = "fclk_div2", },
759 { .fw_name = "fclk_div3", },
760 { .fw_name = "fclk_div5", },
761 { .fw_name = "fclk_div7", },
764 static struct clk_regmap gen_sel = {
765 .data = &(struct clk_regmap_mux_data){
766 .offset = GEN_CLK_CTRL,
771 .hw.init = &(struct clk_init_data){
773 .ops = &clk_regmap_mux_ops,
774 .parent_data = gen_parent_data,
775 .num_parents = ARRAY_SIZE(gen_parent_data),
777 * The GEN clock can be connected to an external pad, so it
778 * may be set up directly from the device tree. Additionally,
779 * the GEN clock can be inherited from a more accurate RTC
780 * clock, so in certain situations, it may be necessary
781 * to freeze its parent.
783 .flags = CLK_SET_RATE_NO_REPARENT,
787 static struct clk_regmap gen_div = {
788 .data = &(struct clk_regmap_div_data){
789 .offset = GEN_CLK_CTRL,
793 .hw.init = &(struct clk_init_data){
795 .ops = &clk_regmap_divider_ops,
796 .parent_hws = (const struct clk_hw *[]) {
800 .flags = CLK_SET_RATE_PARENT,
804 static struct clk_regmap gen = {
805 .data = &(struct clk_regmap_gate_data){
806 .offset = GEN_CLK_CTRL,
809 .hw.init = &(struct clk_init_data) {
811 .ops = &clk_regmap_gate_ops,
812 .parent_hws = (const struct clk_hw *[]) {
816 .flags = CLK_SET_RATE_PARENT,
820 static struct clk_regmap saradc_sel = {
821 .data = &(struct clk_regmap_mux_data){
822 .offset = SAR_ADC_CLK_CTRL,
826 .hw.init = &(struct clk_init_data){
827 .name = "saradc_sel",
828 .ops = &clk_regmap_mux_ops,
829 .parent_data = (const struct clk_parent_data []) {
830 { .fw_name = "xtal", },
837 static struct clk_regmap saradc_div = {
838 .data = &(struct clk_regmap_div_data){
839 .offset = SAR_ADC_CLK_CTRL,
843 .hw.init = &(struct clk_init_data){
844 .name = "saradc_div",
845 .ops = &clk_regmap_divider_ops,
846 .parent_hws = (const struct clk_hw *[]) {
850 .flags = CLK_SET_RATE_PARENT,
854 static struct clk_regmap saradc = {
855 .data = &(struct clk_regmap_gate_data){
856 .offset = SAR_ADC_CLK_CTRL,
859 .hw.init = &(struct clk_init_data) {
861 .ops = &clk_regmap_gate_ops,
862 .parent_hws = (const struct clk_hw *[]) {
866 .flags = CLK_SET_RATE_PARENT,
870 static const struct clk_parent_data pwm_abcd_parents[] = {
871 { .fw_name = "xtal", },
876 static struct clk_regmap pwm_a_sel = {
877 .data = &(struct clk_regmap_mux_data){
878 .offset = PWM_CLK_AB_CTRL,
882 .hw.init = &(struct clk_init_data){
884 .ops = &clk_regmap_mux_ops,
885 .parent_data = pwm_abcd_parents,
886 .num_parents = ARRAY_SIZE(pwm_abcd_parents),
890 static struct clk_regmap pwm_a_div = {
891 .data = &(struct clk_regmap_div_data){
892 .offset = PWM_CLK_AB_CTRL,
896 .hw.init = &(struct clk_init_data){
898 .ops = &clk_regmap_divider_ops,
899 .parent_hws = (const struct clk_hw *[]) {
903 .flags = CLK_SET_RATE_PARENT,
907 static struct clk_regmap pwm_a = {
908 .data = &(struct clk_regmap_gate_data){
909 .offset = PWM_CLK_AB_CTRL,
912 .hw.init = &(struct clk_init_data) {
914 .ops = &clk_regmap_gate_ops,
915 .parent_hws = (const struct clk_hw *[]) {
919 .flags = CLK_SET_RATE_PARENT,
923 static struct clk_regmap pwm_b_sel = {
924 .data = &(struct clk_regmap_mux_data){
925 .offset = PWM_CLK_AB_CTRL,
929 .hw.init = &(struct clk_init_data){
931 .ops = &clk_regmap_mux_ops,
932 .parent_data = pwm_abcd_parents,
933 .num_parents = ARRAY_SIZE(pwm_abcd_parents),
937 static struct clk_regmap pwm_b_div = {
938 .data = &(struct clk_regmap_div_data){
939 .offset = PWM_CLK_AB_CTRL,
943 .hw.init = &(struct clk_init_data){
945 .ops = &clk_regmap_divider_ops,
946 .parent_hws = (const struct clk_hw *[]) {
950 .flags = CLK_SET_RATE_PARENT,
954 static struct clk_regmap pwm_b = {
955 .data = &(struct clk_regmap_gate_data){
956 .offset = PWM_CLK_AB_CTRL,
959 .hw.init = &(struct clk_init_data) {
961 .ops = &clk_regmap_gate_ops,
962 .parent_hws = (const struct clk_hw *[]) {
966 .flags = CLK_SET_RATE_PARENT,
970 static struct clk_regmap pwm_c_sel = {
971 .data = &(struct clk_regmap_mux_data){
972 .offset = PWM_CLK_CD_CTRL,
976 .hw.init = &(struct clk_init_data){
978 .ops = &clk_regmap_mux_ops,
979 .parent_data = pwm_abcd_parents,
980 .num_parents = ARRAY_SIZE(pwm_abcd_parents),
984 static struct clk_regmap pwm_c_div = {
985 .data = &(struct clk_regmap_div_data){
986 .offset = PWM_CLK_CD_CTRL,
990 .hw.init = &(struct clk_init_data){
992 .ops = &clk_regmap_divider_ops,
993 .parent_hws = (const struct clk_hw *[]) {
997 .flags = CLK_SET_RATE_PARENT,
1001 static struct clk_regmap pwm_c = {
1002 .data = &(struct clk_regmap_gate_data){
1003 .offset = PWM_CLK_CD_CTRL,
1006 .hw.init = &(struct clk_init_data) {
1008 .ops = &clk_regmap_gate_ops,
1009 .parent_hws = (const struct clk_hw *[]) {
1013 .flags = CLK_SET_RATE_PARENT,
1017 static struct clk_regmap pwm_d_sel = {
1018 .data = &(struct clk_regmap_mux_data){
1019 .offset = PWM_CLK_CD_CTRL,
1023 .hw.init = &(struct clk_init_data){
1024 .name = "pwm_d_sel",
1025 .ops = &clk_regmap_mux_ops,
1026 .parent_data = pwm_abcd_parents,
1027 .num_parents = ARRAY_SIZE(pwm_abcd_parents),
1031 static struct clk_regmap pwm_d_div = {
1032 .data = &(struct clk_regmap_div_data){
1033 .offset = PWM_CLK_CD_CTRL,
1037 .hw.init = &(struct clk_init_data){
1038 .name = "pwm_d_div",
1039 .ops = &clk_regmap_divider_ops,
1040 .parent_hws = (const struct clk_hw *[]) {
1044 .flags = CLK_SET_RATE_PARENT,
1048 static struct clk_regmap pwm_d = {
1049 .data = &(struct clk_regmap_gate_data){
1050 .offset = PWM_CLK_CD_CTRL,
1053 .hw.init = &(struct clk_init_data) {
1055 .ops = &clk_regmap_gate_ops,
1056 .parent_hws = (const struct clk_hw *[]) {
1060 .flags = CLK_SET_RATE_PARENT,
1064 static const struct clk_parent_data pwm_ef_parents[] = {
1065 { .fw_name = "xtal", },
1067 { .fw_name = "fclk_div5", },
1071 static struct clk_regmap pwm_e_sel = {
1072 .data = &(struct clk_regmap_mux_data){
1073 .offset = PWM_CLK_EF_CTRL,
1077 .hw.init = &(struct clk_init_data){
1078 .name = "pwm_e_sel",
1079 .ops = &clk_regmap_mux_ops,
1080 .parent_data = pwm_ef_parents,
1081 .num_parents = ARRAY_SIZE(pwm_ef_parents),
1085 static struct clk_regmap pwm_e_div = {
1086 .data = &(struct clk_regmap_div_data){
1087 .offset = PWM_CLK_EF_CTRL,
1091 .hw.init = &(struct clk_init_data){
1092 .name = "pwm_e_div",
1093 .ops = &clk_regmap_divider_ops,
1094 .parent_hws = (const struct clk_hw *[]) {
1098 .flags = CLK_SET_RATE_PARENT,
1102 static struct clk_regmap pwm_e = {
1103 .data = &(struct clk_regmap_gate_data){
1104 .offset = PWM_CLK_EF_CTRL,
1107 .hw.init = &(struct clk_init_data) {
1109 .ops = &clk_regmap_gate_ops,
1110 .parent_hws = (const struct clk_hw *[]) {
1114 .flags = CLK_SET_RATE_PARENT,
1118 static struct clk_regmap pwm_f_sel = {
1119 .data = &(struct clk_regmap_mux_data){
1120 .offset = PWM_CLK_EF_CTRL,
1124 .hw.init = &(struct clk_init_data){
1125 .name = "pwm_f_sel",
1126 .ops = &clk_regmap_mux_ops,
1127 .parent_data = pwm_ef_parents,
1128 .num_parents = ARRAY_SIZE(pwm_ef_parents),
1132 static struct clk_regmap pwm_f_div = {
1133 .data = &(struct clk_regmap_div_data){
1134 .offset = PWM_CLK_EF_CTRL,
1138 .hw.init = &(struct clk_init_data){
1139 .name = "pwm_f_div",
1140 .ops = &clk_regmap_divider_ops,
1141 .parent_hws = (const struct clk_hw *[]) {
1145 .flags = CLK_SET_RATE_PARENT,
1149 static struct clk_regmap pwm_f = {
1150 .data = &(struct clk_regmap_gate_data){
1151 .offset = PWM_CLK_EF_CTRL,
1154 .hw.init = &(struct clk_init_data) {
1156 .ops = &clk_regmap_gate_ops,
1157 .parent_hws = (const struct clk_hw *[]) {
1161 .flags = CLK_SET_RATE_PARENT,
1168 * ---------| |---DIV--| | | | spicc out
1169 * ---------| | | |-----|GATE |---------
1170 * ..... |/ | / |_____|
1171 * --------------------|/
1174 static const struct clk_parent_data spicc_spifc_parents[] = {
1175 { .fw_name = "fclk_div2"},
1176 { .fw_name = "fclk_div3"},
1177 { .fw_name = "fclk_div5"},
1178 { .fw_name = "hifi_pll" },
1181 static struct clk_regmap spicc_sel = {
1182 .data = &(struct clk_regmap_mux_data){
1183 .offset = SPICC_CLK_CTRL,
1187 .hw.init = &(struct clk_init_data){
1188 .name = "spicc_sel",
1189 .ops = &clk_regmap_mux_ops,
1190 .parent_data = spicc_spifc_parents,
1191 .num_parents = ARRAY_SIZE(spicc_spifc_parents),
1195 static struct clk_regmap spicc_div = {
1196 .data = &(struct clk_regmap_div_data){
1197 .offset = SPICC_CLK_CTRL,
1201 .hw.init = &(struct clk_init_data){
1202 .name = "spicc_div",
1203 .ops = &clk_regmap_divider_ops,
1204 .parent_hws = (const struct clk_hw *[]) {
1208 .flags = CLK_SET_RATE_PARENT,
1212 static struct clk_regmap spicc_sel2 = {
1213 .data = &(struct clk_regmap_mux_data){
1214 .offset = SPICC_CLK_CTRL,
1218 .hw.init = &(struct clk_init_data){
1219 .name = "spicc_sel2",
1220 .ops = &clk_regmap_mux_ops,
1221 .parent_data = (const struct clk_parent_data []) {
1222 { .hw = &spicc_div.hw },
1223 { .fw_name = "xtal", },
1226 .flags = CLK_SET_RATE_PARENT,
1230 static struct clk_regmap spicc = {
1231 .data = &(struct clk_regmap_gate_data){
1232 .offset = SPICC_CLK_CTRL,
1235 .hw.init = &(struct clk_init_data) {
1237 .ops = &clk_regmap_gate_ops,
1238 .parent_hws = (const struct clk_hw *[]) {
1242 .flags = CLK_SET_RATE_PARENT,
1246 static struct clk_regmap ts_div = {
1247 .data = &(struct clk_regmap_div_data){
1248 .offset = TS_CLK_CTRL,
1252 .hw.init = &(struct clk_init_data){
1254 .ops = &clk_regmap_divider_ops,
1255 .parent_data = &(const struct clk_parent_data) {
1262 static struct clk_regmap ts = {
1263 .data = &(struct clk_regmap_gate_data){
1264 .offset = TS_CLK_CTRL,
1267 .hw.init = &(struct clk_init_data) {
1269 .ops = &clk_regmap_gate_ops,
1270 .parent_hws = (const struct clk_hw *[]) {
1274 .flags = CLK_SET_RATE_PARENT,
1278 static struct clk_regmap spifc_sel = {
1279 .data = &(struct clk_regmap_mux_data){
1280 .offset = SPIFC_CLK_CTRL,
1284 .hw.init = &(struct clk_init_data){
1285 .name = "spifc_sel",
1286 .ops = &clk_regmap_mux_ops,
1287 .parent_data = spicc_spifc_parents,
1288 .num_parents = ARRAY_SIZE(spicc_spifc_parents),
1292 static struct clk_regmap spifc_div = {
1293 .data = &(struct clk_regmap_div_data){
1294 .offset = SPIFC_CLK_CTRL,
1298 .hw.init = &(struct clk_init_data){
1299 .name = "spifc_div",
1300 .ops = &clk_regmap_divider_ops,
1301 .parent_hws = (const struct clk_hw *[]) {
1305 .flags = CLK_SET_RATE_PARENT,
1309 static struct clk_regmap spifc_sel2 = {
1310 .data = &(struct clk_regmap_mux_data){
1311 .offset = SPIFC_CLK_CTRL,
1315 .hw.init = &(struct clk_init_data){
1316 .name = "spifc_sel2",
1317 .ops = &clk_regmap_mux_ops,
1318 .parent_data = (const struct clk_parent_data []) {
1319 { .hw = &spifc_div.hw },
1320 { .fw_name = "xtal", },
1323 .flags = CLK_SET_RATE_PARENT,
1327 static struct clk_regmap spifc = {
1328 .data = &(struct clk_regmap_gate_data){
1329 .offset = SPIFC_CLK_CTRL,
1332 .hw.init = &(struct clk_init_data) {
1334 .ops = &clk_regmap_gate_ops,
1335 .parent_hws = (const struct clk_hw *[]) {
1339 .flags = CLK_SET_RATE_PARENT,
1343 static const struct clk_parent_data usb_bus_parents[] = {
1344 { .fw_name = "xtal", },
1346 { .fw_name = "fclk_div3", },
1347 { .fw_name = "fclk_div5", },
1350 static struct clk_regmap usb_bus_sel = {
1351 .data = &(struct clk_regmap_mux_data){
1352 .offset = USB_BUSCLK_CTRL,
1356 .hw.init = &(struct clk_init_data){
1357 .name = "usb_bus_sel",
1358 .ops = &clk_regmap_mux_ops,
1359 .parent_data = usb_bus_parents,
1360 .num_parents = ARRAY_SIZE(usb_bus_parents),
1361 .flags = CLK_SET_RATE_PARENT,
1365 static struct clk_regmap usb_bus_div = {
1366 .data = &(struct clk_regmap_div_data){
1367 .offset = USB_BUSCLK_CTRL,
1371 .hw.init = &(struct clk_init_data){
1372 .name = "usb_bus_div",
1373 .ops = &clk_regmap_divider_ops,
1374 .parent_hws = (const struct clk_hw *[]) {
1378 .flags = CLK_SET_RATE_PARENT,
1382 static struct clk_regmap usb_bus = {
1383 .data = &(struct clk_regmap_gate_data){
1384 .offset = USB_BUSCLK_CTRL,
1387 .hw.init = &(struct clk_init_data) {
1389 .ops = &clk_regmap_gate_ops,
1390 .parent_hws = (const struct clk_hw *[]) {
1394 .flags = CLK_SET_RATE_PARENT,
1398 static const struct clk_parent_data sd_emmc_psram_dmc_parents[] = {
1399 { .fw_name = "fclk_div2", },
1400 { .fw_name = "fclk_div3", },
1401 { .fw_name = "fclk_div5", },
1402 { .fw_name = "hifi_pll", },
1405 static struct clk_regmap sd_emmc_sel = {
1406 .data = &(struct clk_regmap_mux_data){
1407 .offset = SD_EMMC_CLK_CTRL,
1411 .hw.init = &(struct clk_init_data){
1412 .name = "sd_emmc_sel",
1413 .ops = &clk_regmap_mux_ops,
1414 .parent_data = sd_emmc_psram_dmc_parents,
1415 .num_parents = ARRAY_SIZE(sd_emmc_psram_dmc_parents),
1419 static struct clk_regmap sd_emmc_div = {
1420 .data = &(struct clk_regmap_div_data){
1421 .offset = SD_EMMC_CLK_CTRL,
1425 .hw.init = &(struct clk_init_data){
1426 .name = "sd_emmc_div",
1427 .ops = &clk_regmap_divider_ops,
1428 .parent_hws = (const struct clk_hw *[]) {
1432 .flags = CLK_SET_RATE_PARENT,
1436 static struct clk_regmap sd_emmc_sel2 = {
1437 .data = &(struct clk_regmap_mux_data){
1438 .offset = SD_EMMC_CLK_CTRL,
1442 .hw.init = &(struct clk_init_data){
1443 .name = "sd_emmc_sel2",
1444 .ops = &clk_regmap_mux_ops,
1445 .parent_data = (const struct clk_parent_data []) {
1446 { .hw = &sd_emmc_div.hw },
1447 { .fw_name = "xtal", },
1450 .flags = CLK_SET_RATE_PARENT,
1454 static struct clk_regmap sd_emmc = {
1455 .data = &(struct clk_regmap_gate_data){
1456 .offset = SD_EMMC_CLK_CTRL,
1459 .hw.init = &(struct clk_init_data) {
1461 .ops = &clk_regmap_gate_ops,
1462 .parent_hws = (const struct clk_hw *[]) {
1466 .flags = CLK_SET_RATE_PARENT,
1470 static struct clk_regmap psram_sel = {
1471 .data = &(struct clk_regmap_mux_data){
1472 .offset = PSRAM_CLK_CTRL,
1476 .hw.init = &(struct clk_init_data){
1477 .name = "psram_sel",
1478 .ops = &clk_regmap_mux_ops,
1479 .parent_data = sd_emmc_psram_dmc_parents,
1480 .num_parents = ARRAY_SIZE(sd_emmc_psram_dmc_parents),
1484 static struct clk_regmap psram_div = {
1485 .data = &(struct clk_regmap_div_data){
1486 .offset = PSRAM_CLK_CTRL,
1490 .hw.init = &(struct clk_init_data){
1491 .name = "psram_div",
1492 .ops = &clk_regmap_divider_ops,
1493 .parent_hws = (const struct clk_hw *[]) {
1497 .flags = CLK_SET_RATE_PARENT,
1501 static struct clk_regmap psram_sel2 = {
1502 .data = &(struct clk_regmap_mux_data){
1503 .offset = PSRAM_CLK_CTRL,
1507 .hw.init = &(struct clk_init_data){
1508 .name = "psram_sel2",
1509 .ops = &clk_regmap_mux_ops,
1510 .parent_data = (const struct clk_parent_data []) {
1511 { .hw = &psram_div.hw },
1512 { .fw_name = "xtal", },
1515 .flags = CLK_SET_RATE_PARENT,
1519 static struct clk_regmap psram = {
1520 .data = &(struct clk_regmap_gate_data){
1521 .offset = PSRAM_CLK_CTRL,
1524 .hw.init = &(struct clk_init_data) {
1526 .ops = &clk_regmap_gate_ops,
1527 .parent_hws = (const struct clk_hw *[]) {
1531 .flags = CLK_SET_RATE_PARENT,
1535 static struct clk_regmap dmc_sel = {
1536 .data = &(struct clk_regmap_mux_data){
1537 .offset = DMC_CLK_CTRL,
1541 .hw.init = &(struct clk_init_data){
1543 .ops = &clk_regmap_mux_ops,
1544 .parent_data = sd_emmc_psram_dmc_parents,
1545 .num_parents = ARRAY_SIZE(sd_emmc_psram_dmc_parents),
1549 static struct clk_regmap dmc_div = {
1550 .data = &(struct clk_regmap_div_data){
1551 .offset = DMC_CLK_CTRL,
1555 .hw.init = &(struct clk_init_data){
1557 .ops = &clk_regmap_divider_ops,
1558 .parent_hws = (const struct clk_hw *[]) {
1562 .flags = CLK_SET_RATE_PARENT,
1566 static struct clk_regmap dmc_sel2 = {
1567 .data = &(struct clk_regmap_mux_data){
1568 .offset = DMC_CLK_CTRL,
1572 .hw.init = &(struct clk_init_data){
1574 .ops = &clk_regmap_mux_ops,
1575 .parent_data = (const struct clk_parent_data []) {
1576 { .hw = &dmc_div.hw },
1577 { .fw_name = "xtal", },
1580 .flags = CLK_SET_RATE_PARENT,
1584 static struct clk_regmap dmc = {
1585 .data = &(struct clk_regmap_gate_data){
1586 .offset = DMC_CLK_CTRL,
1589 .hw.init = &(struct clk_init_data) {
1591 .ops = &clk_regmap_gate_ro_ops,
1592 .parent_hws = (const struct clk_hw *[]) {
1596 .flags = CLK_SET_RATE_PARENT,
1600 static struct clk_regmap ceca_32k_in = {
1601 .data = &(struct clk_regmap_gate_data){
1602 .offset = CECA_CLK_CTRL0,
1605 .hw.init = &(struct clk_init_data) {
1606 .name = "ceca_32k_in",
1607 .ops = &clk_regmap_gate_ops,
1608 .parent_data = &(const struct clk_parent_data) {
1615 static struct clk_regmap ceca_32k_div = {
1616 .data = &(struct meson_clk_dualdiv_data){
1618 .reg_off = CECA_CLK_CTRL0,
1623 .reg_off = CECA_CLK_CTRL0,
1628 .reg_off = CECA_CLK_CTRL1,
1633 .reg_off = CECA_CLK_CTRL1,
1638 .reg_off = CECA_CLK_CTRL0,
1642 .table = clk_32k_div_table,
1644 .hw.init = &(struct clk_init_data){
1645 .name = "ceca_32k_div",
1646 .ops = &meson_clk_dualdiv_ops,
1647 .parent_hws = (const struct clk_hw *[]) {
1654 static struct clk_regmap ceca_32k_sel_pre = {
1655 .data = &(struct clk_regmap_mux_data) {
1656 .offset = CECA_CLK_CTRL1,
1659 .flags = CLK_MUX_ROUND_CLOSEST,
1661 .hw.init = &(struct clk_init_data){
1662 .name = "ceca_32k_sel_pre",
1663 .ops = &clk_regmap_mux_ops,
1664 .parent_hws = (const struct clk_hw *[]) {
1669 .flags = CLK_SET_RATE_PARENT,
1673 static struct clk_regmap ceca_32k_sel = {
1674 .data = &(struct clk_regmap_mux_data) {
1675 .offset = CECA_CLK_CTRL1,
1678 .flags = CLK_MUX_ROUND_CLOSEST,
1680 .hw.init = &(struct clk_init_data){
1681 .name = "ceca_32k_sel",
1682 .ops = &clk_regmap_mux_ops,
1683 .parent_hws = (const struct clk_hw *[]) {
1684 &ceca_32k_sel_pre.hw,
1691 static struct clk_regmap ceca_32k_out = {
1692 .data = &(struct clk_regmap_gate_data){
1693 .offset = CECA_CLK_CTRL0,
1696 .hw.init = &(struct clk_init_data){
1697 .name = "ceca_32k_out",
1698 .ops = &clk_regmap_gate_ops,
1699 .parent_hws = (const struct clk_hw *[]) {
1703 .flags = CLK_SET_RATE_PARENT,
1707 static struct clk_regmap cecb_32k_in = {
1708 .data = &(struct clk_regmap_gate_data){
1709 .offset = CECB_CLK_CTRL0,
1712 .hw.init = &(struct clk_init_data) {
1713 .name = "cecb_32k_in",
1714 .ops = &clk_regmap_gate_ops,
1715 .parent_data = &(const struct clk_parent_data) {
1722 static struct clk_regmap cecb_32k_div = {
1723 .data = &(struct meson_clk_dualdiv_data){
1725 .reg_off = CECB_CLK_CTRL0,
1730 .reg_off = CECB_CLK_CTRL0,
1735 .reg_off = CECB_CLK_CTRL1,
1740 .reg_off = CECB_CLK_CTRL1,
1745 .reg_off = CECB_CLK_CTRL0,
1749 .table = clk_32k_div_table,
1751 .hw.init = &(struct clk_init_data){
1752 .name = "cecb_32k_div",
1753 .ops = &meson_clk_dualdiv_ops,
1754 .parent_hws = (const struct clk_hw *[]) {
1761 static struct clk_regmap cecb_32k_sel_pre = {
1762 .data = &(struct clk_regmap_mux_data) {
1763 .offset = CECB_CLK_CTRL1,
1766 .flags = CLK_MUX_ROUND_CLOSEST,
1768 .hw.init = &(struct clk_init_data){
1769 .name = "cecb_32k_sel_pre",
1770 .ops = &clk_regmap_mux_ops,
1771 .parent_hws = (const struct clk_hw *[]) {
1776 .flags = CLK_SET_RATE_PARENT,
1780 static struct clk_regmap cecb_32k_sel = {
1781 .data = &(struct clk_regmap_mux_data) {
1782 .offset = CECB_CLK_CTRL1,
1785 .flags = CLK_MUX_ROUND_CLOSEST,
1787 .hw.init = &(struct clk_init_data){
1788 .name = "cecb_32k_sel",
1789 .ops = &clk_regmap_mux_ops,
1790 .parent_hws = (const struct clk_hw *[]) {
1791 &cecb_32k_sel_pre.hw,
1798 static struct clk_regmap cecb_32k_out = {
1799 .data = &(struct clk_regmap_gate_data){
1800 .offset = CECB_CLK_CTRL0,
1803 .hw.init = &(struct clk_init_data){
1804 .name = "cecb_32k_out",
1805 .ops = &clk_regmap_gate_ops,
1806 .parent_hws = (const struct clk_hw *[]) {
1810 .flags = CLK_SET_RATE_PARENT,
1814 #define MESON_GATE(_name, _reg, _bit) \
1815 MESON_PCLK(_name, _reg, _bit, &sys.hw)
1817 static MESON_GATE(clktree, SYS_CLK_EN0, 0);
1818 static MESON_GATE(reset_ctrl, SYS_CLK_EN0, 1);
1819 static MESON_GATE(analog_ctrl, SYS_CLK_EN0, 2);
1820 static MESON_GATE(pwr_ctrl, SYS_CLK_EN0, 3);
1821 static MESON_GATE(pad_ctrl, SYS_CLK_EN0, 4);
1822 static MESON_GATE(sys_ctrl, SYS_CLK_EN0, 5);
1823 static MESON_GATE(temp_sensor, SYS_CLK_EN0, 6);
1824 static MESON_GATE(am2axi_dev, SYS_CLK_EN0, 7);
1825 static MESON_GATE(spicc_b, SYS_CLK_EN0, 8);
1826 static MESON_GATE(spicc_a, SYS_CLK_EN0, 9);
1827 static MESON_GATE(msr, SYS_CLK_EN0, 10);
1828 static MESON_GATE(audio, SYS_CLK_EN0, 11);
1829 static MESON_GATE(jtag_ctrl, SYS_CLK_EN0, 12);
1830 static MESON_GATE(saradc_en, SYS_CLK_EN0, 13);
1831 static MESON_GATE(pwm_ef, SYS_CLK_EN0, 14);
1832 static MESON_GATE(pwm_cd, SYS_CLK_EN0, 15);
1833 static MESON_GATE(pwm_ab, SYS_CLK_EN0, 16);
1834 static MESON_GATE(cec, SYS_CLK_EN0, 17);
1835 static MESON_GATE(i2c_s, SYS_CLK_EN0, 18);
1836 static MESON_GATE(ir_ctrl, SYS_CLK_EN0, 19);
1837 static MESON_GATE(i2c_m_d, SYS_CLK_EN0, 20);
1838 static MESON_GATE(i2c_m_c, SYS_CLK_EN0, 21);
1839 static MESON_GATE(i2c_m_b, SYS_CLK_EN0, 22);
1840 static MESON_GATE(i2c_m_a, SYS_CLK_EN0, 23);
1841 static MESON_GATE(acodec, SYS_CLK_EN0, 24);
1842 static MESON_GATE(otp, SYS_CLK_EN0, 25);
1843 static MESON_GATE(sd_emmc_a, SYS_CLK_EN0, 26);
1844 static MESON_GATE(usb_phy, SYS_CLK_EN0, 27);
1845 static MESON_GATE(usb_ctrl, SYS_CLK_EN0, 28);
1846 static MESON_GATE(sys_dspb, SYS_CLK_EN0, 29);
1847 static MESON_GATE(sys_dspa, SYS_CLK_EN0, 30);
1848 static MESON_GATE(dma, SYS_CLK_EN0, 31);
1849 static MESON_GATE(irq_ctrl, SYS_CLK_EN1, 0);
1850 static MESON_GATE(nic, SYS_CLK_EN1, 1);
1851 static MESON_GATE(gic, SYS_CLK_EN1, 2);
1852 static MESON_GATE(uart_c, SYS_CLK_EN1, 3);
1853 static MESON_GATE(uart_b, SYS_CLK_EN1, 4);
1854 static MESON_GATE(uart_a, SYS_CLK_EN1, 5);
1855 static MESON_GATE(sys_psram, SYS_CLK_EN1, 6);
1856 static MESON_GATE(rsa, SYS_CLK_EN1, 8);
1857 static MESON_GATE(coresight, SYS_CLK_EN1, 9);
1858 static MESON_GATE(am2axi_vad, AXI_CLK_EN, 0);
1859 static MESON_GATE(audio_vad, AXI_CLK_EN, 1);
1860 static MESON_GATE(axi_dmc, AXI_CLK_EN, 3);
1861 static MESON_GATE(axi_psram, AXI_CLK_EN, 4);
1862 static MESON_GATE(ramb, AXI_CLK_EN, 5);
1863 static MESON_GATE(rama, AXI_CLK_EN, 6);
1864 static MESON_GATE(axi_spifc, AXI_CLK_EN, 7);
1865 static MESON_GATE(axi_nic, AXI_CLK_EN, 8);
1866 static MESON_GATE(axi_dma, AXI_CLK_EN, 9);
1867 static MESON_GATE(cpu_ctrl, AXI_CLK_EN, 10);
1868 static MESON_GATE(rom, AXI_CLK_EN, 11);
1869 static MESON_GATE(prod_i2c, AXI_CLK_EN, 12);
1871 /* Array of all clocks registered by this provider */
1872 static struct clk_hw *a1_periphs_hw_clks[] = {
1873 [CLKID_XTAL_IN] = &xtal_in.hw,
1874 [CLKID_FIXPLL_IN] = &fixpll_in.hw,
1875 [CLKID_USB_PHY_IN] = &usb_phy_in.hw,
1876 [CLKID_USB_CTRL_IN] = &usb_ctrl_in.hw,
1877 [CLKID_HIFIPLL_IN] = &hifipll_in.hw,
1878 [CLKID_SYSPLL_IN] = &syspll_in.hw,
1879 [CLKID_DDS_IN] = &dds_in.hw,
1880 [CLKID_SYS] = &sys.hw,
1881 [CLKID_CLKTREE] = &clktree.hw,
1882 [CLKID_RESET_CTRL] = &reset_ctrl.hw,
1883 [CLKID_ANALOG_CTRL] = &analog_ctrl.hw,
1884 [CLKID_PWR_CTRL] = &pwr_ctrl.hw,
1885 [CLKID_PAD_CTRL] = &pad_ctrl.hw,
1886 [CLKID_SYS_CTRL] = &sys_ctrl.hw,
1887 [CLKID_TEMP_SENSOR] = &temp_sensor.hw,
1888 [CLKID_AM2AXI_DIV] = &am2axi_dev.hw,
1889 [CLKID_SPICC_B] = &spicc_b.hw,
1890 [CLKID_SPICC_A] = &spicc_a.hw,
1891 [CLKID_MSR] = &msr.hw,
1892 [CLKID_AUDIO] = &audio.hw,
1893 [CLKID_JTAG_CTRL] = &jtag_ctrl.hw,
1894 [CLKID_SARADC_EN] = &saradc_en.hw,
1895 [CLKID_PWM_EF] = &pwm_ef.hw,
1896 [CLKID_PWM_CD] = &pwm_cd.hw,
1897 [CLKID_PWM_AB] = &pwm_ab.hw,
1898 [CLKID_CEC] = &cec.hw,
1899 [CLKID_I2C_S] = &i2c_s.hw,
1900 [CLKID_IR_CTRL] = &ir_ctrl.hw,
1901 [CLKID_I2C_M_D] = &i2c_m_d.hw,
1902 [CLKID_I2C_M_C] = &i2c_m_c.hw,
1903 [CLKID_I2C_M_B] = &i2c_m_b.hw,
1904 [CLKID_I2C_M_A] = &i2c_m_a.hw,
1905 [CLKID_ACODEC] = &acodec.hw,
1906 [CLKID_OTP] = &otp.hw,
1907 [CLKID_SD_EMMC_A] = &sd_emmc_a.hw,
1908 [CLKID_USB_PHY] = &usb_phy.hw,
1909 [CLKID_USB_CTRL] = &usb_ctrl.hw,
1910 [CLKID_SYS_DSPB] = &sys_dspb.hw,
1911 [CLKID_SYS_DSPA] = &sys_dspa.hw,
1912 [CLKID_DMA] = &dma.hw,
1913 [CLKID_IRQ_CTRL] = &irq_ctrl.hw,
1914 [CLKID_NIC] = &nic.hw,
1915 [CLKID_GIC] = &gic.hw,
1916 [CLKID_UART_C] = &uart_c.hw,
1917 [CLKID_UART_B] = &uart_b.hw,
1918 [CLKID_UART_A] = &uart_a.hw,
1919 [CLKID_SYS_PSRAM] = &sys_psram.hw,
1920 [CLKID_RSA] = &rsa.hw,
1921 [CLKID_CORESIGHT] = &coresight.hw,
1922 [CLKID_AM2AXI_VAD] = &am2axi_vad.hw,
1923 [CLKID_AUDIO_VAD] = &audio_vad.hw,
1924 [CLKID_AXI_DMC] = &axi_dmc.hw,
1925 [CLKID_AXI_PSRAM] = &axi_psram.hw,
1926 [CLKID_RAMB] = &ramb.hw,
1927 [CLKID_RAMA] = &rama.hw,
1928 [CLKID_AXI_SPIFC] = &axi_spifc.hw,
1929 [CLKID_AXI_NIC] = &axi_nic.hw,
1930 [CLKID_AXI_DMA] = &axi_dma.hw,
1931 [CLKID_CPU_CTRL] = &cpu_ctrl.hw,
1932 [CLKID_ROM] = &rom.hw,
1933 [CLKID_PROC_I2C] = &prod_i2c.hw,
1934 [CLKID_DSPA_SEL] = &dspa_sel.hw,
1935 [CLKID_DSPB_SEL] = &dspb_sel.hw,
1936 [CLKID_DSPA_EN] = &dspa_en.hw,
1937 [CLKID_DSPA_EN_NIC] = &dspa_en_nic.hw,
1938 [CLKID_DSPB_EN] = &dspb_en.hw,
1939 [CLKID_DSPB_EN_NIC] = &dspb_en_nic.hw,
1940 [CLKID_RTC] = &rtc.hw,
1941 [CLKID_CECA_32K] = &ceca_32k_out.hw,
1942 [CLKID_CECB_32K] = &cecb_32k_out.hw,
1943 [CLKID_24M] = &clk_24m.hw,
1944 [CLKID_12M] = &clk_12m.hw,
1945 [CLKID_FCLK_DIV2_DIVN] = &fclk_div2_divn.hw,
1946 [CLKID_GEN] = &gen.hw,
1947 [CLKID_SARADC_SEL] = &saradc_sel.hw,
1948 [CLKID_SARADC] = &saradc.hw,
1949 [CLKID_PWM_A] = &pwm_a.hw,
1950 [CLKID_PWM_B] = &pwm_b.hw,
1951 [CLKID_PWM_C] = &pwm_c.hw,
1952 [CLKID_PWM_D] = &pwm_d.hw,
1953 [CLKID_PWM_E] = &pwm_e.hw,
1954 [CLKID_PWM_F] = &pwm_f.hw,
1955 [CLKID_SPICC] = &spicc.hw,
1956 [CLKID_TS] = &ts.hw,
1957 [CLKID_SPIFC] = &spifc.hw,
1958 [CLKID_USB_BUS] = &usb_bus.hw,
1959 [CLKID_SD_EMMC] = &sd_emmc.hw,
1960 [CLKID_PSRAM] = &psram.hw,
1961 [CLKID_DMC] = &dmc.hw,
1962 [CLKID_SYS_A_SEL] = &sys_a_sel.hw,
1963 [CLKID_SYS_A_DIV] = &sys_a_div.hw,
1964 [CLKID_SYS_A] = &sys_a.hw,
1965 [CLKID_SYS_B_SEL] = &sys_b_sel.hw,
1966 [CLKID_SYS_B_DIV] = &sys_b_div.hw,
1967 [CLKID_SYS_B] = &sys_b.hw,
1968 [CLKID_DSPA_A_SEL] = &dspa_a_sel.hw,
1969 [CLKID_DSPA_A_DIV] = &dspa_a_div.hw,
1970 [CLKID_DSPA_A] = &dspa_a.hw,
1971 [CLKID_DSPA_B_SEL] = &dspa_b_sel.hw,
1972 [CLKID_DSPA_B_DIV] = &dspa_b_div.hw,
1973 [CLKID_DSPA_B] = &dspa_b.hw,
1974 [CLKID_DSPB_A_SEL] = &dspb_a_sel.hw,
1975 [CLKID_DSPB_A_DIV] = &dspb_a_div.hw,
1976 [CLKID_DSPB_A] = &dspb_a.hw,
1977 [CLKID_DSPB_B_SEL] = &dspb_b_sel.hw,
1978 [CLKID_DSPB_B_DIV] = &dspb_b_div.hw,
1979 [CLKID_DSPB_B] = &dspb_b.hw,
1980 [CLKID_RTC_32K_IN] = &rtc_32k_in.hw,
1981 [CLKID_RTC_32K_DIV] = &rtc_32k_div.hw,
1982 [CLKID_RTC_32K_XTAL] = &rtc_32k_xtal.hw,
1983 [CLKID_RTC_32K_SEL] = &rtc_32k_sel.hw,
1984 [CLKID_CECB_32K_IN] = &cecb_32k_in.hw,
1985 [CLKID_CECB_32K_DIV] = &cecb_32k_div.hw,
1986 [CLKID_CECB_32K_SEL_PRE] = &cecb_32k_sel_pre.hw,
1987 [CLKID_CECB_32K_SEL] = &cecb_32k_sel.hw,
1988 [CLKID_CECA_32K_IN] = &ceca_32k_in.hw,
1989 [CLKID_CECA_32K_DIV] = &ceca_32k_div.hw,
1990 [CLKID_CECA_32K_SEL_PRE] = &ceca_32k_sel_pre.hw,
1991 [CLKID_CECA_32K_SEL] = &ceca_32k_sel.hw,
1992 [CLKID_DIV2_PRE] = &fclk_div2_divn_pre.hw,
1993 [CLKID_24M_DIV2] = &clk_24m_div2.hw,
1994 [CLKID_GEN_SEL] = &gen_sel.hw,
1995 [CLKID_GEN_DIV] = &gen_div.hw,
1996 [CLKID_SARADC_DIV] = &saradc_div.hw,
1997 [CLKID_PWM_A_SEL] = &pwm_a_sel.hw,
1998 [CLKID_PWM_A_DIV] = &pwm_a_div.hw,
1999 [CLKID_PWM_B_SEL] = &pwm_b_sel.hw,
2000 [CLKID_PWM_B_DIV] = &pwm_b_div.hw,
2001 [CLKID_PWM_C_SEL] = &pwm_c_sel.hw,
2002 [CLKID_PWM_C_DIV] = &pwm_c_div.hw,
2003 [CLKID_PWM_D_SEL] = &pwm_d_sel.hw,
2004 [CLKID_PWM_D_DIV] = &pwm_d_div.hw,
2005 [CLKID_PWM_E_SEL] = &pwm_e_sel.hw,
2006 [CLKID_PWM_E_DIV] = &pwm_e_div.hw,
2007 [CLKID_PWM_F_SEL] = &pwm_f_sel.hw,
2008 [CLKID_PWM_F_DIV] = &pwm_f_div.hw,
2009 [CLKID_SPICC_SEL] = &spicc_sel.hw,
2010 [CLKID_SPICC_DIV] = &spicc_div.hw,
2011 [CLKID_SPICC_SEL2] = &spicc_sel2.hw,
2012 [CLKID_TS_DIV] = &ts_div.hw,
2013 [CLKID_SPIFC_SEL] = &spifc_sel.hw,
2014 [CLKID_SPIFC_DIV] = &spifc_div.hw,
2015 [CLKID_SPIFC_SEL2] = &spifc_sel2.hw,
2016 [CLKID_USB_BUS_SEL] = &usb_bus_sel.hw,
2017 [CLKID_USB_BUS_DIV] = &usb_bus_div.hw,
2018 [CLKID_SD_EMMC_SEL] = &sd_emmc_sel.hw,
2019 [CLKID_SD_EMMC_DIV] = &sd_emmc_div.hw,
2020 [CLKID_SD_EMMC_SEL2] = &sd_emmc_sel2.hw,
2021 [CLKID_PSRAM_SEL] = &psram_sel.hw,
2022 [CLKID_PSRAM_DIV] = &psram_div.hw,
2023 [CLKID_PSRAM_SEL2] = &psram_sel2.hw,
2024 [CLKID_DMC_SEL] = &dmc_sel.hw,
2025 [CLKID_DMC_DIV] = &dmc_div.hw,
2026 [CLKID_DMC_SEL2] = &dmc_sel2.hw,
2029 /* Convenience table to populate regmap in .probe */
2030 static struct clk_regmap *const a1_periphs_regmaps[] = {
2150 &fclk_div2_divn_pre,
2186 static struct regmap_config a1_periphs_regmap_cfg = {
2192 static struct meson_clk_hw_data a1_periphs_clks = {
2193 .hws = a1_periphs_hw_clks,
2194 .num = ARRAY_SIZE(a1_periphs_hw_clks),
2197 static int meson_a1_periphs_probe(struct platform_device *pdev)
2199 struct device *dev = &pdev->dev;
2204 base = devm_platform_ioremap_resource(pdev, 0);
2206 return dev_err_probe(dev, PTR_ERR(base),
2207 "can't ioremap resource\n");
2209 map = devm_regmap_init_mmio(dev, base, &a1_periphs_regmap_cfg);
2211 return dev_err_probe(dev, PTR_ERR(map),
2212 "can't init regmap mmio region\n");
2214 /* Populate regmap for the regmap backed clocks */
2215 for (i = 0; i < ARRAY_SIZE(a1_periphs_regmaps); i++)
2216 a1_periphs_regmaps[i]->map = map;
2218 for (clkid = 0; clkid < a1_periphs_clks.num; clkid++) {
2219 err = devm_clk_hw_register(dev, a1_periphs_clks.hws[clkid]);
2221 return dev_err_probe(dev, err,
2222 "clock[%d] registration failed\n",
2226 return devm_of_clk_add_hw_provider(dev, meson_clk_hw_get, &a1_periphs_clks);
2229 static const struct of_device_id a1_periphs_clkc_match_table[] = {
2230 { .compatible = "amlogic,a1-peripherals-clkc", },
2233 MODULE_DEVICE_TABLE(of, a1_periphs_clkc_match_table);
2235 static struct platform_driver a1_periphs_clkc_driver = {
2236 .probe = meson_a1_periphs_probe,
2238 .name = "a1-peripherals-clkc",
2239 .of_match_table = a1_periphs_clkc_match_table,
2243 module_platform_driver(a1_periphs_clkc_driver);
2244 MODULE_AUTHOR("Jian Hu <jian.hu@amlogic.com>");
2245 MODULE_AUTHOR("Dmitry Rokosov <ddrokosov@sberdevices.ru>");
2246 MODULE_LICENSE("GPL");