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/platform_device.h>
10 #include <linux/regmap.h>
11
12 #include <dt-bindings/clock/qcom,sm4450-dispcc.h>
13
14 #include "clk-alpha-pll.h"
15 #include "clk-branch.h"
16 #include "clk-pll.h"
17 #include "clk-rcg.h"
18 #include "clk-regmap.h"
19 #include "clk-regmap-divider.h"
20 #include "common.h"
21 #include "gdsc.h"
22 #include "reset.h"
23
24 enum {
25 DT_BI_TCXO,
26 DT_BI_TCXO_AO,
27 DT_AHB_CLK,
28 DT_SLEEP_CLK,
29
30 DT_DSI0_PHY_PLL_OUT_BYTECLK,
31 DT_DSI0_PHY_PLL_OUT_DSICLK,
32 };
33
34 enum {
35 P_BI_TCXO,
36 P_DISP_CC_PLL0_OUT_MAIN,
37 P_DISP_CC_PLL1_OUT_EVEN,
38 P_DISP_CC_PLL1_OUT_MAIN,
39 P_DSI0_PHY_PLL_OUT_BYTECLK,
40 P_DSI0_PHY_PLL_OUT_DSICLK,
41 P_SLEEP_CLK,
42 };
43
44 static const struct pll_vco lucid_evo_vco[] = {
45 { 249600000, 2020000000, 0 },
46 };
47
48 /* 600.0 MHz Configuration */
49 static const struct alpha_pll_config disp_cc_pll0_config = {
50 .l = 0x1f,
51 .alpha = 0x4000,
52 .config_ctl_val = 0x20485699,
53 .config_ctl_hi_val = 0x00182261,
54 .config_ctl_hi1_val = 0x32aa299c,
55 .user_ctl_val = 0x00000000,
56 .user_ctl_hi_val = 0x00000805,
57 };
58
59 static struct clk_alpha_pll disp_cc_pll0 = {
60 .offset = 0x0,
61 .vco_table = lucid_evo_vco,
62 .num_vco = ARRAY_SIZE(lucid_evo_vco),
63 .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_EVO],
64 .clkr = {
65 .hw.init = &(const struct clk_init_data) {
66 .name = "disp_cc_pll0",
67 .parent_data = &(const struct clk_parent_data) {
68 .index = DT_BI_TCXO,
69 },
70 .num_parents = 1,
71 .ops = &clk_alpha_pll_lucid_evo_ops,
72 },
73 },
74 };
75
76 static struct clk_alpha_pll disp_cc_pll1 = {
77 .offset = 0x1000,
78 .vco_table = lucid_evo_vco,
79 .num_vco = ARRAY_SIZE(lucid_evo_vco),
80 .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_EVO],
81 .clkr = {
82 .hw.init = &(const struct clk_init_data) {
83 .name = "disp_cc_pll1",
84 .parent_data = &(const struct clk_parent_data) {
85 .index = DT_BI_TCXO,
86 },
87 .num_parents = 1,
88 .ops = &clk_alpha_pll_lucid_evo_ops,
89 },
90 },
91 };
92
93 static const struct parent_map disp_cc_parent_map_0[] = {
94 { P_BI_TCXO, 0 },
95 { P_DSI0_PHY_PLL_OUT_DSICLK, 1 },
96 { P_DSI0_PHY_PLL_OUT_BYTECLK, 2 },
97 };
98
99 static const struct clk_parent_data disp_cc_parent_data_0[] = {
100 { .index = DT_BI_TCXO },
101 { .index = DT_DSI0_PHY_PLL_OUT_DSICLK },
102 { .index = DT_DSI0_PHY_PLL_OUT_BYTECLK },
103 };
104
105 static const struct parent_map disp_cc_parent_map_1[] = {
106 { P_BI_TCXO, 0 },
107 { P_DISP_CC_PLL0_OUT_MAIN, 1 },
108 { P_DISP_CC_PLL1_OUT_MAIN, 4 },
109 { P_DISP_CC_PLL1_OUT_EVEN, 6 },
110 };
111
112 static const struct clk_parent_data disp_cc_parent_data_1[] = {
113 { .index = DT_BI_TCXO },
114 { .hw = &disp_cc_pll0.clkr.hw },
115 { .hw = &disp_cc_pll1.clkr.hw },
116 { .hw = &disp_cc_pll1.clkr.hw },
117 };
118
119 static const struct parent_map disp_cc_parent_map_2[] = {
120 { P_BI_TCXO, 0 },
121 };
122
123 static const struct clk_parent_data disp_cc_parent_data_2[] = {
124 { .index = DT_BI_TCXO },
125 };
126
127 static const struct clk_parent_data disp_cc_parent_data_2_ao[] = {
128 { .index = DT_BI_TCXO_AO },
129 };
130
131 static const struct parent_map disp_cc_parent_map_3[] = {
132 { P_BI_TCXO, 0 },
133 { P_DISP_CC_PLL1_OUT_MAIN, 4 },
134 { P_DISP_CC_PLL1_OUT_EVEN, 6 },
135 };
136
137 static const struct clk_parent_data disp_cc_parent_data_3[] = {
138 { .index = DT_BI_TCXO },
139 { .hw = &disp_cc_pll1.clkr.hw },
140 { .hw = &disp_cc_pll1.clkr.hw },
141 };
142
143 static const struct parent_map disp_cc_parent_map_4[] = {
144 { P_BI_TCXO, 0 },
145 { P_DSI0_PHY_PLL_OUT_BYTECLK, 2 },
146 };
147
148 static const struct clk_parent_data disp_cc_parent_data_4[] = {
149 { .index = DT_BI_TCXO },
150 { .index = DT_DSI0_PHY_PLL_OUT_BYTECLK },
151 };
152
153 static const struct parent_map disp_cc_parent_map_5[] = {
154 { P_SLEEP_CLK, 0 },
155 };
156
157 static const struct clk_parent_data disp_cc_parent_data_5[] = {
158 { .index = DT_SLEEP_CLK },
159 };
160
161 static const struct freq_tbl ftbl_disp_cc_mdss_ahb_clk_src[] = {
162 F(19200000, P_BI_TCXO, 1, 0, 0),
163 F(37500000, P_DISP_CC_PLL1_OUT_MAIN, 16, 0, 0),
164 F(75000000, P_DISP_CC_PLL1_OUT_MAIN, 8, 0, 0),
165 { }
166 };
167
168 static struct clk_rcg2 disp_cc_mdss_ahb_clk_src = {
169 .cmd_rcgr = 0x82a4,
170 .mnd_width = 0,
171 .hid_width = 5,
172 .parent_map = disp_cc_parent_map_3,
173 .freq_tbl = ftbl_disp_cc_mdss_ahb_clk_src,
174 .clkr.hw.init = &(const struct clk_init_data) {
175 .name = "disp_cc_mdss_ahb_clk_src",
176 .parent_data = disp_cc_parent_data_3,
177 .num_parents = ARRAY_SIZE(disp_cc_parent_data_3),
178 .flags = CLK_SET_RATE_PARENT,
179 .ops = &clk_rcg2_shared_ops,
180 },
181 };
182
183 static const struct freq_tbl ftbl_disp_cc_mdss_byte0_clk_src[] = {
184 F(19200000, P_BI_TCXO, 1, 0, 0),
185 { }
186 };
187
188 static struct clk_rcg2 disp_cc_mdss_byte0_clk_src = {
189 .cmd_rcgr = 0x80f8,
190 .mnd_width = 0,
191 .hid_width = 5,
192 .parent_map = disp_cc_parent_map_0,
193 .freq_tbl = ftbl_disp_cc_mdss_byte0_clk_src,
194 .clkr.hw.init = &(const struct clk_init_data) {
195 .name = "disp_cc_mdss_byte0_clk_src",
196 .parent_data = disp_cc_parent_data_0,
197 .num_parents = ARRAY_SIZE(disp_cc_parent_data_0),
198 .flags = CLK_SET_RATE_PARENT,
199 .ops = &clk_byte2_ops,
200 },
201 };
202
203 static struct clk_rcg2 disp_cc_mdss_esc0_clk_src = {
204 .cmd_rcgr = 0x8114,
205 .mnd_width = 0,
206 .hid_width = 5,
207 .parent_map = disp_cc_parent_map_4,
208 .freq_tbl = ftbl_disp_cc_mdss_byte0_clk_src,
209 .clkr.hw.init = &(const struct clk_init_data) {
210 .name = "disp_cc_mdss_esc0_clk_src",
211 .parent_data = disp_cc_parent_data_4,
212 .num_parents = ARRAY_SIZE(disp_cc_parent_data_4),
213 .flags = CLK_SET_RATE_PARENT,
214 .ops = &clk_rcg2_shared_ops,
215 },
216 };
217
218 static const struct freq_tbl ftbl_disp_cc_mdss_mdp_clk_src[] = {
219 F(200000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0),
220 F(325000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0),
221 F(380000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0),
222 F(506000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0),
223 F(608000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0),
224 { }
225 };
226
227 static struct clk_rcg2 disp_cc_mdss_mdp_clk_src = {
228 .cmd_rcgr = 0x80b0,
229 .mnd_width = 0,
230 .hid_width = 5,
231 .parent_map = disp_cc_parent_map_1,
232 .freq_tbl = ftbl_disp_cc_mdss_mdp_clk_src,
233 .clkr.hw.init = &(const struct clk_init_data) {
234 .name = "disp_cc_mdss_mdp_clk_src",
235 .parent_data = disp_cc_parent_data_1,
236 .num_parents = ARRAY_SIZE(disp_cc_parent_data_1),
237 .flags = CLK_SET_RATE_PARENT,
238 .ops = &clk_rcg2_shared_ops,
239 },
240 };
241
242 static struct clk_rcg2 disp_cc_mdss_pclk0_clk_src = {
243 .cmd_rcgr = 0x8098,
244 .mnd_width = 8,
245 .hid_width = 5,
246 .parent_map = disp_cc_parent_map_0,
247 .freq_tbl = ftbl_disp_cc_mdss_byte0_clk_src,
248 .clkr.hw.init = &(const struct clk_init_data) {
249 .name = "disp_cc_mdss_pclk0_clk_src",
250 .parent_data = disp_cc_parent_data_0,
251 .num_parents = ARRAY_SIZE(disp_cc_parent_data_0),
252 .flags = CLK_SET_RATE_PARENT,
253 .ops = &clk_pixel_ops,
254 },
255 };
256
257 static const struct freq_tbl ftbl_disp_cc_mdss_rot_clk_src[] = {
258 F(200000000, P_DISP_CC_PLL1_OUT_MAIN, 3, 0, 0),
259 F(300000000, P_DISP_CC_PLL1_OUT_MAIN, 2, 0, 0),
260 { }
261 };
262
263 static struct clk_rcg2 disp_cc_mdss_rot_clk_src = {
264 .cmd_rcgr = 0x80c8,
265 .mnd_width = 0,
266 .hid_width = 5,
267 .parent_map = disp_cc_parent_map_1,
268 .freq_tbl = ftbl_disp_cc_mdss_rot_clk_src,
269 .clkr.hw.init = &(const struct clk_init_data) {
270 .name = "disp_cc_mdss_rot_clk_src",
271 .parent_data = disp_cc_parent_data_1,
272 .num_parents = ARRAY_SIZE(disp_cc_parent_data_1),
273 .flags = CLK_SET_RATE_PARENT,
274 .ops = &clk_rcg2_shared_ops,
275 },
276 };
277
278 static struct clk_rcg2 disp_cc_mdss_vsync_clk_src = {
279 .cmd_rcgr = 0x80e0,
280 .mnd_width = 0,
281 .hid_width = 5,
282 .parent_map = disp_cc_parent_map_2,
283 .freq_tbl = ftbl_disp_cc_mdss_byte0_clk_src,
284 .clkr.hw.init = &(const struct clk_init_data) {
285 .name = "disp_cc_mdss_vsync_clk_src",
286 .parent_data = disp_cc_parent_data_2,
287 .num_parents = ARRAY_SIZE(disp_cc_parent_data_2),
288 .flags = CLK_SET_RATE_PARENT,
289 .ops = &clk_rcg2_shared_ops,
290 },
291 };
292
293 static const struct freq_tbl ftbl_disp_cc_sleep_clk_src[] = {
294 F(32000, P_SLEEP_CLK, 1, 0, 0),
295 { }
296 };
297
298 static struct clk_rcg2 disp_cc_sleep_clk_src = {
299 .cmd_rcgr = 0xe058,
300 .mnd_width = 0,
301 .hid_width = 5,
302 .parent_map = disp_cc_parent_map_5,
303 .freq_tbl = ftbl_disp_cc_sleep_clk_src,
304 .clkr.hw.init = &(const struct clk_init_data) {
305 .name = "disp_cc_sleep_clk_src",
306 .parent_data = disp_cc_parent_data_5,
307 .num_parents = ARRAY_SIZE(disp_cc_parent_data_5),
308 .flags = CLK_SET_RATE_PARENT,
309 .ops = &clk_rcg2_shared_ops,
310 },
311 };
312
313 static struct clk_rcg2 disp_cc_xo_clk_src = {
314 .cmd_rcgr = 0xe03c,
315 .mnd_width = 0,
316 .hid_width = 5,
317 .parent_map = disp_cc_parent_map_2,
318 .freq_tbl = ftbl_disp_cc_mdss_byte0_clk_src,
319 .clkr.hw.init = &(const struct clk_init_data) {
320 .name = "disp_cc_xo_clk_src",
321 .parent_data = disp_cc_parent_data_2_ao,
322 .num_parents = ARRAY_SIZE(disp_cc_parent_data_2_ao),
323 .flags = CLK_SET_RATE_PARENT,
324 .ops = &clk_rcg2_shared_ops,
325 },
326 };
327
328 static struct clk_regmap_div disp_cc_mdss_byte0_div_clk_src = {
329 .reg = 0x8110,
330 .shift = 0,
331 .width = 4,
332 .clkr.hw.init = &(const struct clk_init_data) {
333 .name = "disp_cc_mdss_byte0_div_clk_src",
334 .parent_hws = (const struct clk_hw*[]) {
335 &disp_cc_mdss_byte0_clk_src.clkr.hw,
336 },
337 .num_parents = 1,
338 .flags = CLK_SET_RATE_PARENT,
339 .ops = &clk_regmap_div_ops,
340 },
341 };
342
343 static struct clk_branch disp_cc_mdss_ahb1_clk = {
344 .halt_reg = 0xa020,
345 .halt_check = BRANCH_HALT,
346 .clkr = {
347 .enable_reg = 0xa020,
348 .enable_mask = BIT(0),
349 .hw.init = &(const struct clk_init_data) {
350 .name = "disp_cc_mdss_ahb1_clk",
351 .parent_hws = (const struct clk_hw*[]) {
352 &disp_cc_mdss_ahb_clk_src.clkr.hw,
353 },
354 .num_parents = 1,
355 .flags = CLK_SET_RATE_PARENT,
356 .ops = &clk_branch2_ops,
357 },
358 },
359 };
360
361 static struct clk_branch disp_cc_mdss_ahb_clk = {
362 .halt_reg = 0x8094,
363 .halt_check = BRANCH_HALT,
364 .clkr = {
365 .enable_reg = 0x8094,
366 .enable_mask = BIT(0),
367 .hw.init = &(const struct clk_init_data) {
368 .name = "disp_cc_mdss_ahb_clk",
369 .parent_hws = (const struct clk_hw*[]) {
370 &disp_cc_mdss_ahb_clk_src.clkr.hw,
371 },
372 .num_parents = 1,
373 .flags = CLK_SET_RATE_PARENT,
374 .ops = &clk_branch2_ops,
375 },
376 },
377 };
378
379 static struct clk_branch disp_cc_mdss_byte0_clk = {
380 .halt_reg = 0x8024,
381 .halt_check = BRANCH_HALT,
382 .clkr = {
383 .enable_reg = 0x8024,
384 .enable_mask = BIT(0),
385 .hw.init = &(const struct clk_init_data) {
386 .name = "disp_cc_mdss_byte0_clk",
387 .parent_hws = (const struct clk_hw*[]) {
388 &disp_cc_mdss_byte0_clk_src.clkr.hw,
389 },
390 .num_parents = 1,
391 .flags = CLK_SET_RATE_PARENT,
392 .ops = &clk_branch2_ops,
393 },
394 },
395 };
396
397 static struct clk_branch disp_cc_mdss_byte0_intf_clk = {
398 .halt_reg = 0x8028,
399 .halt_check = BRANCH_HALT,
400 .clkr = {
401 .enable_reg = 0x8028,
402 .enable_mask = BIT(0),
403 .hw.init = &(const struct clk_init_data) {
404 .name = "disp_cc_mdss_byte0_intf_clk",
405 .parent_hws = (const struct clk_hw*[]) {
406 &disp_cc_mdss_byte0_div_clk_src.clkr.hw,
407 },
408 .num_parents = 1,
409 .flags = CLK_SET_RATE_PARENT,
410 .ops = &clk_branch2_ops,
411 },
412 },
413 };
414
415 static struct clk_branch disp_cc_mdss_esc0_clk = {
416 .halt_reg = 0x802c,
417 .halt_check = BRANCH_HALT,
418 .clkr = {
419 .enable_reg = 0x802c,
420 .enable_mask = BIT(0),
421 .hw.init = &(const struct clk_init_data) {
422 .name = "disp_cc_mdss_esc0_clk",
423 .parent_hws = (const struct clk_hw*[]) {
424 &disp_cc_mdss_esc0_clk_src.clkr.hw,
425 },
426 .num_parents = 1,
427 .flags = CLK_SET_RATE_PARENT,
428 .ops = &clk_branch2_ops,
429 },
430 },
431 };
432
433 static struct clk_branch disp_cc_mdss_mdp1_clk = {
434 .halt_reg = 0xa004,
435 .halt_check = BRANCH_HALT,
436 .clkr = {
437 .enable_reg = 0xa004,
438 .enable_mask = BIT(0),
439 .hw.init = &(const struct clk_init_data) {
440 .name = "disp_cc_mdss_mdp1_clk",
441 .parent_hws = (const struct clk_hw*[]) {
442 &disp_cc_mdss_mdp_clk_src.clkr.hw,
443 },
444 .num_parents = 1,
445 .flags = CLK_SET_RATE_PARENT,
446 .ops = &clk_branch2_ops,
447 },
448 },
449 };
450
451 static struct clk_branch disp_cc_mdss_mdp_clk = {
452 .halt_reg = 0x8008,
453 .halt_check = BRANCH_HALT,
454 .clkr = {
455 .enable_reg = 0x8008,
456 .enable_mask = BIT(0),
457 .hw.init = &(const struct clk_init_data) {
458 .name = "disp_cc_mdss_mdp_clk",
459 .parent_hws = (const struct clk_hw*[]) {
460 &disp_cc_mdss_mdp_clk_src.clkr.hw,
461 },
462 .num_parents = 1,
463 .flags = CLK_SET_RATE_PARENT,
464 .ops = &clk_branch2_ops,
465 },
466 },
467 };
468
469 static struct clk_branch disp_cc_mdss_mdp_lut1_clk = {
470 .halt_reg = 0xa014,
471 .halt_check = BRANCH_HALT,
472 .clkr = {
473 .enable_reg = 0xa014,
474 .enable_mask = BIT(0),
475 .hw.init = &(const struct clk_init_data) {
476 .name = "disp_cc_mdss_mdp_lut1_clk",
477 .parent_hws = (const struct clk_hw*[]) {
478 &disp_cc_mdss_mdp_clk_src.clkr.hw,
479 },
480 .num_parents = 1,
481 .flags = CLK_SET_RATE_PARENT,
482 .ops = &clk_branch2_ops,
483 },
484 },
485 };
486
487 static struct clk_branch disp_cc_mdss_mdp_lut_clk = {
488 .halt_reg = 0x8018,
489 .halt_check = BRANCH_HALT_VOTED,
490 .clkr = {
491 .enable_reg = 0x8018,
492 .enable_mask = BIT(0),
493 .hw.init = &(const struct clk_init_data) {
494 .name = "disp_cc_mdss_mdp_lut_clk",
495 .parent_hws = (const struct clk_hw*[]) {
496 &disp_cc_mdss_mdp_clk_src.clkr.hw,
497 },
498 .num_parents = 1,
499 .flags = CLK_SET_RATE_PARENT,
500 .ops = &clk_branch2_ops,
501 },
502 },
503 };
504
505 static struct clk_branch disp_cc_mdss_non_gdsc_ahb_clk = {
506 .halt_reg = 0xc004,
507 .halt_check = BRANCH_HALT_VOTED,
508 .clkr = {
509 .enable_reg = 0xc004,
510 .enable_mask = BIT(0),
511 .hw.init = &(const struct clk_init_data) {
512 .name = "disp_cc_mdss_non_gdsc_ahb_clk",
513 .parent_hws = (const struct clk_hw*[]) {
514 &disp_cc_mdss_ahb_clk_src.clkr.hw,
515 },
516 .num_parents = 1,
517 .flags = CLK_SET_RATE_PARENT,
518 .ops = &clk_branch2_ops,
519 },
520 },
521 };
522
523 static struct clk_branch disp_cc_mdss_pclk0_clk = {
524 .halt_reg = 0x8004,
525 .halt_check = BRANCH_HALT,
526 .clkr = {
527 .enable_reg = 0x8004,
528 .enable_mask = BIT(0),
529 .hw.init = &(const struct clk_init_data) {
530 .name = "disp_cc_mdss_pclk0_clk",
531 .parent_hws = (const struct clk_hw*[]) {
532 &disp_cc_mdss_pclk0_clk_src.clkr.hw,
533 },
534 .num_parents = 1,
535 .flags = CLK_SET_RATE_PARENT,
536 .ops = &clk_branch2_ops,
537 },
538 },
539 };
540
541 static struct clk_branch disp_cc_mdss_rot1_clk = {
542 .halt_reg = 0xa00c,
543 .halt_check = BRANCH_HALT,
544 .clkr = {
545 .enable_reg = 0xa00c,
546 .enable_mask = BIT(0),
547 .hw.init = &(const struct clk_init_data) {
548 .name = "disp_cc_mdss_rot1_clk",
549 .parent_hws = (const struct clk_hw*[]) {
550 &disp_cc_mdss_rot_clk_src.clkr.hw,
551 },
552 .num_parents = 1,
553 .flags = CLK_SET_RATE_PARENT,
554 .ops = &clk_branch2_ops,
555 },
556 },
557 };
558
559 static struct clk_branch disp_cc_mdss_rot_clk = {
560 .halt_reg = 0x8010,
561 .halt_check = BRANCH_HALT,
562 .clkr = {
563 .enable_reg = 0x8010,
564 .enable_mask = BIT(0),
565 .hw.init = &(const struct clk_init_data) {
566 .name = "disp_cc_mdss_rot_clk",
567 .parent_hws = (const struct clk_hw*[]) {
568 &disp_cc_mdss_rot_clk_src.clkr.hw,
569 },
570 .num_parents = 1,
571 .flags = CLK_SET_RATE_PARENT,
572 .ops = &clk_branch2_ops,
573 },
574 },
575 };
576
577 static struct clk_branch disp_cc_mdss_rscc_ahb_clk = {
578 .halt_reg = 0xc00c,
579 .halt_check = BRANCH_HALT,
580 .clkr = {
581 .enable_reg = 0xc00c,
582 .enable_mask = BIT(0),
583 .hw.init = &(const struct clk_init_data) {
584 .name = "disp_cc_mdss_rscc_ahb_clk",
585 .parent_hws = (const struct clk_hw*[]) {
586 &disp_cc_mdss_ahb_clk_src.clkr.hw,
587 },
588 .num_parents = 1,
589 .flags = CLK_SET_RATE_PARENT,
590 .ops = &clk_branch2_ops,
591 },
592 },
593 };
594
595 static struct clk_branch disp_cc_mdss_rscc_vsync_clk = {
596 .halt_reg = 0xc008,
597 .halt_check = BRANCH_HALT,
598 .clkr = {
599 .enable_reg = 0xc008,
600 .enable_mask = BIT(0),
601 .hw.init = &(const struct clk_init_data) {
602 .name = "disp_cc_mdss_rscc_vsync_clk",
603 .parent_hws = (const struct clk_hw*[]) {
604 &disp_cc_mdss_vsync_clk_src.clkr.hw,
605 },
606 .num_parents = 1,
607 .flags = CLK_SET_RATE_PARENT,
608 .ops = &clk_branch2_ops,
609 },
610 },
611 };
612
613 static struct clk_branch disp_cc_mdss_vsync1_clk = {
614 .halt_reg = 0xa01c,
615 .halt_check = BRANCH_HALT,
616 .clkr = {
617 .enable_reg = 0xa01c,
618 .enable_mask = BIT(0),
619 .hw.init = &(const struct clk_init_data) {
620 .name = "disp_cc_mdss_vsync1_clk",
621 .parent_hws = (const struct clk_hw*[]) {
622 &disp_cc_mdss_vsync_clk_src.clkr.hw,
623 },
624 .num_parents = 1,
625 .flags = CLK_SET_RATE_PARENT,
626 .ops = &clk_branch2_ops,
627 },
628 },
629 };
630
631 static struct clk_branch disp_cc_mdss_vsync_clk = {
632 .halt_reg = 0x8020,
633 .halt_check = BRANCH_HALT,
634 .clkr = {
635 .enable_reg = 0x8020,
636 .enable_mask = BIT(0),
637 .hw.init = &(const struct clk_init_data) {
638 .name = "disp_cc_mdss_vsync_clk",
639 .parent_hws = (const struct clk_hw*[]) {
640 &disp_cc_mdss_vsync_clk_src.clkr.hw,
641 },
642 .num_parents = 1,
643 .flags = CLK_SET_RATE_PARENT,
644 .ops = &clk_branch2_ops,
645 },
646 },
647 };
648
649 static struct gdsc disp_cc_mdss_core_gdsc = {
650 .gdscr = 0x9000,
651 .en_rest_wait_val = 0x2,
652 .en_few_wait_val = 0x2,
653 .clk_dis_wait_val = 0xf,
654 .pd = {
655 .name = "disp_cc_mdss_core_gdsc",
656 },
657 .pwrsts = PWRSTS_OFF_ON,
658 .flags = HW_CTRL | POLL_CFG_GDSCR | RETAIN_FF_ENABLE,
659 };
660
661 static struct gdsc disp_cc_mdss_core_int2_gdsc = {
662 .gdscr = 0xb000,
663 .en_rest_wait_val = 0x2,
664 .en_few_wait_val = 0x2,
665 .clk_dis_wait_val = 0xf,
666 .pd = {
667 .name = "disp_cc_mdss_core_int2_gdsc",
668 },
669 .pwrsts = PWRSTS_OFF_ON,
670 .flags = HW_CTRL | POLL_CFG_GDSCR | RETAIN_FF_ENABLE,
671 };
672
673 static struct clk_regmap *disp_cc_sm4450_clocks[] = {
674 [DISP_CC_MDSS_AHB1_CLK] = &disp_cc_mdss_ahb1_clk.clkr,
675 [DISP_CC_MDSS_AHB_CLK] = &disp_cc_mdss_ahb_clk.clkr,
676 [DISP_CC_MDSS_AHB_CLK_SRC] = &disp_cc_mdss_ahb_clk_src.clkr,
677 [DISP_CC_MDSS_BYTE0_CLK] = &disp_cc_mdss_byte0_clk.clkr,
678 [DISP_CC_MDSS_BYTE0_CLK_SRC] = &disp_cc_mdss_byte0_clk_src.clkr,
679 [DISP_CC_MDSS_BYTE0_DIV_CLK_SRC] = &disp_cc_mdss_byte0_div_clk_src.clkr,
680 [DISP_CC_MDSS_BYTE0_INTF_CLK] = &disp_cc_mdss_byte0_intf_clk.clkr,
681 [DISP_CC_MDSS_ESC0_CLK] = &disp_cc_mdss_esc0_clk.clkr,
682 [DISP_CC_MDSS_ESC0_CLK_SRC] = &disp_cc_mdss_esc0_clk_src.clkr,
683 [DISP_CC_MDSS_MDP1_CLK] = &disp_cc_mdss_mdp1_clk.clkr,
684 [DISP_CC_MDSS_MDP_CLK] = &disp_cc_mdss_mdp_clk.clkr,
685 [DISP_CC_MDSS_MDP_CLK_SRC] = &disp_cc_mdss_mdp_clk_src.clkr,
686 [DISP_CC_MDSS_MDP_LUT1_CLK] = &disp_cc_mdss_mdp_lut1_clk.clkr,
687 [DISP_CC_MDSS_MDP_LUT_CLK] = &disp_cc_mdss_mdp_lut_clk.clkr,
688 [DISP_CC_MDSS_NON_GDSC_AHB_CLK] = &disp_cc_mdss_non_gdsc_ahb_clk.clkr,
689 [DISP_CC_MDSS_PCLK0_CLK] = &disp_cc_mdss_pclk0_clk.clkr,
690 [DISP_CC_MDSS_PCLK0_CLK_SRC] = &disp_cc_mdss_pclk0_clk_src.clkr,
691 [DISP_CC_MDSS_ROT1_CLK] = &disp_cc_mdss_rot1_clk.clkr,
692 [DISP_CC_MDSS_ROT_CLK] = &disp_cc_mdss_rot_clk.clkr,
693 [DISP_CC_MDSS_ROT_CLK_SRC] = &disp_cc_mdss_rot_clk_src.clkr,
694 [DISP_CC_MDSS_RSCC_AHB_CLK] = &disp_cc_mdss_rscc_ahb_clk.clkr,
695 [DISP_CC_MDSS_RSCC_VSYNC_CLK] = &disp_cc_mdss_rscc_vsync_clk.clkr,
696 [DISP_CC_MDSS_VSYNC1_CLK] = &disp_cc_mdss_vsync1_clk.clkr,
697 [DISP_CC_MDSS_VSYNC_CLK] = &disp_cc_mdss_vsync_clk.clkr,
698 [DISP_CC_MDSS_VSYNC_CLK_SRC] = &disp_cc_mdss_vsync_clk_src.clkr,
699 [DISP_CC_PLL0] = &disp_cc_pll0.clkr,
700 [DISP_CC_PLL1] = &disp_cc_pll1.clkr,
701 [DISP_CC_SLEEP_CLK_SRC] = &disp_cc_sleep_clk_src.clkr,
702 [DISP_CC_XO_CLK_SRC] = &disp_cc_xo_clk_src.clkr,
703 };
704
705 static struct gdsc *disp_cc_sm4450_gdscs[] = {
706 [DISP_CC_MDSS_CORE_GDSC] = &disp_cc_mdss_core_gdsc,
707 [DISP_CC_MDSS_CORE_INT2_GDSC] = &disp_cc_mdss_core_int2_gdsc,
708 };
709
710 static const struct qcom_reset_map disp_cc_sm4450_resets[] = {
711 [DISP_CC_MDSS_CORE_BCR] = { 0x8000 },
712 [DISP_CC_MDSS_CORE_INT2_BCR] = { 0xa000 },
713 [DISP_CC_MDSS_RSCC_BCR] = { 0xc000 },
714 };
715
716 static const struct regmap_config disp_cc_sm4450_regmap_config = {
717 .reg_bits = 32,
718 .reg_stride = 4,
719 .val_bits = 32,
720 .max_register = 0x11008,
721 .fast_io = true,
722 };
723
724 static const struct qcom_cc_desc disp_cc_sm4450_desc = {
725 .config = &disp_cc_sm4450_regmap_config,
726 .clks = disp_cc_sm4450_clocks,
727 .num_clks = ARRAY_SIZE(disp_cc_sm4450_clocks),
728 .resets = disp_cc_sm4450_resets,
729 .num_resets = ARRAY_SIZE(disp_cc_sm4450_resets),
730 .gdscs = disp_cc_sm4450_gdscs,
731 .num_gdscs = ARRAY_SIZE(disp_cc_sm4450_gdscs),
732 };
733
734 static const struct of_device_id disp_cc_sm4450_match_table[] = {
735 { .compatible = "qcom,sm4450-dispcc" },
736 { }
737 };
738 MODULE_DEVICE_TABLE(of, disp_cc_sm4450_match_table);
739
disp_cc_sm4450_probe(struct platform_device * pdev)740 static int disp_cc_sm4450_probe(struct platform_device *pdev)
741 {
742 struct regmap *regmap;
743
744 regmap = qcom_cc_map(pdev, &disp_cc_sm4450_desc);
745 if (IS_ERR(regmap))
746 return PTR_ERR(regmap);
747
748 clk_lucid_evo_pll_configure(&disp_cc_pll0, regmap, &disp_cc_pll0_config);
749 clk_lucid_evo_pll_configure(&disp_cc_pll1, regmap, &disp_cc_pll0_config);
750
751 /* Keep some clocks always enabled */
752 qcom_branch_set_clk_en(regmap, 0xe070); /* DISP_CC_SLEEP_CLK */
753 qcom_branch_set_clk_en(regmap, 0xe054); /* DISP_CC_XO_CLK */
754
755 return qcom_cc_really_probe(&pdev->dev, &disp_cc_sm4450_desc, regmap);
756 }
757
758 static struct platform_driver disp_cc_sm4450_driver = {
759 .probe = disp_cc_sm4450_probe,
760 .driver = {
761 .name = "dispcc-sm4450",
762 .of_match_table = disp_cc_sm4450_match_table,
763 },
764 };
765
766 module_platform_driver(disp_cc_sm4450_driver);
767
768 MODULE_DESCRIPTION("QTI DISPCC SM4450 Driver");
769 MODULE_LICENSE("GPL");
770