xref: /linux/drivers/clk/qcom/dispcc-sm6350.c (revision e814f3fd16acfb7f9966773953de8f740a1e3202)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (c) 2021, The Linux Foundation. All rights reserved.
4  * Copyright (c) 2021, Konrad Dybcio <konrad.dybcio@somainline.org>
5  */
6 
7 #include <linux/clk-provider.h>
8 #include <linux/module.h>
9 #include <linux/platform_device.h>
10 #include <linux/regmap.h>
11 
12 #include <dt-bindings/clock/qcom,dispcc-sm6350.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 	P_BI_TCXO,
25 	P_DISP_CC_PLL0_OUT_EVEN,
26 	P_DISP_CC_PLL0_OUT_MAIN,
27 	P_DP_PHY_PLL_LINK_CLK,
28 	P_DP_PHY_PLL_VCO_DIV_CLK,
29 	P_DSI0_PHY_PLL_OUT_BYTECLK,
30 	P_DSI0_PHY_PLL_OUT_DSICLK,
31 	P_GCC_DISP_GPLL0_CLK,
32 };
33 
34 static const struct pll_vco fabia_vco[] = {
35 	{ 249600000, 2000000000, 0 },
36 };
37 
38 static const struct alpha_pll_config disp_cc_pll0_config = {
39 	.l = 0x3a,
40 	.alpha = 0x5555,
41 	.config_ctl_val = 0x20485699,
42 	.config_ctl_hi_val = 0x00002067,
43 	.test_ctl_val = 0x40000000,
44 	.test_ctl_hi_val = 0x00000002,
45 	.user_ctl_val = 0x00000000,
46 	.user_ctl_hi_val = 0x00004805,
47 };
48 
49 static struct clk_alpha_pll disp_cc_pll0 = {
50 	.offset = 0x0,
51 	.vco_table = fabia_vco,
52 	.num_vco = ARRAY_SIZE(fabia_vco),
53 	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
54 	.clkr = {
55 		.hw.init = &(struct clk_init_data){
56 			.name = "disp_cc_pll0",
57 			.parent_data = &(const struct clk_parent_data){
58 				.fw_name = "bi_tcxo",
59 			},
60 			.num_parents = 1,
61 			.ops = &clk_alpha_pll_fabia_ops,
62 		},
63 	},
64 };
65 
66 static const struct parent_map disp_cc_parent_map_0[] = {
67 	{ P_BI_TCXO, 0 },
68 	{ P_DP_PHY_PLL_LINK_CLK, 1 },
69 	{ P_DP_PHY_PLL_VCO_DIV_CLK, 2 },
70 };
71 
72 static const struct clk_parent_data disp_cc_parent_data_0[] = {
73 	{ .fw_name = "bi_tcxo" },
74 	{ .fw_name = "dp_phy_pll_link_clk" },
75 	{ .fw_name = "dp_phy_pll_vco_div_clk" },
76 };
77 
78 static const struct parent_map disp_cc_parent_map_1[] = {
79 	{ P_BI_TCXO, 0 },
80 	{ P_DSI0_PHY_PLL_OUT_BYTECLK, 1 },
81 };
82 
83 static const struct clk_parent_data disp_cc_parent_data_1[] = {
84 	{ .fw_name = "bi_tcxo" },
85 	{ .fw_name = "dsi0_phy_pll_out_byteclk" },
86 };
87 
88 static const struct parent_map disp_cc_parent_map_3[] = {
89 	{ P_BI_TCXO, 0 },
90 	{ P_DISP_CC_PLL0_OUT_MAIN, 1 },
91 	{ P_GCC_DISP_GPLL0_CLK, 4 },
92 	{ P_DISP_CC_PLL0_OUT_EVEN, 5 },
93 };
94 
95 static const struct clk_parent_data disp_cc_parent_data_3[] = {
96 	{ .fw_name = "bi_tcxo" },
97 	{ .hw = &disp_cc_pll0.clkr.hw },
98 	{ .fw_name = "gcc_disp_gpll0_clk" },
99 	{ .hw = &disp_cc_pll0.clkr.hw },
100 };
101 
102 static const struct parent_map disp_cc_parent_map_4[] = {
103 	{ P_BI_TCXO, 0 },
104 	{ P_GCC_DISP_GPLL0_CLK, 4 },
105 };
106 
107 static const struct clk_parent_data disp_cc_parent_data_4[] = {
108 	{ .fw_name = "bi_tcxo" },
109 	{ .fw_name = "gcc_disp_gpll0_clk" },
110 };
111 
112 static const struct parent_map disp_cc_parent_map_5[] = {
113 	{ P_BI_TCXO, 0 },
114 	{ P_DSI0_PHY_PLL_OUT_DSICLK, 1 },
115 };
116 
117 static const struct clk_parent_data disp_cc_parent_data_5[] = {
118 	{ .fw_name = "bi_tcxo" },
119 	{ .fw_name = "dsi0_phy_pll_out_dsiclk" },
120 };
121 
122 static const struct parent_map disp_cc_parent_map_6[] = {
123 	{ P_BI_TCXO, 0 },
124 };
125 
126 static const struct clk_parent_data disp_cc_parent_data_6[] = {
127 	{ .fw_name = "bi_tcxo" },
128 };
129 
130 static const struct freq_tbl ftbl_disp_cc_mdss_ahb_clk_src[] = {
131 	F(19200000, P_BI_TCXO, 1, 0, 0),
132 	F(37500000, P_GCC_DISP_GPLL0_CLK, 16, 0, 0),
133 	F(75000000, P_GCC_DISP_GPLL0_CLK, 8, 0, 0),
134 	{ }
135 };
136 
137 static struct clk_rcg2 disp_cc_mdss_ahb_clk_src = {
138 	.cmd_rcgr = 0x115c,
139 	.mnd_width = 0,
140 	.hid_width = 5,
141 	.parent_map = disp_cc_parent_map_4,
142 	.freq_tbl = ftbl_disp_cc_mdss_ahb_clk_src,
143 	.clkr.hw.init = &(struct clk_init_data){
144 		.name = "disp_cc_mdss_ahb_clk_src",
145 		.parent_data = disp_cc_parent_data_4,
146 		.num_parents = ARRAY_SIZE(disp_cc_parent_data_4),
147 		.flags = CLK_SET_RATE_PARENT,
148 		.ops = &clk_rcg2_ops,
149 	},
150 };
151 
152 static struct clk_rcg2 disp_cc_mdss_byte0_clk_src = {
153 	.cmd_rcgr = 0x10c4,
154 	.mnd_width = 0,
155 	.hid_width = 5,
156 	.parent_map = disp_cc_parent_map_1,
157 	.clkr.hw.init = &(struct clk_init_data){
158 		.name = "disp_cc_mdss_byte0_clk_src",
159 		.parent_data = disp_cc_parent_data_1,
160 		.num_parents = ARRAY_SIZE(disp_cc_parent_data_1),
161 		.flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE,
162 		.ops = &clk_byte2_ops,
163 	},
164 };
165 
166 static struct clk_regmap_div disp_cc_mdss_byte0_div_clk_src = {
167 	.reg = 0x10dc,
168 	.shift = 0,
169 	.width = 2,
170 	.clkr.hw.init = &(struct clk_init_data) {
171 		.name = "disp_cc_mdss_byte0_div_clk_src",
172 		.parent_hws = (const struct clk_hw*[]){
173 			&disp_cc_mdss_byte0_clk_src.clkr.hw,
174 		},
175 		.num_parents = 1,
176 		.flags = CLK_GET_RATE_NOCACHE,
177 		.ops = &clk_regmap_div_ro_ops,
178 	},
179 };
180 
181 static const struct freq_tbl ftbl_disp_cc_mdss_dp_aux_clk_src[] = {
182 	F(19200000, P_BI_TCXO, 1, 0, 0),
183 	{ }
184 };
185 
186 static struct clk_rcg2 disp_cc_mdss_dp_aux_clk_src = {
187 	.cmd_rcgr = 0x1144,
188 	.mnd_width = 0,
189 	.hid_width = 5,
190 	.parent_map = disp_cc_parent_map_6,
191 	.freq_tbl = ftbl_disp_cc_mdss_dp_aux_clk_src,
192 	.clkr.hw.init = &(struct clk_init_data){
193 		.name = "disp_cc_mdss_dp_aux_clk_src",
194 		.parent_data = disp_cc_parent_data_6,
195 		.num_parents = ARRAY_SIZE(disp_cc_parent_data_6),
196 		.ops = &clk_rcg2_ops,
197 	},
198 };
199 
200 static const struct freq_tbl ftbl_disp_cc_mdss_dp_crypto_clk_src[] = {
201 	F(108000, P_DP_PHY_PLL_LINK_CLK, 3, 0, 0),
202 	F(180000, P_DP_PHY_PLL_LINK_CLK, 3, 0, 0),
203 	F(360000, P_DP_PHY_PLL_LINK_CLK, 1.5, 0, 0),
204 	F(540000, P_DP_PHY_PLL_LINK_CLK, 1.5, 0, 0),
205 	{ }
206 };
207 
208 static struct clk_rcg2 disp_cc_mdss_dp_crypto_clk_src = {
209 	.cmd_rcgr = 0x1114,
210 	.mnd_width = 0,
211 	.hid_width = 5,
212 	.parent_map = disp_cc_parent_map_0,
213 	.freq_tbl = ftbl_disp_cc_mdss_dp_crypto_clk_src,
214 	.clkr.hw.init = &(struct clk_init_data){
215 		.name = "disp_cc_mdss_dp_crypto_clk_src",
216 		.parent_data = disp_cc_parent_data_0,
217 		.num_parents = ARRAY_SIZE(disp_cc_parent_data_0),
218 		.flags = CLK_GET_RATE_NOCACHE,
219 		.ops = &clk_rcg2_ops,
220 	},
221 };
222 
223 static struct clk_rcg2 disp_cc_mdss_dp_link_clk_src = {
224 	.cmd_rcgr = 0x10f8,
225 	.mnd_width = 0,
226 	.hid_width = 5,
227 	.parent_map = disp_cc_parent_map_0,
228 	.clkr.hw.init = &(struct clk_init_data){
229 		.name = "disp_cc_mdss_dp_link_clk_src",
230 		.parent_data = disp_cc_parent_data_0,
231 		.num_parents = ARRAY_SIZE(disp_cc_parent_data_0),
232 		.flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE,
233 		.ops = &clk_byte2_ops,
234 	},
235 };
236 
237 static struct clk_rcg2 disp_cc_mdss_dp_pixel_clk_src = {
238 	.cmd_rcgr = 0x112c,
239 	.mnd_width = 16,
240 	.hid_width = 5,
241 	.parent_map = disp_cc_parent_map_0,
242 	.clkr.hw.init = &(struct clk_init_data){
243 		.name = "disp_cc_mdss_dp_pixel_clk_src",
244 		.parent_data = disp_cc_parent_data_0,
245 		.num_parents = ARRAY_SIZE(disp_cc_parent_data_0),
246 		.flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE,
247 		.ops = &clk_dp_ops,
248 	},
249 };
250 
251 static struct clk_rcg2 disp_cc_mdss_esc0_clk_src = {
252 	.cmd_rcgr = 0x10e0,
253 	.mnd_width = 0,
254 	.hid_width = 5,
255 	.parent_map = disp_cc_parent_map_1,
256 	.freq_tbl = ftbl_disp_cc_mdss_dp_aux_clk_src,
257 	.clkr.hw.init = &(struct clk_init_data){
258 		.name = "disp_cc_mdss_esc0_clk_src",
259 		.parent_data = disp_cc_parent_data_1,
260 		.num_parents = ARRAY_SIZE(disp_cc_parent_data_1),
261 		.ops = &clk_rcg2_ops,
262 	},
263 };
264 
265 static const struct freq_tbl ftbl_disp_cc_mdss_mdp_clk_src[] = {
266 	F(19200000, P_BI_TCXO, 1, 0, 0),
267 	F(200000000, P_GCC_DISP_GPLL0_CLK, 3, 0, 0),
268 	F(300000000, P_GCC_DISP_GPLL0_CLK, 2, 0, 0),
269 	F(373333333, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0),
270 	F(448000000, P_DISP_CC_PLL0_OUT_MAIN, 2.5, 0, 0),
271 	F(560000000, P_DISP_CC_PLL0_OUT_MAIN, 2, 0, 0),
272 	{ }
273 };
274 
275 static struct clk_rcg2 disp_cc_mdss_mdp_clk_src = {
276 	.cmd_rcgr = 0x107c,
277 	.mnd_width = 0,
278 	.hid_width = 5,
279 	.parent_map = disp_cc_parent_map_3,
280 	.freq_tbl = ftbl_disp_cc_mdss_mdp_clk_src,
281 	.clkr.hw.init = &(struct clk_init_data){
282 		.name = "disp_cc_mdss_mdp_clk_src",
283 		.parent_data = disp_cc_parent_data_3,
284 		.num_parents = ARRAY_SIZE(disp_cc_parent_data_3),
285 		.flags = CLK_SET_RATE_PARENT,
286 		.ops = &clk_rcg2_ops,
287 	},
288 };
289 
290 static struct clk_rcg2 disp_cc_mdss_pclk0_clk_src = {
291 	.cmd_rcgr = 0x1064,
292 	.mnd_width = 8,
293 	.hid_width = 5,
294 	.parent_map = disp_cc_parent_map_5,
295 	.clkr.hw.init = &(struct clk_init_data){
296 		.name = "disp_cc_mdss_pclk0_clk_src",
297 		.parent_data = disp_cc_parent_data_5,
298 		.num_parents = ARRAY_SIZE(disp_cc_parent_data_5),
299 		.flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE | CLK_OPS_PARENT_ENABLE,
300 		.ops = &clk_pixel_ops,
301 	},
302 };
303 
304 static struct clk_rcg2 disp_cc_mdss_rot_clk_src = {
305 	.cmd_rcgr = 0x1094,
306 	.mnd_width = 0,
307 	.hid_width = 5,
308 	.parent_map = disp_cc_parent_map_3,
309 	.freq_tbl = ftbl_disp_cc_mdss_mdp_clk_src,
310 	.clkr.hw.init = &(struct clk_init_data){
311 		.name = "disp_cc_mdss_rot_clk_src",
312 		.parent_data = disp_cc_parent_data_3,
313 		.num_parents = ARRAY_SIZE(disp_cc_parent_data_3),
314 		.flags = CLK_SET_RATE_PARENT,
315 		.ops = &clk_rcg2_ops,
316 	},
317 };
318 
319 static struct clk_rcg2 disp_cc_mdss_vsync_clk_src = {
320 	.cmd_rcgr = 0x10ac,
321 	.mnd_width = 0,
322 	.hid_width = 5,
323 	.parent_map = disp_cc_parent_map_6,
324 	.freq_tbl = ftbl_disp_cc_mdss_dp_aux_clk_src,
325 	.clkr.hw.init = &(struct clk_init_data){
326 		.name = "disp_cc_mdss_vsync_clk_src",
327 		.parent_data = disp_cc_parent_data_6,
328 		.num_parents = ARRAY_SIZE(disp_cc_parent_data_6),
329 		.ops = &clk_rcg2_ops,
330 	},
331 };
332 
333 static struct clk_regmap_div disp_cc_mdss_dp_link_div_clk_src = {
334 	.reg = 0x1110,
335 	.shift = 0,
336 	.width = 2,
337 	.clkr.hw.init = &(struct clk_init_data) {
338 		.name = "disp_cc_mdss_dp_link_div_clk_src",
339 		.parent_hws = (const struct clk_hw*[]){
340 			&disp_cc_mdss_dp_link_clk_src.clkr.hw,
341 		},
342 		.num_parents = 1,
343 		.flags = CLK_GET_RATE_NOCACHE,
344 		.ops = &clk_regmap_div_ro_ops,
345 	},
346 };
347 
348 static struct clk_branch disp_cc_mdss_ahb_clk = {
349 	.halt_reg = 0x104c,
350 	.halt_check = BRANCH_HALT,
351 	.clkr = {
352 		.enable_reg = 0x104c,
353 		.enable_mask = BIT(0),
354 		.hw.init = &(struct clk_init_data){
355 			.name = "disp_cc_mdss_ahb_clk",
356 			.parent_hws = (const struct clk_hw*[]){
357 				&disp_cc_mdss_ahb_clk_src.clkr.hw,
358 			},
359 			.num_parents = 1,
360 			.flags = CLK_SET_RATE_PARENT,
361 			.ops = &clk_branch2_ops,
362 		},
363 	},
364 };
365 
366 static struct clk_branch disp_cc_mdss_byte0_clk = {
367 	.halt_reg = 0x102c,
368 	.halt_check = BRANCH_HALT,
369 	.clkr = {
370 		.enable_reg = 0x102c,
371 		.enable_mask = BIT(0),
372 		.hw.init = &(struct clk_init_data){
373 			.name = "disp_cc_mdss_byte0_clk",
374 			.parent_hws = (const struct clk_hw*[]){
375 				&disp_cc_mdss_byte0_clk_src.clkr.hw,
376 			},
377 			.num_parents = 1,
378 			.flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE | CLK_OPS_PARENT_ENABLE,
379 			.ops = &clk_branch2_ops,
380 		},
381 	},
382 };
383 
384 static struct clk_branch disp_cc_mdss_byte0_intf_clk = {
385 	.halt_reg = 0x1030,
386 	.halt_check = BRANCH_HALT,
387 	.clkr = {
388 		.enable_reg = 0x1030,
389 		.enable_mask = BIT(0),
390 		.hw.init = &(struct clk_init_data){
391 			.name = "disp_cc_mdss_byte0_intf_clk",
392 			.parent_hws = (const struct clk_hw*[]){
393 				&disp_cc_mdss_byte0_div_clk_src.clkr.hw,
394 			},
395 			.num_parents = 1,
396 			.flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE,
397 			.ops = &clk_branch2_ops,
398 		},
399 	},
400 };
401 
402 static struct clk_branch disp_cc_mdss_dp_aux_clk = {
403 	.halt_reg = 0x1048,
404 	.halt_check = BRANCH_HALT,
405 	.clkr = {
406 		.enable_reg = 0x1048,
407 		.enable_mask = BIT(0),
408 		.hw.init = &(struct clk_init_data){
409 			.name = "disp_cc_mdss_dp_aux_clk",
410 			.parent_hws = (const struct clk_hw*[]){
411 				&disp_cc_mdss_dp_aux_clk_src.clkr.hw,
412 			},
413 			.num_parents = 1,
414 			.flags = CLK_SET_RATE_PARENT,
415 			.ops = &clk_branch2_ops,
416 		},
417 	},
418 };
419 
420 static struct clk_branch disp_cc_mdss_dp_crypto_clk = {
421 	.halt_reg = 0x1040,
422 	.halt_check = BRANCH_HALT,
423 	.clkr = {
424 		.enable_reg = 0x1040,
425 		.enable_mask = BIT(0),
426 		.hw.init = &(struct clk_init_data){
427 			.name = "disp_cc_mdss_dp_crypto_clk",
428 			.parent_hws = (const struct clk_hw*[]){
429 				&disp_cc_mdss_dp_crypto_clk_src.clkr.hw,
430 			},
431 			.num_parents = 1,
432 			.flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE,
433 			.ops = &clk_branch2_ops,
434 		},
435 	},
436 };
437 
438 static struct clk_branch disp_cc_mdss_dp_link_clk = {
439 	.halt_reg = 0x1038,
440 	.halt_check = BRANCH_HALT,
441 	.clkr = {
442 		.enable_reg = 0x1038,
443 		.enable_mask = BIT(0),
444 		.hw.init = &(struct clk_init_data){
445 			.name = "disp_cc_mdss_dp_link_clk",
446 			.parent_hws = (const struct clk_hw*[]){
447 				&disp_cc_mdss_dp_link_clk_src.clkr.hw,
448 			},
449 			.num_parents = 1,
450 			.flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE,
451 			.ops = &clk_branch2_ops,
452 		},
453 	},
454 };
455 
456 static struct clk_branch disp_cc_mdss_dp_link_intf_clk = {
457 	.halt_reg = 0x103c,
458 	.halt_check = BRANCH_HALT,
459 	.clkr = {
460 		.enable_reg = 0x103c,
461 		.enable_mask = BIT(0),
462 		.hw.init = &(struct clk_init_data){
463 			.name = "disp_cc_mdss_dp_link_intf_clk",
464 			.parent_hws = (const struct clk_hw*[]){
465 				&disp_cc_mdss_dp_link_div_clk_src.clkr.hw,
466 			},
467 			.num_parents = 1,
468 			.flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE,
469 			.ops = &clk_branch2_ops,
470 		},
471 	},
472 };
473 
474 static struct clk_branch disp_cc_mdss_dp_pixel_clk = {
475 	.halt_reg = 0x1044,
476 	.halt_check = BRANCH_HALT,
477 	.clkr = {
478 		.enable_reg = 0x1044,
479 		.enable_mask = BIT(0),
480 		.hw.init = &(struct clk_init_data){
481 			.name = "disp_cc_mdss_dp_pixel_clk",
482 			.parent_hws = (const struct clk_hw*[]){
483 				&disp_cc_mdss_dp_pixel_clk_src.clkr.hw,
484 			},
485 			.num_parents = 1,
486 			.flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE,
487 			.ops = &clk_branch2_ops,
488 		},
489 	},
490 };
491 
492 static struct clk_branch disp_cc_mdss_esc0_clk = {
493 	.halt_reg = 0x1034,
494 	.halt_check = BRANCH_HALT,
495 	.clkr = {
496 		.enable_reg = 0x1034,
497 		.enable_mask = BIT(0),
498 		.hw.init = &(struct clk_init_data){
499 			.name = "disp_cc_mdss_esc0_clk",
500 			.parent_hws = (const struct clk_hw*[]){
501 				&disp_cc_mdss_esc0_clk_src.clkr.hw,
502 			},
503 			.num_parents = 1,
504 			.flags = CLK_SET_RATE_PARENT,
505 			.ops = &clk_branch2_ops,
506 		},
507 	},
508 };
509 
510 static struct clk_branch disp_cc_mdss_mdp_clk = {
511 	.halt_reg = 0x1010,
512 	.halt_check = BRANCH_HALT,
513 	.clkr = {
514 		.enable_reg = 0x1010,
515 		.enable_mask = BIT(0),
516 		.hw.init = &(struct clk_init_data){
517 			.name = "disp_cc_mdss_mdp_clk",
518 			.parent_hws = (const struct clk_hw*[]){
519 				&disp_cc_mdss_mdp_clk_src.clkr.hw,
520 			},
521 			.num_parents = 1,
522 			.flags = CLK_SET_RATE_PARENT,
523 			.ops = &clk_branch2_ops,
524 		},
525 	},
526 };
527 
528 static struct clk_branch disp_cc_mdss_mdp_lut_clk = {
529 	.halt_reg = 0x1020,
530 	.halt_check = BRANCH_HALT_VOTED,
531 	.clkr = {
532 		.enable_reg = 0x1020,
533 		.enable_mask = BIT(0),
534 		.hw.init = &(struct clk_init_data){
535 			.name = "disp_cc_mdss_mdp_lut_clk",
536 			.parent_hws = (const struct clk_hw*[]){
537 				&disp_cc_mdss_mdp_clk_src.clkr.hw,
538 			},
539 			.num_parents = 1,
540 			.flags = CLK_SET_RATE_PARENT,
541 			.ops = &clk_branch2_ops,
542 		},
543 	},
544 };
545 
546 static struct clk_branch disp_cc_mdss_non_gdsc_ahb_clk = {
547 	.halt_reg = 0x2004,
548 	.halt_check = BRANCH_HALT_VOTED,
549 	.clkr = {
550 		.enable_reg = 0x2004,
551 		.enable_mask = BIT(0),
552 		.hw.init = &(struct clk_init_data){
553 			.name = "disp_cc_mdss_non_gdsc_ahb_clk",
554 			.parent_hws = (const struct clk_hw*[]){
555 				&disp_cc_mdss_ahb_clk_src.clkr.hw,
556 			},
557 			.num_parents = 1,
558 			.flags = CLK_SET_RATE_PARENT,
559 			.ops = &clk_branch2_ops,
560 		},
561 	},
562 };
563 
564 static struct clk_branch disp_cc_mdss_pclk0_clk = {
565 	.halt_reg = 0x100c,
566 	.halt_check = BRANCH_HALT,
567 	.clkr = {
568 		.enable_reg = 0x100c,
569 		.enable_mask = BIT(0),
570 		.hw.init = &(struct clk_init_data){
571 			.name = "disp_cc_mdss_pclk0_clk",
572 			.parent_hws = (const struct clk_hw*[]){
573 				&disp_cc_mdss_pclk0_clk_src.clkr.hw,
574 			},
575 			.num_parents = 1,
576 			.flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE,
577 			.ops = &clk_branch2_ops,
578 		},
579 	},
580 };
581 
582 static struct clk_branch disp_cc_mdss_rot_clk = {
583 	.halt_reg = 0x1018,
584 	.halt_check = BRANCH_HALT,
585 	.clkr = {
586 		.enable_reg = 0x1018,
587 		.enable_mask = BIT(0),
588 		.hw.init = &(struct clk_init_data){
589 			.name = "disp_cc_mdss_rot_clk",
590 			.parent_hws = (const struct clk_hw*[]){
591 				&disp_cc_mdss_rot_clk_src.clkr.hw,
592 			},
593 			.num_parents = 1,
594 			.flags = CLK_SET_RATE_PARENT,
595 			.ops = &clk_branch2_ops,
596 		},
597 	},
598 };
599 
600 static struct clk_branch disp_cc_mdss_rscc_ahb_clk = {
601 	.halt_reg = 0x200c,
602 	.halt_check = BRANCH_HALT,
603 	.clkr = {
604 		.enable_reg = 0x200c,
605 		.enable_mask = BIT(0),
606 		.hw.init = &(struct clk_init_data){
607 			.name = "disp_cc_mdss_rscc_ahb_clk",
608 			.parent_hws = (const struct clk_hw*[]){
609 				&disp_cc_mdss_ahb_clk_src.clkr.hw,
610 			},
611 			.num_parents = 1,
612 			.flags = CLK_SET_RATE_PARENT,
613 			.ops = &clk_branch2_ops,
614 		},
615 	},
616 };
617 
618 static struct clk_branch disp_cc_mdss_rscc_vsync_clk = {
619 	.halt_reg = 0x2008,
620 	.halt_check = BRANCH_HALT,
621 	.clkr = {
622 		.enable_reg = 0x2008,
623 		.enable_mask = BIT(0),
624 		.hw.init = &(struct clk_init_data){
625 			.name = "disp_cc_mdss_rscc_vsync_clk",
626 			.parent_hws = (const struct clk_hw*[]){
627 				&disp_cc_mdss_vsync_clk_src.clkr.hw,
628 			},
629 			.num_parents = 1,
630 			.flags = CLK_SET_RATE_PARENT,
631 			.ops = &clk_branch2_ops,
632 		},
633 	},
634 };
635 
636 static struct clk_branch disp_cc_mdss_vsync_clk = {
637 	.halt_reg = 0x1028,
638 	.halt_check = BRANCH_HALT,
639 	.clkr = {
640 		.enable_reg = 0x1028,
641 		.enable_mask = BIT(0),
642 		.hw.init = &(struct clk_init_data){
643 			.name = "disp_cc_mdss_vsync_clk",
644 			.parent_hws = (const struct clk_hw*[]){
645 				&disp_cc_mdss_vsync_clk_src.clkr.hw,
646 			},
647 			.num_parents = 1,
648 			.flags = CLK_SET_RATE_PARENT,
649 			.ops = &clk_branch2_ops,
650 		},
651 	},
652 };
653 
654 static struct clk_branch disp_cc_sleep_clk = {
655 	.halt_reg = 0x5004,
656 	.halt_check = BRANCH_HALT,
657 	.clkr = {
658 		.enable_reg = 0x5004,
659 		.enable_mask = BIT(0),
660 		.hw.init = &(struct clk_init_data){
661 			.name = "disp_cc_sleep_clk",
662 			.ops = &clk_branch2_ops,
663 		},
664 	},
665 };
666 
667 static struct clk_branch disp_cc_xo_clk = {
668 	.halt_reg = 0x5008,
669 	.halt_check = BRANCH_HALT,
670 	.clkr = {
671 		.enable_reg = 0x5008,
672 		.enable_mask = BIT(0),
673 		.hw.init = &(struct clk_init_data){
674 			.name = "disp_cc_xo_clk",
675 			.flags = CLK_IS_CRITICAL,
676 			.ops = &clk_branch2_ops,
677 		},
678 	},
679 };
680 
681 static struct gdsc mdss_gdsc = {
682 	.gdscr = 0x1004,
683 	.pd = {
684 		.name = "mdss_gdsc",
685 	},
686 	.pwrsts = PWRSTS_OFF_ON,
687 	.flags = RETAIN_FF_ENABLE,
688 };
689 
690 static struct clk_regmap *disp_cc_sm6350_clocks[] = {
691 	[DISP_CC_MDSS_AHB_CLK] = &disp_cc_mdss_ahb_clk.clkr,
692 	[DISP_CC_MDSS_AHB_CLK_SRC] = &disp_cc_mdss_ahb_clk_src.clkr,
693 	[DISP_CC_MDSS_BYTE0_CLK] = &disp_cc_mdss_byte0_clk.clkr,
694 	[DISP_CC_MDSS_BYTE0_CLK_SRC] = &disp_cc_mdss_byte0_clk_src.clkr,
695 	[DISP_CC_MDSS_BYTE0_DIV_CLK_SRC] = &disp_cc_mdss_byte0_div_clk_src.clkr,
696 	[DISP_CC_MDSS_BYTE0_INTF_CLK] = &disp_cc_mdss_byte0_intf_clk.clkr,
697 	[DISP_CC_MDSS_DP_AUX_CLK] = &disp_cc_mdss_dp_aux_clk.clkr,
698 	[DISP_CC_MDSS_DP_AUX_CLK_SRC] = &disp_cc_mdss_dp_aux_clk_src.clkr,
699 	[DISP_CC_MDSS_DP_CRYPTO_CLK] = &disp_cc_mdss_dp_crypto_clk.clkr,
700 	[DISP_CC_MDSS_DP_CRYPTO_CLK_SRC] = &disp_cc_mdss_dp_crypto_clk_src.clkr,
701 	[DISP_CC_MDSS_DP_LINK_CLK] = &disp_cc_mdss_dp_link_clk.clkr,
702 	[DISP_CC_MDSS_DP_LINK_CLK_SRC] = &disp_cc_mdss_dp_link_clk_src.clkr,
703 	[DISP_CC_MDSS_DP_LINK_DIV_CLK_SRC] =
704 		&disp_cc_mdss_dp_link_div_clk_src.clkr,
705 	[DISP_CC_MDSS_DP_LINK_INTF_CLK] = &disp_cc_mdss_dp_link_intf_clk.clkr,
706 	[DISP_CC_MDSS_DP_PIXEL_CLK] = &disp_cc_mdss_dp_pixel_clk.clkr,
707 	[DISP_CC_MDSS_DP_PIXEL_CLK_SRC] = &disp_cc_mdss_dp_pixel_clk_src.clkr,
708 	[DISP_CC_MDSS_ESC0_CLK] = &disp_cc_mdss_esc0_clk.clkr,
709 	[DISP_CC_MDSS_ESC0_CLK_SRC] = &disp_cc_mdss_esc0_clk_src.clkr,
710 	[DISP_CC_MDSS_MDP_CLK] = &disp_cc_mdss_mdp_clk.clkr,
711 	[DISP_CC_MDSS_MDP_CLK_SRC] = &disp_cc_mdss_mdp_clk_src.clkr,
712 	[DISP_CC_MDSS_MDP_LUT_CLK] = &disp_cc_mdss_mdp_lut_clk.clkr,
713 	[DISP_CC_MDSS_NON_GDSC_AHB_CLK] = &disp_cc_mdss_non_gdsc_ahb_clk.clkr,
714 	[DISP_CC_MDSS_PCLK0_CLK] = &disp_cc_mdss_pclk0_clk.clkr,
715 	[DISP_CC_MDSS_PCLK0_CLK_SRC] = &disp_cc_mdss_pclk0_clk_src.clkr,
716 	[DISP_CC_MDSS_ROT_CLK] = &disp_cc_mdss_rot_clk.clkr,
717 	[DISP_CC_MDSS_ROT_CLK_SRC] = &disp_cc_mdss_rot_clk_src.clkr,
718 	[DISP_CC_MDSS_RSCC_AHB_CLK] = &disp_cc_mdss_rscc_ahb_clk.clkr,
719 	[DISP_CC_MDSS_RSCC_VSYNC_CLK] = &disp_cc_mdss_rscc_vsync_clk.clkr,
720 	[DISP_CC_MDSS_VSYNC_CLK] = &disp_cc_mdss_vsync_clk.clkr,
721 	[DISP_CC_MDSS_VSYNC_CLK_SRC] = &disp_cc_mdss_vsync_clk_src.clkr,
722 	[DISP_CC_PLL0] = &disp_cc_pll0.clkr,
723 	[DISP_CC_SLEEP_CLK] = &disp_cc_sleep_clk.clkr,
724 	[DISP_CC_XO_CLK] = &disp_cc_xo_clk.clkr,
725 };
726 
727 static struct gdsc *disp_cc_sm6350_gdscs[] = {
728 	[MDSS_GDSC] = &mdss_gdsc,
729 };
730 
731 static const struct regmap_config disp_cc_sm6350_regmap_config = {
732 	.reg_bits = 32,
733 	.reg_stride = 4,
734 	.val_bits = 32,
735 	.max_register = 0x10000,
736 	.fast_io = true,
737 };
738 
739 static const struct qcom_cc_desc disp_cc_sm6350_desc = {
740 	.config = &disp_cc_sm6350_regmap_config,
741 	.clks = disp_cc_sm6350_clocks,
742 	.num_clks = ARRAY_SIZE(disp_cc_sm6350_clocks),
743 	.gdscs = disp_cc_sm6350_gdscs,
744 	.num_gdscs = ARRAY_SIZE(disp_cc_sm6350_gdscs),
745 };
746 
747 static const struct of_device_id disp_cc_sm6350_match_table[] = {
748 	{ .compatible = "qcom,sm6350-dispcc" },
749 	{ }
750 };
751 MODULE_DEVICE_TABLE(of, disp_cc_sm6350_match_table);
752 
753 static int disp_cc_sm6350_probe(struct platform_device *pdev)
754 {
755 	struct regmap *regmap;
756 
757 	regmap = qcom_cc_map(pdev, &disp_cc_sm6350_desc);
758 	if (IS_ERR(regmap))
759 		return PTR_ERR(regmap);
760 
761 	clk_fabia_pll_configure(&disp_cc_pll0, regmap, &disp_cc_pll0_config);
762 
763 	return qcom_cc_really_probe(&pdev->dev, &disp_cc_sm6350_desc, regmap);
764 }
765 
766 static struct platform_driver disp_cc_sm6350_driver = {
767 	.probe = disp_cc_sm6350_probe,
768 	.driver = {
769 		.name = "disp_cc-sm6350",
770 		.of_match_table = disp_cc_sm6350_match_table,
771 	},
772 };
773 
774 module_platform_driver(disp_cc_sm6350_driver);
775 
776 MODULE_DESCRIPTION("QTI DISP_CC SM6350 Driver");
777 MODULE_LICENSE("GPL v2");
778