1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Copyright (c) 2018, 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_CORE_BI_PLL_TEST_SE,
26 P_DISP_CC_PLL0_OUT_MAIN,
27 P_DSI0_PHY_PLL_OUT_BYTECLK,
28 P_DSI0_PHY_PLL_OUT_DSICLK,
29 P_DSI1_PHY_PLL_OUT_BYTECLK,
30 P_DSI1_PHY_PLL_OUT_DSICLK,
31 P_GPLL0_OUT_MAIN,
32 P_GPLL0_OUT_MAIN_DIV,
33 };
34
35 static const struct parent_map disp_cc_parent_map_0[] = {
36 { P_BI_TCXO, 0 },
37 { P_DSI0_PHY_PLL_OUT_BYTECLK, 1 },
38 { P_DSI1_PHY_PLL_OUT_BYTECLK, 2 },
39 { P_CORE_BI_PLL_TEST_SE, 7 },
40 };
41
42 static const char * const disp_cc_parent_names_0[] = {
43 "bi_tcxo",
44 "dsi0_phy_pll_out_byteclk",
45 "dsi1_phy_pll_out_byteclk",
46 "core_bi_pll_test_se",
47 };
48
49 static const struct parent_map disp_cc_parent_map_2[] = {
50 { P_BI_TCXO, 0 },
51 { P_CORE_BI_PLL_TEST_SE, 7 },
52 };
53
54 static const char * const disp_cc_parent_names_2[] = {
55 "bi_tcxo",
56 "core_bi_pll_test_se",
57 };
58
59 static const struct parent_map disp_cc_parent_map_3[] = {
60 { P_BI_TCXO, 0 },
61 { P_DISP_CC_PLL0_OUT_MAIN, 1 },
62 { P_GPLL0_OUT_MAIN, 4 },
63 { P_GPLL0_OUT_MAIN_DIV, 5 },
64 { P_CORE_BI_PLL_TEST_SE, 7 },
65 };
66
67 static const char * const disp_cc_parent_names_3[] = {
68 "bi_tcxo",
69 "disp_cc_pll0",
70 "gcc_disp_gpll0_clk_src",
71 "gcc_disp_gpll0_div_clk_src",
72 "core_bi_pll_test_se",
73 };
74
75 static const struct parent_map disp_cc_parent_map_4[] = {
76 { P_BI_TCXO, 0 },
77 { P_DSI0_PHY_PLL_OUT_DSICLK, 1 },
78 { P_DSI1_PHY_PLL_OUT_DSICLK, 2 },
79 { P_CORE_BI_PLL_TEST_SE, 7 },
80 };
81
82 static const char * const disp_cc_parent_names_4[] = {
83 "bi_tcxo",
84 "dsi0_phy_pll_out_dsiclk",
85 "dsi1_phy_pll_out_dsiclk",
86 "core_bi_pll_test_se",
87 };
88
89 static struct clk_alpha_pll disp_cc_pll0 = {
90 .offset = 0x0,
91 .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
92 .clkr = {
93 .hw.init = &(struct clk_init_data){
94 .name = "disp_cc_pll0",
95 .parent_names = (const char *[]){ "bi_tcxo" },
96 .num_parents = 1,
97 .ops = &clk_alpha_pll_fabia_ops,
98 },
99 },
100 };
101
102 /* Return the HW recalc rate for idle use case */
103 static struct clk_rcg2 disp_cc_mdss_byte0_clk_src = {
104 .cmd_rcgr = 0x20d0,
105 .mnd_width = 0,
106 .hid_width = 5,
107 .parent_map = disp_cc_parent_map_0,
108 .clkr.hw.init = &(struct clk_init_data){
109 .name = "disp_cc_mdss_byte0_clk_src",
110 .parent_names = disp_cc_parent_names_0,
111 .num_parents = 4,
112 .flags = CLK_SET_RATE_PARENT,
113 .ops = &clk_byte2_ops,
114 },
115 };
116
117 /* Return the HW recalc rate for idle use case */
118 static struct clk_rcg2 disp_cc_mdss_byte1_clk_src = {
119 .cmd_rcgr = 0x20ec,
120 .mnd_width = 0,
121 .hid_width = 5,
122 .parent_map = disp_cc_parent_map_0,
123 .clkr.hw.init = &(struct clk_init_data){
124 .name = "disp_cc_mdss_byte1_clk_src",
125 .parent_names = disp_cc_parent_names_0,
126 .num_parents = 4,
127 .flags = CLK_SET_RATE_PARENT,
128 .ops = &clk_byte2_ops,
129 },
130 };
131
132 static const struct freq_tbl ftbl_disp_cc_mdss_esc0_clk_src[] = {
133 F(19200000, P_BI_TCXO, 1, 0, 0),
134 { }
135 };
136
137 static struct clk_rcg2 disp_cc_mdss_esc0_clk_src = {
138 .cmd_rcgr = 0x2108,
139 .mnd_width = 0,
140 .hid_width = 5,
141 .parent_map = disp_cc_parent_map_0,
142 .freq_tbl = ftbl_disp_cc_mdss_esc0_clk_src,
143 .clkr.hw.init = &(struct clk_init_data){
144 .name = "disp_cc_mdss_esc0_clk_src",
145 .parent_names = disp_cc_parent_names_0,
146 .num_parents = 4,
147 .ops = &clk_rcg2_ops,
148 },
149 };
150
151 static struct clk_rcg2 disp_cc_mdss_esc1_clk_src = {
152 .cmd_rcgr = 0x2120,
153 .mnd_width = 0,
154 .hid_width = 5,
155 .parent_map = disp_cc_parent_map_0,
156 .freq_tbl = ftbl_disp_cc_mdss_esc0_clk_src,
157 .clkr.hw.init = &(struct clk_init_data){
158 .name = "disp_cc_mdss_esc1_clk_src",
159 .parent_names = disp_cc_parent_names_0,
160 .num_parents = 4,
161 .ops = &clk_rcg2_ops,
162 },
163 };
164
165 static const struct freq_tbl ftbl_disp_cc_mdss_mdp_clk_src[] = {
166 F(19200000, P_BI_TCXO, 1, 0, 0),
167 F(85714286, P_GPLL0_OUT_MAIN, 7, 0, 0),
168 F(100000000, P_GPLL0_OUT_MAIN, 6, 0, 0),
169 F(150000000, P_GPLL0_OUT_MAIN, 4, 0, 0),
170 F(171428571, P_GPLL0_OUT_MAIN, 3.5, 0, 0),
171 F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0),
172 F(300000000, P_GPLL0_OUT_MAIN, 2, 0, 0),
173 F(344000000, P_DISP_CC_PLL0_OUT_MAIN, 2.5, 0, 0),
174 F(430000000, P_DISP_CC_PLL0_OUT_MAIN, 2, 0, 0),
175 { }
176 };
177
178 static struct clk_rcg2 disp_cc_mdss_mdp_clk_src = {
179 .cmd_rcgr = 0x2088,
180 .mnd_width = 0,
181 .hid_width = 5,
182 .parent_map = disp_cc_parent_map_3,
183 .freq_tbl = ftbl_disp_cc_mdss_mdp_clk_src,
184 .clkr.hw.init = &(struct clk_init_data){
185 .name = "disp_cc_mdss_mdp_clk_src",
186 .parent_names = disp_cc_parent_names_3,
187 .num_parents = 5,
188 .ops = &clk_rcg2_shared_ops,
189 },
190 };
191
192 /* Return the HW recalc rate for idle use case */
193 static struct clk_rcg2 disp_cc_mdss_pclk0_clk_src = {
194 .cmd_rcgr = 0x2058,
195 .mnd_width = 8,
196 .hid_width = 5,
197 .parent_map = disp_cc_parent_map_4,
198 .clkr.hw.init = &(struct clk_init_data){
199 .name = "disp_cc_mdss_pclk0_clk_src",
200 .parent_names = disp_cc_parent_names_4,
201 .num_parents = 4,
202 .flags = CLK_SET_RATE_PARENT,
203 .ops = &clk_pixel_ops,
204 },
205 };
206
207 /* Return the HW recalc rate for idle use case */
208 static struct clk_rcg2 disp_cc_mdss_pclk1_clk_src = {
209 .cmd_rcgr = 0x2070,
210 .mnd_width = 8,
211 .hid_width = 5,
212 .parent_map = disp_cc_parent_map_4,
213 .clkr.hw.init = &(struct clk_init_data){
214 .name = "disp_cc_mdss_pclk1_clk_src",
215 .parent_names = disp_cc_parent_names_4,
216 .num_parents = 4,
217 .flags = CLK_SET_RATE_PARENT,
218 .ops = &clk_pixel_ops,
219 },
220 };
221
222 static const struct freq_tbl ftbl_disp_cc_mdss_rot_clk_src[] = {
223 F(19200000, P_BI_TCXO, 1, 0, 0),
224 F(171428571, P_GPLL0_OUT_MAIN, 3.5, 0, 0),
225 F(300000000, P_GPLL0_OUT_MAIN, 2, 0, 0),
226 F(344000000, P_DISP_CC_PLL0_OUT_MAIN, 2.5, 0, 0),
227 F(430000000, P_DISP_CC_PLL0_OUT_MAIN, 2, 0, 0),
228 { }
229 };
230
231 static struct clk_rcg2 disp_cc_mdss_rot_clk_src = {
232 .cmd_rcgr = 0x20a0,
233 .mnd_width = 0,
234 .hid_width = 5,
235 .parent_map = disp_cc_parent_map_3,
236 .freq_tbl = ftbl_disp_cc_mdss_rot_clk_src,
237 .clkr.hw.init = &(struct clk_init_data){
238 .name = "disp_cc_mdss_rot_clk_src",
239 .parent_names = disp_cc_parent_names_3,
240 .num_parents = 5,
241 .ops = &clk_rcg2_shared_ops,
242 },
243 };
244
245 static struct clk_rcg2 disp_cc_mdss_vsync_clk_src = {
246 .cmd_rcgr = 0x20b8,
247 .mnd_width = 0,
248 .hid_width = 5,
249 .parent_map = disp_cc_parent_map_2,
250 .freq_tbl = ftbl_disp_cc_mdss_esc0_clk_src,
251 .clkr.hw.init = &(struct clk_init_data){
252 .name = "disp_cc_mdss_vsync_clk_src",
253 .parent_names = disp_cc_parent_names_2,
254 .num_parents = 2,
255 .ops = &clk_rcg2_ops,
256 },
257 };
258
259 static struct clk_branch disp_cc_mdss_ahb_clk = {
260 .halt_reg = 0x4004,
261 .halt_check = BRANCH_HALT,
262 .clkr = {
263 .enable_reg = 0x4004,
264 .enable_mask = BIT(0),
265 .hw.init = &(struct clk_init_data){
266 .name = "disp_cc_mdss_ahb_clk",
267 .ops = &clk_branch2_ops,
268 },
269 },
270 };
271
272 static struct clk_branch disp_cc_mdss_axi_clk = {
273 .halt_reg = 0x4008,
274 .halt_check = BRANCH_HALT,
275 .clkr = {
276 .enable_reg = 0x4008,
277 .enable_mask = BIT(0),
278 .hw.init = &(struct clk_init_data){
279 .name = "disp_cc_mdss_axi_clk",
280 .ops = &clk_branch2_ops,
281 },
282 },
283 };
284
285 /* Return the HW recalc rate for idle use case */
286 static struct clk_branch disp_cc_mdss_byte0_clk = {
287 .halt_reg = 0x2028,
288 .halt_check = BRANCH_HALT,
289 .clkr = {
290 .enable_reg = 0x2028,
291 .enable_mask = BIT(0),
292 .hw.init = &(struct clk_init_data){
293 .name = "disp_cc_mdss_byte0_clk",
294 .parent_names = (const char *[]){
295 "disp_cc_mdss_byte0_clk_src",
296 },
297 .num_parents = 1,
298 .flags = CLK_SET_RATE_PARENT,
299 .ops = &clk_branch2_ops,
300 },
301 },
302 };
303
304 /* Return the HW recalc rate for idle use case */
305 static struct clk_regmap_div disp_cc_mdss_byte0_div_clk_src = {
306 .reg = 0x20e8,
307 .shift = 0,
308 .width = 2,
309 .clkr = {
310 .hw.init = &(struct clk_init_data){
311 .name = "disp_cc_mdss_byte0_div_clk_src",
312 .parent_names = (const char *[]){
313 "disp_cc_mdss_byte0_clk_src",
314 },
315 .num_parents = 1,
316 .ops = &clk_regmap_div_ops,
317 },
318 },
319 };
320
321 /* Return the HW recalc rate for idle use case */
322 static struct clk_branch disp_cc_mdss_byte0_intf_clk = {
323 .halt_reg = 0x202c,
324 .halt_check = BRANCH_HALT,
325 .clkr = {
326 .enable_reg = 0x202c,
327 .enable_mask = BIT(0),
328 .hw.init = &(struct clk_init_data){
329 .name = "disp_cc_mdss_byte0_intf_clk",
330 .parent_names = (const char *[]){
331 "disp_cc_mdss_byte0_div_clk_src",
332 },
333 .num_parents = 1,
334 .flags = CLK_SET_RATE_PARENT,
335 .ops = &clk_branch2_ops,
336 },
337 },
338 };
339
340 /* Return the HW recalc rate for idle use case */
341 static struct clk_branch disp_cc_mdss_byte1_clk = {
342 .halt_reg = 0x2030,
343 .halt_check = BRANCH_HALT,
344 .clkr = {
345 .enable_reg = 0x2030,
346 .enable_mask = BIT(0),
347 .hw.init = &(struct clk_init_data){
348 .name = "disp_cc_mdss_byte1_clk",
349 .parent_names = (const char *[]){
350 "disp_cc_mdss_byte1_clk_src",
351 },
352 .num_parents = 1,
353 .flags = CLK_SET_RATE_PARENT,
354 .ops = &clk_branch2_ops,
355 },
356 },
357 };
358
359 /* Return the HW recalc rate for idle use case */
360 static struct clk_regmap_div disp_cc_mdss_byte1_div_clk_src = {
361 .reg = 0x2104,
362 .shift = 0,
363 .width = 2,
364 .clkr = {
365 .hw.init = &(struct clk_init_data){
366 .name = "disp_cc_mdss_byte1_div_clk_src",
367 .parent_names = (const char *[]){
368 "disp_cc_mdss_byte1_clk_src",
369 },
370 .num_parents = 1,
371 .ops = &clk_regmap_div_ops,
372 },
373 },
374 };
375
376 /* Return the HW recalc rate for idle use case */
377 static struct clk_branch disp_cc_mdss_byte1_intf_clk = {
378 .halt_reg = 0x2034,
379 .halt_check = BRANCH_HALT,
380 .clkr = {
381 .enable_reg = 0x2034,
382 .enable_mask = BIT(0),
383 .hw.init = &(struct clk_init_data){
384 .name = "disp_cc_mdss_byte1_intf_clk",
385 .parent_names = (const char *[]){
386 "disp_cc_mdss_byte1_div_clk_src",
387 },
388 .num_parents = 1,
389 .flags = CLK_SET_RATE_PARENT,
390 .ops = &clk_branch2_ops,
391 },
392 },
393 };
394
395 static struct clk_branch disp_cc_mdss_esc0_clk = {
396 .halt_reg = 0x2038,
397 .halt_check = BRANCH_HALT,
398 .clkr = {
399 .enable_reg = 0x2038,
400 .enable_mask = BIT(0),
401 .hw.init = &(struct clk_init_data){
402 .name = "disp_cc_mdss_esc0_clk",
403 .parent_names = (const char *[]){
404 "disp_cc_mdss_esc0_clk_src",
405 },
406 .num_parents = 1,
407 .flags = CLK_SET_RATE_PARENT,
408 .ops = &clk_branch2_ops,
409 },
410 },
411 };
412
413 static struct clk_branch disp_cc_mdss_esc1_clk = {
414 .halt_reg = 0x203c,
415 .halt_check = BRANCH_HALT,
416 .clkr = {
417 .enable_reg = 0x203c,
418 .enable_mask = BIT(0),
419 .hw.init = &(struct clk_init_data){
420 .name = "disp_cc_mdss_esc1_clk",
421 .parent_names = (const char *[]){
422 "disp_cc_mdss_esc1_clk_src",
423 },
424 .num_parents = 1,
425 .flags = CLK_SET_RATE_PARENT,
426 .ops = &clk_branch2_ops,
427 },
428 },
429 };
430
431 static struct clk_branch disp_cc_mdss_mdp_clk = {
432 .halt_reg = 0x200c,
433 .halt_check = BRANCH_HALT,
434 .clkr = {
435 .enable_reg = 0x200c,
436 .enable_mask = BIT(0),
437 .hw.init = &(struct clk_init_data){
438 .name = "disp_cc_mdss_mdp_clk",
439 .parent_names = (const char *[]){
440 "disp_cc_mdss_mdp_clk_src",
441 },
442 .num_parents = 1,
443 .flags = CLK_SET_RATE_PARENT,
444 .ops = &clk_branch2_ops,
445 },
446 },
447 };
448
449 static struct clk_branch disp_cc_mdss_mdp_lut_clk = {
450 .halt_reg = 0x201c,
451 .halt_check = BRANCH_HALT,
452 .clkr = {
453 .enable_reg = 0x201c,
454 .enable_mask = BIT(0),
455 .hw.init = &(struct clk_init_data){
456 .name = "disp_cc_mdss_mdp_lut_clk",
457 .parent_names = (const char *[]){
458 "disp_cc_mdss_mdp_clk_src",
459 },
460 .num_parents = 1,
461 .ops = &clk_branch2_ops,
462 },
463 },
464 };
465
466 /* Return the HW recalc rate for idle use case */
467 static struct clk_branch disp_cc_mdss_pclk0_clk = {
468 .halt_reg = 0x2004,
469 .halt_check = BRANCH_HALT,
470 .clkr = {
471 .enable_reg = 0x2004,
472 .enable_mask = BIT(0),
473 .hw.init = &(struct clk_init_data){
474 .name = "disp_cc_mdss_pclk0_clk",
475 .parent_names = (const char *[]){
476 "disp_cc_mdss_pclk0_clk_src",
477 },
478 .num_parents = 1,
479 .flags = CLK_SET_RATE_PARENT,
480 .ops = &clk_branch2_ops,
481 },
482 },
483 };
484
485 /* Return the HW recalc rate for idle use case */
486 static struct clk_branch disp_cc_mdss_pclk1_clk = {
487 .halt_reg = 0x2008,
488 .halt_check = BRANCH_HALT,
489 .clkr = {
490 .enable_reg = 0x2008,
491 .enable_mask = BIT(0),
492 .hw.init = &(struct clk_init_data){
493 .name = "disp_cc_mdss_pclk1_clk",
494 .parent_names = (const char *[]){
495 "disp_cc_mdss_pclk1_clk_src",
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_rot_clk = {
505 .halt_reg = 0x2014,
506 .halt_check = BRANCH_HALT,
507 .clkr = {
508 .enable_reg = 0x2014,
509 .enable_mask = BIT(0),
510 .hw.init = &(struct clk_init_data){
511 .name = "disp_cc_mdss_rot_clk",
512 .parent_names = (const char *[]){
513 "disp_cc_mdss_rot_clk_src",
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_rscc_ahb_clk = {
523 .halt_reg = 0x5004,
524 .halt_check = BRANCH_HALT,
525 .clkr = {
526 .enable_reg = 0x5004,
527 .enable_mask = BIT(0),
528 .hw.init = &(struct clk_init_data){
529 .name = "disp_cc_mdss_rscc_ahb_clk",
530 .ops = &clk_branch2_ops,
531 },
532 },
533 };
534
535 static struct clk_branch disp_cc_mdss_rscc_vsync_clk = {
536 .halt_reg = 0x5008,
537 .halt_check = BRANCH_HALT,
538 .clkr = {
539 .enable_reg = 0x5008,
540 .enable_mask = BIT(0),
541 .hw.init = &(struct clk_init_data){
542 .name = "disp_cc_mdss_rscc_vsync_clk",
543 .parent_names = (const char *[]){
544 "disp_cc_mdss_vsync_clk_src",
545 },
546 .num_parents = 1,
547 .flags = CLK_SET_RATE_PARENT,
548 .ops = &clk_branch2_ops,
549 },
550 },
551 };
552
553 static struct clk_branch disp_cc_mdss_vsync_clk = {
554 .halt_reg = 0x2024,
555 .halt_check = BRANCH_HALT,
556 .clkr = {
557 .enable_reg = 0x2024,
558 .enable_mask = BIT(0),
559 .hw.init = &(struct clk_init_data){
560 .name = "disp_cc_mdss_vsync_clk",
561 .parent_names = (const char *[]){
562 "disp_cc_mdss_vsync_clk_src",
563 },
564 .num_parents = 1,
565 .flags = CLK_SET_RATE_PARENT,
566 .ops = &clk_branch2_ops,
567 },
568 },
569 };
570
571 static struct gdsc mdss_gdsc = {
572 .gdscr = 0x3000,
573 .pd = {
574 .name = "mdss_gdsc",
575 },
576 .pwrsts = PWRSTS_OFF_ON,
577 .flags = HW_CTRL | POLL_CFG_GDSCR,
578 };
579
580 static struct clk_regmap *disp_cc_sdm845_clocks[] = {
581 [DISP_CC_MDSS_AHB_CLK] = &disp_cc_mdss_ahb_clk.clkr,
582 [DISP_CC_MDSS_AXI_CLK] = &disp_cc_mdss_axi_clk.clkr,
583 [DISP_CC_MDSS_BYTE0_CLK] = &disp_cc_mdss_byte0_clk.clkr,
584 [DISP_CC_MDSS_BYTE0_CLK_SRC] = &disp_cc_mdss_byte0_clk_src.clkr,
585 [DISP_CC_MDSS_BYTE0_INTF_CLK] = &disp_cc_mdss_byte0_intf_clk.clkr,
586 [DISP_CC_MDSS_BYTE0_DIV_CLK_SRC] =
587 &disp_cc_mdss_byte0_div_clk_src.clkr,
588 [DISP_CC_MDSS_BYTE1_CLK] = &disp_cc_mdss_byte1_clk.clkr,
589 [DISP_CC_MDSS_BYTE1_CLK_SRC] = &disp_cc_mdss_byte1_clk_src.clkr,
590 [DISP_CC_MDSS_BYTE1_INTF_CLK] = &disp_cc_mdss_byte1_intf_clk.clkr,
591 [DISP_CC_MDSS_BYTE1_DIV_CLK_SRC] =
592 &disp_cc_mdss_byte1_div_clk_src.clkr,
593 [DISP_CC_MDSS_ESC0_CLK] = &disp_cc_mdss_esc0_clk.clkr,
594 [DISP_CC_MDSS_ESC0_CLK_SRC] = &disp_cc_mdss_esc0_clk_src.clkr,
595 [DISP_CC_MDSS_ESC1_CLK] = &disp_cc_mdss_esc1_clk.clkr,
596 [DISP_CC_MDSS_ESC1_CLK_SRC] = &disp_cc_mdss_esc1_clk_src.clkr,
597 [DISP_CC_MDSS_MDP_CLK] = &disp_cc_mdss_mdp_clk.clkr,
598 [DISP_CC_MDSS_MDP_CLK_SRC] = &disp_cc_mdss_mdp_clk_src.clkr,
599 [DISP_CC_MDSS_MDP_LUT_CLK] = &disp_cc_mdss_mdp_lut_clk.clkr,
600 [DISP_CC_MDSS_PCLK0_CLK] = &disp_cc_mdss_pclk0_clk.clkr,
601 [DISP_CC_MDSS_PCLK0_CLK_SRC] = &disp_cc_mdss_pclk0_clk_src.clkr,
602 [DISP_CC_MDSS_PCLK1_CLK] = &disp_cc_mdss_pclk1_clk.clkr,
603 [DISP_CC_MDSS_PCLK1_CLK_SRC] = &disp_cc_mdss_pclk1_clk_src.clkr,
604 [DISP_CC_MDSS_ROT_CLK] = &disp_cc_mdss_rot_clk.clkr,
605 [DISP_CC_MDSS_ROT_CLK_SRC] = &disp_cc_mdss_rot_clk_src.clkr,
606 [DISP_CC_MDSS_RSCC_AHB_CLK] = &disp_cc_mdss_rscc_ahb_clk.clkr,
607 [DISP_CC_MDSS_RSCC_VSYNC_CLK] = &disp_cc_mdss_rscc_vsync_clk.clkr,
608 [DISP_CC_MDSS_VSYNC_CLK] = &disp_cc_mdss_vsync_clk.clkr,
609 [DISP_CC_MDSS_VSYNC_CLK_SRC] = &disp_cc_mdss_vsync_clk_src.clkr,
610 [DISP_CC_PLL0] = &disp_cc_pll0.clkr,
611 };
612
613 static const struct qcom_reset_map disp_cc_sdm845_resets[] = {
614 [DISP_CC_MDSS_RSCC_BCR] = { 0x5000 },
615 };
616
617 static struct gdsc *disp_cc_sdm845_gdscs[] = {
618 [MDSS_GDSC] = &mdss_gdsc,
619 };
620
621 static const struct regmap_config disp_cc_sdm845_regmap_config = {
622 .reg_bits = 32,
623 .reg_stride = 4,
624 .val_bits = 32,
625 .max_register = 0x10000,
626 .fast_io = true,
627 };
628
629 static const struct qcom_cc_desc disp_cc_sdm845_desc = {
630 .config = &disp_cc_sdm845_regmap_config,
631 .clks = disp_cc_sdm845_clocks,
632 .num_clks = ARRAY_SIZE(disp_cc_sdm845_clocks),
633 .resets = disp_cc_sdm845_resets,
634 .num_resets = ARRAY_SIZE(disp_cc_sdm845_resets),
635 .gdscs = disp_cc_sdm845_gdscs,
636 .num_gdscs = ARRAY_SIZE(disp_cc_sdm845_gdscs),
637 };
638
639 static const struct of_device_id disp_cc_sdm845_match_table[] = {
640 { .compatible = "qcom,sdm845-dispcc" },
641 { }
642 };
643 MODULE_DEVICE_TABLE(of, disp_cc_sdm845_match_table);
644
disp_cc_sdm845_probe(struct platform_device * pdev)645 static int disp_cc_sdm845_probe(struct platform_device *pdev)
646 {
647 struct regmap *regmap;
648 struct alpha_pll_config disp_cc_pll0_config = {};
649
650 regmap = qcom_cc_map(pdev, &disp_cc_sdm845_desc);
651 if (IS_ERR(regmap))
652 return PTR_ERR(regmap);
653
654 disp_cc_pll0_config.l = 0x2c;
655 disp_cc_pll0_config.alpha = 0xcaaa;
656
657 clk_fabia_pll_configure(&disp_cc_pll0, regmap, &disp_cc_pll0_config);
658
659 /* Enable hardware clock gating for DSI and MDP clocks */
660 regmap_update_bits(regmap, 0x8000, 0x7f0, 0x7f0);
661
662 return qcom_cc_really_probe(pdev, &disp_cc_sdm845_desc, regmap);
663 }
664
665 static struct platform_driver disp_cc_sdm845_driver = {
666 .probe = disp_cc_sdm845_probe,
667 .driver = {
668 .name = "disp_cc-sdm845",
669 .of_match_table = disp_cc_sdm845_match_table,
670 .sync_state = clk_sync_state,
671 },
672 };
673
disp_cc_sdm845_init(void)674 static int __init disp_cc_sdm845_init(void)
675 {
676 return platform_driver_register(&disp_cc_sdm845_driver);
677 }
678 subsys_initcall(disp_cc_sdm845_init);
679
disp_cc_sdm845_exit(void)680 static void __exit disp_cc_sdm845_exit(void)
681 {
682 platform_driver_unregister(&disp_cc_sdm845_driver);
683 }
684 module_exit(disp_cc_sdm845_exit);
685
686 MODULE_LICENSE("GPL v2");
687 MODULE_DESCRIPTION("QTI DISPCC SDM845 Driver");
688