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