xref: /linux/drivers/clk/qcom/dispcc-sm6115.c (revision e814f3fd16acfb7f9966773953de8f740a1e3202)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Based on dispcc-qcm2290.c
4  * Copyright (c) 2020, The Linux Foundation. All rights reserved.
5  * Copyright (c) 2021, Linaro Ltd.
6  */
7 
8 #include <linux/err.h>
9 #include <linux/kernel.h>
10 #include <linux/module.h>
11 #include <linux/of.h>
12 #include <linux/platform_device.h>
13 #include <linux/regmap.h>
14 
15 #include <dt-bindings/clock/qcom,sm6115-dispcc.h>
16 
17 #include "clk-alpha-pll.h"
18 #include "clk-branch.h"
19 #include "clk-rcg.h"
20 #include "clk-regmap.h"
21 #include "clk-regmap-divider.h"
22 #include "common.h"
23 #include "gdsc.h"
24 
25 enum {
26 	DT_BI_TCXO,
27 	DT_SLEEP_CLK,
28 	DT_DSI0_PHY_PLL_OUT_BYTECLK,
29 	DT_DSI0_PHY_PLL_OUT_DSICLK,
30 	DT_GPLL0_DISP_DIV,
31 };
32 
33 enum {
34 	P_BI_TCXO,
35 	P_DISP_CC_PLL0_OUT_MAIN,
36 	P_DSI0_PHY_PLL_OUT_BYTECLK,
37 	P_DSI0_PHY_PLL_OUT_DSICLK,
38 	P_GPLL0_OUT_MAIN,
39 	P_SLEEP_CLK,
40 };
41 
42 static const struct clk_parent_data parent_data_tcxo = { .index = DT_BI_TCXO };
43 
44 static const struct pll_vco spark_vco[] = {
45 	{ 500000000, 1000000000, 2 },
46 };
47 
48 /* 768MHz configuration */
49 static const struct alpha_pll_config disp_cc_pll0_config = {
50 	.l = 0x28,
51 	.vco_val = 0x2 << 20,
52 	.vco_mask = GENMASK(21, 20),
53 	.main_output_mask = BIT(0),
54 	.config_ctl_val = 0x4001055B,
55 };
56 
57 static struct clk_alpha_pll disp_cc_pll0 = {
58 	.offset = 0x0,
59 	.vco_table = spark_vco,
60 	.num_vco = ARRAY_SIZE(spark_vco),
61 	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
62 	.clkr = {
63 		.hw.init = &(struct clk_init_data){
64 			.name = "disp_cc_pll0",
65 			.parent_data = &parent_data_tcxo,
66 			.num_parents = 1,
67 			.ops = &clk_alpha_pll_ops,
68 		},
69 	},
70 };
71 
72 static const struct clk_div_table post_div_table_disp_cc_pll0_out_main[] = {
73 	{ 0x0, 1 },
74 	{ }
75 };
76 static struct clk_alpha_pll_postdiv disp_cc_pll0_out_main = {
77 	.offset = 0x0,
78 	.post_div_shift = 8,
79 	.post_div_table = post_div_table_disp_cc_pll0_out_main,
80 	.num_post_div = ARRAY_SIZE(post_div_table_disp_cc_pll0_out_main),
81 	.width = 4,
82 	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
83 	.clkr.hw.init = &(struct clk_init_data){
84 		.name = "disp_cc_pll0_out_main",
85 		.parent_hws = (const struct clk_hw*[]){
86 			&disp_cc_pll0.clkr.hw,
87 		},
88 		.num_parents = 1,
89 		.flags = CLK_SET_RATE_PARENT,
90 		.ops = &clk_alpha_pll_postdiv_ops,
91 	},
92 };
93 
94 static const struct parent_map disp_cc_parent_map_0[] = {
95 	{ P_BI_TCXO, 0 },
96 	{ P_DSI0_PHY_PLL_OUT_BYTECLK, 1 },
97 };
98 
99 static const struct clk_parent_data disp_cc_parent_data_0[] = {
100 	{ .index = DT_BI_TCXO },
101 	{ .index = DT_DSI0_PHY_PLL_OUT_BYTECLK },
102 };
103 
104 static const struct parent_map disp_cc_parent_map_1[] = {
105 	{ P_BI_TCXO, 0 },
106 };
107 
108 static const struct clk_parent_data disp_cc_parent_data_1[] = {
109 	{ .index = DT_BI_TCXO },
110 };
111 
112 static const struct parent_map disp_cc_parent_map_2[] = {
113 	{ P_BI_TCXO, 0 },
114 	{ P_GPLL0_OUT_MAIN, 4 },
115 };
116 
117 static const struct clk_parent_data disp_cc_parent_data_2[] = {
118 	{ .index = DT_BI_TCXO },
119 	{ .index = DT_GPLL0_DISP_DIV },
120 };
121 
122 static const struct parent_map disp_cc_parent_map_3[] = {
123 	{ P_BI_TCXO, 0 },
124 	{ P_DISP_CC_PLL0_OUT_MAIN, 1 },
125 };
126 
127 static const struct clk_parent_data disp_cc_parent_data_3[] = {
128 	{ .index = DT_BI_TCXO },
129 	{ .hw = &disp_cc_pll0_out_main.clkr.hw },
130 };
131 
132 static const struct parent_map disp_cc_parent_map_4[] = {
133 	{ P_BI_TCXO, 0 },
134 	{ P_DSI0_PHY_PLL_OUT_DSICLK, 1 },
135 };
136 
137 static const struct clk_parent_data disp_cc_parent_data_4[] = {
138 	{ .index = DT_BI_TCXO },
139 	{ .index = DT_DSI0_PHY_PLL_OUT_DSICLK },
140 };
141 
142 static const struct parent_map disp_cc_parent_map_5[] = {
143 	{ P_SLEEP_CLK, 0 },
144 };
145 
146 static const struct clk_parent_data disp_cc_parent_data_5[] = {
147 	{ .index = DT_SLEEP_CLK, },
148 };
149 
150 static struct clk_rcg2 disp_cc_mdss_byte0_clk_src = {
151 	.cmd_rcgr = 0x20bc,
152 	.mnd_width = 0,
153 	.hid_width = 5,
154 	.parent_map = disp_cc_parent_map_0,
155 	.clkr.hw.init = &(struct clk_init_data){
156 		.name = "disp_cc_mdss_byte0_clk_src",
157 		.parent_data = disp_cc_parent_data_0,
158 		.num_parents = ARRAY_SIZE(disp_cc_parent_data_0),
159 		/* For set_rate and set_parent to succeed, parent(s) must be enabled */
160 		.flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE | CLK_GET_RATE_NOCACHE,
161 		.ops = &clk_byte2_ops,
162 	},
163 };
164 
165 static struct clk_regmap_div disp_cc_mdss_byte0_div_clk_src = {
166 	.reg = 0x20d4,
167 	.shift = 0,
168 	.width = 2,
169 	.clkr.hw.init = &(struct clk_init_data) {
170 		.name = "disp_cc_mdss_byte0_div_clk_src",
171 		.parent_hws = (const struct clk_hw*[]){
172 			&disp_cc_mdss_byte0_clk_src.clkr.hw,
173 		},
174 		.num_parents = 1,
175 		.ops = &clk_regmap_div_ops,
176 	},
177 };
178 
179 static const struct freq_tbl ftbl_disp_cc_mdss_ahb_clk_src[] = {
180 	F(19200000, P_BI_TCXO, 1, 0, 0),
181 	F(37500000, P_GPLL0_OUT_MAIN, 8, 0, 0),
182 	F(75000000, P_GPLL0_OUT_MAIN, 4, 0, 0),
183 	{ }
184 };
185 
186 static struct clk_rcg2 disp_cc_mdss_ahb_clk_src = {
187 	.cmd_rcgr = 0x2154,
188 	.mnd_width = 0,
189 	.hid_width = 5,
190 	.parent_map = disp_cc_parent_map_2,
191 	.freq_tbl = ftbl_disp_cc_mdss_ahb_clk_src,
192 	.clkr.hw.init = &(struct clk_init_data){
193 		.name = "disp_cc_mdss_ahb_clk_src",
194 		.parent_data = disp_cc_parent_data_2,
195 		.num_parents = ARRAY_SIZE(disp_cc_parent_data_2),
196 		.ops = &clk_rcg2_shared_ops,
197 	},
198 };
199 
200 static const struct freq_tbl ftbl_disp_cc_mdss_esc0_clk_src[] = {
201 	F(19200000, P_BI_TCXO, 1, 0, 0),
202 	{ }
203 };
204 
205 static struct clk_rcg2 disp_cc_mdss_esc0_clk_src = {
206 	.cmd_rcgr = 0x20d8,
207 	.mnd_width = 0,
208 	.hid_width = 5,
209 	.parent_map = disp_cc_parent_map_0,
210 	.freq_tbl = ftbl_disp_cc_mdss_esc0_clk_src,
211 	.clkr.hw.init = &(struct clk_init_data){
212 		.name = "disp_cc_mdss_esc0_clk_src",
213 		.parent_data = disp_cc_parent_data_0,
214 		.num_parents = ARRAY_SIZE(disp_cc_parent_data_0),
215 		.ops = &clk_rcg2_ops,
216 	},
217 };
218 
219 static const struct freq_tbl ftbl_disp_cc_mdss_mdp_clk_src[] = {
220 	F(19200000, P_BI_TCXO, 1, 0, 0),
221 	F(192000000, P_DISP_CC_PLL0_OUT_MAIN, 4, 0, 0),
222 	F(256000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0),
223 	F(307200000, P_DISP_CC_PLL0_OUT_MAIN, 2.5, 0, 0),
224 	F(384000000, P_DISP_CC_PLL0_OUT_MAIN, 2, 0, 0),
225 	{ }
226 };
227 
228 static struct clk_rcg2 disp_cc_mdss_mdp_clk_src = {
229 	.cmd_rcgr = 0x2074,
230 	.mnd_width = 0,
231 	.hid_width = 5,
232 	.parent_map = disp_cc_parent_map_3,
233 	.freq_tbl = ftbl_disp_cc_mdss_mdp_clk_src,
234 	.clkr.hw.init = &(struct clk_init_data){
235 		.name = "disp_cc_mdss_mdp_clk_src",
236 		.parent_data = disp_cc_parent_data_3,
237 		.num_parents = ARRAY_SIZE(disp_cc_parent_data_3),
238 		.flags = CLK_SET_RATE_PARENT,
239 		.ops = &clk_rcg2_shared_ops,
240 	},
241 };
242 
243 static struct clk_rcg2 disp_cc_mdss_pclk0_clk_src = {
244 	.cmd_rcgr = 0x205c,
245 	.mnd_width = 8,
246 	.hid_width = 5,
247 	.parent_map = disp_cc_parent_map_4,
248 	.clkr.hw.init = &(struct clk_init_data){
249 		.name = "disp_cc_mdss_pclk0_clk_src",
250 		.parent_data = disp_cc_parent_data_4,
251 		.num_parents = ARRAY_SIZE(disp_cc_parent_data_4),
252 		/* For set_rate and set_parent to succeed, parent(s) must be enabled */
253 		.flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE | CLK_GET_RATE_NOCACHE,
254 		.ops = &clk_pixel_ops,
255 	},
256 };
257 
258 static const struct freq_tbl ftbl_disp_cc_mdss_rot_clk_src[] = {
259 	F(19200000, P_BI_TCXO, 1, 0, 0),
260 	F(192000000, P_DISP_CC_PLL0_OUT_MAIN, 4, 0, 0),
261 	F(256000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0),
262 	F(307200000, P_DISP_CC_PLL0_OUT_MAIN, 2.5, 0, 0),
263 	{ }
264 };
265 
266 static struct clk_rcg2 disp_cc_mdss_rot_clk_src = {
267 	.cmd_rcgr = 0x208c,
268 	.mnd_width = 0,
269 	.hid_width = 5,
270 	.parent_map = disp_cc_parent_map_3,
271 	.freq_tbl = ftbl_disp_cc_mdss_rot_clk_src,
272 	.clkr.hw.init = &(struct clk_init_data){
273 		.name = "disp_cc_mdss_rot_clk_src",
274 		.parent_data = disp_cc_parent_data_3,
275 		.num_parents = ARRAY_SIZE(disp_cc_parent_data_3),
276 		.flags = CLK_SET_RATE_PARENT,
277 		.ops = &clk_rcg2_shared_ops,
278 	},
279 };
280 
281 static struct clk_rcg2 disp_cc_mdss_vsync_clk_src = {
282 	.cmd_rcgr = 0x20a4,
283 	.mnd_width = 0,
284 	.hid_width = 5,
285 	.parent_map = disp_cc_parent_map_1,
286 	.freq_tbl = ftbl_disp_cc_mdss_esc0_clk_src,
287 	.clkr.hw.init = &(struct clk_init_data){
288 		.name = "disp_cc_mdss_vsync_clk_src",
289 		.parent_data = disp_cc_parent_data_1,
290 		.num_parents = ARRAY_SIZE(disp_cc_parent_data_1),
291 		.flags = CLK_SET_RATE_PARENT,
292 		.ops = &clk_rcg2_shared_ops,
293 	},
294 };
295 
296 static const struct freq_tbl ftbl_disp_cc_sleep_clk_src[] = {
297 	F(32764, P_SLEEP_CLK, 1, 0, 0),
298 	{ }
299 };
300 
301 static struct clk_rcg2 disp_cc_sleep_clk_src = {
302 	.cmd_rcgr = 0x6050,
303 	.mnd_width = 0,
304 	.hid_width = 5,
305 	.parent_map = disp_cc_parent_map_5,
306 	.freq_tbl = ftbl_disp_cc_sleep_clk_src,
307 	.clkr.hw.init = &(struct clk_init_data){
308 		.name = "disp_cc_sleep_clk_src",
309 		.parent_data = disp_cc_parent_data_5,
310 		.num_parents = ARRAY_SIZE(disp_cc_parent_data_5),
311 		.ops = &clk_rcg2_ops,
312 	},
313 };
314 
315 static struct clk_branch disp_cc_mdss_ahb_clk = {
316 	.halt_reg = 0x2044,
317 	.halt_check = BRANCH_HALT,
318 	.clkr = {
319 		.enable_reg = 0x2044,
320 		.enable_mask = BIT(0),
321 		.hw.init = &(struct clk_init_data){
322 			.name = "disp_cc_mdss_ahb_clk",
323 			.parent_hws = (const struct clk_hw*[]){
324 				&disp_cc_mdss_ahb_clk_src.clkr.hw,
325 			},
326 			.num_parents = 1,
327 			.flags = CLK_SET_RATE_PARENT,
328 			.ops = &clk_branch2_ops,
329 		},
330 	},
331 };
332 
333 static struct clk_branch disp_cc_mdss_byte0_clk = {
334 	.halt_reg = 0x2024,
335 	.halt_check = BRANCH_HALT,
336 	.clkr = {
337 		.enable_reg = 0x2024,
338 		.enable_mask = BIT(0),
339 		.hw.init = &(struct clk_init_data){
340 			.name = "disp_cc_mdss_byte0_clk",
341 			.parent_hws = (const struct clk_hw*[]){
342 				&disp_cc_mdss_byte0_clk_src.clkr.hw,
343 			},
344 			.num_parents = 1,
345 			.flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE,
346 			.ops = &clk_branch2_ops,
347 		},
348 	},
349 };
350 
351 static struct clk_branch disp_cc_mdss_byte0_intf_clk = {
352 	.halt_reg = 0x2028,
353 	.halt_check = BRANCH_HALT,
354 	.clkr = {
355 		.enable_reg = 0x2028,
356 		.enable_mask = BIT(0),
357 		.hw.init = &(struct clk_init_data){
358 			.name = "disp_cc_mdss_byte0_intf_clk",
359 			.parent_hws = (const struct clk_hw*[]){
360 				&disp_cc_mdss_byte0_div_clk_src.clkr.hw,
361 			},
362 			.num_parents = 1,
363 			.flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE,
364 			.ops = &clk_branch2_ops,
365 		},
366 	},
367 };
368 
369 static struct clk_branch disp_cc_mdss_esc0_clk = {
370 	.halt_reg = 0x202c,
371 	.halt_check = BRANCH_HALT,
372 	.clkr = {
373 		.enable_reg = 0x202c,
374 		.enable_mask = BIT(0),
375 		.hw.init = &(struct clk_init_data){
376 			.name = "disp_cc_mdss_esc0_clk",
377 			.parent_hws = (const struct clk_hw*[]){
378 				&disp_cc_mdss_esc0_clk_src.clkr.hw,
379 			},
380 			.num_parents = 1,
381 			.flags = CLK_SET_RATE_PARENT,
382 			.ops = &clk_branch2_ops,
383 		},
384 	},
385 };
386 
387 static struct clk_branch disp_cc_mdss_mdp_clk = {
388 	.halt_reg = 0x2008,
389 	.halt_check = BRANCH_HALT,
390 	.clkr = {
391 		.enable_reg = 0x2008,
392 		.enable_mask = BIT(0),
393 		.hw.init = &(struct clk_init_data){
394 			.name = "disp_cc_mdss_mdp_clk",
395 			.parent_hws = (const struct clk_hw*[]){
396 				&disp_cc_mdss_mdp_clk_src.clkr.hw,
397 			},
398 			.num_parents = 1,
399 			.flags = CLK_SET_RATE_PARENT,
400 			.ops = &clk_branch2_ops,
401 		},
402 	},
403 };
404 
405 static struct clk_branch disp_cc_mdss_mdp_lut_clk = {
406 	.halt_reg = 0x2018,
407 	.halt_check = BRANCH_HALT_VOTED,
408 	.clkr = {
409 		.enable_reg = 0x2018,
410 		.enable_mask = BIT(0),
411 		.hw.init = &(struct clk_init_data){
412 			.name = "disp_cc_mdss_mdp_lut_clk",
413 			.parent_hws = (const struct clk_hw*[]){
414 				&disp_cc_mdss_mdp_clk_src.clkr.hw,
415 			},
416 			.num_parents = 1,
417 			.flags = CLK_SET_RATE_PARENT,
418 			.ops = &clk_branch2_ops,
419 		},
420 	},
421 };
422 
423 static struct clk_branch disp_cc_mdss_non_gdsc_ahb_clk = {
424 	.halt_reg = 0x4004,
425 	.halt_check = BRANCH_HALT_VOTED,
426 	.clkr = {
427 		.enable_reg = 0x4004,
428 		.enable_mask = BIT(0),
429 		.hw.init = &(struct clk_init_data){
430 			.name = "disp_cc_mdss_non_gdsc_ahb_clk",
431 			.parent_hws = (const struct clk_hw*[]){
432 				&disp_cc_mdss_ahb_clk_src.clkr.hw,
433 			},
434 			.num_parents = 1,
435 			.flags = CLK_SET_RATE_PARENT,
436 			.ops = &clk_branch2_ops,
437 		},
438 	},
439 };
440 
441 static struct clk_branch disp_cc_mdss_pclk0_clk = {
442 	.halt_reg = 0x2004,
443 	.halt_check = BRANCH_HALT,
444 	.clkr = {
445 		.enable_reg = 0x2004,
446 		.enable_mask = BIT(0),
447 		.hw.init = &(struct clk_init_data){
448 			.name = "disp_cc_mdss_pclk0_clk",
449 			.parent_hws = (const struct clk_hw*[]){
450 				&disp_cc_mdss_pclk0_clk_src.clkr.hw,
451 			},
452 			.num_parents = 1,
453 			.flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE,
454 			.ops = &clk_branch2_ops,
455 		},
456 	},
457 };
458 
459 static struct clk_branch disp_cc_mdss_rot_clk = {
460 	.halt_reg = 0x2010,
461 	.halt_check = BRANCH_HALT,
462 	.clkr = {
463 		.enable_reg = 0x2010,
464 		.enable_mask = BIT(0),
465 		.hw.init = &(struct clk_init_data){
466 			.name = "disp_cc_mdss_rot_clk",
467 			.parent_hws = (const struct clk_hw*[]) {
468 				&disp_cc_mdss_rot_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 disp_cc_mdss_vsync_clk = {
478 	.halt_reg = 0x2020,
479 	.halt_check = BRANCH_HALT,
480 	.clkr = {
481 		.enable_reg = 0x2020,
482 		.enable_mask = BIT(0),
483 		.hw.init = &(struct clk_init_data){
484 			.name = "disp_cc_mdss_vsync_clk",
485 			.parent_hws = (const struct clk_hw*[]){
486 				&disp_cc_mdss_vsync_clk_src.clkr.hw,
487 			},
488 			.num_parents = 1,
489 			.flags = CLK_SET_RATE_PARENT,
490 			.ops = &clk_branch2_ops,
491 		},
492 	},
493 };
494 
495 static struct clk_branch disp_cc_sleep_clk = {
496 	.halt_reg = 0x6068,
497 	.halt_check = BRANCH_HALT,
498 	.clkr = {
499 		.enable_reg = 0x6068,
500 		.enable_mask = BIT(0),
501 		.hw.init = &(struct clk_init_data){
502 			.name = "disp_cc_sleep_clk",
503 			.parent_hws = (const struct clk_hw*[]){
504 				&disp_cc_sleep_clk_src.clkr.hw,
505 			},
506 			.num_parents = 1,
507 			.flags = CLK_SET_RATE_PARENT,
508 			.ops = &clk_branch2_ops,
509 		},
510 	},
511 };
512 
513 static struct gdsc mdss_gdsc = {
514 	.gdscr = 0x3000,
515 	.pd = {
516 		.name = "mdss_gdsc",
517 	},
518 	.pwrsts = PWRSTS_OFF_ON,
519 	.flags = HW_CTRL,
520 };
521 
522 static struct gdsc *disp_cc_sm6115_gdscs[] = {
523 	[MDSS_GDSC] = &mdss_gdsc,
524 };
525 
526 static struct clk_regmap *disp_cc_sm6115_clocks[] = {
527 	[DISP_CC_PLL0] = &disp_cc_pll0.clkr,
528 	[DISP_CC_PLL0_OUT_MAIN] = &disp_cc_pll0_out_main.clkr,
529 	[DISP_CC_MDSS_AHB_CLK] = &disp_cc_mdss_ahb_clk.clkr,
530 	[DISP_CC_MDSS_AHB_CLK_SRC] = &disp_cc_mdss_ahb_clk_src.clkr,
531 	[DISP_CC_MDSS_BYTE0_CLK] = &disp_cc_mdss_byte0_clk.clkr,
532 	[DISP_CC_MDSS_BYTE0_CLK_SRC] = &disp_cc_mdss_byte0_clk_src.clkr,
533 	[DISP_CC_MDSS_BYTE0_DIV_CLK_SRC] = &disp_cc_mdss_byte0_div_clk_src.clkr,
534 	[DISP_CC_MDSS_BYTE0_INTF_CLK] = &disp_cc_mdss_byte0_intf_clk.clkr,
535 	[DISP_CC_MDSS_ESC0_CLK] = &disp_cc_mdss_esc0_clk.clkr,
536 	[DISP_CC_MDSS_ESC0_CLK_SRC] = &disp_cc_mdss_esc0_clk_src.clkr,
537 	[DISP_CC_MDSS_MDP_CLK] = &disp_cc_mdss_mdp_clk.clkr,
538 	[DISP_CC_MDSS_MDP_CLK_SRC] = &disp_cc_mdss_mdp_clk_src.clkr,
539 	[DISP_CC_MDSS_MDP_LUT_CLK] = &disp_cc_mdss_mdp_lut_clk.clkr,
540 	[DISP_CC_MDSS_NON_GDSC_AHB_CLK] = &disp_cc_mdss_non_gdsc_ahb_clk.clkr,
541 	[DISP_CC_MDSS_PCLK0_CLK] = &disp_cc_mdss_pclk0_clk.clkr,
542 	[DISP_CC_MDSS_PCLK0_CLK_SRC] = &disp_cc_mdss_pclk0_clk_src.clkr,
543 	[DISP_CC_MDSS_ROT_CLK] = &disp_cc_mdss_rot_clk.clkr,
544 	[DISP_CC_MDSS_ROT_CLK_SRC] = &disp_cc_mdss_rot_clk_src.clkr,
545 	[DISP_CC_MDSS_VSYNC_CLK] = &disp_cc_mdss_vsync_clk.clkr,
546 	[DISP_CC_MDSS_VSYNC_CLK_SRC] = &disp_cc_mdss_vsync_clk_src.clkr,
547 	[DISP_CC_SLEEP_CLK] = &disp_cc_sleep_clk.clkr,
548 	[DISP_CC_SLEEP_CLK_SRC] = &disp_cc_sleep_clk_src.clkr,
549 };
550 
551 static const struct regmap_config disp_cc_sm6115_regmap_config = {
552 	.reg_bits = 32,
553 	.reg_stride = 4,
554 	.val_bits = 32,
555 	.max_register = 0x10000,
556 	.fast_io = true,
557 };
558 
559 static const struct qcom_cc_desc disp_cc_sm6115_desc = {
560 	.config = &disp_cc_sm6115_regmap_config,
561 	.clks = disp_cc_sm6115_clocks,
562 	.num_clks = ARRAY_SIZE(disp_cc_sm6115_clocks),
563 	.gdscs = disp_cc_sm6115_gdscs,
564 	.num_gdscs = ARRAY_SIZE(disp_cc_sm6115_gdscs),
565 };
566 
567 static const struct of_device_id disp_cc_sm6115_match_table[] = {
568 	{ .compatible = "qcom,sm6115-dispcc" },
569 	{ }
570 };
571 MODULE_DEVICE_TABLE(of, disp_cc_sm6115_match_table);
572 
573 static int disp_cc_sm6115_probe(struct platform_device *pdev)
574 {
575 	struct regmap *regmap;
576 	int ret;
577 
578 	regmap = qcom_cc_map(pdev, &disp_cc_sm6115_desc);
579 	if (IS_ERR(regmap))
580 		return PTR_ERR(regmap);
581 
582 	clk_alpha_pll_configure(&disp_cc_pll0, regmap, &disp_cc_pll0_config);
583 
584 	/* Keep some clocks always-on */
585 	qcom_branch_set_clk_en(regmap, 0x604c); /* DISP_CC_XO_CLK */
586 
587 	ret = qcom_cc_really_probe(&pdev->dev, &disp_cc_sm6115_desc, regmap);
588 	if (ret) {
589 		dev_err(&pdev->dev, "Failed to register DISP CC clocks\n");
590 		return ret;
591 	}
592 
593 	return ret;
594 }
595 
596 static struct platform_driver disp_cc_sm6115_driver = {
597 	.probe = disp_cc_sm6115_probe,
598 	.driver = {
599 		.name = "dispcc-sm6115",
600 		.of_match_table = disp_cc_sm6115_match_table,
601 	},
602 };
603 
604 module_platform_driver(disp_cc_sm6115_driver);
605 MODULE_DESCRIPTION("Qualcomm SM6115 Display Clock controller");
606 MODULE_LICENSE("GPL");
607