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