xref: /linux/drivers/clk/qcom/videocc-kaanapali.c (revision c17ee635fd3a482b2ad2bf5e269755c2eae5f25e)
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/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,kaanapali-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 #define ACCU_CFG_MASK GENMASK(25, 21)
24 
25 enum {
26 	DT_BI_TCXO,
27 	DT_AHB_CLK,
28 };
29 
30 enum {
31 	P_BI_TCXO,
32 	P_VIDEO_CC_PLL0_OUT_MAIN,
33 	P_VIDEO_CC_PLL1_OUT_MAIN,
34 	P_VIDEO_CC_PLL2_OUT_MAIN,
35 	P_VIDEO_CC_PLL3_OUT_MAIN,
36 };
37 
38 static const struct pll_vco taycan_eko_t_vco[] = {
39 	{ 249600000, 2500000000, 0 },
40 };
41 
42 /* 360.0 MHz Configuration */
43 static const struct alpha_pll_config video_cc_pll0_config = {
44 	.l = 0x12,
45 	.cal_l = 0x48,
46 	.alpha = 0xc000,
47 	.config_ctl_val = 0x25c400e7,
48 	.config_ctl_hi_val = 0x0a8062e0,
49 	.config_ctl_hi1_val = 0xf51dea20,
50 	.user_ctl_val = 0x00000008,
51 	.user_ctl_hi_val = 0x00000002,
52 };
53 
54 static struct clk_alpha_pll video_cc_pll0 = {
55 	.offset = 0x0,
56 	.config = &video_cc_pll0_config,
57 	.vco_table = taycan_eko_t_vco,
58 	.num_vco = ARRAY_SIZE(taycan_eko_t_vco),
59 	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T],
60 	.clkr = {
61 		.hw.init = &(const struct clk_init_data) {
62 			.name = "video_cc_pll0",
63 			.parent_data = &(const struct clk_parent_data) {
64 				.index = DT_BI_TCXO,
65 			},
66 			.num_parents = 1,
67 			.ops = &clk_alpha_pll_taycan_eko_t_ops,
68 		},
69 	},
70 };
71 
72 /* 480.0 MHz Configuration */
73 static const struct alpha_pll_config video_cc_pll1_config = {
74 	.l = 0x19,
75 	.cal_l = 0x48,
76 	.alpha = 0x0,
77 	.config_ctl_val = 0x25c400e7,
78 	.config_ctl_hi_val = 0x0a8062e0,
79 	.config_ctl_hi1_val = 0xf51dea20,
80 	.user_ctl_val = 0x00000008,
81 	.user_ctl_hi_val = 0x00000002,
82 };
83 
84 static struct clk_alpha_pll video_cc_pll1 = {
85 	.offset = 0x1000,
86 	.config = &video_cc_pll1_config,
87 	.vco_table = taycan_eko_t_vco,
88 	.num_vco = ARRAY_SIZE(taycan_eko_t_vco),
89 	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T],
90 	.clkr = {
91 		.hw.init = &(const struct clk_init_data) {
92 			.name = "video_cc_pll1",
93 			.parent_data = &(const struct clk_parent_data) {
94 				.index = DT_BI_TCXO,
95 			},
96 			.num_parents = 1,
97 			.ops = &clk_alpha_pll_taycan_eko_t_ops,
98 		},
99 	},
100 };
101 
102 /* 480.0 MHz Configuration */
103 static const struct alpha_pll_config video_cc_pll2_config = {
104 	.l = 0x19,
105 	.cal_l = 0x48,
106 	.alpha = 0x0,
107 	.config_ctl_val = 0x25c400e7,
108 	.config_ctl_hi_val = 0x0a8062e0,
109 	.config_ctl_hi1_val = 0xf51dea20,
110 	.user_ctl_val = 0x00000008,
111 	.user_ctl_hi_val = 0x00000002,
112 };
113 
114 static struct clk_alpha_pll video_cc_pll2 = {
115 	.offset = 0x2000,
116 	.config = &video_cc_pll2_config,
117 	.vco_table = taycan_eko_t_vco,
118 	.num_vco = ARRAY_SIZE(taycan_eko_t_vco),
119 	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T],
120 	.clkr = {
121 		.hw.init = &(const struct clk_init_data) {
122 			.name = "video_cc_pll2",
123 			.parent_data = &(const struct clk_parent_data) {
124 				.index = DT_BI_TCXO,
125 			},
126 			.num_parents = 1,
127 			.ops = &clk_alpha_pll_taycan_eko_t_ops,
128 		},
129 	},
130 };
131 
132 /* 480.0 MHz Configuration */
133 static const struct alpha_pll_config video_cc_pll3_config = {
134 	.l = 0x19,
135 	.cal_l = 0x48,
136 	.alpha = 0x0,
137 	.config_ctl_val = 0x25c400e7,
138 	.config_ctl_hi_val = 0x0a8062e0,
139 	.config_ctl_hi1_val = 0xf51dea20,
140 	.user_ctl_val = 0x00000008,
141 	.user_ctl_hi_val = 0x00000002,
142 };
143 
144 static struct clk_alpha_pll video_cc_pll3 = {
145 	.offset = 0x3000,
146 	.config = &video_cc_pll3_config,
147 	.vco_table = taycan_eko_t_vco,
148 	.num_vco = ARRAY_SIZE(taycan_eko_t_vco),
149 	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T],
150 	.clkr = {
151 		.hw.init = &(const struct clk_init_data) {
152 			.name = "video_cc_pll3",
153 			.parent_data = &(const struct clk_parent_data) {
154 				.index = DT_BI_TCXO,
155 			},
156 			.num_parents = 1,
157 			.ops = &clk_alpha_pll_taycan_eko_t_ops,
158 		},
159 	},
160 };
161 
162 static const struct parent_map video_cc_parent_map_0[] = {
163 	{ P_BI_TCXO, 0 },
164 };
165 
166 static const struct clk_parent_data video_cc_parent_data_0[] = {
167 	{ .index = DT_BI_TCXO },
168 };
169 
170 static const struct parent_map video_cc_parent_map_1[] = {
171 	{ P_BI_TCXO, 0 },
172 	{ P_VIDEO_CC_PLL1_OUT_MAIN, 1 },
173 };
174 
175 static const struct clk_parent_data video_cc_parent_data_1[] = {
176 	{ .index = DT_BI_TCXO },
177 	{ .hw = &video_cc_pll1.clkr.hw },
178 };
179 
180 static const struct parent_map video_cc_parent_map_2[] = {
181 	{ P_BI_TCXO, 0 },
182 	{ P_VIDEO_CC_PLL3_OUT_MAIN, 1 },
183 };
184 
185 static const struct clk_parent_data video_cc_parent_data_2[] = {
186 	{ .index = DT_BI_TCXO },
187 	{ .hw = &video_cc_pll3.clkr.hw },
188 };
189 
190 static const struct parent_map video_cc_parent_map_3[] = {
191 	{ P_BI_TCXO, 0 },
192 	{ P_VIDEO_CC_PLL2_OUT_MAIN, 1 },
193 };
194 
195 static const struct clk_parent_data video_cc_parent_data_3[] = {
196 	{ .index = DT_BI_TCXO },
197 	{ .hw = &video_cc_pll2.clkr.hw },
198 };
199 
200 static const struct parent_map video_cc_parent_map_4[] = {
201 	{ P_BI_TCXO, 0 },
202 	{ P_VIDEO_CC_PLL0_OUT_MAIN, 1 },
203 };
204 
205 static const struct clk_parent_data video_cc_parent_data_4[] = {
206 	{ .index = DT_BI_TCXO },
207 	{ .hw = &video_cc_pll0.clkr.hw },
208 };
209 
210 static const struct freq_tbl ftbl_video_cc_ahb_clk_src[] = {
211 	F(19200000, P_BI_TCXO, 1, 0, 0),
212 	{ }
213 };
214 
215 static struct clk_rcg2 video_cc_ahb_clk_src = {
216 	.cmd_rcgr = 0x8060,
217 	.mnd_width = 0,
218 	.hid_width = 5,
219 	.parent_map = video_cc_parent_map_0,
220 	.freq_tbl = ftbl_video_cc_ahb_clk_src,
221 	.clkr.hw.init = &(const struct clk_init_data) {
222 		.name = "video_cc_ahb_clk_src",
223 		.parent_data = video_cc_parent_data_0,
224 		.num_parents = ARRAY_SIZE(video_cc_parent_data_0),
225 		.flags = CLK_SET_RATE_PARENT,
226 		.ops = &clk_rcg2_shared_ops,
227 	},
228 };
229 
230 static const struct freq_tbl ftbl_video_cc_mvs0_clk_src[] = {
231 	F(240000000, P_VIDEO_CC_PLL1_OUT_MAIN, 2, 0, 0),
232 	F(338000000, P_VIDEO_CC_PLL1_OUT_MAIN, 2, 0, 0),
233 	F(420000000, P_VIDEO_CC_PLL1_OUT_MAIN, 2, 0, 0),
234 	F(444000000, P_VIDEO_CC_PLL1_OUT_MAIN, 2, 0, 0),
235 	F(533000000, P_VIDEO_CC_PLL1_OUT_MAIN, 2, 0, 0),
236 	F(630000000, P_VIDEO_CC_PLL1_OUT_MAIN, 2, 0, 0),
237 	F(800000000, P_VIDEO_CC_PLL1_OUT_MAIN, 2, 0, 0),
238 	F(1000000000, P_VIDEO_CC_PLL1_OUT_MAIN, 2, 0, 0),
239 	{ }
240 };
241 
242 static struct clk_rcg2 video_cc_mvs0_clk_src = {
243 	.cmd_rcgr = 0x8030,
244 	.mnd_width = 0,
245 	.hid_width = 5,
246 	.parent_map = video_cc_parent_map_1,
247 	.freq_tbl = ftbl_video_cc_mvs0_clk_src,
248 	.hw_clk_ctrl = true,
249 	.clkr.hw.init = &(const struct clk_init_data) {
250 		.name = "video_cc_mvs0_clk_src",
251 		.parent_data = video_cc_parent_data_1,
252 		.num_parents = ARRAY_SIZE(video_cc_parent_data_1),
253 		.flags = CLK_SET_RATE_PARENT,
254 		.ops = &clk_rcg2_shared_ops,
255 	},
256 };
257 
258 static const struct freq_tbl ftbl_video_cc_mvs0a_clk_src[] = {
259 	F(240000000, P_VIDEO_CC_PLL3_OUT_MAIN, 2, 0, 0),
260 	F(338000000, P_VIDEO_CC_PLL3_OUT_MAIN, 2, 0, 0),
261 	F(420000000, P_VIDEO_CC_PLL3_OUT_MAIN, 2, 0, 0),
262 	F(444000000, P_VIDEO_CC_PLL3_OUT_MAIN, 2, 0, 0),
263 	F(533000000, P_VIDEO_CC_PLL3_OUT_MAIN, 2, 0, 0),
264 	F(630000000, P_VIDEO_CC_PLL3_OUT_MAIN, 2, 0, 0),
265 	{ }
266 };
267 
268 static struct clk_rcg2 video_cc_mvs0a_clk_src = {
269 	.cmd_rcgr = 0x8000,
270 	.mnd_width = 0,
271 	.hid_width = 5,
272 	.parent_map = video_cc_parent_map_2,
273 	.freq_tbl = ftbl_video_cc_mvs0a_clk_src,
274 	.hw_clk_ctrl = true,
275 	.clkr.hw.init = &(const struct clk_init_data) {
276 		.name = "video_cc_mvs0a_clk_src",
277 		.parent_data = video_cc_parent_data_2,
278 		.num_parents = ARRAY_SIZE(video_cc_parent_data_2),
279 		.flags = CLK_SET_RATE_PARENT,
280 		.ops = &clk_rcg2_shared_ops,
281 	},
282 };
283 
284 static const struct freq_tbl ftbl_video_cc_mvs0b_clk_src[] = {
285 	F(240000000, P_VIDEO_CC_PLL2_OUT_MAIN, 2, 0, 0),
286 	F(338000000, P_VIDEO_CC_PLL2_OUT_MAIN, 2, 0, 0),
287 	F(420000000, P_VIDEO_CC_PLL2_OUT_MAIN, 2, 0, 0),
288 	F(444000000, P_VIDEO_CC_PLL2_OUT_MAIN, 2, 0, 0),
289 	F(533000000, P_VIDEO_CC_PLL2_OUT_MAIN, 2, 0, 0),
290 	F(630000000, P_VIDEO_CC_PLL2_OUT_MAIN, 2, 0, 0),
291 	F(850000000, P_VIDEO_CC_PLL2_OUT_MAIN, 2, 0, 0),
292 	{ }
293 };
294 
295 static struct clk_rcg2 video_cc_mvs0b_clk_src = {
296 	.cmd_rcgr = 0x8018,
297 	.mnd_width = 0,
298 	.hid_width = 5,
299 	.parent_map = video_cc_parent_map_3,
300 	.freq_tbl = ftbl_video_cc_mvs0b_clk_src,
301 	.hw_clk_ctrl = true,
302 	.clkr.hw.init = &(const struct clk_init_data) {
303 		.name = "video_cc_mvs0b_clk_src",
304 		.parent_data = video_cc_parent_data_3,
305 		.num_parents = ARRAY_SIZE(video_cc_parent_data_3),
306 		.flags = CLK_SET_RATE_PARENT,
307 		.ops = &clk_rcg2_shared_ops,
308 	},
309 };
310 
311 static const struct freq_tbl ftbl_video_cc_mvs0c_clk_src[] = {
312 	F(360000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0),
313 	F(507000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0),
314 	F(630000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0),
315 	F(666000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0),
316 	F(800000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0),
317 	F(1104000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0),
318 	F(1260000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0),
319 	{ }
320 };
321 
322 static struct clk_rcg2 video_cc_mvs0c_clk_src = {
323 	.cmd_rcgr = 0x8048,
324 	.mnd_width = 0,
325 	.hid_width = 5,
326 	.parent_map = video_cc_parent_map_4,
327 	.freq_tbl = ftbl_video_cc_mvs0c_clk_src,
328 	.hw_clk_ctrl = true,
329 	.clkr.hw.init = &(const struct clk_init_data) {
330 		.name = "video_cc_mvs0c_clk_src",
331 		.parent_data = video_cc_parent_data_4,
332 		.num_parents = ARRAY_SIZE(video_cc_parent_data_4),
333 		.flags = CLK_SET_RATE_PARENT,
334 		.ops = &clk_rcg2_shared_ops,
335 	},
336 };
337 
338 static struct clk_rcg2 video_cc_xo_clk_src = {
339 	.cmd_rcgr = 0x8194,
340 	.mnd_width = 0,
341 	.hid_width = 5,
342 	.parent_map = video_cc_parent_map_0,
343 	.freq_tbl = ftbl_video_cc_ahb_clk_src,
344 	.clkr.hw.init = &(const struct clk_init_data) {
345 		.name = "video_cc_xo_clk_src",
346 		.parent_data = video_cc_parent_data_0,
347 		.num_parents = ARRAY_SIZE(video_cc_parent_data_0),
348 		.flags = CLK_SET_RATE_PARENT,
349 		.ops = &clk_rcg2_ops,
350 	},
351 };
352 
353 static struct clk_branch video_cc_mvs0_clk = {
354 	.halt_reg = 0x80d0,
355 	.halt_check = BRANCH_HALT_VOTED,
356 	.hwcg_reg = 0x80d0,
357 	.hwcg_bit = 1,
358 	.clkr = {
359 		.enable_reg = 0x80d0,
360 		.enable_mask = BIT(0),
361 		.hw.init = &(const struct clk_init_data) {
362 			.name = "video_cc_mvs0_clk",
363 			.parent_hws = (const struct clk_hw*[]) {
364 				&video_cc_mvs0_clk_src.clkr.hw,
365 			},
366 			.num_parents = 1,
367 			.flags = CLK_SET_RATE_PARENT,
368 			.ops = &clk_branch2_ops,
369 		},
370 	},
371 };
372 
373 static struct clk_mem_branch video_cc_mvs0_freerun_clk = {
374 	.mem_enable_reg = 0x80e4,
375 	.mem_ack_reg =  0x80e4,
376 	.mem_enable_mask = BIT(3),
377 	.mem_enable_ack_mask = GENMASK(11, 10),
378 	.mem_enable_invert = true,
379 	.branch = {
380 		.halt_reg = 0x80e0,
381 		.halt_check = BRANCH_HALT,
382 		.clkr = {
383 			.enable_reg = 0x80e0,
384 			.enable_mask = BIT(0),
385 			.hw.init = &(const struct clk_init_data) {
386 				.name = "video_cc_mvs0_freerun_clk",
387 				.parent_hws = (const struct clk_hw*[]) {
388 					&video_cc_mvs0_clk_src.clkr.hw,
389 				},
390 				.num_parents = 1,
391 				.flags = CLK_SET_RATE_PARENT,
392 				.ops = &clk_branch2_ops,
393 			},
394 		},
395 	},
396 };
397 
398 static struct clk_branch video_cc_mvs0_shift_clk = {
399 	.halt_reg = 0x81b4,
400 	.halt_check = BRANCH_HALT_VOTED,
401 	.hwcg_reg = 0x81b4,
402 	.hwcg_bit = 1,
403 	.clkr = {
404 		.enable_reg = 0x81b4,
405 		.enable_mask = BIT(0),
406 		.hw.init = &(const struct clk_init_data) {
407 			.name = "video_cc_mvs0_shift_clk",
408 			.parent_hws = (const struct clk_hw*[]) {
409 				&video_cc_xo_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 clk_branch video_cc_mvs0_vpp0_clk = {
419 	.halt_reg = 0x8134,
420 	.halt_check = BRANCH_HALT_VOTED,
421 	.hwcg_reg = 0x8134,
422 	.hwcg_bit = 1,
423 	.clkr = {
424 		.enable_reg = 0x8134,
425 		.enable_mask = BIT(0),
426 		.hw.init = &(const struct clk_init_data) {
427 			.name = "video_cc_mvs0_vpp0_clk",
428 			.parent_hws = (const struct clk_hw*[]) {
429 				&video_cc_mvs0_clk_src.clkr.hw,
430 			},
431 			.num_parents = 1,
432 			.flags = CLK_SET_RATE_PARENT,
433 			.ops = &clk_branch2_ops,
434 		},
435 	},
436 };
437 
438 static struct clk_branch video_cc_mvs0_vpp0_freerun_clk = {
439 	.halt_reg = 0x8144,
440 	.halt_check = BRANCH_HALT,
441 	.clkr = {
442 		.enable_reg = 0x8144,
443 		.enable_mask = BIT(0),
444 		.hw.init = &(const struct clk_init_data) {
445 			.name = "video_cc_mvs0_vpp0_freerun_clk",
446 			.parent_hws = (const struct clk_hw*[]) {
447 				&video_cc_mvs0_clk_src.clkr.hw,
448 			},
449 			.num_parents = 1,
450 			.flags = CLK_SET_RATE_PARENT,
451 			.ops = &clk_branch2_ops,
452 		},
453 	},
454 };
455 
456 static struct clk_branch video_cc_mvs0_vpp1_clk = {
457 	.halt_reg = 0x8108,
458 	.halt_check = BRANCH_HALT_VOTED,
459 	.hwcg_reg = 0x8108,
460 	.hwcg_bit = 1,
461 	.clkr = {
462 		.enable_reg = 0x8108,
463 		.enable_mask = BIT(0),
464 		.hw.init = &(const struct clk_init_data) {
465 			.name = "video_cc_mvs0_vpp1_clk",
466 			.parent_hws = (const struct clk_hw*[]) {
467 				&video_cc_mvs0_clk_src.clkr.hw,
468 			},
469 			.num_parents = 1,
470 			.flags = CLK_SET_RATE_PARENT,
471 			.ops = &clk_branch2_ops,
472 		},
473 	},
474 };
475 
476 static struct clk_branch video_cc_mvs0_vpp1_freerun_clk = {
477 	.halt_reg = 0x8118,
478 	.halt_check = BRANCH_HALT,
479 	.clkr = {
480 		.enable_reg = 0x8118,
481 		.enable_mask = BIT(0),
482 		.hw.init = &(const struct clk_init_data) {
483 			.name = "video_cc_mvs0_vpp1_freerun_clk",
484 			.parent_hws = (const struct clk_hw*[]) {
485 				&video_cc_mvs0_clk_src.clkr.hw,
486 			},
487 			.num_parents = 1,
488 			.flags = CLK_SET_RATE_PARENT,
489 			.ops = &clk_branch2_ops,
490 		},
491 	},
492 };
493 
494 static struct clk_branch video_cc_mvs0a_clk = {
495 	.halt_reg = 0x8090,
496 	.halt_check = BRANCH_HALT_VOTED,
497 	.hwcg_reg = 0x8090,
498 	.hwcg_bit = 1,
499 	.clkr = {
500 		.enable_reg = 0x8090,
501 		.enable_mask = BIT(0),
502 		.hw.init = &(const struct clk_init_data) {
503 			.name = "video_cc_mvs0a_clk",
504 			.parent_hws = (const struct clk_hw*[]) {
505 				&video_cc_mvs0a_clk_src.clkr.hw,
506 			},
507 			.num_parents = 1,
508 			.flags = CLK_SET_RATE_PARENT,
509 			.ops = &clk_branch2_ops,
510 		},
511 	},
512 };
513 
514 static struct clk_branch video_cc_mvs0a_freerun_clk = {
515 	.halt_reg = 0x80a0,
516 	.halt_check = BRANCH_HALT,
517 	.clkr = {
518 		.enable_reg = 0x80a0,
519 		.enable_mask = BIT(0),
520 		.hw.init = &(const struct clk_init_data) {
521 			.name = "video_cc_mvs0a_freerun_clk",
522 			.parent_hws = (const struct clk_hw*[]) {
523 				&video_cc_mvs0a_clk_src.clkr.hw,
524 			},
525 			.num_parents = 1,
526 			.flags = CLK_SET_RATE_PARENT,
527 			.ops = &clk_branch2_ops,
528 		},
529 	},
530 };
531 
532 static struct clk_branch video_cc_mvs0b_clk = {
533 	.halt_reg = 0x80bc,
534 	.halt_check = BRANCH_HALT_VOTED,
535 	.hwcg_reg = 0x80bc,
536 	.hwcg_bit = 1,
537 	.clkr = {
538 		.enable_reg = 0x80bc,
539 		.enable_mask = BIT(0),
540 		.hw.init = &(const struct clk_init_data) {
541 			.name = "video_cc_mvs0b_clk",
542 			.parent_hws = (const struct clk_hw*[]) {
543 				&video_cc_mvs0b_clk_src.clkr.hw,
544 			},
545 			.num_parents = 1,
546 			.flags = CLK_SET_RATE_PARENT,
547 			.ops = &clk_branch2_ops,
548 		},
549 	},
550 };
551 
552 static struct clk_branch video_cc_mvs0b_freerun_clk = {
553 	.halt_reg = 0x80cc,
554 	.halt_check = BRANCH_HALT,
555 	.clkr = {
556 		.enable_reg = 0x80cc,
557 		.enable_mask = BIT(0),
558 		.hw.init = &(const struct clk_init_data) {
559 			.name = "video_cc_mvs0b_freerun_clk",
560 			.parent_hws = (const struct clk_hw*[]) {
561 				&video_cc_mvs0b_clk_src.clkr.hw,
562 			},
563 			.num_parents = 1,
564 			.flags = CLK_SET_RATE_PARENT,
565 			.ops = &clk_branch2_ops,
566 		},
567 	},
568 };
569 
570 static struct clk_branch video_cc_mvs0c_clk = {
571 	.halt_reg = 0x8164,
572 	.halt_check = BRANCH_HALT_VOTED,
573 	.hwcg_reg = 0x8164,
574 	.hwcg_bit = 1,
575 	.clkr = {
576 		.enable_reg = 0x8164,
577 		.enable_mask = BIT(0),
578 		.hw.init = &(const struct clk_init_data) {
579 			.name = "video_cc_mvs0c_clk",
580 			.parent_hws = (const struct clk_hw*[]) {
581 				&video_cc_mvs0c_clk_src.clkr.hw,
582 			},
583 			.num_parents = 1,
584 			.flags = CLK_SET_RATE_PARENT,
585 			.ops = &clk_branch2_ops,
586 		},
587 	},
588 };
589 
590 static struct clk_branch video_cc_mvs0c_freerun_clk = {
591 	.halt_reg = 0x8174,
592 	.halt_check = BRANCH_HALT,
593 	.clkr = {
594 		.enable_reg = 0x8174,
595 		.enable_mask = BIT(0),
596 		.hw.init = &(const struct clk_init_data) {
597 			.name = "video_cc_mvs0c_freerun_clk",
598 			.parent_hws = (const struct clk_hw*[]) {
599 				&video_cc_mvs0c_clk_src.clkr.hw,
600 			},
601 			.num_parents = 1,
602 			.flags = CLK_SET_RATE_PARENT,
603 			.ops = &clk_branch2_ops,
604 		},
605 	},
606 };
607 
608 static struct clk_branch video_cc_mvs0c_shift_clk = {
609 	.halt_reg = 0x81b8,
610 	.halt_check = BRANCH_HALT_VOTED,
611 	.hwcg_reg = 0x81b8,
612 	.hwcg_bit = 1,
613 	.clkr = {
614 		.enable_reg = 0x81b8,
615 		.enable_mask = BIT(0),
616 		.hw.init = &(const struct clk_init_data) {
617 			.name = "video_cc_mvs0c_shift_clk",
618 			.parent_hws = (const struct clk_hw*[]) {
619 				&video_cc_xo_clk_src.clkr.hw,
620 			},
621 			.num_parents = 1,
622 			.flags = CLK_SET_RATE_PARENT,
623 			.ops = &clk_branch2_ops,
624 		},
625 	},
626 };
627 
628 static struct gdsc video_cc_mvs0_vpp0_gdsc = {
629 	.gdscr = 0x8120,
630 	.en_rest_wait_val = 0x2,
631 	.en_few_wait_val = 0x2,
632 	.clk_dis_wait_val = 0xf,
633 	.pd = {
634 		.name = "video_cc_mvs0_vpp0_gdsc",
635 	},
636 	.pwrsts = PWRSTS_OFF_ON,
637 	.flags = HW_CTRL_TRIGGER | POLL_CFG_GDSCR | RETAIN_FF_ENABLE,
638 };
639 
640 static struct gdsc video_cc_mvs0_vpp1_gdsc = {
641 	.gdscr = 0x80f4,
642 	.en_rest_wait_val = 0x2,
643 	.en_few_wait_val = 0x2,
644 	.clk_dis_wait_val = 0xf,
645 	.pd = {
646 		.name = "video_cc_mvs0_vpp1_gdsc",
647 	},
648 	.pwrsts = PWRSTS_OFF_ON,
649 	.flags = HW_CTRL_TRIGGER | POLL_CFG_GDSCR | RETAIN_FF_ENABLE,
650 };
651 
652 static struct gdsc video_cc_mvs0a_gdsc = {
653 	.gdscr = 0x807c,
654 	.en_rest_wait_val = 0x2,
655 	.en_few_wait_val = 0x2,
656 	.clk_dis_wait_val = 0xf,
657 	.pd = {
658 		.name = "video_cc_mvs0a_gdsc",
659 	},
660 	.pwrsts = PWRSTS_OFF_ON,
661 	.flags = HW_CTRL_TRIGGER | POLL_CFG_GDSCR | RETAIN_FF_ENABLE,
662 };
663 
664 static struct gdsc video_cc_mvs0c_gdsc = {
665 	.gdscr = 0x814c,
666 	.en_rest_wait_val = 0x2,
667 	.en_few_wait_val = 0x2,
668 	.clk_dis_wait_val = 0x6,
669 	.pd = {
670 		.name = "video_cc_mvs0c_gdsc",
671 	},
672 	.pwrsts = PWRSTS_OFF_ON,
673 	.flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE,
674 };
675 
676 static struct gdsc video_cc_mvs0_gdsc = {
677 	.gdscr = 0x80a8,
678 	.en_rest_wait_val = 0x2,
679 	.en_few_wait_val = 0x2,
680 	.clk_dis_wait_val = 0x6,
681 	.pd = {
682 		.name = "video_cc_mvs0_gdsc",
683 	},
684 	.pwrsts = PWRSTS_OFF_ON,
685 	.parent = &video_cc_mvs0c_gdsc.pd,
686 	.flags = HW_CTRL_TRIGGER | POLL_CFG_GDSCR | RETAIN_FF_ENABLE,
687 };
688 
689 static struct clk_regmap *video_cc_kaanapali_clocks[] = {
690 	[VIDEO_CC_AHB_CLK_SRC] = &video_cc_ahb_clk_src.clkr,
691 	[VIDEO_CC_MVS0_CLK] = &video_cc_mvs0_clk.clkr,
692 	[VIDEO_CC_MVS0_CLK_SRC] = &video_cc_mvs0_clk_src.clkr,
693 	[VIDEO_CC_MVS0_FREERUN_CLK] = &video_cc_mvs0_freerun_clk.branch.clkr,
694 	[VIDEO_CC_MVS0_SHIFT_CLK] = &video_cc_mvs0_shift_clk.clkr,
695 	[VIDEO_CC_MVS0_VPP0_CLK] = &video_cc_mvs0_vpp0_clk.clkr,
696 	[VIDEO_CC_MVS0_VPP0_FREERUN_CLK] = &video_cc_mvs0_vpp0_freerun_clk.clkr,
697 	[VIDEO_CC_MVS0_VPP1_CLK] = &video_cc_mvs0_vpp1_clk.clkr,
698 	[VIDEO_CC_MVS0_VPP1_FREERUN_CLK] = &video_cc_mvs0_vpp1_freerun_clk.clkr,
699 	[VIDEO_CC_MVS0A_CLK] = &video_cc_mvs0a_clk.clkr,
700 	[VIDEO_CC_MVS0A_CLK_SRC] = &video_cc_mvs0a_clk_src.clkr,
701 	[VIDEO_CC_MVS0A_FREERUN_CLK] = &video_cc_mvs0a_freerun_clk.clkr,
702 	[VIDEO_CC_MVS0B_CLK] = &video_cc_mvs0b_clk.clkr,
703 	[VIDEO_CC_MVS0B_CLK_SRC] = &video_cc_mvs0b_clk_src.clkr,
704 	[VIDEO_CC_MVS0B_FREERUN_CLK] = &video_cc_mvs0b_freerun_clk.clkr,
705 	[VIDEO_CC_MVS0C_CLK] = &video_cc_mvs0c_clk.clkr,
706 	[VIDEO_CC_MVS0C_CLK_SRC] = &video_cc_mvs0c_clk_src.clkr,
707 	[VIDEO_CC_MVS0C_FREERUN_CLK] = &video_cc_mvs0c_freerun_clk.clkr,
708 	[VIDEO_CC_MVS0C_SHIFT_CLK] = &video_cc_mvs0c_shift_clk.clkr,
709 	[VIDEO_CC_PLL0] = &video_cc_pll0.clkr,
710 	[VIDEO_CC_PLL1] = &video_cc_pll1.clkr,
711 	[VIDEO_CC_PLL2] = &video_cc_pll2.clkr,
712 	[VIDEO_CC_PLL3] = &video_cc_pll3.clkr,
713 	[VIDEO_CC_XO_CLK_SRC] = &video_cc_xo_clk_src.clkr,
714 };
715 
716 static struct gdsc *video_cc_kaanapali_gdscs[] = {
717 	[VIDEO_CC_MVS0A_GDSC] = &video_cc_mvs0a_gdsc,
718 	[VIDEO_CC_MVS0_GDSC] = &video_cc_mvs0_gdsc,
719 	[VIDEO_CC_MVS0_VPP1_GDSC] = &video_cc_mvs0_vpp1_gdsc,
720 	[VIDEO_CC_MVS0_VPP0_GDSC] = &video_cc_mvs0_vpp0_gdsc,
721 	[VIDEO_CC_MVS0C_GDSC] = &video_cc_mvs0c_gdsc,
722 };
723 
724 static const struct qcom_reset_map video_cc_kaanapali_resets[] = {
725 	[VIDEO_CC_INTERFACE_BCR] = { 0x8178 },
726 	[VIDEO_CC_MVS0_BCR] = { 0x80a4 },
727 	[VIDEO_CC_MVS0_VPP0_BCR] = { 0x811c },
728 	[VIDEO_CC_MVS0_VPP1_BCR] = { 0x80f0 },
729 	[VIDEO_CC_MVS0A_BCR] = { 0x8078 },
730 	[VIDEO_CC_MVS0C_CLK_ARES] = { 0x8164, 2 },
731 	[VIDEO_CC_MVS0C_BCR] = { 0x8148 },
732 	[VIDEO_CC_MVS0_FREERUN_CLK_ARES] = { 0x80e0, 2 },
733 	[VIDEO_CC_MVS0C_FREERUN_CLK_ARES] = { 0x8174, 2 },
734 	[VIDEO_CC_XO_CLK_ARES] = { 0x81ac, 2 },
735 };
736 
737 static struct clk_alpha_pll *video_cc_kaanapali_plls[] = {
738 	&video_cc_pll0,
739 	&video_cc_pll1,
740 	&video_cc_pll2,
741 	&video_cc_pll3,
742 };
743 
744 static u32 video_cc_kaanapali_critical_cbcrs[] = {
745 	0x817c, /* VIDEO_CC_AHB_CLK */
746 	0x81bc, /* VIDEO_CC_SLEEP_CLK */
747 	0x81b0, /* VIDEO_CC_TS_XO_CLK */
748 	0x81ac, /* VIDEO_CC_XO_CLK */
749 };
750 
751 static const struct regmap_config video_cc_kaanapali_regmap_config = {
752 	.reg_bits = 32,
753 	.reg_stride = 4,
754 	.val_bits = 32,
755 	.max_register = 0xa010,
756 	.fast_io = true,
757 };
758 
759 static void clk_kaanapali_regs_configure(struct device *dev, struct regmap *regmap)
760 {
761 	/*
762 	 * Enable clk_on sync for MVS0 and VPP clocks via VIDEO_CC_SPARE1
763 	 * during core reset by default.
764 	 */
765 	regmap_set_bits(regmap, 0x9f24, BIT(0));
766 
767 	/*
768 	 *	As per HW design recommendation
769 	 *	Update DLY_ACCU_RED_SHIFTER_DONE to 0xF for the below GDSCs
770 	 *	MVS0A CFG3, MVS0 CFG3, MVS0 VPP1 CFG3, MVS0 VPP0 CFG3, MVS0C CFG3
771 	 */
772 	regmap_set_bits(regmap, 0x8088, ACCU_CFG_MASK);
773 	regmap_set_bits(regmap, 0x80b4, ACCU_CFG_MASK);
774 	regmap_set_bits(regmap, 0x8100, ACCU_CFG_MASK);
775 	regmap_set_bits(regmap, 0x812c, ACCU_CFG_MASK);
776 	regmap_set_bits(regmap, 0x8158, ACCU_CFG_MASK);
777 }
778 
779 static struct qcom_cc_driver_data video_cc_kaanapali_driver_data = {
780 	.alpha_plls = video_cc_kaanapali_plls,
781 	.num_alpha_plls = ARRAY_SIZE(video_cc_kaanapali_plls),
782 	.clk_cbcrs = video_cc_kaanapali_critical_cbcrs,
783 	.num_clk_cbcrs = ARRAY_SIZE(video_cc_kaanapali_critical_cbcrs),
784 	.clk_regs_configure = clk_kaanapali_regs_configure,
785 };
786 
787 static const struct qcom_cc_desc video_cc_kaanapali_desc = {
788 	.config = &video_cc_kaanapali_regmap_config,
789 	.clks = video_cc_kaanapali_clocks,
790 	.num_clks = ARRAY_SIZE(video_cc_kaanapali_clocks),
791 	.resets = video_cc_kaanapali_resets,
792 	.num_resets = ARRAY_SIZE(video_cc_kaanapali_resets),
793 	.gdscs = video_cc_kaanapali_gdscs,
794 	.num_gdscs = ARRAY_SIZE(video_cc_kaanapali_gdscs),
795 	.use_rpm = true,
796 	.driver_data = &video_cc_kaanapali_driver_data,
797 };
798 
799 static const struct of_device_id video_cc_kaanapali_match_table[] = {
800 	{ .compatible = "qcom,kaanapali-videocc" },
801 	{ }
802 };
803 MODULE_DEVICE_TABLE(of, video_cc_kaanapali_match_table);
804 
805 static int video_cc_kaanapali_probe(struct platform_device *pdev)
806 {
807 	return qcom_cc_probe(pdev, &video_cc_kaanapali_desc);
808 }
809 
810 static struct platform_driver video_cc_kaanapali_driver = {
811 	.probe = video_cc_kaanapali_probe,
812 	.driver = {
813 		.name = "videocc-kaanapali",
814 		.of_match_table = video_cc_kaanapali_match_table,
815 	},
816 };
817 
818 module_platform_driver(video_cc_kaanapali_driver);
819 
820 MODULE_DESCRIPTION("QTI VIDEOCC Kaanapali Driver");
821 MODULE_LICENSE("GPL");
822