1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * Copyright (c) 2019, 2022, 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-sc7180.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
20 enum {
21 P_BI_TCXO,
22 P_DISP_CC_PLL0_OUT_EVEN,
23 P_DISP_CC_PLL0_OUT_MAIN,
24 P_DP_PHY_PLL_LINK_CLK,
25 P_DP_PHY_PLL_VCO_DIV_CLK,
26 P_DSI0_PHY_PLL_OUT_BYTECLK,
27 P_DSI0_PHY_PLL_OUT_DSICLK,
28 P_GPLL0_OUT_MAIN,
29 };
30
31 static const struct pll_vco fabia_vco[] = {
32 { 249600000, 2000000000, 0 },
33 };
34
35 static struct clk_alpha_pll disp_cc_pll0 = {
36 .offset = 0x0,
37 .vco_table = fabia_vco,
38 .num_vco = ARRAY_SIZE(fabia_vco),
39 .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
40 .clkr = {
41 .hw.init = &(struct clk_init_data){
42 .name = "disp_cc_pll0",
43 .parent_data = &(const struct clk_parent_data){
44 .fw_name = "bi_tcxo",
45 },
46 .num_parents = 1,
47 .ops = &clk_alpha_pll_fabia_ops,
48 },
49 },
50 };
51
52 static const struct clk_div_table post_div_table_disp_cc_pll0_out_even[] = {
53 { 0x0, 1 },
54 { }
55 };
56
57 static struct clk_alpha_pll_postdiv disp_cc_pll0_out_even = {
58 .offset = 0x0,
59 .post_div_shift = 8,
60 .post_div_table = post_div_table_disp_cc_pll0_out_even,
61 .num_post_div = ARRAY_SIZE(post_div_table_disp_cc_pll0_out_even),
62 .width = 4,
63 .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
64 .clkr.hw.init = &(struct clk_init_data){
65 .name = "disp_cc_pll0_out_even",
66 .parent_hws = (const struct clk_hw*[]){
67 &disp_cc_pll0.clkr.hw,
68 },
69 .num_parents = 1,
70 .flags = CLK_SET_RATE_PARENT,
71 .ops = &clk_alpha_pll_postdiv_fabia_ops,
72 },
73 };
74
75 static const struct parent_map disp_cc_parent_map_0[] = {
76 { P_BI_TCXO, 0 },
77 };
78
79 static const struct clk_parent_data disp_cc_parent_data_0[] = {
80 { .fw_name = "bi_tcxo" },
81 };
82
83 static const struct parent_map disp_cc_parent_map_1[] = {
84 { P_BI_TCXO, 0 },
85 { P_DP_PHY_PLL_LINK_CLK, 1 },
86 { P_DP_PHY_PLL_VCO_DIV_CLK, 2 },
87 };
88
89 static const struct clk_parent_data disp_cc_parent_data_1[] = {
90 { .fw_name = "bi_tcxo" },
91 { .fw_name = "dp_phy_pll_link_clk" },
92 { .fw_name = "dp_phy_pll_vco_div_clk" },
93 };
94
95 static const struct parent_map disp_cc_parent_map_2[] = {
96 { P_BI_TCXO, 0 },
97 { P_DSI0_PHY_PLL_OUT_BYTECLK, 1 },
98 };
99
100 static const struct clk_parent_data disp_cc_parent_data_2[] = {
101 { .fw_name = "bi_tcxo" },
102 { .fw_name = "dsi0_phy_pll_out_byteclk" },
103 };
104
105 static const struct parent_map disp_cc_parent_map_3[] = {
106 { P_BI_TCXO, 0 },
107 { P_DISP_CC_PLL0_OUT_MAIN, 1 },
108 { P_GPLL0_OUT_MAIN, 4 },
109 { P_DISP_CC_PLL0_OUT_EVEN, 5 },
110 };
111
112 static const struct clk_parent_data disp_cc_parent_data_3[] = {
113 { .fw_name = "bi_tcxo" },
114 { .hw = &disp_cc_pll0.clkr.hw },
115 { .fw_name = "gcc_disp_gpll0_clk_src" },
116 { .hw = &disp_cc_pll0_out_even.clkr.hw },
117 };
118
119 static const struct parent_map disp_cc_parent_map_4[] = {
120 { P_BI_TCXO, 0 },
121 { P_GPLL0_OUT_MAIN, 4 },
122 };
123
124 static const struct clk_parent_data disp_cc_parent_data_4[] = {
125 { .fw_name = "bi_tcxo" },
126 { .fw_name = "gcc_disp_gpll0_clk_src" },
127 };
128
129 static const struct parent_map disp_cc_parent_map_5[] = {
130 { P_BI_TCXO, 0 },
131 { P_DSI0_PHY_PLL_OUT_DSICLK, 1 },
132 };
133
134 static const struct clk_parent_data disp_cc_parent_data_5[] = {
135 { .fw_name = "bi_tcxo" },
136 { .fw_name = "dsi0_phy_pll_out_dsiclk" },
137 };
138
139 static const struct freq_tbl ftbl_disp_cc_mdss_ahb_clk_src[] = {
140 F(19200000, P_BI_TCXO, 1, 0, 0),
141 F(37500000, P_GPLL0_OUT_MAIN, 16, 0, 0),
142 F(75000000, P_GPLL0_OUT_MAIN, 8, 0, 0),
143 { }
144 };
145
146 static struct clk_rcg2 disp_cc_mdss_ahb_clk_src = {
147 .cmd_rcgr = 0x22bc,
148 .mnd_width = 0,
149 .hid_width = 5,
150 .parent_map = disp_cc_parent_map_4,
151 .freq_tbl = ftbl_disp_cc_mdss_ahb_clk_src,
152 .clkr.hw.init = &(struct clk_init_data){
153 .name = "disp_cc_mdss_ahb_clk_src",
154 .parent_data = disp_cc_parent_data_4,
155 .num_parents = ARRAY_SIZE(disp_cc_parent_data_4),
156 .flags = CLK_SET_RATE_PARENT,
157 .ops = &clk_rcg2_shared_ops,
158 },
159 };
160
161 static struct clk_rcg2 disp_cc_mdss_byte0_clk_src = {
162 .cmd_rcgr = 0x2110,
163 .mnd_width = 0,
164 .hid_width = 5,
165 .parent_map = disp_cc_parent_map_2,
166 .clkr.hw.init = &(struct clk_init_data){
167 .name = "disp_cc_mdss_byte0_clk_src",
168 .parent_data = disp_cc_parent_data_2,
169 .num_parents = ARRAY_SIZE(disp_cc_parent_data_2),
170 .flags = CLK_SET_RATE_PARENT,
171 .ops = &clk_byte2_ops,
172 },
173 };
174
175 static const struct freq_tbl ftbl_disp_cc_mdss_dp_aux_clk_src[] = {
176 F(19200000, P_BI_TCXO, 1, 0, 0),
177 { }
178 };
179
180 static struct clk_rcg2 disp_cc_mdss_dp_aux_clk_src = {
181 .cmd_rcgr = 0x21dc,
182 .mnd_width = 0,
183 .hid_width = 5,
184 .parent_map = disp_cc_parent_map_0,
185 .freq_tbl = ftbl_disp_cc_mdss_dp_aux_clk_src,
186 .clkr.hw.init = &(struct clk_init_data){
187 .name = "disp_cc_mdss_dp_aux_clk_src",
188 .parent_data = disp_cc_parent_data_0,
189 .num_parents = ARRAY_SIZE(disp_cc_parent_data_0),
190 .ops = &clk_rcg2_ops,
191 },
192 };
193
194 static struct clk_rcg2 disp_cc_mdss_dp_crypto_clk_src = {
195 .cmd_rcgr = 0x2194,
196 .mnd_width = 0,
197 .hid_width = 5,
198 .parent_map = disp_cc_parent_map_1,
199 .clkr.hw.init = &(struct clk_init_data){
200 .name = "disp_cc_mdss_dp_crypto_clk_src",
201 .parent_data = disp_cc_parent_data_1,
202 .num_parents = ARRAY_SIZE(disp_cc_parent_data_1),
203 .ops = &clk_byte2_ops,
204 },
205 };
206
207 static struct clk_rcg2 disp_cc_mdss_dp_link_clk_src = {
208 .cmd_rcgr = 0x2178,
209 .mnd_width = 0,
210 .hid_width = 5,
211 .parent_map = disp_cc_parent_map_1,
212 .clkr.hw.init = &(struct clk_init_data){
213 .name = "disp_cc_mdss_dp_link_clk_src",
214 .parent_data = disp_cc_parent_data_1,
215 .num_parents = ARRAY_SIZE(disp_cc_parent_data_1),
216 .ops = &clk_byte2_ops,
217 },
218 };
219
220 static struct clk_rcg2 disp_cc_mdss_dp_pixel_clk_src = {
221 .cmd_rcgr = 0x21ac,
222 .mnd_width = 16,
223 .hid_width = 5,
224 .parent_map = disp_cc_parent_map_1,
225 .clkr.hw.init = &(struct clk_init_data){
226 .name = "disp_cc_mdss_dp_pixel_clk_src",
227 .parent_data = disp_cc_parent_data_1,
228 .num_parents = ARRAY_SIZE(disp_cc_parent_data_1),
229 .ops = &clk_dp_ops,
230 },
231 };
232
233 static struct clk_rcg2 disp_cc_mdss_esc0_clk_src = {
234 .cmd_rcgr = 0x2148,
235 .mnd_width = 0,
236 .hid_width = 5,
237 .parent_map = disp_cc_parent_map_2,
238 .freq_tbl = ftbl_disp_cc_mdss_dp_aux_clk_src,
239 .clkr.hw.init = &(struct clk_init_data){
240 .name = "disp_cc_mdss_esc0_clk_src",
241 .parent_data = disp_cc_parent_data_2,
242 .num_parents = ARRAY_SIZE(disp_cc_parent_data_2),
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(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0),
250 F(300000000, P_GPLL0_OUT_MAIN, 2, 0, 0),
251 F(345000000, P_DISP_CC_PLL0_OUT_MAIN, 4, 0, 0),
252 F(460000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0),
253 { }
254 };
255
256 static struct clk_rcg2 disp_cc_mdss_mdp_clk_src = {
257 .cmd_rcgr = 0x20c8,
258 .mnd_width = 0,
259 .hid_width = 5,
260 .parent_map = disp_cc_parent_map_3,
261 .freq_tbl = ftbl_disp_cc_mdss_mdp_clk_src,
262 .clkr.hw.init = &(struct clk_init_data){
263 .name = "disp_cc_mdss_mdp_clk_src",
264 .parent_data = disp_cc_parent_data_3,
265 .num_parents = ARRAY_SIZE(disp_cc_parent_data_3),
266 .ops = &clk_rcg2_shared_ops,
267 },
268 };
269
270 static struct clk_rcg2 disp_cc_mdss_pclk0_clk_src = {
271 .cmd_rcgr = 0x2098,
272 .mnd_width = 8,
273 .hid_width = 5,
274 .parent_map = disp_cc_parent_map_5,
275 .clkr.hw.init = &(struct clk_init_data){
276 .name = "disp_cc_mdss_pclk0_clk_src",
277 .parent_data = disp_cc_parent_data_5,
278 .num_parents = ARRAY_SIZE(disp_cc_parent_data_5),
279 .flags = CLK_SET_RATE_PARENT,
280 .ops = &clk_pixel_ops,
281 },
282 };
283
284 static struct clk_rcg2 disp_cc_mdss_rot_clk_src = {
285 .cmd_rcgr = 0x20e0,
286 .mnd_width = 0,
287 .hid_width = 5,
288 .parent_map = disp_cc_parent_map_3,
289 .freq_tbl = ftbl_disp_cc_mdss_mdp_clk_src,
290 .clkr.hw.init = &(struct clk_init_data){
291 .name = "disp_cc_mdss_rot_clk_src",
292 .parent_data = disp_cc_parent_data_3,
293 .num_parents = ARRAY_SIZE(disp_cc_parent_data_3),
294 .ops = &clk_rcg2_shared_ops,
295 },
296 };
297
298 static struct clk_rcg2 disp_cc_mdss_vsync_clk_src = {
299 .cmd_rcgr = 0x20f8,
300 .mnd_width = 0,
301 .hid_width = 5,
302 .parent_map = disp_cc_parent_map_0,
303 .freq_tbl = ftbl_disp_cc_mdss_dp_aux_clk_src,
304 .clkr.hw.init = &(struct clk_init_data){
305 .name = "disp_cc_mdss_vsync_clk_src",
306 .parent_data = disp_cc_parent_data_0,
307 .num_parents = ARRAY_SIZE(disp_cc_parent_data_0),
308 .ops = &clk_rcg2_shared_ops,
309 },
310 };
311
312 static struct clk_branch disp_cc_mdss_ahb_clk = {
313 .halt_reg = 0x2080,
314 .halt_check = BRANCH_HALT,
315 .clkr = {
316 .enable_reg = 0x2080,
317 .enable_mask = BIT(0),
318 .hw.init = &(struct clk_init_data){
319 .name = "disp_cc_mdss_ahb_clk",
320 .parent_hws = (const struct clk_hw*[]){
321 &disp_cc_mdss_ahb_clk_src.clkr.hw,
322 },
323 .num_parents = 1,
324 .flags = CLK_SET_RATE_PARENT,
325 .ops = &clk_branch2_ops,
326 },
327 },
328 };
329
330 static struct clk_branch disp_cc_mdss_byte0_clk = {
331 .halt_reg = 0x2028,
332 .halt_check = BRANCH_HALT,
333 .clkr = {
334 .enable_reg = 0x2028,
335 .enable_mask = BIT(0),
336 .hw.init = &(struct clk_init_data){
337 .name = "disp_cc_mdss_byte0_clk",
338 .parent_hws = (const struct clk_hw*[]){
339 &disp_cc_mdss_byte0_clk_src.clkr.hw,
340 },
341 .num_parents = 1,
342 .flags = CLK_SET_RATE_PARENT,
343 .ops = &clk_branch2_ops,
344 },
345 },
346 };
347
348 static struct clk_regmap_div disp_cc_mdss_byte0_div_clk_src = {
349 .reg = 0x2128,
350 .shift = 0,
351 .width = 2,
352 .clkr.hw.init = &(struct clk_init_data) {
353 .name = "disp_cc_mdss_byte0_div_clk_src",
354 .parent_hws = (const struct clk_hw*[]) {
355 &disp_cc_mdss_byte0_clk_src.clkr.hw,
356 },
357 .num_parents = 1,
358 .ops = &clk_regmap_div_ops,
359 },
360 };
361
362 static struct clk_regmap_div disp_cc_mdss_dp_link_div_clk_src = {
363 .reg = 0x2190,
364 .shift = 0,
365 .width = 2,
366 .clkr.hw.init = &(struct clk_init_data) {
367 .name = "disp_cc_mdss_dp_link_div_clk_src",
368 .parent_hws = (const struct clk_hw*[]) {
369 &disp_cc_mdss_dp_link_clk_src.clkr.hw,
370 },
371 .num_parents = 1,
372 .ops = &clk_regmap_div_ops,
373 },
374 };
375
376 static struct clk_branch disp_cc_mdss_byte0_intf_clk = {
377 .halt_reg = 0x202c,
378 .halt_check = BRANCH_HALT,
379 .clkr = {
380 .enable_reg = 0x202c,
381 .enable_mask = BIT(0),
382 .hw.init = &(struct clk_init_data){
383 .name = "disp_cc_mdss_byte0_intf_clk",
384 .parent_hws = (const struct clk_hw*[]){
385 &disp_cc_mdss_byte0_div_clk_src.clkr.hw,
386 },
387 .num_parents = 1,
388 .flags = CLK_SET_RATE_PARENT,
389 .ops = &clk_branch2_ops,
390 },
391 },
392 };
393
394 static struct clk_branch disp_cc_mdss_dp_aux_clk = {
395 .halt_reg = 0x2054,
396 .halt_check = BRANCH_HALT,
397 .clkr = {
398 .enable_reg = 0x2054,
399 .enable_mask = BIT(0),
400 .hw.init = &(struct clk_init_data){
401 .name = "disp_cc_mdss_dp_aux_clk",
402 .parent_hws = (const struct clk_hw*[]){
403 &disp_cc_mdss_dp_aux_clk_src.clkr.hw,
404 },
405 .num_parents = 1,
406 .flags = CLK_SET_RATE_PARENT,
407 .ops = &clk_branch2_ops,
408 },
409 },
410 };
411
412 static struct clk_branch disp_cc_mdss_dp_crypto_clk = {
413 .halt_reg = 0x2048,
414 .halt_check = BRANCH_HALT,
415 .clkr = {
416 .enable_reg = 0x2048,
417 .enable_mask = BIT(0),
418 .hw.init = &(struct clk_init_data){
419 .name = "disp_cc_mdss_dp_crypto_clk",
420 .parent_hws = (const struct clk_hw*[]){
421 &disp_cc_mdss_dp_crypto_clk_src.clkr.hw,
422 },
423 .num_parents = 1,
424 .flags = CLK_SET_RATE_PARENT,
425 .ops = &clk_branch2_ops,
426 },
427 },
428 };
429
430 static struct clk_branch disp_cc_mdss_dp_link_clk = {
431 .halt_reg = 0x2040,
432 .halt_check = BRANCH_HALT,
433 .clkr = {
434 .enable_reg = 0x2040,
435 .enable_mask = BIT(0),
436 .hw.init = &(struct clk_init_data){
437 .name = "disp_cc_mdss_dp_link_clk",
438 .parent_hws = (const struct clk_hw*[]){
439 &disp_cc_mdss_dp_link_clk_src.clkr.hw,
440 },
441 .num_parents = 1,
442 .flags = CLK_SET_RATE_PARENT,
443 .ops = &clk_branch2_ops,
444 },
445 },
446 };
447
448 static struct clk_branch disp_cc_mdss_dp_link_intf_clk = {
449 .halt_reg = 0x2044,
450 .halt_check = BRANCH_HALT,
451 .clkr = {
452 .enable_reg = 0x2044,
453 .enable_mask = BIT(0),
454 .hw.init = &(struct clk_init_data){
455 .name = "disp_cc_mdss_dp_link_intf_clk",
456 .parent_hws = (const struct clk_hw*[]){
457 &disp_cc_mdss_dp_link_div_clk_src.clkr.hw,
458 },
459 .num_parents = 1,
460 .ops = &clk_branch2_ops,
461 },
462 },
463 };
464
465 static struct clk_branch disp_cc_mdss_dp_pixel_clk = {
466 .halt_reg = 0x204c,
467 .halt_check = BRANCH_HALT,
468 .clkr = {
469 .enable_reg = 0x204c,
470 .enable_mask = BIT(0),
471 .hw.init = &(struct clk_init_data){
472 .name = "disp_cc_mdss_dp_pixel_clk",
473 .parent_hws = (const struct clk_hw*[]){
474 &disp_cc_mdss_dp_pixel_clk_src.clkr.hw,
475 },
476 .num_parents = 1,
477 .flags = CLK_SET_RATE_PARENT,
478 .ops = &clk_branch2_ops,
479 },
480 },
481 };
482
483 static struct clk_branch disp_cc_mdss_esc0_clk = {
484 .halt_reg = 0x2038,
485 .halt_check = BRANCH_HALT,
486 .clkr = {
487 .enable_reg = 0x2038,
488 .enable_mask = BIT(0),
489 .hw.init = &(struct clk_init_data){
490 .name = "disp_cc_mdss_esc0_clk",
491 .parent_hws = (const struct clk_hw*[]){
492 &disp_cc_mdss_esc0_clk_src.clkr.hw,
493 },
494 .num_parents = 1,
495 .flags = CLK_SET_RATE_PARENT,
496 .ops = &clk_branch2_ops,
497 },
498 },
499 };
500
501 static struct clk_branch disp_cc_mdss_mdp_clk = {
502 .halt_reg = 0x200c,
503 .halt_check = BRANCH_HALT,
504 .clkr = {
505 .enable_reg = 0x200c,
506 .enable_mask = BIT(0),
507 .hw.init = &(struct clk_init_data){
508 .name = "disp_cc_mdss_mdp_clk",
509 .parent_hws = (const struct clk_hw*[]){
510 &disp_cc_mdss_mdp_clk_src.clkr.hw,
511 },
512 .num_parents = 1,
513 .flags = CLK_SET_RATE_PARENT,
514 .ops = &clk_branch2_ops,
515 },
516 },
517 };
518
519 static struct clk_branch disp_cc_mdss_mdp_lut_clk = {
520 .halt_reg = 0x201c,
521 .halt_check = BRANCH_VOTED,
522 .clkr = {
523 .enable_reg = 0x201c,
524 .enable_mask = BIT(0),
525 .hw.init = &(struct clk_init_data){
526 .name = "disp_cc_mdss_mdp_lut_clk",
527 .parent_hws = (const struct clk_hw*[]){
528 &disp_cc_mdss_mdp_clk_src.clkr.hw,
529 },
530 .num_parents = 1,
531 .ops = &clk_branch2_ops,
532 },
533 },
534 };
535
536 static struct clk_branch disp_cc_mdss_non_gdsc_ahb_clk = {
537 .halt_reg = 0x4004,
538 .halt_check = BRANCH_VOTED,
539 .clkr = {
540 .enable_reg = 0x4004,
541 .enable_mask = BIT(0),
542 .hw.init = &(struct clk_init_data){
543 .name = "disp_cc_mdss_non_gdsc_ahb_clk",
544 .parent_hws = (const struct clk_hw*[]){
545 &disp_cc_mdss_ahb_clk_src.clkr.hw,
546 },
547 .num_parents = 1,
548 .flags = CLK_SET_RATE_PARENT,
549 .ops = &clk_branch2_ops,
550 },
551 },
552 };
553
554 static struct clk_branch disp_cc_mdss_pclk0_clk = {
555 .halt_reg = 0x2004,
556 .halt_check = BRANCH_HALT,
557 .clkr = {
558 .enable_reg = 0x2004,
559 .enable_mask = BIT(0),
560 .hw.init = &(struct clk_init_data){
561 .name = "disp_cc_mdss_pclk0_clk",
562 .parent_hws = (const struct clk_hw*[]){
563 &disp_cc_mdss_pclk0_clk_src.clkr.hw,
564 },
565 .num_parents = 1,
566 .flags = CLK_SET_RATE_PARENT,
567 .ops = &clk_branch2_ops,
568 },
569 },
570 };
571
572 static struct clk_branch disp_cc_mdss_rot_clk = {
573 .halt_reg = 0x2014,
574 .halt_check = BRANCH_HALT,
575 .clkr = {
576 .enable_reg = 0x2014,
577 .enable_mask = BIT(0),
578 .hw.init = &(struct clk_init_data){
579 .name = "disp_cc_mdss_rot_clk",
580 .parent_hws = (const struct clk_hw*[]){
581 &disp_cc_mdss_rot_clk_src.clkr.hw,
582 },
583 .num_parents = 1,
584 .flags = CLK_SET_RATE_PARENT,
585 .ops = &clk_branch2_ops,
586 },
587 },
588 };
589
590 static struct clk_branch disp_cc_mdss_rscc_vsync_clk = {
591 .halt_reg = 0x4008,
592 .halt_check = BRANCH_HALT,
593 .clkr = {
594 .enable_reg = 0x4008,
595 .enable_mask = BIT(0),
596 .hw.init = &(struct clk_init_data){
597 .name = "disp_cc_mdss_rscc_vsync_clk",
598 .parent_hws = (const struct clk_hw*[]){
599 &disp_cc_mdss_vsync_clk_src.clkr.hw,
600 },
601 .num_parents = 1,
602 .flags = CLK_SET_RATE_PARENT,
603 .ops = &clk_branch2_ops,
604 },
605 },
606 };
607
608 static struct clk_branch disp_cc_mdss_vsync_clk = {
609 .halt_reg = 0x2024,
610 .halt_check = BRANCH_HALT,
611 .clkr = {
612 .enable_reg = 0x2024,
613 .enable_mask = BIT(0),
614 .hw.init = &(struct clk_init_data){
615 .name = "disp_cc_mdss_vsync_clk",
616 .parent_hws = (const struct clk_hw*[]){
617 &disp_cc_mdss_vsync_clk_src.clkr.hw,
618 },
619 .num_parents = 1,
620 .flags = CLK_SET_RATE_PARENT,
621 .ops = &clk_branch2_ops,
622 },
623 },
624 };
625
626 static struct gdsc mdss_gdsc = {
627 .gdscr = 0x3000,
628 .en_rest_wait_val = 0x2,
629 .en_few_wait_val = 0x2,
630 .clk_dis_wait_val = 0xf,
631 .pd = {
632 .name = "mdss_gdsc",
633 },
634 .pwrsts = PWRSTS_OFF_ON,
635 .flags = HW_CTRL,
636 };
637
638 static struct gdsc *disp_cc_sc7180_gdscs[] = {
639 [MDSS_GDSC] = &mdss_gdsc,
640 };
641
642 static struct clk_regmap *disp_cc_sc7180_clocks[] = {
643 [DISP_CC_MDSS_AHB_CLK] = &disp_cc_mdss_ahb_clk.clkr,
644 [DISP_CC_MDSS_AHB_CLK_SRC] = &disp_cc_mdss_ahb_clk_src.clkr,
645 [DISP_CC_MDSS_BYTE0_CLK] = &disp_cc_mdss_byte0_clk.clkr,
646 [DISP_CC_MDSS_BYTE0_CLK_SRC] = &disp_cc_mdss_byte0_clk_src.clkr,
647 [DISP_CC_MDSS_BYTE0_DIV_CLK_SRC] = &disp_cc_mdss_byte0_div_clk_src.clkr,
648 [DISP_CC_MDSS_BYTE0_INTF_CLK] = &disp_cc_mdss_byte0_intf_clk.clkr,
649 [DISP_CC_MDSS_DP_AUX_CLK] = &disp_cc_mdss_dp_aux_clk.clkr,
650 [DISP_CC_MDSS_DP_AUX_CLK_SRC] = &disp_cc_mdss_dp_aux_clk_src.clkr,
651 [DISP_CC_MDSS_DP_CRYPTO_CLK] = &disp_cc_mdss_dp_crypto_clk.clkr,
652 [DISP_CC_MDSS_DP_CRYPTO_CLK_SRC] = &disp_cc_mdss_dp_crypto_clk_src.clkr,
653 [DISP_CC_MDSS_DP_LINK_CLK] = &disp_cc_mdss_dp_link_clk.clkr,
654 [DISP_CC_MDSS_DP_LINK_CLK_SRC] = &disp_cc_mdss_dp_link_clk_src.clkr,
655 [DISP_CC_MDSS_DP_LINK_DIV_CLK_SRC] =
656 &disp_cc_mdss_dp_link_div_clk_src.clkr,
657 [DISP_CC_MDSS_DP_LINK_INTF_CLK] = &disp_cc_mdss_dp_link_intf_clk.clkr,
658 [DISP_CC_MDSS_DP_PIXEL_CLK] = &disp_cc_mdss_dp_pixel_clk.clkr,
659 [DISP_CC_MDSS_DP_PIXEL_CLK_SRC] = &disp_cc_mdss_dp_pixel_clk_src.clkr,
660 [DISP_CC_MDSS_ESC0_CLK] = &disp_cc_mdss_esc0_clk.clkr,
661 [DISP_CC_MDSS_ESC0_CLK_SRC] = &disp_cc_mdss_esc0_clk_src.clkr,
662 [DISP_CC_MDSS_MDP_CLK] = &disp_cc_mdss_mdp_clk.clkr,
663 [DISP_CC_MDSS_MDP_CLK_SRC] = &disp_cc_mdss_mdp_clk_src.clkr,
664 [DISP_CC_MDSS_MDP_LUT_CLK] = &disp_cc_mdss_mdp_lut_clk.clkr,
665 [DISP_CC_MDSS_NON_GDSC_AHB_CLK] = &disp_cc_mdss_non_gdsc_ahb_clk.clkr,
666 [DISP_CC_MDSS_PCLK0_CLK] = &disp_cc_mdss_pclk0_clk.clkr,
667 [DISP_CC_MDSS_PCLK0_CLK_SRC] = &disp_cc_mdss_pclk0_clk_src.clkr,
668 [DISP_CC_MDSS_ROT_CLK] = &disp_cc_mdss_rot_clk.clkr,
669 [DISP_CC_MDSS_ROT_CLK_SRC] = &disp_cc_mdss_rot_clk_src.clkr,
670 [DISP_CC_MDSS_RSCC_VSYNC_CLK] = &disp_cc_mdss_rscc_vsync_clk.clkr,
671 [DISP_CC_MDSS_VSYNC_CLK] = &disp_cc_mdss_vsync_clk.clkr,
672 [DISP_CC_MDSS_VSYNC_CLK_SRC] = &disp_cc_mdss_vsync_clk_src.clkr,
673 [DISP_CC_PLL0] = &disp_cc_pll0.clkr,
674 [DISP_CC_PLL0_OUT_EVEN] = &disp_cc_pll0_out_even.clkr,
675 };
676
677 static const struct regmap_config disp_cc_sc7180_regmap_config = {
678 .reg_bits = 32,
679 .reg_stride = 4,
680 .val_bits = 32,
681 .max_register = 0x10000,
682 .fast_io = true,
683 };
684
685 static const struct qcom_cc_desc disp_cc_sc7180_desc = {
686 .config = &disp_cc_sc7180_regmap_config,
687 .clks = disp_cc_sc7180_clocks,
688 .num_clks = ARRAY_SIZE(disp_cc_sc7180_clocks),
689 .gdscs = disp_cc_sc7180_gdscs,
690 .num_gdscs = ARRAY_SIZE(disp_cc_sc7180_gdscs),
691 };
692
693 static const struct of_device_id disp_cc_sc7180_match_table[] = {
694 { .compatible = "qcom,sc7180-dispcc" },
695 { }
696 };
697 MODULE_DEVICE_TABLE(of, disp_cc_sc7180_match_table);
698
disp_cc_sc7180_probe(struct platform_device * pdev)699 static int disp_cc_sc7180_probe(struct platform_device *pdev)
700 {
701 struct regmap *regmap;
702 struct alpha_pll_config disp_cc_pll_config = {};
703
704 regmap = qcom_cc_map(pdev, &disp_cc_sc7180_desc);
705 if (IS_ERR(regmap))
706 return PTR_ERR(regmap);
707
708 /* 1380MHz configuration */
709 disp_cc_pll_config.l = 0x47;
710 disp_cc_pll_config.alpha = 0xe000;
711 disp_cc_pll_config.user_ctl_val = 0x00000001;
712 disp_cc_pll_config.user_ctl_hi_val = 0x00004805;
713
714 clk_fabia_pll_configure(&disp_cc_pll0, regmap, &disp_cc_pll_config);
715
716 return qcom_cc_really_probe(pdev, &disp_cc_sc7180_desc, regmap);
717 }
718
719 static struct platform_driver disp_cc_sc7180_driver = {
720 .probe = disp_cc_sc7180_probe,
721 .driver = {
722 .name = "sc7180-dispcc",
723 .of_match_table = disp_cc_sc7180_match_table,
724 },
725 };
726
disp_cc_sc7180_init(void)727 static int __init disp_cc_sc7180_init(void)
728 {
729 return platform_driver_register(&disp_cc_sc7180_driver);
730 }
731 subsys_initcall(disp_cc_sc7180_init);
732
disp_cc_sc7180_exit(void)733 static void __exit disp_cc_sc7180_exit(void)
734 {
735 platform_driver_unregister(&disp_cc_sc7180_driver);
736 }
737 module_exit(disp_cc_sc7180_exit);
738
739 MODULE_DESCRIPTION("QTI DISP_CC SC7180 Driver");
740 MODULE_LICENSE("GPL v2");
741