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,hawi-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 enum {
23 DT_BI_TCXO,
24 DT_AHB_CLK,
25 };
26
27 enum {
28 P_BI_TCXO,
29 P_VIDEO_CC_PLL0_OUT_EVEN,
30 P_VIDEO_CC_PLL0_OUT_MAIN,
31 P_VIDEO_CC_PLL1_OUT_MAIN,
32 P_VIDEO_CC_PLL2_OUT_MAIN,
33 P_VIDEO_CC_PLL3_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 = 0x48,
44 .alpha = 0xc000,
45 .config_ctl_val = 0xa5c400e7,
46 .config_ctl_hi_val = 0x0a8060e0,
47 .config_ctl_hi1_val = 0xf51dea20,
48 .user_ctl_val = 0x00000400,
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 static const struct clk_div_table post_div_table_video_cc_pll0_out_even[] = {
71 { 0x1, 2 },
72 { }
73 };
74
75 static struct clk_alpha_pll_postdiv video_cc_pll0_out_even = {
76 .offset = 0x0,
77 .post_div_shift = 10,
78 .post_div_table = post_div_table_video_cc_pll0_out_even,
79 .num_post_div = ARRAY_SIZE(post_div_table_video_cc_pll0_out_even),
80 .width = 4,
81 .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EHA_T],
82 .clkr.hw.init = &(const struct clk_init_data) {
83 .name = "video_cc_pll0_out_even",
84 .parent_hws = (const struct clk_hw*[]) {
85 &video_cc_pll0.clkr.hw,
86 },
87 .num_parents = 1,
88 .flags = CLK_SET_RATE_PARENT,
89 .ops = &clk_alpha_pll_postdiv_taycan_eha_t_ops,
90 },
91 };
92
93 /* 300.0 MHz Configuration */
94 static const struct alpha_pll_config video_cc_pll1_config = {
95 .l = 0xf,
96 .cal_l = 0x48,
97 .alpha = 0xa000,
98 .config_ctl_val = 0xa5c400e7,
99 .config_ctl_hi_val = 0x0a8060e0,
100 .config_ctl_hi1_val = 0xf51dea20,
101 .user_ctl_val = 0x00000000,
102 .user_ctl_hi_val = 0x00000002,
103 };
104
105 static struct clk_alpha_pll video_cc_pll1 = {
106 .offset = 0x1000,
107 .config = &video_cc_pll1_config,
108 .vco_table = taycan_eha_t_vco,
109 .num_vco = ARRAY_SIZE(taycan_eha_t_vco),
110 .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EHA_T],
111 .clkr = {
112 .hw.init = &(const struct clk_init_data) {
113 .name = "video_cc_pll1",
114 .parent_data = &(const struct clk_parent_data) {
115 .index = DT_BI_TCXO,
116 },
117 .num_parents = 1,
118 .ops = &clk_alpha_pll_taycan_eha_t_ops,
119 },
120 },
121 };
122
123 /* 300.0 MHz Configuration */
124 static const struct alpha_pll_config video_cc_pll2_config = {
125 .l = 0xf,
126 .cal_l = 0x48,
127 .alpha = 0xa000,
128 .config_ctl_val = 0xa5c400e7,
129 .config_ctl_hi_val = 0x0a8060e0,
130 .config_ctl_hi1_val = 0xf51dea20,
131 .user_ctl_val = 0x00000000,
132 .user_ctl_hi_val = 0x00000002,
133 };
134
135 static struct clk_alpha_pll video_cc_pll2 = {
136 .offset = 0x2000,
137 .config = &video_cc_pll2_config,
138 .vco_table = taycan_eha_t_vco,
139 .num_vco = ARRAY_SIZE(taycan_eha_t_vco),
140 .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EHA_T],
141 .clkr = {
142 .hw.init = &(const struct clk_init_data) {
143 .name = "video_cc_pll2",
144 .parent_data = &(const struct clk_parent_data) {
145 .index = DT_BI_TCXO,
146 },
147 .num_parents = 1,
148 .ops = &clk_alpha_pll_taycan_eha_t_ops,
149 },
150 },
151 };
152
153 /* 300.0 MHz Configuration */
154 static const struct alpha_pll_config video_cc_pll3_config = {
155 .l = 0xf,
156 .cal_l = 0x48,
157 .alpha = 0xa000,
158 .config_ctl_val = 0xa5c400e7,
159 .config_ctl_hi_val = 0x0a8060e0,
160 .config_ctl_hi1_val = 0xf51dea20,
161 .user_ctl_val = 0x00000000,
162 .user_ctl_hi_val = 0x00000002,
163 };
164
165 static struct clk_alpha_pll video_cc_pll3 = {
166 .offset = 0x3000,
167 .config = &video_cc_pll3_config,
168 .vco_table = taycan_eha_t_vco,
169 .num_vco = ARRAY_SIZE(taycan_eha_t_vco),
170 .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EHA_T],
171 .clkr = {
172 .hw.init = &(const struct clk_init_data) {
173 .name = "video_cc_pll3",
174 .parent_data = &(const struct clk_parent_data) {
175 .index = DT_BI_TCXO,
176 },
177 .num_parents = 1,
178 .ops = &clk_alpha_pll_taycan_eha_t_ops,
179 },
180 },
181 };
182
183 static const struct parent_map video_cc_parent_map_0[] = {
184 { P_BI_TCXO, 0 },
185 };
186
187 static const struct clk_parent_data video_cc_parent_data_0[] = {
188 { .index = DT_BI_TCXO },
189 };
190
191 static const struct parent_map video_cc_parent_map_1[] = {
192 { P_BI_TCXO, 0 },
193 { P_VIDEO_CC_PLL1_OUT_MAIN, 1 },
194 };
195
196 static const struct clk_parent_data video_cc_parent_data_1[] = {
197 { .index = DT_BI_TCXO },
198 { .hw = &video_cc_pll1.clkr.hw },
199 };
200
201 static const struct parent_map video_cc_parent_map_2[] = {
202 { P_BI_TCXO, 0 },
203 { P_VIDEO_CC_PLL3_OUT_MAIN, 1 },
204 };
205
206 static const struct clk_parent_data video_cc_parent_data_2[] = {
207 { .index = DT_BI_TCXO },
208 { .hw = &video_cc_pll3.clkr.hw },
209 };
210
211 static const struct parent_map video_cc_parent_map_3[] = {
212 { P_BI_TCXO, 0 },
213 { P_VIDEO_CC_PLL2_OUT_MAIN, 1 },
214 };
215
216 static const struct clk_parent_data video_cc_parent_data_3[] = {
217 { .index = DT_BI_TCXO },
218 { .hw = &video_cc_pll2.clkr.hw },
219 };
220
221 static const struct parent_map video_cc_parent_map_4[] = {
222 { P_BI_TCXO, 0 },
223 { P_VIDEO_CC_PLL0_OUT_MAIN, 1 },
224 { P_VIDEO_CC_PLL0_OUT_EVEN, 2 },
225 };
226
227 static const struct clk_parent_data video_cc_parent_data_4[] = {
228 { .index = DT_BI_TCXO },
229 { .hw = &video_cc_pll0.clkr.hw },
230 { .hw = &video_cc_pll0_out_even.clkr.hw },
231 };
232
233 static const struct freq_tbl ftbl_video_cc_ahb_clk_src[] = {
234 F(19200000, P_BI_TCXO, 1, 0, 0),
235 { }
236 };
237
238 static struct clk_rcg2 video_cc_ahb_clk_src = {
239 .cmd_rcgr = 0x8060,
240 .mnd_width = 0,
241 .hid_width = 5,
242 .parent_map = video_cc_parent_map_0,
243 .freq_tbl = ftbl_video_cc_ahb_clk_src,
244 .clkr.hw.init = &(const struct clk_init_data) {
245 .name = "video_cc_ahb_clk_src",
246 .parent_data = video_cc_parent_data_0,
247 .num_parents = ARRAY_SIZE(video_cc_parent_data_0),
248 .flags = CLK_SET_RATE_PARENT,
249 .ops = &clk_rcg2_shared_ops,
250 },
251 };
252
253 static const struct freq_tbl ftbl_video_cc_mvs0_clk_src[] = {
254 F(150000000, P_VIDEO_CC_PLL1_OUT_MAIN, 2, 0, 0),
255 F(240000000, P_VIDEO_CC_PLL1_OUT_MAIN, 2, 0, 0),
256 F(285000000, P_VIDEO_CC_PLL1_OUT_MAIN, 2, 0, 0),
257 F(311000000, P_VIDEO_CC_PLL1_OUT_MAIN, 2, 0, 0),
258 F(420000000, P_VIDEO_CC_PLL1_OUT_MAIN, 2, 0, 0),
259 F(444000000, P_VIDEO_CC_PLL1_OUT_MAIN, 2, 0, 0),
260 F(533000000, P_VIDEO_CC_PLL1_OUT_MAIN, 2, 0, 0),
261 F(630000000, P_VIDEO_CC_PLL1_OUT_MAIN, 2, 0, 0),
262 F(714000000, P_VIDEO_CC_PLL1_OUT_MAIN, 2, 0, 0),
263 { }
264 };
265
266 static struct clk_rcg2 video_cc_mvs0_clk_src = {
267 .cmd_rcgr = 0x8030,
268 .mnd_width = 0,
269 .hid_width = 5,
270 .parent_map = video_cc_parent_map_1,
271 .freq_tbl = ftbl_video_cc_mvs0_clk_src,
272 .hw_clk_ctrl = true,
273 .clkr.hw.init = &(const struct clk_init_data) {
274 .name = "video_cc_mvs0_clk_src",
275 .parent_data = video_cc_parent_data_1,
276 .num_parents = ARRAY_SIZE(video_cc_parent_data_1),
277 .flags = CLK_SET_RATE_PARENT,
278 .ops = &clk_rcg2_shared_ops,
279 },
280 };
281
282 static const struct freq_tbl ftbl_video_cc_mvs0a_clk_src[] = {
283 F(150000000, P_VIDEO_CC_PLL3_OUT_MAIN, 2, 0, 0),
284 F(240000000, P_VIDEO_CC_PLL3_OUT_MAIN, 2, 0, 0),
285 F(338000000, P_VIDEO_CC_PLL3_OUT_MAIN, 2, 0, 0),
286 F(420000000, P_VIDEO_CC_PLL3_OUT_MAIN, 2, 0, 0),
287 F(444000000, P_VIDEO_CC_PLL3_OUT_MAIN, 2, 0, 0),
288 F(533000000, P_VIDEO_CC_PLL3_OUT_MAIN, 2, 0, 0),
289 F(630000000, P_VIDEO_CC_PLL3_OUT_MAIN, 2, 0, 0),
290 F(710000000, P_VIDEO_CC_PLL3_OUT_MAIN, 2, 0, 0),
291 { }
292 };
293
294 static struct clk_rcg2 video_cc_mvs0a_clk_src = {
295 .cmd_rcgr = 0x8000,
296 .mnd_width = 0,
297 .hid_width = 5,
298 .parent_map = video_cc_parent_map_2,
299 .freq_tbl = ftbl_video_cc_mvs0a_clk_src,
300 .hw_clk_ctrl = true,
301 .clkr.hw.init = &(const struct clk_init_data) {
302 .name = "video_cc_mvs0a_clk_src",
303 .parent_data = video_cc_parent_data_2,
304 .num_parents = ARRAY_SIZE(video_cc_parent_data_2),
305 .flags = CLK_SET_RATE_PARENT,
306 .ops = &clk_rcg2_shared_ops,
307 },
308 };
309
310 static const struct freq_tbl ftbl_video_cc_mvs0b_clk_src[] = {
311 F(150000000, P_VIDEO_CC_PLL2_OUT_MAIN, 2, 0, 0),
312 F(240000000, P_VIDEO_CC_PLL2_OUT_MAIN, 2, 0, 0),
313 F(311000000, P_VIDEO_CC_PLL2_OUT_MAIN, 2, 0, 0),
314 F(420000000, P_VIDEO_CC_PLL2_OUT_MAIN, 2, 0, 0),
315 F(444000000, P_VIDEO_CC_PLL2_OUT_MAIN, 2, 0, 0),
316 F(533000000, P_VIDEO_CC_PLL2_OUT_MAIN, 2, 0, 0),
317 F(630000000, P_VIDEO_CC_PLL2_OUT_MAIN, 2, 0, 0),
318 F(667000000, P_VIDEO_CC_PLL2_OUT_MAIN, 2, 0, 0),
319 { }
320 };
321
322 static struct clk_rcg2 video_cc_mvs0b_clk_src = {
323 .cmd_rcgr = 0x8018,
324 .mnd_width = 0,
325 .hid_width = 5,
326 .parent_map = video_cc_parent_map_3,
327 .freq_tbl = ftbl_video_cc_mvs0b_clk_src,
328 .hw_clk_ctrl = true,
329 .clkr.hw.init = &(const struct clk_init_data) {
330 .name = "video_cc_mvs0b_clk_src",
331 .parent_data = video_cc_parent_data_3,
332 .num_parents = ARRAY_SIZE(video_cc_parent_data_3),
333 .flags = CLK_SET_RATE_PARENT,
334 .ops = &clk_rcg2_shared_ops,
335 },
336 };
337
338 static const struct freq_tbl ftbl_video_cc_mvs0c_clk_src[] = {
339 F(225000000, P_VIDEO_CC_PLL0_OUT_EVEN, 1, 0, 0),
340 F(360000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0),
341 F(430000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0),
342 F(557000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0),
343 F(634000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0),
344 F(782000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0),
345 F(928000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0),
346 F(1060000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0),
347 { }
348 };
349
350 static struct clk_rcg2 video_cc_mvs0c_clk_src = {
351 .cmd_rcgr = 0x8048,
352 .mnd_width = 0,
353 .hid_width = 5,
354 .parent_map = video_cc_parent_map_4,
355 .freq_tbl = ftbl_video_cc_mvs0c_clk_src,
356 .hw_clk_ctrl = true,
357 .clkr.hw.init = &(const struct clk_init_data) {
358 .name = "video_cc_mvs0c_clk_src",
359 .parent_data = video_cc_parent_data_4,
360 .num_parents = ARRAY_SIZE(video_cc_parent_data_4),
361 .flags = CLK_SET_RATE_PARENT,
362 .ops = &clk_rcg2_shared_ops,
363 },
364 };
365
366 static struct clk_rcg2 video_cc_xo_clk_src = {
367 .cmd_rcgr = 0x8180,
368 .mnd_width = 0,
369 .hid_width = 5,
370 .parent_map = video_cc_parent_map_0,
371 .freq_tbl = ftbl_video_cc_ahb_clk_src,
372 .hw_clk_ctrl = true,
373 .clkr.hw.init = &(const struct clk_init_data) {
374 .name = "video_cc_xo_clk_src",
375 .parent_data = video_cc_parent_data_0,
376 .num_parents = ARRAY_SIZE(video_cc_parent_data_0),
377 .flags = CLK_SET_RATE_PARENT,
378 .ops = &clk_rcg2_ops,
379 },
380 };
381
382 static struct clk_branch video_cc_cx_axi0_clk = {
383 .halt_reg = 0x81e8,
384 .halt_check = BRANCH_HALT_VOTED,
385 .hwcg_reg = 0x81e8,
386 .hwcg_bit = 1,
387 .clkr = {
388 .enable_reg = 0x81e8,
389 .enable_mask = BIT(0),
390 .hw.init = &(const struct clk_init_data) {
391 .name = "video_cc_cx_axi0_clk",
392 .ops = &clk_branch2_ops,
393 },
394 },
395 };
396
397 static struct clk_branch video_cc_mvs0_clk = {
398 .halt_reg = 0x80cc,
399 .halt_check = BRANCH_HALT_VOTED,
400 .hwcg_reg = 0x80cc,
401 .hwcg_bit = 1,
402 .clkr = {
403 .enable_reg = 0x80cc,
404 .enable_mask = BIT(0),
405 .hw.init = &(const struct clk_init_data) {
406 .name = "video_cc_mvs0_clk",
407 .parent_hws = (const struct clk_hw*[]) {
408 &video_cc_mvs0_clk_src.clkr.hw,
409 },
410 .num_parents = 1,
411 .flags = CLK_SET_RATE_PARENT,
412 .ops = &clk_branch2_aon_ops,
413 },
414 },
415 };
416
417 static struct clk_branch video_cc_mvs0_shift_clk = {
418 .halt_reg = 0x81a4,
419 .halt_check = BRANCH_HALT_VOTED,
420 .hwcg_reg = 0x81a4,
421 .hwcg_bit = 1,
422 .clkr = {
423 .enable_reg = 0x81a4,
424 .enable_mask = BIT(0),
425 .hw.init = &(const struct clk_init_data) {
426 .name = "video_cc_mvs0_shift_clk",
427 .parent_hws = (const struct clk_hw*[]) {
428 &video_cc_xo_clk_src.clkr.hw,
429 },
430 .num_parents = 1,
431 .flags = CLK_SET_RATE_PARENT,
432 .ops = &clk_branch2_ops,
433 },
434 },
435 };
436
437 static struct clk_branch video_cc_mvs0_vpp0_clk = {
438 .halt_reg = 0x811c,
439 .halt_check = BRANCH_HALT_VOTED,
440 .hwcg_reg = 0x811c,
441 .hwcg_bit = 1,
442 .clkr = {
443 .enable_reg = 0x811c,
444 .enable_mask = BIT(0),
445 .hw.init = &(const struct clk_init_data) {
446 .name = "video_cc_mvs0_vpp0_clk",
447 .parent_hws = (const struct clk_hw*[]) {
448 &video_cc_mvs0_clk_src.clkr.hw,
449 },
450 .num_parents = 1,
451 .flags = CLK_SET_RATE_PARENT,
452 .ops = &clk_branch2_aon_ops,
453 },
454 },
455 };
456
457 static struct clk_branch video_cc_mvs0_vpp0_vpp1_gating_clk = {
458 .halt_reg = 0x80c8,
459 .halt_check = BRANCH_HALT_VOTED,
460 .hwcg_reg = 0x80c8,
461 .hwcg_bit = 1,
462 .clkr = {
463 .enable_reg = 0x80c8,
464 .enable_mask = BIT(0),
465 .hw.init = &(const struct clk_init_data) {
466 .name = "video_cc_mvs0_vpp0_vpp1_gating_clk",
467 .parent_hws = (const struct clk_hw*[]) {
468 &video_cc_mvs0_clk_src.clkr.hw,
469 },
470 .num_parents = 1,
471 .flags = CLK_SET_RATE_PARENT,
472 .ops = &clk_branch2_ops,
473 },
474 },
475 };
476
477 static struct clk_branch video_cc_mvs0_vpp1_clk = {
478 .halt_reg = 0x80f4,
479 .halt_check = BRANCH_HALT_VOTED,
480 .hwcg_reg = 0x80f4,
481 .hwcg_bit = 1,
482 .clkr = {
483 .enable_reg = 0x80f4,
484 .enable_mask = BIT(0),
485 .hw.init = &(const struct clk_init_data) {
486 .name = "video_cc_mvs0_vpp1_clk",
487 .parent_hws = (const struct clk_hw*[]) {
488 &video_cc_mvs0_clk_src.clkr.hw,
489 },
490 .num_parents = 1,
491 .flags = CLK_SET_RATE_PARENT,
492 .ops = &clk_branch2_aon_ops,
493 },
494 },
495 };
496
497 static struct clk_branch video_cc_mvs0a_clk = {
498 .halt_reg = 0x8090,
499 .halt_check = BRANCH_HALT_VOTED,
500 .hwcg_reg = 0x8090,
501 .hwcg_bit = 1,
502 .clkr = {
503 .enable_reg = 0x8090,
504 .enable_mask = BIT(0),
505 .hw.init = &(const struct clk_init_data) {
506 .name = "video_cc_mvs0a_clk",
507 .parent_hws = (const struct clk_hw*[]) {
508 &video_cc_mvs0a_clk_src.clkr.hw,
509 },
510 .num_parents = 1,
511 .flags = CLK_SET_RATE_PARENT,
512 .ops = &clk_branch2_ops,
513 },
514 },
515 };
516
517 static struct clk_branch video_cc_mvs0b_clk = {
518 .halt_reg = 0x80b8,
519 .halt_check = BRANCH_HALT_VOTED,
520 .hwcg_reg = 0x80b8,
521 .hwcg_bit = 1,
522 .clkr = {
523 .enable_reg = 0x80b8,
524 .enable_mask = BIT(0),
525 .hw.init = &(const struct clk_init_data) {
526 .name = "video_cc_mvs0b_clk",
527 .parent_hws = (const struct clk_hw*[]) {
528 &video_cc_mvs0b_clk_src.clkr.hw,
529 },
530 .num_parents = 1,
531 .flags = CLK_SET_RATE_PARENT,
532 .ops = &clk_branch2_ops,
533 },
534 },
535 };
536
537 static struct clk_branch video_cc_mvs0c_clk = {
538 .halt_reg = 0x814c,
539 .halt_check = BRANCH_HALT_VOTED,
540 .hwcg_reg = 0x814c,
541 .hwcg_bit = 1,
542 .clkr = {
543 .enable_reg = 0x814c,
544 .enable_mask = BIT(0),
545 .hw.init = &(const struct clk_init_data) {
546 .name = "video_cc_mvs0c_clk",
547 .parent_hws = (const struct clk_hw*[]) {
548 &video_cc_mvs0c_clk_src.clkr.hw,
549 },
550 .num_parents = 1,
551 .flags = CLK_SET_RATE_PARENT,
552 .ops = &clk_branch2_ops,
553 },
554 },
555 };
556
557 static struct clk_branch video_cc_mvs0c_ctl_freerun_clk = {
558 .halt_reg = 0x8160,
559 .halt_check = BRANCH_HALT,
560 .clkr = {
561 .enable_reg = 0x8160,
562 .enable_mask = BIT(0),
563 .hw.init = &(const struct clk_init_data) {
564 .name = "video_cc_mvs0c_ctl_freerun_clk",
565 .parent_hws = (const struct clk_hw*[]) {
566 &video_cc_mvs0c_clk_src.clkr.hw,
567 },
568 .num_parents = 1,
569 .flags = CLK_SET_RATE_PARENT,
570 .ops = &clk_branch2_ops,
571 },
572 },
573 };
574
575 static struct clk_branch video_cc_mvs0c_debug_clk = {
576 .halt_reg = 0x8148,
577 .halt_check = BRANCH_HALT,
578 .clkr = {
579 .enable_reg = 0x8148,
580 .enable_mask = BIT(0),
581 .hw.init = &(const struct clk_init_data) {
582 .name = "video_cc_mvs0c_debug_clk",
583 .parent_hws = (const struct clk_hw*[]) {
584 &video_cc_mvs0c_clk_src.clkr.hw,
585 },
586 .num_parents = 1,
587 .flags = CLK_SET_RATE_PARENT,
588 .ops = &clk_branch2_ops,
589 },
590 },
591 };
592
593 static struct clk_branch video_cc_mvs0c_freerun_clk = {
594 .halt_reg = 0x815c,
595 .halt_check = BRANCH_HALT,
596 .clkr = {
597 .enable_reg = 0x815c,
598 .enable_mask = BIT(0),
599 .hw.init = &(const struct clk_init_data) {
600 .name = "video_cc_mvs0c_freerun_clk",
601 .parent_hws = (const struct clk_hw*[]) {
602 &video_cc_mvs0c_clk_src.clkr.hw,
603 },
604 .num_parents = 1,
605 .flags = CLK_SET_RATE_PARENT,
606 .ops = &clk_branch2_ops,
607 },
608 },
609 };
610
611 static struct clk_branch video_cc_mvs0c_shift_clk = {
612 .halt_reg = 0x81a8,
613 .halt_check = BRANCH_HALT_VOTED,
614 .hwcg_reg = 0x81a8,
615 .hwcg_bit = 1,
616 .clkr = {
617 .enable_reg = 0x81a8,
618 .enable_mask = BIT(0),
619 .hw.init = &(const struct clk_init_data) {
620 .name = "video_cc_mvs0c_shift_clk",
621 .parent_hws = (const struct clk_hw*[]) {
622 &video_cc_xo_clk_src.clkr.hw,
623 },
624 .num_parents = 1,
625 .flags = CLK_SET_RATE_PARENT,
626 .ops = &clk_branch2_ops,
627 },
628 },
629 };
630
631 static struct gdsc video_cc_mvs0c_gdsc = {
632 .gdscr = 0x8130,
633 .en_rest_wait_val = 0x2,
634 .en_few_wait_val = 0x2,
635 .clk_dis_wait_val = 0x6,
636 .pd = {
637 .name = "video_cc_mvs0c_gdsc",
638 },
639 .pwrsts = PWRSTS_OFF_ON,
640 .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE,
641 };
642
643 static struct gdsc video_cc_axi0_cx_int_gdsc = {
644 .gdscr = 0x81cc,
645 .en_rest_wait_val = 0x2,
646 .en_few_wait_val = 0x2,
647 .clk_dis_wait_val = 0xf,
648 .pd = {
649 .name = "video_cc_axi0_cx_int_gdsc",
650 },
651 .pwrsts = PWRSTS_OFF_ON,
652 .parent = &video_cc_mvs0c_gdsc.pd,
653 .flags = HW_CTRL_TRIGGER | POLL_CFG_GDSCR | RETAIN_FF_ENABLE,
654 };
655
656 static struct gdsc video_cc_mm_int_gdsc = {
657 .gdscr = 0x81b4,
658 .en_rest_wait_val = 0x2,
659 .en_few_wait_val = 0x2,
660 .clk_dis_wait_val = 0x2,
661 .pd = {
662 .name = "video_cc_mm_int_gdsc",
663 },
664 .pwrsts = PWRSTS_OFF_ON,
665 .parent = &video_cc_axi0_cx_int_gdsc.pd,
666 .flags = HW_CTRL_TRIGGER | POLL_CFG_GDSCR | RETAIN_FF_ENABLE,
667 };
668
669 static struct gdsc video_cc_mvs0_gdsc = {
670 .gdscr = 0x80a4,
671 .en_rest_wait_val = 0x2,
672 .en_few_wait_val = 0x2,
673 .clk_dis_wait_val = 0x6,
674 .pd = {
675 .name = "video_cc_mvs0_gdsc",
676 },
677 .pwrsts = PWRSTS_OFF_ON,
678 .parent = &video_cc_mm_int_gdsc.pd,
679 .flags = HW_CTRL_TRIGGER | POLL_CFG_GDSCR | RETAIN_FF_ENABLE,
680 };
681
682 static struct gdsc video_cc_mvs0_vpp0_gdsc = {
683 .gdscr = 0x8108,
684 .en_rest_wait_val = 0x2,
685 .en_few_wait_val = 0x2,
686 .clk_dis_wait_val = 0xf,
687 .pd = {
688 .name = "video_cc_mvs0_vpp0_gdsc",
689 },
690 .pwrsts = PWRSTS_OFF_ON,
691 .parent = &video_cc_mvs0_gdsc.pd,
692 .flags = HW_CTRL_TRIGGER | POLL_CFG_GDSCR | RETAIN_FF_ENABLE,
693 };
694
695 static struct gdsc video_cc_mvs0_vpp1_gdsc = {
696 .gdscr = 0x80e0,
697 .en_rest_wait_val = 0x2,
698 .en_few_wait_val = 0x2,
699 .clk_dis_wait_val = 0xf,
700 .pd = {
701 .name = "video_cc_mvs0_vpp1_gdsc",
702 },
703 .pwrsts = PWRSTS_OFF_ON,
704 .parent = &video_cc_mvs0_gdsc.pd,
705 .flags = HW_CTRL_TRIGGER | POLL_CFG_GDSCR | RETAIN_FF_ENABLE,
706 };
707
708 static struct gdsc video_cc_mvs0a_gdsc = {
709 .gdscr = 0x807c,
710 .en_rest_wait_val = 0x2,
711 .en_few_wait_val = 0x2,
712 .clk_dis_wait_val = 0xf,
713 .pd = {
714 .name = "video_cc_mvs0a_gdsc",
715 },
716 .pwrsts = PWRSTS_OFF_ON,
717 .parent = &video_cc_mm_int_gdsc.pd,
718 .flags = HW_CTRL_TRIGGER | POLL_CFG_GDSCR | RETAIN_FF_ENABLE,
719 };
720
721 static struct clk_regmap *video_cc_hawi_clocks[] = {
722 [VIDEO_CC_AHB_CLK_SRC] = &video_cc_ahb_clk_src.clkr,
723 [VIDEO_CC_CX_AXI0_CLK] = &video_cc_cx_axi0_clk.clkr,
724 [VIDEO_CC_MVS0_CLK] = &video_cc_mvs0_clk.clkr,
725 [VIDEO_CC_MVS0_CLK_SRC] = &video_cc_mvs0_clk_src.clkr,
726 [VIDEO_CC_MVS0_SHIFT_CLK] = &video_cc_mvs0_shift_clk.clkr,
727 [VIDEO_CC_MVS0_VPP0_CLK] = &video_cc_mvs0_vpp0_clk.clkr,
728 [VIDEO_CC_MVS0_VPP0_VPP1_GATING_CLK] = &video_cc_mvs0_vpp0_vpp1_gating_clk.clkr,
729 [VIDEO_CC_MVS0_VPP1_CLK] = &video_cc_mvs0_vpp1_clk.clkr,
730 [VIDEO_CC_MVS0A_CLK] = &video_cc_mvs0a_clk.clkr,
731 [VIDEO_CC_MVS0A_CLK_SRC] = &video_cc_mvs0a_clk_src.clkr,
732 [VIDEO_CC_MVS0B_CLK] = &video_cc_mvs0b_clk.clkr,
733 [VIDEO_CC_MVS0B_CLK_SRC] = &video_cc_mvs0b_clk_src.clkr,
734 [VIDEO_CC_MVS0C_CLK] = &video_cc_mvs0c_clk.clkr,
735 [VIDEO_CC_MVS0C_CLK_SRC] = &video_cc_mvs0c_clk_src.clkr,
736 [VIDEO_CC_MVS0C_CTL_FREERUN_CLK] = &video_cc_mvs0c_ctl_freerun_clk.clkr,
737 [VIDEO_CC_MVS0C_DEBUG_CLK] = &video_cc_mvs0c_debug_clk.clkr,
738 [VIDEO_CC_MVS0C_FREERUN_CLK] = &video_cc_mvs0c_freerun_clk.clkr,
739 [VIDEO_CC_MVS0C_SHIFT_CLK] = &video_cc_mvs0c_shift_clk.clkr,
740 [VIDEO_CC_PLL0] = &video_cc_pll0.clkr,
741 [VIDEO_CC_PLL0_OUT_EVEN] = &video_cc_pll0_out_even.clkr,
742 [VIDEO_CC_PLL1] = &video_cc_pll1.clkr,
743 [VIDEO_CC_PLL2] = &video_cc_pll2.clkr,
744 [VIDEO_CC_PLL3] = &video_cc_pll3.clkr,
745 [VIDEO_CC_XO_CLK_SRC] = &video_cc_xo_clk_src.clkr,
746 };
747
748 static struct gdsc *video_cc_hawi_gdscs[] = {
749 [VIDEO_CC_AXI0_CX_INT_GDSC] = &video_cc_axi0_cx_int_gdsc,
750 [VIDEO_CC_MM_INT_GDSC] = &video_cc_mm_int_gdsc,
751 [VIDEO_CC_MVS0_GDSC] = &video_cc_mvs0_gdsc,
752 [VIDEO_CC_MVS0_VPP0_GDSC] = &video_cc_mvs0_vpp0_gdsc,
753 [VIDEO_CC_MVS0_VPP1_GDSC] = &video_cc_mvs0_vpp1_gdsc,
754 [VIDEO_CC_MVS0A_GDSC] = &video_cc_mvs0a_gdsc,
755 [VIDEO_CC_MVS0C_GDSC] = &video_cc_mvs0c_gdsc,
756 };
757
758 static const struct qcom_reset_map video_cc_hawi_resets[] = {
759 [VIDEO_CC_AXI0_CX_INT_BCR] = { 0x81c8 },
760 [VIDEO_CC_INTERFACE_BCR] = { 0x8164 },
761 [VIDEO_CC_MM_INT_BCR] = { 0x81b0 },
762 [VIDEO_CC_MVS0_BCR] = { 0x80a0 },
763 [VIDEO_CC_MVS0_VPP0_BCR] = { 0x8104 },
764 [VIDEO_CC_MVS0_VPP1_BCR] = { 0x80dc },
765 [VIDEO_CC_MVS0A_BCR] = { 0x8078 },
766 [VIDEO_CC_MVS0C_CLK_ARES] = { 0x814c, 2 },
767 [VIDEO_CC_MVS0C_BCR] = { 0x812c },
768 [VIDEO_CC_MVS0C_CTL_FREERUN_CLK_ARES] = { 0x8160, 2 },
769 [VIDEO_CC_MVS0C_FREERUN_CLK_ARES] = { 0x815c, 2 },
770 [VIDEO_CC_XO_CLK_ARES] = { 0x8198, 2 },
771 };
772
773 static struct clk_alpha_pll *video_cc_hawi_plls[] = {
774 &video_cc_pll0,
775 &video_cc_pll1,
776 &video_cc_pll2,
777 &video_cc_pll3,
778 };
779
780 static const u32 video_cc_hawi_critical_cbcrs[] = {
781 0x8168, /* VIDEO_CC_AHB_CLK */
782 0x81e4, /* VIDEO_CC_CX_DBGCH_XO_CLK */
783 0x81e0, /* VIDEO_CC_CX_XO_CLK */
784 0x81a0, /* VIDEO_CC_DBGCH_XO_CLK */
785 0x81ac, /* VIDEO_CC_SLEEP_CLK */
786 0x819c, /* VIDEO_CC_TS_XO_CLK */
787 0x8198, /* VIDEO_CC_XO_CLK */
788 };
789
790 static const struct regmap_config video_cc_hawi_regmap_config = {
791 .reg_bits = 32,
792 .reg_stride = 4,
793 .val_bits = 32,
794 .max_register = 0xa018,
795 .fast_io = true,
796 };
797
798 static struct qcom_cc_driver_data video_cc_hawi_driver_data = {
799 .alpha_plls = video_cc_hawi_plls,
800 .num_alpha_plls = ARRAY_SIZE(video_cc_hawi_plls),
801 .clk_cbcrs = video_cc_hawi_critical_cbcrs,
802 .num_clk_cbcrs = ARRAY_SIZE(video_cc_hawi_critical_cbcrs),
803 };
804
805 static const struct qcom_cc_desc video_cc_hawi_desc = {
806 .config = &video_cc_hawi_regmap_config,
807 .clks = video_cc_hawi_clocks,
808 .num_clks = ARRAY_SIZE(video_cc_hawi_clocks),
809 .resets = video_cc_hawi_resets,
810 .num_resets = ARRAY_SIZE(video_cc_hawi_resets),
811 .gdscs = video_cc_hawi_gdscs,
812 .num_gdscs = ARRAY_SIZE(video_cc_hawi_gdscs),
813 .use_rpm = true,
814 .driver_data = &video_cc_hawi_driver_data,
815 };
816
817 static const struct of_device_id video_cc_hawi_match_table[] = {
818 { .compatible = "qcom,hawi-videocc" },
819 { }
820 };
821 MODULE_DEVICE_TABLE(of, video_cc_hawi_match_table);
822
video_cc_hawi_probe(struct platform_device * pdev)823 static int video_cc_hawi_probe(struct platform_device *pdev)
824 {
825 return qcom_cc_probe(pdev, &video_cc_hawi_desc);
826 }
827
828 static struct platform_driver video_cc_hawi_driver = {
829 .probe = video_cc_hawi_probe,
830 .driver = {
831 .name = "videocc-hawi",
832 .of_match_table = video_cc_hawi_match_table,
833 },
834 };
835
836 module_platform_driver(video_cc_hawi_driver);
837
838 MODULE_DESCRIPTION("QTI VIDEOCC Hawi Driver");
839 MODULE_LICENSE("GPL");
840