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 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 .parent_map = disp_cc_parent_map_6,
191 .freq_tbl = ftbl_disp_cc_mdss_dp_aux_clk_src,
192 .clkr.hw.init = &(struct clk_init_data){
193 .name = "disp_cc_mdss_dp_aux_clk_src",
194 .parent_data = disp_cc_parent_data_6,
195 .num_parents = ARRAY_SIZE(disp_cc_parent_data_6),
196 .ops = &clk_rcg2_ops,
197 },
198 };
199
200 static const struct freq_tbl ftbl_disp_cc_mdss_dp_crypto_clk_src[] = {
201 F(108000, P_DP_PHY_PLL_LINK_CLK, 3, 0, 0),
202 F(180000, P_DP_PHY_PLL_LINK_CLK, 3, 0, 0),
203 F(360000, P_DP_PHY_PLL_LINK_CLK, 1.5, 0, 0),
204 F(540000, P_DP_PHY_PLL_LINK_CLK, 1.5, 0, 0),
205 { }
206 };
207
208 static struct clk_rcg2 disp_cc_mdss_dp_crypto_clk_src = {
209 .cmd_rcgr = 0x1114,
210 .mnd_width = 0,
211 .hid_width = 5,
212 .parent_map = disp_cc_parent_map_0,
213 .freq_tbl = ftbl_disp_cc_mdss_dp_crypto_clk_src,
214 .clkr.hw.init = &(struct clk_init_data){
215 .name = "disp_cc_mdss_dp_crypto_clk_src",
216 .parent_data = disp_cc_parent_data_0,
217 .num_parents = ARRAY_SIZE(disp_cc_parent_data_0),
218 .flags = CLK_GET_RATE_NOCACHE,
219 .ops = &clk_rcg2_ops,
220 },
221 };
222
223 static struct clk_rcg2 disp_cc_mdss_dp_link_clk_src = {
224 .cmd_rcgr = 0x10f8,
225 .mnd_width = 0,
226 .hid_width = 5,
227 .parent_map = disp_cc_parent_map_0,
228 .clkr.hw.init = &(struct clk_init_data){
229 .name = "disp_cc_mdss_dp_link_clk_src",
230 .parent_data = disp_cc_parent_data_0,
231 .num_parents = ARRAY_SIZE(disp_cc_parent_data_0),
232 .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE,
233 .ops = &clk_byte2_ops,
234 },
235 };
236
237 static struct clk_rcg2 disp_cc_mdss_dp_pixel_clk_src = {
238 .cmd_rcgr = 0x112c,
239 .mnd_width = 16,
240 .hid_width = 5,
241 .parent_map = disp_cc_parent_map_0,
242 .clkr.hw.init = &(struct clk_init_data){
243 .name = "disp_cc_mdss_dp_pixel_clk_src",
244 .parent_data = disp_cc_parent_data_0,
245 .num_parents = ARRAY_SIZE(disp_cc_parent_data_0),
246 .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE,
247 .ops = &clk_dp_ops,
248 },
249 };
250
251 static struct clk_rcg2 disp_cc_mdss_esc0_clk_src = {
252 .cmd_rcgr = 0x10e0,
253 .mnd_width = 0,
254 .hid_width = 5,
255 .parent_map = disp_cc_parent_map_1,
256 .freq_tbl = ftbl_disp_cc_mdss_dp_aux_clk_src,
257 .clkr.hw.init = &(struct clk_init_data){
258 .name = "disp_cc_mdss_esc0_clk_src",
259 .parent_data = disp_cc_parent_data_1,
260 .num_parents = ARRAY_SIZE(disp_cc_parent_data_1),
261 .ops = &clk_rcg2_ops,
262 },
263 };
264
265 static const struct freq_tbl ftbl_disp_cc_mdss_mdp_clk_src[] = {
266 F(19200000, P_BI_TCXO, 1, 0, 0),
267 F(200000000, P_GCC_DISP_GPLL0_CLK, 3, 0, 0),
268 F(300000000, P_GCC_DISP_GPLL0_CLK, 2, 0, 0),
269 F(373333333, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0),
270 F(448000000, P_DISP_CC_PLL0_OUT_MAIN, 2.5, 0, 0),
271 F(560000000, P_DISP_CC_PLL0_OUT_MAIN, 2, 0, 0),
272 { }
273 };
274
275 static struct clk_rcg2 disp_cc_mdss_mdp_clk_src = {
276 .cmd_rcgr = 0x107c,
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 = &(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_ops,
287 },
288 };
289
290 static struct clk_rcg2 disp_cc_mdss_pclk0_clk_src = {
291 .cmd_rcgr = 0x1064,
292 .mnd_width = 8,
293 .hid_width = 5,
294 .parent_map = disp_cc_parent_map_5,
295 .clkr.hw.init = &(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 | CLK_GET_RATE_NOCACHE | CLK_OPS_PARENT_ENABLE,
300 .ops = &clk_pixel_ops,
301 },
302 };
303
304 static struct clk_rcg2 disp_cc_mdss_rot_clk_src = {
305 .cmd_rcgr = 0x1094,
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 = &(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_ops,
316 },
317 };
318
319 static struct clk_rcg2 disp_cc_mdss_vsync_clk_src = {
320 .cmd_rcgr = 0x10ac,
321 .mnd_width = 0,
322 .hid_width = 5,
323 .parent_map = disp_cc_parent_map_6,
324 .freq_tbl = ftbl_disp_cc_mdss_dp_aux_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_6,
328 .num_parents = ARRAY_SIZE(disp_cc_parent_data_6),
329 .ops = &clk_rcg2_ops,
330 },
331 };
332
333 static struct clk_regmap_div disp_cc_mdss_dp_link_div_clk_src = {
334 .reg = 0x1110,
335 .shift = 0,
336 .width = 2,
337 .clkr.hw.init = &(struct clk_init_data) {
338 .name = "disp_cc_mdss_dp_link_div_clk_src",
339 .parent_hws = (const struct clk_hw*[]){
340 &disp_cc_mdss_dp_link_clk_src.clkr.hw,
341 },
342 .num_parents = 1,
343 .flags = CLK_GET_RATE_NOCACHE,
344 .ops = &clk_regmap_div_ro_ops,
345 },
346 };
347
348 static struct clk_branch disp_cc_mdss_ahb_clk = {
349 .halt_reg = 0x104c,
350 .halt_check = BRANCH_HALT,
351 .clkr = {
352 .enable_reg = 0x104c,
353 .enable_mask = BIT(0),
354 .hw.init = &(struct clk_init_data){
355 .name = "disp_cc_mdss_ahb_clk",
356 .parent_hws = (const struct clk_hw*[]){
357 &disp_cc_mdss_ahb_clk_src.clkr.hw,
358 },
359 .num_parents = 1,
360 .flags = CLK_SET_RATE_PARENT,
361 .ops = &clk_branch2_ops,
362 },
363 },
364 };
365
366 static struct clk_branch disp_cc_mdss_byte0_clk = {
367 .halt_reg = 0x102c,
368 .halt_check = BRANCH_HALT,
369 .clkr = {
370 .enable_reg = 0x102c,
371 .enable_mask = BIT(0),
372 .hw.init = &(struct clk_init_data){
373 .name = "disp_cc_mdss_byte0_clk",
374 .parent_hws = (const struct clk_hw*[]){
375 &disp_cc_mdss_byte0_clk_src.clkr.hw,
376 },
377 .num_parents = 1,
378 .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE | CLK_OPS_PARENT_ENABLE,
379 .ops = &clk_branch2_ops,
380 },
381 },
382 };
383
384 static struct clk_branch disp_cc_mdss_byte0_intf_clk = {
385 .halt_reg = 0x1030,
386 .halt_check = BRANCH_HALT,
387 .clkr = {
388 .enable_reg = 0x1030,
389 .enable_mask = BIT(0),
390 .hw.init = &(struct clk_init_data){
391 .name = "disp_cc_mdss_byte0_intf_clk",
392 .parent_hws = (const struct clk_hw*[]){
393 &disp_cc_mdss_byte0_div_clk_src.clkr.hw,
394 },
395 .num_parents = 1,
396 .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE,
397 .ops = &clk_branch2_ops,
398 },
399 },
400 };
401
402 static struct clk_branch disp_cc_mdss_dp_aux_clk = {
403 .halt_reg = 0x1048,
404 .halt_check = BRANCH_HALT,
405 .clkr = {
406 .enable_reg = 0x1048,
407 .enable_mask = BIT(0),
408 .hw.init = &(struct clk_init_data){
409 .name = "disp_cc_mdss_dp_aux_clk",
410 .parent_hws = (const struct clk_hw*[]){
411 &disp_cc_mdss_dp_aux_clk_src.clkr.hw,
412 },
413 .num_parents = 1,
414 .flags = CLK_SET_RATE_PARENT,
415 .ops = &clk_branch2_ops,
416 },
417 },
418 };
419
420 static struct clk_branch disp_cc_mdss_dp_crypto_clk = {
421 .halt_reg = 0x1040,
422 .halt_check = BRANCH_HALT,
423 .clkr = {
424 .enable_reg = 0x1040,
425 .enable_mask = BIT(0),
426 .hw.init = &(struct clk_init_data){
427 .name = "disp_cc_mdss_dp_crypto_clk",
428 .parent_hws = (const struct clk_hw*[]){
429 &disp_cc_mdss_dp_crypto_clk_src.clkr.hw,
430 },
431 .num_parents = 1,
432 .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE,
433 .ops = &clk_branch2_ops,
434 },
435 },
436 };
437
438 static struct clk_branch disp_cc_mdss_dp_link_clk = {
439 .halt_reg = 0x1038,
440 .halt_check = BRANCH_HALT,
441 .clkr = {
442 .enable_reg = 0x1038,
443 .enable_mask = BIT(0),
444 .hw.init = &(struct clk_init_data){
445 .name = "disp_cc_mdss_dp_link_clk",
446 .parent_hws = (const struct clk_hw*[]){
447 &disp_cc_mdss_dp_link_clk_src.clkr.hw,
448 },
449 .num_parents = 1,
450 .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE,
451 .ops = &clk_branch2_ops,
452 },
453 },
454 };
455
456 static struct clk_branch disp_cc_mdss_dp_link_intf_clk = {
457 .halt_reg = 0x103c,
458 .halt_check = BRANCH_HALT,
459 .clkr = {
460 .enable_reg = 0x103c,
461 .enable_mask = BIT(0),
462 .hw.init = &(struct clk_init_data){
463 .name = "disp_cc_mdss_dp_link_intf_clk",
464 .parent_hws = (const struct clk_hw*[]){
465 &disp_cc_mdss_dp_link_div_clk_src.clkr.hw,
466 },
467 .num_parents = 1,
468 .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE,
469 .ops = &clk_branch2_ops,
470 },
471 },
472 };
473
474 static struct clk_branch disp_cc_mdss_dp_pixel_clk = {
475 .halt_reg = 0x1044,
476 .halt_check = BRANCH_HALT,
477 .clkr = {
478 .enable_reg = 0x1044,
479 .enable_mask = BIT(0),
480 .hw.init = &(struct clk_init_data){
481 .name = "disp_cc_mdss_dp_pixel_clk",
482 .parent_hws = (const struct clk_hw*[]){
483 &disp_cc_mdss_dp_pixel_clk_src.clkr.hw,
484 },
485 .num_parents = 1,
486 .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE,
487 .ops = &clk_branch2_ops,
488 },
489 },
490 };
491
492 static struct clk_branch disp_cc_mdss_esc0_clk = {
493 .halt_reg = 0x1034,
494 .halt_check = BRANCH_HALT,
495 .clkr = {
496 .enable_reg = 0x1034,
497 .enable_mask = BIT(0),
498 .hw.init = &(struct clk_init_data){
499 .name = "disp_cc_mdss_esc0_clk",
500 .parent_hws = (const struct clk_hw*[]){
501 &disp_cc_mdss_esc0_clk_src.clkr.hw,
502 },
503 .num_parents = 1,
504 .flags = CLK_SET_RATE_PARENT,
505 .ops = &clk_branch2_ops,
506 },
507 },
508 };
509
510 static struct clk_branch disp_cc_mdss_mdp_clk = {
511 .halt_reg = 0x1010,
512 .halt_check = BRANCH_HALT,
513 .clkr = {
514 .enable_reg = 0x1010,
515 .enable_mask = BIT(0),
516 .hw.init = &(struct clk_init_data){
517 .name = "disp_cc_mdss_mdp_clk",
518 .parent_hws = (const struct clk_hw*[]){
519 &disp_cc_mdss_mdp_clk_src.clkr.hw,
520 },
521 .num_parents = 1,
522 .flags = CLK_SET_RATE_PARENT,
523 .ops = &clk_branch2_ops,
524 },
525 },
526 };
527
528 static struct clk_branch disp_cc_mdss_mdp_lut_clk = {
529 .halt_reg = 0x1020,
530 .halt_check = BRANCH_HALT_VOTED,
531 .clkr = {
532 .enable_reg = 0x1020,
533 .enable_mask = BIT(0),
534 .hw.init = &(struct clk_init_data){
535 .name = "disp_cc_mdss_mdp_lut_clk",
536 .parent_hws = (const struct clk_hw*[]){
537 &disp_cc_mdss_mdp_clk_src.clkr.hw,
538 },
539 .num_parents = 1,
540 .flags = CLK_SET_RATE_PARENT,
541 .ops = &clk_branch2_ops,
542 },
543 },
544 };
545
546 static struct clk_branch disp_cc_mdss_non_gdsc_ahb_clk = {
547 .halt_reg = 0x2004,
548 .halt_check = BRANCH_HALT_VOTED,
549 .clkr = {
550 .enable_reg = 0x2004,
551 .enable_mask = BIT(0),
552 .hw.init = &(struct clk_init_data){
553 .name = "disp_cc_mdss_non_gdsc_ahb_clk",
554 .parent_hws = (const struct clk_hw*[]){
555 &disp_cc_mdss_ahb_clk_src.clkr.hw,
556 },
557 .num_parents = 1,
558 .flags = CLK_SET_RATE_PARENT,
559 .ops = &clk_branch2_ops,
560 },
561 },
562 };
563
564 static struct clk_branch disp_cc_mdss_pclk0_clk = {
565 .halt_reg = 0x100c,
566 .halt_check = BRANCH_HALT,
567 .clkr = {
568 .enable_reg = 0x100c,
569 .enable_mask = BIT(0),
570 .hw.init = &(struct clk_init_data){
571 .name = "disp_cc_mdss_pclk0_clk",
572 .parent_hws = (const struct clk_hw*[]){
573 &disp_cc_mdss_pclk0_clk_src.clkr.hw,
574 },
575 .num_parents = 1,
576 .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE,
577 .ops = &clk_branch2_ops,
578 },
579 },
580 };
581
582 static struct clk_branch disp_cc_mdss_rot_clk = {
583 .halt_reg = 0x1018,
584 .halt_check = BRANCH_HALT,
585 .clkr = {
586 .enable_reg = 0x1018,
587 .enable_mask = BIT(0),
588 .hw.init = &(struct clk_init_data){
589 .name = "disp_cc_mdss_rot_clk",
590 .parent_hws = (const struct clk_hw*[]){
591 &disp_cc_mdss_rot_clk_src.clkr.hw,
592 },
593 .num_parents = 1,
594 .flags = CLK_SET_RATE_PARENT,
595 .ops = &clk_branch2_ops,
596 },
597 },
598 };
599
600 static struct clk_branch disp_cc_mdss_rscc_ahb_clk = {
601 .halt_reg = 0x200c,
602 .halt_check = BRANCH_HALT,
603 .clkr = {
604 .enable_reg = 0x200c,
605 .enable_mask = BIT(0),
606 .hw.init = &(struct clk_init_data){
607 .name = "disp_cc_mdss_rscc_ahb_clk",
608 .parent_hws = (const struct clk_hw*[]){
609 &disp_cc_mdss_ahb_clk_src.clkr.hw,
610 },
611 .num_parents = 1,
612 .flags = CLK_SET_RATE_PARENT,
613 .ops = &clk_branch2_ops,
614 },
615 },
616 };
617
618 static struct clk_branch disp_cc_mdss_rscc_vsync_clk = {
619 .halt_reg = 0x2008,
620 .halt_check = BRANCH_HALT,
621 .clkr = {
622 .enable_reg = 0x2008,
623 .enable_mask = BIT(0),
624 .hw.init = &(struct clk_init_data){
625 .name = "disp_cc_mdss_rscc_vsync_clk",
626 .parent_hws = (const struct clk_hw*[]){
627 &disp_cc_mdss_vsync_clk_src.clkr.hw,
628 },
629 .num_parents = 1,
630 .flags = CLK_SET_RATE_PARENT,
631 .ops = &clk_branch2_ops,
632 },
633 },
634 };
635
636 static struct clk_branch disp_cc_mdss_vsync_clk = {
637 .halt_reg = 0x1028,
638 .halt_check = BRANCH_HALT,
639 .clkr = {
640 .enable_reg = 0x1028,
641 .enable_mask = BIT(0),
642 .hw.init = &(struct clk_init_data){
643 .name = "disp_cc_mdss_vsync_clk",
644 .parent_hws = (const struct clk_hw*[]){
645 &disp_cc_mdss_vsync_clk_src.clkr.hw,
646 },
647 .num_parents = 1,
648 .flags = CLK_SET_RATE_PARENT,
649 .ops = &clk_branch2_ops,
650 },
651 },
652 };
653
654 static struct clk_branch disp_cc_sleep_clk = {
655 .halt_reg = 0x5004,
656 .halt_check = BRANCH_HALT,
657 .clkr = {
658 .enable_reg = 0x5004,
659 .enable_mask = BIT(0),
660 .hw.init = &(struct clk_init_data){
661 .name = "disp_cc_sleep_clk",
662 .ops = &clk_branch2_ops,
663 },
664 },
665 };
666
667 static struct clk_branch disp_cc_xo_clk = {
668 .halt_reg = 0x5008,
669 .halt_check = BRANCH_HALT,
670 .clkr = {
671 .enable_reg = 0x5008,
672 .enable_mask = BIT(0),
673 .hw.init = &(struct clk_init_data){
674 .name = "disp_cc_xo_clk",
675 .flags = CLK_IS_CRITICAL,
676 .ops = &clk_branch2_ops,
677 },
678 },
679 };
680
681 static struct gdsc mdss_gdsc = {
682 .gdscr = 0x1004,
683 .pd = {
684 .name = "mdss_gdsc",
685 },
686 .pwrsts = PWRSTS_OFF_ON,
687 .flags = RETAIN_FF_ENABLE,
688 };
689
690 static struct clk_regmap *disp_cc_sm6350_clocks[] = {
691 [DISP_CC_MDSS_AHB_CLK] = &disp_cc_mdss_ahb_clk.clkr,
692 [DISP_CC_MDSS_AHB_CLK_SRC] = &disp_cc_mdss_ahb_clk_src.clkr,
693 [DISP_CC_MDSS_BYTE0_CLK] = &disp_cc_mdss_byte0_clk.clkr,
694 [DISP_CC_MDSS_BYTE0_CLK_SRC] = &disp_cc_mdss_byte0_clk_src.clkr,
695 [DISP_CC_MDSS_BYTE0_DIV_CLK_SRC] = &disp_cc_mdss_byte0_div_clk_src.clkr,
696 [DISP_CC_MDSS_BYTE0_INTF_CLK] = &disp_cc_mdss_byte0_intf_clk.clkr,
697 [DISP_CC_MDSS_DP_AUX_CLK] = &disp_cc_mdss_dp_aux_clk.clkr,
698 [DISP_CC_MDSS_DP_AUX_CLK_SRC] = &disp_cc_mdss_dp_aux_clk_src.clkr,
699 [DISP_CC_MDSS_DP_CRYPTO_CLK] = &disp_cc_mdss_dp_crypto_clk.clkr,
700 [DISP_CC_MDSS_DP_CRYPTO_CLK_SRC] = &disp_cc_mdss_dp_crypto_clk_src.clkr,
701 [DISP_CC_MDSS_DP_LINK_CLK] = &disp_cc_mdss_dp_link_clk.clkr,
702 [DISP_CC_MDSS_DP_LINK_CLK_SRC] = &disp_cc_mdss_dp_link_clk_src.clkr,
703 [DISP_CC_MDSS_DP_LINK_DIV_CLK_SRC] =
704 &disp_cc_mdss_dp_link_div_clk_src.clkr,
705 [DISP_CC_MDSS_DP_LINK_INTF_CLK] = &disp_cc_mdss_dp_link_intf_clk.clkr,
706 [DISP_CC_MDSS_DP_PIXEL_CLK] = &disp_cc_mdss_dp_pixel_clk.clkr,
707 [DISP_CC_MDSS_DP_PIXEL_CLK_SRC] = &disp_cc_mdss_dp_pixel_clk_src.clkr,
708 [DISP_CC_MDSS_ESC0_CLK] = &disp_cc_mdss_esc0_clk.clkr,
709 [DISP_CC_MDSS_ESC0_CLK_SRC] = &disp_cc_mdss_esc0_clk_src.clkr,
710 [DISP_CC_MDSS_MDP_CLK] = &disp_cc_mdss_mdp_clk.clkr,
711 [DISP_CC_MDSS_MDP_CLK_SRC] = &disp_cc_mdss_mdp_clk_src.clkr,
712 [DISP_CC_MDSS_MDP_LUT_CLK] = &disp_cc_mdss_mdp_lut_clk.clkr,
713 [DISP_CC_MDSS_NON_GDSC_AHB_CLK] = &disp_cc_mdss_non_gdsc_ahb_clk.clkr,
714 [DISP_CC_MDSS_PCLK0_CLK] = &disp_cc_mdss_pclk0_clk.clkr,
715 [DISP_CC_MDSS_PCLK0_CLK_SRC] = &disp_cc_mdss_pclk0_clk_src.clkr,
716 [DISP_CC_MDSS_ROT_CLK] = &disp_cc_mdss_rot_clk.clkr,
717 [DISP_CC_MDSS_ROT_CLK_SRC] = &disp_cc_mdss_rot_clk_src.clkr,
718 [DISP_CC_MDSS_RSCC_AHB_CLK] = &disp_cc_mdss_rscc_ahb_clk.clkr,
719 [DISP_CC_MDSS_RSCC_VSYNC_CLK] = &disp_cc_mdss_rscc_vsync_clk.clkr,
720 [DISP_CC_MDSS_VSYNC_CLK] = &disp_cc_mdss_vsync_clk.clkr,
721 [DISP_CC_MDSS_VSYNC_CLK_SRC] = &disp_cc_mdss_vsync_clk_src.clkr,
722 [DISP_CC_PLL0] = &disp_cc_pll0.clkr,
723 [DISP_CC_SLEEP_CLK] = &disp_cc_sleep_clk.clkr,
724 [DISP_CC_XO_CLK] = &disp_cc_xo_clk.clkr,
725 };
726
727 static struct gdsc *disp_cc_sm6350_gdscs[] = {
728 [MDSS_GDSC] = &mdss_gdsc,
729 };
730
731 static const struct regmap_config disp_cc_sm6350_regmap_config = {
732 .reg_bits = 32,
733 .reg_stride = 4,
734 .val_bits = 32,
735 .max_register = 0x10000,
736 .fast_io = true,
737 };
738
739 static const struct qcom_cc_desc disp_cc_sm6350_desc = {
740 .config = &disp_cc_sm6350_regmap_config,
741 .clks = disp_cc_sm6350_clocks,
742 .num_clks = ARRAY_SIZE(disp_cc_sm6350_clocks),
743 .gdscs = disp_cc_sm6350_gdscs,
744 .num_gdscs = ARRAY_SIZE(disp_cc_sm6350_gdscs),
745 };
746
747 static const struct of_device_id disp_cc_sm6350_match_table[] = {
748 { .compatible = "qcom,sm6350-dispcc" },
749 { }
750 };
751 MODULE_DEVICE_TABLE(of, disp_cc_sm6350_match_table);
752
disp_cc_sm6350_probe(struct platform_device * pdev)753 static int disp_cc_sm6350_probe(struct platform_device *pdev)
754 {
755 struct regmap *regmap;
756
757 regmap = qcom_cc_map(pdev, &disp_cc_sm6350_desc);
758 if (IS_ERR(regmap))
759 return PTR_ERR(regmap);
760
761 clk_fabia_pll_configure(&disp_cc_pll0, regmap, &disp_cc_pll0_config);
762
763 return qcom_cc_really_probe(pdev, &disp_cc_sm6350_desc, regmap);
764 }
765
766 static struct platform_driver disp_cc_sm6350_driver = {
767 .probe = disp_cc_sm6350_probe,
768 .driver = {
769 .name = "disp_cc-sm6350",
770 .of_match_table = disp_cc_sm6350_match_table,
771 },
772 };
773
disp_cc_sm6350_init(void)774 static int __init disp_cc_sm6350_init(void)
775 {
776 return platform_driver_register(&disp_cc_sm6350_driver);
777 }
778 subsys_initcall(disp_cc_sm6350_init);
779
disp_cc_sm6350_exit(void)780 static void __exit disp_cc_sm6350_exit(void)
781 {
782 platform_driver_unregister(&disp_cc_sm6350_driver);
783 }
784 module_exit(disp_cc_sm6350_exit);
785
786 MODULE_DESCRIPTION("QTI DISP_CC SM6350 Driver");
787 MODULE_LICENSE("GPL v2");
788