1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * Copyright (c) 2021, The Linux Foundation. All rights reserved.
4 */
5
6 #include <linux/clk-provider.h>
7 #include <linux/module.h>
8 #include <linux/platform_device.h>
9 #include <linux/regmap.h>
10
11 #include <dt-bindings/clock/qcom,dispcc-sm6125.h>
12
13 #include "clk-alpha-pll.h"
14 #include "clk-branch.h"
15 #include "clk-rcg.h"
16 #include "clk-regmap.h"
17 #include "common.h"
18 #include "gdsc.h"
19
20 enum {
21 P_BI_TCXO,
22 P_DISP_CC_PLL0_OUT_MAIN,
23 P_DP_PHY_PLL_LINK_CLK,
24 P_DP_PHY_PLL_VCO_DIV_CLK,
25 P_DSI0_PHY_PLL_OUT_BYTECLK,
26 P_DSI0_PHY_PLL_OUT_DSICLK,
27 P_DSI1_PHY_PLL_OUT_DSICLK,
28 P_GPLL0_OUT_MAIN,
29 };
30
31 static struct pll_vco disp_cc_pll_vco[] = {
32 { 500000000, 1000000000, 2 },
33 };
34
35 static struct clk_alpha_pll disp_cc_pll0 = {
36 .offset = 0x0,
37 .vco_table = disp_cc_pll_vco,
38 .num_vco = ARRAY_SIZE(disp_cc_pll_vco),
39 .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
40 .flags = SUPPORTS_DYNAMIC_UPDATE,
41 .clkr = {
42 .hw.init = &(struct clk_init_data){
43 .name = "disp_cc_pll0",
44 .parent_data = &(const struct clk_parent_data){
45 .fw_name = "bi_tcxo",
46 },
47 .num_parents = 1,
48 .ops = &clk_alpha_pll_ops,
49 },
50 },
51 };
52
53 /* 768MHz configuration */
54 static const struct alpha_pll_config disp_cc_pll0_config = {
55 .l = 0x28,
56 .vco_val = 0x2 << 20,
57 .vco_mask = 0x3 << 20,
58 .main_output_mask = BIT(0),
59 .config_ctl_val = 0x4001055b,
60 };
61
62 static const struct parent_map disp_cc_parent_map_0[] = {
63 { P_BI_TCXO, 0 },
64 };
65
66 static const struct clk_parent_data disp_cc_parent_data_0[] = {
67 { .fw_name = "bi_tcxo" },
68 };
69
70 static const struct parent_map disp_cc_parent_map_1[] = {
71 { P_BI_TCXO, 0 },
72 { P_DP_PHY_PLL_LINK_CLK, 1 },
73 { P_DP_PHY_PLL_VCO_DIV_CLK, 2 },
74 };
75
76 static const struct clk_parent_data disp_cc_parent_data_1[] = {
77 { .fw_name = "bi_tcxo" },
78 { .fw_name = "dp_phy_pll_link_clk" },
79 { .fw_name = "dp_phy_pll_vco_div_clk" },
80 };
81
82 static const struct parent_map disp_cc_parent_map_2[] = {
83 { P_BI_TCXO, 0 },
84 { P_DSI0_PHY_PLL_OUT_BYTECLK, 1 },
85 };
86
87 static const struct clk_parent_data disp_cc_parent_data_2[] = {
88 { .fw_name = "bi_tcxo" },
89 { .fw_name = "dsi0_phy_pll_out_byteclk" },
90 };
91
92 static const struct parent_map disp_cc_parent_map_3[] = {
93 { P_BI_TCXO, 0 },
94 { P_DISP_CC_PLL0_OUT_MAIN, 1 },
95 { P_GPLL0_OUT_MAIN, 4 },
96 };
97
98 static const struct clk_parent_data disp_cc_parent_data_3[] = {
99 { .fw_name = "bi_tcxo" },
100 { .hw = &disp_cc_pll0.clkr.hw },
101 { .fw_name = "gcc_disp_gpll0_div_clk_src" },
102 };
103
104 static const struct parent_map disp_cc_parent_map_4[] = {
105 { P_BI_TCXO, 0 },
106 { P_GPLL0_OUT_MAIN, 4 },
107 };
108
109 static const struct clk_parent_data disp_cc_parent_data_4[] = {
110 { .fw_name = "bi_tcxo" },
111 { .fw_name = "gcc_disp_gpll0_div_clk_src" },
112 };
113
114 static const struct parent_map disp_cc_parent_map_5[] = {
115 { P_BI_TCXO, 0 },
116 { P_DSI0_PHY_PLL_OUT_DSICLK, 1 },
117 { P_DSI1_PHY_PLL_OUT_DSICLK, 2 },
118 };
119
120 static const struct clk_parent_data disp_cc_parent_data_5[] = {
121 { .fw_name = "bi_tcxo" },
122 { .fw_name = "dsi0_phy_pll_out_dsiclk" },
123 { .fw_name = "dsi1_phy_pll_out_dsiclk" },
124 };
125
126 static const struct freq_tbl ftbl_disp_cc_mdss_ahb_clk_src[] = {
127 F(19200000, P_BI_TCXO, 1, 0, 0),
128 F(37500000, P_GPLL0_OUT_MAIN, 16, 0, 0),
129 F(75000000, P_GPLL0_OUT_MAIN, 8, 0, 0),
130 { }
131 };
132
133 static struct clk_rcg2 disp_cc_mdss_ahb_clk_src = {
134 .cmd_rcgr = 0x2154,
135 .mnd_width = 0,
136 .hid_width = 5,
137 .parent_map = disp_cc_parent_map_4,
138 .freq_tbl = ftbl_disp_cc_mdss_ahb_clk_src,
139 .clkr.hw.init = &(struct clk_init_data){
140 .name = "disp_cc_mdss_ahb_clk_src",
141 .parent_data = disp_cc_parent_data_4,
142 .num_parents = ARRAY_SIZE(disp_cc_parent_data_4),
143 .ops = &clk_rcg2_shared_ops,
144 },
145 };
146
147 static struct clk_rcg2 disp_cc_mdss_byte0_clk_src = {
148 .cmd_rcgr = 0x20bc,
149 .mnd_width = 0,
150 .hid_width = 5,
151 .parent_map = disp_cc_parent_map_2,
152 .clkr.hw.init = &(struct clk_init_data){
153 .name = "disp_cc_mdss_byte0_clk_src",
154 .parent_data = disp_cc_parent_data_2,
155 .num_parents = ARRAY_SIZE(disp_cc_parent_data_2),
156 .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE,
157 .ops = &clk_byte2_ops,
158 },
159 };
160
161 static const struct freq_tbl ftbl_disp_cc_mdss_dp_aux1_clk_src[] = {
162 F(19200000, P_BI_TCXO, 1, 0, 0),
163 { }
164 };
165
166 static struct clk_rcg2 disp_cc_mdss_dp_aux_clk_src = {
167 .cmd_rcgr = 0x213c,
168 .mnd_width = 0,
169 .hid_width = 5,
170 .parent_map = disp_cc_parent_map_0,
171 .freq_tbl = ftbl_disp_cc_mdss_dp_aux1_clk_src,
172 .clkr.hw.init = &(struct clk_init_data){
173 .name = "disp_cc_mdss_dp_aux_clk_src",
174 .parent_data = disp_cc_parent_data_0,
175 .num_parents = ARRAY_SIZE(disp_cc_parent_data_0),
176 .ops = &clk_rcg2_ops,
177 },
178 };
179
180 static const struct freq_tbl ftbl_disp_cc_mdss_dp_crypto_clk_src[] = {
181 F( 180000, P_DP_PHY_PLL_LINK_CLK, 1.5, 0, 0),
182 F( 360000, P_DP_PHY_PLL_LINK_CLK, 1.5, 0, 0),
183 { }
184 };
185
186 static struct clk_rcg2 disp_cc_mdss_dp_crypto_clk_src = {
187 .cmd_rcgr = 0x210c,
188 .mnd_width = 0,
189 .hid_width = 5,
190 .parent_map = disp_cc_parent_map_1,
191 .freq_tbl = ftbl_disp_cc_mdss_dp_crypto_clk_src,
192 .clkr.hw.init = &(struct clk_init_data){
193 .name = "disp_cc_mdss_dp_crypto_clk_src",
194 .parent_data = disp_cc_parent_data_1,
195 .num_parents = ARRAY_SIZE(disp_cc_parent_data_1),
196 .flags = CLK_GET_RATE_NOCACHE,
197 .ops = &clk_rcg2_ops,
198 },
199 };
200
201 static const struct freq_tbl ftbl_disp_cc_mdss_dp_link_clk_src[] = {
202 F( 162000, P_DP_PHY_PLL_LINK_CLK, 1, 0, 0),
203 F( 270000, P_DP_PHY_PLL_LINK_CLK, 1, 0, 0),
204 F( 540000, P_DP_PHY_PLL_LINK_CLK, 1, 0, 0),
205 { }
206 };
207
208 static struct clk_rcg2 disp_cc_mdss_dp_link_clk_src = {
209 .cmd_rcgr = 0x20f0,
210 .mnd_width = 0,
211 .hid_width = 5,
212 .parent_map = disp_cc_parent_map_1,
213 .freq_tbl = ftbl_disp_cc_mdss_dp_link_clk_src,
214 .clkr.hw.init = &(struct clk_init_data){
215 .name = "disp_cc_mdss_dp_link_clk_src",
216 .parent_data = disp_cc_parent_data_1,
217 .num_parents = ARRAY_SIZE(disp_cc_parent_data_1),
218 .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE,
219 .ops = &clk_rcg2_ops,
220 },
221 };
222
223 static struct clk_rcg2 disp_cc_mdss_dp_pixel_clk_src = {
224 .cmd_rcgr = 0x2124,
225 .mnd_width = 16,
226 .hid_width = 5,
227 .parent_map = disp_cc_parent_map_1,
228 .clkr.hw.init = &(struct clk_init_data){
229 .name = "disp_cc_mdss_dp_pixel_clk_src",
230 .parent_data = disp_cc_parent_data_1,
231 .num_parents = ARRAY_SIZE(disp_cc_parent_data_1),
232 .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE,
233 .ops = &clk_dp_ops,
234 },
235 };
236
237 static struct clk_rcg2 disp_cc_mdss_esc0_clk_src = {
238 .cmd_rcgr = 0x20d8,
239 .mnd_width = 0,
240 .hid_width = 5,
241 .parent_map = disp_cc_parent_map_2,
242 .freq_tbl = ftbl_disp_cc_mdss_dp_aux1_clk_src,
243 .clkr.hw.init = &(struct clk_init_data){
244 .name = "disp_cc_mdss_esc0_clk_src",
245 .parent_data = disp_cc_parent_data_2,
246 .num_parents = ARRAY_SIZE(disp_cc_parent_data_2),
247 .ops = &clk_rcg2_ops,
248 },
249 };
250
251 static const struct freq_tbl ftbl_disp_cc_mdss_mdp_clk_src[] = {
252 F(19200000, P_BI_TCXO, 1, 0, 0),
253 F(192000000, P_DISP_CC_PLL0_OUT_MAIN, 4, 0, 0),
254 F(256000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0),
255 F(307200000, P_DISP_CC_PLL0_OUT_MAIN, 2.5, 0, 0),
256 F(384000000, P_DISP_CC_PLL0_OUT_MAIN, 2, 0, 0),
257 F(400000000, P_GPLL0_OUT_MAIN, 1.5, 0, 0),
258 { }
259 };
260
261 static struct clk_rcg2 disp_cc_mdss_mdp_clk_src = {
262 .cmd_rcgr = 0x2074,
263 .mnd_width = 0,
264 .hid_width = 5,
265 .parent_map = disp_cc_parent_map_3,
266 .freq_tbl = ftbl_disp_cc_mdss_mdp_clk_src,
267 .clkr.hw.init = &(struct clk_init_data){
268 .name = "disp_cc_mdss_mdp_clk_src",
269 .parent_data = disp_cc_parent_data_3,
270 .num_parents = ARRAY_SIZE(disp_cc_parent_data_3),
271 .ops = &clk_rcg2_shared_ops,
272 },
273 };
274
275 static struct clk_rcg2 disp_cc_mdss_pclk0_clk_src = {
276 .cmd_rcgr = 0x205c,
277 .mnd_width = 8,
278 .hid_width = 5,
279 .parent_map = disp_cc_parent_map_5,
280 .clkr.hw.init = &(struct clk_init_data){
281 .name = "disp_cc_mdss_pclk0_clk_src",
282 .parent_data = disp_cc_parent_data_5,
283 .num_parents = ARRAY_SIZE(disp_cc_parent_data_5),
284 .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE,
285 .ops = &clk_pixel_ops,
286 },
287 };
288
289 static const struct freq_tbl ftbl_disp_cc_mdss_rot_clk_src[] = {
290 F(19200000, P_BI_TCXO, 1, 0, 0),
291 F(192000000, P_DISP_CC_PLL0_OUT_MAIN, 4, 0, 0),
292 F(256000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0),
293 F(307200000, P_DISP_CC_PLL0_OUT_MAIN, 2.5, 0, 0),
294 { }
295 };
296
297 static struct clk_rcg2 disp_cc_mdss_rot_clk_src = {
298 .cmd_rcgr = 0x208c,
299 .mnd_width = 0,
300 .hid_width = 5,
301 .parent_map = disp_cc_parent_map_3,
302 .freq_tbl = ftbl_disp_cc_mdss_rot_clk_src,
303 .clkr.hw.init = &(struct clk_init_data){
304 .name = "disp_cc_mdss_rot_clk_src",
305 .parent_data = disp_cc_parent_data_3,
306 .num_parents = ARRAY_SIZE(disp_cc_parent_data_3),
307 .flags = CLK_SET_RATE_PARENT,
308 .ops = &clk_rcg2_shared_ops,
309 },
310 };
311
312 static struct clk_rcg2 disp_cc_mdss_vsync_clk_src = {
313 .cmd_rcgr = 0x20a4,
314 .mnd_width = 0,
315 .hid_width = 5,
316 .parent_map = disp_cc_parent_map_0,
317 .freq_tbl = ftbl_disp_cc_mdss_dp_aux1_clk_src,
318 .clkr.hw.init = &(struct clk_init_data){
319 .name = "disp_cc_mdss_vsync_clk_src",
320 .parent_data = disp_cc_parent_data_0,
321 .num_parents = ARRAY_SIZE(disp_cc_parent_data_0),
322 .ops = &clk_rcg2_ops,
323 },
324 };
325
326 static struct clk_branch disp_cc_mdss_ahb_clk = {
327 .halt_reg = 0x2044,
328 .halt_check = BRANCH_HALT,
329 .clkr = {
330 .enable_reg = 0x2044,
331 .enable_mask = BIT(0),
332 .hw.init = &(struct clk_init_data){
333 .name = "disp_cc_mdss_ahb_clk",
334 .parent_hws = (const struct clk_hw*[]){
335 &disp_cc_mdss_ahb_clk_src.clkr.hw,
336 },
337 .num_parents = 1,
338 .flags = CLK_SET_RATE_PARENT,
339 .ops = &clk_branch2_ops,
340 },
341 },
342 };
343
344 static struct clk_branch disp_cc_mdss_byte0_clk = {
345 .halt_reg = 0x2024,
346 .halt_check = BRANCH_HALT,
347 .clkr = {
348 .enable_reg = 0x2024,
349 .enable_mask = BIT(0),
350 .hw.init = &(struct clk_init_data){
351 .name = "disp_cc_mdss_byte0_clk",
352 .parent_hws = (const struct clk_hw*[]){
353 &disp_cc_mdss_byte0_clk_src.clkr.hw,
354 },
355 .num_parents = 1,
356 .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE,
357 .ops = &clk_branch2_ops,
358 },
359 },
360 };
361
362 static struct clk_branch disp_cc_mdss_byte0_intf_clk = {
363 .halt_reg = 0x2028,
364 .halt_check = BRANCH_HALT,
365 .clkr = {
366 .enable_reg = 0x2028,
367 .enable_mask = BIT(0),
368 .hw.init = &(struct clk_init_data){
369 .name = "disp_cc_mdss_byte0_intf_clk",
370 .parent_hws = (const struct clk_hw*[]){
371 &disp_cc_mdss_byte0_clk_src.clkr.hw,
372 },
373 .num_parents = 1,
374 .flags = CLK_GET_RATE_NOCACHE,
375 .ops = &clk_branch2_ops,
376 },
377 },
378 };
379
380 static struct clk_branch disp_cc_mdss_dp_aux_clk = {
381 .halt_reg = 0x2040,
382 .halt_check = BRANCH_HALT,
383 .clkr = {
384 .enable_reg = 0x2040,
385 .enable_mask = BIT(0),
386 .hw.init = &(struct clk_init_data){
387 .name = "disp_cc_mdss_dp_aux_clk",
388 .parent_hws = (const struct clk_hw*[]){
389 &disp_cc_mdss_dp_aux_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_dp_crypto_clk = {
399 .halt_reg = 0x2038,
400 .halt_check = BRANCH_HALT,
401 .clkr = {
402 .enable_reg = 0x2038,
403 .enable_mask = BIT(0),
404 .hw.init = &(struct clk_init_data){
405 .name = "disp_cc_mdss_dp_crypto_clk",
406 .parent_hws = (const struct clk_hw*[]){
407 &disp_cc_mdss_dp_crypto_clk_src.clkr.hw,
408 },
409 .num_parents = 1,
410 .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE,
411 .ops = &clk_branch2_ops,
412 },
413 },
414 };
415
416 static struct clk_branch disp_cc_mdss_dp_link_clk = {
417 .halt_reg = 0x2030,
418 .halt_check = BRANCH_HALT,
419 .clkr = {
420 .enable_reg = 0x2030,
421 .enable_mask = BIT(0),
422 .hw.init = &(struct clk_init_data){
423 .name = "disp_cc_mdss_dp_link_clk",
424 .parent_hws = (const struct clk_hw*[]){
425 &disp_cc_mdss_dp_link_clk_src.clkr.hw,
426 },
427 .num_parents = 1,
428 .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE,
429 .ops = &clk_branch2_ops,
430 },
431 },
432 };
433
434 static struct clk_branch disp_cc_mdss_dp_link_intf_clk = {
435 .halt_reg = 0x2034,
436 .halt_check = BRANCH_HALT,
437 .clkr = {
438 .enable_reg = 0x2034,
439 .enable_mask = BIT(0),
440 .hw.init = &(struct clk_init_data){
441 .name = "disp_cc_mdss_dp_link_intf_clk",
442 .parent_hws = (const struct clk_hw*[]){
443 &disp_cc_mdss_dp_link_clk_src.clkr.hw,
444 },
445 .num_parents = 1,
446 .flags = CLK_GET_RATE_NOCACHE,
447 .ops = &clk_branch2_ops,
448 },
449 },
450 };
451
452 static struct clk_branch disp_cc_mdss_dp_pixel_clk = {
453 .halt_reg = 0x203c,
454 .halt_check = BRANCH_HALT,
455 .clkr = {
456 .enable_reg = 0x203c,
457 .enable_mask = BIT(0),
458 .hw.init = &(struct clk_init_data){
459 .name = "disp_cc_mdss_dp_pixel_clk",
460 .parent_hws = (const struct clk_hw*[]){
461 &disp_cc_mdss_dp_pixel_clk_src.clkr.hw,
462 },
463 .num_parents = 1,
464 .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE,
465 .ops = &clk_branch2_ops,
466 },
467 },
468 };
469
470 static struct clk_branch disp_cc_mdss_esc0_clk = {
471 .halt_reg = 0x202c,
472 .halt_check = BRANCH_HALT,
473 .clkr = {
474 .enable_reg = 0x202c,
475 .enable_mask = BIT(0),
476 .hw.init = &(struct clk_init_data){
477 .name = "disp_cc_mdss_esc0_clk",
478 .parent_hws = (const struct clk_hw*[]){
479 &disp_cc_mdss_esc0_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_clk = {
489 .halt_reg = 0x2008,
490 .halt_check = BRANCH_HALT,
491 .clkr = {
492 .enable_reg = 0x2008,
493 .enable_mask = BIT(0),
494 .hw.init = &(struct clk_init_data){
495 .name = "disp_cc_mdss_mdp_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_mdp_lut_clk = {
507 .halt_reg = 0x2018,
508 .halt_check = BRANCH_VOTED,
509 .clkr = {
510 .enable_reg = 0x2018,
511 .enable_mask = BIT(0),
512 .hw.init = &(struct clk_init_data){
513 .name = "disp_cc_mdss_mdp_lut_clk",
514 .parent_hws = (const struct clk_hw*[]){
515 &disp_cc_mdss_mdp_clk_src.clkr.hw,
516 },
517 .num_parents = 1,
518 .ops = &clk_branch2_ops,
519 },
520 },
521 };
522
523 static struct clk_branch disp_cc_mdss_non_gdsc_ahb_clk = {
524 .halt_reg = 0x4004,
525 .halt_check = BRANCH_VOTED,
526 .clkr = {
527 .enable_reg = 0x4004,
528 .enable_mask = BIT(0),
529 .hw.init = &(struct clk_init_data){
530 .name = "disp_cc_mdss_non_gdsc_ahb_clk",
531 .parent_hws = (const struct clk_hw*[]){
532 &disp_cc_mdss_ahb_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_pclk0_clk = {
542 .halt_reg = 0x2004,
543 .halt_check = BRANCH_HALT,
544 .clkr = {
545 .enable_reg = 0x2004,
546 .enable_mask = BIT(0),
547 .hw.init = &(struct clk_init_data){
548 .name = "disp_cc_mdss_pclk0_clk",
549 .parent_hws = (const struct clk_hw*[]){
550 &disp_cc_mdss_pclk0_clk_src.clkr.hw,
551 },
552 .num_parents = 1,
553 .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE,
554 .ops = &clk_branch2_ops,
555 },
556 },
557 };
558
559 static struct clk_branch disp_cc_mdss_rot_clk = {
560 .halt_reg = 0x2010,
561 .halt_check = BRANCH_HALT,
562 .clkr = {
563 .enable_reg = 0x2010,
564 .enable_mask = BIT(0),
565 .hw.init = &(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_vsync_clk = {
578 .halt_reg = 0x2020,
579 .halt_check = BRANCH_HALT,
580 .clkr = {
581 .enable_reg = 0x2020,
582 .enable_mask = BIT(0),
583 .hw.init = &(struct clk_init_data){
584 .name = "disp_cc_mdss_vsync_clk",
585 .parent_hws = (const struct clk_hw*[]){
586 &disp_cc_mdss_vsync_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_xo_clk = {
596 .halt_reg = 0x604c,
597 .halt_check = BRANCH_HALT,
598 .clkr = {
599 .enable_reg = 0x604c,
600 .enable_mask = BIT(0),
601 .hw.init = &(struct clk_init_data){
602 .name = "disp_cc_xo_clk",
603 .flags = CLK_IS_CRITICAL,
604 .ops = &clk_branch2_ops,
605 },
606 },
607 };
608
609 static struct gdsc mdss_gdsc = {
610 .gdscr = 0x3000,
611 .pd = {
612 .name = "mdss_gdsc",
613 },
614 .pwrsts = PWRSTS_OFF_ON,
615 .flags = HW_CTRL,
616 };
617
618 static struct clk_regmap *disp_cc_sm6125_clocks[] = {
619 [DISP_CC_MDSS_AHB_CLK] = &disp_cc_mdss_ahb_clk.clkr,
620 [DISP_CC_MDSS_AHB_CLK_SRC] = &disp_cc_mdss_ahb_clk_src.clkr,
621 [DISP_CC_MDSS_BYTE0_CLK] = &disp_cc_mdss_byte0_clk.clkr,
622 [DISP_CC_MDSS_BYTE0_CLK_SRC] = &disp_cc_mdss_byte0_clk_src.clkr,
623 [DISP_CC_MDSS_BYTE0_INTF_CLK] = &disp_cc_mdss_byte0_intf_clk.clkr,
624 [DISP_CC_MDSS_DP_AUX_CLK] = &disp_cc_mdss_dp_aux_clk.clkr,
625 [DISP_CC_MDSS_DP_AUX_CLK_SRC] = &disp_cc_mdss_dp_aux_clk_src.clkr,
626 [DISP_CC_MDSS_DP_CRYPTO_CLK] = &disp_cc_mdss_dp_crypto_clk.clkr,
627 [DISP_CC_MDSS_DP_CRYPTO_CLK_SRC] = &disp_cc_mdss_dp_crypto_clk_src.clkr,
628 [DISP_CC_MDSS_DP_LINK_CLK] = &disp_cc_mdss_dp_link_clk.clkr,
629 [DISP_CC_MDSS_DP_LINK_CLK_SRC] = &disp_cc_mdss_dp_link_clk_src.clkr,
630 [DISP_CC_MDSS_DP_LINK_INTF_CLK] = &disp_cc_mdss_dp_link_intf_clk.clkr,
631 [DISP_CC_MDSS_DP_PIXEL_CLK] = &disp_cc_mdss_dp_pixel_clk.clkr,
632 [DISP_CC_MDSS_DP_PIXEL_CLK_SRC] = &disp_cc_mdss_dp_pixel_clk_src.clkr,
633 [DISP_CC_MDSS_ESC0_CLK] = &disp_cc_mdss_esc0_clk.clkr,
634 [DISP_CC_MDSS_ESC0_CLK_SRC] = &disp_cc_mdss_esc0_clk_src.clkr,
635 [DISP_CC_MDSS_MDP_CLK] = &disp_cc_mdss_mdp_clk.clkr,
636 [DISP_CC_MDSS_MDP_CLK_SRC] = &disp_cc_mdss_mdp_clk_src.clkr,
637 [DISP_CC_MDSS_MDP_LUT_CLK] = &disp_cc_mdss_mdp_lut_clk.clkr,
638 [DISP_CC_MDSS_NON_GDSC_AHB_CLK] = &disp_cc_mdss_non_gdsc_ahb_clk.clkr,
639 [DISP_CC_MDSS_PCLK0_CLK] = &disp_cc_mdss_pclk0_clk.clkr,
640 [DISP_CC_MDSS_PCLK0_CLK_SRC] = &disp_cc_mdss_pclk0_clk_src.clkr,
641 [DISP_CC_MDSS_ROT_CLK] = &disp_cc_mdss_rot_clk.clkr,
642 [DISP_CC_MDSS_ROT_CLK_SRC] = &disp_cc_mdss_rot_clk_src.clkr,
643 [DISP_CC_MDSS_VSYNC_CLK] = &disp_cc_mdss_vsync_clk.clkr,
644 [DISP_CC_MDSS_VSYNC_CLK_SRC] = &disp_cc_mdss_vsync_clk_src.clkr,
645 [DISP_CC_PLL0] = &disp_cc_pll0.clkr,
646 [DISP_CC_XO_CLK] = &disp_cc_xo_clk.clkr,
647 };
648
649 static struct gdsc *disp_cc_sm6125_gdscs[] = {
650 [MDSS_GDSC] = &mdss_gdsc,
651 };
652
653 static const struct regmap_config disp_cc_sm6125_regmap_config = {
654 .reg_bits = 32,
655 .reg_stride = 4,
656 .val_bits = 32,
657 .max_register = 0x10000,
658 .fast_io = true,
659 };
660
661 static const struct qcom_cc_desc disp_cc_sm6125_desc = {
662 .config = &disp_cc_sm6125_regmap_config,
663 .clks = disp_cc_sm6125_clocks,
664 .num_clks = ARRAY_SIZE(disp_cc_sm6125_clocks),
665 .gdscs = disp_cc_sm6125_gdscs,
666 .num_gdscs = ARRAY_SIZE(disp_cc_sm6125_gdscs),
667 };
668
669 static const struct of_device_id disp_cc_sm6125_match_table[] = {
670 { .compatible = "qcom,sm6125-dispcc" },
671 { }
672 };
673 MODULE_DEVICE_TABLE(of, disp_cc_sm6125_match_table);
674
disp_cc_sm6125_probe(struct platform_device * pdev)675 static int disp_cc_sm6125_probe(struct platform_device *pdev)
676 {
677 struct regmap *regmap;
678
679 regmap = qcom_cc_map(pdev, &disp_cc_sm6125_desc);
680 if (IS_ERR(regmap))
681 return PTR_ERR(regmap);
682
683 clk_alpha_pll_configure(&disp_cc_pll0, regmap, &disp_cc_pll0_config);
684
685 return qcom_cc_really_probe(pdev, &disp_cc_sm6125_desc, regmap);
686 }
687
688 static struct platform_driver disp_cc_sm6125_driver = {
689 .probe = disp_cc_sm6125_probe,
690 .driver = {
691 .name = "disp_cc-sm6125",
692 .of_match_table = disp_cc_sm6125_match_table,
693 },
694 };
695
disp_cc_sm6125_init(void)696 static int __init disp_cc_sm6125_init(void)
697 {
698 return platform_driver_register(&disp_cc_sm6125_driver);
699 }
700 subsys_initcall(disp_cc_sm6125_init);
701
disp_cc_sm6125_exit(void)702 static void __exit disp_cc_sm6125_exit(void)
703 {
704 platform_driver_unregister(&disp_cc_sm6125_driver);
705 }
706 module_exit(disp_cc_sm6125_exit);
707
708 MODULE_DESCRIPTION("QTI DISPCC SM6125 Driver");
709 MODULE_LICENSE("GPL v2");
710