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