xref: /linux/drivers/clk/qcom/dispcc-sdm845.c (revision 18fbf5151d2c0bfe433c7428eef03cabf5fdb2fa)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
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,dispcc-sdm845.h>
12 
13 #include "clk-alpha-pll.h"
14 #include "clk-branch.h"
15 #include "clk-rcg.h"
16 #include "clk-regmap-divider.h"
17 #include "common.h"
18 #include "gdsc.h"
19 #include "reset.h"
20 
21 enum {
22 	P_BI_TCXO,
23 	P_DISP_CC_PLL0_OUT_MAIN,
24 	P_DSI0_PHY_PLL_OUT_BYTECLK,
25 	P_DSI0_PHY_PLL_OUT_DSICLK,
26 	P_DSI1_PHY_PLL_OUT_BYTECLK,
27 	P_DSI1_PHY_PLL_OUT_DSICLK,
28 	P_GPLL0_OUT_MAIN,
29 	P_GPLL0_OUT_MAIN_DIV,
30 	P_DP_PHY_PLL_LINK_CLK,
31 	P_DP_PHY_PLL_VCO_DIV_CLK,
32 };
33 
34 static struct clk_alpha_pll disp_cc_pll0 = {
35 	.offset = 0x0,
36 	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
37 	.clkr = {
38 		.hw.init = &(struct clk_init_data){
39 			.name = "disp_cc_pll0",
40 			.parent_data = &(const struct clk_parent_data){
41 				.fw_name = "bi_tcxo", .name = "bi_tcxo",
42 			},
43 			.num_parents = 1,
44 			.ops = &clk_alpha_pll_fabia_ops,
45 		},
46 	},
47 };
48 
49 static const struct parent_map disp_cc_parent_map_0[] = {
50 	{ P_BI_TCXO, 0 },
51 	{ P_DSI0_PHY_PLL_OUT_BYTECLK, 1 },
52 	{ P_DSI1_PHY_PLL_OUT_BYTECLK, 2 },
53 };
54 
55 static const struct clk_parent_data disp_cc_parent_data_0[] = {
56 	{ .fw_name = "bi_tcxo", .name = "bi_tcxo" },
57 	{ .fw_name = "dsi0_phy_pll_out_byteclk", .name = "dsi0_phy_pll_out_byteclk" },
58 	{ .fw_name = "dsi1_phy_pll_out_byteclk", .name = "dsi1_phy_pll_out_byteclk" },
59 };
60 
61 static const struct parent_map disp_cc_parent_map_1[] = {
62 	{ P_BI_TCXO, 0 },
63 	{ P_DP_PHY_PLL_LINK_CLK, 1 },
64 	{ P_DP_PHY_PLL_VCO_DIV_CLK, 2 },
65 };
66 
67 static const struct clk_parent_data disp_cc_parent_data_1[] = {
68 	{ .fw_name = "bi_tcxo", .name = "bi_tcxo" },
69 	{ .fw_name = "dp_link_clk_divsel_ten", .name = "dp_link_clk_divsel_ten" },
70 	{ .fw_name = "dp_vco_divided_clk_src_mux", .name = "dp_vco_divided_clk_src_mux" },
71 };
72 
73 static const struct parent_map disp_cc_parent_map_2[] = {
74 	{ P_BI_TCXO, 0 },
75 };
76 
77 static const struct clk_parent_data disp_cc_parent_data_2[] = {
78 	{ .fw_name = "bi_tcxo", .name = "bi_tcxo" },
79 };
80 
81 static const struct parent_map disp_cc_parent_map_3[] = {
82 	{ P_BI_TCXO, 0 },
83 	{ P_DISP_CC_PLL0_OUT_MAIN, 1 },
84 	{ P_GPLL0_OUT_MAIN, 4 },
85 	{ P_GPLL0_OUT_MAIN_DIV, 5 },
86 };
87 
88 static const struct clk_parent_data disp_cc_parent_data_3[] = {
89 	{ .fw_name = "bi_tcxo", .name = "bi_tcxo" },
90 	{ .hw = &disp_cc_pll0.clkr.hw },
91 	{ .fw_name = "gcc_disp_gpll0_clk_src", .name = "gcc_disp_gpll0_clk_src" },
92 	{ .fw_name = "gcc_disp_gpll0_div_clk_src", .name = "gcc_disp_gpll0_div_clk_src" },
93 };
94 
95 static const struct parent_map disp_cc_parent_map_4[] = {
96 	{ P_BI_TCXO, 0 },
97 	{ P_DSI0_PHY_PLL_OUT_DSICLK, 1 },
98 	{ P_DSI1_PHY_PLL_OUT_DSICLK, 2 },
99 };
100 
101 static const struct clk_parent_data disp_cc_parent_data_4[] = {
102 	{ .fw_name = "bi_tcxo", .name = "bi_tcxo" },
103 	{ .fw_name = "dsi0_phy_pll_out_dsiclk", .name = "dsi0_phy_pll_out_dsiclk" },
104 	{ .fw_name = "dsi1_phy_pll_out_dsiclk", .name = "dsi1_phy_pll_out_dsiclk" },
105 };
106 
107 /* Return the HW recalc rate for idle use case */
108 static struct clk_rcg2 disp_cc_mdss_byte0_clk_src = {
109 	.cmd_rcgr = 0x20d0,
110 	.mnd_width = 0,
111 	.hid_width = 5,
112 	.parent_map = disp_cc_parent_map_0,
113 	.clkr.hw.init = &(struct clk_init_data){
114 		.name = "disp_cc_mdss_byte0_clk_src",
115 		.parent_data = disp_cc_parent_data_0,
116 		.num_parents = ARRAY_SIZE(disp_cc_parent_data_0),
117 		.flags = CLK_SET_RATE_PARENT,
118 		.ops = &clk_byte2_ops,
119 	},
120 };
121 
122 /* Return the HW recalc rate for idle use case */
123 static struct clk_rcg2 disp_cc_mdss_byte1_clk_src = {
124 	.cmd_rcgr = 0x20ec,
125 	.mnd_width = 0,
126 	.hid_width = 5,
127 	.parent_map = disp_cc_parent_map_0,
128 	.clkr.hw.init = &(struct clk_init_data){
129 		.name = "disp_cc_mdss_byte1_clk_src",
130 		.parent_data = disp_cc_parent_data_0,
131 		.num_parents = ARRAY_SIZE(disp_cc_parent_data_0),
132 		.flags = CLK_SET_RATE_PARENT,
133 		.ops = &clk_byte2_ops,
134 	},
135 };
136 
137 static const struct freq_tbl ftbl_disp_cc_mdss_dp_aux_clk_src[] = {
138 	F(19200000, P_BI_TCXO, 1, 0, 0),
139 	{ }
140 };
141 
142 static struct clk_rcg2 disp_cc_mdss_dp_aux_clk_src = {
143 	.cmd_rcgr = 0x219c,
144 	.mnd_width = 0,
145 	.hid_width = 5,
146 	.parent_map = disp_cc_parent_map_2,
147 	.freq_tbl = ftbl_disp_cc_mdss_dp_aux_clk_src,
148 	.clkr.hw.init = &(struct clk_init_data){
149 		.name = "disp_cc_mdss_dp_aux_clk_src",
150 		.parent_data = disp_cc_parent_data_2,
151 		.num_parents = ARRAY_SIZE(disp_cc_parent_data_2),
152 		.flags = CLK_SET_RATE_PARENT,
153 		.ops = &clk_rcg2_ops,
154 	},
155 };
156 
157 static struct clk_rcg2 disp_cc_mdss_dp_crypto_clk_src = {
158 	.cmd_rcgr = 0x2154,
159 	.mnd_width = 0,
160 	.hid_width = 5,
161 	.parent_map = disp_cc_parent_map_1,
162 	.clkr.hw.init = &(struct clk_init_data){
163 		.name = "disp_cc_mdss_dp_crypto_clk_src",
164 		.parent_data = disp_cc_parent_data_1,
165 		.num_parents = ARRAY_SIZE(disp_cc_parent_data_1),
166 		.ops = &clk_byte2_ops,
167 	},
168 };
169 
170 static struct clk_rcg2 disp_cc_mdss_dp_link_clk_src = {
171 	.cmd_rcgr = 0x2138,
172 	.mnd_width = 0,
173 	.hid_width = 5,
174 	.parent_map = disp_cc_parent_map_1,
175 	.clkr.hw.init = &(struct clk_init_data){
176 		.name = "disp_cc_mdss_dp_link_clk_src",
177 		.parent_data = disp_cc_parent_data_1,
178 		.num_parents = ARRAY_SIZE(disp_cc_parent_data_1),
179 		.flags = CLK_SET_RATE_PARENT,
180 		.ops = &clk_byte2_ops,
181 	},
182 };
183 
184 static struct clk_rcg2 disp_cc_mdss_dp_pixel1_clk_src = {
185 	.cmd_rcgr = 0x2184,
186 	.mnd_width = 16,
187 	.hid_width = 5,
188 	.parent_map = disp_cc_parent_map_1,
189 	.clkr.hw.init = &(struct clk_init_data){
190 		.name = "disp_cc_mdss_dp_pixel1_clk_src",
191 		.parent_data = disp_cc_parent_data_1,
192 		.num_parents = ARRAY_SIZE(disp_cc_parent_data_1),
193 		.flags = CLK_SET_RATE_PARENT,
194 		.ops = &clk_dp_ops,
195 	},
196 };
197 
198 static struct clk_rcg2 disp_cc_mdss_dp_pixel_clk_src = {
199 	.cmd_rcgr = 0x216c,
200 	.mnd_width = 16,
201 	.hid_width = 5,
202 	.parent_map = disp_cc_parent_map_1,
203 	.clkr.hw.init = &(struct clk_init_data){
204 		.name = "disp_cc_mdss_dp_pixel_clk_src",
205 		.parent_data = disp_cc_parent_data_1,
206 		.num_parents = ARRAY_SIZE(disp_cc_parent_data_1),
207 		.flags = CLK_SET_RATE_PARENT,
208 		.ops = &clk_dp_ops,
209 	},
210 };
211 
212 static const struct freq_tbl ftbl_disp_cc_mdss_esc0_clk_src[] = {
213 	F(19200000, P_BI_TCXO, 1, 0, 0),
214 	{ }
215 };
216 
217 static struct clk_rcg2 disp_cc_mdss_esc0_clk_src = {
218 	.cmd_rcgr = 0x2108,
219 	.mnd_width = 0,
220 	.hid_width = 5,
221 	.parent_map = disp_cc_parent_map_0,
222 	.freq_tbl = ftbl_disp_cc_mdss_esc0_clk_src,
223 	.clkr.hw.init = &(struct clk_init_data){
224 		.name = "disp_cc_mdss_esc0_clk_src",
225 		.parent_data = disp_cc_parent_data_0,
226 		.num_parents = ARRAY_SIZE(disp_cc_parent_data_0),
227 		.ops = &clk_rcg2_ops,
228 	},
229 };
230 
231 static struct clk_rcg2 disp_cc_mdss_esc1_clk_src = {
232 	.cmd_rcgr = 0x2120,
233 	.mnd_width = 0,
234 	.hid_width = 5,
235 	.parent_map = disp_cc_parent_map_0,
236 	.freq_tbl = ftbl_disp_cc_mdss_esc0_clk_src,
237 	.clkr.hw.init = &(struct clk_init_data){
238 		.name = "disp_cc_mdss_esc1_clk_src",
239 		.parent_data = disp_cc_parent_data_0,
240 		.num_parents = ARRAY_SIZE(disp_cc_parent_data_0),
241 		.ops = &clk_rcg2_ops,
242 	},
243 };
244 
245 static const struct freq_tbl ftbl_disp_cc_mdss_mdp_clk_src[] = {
246 	F(19200000, P_BI_TCXO, 1, 0, 0),
247 	F(85714286, P_GPLL0_OUT_MAIN, 7, 0, 0),
248 	F(100000000, P_GPLL0_OUT_MAIN, 6, 0, 0),
249 	F(150000000, P_GPLL0_OUT_MAIN, 4, 0, 0),
250 	F(171428571, P_GPLL0_OUT_MAIN, 3.5, 0, 0),
251 	F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0),
252 	F(300000000, P_GPLL0_OUT_MAIN, 2, 0, 0),
253 	F(344000000, P_DISP_CC_PLL0_OUT_MAIN, 2.5, 0, 0),
254 	F(430000000, P_DISP_CC_PLL0_OUT_MAIN, 2, 0, 0),
255 	{ }
256 };
257 
258 static struct clk_rcg2 disp_cc_mdss_mdp_clk_src = {
259 	.cmd_rcgr = 0x2088,
260 	.mnd_width = 0,
261 	.hid_width = 5,
262 	.parent_map = disp_cc_parent_map_3,
263 	.freq_tbl = ftbl_disp_cc_mdss_mdp_clk_src,
264 	.clkr.hw.init = &(struct clk_init_data){
265 		.name = "disp_cc_mdss_mdp_clk_src",
266 		.parent_data = disp_cc_parent_data_3,
267 		.num_parents = ARRAY_SIZE(disp_cc_parent_data_3),
268 		.ops = &clk_rcg2_shared_ops,
269 	},
270 };
271 
272 /* Return the HW recalc rate for idle use case */
273 static struct clk_rcg2 disp_cc_mdss_pclk0_clk_src = {
274 	.cmd_rcgr = 0x2058,
275 	.mnd_width = 8,
276 	.hid_width = 5,
277 	.parent_map = disp_cc_parent_map_4,
278 	.clkr.hw.init = &(struct clk_init_data){
279 		.name = "disp_cc_mdss_pclk0_clk_src",
280 		.parent_data = disp_cc_parent_data_4,
281 		.num_parents = ARRAY_SIZE(disp_cc_parent_data_4),
282 		.flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
283 		.ops = &clk_pixel_ops,
284 	},
285 };
286 
287 /* Return the HW recalc rate for idle use case */
288 static struct clk_rcg2 disp_cc_mdss_pclk1_clk_src = {
289 	.cmd_rcgr = 0x2070,
290 	.mnd_width = 8,
291 	.hid_width = 5,
292 	.parent_map = disp_cc_parent_map_4,
293 	.clkr.hw.init = &(struct clk_init_data){
294 		.name = "disp_cc_mdss_pclk1_clk_src",
295 		.parent_data = disp_cc_parent_data_4,
296 		.num_parents = ARRAY_SIZE(disp_cc_parent_data_4),
297 		.flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
298 		.ops = &clk_pixel_ops,
299 	},
300 };
301 
302 static const struct freq_tbl ftbl_disp_cc_mdss_rot_clk_src[] = {
303 	F(19200000, P_BI_TCXO, 1, 0, 0),
304 	F(171428571, P_GPLL0_OUT_MAIN, 3.5, 0, 0),
305 	F(300000000, P_GPLL0_OUT_MAIN, 2, 0, 0),
306 	F(344000000, P_DISP_CC_PLL0_OUT_MAIN, 2.5, 0, 0),
307 	F(430000000, P_DISP_CC_PLL0_OUT_MAIN, 2, 0, 0),
308 	{ }
309 };
310 
311 static struct clk_rcg2 disp_cc_mdss_rot_clk_src = {
312 	.cmd_rcgr = 0x20a0,
313 	.mnd_width = 0,
314 	.hid_width = 5,
315 	.parent_map = disp_cc_parent_map_3,
316 	.freq_tbl = ftbl_disp_cc_mdss_rot_clk_src,
317 	.clkr.hw.init = &(struct clk_init_data){
318 		.name = "disp_cc_mdss_rot_clk_src",
319 		.parent_data = disp_cc_parent_data_3,
320 		.num_parents = ARRAY_SIZE(disp_cc_parent_data_3),
321 		.ops = &clk_rcg2_shared_ops,
322 	},
323 };
324 
325 static struct clk_rcg2 disp_cc_mdss_vsync_clk_src = {
326 	.cmd_rcgr = 0x20b8,
327 	.mnd_width = 0,
328 	.hid_width = 5,
329 	.parent_map = disp_cc_parent_map_2,
330 	.freq_tbl = ftbl_disp_cc_mdss_esc0_clk_src,
331 	.clkr.hw.init = &(struct clk_init_data){
332 		.name = "disp_cc_mdss_vsync_clk_src",
333 		.parent_data = disp_cc_parent_data_2,
334 		.num_parents = ARRAY_SIZE(disp_cc_parent_data_2),
335 		.ops = &clk_rcg2_ops,
336 	},
337 };
338 
339 static struct clk_branch disp_cc_mdss_ahb_clk = {
340 	.halt_reg = 0x4004,
341 	.halt_check = BRANCH_HALT,
342 	.clkr = {
343 		.enable_reg = 0x4004,
344 		.enable_mask = BIT(0),
345 		.hw.init = &(struct clk_init_data){
346 			.name = "disp_cc_mdss_ahb_clk",
347 			.ops = &clk_branch2_ops,
348 		},
349 	},
350 };
351 
352 static struct clk_branch disp_cc_mdss_axi_clk = {
353 	.halt_reg = 0x4008,
354 	.halt_check = BRANCH_HALT,
355 	.clkr = {
356 		.enable_reg = 0x4008,
357 		.enable_mask = BIT(0),
358 		.hw.init = &(struct clk_init_data){
359 			.name = "disp_cc_mdss_axi_clk",
360 			.ops = &clk_branch2_ops,
361 		},
362 	},
363 };
364 
365 /* Return the HW recalc rate for idle use case */
366 static struct clk_branch disp_cc_mdss_byte0_clk = {
367 	.halt_reg = 0x2028,
368 	.halt_check = BRANCH_HALT,
369 	.clkr = {
370 		.enable_reg = 0x2028,
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,
379 			.ops = &clk_branch2_ops,
380 		},
381 	},
382 };
383 
384 /* Return the HW recalc rate for idle use case */
385 static struct clk_regmap_div disp_cc_mdss_byte0_div_clk_src = {
386 	.reg = 0x20e8,
387 	.shift = 0,
388 	.width = 2,
389 	.clkr = {
390 		.hw.init = &(struct clk_init_data){
391 			.name = "disp_cc_mdss_byte0_div_clk_src",
392 			.parent_hws = (const struct clk_hw*[]){
393 				&disp_cc_mdss_byte0_clk_src.clkr.hw,
394 			},
395 			.num_parents = 1,
396 			.ops = &clk_regmap_div_ops,
397 		},
398 	},
399 };
400 
401 /* Return the HW recalc rate for idle use case */
402 static struct clk_branch disp_cc_mdss_byte0_intf_clk = {
403 	.halt_reg = 0x202c,
404 	.halt_check = BRANCH_HALT,
405 	.clkr = {
406 		.enable_reg = 0x202c,
407 		.enable_mask = BIT(0),
408 		.hw.init = &(struct clk_init_data){
409 			.name = "disp_cc_mdss_byte0_intf_clk",
410 			.parent_hws = (const struct clk_hw*[]){
411 				&disp_cc_mdss_byte0_div_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 /* Return the HW recalc rate for idle use case */
421 static struct clk_branch disp_cc_mdss_byte1_clk = {
422 	.halt_reg = 0x2030,
423 	.halt_check = BRANCH_HALT,
424 	.clkr = {
425 		.enable_reg = 0x2030,
426 		.enable_mask = BIT(0),
427 		.hw.init = &(struct clk_init_data){
428 			.name = "disp_cc_mdss_byte1_clk",
429 			.parent_hws = (const struct clk_hw*[]){
430 				&disp_cc_mdss_byte1_clk_src.clkr.hw,
431 			},
432 			.num_parents = 1,
433 			.flags = CLK_SET_RATE_PARENT,
434 			.ops = &clk_branch2_ops,
435 		},
436 	},
437 };
438 
439 /* Return the HW recalc rate for idle use case */
440 static struct clk_regmap_div disp_cc_mdss_byte1_div_clk_src = {
441 	.reg = 0x2104,
442 	.shift = 0,
443 	.width = 2,
444 	.clkr = {
445 		.hw.init = &(struct clk_init_data){
446 			.name = "disp_cc_mdss_byte1_div_clk_src",
447 			.parent_hws = (const struct clk_hw*[]){
448 				&disp_cc_mdss_byte1_clk_src.clkr.hw,
449 			},
450 			.num_parents = 1,
451 			.ops = &clk_regmap_div_ops,
452 		},
453 	},
454 };
455 
456 /* Return the HW recalc rate for idle use case */
457 static struct clk_branch disp_cc_mdss_byte1_intf_clk = {
458 	.halt_reg = 0x2034,
459 	.halt_check = BRANCH_HALT,
460 	.clkr = {
461 		.enable_reg = 0x2034,
462 		.enable_mask = BIT(0),
463 		.hw.init = &(struct clk_init_data){
464 			.name = "disp_cc_mdss_byte1_intf_clk",
465 			.parent_hws = (const struct clk_hw*[]){
466 				&disp_cc_mdss_byte1_div_clk_src.clkr.hw,
467 			},
468 			.num_parents = 1,
469 			.flags = CLK_SET_RATE_PARENT,
470 			.ops = &clk_branch2_ops,
471 		},
472 	},
473 };
474 
475 static struct clk_branch disp_cc_mdss_dp_aux_clk = {
476 	.halt_reg = 0x2054,
477 	.halt_check = BRANCH_HALT,
478 	.clkr = {
479 		.enable_reg = 0x2054,
480 		.enable_mask = BIT(0),
481 		.hw.init = &(struct clk_init_data){
482 			.name = "disp_cc_mdss_dp_aux_clk",
483 			.parent_hws = (const struct clk_hw*[]){
484 				&disp_cc_mdss_dp_aux_clk_src.clkr.hw,
485 			},
486 			.num_parents = 1,
487 			.flags = CLK_SET_RATE_PARENT,
488 			.ops = &clk_branch2_ops,
489 		},
490 	},
491 };
492 
493 static struct clk_branch disp_cc_mdss_dp_crypto_clk = {
494 	.halt_reg = 0x2048,
495 	.halt_check = BRANCH_HALT,
496 	.clkr = {
497 		.enable_reg = 0x2048,
498 		.enable_mask = BIT(0),
499 		.hw.init = &(struct clk_init_data){
500 			.name = "disp_cc_mdss_dp_crypto_clk",
501 			.parent_hws = (const struct clk_hw*[]){
502 				&disp_cc_mdss_dp_crypto_clk_src.clkr.hw,
503 			},
504 			.num_parents = 1,
505 			.flags = CLK_SET_RATE_PARENT,
506 			.ops = &clk_branch2_ops,
507 		},
508 	},
509 };
510 
511 static struct clk_branch disp_cc_mdss_dp_link_clk = {
512 	.halt_reg = 0x2040,
513 	.halt_check = BRANCH_HALT,
514 	.clkr = {
515 		.enable_reg = 0x2040,
516 		.enable_mask = BIT(0),
517 		.hw.init = &(struct clk_init_data){
518 			.name = "disp_cc_mdss_dp_link_clk",
519 			.parent_hws = (const struct clk_hw*[]){
520 				&disp_cc_mdss_dp_link_clk_src.clkr.hw,
521 			},
522 			.num_parents = 1,
523 			.flags = CLK_SET_RATE_PARENT,
524 			.ops = &clk_branch2_ops,
525 		},
526 	},
527 };
528 
529 /* reset state of disp_cc_mdss_dp_link_div_clk_src divider is 0x3 (div 4) */
530 static struct clk_branch disp_cc_mdss_dp_link_intf_clk = {
531 	.halt_reg = 0x2044,
532 	.halt_check = BRANCH_HALT,
533 	.clkr = {
534 		.enable_reg = 0x2044,
535 		.enable_mask = BIT(0),
536 		.hw.init = &(struct clk_init_data){
537 			.name = "disp_cc_mdss_dp_link_intf_clk",
538 			.parent_hws = (const struct clk_hw*[]){
539 				&disp_cc_mdss_dp_link_clk_src.clkr.hw,
540 			},
541 			.num_parents = 1,
542 			.ops = &clk_branch2_ops,
543 		},
544 	},
545 };
546 
547 static struct clk_branch disp_cc_mdss_dp_pixel1_clk = {
548 	.halt_reg = 0x2050,
549 	.halt_check = BRANCH_HALT,
550 	.clkr = {
551 		.enable_reg = 0x2050,
552 		.enable_mask = BIT(0),
553 		.hw.init = &(struct clk_init_data){
554 			.name = "disp_cc_mdss_dp_pixel1_clk",
555 			.parent_hws = (const struct clk_hw*[]){
556 				&disp_cc_mdss_dp_pixel1_clk_src.clkr.hw,
557 			},
558 			.num_parents = 1,
559 			.flags = CLK_SET_RATE_PARENT,
560 			.ops = &clk_branch2_ops,
561 		},
562 	},
563 };
564 
565 static struct clk_branch disp_cc_mdss_dp_pixel_clk = {
566 	.halt_reg = 0x204c,
567 	.halt_check = BRANCH_HALT,
568 	.clkr = {
569 		.enable_reg = 0x204c,
570 		.enable_mask = BIT(0),
571 		.hw.init = &(struct clk_init_data){
572 			.name = "disp_cc_mdss_dp_pixel_clk",
573 			.parent_hws = (const struct clk_hw*[]){
574 				&disp_cc_mdss_dp_pixel_clk_src.clkr.hw,
575 			},
576 			.num_parents = 1,
577 			.flags = CLK_SET_RATE_PARENT,
578 			.ops = &clk_branch2_ops,
579 		},
580 	},
581 };
582 
583 static struct clk_branch disp_cc_mdss_esc0_clk = {
584 	.halt_reg = 0x2038,
585 	.halt_check = BRANCH_HALT,
586 	.clkr = {
587 		.enable_reg = 0x2038,
588 		.enable_mask = BIT(0),
589 		.hw.init = &(struct clk_init_data){
590 			.name = "disp_cc_mdss_esc0_clk",
591 			.parent_hws = (const struct clk_hw*[]){
592 				&disp_cc_mdss_esc0_clk_src.clkr.hw,
593 			},
594 			.num_parents = 1,
595 			.flags = CLK_SET_RATE_PARENT,
596 			.ops = &clk_branch2_ops,
597 		},
598 	},
599 };
600 
601 static struct clk_branch disp_cc_mdss_esc1_clk = {
602 	.halt_reg = 0x203c,
603 	.halt_check = BRANCH_HALT,
604 	.clkr = {
605 		.enable_reg = 0x203c,
606 		.enable_mask = BIT(0),
607 		.hw.init = &(struct clk_init_data){
608 			.name = "disp_cc_mdss_esc1_clk",
609 			.parent_hws = (const struct clk_hw*[]){
610 				&disp_cc_mdss_esc1_clk_src.clkr.hw,
611 			},
612 			.num_parents = 1,
613 			.flags = CLK_SET_RATE_PARENT,
614 			.ops = &clk_branch2_ops,
615 		},
616 	},
617 };
618 
619 static struct clk_branch disp_cc_mdss_mdp_clk = {
620 	.halt_reg = 0x200c,
621 	.halt_check = BRANCH_HALT,
622 	.clkr = {
623 		.enable_reg = 0x200c,
624 		.enable_mask = BIT(0),
625 		.hw.init = &(struct clk_init_data){
626 			.name = "disp_cc_mdss_mdp_clk",
627 			.parent_hws = (const struct clk_hw*[]){
628 				&disp_cc_mdss_mdp_clk_src.clkr.hw,
629 			},
630 			.num_parents = 1,
631 			.flags = CLK_SET_RATE_PARENT,
632 			.ops = &clk_branch2_ops,
633 		},
634 	},
635 };
636 
637 static struct clk_branch disp_cc_mdss_mdp_lut_clk = {
638 	.halt_reg = 0x201c,
639 	.halt_check = BRANCH_HALT,
640 	.clkr = {
641 		.enable_reg = 0x201c,
642 		.enable_mask = BIT(0),
643 		.hw.init = &(struct clk_init_data){
644 			.name = "disp_cc_mdss_mdp_lut_clk",
645 			.parent_hws = (const struct clk_hw*[]){
646 				&disp_cc_mdss_mdp_clk_src.clkr.hw,
647 			},
648 			.num_parents = 1,
649 			.ops = &clk_branch2_ops,
650 		},
651 	},
652 };
653 
654 /* Return the HW recalc rate for idle use case */
655 static struct clk_branch disp_cc_mdss_pclk0_clk = {
656 	.halt_reg = 0x2004,
657 	.halt_check = BRANCH_HALT,
658 	.clkr = {
659 		.enable_reg = 0x2004,
660 		.enable_mask = BIT(0),
661 		.hw.init = &(struct clk_init_data){
662 			.name = "disp_cc_mdss_pclk0_clk",
663 			.parent_hws = (const struct clk_hw*[]){
664 				&disp_cc_mdss_pclk0_clk_src.clkr.hw,
665 			},
666 			.num_parents = 1,
667 			.flags = CLK_SET_RATE_PARENT,
668 			.ops = &clk_branch2_ops,
669 		},
670 	},
671 };
672 
673 /* Return the HW recalc rate for idle use case */
674 static struct clk_branch disp_cc_mdss_pclk1_clk = {
675 	.halt_reg = 0x2008,
676 	.halt_check = BRANCH_HALT,
677 	.clkr = {
678 		.enable_reg = 0x2008,
679 		.enable_mask = BIT(0),
680 		.hw.init = &(struct clk_init_data){
681 			.name = "disp_cc_mdss_pclk1_clk",
682 			.parent_hws = (const struct clk_hw*[]){
683 				&disp_cc_mdss_pclk1_clk_src.clkr.hw,
684 			},
685 			.num_parents = 1,
686 			.flags = CLK_SET_RATE_PARENT,
687 			.ops = &clk_branch2_ops,
688 		},
689 	},
690 };
691 
692 static struct clk_branch disp_cc_mdss_rot_clk = {
693 	.halt_reg = 0x2014,
694 	.halt_check = BRANCH_HALT,
695 	.clkr = {
696 		.enable_reg = 0x2014,
697 		.enable_mask = BIT(0),
698 		.hw.init = &(struct clk_init_data){
699 			.name = "disp_cc_mdss_rot_clk",
700 			.parent_hws = (const struct clk_hw*[]){
701 				&disp_cc_mdss_rot_clk_src.clkr.hw,
702 			},
703 			.num_parents = 1,
704 			.flags = CLK_SET_RATE_PARENT,
705 			.ops = &clk_branch2_ops,
706 		},
707 	},
708 };
709 
710 static struct clk_branch disp_cc_mdss_rscc_ahb_clk = {
711 	.halt_reg = 0x5004,
712 	.halt_check = BRANCH_HALT,
713 	.clkr = {
714 		.enable_reg = 0x5004,
715 		.enable_mask = BIT(0),
716 		.hw.init = &(struct clk_init_data){
717 			.name = "disp_cc_mdss_rscc_ahb_clk",
718 			.ops = &clk_branch2_ops,
719 		},
720 	},
721 };
722 
723 static struct clk_branch disp_cc_mdss_rscc_vsync_clk = {
724 	.halt_reg = 0x5008,
725 	.halt_check = BRANCH_HALT,
726 	.clkr = {
727 		.enable_reg = 0x5008,
728 		.enable_mask = BIT(0),
729 		.hw.init = &(struct clk_init_data){
730 			.name = "disp_cc_mdss_rscc_vsync_clk",
731 			.parent_hws = (const struct clk_hw*[]){
732 				&disp_cc_mdss_vsync_clk_src.clkr.hw,
733 			},
734 			.num_parents = 1,
735 			.flags = CLK_SET_RATE_PARENT,
736 			.ops = &clk_branch2_ops,
737 		},
738 	},
739 };
740 
741 static struct clk_branch disp_cc_mdss_vsync_clk = {
742 	.halt_reg = 0x2024,
743 	.halt_check = BRANCH_HALT,
744 	.clkr = {
745 		.enable_reg = 0x2024,
746 		.enable_mask = BIT(0),
747 		.hw.init = &(struct clk_init_data){
748 			.name = "disp_cc_mdss_vsync_clk",
749 			.parent_hws = (const struct clk_hw*[]){
750 				&disp_cc_mdss_vsync_clk_src.clkr.hw,
751 			},
752 			.num_parents = 1,
753 			.flags = CLK_SET_RATE_PARENT,
754 			.ops = &clk_branch2_ops,
755 		},
756 	},
757 };
758 
759 static struct gdsc mdss_gdsc = {
760 	.gdscr = 0x3000,
761 	.en_few_wait_val = 0x6,
762 	.en_rest_wait_val = 0x5,
763 	.pd = {
764 		.name = "mdss_gdsc",
765 	},
766 	.pwrsts = PWRSTS_OFF_ON,
767 	.flags = HW_CTRL | POLL_CFG_GDSCR,
768 };
769 
770 static struct clk_regmap *disp_cc_sdm845_clocks[] = {
771 	[DISP_CC_MDSS_AHB_CLK] = &disp_cc_mdss_ahb_clk.clkr,
772 	[DISP_CC_MDSS_AXI_CLK] = &disp_cc_mdss_axi_clk.clkr,
773 	[DISP_CC_MDSS_BYTE0_CLK] = &disp_cc_mdss_byte0_clk.clkr,
774 	[DISP_CC_MDSS_BYTE0_CLK_SRC] = &disp_cc_mdss_byte0_clk_src.clkr,
775 	[DISP_CC_MDSS_BYTE0_INTF_CLK] = &disp_cc_mdss_byte0_intf_clk.clkr,
776 	[DISP_CC_MDSS_BYTE0_DIV_CLK_SRC] =
777 					&disp_cc_mdss_byte0_div_clk_src.clkr,
778 	[DISP_CC_MDSS_BYTE1_CLK] = &disp_cc_mdss_byte1_clk.clkr,
779 	[DISP_CC_MDSS_BYTE1_CLK_SRC] = &disp_cc_mdss_byte1_clk_src.clkr,
780 	[DISP_CC_MDSS_BYTE1_INTF_CLK] = &disp_cc_mdss_byte1_intf_clk.clkr,
781 	[DISP_CC_MDSS_BYTE1_DIV_CLK_SRC] =
782 					&disp_cc_mdss_byte1_div_clk_src.clkr,
783 	[DISP_CC_MDSS_DP_AUX_CLK] = &disp_cc_mdss_dp_aux_clk.clkr,
784 	[DISP_CC_MDSS_DP_AUX_CLK_SRC] = &disp_cc_mdss_dp_aux_clk_src.clkr,
785 	[DISP_CC_MDSS_DP_CRYPTO_CLK] = &disp_cc_mdss_dp_crypto_clk.clkr,
786 	[DISP_CC_MDSS_DP_CRYPTO_CLK_SRC] =
787 					&disp_cc_mdss_dp_crypto_clk_src.clkr,
788 	[DISP_CC_MDSS_DP_LINK_CLK] = &disp_cc_mdss_dp_link_clk.clkr,
789 	[DISP_CC_MDSS_DP_LINK_CLK_SRC] = &disp_cc_mdss_dp_link_clk_src.clkr,
790 	[DISP_CC_MDSS_DP_LINK_INTF_CLK] = &disp_cc_mdss_dp_link_intf_clk.clkr,
791 	[DISP_CC_MDSS_DP_PIXEL1_CLK] = &disp_cc_mdss_dp_pixel1_clk.clkr,
792 	[DISP_CC_MDSS_DP_PIXEL1_CLK_SRC] =
793 					&disp_cc_mdss_dp_pixel1_clk_src.clkr,
794 	[DISP_CC_MDSS_DP_PIXEL_CLK] = &disp_cc_mdss_dp_pixel_clk.clkr,
795 	[DISP_CC_MDSS_DP_PIXEL_CLK_SRC] = &disp_cc_mdss_dp_pixel_clk_src.clkr,
796 	[DISP_CC_MDSS_ESC0_CLK] = &disp_cc_mdss_esc0_clk.clkr,
797 	[DISP_CC_MDSS_ESC0_CLK_SRC] = &disp_cc_mdss_esc0_clk_src.clkr,
798 	[DISP_CC_MDSS_ESC1_CLK] = &disp_cc_mdss_esc1_clk.clkr,
799 	[DISP_CC_MDSS_ESC1_CLK_SRC] = &disp_cc_mdss_esc1_clk_src.clkr,
800 	[DISP_CC_MDSS_MDP_CLK] = &disp_cc_mdss_mdp_clk.clkr,
801 	[DISP_CC_MDSS_MDP_CLK_SRC] = &disp_cc_mdss_mdp_clk_src.clkr,
802 	[DISP_CC_MDSS_MDP_LUT_CLK] = &disp_cc_mdss_mdp_lut_clk.clkr,
803 	[DISP_CC_MDSS_PCLK0_CLK] = &disp_cc_mdss_pclk0_clk.clkr,
804 	[DISP_CC_MDSS_PCLK0_CLK_SRC] = &disp_cc_mdss_pclk0_clk_src.clkr,
805 	[DISP_CC_MDSS_PCLK1_CLK] = &disp_cc_mdss_pclk1_clk.clkr,
806 	[DISP_CC_MDSS_PCLK1_CLK_SRC] = &disp_cc_mdss_pclk1_clk_src.clkr,
807 	[DISP_CC_MDSS_ROT_CLK] = &disp_cc_mdss_rot_clk.clkr,
808 	[DISP_CC_MDSS_ROT_CLK_SRC] = &disp_cc_mdss_rot_clk_src.clkr,
809 	[DISP_CC_MDSS_RSCC_AHB_CLK] = &disp_cc_mdss_rscc_ahb_clk.clkr,
810 	[DISP_CC_MDSS_RSCC_VSYNC_CLK] = &disp_cc_mdss_rscc_vsync_clk.clkr,
811 	[DISP_CC_MDSS_VSYNC_CLK] = &disp_cc_mdss_vsync_clk.clkr,
812 	[DISP_CC_MDSS_VSYNC_CLK_SRC] = &disp_cc_mdss_vsync_clk_src.clkr,
813 	[DISP_CC_PLL0] = &disp_cc_pll0.clkr,
814 };
815 
816 static const struct qcom_reset_map disp_cc_sdm845_resets[] = {
817 	[DISP_CC_MDSS_RSCC_BCR] = { 0x5000 },
818 };
819 
820 static struct gdsc *disp_cc_sdm845_gdscs[] = {
821 	[MDSS_GDSC] = &mdss_gdsc,
822 };
823 
824 static const struct regmap_config disp_cc_sdm845_regmap_config = {
825 	.reg_bits	= 32,
826 	.reg_stride	= 4,
827 	.val_bits	= 32,
828 	.max_register	= 0x10000,
829 	.fast_io	= true,
830 };
831 
832 static const struct qcom_cc_desc disp_cc_sdm845_desc = {
833 	.config = &disp_cc_sdm845_regmap_config,
834 	.clks = disp_cc_sdm845_clocks,
835 	.num_clks = ARRAY_SIZE(disp_cc_sdm845_clocks),
836 	.resets = disp_cc_sdm845_resets,
837 	.num_resets = ARRAY_SIZE(disp_cc_sdm845_resets),
838 	.gdscs = disp_cc_sdm845_gdscs,
839 	.num_gdscs = ARRAY_SIZE(disp_cc_sdm845_gdscs),
840 };
841 
842 static const struct of_device_id disp_cc_sdm845_match_table[] = {
843 	{ .compatible = "qcom,sdm845-dispcc" },
844 	{ }
845 };
846 MODULE_DEVICE_TABLE(of, disp_cc_sdm845_match_table);
847 
848 static int disp_cc_sdm845_probe(struct platform_device *pdev)
849 {
850 	struct regmap *regmap;
851 	struct alpha_pll_config disp_cc_pll0_config = {};
852 
853 	regmap = qcom_cc_map(pdev, &disp_cc_sdm845_desc);
854 	if (IS_ERR(regmap))
855 		return PTR_ERR(regmap);
856 
857 	disp_cc_pll0_config.l = 0x2c;
858 	disp_cc_pll0_config.alpha = 0xcaaa;
859 
860 	clk_fabia_pll_configure(&disp_cc_pll0, regmap, &disp_cc_pll0_config);
861 
862 	/* Enable hardware clock gating for DSI and MDP clocks */
863 	regmap_update_bits(regmap, 0x8000, 0x7f0, 0x7f0);
864 
865 	return qcom_cc_really_probe(&pdev->dev, &disp_cc_sdm845_desc, regmap);
866 }
867 
868 static struct platform_driver disp_cc_sdm845_driver = {
869 	.probe		= disp_cc_sdm845_probe,
870 	.driver		= {
871 		.name	= "disp_cc-sdm845",
872 		.of_match_table = disp_cc_sdm845_match_table,
873 	},
874 };
875 
876 module_platform_driver(disp_cc_sdm845_driver);
877 
878 MODULE_LICENSE("GPL v2");
879 MODULE_DESCRIPTION("QTI DISPCC SDM845 Driver");
880