xref: /linux/drivers/clk/qcom/videocc-hawi.c (revision 502d45774af09f1c681c754c4b7cdfb5d7f72fd9)
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