1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved.
4 */
5
6 #include <linux/clk-provider.h>
7 #include <linux/module.h>
8 #include <linux/mod_devicetable.h>
9 #include <linux/of.h>
10 #include <linux/platform_device.h>
11 #include <linux/regmap.h>
12
13 #include <dt-bindings/clock/qcom,qcs615-dispcc.h>
14
15 #include "clk-alpha-pll.h"
16 #include "clk-branch.h"
17 #include "clk-pll.h"
18 #include "clk-rcg.h"
19 #include "clk-regmap.h"
20 #include "clk-regmap-divider.h"
21 #include "clk-regmap-mux.h"
22 #include "common.h"
23 #include "gdsc.h"
24 #include "reset.h"
25
26 enum {
27 DT_BI_TCXO,
28 DT_GPLL0,
29 DT_DSI0_PHY_PLL_OUT_BYTECLK,
30 DT_DSI0_PHY_PLL_OUT_DSICLK,
31 DT_DSI1_PHY_PLL_OUT_DSICLK,
32 DT_DP_PHY_PLL_LINK_CLK,
33 DT_DP_PHY_PLL_VCO_DIV_CLK,
34 };
35
36 enum {
37 P_BI_TCXO,
38 P_DISP_CC_PLL0_OUT_MAIN,
39 P_DP_PHY_PLL_LINK_CLK,
40 P_DP_PHY_PLL_VCO_DIV_CLK,
41 P_DSI0_PHY_PLL_OUT_BYTECLK,
42 P_DSI0_PHY_PLL_OUT_DSICLK,
43 P_DSI1_PHY_PLL_OUT_DSICLK,
44 P_GPLL0_OUT_MAIN,
45 };
46
47 static const struct pll_vco disp_cc_pll_vco[] = {
48 { 500000000, 1000000000, 2 },
49 };
50
51 /* 576MHz configuration VCO - 2 */
52 static struct alpha_pll_config disp_cc_pll0_config = {
53 .l = 0x1e,
54 .vco_val = BIT(21),
55 .vco_mask = GENMASK(21, 20),
56 .main_output_mask = BIT(0),
57 .config_ctl_val = 0x4001055b,
58 .test_ctl_hi_val = 0x1,
59 .test_ctl_hi_mask = 0x1,
60 };
61
62 static struct clk_alpha_pll disp_cc_pll0 = {
63 .offset = 0x0,
64 .config = &disp_cc_pll0_config,
65 .vco_table = disp_cc_pll_vco,
66 .num_vco = ARRAY_SIZE(disp_cc_pll_vco),
67 .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
68 .clkr = {
69 .hw.init = &(const struct clk_init_data) {
70 .name = "disp_cc_pll0",
71 .parent_data = &(const struct clk_parent_data) {
72 .index = DT_BI_TCXO,
73 },
74 .num_parents = 1,
75 .ops = &clk_alpha_pll_slew_ops,
76 },
77 },
78 };
79
80 static const struct parent_map disp_cc_parent_map_0[] = {
81 { P_BI_TCXO, 0 },
82 { P_DP_PHY_PLL_LINK_CLK, 1 },
83 { P_DP_PHY_PLL_VCO_DIV_CLK, 2 },
84 };
85
86 static const struct clk_parent_data disp_cc_parent_data_0[] = {
87 { .index = DT_BI_TCXO },
88 { .index = DT_DP_PHY_PLL_LINK_CLK },
89 { .index = DT_DP_PHY_PLL_VCO_DIV_CLK },
90 };
91
92 static const struct parent_map disp_cc_parent_map_1[] = {
93 { P_BI_TCXO, 0 },
94 };
95
96 static const struct clk_parent_data disp_cc_parent_data_1[] = {
97 { .index = DT_BI_TCXO },
98 };
99
100 static const struct parent_map disp_cc_parent_map_2[] = {
101 { P_BI_TCXO, 0 },
102 { P_DSI0_PHY_PLL_OUT_BYTECLK, 1 },
103 };
104
105 static const struct clk_parent_data disp_cc_parent_data_2[] = {
106 { .index = DT_BI_TCXO },
107 { .index = DT_DSI0_PHY_PLL_OUT_BYTECLK },
108 };
109
110 static const struct parent_map disp_cc_parent_map_3[] = {
111 { P_BI_TCXO, 0 },
112 { P_DISP_CC_PLL0_OUT_MAIN, 1 },
113 { P_GPLL0_OUT_MAIN, 4 },
114 };
115
116 static const struct clk_parent_data disp_cc_parent_data_3[] = {
117 { .index = DT_BI_TCXO },
118 { .hw = &disp_cc_pll0.clkr.hw },
119 { .index = DT_GPLL0 },
120 };
121
122 static const struct parent_map disp_cc_parent_map_4[] = {
123 { P_BI_TCXO, 0 },
124 { P_GPLL0_OUT_MAIN, 4 },
125 };
126
127 static const struct clk_parent_data disp_cc_parent_data_4[] = {
128 { .index = DT_BI_TCXO },
129 { .index = DT_GPLL0 },
130 };
131
132 static const struct parent_map disp_cc_parent_map_5[] = {
133 { P_BI_TCXO, 0 },
134 { P_DSI0_PHY_PLL_OUT_DSICLK, 1 },
135 { P_DSI1_PHY_PLL_OUT_DSICLK, 2 },
136 };
137
138 static const struct clk_parent_data disp_cc_parent_data_5[] = {
139 { .index = DT_BI_TCXO },
140 { .index = DT_DSI0_PHY_PLL_OUT_DSICLK },
141 { .index = DT_DSI1_PHY_PLL_OUT_DSICLK },
142 };
143
144 static const struct freq_tbl ftbl_disp_cc_mdss_ahb_clk_src[] = {
145 F(19200000, P_BI_TCXO, 1, 0, 0),
146 F(37500000, P_GPLL0_OUT_MAIN, 8, 0, 0),
147 F(75000000, P_GPLL0_OUT_MAIN, 4, 0, 0),
148 { }
149 };
150
151 static struct clk_rcg2 disp_cc_mdss_ahb_clk_src = {
152 .cmd_rcgr = 0x2170,
153 .mnd_width = 0,
154 .hid_width = 5,
155 .parent_map = disp_cc_parent_map_4,
156 .freq_tbl = ftbl_disp_cc_mdss_ahb_clk_src,
157 .clkr.hw.init = &(const struct clk_init_data) {
158 .name = "disp_cc_mdss_ahb_clk_src",
159 .parent_data = disp_cc_parent_data_4,
160 .num_parents = ARRAY_SIZE(disp_cc_parent_data_4),
161 .ops = &clk_rcg2_shared_ops,
162 },
163 };
164
165 static struct clk_rcg2 disp_cc_mdss_byte0_clk_src = {
166 .cmd_rcgr = 0x20c0,
167 .mnd_width = 0,
168 .hid_width = 5,
169 .parent_map = disp_cc_parent_map_2,
170 .clkr.hw.init = &(const struct clk_init_data) {
171 .name = "disp_cc_mdss_byte0_clk_src",
172 .parent_data = disp_cc_parent_data_2,
173 .num_parents = ARRAY_SIZE(disp_cc_parent_data_2),
174 .flags = CLK_SET_RATE_PARENT,
175 .ops = &clk_byte2_ops,
176 },
177 };
178
179 static const struct freq_tbl ftbl_disp_cc_mdss_dp_aux1_clk_src[] = {
180 F(19200000, P_BI_TCXO, 1, 0, 0),
181 { }
182 };
183
184 static struct clk_rcg2 disp_cc_mdss_dp_aux_clk_src = {
185 .cmd_rcgr = 0x2158,
186 .mnd_width = 0,
187 .hid_width = 5,
188 .parent_map = disp_cc_parent_map_1,
189 .freq_tbl = ftbl_disp_cc_mdss_dp_aux1_clk_src,
190 .clkr.hw.init = &(struct clk_init_data){
191 .name = "disp_cc_mdss_dp_aux_clk_src",
192 .parent_data = disp_cc_parent_data_1,
193 .num_parents = ARRAY_SIZE(disp_cc_parent_data_1),
194 .ops = &clk_rcg2_shared_ops,
195 },
196 };
197
198 static struct clk_rcg2 disp_cc_mdss_dp_crypto_clk_src = {
199 .cmd_rcgr = 0x2110,
200 .mnd_width = 0,
201 .hid_width = 5,
202 .parent_map = disp_cc_parent_map_0,
203 .clkr.hw.init = &(const struct clk_init_data) {
204 .name = "disp_cc_mdss_dp_crypto_clk_src",
205 .parent_data = disp_cc_parent_data_0,
206 .num_parents = ARRAY_SIZE(disp_cc_parent_data_0),
207 .ops = &clk_byte2_ops,
208 },
209 };
210
211 static struct clk_rcg2 disp_cc_mdss_dp_link_clk_src = {
212 .cmd_rcgr = 0x20f4,
213 .mnd_width = 0,
214 .hid_width = 5,
215 .parent_map = disp_cc_parent_map_0,
216 .clkr.hw.init = &(const struct clk_init_data) {
217 .name = "disp_cc_mdss_dp_link_clk_src",
218 .parent_data = disp_cc_parent_data_0,
219 .num_parents = ARRAY_SIZE(disp_cc_parent_data_0),
220 .flags = CLK_SET_RATE_PARENT,
221 .ops = &clk_byte2_ops,
222 },
223 };
224
225 static struct clk_rcg2 disp_cc_mdss_dp_pixel1_clk_src = {
226 .cmd_rcgr = 0x2140,
227 .mnd_width = 16,
228 .hid_width = 5,
229 .parent_map = disp_cc_parent_map_0,
230 .clkr.hw.init = &(const struct clk_init_data) {
231 .name = "disp_cc_mdss_dp_pixel1_clk_src",
232 .parent_data = disp_cc_parent_data_0,
233 .num_parents = ARRAY_SIZE(disp_cc_parent_data_0),
234 .flags = CLK_SET_RATE_PARENT,
235 .ops = &clk_dp_ops,
236 },
237 };
238
239 static struct clk_rcg2 disp_cc_mdss_dp_pixel_clk_src = {
240 .cmd_rcgr = 0x2128,
241 .mnd_width = 16,
242 .hid_width = 5,
243 .parent_map = disp_cc_parent_map_0,
244 .clkr.hw.init = &(const struct clk_init_data) {
245 .name = "disp_cc_mdss_dp_pixel_clk_src",
246 .parent_data = disp_cc_parent_data_0,
247 .num_parents = ARRAY_SIZE(disp_cc_parent_data_0),
248 .flags = CLK_SET_RATE_PARENT,
249 .ops = &clk_dp_ops,
250 },
251 };
252
253 static struct clk_rcg2 disp_cc_mdss_esc0_clk_src = {
254 .cmd_rcgr = 0x20dc,
255 .mnd_width = 0,
256 .hid_width = 5,
257 .parent_map = disp_cc_parent_map_2,
258 .freq_tbl = ftbl_disp_cc_mdss_dp_aux1_clk_src,
259 .clkr.hw.init = &(struct clk_init_data){
260 .name = "disp_cc_mdss_esc0_clk_src",
261 .parent_data = disp_cc_parent_data_2,
262 .num_parents = ARRAY_SIZE(disp_cc_parent_data_2),
263 .ops = &clk_rcg2_ops,
264 },
265 };
266
267 static const struct freq_tbl ftbl_disp_cc_mdss_mdp_clk_src[] = {
268 F(19200000, P_BI_TCXO, 1, 0, 0),
269 F(192000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0),
270 F(256000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0),
271 F(307000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0),
272 { }
273 };
274
275 static struct clk_rcg2 disp_cc_mdss_mdp_clk_src = {
276 .cmd_rcgr = 0x2078,
277 .mnd_width = 0,
278 .hid_width = 5,
279 .parent_map = disp_cc_parent_map_3,
280 .freq_tbl = ftbl_disp_cc_mdss_mdp_clk_src,
281 .clkr.hw.init = &(const struct clk_init_data) {
282 .name = "disp_cc_mdss_mdp_clk_src",
283 .parent_data = disp_cc_parent_data_3,
284 .num_parents = ARRAY_SIZE(disp_cc_parent_data_3),
285 .flags = CLK_SET_RATE_PARENT,
286 .ops = &clk_rcg2_shared_ops,
287 },
288 };
289
290 static struct clk_rcg2 disp_cc_mdss_pclk0_clk_src = {
291 .cmd_rcgr = 0x2060,
292 .mnd_width = 8,
293 .hid_width = 5,
294 .parent_map = disp_cc_parent_map_5,
295 .clkr.hw.init = &(const struct clk_init_data) {
296 .name = "disp_cc_mdss_pclk0_clk_src",
297 .parent_data = disp_cc_parent_data_5,
298 .num_parents = ARRAY_SIZE(disp_cc_parent_data_5),
299 .flags = CLK_SET_RATE_PARENT,
300 .ops = &clk_pixel_ops,
301 },
302 };
303
304 static struct clk_rcg2 disp_cc_mdss_rot_clk_src = {
305 .cmd_rcgr = 0x2090,
306 .mnd_width = 0,
307 .hid_width = 5,
308 .parent_map = disp_cc_parent_map_3,
309 .freq_tbl = ftbl_disp_cc_mdss_mdp_clk_src,
310 .clkr.hw.init = &(const struct clk_init_data) {
311 .name = "disp_cc_mdss_rot_clk_src",
312 .parent_data = disp_cc_parent_data_3,
313 .num_parents = ARRAY_SIZE(disp_cc_parent_data_3),
314 .flags = CLK_SET_RATE_PARENT,
315 .ops = &clk_rcg2_shared_ops,
316 },
317 };
318
319 static struct clk_rcg2 disp_cc_mdss_vsync_clk_src = {
320 .cmd_rcgr = 0x20a8,
321 .mnd_width = 0,
322 .hid_width = 5,
323 .parent_map = disp_cc_parent_map_1,
324 .freq_tbl = ftbl_disp_cc_mdss_dp_aux1_clk_src,
325 .clkr.hw.init = &(struct clk_init_data){
326 .name = "disp_cc_mdss_vsync_clk_src",
327 .parent_data = disp_cc_parent_data_1,
328 .num_parents = ARRAY_SIZE(disp_cc_parent_data_1),
329 .ops = &clk_rcg2_shared_ops,
330 },
331 };
332
333 static struct clk_regmap_div disp_cc_mdss_byte0_div_clk_src = {
334 .reg = 0x20d8,
335 .shift = 0,
336 .width = 2,
337 .clkr.hw.init = &(const struct clk_init_data) {
338 .name = "disp_cc_mdss_byte0_div_clk_src",
339 .parent_hws = (const struct clk_hw*[]) {
340 &disp_cc_mdss_byte0_clk_src.clkr.hw,
341 },
342 .num_parents = 1,
343 .ops = &clk_regmap_div_ro_ops,
344 },
345 };
346
347 static struct clk_regmap_div disp_cc_mdss_dp_link_div_clk_src = {
348 .reg = 0x210c,
349 .shift = 0,
350 .width = 2,
351 .clkr.hw.init = &(const struct clk_init_data) {
352 .name = "disp_cc_mdss_dp_link_div_clk_src",
353 .parent_hws = (const struct clk_hw*[]) {
354 &disp_cc_mdss_dp_link_clk_src.clkr.hw,
355 },
356 .num_parents = 1,
357 .flags = CLK_SET_RATE_PARENT,
358 .ops = &clk_regmap_div_ro_ops,
359 },
360 };
361
362 static struct clk_branch disp_cc_mdss_ahb_clk = {
363 .halt_reg = 0x2048,
364 .halt_check = BRANCH_HALT,
365 .clkr = {
366 .enable_reg = 0x2048,
367 .enable_mask = BIT(0),
368 .hw.init = &(const struct clk_init_data) {
369 .name = "disp_cc_mdss_ahb_clk",
370 .parent_hws = (const struct clk_hw*[]) {
371 &disp_cc_mdss_ahb_clk_src.clkr.hw,
372 },
373 .num_parents = 1,
374 .flags = CLK_SET_RATE_PARENT,
375 .ops = &clk_branch2_ops,
376 },
377 },
378 };
379
380 static struct clk_branch disp_cc_mdss_byte0_clk = {
381 .halt_reg = 0x2024,
382 .halt_check = BRANCH_HALT,
383 .clkr = {
384 .enable_reg = 0x2024,
385 .enable_mask = BIT(0),
386 .hw.init = &(const struct clk_init_data) {
387 .name = "disp_cc_mdss_byte0_clk",
388 .parent_hws = (const struct clk_hw*[]) {
389 &disp_cc_mdss_byte0_clk_src.clkr.hw,
390 },
391 .num_parents = 1,
392 .flags = CLK_SET_RATE_PARENT,
393 .ops = &clk_branch2_ops,
394 },
395 },
396 };
397
398 static struct clk_branch disp_cc_mdss_byte0_intf_clk = {
399 .halt_reg = 0x2028,
400 .halt_check = BRANCH_HALT,
401 .clkr = {
402 .enable_reg = 0x2028,
403 .enable_mask = BIT(0),
404 .hw.init = &(const struct clk_init_data) {
405 .name = "disp_cc_mdss_byte0_intf_clk",
406 .parent_hws = (const struct clk_hw*[]) {
407 &disp_cc_mdss_byte0_div_clk_src.clkr.hw,
408 },
409 .num_parents = 1,
410 .flags = CLK_SET_RATE_PARENT,
411 .ops = &clk_branch2_ops,
412 },
413 },
414 };
415
416 static struct clk_branch disp_cc_mdss_dp_aux_clk = {
417 .halt_reg = 0x2044,
418 .halt_check = BRANCH_HALT,
419 .clkr = {
420 .enable_reg = 0x2044,
421 .enable_mask = BIT(0),
422 .hw.init = &(const struct clk_init_data) {
423 .name = "disp_cc_mdss_dp_aux_clk",
424 .parent_hws = (const struct clk_hw*[]) {
425 &disp_cc_mdss_dp_aux_clk_src.clkr.hw,
426 },
427 .num_parents = 1,
428 .flags = CLK_SET_RATE_PARENT,
429 .ops = &clk_branch2_ops,
430 },
431 },
432 };
433
434 static struct clk_branch disp_cc_mdss_dp_crypto_clk = {
435 .halt_reg = 0x2038,
436 .halt_check = BRANCH_HALT,
437 .clkr = {
438 .enable_reg = 0x2038,
439 .enable_mask = BIT(0),
440 .hw.init = &(const struct clk_init_data) {
441 .name = "disp_cc_mdss_dp_crypto_clk",
442 .parent_hws = (const struct clk_hw*[]) {
443 &disp_cc_mdss_dp_crypto_clk_src.clkr.hw,
444 },
445 .num_parents = 1,
446 .flags = CLK_SET_RATE_PARENT,
447 .ops = &clk_branch2_ops,
448 },
449 },
450 };
451
452 static struct clk_branch disp_cc_mdss_dp_link_clk = {
453 .halt_reg = 0x2030,
454 .halt_check = BRANCH_HALT,
455 .clkr = {
456 .enable_reg = 0x2030,
457 .enable_mask = BIT(0),
458 .hw.init = &(const struct clk_init_data) {
459 .name = "disp_cc_mdss_dp_link_clk",
460 .parent_hws = (const struct clk_hw*[]) {
461 &disp_cc_mdss_dp_link_clk_src.clkr.hw,
462 },
463 .num_parents = 1,
464 .flags = CLK_SET_RATE_PARENT,
465 .ops = &clk_branch2_ops,
466 },
467 },
468 };
469
470 static struct clk_branch disp_cc_mdss_dp_link_intf_clk = {
471 .halt_reg = 0x2034,
472 .halt_check = BRANCH_HALT,
473 .clkr = {
474 .enable_reg = 0x2034,
475 .enable_mask = BIT(0),
476 .hw.init = &(const struct clk_init_data) {
477 .name = "disp_cc_mdss_dp_link_intf_clk",
478 .parent_hws = (const struct clk_hw*[]) {
479 &disp_cc_mdss_dp_link_div_clk_src.clkr.hw,
480 },
481 .num_parents = 1,
482 .flags = CLK_SET_RATE_PARENT,
483 .ops = &clk_branch2_ops,
484 },
485 },
486 };
487
488 static struct clk_branch disp_cc_mdss_dp_pixel1_clk = {
489 .halt_reg = 0x2040,
490 .halt_check = BRANCH_HALT,
491 .clkr = {
492 .enable_reg = 0x2040,
493 .enable_mask = BIT(0),
494 .hw.init = &(const struct clk_init_data) {
495 .name = "disp_cc_mdss_dp_pixel1_clk",
496 .parent_hws = (const struct clk_hw*[]) {
497 &disp_cc_mdss_dp_pixel1_clk_src.clkr.hw,
498 },
499 .num_parents = 1,
500 .flags = CLK_SET_RATE_PARENT,
501 .ops = &clk_branch2_ops,
502 },
503 },
504 };
505
506 static struct clk_branch disp_cc_mdss_dp_pixel_clk = {
507 .halt_reg = 0x203c,
508 .halt_check = BRANCH_HALT,
509 .clkr = {
510 .enable_reg = 0x203c,
511 .enable_mask = BIT(0),
512 .hw.init = &(const struct clk_init_data) {
513 .name = "disp_cc_mdss_dp_pixel_clk",
514 .parent_hws = (const struct clk_hw*[]) {
515 &disp_cc_mdss_dp_pixel_clk_src.clkr.hw,
516 },
517 .num_parents = 1,
518 .flags = CLK_SET_RATE_PARENT,
519 .ops = &clk_branch2_ops,
520 },
521 },
522 };
523
524 static struct clk_branch disp_cc_mdss_esc0_clk = {
525 .halt_reg = 0x202c,
526 .halt_check = BRANCH_HALT,
527 .clkr = {
528 .enable_reg = 0x202c,
529 .enable_mask = BIT(0),
530 .hw.init = &(const struct clk_init_data) {
531 .name = "disp_cc_mdss_esc0_clk",
532 .parent_hws = (const struct clk_hw*[]) {
533 &disp_cc_mdss_esc0_clk_src.clkr.hw,
534 },
535 .num_parents = 1,
536 .flags = CLK_SET_RATE_PARENT,
537 .ops = &clk_branch2_ops,
538 },
539 },
540 };
541
542 static struct clk_branch disp_cc_mdss_mdp_clk = {
543 .halt_reg = 0x2008,
544 .halt_check = BRANCH_HALT,
545 .clkr = {
546 .enable_reg = 0x2008,
547 .enable_mask = BIT(0),
548 .hw.init = &(const struct clk_init_data) {
549 .name = "disp_cc_mdss_mdp_clk",
550 .parent_hws = (const struct clk_hw*[]) {
551 &disp_cc_mdss_mdp_clk_src.clkr.hw,
552 },
553 .num_parents = 1,
554 .flags = CLK_SET_RATE_PARENT,
555 .ops = &clk_branch2_ops,
556 },
557 },
558 };
559
560 static struct clk_branch disp_cc_mdss_mdp_lut_clk = {
561 .halt_reg = 0x2018,
562 .halt_check = BRANCH_HALT,
563 .clkr = {
564 .enable_reg = 0x2018,
565 .enable_mask = BIT(0),
566 .hw.init = &(const struct clk_init_data) {
567 .name = "disp_cc_mdss_mdp_lut_clk",
568 .parent_hws = (const struct clk_hw*[]) {
569 &disp_cc_mdss_mdp_clk_src.clkr.hw,
570 },
571 .num_parents = 1,
572 .flags = CLK_SET_RATE_PARENT,
573 .ops = &clk_branch2_ops,
574 },
575 },
576 };
577
578 static struct clk_branch disp_cc_mdss_non_gdsc_ahb_clk = {
579 .halt_reg = 0x4004,
580 .halt_check = BRANCH_HALT_VOTED,
581 .clkr = {
582 .enable_reg = 0x4004,
583 .enable_mask = BIT(0),
584 .hw.init = &(const struct clk_init_data) {
585 .name = "disp_cc_mdss_non_gdsc_ahb_clk",
586 .parent_hws = (const struct clk_hw*[]) {
587 &disp_cc_mdss_ahb_clk_src.clkr.hw,
588 },
589 .num_parents = 1,
590 .flags = CLK_SET_RATE_PARENT,
591 .ops = &clk_branch2_ops,
592 },
593 },
594 };
595
596 static struct clk_branch disp_cc_mdss_pclk0_clk = {
597 .halt_reg = 0x2004,
598 .halt_check = BRANCH_HALT,
599 .clkr = {
600 .enable_reg = 0x2004,
601 .enable_mask = BIT(0),
602 .hw.init = &(const struct clk_init_data) {
603 .name = "disp_cc_mdss_pclk0_clk",
604 .parent_hws = (const struct clk_hw*[]) {
605 &disp_cc_mdss_pclk0_clk_src.clkr.hw,
606 },
607 .num_parents = 1,
608 .flags = CLK_SET_RATE_PARENT,
609 .ops = &clk_branch2_ops,
610 },
611 },
612 };
613
614 static struct clk_branch disp_cc_mdss_rot_clk = {
615 .halt_reg = 0x2010,
616 .halt_check = BRANCH_HALT,
617 .clkr = {
618 .enable_reg = 0x2010,
619 .enable_mask = BIT(0),
620 .hw.init = &(const struct clk_init_data) {
621 .name = "disp_cc_mdss_rot_clk",
622 .parent_hws = (const struct clk_hw*[]) {
623 &disp_cc_mdss_rot_clk_src.clkr.hw,
624 },
625 .num_parents = 1,
626 .flags = CLK_SET_RATE_PARENT,
627 .ops = &clk_branch2_ops,
628 },
629 },
630 };
631
632 static struct clk_branch disp_cc_mdss_rscc_ahb_clk = {
633 .halt_reg = 0x400c,
634 .halt_check = BRANCH_HALT,
635 .clkr = {
636 .enable_reg = 0x400c,
637 .enable_mask = BIT(0),
638 .hw.init = &(const struct clk_init_data) {
639 .name = "disp_cc_mdss_rscc_ahb_clk",
640 .parent_hws = (const struct clk_hw*[]) {
641 &disp_cc_mdss_ahb_clk_src.clkr.hw,
642 },
643 .num_parents = 1,
644 .flags = CLK_SET_RATE_PARENT,
645 .ops = &clk_branch2_ops,
646 },
647 },
648 };
649
650 static struct clk_branch disp_cc_mdss_rscc_vsync_clk = {
651 .halt_reg = 0x4008,
652 .halt_check = BRANCH_HALT,
653 .clkr = {
654 .enable_reg = 0x4008,
655 .enable_mask = BIT(0),
656 .hw.init = &(const struct clk_init_data) {
657 .name = "disp_cc_mdss_rscc_vsync_clk",
658 .parent_hws = (const struct clk_hw*[]) {
659 &disp_cc_mdss_vsync_clk_src.clkr.hw,
660 },
661 .num_parents = 1,
662 .flags = CLK_SET_RATE_PARENT,
663 .ops = &clk_branch2_ops,
664 },
665 },
666 };
667
668 static struct clk_branch disp_cc_mdss_vsync_clk = {
669 .halt_reg = 0x2020,
670 .halt_check = BRANCH_HALT,
671 .clkr = {
672 .enable_reg = 0x2020,
673 .enable_mask = BIT(0),
674 .hw.init = &(const struct clk_init_data) {
675 .name = "disp_cc_mdss_vsync_clk",
676 .parent_hws = (const struct clk_hw*[]) {
677 &disp_cc_mdss_vsync_clk_src.clkr.hw,
678 },
679 .num_parents = 1,
680 .flags = CLK_SET_RATE_PARENT,
681 .ops = &clk_branch2_ops,
682 },
683 },
684 };
685
686 static struct gdsc mdss_core_gdsc = {
687 .gdscr = 0x3000,
688 .en_rest_wait_val = 0x2,
689 .en_few_wait_val = 0x2,
690 .clk_dis_wait_val = 0xf,
691 .pd = {
692 .name = "mdss_core_gdsc",
693 },
694 .pwrsts = PWRSTS_OFF_ON,
695 .flags = HW_CTRL | POLL_CFG_GDSCR,
696 };
697
698 static struct clk_regmap *disp_cc_qcs615_clocks[] = {
699 [DISP_CC_MDSS_AHB_CLK] = &disp_cc_mdss_ahb_clk.clkr,
700 [DISP_CC_MDSS_AHB_CLK_SRC] = &disp_cc_mdss_ahb_clk_src.clkr,
701 [DISP_CC_MDSS_BYTE0_CLK] = &disp_cc_mdss_byte0_clk.clkr,
702 [DISP_CC_MDSS_BYTE0_CLK_SRC] = &disp_cc_mdss_byte0_clk_src.clkr,
703 [DISP_CC_MDSS_BYTE0_DIV_CLK_SRC] = &disp_cc_mdss_byte0_div_clk_src.clkr,
704 [DISP_CC_MDSS_BYTE0_INTF_CLK] = &disp_cc_mdss_byte0_intf_clk.clkr,
705 [DISP_CC_MDSS_DP_AUX_CLK] = &disp_cc_mdss_dp_aux_clk.clkr,
706 [DISP_CC_MDSS_DP_AUX_CLK_SRC] = &disp_cc_mdss_dp_aux_clk_src.clkr,
707 [DISP_CC_MDSS_DP_CRYPTO_CLK] = &disp_cc_mdss_dp_crypto_clk.clkr,
708 [DISP_CC_MDSS_DP_CRYPTO_CLK_SRC] = &disp_cc_mdss_dp_crypto_clk_src.clkr,
709 [DISP_CC_MDSS_DP_LINK_CLK] = &disp_cc_mdss_dp_link_clk.clkr,
710 [DISP_CC_MDSS_DP_LINK_CLK_SRC] = &disp_cc_mdss_dp_link_clk_src.clkr,
711 [DISP_CC_MDSS_DP_LINK_DIV_CLK_SRC] = &disp_cc_mdss_dp_link_div_clk_src.clkr,
712 [DISP_CC_MDSS_DP_LINK_INTF_CLK] = &disp_cc_mdss_dp_link_intf_clk.clkr,
713 [DISP_CC_MDSS_DP_PIXEL1_CLK] = &disp_cc_mdss_dp_pixel1_clk.clkr,
714 [DISP_CC_MDSS_DP_PIXEL1_CLK_SRC] = &disp_cc_mdss_dp_pixel1_clk_src.clkr,
715 [DISP_CC_MDSS_DP_PIXEL_CLK] = &disp_cc_mdss_dp_pixel_clk.clkr,
716 [DISP_CC_MDSS_DP_PIXEL_CLK_SRC] = &disp_cc_mdss_dp_pixel_clk_src.clkr,
717 [DISP_CC_MDSS_ESC0_CLK] = &disp_cc_mdss_esc0_clk.clkr,
718 [DISP_CC_MDSS_ESC0_CLK_SRC] = &disp_cc_mdss_esc0_clk_src.clkr,
719 [DISP_CC_MDSS_MDP_CLK] = &disp_cc_mdss_mdp_clk.clkr,
720 [DISP_CC_MDSS_MDP_CLK_SRC] = &disp_cc_mdss_mdp_clk_src.clkr,
721 [DISP_CC_MDSS_MDP_LUT_CLK] = &disp_cc_mdss_mdp_lut_clk.clkr,
722 [DISP_CC_MDSS_NON_GDSC_AHB_CLK] = &disp_cc_mdss_non_gdsc_ahb_clk.clkr,
723 [DISP_CC_MDSS_PCLK0_CLK] = &disp_cc_mdss_pclk0_clk.clkr,
724 [DISP_CC_MDSS_PCLK0_CLK_SRC] = &disp_cc_mdss_pclk0_clk_src.clkr,
725 [DISP_CC_MDSS_ROT_CLK] = &disp_cc_mdss_rot_clk.clkr,
726 [DISP_CC_MDSS_ROT_CLK_SRC] = &disp_cc_mdss_rot_clk_src.clkr,
727 [DISP_CC_MDSS_RSCC_AHB_CLK] = &disp_cc_mdss_rscc_ahb_clk.clkr,
728 [DISP_CC_MDSS_RSCC_VSYNC_CLK] = &disp_cc_mdss_rscc_vsync_clk.clkr,
729 [DISP_CC_MDSS_VSYNC_CLK] = &disp_cc_mdss_vsync_clk.clkr,
730 [DISP_CC_MDSS_VSYNC_CLK_SRC] = &disp_cc_mdss_vsync_clk_src.clkr,
731 [DISP_CC_PLL0] = &disp_cc_pll0.clkr,
732 };
733
734 static struct gdsc *disp_cc_qcs615_gdscs[] = {
735 [MDSS_CORE_GDSC] = &mdss_core_gdsc,
736 };
737
738 static struct clk_alpha_pll *disp_cc_qcs615_plls[] = {
739 &disp_cc_pll0,
740 };
741
742 static u32 disp_cc_qcs615_critical_cbcrs[] = {
743 0x6054, /* DISP_CC_XO_CLK */
744 };
745
746 static const struct regmap_config disp_cc_qcs615_regmap_config = {
747 .reg_bits = 32,
748 .reg_stride = 4,
749 .val_bits = 32,
750 .max_register = 0x10000,
751 .fast_io = true,
752 };
753
754 static struct qcom_cc_driver_data disp_cc_qcs615_driver_data = {
755 .alpha_plls = disp_cc_qcs615_plls,
756 .num_alpha_plls = ARRAY_SIZE(disp_cc_qcs615_plls),
757 .clk_cbcrs = disp_cc_qcs615_critical_cbcrs,
758 .num_clk_cbcrs = ARRAY_SIZE(disp_cc_qcs615_critical_cbcrs),
759 };
760
761 static const struct qcom_cc_desc disp_cc_qcs615_desc = {
762 .config = &disp_cc_qcs615_regmap_config,
763 .clks = disp_cc_qcs615_clocks,
764 .num_clks = ARRAY_SIZE(disp_cc_qcs615_clocks),
765 .gdscs = disp_cc_qcs615_gdscs,
766 .num_gdscs = ARRAY_SIZE(disp_cc_qcs615_gdscs),
767 .driver_data = &disp_cc_qcs615_driver_data,
768 };
769
770 static const struct of_device_id disp_cc_qcs615_match_table[] = {
771 { .compatible = "qcom,qcs615-dispcc" },
772 { }
773 };
774 MODULE_DEVICE_TABLE(of, disp_cc_qcs615_match_table);
775
disp_cc_qcs615_probe(struct platform_device * pdev)776 static int disp_cc_qcs615_probe(struct platform_device *pdev)
777 {
778 return qcom_cc_probe(pdev, &disp_cc_qcs615_desc);
779 }
780
781 static struct platform_driver disp_cc_qcs615_driver = {
782 .probe = disp_cc_qcs615_probe,
783 .driver = {
784 .name = "dispcc-qcs615",
785 .of_match_table = disp_cc_qcs615_match_table,
786 },
787 };
788
789 module_platform_driver(disp_cc_qcs615_driver);
790
791 MODULE_DESCRIPTION("QTI DISPCC QCS615 Driver");
792 MODULE_LICENSE("GPL");
793