xref: /linux/drivers/clk/qcom/dispcc-sm4450.c (revision fbf5df34a4dbcd09d433dd4f0916bf9b2ddb16de)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved.
4  */
5 
6 #include <linux/clk-provider.h>
7 #include <linux/module.h>
8 #include <linux/mod_devicetable.h>
9 #include <linux/platform_device.h>
10 #include <linux/regmap.h>
11 
12 #include <dt-bindings/clock/qcom,sm4450-dispcc.h>
13 
14 #include "clk-alpha-pll.h"
15 #include "clk-branch.h"
16 #include "clk-pll.h"
17 #include "clk-rcg.h"
18 #include "clk-regmap.h"
19 #include "clk-regmap-divider.h"
20 #include "common.h"
21 #include "gdsc.h"
22 #include "reset.h"
23 
24 enum {
25 	DT_BI_TCXO,
26 	DT_BI_TCXO_AO,
27 	DT_AHB_CLK,
28 	DT_SLEEP_CLK,
29 
30 	DT_DSI0_PHY_PLL_OUT_BYTECLK,
31 	DT_DSI0_PHY_PLL_OUT_DSICLK,
32 };
33 
34 enum {
35 	P_BI_TCXO,
36 	P_DISP_CC_PLL0_OUT_MAIN,
37 	P_DISP_CC_PLL1_OUT_EVEN,
38 	P_DISP_CC_PLL1_OUT_MAIN,
39 	P_DSI0_PHY_PLL_OUT_BYTECLK,
40 	P_DSI0_PHY_PLL_OUT_DSICLK,
41 	P_SLEEP_CLK,
42 };
43 
44 static const struct pll_vco lucid_evo_vco[] = {
45 	{ 249600000, 2020000000, 0 },
46 };
47 
48 /* 600.0 MHz Configuration */
49 static const struct alpha_pll_config disp_cc_pll0_config = {
50 	.l = 0x1f,
51 	.alpha = 0x4000,
52 	.config_ctl_val = 0x20485699,
53 	.config_ctl_hi_val = 0x00182261,
54 	.config_ctl_hi1_val = 0x32aa299c,
55 	.user_ctl_val = 0x00000000,
56 	.user_ctl_hi_val = 0x00000805,
57 };
58 
59 static struct clk_alpha_pll disp_cc_pll0 = {
60 	.offset = 0x0,
61 	.vco_table = lucid_evo_vco,
62 	.num_vco = ARRAY_SIZE(lucid_evo_vco),
63 	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_EVO],
64 	.clkr = {
65 		.hw.init = &(const struct clk_init_data) {
66 			.name = "disp_cc_pll0",
67 			.parent_data = &(const struct clk_parent_data) {
68 				.index = DT_BI_TCXO,
69 			},
70 			.num_parents = 1,
71 			.ops = &clk_alpha_pll_lucid_evo_ops,
72 		},
73 	},
74 };
75 
76 static struct clk_alpha_pll disp_cc_pll1 = {
77 	.offset = 0x1000,
78 	.vco_table = lucid_evo_vco,
79 	.num_vco = ARRAY_SIZE(lucid_evo_vco),
80 	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_EVO],
81 	.clkr = {
82 		.hw.init = &(const struct clk_init_data) {
83 			.name = "disp_cc_pll1",
84 			.parent_data = &(const struct clk_parent_data) {
85 				.index = DT_BI_TCXO,
86 			},
87 			.num_parents = 1,
88 			.ops = &clk_alpha_pll_lucid_evo_ops,
89 		},
90 	},
91 };
92 
93 static const struct parent_map disp_cc_parent_map_0[] = {
94 	{ P_BI_TCXO, 0 },
95 	{ P_DSI0_PHY_PLL_OUT_DSICLK, 1 },
96 	{ P_DSI0_PHY_PLL_OUT_BYTECLK, 2 },
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_DSICLK },
102 	{ .index = DT_DSI0_PHY_PLL_OUT_BYTECLK },
103 };
104 
105 static const struct parent_map disp_cc_parent_map_1[] = {
106 	{ P_BI_TCXO, 0 },
107 	{ P_DISP_CC_PLL0_OUT_MAIN, 1 },
108 	{ P_DISP_CC_PLL1_OUT_MAIN, 4 },
109 	{ P_DISP_CC_PLL1_OUT_EVEN, 6 },
110 };
111 
112 static const struct clk_parent_data disp_cc_parent_data_1[] = {
113 	{ .index = DT_BI_TCXO },
114 	{ .hw = &disp_cc_pll0.clkr.hw },
115 	{ .hw = &disp_cc_pll1.clkr.hw },
116 	{ .hw = &disp_cc_pll1.clkr.hw },
117 };
118 
119 static const struct parent_map disp_cc_parent_map_2[] = {
120 	{ P_BI_TCXO, 0 },
121 };
122 
123 static const struct clk_parent_data disp_cc_parent_data_2[] = {
124 	{ .index = DT_BI_TCXO },
125 };
126 
127 static const struct clk_parent_data disp_cc_parent_data_2_ao[] = {
128 	{ .index = DT_BI_TCXO_AO },
129 };
130 
131 static const struct parent_map disp_cc_parent_map_3[] = {
132 	{ P_BI_TCXO, 0 },
133 	{ P_DISP_CC_PLL1_OUT_MAIN, 4 },
134 	{ P_DISP_CC_PLL1_OUT_EVEN, 6 },
135 };
136 
137 static const struct clk_parent_data disp_cc_parent_data_3[] = {
138 	{ .index = DT_BI_TCXO },
139 	{ .hw = &disp_cc_pll1.clkr.hw },
140 	{ .hw = &disp_cc_pll1.clkr.hw },
141 };
142 
143 static const struct parent_map disp_cc_parent_map_4[] = {
144 	{ P_BI_TCXO, 0 },
145 	{ P_DSI0_PHY_PLL_OUT_BYTECLK, 2 },
146 };
147 
148 static const struct clk_parent_data disp_cc_parent_data_4[] = {
149 	{ .index = DT_BI_TCXO },
150 	{ .index = DT_DSI0_PHY_PLL_OUT_BYTECLK },
151 };
152 
153 static const struct parent_map disp_cc_parent_map_5[] = {
154 	{ P_SLEEP_CLK, 0 },
155 };
156 
157 static const struct clk_parent_data disp_cc_parent_data_5[] = {
158 	{ .index = DT_SLEEP_CLK },
159 };
160 
161 static const struct freq_tbl ftbl_disp_cc_mdss_ahb_clk_src[] = {
162 	F(19200000, P_BI_TCXO, 1, 0, 0),
163 	F(37500000, P_DISP_CC_PLL1_OUT_MAIN, 16, 0, 0),
164 	F(75000000, P_DISP_CC_PLL1_OUT_MAIN, 8, 0, 0),
165 	{ }
166 };
167 
168 static struct clk_rcg2 disp_cc_mdss_ahb_clk_src = {
169 	.cmd_rcgr = 0x82a4,
170 	.mnd_width = 0,
171 	.hid_width = 5,
172 	.parent_map = disp_cc_parent_map_3,
173 	.freq_tbl = ftbl_disp_cc_mdss_ahb_clk_src,
174 	.clkr.hw.init = &(const struct clk_init_data) {
175 		.name = "disp_cc_mdss_ahb_clk_src",
176 		.parent_data = disp_cc_parent_data_3,
177 		.num_parents = ARRAY_SIZE(disp_cc_parent_data_3),
178 		.flags = CLK_SET_RATE_PARENT,
179 		.ops = &clk_rcg2_shared_ops,
180 	},
181 };
182 
183 static const struct freq_tbl ftbl_disp_cc_mdss_byte0_clk_src[] = {
184 	F(19200000, P_BI_TCXO, 1, 0, 0),
185 	{ }
186 };
187 
188 static struct clk_rcg2 disp_cc_mdss_byte0_clk_src = {
189 	.cmd_rcgr = 0x80f8,
190 	.mnd_width = 0,
191 	.hid_width = 5,
192 	.parent_map = disp_cc_parent_map_0,
193 	.freq_tbl = ftbl_disp_cc_mdss_byte0_clk_src,
194 	.clkr.hw.init = &(const struct clk_init_data) {
195 		.name = "disp_cc_mdss_byte0_clk_src",
196 		.parent_data = disp_cc_parent_data_0,
197 		.num_parents = ARRAY_SIZE(disp_cc_parent_data_0),
198 		.flags = CLK_SET_RATE_PARENT,
199 		.ops = &clk_byte2_ops,
200 	},
201 };
202 
203 static struct clk_rcg2 disp_cc_mdss_esc0_clk_src = {
204 	.cmd_rcgr = 0x8114,
205 	.mnd_width = 0,
206 	.hid_width = 5,
207 	.parent_map = disp_cc_parent_map_4,
208 	.freq_tbl = ftbl_disp_cc_mdss_byte0_clk_src,
209 	.clkr.hw.init = &(const struct clk_init_data) {
210 		.name = "disp_cc_mdss_esc0_clk_src",
211 		.parent_data = disp_cc_parent_data_4,
212 		.num_parents = ARRAY_SIZE(disp_cc_parent_data_4),
213 		.flags = CLK_SET_RATE_PARENT,
214 		.ops = &clk_rcg2_shared_ops,
215 	},
216 };
217 
218 static const struct freq_tbl ftbl_disp_cc_mdss_mdp_clk_src[] = {
219 	F(200000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0),
220 	F(325000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0),
221 	F(380000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0),
222 	F(506000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0),
223 	F(608000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0),
224 	{ }
225 };
226 
227 static struct clk_rcg2 disp_cc_mdss_mdp_clk_src = {
228 	.cmd_rcgr = 0x80b0,
229 	.mnd_width = 0,
230 	.hid_width = 5,
231 	.parent_map = disp_cc_parent_map_1,
232 	.freq_tbl = ftbl_disp_cc_mdss_mdp_clk_src,
233 	.clkr.hw.init = &(const struct clk_init_data) {
234 		.name = "disp_cc_mdss_mdp_clk_src",
235 		.parent_data = disp_cc_parent_data_1,
236 		.num_parents = ARRAY_SIZE(disp_cc_parent_data_1),
237 		.flags = CLK_SET_RATE_PARENT,
238 		.ops = &clk_rcg2_shared_ops,
239 	},
240 };
241 
242 static struct clk_rcg2 disp_cc_mdss_pclk0_clk_src = {
243 	.cmd_rcgr = 0x8098,
244 	.mnd_width = 8,
245 	.hid_width = 5,
246 	.parent_map = disp_cc_parent_map_0,
247 	.freq_tbl = ftbl_disp_cc_mdss_byte0_clk_src,
248 	.clkr.hw.init = &(const struct clk_init_data) {
249 		.name = "disp_cc_mdss_pclk0_clk_src",
250 		.parent_data = disp_cc_parent_data_0,
251 		.num_parents = ARRAY_SIZE(disp_cc_parent_data_0),
252 		.flags = CLK_SET_RATE_PARENT,
253 		.ops = &clk_pixel_ops,
254 	},
255 };
256 
257 static const struct freq_tbl ftbl_disp_cc_mdss_rot_clk_src[] = {
258 	F(200000000, P_DISP_CC_PLL1_OUT_MAIN, 3, 0, 0),
259 	F(300000000, P_DISP_CC_PLL1_OUT_MAIN, 2, 0, 0),
260 	{ }
261 };
262 
263 static struct clk_rcg2 disp_cc_mdss_rot_clk_src = {
264 	.cmd_rcgr = 0x80c8,
265 	.mnd_width = 0,
266 	.hid_width = 5,
267 	.parent_map = disp_cc_parent_map_1,
268 	.freq_tbl = ftbl_disp_cc_mdss_rot_clk_src,
269 	.clkr.hw.init = &(const struct clk_init_data) {
270 		.name = "disp_cc_mdss_rot_clk_src",
271 		.parent_data = disp_cc_parent_data_1,
272 		.num_parents = ARRAY_SIZE(disp_cc_parent_data_1),
273 		.flags = CLK_SET_RATE_PARENT,
274 		.ops = &clk_rcg2_shared_ops,
275 	},
276 };
277 
278 static struct clk_rcg2 disp_cc_mdss_vsync_clk_src = {
279 	.cmd_rcgr = 0x80e0,
280 	.mnd_width = 0,
281 	.hid_width = 5,
282 	.parent_map = disp_cc_parent_map_2,
283 	.freq_tbl = ftbl_disp_cc_mdss_byte0_clk_src,
284 	.clkr.hw.init = &(const struct clk_init_data) {
285 		.name = "disp_cc_mdss_vsync_clk_src",
286 		.parent_data = disp_cc_parent_data_2,
287 		.num_parents = ARRAY_SIZE(disp_cc_parent_data_2),
288 		.flags = CLK_SET_RATE_PARENT,
289 		.ops = &clk_rcg2_shared_ops,
290 	},
291 };
292 
293 static const struct freq_tbl ftbl_disp_cc_sleep_clk_src[] = {
294 	F(32000, P_SLEEP_CLK, 1, 0, 0),
295 	{ }
296 };
297 
298 static struct clk_rcg2 disp_cc_sleep_clk_src = {
299 	.cmd_rcgr = 0xe058,
300 	.mnd_width = 0,
301 	.hid_width = 5,
302 	.parent_map = disp_cc_parent_map_5,
303 	.freq_tbl = ftbl_disp_cc_sleep_clk_src,
304 	.clkr.hw.init = &(const struct clk_init_data) {
305 		.name = "disp_cc_sleep_clk_src",
306 		.parent_data = disp_cc_parent_data_5,
307 		.num_parents = ARRAY_SIZE(disp_cc_parent_data_5),
308 		.flags = CLK_SET_RATE_PARENT,
309 		.ops = &clk_rcg2_shared_ops,
310 	},
311 };
312 
313 static struct clk_rcg2 disp_cc_xo_clk_src = {
314 	.cmd_rcgr = 0xe03c,
315 	.mnd_width = 0,
316 	.hid_width = 5,
317 	.parent_map = disp_cc_parent_map_2,
318 	.freq_tbl = ftbl_disp_cc_mdss_byte0_clk_src,
319 	.clkr.hw.init = &(const struct clk_init_data) {
320 		.name = "disp_cc_xo_clk_src",
321 		.parent_data = disp_cc_parent_data_2_ao,
322 		.num_parents = ARRAY_SIZE(disp_cc_parent_data_2_ao),
323 		.flags = CLK_SET_RATE_PARENT,
324 		.ops = &clk_rcg2_shared_ops,
325 	},
326 };
327 
328 static struct clk_regmap_div disp_cc_mdss_byte0_div_clk_src = {
329 	.reg = 0x8110,
330 	.shift = 0,
331 	.width = 4,
332 	.clkr.hw.init = &(const struct clk_init_data) {
333 		.name = "disp_cc_mdss_byte0_div_clk_src",
334 		.parent_hws = (const struct clk_hw*[]) {
335 			&disp_cc_mdss_byte0_clk_src.clkr.hw,
336 		},
337 		.num_parents = 1,
338 		.ops = &clk_regmap_div_ops,
339 	},
340 };
341 
342 static struct clk_branch disp_cc_mdss_ahb1_clk = {
343 	.halt_reg = 0xa020,
344 	.halt_check = BRANCH_HALT,
345 	.clkr = {
346 		.enable_reg = 0xa020,
347 		.enable_mask = BIT(0),
348 		.hw.init = &(const struct clk_init_data) {
349 			.name = "disp_cc_mdss_ahb1_clk",
350 			.parent_hws = (const struct clk_hw*[]) {
351 				&disp_cc_mdss_ahb_clk_src.clkr.hw,
352 			},
353 			.num_parents = 1,
354 			.flags = CLK_SET_RATE_PARENT,
355 			.ops = &clk_branch2_ops,
356 		},
357 	},
358 };
359 
360 static struct clk_branch disp_cc_mdss_ahb_clk = {
361 	.halt_reg = 0x8094,
362 	.halt_check = BRANCH_HALT,
363 	.clkr = {
364 		.enable_reg = 0x8094,
365 		.enable_mask = BIT(0),
366 		.hw.init = &(const struct clk_init_data) {
367 			.name = "disp_cc_mdss_ahb_clk",
368 			.parent_hws = (const struct clk_hw*[]) {
369 				&disp_cc_mdss_ahb_clk_src.clkr.hw,
370 			},
371 			.num_parents = 1,
372 			.flags = CLK_SET_RATE_PARENT,
373 			.ops = &clk_branch2_ops,
374 		},
375 	},
376 };
377 
378 static struct clk_branch disp_cc_mdss_byte0_clk = {
379 	.halt_reg = 0x8024,
380 	.halt_check = BRANCH_HALT,
381 	.clkr = {
382 		.enable_reg = 0x8024,
383 		.enable_mask = BIT(0),
384 		.hw.init = &(const struct clk_init_data) {
385 			.name = "disp_cc_mdss_byte0_clk",
386 			.parent_hws = (const struct clk_hw*[]) {
387 				&disp_cc_mdss_byte0_clk_src.clkr.hw,
388 			},
389 			.num_parents = 1,
390 			.flags = CLK_SET_RATE_PARENT,
391 			.ops = &clk_branch2_ops,
392 		},
393 	},
394 };
395 
396 static struct clk_branch disp_cc_mdss_byte0_intf_clk = {
397 	.halt_reg = 0x8028,
398 	.halt_check = BRANCH_HALT,
399 	.clkr = {
400 		.enable_reg = 0x8028,
401 		.enable_mask = BIT(0),
402 		.hw.init = &(const struct clk_init_data) {
403 			.name = "disp_cc_mdss_byte0_intf_clk",
404 			.parent_hws = (const struct clk_hw*[]) {
405 				&disp_cc_mdss_byte0_div_clk_src.clkr.hw,
406 			},
407 			.num_parents = 1,
408 			.flags = CLK_SET_RATE_PARENT,
409 			.ops = &clk_branch2_ops,
410 		},
411 	},
412 };
413 
414 static struct clk_branch disp_cc_mdss_esc0_clk = {
415 	.halt_reg = 0x802c,
416 	.halt_check = BRANCH_HALT,
417 	.clkr = {
418 		.enable_reg = 0x802c,
419 		.enable_mask = BIT(0),
420 		.hw.init = &(const struct clk_init_data) {
421 			.name = "disp_cc_mdss_esc0_clk",
422 			.parent_hws = (const struct clk_hw*[]) {
423 				&disp_cc_mdss_esc0_clk_src.clkr.hw,
424 			},
425 			.num_parents = 1,
426 			.flags = CLK_SET_RATE_PARENT,
427 			.ops = &clk_branch2_ops,
428 		},
429 	},
430 };
431 
432 static struct clk_branch disp_cc_mdss_mdp1_clk = {
433 	.halt_reg = 0xa004,
434 	.halt_check = BRANCH_HALT,
435 	.clkr = {
436 		.enable_reg = 0xa004,
437 		.enable_mask = BIT(0),
438 		.hw.init = &(const struct clk_init_data) {
439 			.name = "disp_cc_mdss_mdp1_clk",
440 			.parent_hws = (const struct clk_hw*[]) {
441 				&disp_cc_mdss_mdp_clk_src.clkr.hw,
442 			},
443 			.num_parents = 1,
444 			.flags = CLK_SET_RATE_PARENT,
445 			.ops = &clk_branch2_ops,
446 		},
447 	},
448 };
449 
450 static struct clk_branch disp_cc_mdss_mdp_clk = {
451 	.halt_reg = 0x8008,
452 	.halt_check = BRANCH_HALT,
453 	.clkr = {
454 		.enable_reg = 0x8008,
455 		.enable_mask = BIT(0),
456 		.hw.init = &(const struct clk_init_data) {
457 			.name = "disp_cc_mdss_mdp_clk",
458 			.parent_hws = (const struct clk_hw*[]) {
459 				&disp_cc_mdss_mdp_clk_src.clkr.hw,
460 			},
461 			.num_parents = 1,
462 			.flags = CLK_SET_RATE_PARENT,
463 			.ops = &clk_branch2_ops,
464 		},
465 	},
466 };
467 
468 static struct clk_branch disp_cc_mdss_mdp_lut1_clk = {
469 	.halt_reg = 0xa014,
470 	.halt_check = BRANCH_HALT,
471 	.clkr = {
472 		.enable_reg = 0xa014,
473 		.enable_mask = BIT(0),
474 		.hw.init = &(const struct clk_init_data) {
475 			.name = "disp_cc_mdss_mdp_lut1_clk",
476 			.parent_hws = (const struct clk_hw*[]) {
477 				&disp_cc_mdss_mdp_clk_src.clkr.hw,
478 			},
479 			.num_parents = 1,
480 			.flags = CLK_SET_RATE_PARENT,
481 			.ops = &clk_branch2_ops,
482 		},
483 	},
484 };
485 
486 static struct clk_branch disp_cc_mdss_mdp_lut_clk = {
487 	.halt_reg = 0x8018,
488 	.halt_check = BRANCH_HALT_VOTED,
489 	.clkr = {
490 		.enable_reg = 0x8018,
491 		.enable_mask = BIT(0),
492 		.hw.init = &(const struct clk_init_data) {
493 			.name = "disp_cc_mdss_mdp_lut_clk",
494 			.parent_hws = (const struct clk_hw*[]) {
495 				&disp_cc_mdss_mdp_clk_src.clkr.hw,
496 			},
497 			.num_parents = 1,
498 			.flags = CLK_SET_RATE_PARENT,
499 			.ops = &clk_branch2_ops,
500 		},
501 	},
502 };
503 
504 static struct clk_branch disp_cc_mdss_non_gdsc_ahb_clk = {
505 	.halt_reg = 0xc004,
506 	.halt_check = BRANCH_HALT_VOTED,
507 	.clkr = {
508 		.enable_reg = 0xc004,
509 		.enable_mask = BIT(0),
510 		.hw.init = &(const struct clk_init_data) {
511 			.name = "disp_cc_mdss_non_gdsc_ahb_clk",
512 			.parent_hws = (const struct clk_hw*[]) {
513 				&disp_cc_mdss_ahb_clk_src.clkr.hw,
514 			},
515 			.num_parents = 1,
516 			.flags = CLK_SET_RATE_PARENT,
517 			.ops = &clk_branch2_ops,
518 		},
519 	},
520 };
521 
522 static struct clk_branch disp_cc_mdss_pclk0_clk = {
523 	.halt_reg = 0x8004,
524 	.halt_check = BRANCH_HALT,
525 	.clkr = {
526 		.enable_reg = 0x8004,
527 		.enable_mask = BIT(0),
528 		.hw.init = &(const struct clk_init_data) {
529 			.name = "disp_cc_mdss_pclk0_clk",
530 			.parent_hws = (const struct clk_hw*[]) {
531 				&disp_cc_mdss_pclk0_clk_src.clkr.hw,
532 			},
533 			.num_parents = 1,
534 			.flags = CLK_SET_RATE_PARENT,
535 			.ops = &clk_branch2_ops,
536 		},
537 	},
538 };
539 
540 static struct clk_branch disp_cc_mdss_rot1_clk = {
541 	.halt_reg = 0xa00c,
542 	.halt_check = BRANCH_HALT,
543 	.clkr = {
544 		.enable_reg = 0xa00c,
545 		.enable_mask = BIT(0),
546 		.hw.init = &(const struct clk_init_data) {
547 			.name = "disp_cc_mdss_rot1_clk",
548 			.parent_hws = (const struct clk_hw*[]) {
549 				&disp_cc_mdss_rot_clk_src.clkr.hw,
550 			},
551 			.num_parents = 1,
552 			.flags = CLK_SET_RATE_PARENT,
553 			.ops = &clk_branch2_ops,
554 		},
555 	},
556 };
557 
558 static struct clk_branch disp_cc_mdss_rot_clk = {
559 	.halt_reg = 0x8010,
560 	.halt_check = BRANCH_HALT,
561 	.clkr = {
562 		.enable_reg = 0x8010,
563 		.enable_mask = BIT(0),
564 		.hw.init = &(const struct clk_init_data) {
565 			.name = "disp_cc_mdss_rot_clk",
566 			.parent_hws = (const struct clk_hw*[]) {
567 				&disp_cc_mdss_rot_clk_src.clkr.hw,
568 			},
569 			.num_parents = 1,
570 			.flags = CLK_SET_RATE_PARENT,
571 			.ops = &clk_branch2_ops,
572 		},
573 	},
574 };
575 
576 static struct clk_branch disp_cc_mdss_rscc_ahb_clk = {
577 	.halt_reg = 0xc00c,
578 	.halt_check = BRANCH_HALT,
579 	.clkr = {
580 		.enable_reg = 0xc00c,
581 		.enable_mask = BIT(0),
582 		.hw.init = &(const struct clk_init_data) {
583 			.name = "disp_cc_mdss_rscc_ahb_clk",
584 			.parent_hws = (const struct clk_hw*[]) {
585 				&disp_cc_mdss_ahb_clk_src.clkr.hw,
586 			},
587 			.num_parents = 1,
588 			.flags = CLK_SET_RATE_PARENT,
589 			.ops = &clk_branch2_ops,
590 		},
591 	},
592 };
593 
594 static struct clk_branch disp_cc_mdss_rscc_vsync_clk = {
595 	.halt_reg = 0xc008,
596 	.halt_check = BRANCH_HALT,
597 	.clkr = {
598 		.enable_reg = 0xc008,
599 		.enable_mask = BIT(0),
600 		.hw.init = &(const struct clk_init_data) {
601 			.name = "disp_cc_mdss_rscc_vsync_clk",
602 			.parent_hws = (const struct clk_hw*[]) {
603 				&disp_cc_mdss_vsync_clk_src.clkr.hw,
604 			},
605 			.num_parents = 1,
606 			.flags = CLK_SET_RATE_PARENT,
607 			.ops = &clk_branch2_ops,
608 		},
609 	},
610 };
611 
612 static struct clk_branch disp_cc_mdss_vsync1_clk = {
613 	.halt_reg = 0xa01c,
614 	.halt_check = BRANCH_HALT,
615 	.clkr = {
616 		.enable_reg = 0xa01c,
617 		.enable_mask = BIT(0),
618 		.hw.init = &(const struct clk_init_data) {
619 			.name = "disp_cc_mdss_vsync1_clk",
620 			.parent_hws = (const struct clk_hw*[]) {
621 				&disp_cc_mdss_vsync_clk_src.clkr.hw,
622 			},
623 			.num_parents = 1,
624 			.flags = CLK_SET_RATE_PARENT,
625 			.ops = &clk_branch2_ops,
626 		},
627 	},
628 };
629 
630 static struct clk_branch disp_cc_mdss_vsync_clk = {
631 	.halt_reg = 0x8020,
632 	.halt_check = BRANCH_HALT,
633 	.clkr = {
634 		.enable_reg = 0x8020,
635 		.enable_mask = BIT(0),
636 		.hw.init = &(const struct clk_init_data) {
637 			.name = "disp_cc_mdss_vsync_clk",
638 			.parent_hws = (const struct clk_hw*[]) {
639 				&disp_cc_mdss_vsync_clk_src.clkr.hw,
640 			},
641 			.num_parents = 1,
642 			.flags = CLK_SET_RATE_PARENT,
643 			.ops = &clk_branch2_ops,
644 		},
645 	},
646 };
647 
648 static struct gdsc disp_cc_mdss_core_gdsc = {
649 	.gdscr = 0x9000,
650 	.en_rest_wait_val = 0x2,
651 	.en_few_wait_val = 0x2,
652 	.clk_dis_wait_val = 0xf,
653 	.pd = {
654 		.name = "disp_cc_mdss_core_gdsc",
655 	},
656 	.pwrsts = PWRSTS_OFF_ON,
657 	.flags = HW_CTRL | POLL_CFG_GDSCR | RETAIN_FF_ENABLE,
658 };
659 
660 static struct gdsc disp_cc_mdss_core_int2_gdsc = {
661 	.gdscr = 0xb000,
662 	.en_rest_wait_val = 0x2,
663 	.en_few_wait_val = 0x2,
664 	.clk_dis_wait_val = 0xf,
665 	.pd = {
666 		.name = "disp_cc_mdss_core_int2_gdsc",
667 	},
668 	.pwrsts = PWRSTS_OFF_ON,
669 	.flags = HW_CTRL | POLL_CFG_GDSCR | RETAIN_FF_ENABLE,
670 };
671 
672 static struct clk_regmap *disp_cc_sm4450_clocks[] = {
673 	[DISP_CC_MDSS_AHB1_CLK] = &disp_cc_mdss_ahb1_clk.clkr,
674 	[DISP_CC_MDSS_AHB_CLK] = &disp_cc_mdss_ahb_clk.clkr,
675 	[DISP_CC_MDSS_AHB_CLK_SRC] = &disp_cc_mdss_ahb_clk_src.clkr,
676 	[DISP_CC_MDSS_BYTE0_CLK] = &disp_cc_mdss_byte0_clk.clkr,
677 	[DISP_CC_MDSS_BYTE0_CLK_SRC] = &disp_cc_mdss_byte0_clk_src.clkr,
678 	[DISP_CC_MDSS_BYTE0_DIV_CLK_SRC] = &disp_cc_mdss_byte0_div_clk_src.clkr,
679 	[DISP_CC_MDSS_BYTE0_INTF_CLK] = &disp_cc_mdss_byte0_intf_clk.clkr,
680 	[DISP_CC_MDSS_ESC0_CLK] = &disp_cc_mdss_esc0_clk.clkr,
681 	[DISP_CC_MDSS_ESC0_CLK_SRC] = &disp_cc_mdss_esc0_clk_src.clkr,
682 	[DISP_CC_MDSS_MDP1_CLK] = &disp_cc_mdss_mdp1_clk.clkr,
683 	[DISP_CC_MDSS_MDP_CLK] = &disp_cc_mdss_mdp_clk.clkr,
684 	[DISP_CC_MDSS_MDP_CLK_SRC] = &disp_cc_mdss_mdp_clk_src.clkr,
685 	[DISP_CC_MDSS_MDP_LUT1_CLK] = &disp_cc_mdss_mdp_lut1_clk.clkr,
686 	[DISP_CC_MDSS_MDP_LUT_CLK] = &disp_cc_mdss_mdp_lut_clk.clkr,
687 	[DISP_CC_MDSS_NON_GDSC_AHB_CLK] = &disp_cc_mdss_non_gdsc_ahb_clk.clkr,
688 	[DISP_CC_MDSS_PCLK0_CLK] = &disp_cc_mdss_pclk0_clk.clkr,
689 	[DISP_CC_MDSS_PCLK0_CLK_SRC] = &disp_cc_mdss_pclk0_clk_src.clkr,
690 	[DISP_CC_MDSS_ROT1_CLK] = &disp_cc_mdss_rot1_clk.clkr,
691 	[DISP_CC_MDSS_ROT_CLK] = &disp_cc_mdss_rot_clk.clkr,
692 	[DISP_CC_MDSS_ROT_CLK_SRC] = &disp_cc_mdss_rot_clk_src.clkr,
693 	[DISP_CC_MDSS_RSCC_AHB_CLK] = &disp_cc_mdss_rscc_ahb_clk.clkr,
694 	[DISP_CC_MDSS_RSCC_VSYNC_CLK] = &disp_cc_mdss_rscc_vsync_clk.clkr,
695 	[DISP_CC_MDSS_VSYNC1_CLK] = &disp_cc_mdss_vsync1_clk.clkr,
696 	[DISP_CC_MDSS_VSYNC_CLK] = &disp_cc_mdss_vsync_clk.clkr,
697 	[DISP_CC_MDSS_VSYNC_CLK_SRC] = &disp_cc_mdss_vsync_clk_src.clkr,
698 	[DISP_CC_PLL0] = &disp_cc_pll0.clkr,
699 	[DISP_CC_PLL1] = &disp_cc_pll1.clkr,
700 	[DISP_CC_SLEEP_CLK_SRC] = &disp_cc_sleep_clk_src.clkr,
701 	[DISP_CC_XO_CLK_SRC] = &disp_cc_xo_clk_src.clkr,
702 };
703 
704 static struct gdsc *disp_cc_sm4450_gdscs[] = {
705 	[DISP_CC_MDSS_CORE_GDSC] = &disp_cc_mdss_core_gdsc,
706 	[DISP_CC_MDSS_CORE_INT2_GDSC] = &disp_cc_mdss_core_int2_gdsc,
707 };
708 
709 static const struct qcom_reset_map disp_cc_sm4450_resets[] = {
710 	[DISP_CC_MDSS_CORE_BCR] = { 0x8000 },
711 	[DISP_CC_MDSS_CORE_INT2_BCR] = { 0xa000 },
712 	[DISP_CC_MDSS_RSCC_BCR] = { 0xc000 },
713 };
714 
715 static const struct regmap_config disp_cc_sm4450_regmap_config = {
716 	.reg_bits = 32,
717 	.reg_stride = 4,
718 	.val_bits = 32,
719 	.max_register = 0x11008,
720 	.fast_io = true,
721 };
722 
723 static const struct qcom_cc_desc disp_cc_sm4450_desc = {
724 	.config = &disp_cc_sm4450_regmap_config,
725 	.clks = disp_cc_sm4450_clocks,
726 	.num_clks = ARRAY_SIZE(disp_cc_sm4450_clocks),
727 	.resets = disp_cc_sm4450_resets,
728 	.num_resets = ARRAY_SIZE(disp_cc_sm4450_resets),
729 	.gdscs = disp_cc_sm4450_gdscs,
730 	.num_gdscs = ARRAY_SIZE(disp_cc_sm4450_gdscs),
731 };
732 
733 static const struct of_device_id disp_cc_sm4450_match_table[] = {
734 	{ .compatible = "qcom,sm4450-dispcc" },
735 	{ }
736 };
737 MODULE_DEVICE_TABLE(of, disp_cc_sm4450_match_table);
738 
739 static int disp_cc_sm4450_probe(struct platform_device *pdev)
740 {
741 	struct regmap *regmap;
742 
743 	regmap = qcom_cc_map(pdev, &disp_cc_sm4450_desc);
744 	if (IS_ERR(regmap))
745 		return PTR_ERR(regmap);
746 
747 	clk_lucid_evo_pll_configure(&disp_cc_pll0, regmap, &disp_cc_pll0_config);
748 	clk_lucid_evo_pll_configure(&disp_cc_pll1, regmap, &disp_cc_pll0_config);
749 
750 	/* Keep some clocks always enabled */
751 	qcom_branch_set_clk_en(regmap, 0xe070); /* DISP_CC_SLEEP_CLK */
752 	qcom_branch_set_clk_en(regmap, 0xe054); /* DISP_CC_XO_CLK */
753 
754 	return qcom_cc_really_probe(&pdev->dev, &disp_cc_sm4450_desc, regmap);
755 }
756 
757 static struct platform_driver disp_cc_sm4450_driver = {
758 	.probe = disp_cc_sm4450_probe,
759 	.driver = {
760 		.name = "dispcc-sm4450",
761 		.of_match_table = disp_cc_sm4450_match_table,
762 	},
763 };
764 
765 module_platform_driver(disp_cc_sm4450_driver);
766 
767 MODULE_DESCRIPTION("QTI DISPCC SM4450 Driver");
768 MODULE_LICENSE("GPL");
769