1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
4 * Author: Jian Hu <jian.hu@amlogic.com>
5 *
6 * Copyright (c) 2023, SberDevices. All Rights Reserved.
7 * Author: Dmitry Rokosov <ddrokosov@sberdevices.ru>
8 */
9
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"
17
18#include <dt-bindings/clock/amlogic,a1-peripherals-clkc.h>
19
20static struct clk_regmap xtal_in = {
21	.data = &(struct clk_regmap_gate_data){
22		.offset = SYS_OSCIN_CTRL,
23		.bit_idx = 0,
24	},
25	.hw.init = &(struct clk_init_data) {
26		.name = "xtal_in",
27		.ops = &clk_regmap_gate_ro_ops,
28		.parent_data = &(const struct clk_parent_data) {
29			.fw_name = "xtal",
30		},
31		.num_parents = 1,
32	},
33};
34
35static struct clk_regmap fixpll_in = {
36	.data = &(struct clk_regmap_gate_data){
37		.offset = SYS_OSCIN_CTRL,
38		.bit_idx = 1,
39	},
40	.hw.init = &(struct clk_init_data) {
41		.name = "fixpll_in",
42		.ops = &clk_regmap_gate_ro_ops,
43		.parent_data = &(const struct clk_parent_data) {
44			.fw_name = "xtal",
45		},
46		.num_parents = 1,
47	},
48};
49
50static struct clk_regmap usb_phy_in = {
51	.data = &(struct clk_regmap_gate_data){
52		.offset = SYS_OSCIN_CTRL,
53		.bit_idx = 2,
54	},
55	.hw.init = &(struct clk_init_data) {
56		.name = "usb_phy_in",
57		.ops = &clk_regmap_gate_ops,
58		.parent_data = &(const struct clk_parent_data) {
59			.fw_name = "xtal",
60		},
61		.num_parents = 1,
62	},
63};
64
65static struct clk_regmap usb_ctrl_in = {
66	.data = &(struct clk_regmap_gate_data){
67		.offset = SYS_OSCIN_CTRL,
68		.bit_idx = 3,
69	},
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) {
74			.fw_name = "xtal",
75		},
76		.num_parents = 1,
77	},
78};
79
80static struct clk_regmap hifipll_in = {
81	.data = &(struct clk_regmap_gate_data){
82		.offset = SYS_OSCIN_CTRL,
83		.bit_idx = 4,
84	},
85	.hw.init = &(struct clk_init_data) {
86		.name = "hifipll_in",
87		.ops = &clk_regmap_gate_ops,
88		.parent_data = &(const struct clk_parent_data) {
89			.fw_name = "xtal",
90		},
91		.num_parents = 1,
92	},
93};
94
95static struct clk_regmap syspll_in = {
96	.data = &(struct clk_regmap_gate_data){
97		.offset = SYS_OSCIN_CTRL,
98		.bit_idx = 5,
99	},
100	.hw.init = &(struct clk_init_data) {
101		.name = "syspll_in",
102		.ops = &clk_regmap_gate_ops,
103		.parent_data = &(const struct clk_parent_data) {
104			.fw_name = "xtal",
105		},
106		.num_parents = 1,
107	},
108};
109
110static struct clk_regmap dds_in = {
111	.data = &(struct clk_regmap_gate_data){
112		.offset = SYS_OSCIN_CTRL,
113		.bit_idx = 6,
114	},
115	.hw.init = &(struct clk_init_data) {
116		.name = "dds_in",
117		.ops = &clk_regmap_gate_ops,
118		.parent_data = &(const struct clk_parent_data) {
119			.fw_name = "xtal",
120		},
121		.num_parents = 1,
122	},
123};
124
125static struct clk_regmap rtc_32k_in = {
126	.data = &(struct clk_regmap_gate_data){
127		.offset = RTC_BY_OSCIN_CTRL0,
128		.bit_idx = 31,
129	},
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) {
134			.fw_name = "xtal",
135		},
136		.num_parents = 1,
137	},
138};
139
140static const struct meson_clk_dualdiv_param clk_32k_div_table[] = {
141	{
142		.dual		= 1,
143		.n1		= 733,
144		.m1		= 8,
145		.n2		= 732,
146		.m2		= 11,
147	},
148	{}
149};
150
151static struct clk_regmap rtc_32k_div = {
152	.data = &(struct meson_clk_dualdiv_data){
153		.n1 = {
154			.reg_off = RTC_BY_OSCIN_CTRL0,
155			.shift   = 0,
156			.width   = 12,
157		},
158		.n2 = {
159			.reg_off = RTC_BY_OSCIN_CTRL0,
160			.shift   = 12,
161			.width   = 12,
162		},
163		.m1 = {
164			.reg_off = RTC_BY_OSCIN_CTRL1,
165			.shift   = 0,
166			.width   = 12,
167		},
168		.m2 = {
169			.reg_off = RTC_BY_OSCIN_CTRL1,
170			.shift   = 12,
171			.width   = 12,
172		},
173		.dual = {
174			.reg_off = RTC_BY_OSCIN_CTRL0,
175			.shift   = 28,
176			.width   = 1,
177		},
178		.table = clk_32k_div_table,
179	},
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 *[]) {
184			&rtc_32k_in.hw
185		},
186		.num_parents = 1,
187	},
188};
189
190static struct clk_regmap rtc_32k_xtal = {
191	.data = &(struct clk_regmap_gate_data){
192		.offset = RTC_BY_OSCIN_CTRL1,
193		.bit_idx = 24,
194	},
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 *[]) {
199			&rtc_32k_in.hw
200		},
201		.num_parents = 1,
202	},
203};
204
205static struct clk_regmap rtc_32k_sel = {
206	.data = &(struct clk_regmap_mux_data) {
207		.offset = RTC_CTRL,
208		.mask = 0x3,
209		.shift = 0,
210		.flags = CLK_MUX_ROUND_CLOSEST,
211	},
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 *[]) {
216			&rtc_32k_xtal.hw,
217			&rtc_32k_div.hw,
218		},
219		.num_parents = 2,
220		.flags = CLK_SET_RATE_PARENT,
221	},
222};
223
224static struct clk_regmap rtc = {
225	.data = &(struct clk_regmap_gate_data){
226		.offset = RTC_BY_OSCIN_CTRL0,
227		.bit_idx = 30,
228	},
229	.hw.init = &(struct clk_init_data){
230		.name = "rtc",
231		.ops = &clk_regmap_gate_ops,
232		.parent_hws = (const struct clk_hw *[]) {
233			&rtc_32k_sel.hw
234		},
235		.num_parents = 1,
236		.flags = CLK_SET_RATE_PARENT,
237	},
238};
239
240static u32 mux_table_sys[] = { 0, 1, 2, 3, 7 };
241static 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" },
246	{ .hw = &rtc.hw },
247};
248
249static struct clk_regmap sys_b_sel = {
250	.data = &(struct clk_regmap_mux_data){
251		.offset = SYS_CLK_CTRL0,
252		.mask = 0x7,
253		.shift = 26,
254		.table = mux_table_sys,
255	},
256	.hw.init = &(struct clk_init_data){
257		.name = "sys_b_sel",
258		.ops = &clk_regmap_mux_ro_ops,
259		.parent_data = sys_parents,
260		.num_parents = ARRAY_SIZE(sys_parents),
261	},
262};
263
264static struct clk_regmap sys_b_div = {
265	.data = &(struct clk_regmap_div_data){
266		.offset = SYS_CLK_CTRL0,
267		.shift = 16,
268		.width = 10,
269	},
270	.hw.init = &(struct clk_init_data){
271		.name = "sys_b_div",
272		.ops = &clk_regmap_divider_ro_ops,
273		.parent_hws = (const struct clk_hw *[]) {
274			&sys_b_sel.hw
275		},
276		.num_parents = 1,
277		.flags = CLK_SET_RATE_PARENT,
278	},
279};
280
281static struct clk_regmap sys_b = {
282	.data = &(struct clk_regmap_gate_data){
283		.offset = SYS_CLK_CTRL0,
284		.bit_idx = 29,
285	},
286	.hw.init = &(struct clk_init_data) {
287		.name = "sys_b",
288		.ops = &clk_regmap_gate_ro_ops,
289		.parent_hws = (const struct clk_hw *[]) {
290			&sys_b_div.hw
291		},
292		.num_parents = 1,
293		.flags = CLK_SET_RATE_PARENT,
294	},
295};
296
297static struct clk_regmap sys_a_sel = {
298	.data = &(struct clk_regmap_mux_data){
299		.offset = SYS_CLK_CTRL0,
300		.mask = 0x7,
301		.shift = 10,
302		.table = mux_table_sys,
303	},
304	.hw.init = &(struct clk_init_data){
305		.name = "sys_a_sel",
306		.ops = &clk_regmap_mux_ro_ops,
307		.parent_data = sys_parents,
308		.num_parents = ARRAY_SIZE(sys_parents),
309	},
310};
311
312static struct clk_regmap sys_a_div = {
313	.data = &(struct clk_regmap_div_data){
314		.offset = SYS_CLK_CTRL0,
315		.shift = 0,
316		.width = 10,
317	},
318	.hw.init = &(struct clk_init_data){
319		.name = "sys_a_div",
320		.ops = &clk_regmap_divider_ro_ops,
321		.parent_hws = (const struct clk_hw *[]) {
322			&sys_a_sel.hw
323		},
324		.num_parents = 1,
325		.flags = CLK_SET_RATE_PARENT,
326	},
327};
328
329static struct clk_regmap sys_a = {
330	.data = &(struct clk_regmap_gate_data){
331		.offset = SYS_CLK_CTRL0,
332		.bit_idx = 13,
333	},
334	.hw.init = &(struct clk_init_data) {
335		.name = "sys_a",
336		.ops = &clk_regmap_gate_ro_ops,
337		.parent_hws = (const struct clk_hw *[]) {
338			&sys_a_div.hw
339		},
340		.num_parents = 1,
341		.flags = CLK_SET_RATE_PARENT,
342	},
343};
344
345static struct clk_regmap sys = {
346	.data = &(struct clk_regmap_mux_data){
347		.offset = SYS_CLK_CTRL0,
348		.mask = 0x1,
349		.shift = 31,
350	},
351	.hw.init = &(struct clk_init_data){
352		.name = "sys",
353		.ops = &clk_regmap_mux_ro_ops,
354		.parent_hws = (const struct clk_hw *[]) {
355			&sys_a.hw,
356			&sys_b.hw,
357		},
358		.num_parents = 2,
359		/*
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
367		 */
368		.flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL,
369	},
370};
371
372static u32 mux_table_dsp_ab[] = { 0, 1, 2, 3, 4, 7 };
373static 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", },
379	{ .hw = &rtc.hw },
380};
381
382static struct clk_regmap dspa_a_sel = {
383	.data = &(struct clk_regmap_mux_data){
384		.offset = DSPA_CLK_CTRL0,
385		.mask = 0x7,
386		.shift = 10,
387		.table = mux_table_dsp_ab,
388	},
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),
394	},
395};
396
397static struct clk_regmap dspa_a_div = {
398	.data = &(struct clk_regmap_div_data){
399		.offset = DSPA_CLK_CTRL0,
400		.shift = 0,
401		.width = 10,
402	},
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 *[]) {
407			&dspa_a_sel.hw
408		},
409		.num_parents = 1,
410		.flags = CLK_SET_RATE_PARENT,
411	},
412};
413
414static struct clk_regmap dspa_a = {
415	.data = &(struct clk_regmap_gate_data){
416		.offset = DSPA_CLK_CTRL0,
417		.bit_idx = 13,
418	},
419	.hw.init = &(struct clk_init_data) {
420		.name = "dspa_a",
421		.ops = &clk_regmap_gate_ops,
422		.parent_hws = (const struct clk_hw *[]) {
423			&dspa_a_div.hw
424		},
425		.num_parents = 1,
426		.flags = CLK_SET_RATE_PARENT,
427	},
428};
429
430static struct clk_regmap dspa_b_sel = {
431	.data = &(struct clk_regmap_mux_data){
432		.offset = DSPA_CLK_CTRL0,
433		.mask = 0x7,
434		.shift = 26,
435		.table = mux_table_dsp_ab,
436	},
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),
442	},
443};
444
445static struct clk_regmap dspa_b_div = {
446	.data = &(struct clk_regmap_div_data){
447		.offset = DSPA_CLK_CTRL0,
448		.shift = 16,
449		.width = 10,
450	},
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 *[]) {
455			&dspa_b_sel.hw
456		},
457		.num_parents = 1,
458		.flags = CLK_SET_RATE_PARENT,
459	},
460};
461
462static struct clk_regmap dspa_b = {
463	.data = &(struct clk_regmap_gate_data){
464		.offset = DSPA_CLK_CTRL0,
465		.bit_idx = 29,
466	},
467	.hw.init = &(struct clk_init_data) {
468		.name = "dspa_b",
469		.ops = &clk_regmap_gate_ops,
470		.parent_hws = (const struct clk_hw *[]) {
471			&dspa_b_div.hw
472		},
473		.num_parents = 1,
474		.flags = CLK_SET_RATE_PARENT,
475	},
476};
477
478static struct clk_regmap dspa_sel = {
479	.data = &(struct clk_regmap_mux_data){
480		.offset = DSPA_CLK_CTRL0,
481		.mask = 0x1,
482		.shift = 15,
483	},
484	.hw.init = &(struct clk_init_data){
485		.name = "dspa_sel",
486		.ops = &clk_regmap_mux_ops,
487		.parent_hws = (const struct clk_hw *[]) {
488			&dspa_a.hw,
489			&dspa_b.hw,
490		},
491		.num_parents = 2,
492		.flags = CLK_SET_RATE_PARENT,
493	},
494};
495
496static struct clk_regmap dspa_en = {
497	.data = &(struct clk_regmap_gate_data){
498		.offset = DSPA_CLK_EN,
499		.bit_idx = 1,
500	},
501	.hw.init = &(struct clk_init_data) {
502		.name = "dspa_en",
503		.ops = &clk_regmap_gate_ops,
504		.parent_hws = (const struct clk_hw *[]) {
505			&dspa_sel.hw
506		},
507		.num_parents = 1,
508		.flags = CLK_SET_RATE_PARENT,
509	},
510};
511
512static struct clk_regmap dspa_en_nic = {
513	.data = &(struct clk_regmap_gate_data){
514		.offset = DSPA_CLK_EN,
515		.bit_idx = 0,
516	},
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 *[]) {
521			&dspa_sel.hw
522		},
523		.num_parents = 1,
524		.flags = CLK_SET_RATE_PARENT,
525	},
526};
527
528static struct clk_regmap dspb_a_sel = {
529	.data = &(struct clk_regmap_mux_data){
530		.offset = DSPB_CLK_CTRL0,
531		.mask = 0x7,
532		.shift = 10,
533		.table = mux_table_dsp_ab,
534	},
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),
540	},
541};
542
543static struct clk_regmap dspb_a_div = {
544	.data = &(struct clk_regmap_div_data){
545		.offset = DSPB_CLK_CTRL0,
546		.shift = 0,
547		.width = 10,
548	},
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 *[]) {
553			&dspb_a_sel.hw
554		},
555		.num_parents = 1,
556		.flags = CLK_SET_RATE_PARENT,
557	},
558};
559
560static struct clk_regmap dspb_a = {
561	.data = &(struct clk_regmap_gate_data){
562		.offset = DSPB_CLK_CTRL0,
563		.bit_idx = 13,
564	},
565	.hw.init = &(struct clk_init_data) {
566		.name = "dspb_a",
567		.ops = &clk_regmap_gate_ops,
568		.parent_hws = (const struct clk_hw *[]) {
569			&dspb_a_div.hw
570		},
571		.num_parents = 1,
572		.flags = CLK_SET_RATE_PARENT,
573	},
574};
575
576static struct clk_regmap dspb_b_sel = {
577	.data = &(struct clk_regmap_mux_data){
578		.offset = DSPB_CLK_CTRL0,
579		.mask = 0x7,
580		.shift = 26,
581		.table = mux_table_dsp_ab,
582	},
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),
588	},
589};
590
591static struct clk_regmap dspb_b_div = {
592	.data = &(struct clk_regmap_div_data){
593		.offset = DSPB_CLK_CTRL0,
594		.shift = 16,
595		.width = 10,
596	},
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 *[]) {
601			&dspb_b_sel.hw
602		},
603		.num_parents = 1,
604		.flags = CLK_SET_RATE_PARENT,
605	},
606};
607
608static struct clk_regmap dspb_b = {
609	.data = &(struct clk_regmap_gate_data){
610		.offset = DSPB_CLK_CTRL0,
611		.bit_idx = 29,
612	},
613	.hw.init = &(struct clk_init_data) {
614		.name = "dspb_b",
615		.ops = &clk_regmap_gate_ops,
616		.parent_hws = (const struct clk_hw *[]) {
617			&dspb_b_div.hw
618		},
619		.num_parents = 1,
620		.flags = CLK_SET_RATE_PARENT,
621	},
622};
623
624static struct clk_regmap dspb_sel = {
625	.data = &(struct clk_regmap_mux_data){
626		.offset = DSPB_CLK_CTRL0,
627		.mask = 0x1,
628		.shift = 15,
629	},
630	.hw.init = &(struct clk_init_data){
631		.name = "dspb_sel",
632		.ops = &clk_regmap_mux_ops,
633		.parent_hws = (const struct clk_hw *[]) {
634			&dspb_a.hw,
635			&dspb_b.hw,
636		},
637		.num_parents = 2,
638		.flags = CLK_SET_RATE_PARENT,
639	},
640};
641
642static struct clk_regmap dspb_en = {
643	.data = &(struct clk_regmap_gate_data){
644		.offset = DSPB_CLK_EN,
645		.bit_idx = 1,
646	},
647	.hw.init = &(struct clk_init_data) {
648		.name = "dspb_en",
649		.ops = &clk_regmap_gate_ops,
650		.parent_hws = (const struct clk_hw *[]) {
651			&dspb_sel.hw
652		},
653		.num_parents = 1,
654		.flags = CLK_SET_RATE_PARENT,
655	},
656};
657
658static struct clk_regmap dspb_en_nic = {
659	.data = &(struct clk_regmap_gate_data){
660		.offset = DSPB_CLK_EN,
661		.bit_idx = 0,
662	},
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 *[]) {
667			&dspb_sel.hw
668		},
669		.num_parents = 1,
670		.flags = CLK_SET_RATE_PARENT,
671	},
672};
673
674static struct clk_regmap clk_24m = {
675	.data = &(struct clk_regmap_gate_data){
676		.offset = CLK12_24_CTRL,
677		.bit_idx = 11,
678	},
679	.hw.init = &(struct clk_init_data) {
680		.name = "24m",
681		.ops = &clk_regmap_gate_ops,
682		.parent_data = &(const struct clk_parent_data) {
683			.fw_name = "xtal",
684		},
685		.num_parents = 1,
686	},
687};
688
689static struct clk_fixed_factor clk_24m_div2 = {
690	.mult = 1,
691	.div = 2,
692	.hw.init = &(struct clk_init_data){
693		.name = "24m_div2",
694		.ops = &clk_fixed_factor_ops,
695		.parent_hws = (const struct clk_hw *[]) {
696			&clk_24m.hw
697		},
698		.num_parents = 1,
699	},
700};
701
702static struct clk_regmap clk_12m = {
703	.data = &(struct clk_regmap_gate_data){
704		.offset = CLK12_24_CTRL,
705		.bit_idx = 10,
706	},
707	.hw.init = &(struct clk_init_data) {
708		.name = "12m",
709		.ops = &clk_regmap_gate_ops,
710		.parent_hws = (const struct clk_hw *[]) {
711			&clk_24m_div2.hw
712		},
713		.num_parents = 1,
714	},
715};
716
717static struct clk_regmap fclk_div2_divn_pre = {
718	.data = &(struct clk_regmap_div_data){
719		.offset = CLK12_24_CTRL,
720		.shift = 0,
721		.width = 8,
722	},
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",
728		},
729		.num_parents = 1,
730	},
731};
732
733static struct clk_regmap fclk_div2_divn = {
734	.data = &(struct clk_regmap_gate_data){
735		.offset = CLK12_24_CTRL,
736		.bit_idx = 12,
737	},
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
743		},
744		.num_parents = 1,
745		.flags = CLK_SET_RATE_PARENT,
746	},
747};
748
749/*
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
752 */
753static u32 gen_table[] = { 0, 1, 3, 5, 6, 7, 8 };
754static const struct clk_parent_data gen_parent_data[] = {
755	{ .fw_name = "xtal", },
756	{ .hw = &rtc.hw },
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", },
762};
763
764static struct clk_regmap gen_sel = {
765	.data = &(struct clk_regmap_mux_data){
766		.offset = GEN_CLK_CTRL,
767		.mask = 0xf,
768		.shift = 12,
769		.table = gen_table,
770	},
771	.hw.init = &(struct clk_init_data){
772		.name = "gen_sel",
773		.ops = &clk_regmap_mux_ops,
774		.parent_data = gen_parent_data,
775		.num_parents = ARRAY_SIZE(gen_parent_data),
776		/*
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.
782		 */
783		.flags = CLK_SET_RATE_NO_REPARENT,
784	},
785};
786
787static struct clk_regmap gen_div = {
788	.data = &(struct clk_regmap_div_data){
789		.offset = GEN_CLK_CTRL,
790		.shift = 0,
791		.width = 11,
792	},
793	.hw.init = &(struct clk_init_data){
794		.name = "gen_div",
795		.ops = &clk_regmap_divider_ops,
796		.parent_hws = (const struct clk_hw *[]) {
797			&gen_sel.hw
798		},
799		.num_parents = 1,
800		.flags = CLK_SET_RATE_PARENT,
801	},
802};
803
804static struct clk_regmap gen = {
805	.data = &(struct clk_regmap_gate_data){
806		.offset = GEN_CLK_CTRL,
807		.bit_idx = 11,
808	},
809	.hw.init = &(struct clk_init_data) {
810		.name = "gen",
811		.ops = &clk_regmap_gate_ops,
812		.parent_hws = (const struct clk_hw *[]) {
813			&gen_div.hw
814		},
815		.num_parents = 1,
816		.flags = CLK_SET_RATE_PARENT,
817	},
818};
819
820static struct clk_regmap saradc_sel = {
821	.data = &(struct clk_regmap_mux_data){
822		.offset = SAR_ADC_CLK_CTRL,
823		.mask = 0x1,
824		.shift = 9,
825	},
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", },
831			{ .hw = &sys.hw, },
832		},
833		.num_parents = 2,
834	},
835};
836
837static struct clk_regmap saradc_div = {
838	.data = &(struct clk_regmap_div_data){
839		.offset = SAR_ADC_CLK_CTRL,
840		.shift = 0,
841		.width = 8,
842	},
843	.hw.init = &(struct clk_init_data){
844		.name = "saradc_div",
845		.ops = &clk_regmap_divider_ops,
846		.parent_hws = (const struct clk_hw *[]) {
847			&saradc_sel.hw
848		},
849		.num_parents = 1,
850		.flags = CLK_SET_RATE_PARENT,
851	},
852};
853
854static struct clk_regmap saradc = {
855	.data = &(struct clk_regmap_gate_data){
856		.offset = SAR_ADC_CLK_CTRL,
857		.bit_idx = 8,
858	},
859	.hw.init = &(struct clk_init_data) {
860		.name = "saradc",
861		.ops = &clk_regmap_gate_ops,
862		.parent_hws = (const struct clk_hw *[]) {
863			&saradc_div.hw
864		},
865		.num_parents = 1,
866		.flags = CLK_SET_RATE_PARENT,
867	},
868};
869
870static const struct clk_parent_data pwm_abcd_parents[] = {
871	{ .fw_name = "xtal", },
872	{ .hw = &sys.hw },
873	{ .hw = &rtc.hw },
874};
875
876static struct clk_regmap pwm_a_sel = {
877	.data = &(struct clk_regmap_mux_data){
878		.offset = PWM_CLK_AB_CTRL,
879		.mask = 0x1,
880		.shift = 9,
881	},
882	.hw.init = &(struct clk_init_data){
883		.name = "pwm_a_sel",
884		.ops = &clk_regmap_mux_ops,
885		.parent_data = pwm_abcd_parents,
886		.num_parents = ARRAY_SIZE(pwm_abcd_parents),
887	},
888};
889
890static struct clk_regmap pwm_a_div = {
891	.data = &(struct clk_regmap_div_data){
892		.offset = PWM_CLK_AB_CTRL,
893		.shift = 0,
894		.width = 8,
895	},
896	.hw.init = &(struct clk_init_data){
897		.name = "pwm_a_div",
898		.ops = &clk_regmap_divider_ops,
899		.parent_hws = (const struct clk_hw *[]) {
900			&pwm_a_sel.hw
901		},
902		.num_parents = 1,
903		.flags = CLK_SET_RATE_PARENT,
904	},
905};
906
907static struct clk_regmap pwm_a = {
908	.data = &(struct clk_regmap_gate_data){
909		.offset = PWM_CLK_AB_CTRL,
910		.bit_idx = 8,
911	},
912	.hw.init = &(struct clk_init_data) {
913		.name = "pwm_a",
914		.ops = &clk_regmap_gate_ops,
915		.parent_hws = (const struct clk_hw *[]) {
916			&pwm_a_div.hw
917		},
918		.num_parents = 1,
919		.flags = CLK_SET_RATE_PARENT,
920	},
921};
922
923static struct clk_regmap pwm_b_sel = {
924	.data = &(struct clk_regmap_mux_data){
925		.offset = PWM_CLK_AB_CTRL,
926		.mask = 0x1,
927		.shift = 25,
928	},
929	.hw.init = &(struct clk_init_data){
930		.name = "pwm_b_sel",
931		.ops = &clk_regmap_mux_ops,
932		.parent_data = pwm_abcd_parents,
933		.num_parents = ARRAY_SIZE(pwm_abcd_parents),
934	},
935};
936
937static struct clk_regmap pwm_b_div = {
938	.data = &(struct clk_regmap_div_data){
939		.offset = PWM_CLK_AB_CTRL,
940		.shift = 16,
941		.width = 8,
942	},
943	.hw.init = &(struct clk_init_data){
944		.name = "pwm_b_div",
945		.ops = &clk_regmap_divider_ops,
946		.parent_hws = (const struct clk_hw *[]) {
947			&pwm_b_sel.hw
948		},
949		.num_parents = 1,
950		.flags = CLK_SET_RATE_PARENT,
951	},
952};
953
954static struct clk_regmap pwm_b = {
955	.data = &(struct clk_regmap_gate_data){
956		.offset = PWM_CLK_AB_CTRL,
957		.bit_idx = 24,
958	},
959	.hw.init = &(struct clk_init_data) {
960		.name = "pwm_b",
961		.ops = &clk_regmap_gate_ops,
962		.parent_hws = (const struct clk_hw *[]) {
963			&pwm_b_div.hw
964		},
965		.num_parents = 1,
966		.flags = CLK_SET_RATE_PARENT,
967	},
968};
969
970static struct clk_regmap pwm_c_sel = {
971	.data = &(struct clk_regmap_mux_data){
972		.offset = PWM_CLK_CD_CTRL,
973		.mask = 0x1,
974		.shift = 9,
975	},
976	.hw.init = &(struct clk_init_data){
977		.name = "pwm_c_sel",
978		.ops = &clk_regmap_mux_ops,
979		.parent_data = pwm_abcd_parents,
980		.num_parents = ARRAY_SIZE(pwm_abcd_parents),
981	},
982};
983
984static struct clk_regmap pwm_c_div = {
985	.data = &(struct clk_regmap_div_data){
986		.offset = PWM_CLK_CD_CTRL,
987		.shift = 0,
988		.width = 8,
989	},
990	.hw.init = &(struct clk_init_data){
991		.name = "pwm_c_div",
992		.ops = &clk_regmap_divider_ops,
993		.parent_hws = (const struct clk_hw *[]) {
994			&pwm_c_sel.hw
995		},
996		.num_parents = 1,
997		.flags = CLK_SET_RATE_PARENT,
998	},
999};
1000
1001static struct clk_regmap pwm_c = {
1002	.data = &(struct clk_regmap_gate_data){
1003		.offset = PWM_CLK_CD_CTRL,
1004		.bit_idx = 8,
1005	},
1006	.hw.init = &(struct clk_init_data) {
1007		.name = "pwm_c",
1008		.ops = &clk_regmap_gate_ops,
1009		.parent_hws = (const struct clk_hw *[]) {
1010			&pwm_c_div.hw
1011		},
1012		.num_parents = 1,
1013		.flags = CLK_SET_RATE_PARENT,
1014	},
1015};
1016
1017static struct clk_regmap pwm_d_sel = {
1018	.data = &(struct clk_regmap_mux_data){
1019		.offset = PWM_CLK_CD_CTRL,
1020		.mask = 0x1,
1021		.shift = 25,
1022	},
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),
1028	},
1029};
1030
1031static struct clk_regmap pwm_d_div = {
1032	.data = &(struct clk_regmap_div_data){
1033		.offset = PWM_CLK_CD_CTRL,
1034		.shift = 16,
1035		.width = 8,
1036	},
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 *[]) {
1041			&pwm_d_sel.hw
1042		},
1043		.num_parents = 1,
1044		.flags = CLK_SET_RATE_PARENT,
1045	},
1046};
1047
1048static struct clk_regmap pwm_d = {
1049	.data = &(struct clk_regmap_gate_data){
1050		.offset = PWM_CLK_CD_CTRL,
1051		.bit_idx = 24,
1052	},
1053	.hw.init = &(struct clk_init_data) {
1054		.name = "pwm_d",
1055		.ops = &clk_regmap_gate_ops,
1056		.parent_hws = (const struct clk_hw *[]) {
1057			&pwm_d_div.hw
1058		},
1059		.num_parents = 1,
1060		.flags = CLK_SET_RATE_PARENT,
1061	},
1062};
1063
1064static const struct clk_parent_data pwm_ef_parents[] = {
1065	{ .fw_name = "xtal", },
1066	{ .hw = &sys.hw },
1067	{ .fw_name = "fclk_div5", },
1068	{ .hw = &rtc.hw },
1069};
1070
1071static struct clk_regmap pwm_e_sel = {
1072	.data = &(struct clk_regmap_mux_data){
1073		.offset = PWM_CLK_EF_CTRL,
1074		.mask = 0x3,
1075		.shift = 9,
1076	},
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),
1082	},
1083};
1084
1085static struct clk_regmap pwm_e_div = {
1086	.data = &(struct clk_regmap_div_data){
1087		.offset = PWM_CLK_EF_CTRL,
1088		.shift = 0,
1089		.width = 8,
1090	},
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 *[]) {
1095			&pwm_e_sel.hw
1096		},
1097		.num_parents = 1,
1098		.flags = CLK_SET_RATE_PARENT,
1099	},
1100};
1101
1102static struct clk_regmap pwm_e = {
1103	.data = &(struct clk_regmap_gate_data){
1104		.offset = PWM_CLK_EF_CTRL,
1105		.bit_idx = 8,
1106	},
1107	.hw.init = &(struct clk_init_data) {
1108		.name = "pwm_e",
1109		.ops = &clk_regmap_gate_ops,
1110		.parent_hws = (const struct clk_hw *[]) {
1111			&pwm_e_div.hw
1112		},
1113		.num_parents = 1,
1114		.flags = CLK_SET_RATE_PARENT,
1115	},
1116};
1117
1118static struct clk_regmap pwm_f_sel = {
1119	.data = &(struct clk_regmap_mux_data){
1120		.offset = PWM_CLK_EF_CTRL,
1121		.mask = 0x3,
1122		.shift = 25,
1123	},
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),
1129	},
1130};
1131
1132static struct clk_regmap pwm_f_div = {
1133	.data = &(struct clk_regmap_div_data){
1134		.offset = PWM_CLK_EF_CTRL,
1135		.shift = 16,
1136		.width = 8,
1137	},
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 *[]) {
1142			&pwm_f_sel.hw
1143		},
1144		.num_parents = 1,
1145		.flags = CLK_SET_RATE_PARENT,
1146	},
1147};
1148
1149static struct clk_regmap pwm_f = {
1150	.data = &(struct clk_regmap_gate_data){
1151		.offset = PWM_CLK_EF_CTRL,
1152		.bit_idx = 24,
1153	},
1154	.hw.init = &(struct clk_init_data) {
1155		.name = "pwm_f",
1156		.ops = &clk_regmap_gate_ops,
1157		.parent_hws = (const struct clk_hw *[]) {
1158			&pwm_f_div.hw
1159		},
1160		.num_parents = 1,
1161		.flags = CLK_SET_RATE_PARENT,
1162	},
1163};
1164
1165/*
1166 * spicc clk
1167 *   fdiv2   |\         |\       _____
1168 *  ---------| |---DIV--| |     |     |    spicc out
1169 *  ---------| |        | |-----|GATE |---------
1170 *     ..... |/         | /     |_____|
1171 *  --------------------|/
1172 *                 24M
1173 */
1174static 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" },
1179};
1180
1181static struct clk_regmap spicc_sel = {
1182	.data = &(struct clk_regmap_mux_data){
1183		.offset = SPICC_CLK_CTRL,
1184		.mask = 0x3,
1185		.shift = 9,
1186	},
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),
1192	},
1193};
1194
1195static struct clk_regmap spicc_div = {
1196	.data = &(struct clk_regmap_div_data){
1197		.offset = SPICC_CLK_CTRL,
1198		.shift = 0,
1199		.width = 8,
1200	},
1201	.hw.init = &(struct clk_init_data){
1202		.name = "spicc_div",
1203		.ops = &clk_regmap_divider_ops,
1204		.parent_hws = (const struct clk_hw *[]) {
1205			&spicc_sel.hw
1206		},
1207		.num_parents = 1,
1208		.flags = CLK_SET_RATE_PARENT,
1209	},
1210};
1211
1212static struct clk_regmap spicc_sel2 = {
1213	.data = &(struct clk_regmap_mux_data){
1214		.offset = SPICC_CLK_CTRL,
1215		.mask = 0x1,
1216		.shift = 15,
1217	},
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", },
1224		},
1225		.num_parents = 2,
1226		.flags = CLK_SET_RATE_PARENT,
1227	},
1228};
1229
1230static struct clk_regmap spicc = {
1231	.data = &(struct clk_regmap_gate_data){
1232		.offset = SPICC_CLK_CTRL,
1233		.bit_idx = 8,
1234	},
1235	.hw.init = &(struct clk_init_data) {
1236		.name = "spicc",
1237		.ops = &clk_regmap_gate_ops,
1238		.parent_hws = (const struct clk_hw *[]) {
1239			&spicc_sel2.hw
1240		},
1241		.num_parents = 1,
1242		.flags = CLK_SET_RATE_PARENT,
1243	},
1244};
1245
1246static struct clk_regmap ts_div = {
1247	.data = &(struct clk_regmap_div_data){
1248		.offset = TS_CLK_CTRL,
1249		.shift = 0,
1250		.width = 8,
1251	},
1252	.hw.init = &(struct clk_init_data){
1253		.name = "ts_div",
1254		.ops = &clk_regmap_divider_ops,
1255		.parent_data = &(const struct clk_parent_data) {
1256			.fw_name = "xtal",
1257		},
1258		.num_parents = 1,
1259	},
1260};
1261
1262static struct clk_regmap ts = {
1263	.data = &(struct clk_regmap_gate_data){
1264		.offset = TS_CLK_CTRL,
1265		.bit_idx = 8,
1266	},
1267	.hw.init = &(struct clk_init_data) {
1268		.name = "ts",
1269		.ops = &clk_regmap_gate_ops,
1270		.parent_hws = (const struct clk_hw *[]) {
1271			&ts_div.hw
1272		},
1273		.num_parents = 1,
1274		.flags = CLK_SET_RATE_PARENT,
1275	},
1276};
1277
1278static struct clk_regmap spifc_sel = {
1279	.data = &(struct clk_regmap_mux_data){
1280		.offset = SPIFC_CLK_CTRL,
1281		.mask = 0x3,
1282		.shift = 9,
1283	},
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),
1289	},
1290};
1291
1292static struct clk_regmap spifc_div = {
1293	.data = &(struct clk_regmap_div_data){
1294		.offset = SPIFC_CLK_CTRL,
1295		.shift = 0,
1296		.width = 8,
1297	},
1298	.hw.init = &(struct clk_init_data){
1299		.name = "spifc_div",
1300		.ops = &clk_regmap_divider_ops,
1301		.parent_hws = (const struct clk_hw *[]) {
1302			&spifc_sel.hw
1303		},
1304		.num_parents = 1,
1305		.flags = CLK_SET_RATE_PARENT,
1306	},
1307};
1308
1309static struct clk_regmap spifc_sel2 = {
1310	.data = &(struct clk_regmap_mux_data){
1311		.offset = SPIFC_CLK_CTRL,
1312		.mask = 0x1,
1313		.shift = 15,
1314	},
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", },
1321		},
1322		.num_parents = 2,
1323		.flags = CLK_SET_RATE_PARENT,
1324	},
1325};
1326
1327static struct clk_regmap spifc = {
1328	.data = &(struct clk_regmap_gate_data){
1329		.offset = SPIFC_CLK_CTRL,
1330		.bit_idx = 8,
1331	},
1332	.hw.init = &(struct clk_init_data) {
1333		.name = "spifc",
1334		.ops = &clk_regmap_gate_ops,
1335		.parent_hws = (const struct clk_hw *[]) {
1336			&spifc_sel2.hw
1337		},
1338		.num_parents = 1,
1339		.flags = CLK_SET_RATE_PARENT,
1340	},
1341};
1342
1343static const struct clk_parent_data usb_bus_parents[] = {
1344	{ .fw_name = "xtal", },
1345	{ .hw = &sys.hw },
1346	{ .fw_name = "fclk_div3", },
1347	{ .fw_name = "fclk_div5", },
1348};
1349
1350static struct clk_regmap usb_bus_sel = {
1351	.data = &(struct clk_regmap_mux_data){
1352		.offset = USB_BUSCLK_CTRL,
1353		.mask = 0x3,
1354		.shift = 9,
1355	},
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,
1362	},
1363};
1364
1365static struct clk_regmap usb_bus_div = {
1366	.data = &(struct clk_regmap_div_data){
1367		.offset = USB_BUSCLK_CTRL,
1368		.shift = 0,
1369		.width = 8,
1370	},
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 *[]) {
1375			&usb_bus_sel.hw
1376		},
1377		.num_parents = 1,
1378		.flags = CLK_SET_RATE_PARENT,
1379	},
1380};
1381
1382static struct clk_regmap usb_bus = {
1383	.data = &(struct clk_regmap_gate_data){
1384		.offset = USB_BUSCLK_CTRL,
1385		.bit_idx = 8,
1386	},
1387	.hw.init = &(struct clk_init_data) {
1388		.name = "usb_bus",
1389		.ops = &clk_regmap_gate_ops,
1390		.parent_hws = (const struct clk_hw *[]) {
1391			&usb_bus_div.hw
1392		},
1393		.num_parents = 1,
1394		.flags = CLK_SET_RATE_PARENT,
1395	},
1396};
1397
1398static 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", },
1403};
1404
1405static struct clk_regmap sd_emmc_sel = {
1406	.data = &(struct clk_regmap_mux_data){
1407		.offset = SD_EMMC_CLK_CTRL,
1408		.mask = 0x3,
1409		.shift = 9,
1410	},
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),
1416	},
1417};
1418
1419static struct clk_regmap sd_emmc_div = {
1420	.data = &(struct clk_regmap_div_data){
1421		.offset = SD_EMMC_CLK_CTRL,
1422		.shift = 0,
1423		.width = 8,
1424	},
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 *[]) {
1429			&sd_emmc_sel.hw
1430		},
1431		.num_parents = 1,
1432		.flags = CLK_SET_RATE_PARENT,
1433	},
1434};
1435
1436static struct clk_regmap sd_emmc_sel2 = {
1437	.data = &(struct clk_regmap_mux_data){
1438		.offset = SD_EMMC_CLK_CTRL,
1439		.mask = 0x1,
1440		.shift = 15,
1441	},
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", },
1448		},
1449		.num_parents = 2,
1450		.flags = CLK_SET_RATE_PARENT,
1451	},
1452};
1453
1454static struct clk_regmap sd_emmc = {
1455	.data = &(struct clk_regmap_gate_data){
1456		.offset = SD_EMMC_CLK_CTRL,
1457		.bit_idx = 8,
1458	},
1459	.hw.init = &(struct clk_init_data) {
1460		.name = "sd_emmc",
1461		.ops = &clk_regmap_gate_ops,
1462		.parent_hws = (const struct clk_hw *[]) {
1463			&sd_emmc_sel2.hw
1464		},
1465		.num_parents = 1,
1466		.flags = CLK_SET_RATE_PARENT,
1467	},
1468};
1469
1470static struct clk_regmap psram_sel = {
1471	.data = &(struct clk_regmap_mux_data){
1472		.offset = PSRAM_CLK_CTRL,
1473		.mask = 0x3,
1474		.shift = 9,
1475	},
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),
1481	},
1482};
1483
1484static struct clk_regmap psram_div = {
1485	.data = &(struct clk_regmap_div_data){
1486		.offset = PSRAM_CLK_CTRL,
1487		.shift = 0,
1488		.width = 8,
1489	},
1490	.hw.init = &(struct clk_init_data){
1491		.name = "psram_div",
1492		.ops = &clk_regmap_divider_ops,
1493		.parent_hws = (const struct clk_hw *[]) {
1494			&psram_sel.hw
1495		},
1496		.num_parents = 1,
1497		.flags = CLK_SET_RATE_PARENT,
1498	},
1499};
1500
1501static struct clk_regmap psram_sel2 = {
1502	.data = &(struct clk_regmap_mux_data){
1503		.offset = PSRAM_CLK_CTRL,
1504		.mask = 0x1,
1505		.shift = 15,
1506	},
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", },
1513		},
1514		.num_parents = 2,
1515		.flags = CLK_SET_RATE_PARENT,
1516	},
1517};
1518
1519static struct clk_regmap psram = {
1520	.data = &(struct clk_regmap_gate_data){
1521		.offset = PSRAM_CLK_CTRL,
1522		.bit_idx = 8,
1523	},
1524	.hw.init = &(struct clk_init_data) {
1525		.name = "psram",
1526		.ops = &clk_regmap_gate_ops,
1527		.parent_hws = (const struct clk_hw *[]) {
1528			&psram_sel2.hw
1529		},
1530		.num_parents = 1,
1531		.flags = CLK_SET_RATE_PARENT,
1532	},
1533};
1534
1535static struct clk_regmap dmc_sel = {
1536	.data = &(struct clk_regmap_mux_data){
1537		.offset = DMC_CLK_CTRL,
1538		.mask = 0x3,
1539		.shift = 9,
1540	},
1541	.hw.init = &(struct clk_init_data){
1542		.name = "dmc_sel",
1543		.ops = &clk_regmap_mux_ops,
1544		.parent_data = sd_emmc_psram_dmc_parents,
1545		.num_parents = ARRAY_SIZE(sd_emmc_psram_dmc_parents),
1546	},
1547};
1548
1549static struct clk_regmap dmc_div = {
1550	.data = &(struct clk_regmap_div_data){
1551		.offset = DMC_CLK_CTRL,
1552		.shift = 0,
1553		.width = 8,
1554	},
1555	.hw.init = &(struct clk_init_data){
1556		.name = "dmc_div",
1557		.ops = &clk_regmap_divider_ops,
1558		.parent_hws = (const struct clk_hw *[]) {
1559			&dmc_sel.hw
1560		},
1561		.num_parents = 1,
1562		.flags = CLK_SET_RATE_PARENT,
1563	},
1564};
1565
1566static struct clk_regmap dmc_sel2 = {
1567	.data = &(struct clk_regmap_mux_data){
1568		.offset = DMC_CLK_CTRL,
1569		.mask = 0x1,
1570		.shift = 15,
1571	},
1572	.hw.init = &(struct clk_init_data){
1573		.name = "dmc_sel2",
1574		.ops = &clk_regmap_mux_ops,
1575		.parent_data = (const struct clk_parent_data []) {
1576			{ .hw = &dmc_div.hw },
1577			{ .fw_name = "xtal", },
1578		},
1579		.num_parents = 2,
1580		.flags = CLK_SET_RATE_PARENT,
1581	},
1582};
1583
1584static struct clk_regmap dmc = {
1585	.data = &(struct clk_regmap_gate_data){
1586		.offset = DMC_CLK_CTRL,
1587		.bit_idx = 8,
1588	},
1589	.hw.init = &(struct clk_init_data) {
1590		.name = "dmc",
1591		.ops = &clk_regmap_gate_ro_ops,
1592		.parent_hws = (const struct clk_hw *[]) {
1593			&dmc_sel2.hw
1594		},
1595		.num_parents = 1,
1596		.flags = CLK_SET_RATE_PARENT,
1597	},
1598};
1599
1600static struct clk_regmap ceca_32k_in = {
1601	.data = &(struct clk_regmap_gate_data){
1602		.offset = CECA_CLK_CTRL0,
1603		.bit_idx = 31,
1604	},
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) {
1609			.fw_name = "xtal",
1610		},
1611		.num_parents = 1,
1612	},
1613};
1614
1615static struct clk_regmap ceca_32k_div = {
1616	.data = &(struct meson_clk_dualdiv_data){
1617		.n1 = {
1618			.reg_off = CECA_CLK_CTRL0,
1619			.shift   = 0,
1620			.width   = 12,
1621		},
1622		.n2 = {
1623			.reg_off = CECA_CLK_CTRL0,
1624			.shift   = 12,
1625			.width   = 12,
1626		},
1627		.m1 = {
1628			.reg_off = CECA_CLK_CTRL1,
1629			.shift   = 0,
1630			.width   = 12,
1631		},
1632		.m2 = {
1633			.reg_off = CECA_CLK_CTRL1,
1634			.shift   = 12,
1635			.width   = 12,
1636		},
1637		.dual = {
1638			.reg_off = CECA_CLK_CTRL0,
1639			.shift   = 28,
1640			.width   = 1,
1641		},
1642		.table = clk_32k_div_table,
1643	},
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 *[]) {
1648			&ceca_32k_in.hw
1649		},
1650		.num_parents = 1,
1651	},
1652};
1653
1654static struct clk_regmap ceca_32k_sel_pre = {
1655	.data = &(struct clk_regmap_mux_data) {
1656		.offset = CECA_CLK_CTRL1,
1657		.mask = 0x1,
1658		.shift = 24,
1659		.flags = CLK_MUX_ROUND_CLOSEST,
1660	},
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 *[]) {
1665			&ceca_32k_div.hw,
1666			&ceca_32k_in.hw,
1667		},
1668		.num_parents = 2,
1669		.flags = CLK_SET_RATE_PARENT,
1670	},
1671};
1672
1673static struct clk_regmap ceca_32k_sel = {
1674	.data = &(struct clk_regmap_mux_data) {
1675		.offset = CECA_CLK_CTRL1,
1676		.mask = 0x1,
1677		.shift = 31,
1678		.flags = CLK_MUX_ROUND_CLOSEST,
1679	},
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,
1685			&rtc.hw,
1686		},
1687		.num_parents = 2,
1688	},
1689};
1690
1691static struct clk_regmap ceca_32k_out = {
1692	.data = &(struct clk_regmap_gate_data){
1693		.offset = CECA_CLK_CTRL0,
1694		.bit_idx = 30,
1695	},
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 *[]) {
1700			&ceca_32k_sel.hw
1701		},
1702		.num_parents = 1,
1703		.flags = CLK_SET_RATE_PARENT,
1704	},
1705};
1706
1707static struct clk_regmap cecb_32k_in = {
1708	.data = &(struct clk_regmap_gate_data){
1709		.offset = CECB_CLK_CTRL0,
1710		.bit_idx = 31,
1711	},
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) {
1716			.fw_name = "xtal",
1717		},
1718		.num_parents = 1,
1719	},
1720};
1721
1722static struct clk_regmap cecb_32k_div = {
1723	.data = &(struct meson_clk_dualdiv_data){
1724		.n1 = {
1725			.reg_off = CECB_CLK_CTRL0,
1726			.shift   = 0,
1727			.width   = 12,
1728		},
1729		.n2 = {
1730			.reg_off = CECB_CLK_CTRL0,
1731			.shift   = 12,
1732			.width   = 12,
1733		},
1734		.m1 = {
1735			.reg_off = CECB_CLK_CTRL1,
1736			.shift   = 0,
1737			.width   = 12,
1738		},
1739		.m2 = {
1740			.reg_off = CECB_CLK_CTRL1,
1741			.shift   = 12,
1742			.width   = 12,
1743		},
1744		.dual = {
1745			.reg_off = CECB_CLK_CTRL0,
1746			.shift   = 28,
1747			.width   = 1,
1748		},
1749		.table = clk_32k_div_table,
1750	},
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 *[]) {
1755			&cecb_32k_in.hw
1756		},
1757		.num_parents = 1,
1758	},
1759};
1760
1761static struct clk_regmap cecb_32k_sel_pre = {
1762	.data = &(struct clk_regmap_mux_data) {
1763		.offset = CECB_CLK_CTRL1,
1764		.mask = 0x1,
1765		.shift = 24,
1766		.flags = CLK_MUX_ROUND_CLOSEST,
1767	},
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 *[]) {
1772			&cecb_32k_div.hw,
1773			&cecb_32k_in.hw,
1774		},
1775		.num_parents = 2,
1776		.flags = CLK_SET_RATE_PARENT,
1777	},
1778};
1779
1780static struct clk_regmap cecb_32k_sel = {
1781	.data = &(struct clk_regmap_mux_data) {
1782		.offset = CECB_CLK_CTRL1,
1783		.mask = 0x1,
1784		.shift = 31,
1785		.flags = CLK_MUX_ROUND_CLOSEST,
1786	},
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,
1792			&rtc.hw,
1793		},
1794		.num_parents = 2,
1795	},
1796};
1797
1798static struct clk_regmap cecb_32k_out = {
1799	.data = &(struct clk_regmap_gate_data){
1800		.offset = CECB_CLK_CTRL0,
1801		.bit_idx = 30,
1802	},
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 *[]) {
1807			&cecb_32k_sel.hw
1808		},
1809		.num_parents = 1,
1810		.flags = CLK_SET_RATE_PARENT,
1811	},
1812};
1813
1814#define MESON_GATE(_name, _reg, _bit) \
1815	MESON_PCLK(_name, _reg, _bit, &sys.hw)
1816
1817static MESON_GATE(clktree,	SYS_CLK_EN0,	0);
1818static MESON_GATE(reset_ctrl,	SYS_CLK_EN0,	1);
1819static MESON_GATE(analog_ctrl,	SYS_CLK_EN0,	2);
1820static MESON_GATE(pwr_ctrl,	SYS_CLK_EN0,	3);
1821static MESON_GATE(pad_ctrl,	SYS_CLK_EN0,	4);
1822static MESON_GATE(sys_ctrl,	SYS_CLK_EN0,	5);
1823static MESON_GATE(temp_sensor,	SYS_CLK_EN0,	6);
1824static MESON_GATE(am2axi_dev,	SYS_CLK_EN0,	7);
1825static MESON_GATE(spicc_b,	SYS_CLK_EN0,	8);
1826static MESON_GATE(spicc_a,	SYS_CLK_EN0,	9);
1827static MESON_GATE(msr,		SYS_CLK_EN0,	10);
1828static MESON_GATE(audio,	SYS_CLK_EN0,	11);
1829static MESON_GATE(jtag_ctrl,	SYS_CLK_EN0,	12);
1830static MESON_GATE(saradc_en,	SYS_CLK_EN0,	13);
1831static MESON_GATE(pwm_ef,	SYS_CLK_EN0,	14);
1832static MESON_GATE(pwm_cd,	SYS_CLK_EN0,	15);
1833static MESON_GATE(pwm_ab,	SYS_CLK_EN0,	16);
1834static MESON_GATE(cec,		SYS_CLK_EN0,	17);
1835static MESON_GATE(i2c_s,	SYS_CLK_EN0,	18);
1836static MESON_GATE(ir_ctrl,	SYS_CLK_EN0,	19);
1837static MESON_GATE(i2c_m_d,	SYS_CLK_EN0,	20);
1838static MESON_GATE(i2c_m_c,	SYS_CLK_EN0,	21);
1839static MESON_GATE(i2c_m_b,	SYS_CLK_EN0,	22);
1840static MESON_GATE(i2c_m_a,	SYS_CLK_EN0,	23);
1841static MESON_GATE(acodec,	SYS_CLK_EN0,	24);
1842static MESON_GATE(otp,		SYS_CLK_EN0,	25);
1843static MESON_GATE(sd_emmc_a,	SYS_CLK_EN0,	26);
1844static MESON_GATE(usb_phy,	SYS_CLK_EN0,	27);
1845static MESON_GATE(usb_ctrl,	SYS_CLK_EN0,	28);
1846static MESON_GATE(sys_dspb,	SYS_CLK_EN0,	29);
1847static MESON_GATE(sys_dspa,	SYS_CLK_EN0,	30);
1848static MESON_GATE(dma,		SYS_CLK_EN0,	31);
1849static MESON_GATE(irq_ctrl,	SYS_CLK_EN1,	0);
1850static MESON_GATE(nic,		SYS_CLK_EN1,	1);
1851static MESON_GATE(gic,		SYS_CLK_EN1,	2);
1852static MESON_GATE(uart_c,	SYS_CLK_EN1,	3);
1853static MESON_GATE(uart_b,	SYS_CLK_EN1,	4);
1854static MESON_GATE(uart_a,	SYS_CLK_EN1,	5);
1855static MESON_GATE(sys_psram,	SYS_CLK_EN1,	6);
1856static MESON_GATE(rsa,		SYS_CLK_EN1,	8);
1857static MESON_GATE(coresight,	SYS_CLK_EN1,	9);
1858static MESON_GATE(am2axi_vad,	AXI_CLK_EN,	0);
1859static MESON_GATE(audio_vad,	AXI_CLK_EN,	1);
1860static MESON_GATE(axi_dmc,	AXI_CLK_EN,	3);
1861static MESON_GATE(axi_psram,	AXI_CLK_EN,	4);
1862static MESON_GATE(ramb,		AXI_CLK_EN,	5);
1863static MESON_GATE(rama,		AXI_CLK_EN,	6);
1864static MESON_GATE(axi_spifc,	AXI_CLK_EN,	7);
1865static MESON_GATE(axi_nic,	AXI_CLK_EN,	8);
1866static MESON_GATE(axi_dma,	AXI_CLK_EN,	9);
1867static MESON_GATE(cpu_ctrl,	AXI_CLK_EN,	10);
1868static MESON_GATE(rom,		AXI_CLK_EN,	11);
1869static MESON_GATE(prod_i2c,	AXI_CLK_EN,	12);
1870
1871/* Array of all clocks registered by this provider */
1872static 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,
2027};
2028
2029/* Convenience table to populate regmap in .probe */
2030static struct clk_regmap *const a1_periphs_regmaps[] = {
2031	&xtal_in,
2032	&fixpll_in,
2033	&usb_phy_in,
2034	&usb_ctrl_in,
2035	&hifipll_in,
2036	&syspll_in,
2037	&dds_in,
2038	&sys,
2039	&clktree,
2040	&reset_ctrl,
2041	&analog_ctrl,
2042	&pwr_ctrl,
2043	&pad_ctrl,
2044	&sys_ctrl,
2045	&temp_sensor,
2046	&am2axi_dev,
2047	&spicc_b,
2048	&spicc_a,
2049	&msr,
2050	&audio,
2051	&jtag_ctrl,
2052	&saradc_en,
2053	&pwm_ef,
2054	&pwm_cd,
2055	&pwm_ab,
2056	&cec,
2057	&i2c_s,
2058	&ir_ctrl,
2059	&i2c_m_d,
2060	&i2c_m_c,
2061	&i2c_m_b,
2062	&i2c_m_a,
2063	&acodec,
2064	&otp,
2065	&sd_emmc_a,
2066	&usb_phy,
2067	&usb_ctrl,
2068	&sys_dspb,
2069	&sys_dspa,
2070	&dma,
2071	&irq_ctrl,
2072	&nic,
2073	&gic,
2074	&uart_c,
2075	&uart_b,
2076	&uart_a,
2077	&sys_psram,
2078	&rsa,
2079	&coresight,
2080	&am2axi_vad,
2081	&audio_vad,
2082	&axi_dmc,
2083	&axi_psram,
2084	&ramb,
2085	&rama,
2086	&axi_spifc,
2087	&axi_nic,
2088	&axi_dma,
2089	&cpu_ctrl,
2090	&rom,
2091	&prod_i2c,
2092	&dspa_sel,
2093	&dspb_sel,
2094	&dspa_en,
2095	&dspa_en_nic,
2096	&dspb_en,
2097	&dspb_en_nic,
2098	&rtc,
2099	&ceca_32k_out,
2100	&cecb_32k_out,
2101	&clk_24m,
2102	&clk_12m,
2103	&fclk_div2_divn,
2104	&gen,
2105	&saradc_sel,
2106	&saradc,
2107	&pwm_a,
2108	&pwm_b,
2109	&pwm_c,
2110	&pwm_d,
2111	&pwm_e,
2112	&pwm_f,
2113	&spicc,
2114	&ts,
2115	&spifc,
2116	&usb_bus,
2117	&sd_emmc,
2118	&psram,
2119	&dmc,
2120	&sys_a_sel,
2121	&sys_a_div,
2122	&sys_a,
2123	&sys_b_sel,
2124	&sys_b_div,
2125	&sys_b,
2126	&dspa_a_sel,
2127	&dspa_a_div,
2128	&dspa_a,
2129	&dspa_b_sel,
2130	&dspa_b_div,
2131	&dspa_b,
2132	&dspb_a_sel,
2133	&dspb_a_div,
2134	&dspb_a,
2135	&dspb_b_sel,
2136	&dspb_b_div,
2137	&dspb_b,
2138	&rtc_32k_in,
2139	&rtc_32k_div,
2140	&rtc_32k_xtal,
2141	&rtc_32k_sel,
2142	&cecb_32k_in,
2143	&cecb_32k_div,
2144	&cecb_32k_sel_pre,
2145	&cecb_32k_sel,
2146	&ceca_32k_in,
2147	&ceca_32k_div,
2148	&ceca_32k_sel_pre,
2149	&ceca_32k_sel,
2150	&fclk_div2_divn_pre,
2151	&gen_sel,
2152	&gen_div,
2153	&saradc_div,
2154	&pwm_a_sel,
2155	&pwm_a_div,
2156	&pwm_b_sel,
2157	&pwm_b_div,
2158	&pwm_c_sel,
2159	&pwm_c_div,
2160	&pwm_d_sel,
2161	&pwm_d_div,
2162	&pwm_e_sel,
2163	&pwm_e_div,
2164	&pwm_f_sel,
2165	&pwm_f_div,
2166	&spicc_sel,
2167	&spicc_div,
2168	&spicc_sel2,
2169	&ts_div,
2170	&spifc_sel,
2171	&spifc_div,
2172	&spifc_sel2,
2173	&usb_bus_sel,
2174	&usb_bus_div,
2175	&sd_emmc_sel,
2176	&sd_emmc_div,
2177	&sd_emmc_sel2,
2178	&psram_sel,
2179	&psram_div,
2180	&psram_sel2,
2181	&dmc_sel,
2182	&dmc_div,
2183	&dmc_sel2,
2184};
2185
2186static struct regmap_config a1_periphs_regmap_cfg = {
2187	.reg_bits   = 32,
2188	.val_bits   = 32,
2189	.reg_stride = 4,
2190};
2191
2192static struct meson_clk_hw_data a1_periphs_clks = {
2193	.hws = a1_periphs_hw_clks,
2194	.num = ARRAY_SIZE(a1_periphs_hw_clks),
2195};
2196
2197static int meson_a1_periphs_probe(struct platform_device *pdev)
2198{
2199	struct device *dev = &pdev->dev;
2200	void __iomem *base;
2201	struct regmap *map;
2202	int clkid, i, err;
2203
2204	base = devm_platform_ioremap_resource(pdev, 0);
2205	if (IS_ERR(base))
2206		return dev_err_probe(dev, PTR_ERR(base),
2207				     "can't ioremap resource\n");
2208
2209	map = devm_regmap_init_mmio(dev, base, &a1_periphs_regmap_cfg);
2210	if (IS_ERR(map))
2211		return dev_err_probe(dev, PTR_ERR(map),
2212				     "can't init regmap mmio region\n");
2213
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;
2217
2218	for (clkid = 0; clkid < a1_periphs_clks.num; clkid++) {
2219		err = devm_clk_hw_register(dev, a1_periphs_clks.hws[clkid]);
2220		if (err)
2221			return dev_err_probe(dev, err,
2222					     "clock[%d] registration failed\n",
2223					     clkid);
2224	}
2225
2226	return devm_of_clk_add_hw_provider(dev, meson_clk_hw_get, &a1_periphs_clks);
2227}
2228
2229static const struct of_device_id a1_periphs_clkc_match_table[] = {
2230	{ .compatible = "amlogic,a1-peripherals-clkc", },
2231	{}
2232};
2233MODULE_DEVICE_TABLE(of, a1_periphs_clkc_match_table);
2234
2235static struct platform_driver a1_periphs_clkc_driver = {
2236	.probe = meson_a1_periphs_probe,
2237	.driver = {
2238		.name = "a1-peripherals-clkc",
2239		.of_match_table = a1_periphs_clkc_match_table,
2240	},
2241};
2242
2243module_platform_driver(a1_periphs_clkc_driver);
2244MODULE_AUTHOR("Jian Hu <jian.hu@amlogic.com>");
2245MODULE_AUTHOR("Dmitry Rokosov <ddrokosov@sberdevices.ru>");
2246MODULE_LICENSE("GPL");
2247