xref: /linux/drivers/clk/meson/s4-peripherals.c (revision 2d945dde7fa3f17f46349360a9f97614de9f47da)
1 // SPDX-License-Identifier: (GPL-2.0-only OR MIT)
2 /*
3  * Amlogic S4 Peripherals Clock Controller Driver
4  *
5  * Copyright (c) 2022-2023 Amlogic, inc. All rights reserved
6  * Author: Yu Tu <yu.tu@amlogic.com>
7  */
8 
9 #include <linux/clk-provider.h>
10 #include <linux/of_device.h>
11 #include <linux/platform_device.h>
12 
13 #include "clk-regmap.h"
14 #include "vid-pll-div.h"
15 #include "clk-dualdiv.h"
16 #include "meson-clkc-utils.h"
17 #include <dt-bindings/clock/amlogic,s4-peripherals-clkc.h>
18 
19 #define CLKCTRL_RTC_BY_OSCIN_CTRL0                 0x008
20 #define CLKCTRL_RTC_BY_OSCIN_CTRL1                 0x00c
21 #define CLKCTRL_RTC_CTRL                           0x010
22 #define CLKCTRL_SYS_CLK_CTRL0                      0x040
23 #define CLKCTRL_SYS_CLK_EN0_REG0                   0x044
24 #define CLKCTRL_SYS_CLK_EN0_REG1                   0x048
25 #define CLKCTRL_SYS_CLK_EN0_REG2                   0x04c
26 #define CLKCTRL_SYS_CLK_EN0_REG3                   0x050
27 #define CLKCTRL_CECA_CTRL0                         0x088
28 #define CLKCTRL_CECA_CTRL1                         0x08c
29 #define CLKCTRL_CECB_CTRL0                         0x090
30 #define CLKCTRL_CECB_CTRL1                         0x094
31 #define CLKCTRL_SC_CLK_CTRL                        0x098
32 #define CLKCTRL_CLK12_24_CTRL                      0x0a8
33 #define CLKCTRL_VID_CLK_CTRL                       0x0c0
34 #define CLKCTRL_VID_CLK_CTRL2                      0x0c4
35 #define CLKCTRL_VID_CLK_DIV                        0x0c8
36 #define CLKCTRL_VIID_CLK_DIV                       0x0cc
37 #define CLKCTRL_VIID_CLK_CTRL                      0x0d0
38 #define CLKCTRL_HDMI_CLK_CTRL                      0x0e0
39 #define CLKCTRL_VID_PLL_CLK_DIV                    0x0e4
40 #define CLKCTRL_VPU_CLK_CTRL                       0x0e8
41 #define CLKCTRL_VPU_CLKB_CTRL                      0x0ec
42 #define CLKCTRL_VPU_CLKC_CTRL                      0x0f0
43 #define CLKCTRL_VID_LOCK_CLK_CTRL                  0x0f4
44 #define CLKCTRL_VDIN_MEAS_CLK_CTRL                 0x0f8
45 #define CLKCTRL_VAPBCLK_CTRL                       0x0fc
46 #define CLKCTRL_HDCP22_CTRL                        0x100
47 #define CLKCTRL_VDEC_CLK_CTRL                      0x140
48 #define CLKCTRL_VDEC2_CLK_CTRL                     0x144
49 #define CLKCTRL_VDEC3_CLK_CTRL                     0x148
50 #define CLKCTRL_VDEC4_CLK_CTRL                     0x14c
51 #define CLKCTRL_TS_CLK_CTRL                        0x158
52 #define CLKCTRL_MALI_CLK_CTRL                      0x15c
53 #define CLKCTRL_NAND_CLK_CTRL                      0x168
54 #define CLKCTRL_SD_EMMC_CLK_CTRL                   0x16c
55 #define CLKCTRL_SPICC_CLK_CTRL                     0x174
56 #define CLKCTRL_GEN_CLK_CTRL                       0x178
57 #define CLKCTRL_SAR_CLK_CTRL                       0x17c
58 #define CLKCTRL_PWM_CLK_AB_CTRL                    0x180
59 #define CLKCTRL_PWM_CLK_CD_CTRL                    0x184
60 #define CLKCTRL_PWM_CLK_EF_CTRL                    0x188
61 #define CLKCTRL_PWM_CLK_GH_CTRL                    0x18c
62 #define CLKCTRL_PWM_CLK_IJ_CTRL                    0x190
63 #define CLKCTRL_DEMOD_CLK_CTRL                     0x200
64 
65 static struct clk_regmap s4_rtc_32k_by_oscin_clkin = {
66 	.data = &(struct clk_regmap_gate_data){
67 		.offset = CLKCTRL_RTC_BY_OSCIN_CTRL0,
68 		.bit_idx = 31,
69 	},
70 	.hw.init = &(struct clk_init_data) {
71 		.name = "rtc_32k_by_oscin_clkin",
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 
80 static const struct meson_clk_dualdiv_param s4_32k_div_table[] = {
81 	{
82 		.dual	= 1,
83 		.n1	= 733,
84 		.m1	= 8,
85 		.n2	= 732,
86 		.m2	= 11,
87 	},
88 	{}
89 };
90 
91 static struct clk_regmap s4_rtc_32k_by_oscin_div = {
92 	.data = &(struct meson_clk_dualdiv_data){
93 		.n1 = {
94 			.reg_off = CLKCTRL_RTC_BY_OSCIN_CTRL0,
95 			.shift   = 0,
96 			.width   = 12,
97 		},
98 		.n2 = {
99 			.reg_off = CLKCTRL_RTC_BY_OSCIN_CTRL0,
100 			.shift   = 12,
101 			.width   = 12,
102 		},
103 		.m1 = {
104 			.reg_off = CLKCTRL_RTC_BY_OSCIN_CTRL1,
105 			.shift   = 0,
106 			.width   = 12,
107 		},
108 		.m2 = {
109 			.reg_off = CLKCTRL_RTC_BY_OSCIN_CTRL1,
110 			.shift   = 12,
111 			.width   = 12,
112 		},
113 		.dual = {
114 			.reg_off = CLKCTRL_RTC_BY_OSCIN_CTRL0,
115 			.shift   = 28,
116 			.width   = 1,
117 		},
118 		.table = s4_32k_div_table,
119 	},
120 	.hw.init = &(struct clk_init_data){
121 		.name = "rtc_32k_by_oscin_div",
122 		.ops = &meson_clk_dualdiv_ops,
123 		.parent_hws = (const struct clk_hw *[]) {
124 			&s4_rtc_32k_by_oscin_clkin.hw
125 		},
126 		.num_parents = 1,
127 	},
128 };
129 
130 static struct clk_regmap s4_rtc_32k_by_oscin_sel = {
131 	.data = &(struct clk_regmap_mux_data) {
132 		.offset = CLKCTRL_RTC_BY_OSCIN_CTRL1,
133 		.mask = 0x1,
134 		.shift = 24,
135 		.flags = CLK_MUX_ROUND_CLOSEST,
136 	},
137 	.hw.init = &(struct clk_init_data){
138 		.name = "rtc_32k_by_oscin_sel",
139 		.ops = &clk_regmap_mux_ops,
140 		.parent_hws = (const struct clk_hw *[]) {
141 			&s4_rtc_32k_by_oscin_div.hw,
142 			&s4_rtc_32k_by_oscin_clkin.hw,
143 		},
144 		.num_parents = 2,
145 		.flags = CLK_SET_RATE_PARENT,
146 	},
147 };
148 
149 static struct clk_regmap s4_rtc_32k_by_oscin = {
150 	.data = &(struct clk_regmap_gate_data){
151 		.offset = CLKCTRL_RTC_BY_OSCIN_CTRL0,
152 		.bit_idx = 30,
153 	},
154 	.hw.init = &(struct clk_init_data) {
155 		.name = "rtc_32k_by_oscin",
156 		.ops = &clk_regmap_gate_ops,
157 		.parent_hws = (const struct clk_hw *[]) {
158 			&s4_rtc_32k_by_oscin_sel.hw
159 		},
160 		.num_parents = 1,
161 		.flags = CLK_SET_RATE_PARENT,
162 	},
163 };
164 
165 static struct clk_regmap s4_rtc_clk = {
166 	.data = &(struct clk_regmap_mux_data) {
167 		.offset = CLKCTRL_RTC_CTRL,
168 		.mask = 0x3,
169 		.shift = 0,
170 		.flags = CLK_MUX_ROUND_CLOSEST,
171 	},
172 	.hw.init = &(struct clk_init_data){
173 		.name = "rtc_clk_sel",
174 		.ops = &clk_regmap_mux_ops,
175 		.parent_hws = (const struct clk_hw *[]) {
176 			&s4_rtc_32k_by_oscin.hw,
177 			&s4_rtc_32k_by_oscin_div.hw,
178 		},
179 		.num_parents = 2,
180 		.flags = CLK_SET_RATE_PARENT,
181 	},
182 };
183 
184 /* The index 5 is AXI_CLK, which is dedicated to AXI. So skip it. */
185 static u32 mux_table_sys_ab_clk_sel[] = { 0, 1, 2, 3, 4, 6, 7 };
186 static const struct clk_parent_data sys_ab_clk_parent_data[] = {
187 	{ .fw_name = "xtal" },
188 	{ .fw_name = "fclk_div2" },
189 	{ .fw_name = "fclk_div3" },
190 	{ .fw_name = "fclk_div4" },
191 	{ .fw_name = "fclk_div5" },
192 	{ .fw_name = "fclk_div7" },
193 	{ .hw = &s4_rtc_clk.hw }
194 };
195 
196 /*
197  * This clock is initialized by ROMcode.
198  * The chip was changed SYS CLK for security reasons. SYS CLK registers are not writable
199  * in the kernel phase. Write of SYS related register will cause the system to crash.
200  * Meanwhile, these clock won't ever change at runtime.
201  * For the above reasons, we can only use ro_ops for SYS related clocks.
202  */
203 static struct clk_regmap s4_sysclk_b_sel = {
204 	.data = &(struct clk_regmap_mux_data){
205 		.offset = CLKCTRL_SYS_CLK_CTRL0,
206 		.mask = 0x7,
207 		.shift = 26,
208 		.table = mux_table_sys_ab_clk_sel,
209 	},
210 	.hw.init = &(struct clk_init_data){
211 		.name = "sysclk_b_sel",
212 		.ops = &clk_regmap_mux_ro_ops,
213 		.parent_data = sys_ab_clk_parent_data,
214 		.num_parents = ARRAY_SIZE(sys_ab_clk_parent_data),
215 	},
216 };
217 
218 static struct clk_regmap s4_sysclk_b_div = {
219 	.data = &(struct clk_regmap_div_data){
220 		.offset = CLKCTRL_SYS_CLK_CTRL0,
221 		.shift = 16,
222 		.width = 10,
223 	},
224 	.hw.init = &(struct clk_init_data){
225 		.name = "sysclk_b_div",
226 		.ops = &clk_regmap_divider_ro_ops,
227 		.parent_hws = (const struct clk_hw *[]) {
228 			&s4_sysclk_b_sel.hw
229 		},
230 		.num_parents = 1,
231 	},
232 };
233 
234 static struct clk_regmap s4_sysclk_b = {
235 	.data = &(struct clk_regmap_gate_data){
236 		.offset = CLKCTRL_SYS_CLK_CTRL0,
237 		.bit_idx = 29,
238 	},
239 	.hw.init = &(struct clk_init_data) {
240 		.name = "sysclk_b",
241 		.ops = &clk_regmap_gate_ro_ops,
242 		.parent_hws = (const struct clk_hw *[]) {
243 			&s4_sysclk_b_div.hw
244 		},
245 		.num_parents = 1,
246 	},
247 };
248 
249 static struct clk_regmap s4_sysclk_a_sel = {
250 	.data = &(struct clk_regmap_mux_data){
251 		.offset = CLKCTRL_SYS_CLK_CTRL0,
252 		.mask = 0x7,
253 		.shift = 10,
254 		.table = mux_table_sys_ab_clk_sel,
255 	},
256 	.hw.init = &(struct clk_init_data){
257 		.name = "sysclk_a_sel",
258 		.ops = &clk_regmap_mux_ro_ops,
259 		.parent_data = sys_ab_clk_parent_data,
260 		.num_parents = ARRAY_SIZE(sys_ab_clk_parent_data),
261 	},
262 };
263 
264 static struct clk_regmap s4_sysclk_a_div = {
265 	.data = &(struct clk_regmap_div_data){
266 		.offset = CLKCTRL_SYS_CLK_CTRL0,
267 		.shift = 0,
268 		.width = 10,
269 	},
270 	.hw.init = &(struct clk_init_data){
271 		.name = "sysclk_a_div",
272 		.ops = &clk_regmap_divider_ro_ops,
273 		.parent_hws = (const struct clk_hw *[]) {
274 			&s4_sysclk_a_sel.hw
275 		},
276 		.num_parents = 1,
277 	},
278 };
279 
280 static struct clk_regmap s4_sysclk_a = {
281 	.data = &(struct clk_regmap_gate_data){
282 		.offset = CLKCTRL_SYS_CLK_CTRL0,
283 		.bit_idx = 13,
284 	},
285 	.hw.init = &(struct clk_init_data) {
286 		.name = "sysclk_a",
287 		.ops = &clk_regmap_gate_ro_ops,
288 		.parent_hws = (const struct clk_hw *[]) {
289 			&s4_sysclk_a_div.hw
290 		},
291 		.num_parents = 1,
292 	},
293 };
294 
295 static struct clk_regmap s4_sys_clk = {
296 	.data = &(struct clk_regmap_mux_data){
297 		.offset = CLKCTRL_SYS_CLK_CTRL0,
298 		.mask = 0x1,
299 		.shift = 31,
300 	},
301 	.hw.init = &(struct clk_init_data){
302 		.name = "sys_clk",
303 		.ops = &clk_regmap_mux_ro_ops,
304 		.parent_hws = (const struct clk_hw *[]) {
305 			&s4_sysclk_a.hw,
306 			&s4_sysclk_b.hw
307 		},
308 		.num_parents = 2,
309 	},
310 };
311 
312 static struct clk_regmap s4_ceca_32k_clkin = {
313 	.data = &(struct clk_regmap_gate_data){
314 		.offset = CLKCTRL_CECA_CTRL0,
315 		.bit_idx = 31,
316 	},
317 	.hw.init = &(struct clk_init_data) {
318 		.name = "ceca_32k_clkin",
319 		.ops = &clk_regmap_gate_ops,
320 		.parent_data = (const struct clk_parent_data []) {
321 			{ .fw_name = "xtal", }
322 		},
323 		.num_parents = 1,
324 	},
325 };
326 
327 static struct clk_regmap s4_ceca_32k_div = {
328 	.data = &(struct meson_clk_dualdiv_data){
329 		.n1 = {
330 			.reg_off = CLKCTRL_CECA_CTRL0,
331 			.shift   = 0,
332 			.width   = 12,
333 		},
334 		.n2 = {
335 			.reg_off = CLKCTRL_CECA_CTRL0,
336 			.shift   = 12,
337 			.width   = 12,
338 		},
339 		.m1 = {
340 			.reg_off = CLKCTRL_CECA_CTRL1,
341 			.shift   = 0,
342 			.width   = 12,
343 		},
344 		.m2 = {
345 			.reg_off = CLKCTRL_CECA_CTRL1,
346 			.shift   = 12,
347 			.width   = 12,
348 		},
349 		.dual = {
350 			.reg_off = CLKCTRL_CECA_CTRL0,
351 			.shift   = 28,
352 			.width   = 1,
353 		},
354 		.table = s4_32k_div_table,
355 	},
356 	.hw.init = &(struct clk_init_data){
357 		.name = "ceca_32k_div",
358 		.ops = &meson_clk_dualdiv_ops,
359 		.parent_hws = (const struct clk_hw *[]) {
360 			&s4_ceca_32k_clkin.hw
361 		},
362 		.num_parents = 1,
363 	},
364 };
365 
366 static struct clk_regmap s4_ceca_32k_sel_pre = {
367 	.data = &(struct clk_regmap_mux_data) {
368 		.offset = CLKCTRL_CECA_CTRL1,
369 		.mask = 0x1,
370 		.shift = 24,
371 		.flags = CLK_MUX_ROUND_CLOSEST,
372 	},
373 	.hw.init = &(struct clk_init_data){
374 		.name = "ceca_32k_sel_pre",
375 		.ops = &clk_regmap_mux_ops,
376 		.parent_hws = (const struct clk_hw *[]) {
377 			&s4_ceca_32k_div.hw,
378 			&s4_ceca_32k_clkin.hw
379 		},
380 		.num_parents = 2,
381 		.flags = CLK_SET_RATE_PARENT,
382 	},
383 };
384 
385 static struct clk_regmap s4_ceca_32k_sel = {
386 	.data = &(struct clk_regmap_mux_data) {
387 		.offset = CLKCTRL_CECA_CTRL1,
388 		.mask = 0x1,
389 		.shift = 31,
390 		.flags = CLK_MUX_ROUND_CLOSEST,
391 	},
392 	.hw.init = &(struct clk_init_data){
393 		.name = "ceca_32k_sel",
394 		.ops = &clk_regmap_mux_ops,
395 		.parent_hws = (const struct clk_hw *[]) {
396 			&s4_ceca_32k_sel_pre.hw,
397 			&s4_rtc_clk.hw
398 		},
399 		.num_parents = 2,
400 	},
401 };
402 
403 static struct clk_regmap s4_ceca_32k_clkout = {
404 	.data = &(struct clk_regmap_gate_data){
405 		.offset = CLKCTRL_CECA_CTRL0,
406 		.bit_idx = 30,
407 	},
408 	.hw.init = &(struct clk_init_data){
409 		.name = "ceca_32k_clkout",
410 		.ops = &clk_regmap_gate_ops,
411 		.parent_hws = (const struct clk_hw *[]) {
412 			&s4_ceca_32k_sel.hw
413 		},
414 		.num_parents = 1,
415 		.flags = CLK_SET_RATE_PARENT,
416 	},
417 };
418 
419 static struct clk_regmap s4_cecb_32k_clkin = {
420 	.data = &(struct clk_regmap_gate_data){
421 		.offset = CLKCTRL_CECB_CTRL0,
422 		.bit_idx = 31,
423 	},
424 	.hw.init = &(struct clk_init_data) {
425 		.name = "cecb_32k_clkin",
426 		.ops = &clk_regmap_gate_ops,
427 		.parent_data = (const struct clk_parent_data []) {
428 			{ .fw_name = "xtal", }
429 		},
430 		.num_parents = 1,
431 	},
432 };
433 
434 static struct clk_regmap s4_cecb_32k_div = {
435 	.data = &(struct meson_clk_dualdiv_data){
436 		.n1 = {
437 			.reg_off = CLKCTRL_CECB_CTRL0,
438 			.shift   = 0,
439 			.width   = 12,
440 		},
441 		.n2 = {
442 			.reg_off = CLKCTRL_CECB_CTRL0,
443 			.shift   = 12,
444 			.width   = 12,
445 		},
446 		.m1 = {
447 			.reg_off = CLKCTRL_CECB_CTRL1,
448 			.shift   = 0,
449 			.width   = 12,
450 		},
451 		.m2 = {
452 			.reg_off = CLKCTRL_CECB_CTRL1,
453 			.shift   = 12,
454 			.width   = 12,
455 		},
456 		.dual = {
457 			.reg_off = CLKCTRL_CECB_CTRL0,
458 			.shift   = 28,
459 			.width   = 1,
460 		},
461 		.table = s4_32k_div_table,
462 	},
463 	.hw.init = &(struct clk_init_data){
464 		.name = "cecb_32k_div",
465 		.ops = &meson_clk_dualdiv_ops,
466 		.parent_hws = (const struct clk_hw *[]) {
467 			&s4_cecb_32k_clkin.hw
468 		},
469 		.num_parents = 1,
470 	},
471 };
472 
473 static struct clk_regmap s4_cecb_32k_sel_pre = {
474 	.data = &(struct clk_regmap_mux_data) {
475 		.offset = CLKCTRL_CECB_CTRL1,
476 		.mask = 0x1,
477 		.shift = 24,
478 		.flags = CLK_MUX_ROUND_CLOSEST,
479 	},
480 	.hw.init = &(struct clk_init_data){
481 		.name = "cecb_32k_sel_pre",
482 		.ops = &clk_regmap_mux_ops,
483 		.parent_hws = (const struct clk_hw *[]) {
484 			&s4_cecb_32k_div.hw,
485 			&s4_cecb_32k_clkin.hw
486 		},
487 		.num_parents = 2,
488 		.flags = CLK_SET_RATE_PARENT,
489 	},
490 };
491 
492 static struct clk_regmap s4_cecb_32k_sel = {
493 	.data = &(struct clk_regmap_mux_data) {
494 		.offset = CLKCTRL_CECB_CTRL1,
495 		.mask = 0x1,
496 		.shift = 31,
497 		.flags = CLK_MUX_ROUND_CLOSEST,
498 	},
499 	.hw.init = &(struct clk_init_data){
500 		.name = "cecb_32k_sel",
501 		.ops = &clk_regmap_mux_ops,
502 		.parent_hws = (const struct clk_hw *[]) {
503 			&s4_cecb_32k_sel_pre.hw,
504 			&s4_rtc_clk.hw
505 		},
506 		.num_parents = 2,
507 	},
508 };
509 
510 static struct clk_regmap s4_cecb_32k_clkout = {
511 	.data = &(struct clk_regmap_gate_data){
512 		.offset = CLKCTRL_CECB_CTRL0,
513 		.bit_idx = 30,
514 	},
515 	.hw.init = &(struct clk_init_data){
516 		.name = "cecb_32k_clkout",
517 		.ops = &clk_regmap_gate_ops,
518 		.parent_hws = (const struct clk_hw *[]) {
519 			&s4_cecb_32k_sel.hw
520 		},
521 		.num_parents = 1,
522 		.flags = CLK_SET_RATE_PARENT,
523 	},
524 };
525 
526 static const struct clk_parent_data s4_sc_parent_data[] = {
527 	{ .fw_name = "fclk_div4" },
528 	{ .fw_name = "fclk_div3" },
529 	{ .fw_name = "fclk_div5" },
530 	{ .fw_name = "xtal", }
531 };
532 
533 static struct clk_regmap s4_sc_clk_mux = {
534 	.data = &(struct clk_regmap_mux_data){
535 		.offset = CLKCTRL_SC_CLK_CTRL,
536 		.mask = 0x3,
537 		.shift = 9,
538 	},
539 	.hw.init = &(struct clk_init_data) {
540 		.name = "sc_clk_mux",
541 		.ops = &clk_regmap_mux_ops,
542 		.parent_data = s4_sc_parent_data,
543 		.num_parents = ARRAY_SIZE(s4_sc_parent_data),
544 		.flags = CLK_SET_RATE_PARENT,
545 	},
546 };
547 
548 static struct clk_regmap s4_sc_clk_div = {
549 	.data = &(struct clk_regmap_div_data){
550 		.offset = CLKCTRL_SC_CLK_CTRL,
551 		.shift = 0,
552 		.width = 8,
553 	},
554 	.hw.init = &(struct clk_init_data) {
555 		.name = "sc_clk_div",
556 		.ops = &clk_regmap_divider_ops,
557 		.parent_hws = (const struct clk_hw *[]) {
558 			&s4_sc_clk_mux.hw
559 		},
560 		.num_parents = 1,
561 		.flags = CLK_SET_RATE_PARENT,
562 	},
563 };
564 
565 static struct clk_regmap s4_sc_clk_gate = {
566 	.data = &(struct clk_regmap_gate_data){
567 		.offset = CLKCTRL_SC_CLK_CTRL,
568 		.bit_idx = 8,
569 	},
570 	.hw.init = &(struct clk_init_data){
571 		.name = "sc_clk_gate",
572 		.ops = &clk_regmap_gate_ops,
573 		.parent_hws = (const struct clk_hw *[]) {
574 			&s4_sc_clk_div.hw
575 		},
576 		.num_parents = 1,
577 		.flags = CLK_SET_RATE_PARENT,
578 	},
579 };
580 
581 static struct clk_regmap s4_12_24M_clk_gate = {
582 	.data = &(struct clk_regmap_gate_data){
583 		.offset = CLKCTRL_CLK12_24_CTRL,
584 		.bit_idx = 11,
585 	},
586 	.hw.init = &(struct clk_init_data) {
587 		.name = "12_24m_gate",
588 		.ops = &clk_regmap_gate_ops,
589 		.parent_data = (const struct clk_parent_data []) {
590 			{ .fw_name = "xtal", }
591 		},
592 		.num_parents = 1,
593 	},
594 };
595 
596 static struct clk_fixed_factor s4_12M_clk_div = {
597 	.mult = 1,
598 	.div = 2,
599 	.hw.init = &(struct clk_init_data){
600 		.name = "12M",
601 		.ops = &clk_fixed_factor_ops,
602 		.parent_hws = (const struct clk_hw *[]) {
603 			&s4_12_24M_clk_gate.hw
604 		},
605 		.num_parents = 1,
606 		.flags = CLK_SET_RATE_PARENT,
607 	},
608 };
609 
610 static struct clk_regmap s4_12_24M_clk = {
611 	.data = &(struct clk_regmap_mux_data){
612 		.offset = CLKCTRL_CLK12_24_CTRL,
613 		.mask = 0x1,
614 		.shift = 10,
615 	},
616 	.hw.init = &(struct clk_init_data) {
617 		.name = "12_24m",
618 		.ops = &clk_regmap_mux_ops,
619 		.parent_hws = (const struct clk_hw *[]) {
620 			&s4_12_24M_clk_gate.hw,
621 			&s4_12M_clk_div.hw,
622 		},
623 		.num_parents = 2,
624 		.flags = CLK_SET_RATE_PARENT,
625 	},
626 };
627 
628 /* Video Clocks */
629 static struct clk_regmap s4_vid_pll_div = {
630 	.data = &(struct meson_vid_pll_div_data){
631 		.val = {
632 			.reg_off = CLKCTRL_VID_PLL_CLK_DIV,
633 			.shift   = 0,
634 			.width   = 15,
635 		},
636 		.sel = {
637 			.reg_off = CLKCTRL_VID_PLL_CLK_DIV,
638 			.shift   = 16,
639 			.width   = 2,
640 		},
641 	},
642 	.hw.init = &(struct clk_init_data) {
643 		.name = "vid_pll_div",
644 		/*
645 		 * TODO meson_vid_pll_div_ro_ops to meson_vid_pll_div_ops
646 		 */
647 		.ops = &meson_vid_pll_div_ro_ops,
648 		.parent_data = (const struct clk_parent_data []) {
649 			{ .fw_name = "hdmi_pll", }
650 		},
651 		.num_parents = 1,
652 		.flags = CLK_SET_RATE_PARENT,
653 	},
654 };
655 
656 static struct clk_regmap s4_vid_pll_sel = {
657 	.data = &(struct clk_regmap_mux_data){
658 		.offset = CLKCTRL_VID_PLL_CLK_DIV,
659 		.mask = 0x1,
660 		.shift = 18,
661 	},
662 	.hw.init = &(struct clk_init_data){
663 		.name = "vid_pll_sel",
664 		.ops = &clk_regmap_mux_ops,
665 		.parent_data = (const struct clk_parent_data []) {
666 			{ .hw = &s4_vid_pll_div.hw },
667 			{ .fw_name = "hdmi_pll", }
668 		},
669 		.num_parents = 2,
670 		.flags = CLK_SET_RATE_PARENT,
671 	},
672 };
673 
674 static struct clk_regmap s4_vid_pll = {
675 	.data = &(struct clk_regmap_gate_data){
676 		.offset = CLKCTRL_VID_PLL_CLK_DIV,
677 		.bit_idx = 19,
678 	},
679 	.hw.init = &(struct clk_init_data) {
680 		.name = "vid_pll",
681 		.ops = &clk_regmap_gate_ops,
682 		.parent_hws = (const struct clk_hw *[]) {
683 			&s4_vid_pll_sel.hw
684 		},
685 		.num_parents = 1,
686 		.flags = CLK_SET_RATE_PARENT,
687 	},
688 };
689 
690 static const struct clk_parent_data s4_vclk_parent_data[] = {
691 	{ .hw = &s4_vid_pll.hw },
692 	{ .fw_name = "gp0_pll", },
693 	{ .fw_name = "hifi_pll", },
694 	{ .fw_name = "mpll1", },
695 	{ .fw_name = "fclk_div3", },
696 	{ .fw_name = "fclk_div4", },
697 	{ .fw_name = "fclk_div5", },
698 	{ .fw_name = "fclk_div7", },
699 };
700 
701 static struct clk_regmap s4_vclk_sel = {
702 	.data = &(struct clk_regmap_mux_data){
703 		.offset = CLKCTRL_VID_CLK_CTRL,
704 		.mask = 0x7,
705 		.shift = 16,
706 	},
707 	.hw.init = &(struct clk_init_data){
708 		.name = "vclk_sel",
709 		.ops = &clk_regmap_mux_ops,
710 		.parent_data = s4_vclk_parent_data,
711 		.num_parents = ARRAY_SIZE(s4_vclk_parent_data),
712 		.flags = 0,
713 	},
714 };
715 
716 static struct clk_regmap s4_vclk2_sel = {
717 	.data = &(struct clk_regmap_mux_data){
718 		.offset = CLKCTRL_VIID_CLK_CTRL,
719 		.mask = 0x7,
720 		.shift = 16,
721 	},
722 	.hw.init = &(struct clk_init_data){
723 		.name = "vclk2_sel",
724 		.ops = &clk_regmap_mux_ops,
725 		.parent_data = s4_vclk_parent_data,
726 		.num_parents = ARRAY_SIZE(s4_vclk_parent_data),
727 		.flags = 0,
728 	},
729 };
730 
731 static struct clk_regmap s4_vclk_input = {
732 	.data = &(struct clk_regmap_gate_data){
733 		.offset = CLKCTRL_VID_CLK_DIV,
734 		.bit_idx = 16,
735 	},
736 	.hw.init = &(struct clk_init_data) {
737 		.name = "vclk_input",
738 		.ops = &clk_regmap_gate_ops,
739 		.parent_hws = (const struct clk_hw *[]) { &s4_vclk_sel.hw },
740 		.num_parents = 1,
741 		.flags = CLK_SET_RATE_PARENT,
742 	},
743 };
744 
745 static struct clk_regmap s4_vclk2_input = {
746 	.data = &(struct clk_regmap_gate_data){
747 		.offset = CLKCTRL_VIID_CLK_DIV,
748 		.bit_idx = 16,
749 	},
750 	.hw.init = &(struct clk_init_data) {
751 		.name = "vclk2_input",
752 		.ops = &clk_regmap_gate_ops,
753 		.parent_hws = (const struct clk_hw *[]) { &s4_vclk2_sel.hw },
754 		.num_parents = 1,
755 		.flags = CLK_SET_RATE_PARENT,
756 	},
757 };
758 
759 static struct clk_regmap s4_vclk_div = {
760 	.data = &(struct clk_regmap_div_data){
761 		.offset = CLKCTRL_VID_CLK_DIV,
762 		.shift = 0,
763 		.width = 8,
764 	},
765 	.hw.init = &(struct clk_init_data){
766 		.name = "vclk_div",
767 		.ops = &clk_regmap_divider_ops,
768 		.parent_hws = (const struct clk_hw *[]) {
769 			&s4_vclk_input.hw
770 		},
771 		.num_parents = 1,
772 		.flags = CLK_SET_RATE_PARENT,
773 	},
774 };
775 
776 static struct clk_regmap s4_vclk2_div = {
777 	.data = &(struct clk_regmap_div_data){
778 		.offset = CLKCTRL_VIID_CLK_DIV,
779 		.shift = 0,
780 		.width = 8,
781 	},
782 	.hw.init = &(struct clk_init_data){
783 		.name = "vclk2_div",
784 		.ops = &clk_regmap_divider_ops,
785 		.parent_hws = (const struct clk_hw *[]) {
786 			&s4_vclk2_input.hw
787 		},
788 		.num_parents = 1,
789 		.flags = CLK_SET_RATE_PARENT,
790 	},
791 };
792 
793 static struct clk_regmap s4_vclk = {
794 	.data = &(struct clk_regmap_gate_data){
795 		.offset = CLKCTRL_VID_CLK_CTRL,
796 		.bit_idx = 19,
797 	},
798 	.hw.init = &(struct clk_init_data) {
799 		.name = "vclk",
800 		.ops = &clk_regmap_gate_ops,
801 		.parent_hws = (const struct clk_hw *[]) { &s4_vclk_div.hw },
802 		.num_parents = 1,
803 		.flags = CLK_SET_RATE_PARENT,
804 	},
805 };
806 
807 static struct clk_regmap s4_vclk2 = {
808 	.data = &(struct clk_regmap_gate_data){
809 		.offset = CLKCTRL_VIID_CLK_CTRL,
810 		.bit_idx = 19,
811 	},
812 	.hw.init = &(struct clk_init_data) {
813 		.name = "vclk2",
814 		.ops = &clk_regmap_gate_ops,
815 		.parent_hws = (const struct clk_hw *[]) { &s4_vclk2_div.hw },
816 		.num_parents = 1,
817 		.flags = CLK_SET_RATE_PARENT,
818 	},
819 };
820 
821 static struct clk_regmap s4_vclk_div1 = {
822 	.data = &(struct clk_regmap_gate_data){
823 		.offset = CLKCTRL_VID_CLK_CTRL,
824 		.bit_idx = 0,
825 	},
826 	.hw.init = &(struct clk_init_data) {
827 		.name = "vclk_div1",
828 		.ops = &clk_regmap_gate_ops,
829 		.parent_hws = (const struct clk_hw *[]) { &s4_vclk.hw },
830 		.num_parents = 1,
831 		.flags = CLK_SET_RATE_PARENT,
832 	},
833 };
834 
835 static struct clk_regmap s4_vclk_div2_en = {
836 	.data = &(struct clk_regmap_gate_data){
837 		.offset = CLKCTRL_VID_CLK_CTRL,
838 		.bit_idx = 1,
839 	},
840 	.hw.init = &(struct clk_init_data) {
841 		.name = "vclk_div2_en",
842 		.ops = &clk_regmap_gate_ops,
843 		.parent_hws = (const struct clk_hw *[]) { &s4_vclk.hw },
844 		.num_parents = 1,
845 		.flags = CLK_SET_RATE_PARENT,
846 	},
847 };
848 
849 static struct clk_regmap s4_vclk_div4_en = {
850 	.data = &(struct clk_regmap_gate_data){
851 		.offset = CLKCTRL_VID_CLK_CTRL,
852 		.bit_idx = 2,
853 	},
854 	.hw.init = &(struct clk_init_data) {
855 		.name = "vclk_div4_en",
856 		.ops = &clk_regmap_gate_ops,
857 		.parent_hws = (const struct clk_hw *[]) { &s4_vclk.hw },
858 		.num_parents = 1,
859 		.flags = CLK_SET_RATE_PARENT,
860 	},
861 };
862 
863 static struct clk_regmap s4_vclk_div6_en = {
864 	.data = &(struct clk_regmap_gate_data){
865 		.offset = CLKCTRL_VID_CLK_CTRL,
866 		.bit_idx = 3,
867 	},
868 	.hw.init = &(struct clk_init_data) {
869 		.name = "vclk_div6_en",
870 		.ops = &clk_regmap_gate_ops,
871 		.parent_hws = (const struct clk_hw *[]) { &s4_vclk.hw },
872 		.num_parents = 1,
873 		.flags = CLK_SET_RATE_PARENT,
874 	},
875 };
876 
877 static struct clk_regmap s4_vclk_div12_en = {
878 	.data = &(struct clk_regmap_gate_data){
879 		.offset = CLKCTRL_VID_CLK_CTRL,
880 		.bit_idx = 4,
881 	},
882 	.hw.init = &(struct clk_init_data) {
883 		.name = "vclk_div12_en",
884 		.ops = &clk_regmap_gate_ops,
885 		.parent_hws = (const struct clk_hw *[]) { &s4_vclk.hw },
886 		.num_parents = 1,
887 		.flags = CLK_SET_RATE_PARENT,
888 	},
889 };
890 
891 static struct clk_regmap s4_vclk2_div1 = {
892 	.data = &(struct clk_regmap_gate_data){
893 		.offset = CLKCTRL_VIID_CLK_CTRL,
894 		.bit_idx = 0,
895 	},
896 	.hw.init = &(struct clk_init_data) {
897 		.name = "vclk2_div1",
898 		.ops = &clk_regmap_gate_ops,
899 		.parent_hws = (const struct clk_hw *[]) { &s4_vclk2.hw },
900 		.num_parents = 1,
901 		.flags = CLK_SET_RATE_PARENT,
902 	},
903 };
904 
905 static struct clk_regmap s4_vclk2_div2_en = {
906 	.data = &(struct clk_regmap_gate_data){
907 		.offset = CLKCTRL_VIID_CLK_CTRL,
908 		.bit_idx = 1,
909 	},
910 	.hw.init = &(struct clk_init_data) {
911 		.name = "vclk2_div2_en",
912 		.ops = &clk_regmap_gate_ops,
913 		.parent_hws = (const struct clk_hw *[]) { &s4_vclk2.hw },
914 		.num_parents = 1,
915 		.flags = CLK_SET_RATE_PARENT,
916 	},
917 };
918 
919 static struct clk_regmap s4_vclk2_div4_en = {
920 	.data = &(struct clk_regmap_gate_data){
921 		.offset = CLKCTRL_VIID_CLK_CTRL,
922 		.bit_idx = 2,
923 	},
924 	.hw.init = &(struct clk_init_data) {
925 		.name = "vclk2_div4_en",
926 		.ops = &clk_regmap_gate_ops,
927 		.parent_hws = (const struct clk_hw *[]) { &s4_vclk2.hw },
928 		.num_parents = 1,
929 		.flags = CLK_SET_RATE_PARENT,
930 	},
931 };
932 
933 static struct clk_regmap s4_vclk2_div6_en = {
934 	.data = &(struct clk_regmap_gate_data){
935 		.offset = CLKCTRL_VIID_CLK_CTRL,
936 		.bit_idx = 3,
937 	},
938 	.hw.init = &(struct clk_init_data) {
939 		.name = "vclk2_div6_en",
940 		.ops = &clk_regmap_gate_ops,
941 		.parent_hws = (const struct clk_hw *[]) { &s4_vclk2.hw },
942 		.num_parents = 1,
943 		.flags = CLK_SET_RATE_PARENT,
944 	},
945 };
946 
947 static struct clk_regmap s4_vclk2_div12_en = {
948 	.data = &(struct clk_regmap_gate_data){
949 		.offset = CLKCTRL_VIID_CLK_CTRL,
950 		.bit_idx = 4,
951 	},
952 	.hw.init = &(struct clk_init_data) {
953 		.name = "vclk2_div12_en",
954 		.ops = &clk_regmap_gate_ops,
955 		.parent_hws = (const struct clk_hw *[]) { &s4_vclk2.hw },
956 		.num_parents = 1,
957 		.flags = CLK_SET_RATE_PARENT,
958 	},
959 };
960 
961 static struct clk_fixed_factor s4_vclk_div2 = {
962 	.mult = 1,
963 	.div = 2,
964 	.hw.init = &(struct clk_init_data){
965 		.name = "vclk_div2",
966 		.ops = &clk_fixed_factor_ops,
967 		.parent_hws = (const struct clk_hw *[]) {
968 			&s4_vclk_div2_en.hw
969 		},
970 		.num_parents = 1,
971 		.flags = CLK_SET_RATE_PARENT,
972 	},
973 };
974 
975 static struct clk_fixed_factor s4_vclk_div4 = {
976 	.mult = 1,
977 	.div = 4,
978 	.hw.init = &(struct clk_init_data){
979 		.name = "vclk_div4",
980 		.ops = &clk_fixed_factor_ops,
981 		.parent_hws = (const struct clk_hw *[]) {
982 			&s4_vclk_div4_en.hw
983 		},
984 		.num_parents = 1,
985 		.flags = CLK_SET_RATE_PARENT,
986 	},
987 };
988 
989 static struct clk_fixed_factor s4_vclk_div6 = {
990 	.mult = 1,
991 	.div = 6,
992 	.hw.init = &(struct clk_init_data){
993 		.name = "vclk_div6",
994 		.ops = &clk_fixed_factor_ops,
995 		.parent_hws = (const struct clk_hw *[]) {
996 			&s4_vclk_div6_en.hw
997 		},
998 		.num_parents = 1,
999 		.flags = CLK_SET_RATE_PARENT,
1000 	},
1001 };
1002 
1003 static struct clk_fixed_factor s4_vclk_div12 = {
1004 	.mult = 1,
1005 	.div = 12,
1006 	.hw.init = &(struct clk_init_data){
1007 		.name = "vclk_div12",
1008 		.ops = &clk_fixed_factor_ops,
1009 		.parent_hws = (const struct clk_hw *[]) {
1010 			&s4_vclk_div12_en.hw
1011 		},
1012 		.num_parents = 1,
1013 		.flags = CLK_SET_RATE_PARENT,
1014 	},
1015 };
1016 
1017 static struct clk_fixed_factor s4_vclk2_div2 = {
1018 	.mult = 1,
1019 	.div = 2,
1020 	.hw.init = &(struct clk_init_data){
1021 		.name = "vclk2_div2",
1022 		.ops = &clk_fixed_factor_ops,
1023 		.parent_hws = (const struct clk_hw *[]) {
1024 			&s4_vclk2_div2_en.hw
1025 		},
1026 		.num_parents = 1,
1027 		.flags = CLK_SET_RATE_PARENT,
1028 	},
1029 };
1030 
1031 static struct clk_fixed_factor s4_vclk2_div4 = {
1032 	.mult = 1,
1033 	.div = 4,
1034 	.hw.init = &(struct clk_init_data){
1035 		.name = "vclk2_div4",
1036 		.ops = &clk_fixed_factor_ops,
1037 		.parent_hws = (const struct clk_hw *[]) {
1038 			&s4_vclk2_div4_en.hw
1039 		},
1040 		.num_parents = 1,
1041 		.flags = CLK_SET_RATE_PARENT,
1042 	},
1043 };
1044 
1045 static struct clk_fixed_factor s4_vclk2_div6 = {
1046 	.mult = 1,
1047 	.div = 6,
1048 	.hw.init = &(struct clk_init_data){
1049 		.name = "vclk2_div6",
1050 		.ops = &clk_fixed_factor_ops,
1051 		.parent_hws = (const struct clk_hw *[]) {
1052 			&s4_vclk2_div6_en.hw
1053 		},
1054 		.num_parents = 1,
1055 		.flags = CLK_SET_RATE_PARENT,
1056 	},
1057 };
1058 
1059 static struct clk_fixed_factor s4_vclk2_div12 = {
1060 	.mult = 1,
1061 	.div = 12,
1062 	.hw.init = &(struct clk_init_data){
1063 		.name = "vclk2_div12",
1064 		.ops = &clk_fixed_factor_ops,
1065 		.parent_hws = (const struct clk_hw *[]) {
1066 			&s4_vclk2_div12_en.hw
1067 		},
1068 		.num_parents = 1,
1069 		.flags = CLK_SET_RATE_PARENT,
1070 	},
1071 };
1072 
1073 /* The 5,6,7 indexes corresponds to no real clock, so there are not used. */
1074 static u32 mux_table_cts_sel[] = { 0, 1, 2, 3, 4, 8, 9, 10, 11, 12 };
1075 static const struct clk_hw *s4_cts_parent_hws[] = {
1076 	&s4_vclk_div1.hw,
1077 	&s4_vclk_div2.hw,
1078 	&s4_vclk_div4.hw,
1079 	&s4_vclk_div6.hw,
1080 	&s4_vclk_div12.hw,
1081 	&s4_vclk2_div1.hw,
1082 	&s4_vclk2_div2.hw,
1083 	&s4_vclk2_div4.hw,
1084 	&s4_vclk2_div6.hw,
1085 	&s4_vclk2_div12.hw
1086 };
1087 
1088 static struct clk_regmap s4_cts_enci_sel = {
1089 	.data = &(struct clk_regmap_mux_data){
1090 		.offset = CLKCTRL_VID_CLK_DIV,
1091 		.mask = 0xf,
1092 		.shift = 28,
1093 		.table = mux_table_cts_sel,
1094 	},
1095 	.hw.init = &(struct clk_init_data){
1096 		.name = "cts_enci_sel",
1097 		.ops = &clk_regmap_mux_ops,
1098 		.parent_hws = s4_cts_parent_hws,
1099 		.num_parents = ARRAY_SIZE(s4_cts_parent_hws),
1100 		.flags = CLK_SET_RATE_PARENT,
1101 	},
1102 };
1103 
1104 static struct clk_regmap s4_cts_encp_sel = {
1105 	.data = &(struct clk_regmap_mux_data){
1106 		.offset = CLKCTRL_VID_CLK_DIV,
1107 		.mask = 0xf,
1108 		.shift = 20,
1109 		.table = mux_table_cts_sel,
1110 	},
1111 	.hw.init = &(struct clk_init_data){
1112 		.name = "cts_encp_sel",
1113 		.ops = &clk_regmap_mux_ops,
1114 		.parent_hws = s4_cts_parent_hws,
1115 		.num_parents = ARRAY_SIZE(s4_cts_parent_hws),
1116 		.flags = CLK_SET_RATE_PARENT,
1117 	},
1118 };
1119 
1120 static struct clk_regmap s4_cts_vdac_sel = {
1121 	.data = &(struct clk_regmap_mux_data){
1122 		.offset = CLKCTRL_VIID_CLK_DIV,
1123 		.mask = 0xf,
1124 		.shift = 28,
1125 		.table = mux_table_cts_sel,
1126 	},
1127 	.hw.init = &(struct clk_init_data){
1128 		.name = "cts_vdac_sel",
1129 		.ops = &clk_regmap_mux_ops,
1130 		.parent_hws = s4_cts_parent_hws,
1131 		.num_parents = ARRAY_SIZE(s4_cts_parent_hws),
1132 		.flags = CLK_SET_RATE_PARENT,
1133 	},
1134 };
1135 
1136 /* The 5,6,7 indexes corresponds to no real clock, so there are not used. */
1137 static u32 mux_table_hdmi_tx_sel[] = { 0, 1, 2, 3, 4, 8, 9, 10, 11, 12 };
1138 static const struct clk_hw *s4_cts_hdmi_tx_parent_hws[] = {
1139 	&s4_vclk_div1.hw,
1140 	&s4_vclk_div2.hw,
1141 	&s4_vclk_div4.hw,
1142 	&s4_vclk_div6.hw,
1143 	&s4_vclk_div12.hw,
1144 	&s4_vclk2_div1.hw,
1145 	&s4_vclk2_div2.hw,
1146 	&s4_vclk2_div4.hw,
1147 	&s4_vclk2_div6.hw,
1148 	&s4_vclk2_div12.hw
1149 };
1150 
1151 static struct clk_regmap s4_hdmi_tx_sel = {
1152 	.data = &(struct clk_regmap_mux_data){
1153 		.offset = CLKCTRL_HDMI_CLK_CTRL,
1154 		.mask = 0xf,
1155 		.shift = 16,
1156 		.table = mux_table_hdmi_tx_sel,
1157 	},
1158 	.hw.init = &(struct clk_init_data){
1159 		.name = "hdmi_tx_sel",
1160 		.ops = &clk_regmap_mux_ops,
1161 		.parent_hws = s4_cts_hdmi_tx_parent_hws,
1162 		.num_parents = ARRAY_SIZE(s4_cts_hdmi_tx_parent_hws),
1163 		.flags = CLK_SET_RATE_PARENT,
1164 	},
1165 };
1166 
1167 static struct clk_regmap s4_cts_enci = {
1168 	.data = &(struct clk_regmap_gate_data){
1169 		.offset = CLKCTRL_VID_CLK_CTRL2,
1170 		.bit_idx = 0,
1171 	},
1172 	.hw.init = &(struct clk_init_data) {
1173 		.name = "cts_enci",
1174 		.ops = &clk_regmap_gate_ops,
1175 		.parent_hws = (const struct clk_hw *[]) {
1176 			&s4_cts_enci_sel.hw
1177 		},
1178 		.num_parents = 1,
1179 		.flags = CLK_SET_RATE_PARENT,
1180 	},
1181 };
1182 
1183 static struct clk_regmap s4_cts_encp = {
1184 	.data = &(struct clk_regmap_gate_data){
1185 		.offset = CLKCTRL_VID_CLK_CTRL2,
1186 		.bit_idx = 2,
1187 	},
1188 	.hw.init = &(struct clk_init_data) {
1189 		.name = "cts_encp",
1190 		.ops = &clk_regmap_gate_ops,
1191 		.parent_hws = (const struct clk_hw *[]) {
1192 			&s4_cts_encp_sel.hw
1193 		},
1194 		.num_parents = 1,
1195 		.flags = CLK_SET_RATE_PARENT,
1196 	},
1197 };
1198 
1199 static struct clk_regmap s4_cts_vdac = {
1200 	.data = &(struct clk_regmap_gate_data){
1201 		.offset = CLKCTRL_VID_CLK_CTRL2,
1202 		.bit_idx = 4,
1203 	},
1204 	.hw.init = &(struct clk_init_data) {
1205 		.name = "cts_vdac",
1206 		.ops = &clk_regmap_gate_ops,
1207 		.parent_hws = (const struct clk_hw *[]) {
1208 			&s4_cts_vdac_sel.hw
1209 		},
1210 		.num_parents = 1,
1211 		.flags = CLK_SET_RATE_PARENT,
1212 	},
1213 };
1214 
1215 static struct clk_regmap s4_hdmi_tx = {
1216 	.data = &(struct clk_regmap_gate_data){
1217 		.offset = CLKCTRL_VID_CLK_CTRL2,
1218 		.bit_idx = 5,
1219 	},
1220 	.hw.init = &(struct clk_init_data) {
1221 		.name = "hdmi_tx",
1222 		.ops = &clk_regmap_gate_ops,
1223 		.parent_hws = (const struct clk_hw *[]) {
1224 			&s4_hdmi_tx_sel.hw
1225 		},
1226 		.num_parents = 1,
1227 		.flags = CLK_SET_RATE_PARENT,
1228 	},
1229 };
1230 
1231 /* HDMI Clocks */
1232 static const struct clk_parent_data s4_hdmi_parent_data[] = {
1233 	{ .fw_name = "xtal", },
1234 	{ .fw_name = "fclk_div4", },
1235 	{ .fw_name = "fclk_div3", },
1236 	{ .fw_name = "fclk_div5", }
1237 };
1238 
1239 static struct clk_regmap s4_hdmi_sel = {
1240 	.data = &(struct clk_regmap_mux_data){
1241 		.offset = CLKCTRL_HDMI_CLK_CTRL,
1242 		.mask = 0x3,
1243 		.shift = 9,
1244 		.flags = CLK_MUX_ROUND_CLOSEST,
1245 	},
1246 	.hw.init = &(struct clk_init_data){
1247 		.name = "hdmi_sel",
1248 		.ops = &clk_regmap_mux_ops,
1249 		.parent_data = s4_hdmi_parent_data,
1250 		.num_parents = ARRAY_SIZE(s4_hdmi_parent_data),
1251 		.flags = CLK_SET_RATE_PARENT,
1252 	},
1253 };
1254 
1255 static struct clk_regmap s4_hdmi_div = {
1256 	.data = &(struct clk_regmap_div_data){
1257 		.offset = CLKCTRL_HDMI_CLK_CTRL,
1258 		.shift = 0,
1259 		.width = 7,
1260 	},
1261 	.hw.init = &(struct clk_init_data){
1262 		.name = "hdmi_div",
1263 		.ops = &clk_regmap_divider_ops,
1264 		.parent_hws = (const struct clk_hw *[]) { &s4_hdmi_sel.hw },
1265 		.num_parents = 1,
1266 		.flags = CLK_SET_RATE_PARENT,
1267 	},
1268 };
1269 
1270 static struct clk_regmap s4_hdmi = {
1271 	.data = &(struct clk_regmap_gate_data){
1272 		.offset = CLKCTRL_HDMI_CLK_CTRL,
1273 		.bit_idx = 8,
1274 	},
1275 	.hw.init = &(struct clk_init_data) {
1276 		.name = "hdmi",
1277 		.ops = &clk_regmap_gate_ops,
1278 		.parent_hws = (const struct clk_hw *[]) { &s4_hdmi_div.hw },
1279 		.num_parents = 1,
1280 		.flags = CLK_SET_RATE_PARENT,
1281 	},
1282 };
1283 
1284 static struct clk_regmap s4_ts_clk_div = {
1285 	.data = &(struct clk_regmap_div_data){
1286 		.offset = CLKCTRL_TS_CLK_CTRL,
1287 		.shift = 0,
1288 		.width = 8,
1289 	},
1290 	.hw.init = &(struct clk_init_data){
1291 		.name = "ts_clk_div",
1292 		.ops = &clk_regmap_divider_ops,
1293 		.parent_data = &(const struct clk_parent_data) {
1294 			.fw_name = "xtal",
1295 		},
1296 		.num_parents = 1,
1297 		.flags = CLK_SET_RATE_PARENT,
1298 	},
1299 };
1300 
1301 static struct clk_regmap s4_ts_clk_gate = {
1302 	.data = &(struct clk_regmap_gate_data){
1303 		.offset = CLKCTRL_TS_CLK_CTRL,
1304 		.bit_idx = 8,
1305 	},
1306 	.hw.init = &(struct clk_init_data){
1307 		.name = "ts_clk",
1308 		.ops = &clk_regmap_gate_ops,
1309 		.parent_hws = (const struct clk_hw *[]) {
1310 			&s4_ts_clk_div.hw
1311 		},
1312 		.num_parents = 1,
1313 		.flags = CLK_SET_RATE_PARENT,
1314 	},
1315 };
1316 
1317 /*
1318  * The MALI IP is clocked by two identical clocks (mali_0 and mali_1)
1319  * muxed by a glitch-free switch. The CCF can manage this glitch-free
1320  * mux because it does top-to-bottom updates the each clock tree and
1321  * switches to the "inactive" one when CLK_SET_RATE_GATE is set.
1322  */
1323 static const struct clk_parent_data s4_mali_0_1_parent_data[] = {
1324 	{ .fw_name = "xtal", },
1325 	{ .fw_name = "gp0_pll", },
1326 	{ .fw_name = "hifi_pll", },
1327 	{ .fw_name = "fclk_div2p5", },
1328 	{ .fw_name = "fclk_div3", },
1329 	{ .fw_name = "fclk_div4", },
1330 	{ .fw_name = "fclk_div5", },
1331 	{ .fw_name = "fclk_div7", }
1332 };
1333 
1334 static struct clk_regmap s4_mali_0_sel = {
1335 	.data = &(struct clk_regmap_mux_data){
1336 		.offset = CLKCTRL_MALI_CLK_CTRL,
1337 		.mask = 0x7,
1338 		.shift = 9,
1339 	},
1340 	.hw.init = &(struct clk_init_data){
1341 		.name = "mali_0_sel",
1342 		.ops = &clk_regmap_mux_ops,
1343 		.parent_data = s4_mali_0_1_parent_data,
1344 		.num_parents = ARRAY_SIZE(s4_mali_0_1_parent_data),
1345 		/*
1346 		 * Don't request the parent to change the rate because
1347 		 * all GPU frequencies can be derived from the fclk_*
1348 		 * clocks and one special GP0_PLL setting. This is
1349 		 * important because we need the HIFI PLL clock for audio.
1350 		 */
1351 		.flags = 0,
1352 	},
1353 };
1354 
1355 static struct clk_regmap s4_mali_0_div = {
1356 	.data = &(struct clk_regmap_div_data){
1357 		.offset = CLKCTRL_MALI_CLK_CTRL,
1358 		.shift = 0,
1359 		.width = 7,
1360 	},
1361 	.hw.init = &(struct clk_init_data){
1362 		.name = "mali_0_div",
1363 		.ops = &clk_regmap_divider_ops,
1364 		.parent_hws = (const struct clk_hw *[]) {
1365 			&s4_mali_0_sel.hw
1366 		},
1367 		.num_parents = 1,
1368 		.flags = CLK_SET_RATE_PARENT,
1369 	},
1370 };
1371 
1372 static struct clk_regmap s4_mali_0 = {
1373 	.data = &(struct clk_regmap_gate_data){
1374 		.offset = CLKCTRL_MALI_CLK_CTRL,
1375 		.bit_idx = 8,
1376 	},
1377 	.hw.init = &(struct clk_init_data){
1378 		.name = "mali_0",
1379 		.ops = &clk_regmap_gate_ops,
1380 		.parent_hws = (const struct clk_hw *[]) {
1381 			&s4_mali_0_div.hw
1382 		},
1383 		.num_parents = 1,
1384 		.flags = CLK_SET_RATE_GATE | CLK_SET_RATE_PARENT,
1385 	},
1386 };
1387 
1388 static struct clk_regmap s4_mali_1_sel = {
1389 	.data = &(struct clk_regmap_mux_data){
1390 		.offset = CLKCTRL_MALI_CLK_CTRL,
1391 		.mask = 0x7,
1392 		.shift = 25,
1393 	},
1394 	.hw.init = &(struct clk_init_data){
1395 		.name = "mali_1_sel",
1396 		.ops = &clk_regmap_mux_ops,
1397 		.parent_data = s4_mali_0_1_parent_data,
1398 		.num_parents = ARRAY_SIZE(s4_mali_0_1_parent_data),
1399 		.flags = 0,
1400 	},
1401 };
1402 
1403 static struct clk_regmap s4_mali_1_div = {
1404 	.data = &(struct clk_regmap_div_data){
1405 		.offset = CLKCTRL_MALI_CLK_CTRL,
1406 		.shift = 16,
1407 		.width = 7,
1408 	},
1409 	.hw.init = &(struct clk_init_data){
1410 		.name = "mali_1_div",
1411 		.ops = &clk_regmap_divider_ops,
1412 		.parent_hws = (const struct clk_hw *[]) {
1413 			&s4_mali_1_sel.hw
1414 		},
1415 		.num_parents = 1,
1416 		.flags = CLK_SET_RATE_PARENT,
1417 	},
1418 };
1419 
1420 static struct clk_regmap s4_mali_1 = {
1421 	.data = &(struct clk_regmap_gate_data){
1422 		.offset = CLKCTRL_MALI_CLK_CTRL,
1423 		.bit_idx = 24,
1424 	},
1425 	.hw.init = &(struct clk_init_data){
1426 		.name = "mali_1",
1427 		.ops = &clk_regmap_gate_ops,
1428 		.parent_hws = (const struct clk_hw *[]) {
1429 			&s4_mali_1_div.hw
1430 		},
1431 		.num_parents = 1,
1432 		.flags = CLK_SET_RATE_GATE | CLK_SET_RATE_PARENT,
1433 	},
1434 };
1435 
1436 static const struct clk_hw *s4_mali_parent_hws[] = {
1437 	&s4_mali_0.hw,
1438 	&s4_mali_1.hw
1439 };
1440 
1441 static struct clk_regmap s4_mali_mux = {
1442 	.data = &(struct clk_regmap_mux_data){
1443 		.offset = CLKCTRL_MALI_CLK_CTRL,
1444 		.mask = 1,
1445 		.shift = 31,
1446 	},
1447 	.hw.init = &(struct clk_init_data){
1448 		.name = "mali",
1449 		.ops = &clk_regmap_mux_ops,
1450 		.parent_hws = s4_mali_parent_hws,
1451 		.num_parents = 2,
1452 		.flags = CLK_SET_RATE_PARENT,
1453 	},
1454 };
1455 
1456 /* VDEC clocks */
1457 static const struct clk_parent_data s4_dec_parent_data[] = {
1458 	{ .fw_name = "fclk_div2p5", },
1459 	{ .fw_name = "fclk_div3", },
1460 	{ .fw_name = "fclk_div4", },
1461 	{ .fw_name = "fclk_div5", },
1462 	{ .fw_name = "fclk_div7", },
1463 	{ .fw_name = "hifi_pll", },
1464 	{ .fw_name = "gp0_pll", },
1465 	{ .fw_name = "xtal", }
1466 };
1467 
1468 static struct clk_regmap s4_vdec_p0_mux = {
1469 	.data = &(struct clk_regmap_mux_data){
1470 		.offset = CLKCTRL_VDEC_CLK_CTRL,
1471 		.mask = 0x7,
1472 		.shift = 9,
1473 		.flags = CLK_MUX_ROUND_CLOSEST,
1474 	},
1475 	.hw.init = &(struct clk_init_data) {
1476 		.name = "vdec_p0_mux",
1477 		.ops = &clk_regmap_mux_ops,
1478 		.parent_data = s4_dec_parent_data,
1479 		.num_parents = ARRAY_SIZE(s4_dec_parent_data),
1480 		.flags = 0,
1481 	},
1482 };
1483 
1484 static struct clk_regmap s4_vdec_p0_div = {
1485 	.data = &(struct clk_regmap_div_data){
1486 		.offset = CLKCTRL_VDEC_CLK_CTRL,
1487 		.shift = 0,
1488 		.width = 7,
1489 		.flags = CLK_DIVIDER_ROUND_CLOSEST,
1490 	},
1491 	.hw.init = &(struct clk_init_data) {
1492 		.name = "vdec_p0_div",
1493 		.ops = &clk_regmap_divider_ops,
1494 		.parent_hws = (const struct clk_hw *[]) {
1495 			&s4_vdec_p0_mux.hw
1496 		},
1497 		.num_parents = 1,
1498 		.flags = CLK_SET_RATE_PARENT,
1499 	},
1500 };
1501 
1502 static struct clk_regmap s4_vdec_p0 = {
1503 	.data = &(struct clk_regmap_gate_data){
1504 		.offset = CLKCTRL_VDEC_CLK_CTRL,
1505 		.bit_idx = 8,
1506 	},
1507 	.hw.init = &(struct clk_init_data){
1508 		.name = "vdec_p0",
1509 		.ops = &clk_regmap_gate_ops,
1510 		.parent_hws = (const struct clk_hw *[]) {
1511 			&s4_vdec_p0_div.hw
1512 		},
1513 		.num_parents = 1,
1514 		.flags = CLK_SET_RATE_PARENT,
1515 	},
1516 };
1517 
1518 static struct clk_regmap s4_vdec_p1_mux = {
1519 	.data = &(struct clk_regmap_mux_data){
1520 		.offset = CLKCTRL_VDEC3_CLK_CTRL,
1521 		.mask = 0x7,
1522 		.shift = 9,
1523 		.flags = CLK_MUX_ROUND_CLOSEST,
1524 	},
1525 	.hw.init = &(struct clk_init_data) {
1526 		.name = "vdec_p1_mux",
1527 		.ops = &clk_regmap_mux_ops,
1528 		.parent_data = s4_dec_parent_data,
1529 		.num_parents = ARRAY_SIZE(s4_dec_parent_data),
1530 		.flags = 0,
1531 	},
1532 };
1533 
1534 static struct clk_regmap s4_vdec_p1_div = {
1535 	.data = &(struct clk_regmap_div_data){
1536 		.offset = CLKCTRL_VDEC3_CLK_CTRL,
1537 		.shift = 0,
1538 		.width = 7,
1539 		.flags = CLK_DIVIDER_ROUND_CLOSEST,
1540 	},
1541 	.hw.init = &(struct clk_init_data) {
1542 		.name = "vdec_p1_div",
1543 		.ops = &clk_regmap_divider_ops,
1544 		.parent_hws = (const struct clk_hw *[]) {
1545 			&s4_vdec_p1_mux.hw
1546 		},
1547 		.num_parents = 1,
1548 		.flags = CLK_SET_RATE_PARENT,
1549 	},
1550 };
1551 
1552 static struct clk_regmap s4_vdec_p1 = {
1553 	.data = &(struct clk_regmap_gate_data){
1554 		.offset = CLKCTRL_VDEC3_CLK_CTRL,
1555 		.bit_idx = 8,
1556 	},
1557 	.hw.init = &(struct clk_init_data){
1558 		.name = "vdec_p1",
1559 		.ops = &clk_regmap_gate_ops,
1560 		.parent_hws = (const struct clk_hw *[]) {
1561 			&s4_vdec_p1_div.hw
1562 		},
1563 		.num_parents = 1,
1564 		.flags = CLK_SET_RATE_PARENT,
1565 	},
1566 };
1567 
1568 static const struct clk_hw *s4_vdec_mux_parent_hws[] = {
1569 	&s4_vdec_p0.hw,
1570 	&s4_vdec_p1.hw
1571 };
1572 
1573 static struct clk_regmap s4_vdec_mux = {
1574 	.data = &(struct clk_regmap_mux_data){
1575 		.offset = CLKCTRL_VDEC3_CLK_CTRL,
1576 		.mask = 0x1,
1577 		.shift = 15,
1578 	},
1579 	.hw.init = &(struct clk_init_data) {
1580 		.name = "vdec_mux",
1581 		.ops = &clk_regmap_mux_ops,
1582 		.parent_hws = s4_vdec_mux_parent_hws,
1583 		.num_parents = ARRAY_SIZE(s4_vdec_mux_parent_hws),
1584 		.flags = CLK_SET_RATE_PARENT,
1585 	},
1586 };
1587 
1588 static struct clk_regmap s4_hevcf_p0_mux = {
1589 	.data = &(struct clk_regmap_mux_data){
1590 		.offset = CLKCTRL_VDEC2_CLK_CTRL,
1591 		.mask = 0x7,
1592 		.shift = 9,
1593 		.flags = CLK_MUX_ROUND_CLOSEST,
1594 	},
1595 	.hw.init = &(struct clk_init_data) {
1596 		.name = "hevcf_p0_mux",
1597 		.ops = &clk_regmap_mux_ops,
1598 		.parent_data = s4_dec_parent_data,
1599 		.num_parents = ARRAY_SIZE(s4_dec_parent_data),
1600 		.flags = 0,
1601 	},
1602 };
1603 
1604 static struct clk_regmap s4_hevcf_p0_div = {
1605 	.data = &(struct clk_regmap_div_data){
1606 		.offset = CLKCTRL_VDEC2_CLK_CTRL,
1607 		.shift = 0,
1608 		.width = 7,
1609 		.flags = CLK_DIVIDER_ROUND_CLOSEST,
1610 	},
1611 	.hw.init = &(struct clk_init_data) {
1612 		.name = "hevcf_p0_div",
1613 		.ops = &clk_regmap_divider_ops,
1614 		.parent_hws = (const struct clk_hw *[]) {
1615 			&s4_hevcf_p0_mux.hw
1616 		},
1617 		.num_parents = 1,
1618 		.flags = CLK_SET_RATE_PARENT,
1619 	},
1620 };
1621 
1622 static struct clk_regmap s4_hevcf_p0 = {
1623 	.data = &(struct clk_regmap_gate_data){
1624 		.offset = CLKCTRL_VDEC2_CLK_CTRL,
1625 		.bit_idx = 8,
1626 	},
1627 	.hw.init = &(struct clk_init_data){
1628 		.name = "hevcf_p0_gate",
1629 		.ops = &clk_regmap_gate_ops,
1630 		.parent_hws = (const struct clk_hw *[]) {
1631 			&s4_hevcf_p0_div.hw
1632 		},
1633 		.num_parents = 1,
1634 		.flags = CLK_SET_RATE_PARENT,
1635 	},
1636 };
1637 
1638 static struct clk_regmap s4_hevcf_p1_mux = {
1639 	.data = &(struct clk_regmap_mux_data){
1640 		.offset = CLKCTRL_VDEC4_CLK_CTRL,
1641 		.mask = 0x7,
1642 		.shift = 9,
1643 		.flags = CLK_MUX_ROUND_CLOSEST,
1644 	},
1645 	.hw.init = &(struct clk_init_data) {
1646 		.name = "hevcf_p1_mux",
1647 		.ops = &clk_regmap_mux_ops,
1648 		.parent_data = s4_dec_parent_data,
1649 		.num_parents = ARRAY_SIZE(s4_dec_parent_data),
1650 		.flags = 0,
1651 	},
1652 };
1653 
1654 static struct clk_regmap s4_hevcf_p1_div = {
1655 	.data = &(struct clk_regmap_div_data){
1656 		.offset = CLKCTRL_VDEC4_CLK_CTRL,
1657 		.shift = 0,
1658 		.width = 7,
1659 		.flags = CLK_DIVIDER_ROUND_CLOSEST,
1660 	},
1661 	.hw.init = &(struct clk_init_data) {
1662 		.name = "hevcf_p1_div",
1663 		.ops = &clk_regmap_divider_ops,
1664 		.parent_hws = (const struct clk_hw *[]) {
1665 			&s4_hevcf_p1_mux.hw
1666 		},
1667 		.num_parents = 1,
1668 		.flags = CLK_SET_RATE_PARENT,
1669 	},
1670 };
1671 
1672 static struct clk_regmap s4_hevcf_p1 = {
1673 	.data = &(struct clk_regmap_gate_data){
1674 		.offset = CLKCTRL_VDEC4_CLK_CTRL,
1675 		.bit_idx = 8,
1676 	},
1677 	.hw.init = &(struct clk_init_data){
1678 		.name = "hevcf_p1",
1679 		.ops = &clk_regmap_gate_ops,
1680 		.parent_hws = (const struct clk_hw *[]) {
1681 			&s4_hevcf_p1_div.hw
1682 		},
1683 		.num_parents = 1,
1684 		.flags = CLK_SET_RATE_PARENT,
1685 	},
1686 };
1687 
1688 static const struct clk_hw *s4_hevcf_mux_parent_hws[] = {
1689 	&s4_hevcf_p0.hw,
1690 	&s4_hevcf_p1.hw
1691 };
1692 
1693 static struct clk_regmap s4_hevcf_mux = {
1694 	.data = &(struct clk_regmap_mux_data){
1695 		.offset = CLKCTRL_VDEC4_CLK_CTRL,
1696 		.mask = 0x1,
1697 		.shift = 15,
1698 	},
1699 	.hw.init = &(struct clk_init_data) {
1700 		.name = "hevcf",
1701 		.ops = &clk_regmap_mux_ops,
1702 		.parent_hws = s4_hevcf_mux_parent_hws,
1703 		.num_parents = ARRAY_SIZE(s4_hevcf_mux_parent_hws),
1704 		.flags = CLK_SET_RATE_PARENT,
1705 	},
1706 };
1707 
1708 /* VPU Clock */
1709 static const struct clk_parent_data s4_vpu_parent_data[] = {
1710 	{ .fw_name = "fclk_div3", },
1711 	{ .fw_name = "fclk_div4", },
1712 	{ .fw_name = "fclk_div5", },
1713 	{ .fw_name = "fclk_div7", },
1714 	{ .fw_name = "mpll1", },
1715 	{ .hw = &s4_vid_pll.hw },
1716 	{ .fw_name = "hifi_pll", },
1717 	{ .fw_name = "gp0_pll", },
1718 };
1719 
1720 static struct clk_regmap s4_vpu_0_sel = {
1721 	.data = &(struct clk_regmap_mux_data){
1722 		.offset = CLKCTRL_VPU_CLK_CTRL,
1723 		.mask = 0x7,
1724 		.shift = 9,
1725 	},
1726 	.hw.init = &(struct clk_init_data){
1727 		.name = "vpu_0_sel",
1728 		.ops = &clk_regmap_mux_ops,
1729 		.parent_data = s4_vpu_parent_data,
1730 		.num_parents = ARRAY_SIZE(s4_vpu_parent_data),
1731 		.flags = 0,
1732 	},
1733 };
1734 
1735 static struct clk_regmap s4_vpu_0_div = {
1736 	.data = &(struct clk_regmap_div_data){
1737 		.offset = CLKCTRL_VPU_CLK_CTRL,
1738 		.shift = 0,
1739 		.width = 7,
1740 	},
1741 	.hw.init = &(struct clk_init_data){
1742 		.name = "vpu_0_div",
1743 		.ops = &clk_regmap_divider_ops,
1744 		.parent_hws = (const struct clk_hw *[]) { &s4_vpu_0_sel.hw },
1745 		.num_parents = 1,
1746 		.flags = CLK_SET_RATE_PARENT,
1747 	},
1748 };
1749 
1750 static struct clk_regmap s4_vpu_0 = {
1751 	.data = &(struct clk_regmap_gate_data){
1752 		.offset = CLKCTRL_VPU_CLK_CTRL,
1753 		.bit_idx = 8,
1754 	},
1755 	.hw.init = &(struct clk_init_data) {
1756 		.name = "vpu_0",
1757 		.ops = &clk_regmap_gate_ops,
1758 		.parent_hws = (const struct clk_hw *[]) { &s4_vpu_0_div.hw },
1759 		.num_parents = 1,
1760 		.flags = CLK_SET_RATE_PARENT,
1761 	},
1762 };
1763 
1764 static struct clk_regmap s4_vpu_1_sel = {
1765 	.data = &(struct clk_regmap_mux_data){
1766 		.offset = CLKCTRL_VPU_CLK_CTRL,
1767 		.mask = 0x7,
1768 		.shift = 25,
1769 	},
1770 	.hw.init = &(struct clk_init_data){
1771 		.name = "vpu_1_sel",
1772 		.ops = &clk_regmap_mux_ops,
1773 		.parent_data = s4_vpu_parent_data,
1774 		.num_parents = ARRAY_SIZE(s4_vpu_parent_data),
1775 		.flags = 0,
1776 	},
1777 };
1778 
1779 static struct clk_regmap s4_vpu_1_div = {
1780 	.data = &(struct clk_regmap_div_data){
1781 		.offset = CLKCTRL_VPU_CLK_CTRL,
1782 		.shift = 16,
1783 		.width = 7,
1784 	},
1785 	.hw.init = &(struct clk_init_data){
1786 		.name = "vpu_1_div",
1787 		.ops = &clk_regmap_divider_ops,
1788 		.parent_hws = (const struct clk_hw *[]) { &s4_vpu_1_sel.hw },
1789 		.num_parents = 1,
1790 		.flags = CLK_SET_RATE_PARENT,
1791 	},
1792 };
1793 
1794 static struct clk_regmap s4_vpu_1 = {
1795 	.data = &(struct clk_regmap_gate_data){
1796 		.offset = CLKCTRL_VPU_CLK_CTRL,
1797 		.bit_idx = 24,
1798 	},
1799 	.hw.init = &(struct clk_init_data) {
1800 		.name = "vpu_1",
1801 		.ops = &clk_regmap_gate_ops,
1802 		.parent_hws = (const struct clk_hw *[]) { &s4_vpu_1_div.hw },
1803 		.num_parents = 1,
1804 		.flags = CLK_SET_RATE_PARENT,
1805 	},
1806 };
1807 
1808 static struct clk_regmap s4_vpu = {
1809 	.data = &(struct clk_regmap_mux_data){
1810 		.offset = CLKCTRL_VPU_CLK_CTRL,
1811 		.mask = 1,
1812 		.shift = 31,
1813 	},
1814 	.hw.init = &(struct clk_init_data){
1815 		.name = "vpu",
1816 		.ops = &clk_regmap_mux_ops,
1817 		.parent_hws = (const struct clk_hw *[]) {
1818 			&s4_vpu_0.hw,
1819 			&s4_vpu_1.hw,
1820 		},
1821 		.num_parents = 2,
1822 		.flags = CLK_SET_RATE_PARENT,
1823 	},
1824 };
1825 
1826 static const struct clk_parent_data vpu_clkb_tmp_parent_data[] = {
1827 	{ .hw = &s4_vpu.hw },
1828 	{ .fw_name = "fclk_div4", },
1829 	{ .fw_name = "fclk_div5", },
1830 	{ .fw_name = "fclk_div7", }
1831 };
1832 
1833 static struct clk_regmap s4_vpu_clkb_tmp_mux = {
1834 	.data = &(struct clk_regmap_mux_data){
1835 		.offset = CLKCTRL_VPU_CLKB_CTRL,
1836 		.mask = 0x3,
1837 		.shift = 20,
1838 	},
1839 	.hw.init = &(struct clk_init_data) {
1840 		.name = "vpu_clkb_tmp_mux",
1841 		.ops = &clk_regmap_mux_ops,
1842 		.parent_data = vpu_clkb_tmp_parent_data,
1843 		.num_parents = ARRAY_SIZE(vpu_clkb_tmp_parent_data),
1844 		.flags = CLK_SET_RATE_PARENT,
1845 	},
1846 };
1847 
1848 static struct clk_regmap s4_vpu_clkb_tmp_div = {
1849 	.data = &(struct clk_regmap_div_data){
1850 		.offset = CLKCTRL_VPU_CLKB_CTRL,
1851 		.shift = 16,
1852 		.width = 4,
1853 	},
1854 	.hw.init = &(struct clk_init_data) {
1855 		.name = "vpu_clkb_tmp_div",
1856 		.ops = &clk_regmap_divider_ops,
1857 		.parent_hws = (const struct clk_hw *[]) {
1858 			&s4_vpu_clkb_tmp_mux.hw
1859 		},
1860 		.num_parents = 1,
1861 		.flags = CLK_SET_RATE_PARENT,
1862 	},
1863 };
1864 
1865 static struct clk_regmap s4_vpu_clkb_tmp = {
1866 	.data = &(struct clk_regmap_gate_data){
1867 		.offset = CLKCTRL_VPU_CLKB_CTRL,
1868 		.bit_idx = 24,
1869 	},
1870 	.hw.init = &(struct clk_init_data){
1871 		.name = "vpu_clkb_tmp",
1872 		.ops = &clk_regmap_gate_ops,
1873 		.parent_hws = (const struct clk_hw *[]) {
1874 			&s4_vpu_clkb_tmp_div.hw
1875 		},
1876 		.num_parents = 1,
1877 		.flags = CLK_SET_RATE_PARENT,
1878 	},
1879 };
1880 
1881 static struct clk_regmap s4_vpu_clkb_div = {
1882 	.data = &(struct clk_regmap_div_data){
1883 		.offset = CLKCTRL_VPU_CLKB_CTRL,
1884 		.shift = 0,
1885 		.width = 8,
1886 	},
1887 	.hw.init = &(struct clk_init_data) {
1888 		.name = "vpu_clkb_div",
1889 		.ops = &clk_regmap_divider_ops,
1890 		.parent_hws = (const struct clk_hw *[]) {
1891 			&s4_vpu_clkb_tmp.hw
1892 		},
1893 		.num_parents = 1,
1894 		.flags = CLK_SET_RATE_PARENT,
1895 	},
1896 };
1897 
1898 static struct clk_regmap s4_vpu_clkb = {
1899 	.data = &(struct clk_regmap_gate_data){
1900 		.offset = CLKCTRL_VPU_CLKB_CTRL,
1901 		.bit_idx = 8,
1902 	},
1903 	.hw.init = &(struct clk_init_data){
1904 		.name = "vpu_clkb",
1905 		.ops = &clk_regmap_gate_ops,
1906 		.parent_hws = (const struct clk_hw *[]) {
1907 			&s4_vpu_clkb_div.hw
1908 		},
1909 		.num_parents = 1,
1910 		.flags = CLK_SET_RATE_PARENT,
1911 	},
1912 };
1913 
1914 static const struct clk_parent_data s4_vpu_clkc_parent_data[] = {
1915 	{ .fw_name = "fclk_div4", },
1916 	{ .fw_name = "fclk_div3", },
1917 	{ .fw_name = "fclk_div5", },
1918 	{ .fw_name = "fclk_div7", },
1919 	{ .fw_name = "mpll1", },
1920 	{ .hw = &s4_vid_pll.hw },
1921 	{ .fw_name = "mpll2", },
1922 	{ .fw_name = "gp0_pll", },
1923 };
1924 
1925 static struct clk_regmap s4_vpu_clkc_p0_mux  = {
1926 	.data = &(struct clk_regmap_mux_data){
1927 		.offset = CLKCTRL_VPU_CLKC_CTRL,
1928 		.mask = 0x7,
1929 		.shift = 9,
1930 	},
1931 	.hw.init = &(struct clk_init_data) {
1932 		.name = "vpu_clkc_p0_mux",
1933 		.ops = &clk_regmap_mux_ops,
1934 		.parent_data = s4_vpu_clkc_parent_data,
1935 		.num_parents = ARRAY_SIZE(s4_vpu_clkc_parent_data),
1936 		.flags = 0,
1937 	},
1938 };
1939 
1940 static struct clk_regmap s4_vpu_clkc_p0_div = {
1941 	.data = &(struct clk_regmap_div_data){
1942 		.offset = CLKCTRL_VPU_CLKC_CTRL,
1943 		.shift = 0,
1944 		.width = 7,
1945 	},
1946 	.hw.init = &(struct clk_init_data) {
1947 		.name = "vpu_clkc_p0_div",
1948 		.ops = &clk_regmap_divider_ops,
1949 		.parent_hws = (const struct clk_hw *[]) {
1950 			&s4_vpu_clkc_p0_mux.hw
1951 		},
1952 		.num_parents = 1,
1953 		.flags = CLK_SET_RATE_PARENT,
1954 	},
1955 };
1956 
1957 static struct clk_regmap s4_vpu_clkc_p0 = {
1958 	.data = &(struct clk_regmap_gate_data){
1959 		.offset = CLKCTRL_VPU_CLKC_CTRL,
1960 		.bit_idx = 8,
1961 	},
1962 	.hw.init = &(struct clk_init_data){
1963 		.name = "vpu_clkc_p0",
1964 		.ops = &clk_regmap_gate_ops,
1965 		.parent_hws = (const struct clk_hw *[]) {
1966 			&s4_vpu_clkc_p0_div.hw
1967 		},
1968 		.num_parents = 1,
1969 		.flags = CLK_SET_RATE_PARENT,
1970 	},
1971 };
1972 
1973 static struct clk_regmap s4_vpu_clkc_p1_mux = {
1974 	.data = &(struct clk_regmap_mux_data){
1975 		.offset = CLKCTRL_VPU_CLKC_CTRL,
1976 		.mask = 0x7,
1977 		.shift = 25,
1978 	},
1979 	.hw.init = &(struct clk_init_data) {
1980 		.name = "vpu_clkc_p1_mux",
1981 		.ops = &clk_regmap_mux_ops,
1982 		.parent_data = s4_vpu_clkc_parent_data,
1983 		.num_parents = ARRAY_SIZE(s4_vpu_clkc_parent_data),
1984 		.flags = 0,
1985 	},
1986 };
1987 
1988 static struct clk_regmap s4_vpu_clkc_p1_div = {
1989 	.data = &(struct clk_regmap_div_data){
1990 		.offset = CLKCTRL_VPU_CLKC_CTRL,
1991 		.shift = 16,
1992 		.width = 7,
1993 	},
1994 	.hw.init = &(struct clk_init_data) {
1995 		.name = "vpu_clkc_p1_div",
1996 		.ops = &clk_regmap_divider_ops,
1997 		.parent_hws = (const struct clk_hw *[]) {
1998 			&s4_vpu_clkc_p1_mux.hw
1999 		},
2000 		.num_parents = 1,
2001 		.flags = CLK_SET_RATE_PARENT,
2002 	},
2003 };
2004 
2005 static struct clk_regmap s4_vpu_clkc_p1 = {
2006 	.data = &(struct clk_regmap_gate_data){
2007 		.offset = CLKCTRL_VPU_CLKC_CTRL,
2008 		.bit_idx = 24,
2009 	},
2010 	.hw.init = &(struct clk_init_data){
2011 		.name = "vpu_clkc_p1",
2012 		.ops = &clk_regmap_gate_ops,
2013 		.parent_hws = (const struct clk_hw *[]) {
2014 			&s4_vpu_clkc_p1_div.hw
2015 		},
2016 		.num_parents = 1,
2017 		.flags = CLK_SET_RATE_PARENT,
2018 	},
2019 };
2020 
2021 static const struct clk_hw *s4_vpu_mux_parent_hws[] = {
2022 	&s4_vpu_clkc_p0.hw,
2023 	&s4_vpu_clkc_p1.hw
2024 };
2025 
2026 static struct clk_regmap s4_vpu_clkc_mux = {
2027 	.data = &(struct clk_regmap_mux_data){
2028 		.offset = CLKCTRL_VPU_CLKC_CTRL,
2029 		.mask = 0x1,
2030 		.shift = 31,
2031 	},
2032 	.hw.init = &(struct clk_init_data) {
2033 		.name = "vpu_clkc_mux",
2034 		.ops = &clk_regmap_mux_ops,
2035 		.parent_hws = s4_vpu_mux_parent_hws,
2036 		.num_parents = ARRAY_SIZE(s4_vpu_mux_parent_hws),
2037 		.flags = CLK_SET_RATE_PARENT,
2038 	},
2039 };
2040 
2041 /* VAPB Clock */
2042 static const struct clk_parent_data s4_vapb_parent_data[] = {
2043 	{ .fw_name = "fclk_div4", },
2044 	{ .fw_name = "fclk_div3", },
2045 	{ .fw_name = "fclk_div5", },
2046 	{ .fw_name = "fclk_div7", },
2047 	{ .fw_name = "mpll1", },
2048 	{ .hw = &s4_vid_pll.hw },
2049 	{ .fw_name = "mpll2", },
2050 	{ .fw_name = "fclk_div2p5", },
2051 };
2052 
2053 static struct clk_regmap s4_vapb_0_sel = {
2054 	.data = &(struct clk_regmap_mux_data){
2055 		.offset = CLKCTRL_VAPBCLK_CTRL,
2056 		.mask = 0x7,
2057 		.shift = 9,
2058 	},
2059 	.hw.init = &(struct clk_init_data){
2060 		.name = "vapb_0_sel",
2061 		.ops = &clk_regmap_mux_ops,
2062 		.parent_data = s4_vapb_parent_data,
2063 		.num_parents = ARRAY_SIZE(s4_vapb_parent_data),
2064 		.flags = 0,
2065 	},
2066 };
2067 
2068 static struct clk_regmap s4_vapb_0_div = {
2069 	.data = &(struct clk_regmap_div_data){
2070 		.offset = CLKCTRL_VAPBCLK_CTRL,
2071 		.shift = 0,
2072 		.width = 7,
2073 	},
2074 	.hw.init = &(struct clk_init_data){
2075 		.name = "vapb_0_div",
2076 		.ops = &clk_regmap_divider_ops,
2077 		.parent_hws = (const struct clk_hw *[]) {
2078 			&s4_vapb_0_sel.hw
2079 		},
2080 		.num_parents = 1,
2081 		.flags = CLK_SET_RATE_PARENT,
2082 	},
2083 };
2084 
2085 static struct clk_regmap s4_vapb_0 = {
2086 	.data = &(struct clk_regmap_gate_data){
2087 		.offset = CLKCTRL_VAPBCLK_CTRL,
2088 		.bit_idx = 8,
2089 	},
2090 	.hw.init = &(struct clk_init_data) {
2091 		.name = "vapb_0",
2092 		.ops = &clk_regmap_gate_ops,
2093 		.parent_hws = (const struct clk_hw *[]) {
2094 			&s4_vapb_0_div.hw
2095 		},
2096 		.num_parents = 1,
2097 		.flags = CLK_SET_RATE_PARENT,
2098 	},
2099 };
2100 
2101 static struct clk_regmap s4_vapb_1_sel = {
2102 	.data = &(struct clk_regmap_mux_data){
2103 		.offset = CLKCTRL_VAPBCLK_CTRL,
2104 		.mask = 0x7,
2105 		.shift = 25,
2106 	},
2107 	.hw.init = &(struct clk_init_data){
2108 		.name = "vapb_1_sel",
2109 		.ops = &clk_regmap_mux_ops,
2110 		.parent_data = s4_vapb_parent_data,
2111 		.num_parents = ARRAY_SIZE(s4_vapb_parent_data),
2112 		.flags = 0,
2113 	},
2114 };
2115 
2116 static struct clk_regmap s4_vapb_1_div = {
2117 	.data = &(struct clk_regmap_div_data){
2118 		.offset = CLKCTRL_VAPBCLK_CTRL,
2119 		.shift = 16,
2120 		.width = 7,
2121 	},
2122 	.hw.init = &(struct clk_init_data){
2123 		.name = "vapb_1_div",
2124 		.ops = &clk_regmap_divider_ops,
2125 		.parent_hws = (const struct clk_hw *[]) {
2126 			&s4_vapb_1_sel.hw
2127 		},
2128 		.num_parents = 1,
2129 		.flags = CLK_SET_RATE_PARENT,
2130 	},
2131 };
2132 
2133 static struct clk_regmap s4_vapb_1 = {
2134 	.data = &(struct clk_regmap_gate_data){
2135 		.offset = CLKCTRL_VAPBCLK_CTRL,
2136 		.bit_idx = 24,
2137 	},
2138 	.hw.init = &(struct clk_init_data) {
2139 		.name = "vapb_1",
2140 		.ops = &clk_regmap_gate_ops,
2141 		.parent_hws = (const struct clk_hw *[]) {
2142 			&s4_vapb_1_div.hw
2143 		},
2144 		.num_parents = 1,
2145 		.flags = CLK_SET_RATE_PARENT,
2146 	},
2147 };
2148 
2149 static struct clk_regmap s4_vapb = {
2150 	.data = &(struct clk_regmap_mux_data){
2151 		.offset = CLKCTRL_VAPBCLK_CTRL,
2152 		.mask = 1,
2153 		.shift = 31,
2154 	},
2155 	.hw.init = &(struct clk_init_data){
2156 		.name = "vapb_sel",
2157 		.ops = &clk_regmap_mux_ops,
2158 		.parent_hws = (const struct clk_hw *[]) {
2159 			&s4_vapb_0.hw,
2160 			&s4_vapb_1.hw
2161 		},
2162 		.num_parents = 2,
2163 		.flags = CLK_SET_RATE_PARENT,
2164 	},
2165 };
2166 
2167 static struct clk_regmap s4_ge2d_gate = {
2168 	.data = &(struct clk_regmap_gate_data){
2169 		.offset = CLKCTRL_VAPBCLK_CTRL,
2170 		.bit_idx = 30,
2171 	},
2172 	.hw.init = &(struct clk_init_data) {
2173 		.name = "ge2d_clk",
2174 		.ops = &clk_regmap_gate_ops,
2175 		.parent_hws = (const struct clk_hw *[]) { &s4_vapb.hw },
2176 		.num_parents = 1,
2177 		.flags = CLK_SET_RATE_PARENT,
2178 	},
2179 };
2180 
2181 static const struct clk_parent_data s4_esmclk_parent_data[] = {
2182 	{ .fw_name = "fclk_div7", },
2183 	{ .fw_name = "fclk_div4", },
2184 	{ .fw_name = "fclk_div3", },
2185 	{ .fw_name = "fclk_div5", },
2186 };
2187 
2188 static struct clk_regmap s4_hdcp22_esmclk_mux = {
2189 	.data = &(struct clk_regmap_mux_data){
2190 		.offset = CLKCTRL_HDCP22_CTRL,
2191 		.mask = 0x3,
2192 		.shift = 9,
2193 	},
2194 	.hw.init = &(struct clk_init_data) {
2195 		.name = "hdcp22_esmclk_mux",
2196 		.ops = &clk_regmap_mux_ops,
2197 		.parent_data = s4_esmclk_parent_data,
2198 		.num_parents = ARRAY_SIZE(s4_esmclk_parent_data),
2199 		.flags = CLK_SET_RATE_PARENT,
2200 	},
2201 };
2202 
2203 static struct clk_regmap s4_hdcp22_esmclk_div = {
2204 	.data = &(struct clk_regmap_div_data){
2205 		.offset = CLKCTRL_HDCP22_CTRL,
2206 		.shift = 0,
2207 		.width = 7,
2208 	},
2209 	.hw.init = &(struct clk_init_data) {
2210 		.name = "hdcp22_esmclk_div",
2211 		.ops = &clk_regmap_divider_ops,
2212 		.parent_hws = (const struct clk_hw *[]) {
2213 			&s4_hdcp22_esmclk_mux.hw
2214 		},
2215 		.num_parents = 1,
2216 		.flags = CLK_SET_RATE_PARENT,
2217 	},
2218 };
2219 
2220 static struct clk_regmap s4_hdcp22_esmclk_gate = {
2221 	.data = &(struct clk_regmap_gate_data){
2222 		.offset = CLKCTRL_HDCP22_CTRL,
2223 		.bit_idx = 8,
2224 	},
2225 	.hw.init = &(struct clk_init_data){
2226 		.name = "hdcp22_esmclk_gate",
2227 		.ops = &clk_regmap_gate_ops,
2228 		.parent_hws = (const struct clk_hw *[]) {
2229 			&s4_hdcp22_esmclk_div.hw
2230 		},
2231 		.num_parents = 1,
2232 		.flags = CLK_SET_RATE_PARENT,
2233 	},
2234 };
2235 
2236 static const struct clk_parent_data s4_skpclk_parent_data[] = {
2237 	{ .fw_name = "xtal", },
2238 	{ .fw_name = "fclk_div4", },
2239 	{ .fw_name = "fclk_div3", },
2240 	{ .fw_name = "fclk_div5", },
2241 };
2242 
2243 static struct clk_regmap s4_hdcp22_skpclk_mux = {
2244 	.data = &(struct clk_regmap_mux_data){
2245 		.offset = CLKCTRL_HDCP22_CTRL,
2246 		.mask = 0x3,
2247 		.shift = 25,
2248 	},
2249 	.hw.init = &(struct clk_init_data) {
2250 		.name = "hdcp22_skpclk_mux",
2251 		.ops = &clk_regmap_mux_ops,
2252 		.parent_data = s4_skpclk_parent_data,
2253 		.num_parents = ARRAY_SIZE(s4_skpclk_parent_data),
2254 		.flags = CLK_SET_RATE_PARENT,
2255 	},
2256 };
2257 
2258 static struct clk_regmap s4_hdcp22_skpclk_div = {
2259 	.data = &(struct clk_regmap_div_data){
2260 		.offset = CLKCTRL_HDCP22_CTRL,
2261 		.shift = 16,
2262 		.width = 7,
2263 	},
2264 	.hw.init = &(struct clk_init_data) {
2265 		.name = "hdcp22_skpclk_div",
2266 		.ops = &clk_regmap_divider_ops,
2267 		.parent_hws = (const struct clk_hw *[]) {
2268 			&s4_hdcp22_skpclk_mux.hw
2269 		},
2270 		.num_parents = 1,
2271 		.flags = CLK_SET_RATE_PARENT,
2272 	},
2273 };
2274 
2275 static struct clk_regmap s4_hdcp22_skpclk_gate = {
2276 	.data = &(struct clk_regmap_gate_data){
2277 		.offset = CLKCTRL_HDCP22_CTRL,
2278 		.bit_idx = 24,
2279 	},
2280 	.hw.init = &(struct clk_init_data){
2281 		.name = "hdcp22_skpclk_gate",
2282 		.ops = &clk_regmap_gate_ops,
2283 		.parent_hws = (const struct clk_hw *[]) {
2284 			&s4_hdcp22_skpclk_div.hw
2285 		},
2286 		.num_parents = 1,
2287 		.flags = CLK_SET_RATE_PARENT,
2288 	},
2289 };
2290 
2291 static const struct clk_parent_data s4_vdin_parent_data[]  = {
2292 	{ .fw_name = "xtal", },
2293 	{ .fw_name = "fclk_div4", },
2294 	{ .fw_name = "fclk_div3", },
2295 	{ .fw_name = "fclk_div5", },
2296 	{ .hw = &s4_vid_pll.hw }
2297 };
2298 
2299 static struct clk_regmap s4_vdin_meas_mux = {
2300 	.data = &(struct clk_regmap_mux_data){
2301 		.offset = CLKCTRL_VDIN_MEAS_CLK_CTRL,
2302 		.mask = 0x7,
2303 		.shift = 9,
2304 	},
2305 	.hw.init = &(struct clk_init_data) {
2306 		.name = "vdin_meas_mux",
2307 		.ops = &clk_regmap_mux_ops,
2308 		.parent_data = s4_vdin_parent_data,
2309 		.num_parents = ARRAY_SIZE(s4_vdin_parent_data),
2310 		.flags = CLK_SET_RATE_PARENT,
2311 	},
2312 };
2313 
2314 static struct clk_regmap s4_vdin_meas_div = {
2315 	.data = &(struct clk_regmap_div_data){
2316 		.offset = CLKCTRL_VDIN_MEAS_CLK_CTRL,
2317 		.shift = 0,
2318 		.width = 7,
2319 	},
2320 	.hw.init = &(struct clk_init_data) {
2321 		.name = "vdin_meas_div",
2322 		.ops = &clk_regmap_divider_ops,
2323 		.parent_hws = (const struct clk_hw *[]) {
2324 			&s4_vdin_meas_mux.hw
2325 		},
2326 		.num_parents = 1,
2327 		.flags = CLK_SET_RATE_PARENT,
2328 	},
2329 };
2330 
2331 static struct clk_regmap s4_vdin_meas_gate = {
2332 	.data = &(struct clk_regmap_gate_data){
2333 		.offset = CLKCTRL_VDIN_MEAS_CLK_CTRL,
2334 		.bit_idx = 8,
2335 	},
2336 	.hw.init = &(struct clk_init_data){
2337 		.name = "vdin_meas_gate",
2338 		.ops = &clk_regmap_gate_ops,
2339 		.parent_hws = (const struct clk_hw *[]) {
2340 			&s4_vdin_meas_div.hw
2341 		},
2342 		.num_parents = 1,
2343 		.flags = CLK_SET_RATE_PARENT,
2344 	},
2345 };
2346 
2347 /* EMMC/NAND clock */
2348 static const struct clk_parent_data s4_sd_emmc_clk0_parent_data[] = {
2349 	{ .fw_name = "xtal", },
2350 	{ .fw_name = "fclk_div2", },
2351 	{ .fw_name = "fclk_div3", },
2352 	{ .fw_name = "hifi_pll", },
2353 	{ .fw_name = "fclk_div2p5", },
2354 	{ .fw_name = "mpll2", },
2355 	{ .fw_name = "mpll3", },
2356 	{ .fw_name = "gp0_pll", },
2357 };
2358 
2359 static struct clk_regmap s4_sd_emmc_c_clk0_sel = {
2360 	.data = &(struct clk_regmap_mux_data){
2361 		.offset = CLKCTRL_NAND_CLK_CTRL,
2362 		.mask = 0x7,
2363 		.shift = 9,
2364 	},
2365 	.hw.init = &(struct clk_init_data) {
2366 		.name = "sd_emmc_c_clk0_sel",
2367 		.ops = &clk_regmap_mux_ops,
2368 		.parent_data = s4_sd_emmc_clk0_parent_data,
2369 		.num_parents = ARRAY_SIZE(s4_sd_emmc_clk0_parent_data),
2370 		.flags = 0,
2371 	},
2372 };
2373 
2374 static struct clk_regmap s4_sd_emmc_c_clk0_div = {
2375 	.data = &(struct clk_regmap_div_data){
2376 		.offset = CLKCTRL_NAND_CLK_CTRL,
2377 		.shift = 0,
2378 		.width = 7,
2379 	},
2380 	.hw.init = &(struct clk_init_data) {
2381 		.name = "sd_emmc_c_clk0_div",
2382 		.ops = &clk_regmap_divider_ops,
2383 		.parent_hws = (const struct clk_hw *[]) {
2384 			&s4_sd_emmc_c_clk0_sel.hw
2385 		},
2386 		.num_parents = 1,
2387 		.flags = CLK_SET_RATE_PARENT,
2388 	},
2389 };
2390 
2391 static struct clk_regmap s4_sd_emmc_c_clk0 = {
2392 	.data = &(struct clk_regmap_gate_data){
2393 		.offset = CLKCTRL_NAND_CLK_CTRL,
2394 		.bit_idx = 7,
2395 	},
2396 	.hw.init = &(struct clk_init_data){
2397 		.name = "sd_emmc_c_clk0",
2398 		.ops = &clk_regmap_gate_ops,
2399 		.parent_hws = (const struct clk_hw *[]) {
2400 			&s4_sd_emmc_c_clk0_div.hw
2401 		},
2402 		.num_parents = 1,
2403 		.flags = CLK_SET_RATE_PARENT,
2404 	},
2405 };
2406 
2407 static struct clk_regmap s4_sd_emmc_a_clk0_sel = {
2408 	.data = &(struct clk_regmap_mux_data){
2409 		.offset = CLKCTRL_SD_EMMC_CLK_CTRL,
2410 		.mask = 0x7,
2411 		.shift = 9,
2412 	},
2413 	.hw.init = &(struct clk_init_data) {
2414 		.name = "sd_emmc_a_clk0_sel",
2415 		.ops = &clk_regmap_mux_ops,
2416 		.parent_data = s4_sd_emmc_clk0_parent_data,
2417 		.num_parents = ARRAY_SIZE(s4_sd_emmc_clk0_parent_data),
2418 		.flags = 0,
2419 	},
2420 };
2421 
2422 static struct clk_regmap s4_sd_emmc_a_clk0_div = {
2423 	.data = &(struct clk_regmap_div_data){
2424 		.offset = CLKCTRL_SD_EMMC_CLK_CTRL,
2425 		.shift = 0,
2426 		.width = 7,
2427 	},
2428 	.hw.init = &(struct clk_init_data) {
2429 		.name = "sd_emmc_a_clk0_div",
2430 		.ops = &clk_regmap_divider_ops,
2431 		.parent_hws = (const struct clk_hw *[]) {
2432 			&s4_sd_emmc_a_clk0_sel.hw
2433 		},
2434 		.num_parents = 1,
2435 		.flags = CLK_SET_RATE_PARENT,
2436 	},
2437 };
2438 
2439 static struct clk_regmap s4_sd_emmc_a_clk0 = {
2440 	.data = &(struct clk_regmap_gate_data){
2441 		.offset = CLKCTRL_SD_EMMC_CLK_CTRL,
2442 		.bit_idx = 7,
2443 	},
2444 	.hw.init = &(struct clk_init_data){
2445 		.name = "sd_emmc_a_clk0",
2446 		.ops = &clk_regmap_gate_ops,
2447 		.parent_hws = (const struct clk_hw *[]) {
2448 			&s4_sd_emmc_a_clk0_div.hw
2449 		},
2450 		.num_parents = 1,
2451 		.flags = CLK_SET_RATE_PARENT,
2452 	},
2453 };
2454 
2455 static struct clk_regmap s4_sd_emmc_b_clk0_sel = {
2456 	.data = &(struct clk_regmap_mux_data){
2457 		.offset = CLKCTRL_SD_EMMC_CLK_CTRL,
2458 		.mask = 0x7,
2459 		.shift = 25,
2460 	},
2461 	.hw.init = &(struct clk_init_data) {
2462 		.name = "sd_emmc_b_clk0_sel",
2463 		.ops = &clk_regmap_mux_ops,
2464 		.parent_data = s4_sd_emmc_clk0_parent_data,
2465 		.num_parents = ARRAY_SIZE(s4_sd_emmc_clk0_parent_data),
2466 		.flags = 0,
2467 	},
2468 };
2469 
2470 static struct clk_regmap s4_sd_emmc_b_clk0_div = {
2471 	.data = &(struct clk_regmap_div_data){
2472 		.offset = CLKCTRL_SD_EMMC_CLK_CTRL,
2473 		.shift = 16,
2474 		.width = 7,
2475 	},
2476 	.hw.init = &(struct clk_init_data) {
2477 		.name = "sd_emmc_b_clk0_div",
2478 		.ops = &clk_regmap_divider_ops,
2479 		.parent_hws = (const struct clk_hw *[]) {
2480 			&s4_sd_emmc_b_clk0_sel.hw
2481 		},
2482 		.num_parents = 1,
2483 		.flags = CLK_SET_RATE_PARENT,
2484 	},
2485 };
2486 
2487 static struct clk_regmap s4_sd_emmc_b_clk0 = {
2488 	.data = &(struct clk_regmap_gate_data){
2489 		.offset = CLKCTRL_SD_EMMC_CLK_CTRL,
2490 		.bit_idx = 23,
2491 	},
2492 	.hw.init = &(struct clk_init_data){
2493 		.name = "sd_emmc_b_clk0",
2494 		.ops = &clk_regmap_gate_ops,
2495 		.parent_hws = (const struct clk_hw *[]) {
2496 			&s4_sd_emmc_b_clk0_div.hw
2497 		},
2498 		.num_parents = 1,
2499 		.flags = CLK_SET_RATE_PARENT,
2500 	},
2501 };
2502 
2503 /* SPICC Clock */
2504 static const struct clk_parent_data s4_spicc_parent_data[] = {
2505 	{ .fw_name = "xtal", },
2506 	{ .hw = &s4_sys_clk.hw },
2507 	{ .fw_name = "fclk_div4", },
2508 	{ .fw_name = "fclk_div3", },
2509 	{ .fw_name = "fclk_div2", },
2510 	{ .fw_name = "fclk_div5", },
2511 	{ .fw_name = "fclk_div7", },
2512 };
2513 
2514 static struct clk_regmap s4_spicc0_mux = {
2515 	.data = &(struct clk_regmap_mux_data){
2516 		.offset = CLKCTRL_SPICC_CLK_CTRL,
2517 		.mask = 0x7,
2518 		.shift = 7,
2519 	},
2520 	.hw.init = &(struct clk_init_data) {
2521 		.name = "spicc0_mux",
2522 		.ops = &clk_regmap_mux_ops,
2523 		.parent_data = s4_spicc_parent_data,
2524 		.num_parents = ARRAY_SIZE(s4_spicc_parent_data),
2525 		.flags = CLK_SET_RATE_PARENT,
2526 	},
2527 };
2528 
2529 static struct clk_regmap s4_spicc0_div = {
2530 	.data = &(struct clk_regmap_div_data){
2531 		.offset = CLKCTRL_SPICC_CLK_CTRL,
2532 		.shift = 0,
2533 		.width = 6,
2534 	},
2535 	.hw.init = &(struct clk_init_data) {
2536 		.name = "spicc0_div",
2537 		.ops = &clk_regmap_divider_ops,
2538 		.parent_hws = (const struct clk_hw *[]) {
2539 			&s4_spicc0_mux.hw
2540 		},
2541 		.num_parents = 1,
2542 		.flags = CLK_SET_RATE_PARENT,
2543 	},
2544 };
2545 
2546 static struct clk_regmap s4_spicc0_gate = {
2547 	.data = &(struct clk_regmap_gate_data){
2548 		.offset = CLKCTRL_SPICC_CLK_CTRL,
2549 		.bit_idx = 6,
2550 	},
2551 	.hw.init = &(struct clk_init_data){
2552 		.name = "spicc0",
2553 		.ops = &clk_regmap_gate_ops,
2554 		.parent_hws = (const struct clk_hw *[]) {
2555 			&s4_spicc0_div.hw
2556 		},
2557 		.num_parents = 1,
2558 		.flags = CLK_SET_RATE_PARENT,
2559 	},
2560 };
2561 
2562 /* PWM Clock */
2563 static const struct clk_parent_data s4_pwm_parent_data[] = {
2564 	{ .fw_name = "xtal", },
2565 	{ .hw = &s4_vid_pll.hw },
2566 	{ .fw_name = "fclk_div4", },
2567 	{ .fw_name = "fclk_div3", },
2568 };
2569 
2570 static struct clk_regmap s4_pwm_a_mux = {
2571 	.data = &(struct clk_regmap_mux_data) {
2572 		.offset = CLKCTRL_PWM_CLK_AB_CTRL,
2573 		.mask = 0x3,
2574 		.shift = 9,
2575 	},
2576 	.hw.init = &(struct clk_init_data){
2577 		.name = "pwm_a_mux",
2578 		.ops = &clk_regmap_mux_ops,
2579 		.parent_data = s4_pwm_parent_data,
2580 		.num_parents = ARRAY_SIZE(s4_pwm_parent_data),
2581 		.flags = 0,
2582 	},
2583 };
2584 
2585 static struct clk_regmap s4_pwm_a_div = {
2586 	.data = &(struct clk_regmap_div_data) {
2587 		.offset = CLKCTRL_PWM_CLK_AB_CTRL,
2588 		.shift = 0,
2589 		.width = 8,
2590 	},
2591 	.hw.init = &(struct clk_init_data){
2592 		.name = "pwm_a_div",
2593 		.ops = &clk_regmap_divider_ops,
2594 		.parent_hws = (const struct clk_hw *[]) {
2595 			&s4_pwm_a_mux.hw
2596 		},
2597 		.num_parents = 1,
2598 		.flags = CLK_SET_RATE_PARENT,
2599 	},
2600 };
2601 
2602 static struct clk_regmap s4_pwm_a_gate = {
2603 	.data = &(struct clk_regmap_gate_data) {
2604 		.offset = CLKCTRL_PWM_CLK_AB_CTRL,
2605 		.bit_idx = 8,
2606 	},
2607 	.hw.init = &(struct clk_init_data){
2608 		.name = "pwm_a_gate",
2609 		.ops = &clk_regmap_gate_ops,
2610 		.parent_hws = (const struct clk_hw *[]) {
2611 			&s4_pwm_a_div.hw
2612 		},
2613 		.num_parents = 1,
2614 		.flags = CLK_SET_RATE_PARENT,
2615 	},
2616 };
2617 
2618 static struct clk_regmap s4_pwm_b_mux = {
2619 	.data = &(struct clk_regmap_mux_data) {
2620 		.offset = CLKCTRL_PWM_CLK_AB_CTRL,
2621 		.mask = 0x3,
2622 		.shift = 25,
2623 	},
2624 	.hw.init = &(struct clk_init_data){
2625 		.name = "pwm_b_mux",
2626 		.ops = &clk_regmap_mux_ops,
2627 		.parent_data = s4_pwm_parent_data,
2628 		.num_parents = ARRAY_SIZE(s4_pwm_parent_data),
2629 		.flags = 0,
2630 	},
2631 };
2632 
2633 static struct clk_regmap s4_pwm_b_div = {
2634 	.data = &(struct clk_regmap_div_data) {
2635 		.offset = CLKCTRL_PWM_CLK_AB_CTRL,
2636 		.shift = 16,
2637 		.width = 8,
2638 	},
2639 	.hw.init = &(struct clk_init_data){
2640 		.name = "pwm_b_div",
2641 		.ops = &clk_regmap_divider_ops,
2642 		.parent_hws = (const struct clk_hw *[]) {
2643 			&s4_pwm_b_mux.hw
2644 		},
2645 		.num_parents = 1,
2646 		.flags = CLK_SET_RATE_PARENT,
2647 	},
2648 };
2649 
2650 static struct clk_regmap s4_pwm_b_gate = {
2651 	.data = &(struct clk_regmap_gate_data) {
2652 		.offset = CLKCTRL_PWM_CLK_AB_CTRL,
2653 		.bit_idx = 24,
2654 	},
2655 	.hw.init = &(struct clk_init_data){
2656 		.name = "pwm_b_gate",
2657 		.ops = &clk_regmap_gate_ops,
2658 		.parent_hws = (const struct clk_hw *[]) {
2659 			&s4_pwm_b_div.hw
2660 		},
2661 		.num_parents = 1,
2662 		.flags = CLK_SET_RATE_PARENT,
2663 	},
2664 };
2665 
2666 static struct clk_regmap s4_pwm_c_mux = {
2667 	.data = &(struct clk_regmap_mux_data) {
2668 		.offset = CLKCTRL_PWM_CLK_CD_CTRL,
2669 		.mask = 0x3,
2670 		.shift = 9,
2671 	},
2672 	.hw.init = &(struct clk_init_data){
2673 		.name = "pwm_c_mux",
2674 		.ops = &clk_regmap_mux_ops,
2675 		.parent_data = s4_pwm_parent_data,
2676 		.num_parents = ARRAY_SIZE(s4_pwm_parent_data),
2677 		.flags = 0,
2678 	},
2679 };
2680 
2681 static struct clk_regmap s4_pwm_c_div = {
2682 	.data = &(struct clk_regmap_div_data) {
2683 		.offset = CLKCTRL_PWM_CLK_CD_CTRL,
2684 		.shift = 0,
2685 		.width = 8,
2686 	},
2687 	.hw.init = &(struct clk_init_data){
2688 		.name = "pwm_c_div",
2689 		.ops = &clk_regmap_divider_ops,
2690 		.parent_hws = (const struct clk_hw *[]) {
2691 			&s4_pwm_c_mux.hw
2692 		},
2693 		.num_parents = 1,
2694 	},
2695 };
2696 
2697 static struct clk_regmap s4_pwm_c_gate = {
2698 	.data = &(struct clk_regmap_gate_data) {
2699 		.offset = CLKCTRL_PWM_CLK_CD_CTRL,
2700 		.bit_idx = 8,
2701 	},
2702 	.hw.init = &(struct clk_init_data){
2703 		.name = "pwm_c_gate",
2704 		.ops = &clk_regmap_gate_ops,
2705 		.parent_hws = (const struct clk_hw *[]) {
2706 			&s4_pwm_c_div.hw
2707 		},
2708 		.num_parents = 1,
2709 		.flags = CLK_SET_RATE_PARENT,
2710 	},
2711 };
2712 
2713 static struct clk_regmap s4_pwm_d_mux = {
2714 	.data = &(struct clk_regmap_mux_data) {
2715 		.offset = CLKCTRL_PWM_CLK_CD_CTRL,
2716 		.mask = 0x3,
2717 		.shift = 25,
2718 	},
2719 	.hw.init = &(struct clk_init_data){
2720 		.name = "pwm_d_mux",
2721 		.ops = &clk_regmap_mux_ops,
2722 		.parent_data = s4_pwm_parent_data,
2723 		.num_parents = ARRAY_SIZE(s4_pwm_parent_data),
2724 		.flags = 0,
2725 	},
2726 };
2727 
2728 static struct clk_regmap s4_pwm_d_div = {
2729 	.data = &(struct clk_regmap_div_data) {
2730 		.offset = CLKCTRL_PWM_CLK_CD_CTRL,
2731 		.shift = 16,
2732 		.width = 8,
2733 	},
2734 	.hw.init = &(struct clk_init_data){
2735 		.name = "pwm_d_div",
2736 		.ops = &clk_regmap_divider_ops,
2737 		.parent_hws = (const struct clk_hw *[]) {
2738 			&s4_pwm_d_mux.hw
2739 		},
2740 		.num_parents = 1,
2741 		.flags = CLK_SET_RATE_PARENT,
2742 	},
2743 };
2744 
2745 static struct clk_regmap s4_pwm_d_gate = {
2746 	.data = &(struct clk_regmap_gate_data) {
2747 		.offset = CLKCTRL_PWM_CLK_CD_CTRL,
2748 		.bit_idx = 24,
2749 	},
2750 	.hw.init = &(struct clk_init_data){
2751 		.name = "pwm_d_gate",
2752 		.ops = &clk_regmap_gate_ops,
2753 		.parent_hws = (const struct clk_hw *[]) {
2754 			&s4_pwm_d_div.hw
2755 		},
2756 		.num_parents = 1,
2757 		.flags = CLK_SET_RATE_PARENT,
2758 	},
2759 };
2760 
2761 static struct clk_regmap s4_pwm_e_mux = {
2762 	.data = &(struct clk_regmap_mux_data) {
2763 		.offset = CLKCTRL_PWM_CLK_EF_CTRL,
2764 		.mask = 0x3,
2765 		.shift = 9,
2766 	},
2767 	.hw.init = &(struct clk_init_data){
2768 		.name = "pwm_e_mux",
2769 		.ops = &clk_regmap_mux_ops,
2770 		.parent_data = s4_pwm_parent_data,
2771 		.num_parents = ARRAY_SIZE(s4_pwm_parent_data),
2772 		.flags = 0,
2773 	},
2774 };
2775 
2776 static struct clk_regmap s4_pwm_e_div = {
2777 	.data = &(struct clk_regmap_div_data) {
2778 		.offset = CLKCTRL_PWM_CLK_EF_CTRL,
2779 		.shift = 0,
2780 		.width = 8,
2781 	},
2782 	.hw.init = &(struct clk_init_data){
2783 		.name = "pwm_e_div",
2784 		.ops = &clk_regmap_divider_ops,
2785 		.parent_hws = (const struct clk_hw *[]) {
2786 			&s4_pwm_e_mux.hw
2787 		},
2788 		.num_parents = 1,
2789 		.flags = CLK_SET_RATE_PARENT,
2790 	},
2791 };
2792 
2793 static struct clk_regmap s4_pwm_e_gate = {
2794 	.data = &(struct clk_regmap_gate_data) {
2795 		.offset = CLKCTRL_PWM_CLK_EF_CTRL,
2796 		.bit_idx = 8,
2797 	},
2798 	.hw.init = &(struct clk_init_data){
2799 		.name = "pwm_e_gate",
2800 		.ops = &clk_regmap_gate_ops,
2801 		.parent_hws = (const struct clk_hw *[]) {
2802 			&s4_pwm_e_div.hw
2803 		},
2804 		.num_parents = 1,
2805 		.flags = CLK_SET_RATE_PARENT,
2806 	},
2807 };
2808 
2809 static struct clk_regmap s4_pwm_f_mux = {
2810 	.data = &(struct clk_regmap_mux_data) {
2811 		.offset = CLKCTRL_PWM_CLK_EF_CTRL,
2812 		.mask = 0x3,
2813 		.shift = 25,
2814 	},
2815 	.hw.init = &(struct clk_init_data){
2816 		.name = "pwm_f_mux",
2817 		.ops = &clk_regmap_mux_ops,
2818 		.parent_data = s4_pwm_parent_data,
2819 		.num_parents = ARRAY_SIZE(s4_pwm_parent_data),
2820 		.flags = 0,
2821 	},
2822 };
2823 
2824 static struct clk_regmap s4_pwm_f_div = {
2825 	.data = &(struct clk_regmap_div_data) {
2826 		.offset = CLKCTRL_PWM_CLK_EF_CTRL,
2827 		.shift = 16,
2828 		.width = 8,
2829 	},
2830 	.hw.init = &(struct clk_init_data){
2831 		.name = "pwm_f_div",
2832 		.ops = &clk_regmap_divider_ops,
2833 		.parent_hws = (const struct clk_hw *[]) {
2834 			&s4_pwm_f_mux.hw
2835 		},
2836 		.num_parents = 1,
2837 		.flags = CLK_SET_RATE_PARENT,
2838 	},
2839 };
2840 
2841 static struct clk_regmap s4_pwm_f_gate = {
2842 	.data = &(struct clk_regmap_gate_data) {
2843 		.offset = CLKCTRL_PWM_CLK_EF_CTRL,
2844 		.bit_idx = 24,
2845 	},
2846 	.hw.init = &(struct clk_init_data){
2847 		.name = "pwm_f_gate",
2848 		.ops = &clk_regmap_gate_ops,
2849 		.parent_hws = (const struct clk_hw *[]) {
2850 			&s4_pwm_f_div.hw
2851 		},
2852 		.num_parents = 1,
2853 		.flags = CLK_SET_RATE_PARENT,
2854 	},
2855 };
2856 
2857 static struct clk_regmap s4_pwm_g_mux = {
2858 	.data = &(struct clk_regmap_mux_data) {
2859 		.offset = CLKCTRL_PWM_CLK_GH_CTRL,
2860 		.mask = 0x3,
2861 		.shift = 9,
2862 	},
2863 	.hw.init = &(struct clk_init_data){
2864 		.name = "pwm_g_mux",
2865 		.ops = &clk_regmap_mux_ops,
2866 		.parent_data = s4_pwm_parent_data,
2867 		.num_parents = ARRAY_SIZE(s4_pwm_parent_data),
2868 		.flags = 0,
2869 	},
2870 };
2871 
2872 static struct clk_regmap s4_pwm_g_div = {
2873 	.data = &(struct clk_regmap_div_data) {
2874 		.offset = CLKCTRL_PWM_CLK_GH_CTRL,
2875 		.shift = 0,
2876 		.width = 8,
2877 	},
2878 	.hw.init = &(struct clk_init_data){
2879 		.name = "pwm_g_div",
2880 		.ops = &clk_regmap_divider_ops,
2881 		.parent_hws = (const struct clk_hw *[]) {
2882 			&s4_pwm_g_mux.hw
2883 		},
2884 		.num_parents = 1,
2885 		.flags = CLK_SET_RATE_PARENT,
2886 	},
2887 };
2888 
2889 static struct clk_regmap s4_pwm_g_gate = {
2890 	.data = &(struct clk_regmap_gate_data) {
2891 		.offset = CLKCTRL_PWM_CLK_GH_CTRL,
2892 		.bit_idx = 8,
2893 	},
2894 	.hw.init = &(struct clk_init_data){
2895 		.name = "pwm_g_gate",
2896 		.ops = &clk_regmap_gate_ops,
2897 		.parent_hws = (const struct clk_hw *[]) {
2898 			&s4_pwm_g_div.hw
2899 		},
2900 		.num_parents = 1,
2901 		.flags = CLK_SET_RATE_PARENT,
2902 	},
2903 };
2904 
2905 static struct clk_regmap s4_pwm_h_mux = {
2906 	.data = &(struct clk_regmap_mux_data) {
2907 		.offset = CLKCTRL_PWM_CLK_GH_CTRL,
2908 		.mask = 0x3,
2909 		.shift = 25,
2910 	},
2911 	.hw.init = &(struct clk_init_data){
2912 		.name = "pwm_h_mux",
2913 		.ops = &clk_regmap_mux_ops,
2914 		.parent_data = s4_pwm_parent_data,
2915 		.num_parents = ARRAY_SIZE(s4_pwm_parent_data),
2916 		.flags = 0,
2917 	},
2918 };
2919 
2920 static struct clk_regmap s4_pwm_h_div = {
2921 	.data = &(struct clk_regmap_div_data) {
2922 		.offset = CLKCTRL_PWM_CLK_GH_CTRL,
2923 		.shift = 16,
2924 		.width = 8,
2925 	},
2926 	.hw.init = &(struct clk_init_data){
2927 		.name = "pwm_h_div",
2928 		.ops = &clk_regmap_divider_ops,
2929 		.parent_hws = (const struct clk_hw *[]) {
2930 			&s4_pwm_h_mux.hw
2931 		},
2932 		.num_parents = 1,
2933 		.flags = CLK_SET_RATE_PARENT,
2934 	},
2935 };
2936 
2937 static struct clk_regmap s4_pwm_h_gate = {
2938 	.data = &(struct clk_regmap_gate_data) {
2939 		.offset = CLKCTRL_PWM_CLK_GH_CTRL,
2940 		.bit_idx = 24,
2941 	},
2942 	.hw.init = &(struct clk_init_data){
2943 		.name = "pwm_h_gate",
2944 		.ops = &clk_regmap_gate_ops,
2945 		.parent_hws = (const struct clk_hw *[]) {
2946 			&s4_pwm_h_div.hw
2947 		},
2948 		.num_parents = 1,
2949 		.flags = CLK_SET_RATE_PARENT,
2950 	},
2951 };
2952 
2953 static struct clk_regmap s4_pwm_i_mux = {
2954 	.data = &(struct clk_regmap_mux_data) {
2955 		.offset = CLKCTRL_PWM_CLK_IJ_CTRL,
2956 		.mask = 0x3,
2957 		.shift = 9,
2958 	},
2959 	.hw.init = &(struct clk_init_data){
2960 		.name = "pwm_i_mux",
2961 		.ops = &clk_regmap_mux_ops,
2962 		.parent_data = s4_pwm_parent_data,
2963 		.num_parents = ARRAY_SIZE(s4_pwm_parent_data),
2964 		.flags = 0,
2965 	},
2966 };
2967 
2968 static struct clk_regmap s4_pwm_i_div = {
2969 	.data = &(struct clk_regmap_div_data) {
2970 		.offset = CLKCTRL_PWM_CLK_IJ_CTRL,
2971 		.shift = 0,
2972 		.width = 8,
2973 	},
2974 	.hw.init = &(struct clk_init_data){
2975 		.name = "pwm_i_div",
2976 		.ops = &clk_regmap_divider_ops,
2977 		.parent_hws = (const struct clk_hw *[]) {
2978 			&s4_pwm_i_mux.hw
2979 		},
2980 		.num_parents = 1,
2981 		.flags = CLK_SET_RATE_PARENT,
2982 	},
2983 };
2984 
2985 static struct clk_regmap s4_pwm_i_gate = {
2986 	.data = &(struct clk_regmap_gate_data) {
2987 		.offset = CLKCTRL_PWM_CLK_IJ_CTRL,
2988 		.bit_idx = 8,
2989 	},
2990 	.hw.init = &(struct clk_init_data){
2991 		.name = "pwm_i_gate",
2992 		.ops = &clk_regmap_gate_ops,
2993 		.parent_hws = (const struct clk_hw *[]) {
2994 			&s4_pwm_i_div.hw
2995 		},
2996 		.num_parents = 1,
2997 		.flags = CLK_SET_RATE_PARENT,
2998 	},
2999 };
3000 
3001 static struct clk_regmap s4_pwm_j_mux = {
3002 	.data = &(struct clk_regmap_mux_data) {
3003 		.offset = CLKCTRL_PWM_CLK_IJ_CTRL,
3004 		.mask = 0x3,
3005 		.shift = 25,
3006 	},
3007 	.hw.init = &(struct clk_init_data){
3008 		.name = "pwm_j_mux",
3009 		.ops = &clk_regmap_mux_ops,
3010 		.parent_data = s4_pwm_parent_data,
3011 		.num_parents = ARRAY_SIZE(s4_pwm_parent_data),
3012 		.flags = 0,
3013 	},
3014 };
3015 
3016 static struct clk_regmap s4_pwm_j_div = {
3017 	.data = &(struct clk_regmap_div_data) {
3018 		.offset = CLKCTRL_PWM_CLK_IJ_CTRL,
3019 		.shift = 16,
3020 		.width = 8,
3021 	},
3022 	.hw.init = &(struct clk_init_data){
3023 		.name = "pwm_j_div",
3024 		.ops = &clk_regmap_divider_ops,
3025 		.parent_hws = (const struct clk_hw *[]) {
3026 			&s4_pwm_j_mux.hw
3027 		},
3028 		.num_parents = 1,
3029 		.flags = CLK_SET_RATE_PARENT,
3030 	},
3031 };
3032 
3033 static struct clk_regmap s4_pwm_j_gate = {
3034 	.data = &(struct clk_regmap_gate_data) {
3035 		.offset = CLKCTRL_PWM_CLK_IJ_CTRL,
3036 		.bit_idx = 24,
3037 	},
3038 	.hw.init = &(struct clk_init_data){
3039 		.name = "pwm_j_gate",
3040 		.ops = &clk_regmap_gate_ops,
3041 		.parent_hws = (const struct clk_hw *[]) {
3042 			&s4_pwm_j_div.hw
3043 		},
3044 		.num_parents = 1,
3045 		.flags = CLK_SET_RATE_PARENT,
3046 	},
3047 };
3048 
3049 static struct clk_regmap s4_saradc_mux = {
3050 	.data = &(struct clk_regmap_mux_data) {
3051 		.offset = CLKCTRL_SAR_CLK_CTRL,
3052 		.mask = 0x3,
3053 		.shift = 9,
3054 	},
3055 	.hw.init = &(struct clk_init_data){
3056 		.name = "saradc_mux",
3057 		.ops = &clk_regmap_mux_ops,
3058 		.parent_data = (const struct clk_parent_data []) {
3059 			{ .fw_name = "xtal", },
3060 			{ .hw = &s4_sys_clk.hw },
3061 		},
3062 		.num_parents = 2,
3063 		.flags = CLK_SET_RATE_PARENT,
3064 	},
3065 };
3066 
3067 static struct clk_regmap s4_saradc_div = {
3068 	.data = &(struct clk_regmap_div_data) {
3069 		.offset = CLKCTRL_SAR_CLK_CTRL,
3070 		.shift = 0,
3071 		.width = 8,
3072 	},
3073 	.hw.init = &(struct clk_init_data){
3074 		.name = "saradc_div",
3075 		.ops = &clk_regmap_divider_ops,
3076 		.parent_hws = (const struct clk_hw *[]) {
3077 			&s4_saradc_mux.hw
3078 		},
3079 		.num_parents = 1,
3080 		.flags = CLK_SET_RATE_PARENT,
3081 	},
3082 };
3083 
3084 static struct clk_regmap s4_saradc_gate = {
3085 	.data = &(struct clk_regmap_gate_data) {
3086 		.offset = CLKCTRL_SAR_CLK_CTRL,
3087 		.bit_idx = 8,
3088 	},
3089 	.hw.init = &(struct clk_init_data){
3090 		.name = "saradc_clk",
3091 		.ops = &clk_regmap_gate_ops,
3092 		.parent_hws = (const struct clk_hw *[]) {
3093 			&s4_saradc_div.hw
3094 		},
3095 		.num_parents = 1,
3096 		.flags = CLK_SET_RATE_PARENT,
3097 	},
3098 };
3099 
3100 /*
3101  * gen clk is designed for debug/monitor some internal clock quality. Some of the
3102  * corresponding clock sources are not described in the clock tree and internal clock
3103  * for debug, so they are skipped.
3104  */
3105 static u32 s4_gen_clk_mux_table[] = { 0, 4, 5, 7, 19, 21, 22,
3106 				      23, 24, 25, 26, 27, 28 };
3107 static const struct clk_parent_data s4_gen_clk_parent_data[] = {
3108 	{ .fw_name = "xtal", },
3109 	{ .hw = &s4_vid_pll.hw },
3110 	{ .fw_name = "gp0_pll", },
3111 	{ .fw_name = "hifi_pll", },
3112 	{ .fw_name = "fclk_div2", },
3113 	{ .fw_name = "fclk_div3", },
3114 	{ .fw_name = "fclk_div4", },
3115 	{ .fw_name = "fclk_div5", },
3116 	{ .fw_name = "fclk_div7", },
3117 	{ .fw_name = "mpll0", },
3118 	{ .fw_name = "mpll1", },
3119 	{ .fw_name = "mpll2", },
3120 	{ .fw_name = "mpll3", },
3121 };
3122 
3123 static struct clk_regmap s4_gen_clk_sel = {
3124 	.data = &(struct clk_regmap_mux_data){
3125 		.offset = CLKCTRL_GEN_CLK_CTRL,
3126 		.mask = 0x1f,
3127 		.shift = 12,
3128 		.table = s4_gen_clk_mux_table,
3129 	},
3130 	.hw.init = &(struct clk_init_data){
3131 		.name = "gen_clk_sel",
3132 		.ops = &clk_regmap_mux_ops,
3133 		.parent_data = s4_gen_clk_parent_data,
3134 		.num_parents = ARRAY_SIZE(s4_gen_clk_parent_data),
3135 		/*
3136 		 *  Because the GEN clock can be connected to an external pad
3137 		 *  and may be set up directly from the device tree. Don't
3138 		 *  really want to automatically reparent.
3139 		 */
3140 		.flags = CLK_SET_RATE_NO_REPARENT,
3141 	},
3142 };
3143 
3144 static struct clk_regmap s4_gen_clk_div = {
3145 	.data = &(struct clk_regmap_div_data){
3146 		.offset = CLKCTRL_GEN_CLK_CTRL,
3147 		.shift = 0,
3148 		.width = 11,
3149 	},
3150 	.hw.init = &(struct clk_init_data){
3151 		.name = "gen_clk_div",
3152 		.ops = &clk_regmap_divider_ops,
3153 		.parent_hws = (const struct clk_hw *[]) {
3154 			&s4_gen_clk_sel.hw
3155 		},
3156 		.num_parents = 1,
3157 		.flags = CLK_SET_RATE_PARENT,
3158 	},
3159 };
3160 
3161 static struct clk_regmap s4_gen_clk = {
3162 	.data = &(struct clk_regmap_gate_data){
3163 		.offset = CLKCTRL_GEN_CLK_CTRL,
3164 		.bit_idx = 11,
3165 	},
3166 	.hw.init = &(struct clk_init_data) {
3167 		.name = "gen_clk",
3168 		.ops = &clk_regmap_gate_ops,
3169 		.parent_hws = (const struct clk_hw *[]) {
3170 			&s4_gen_clk_div.hw
3171 		},
3172 		.num_parents = 1,
3173 		.flags = CLK_SET_RATE_PARENT,
3174 	},
3175 };
3176 
3177 #define MESON_GATE(_name, _reg, _bit) \
3178 	MESON_PCLK(_name, _reg, _bit, &s4_sys_clk.hw)
3179 
3180 static MESON_GATE(s4_ddr,		CLKCTRL_SYS_CLK_EN0_REG0, 0);
3181 static MESON_GATE(s4_dos,		CLKCTRL_SYS_CLK_EN0_REG0, 1);
3182 static MESON_GATE(s4_ethphy,		CLKCTRL_SYS_CLK_EN0_REG0, 4);
3183 static MESON_GATE(s4_mali,		CLKCTRL_SYS_CLK_EN0_REG0, 6);
3184 static MESON_GATE(s4_aocpu,		CLKCTRL_SYS_CLK_EN0_REG0, 13);
3185 static MESON_GATE(s4_aucpu,		CLKCTRL_SYS_CLK_EN0_REG0, 14);
3186 static MESON_GATE(s4_cec,		CLKCTRL_SYS_CLK_EN0_REG0, 16);
3187 static MESON_GATE(s4_sdemmca,		CLKCTRL_SYS_CLK_EN0_REG0, 24);
3188 static MESON_GATE(s4_sdemmcb,		CLKCTRL_SYS_CLK_EN0_REG0, 25);
3189 static MESON_GATE(s4_nand,		CLKCTRL_SYS_CLK_EN0_REG0, 26);
3190 static MESON_GATE(s4_smartcard,		CLKCTRL_SYS_CLK_EN0_REG0, 27);
3191 static MESON_GATE(s4_acodec,		CLKCTRL_SYS_CLK_EN0_REG0, 28);
3192 static MESON_GATE(s4_spifc,		CLKCTRL_SYS_CLK_EN0_REG0, 29);
3193 static MESON_GATE(s4_msr_clk,		CLKCTRL_SYS_CLK_EN0_REG0, 30);
3194 static MESON_GATE(s4_ir_ctrl,		CLKCTRL_SYS_CLK_EN0_REG0, 31);
3195 static MESON_GATE(s4_audio,		CLKCTRL_SYS_CLK_EN0_REG1, 0);
3196 static MESON_GATE(s4_eth,		CLKCTRL_SYS_CLK_EN0_REG1, 3);
3197 static MESON_GATE(s4_uart_a,		CLKCTRL_SYS_CLK_EN0_REG1, 5);
3198 static MESON_GATE(s4_uart_b,		CLKCTRL_SYS_CLK_EN0_REG1, 6);
3199 static MESON_GATE(s4_uart_c,		CLKCTRL_SYS_CLK_EN0_REG1, 7);
3200 static MESON_GATE(s4_uart_d,		CLKCTRL_SYS_CLK_EN0_REG1, 8);
3201 static MESON_GATE(s4_uart_e,		CLKCTRL_SYS_CLK_EN0_REG1, 9);
3202 static MESON_GATE(s4_aififo,		CLKCTRL_SYS_CLK_EN0_REG1, 11);
3203 static MESON_GATE(s4_ts_ddr,		CLKCTRL_SYS_CLK_EN0_REG1, 15);
3204 static MESON_GATE(s4_ts_pll,		CLKCTRL_SYS_CLK_EN0_REG1, 16);
3205 static MESON_GATE(s4_g2d,		CLKCTRL_SYS_CLK_EN0_REG1, 20);
3206 static MESON_GATE(s4_spicc0,		CLKCTRL_SYS_CLK_EN0_REG1, 21);
3207 static MESON_GATE(s4_usb,		CLKCTRL_SYS_CLK_EN0_REG1, 26);
3208 static MESON_GATE(s4_i2c_m_a,		CLKCTRL_SYS_CLK_EN0_REG1, 30);
3209 static MESON_GATE(s4_i2c_m_b,		CLKCTRL_SYS_CLK_EN0_REG1, 31);
3210 static MESON_GATE(s4_i2c_m_c,		CLKCTRL_SYS_CLK_EN0_REG2, 0);
3211 static MESON_GATE(s4_i2c_m_d,		CLKCTRL_SYS_CLK_EN0_REG2, 1);
3212 static MESON_GATE(s4_i2c_m_e,		CLKCTRL_SYS_CLK_EN0_REG2, 2);
3213 static MESON_GATE(s4_hdmitx_apb,	CLKCTRL_SYS_CLK_EN0_REG2, 4);
3214 static MESON_GATE(s4_i2c_s_a,		CLKCTRL_SYS_CLK_EN0_REG2, 5);
3215 static MESON_GATE(s4_usb1_to_ddr,	CLKCTRL_SYS_CLK_EN0_REG2, 8);
3216 static MESON_GATE(s4_hdcp22,		CLKCTRL_SYS_CLK_EN0_REG2, 10);
3217 static MESON_GATE(s4_mmc_apb,		CLKCTRL_SYS_CLK_EN0_REG2, 11);
3218 static MESON_GATE(s4_rsa,		CLKCTRL_SYS_CLK_EN0_REG2, 18);
3219 static MESON_GATE(s4_cpu_debug,		CLKCTRL_SYS_CLK_EN0_REG2, 19);
3220 static MESON_GATE(s4_vpu_intr,		CLKCTRL_SYS_CLK_EN0_REG2, 25);
3221 static MESON_GATE(s4_demod,		CLKCTRL_SYS_CLK_EN0_REG2, 27);
3222 static MESON_GATE(s4_sar_adc,		CLKCTRL_SYS_CLK_EN0_REG2, 28);
3223 static MESON_GATE(s4_gic,		CLKCTRL_SYS_CLK_EN0_REG2, 30);
3224 static MESON_GATE(s4_pwm_ab,		CLKCTRL_SYS_CLK_EN0_REG3, 7);
3225 static MESON_GATE(s4_pwm_cd,		CLKCTRL_SYS_CLK_EN0_REG3, 8);
3226 static MESON_GATE(s4_pwm_ef,		CLKCTRL_SYS_CLK_EN0_REG3, 9);
3227 static MESON_GATE(s4_pwm_gh,		CLKCTRL_SYS_CLK_EN0_REG3, 10);
3228 static MESON_GATE(s4_pwm_ij,		CLKCTRL_SYS_CLK_EN0_REG3, 11);
3229 
3230 /* Array of all clocks provided by this provider */
3231 static struct clk_hw *s4_periphs_hw_clks[] = {
3232 	[CLKID_RTC_32K_CLKIN]		= &s4_rtc_32k_by_oscin_clkin.hw,
3233 	[CLKID_RTC_32K_DIV]		= &s4_rtc_32k_by_oscin_div.hw,
3234 	[CLKID_RTC_32K_SEL]		= &s4_rtc_32k_by_oscin_sel.hw,
3235 	[CLKID_RTC_32K_XATL]		= &s4_rtc_32k_by_oscin.hw,
3236 	[CLKID_RTC]			= &s4_rtc_clk.hw,
3237 	[CLKID_SYS_CLK_B_SEL]		= &s4_sysclk_b_sel.hw,
3238 	[CLKID_SYS_CLK_B_DIV]		= &s4_sysclk_b_div.hw,
3239 	[CLKID_SYS_CLK_B]		= &s4_sysclk_b.hw,
3240 	[CLKID_SYS_CLK_A_SEL]		= &s4_sysclk_a_sel.hw,
3241 	[CLKID_SYS_CLK_A_DIV]		= &s4_sysclk_a_div.hw,
3242 	[CLKID_SYS_CLK_A]		= &s4_sysclk_a.hw,
3243 	[CLKID_SYS]			= &s4_sys_clk.hw,
3244 	[CLKID_CECA_32K_CLKIN]		= &s4_ceca_32k_clkin.hw,
3245 	[CLKID_CECA_32K_DIV]		= &s4_ceca_32k_div.hw,
3246 	[CLKID_CECA_32K_SEL_PRE]	= &s4_ceca_32k_sel_pre.hw,
3247 	[CLKID_CECA_32K_SEL]		= &s4_ceca_32k_sel.hw,
3248 	[CLKID_CECA_32K_CLKOUT]		= &s4_ceca_32k_clkout.hw,
3249 	[CLKID_CECB_32K_CLKIN]		= &s4_cecb_32k_clkin.hw,
3250 	[CLKID_CECB_32K_DIV]		= &s4_cecb_32k_div.hw,
3251 	[CLKID_CECB_32K_SEL_PRE]	= &s4_cecb_32k_sel_pre.hw,
3252 	[CLKID_CECB_32K_SEL]		= &s4_cecb_32k_sel.hw,
3253 	[CLKID_CECB_32K_CLKOUT]		= &s4_cecb_32k_clkout.hw,
3254 	[CLKID_SC_CLK_SEL]		= &s4_sc_clk_mux.hw,
3255 	[CLKID_SC_CLK_DIV]		= &s4_sc_clk_div.hw,
3256 	[CLKID_SC]			= &s4_sc_clk_gate.hw,
3257 	[CLKID_12_24M]			= &s4_12_24M_clk_gate.hw,
3258 	[CLKID_12M_CLK_DIV]		= &s4_12M_clk_div.hw,
3259 	[CLKID_12_24M_CLK_SEL]		= &s4_12_24M_clk.hw,
3260 	[CLKID_VID_PLL_DIV]		= &s4_vid_pll_div.hw,
3261 	[CLKID_VID_PLL_SEL]		= &s4_vid_pll_sel.hw,
3262 	[CLKID_VID_PLL]			= &s4_vid_pll.hw,
3263 	[CLKID_VCLK_SEL]		= &s4_vclk_sel.hw,
3264 	[CLKID_VCLK2_SEL]		= &s4_vclk2_sel.hw,
3265 	[CLKID_VCLK_INPUT]		= &s4_vclk_input.hw,
3266 	[CLKID_VCLK2_INPUT]		= &s4_vclk2_input.hw,
3267 	[CLKID_VCLK_DIV]		= &s4_vclk_div.hw,
3268 	[CLKID_VCLK2_DIV]		= &s4_vclk2_div.hw,
3269 	[CLKID_VCLK]			= &s4_vclk.hw,
3270 	[CLKID_VCLK2]			= &s4_vclk2.hw,
3271 	[CLKID_VCLK_DIV1]		= &s4_vclk_div1.hw,
3272 	[CLKID_VCLK_DIV2_EN]		= &s4_vclk_div2_en.hw,
3273 	[CLKID_VCLK_DIV4_EN]		= &s4_vclk_div4_en.hw,
3274 	[CLKID_VCLK_DIV6_EN]		= &s4_vclk_div6_en.hw,
3275 	[CLKID_VCLK_DIV12_EN]		= &s4_vclk_div12_en.hw,
3276 	[CLKID_VCLK2_DIV1]		= &s4_vclk2_div1.hw,
3277 	[CLKID_VCLK2_DIV2_EN]		= &s4_vclk2_div2_en.hw,
3278 	[CLKID_VCLK2_DIV4_EN]		= &s4_vclk2_div4_en.hw,
3279 	[CLKID_VCLK2_DIV6_EN]		= &s4_vclk2_div6_en.hw,
3280 	[CLKID_VCLK2_DIV12_EN]		= &s4_vclk2_div12_en.hw,
3281 	[CLKID_VCLK_DIV2]		= &s4_vclk_div2.hw,
3282 	[CLKID_VCLK_DIV4]		= &s4_vclk_div4.hw,
3283 	[CLKID_VCLK_DIV6]		= &s4_vclk_div6.hw,
3284 	[CLKID_VCLK_DIV12]		= &s4_vclk_div12.hw,
3285 	[CLKID_VCLK2_DIV2]		= &s4_vclk2_div2.hw,
3286 	[CLKID_VCLK2_DIV4]		= &s4_vclk2_div4.hw,
3287 	[CLKID_VCLK2_DIV6]		= &s4_vclk2_div6.hw,
3288 	[CLKID_VCLK2_DIV12]		= &s4_vclk2_div12.hw,
3289 	[CLKID_CTS_ENCI_SEL]		= &s4_cts_enci_sel.hw,
3290 	[CLKID_CTS_ENCP_SEL]		= &s4_cts_encp_sel.hw,
3291 	[CLKID_CTS_VDAC_SEL]		= &s4_cts_vdac_sel.hw,
3292 	[CLKID_HDMI_TX_SEL]		= &s4_hdmi_tx_sel.hw,
3293 	[CLKID_CTS_ENCI]		= &s4_cts_enci.hw,
3294 	[CLKID_CTS_ENCP]		= &s4_cts_encp.hw,
3295 	[CLKID_CTS_VDAC]		= &s4_cts_vdac.hw,
3296 	[CLKID_HDMI_TX]			= &s4_hdmi_tx.hw,
3297 	[CLKID_HDMI_SEL]		= &s4_hdmi_sel.hw,
3298 	[CLKID_HDMI_DIV]		= &s4_hdmi_div.hw,
3299 	[CLKID_HDMI]			= &s4_hdmi.hw,
3300 	[CLKID_TS_CLK_DIV]		= &s4_ts_clk_div.hw,
3301 	[CLKID_TS]			= &s4_ts_clk_gate.hw,
3302 	[CLKID_MALI_0_SEL]		= &s4_mali_0_sel.hw,
3303 	[CLKID_MALI_0_DIV]		= &s4_mali_0_div.hw,
3304 	[CLKID_MALI_0]			= &s4_mali_0.hw,
3305 	[CLKID_MALI_1_SEL]		= &s4_mali_1_sel.hw,
3306 	[CLKID_MALI_1_DIV]		= &s4_mali_1_div.hw,
3307 	[CLKID_MALI_1]			= &s4_mali_1.hw,
3308 	[CLKID_MALI_SEL]		= &s4_mali_mux.hw,
3309 	[CLKID_VDEC_P0_SEL]		= &s4_vdec_p0_mux.hw,
3310 	[CLKID_VDEC_P0_DIV]		= &s4_vdec_p0_div.hw,
3311 	[CLKID_VDEC_P0]			= &s4_vdec_p0.hw,
3312 	[CLKID_VDEC_P1_SEL]		= &s4_vdec_p1_mux.hw,
3313 	[CLKID_VDEC_P1_DIV]		= &s4_vdec_p1_div.hw,
3314 	[CLKID_VDEC_P1]			= &s4_vdec_p1.hw,
3315 	[CLKID_VDEC_SEL]		= &s4_vdec_mux.hw,
3316 	[CLKID_HEVCF_P0_SEL]		= &s4_hevcf_p0_mux.hw,
3317 	[CLKID_HEVCF_P0_DIV]		= &s4_hevcf_p0_div.hw,
3318 	[CLKID_HEVCF_P0]		= &s4_hevcf_p0.hw,
3319 	[CLKID_HEVCF_P1_SEL]		= &s4_hevcf_p1_mux.hw,
3320 	[CLKID_HEVCF_P1_DIV]		= &s4_hevcf_p1_div.hw,
3321 	[CLKID_HEVCF_P1]		= &s4_hevcf_p1.hw,
3322 	[CLKID_HEVCF_SEL]		= &s4_hevcf_mux.hw,
3323 	[CLKID_VPU_0_SEL]		= &s4_vpu_0_sel.hw,
3324 	[CLKID_VPU_0_DIV]		= &s4_vpu_0_div.hw,
3325 	[CLKID_VPU_0]			= &s4_vpu_0.hw,
3326 	[CLKID_VPU_1_SEL]		= &s4_vpu_1_sel.hw,
3327 	[CLKID_VPU_1_DIV]		= &s4_vpu_1_div.hw,
3328 	[CLKID_VPU_1]			= &s4_vpu_1.hw,
3329 	[CLKID_VPU]			= &s4_vpu.hw,
3330 	[CLKID_VPU_CLKB_TMP_SEL]	= &s4_vpu_clkb_tmp_mux.hw,
3331 	[CLKID_VPU_CLKB_TMP_DIV]	= &s4_vpu_clkb_tmp_div.hw,
3332 	[CLKID_VPU_CLKB_TMP]		= &s4_vpu_clkb_tmp.hw,
3333 	[CLKID_VPU_CLKB_DIV]		= &s4_vpu_clkb_div.hw,
3334 	[CLKID_VPU_CLKB]		= &s4_vpu_clkb.hw,
3335 	[CLKID_VPU_CLKC_P0_SEL]		= &s4_vpu_clkc_p0_mux.hw,
3336 	[CLKID_VPU_CLKC_P0_DIV]		= &s4_vpu_clkc_p0_div.hw,
3337 	[CLKID_VPU_CLKC_P0]		= &s4_vpu_clkc_p0.hw,
3338 	[CLKID_VPU_CLKC_P1_SEL]		= &s4_vpu_clkc_p1_mux.hw,
3339 	[CLKID_VPU_CLKC_P1_DIV]		= &s4_vpu_clkc_p1_div.hw,
3340 	[CLKID_VPU_CLKC_P1]		= &s4_vpu_clkc_p1.hw,
3341 	[CLKID_VPU_CLKC_SEL]		= &s4_vpu_clkc_mux.hw,
3342 	[CLKID_VAPB_0_SEL]		= &s4_vapb_0_sel.hw,
3343 	[CLKID_VAPB_0_DIV]		= &s4_vapb_0_div.hw,
3344 	[CLKID_VAPB_0]			= &s4_vapb_0.hw,
3345 	[CLKID_VAPB_1_SEL]		= &s4_vapb_1_sel.hw,
3346 	[CLKID_VAPB_1_DIV]		= &s4_vapb_1_div.hw,
3347 	[CLKID_VAPB_1]			= &s4_vapb_1.hw,
3348 	[CLKID_VAPB]			= &s4_vapb.hw,
3349 	[CLKID_GE2D]			= &s4_ge2d_gate.hw,
3350 	[CLKID_VDIN_MEAS_SEL]		= &s4_vdin_meas_mux.hw,
3351 	[CLKID_VDIN_MEAS_DIV]		= &s4_vdin_meas_div.hw,
3352 	[CLKID_VDIN_MEAS]		= &s4_vdin_meas_gate.hw,
3353 	[CLKID_SD_EMMC_C_CLK_SEL]	= &s4_sd_emmc_c_clk0_sel.hw,
3354 	[CLKID_SD_EMMC_C_CLK_DIV]	= &s4_sd_emmc_c_clk0_div.hw,
3355 	[CLKID_SD_EMMC_C]		= &s4_sd_emmc_c_clk0.hw,
3356 	[CLKID_SD_EMMC_A_CLK_SEL]	= &s4_sd_emmc_a_clk0_sel.hw,
3357 	[CLKID_SD_EMMC_A_CLK_DIV]	= &s4_sd_emmc_a_clk0_div.hw,
3358 	[CLKID_SD_EMMC_A]		= &s4_sd_emmc_a_clk0.hw,
3359 	[CLKID_SD_EMMC_B_CLK_SEL]	= &s4_sd_emmc_b_clk0_sel.hw,
3360 	[CLKID_SD_EMMC_B_CLK_DIV]	= &s4_sd_emmc_b_clk0_div.hw,
3361 	[CLKID_SD_EMMC_B]		= &s4_sd_emmc_b_clk0.hw,
3362 	[CLKID_SPICC0_SEL]		= &s4_spicc0_mux.hw,
3363 	[CLKID_SPICC0_DIV]		= &s4_spicc0_div.hw,
3364 	[CLKID_SPICC0_EN]		= &s4_spicc0_gate.hw,
3365 	[CLKID_PWM_A_SEL]		= &s4_pwm_a_mux.hw,
3366 	[CLKID_PWM_A_DIV]		= &s4_pwm_a_div.hw,
3367 	[CLKID_PWM_A]			= &s4_pwm_a_gate.hw,
3368 	[CLKID_PWM_B_SEL]		= &s4_pwm_b_mux.hw,
3369 	[CLKID_PWM_B_DIV]		= &s4_pwm_b_div.hw,
3370 	[CLKID_PWM_B]			= &s4_pwm_b_gate.hw,
3371 	[CLKID_PWM_C_SEL]		= &s4_pwm_c_mux.hw,
3372 	[CLKID_PWM_C_DIV]		= &s4_pwm_c_div.hw,
3373 	[CLKID_PWM_C]			= &s4_pwm_c_gate.hw,
3374 	[CLKID_PWM_D_SEL]		= &s4_pwm_d_mux.hw,
3375 	[CLKID_PWM_D_DIV]		= &s4_pwm_d_div.hw,
3376 	[CLKID_PWM_D]			= &s4_pwm_d_gate.hw,
3377 	[CLKID_PWM_E_SEL]		= &s4_pwm_e_mux.hw,
3378 	[CLKID_PWM_E_DIV]		= &s4_pwm_e_div.hw,
3379 	[CLKID_PWM_E]			= &s4_pwm_e_gate.hw,
3380 	[CLKID_PWM_F_SEL]		= &s4_pwm_f_mux.hw,
3381 	[CLKID_PWM_F_DIV]		= &s4_pwm_f_div.hw,
3382 	[CLKID_PWM_F]			= &s4_pwm_f_gate.hw,
3383 	[CLKID_PWM_G_SEL]		= &s4_pwm_g_mux.hw,
3384 	[CLKID_PWM_G_DIV]		= &s4_pwm_g_div.hw,
3385 	[CLKID_PWM_G]			= &s4_pwm_g_gate.hw,
3386 	[CLKID_PWM_H_SEL]		= &s4_pwm_h_mux.hw,
3387 	[CLKID_PWM_H_DIV]		= &s4_pwm_h_div.hw,
3388 	[CLKID_PWM_H]			= &s4_pwm_h_gate.hw,
3389 	[CLKID_PWM_I_SEL]		= &s4_pwm_i_mux.hw,
3390 	[CLKID_PWM_I_DIV]		= &s4_pwm_i_div.hw,
3391 	[CLKID_PWM_I]			= &s4_pwm_i_gate.hw,
3392 	[CLKID_PWM_J_SEL]		= &s4_pwm_j_mux.hw,
3393 	[CLKID_PWM_J_DIV]		= &s4_pwm_j_div.hw,
3394 	[CLKID_PWM_J]			= &s4_pwm_j_gate.hw,
3395 	[CLKID_SARADC_SEL]		= &s4_saradc_mux.hw,
3396 	[CLKID_SARADC_DIV]		= &s4_saradc_div.hw,
3397 	[CLKID_SARADC]			= &s4_saradc_gate.hw,
3398 	[CLKID_GEN_SEL]			= &s4_gen_clk_sel.hw,
3399 	[CLKID_GEN_DIV]			= &s4_gen_clk_div.hw,
3400 	[CLKID_GEN]			= &s4_gen_clk.hw,
3401 	[CLKID_DDR]			= &s4_ddr.hw,
3402 	[CLKID_DOS]			= &s4_dos.hw,
3403 	[CLKID_ETHPHY]			= &s4_ethphy.hw,
3404 	[CLKID_MALI]			= &s4_mali.hw,
3405 	[CLKID_AOCPU]			= &s4_aocpu.hw,
3406 	[CLKID_AUCPU]			= &s4_aucpu.hw,
3407 	[CLKID_CEC]			= &s4_cec.hw,
3408 	[CLKID_SDEMMC_A]		= &s4_sdemmca.hw,
3409 	[CLKID_SDEMMC_B]		= &s4_sdemmcb.hw,
3410 	[CLKID_NAND]			= &s4_nand.hw,
3411 	[CLKID_SMARTCARD]		= &s4_smartcard.hw,
3412 	[CLKID_ACODEC]			= &s4_acodec.hw,
3413 	[CLKID_SPIFC]			= &s4_spifc.hw,
3414 	[CLKID_MSR]			= &s4_msr_clk.hw,
3415 	[CLKID_IR_CTRL]			= &s4_ir_ctrl.hw,
3416 	[CLKID_AUDIO]			= &s4_audio.hw,
3417 	[CLKID_ETH]			= &s4_eth.hw,
3418 	[CLKID_UART_A]			= &s4_uart_a.hw,
3419 	[CLKID_UART_B]			= &s4_uart_b.hw,
3420 	[CLKID_UART_C]			= &s4_uart_c.hw,
3421 	[CLKID_UART_D]			= &s4_uart_d.hw,
3422 	[CLKID_UART_E]			= &s4_uart_e.hw,
3423 	[CLKID_AIFIFO]			= &s4_aififo.hw,
3424 	[CLKID_TS_DDR]			= &s4_ts_ddr.hw,
3425 	[CLKID_TS_PLL]			= &s4_ts_pll.hw,
3426 	[CLKID_G2D]			= &s4_g2d.hw,
3427 	[CLKID_SPICC0]			= &s4_spicc0.hw,
3428 	[CLKID_USB]			= &s4_usb.hw,
3429 	[CLKID_I2C_M_A]			= &s4_i2c_m_a.hw,
3430 	[CLKID_I2C_M_B]			= &s4_i2c_m_b.hw,
3431 	[CLKID_I2C_M_C]			= &s4_i2c_m_c.hw,
3432 	[CLKID_I2C_M_D]			= &s4_i2c_m_d.hw,
3433 	[CLKID_I2C_M_E]			= &s4_i2c_m_e.hw,
3434 	[CLKID_HDMITX_APB]		= &s4_hdmitx_apb.hw,
3435 	[CLKID_I2C_S_A]			= &s4_i2c_s_a.hw,
3436 	[CLKID_USB1_TO_DDR]		= &s4_usb1_to_ddr.hw,
3437 	[CLKID_HDCP22]			= &s4_hdcp22.hw,
3438 	[CLKID_MMC_APB]			= &s4_mmc_apb.hw,
3439 	[CLKID_RSA]			= &s4_rsa.hw,
3440 	[CLKID_CPU_DEBUG]		= &s4_cpu_debug.hw,
3441 	[CLKID_VPU_INTR]		= &s4_vpu_intr.hw,
3442 	[CLKID_DEMOD]			= &s4_demod.hw,
3443 	[CLKID_SAR_ADC]			= &s4_sar_adc.hw,
3444 	[CLKID_GIC]			= &s4_gic.hw,
3445 	[CLKID_PWM_AB]			= &s4_pwm_ab.hw,
3446 	[CLKID_PWM_CD]			= &s4_pwm_cd.hw,
3447 	[CLKID_PWM_EF]			= &s4_pwm_ef.hw,
3448 	[CLKID_PWM_GH]			= &s4_pwm_gh.hw,
3449 	[CLKID_PWM_IJ]			= &s4_pwm_ij.hw,
3450 	[CLKID_HDCP22_ESMCLK_SEL]	= &s4_hdcp22_esmclk_mux.hw,
3451 	[CLKID_HDCP22_ESMCLK_DIV]	= &s4_hdcp22_esmclk_div.hw,
3452 	[CLKID_HDCP22_ESMCLK]		= &s4_hdcp22_esmclk_gate.hw,
3453 	[CLKID_HDCP22_SKPCLK_SEL]	= &s4_hdcp22_skpclk_mux.hw,
3454 	[CLKID_HDCP22_SKPCLK_DIV]	= &s4_hdcp22_skpclk_div.hw,
3455 	[CLKID_HDCP22_SKPCLK]		= &s4_hdcp22_skpclk_gate.hw,
3456 };
3457 
3458 static const struct regmap_config clkc_regmap_config = {
3459 	.reg_bits       = 32,
3460 	.val_bits       = 32,
3461 	.reg_stride     = 4,
3462 	.max_register   = CLKCTRL_DEMOD_CLK_CTRL,
3463 };
3464 
3465 static struct meson_clk_hw_data s4_periphs_clks = {
3466 	.hws = s4_periphs_hw_clks,
3467 	.num = ARRAY_SIZE(s4_periphs_hw_clks),
3468 };
3469 
meson_s4_periphs_probe(struct platform_device * pdev)3470 static int meson_s4_periphs_probe(struct platform_device *pdev)
3471 {
3472 	struct device *dev = &pdev->dev;
3473 	struct regmap *regmap;
3474 	void __iomem *base;
3475 	int ret, i;
3476 
3477 	base = devm_platform_ioremap_resource(pdev, 0);
3478 	if (IS_ERR(base))
3479 		return dev_err_probe(dev, PTR_ERR(base),
3480 				     "can't ioremap resource\n");
3481 
3482 	regmap = devm_regmap_init_mmio(dev, base, &clkc_regmap_config);
3483 	if (IS_ERR(regmap))
3484 		return dev_err_probe(dev, PTR_ERR(regmap),
3485 				     "can't init regmap mmio region\n");
3486 
3487 	for (i = 0; i < s4_periphs_clks.num; i++) {
3488 		/* array might be sparse */
3489 		if (!s4_periphs_clks.hws[i])
3490 			continue;
3491 
3492 		ret = devm_clk_hw_register(dev, s4_periphs_clks.hws[i]);
3493 		if (ret)
3494 			return dev_err_probe(dev, ret,
3495 					     "clock[%d] registration failed\n", i);
3496 	}
3497 
3498 	return devm_of_clk_add_hw_provider(dev, meson_clk_hw_get, &s4_periphs_clks);
3499 }
3500 
3501 static const struct of_device_id clkc_match_table[] = {
3502 	{
3503 		.compatible = "amlogic,s4-peripherals-clkc",
3504 	},
3505 	{}
3506 };
3507 MODULE_DEVICE_TABLE(of, clkc_match_table);
3508 
3509 static struct platform_driver s4_driver = {
3510 	.probe		= meson_s4_periphs_probe,
3511 	.driver		= {
3512 		.name	= "s4-periphs-clkc",
3513 		.of_match_table = clkc_match_table,
3514 	},
3515 };
3516 module_platform_driver(s4_driver);
3517 
3518 MODULE_DESCRIPTION("Amlogic S4 Peripherals Clock Controller driver");
3519 MODULE_AUTHOR("Yu Tu <yu.tu@amlogic.com>");
3520 MODULE_LICENSE("GPL");
3521 MODULE_IMPORT_NS("CLK_MESON");
3522