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