• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.h>
7 #include <linux/clk-provider.h>
8 #include <linux/module.h>
9 #include <linux/platform_device.h>
10 #include <linux/regmap.h>
11 #include <linux/reset-controller.h>
12 
13 #include <dt-bindings/clock/qcom,dispcc-sdm845.h>
14 
15 #include "clk-alpha-pll.h"
16 #include "clk-branch.h"
17 #include "clk-rcg.h"
18 #include "clk-regmap-divider.h"
19 #include "common.h"
20 #include "gdsc.h"
21 #include "reset.h"
22 
23 enum {
24 	P_BI_TCXO,
25 	P_DISP_CC_PLL0_OUT_MAIN,
26 	P_DSI0_PHY_PLL_OUT_BYTECLK,
27 	P_DSI0_PHY_PLL_OUT_DSICLK,
28 	P_DSI1_PHY_PLL_OUT_BYTECLK,
29 	P_DSI1_PHY_PLL_OUT_DSICLK,
30 	P_GPLL0_OUT_MAIN,
31 	P_GPLL0_OUT_MAIN_DIV,
32 	P_DP_PHY_PLL_LINK_CLK,
33 	P_DP_PHY_PLL_VCO_DIV_CLK,
34 };
35 
36 static struct clk_alpha_pll disp_cc_pll0 = {
37 	.offset = 0x0,
38 	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
39 	.clkr = {
40 		.hw.init = &(struct clk_init_data){
41 			.name = "disp_cc_pll0",
42 			.parent_data = &(const struct clk_parent_data){
43 				.fw_name = "bi_tcxo", .name = "bi_tcxo",
44 			},
45 			.num_parents = 1,
46 			.ops = &clk_alpha_pll_fabia_ops,
47 		},
48 	},
49 };
50 
51 static const struct parent_map disp_cc_parent_map_0[] = {
52 	{ P_BI_TCXO, 0 },
53 	{ P_DSI0_PHY_PLL_OUT_BYTECLK, 1 },
54 	{ P_DSI1_PHY_PLL_OUT_BYTECLK, 2 },
55 };
56 
57 static const struct clk_parent_data disp_cc_parent_data_0[] = {
58 	{ .fw_name = "bi_tcxo", .name = "bi_tcxo" },
59 	{ .fw_name = "dsi0_phy_pll_out_byteclk", .name = "dsi0_phy_pll_out_byteclk" },
60 	{ .fw_name = "dsi1_phy_pll_out_byteclk", .name = "dsi1_phy_pll_out_byteclk" },
61 };
62 
63 static const struct parent_map disp_cc_parent_map_1[] = {
64 	{ P_BI_TCXO, 0 },
65 	{ P_DP_PHY_PLL_LINK_CLK, 1 },
66 	{ P_DP_PHY_PLL_VCO_DIV_CLK, 2 },
67 };
68 
69 static const struct clk_parent_data disp_cc_parent_data_1[] = {
70 	{ .fw_name = "bi_tcxo", .name = "bi_tcxo" },
71 	{ .fw_name = "dp_link_clk_divsel_ten", .name = "dp_link_clk_divsel_ten" },
72 	{ .fw_name = "dp_vco_divided_clk_src_mux", .name = "dp_vco_divided_clk_src_mux" },
73 };
74 
75 static const struct parent_map disp_cc_parent_map_2[] = {
76 	{ P_BI_TCXO, 0 },
77 };
78 
79 static const struct clk_parent_data disp_cc_parent_data_2[] = {
80 	{ .fw_name = "bi_tcxo", .name = "bi_tcxo" },
81 };
82 
83 static const struct parent_map disp_cc_parent_map_3[] = {
84 	{ P_BI_TCXO, 0 },
85 	{ P_DISP_CC_PLL0_OUT_MAIN, 1 },
86 	{ P_GPLL0_OUT_MAIN, 4 },
87 	{ P_GPLL0_OUT_MAIN_DIV, 5 },
88 };
89 
90 static const struct clk_parent_data disp_cc_parent_data_3[] = {
91 	{ .fw_name = "bi_tcxo", .name = "bi_tcxo" },
92 	{ .hw = &disp_cc_pll0.clkr.hw },
93 	{ .fw_name = "gcc_disp_gpll0_clk_src", .name = "gcc_disp_gpll0_clk_src" },
94 	{ .fw_name = "gcc_disp_gpll0_div_clk_src", .name = "gcc_disp_gpll0_div_clk_src" },
95 };
96 
97 static const struct parent_map disp_cc_parent_map_4[] = {
98 	{ P_BI_TCXO, 0 },
99 	{ P_DSI0_PHY_PLL_OUT_DSICLK, 1 },
100 	{ P_DSI1_PHY_PLL_OUT_DSICLK, 2 },
101 };
102 
103 static const struct clk_parent_data disp_cc_parent_data_4[] = {
104 	{ .fw_name = "bi_tcxo", .name = "bi_tcxo" },
105 	{ .fw_name = "dsi0_phy_pll_out_dsiclk", .name = "dsi0_phy_pll_out_dsiclk" },
106 	{ .fw_name = "dsi1_phy_pll_out_dsiclk", .name = "dsi1_phy_pll_out_dsiclk" },
107 };
108 
109 /* Return the HW recalc rate for idle use case */
110 static struct clk_rcg2 disp_cc_mdss_byte0_clk_src = {
111 	.cmd_rcgr = 0x20d0,
112 	.mnd_width = 0,
113 	.hid_width = 5,
114 	.parent_map = disp_cc_parent_map_0,
115 	.clkr.hw.init = &(struct clk_init_data){
116 		.name = "disp_cc_mdss_byte0_clk_src",
117 		.parent_data = disp_cc_parent_data_0,
118 		.num_parents = ARRAY_SIZE(disp_cc_parent_data_0),
119 		.flags = CLK_SET_RATE_PARENT,
120 		.ops = &clk_byte2_ops,
121 	},
122 };
123 
124 /* Return the HW recalc rate for idle use case */
125 static struct clk_rcg2 disp_cc_mdss_byte1_clk_src = {
126 	.cmd_rcgr = 0x20ec,
127 	.mnd_width = 0,
128 	.hid_width = 5,
129 	.parent_map = disp_cc_parent_map_0,
130 	.clkr.hw.init = &(struct clk_init_data){
131 		.name = "disp_cc_mdss_byte1_clk_src",
132 		.parent_data = disp_cc_parent_data_0,
133 		.num_parents = ARRAY_SIZE(disp_cc_parent_data_0),
134 		.flags = CLK_SET_RATE_PARENT,
135 		.ops = &clk_byte2_ops,
136 	},
137 };
138 
139 static const struct freq_tbl ftbl_disp_cc_mdss_dp_aux_clk_src[] = {
140 	F(19200000, P_BI_TCXO, 1, 0, 0),
141 	{ }
142 };
143 
144 static struct clk_rcg2 disp_cc_mdss_dp_aux_clk_src = {
145 	.cmd_rcgr = 0x219c,
146 	.mnd_width = 0,
147 	.hid_width = 5,
148 	.parent_map = disp_cc_parent_map_2,
149 	.freq_tbl = ftbl_disp_cc_mdss_dp_aux_clk_src,
150 	.clkr.hw.init = &(struct clk_init_data){
151 		.name = "disp_cc_mdss_dp_aux_clk_src",
152 		.parent_data = disp_cc_parent_data_2,
153 		.num_parents = ARRAY_SIZE(disp_cc_parent_data_2),
154 		.flags = CLK_SET_RATE_PARENT,
155 		.ops = &clk_rcg2_ops,
156 	},
157 };
158 
159 static struct clk_rcg2 disp_cc_mdss_dp_crypto_clk_src = {
160 	.cmd_rcgr = 0x2154,
161 	.mnd_width = 0,
162 	.hid_width = 5,
163 	.parent_map = disp_cc_parent_map_1,
164 	.clkr.hw.init = &(struct clk_init_data){
165 		.name = "disp_cc_mdss_dp_crypto_clk_src",
166 		.parent_data = disp_cc_parent_data_1,
167 		.num_parents = ARRAY_SIZE(disp_cc_parent_data_1),
168 		.ops = &clk_byte2_ops,
169 	},
170 };
171 
172 static struct clk_rcg2 disp_cc_mdss_dp_link_clk_src = {
173 	.cmd_rcgr = 0x2138,
174 	.mnd_width = 0,
175 	.hid_width = 5,
176 	.parent_map = disp_cc_parent_map_1,
177 	.clkr.hw.init = &(struct clk_init_data){
178 		.name = "disp_cc_mdss_dp_link_clk_src",
179 		.parent_data = disp_cc_parent_data_1,
180 		.num_parents = ARRAY_SIZE(disp_cc_parent_data_1),
181 		.flags = CLK_SET_RATE_PARENT,
182 		.ops = &clk_byte2_ops,
183 	},
184 };
185 
186 static struct clk_rcg2 disp_cc_mdss_dp_pixel1_clk_src = {
187 	.cmd_rcgr = 0x2184,
188 	.mnd_width = 16,
189 	.hid_width = 5,
190 	.parent_map = disp_cc_parent_map_1,
191 	.clkr.hw.init = &(struct clk_init_data){
192 		.name = "disp_cc_mdss_dp_pixel1_clk_src",
193 		.parent_data = disp_cc_parent_data_1,
194 		.num_parents = ARRAY_SIZE(disp_cc_parent_data_1),
195 		.flags = CLK_SET_RATE_PARENT,
196 		.ops = &clk_dp_ops,
197 	},
198 };
199 
200 static struct clk_rcg2 disp_cc_mdss_dp_pixel_clk_src = {
201 	.cmd_rcgr = 0x216c,
202 	.mnd_width = 16,
203 	.hid_width = 5,
204 	.parent_map = disp_cc_parent_map_1,
205 	.clkr.hw.init = &(struct clk_init_data){
206 		.name = "disp_cc_mdss_dp_pixel_clk_src",
207 		.parent_data = disp_cc_parent_data_1,
208 		.num_parents = ARRAY_SIZE(disp_cc_parent_data_1),
209 		.flags = CLK_SET_RATE_PARENT,
210 		.ops = &clk_dp_ops,
211 	},
212 };
213 
214 static const struct freq_tbl ftbl_disp_cc_mdss_esc0_clk_src[] = {
215 	F(19200000, P_BI_TCXO, 1, 0, 0),
216 	{ }
217 };
218 
219 static struct clk_rcg2 disp_cc_mdss_esc0_clk_src = {
220 	.cmd_rcgr = 0x2108,
221 	.mnd_width = 0,
222 	.hid_width = 5,
223 	.parent_map = disp_cc_parent_map_0,
224 	.freq_tbl = ftbl_disp_cc_mdss_esc0_clk_src,
225 	.clkr.hw.init = &(struct clk_init_data){
226 		.name = "disp_cc_mdss_esc0_clk_src",
227 		.parent_data = disp_cc_parent_data_0,
228 		.num_parents = ARRAY_SIZE(disp_cc_parent_data_0),
229 		.ops = &clk_rcg2_ops,
230 	},
231 };
232 
233 static struct clk_rcg2 disp_cc_mdss_esc1_clk_src = {
234 	.cmd_rcgr = 0x2120,
235 	.mnd_width = 0,
236 	.hid_width = 5,
237 	.parent_map = disp_cc_parent_map_0,
238 	.freq_tbl = ftbl_disp_cc_mdss_esc0_clk_src,
239 	.clkr.hw.init = &(struct clk_init_data){
240 		.name = "disp_cc_mdss_esc1_clk_src",
241 		.parent_data = disp_cc_parent_data_0,
242 		.num_parents = ARRAY_SIZE(disp_cc_parent_data_0),
243 		.ops = &clk_rcg2_ops,
244 	},
245 };
246 
247 static const struct freq_tbl ftbl_disp_cc_mdss_mdp_clk_src[] = {
248 	F(19200000, P_BI_TCXO, 1, 0, 0),
249 	F(85714286, P_GPLL0_OUT_MAIN, 7, 0, 0),
250 	F(100000000, P_GPLL0_OUT_MAIN, 6, 0, 0),
251 	F(150000000, P_GPLL0_OUT_MAIN, 4, 0, 0),
252 	F(171428571, P_GPLL0_OUT_MAIN, 3.5, 0, 0),
253 	F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0),
254 	F(300000000, P_GPLL0_OUT_MAIN, 2, 0, 0),
255 	F(344000000, P_DISP_CC_PLL0_OUT_MAIN, 2.5, 0, 0),
256 	F(430000000, P_DISP_CC_PLL0_OUT_MAIN, 2, 0, 0),
257 	{ }
258 };
259 
260 static struct clk_rcg2 disp_cc_mdss_mdp_clk_src = {
261 	.cmd_rcgr = 0x2088,
262 	.mnd_width = 0,
263 	.hid_width = 5,
264 	.parent_map = disp_cc_parent_map_3,
265 	.freq_tbl = ftbl_disp_cc_mdss_mdp_clk_src,
266 	.clkr.hw.init = &(struct clk_init_data){
267 		.name = "disp_cc_mdss_mdp_clk_src",
268 		.parent_data = disp_cc_parent_data_3,
269 		.num_parents = ARRAY_SIZE(disp_cc_parent_data_3),
270 		.ops = &clk_rcg2_shared_ops,
271 	},
272 };
273 
274 /* Return the HW recalc rate for idle use case */
275 static struct clk_rcg2 disp_cc_mdss_pclk0_clk_src = {
276 	.cmd_rcgr = 0x2058,
277 	.mnd_width = 8,
278 	.hid_width = 5,
279 	.parent_map = disp_cc_parent_map_4,
280 	.clkr.hw.init = &(struct clk_init_data){
281 		.name = "disp_cc_mdss_pclk0_clk_src",
282 		.parent_data = disp_cc_parent_data_4,
283 		.num_parents = ARRAY_SIZE(disp_cc_parent_data_4),
284 		.flags = CLK_SET_RATE_PARENT,
285 		.ops = &clk_pixel_ops,
286 	},
287 };
288 
289 /* Return the HW recalc rate for idle use case */
290 static struct clk_rcg2 disp_cc_mdss_pclk1_clk_src = {
291 	.cmd_rcgr = 0x2070,
292 	.mnd_width = 8,
293 	.hid_width = 5,
294 	.parent_map = disp_cc_parent_map_4,
295 	.clkr.hw.init = &(struct clk_init_data){
296 		.name = "disp_cc_mdss_pclk1_clk_src",
297 		.parent_data = disp_cc_parent_data_4,
298 		.num_parents = ARRAY_SIZE(disp_cc_parent_data_4),
299 		.flags = CLK_SET_RATE_PARENT,
300 		.ops = &clk_pixel_ops,
301 	},
302 };
303 
304 static const struct freq_tbl ftbl_disp_cc_mdss_rot_clk_src[] = {
305 	F(19200000, P_BI_TCXO, 1, 0, 0),
306 	F(171428571, P_GPLL0_OUT_MAIN, 3.5, 0, 0),
307 	F(300000000, P_GPLL0_OUT_MAIN, 2, 0, 0),
308 	F(344000000, P_DISP_CC_PLL0_OUT_MAIN, 2.5, 0, 0),
309 	F(430000000, P_DISP_CC_PLL0_OUT_MAIN, 2, 0, 0),
310 	{ }
311 };
312 
313 static struct clk_rcg2 disp_cc_mdss_rot_clk_src = {
314 	.cmd_rcgr = 0x20a0,
315 	.mnd_width = 0,
316 	.hid_width = 5,
317 	.parent_map = disp_cc_parent_map_3,
318 	.freq_tbl = ftbl_disp_cc_mdss_rot_clk_src,
319 	.clkr.hw.init = &(struct clk_init_data){
320 		.name = "disp_cc_mdss_rot_clk_src",
321 		.parent_data = disp_cc_parent_data_3,
322 		.num_parents = ARRAY_SIZE(disp_cc_parent_data_3),
323 		.ops = &clk_rcg2_shared_ops,
324 	},
325 };
326 
327 static struct clk_rcg2 disp_cc_mdss_vsync_clk_src = {
328 	.cmd_rcgr = 0x20b8,
329 	.mnd_width = 0,
330 	.hid_width = 5,
331 	.parent_map = disp_cc_parent_map_2,
332 	.freq_tbl = ftbl_disp_cc_mdss_esc0_clk_src,
333 	.clkr.hw.init = &(struct clk_init_data){
334 		.name = "disp_cc_mdss_vsync_clk_src",
335 		.parent_data = disp_cc_parent_data_2,
336 		.num_parents = ARRAY_SIZE(disp_cc_parent_data_2),
337 		.ops = &clk_rcg2_ops,
338 	},
339 };
340 
341 static struct clk_branch disp_cc_mdss_ahb_clk = {
342 	.halt_reg = 0x4004,
343 	.halt_check = BRANCH_HALT,
344 	.clkr = {
345 		.enable_reg = 0x4004,
346 		.enable_mask = BIT(0),
347 		.hw.init = &(struct clk_init_data){
348 			.name = "disp_cc_mdss_ahb_clk",
349 			.ops = &clk_branch2_ops,
350 		},
351 	},
352 };
353 
354 static struct clk_branch disp_cc_mdss_axi_clk = {
355 	.halt_reg = 0x4008,
356 	.halt_check = BRANCH_HALT,
357 	.clkr = {
358 		.enable_reg = 0x4008,
359 		.enable_mask = BIT(0),
360 		.hw.init = &(struct clk_init_data){
361 			.name = "disp_cc_mdss_axi_clk",
362 			.ops = &clk_branch2_ops,
363 		},
364 	},
365 };
366 
367 /* Return the HW recalc rate for idle use case */
368 static struct clk_branch disp_cc_mdss_byte0_clk = {
369 	.halt_reg = 0x2028,
370 	.halt_check = BRANCH_HALT,
371 	.clkr = {
372 		.enable_reg = 0x2028,
373 		.enable_mask = BIT(0),
374 		.hw.init = &(struct clk_init_data){
375 			.name = "disp_cc_mdss_byte0_clk",
376 			.parent_hws = (const struct clk_hw*[]){
377 				&disp_cc_mdss_byte0_clk_src.clkr.hw,
378 			},
379 			.num_parents = 1,
380 			.flags = CLK_SET_RATE_PARENT,
381 			.ops = &clk_branch2_ops,
382 		},
383 	},
384 };
385 
386 /* Return the HW recalc rate for idle use case */
387 static struct clk_regmap_div disp_cc_mdss_byte0_div_clk_src = {
388 	.reg = 0x20e8,
389 	.shift = 0,
390 	.width = 2,
391 	.clkr = {
392 		.hw.init = &(struct clk_init_data){
393 			.name = "disp_cc_mdss_byte0_div_clk_src",
394 			.parent_hws = (const struct clk_hw*[]){
395 				&disp_cc_mdss_byte0_clk_src.clkr.hw,
396 			},
397 			.num_parents = 1,
398 			.ops = &clk_regmap_div_ops,
399 		},
400 	},
401 };
402 
403 /* Return the HW recalc rate for idle use case */
404 static struct clk_branch disp_cc_mdss_byte0_intf_clk = {
405 	.halt_reg = 0x202c,
406 	.halt_check = BRANCH_HALT,
407 	.clkr = {
408 		.enable_reg = 0x202c,
409 		.enable_mask = BIT(0),
410 		.hw.init = &(struct clk_init_data){
411 			.name = "disp_cc_mdss_byte0_intf_clk",
412 			.parent_hws = (const struct clk_hw*[]){
413 				&disp_cc_mdss_byte0_div_clk_src.clkr.hw,
414 			},
415 			.num_parents = 1,
416 			.flags = CLK_SET_RATE_PARENT,
417 			.ops = &clk_branch2_ops,
418 		},
419 	},
420 };
421 
422 /* Return the HW recalc rate for idle use case */
423 static struct clk_branch disp_cc_mdss_byte1_clk = {
424 	.halt_reg = 0x2030,
425 	.halt_check = BRANCH_HALT,
426 	.clkr = {
427 		.enable_reg = 0x2030,
428 		.enable_mask = BIT(0),
429 		.hw.init = &(struct clk_init_data){
430 			.name = "disp_cc_mdss_byte1_clk",
431 			.parent_hws = (const struct clk_hw*[]){
432 				&disp_cc_mdss_byte1_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 /* Return the HW recalc rate for idle use case */
442 static struct clk_regmap_div disp_cc_mdss_byte1_div_clk_src = {
443 	.reg = 0x2104,
444 	.shift = 0,
445 	.width = 2,
446 	.clkr = {
447 		.hw.init = &(struct clk_init_data){
448 			.name = "disp_cc_mdss_byte1_div_clk_src",
449 			.parent_hws = (const struct clk_hw*[]){
450 				&disp_cc_mdss_byte1_clk_src.clkr.hw,
451 			},
452 			.num_parents = 1,
453 			.ops = &clk_regmap_div_ops,
454 		},
455 	},
456 };
457 
458 /* Return the HW recalc rate for idle use case */
459 static struct clk_branch disp_cc_mdss_byte1_intf_clk = {
460 	.halt_reg = 0x2034,
461 	.halt_check = BRANCH_HALT,
462 	.clkr = {
463 		.enable_reg = 0x2034,
464 		.enable_mask = BIT(0),
465 		.hw.init = &(struct clk_init_data){
466 			.name = "disp_cc_mdss_byte1_intf_clk",
467 			.parent_hws = (const struct clk_hw*[]){
468 				&disp_cc_mdss_byte1_div_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_dp_aux_clk = {
478 	.halt_reg = 0x2054,
479 	.halt_check = BRANCH_HALT,
480 	.clkr = {
481 		.enable_reg = 0x2054,
482 		.enable_mask = BIT(0),
483 		.hw.init = &(struct clk_init_data){
484 			.name = "disp_cc_mdss_dp_aux_clk",
485 			.parent_hws = (const struct clk_hw*[]){
486 				&disp_cc_mdss_dp_aux_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_mdss_dp_crypto_clk = {
496 	.halt_reg = 0x2048,
497 	.halt_check = BRANCH_HALT,
498 	.clkr = {
499 		.enable_reg = 0x2048,
500 		.enable_mask = BIT(0),
501 		.hw.init = &(struct clk_init_data){
502 			.name = "disp_cc_mdss_dp_crypto_clk",
503 			.parent_hws = (const struct clk_hw*[]){
504 				&disp_cc_mdss_dp_crypto_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 clk_branch disp_cc_mdss_dp_link_clk = {
514 	.halt_reg = 0x2040,
515 	.halt_check = BRANCH_HALT,
516 	.clkr = {
517 		.enable_reg = 0x2040,
518 		.enable_mask = BIT(0),
519 		.hw.init = &(struct clk_init_data){
520 			.name = "disp_cc_mdss_dp_link_clk",
521 			.parent_hws = (const struct clk_hw*[]){
522 				&disp_cc_mdss_dp_link_clk_src.clkr.hw,
523 			},
524 			.num_parents = 1,
525 			.flags = CLK_SET_RATE_PARENT,
526 			.ops = &clk_branch2_ops,
527 		},
528 	},
529 };
530 
531 /* reset state of disp_cc_mdss_dp_link_div_clk_src divider is 0x3 (div 4) */
532 static struct clk_branch disp_cc_mdss_dp_link_intf_clk = {
533 	.halt_reg = 0x2044,
534 	.halt_check = BRANCH_HALT,
535 	.clkr = {
536 		.enable_reg = 0x2044,
537 		.enable_mask = BIT(0),
538 		.hw.init = &(struct clk_init_data){
539 			.name = "disp_cc_mdss_dp_link_intf_clk",
540 			.parent_hws = (const struct clk_hw*[]){
541 				&disp_cc_mdss_dp_link_clk_src.clkr.hw,
542 			},
543 			.num_parents = 1,
544 			.ops = &clk_branch2_ops,
545 		},
546 	},
547 };
548 
549 static struct clk_branch disp_cc_mdss_dp_pixel1_clk = {
550 	.halt_reg = 0x2050,
551 	.halt_check = BRANCH_HALT,
552 	.clkr = {
553 		.enable_reg = 0x2050,
554 		.enable_mask = BIT(0),
555 		.hw.init = &(struct clk_init_data){
556 			.name = "disp_cc_mdss_dp_pixel1_clk",
557 			.parent_hws = (const struct clk_hw*[]){
558 				&disp_cc_mdss_dp_pixel1_clk_src.clkr.hw,
559 			},
560 			.num_parents = 1,
561 			.flags = CLK_SET_RATE_PARENT,
562 			.ops = &clk_branch2_ops,
563 		},
564 	},
565 };
566 
567 static struct clk_branch disp_cc_mdss_dp_pixel_clk = {
568 	.halt_reg = 0x204c,
569 	.halt_check = BRANCH_HALT,
570 	.clkr = {
571 		.enable_reg = 0x204c,
572 		.enable_mask = BIT(0),
573 		.hw.init = &(struct clk_init_data){
574 			.name = "disp_cc_mdss_dp_pixel_clk",
575 			.parent_hws = (const struct clk_hw*[]){
576 				&disp_cc_mdss_dp_pixel_clk_src.clkr.hw,
577 			},
578 			.num_parents = 1,
579 			.flags = CLK_SET_RATE_PARENT,
580 			.ops = &clk_branch2_ops,
581 		},
582 	},
583 };
584 
585 static struct clk_branch disp_cc_mdss_esc0_clk = {
586 	.halt_reg = 0x2038,
587 	.halt_check = BRANCH_HALT,
588 	.clkr = {
589 		.enable_reg = 0x2038,
590 		.enable_mask = BIT(0),
591 		.hw.init = &(struct clk_init_data){
592 			.name = "disp_cc_mdss_esc0_clk",
593 			.parent_hws = (const struct clk_hw*[]){
594 				&disp_cc_mdss_esc0_clk_src.clkr.hw,
595 			},
596 			.num_parents = 1,
597 			.flags = CLK_SET_RATE_PARENT,
598 			.ops = &clk_branch2_ops,
599 		},
600 	},
601 };
602 
603 static struct clk_branch disp_cc_mdss_esc1_clk = {
604 	.halt_reg = 0x203c,
605 	.halt_check = BRANCH_HALT,
606 	.clkr = {
607 		.enable_reg = 0x203c,
608 		.enable_mask = BIT(0),
609 		.hw.init = &(struct clk_init_data){
610 			.name = "disp_cc_mdss_esc1_clk",
611 			.parent_hws = (const struct clk_hw*[]){
612 				&disp_cc_mdss_esc1_clk_src.clkr.hw,
613 			},
614 			.num_parents = 1,
615 			.flags = CLK_SET_RATE_PARENT,
616 			.ops = &clk_branch2_ops,
617 		},
618 	},
619 };
620 
621 static struct clk_branch disp_cc_mdss_mdp_clk = {
622 	.halt_reg = 0x200c,
623 	.halt_check = BRANCH_HALT,
624 	.clkr = {
625 		.enable_reg = 0x200c,
626 		.enable_mask = BIT(0),
627 		.hw.init = &(struct clk_init_data){
628 			.name = "disp_cc_mdss_mdp_clk",
629 			.parent_hws = (const struct clk_hw*[]){
630 				&disp_cc_mdss_mdp_clk_src.clkr.hw,
631 			},
632 			.num_parents = 1,
633 			.flags = CLK_SET_RATE_PARENT,
634 			.ops = &clk_branch2_ops,
635 		},
636 	},
637 };
638 
639 static struct clk_branch disp_cc_mdss_mdp_lut_clk = {
640 	.halt_reg = 0x201c,
641 	.halt_check = BRANCH_HALT,
642 	.clkr = {
643 		.enable_reg = 0x201c,
644 		.enable_mask = BIT(0),
645 		.hw.init = &(struct clk_init_data){
646 			.name = "disp_cc_mdss_mdp_lut_clk",
647 			.parent_hws = (const struct clk_hw*[]){
648 				&disp_cc_mdss_mdp_clk_src.clkr.hw,
649 			},
650 			.num_parents = 1,
651 			.ops = &clk_branch2_ops,
652 		},
653 	},
654 };
655 
656 /* Return the HW recalc rate for idle use case */
657 static struct clk_branch disp_cc_mdss_pclk0_clk = {
658 	.halt_reg = 0x2004,
659 	.halt_check = BRANCH_HALT,
660 	.clkr = {
661 		.enable_reg = 0x2004,
662 		.enable_mask = BIT(0),
663 		.hw.init = &(struct clk_init_data){
664 			.name = "disp_cc_mdss_pclk0_clk",
665 			.parent_hws = (const struct clk_hw*[]){
666 				&disp_cc_mdss_pclk0_clk_src.clkr.hw,
667 			},
668 			.num_parents = 1,
669 			.flags = CLK_SET_RATE_PARENT,
670 			.ops = &clk_branch2_ops,
671 		},
672 	},
673 };
674 
675 /* Return the HW recalc rate for idle use case */
676 static struct clk_branch disp_cc_mdss_pclk1_clk = {
677 	.halt_reg = 0x2008,
678 	.halt_check = BRANCH_HALT,
679 	.clkr = {
680 		.enable_reg = 0x2008,
681 		.enable_mask = BIT(0),
682 		.hw.init = &(struct clk_init_data){
683 			.name = "disp_cc_mdss_pclk1_clk",
684 			.parent_hws = (const struct clk_hw*[]){
685 				&disp_cc_mdss_pclk1_clk_src.clkr.hw,
686 			},
687 			.num_parents = 1,
688 			.flags = CLK_SET_RATE_PARENT,
689 			.ops = &clk_branch2_ops,
690 		},
691 	},
692 };
693 
694 static struct clk_branch disp_cc_mdss_rot_clk = {
695 	.halt_reg = 0x2014,
696 	.halt_check = BRANCH_HALT,
697 	.clkr = {
698 		.enable_reg = 0x2014,
699 		.enable_mask = BIT(0),
700 		.hw.init = &(struct clk_init_data){
701 			.name = "disp_cc_mdss_rot_clk",
702 			.parent_hws = (const struct clk_hw*[]){
703 				&disp_cc_mdss_rot_clk_src.clkr.hw,
704 			},
705 			.num_parents = 1,
706 			.flags = CLK_SET_RATE_PARENT,
707 			.ops = &clk_branch2_ops,
708 		},
709 	},
710 };
711 
712 static struct clk_branch disp_cc_mdss_rscc_ahb_clk = {
713 	.halt_reg = 0x5004,
714 	.halt_check = BRANCH_HALT,
715 	.clkr = {
716 		.enable_reg = 0x5004,
717 		.enable_mask = BIT(0),
718 		.hw.init = &(struct clk_init_data){
719 			.name = "disp_cc_mdss_rscc_ahb_clk",
720 			.ops = &clk_branch2_ops,
721 		},
722 	},
723 };
724 
725 static struct clk_branch disp_cc_mdss_rscc_vsync_clk = {
726 	.halt_reg = 0x5008,
727 	.halt_check = BRANCH_HALT,
728 	.clkr = {
729 		.enable_reg = 0x5008,
730 		.enable_mask = BIT(0),
731 		.hw.init = &(struct clk_init_data){
732 			.name = "disp_cc_mdss_rscc_vsync_clk",
733 			.parent_hws = (const struct clk_hw*[]){
734 				&disp_cc_mdss_vsync_clk_src.clkr.hw,
735 			},
736 			.num_parents = 1,
737 			.flags = CLK_SET_RATE_PARENT,
738 			.ops = &clk_branch2_ops,
739 		},
740 	},
741 };
742 
743 static struct clk_branch disp_cc_mdss_vsync_clk = {
744 	.halt_reg = 0x2024,
745 	.halt_check = BRANCH_HALT,
746 	.clkr = {
747 		.enable_reg = 0x2024,
748 		.enable_mask = BIT(0),
749 		.hw.init = &(struct clk_init_data){
750 			.name = "disp_cc_mdss_vsync_clk",
751 			.parent_hws = (const struct clk_hw*[]){
752 				&disp_cc_mdss_vsync_clk_src.clkr.hw,
753 			},
754 			.num_parents = 1,
755 			.flags = CLK_SET_RATE_PARENT,
756 			.ops = &clk_branch2_ops,
757 		},
758 	},
759 };
760 
761 static struct gdsc mdss_gdsc = {
762 	.gdscr = 0x3000,
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 
disp_cc_sdm845_probe(struct platform_device * pdev)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, &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 		.sync_state = clk_sync_state,
874 	},
875 };
876 
disp_cc_sdm845_init(void)877 static int __init disp_cc_sdm845_init(void)
878 {
879 	return platform_driver_register(&disp_cc_sdm845_driver);
880 }
881 subsys_initcall(disp_cc_sdm845_init);
882 
disp_cc_sdm845_exit(void)883 static void __exit disp_cc_sdm845_exit(void)
884 {
885 	platform_driver_unregister(&disp_cc_sdm845_driver);
886 }
887 module_exit(disp_cc_sdm845_exit);
888 
889 MODULE_LICENSE("GPL v2");
890 MODULE_DESCRIPTION("QTI DISPCC SDM845 Driver");
891