xref: /linux/drivers/clk/qcom/videocc-sa8775p.c (revision 3a2c4d55e32ad65efebdb6de44eef3bfa08bb49d)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved.
4  */
5 
6 #include <linux/clk-provider.h>
7 #include <linux/module.h>
8 #include <linux/of.h>
9 #include <linux/platform_device.h>
10 #include <linux/pm_runtime.h>
11 #include <linux/regmap.h>
12 
13 #include <dt-bindings/clock/qcom,sa8775p-videocc.h>
14 
15 #include "clk-alpha-pll.h"
16 #include "clk-branch.h"
17 #include "clk-pll.h"
18 #include "clk-rcg.h"
19 #include "clk-regmap.h"
20 #include "clk-regmap-divider.h"
21 #include "clk-regmap-mux.h"
22 #include "common.h"
23 #include "gdsc.h"
24 #include "reset.h"
25 
26 enum {
27 	DT_IFACE,
28 	DT_BI_TCXO,
29 	DT_BI_TCXO_AO,
30 	DT_SLEEP_CLK,
31 };
32 
33 enum {
34 	P_BI_TCXO,
35 	P_BI_TCXO_AO,
36 	P_SLEEP_CLK,
37 	P_VIDEO_PLL0_OUT_MAIN,
38 	P_VIDEO_PLL1_OUT_MAIN,
39 };
40 
41 static const struct pll_vco lucid_evo_vco[] = {
42 	{ 249600000, 2020000000, 0 },
43 };
44 
45 static const struct alpha_pll_config video_pll0_config = {
46 	.l = 0x39,
47 	.alpha = 0x3000,
48 	.config_ctl_val = 0x20485699,
49 	.config_ctl_hi_val = 0x00182261,
50 	.config_ctl_hi1_val = 0x32aa299c,
51 	.user_ctl_val = 0x00000000,
52 	.user_ctl_hi_val = 0x00400805,
53 };
54 
55 static struct clk_alpha_pll video_pll0 = {
56 	.offset = 0x0,
57 	.vco_table = lucid_evo_vco,
58 	.num_vco = ARRAY_SIZE(lucid_evo_vco),
59 	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_EVO],
60 	.clkr = {
61 		.hw.init = &(const struct clk_init_data) {
62 			.name = "video_pll0",
63 			.parent_data = &(const struct clk_parent_data) {
64 				.index = DT_BI_TCXO,
65 			},
66 			.num_parents = 1,
67 			.ops = &clk_alpha_pll_lucid_evo_ops,
68 		},
69 	},
70 };
71 
72 static const struct alpha_pll_config video_pll1_config = {
73 	.l = 0x39,
74 	.alpha = 0x3000,
75 	.config_ctl_val = 0x20485699,
76 	.config_ctl_hi_val = 0x00182261,
77 	.config_ctl_hi1_val = 0x32aa299c,
78 	.user_ctl_val = 0x00000000,
79 	.user_ctl_hi_val = 0x00400805,
80 };
81 
82 static struct clk_alpha_pll video_pll1 = {
83 	.offset = 0x1000,
84 	.vco_table = lucid_evo_vco,
85 	.num_vco = ARRAY_SIZE(lucid_evo_vco),
86 	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_EVO],
87 	.clkr = {
88 		.hw.init = &(const struct clk_init_data) {
89 			.name = "video_pll1",
90 			.parent_data = &(const struct clk_parent_data) {
91 				.index = DT_BI_TCXO,
92 			},
93 			.num_parents = 1,
94 			.ops = &clk_alpha_pll_lucid_evo_ops,
95 		},
96 	},
97 };
98 
99 static const struct parent_map video_cc_parent_map_0_ao[] = {
100 	{ P_BI_TCXO_AO, 0 },
101 };
102 
103 static const struct clk_parent_data video_cc_parent_data_0_ao[] = {
104 	{ .index = DT_BI_TCXO_AO },
105 };
106 
107 static const struct parent_map video_cc_parent_map_1[] = {
108 	{ P_BI_TCXO, 0 },
109 	{ P_VIDEO_PLL0_OUT_MAIN, 1 },
110 };
111 
112 static const struct clk_parent_data video_cc_parent_data_1[] = {
113 	{ .index = DT_BI_TCXO },
114 	{ .hw = &video_pll0.clkr.hw },
115 };
116 
117 static const struct parent_map video_cc_parent_map_2[] = {
118 	{ P_BI_TCXO, 0 },
119 	{ P_VIDEO_PLL1_OUT_MAIN, 1 },
120 };
121 
122 static const struct clk_parent_data video_cc_parent_data_2[] = {
123 	{ .index = DT_BI_TCXO },
124 	{ .hw = &video_pll1.clkr.hw },
125 };
126 
127 static const struct parent_map video_cc_parent_map_3[] = {
128 	{ P_SLEEP_CLK, 0 },
129 };
130 
131 static const struct clk_parent_data video_cc_parent_data_3[] = {
132 	{ .index = DT_SLEEP_CLK },
133 };
134 
135 static const struct freq_tbl ftbl_video_cc_ahb_clk_src[] = {
136 	F(19200000, P_BI_TCXO_AO, 1, 0, 0),
137 	{ }
138 };
139 
140 static struct clk_rcg2 video_cc_ahb_clk_src = {
141 	.cmd_rcgr = 0x8030,
142 	.mnd_width = 0,
143 	.hid_width = 5,
144 	.parent_map = video_cc_parent_map_0_ao,
145 	.freq_tbl = ftbl_video_cc_ahb_clk_src,
146 	.clkr.hw.init = &(const struct clk_init_data) {
147 		.name = "video_cc_ahb_clk_src",
148 		.parent_data = video_cc_parent_data_0_ao,
149 		.num_parents = ARRAY_SIZE(video_cc_parent_data_0_ao),
150 		.flags = CLK_SET_RATE_PARENT,
151 		.ops = &clk_rcg2_shared_ops,
152 	},
153 };
154 
155 static const struct freq_tbl ftbl_video_cc_mvs0_clk_src[] = {
156 	F(1098000000, P_VIDEO_PLL0_OUT_MAIN, 1, 0, 0),
157 	F(1332000000, P_VIDEO_PLL0_OUT_MAIN, 1, 0, 0),
158 	F(1599000000, P_VIDEO_PLL0_OUT_MAIN, 1, 0, 0),
159 	F(1680000000, P_VIDEO_PLL0_OUT_MAIN, 1, 0, 0),
160 	{ }
161 };
162 
163 static struct clk_rcg2 video_cc_mvs0_clk_src = {
164 	.cmd_rcgr = 0x8000,
165 	.mnd_width = 0,
166 	.hid_width = 5,
167 	.parent_map = video_cc_parent_map_1,
168 	.freq_tbl = ftbl_video_cc_mvs0_clk_src,
169 	.clkr.hw.init = &(const struct clk_init_data) {
170 		.name = "video_cc_mvs0_clk_src",
171 		.parent_data = video_cc_parent_data_1,
172 		.num_parents = ARRAY_SIZE(video_cc_parent_data_1),
173 		.flags = CLK_SET_RATE_PARENT,
174 		.ops = &clk_rcg2_shared_ops,
175 	},
176 };
177 
178 static const struct freq_tbl ftbl_video_cc_mvs1_clk_src[] = {
179 	F(1098000000, P_VIDEO_PLL1_OUT_MAIN, 1, 0, 0),
180 	F(1332000000, P_VIDEO_PLL1_OUT_MAIN, 1, 0, 0),
181 	F(1600000000, P_VIDEO_PLL1_OUT_MAIN, 1, 0, 0),
182 	F(1800000000, P_VIDEO_PLL1_OUT_MAIN, 1, 0, 0),
183 	{ }
184 };
185 
186 static struct clk_rcg2 video_cc_mvs1_clk_src = {
187 	.cmd_rcgr = 0x8018,
188 	.mnd_width = 0,
189 	.hid_width = 5,
190 	.parent_map = video_cc_parent_map_2,
191 	.freq_tbl = ftbl_video_cc_mvs1_clk_src,
192 	.clkr.hw.init = &(const struct clk_init_data) {
193 		.name = "video_cc_mvs1_clk_src",
194 		.parent_data = video_cc_parent_data_2,
195 		.num_parents = ARRAY_SIZE(video_cc_parent_data_2),
196 		.flags = CLK_SET_RATE_PARENT,
197 		.ops = &clk_rcg2_shared_ops,
198 	},
199 };
200 
201 static const struct freq_tbl ftbl_video_cc_sleep_clk_src[] = {
202 	F(32000, P_SLEEP_CLK, 1, 0, 0),
203 	{ }
204 };
205 
206 static struct clk_rcg2 video_cc_sleep_clk_src = {
207 	.cmd_rcgr = 0x812c,
208 	.mnd_width = 0,
209 	.hid_width = 5,
210 	.parent_map = video_cc_parent_map_3,
211 	.freq_tbl = ftbl_video_cc_sleep_clk_src,
212 	.clkr.hw.init = &(const struct clk_init_data) {
213 		.name = "video_cc_sleep_clk_src",
214 		.parent_data = video_cc_parent_data_3,
215 		.num_parents = ARRAY_SIZE(video_cc_parent_data_3),
216 		.flags = CLK_SET_RATE_PARENT,
217 		.ops = &clk_rcg2_shared_ops,
218 	},
219 };
220 
221 static struct clk_rcg2 video_cc_xo_clk_src = {
222 	.cmd_rcgr = 0x8110,
223 	.mnd_width = 0,
224 	.hid_width = 5,
225 	.parent_map = video_cc_parent_map_0_ao,
226 	.freq_tbl = ftbl_video_cc_ahb_clk_src,
227 	.clkr.hw.init = &(const struct clk_init_data) {
228 		.name = "video_cc_xo_clk_src",
229 		.parent_data = video_cc_parent_data_0_ao,
230 		.num_parents = ARRAY_SIZE(video_cc_parent_data_0_ao),
231 		.flags = CLK_SET_RATE_PARENT,
232 		.ops = &clk_rcg2_shared_ops,
233 	},
234 };
235 
236 static struct clk_regmap_div video_cc_mvs0_div_clk_src = {
237 	.reg = 0x80b8,
238 	.shift = 0,
239 	.width = 4,
240 	.clkr.hw.init = &(const struct clk_init_data) {
241 		.name = "video_cc_mvs0_div_clk_src",
242 		.parent_hws = (const struct clk_hw*[]) {
243 			&video_cc_mvs0_clk_src.clkr.hw,
244 		},
245 		.num_parents = 1,
246 		.flags = CLK_SET_RATE_PARENT,
247 		.ops = &clk_regmap_div_ro_ops,
248 	},
249 };
250 
251 static struct clk_regmap_div video_cc_mvs0c_div2_div_clk_src = {
252 	.reg = 0x806c,
253 	.shift = 0,
254 	.width = 4,
255 	.clkr.hw.init = &(const struct clk_init_data) {
256 		.name = "video_cc_mvs0c_div2_div_clk_src",
257 		.parent_hws = (const struct clk_hw*[]) {
258 			&video_cc_mvs0_clk_src.clkr.hw,
259 		},
260 		.num_parents = 1,
261 		.flags = CLK_SET_RATE_PARENT,
262 		.ops = &clk_regmap_div_ro_ops,
263 	},
264 };
265 
266 static struct clk_regmap_div video_cc_mvs1_div_clk_src = {
267 	.reg = 0x80dc,
268 	.shift = 0,
269 	.width = 4,
270 	.clkr.hw.init = &(const struct clk_init_data) {
271 		.name = "video_cc_mvs1_div_clk_src",
272 		.parent_hws = (const struct clk_hw*[]) {
273 			&video_cc_mvs1_clk_src.clkr.hw,
274 		},
275 		.num_parents = 1,
276 		.flags = CLK_SET_RATE_PARENT,
277 		.ops = &clk_regmap_div_ro_ops,
278 	},
279 };
280 
281 static struct clk_regmap_div video_cc_mvs1c_div2_div_clk_src = {
282 	.reg = 0x8094,
283 	.shift = 0,
284 	.width = 4,
285 	.clkr.hw.init = &(const struct clk_init_data) {
286 		.name = "video_cc_mvs1c_div2_div_clk_src",
287 		.parent_hws = (const struct clk_hw*[]) {
288 			&video_cc_mvs1_clk_src.clkr.hw,
289 		},
290 		.num_parents = 1,
291 		.flags = CLK_SET_RATE_PARENT,
292 		.ops = &clk_regmap_div_ro_ops,
293 	},
294 };
295 
296 static struct clk_regmap_div video_cc_sm_div_clk_src = {
297 	.reg = 0x8108,
298 	.shift = 0,
299 	.width = 4,
300 	.clkr.hw.init = &(const struct clk_init_data) {
301 		.name = "video_cc_sm_div_clk_src",
302 		.ops = &clk_regmap_div_ro_ops,
303 	},
304 };
305 
306 static struct clk_branch video_cc_mvs0_clk = {
307 	.halt_reg = 0x80b0,
308 	.halt_check = BRANCH_HALT_VOTED,
309 	.hwcg_reg = 0x80b0,
310 	.hwcg_bit = 1,
311 	.clkr = {
312 		.enable_reg = 0x80b0,
313 		.enable_mask = BIT(0),
314 		.hw.init = &(const struct clk_init_data) {
315 			.name = "video_cc_mvs0_clk",
316 			.parent_hws = (const struct clk_hw*[]) {
317 				&video_cc_mvs0_div_clk_src.clkr.hw,
318 			},
319 			.num_parents = 1,
320 			.flags = CLK_SET_RATE_PARENT,
321 			.ops = &clk_branch2_ops,
322 		},
323 	},
324 };
325 
326 static struct clk_branch video_cc_mvs0c_clk = {
327 	.halt_reg = 0x8064,
328 	.halt_check = BRANCH_HALT,
329 	.clkr = {
330 		.enable_reg = 0x8064,
331 		.enable_mask = BIT(0),
332 		.hw.init = &(const struct clk_init_data) {
333 			.name = "video_cc_mvs0c_clk",
334 			.parent_hws = (const struct clk_hw*[]) {
335 				&video_cc_mvs0c_div2_div_clk_src.clkr.hw,
336 			},
337 			.num_parents = 1,
338 			.flags = CLK_SET_RATE_PARENT,
339 			.ops = &clk_branch2_ops,
340 		},
341 	},
342 };
343 
344 static struct clk_branch video_cc_mvs1_clk = {
345 	.halt_reg = 0x80d4,
346 	.halt_check = BRANCH_HALT_VOTED,
347 	.hwcg_reg = 0x80d4,
348 	.hwcg_bit = 1,
349 	.clkr = {
350 		.enable_reg = 0x80d4,
351 		.enable_mask = BIT(0),
352 		.hw.init = &(const struct clk_init_data) {
353 			.name = "video_cc_mvs1_clk",
354 			.parent_hws = (const struct clk_hw*[]) {
355 				&video_cc_mvs1_div_clk_src.clkr.hw,
356 			},
357 			.num_parents = 1,
358 			.flags = CLK_SET_RATE_PARENT,
359 			.ops = &clk_branch2_ops,
360 		},
361 	},
362 };
363 
364 static struct clk_branch video_cc_mvs1c_clk = {
365 	.halt_reg = 0x808c,
366 	.halt_check = BRANCH_HALT,
367 	.clkr = {
368 		.enable_reg = 0x808c,
369 		.enable_mask = BIT(0),
370 		.hw.init = &(const struct clk_init_data) {
371 			.name = "video_cc_mvs1c_clk",
372 			.parent_hws = (const struct clk_hw*[]) {
373 				&video_cc_mvs1c_div2_div_clk_src.clkr.hw,
374 			},
375 			.num_parents = 1,
376 			.flags = CLK_SET_RATE_PARENT,
377 			.ops = &clk_branch2_ops,
378 		},
379 	},
380 };
381 
382 static struct clk_branch video_cc_pll_lock_monitor_clk = {
383 	.halt_reg = 0x9000,
384 	.halt_check = BRANCH_HALT,
385 	.clkr = {
386 		.enable_reg = 0x9000,
387 		.enable_mask = BIT(0),
388 		.hw.init = &(const struct clk_init_data) {
389 			.name = "video_cc_pll_lock_monitor_clk",
390 			.parent_hws = (const struct clk_hw*[]) {
391 				&video_cc_xo_clk_src.clkr.hw,
392 			},
393 			.num_parents = 1,
394 			.flags = CLK_SET_RATE_PARENT,
395 			.ops = &clk_branch2_ops,
396 		},
397 	},
398 };
399 
400 static struct clk_branch video_cc_sm_obs_clk = {
401 	.halt_reg = 0x810c,
402 	.halt_check = BRANCH_HALT_SKIP,
403 	.clkr = {
404 		.enable_reg = 0x810c,
405 		.enable_mask = BIT(0),
406 		.hw.init = &(const struct clk_init_data) {
407 			.name = "video_cc_sm_obs_clk",
408 			.parent_hws = (const struct clk_hw*[]) {
409 				&video_cc_sm_div_clk_src.clkr.hw,
410 			},
411 			.num_parents = 1,
412 			.flags = CLK_SET_RATE_PARENT,
413 			.ops = &clk_branch2_ops,
414 		},
415 	},
416 };
417 
418 static struct gdsc video_cc_mvs0c_gdsc = {
419 	.gdscr = 0x804c,
420 	.en_rest_wait_val = 0x2,
421 	.en_few_wait_val = 0x2,
422 	.clk_dis_wait_val = 0x6,
423 	.pd = {
424 		.name = "video_cc_mvs0c_gdsc",
425 	},
426 	.pwrsts = PWRSTS_OFF_ON,
427 	.flags = RETAIN_FF_ENABLE | POLL_CFG_GDSCR,
428 };
429 
430 static struct gdsc video_cc_mvs0_gdsc = {
431 	.gdscr = 0x809c,
432 	.en_rest_wait_val = 0x2,
433 	.en_few_wait_val = 0x2,
434 	.clk_dis_wait_val = 0x6,
435 	.pd = {
436 		.name = "video_cc_mvs0_gdsc",
437 	},
438 	.pwrsts = PWRSTS_OFF_ON,
439 	.parent = &video_cc_mvs0c_gdsc.pd,
440 	.flags = RETAIN_FF_ENABLE | POLL_CFG_GDSCR | HW_CTRL_TRIGGER,
441 };
442 
443 static struct gdsc video_cc_mvs1c_gdsc = {
444 	.gdscr = 0x8074,
445 	.en_rest_wait_val = 0x2,
446 	.en_few_wait_val = 0x2,
447 	.clk_dis_wait_val = 0x6,
448 	.pd = {
449 		.name = "video_cc_mvs1c_gdsc",
450 	},
451 	.pwrsts = PWRSTS_OFF_ON,
452 	.flags = RETAIN_FF_ENABLE | POLL_CFG_GDSCR,
453 };
454 
455 static struct gdsc video_cc_mvs1_gdsc = {
456 	.gdscr = 0x80c0,
457 	.en_rest_wait_val = 0x2,
458 	.en_few_wait_val = 0x2,
459 	.clk_dis_wait_val = 0x6,
460 	.pd = {
461 		.name = "video_cc_mvs1_gdsc",
462 	},
463 	.pwrsts = PWRSTS_OFF_ON,
464 	.parent = &video_cc_mvs1c_gdsc.pd,
465 	.flags = RETAIN_FF_ENABLE | POLL_CFG_GDSCR | HW_CTRL_TRIGGER,
466 };
467 
468 static struct clk_regmap *video_cc_sa8775p_clocks[] = {
469 	[VIDEO_CC_AHB_CLK_SRC] = &video_cc_ahb_clk_src.clkr,
470 	[VIDEO_CC_MVS0_CLK] = &video_cc_mvs0_clk.clkr,
471 	[VIDEO_CC_MVS0_CLK_SRC] = &video_cc_mvs0_clk_src.clkr,
472 	[VIDEO_CC_MVS0_DIV_CLK_SRC] = &video_cc_mvs0_div_clk_src.clkr,
473 	[VIDEO_CC_MVS0C_CLK] = &video_cc_mvs0c_clk.clkr,
474 	[VIDEO_CC_MVS0C_DIV2_DIV_CLK_SRC] = &video_cc_mvs0c_div2_div_clk_src.clkr,
475 	[VIDEO_CC_MVS1_CLK] = &video_cc_mvs1_clk.clkr,
476 	[VIDEO_CC_MVS1_CLK_SRC] = &video_cc_mvs1_clk_src.clkr,
477 	[VIDEO_CC_MVS1_DIV_CLK_SRC] = &video_cc_mvs1_div_clk_src.clkr,
478 	[VIDEO_CC_MVS1C_CLK] = &video_cc_mvs1c_clk.clkr,
479 	[VIDEO_CC_MVS1C_DIV2_DIV_CLK_SRC] = &video_cc_mvs1c_div2_div_clk_src.clkr,
480 	[VIDEO_CC_PLL_LOCK_MONITOR_CLK] = &video_cc_pll_lock_monitor_clk.clkr,
481 	[VIDEO_CC_SLEEP_CLK_SRC] = &video_cc_sleep_clk_src.clkr,
482 	[VIDEO_CC_SM_DIV_CLK_SRC] = &video_cc_sm_div_clk_src.clkr,
483 	[VIDEO_CC_SM_OBS_CLK] = &video_cc_sm_obs_clk.clkr,
484 	[VIDEO_CC_XO_CLK_SRC] = &video_cc_xo_clk_src.clkr,
485 	[VIDEO_PLL0] = &video_pll0.clkr,
486 	[VIDEO_PLL1] = &video_pll1.clkr,
487 };
488 
489 static struct gdsc *video_cc_sa8775p_gdscs[] = {
490 	[VIDEO_CC_MVS0_GDSC] = &video_cc_mvs0_gdsc,
491 	[VIDEO_CC_MVS0C_GDSC] = &video_cc_mvs0c_gdsc,
492 	[VIDEO_CC_MVS1_GDSC] = &video_cc_mvs1_gdsc,
493 	[VIDEO_CC_MVS1C_GDSC] = &video_cc_mvs1c_gdsc,
494 };
495 
496 static const struct qcom_reset_map video_cc_sa8775p_resets[] = {
497 	[VIDEO_CC_INTERFACE_BCR] = { 0x80e8 },
498 	[VIDEO_CC_MVS0_BCR] = { 0x8098 },
499 	[VIDEO_CC_MVS0C_CLK_ARES] = { 0x8064, 2 },
500 	[VIDEO_CC_MVS0C_BCR] = { 0x8048 },
501 	[VIDEO_CC_MVS1_BCR] = { 0x80bc },
502 	[VIDEO_CC_MVS1C_CLK_ARES] = { 0x808c, 2 },
503 	[VIDEO_CC_MVS1C_BCR] = { 0x8070 },
504 };
505 
506 static const struct regmap_config video_cc_sa8775p_regmap_config = {
507 	.reg_bits = 32,
508 	.reg_stride = 4,
509 	.val_bits = 32,
510 	.max_register = 0xb000,
511 	.fast_io = true,
512 };
513 
514 static const struct qcom_cc_desc video_cc_sa8775p_desc = {
515 	.config = &video_cc_sa8775p_regmap_config,
516 	.clks = video_cc_sa8775p_clocks,
517 	.num_clks = ARRAY_SIZE(video_cc_sa8775p_clocks),
518 	.resets = video_cc_sa8775p_resets,
519 	.num_resets = ARRAY_SIZE(video_cc_sa8775p_resets),
520 	.gdscs = video_cc_sa8775p_gdscs,
521 	.num_gdscs = ARRAY_SIZE(video_cc_sa8775p_gdscs),
522 };
523 
524 static const struct of_device_id video_cc_sa8775p_match_table[] = {
525 	{ .compatible = "qcom,qcs8300-videocc" },
526 	{ .compatible = "qcom,sa8775p-videocc" },
527 	{ }
528 };
529 MODULE_DEVICE_TABLE(of, video_cc_sa8775p_match_table);
530 
531 static int video_cc_sa8775p_probe(struct platform_device *pdev)
532 {
533 	struct regmap *regmap;
534 	int ret;
535 
536 	ret = devm_pm_runtime_enable(&pdev->dev);
537 	if (ret)
538 		return ret;
539 
540 	ret = pm_runtime_resume_and_get(&pdev->dev);
541 	if (ret)
542 		return ret;
543 
544 	regmap = qcom_cc_map(pdev, &video_cc_sa8775p_desc);
545 	if (IS_ERR(regmap)) {
546 		pm_runtime_put(&pdev->dev);
547 		return PTR_ERR(regmap);
548 	}
549 
550 	clk_lucid_evo_pll_configure(&video_pll0, regmap, &video_pll0_config);
551 	clk_lucid_evo_pll_configure(&video_pll1, regmap, &video_pll1_config);
552 
553 	/*
554 	 * Set mvs0c clock divider to div-3 to make the mvs0 and
555 	 * mvs0c clocks to run at the same frequency on QCS8300
556 	 */
557 	if (of_device_is_compatible(pdev->dev.of_node, "qcom,qcs8300-videocc"))
558 		regmap_write(regmap, video_cc_mvs0c_div2_div_clk_src.reg, 2);
559 
560 	/* Keep some clocks always enabled */
561 	qcom_branch_set_clk_en(regmap, 0x80ec); /* VIDEO_CC_AHB_CLK */
562 	qcom_branch_set_clk_en(regmap, 0x8144); /* VIDEO_CC_SLEEP_CLK */
563 	qcom_branch_set_clk_en(regmap, 0x8128); /* VIDEO_CC_XO_CLK */
564 
565 	ret = qcom_cc_really_probe(&pdev->dev, &video_cc_sa8775p_desc, regmap);
566 
567 	pm_runtime_put(&pdev->dev);
568 
569 	return ret;
570 }
571 
572 static struct platform_driver video_cc_sa8775p_driver = {
573 	.probe = video_cc_sa8775p_probe,
574 	.driver = {
575 		.name = "videocc-sa8775p",
576 		.of_match_table = video_cc_sa8775p_match_table,
577 	},
578 };
579 
580 module_platform_driver(video_cc_sa8775p_driver);
581 
582 MODULE_DESCRIPTION("QTI VIDEOCC SA8775P Driver");
583 MODULE_LICENSE("GPL");
584