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