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

source code of linux/drivers/clk/qcom/dispcc-sm6350.c