1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
4 */
5
6 #include <linux/clk-provider.h>
7 #include <linux/module.h>
8 #include <linux/platform_device.h>
9 #include <linux/regmap.h>
10
11 #include <dt-bindings/clock/qcom,maili-videocc.h>
12
13 #include "clk-alpha-pll.h"
14 #include "clk-branch.h"
15 #include "clk-rcg.h"
16 #include "clk-regmap.h"
17 #include "clk-regmap-divider.h"
18 #include "common.h"
19 #include "gdsc.h"
20 #include "reset.h"
21
22 #define ACCU_CFG_MASK GENMASK(25, 21)
23
24 enum {
25 DT_BI_TCXO,
26 DT_AHB_CLK,
27 };
28
29 enum {
30 P_BI_TCXO,
31 P_VIDEO_CC_PLL0_OUT_MAIN,
32 P_VIDEO_CC_PLL1_OUT_MAIN,
33 P_VIDEO_CC_PLL2_OUT_MAIN,
34 };
35
36 static const struct pll_vco taycan_eha_t_vco[] = {
37 { 249600000, 2500000000, 0 },
38 };
39
40 /* 360.0 MHz Configuration */
41 static const struct alpha_pll_config video_cc_pll0_config = {
42 .l = 0x12,
43 .cal_l = 0x42,
44 .alpha = 0xc000,
45 .config_ctl_val = 0xa5c400e7,
46 .config_ctl_hi_val = 0x0a806160,
47 .config_ctl_hi1_val = 0xf51dea20,
48 .user_ctl_val = 0x00000000,
49 .user_ctl_hi_val = 0x00000002,
50 };
51
52 static struct clk_alpha_pll video_cc_pll0 = {
53 .offset = 0x0,
54 .config = &video_cc_pll0_config,
55 .vco_table = taycan_eha_t_vco,
56 .num_vco = ARRAY_SIZE(taycan_eha_t_vco),
57 .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EHA_T],
58 .clkr = {
59 .hw.init = &(const struct clk_init_data) {
60 .name = "video_cc_pll0",
61 .parent_data = &(const struct clk_parent_data) {
62 .index = DT_BI_TCXO,
63 },
64 .num_parents = 1,
65 .ops = &clk_alpha_pll_taycan_eha_t_ops,
66 },
67 },
68 };
69
70 /* 480.0 MHz Configuration */
71 static const struct alpha_pll_config video_cc_pll1_config = {
72 .l = 0x19,
73 .cal_l = 0x42,
74 .alpha = 0x0,
75 .config_ctl_val = 0xa5c400e7,
76 .config_ctl_hi_val = 0x0a806160,
77 .config_ctl_hi1_val = 0xf51dea20,
78 .user_ctl_val = 0x00000000,
79 .user_ctl_hi_val = 0x00000002,
80 };
81
82 static struct clk_alpha_pll video_cc_pll1 = {
83 .offset = 0x1000,
84 .config = &video_cc_pll1_config,
85 .vco_table = taycan_eha_t_vco,
86 .num_vco = ARRAY_SIZE(taycan_eha_t_vco),
87 .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EHA_T],
88 .clkr = {
89 .hw.init = &(const struct clk_init_data) {
90 .name = "video_cc_pll1",
91 .parent_data = &(const struct clk_parent_data) {
92 .index = DT_BI_TCXO,
93 },
94 .num_parents = 1,
95 .ops = &clk_alpha_pll_taycan_eha_t_ops,
96 },
97 },
98 };
99
100 /* 480.0 MHz Configuration */
101 static const struct alpha_pll_config video_cc_pll2_config = {
102 .l = 0x19,
103 .cal_l = 0x42,
104 .alpha = 0x0,
105 .config_ctl_val = 0xa5c400e7,
106 .config_ctl_hi_val = 0x0a806160,
107 .config_ctl_hi1_val = 0xf51dea20,
108 .user_ctl_val = 0x00000000,
109 .user_ctl_hi_val = 0x00000002,
110 };
111
112 static struct clk_alpha_pll video_cc_pll2 = {
113 .offset = 0x2000,
114 .config = &video_cc_pll2_config,
115 .vco_table = taycan_eha_t_vco,
116 .num_vco = ARRAY_SIZE(taycan_eha_t_vco),
117 .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EHA_T],
118 .clkr = {
119 .hw.init = &(const struct clk_init_data) {
120 .name = "video_cc_pll2",
121 .parent_data = &(const struct clk_parent_data) {
122 .index = DT_BI_TCXO,
123 },
124 .num_parents = 1,
125 .ops = &clk_alpha_pll_taycan_eha_t_ops,
126 },
127 },
128 };
129
130 static const struct parent_map video_cc_parent_map_0[] = {
131 { P_BI_TCXO, 0 },
132 };
133
134 static const struct clk_parent_data video_cc_parent_data_0[] = {
135 { .index = DT_BI_TCXO },
136 };
137
138 static const struct parent_map video_cc_parent_map_1[] = {
139 { P_BI_TCXO, 0 },
140 { P_VIDEO_CC_PLL1_OUT_MAIN, 1 },
141 };
142
143 static const struct clk_parent_data video_cc_parent_data_1[] = {
144 { .index = DT_BI_TCXO },
145 { .hw = &video_cc_pll1.clkr.hw },
146 };
147
148 static const struct parent_map video_cc_parent_map_2[] = {
149 { P_BI_TCXO, 0 },
150 { P_VIDEO_CC_PLL2_OUT_MAIN, 1 },
151 };
152
153 static const struct clk_parent_data video_cc_parent_data_2[] = {
154 { .index = DT_BI_TCXO },
155 { .hw = &video_cc_pll2.clkr.hw },
156 };
157
158 static const struct parent_map video_cc_parent_map_3[] = {
159 { P_BI_TCXO, 0 },
160 { P_VIDEO_CC_PLL0_OUT_MAIN, 1 },
161 };
162
163 static const struct clk_parent_data video_cc_parent_data_3[] = {
164 { .index = DT_BI_TCXO },
165 { .hw = &video_cc_pll0.clkr.hw },
166 };
167
168 static const struct freq_tbl ftbl_video_cc_ahb_clk_src[] = {
169 F(19200000, P_BI_TCXO, 1, 0, 0),
170 { }
171 };
172
173 static struct clk_rcg2 video_cc_ahb_clk_src = {
174 .cmd_rcgr = 0x8060,
175 .mnd_width = 0,
176 .hid_width = 5,
177 .parent_map = video_cc_parent_map_0,
178 .freq_tbl = ftbl_video_cc_ahb_clk_src,
179 .hw_clk_ctrl = true,
180 .clkr.hw.init = &(const struct clk_init_data) {
181 .name = "video_cc_ahb_clk_src",
182 .parent_data = video_cc_parent_data_0,
183 .num_parents = ARRAY_SIZE(video_cc_parent_data_0),
184 .flags = CLK_SET_RATE_PARENT,
185 .ops = &clk_rcg2_shared_ops,
186 },
187 };
188
189 static const struct freq_tbl ftbl_video_cc_mvs0_clk_src[] = {
190 F(240000000, P_VIDEO_CC_PLL1_OUT_MAIN, 2, 0, 0),
191 F(338000000, P_VIDEO_CC_PLL1_OUT_MAIN, 2, 0, 0),
192 F(420000000, P_VIDEO_CC_PLL1_OUT_MAIN, 2, 0, 0),
193 F(444000000, P_VIDEO_CC_PLL1_OUT_MAIN, 2, 0, 0),
194 F(600000000, P_VIDEO_CC_PLL1_OUT_MAIN, 2, 0, 0),
195 F(630000000, P_VIDEO_CC_PLL1_OUT_MAIN, 2, 0, 0),
196 F(800000000, P_VIDEO_CC_PLL1_OUT_MAIN, 2, 0, 0),
197 F(1000000000, P_VIDEO_CC_PLL1_OUT_MAIN, 2, 0, 0),
198 { }
199 };
200
201 static struct clk_rcg2 video_cc_mvs0_clk_src = {
202 .cmd_rcgr = 0x8030,
203 .mnd_width = 0,
204 .hid_width = 5,
205 .parent_map = video_cc_parent_map_1,
206 .freq_tbl = ftbl_video_cc_mvs0_clk_src,
207 .hw_clk_ctrl = true,
208 .clkr.hw.init = &(const struct clk_init_data) {
209 .name = "video_cc_mvs0_clk_src",
210 .parent_data = video_cc_parent_data_1,
211 .num_parents = ARRAY_SIZE(video_cc_parent_data_1),
212 .flags = CLK_SET_RATE_PARENT,
213 .ops = &clk_rcg2_shared_ops,
214 },
215 };
216
217 static const struct freq_tbl ftbl_video_cc_mvs0b_clk_src[] = {
218 F(240000000, P_VIDEO_CC_PLL2_OUT_MAIN, 2, 0, 0),
219 F(338000000, P_VIDEO_CC_PLL2_OUT_MAIN, 2, 0, 0),
220 F(420000000, P_VIDEO_CC_PLL2_OUT_MAIN, 2, 0, 0),
221 F(444000000, P_VIDEO_CC_PLL2_OUT_MAIN, 2, 0, 0),
222 F(533000000, P_VIDEO_CC_PLL2_OUT_MAIN, 2, 0, 0),
223 F(630000000, P_VIDEO_CC_PLL2_OUT_MAIN, 2, 0, 0),
224 F(800000000, P_VIDEO_CC_PLL2_OUT_MAIN, 2, 0, 0),
225 { }
226 };
227
228 static struct clk_rcg2 video_cc_mvs0b_clk_src = {
229 .cmd_rcgr = 0x8018,
230 .mnd_width = 0,
231 .hid_width = 5,
232 .parent_map = video_cc_parent_map_2,
233 .freq_tbl = ftbl_video_cc_mvs0b_clk_src,
234 .hw_clk_ctrl = true,
235 .clkr.hw.init = &(const struct clk_init_data) {
236 .name = "video_cc_mvs0b_clk_src",
237 .parent_data = video_cc_parent_data_2,
238 .num_parents = ARRAY_SIZE(video_cc_parent_data_2),
239 .flags = CLK_SET_RATE_PARENT,
240 .ops = &clk_rcg2_shared_ops,
241 },
242 };
243
244 static const struct freq_tbl ftbl_video_cc_mvs0c_clk_src[] = {
245 F(360000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0),
246 F(507000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0),
247 F(630000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0),
248 F(666000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0),
249 F(800000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0),
250 F(1104000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0),
251 F(1260000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0),
252 { }
253 };
254
255 static struct clk_rcg2 video_cc_mvs0c_clk_src = {
256 .cmd_rcgr = 0x8048,
257 .mnd_width = 0,
258 .hid_width = 5,
259 .parent_map = video_cc_parent_map_3,
260 .freq_tbl = ftbl_video_cc_mvs0c_clk_src,
261 .hw_clk_ctrl = true,
262 .clkr.hw.init = &(const struct clk_init_data) {
263 .name = "video_cc_mvs0c_clk_src",
264 .parent_data = video_cc_parent_data_3,
265 .num_parents = ARRAY_SIZE(video_cc_parent_data_3),
266 .flags = CLK_SET_RATE_PARENT,
267 .ops = &clk_rcg2_shared_ops,
268 },
269 };
270
271 static struct clk_rcg2 video_cc_xo_clk_src = {
272 .cmd_rcgr = 0x8194,
273 .mnd_width = 0,
274 .hid_width = 5,
275 .parent_map = video_cc_parent_map_0,
276 .freq_tbl = ftbl_video_cc_ahb_clk_src,
277 .clkr.hw.init = &(const struct clk_init_data) {
278 .name = "video_cc_xo_clk_src",
279 .parent_data = video_cc_parent_data_0,
280 .num_parents = ARRAY_SIZE(video_cc_parent_data_0),
281 .flags = CLK_SET_RATE_PARENT,
282 .ops = &clk_rcg2_ops,
283 },
284 };
285
286 static struct clk_branch video_cc_mvs0_clk = {
287 .halt_reg = 0x80d0,
288 .halt_check = BRANCH_HALT_VOTED,
289 .hwcg_reg = 0x80d0,
290 .hwcg_bit = 1,
291 .clkr = {
292 .enable_reg = 0x80d0,
293 .enable_mask = BIT(0),
294 .hw.init = &(const struct clk_init_data) {
295 .name = "video_cc_mvs0_clk",
296 .parent_hws = (const struct clk_hw*[]) {
297 &video_cc_mvs0_clk_src.clkr.hw,
298 },
299 .num_parents = 1,
300 .flags = CLK_SET_RATE_PARENT,
301 .ops = &clk_branch2_ops,
302 },
303 },
304 };
305
306 static struct clk_mem_branch video_cc_mvs0_freerun_clk = {
307 .mem_enable_reg = 0x80e4,
308 .mem_ack_reg = 0x80e4,
309 .mem_enable_mask = BIT(3),
310 .mem_enable_ack_mask = GENMASK(11, 10),
311 .mem_enable_invert = true,
312 .branch = {
313 .halt_reg = 0x80e0,
314 .halt_check = BRANCH_HALT,
315 .clkr = {
316 .enable_reg = 0x80e0,
317 .enable_mask = BIT(0),
318 .hw.init = &(const struct clk_init_data) {
319 .name = "video_cc_mvs0_freerun_clk",
320 .parent_hws = (const struct clk_hw*[]) {
321 &video_cc_mvs0_clk_src.clkr.hw,
322 },
323 .num_parents = 1,
324 .flags = CLK_SET_RATE_PARENT,
325 .ops = &clk_branch2_mem_ops,
326 },
327 },
328 },
329 };
330
331 static struct clk_branch video_cc_mvs0_shift_clk = {
332 .halt_reg = 0x81b4,
333 .halt_check = BRANCH_HALT_VOTED,
334 .hwcg_reg = 0x81b4,
335 .hwcg_bit = 1,
336 .clkr = {
337 .enable_reg = 0x81b4,
338 .enable_mask = BIT(0),
339 .hw.init = &(const struct clk_init_data) {
340 .name = "video_cc_mvs0_shift_clk",
341 .parent_hws = (const struct clk_hw*[]) {
342 &video_cc_xo_clk_src.clkr.hw,
343 },
344 .num_parents = 1,
345 .flags = CLK_SET_RATE_PARENT,
346 .ops = &clk_branch2_ops,
347 },
348 },
349 };
350
351 static struct clk_branch video_cc_mvs0_vpp0_clk = {
352 .halt_reg = 0x8134,
353 .halt_check = BRANCH_HALT_VOTED,
354 .hwcg_reg = 0x8134,
355 .hwcg_bit = 1,
356 .clkr = {
357 .enable_reg = 0x8134,
358 .enable_mask = BIT(0),
359 .hw.init = &(const struct clk_init_data) {
360 .name = "video_cc_mvs0_vpp0_clk",
361 .parent_hws = (const struct clk_hw*[]) {
362 &video_cc_mvs0_clk_src.clkr.hw,
363 },
364 .num_parents = 1,
365 .flags = CLK_SET_RATE_PARENT,
366 .ops = &clk_branch2_ops,
367 },
368 },
369 };
370
371 static struct clk_branch video_cc_mvs0_vpp0_freerun_clk = {
372 .halt_reg = 0x8144,
373 .halt_check = BRANCH_HALT,
374 .clkr = {
375 .enable_reg = 0x8144,
376 .enable_mask = BIT(0),
377 .hw.init = &(const struct clk_init_data) {
378 .name = "video_cc_mvs0_vpp0_freerun_clk",
379 .parent_hws = (const struct clk_hw*[]) {
380 &video_cc_mvs0_clk_src.clkr.hw,
381 },
382 .num_parents = 1,
383 .flags = CLK_SET_RATE_PARENT,
384 .ops = &clk_branch2_ops,
385 },
386 },
387 };
388
389 static struct clk_branch video_cc_mvs0b_clk = {
390 .halt_reg = 0x80bc,
391 .halt_check = BRANCH_HALT_VOTED,
392 .hwcg_reg = 0x80bc,
393 .hwcg_bit = 1,
394 .clkr = {
395 .enable_reg = 0x80bc,
396 .enable_mask = BIT(0),
397 .hw.init = &(const struct clk_init_data) {
398 .name = "video_cc_mvs0b_clk",
399 .parent_hws = (const struct clk_hw*[]) {
400 &video_cc_mvs0b_clk_src.clkr.hw,
401 },
402 .num_parents = 1,
403 .flags = CLK_SET_RATE_PARENT,
404 .ops = &clk_branch2_ops,
405 },
406 },
407 };
408
409 static struct clk_branch video_cc_mvs0b_freerun_clk = {
410 .halt_reg = 0x80cc,
411 .halt_check = BRANCH_HALT,
412 .clkr = {
413 .enable_reg = 0x80cc,
414 .enable_mask = BIT(0),
415 .hw.init = &(const struct clk_init_data) {
416 .name = "video_cc_mvs0b_freerun_clk",
417 .parent_hws = (const struct clk_hw*[]) {
418 &video_cc_mvs0b_clk_src.clkr.hw,
419 },
420 .num_parents = 1,
421 .flags = CLK_SET_RATE_PARENT,
422 .ops = &clk_branch2_ops,
423 },
424 },
425 };
426
427 static struct clk_branch video_cc_mvs0c_clk = {
428 .halt_reg = 0x8164,
429 .halt_check = BRANCH_HALT_VOTED,
430 .hwcg_reg = 0x8164,
431 .hwcg_bit = 1,
432 .clkr = {
433 .enable_reg = 0x8164,
434 .enable_mask = BIT(0),
435 .hw.init = &(const struct clk_init_data) {
436 .name = "video_cc_mvs0c_clk",
437 .parent_hws = (const struct clk_hw*[]) {
438 &video_cc_mvs0c_clk_src.clkr.hw,
439 },
440 .num_parents = 1,
441 .flags = CLK_SET_RATE_PARENT,
442 .ops = &clk_branch2_ops,
443 },
444 },
445 };
446
447 static struct clk_branch video_cc_mvs0c_debug_clk = {
448 .halt_reg = 0x81c0,
449 .halt_check = BRANCH_HALT,
450 .clkr = {
451 .enable_reg = 0x81c0,
452 .enable_mask = BIT(0),
453 .hw.init = &(const struct clk_init_data) {
454 .name = "video_cc_mvs0c_debug_clk",
455 .parent_hws = (const struct clk_hw*[]) {
456 &video_cc_mvs0c_clk_src.clkr.hw,
457 },
458 .num_parents = 1,
459 .flags = CLK_SET_RATE_PARENT,
460 .ops = &clk_branch2_ops,
461 },
462 },
463 };
464
465 static struct clk_branch video_cc_mvs0c_freerun_clk = {
466 .halt_reg = 0x8174,
467 .halt_check = BRANCH_HALT,
468 .clkr = {
469 .enable_reg = 0x8174,
470 .enable_mask = BIT(0),
471 .hw.init = &(const struct clk_init_data) {
472 .name = "video_cc_mvs0c_freerun_clk",
473 .parent_hws = (const struct clk_hw*[]) {
474 &video_cc_mvs0c_clk_src.clkr.hw,
475 },
476 .num_parents = 1,
477 .flags = CLK_SET_RATE_PARENT,
478 .ops = &clk_branch2_ops,
479 },
480 },
481 };
482
483 static struct clk_branch video_cc_mvs0c_shift_clk = {
484 .halt_reg = 0x81b8,
485 .halt_check = BRANCH_HALT_VOTED,
486 .hwcg_reg = 0x81b8,
487 .hwcg_bit = 1,
488 .clkr = {
489 .enable_reg = 0x81b8,
490 .enable_mask = BIT(0),
491 .hw.init = &(const struct clk_init_data) {
492 .name = "video_cc_mvs0c_shift_clk",
493 .parent_hws = (const struct clk_hw*[]) {
494 &video_cc_xo_clk_src.clkr.hw,
495 },
496 .num_parents = 1,
497 .flags = CLK_SET_RATE_PARENT,
498 .ops = &clk_branch2_ops,
499 },
500 },
501 };
502
503 static struct gdsc video_cc_mvs0c_gdsc = {
504 .gdscr = 0x814c,
505 .en_rest_wait_val = 0x2,
506 .en_few_wait_val = 0x2,
507 .clk_dis_wait_val = 0x6,
508 .pd = {
509 .name = "video_cc_mvs0c_gdsc",
510 },
511 .pwrsts = PWRSTS_OFF_ON,
512 .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE,
513 };
514
515 static struct gdsc video_cc_mvs0_gdsc = {
516 .gdscr = 0x80a8,
517 .en_rest_wait_val = 0x2,
518 .en_few_wait_val = 0x2,
519 .clk_dis_wait_val = 0x6,
520 .pd = {
521 .name = "video_cc_mvs0_gdsc",
522 },
523 .parent = &video_cc_mvs0c_gdsc.pd,
524 .pwrsts = PWRSTS_OFF_ON,
525 .flags = HW_CTRL_TRIGGER | POLL_CFG_GDSCR | RETAIN_FF_ENABLE,
526 };
527
528 static struct gdsc video_cc_mvs0_vpp0_gdsc = {
529 .gdscr = 0x8120,
530 .en_rest_wait_val = 0x2,
531 .en_few_wait_val = 0x2,
532 .clk_dis_wait_val = 0xf,
533 .pd = {
534 .name = "video_cc_mvs0_vpp0_gdsc",
535 },
536 .pwrsts = PWRSTS_OFF_ON,
537 .flags = HW_CTRL_TRIGGER | POLL_CFG_GDSCR | RETAIN_FF_ENABLE,
538 };
539
540 static struct clk_regmap *video_cc_maili_clocks[] = {
541 [VIDEO_CC_AHB_CLK_SRC] = &video_cc_ahb_clk_src.clkr,
542 [VIDEO_CC_MVS0_CLK] = &video_cc_mvs0_clk.clkr,
543 [VIDEO_CC_MVS0_CLK_SRC] = &video_cc_mvs0_clk_src.clkr,
544 [VIDEO_CC_MVS0_FREERUN_CLK] = &video_cc_mvs0_freerun_clk.branch.clkr,
545 [VIDEO_CC_MVS0_SHIFT_CLK] = &video_cc_mvs0_shift_clk.clkr,
546 [VIDEO_CC_MVS0_VPP0_CLK] = &video_cc_mvs0_vpp0_clk.clkr,
547 [VIDEO_CC_MVS0_VPP0_FREERUN_CLK] = &video_cc_mvs0_vpp0_freerun_clk.clkr,
548 [VIDEO_CC_MVS0B_CLK] = &video_cc_mvs0b_clk.clkr,
549 [VIDEO_CC_MVS0B_CLK_SRC] = &video_cc_mvs0b_clk_src.clkr,
550 [VIDEO_CC_MVS0B_FREERUN_CLK] = &video_cc_mvs0b_freerun_clk.clkr,
551 [VIDEO_CC_MVS0C_CLK] = &video_cc_mvs0c_clk.clkr,
552 [VIDEO_CC_MVS0C_CLK_SRC] = &video_cc_mvs0c_clk_src.clkr,
553 [VIDEO_CC_MVS0C_DEBUG_CLK] = &video_cc_mvs0c_debug_clk.clkr,
554 [VIDEO_CC_MVS0C_FREERUN_CLK] = &video_cc_mvs0c_freerun_clk.clkr,
555 [VIDEO_CC_MVS0C_SHIFT_CLK] = &video_cc_mvs0c_shift_clk.clkr,
556 [VIDEO_CC_PLL0] = &video_cc_pll0.clkr,
557 [VIDEO_CC_PLL1] = &video_cc_pll1.clkr,
558 [VIDEO_CC_PLL2] = &video_cc_pll2.clkr,
559 [VIDEO_CC_XO_CLK_SRC] = &video_cc_xo_clk_src.clkr,
560 };
561
562 static struct gdsc *video_cc_maili_gdscs[] = {
563 [VIDEO_CC_MVS0_GDSC] = &video_cc_mvs0_gdsc,
564 [VIDEO_CC_MVS0_VPP0_GDSC] = &video_cc_mvs0_vpp0_gdsc,
565 [VIDEO_CC_MVS0C_GDSC] = &video_cc_mvs0c_gdsc,
566 };
567
568 static const struct qcom_reset_map video_cc_maili_resets[] = {
569 [VIDEO_CC_INTERFACE_BCR] = { 0x8178 },
570 [VIDEO_CC_MVS0_BCR] = { 0x80a4 },
571 [VIDEO_CC_MVS0_CLK_ARES] = { 0x80d0, 2 },
572 [VIDEO_CC_MVS0_FREERUN_CLK_ARES] = { 0x80e0, 2 },
573 [VIDEO_CC_MVS0_VPP0_BCR] = { 0x811c },
574 [VIDEO_CC_MVS0C_BCR] = { 0x8148 },
575 [VIDEO_CC_MVS0C_CLK_ARES] = { 0x8164, 2 },
576 [VIDEO_CC_MVS0C_FREERUN_CLK_ARES] = { 0x8174, 2 },
577 [VIDEO_CC_XO_CLK_ARES] = { 0x81ac, 2 },
578 };
579
580 static struct clk_alpha_pll *video_cc_maili_plls[] = {
581 &video_cc_pll0,
582 &video_cc_pll1,
583 &video_cc_pll2,
584 };
585
586 static const u32 video_cc_maili_critical_cbcrs[] = {
587 0x817c, /* VIDEO_CC_AHB_CLK */
588 0x81bc, /* VIDEO_CC_SLEEP_CLK */
589 0x81b0, /* VIDEO_CC_TS_XO_CLK */
590 0x81ac, /* VIDEO_CC_XO_CLK */
591 };
592
593 static const struct regmap_config video_cc_maili_regmap_config = {
594 .reg_bits = 32,
595 .reg_stride = 4,
596 .val_bits = 32,
597 .max_register = 0xa010,
598 .fast_io = true,
599 };
600
clk_maili_regs_configure(struct device * dev,struct regmap * regmap)601 static void clk_maili_regs_configure(struct device *dev, struct regmap *regmap)
602 {
603 /*
604 * Enable clk_on sync for MVS0 and VPP clocks as per the
605 * hardware recommendation.
606 */
607 regmap_set_bits(regmap, 0x9f24, BIT(0));
608
609 /*
610 * Update ACCU configuration for MVS0 CFG3, MVS0 VPP0 CFG3,
611 * MVS0C CFG3 GDSCRs as per the hardware recommendation.
612 */
613 regmap_set_bits(regmap, 0x80b4, ACCU_CFG_MASK);
614 regmap_set_bits(regmap, 0x812c, ACCU_CFG_MASK);
615 regmap_set_bits(regmap, 0x8158, ACCU_CFG_MASK);
616 }
617
618 static const struct qcom_cc_driver_data video_cc_maili_driver_data = {
619 .alpha_plls = video_cc_maili_plls,
620 .num_alpha_plls = ARRAY_SIZE(video_cc_maili_plls),
621 .clk_cbcrs = video_cc_maili_critical_cbcrs,
622 .num_clk_cbcrs = ARRAY_SIZE(video_cc_maili_critical_cbcrs),
623 .clk_regs_configure = clk_maili_regs_configure,
624 };
625
626 static const struct qcom_cc_desc video_cc_maili_desc = {
627 .config = &video_cc_maili_regmap_config,
628 .clks = video_cc_maili_clocks,
629 .num_clks = ARRAY_SIZE(video_cc_maili_clocks),
630 .resets = video_cc_maili_resets,
631 .num_resets = ARRAY_SIZE(video_cc_maili_resets),
632 .gdscs = video_cc_maili_gdscs,
633 .num_gdscs = ARRAY_SIZE(video_cc_maili_gdscs),
634 .use_rpm = true,
635 .driver_data = &video_cc_maili_driver_data,
636 };
637
638 static const struct of_device_id video_cc_maili_match_table[] = {
639 { .compatible = "qcom,maili-videocc" },
640 { }
641 };
642 MODULE_DEVICE_TABLE(of, video_cc_maili_match_table);
643
video_cc_maili_probe(struct platform_device * pdev)644 static int video_cc_maili_probe(struct platform_device *pdev)
645 {
646 return qcom_cc_probe(pdev, &video_cc_maili_desc);
647 }
648
649 static struct platform_driver video_cc_maili_driver = {
650 .probe = video_cc_maili_probe,
651 .driver = {
652 .name = "videocc-maili",
653 .of_match_table = video_cc_maili_match_table,
654 },
655 };
656
657 module_platform_driver(video_cc_maili_driver);
658
659 MODULE_DESCRIPTION("QTI VIDEOCC Maili Driver");
660 MODULE_LICENSE("GPL");
661