xref: /linux/drivers/clk/qcom/videocc-sm8550.c (revision 59cb902371227c2cd7932a565eda97ac7e4707bf)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (c) 2023-2024, Qualcomm Innovation Center, Inc. All rights reserved.
4  */
5 
6 #include <linux/clk-provider.h>
7 #include <linux/mod_devicetable.h>
8 #include <linux/module.h>
9 #include <linux/platform_device.h>
10 #include <linux/regmap.h>
11 
12 #include <dt-bindings/clock/qcom,sm8650-videocc.h>
13 
14 #include "clk-alpha-pll.h"
15 #include "clk-branch.h"
16 #include "clk-rcg.h"
17 #include "clk-regmap.h"
18 #include "clk-regmap-divider.h"
19 #include "common.h"
20 #include "gdsc.h"
21 #include "reset.h"
22 
23 enum {
24 	DT_BI_TCXO,
25 };
26 
27 enum {
28 	P_BI_TCXO,
29 	P_VIDEO_CC_PLL0_OUT_MAIN,
30 	P_VIDEO_CC_PLL1_OUT_MAIN,
31 };
32 
33 static const struct pll_vco lucid_ole_vco[] = {
34 	{ 249600000, 2300000000, 0 },
35 };
36 
37 static struct alpha_pll_config video_cc_pll0_config = {
38 	.l = 0x25,
39 	.alpha = 0x8000,
40 	.config_ctl_val = 0x20485699,
41 	.config_ctl_hi_val = 0x00182261,
42 	.config_ctl_hi1_val = 0x82aa299c,
43 	.test_ctl_val = 0x00000000,
44 	.test_ctl_hi_val = 0x00000003,
45 	.test_ctl_hi1_val = 0x00009000,
46 	.test_ctl_hi2_val = 0x00000034,
47 	.user_ctl_val = 0x00000000,
48 	.user_ctl_hi_val = 0x00000005,
49 };
50 
51 static struct clk_alpha_pll video_cc_pll0 = {
52 	.offset = 0x0,
53 	.config = &video_cc_pll0_config,
54 	.vco_table = lucid_ole_vco,
55 	.num_vco = ARRAY_SIZE(lucid_ole_vco),
56 	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE],
57 	.clkr = {
58 		.hw.init = &(const struct clk_init_data) {
59 			.name = "video_cc_pll0",
60 			.parent_data = &(const struct clk_parent_data) {
61 				.index = DT_BI_TCXO,
62 			},
63 			.num_parents = 1,
64 			.ops = &clk_alpha_pll_lucid_evo_ops,
65 		},
66 	},
67 };
68 
69 static struct alpha_pll_config video_cc_pll1_config = {
70 	.l = 0x36,
71 	.alpha = 0xb000,
72 	.config_ctl_val = 0x20485699,
73 	.config_ctl_hi_val = 0x00182261,
74 	.config_ctl_hi1_val = 0x82aa299c,
75 	.test_ctl_val = 0x00000000,
76 	.test_ctl_hi_val = 0x00000003,
77 	.test_ctl_hi1_val = 0x00009000,
78 	.test_ctl_hi2_val = 0x00000034,
79 	.user_ctl_val = 0x00000000,
80 	.user_ctl_hi_val = 0x00000005,
81 };
82 
83 static struct clk_alpha_pll video_cc_pll1 = {
84 	.offset = 0x1000,
85 	.config = &video_cc_pll1_config,
86 	.vco_table = lucid_ole_vco,
87 	.num_vco = ARRAY_SIZE(lucid_ole_vco),
88 	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE],
89 	.clkr = {
90 		.hw.init = &(const struct clk_init_data) {
91 			.name = "video_cc_pll1",
92 			.parent_data = &(const struct clk_parent_data) {
93 				.index = DT_BI_TCXO,
94 			},
95 			.num_parents = 1,
96 			.ops = &clk_alpha_pll_lucid_evo_ops,
97 		},
98 	},
99 };
100 
101 static const struct parent_map video_cc_parent_map_0[] = {
102 	{ P_BI_TCXO, 0 },
103 	{ P_VIDEO_CC_PLL0_OUT_MAIN, 1 },
104 };
105 
106 static const struct clk_parent_data video_cc_parent_data_0[] = {
107 	{ .index = DT_BI_TCXO },
108 	{ .hw = &video_cc_pll0.clkr.hw },
109 };
110 
111 static const struct parent_map video_cc_parent_map_1[] = {
112 	{ P_BI_TCXO, 0 },
113 	{ P_VIDEO_CC_PLL1_OUT_MAIN, 1 },
114 };
115 
116 static const struct clk_parent_data video_cc_parent_data_1[] = {
117 	{ .index = DT_BI_TCXO },
118 	{ .hw = &video_cc_pll1.clkr.hw },
119 };
120 
121 static const struct parent_map video_cc_parent_map_2[] = {
122 	{ P_BI_TCXO, 0 },
123 };
124 
125 static const struct clk_parent_data video_cc_parent_data_2[] = {
126 	{ .index = DT_BI_TCXO },
127 };
128 
129 static const struct freq_tbl ftbl_video_cc_mvs0_clk_src[] = {
130 	F(720000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0),
131 	F(1014000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0),
132 	F(1098000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0),
133 	F(1332000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0),
134 	F(1600000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0),
135 	{ }
136 };
137 
138 static const struct freq_tbl ftbl_video_cc_mvs0_clk_src_sm8650[] = {
139 	F(588000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0),
140 	F(900000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0),
141 	F(1140000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0),
142 	F(1305000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0),
143 	F(1440000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0),
144 	F(1600000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0),
145 	{ }
146 };
147 
148 static const struct freq_tbl ftbl_video_cc_mvs0_clk_src_x1e80100[] = {
149 	F(576000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0),
150 	F(720000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0),
151 	F(1014000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0),
152 	F(1098000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0),
153 	F(1332000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0),
154 	F(1443000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0),
155 	{ }
156 };
157 
158 static struct clk_rcg2 video_cc_mvs0_clk_src = {
159 	.cmd_rcgr = 0x8000,
160 	.mnd_width = 0,
161 	.hid_width = 5,
162 	.parent_map = video_cc_parent_map_0,
163 	.freq_tbl = ftbl_video_cc_mvs0_clk_src,
164 	.clkr.hw.init = &(const struct clk_init_data) {
165 		.name = "video_cc_mvs0_clk_src",
166 		.parent_data = video_cc_parent_data_0,
167 		.num_parents = ARRAY_SIZE(video_cc_parent_data_0),
168 		.flags = CLK_SET_RATE_PARENT,
169 		.ops = &clk_rcg2_shared_ops,
170 	},
171 };
172 
173 static const struct freq_tbl ftbl_video_cc_mvs1_clk_src[] = {
174 	F(1050000000, P_VIDEO_CC_PLL1_OUT_MAIN, 1, 0, 0),
175 	F(1350000000, P_VIDEO_CC_PLL1_OUT_MAIN, 1, 0, 0),
176 	F(1500000000, P_VIDEO_CC_PLL1_OUT_MAIN, 1, 0, 0),
177 	F(1650000000, P_VIDEO_CC_PLL1_OUT_MAIN, 1, 0, 0),
178 	{ }
179 };
180 
181 static const struct freq_tbl ftbl_video_cc_mvs1_clk_src_sm8650[] = {
182 	F(840000000, P_VIDEO_CC_PLL1_OUT_MAIN, 1, 0, 0),
183 	F(1110000000, P_VIDEO_CC_PLL1_OUT_MAIN, 1, 0, 0),
184 	F(1350000000, P_VIDEO_CC_PLL1_OUT_MAIN, 1, 0, 0),
185 	F(1500000000, P_VIDEO_CC_PLL1_OUT_MAIN, 1, 0, 0),
186 	F(1650000000, P_VIDEO_CC_PLL1_OUT_MAIN, 1, 0, 0),
187 	{ }
188 };
189 
190 static const struct freq_tbl ftbl_video_cc_mvs1_clk_src_x1e80100[] = {
191 	F(840000000, P_VIDEO_CC_PLL1_OUT_MAIN, 1, 0, 0),
192 	F(1050000000, P_VIDEO_CC_PLL1_OUT_MAIN, 1, 0, 0),
193 	F(1350000000, P_VIDEO_CC_PLL1_OUT_MAIN, 1, 0, 0),
194 	F(1500000000, P_VIDEO_CC_PLL1_OUT_MAIN, 1, 0, 0),
195 	F(1650000000, P_VIDEO_CC_PLL1_OUT_MAIN, 1, 0, 0),
196 	{ }
197 };
198 
199 static struct clk_rcg2 video_cc_mvs1_clk_src = {
200 	.cmd_rcgr = 0x8018,
201 	.mnd_width = 0,
202 	.hid_width = 5,
203 	.parent_map = video_cc_parent_map_1,
204 	.freq_tbl = ftbl_video_cc_mvs1_clk_src,
205 	.clkr.hw.init = &(const struct clk_init_data) {
206 		.name = "video_cc_mvs1_clk_src",
207 		.parent_data = video_cc_parent_data_1,
208 		.num_parents = ARRAY_SIZE(video_cc_parent_data_1),
209 		.flags = CLK_SET_RATE_PARENT,
210 		.ops = &clk_rcg2_shared_ops,
211 	},
212 };
213 
214 static const struct freq_tbl ftbl_video_cc_xo_clk_src[] = {
215 	F(19200000, P_BI_TCXO, 1, 0, 0),
216 	{ }
217 };
218 
219 static struct clk_rcg2 video_cc_xo_clk_src = {
220 	.cmd_rcgr = 0x810c,
221 	.mnd_width = 0,
222 	.hid_width = 5,
223 	.parent_map = video_cc_parent_map_2,
224 	.freq_tbl = ftbl_video_cc_xo_clk_src,
225 	.clkr.hw.init = &(const struct clk_init_data) {
226 		.name = "video_cc_xo_clk_src",
227 		.parent_data = video_cc_parent_data_2,
228 		.num_parents = ARRAY_SIZE(video_cc_parent_data_2),
229 		.flags = CLK_SET_RATE_PARENT,
230 		.ops = &clk_rcg2_shared_ops,
231 	},
232 };
233 
234 static struct clk_regmap_div video_cc_mvs0_div_clk_src = {
235 	.reg = 0x80c4,
236 	.shift = 0,
237 	.width = 4,
238 	.clkr.hw.init = &(const struct clk_init_data) {
239 		.name = "video_cc_mvs0_div_clk_src",
240 		.parent_hws = (const struct clk_hw*[]) {
241 			&video_cc_mvs0_clk_src.clkr.hw,
242 		},
243 		.num_parents = 1,
244 		.flags = CLK_SET_RATE_PARENT,
245 		.ops = &clk_regmap_div_ro_ops,
246 	},
247 };
248 
249 static struct clk_regmap_div video_cc_mvs0c_div2_div_clk_src = {
250 	.reg = 0x8070,
251 	.shift = 0,
252 	.width = 4,
253 	.clkr.hw.init = &(const struct clk_init_data) {
254 		.name = "video_cc_mvs0c_div2_div_clk_src",
255 		.parent_hws = (const struct clk_hw*[]) {
256 			&video_cc_mvs0_clk_src.clkr.hw,
257 		},
258 		.num_parents = 1,
259 		.flags = CLK_SET_RATE_PARENT,
260 		.ops = &clk_regmap_div_ro_ops,
261 	},
262 };
263 
264 static struct clk_regmap_div video_cc_mvs1_div_clk_src = {
265 	.reg = 0x80ec,
266 	.shift = 0,
267 	.width = 4,
268 	.clkr.hw.init = &(const struct clk_init_data) {
269 		.name = "video_cc_mvs1_div_clk_src",
270 		.parent_hws = (const struct clk_hw*[]) {
271 			&video_cc_mvs1_clk_src.clkr.hw,
272 		},
273 		.num_parents = 1,
274 		.flags = CLK_SET_RATE_PARENT,
275 		.ops = &clk_regmap_div_ro_ops,
276 	},
277 };
278 
279 static struct clk_regmap_div video_cc_mvs1c_div2_div_clk_src = {
280 	.reg = 0x809c,
281 	.shift = 0,
282 	.width = 4,
283 	.clkr.hw.init = &(const struct clk_init_data) {
284 		.name = "video_cc_mvs1c_div2_div_clk_src",
285 		.parent_hws = (const struct clk_hw*[]) {
286 			&video_cc_mvs1_clk_src.clkr.hw,
287 		},
288 		.num_parents = 1,
289 		.flags = CLK_SET_RATE_PARENT,
290 		.ops = &clk_regmap_div_ro_ops,
291 	},
292 };
293 
294 static struct clk_branch video_cc_mvs0_clk = {
295 	.halt_reg = 0x80b8,
296 	.halt_check = BRANCH_HALT_SKIP,
297 	.hwcg_reg = 0x80b8,
298 	.hwcg_bit = 1,
299 	.clkr = {
300 		.enable_reg = 0x80b8,
301 		.enable_mask = BIT(0),
302 		.hw.init = &(const struct clk_init_data) {
303 			.name = "video_cc_mvs0_clk",
304 			.parent_hws = (const struct clk_hw*[]) {
305 				&video_cc_mvs0_div_clk_src.clkr.hw,
306 			},
307 			.num_parents = 1,
308 			.flags = CLK_SET_RATE_PARENT,
309 			.ops = &clk_branch2_ops,
310 		},
311 	},
312 };
313 
314 static struct clk_branch video_cc_mvs0_shift_clk = {
315 	.halt_reg = 0x8128,
316 	.halt_check = BRANCH_HALT_VOTED,
317 	.hwcg_reg = 0x8128,
318 	.hwcg_bit = 1,
319 	.clkr = {
320 		.enable_reg = 0x8128,
321 		.enable_mask = BIT(0),
322 		.hw.init = &(const struct clk_init_data) {
323 			.name = "video_cc_mvs0_shift_clk",
324 			.parent_hws = (const struct clk_hw*[]) {
325 				&video_cc_xo_clk_src.clkr.hw,
326 			},
327 			.num_parents = 1,
328 			.flags = CLK_SET_RATE_PARENT,
329 			.ops = &clk_branch2_ops,
330 		},
331 	},
332 };
333 
334 static struct clk_branch video_cc_mvs0c_clk = {
335 	.halt_reg = 0x8064,
336 	.halt_check = BRANCH_HALT,
337 	.clkr = {
338 		.enable_reg = 0x8064,
339 		.enable_mask = BIT(0),
340 		.hw.init = &(const struct clk_init_data) {
341 			.name = "video_cc_mvs0c_clk",
342 			.parent_hws = (const struct clk_hw*[]) {
343 				&video_cc_mvs0c_div2_div_clk_src.clkr.hw,
344 			},
345 			.num_parents = 1,
346 			.flags = CLK_SET_RATE_PARENT,
347 			.ops = &clk_branch2_ops,
348 		},
349 	},
350 };
351 
352 static struct clk_branch video_cc_mvs0c_shift_clk = {
353 	.halt_reg = 0x812c,
354 	.halt_check = BRANCH_HALT_VOTED,
355 	.hwcg_reg = 0x812c,
356 	.hwcg_bit = 1,
357 	.clkr = {
358 		.enable_reg = 0x812c,
359 		.enable_mask = BIT(0),
360 		.hw.init = &(const struct clk_init_data) {
361 			.name = "video_cc_mvs0c_shift_clk",
362 			.parent_hws = (const struct clk_hw*[]) {
363 				&video_cc_xo_clk_src.clkr.hw,
364 			},
365 			.num_parents = 1,
366 			.flags = CLK_SET_RATE_PARENT,
367 			.ops = &clk_branch2_ops,
368 		},
369 	},
370 };
371 
372 static struct clk_branch video_cc_mvs1_clk = {
373 	.halt_reg = 0x80e0,
374 	.halt_check = BRANCH_HALT_SKIP,
375 	.hwcg_reg = 0x80e0,
376 	.hwcg_bit = 1,
377 	.clkr = {
378 		.enable_reg = 0x80e0,
379 		.enable_mask = BIT(0),
380 		.hw.init = &(const struct clk_init_data) {
381 			.name = "video_cc_mvs1_clk",
382 			.parent_hws = (const struct clk_hw*[]) {
383 				&video_cc_mvs1_div_clk_src.clkr.hw,
384 			},
385 			.num_parents = 1,
386 			.flags = CLK_SET_RATE_PARENT,
387 			.ops = &clk_branch2_ops,
388 		},
389 	},
390 };
391 
392 static struct clk_branch video_cc_mvs1_shift_clk = {
393 	.halt_reg = 0x8130,
394 	.halt_check = BRANCH_HALT_VOTED,
395 	.hwcg_reg = 0x8130,
396 	.hwcg_bit = 1,
397 	.clkr = {
398 		.enable_reg = 0x8130,
399 		.enable_mask = BIT(0),
400 		.hw.init = &(const struct clk_init_data) {
401 			.name = "video_cc_mvs1_shift_clk",
402 			.parent_hws = (const struct clk_hw*[]) {
403 				&video_cc_xo_clk_src.clkr.hw,
404 			},
405 			.num_parents = 1,
406 			.flags = CLK_SET_RATE_PARENT,
407 			.ops = &clk_branch2_ops,
408 		},
409 	},
410 };
411 
412 static struct clk_branch video_cc_mvs1c_clk = {
413 	.halt_reg = 0x8090,
414 	.halt_check = BRANCH_HALT,
415 	.clkr = {
416 		.enable_reg = 0x8090,
417 		.enable_mask = BIT(0),
418 		.hw.init = &(const struct clk_init_data) {
419 			.name = "video_cc_mvs1c_clk",
420 			.parent_hws = (const struct clk_hw*[]) {
421 				&video_cc_mvs1c_div2_div_clk_src.clkr.hw,
422 			},
423 			.num_parents = 1,
424 			.flags = CLK_SET_RATE_PARENT,
425 			.ops = &clk_branch2_ops,
426 		},
427 	},
428 };
429 
430 static struct clk_branch video_cc_mvs1c_shift_clk = {
431 	.halt_reg = 0x8134,
432 	.halt_check = BRANCH_HALT_VOTED,
433 	.hwcg_reg = 0x8134,
434 	.hwcg_bit = 1,
435 	.clkr = {
436 		.enable_reg = 0x8134,
437 		.enable_mask = BIT(0),
438 		.hw.init = &(const struct clk_init_data) {
439 			.name = "video_cc_mvs1c_shift_clk",
440 			.parent_hws = (const struct clk_hw*[]) {
441 				&video_cc_xo_clk_src.clkr.hw,
442 			},
443 			.num_parents = 1,
444 			.flags = CLK_SET_RATE_PARENT,
445 			.ops = &clk_branch2_ops,
446 		},
447 	},
448 };
449 
450 static struct gdsc video_cc_mvs0c_gdsc = {
451 	.gdscr = 0x804c,
452 	.en_rest_wait_val = 0x2,
453 	.en_few_wait_val = 0x2,
454 	.clk_dis_wait_val = 0x6,
455 	.pd = {
456 		.name = "video_cc_mvs0c_gdsc",
457 	},
458 	.pwrsts = PWRSTS_OFF_ON,
459 	.flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE,
460 };
461 
462 static struct gdsc video_cc_mvs0_gdsc = {
463 	.gdscr = 0x80a4,
464 	.en_rest_wait_val = 0x2,
465 	.en_few_wait_val = 0x2,
466 	.clk_dis_wait_val = 0x6,
467 	.pd = {
468 		.name = "video_cc_mvs0_gdsc",
469 	},
470 	.pwrsts = PWRSTS_OFF_ON,
471 	.parent = &video_cc_mvs0c_gdsc.pd,
472 	.flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE | HW_CTRL_TRIGGER,
473 };
474 
475 static struct gdsc video_cc_mvs1c_gdsc = {
476 	.gdscr = 0x8078,
477 	.en_rest_wait_val = 0x2,
478 	.en_few_wait_val = 0x2,
479 	.clk_dis_wait_val = 0x6,
480 	.pd = {
481 		.name = "video_cc_mvs1c_gdsc",
482 	},
483 	.pwrsts = PWRSTS_OFF_ON,
484 	.flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE,
485 };
486 
487 static struct gdsc video_cc_mvs1_gdsc = {
488 	.gdscr = 0x80cc,
489 	.en_rest_wait_val = 0x2,
490 	.en_few_wait_val = 0x2,
491 	.clk_dis_wait_val = 0x6,
492 	.pd = {
493 		.name = "video_cc_mvs1_gdsc",
494 	},
495 	.pwrsts = PWRSTS_OFF_ON,
496 	.parent = &video_cc_mvs1c_gdsc.pd,
497 	.flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE | HW_CTRL_TRIGGER,
498 };
499 
500 static struct clk_regmap *video_cc_sm8550_clocks[] = {
501 	[VIDEO_CC_MVS0_CLK] = &video_cc_mvs0_clk.clkr,
502 	[VIDEO_CC_MVS0_CLK_SRC] = &video_cc_mvs0_clk_src.clkr,
503 	[VIDEO_CC_MVS0_DIV_CLK_SRC] = &video_cc_mvs0_div_clk_src.clkr,
504 	[VIDEO_CC_MVS0C_CLK] = &video_cc_mvs0c_clk.clkr,
505 	[VIDEO_CC_MVS0C_DIV2_DIV_CLK_SRC] = &video_cc_mvs0c_div2_div_clk_src.clkr,
506 	[VIDEO_CC_MVS1_CLK] = &video_cc_mvs1_clk.clkr,
507 	[VIDEO_CC_MVS1_CLK_SRC] = &video_cc_mvs1_clk_src.clkr,
508 	[VIDEO_CC_MVS1_DIV_CLK_SRC] = &video_cc_mvs1_div_clk_src.clkr,
509 	[VIDEO_CC_MVS1C_CLK] = &video_cc_mvs1c_clk.clkr,
510 	[VIDEO_CC_MVS1C_DIV2_DIV_CLK_SRC] = &video_cc_mvs1c_div2_div_clk_src.clkr,
511 	[VIDEO_CC_PLL0] = &video_cc_pll0.clkr,
512 	[VIDEO_CC_PLL1] = &video_cc_pll1.clkr,
513 	[VIDEO_CC_XO_CLK_SRC] = NULL,
514 };
515 
516 static struct gdsc *video_cc_sm8550_gdscs[] = {
517 	[VIDEO_CC_MVS0C_GDSC] = &video_cc_mvs0c_gdsc,
518 	[VIDEO_CC_MVS0_GDSC] = &video_cc_mvs0_gdsc,
519 	[VIDEO_CC_MVS1C_GDSC] = &video_cc_mvs1c_gdsc,
520 	[VIDEO_CC_MVS1_GDSC] = &video_cc_mvs1_gdsc,
521 };
522 
523 static const struct qcom_reset_map video_cc_sm8550_resets[] = {
524 	[CVP_VIDEO_CC_INTERFACE_BCR] = { 0x80f0 },
525 	[CVP_VIDEO_CC_MVS0_BCR] = { 0x80a0 },
526 	[CVP_VIDEO_CC_MVS0C_BCR] = { 0x8048 },
527 	[CVP_VIDEO_CC_MVS1_BCR] = { 0x80c8 },
528 	[CVP_VIDEO_CC_MVS1C_BCR] = { 0x8074 },
529 	[VIDEO_CC_MVS0C_CLK_ARES] = { .reg = 0x8064, .bit = 2, .udelay = 1000 },
530 	[VIDEO_CC_MVS1C_CLK_ARES] = { .reg = 0x8090, .bit = 2, .udelay = 1000 },
531 	[VIDEO_CC_XO_CLK_ARES] = { .reg = 0x8124, .bit = 2, .udelay = 100 },
532 };
533 
534 static struct clk_alpha_pll *video_cc_sm8550_plls[] = {
535 	&video_cc_pll0,
536 	&video_cc_pll1,
537 };
538 
539 static u32 video_cc_sm8550_critical_cbcrs[] = {
540 	0x80f4, /* VIDEO_CC_AHB_CLK */
541 	0x8124, /* VIDEO_CC_XO_CLK */
542 	0x8140, /* VIDEO_CC_SLEEP_CLK */
543 };
544 
545 static u32 video_cc_sm8650_critical_cbcrs[] = {
546 	0x80f4, /* VIDEO_CC_AHB_CLK */
547 	0x8124, /* VIDEO_CC_XO_CLK */
548 	0x8150, /* VIDEO_CC_SLEEP_CLK */
549 };
550 
551 static const struct regmap_config video_cc_sm8550_regmap_config = {
552 	.reg_bits = 32,
553 	.reg_stride = 4,
554 	.val_bits = 32,
555 	.max_register = 0x9f4c,
556 	.fast_io = true,
557 };
558 
559 static struct qcom_cc_driver_data video_cc_sm8550_driver_data = {
560 	.alpha_plls = video_cc_sm8550_plls,
561 	.num_alpha_plls = ARRAY_SIZE(video_cc_sm8550_plls),
562 	.clk_cbcrs = video_cc_sm8550_critical_cbcrs,
563 	.num_clk_cbcrs = ARRAY_SIZE(video_cc_sm8550_critical_cbcrs),
564 };
565 
566 static const struct qcom_cc_desc video_cc_sm8550_desc = {
567 	.config = &video_cc_sm8550_regmap_config,
568 	.clks = video_cc_sm8550_clocks,
569 	.num_clks = ARRAY_SIZE(video_cc_sm8550_clocks),
570 	.resets = video_cc_sm8550_resets,
571 	.num_resets = ARRAY_SIZE(video_cc_sm8550_resets),
572 	.gdscs = video_cc_sm8550_gdscs,
573 	.num_gdscs = ARRAY_SIZE(video_cc_sm8550_gdscs),
574 	.use_rpm = true,
575 	.driver_data = &video_cc_sm8550_driver_data,
576 };
577 
578 static const struct of_device_id video_cc_sm8550_match_table[] = {
579 	{ .compatible = "qcom,sm8550-videocc" },
580 	{ .compatible = "qcom,sm8650-videocc" },
581 	{ .compatible = "qcom,x1e80100-videocc" },
582 	{ }
583 };
584 MODULE_DEVICE_TABLE(of, video_cc_sm8550_match_table);
585 
586 static int video_cc_sm8550_probe(struct platform_device *pdev)
587 {
588 	if (of_device_is_compatible(pdev->dev.of_node, "qcom,x1e80100-videocc")) {
589 		video_cc_pll0_config.l = 0x1e;
590 		video_cc_pll0_config.alpha = 0x0000;
591 		video_cc_pll1_config.l = 0x2b;
592 		video_cc_pll1_config.alpha = 0xc000;
593 		video_cc_mvs0_clk_src.freq_tbl = ftbl_video_cc_mvs0_clk_src_x1e80100;
594 		video_cc_mvs1_clk_src.freq_tbl = ftbl_video_cc_mvs1_clk_src_x1e80100;
595 	}
596 
597 	if (of_device_is_compatible(pdev->dev.of_node, "qcom,sm8650-videocc")) {
598 		video_cc_pll0_config.l = 0x1e;
599 		video_cc_pll0_config.alpha = 0xa000;
600 		video_cc_pll1_config.l = 0x2b;
601 		video_cc_pll1_config.alpha = 0xc000;
602 		video_cc_mvs0_clk_src.freq_tbl = ftbl_video_cc_mvs0_clk_src_sm8650;
603 		video_cc_mvs1_clk_src.freq_tbl = ftbl_video_cc_mvs1_clk_src_sm8650;
604 		video_cc_sm8550_clocks[VIDEO_CC_MVS0_SHIFT_CLK] = &video_cc_mvs0_shift_clk.clkr;
605 		video_cc_sm8550_clocks[VIDEO_CC_MVS0C_SHIFT_CLK] = &video_cc_mvs0c_shift_clk.clkr;
606 		video_cc_sm8550_clocks[VIDEO_CC_MVS1_SHIFT_CLK] = &video_cc_mvs1_shift_clk.clkr;
607 		video_cc_sm8550_clocks[VIDEO_CC_MVS1C_SHIFT_CLK] = &video_cc_mvs1c_shift_clk.clkr;
608 		video_cc_sm8550_clocks[VIDEO_CC_XO_CLK_SRC] = &video_cc_xo_clk_src.clkr;
609 
610 		video_cc_sm8550_driver_data.clk_cbcrs = video_cc_sm8650_critical_cbcrs;
611 		video_cc_sm8550_driver_data.num_clk_cbcrs =
612 							ARRAY_SIZE(video_cc_sm8650_critical_cbcrs);
613 	}
614 
615 	return qcom_cc_probe(pdev, &video_cc_sm8550_desc);
616 }
617 
618 static struct platform_driver video_cc_sm8550_driver = {
619 	.probe = video_cc_sm8550_probe,
620 	.driver = {
621 		.name = "video_cc-sm8550",
622 		.of_match_table = video_cc_sm8550_match_table,
623 	},
624 };
625 
626 module_platform_driver(video_cc_sm8550_driver);
627 
628 MODULE_DESCRIPTION("QTI VIDEOCC SM8550 Driver");
629 MODULE_LICENSE("GPL");
630