1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (c) 2018, The Linux Foundation. All rights reserved.
4 * Copyright (c) 2024, Danila Tikhonov <danila@jiaxyga.com>
5 * Copyright (c) 2024, David Wronek <david@mainlining.org>
8 #include <linux/clk-provider.h>
9 #include <linux/mod_devicetable.h>
10 #include <linux/module.h>
12 #include <linux/platform_device.h>
13 #include <linux/regmap.h>
15 #include <dt-bindings/clock/qcom,sm7150-dispcc.h>
17 #include "clk-alpha-pll.h"
18 #include "clk-branch.h"
20 #include "clk-regmap.h"
21 #include "clk-regmap-divider.h"
28 DT_GCC_DISP_GPLL0_CLK
,
30 DT_DSI0_PHY_PLL_OUT_BYTECLK
,
31 DT_DSI0_PHY_PLL_OUT_DSICLK
,
32 DT_DSI1_PHY_PLL_OUT_BYTECLK
,
33 DT_DSI1_PHY_PLL_OUT_DSICLK
,
34 DT_DP_PHY_PLL_LINK_CLK
,
35 DT_DP_PHY_PLL_VCO_DIV_CLK
,
41 P_DISPCC_PLL0_OUT_EVEN
,
42 P_DISPCC_PLL0_OUT_MAIN
,
43 P_DP_PHY_PLL_LINK_CLK
,
44 P_DP_PHY_PLL_VCO_DIV_CLK
,
45 P_DSI0_PHY_PLL_OUT_BYTECLK
,
46 P_DSI0_PHY_PLL_OUT_DSICLK
,
47 P_DSI1_PHY_PLL_OUT_BYTECLK
,
48 P_DSI1_PHY_PLL_OUT_DSICLK
,
52 static const struct pll_vco fabia_vco
[] = {
53 { 249600000, 2000000000, 0 },
54 { 125000000, 1000000000, 1 },
57 /* 860MHz configuration */
58 static const struct alpha_pll_config dispcc_pll0_config
= {
61 .test_ctl_val
= 0x40000000,
64 static struct clk_alpha_pll dispcc_pll0
= {
66 .vco_table
= fabia_vco
,
67 .num_vco
= ARRAY_SIZE(fabia_vco
),
68 .regs
= clk_alpha_pll_regs
[CLK_ALPHA_PLL_TYPE_FABIA
],
70 .hw
.init
= &(const struct clk_init_data
) {
71 .name
= "dispcc_pll0",
72 .parent_data
= &(const struct clk_parent_data
) {
76 .ops
= &clk_alpha_pll_fabia_ops
,
81 static const struct parent_map dispcc_parent_map_0
[] = {
83 { P_DSI0_PHY_PLL_OUT_BYTECLK
, 1 },
84 { P_DSI1_PHY_PLL_OUT_BYTECLK
, 2 },
87 static const struct clk_parent_data dispcc_parent_data_0
[] = {
88 { .index
= DT_BI_TCXO
},
89 { .index
= DT_DSI0_PHY_PLL_OUT_BYTECLK
},
90 { .index
= DT_DSI1_PHY_PLL_OUT_BYTECLK
},
93 static const struct parent_map dispcc_parent_map_1
[] = {
95 { P_DP_PHY_PLL_LINK_CLK
, 1 },
96 { P_DP_PHY_PLL_VCO_DIV_CLK
, 2 },
99 static const struct clk_parent_data dispcc_parent_data_1
[] = {
100 { .index
= DT_BI_TCXO
},
101 { .index
= DT_DP_PHY_PLL_LINK_CLK
},
102 { .index
= DT_DP_PHY_PLL_VCO_DIV_CLK
},
105 static const struct parent_map dispcc_parent_map_2
[] = {
109 static const struct clk_parent_data dispcc_parent_data_2
[] = {
110 { .index
= DT_BI_TCXO
},
113 static const struct clk_parent_data dispcc_parent_data_2_ao
[] = {
114 { .index
= DT_BI_TCXO_AO
},
117 static const struct parent_map dispcc_parent_map_3
[] = {
119 { P_DISPCC_PLL0_OUT_MAIN
, 1 },
120 { P_GCC_DISP_GPLL0_CLK
, 4 },
121 { P_DISPCC_PLL0_OUT_EVEN
, 5 },
124 static const struct clk_parent_data dispcc_parent_data_3
[] = {
125 { .index
= DT_BI_TCXO
},
126 { .hw
= &dispcc_pll0
.clkr
.hw
},
127 { .index
= DT_GCC_DISP_GPLL0_CLK
},
128 { .hw
= &dispcc_pll0
.clkr
.hw
},
131 static const struct parent_map dispcc_parent_map_4
[] = {
133 { P_DSI0_PHY_PLL_OUT_DSICLK
, 1 },
134 { P_DSI1_PHY_PLL_OUT_DSICLK
, 2 },
137 static const struct clk_parent_data dispcc_parent_data_4
[] = {
138 { .index
= DT_BI_TCXO
},
139 { .index
= DT_DSI0_PHY_PLL_OUT_DSICLK
},
140 { .index
= DT_DSI1_PHY_PLL_OUT_DSICLK
},
143 static const struct parent_map dispcc_parent_map_5
[] = {
145 { P_GCC_DISP_GPLL0_CLK
, 4 },
148 static const struct clk_parent_data dispcc_parent_data_5
[] = {
149 { .index
= DT_BI_TCXO
},
150 { .index
= DT_GCC_DISP_GPLL0_CLK
},
153 static const struct parent_map dispcc_parent_map_6
[] = {
154 { P_CHIP_SLEEP_CLK
, 0 },
157 static const struct clk_parent_data dispcc_parent_data_6
[] = {
158 { .index
= DT_CHIP_SLEEP_CLK
},
161 static const struct freq_tbl ftbl_dispcc_mdss_ahb_clk_src
[] = {
162 F(19200000, P_BI_TCXO
, 1, 0, 0),
163 F(37500000, P_GCC_DISP_GPLL0_CLK
, 16, 0, 0),
164 F(75000000, P_GCC_DISP_GPLL0_CLK
, 8, 0, 0),
168 static struct clk_rcg2 dispcc_mdss_ahb_clk_src
= {
172 .parent_map
= dispcc_parent_map_5
,
173 .freq_tbl
= ftbl_dispcc_mdss_ahb_clk_src
,
174 .clkr
.hw
.init
= &(const struct clk_init_data
) {
175 .name
= "dispcc_mdss_ahb_clk_src",
176 .parent_data
= dispcc_parent_data_5
,
177 .num_parents
= ARRAY_SIZE(dispcc_parent_data_5
),
178 .flags
= CLK_SET_RATE_PARENT
,
179 .ops
= &clk_rcg2_shared_ops
,
183 static const struct freq_tbl ftbl_dispcc_mdss_byte0_clk_src
[] = {
184 F(19200000, P_BI_TCXO
, 1, 0, 0),
188 static struct clk_rcg2 dispcc_mdss_byte0_clk_src
= {
192 .parent_map
= dispcc_parent_map_0
,
193 .clkr
.hw
.init
= &(const struct clk_init_data
) {
194 .name
= "dispcc_mdss_byte0_clk_src",
195 .parent_data
= dispcc_parent_data_0
,
196 .num_parents
= ARRAY_SIZE(dispcc_parent_data_0
),
197 .flags
= CLK_SET_RATE_PARENT
,
198 .ops
= &clk_byte2_ops
,
202 static struct clk_rcg2 dispcc_mdss_byte1_clk_src
= {
206 .parent_map
= dispcc_parent_map_0
,
207 .clkr
.hw
.init
= &(const struct clk_init_data
) {
208 .name
= "dispcc_mdss_byte1_clk_src",
209 .parent_data
= dispcc_parent_data_0
,
210 .num_parents
= ARRAY_SIZE(dispcc_parent_data_0
),
211 .flags
= CLK_SET_RATE_PARENT
,
212 .ops
= &clk_byte2_ops
,
216 static struct clk_rcg2 dispcc_mdss_dp_aux_clk_src
= {
220 .parent_map
= dispcc_parent_map_2
,
221 .freq_tbl
= ftbl_dispcc_mdss_byte0_clk_src
,
222 .clkr
.hw
.init
= &(const struct clk_init_data
) {
223 .name
= "dispcc_mdss_dp_aux_clk_src",
224 .parent_data
= dispcc_parent_data_2
,
225 .num_parents
= ARRAY_SIZE(dispcc_parent_data_2
),
226 .ops
= &clk_rcg2_ops
,
230 static const struct freq_tbl ftbl_dispcc_mdss_dp_crypto_clk_src
[] = {
231 F(108000, P_DP_PHY_PLL_LINK_CLK
, 3, 0, 0),
232 F(180000, P_DP_PHY_PLL_LINK_CLK
, 3, 0, 0),
233 F(360000, P_DP_PHY_PLL_LINK_CLK
, 1.5, 0, 0),
234 F(540000, P_DP_PHY_PLL_LINK_CLK
, 1.5, 0, 0),
238 static struct clk_rcg2 dispcc_mdss_dp_crypto_clk_src
= {
242 .parent_map
= dispcc_parent_map_1
,
243 .freq_tbl
= ftbl_dispcc_mdss_dp_crypto_clk_src
,
244 .clkr
.hw
.init
= &(const struct clk_init_data
) {
245 .name
= "dispcc_mdss_dp_crypto_clk_src",
246 .parent_data
= dispcc_parent_data_1
,
247 .num_parents
= ARRAY_SIZE(dispcc_parent_data_1
),
248 .ops
= &clk_rcg2_ops
,
252 static struct clk_rcg2 dispcc_mdss_dp_link_clk_src
= {
256 .parent_map
= dispcc_parent_map_1
,
257 .clkr
.hw
.init
= &(const struct clk_init_data
) {
258 .name
= "dispcc_mdss_dp_link_clk_src",
259 .parent_data
= dispcc_parent_data_1
,
260 .num_parents
= ARRAY_SIZE(dispcc_parent_data_1
),
261 .flags
= CLK_SET_RATE_PARENT
,
262 .ops
= &clk_byte2_ops
,
266 static struct clk_rcg2 dispcc_mdss_dp_pixel1_clk_src
= {
270 .parent_map
= dispcc_parent_map_1
,
271 .clkr
.hw
.init
= &(const struct clk_init_data
) {
272 .name
= "dispcc_mdss_dp_pixel1_clk_src",
273 .parent_data
= dispcc_parent_data_1
,
274 .num_parents
= ARRAY_SIZE(dispcc_parent_data_1
),
275 .flags
= CLK_SET_RATE_PARENT
,
280 static struct clk_rcg2 dispcc_mdss_dp_pixel_clk_src
= {
284 .parent_map
= dispcc_parent_map_1
,
285 .clkr
.hw
.init
= &(const struct clk_init_data
) {
286 .name
= "dispcc_mdss_dp_pixel_clk_src",
287 .parent_data
= dispcc_parent_data_1
,
288 .num_parents
= ARRAY_SIZE(dispcc_parent_data_1
),
289 .flags
= CLK_SET_RATE_PARENT
,
294 static struct clk_rcg2 dispcc_mdss_esc0_clk_src
= {
298 .parent_map
= dispcc_parent_map_0
,
299 .freq_tbl
= ftbl_dispcc_mdss_byte0_clk_src
,
300 .clkr
.hw
.init
= &(const struct clk_init_data
) {
301 .name
= "dispcc_mdss_esc0_clk_src",
302 .parent_data
= dispcc_parent_data_0
,
303 .num_parents
= ARRAY_SIZE(dispcc_parent_data_0
),
304 .ops
= &clk_rcg2_ops
,
308 static struct clk_rcg2 dispcc_mdss_esc1_clk_src
= {
312 .parent_map
= dispcc_parent_map_0
,
313 .freq_tbl
= ftbl_dispcc_mdss_byte0_clk_src
,
314 .clkr
.hw
.init
= &(const struct clk_init_data
) {
315 .name
= "dispcc_mdss_esc1_clk_src",
316 .parent_data
= dispcc_parent_data_0
,
317 .num_parents
= ARRAY_SIZE(dispcc_parent_data_0
),
318 .ops
= &clk_rcg2_ops
,
322 static const struct freq_tbl ftbl_dispcc_mdss_mdp_clk_src
[] = {
323 F(19200000, P_BI_TCXO
, 1, 0, 0),
324 F(85714286, P_GCC_DISP_GPLL0_CLK
, 7, 0, 0),
325 F(100000000, P_GCC_DISP_GPLL0_CLK
, 6, 0, 0),
326 F(150000000, P_GCC_DISP_GPLL0_CLK
, 4, 0, 0),
327 F(172000000, P_DISPCC_PLL0_OUT_MAIN
, 5, 0, 0),
328 F(200000000, P_GCC_DISP_GPLL0_CLK
, 3, 0, 0),
329 F(286666667, P_DISPCC_PLL0_OUT_MAIN
, 3, 0, 0),
330 F(300000000, P_GCC_DISP_GPLL0_CLK
, 2, 0, 0),
331 F(344000000, P_DISPCC_PLL0_OUT_MAIN
, 2.5, 0, 0),
332 F(430000000, P_DISPCC_PLL0_OUT_MAIN
, 2, 0, 0),
336 static struct clk_rcg2 dispcc_mdss_mdp_clk_src
= {
340 .parent_map
= dispcc_parent_map_3
,
341 .freq_tbl
= ftbl_dispcc_mdss_mdp_clk_src
,
342 .clkr
.hw
.init
= &(const struct clk_init_data
) {
343 .name
= "dispcc_mdss_mdp_clk_src",
344 .parent_data
= dispcc_parent_data_3
,
345 .num_parents
= ARRAY_SIZE(dispcc_parent_data_3
),
346 .flags
= CLK_SET_RATE_PARENT
,
347 .ops
= &clk_rcg2_shared_ops
,
351 static struct clk_rcg2 dispcc_mdss_pclk0_clk_src
= {
355 .parent_map
= dispcc_parent_map_4
,
356 .clkr
.hw
.init
= &(const struct clk_init_data
) {
357 .name
= "dispcc_mdss_pclk0_clk_src",
358 .parent_data
= dispcc_parent_data_4
,
359 .num_parents
= ARRAY_SIZE(dispcc_parent_data_4
),
360 .flags
= CLK_SET_RATE_PARENT
,
361 .ops
= &clk_pixel_ops
,
365 static struct clk_rcg2 dispcc_mdss_pclk1_clk_src
= {
369 .parent_map
= dispcc_parent_map_4
,
370 .clkr
.hw
.init
= &(const struct clk_init_data
) {
371 .name
= "dispcc_mdss_pclk1_clk_src",
372 .parent_data
= dispcc_parent_data_4
,
373 .num_parents
= ARRAY_SIZE(dispcc_parent_data_4
),
374 .flags
= CLK_SET_RATE_PARENT
,
375 .ops
= &clk_pixel_ops
,
379 static const struct freq_tbl ftbl_dispcc_mdss_rot_clk_src
[] = {
380 F(19200000, P_BI_TCXO
, 1, 0, 0),
381 F(171428571, P_GCC_DISP_GPLL0_CLK
, 3.5, 0, 0),
382 F(200000000, P_GCC_DISP_GPLL0_CLK
, 3, 0, 0),
383 F(300000000, P_GCC_DISP_GPLL0_CLK
, 2, 0, 0),
384 F(344000000, P_DISPCC_PLL0_OUT_MAIN
, 2.5, 0, 0),
385 F(430000000, P_DISPCC_PLL0_OUT_MAIN
, 2, 0, 0),
389 static struct clk_rcg2 dispcc_mdss_rot_clk_src
= {
393 .parent_map
= dispcc_parent_map_3
,
394 .freq_tbl
= ftbl_dispcc_mdss_rot_clk_src
,
395 .clkr
.hw
.init
= &(const struct clk_init_data
) {
396 .name
= "dispcc_mdss_rot_clk_src",
397 .parent_data
= dispcc_parent_data_3
,
398 .num_parents
= ARRAY_SIZE(dispcc_parent_data_3
),
399 .ops
= &clk_rcg2_shared_ops
,
403 static struct clk_rcg2 dispcc_mdss_vsync_clk_src
= {
407 .parent_map
= dispcc_parent_map_2
,
408 .freq_tbl
= ftbl_dispcc_mdss_byte0_clk_src
,
409 .clkr
.hw
.init
= &(const struct clk_init_data
) {
410 .name
= "dispcc_mdss_vsync_clk_src",
411 .parent_data
= dispcc_parent_data_2
,
412 .num_parents
= ARRAY_SIZE(dispcc_parent_data_2
),
413 .ops
= &clk_rcg2_ops
,
417 static const struct freq_tbl ftbl_dispcc_sleep_clk_src
[] = {
418 F(32000, P_CHIP_SLEEP_CLK
, 1, 0, 0),
422 static struct clk_rcg2 dispcc_sleep_clk_src
= {
426 .parent_map
= dispcc_parent_map_6
,
427 .freq_tbl
= ftbl_dispcc_sleep_clk_src
,
428 .clkr
.hw
.init
= &(const struct clk_init_data
) {
429 .name
= "dispcc_sleep_clk_src",
430 .parent_data
= dispcc_parent_data_6
,
431 .num_parents
= ARRAY_SIZE(dispcc_parent_data_6
),
432 .ops
= &clk_rcg2_ops
,
436 static struct clk_rcg2 dispcc_xo_clk_src
= {
440 .parent_map
= dispcc_parent_map_2
,
441 .freq_tbl
= ftbl_dispcc_mdss_byte0_clk_src
,
442 .clkr
.hw
.init
= &(const struct clk_init_data
) {
443 .name
= "dispcc_xo_clk_src",
444 .parent_data
= dispcc_parent_data_2_ao
,
445 .num_parents
= ARRAY_SIZE(dispcc_parent_data_2_ao
),
446 .ops
= &clk_rcg2_ops
,
450 static struct clk_branch dispcc_mdss_ahb_clk
= {
452 .halt_check
= BRANCH_HALT
,
454 .enable_reg
= 0x2080,
455 .enable_mask
= BIT(0),
456 .hw
.init
= &(const struct clk_init_data
) {
457 .name
= "dispcc_mdss_ahb_clk",
458 .parent_hws
= (const struct clk_hw
*[]) {
459 &dispcc_mdss_ahb_clk_src
.clkr
.hw
,
462 .flags
= CLK_SET_RATE_PARENT
,
463 .ops
= &clk_branch2_ops
,
468 static struct clk_branch dispcc_mdss_byte0_clk
= {
470 .halt_check
= BRANCH_HALT
,
472 .enable_reg
= 0x2028,
473 .enable_mask
= BIT(0),
474 .hw
.init
= &(const struct clk_init_data
) {
475 .name
= "dispcc_mdss_byte0_clk",
476 .parent_hws
= (const struct clk_hw
*[]) {
477 &dispcc_mdss_byte0_clk_src
.clkr
.hw
,
480 .flags
= CLK_SET_RATE_PARENT
,
481 .ops
= &clk_branch2_ops
,
486 static struct clk_regmap_div dispcc_mdss_byte0_div_clk_src
= {
491 .hw
.init
= &(const struct clk_init_data
) {
492 .name
= "dispcc_mdss_byte0_div_clk_src",
493 .parent_hws
= (const struct clk_hw
*[]) {
494 &dispcc_mdss_byte0_clk_src
.clkr
.hw
,
497 .ops
= &clk_regmap_div_ops
,
502 static struct clk_branch dispcc_mdss_byte0_intf_clk
= {
504 .halt_check
= BRANCH_HALT
,
506 .enable_reg
= 0x202c,
507 .enable_mask
= BIT(0),
508 .hw
.init
= &(const struct clk_init_data
) {
509 .name
= "dispcc_mdss_byte0_intf_clk",
510 .parent_hws
= (const struct clk_hw
*[]) {
511 &dispcc_mdss_byte0_div_clk_src
.clkr
.hw
,
514 .ops
= &clk_branch2_ops
,
519 static struct clk_branch dispcc_mdss_byte1_clk
= {
521 .halt_check
= BRANCH_HALT
,
523 .enable_reg
= 0x2030,
524 .enable_mask
= BIT(0),
525 .hw
.init
= &(const struct clk_init_data
) {
526 .name
= "dispcc_mdss_byte1_clk",
527 .parent_hws
= (const struct clk_hw
*[]) {
528 &dispcc_mdss_byte1_clk_src
.clkr
.hw
,
531 .flags
= CLK_SET_RATE_PARENT
,
532 .ops
= &clk_branch2_ops
,
537 static struct clk_regmap_div dispcc_mdss_byte1_div_clk_src
= {
542 .hw
.init
= &(const struct clk_init_data
) {
543 .name
= "dispcc_mdss_byte1_div_clk_src",
544 .parent_hws
= (const struct clk_hw
*[]) {
545 &dispcc_mdss_byte1_clk_src
.clkr
.hw
,
548 .ops
= &clk_regmap_div_ops
,
553 static struct clk_branch dispcc_mdss_byte1_intf_clk
= {
555 .halt_check
= BRANCH_HALT
,
557 .enable_reg
= 0x2034,
558 .enable_mask
= BIT(0),
559 .hw
.init
= &(const struct clk_init_data
) {
560 .name
= "dispcc_mdss_byte1_intf_clk",
561 .parent_hws
= (const struct clk_hw
*[]) {
562 &dispcc_mdss_byte1_div_clk_src
.clkr
.hw
,
565 .flags
= CLK_SET_RATE_PARENT
,
566 .ops
= &clk_branch2_ops
,
571 static struct clk_branch dispcc_mdss_dp_aux_clk
= {
573 .halt_check
= BRANCH_HALT
,
575 .enable_reg
= 0x2054,
576 .enable_mask
= BIT(0),
577 .hw
.init
= &(const struct clk_init_data
) {
578 .name
= "dispcc_mdss_dp_aux_clk",
579 .parent_hws
= (const struct clk_hw
*[]) {
580 &dispcc_mdss_dp_aux_clk_src
.clkr
.hw
,
583 .flags
= CLK_SET_RATE_PARENT
,
584 .ops
= &clk_branch2_ops
,
589 static struct clk_branch dispcc_mdss_dp_crypto_clk
= {
591 .halt_check
= BRANCH_HALT
,
593 .enable_reg
= 0x2048,
594 .enable_mask
= BIT(0),
595 .hw
.init
= &(const struct clk_init_data
) {
596 .name
= "dispcc_mdss_dp_crypto_clk",
597 .parent_hws
= (const struct clk_hw
*[]) {
598 &dispcc_mdss_dp_crypto_clk_src
.clkr
.hw
,
601 .flags
= CLK_SET_RATE_PARENT
,
602 .ops
= &clk_branch2_ops
,
607 static struct clk_branch dispcc_mdss_dp_link_clk
= {
609 .halt_check
= BRANCH_HALT
,
611 .enable_reg
= 0x2040,
612 .enable_mask
= BIT(0),
613 .hw
.init
= &(const struct clk_init_data
) {
614 .name
= "dispcc_mdss_dp_link_clk",
615 .parent_hws
= (const struct clk_hw
*[]) {
616 &dispcc_mdss_dp_link_clk_src
.clkr
.hw
,
619 .flags
= CLK_SET_RATE_PARENT
,
620 .ops
= &clk_branch2_ops
,
625 static struct clk_branch dispcc_mdss_dp_link_intf_clk
= {
627 .halt_check
= BRANCH_HALT
,
629 .enable_reg
= 0x2044,
630 .enable_mask
= BIT(0),
631 .hw
.init
= &(const struct clk_init_data
) {
632 .name
= "dispcc_mdss_dp_link_intf_clk",
633 .parent_hws
= (const struct clk_hw
*[]) {
634 &dispcc_mdss_dp_link_clk_src
.clkr
.hw
,
637 .ops
= &clk_branch2_ops
,
642 static struct clk_branch dispcc_mdss_dp_pixel1_clk
= {
644 .halt_check
= BRANCH_HALT
,
646 .enable_reg
= 0x2050,
647 .enable_mask
= BIT(0),
648 .hw
.init
= &(const struct clk_init_data
) {
649 .name
= "dispcc_mdss_dp_pixel1_clk",
650 .parent_hws
= (const struct clk_hw
*[]) {
651 &dispcc_mdss_dp_pixel1_clk_src
.clkr
.hw
,
654 .flags
= CLK_SET_RATE_PARENT
,
655 .ops
= &clk_branch2_ops
,
660 static struct clk_branch dispcc_mdss_dp_pixel_clk
= {
662 .halt_check
= BRANCH_HALT
,
664 .enable_reg
= 0x204c,
665 .enable_mask
= BIT(0),
666 .hw
.init
= &(const struct clk_init_data
) {
667 .name
= "dispcc_mdss_dp_pixel_clk",
668 .parent_hws
= (const struct clk_hw
*[]) {
669 &dispcc_mdss_dp_pixel_clk_src
.clkr
.hw
,
672 .flags
= CLK_SET_RATE_PARENT
,
673 .ops
= &clk_branch2_ops
,
678 static struct clk_branch dispcc_mdss_esc0_clk
= {
680 .halt_check
= BRANCH_HALT
,
682 .enable_reg
= 0x2038,
683 .enable_mask
= BIT(0),
684 .hw
.init
= &(const struct clk_init_data
) {
685 .name
= "dispcc_mdss_esc0_clk",
686 .parent_hws
= (const struct clk_hw
*[]) {
687 &dispcc_mdss_esc0_clk_src
.clkr
.hw
,
690 .flags
= CLK_SET_RATE_PARENT
,
691 .ops
= &clk_branch2_ops
,
696 static struct clk_branch dispcc_mdss_esc1_clk
= {
698 .halt_check
= BRANCH_HALT
,
700 .enable_reg
= 0x203c,
701 .enable_mask
= BIT(0),
702 .hw
.init
= &(const struct clk_init_data
) {
703 .name
= "dispcc_mdss_esc1_clk",
704 .parent_hws
= (const struct clk_hw
*[]) {
705 &dispcc_mdss_esc1_clk_src
.clkr
.hw
,
708 .flags
= CLK_SET_RATE_PARENT
,
709 .ops
= &clk_branch2_ops
,
714 static struct clk_branch dispcc_mdss_mdp_clk
= {
716 .halt_check
= BRANCH_HALT
,
718 .enable_reg
= 0x200c,
719 .enable_mask
= BIT(0),
720 .hw
.init
= &(const struct clk_init_data
) {
721 .name
= "dispcc_mdss_mdp_clk",
722 .parent_hws
= (const struct clk_hw
*[]) {
723 &dispcc_mdss_mdp_clk_src
.clkr
.hw
,
726 .flags
= CLK_SET_RATE_PARENT
,
727 .ops
= &clk_branch2_ops
,
732 static struct clk_branch dispcc_mdss_mdp_lut_clk
= {
734 .halt_check
= BRANCH_VOTED
,
736 .enable_reg
= 0x201c,
737 .enable_mask
= BIT(0),
738 .hw
.init
= &(const struct clk_init_data
) {
739 .name
= "dispcc_mdss_mdp_lut_clk",
740 .parent_hws
= (const struct clk_hw
*[]) {
741 &dispcc_mdss_mdp_clk_src
.clkr
.hw
,
744 .ops
= &clk_branch2_ops
,
749 static struct clk_branch dispcc_mdss_non_gdsc_ahb_clk
= {
751 .halt_check
= BRANCH_VOTED
,
753 .enable_reg
= 0x4004,
754 .enable_mask
= BIT(0),
755 .hw
.init
= &(const struct clk_init_data
) {
756 .name
= "dispcc_mdss_non_gdsc_ahb_clk",
757 .parent_hws
= (const struct clk_hw
*[]) {
758 &dispcc_mdss_ahb_clk_src
.clkr
.hw
,
761 .flags
= CLK_SET_RATE_PARENT
,
762 .ops
= &clk_branch2_ops
,
767 static struct clk_branch dispcc_mdss_pclk0_clk
= {
769 .halt_check
= BRANCH_HALT
,
771 .enable_reg
= 0x2004,
772 .enable_mask
= BIT(0),
773 .hw
.init
= &(const struct clk_init_data
) {
774 .name
= "dispcc_mdss_pclk0_clk",
775 .parent_hws
= (const struct clk_hw
*[]) {
776 &dispcc_mdss_pclk0_clk_src
.clkr
.hw
,
779 .flags
= CLK_SET_RATE_PARENT
,
780 .ops
= &clk_branch2_ops
,
785 static struct clk_branch dispcc_mdss_pclk1_clk
= {
787 .halt_check
= BRANCH_HALT
,
789 .enable_reg
= 0x2008,
790 .enable_mask
= BIT(0),
791 .hw
.init
= &(const struct clk_init_data
) {
792 .name
= "dispcc_mdss_pclk1_clk",
793 .parent_hws
= (const struct clk_hw
*[]) {
794 &dispcc_mdss_pclk1_clk_src
.clkr
.hw
,
797 .flags
= CLK_SET_RATE_PARENT
,
798 .ops
= &clk_branch2_ops
,
803 static struct clk_branch dispcc_mdss_rot_clk
= {
805 .halt_check
= BRANCH_HALT
,
807 .enable_reg
= 0x2014,
808 .enable_mask
= BIT(0),
809 .hw
.init
= &(const struct clk_init_data
) {
810 .name
= "dispcc_mdss_rot_clk",
811 .parent_hws
= (const struct clk_hw
*[]) {
812 &dispcc_mdss_rot_clk_src
.clkr
.hw
,
815 .flags
= CLK_SET_RATE_PARENT
,
816 .ops
= &clk_branch2_ops
,
821 static struct clk_branch dispcc_mdss_rscc_ahb_clk
= {
823 .halt_check
= BRANCH_HALT
,
825 .enable_reg
= 0x400c,
826 .enable_mask
= BIT(0),
827 .hw
.init
= &(const struct clk_init_data
) {
828 .name
= "dispcc_mdss_rscc_ahb_clk",
829 .parent_names
= (const char *[]) {
830 "dispcc_mdss_ahb_clk_src",
833 .flags
= CLK_SET_RATE_PARENT
,
834 .ops
= &clk_branch2_ops
,
839 static struct clk_branch dispcc_mdss_rscc_vsync_clk
= {
841 .halt_check
= BRANCH_HALT
,
843 .enable_reg
= 0x4008,
844 .enable_mask
= BIT(0),
845 .hw
.init
= &(const struct clk_init_data
) {
846 .name
= "dispcc_mdss_rscc_vsync_clk",
847 .parent_hws
= (const struct clk_hw
*[]) {
848 &dispcc_mdss_vsync_clk_src
.clkr
.hw
,
851 .flags
= CLK_SET_RATE_PARENT
,
852 .ops
= &clk_branch2_ops
,
857 static struct clk_branch dispcc_mdss_vsync_clk
= {
859 .halt_check
= BRANCH_HALT
,
861 .enable_reg
= 0x2024,
862 .enable_mask
= BIT(0),
863 .hw
.init
= &(const struct clk_init_data
) {
864 .name
= "dispcc_mdss_vsync_clk",
865 .parent_hws
= (const struct clk_hw
*[]) {
866 &dispcc_mdss_vsync_clk_src
.clkr
.hw
,
869 .flags
= CLK_SET_RATE_PARENT
,
870 .ops
= &clk_branch2_ops
,
875 static struct clk_branch dispcc_sleep_clk
= {
877 .halt_check
= BRANCH_HALT
,
879 .enable_reg
= 0x6078,
880 .enable_mask
= BIT(0),
881 .hw
.init
= &(const struct clk_init_data
) {
882 .name
= "dispcc_sleep_clk",
883 .parent_names
= (const char *[]) {
884 "dispcc_sleep_clk_src",
887 .flags
= CLK_SET_RATE_PARENT
,
888 .ops
= &clk_branch2_ops
,
893 static struct gdsc mdss_gdsc
= {
895 .en_rest_wait_val
= 0x2,
896 .en_few_wait_val
= 0x2,
897 .clk_dis_wait_val
= 0xf,
901 .pwrsts
= PWRSTS_OFF_ON
,
905 static struct clk_regmap
*dispcc_sm7150_clocks
[] = {
906 [DISPCC_MDSS_AHB_CLK
] = &dispcc_mdss_ahb_clk
.clkr
,
907 [DISPCC_MDSS_AHB_CLK_SRC
] = &dispcc_mdss_ahb_clk_src
.clkr
,
908 [DISPCC_MDSS_BYTE0_CLK
] = &dispcc_mdss_byte0_clk
.clkr
,
909 [DISPCC_MDSS_BYTE0_CLK_SRC
] = &dispcc_mdss_byte0_clk_src
.clkr
,
910 [DISPCC_MDSS_BYTE0_DIV_CLK_SRC
] = &dispcc_mdss_byte0_div_clk_src
.clkr
,
911 [DISPCC_MDSS_BYTE0_INTF_CLK
] = &dispcc_mdss_byte0_intf_clk
.clkr
,
912 [DISPCC_MDSS_BYTE1_CLK
] = &dispcc_mdss_byte1_clk
.clkr
,
913 [DISPCC_MDSS_BYTE1_CLK_SRC
] = &dispcc_mdss_byte1_clk_src
.clkr
,
914 [DISPCC_MDSS_BYTE1_DIV_CLK_SRC
] = &dispcc_mdss_byte1_div_clk_src
.clkr
,
915 [DISPCC_MDSS_BYTE1_INTF_CLK
] = &dispcc_mdss_byte1_intf_clk
.clkr
,
916 [DISPCC_MDSS_DP_AUX_CLK
] = &dispcc_mdss_dp_aux_clk
.clkr
,
917 [DISPCC_MDSS_DP_AUX_CLK_SRC
] = &dispcc_mdss_dp_aux_clk_src
.clkr
,
918 [DISPCC_MDSS_DP_CRYPTO_CLK
] = &dispcc_mdss_dp_crypto_clk
.clkr
,
919 [DISPCC_MDSS_DP_CRYPTO_CLK_SRC
] = &dispcc_mdss_dp_crypto_clk_src
.clkr
,
920 [DISPCC_MDSS_DP_LINK_CLK
] = &dispcc_mdss_dp_link_clk
.clkr
,
921 [DISPCC_MDSS_DP_LINK_CLK_SRC
] = &dispcc_mdss_dp_link_clk_src
.clkr
,
922 [DISPCC_MDSS_DP_LINK_INTF_CLK
] = &dispcc_mdss_dp_link_intf_clk
.clkr
,
923 [DISPCC_MDSS_DP_PIXEL1_CLK
] = &dispcc_mdss_dp_pixel1_clk
.clkr
,
924 [DISPCC_MDSS_DP_PIXEL1_CLK_SRC
] = &dispcc_mdss_dp_pixel1_clk_src
.clkr
,
925 [DISPCC_MDSS_DP_PIXEL_CLK
] = &dispcc_mdss_dp_pixel_clk
.clkr
,
926 [DISPCC_MDSS_DP_PIXEL_CLK_SRC
] = &dispcc_mdss_dp_pixel_clk_src
.clkr
,
927 [DISPCC_MDSS_ESC0_CLK
] = &dispcc_mdss_esc0_clk
.clkr
,
928 [DISPCC_MDSS_ESC0_CLK_SRC
] = &dispcc_mdss_esc0_clk_src
.clkr
,
929 [DISPCC_MDSS_ESC1_CLK
] = &dispcc_mdss_esc1_clk
.clkr
,
930 [DISPCC_MDSS_ESC1_CLK_SRC
] = &dispcc_mdss_esc1_clk_src
.clkr
,
931 [DISPCC_MDSS_MDP_CLK
] = &dispcc_mdss_mdp_clk
.clkr
,
932 [DISPCC_MDSS_MDP_CLK_SRC
] = &dispcc_mdss_mdp_clk_src
.clkr
,
933 [DISPCC_MDSS_MDP_LUT_CLK
] = &dispcc_mdss_mdp_lut_clk
.clkr
,
934 [DISPCC_MDSS_NON_GDSC_AHB_CLK
] = &dispcc_mdss_non_gdsc_ahb_clk
.clkr
,
935 [DISPCC_MDSS_PCLK0_CLK
] = &dispcc_mdss_pclk0_clk
.clkr
,
936 [DISPCC_MDSS_PCLK0_CLK_SRC
] = &dispcc_mdss_pclk0_clk_src
.clkr
,
937 [DISPCC_MDSS_PCLK1_CLK
] = &dispcc_mdss_pclk1_clk
.clkr
,
938 [DISPCC_MDSS_PCLK1_CLK_SRC
] = &dispcc_mdss_pclk1_clk_src
.clkr
,
939 [DISPCC_MDSS_ROT_CLK
] = &dispcc_mdss_rot_clk
.clkr
,
940 [DISPCC_MDSS_ROT_CLK_SRC
] = &dispcc_mdss_rot_clk_src
.clkr
,
941 [DISPCC_MDSS_RSCC_AHB_CLK
] = &dispcc_mdss_rscc_ahb_clk
.clkr
,
942 [DISPCC_MDSS_RSCC_VSYNC_CLK
] = &dispcc_mdss_rscc_vsync_clk
.clkr
,
943 [DISPCC_MDSS_VSYNC_CLK
] = &dispcc_mdss_vsync_clk
.clkr
,
944 [DISPCC_MDSS_VSYNC_CLK_SRC
] = &dispcc_mdss_vsync_clk_src
.clkr
,
945 [DISPCC_PLL0
] = &dispcc_pll0
.clkr
,
946 [DISPCC_SLEEP_CLK
] = &dispcc_sleep_clk
.clkr
,
947 [DISPCC_SLEEP_CLK_SRC
] = &dispcc_sleep_clk_src
.clkr
,
948 [DISPCC_XO_CLK_SRC
] = &dispcc_xo_clk_src
.clkr
,
951 static struct gdsc
*dispcc_sm7150_gdscs
[] = {
952 [MDSS_GDSC
] = &mdss_gdsc
,
955 static const struct regmap_config dispcc_sm7150_regmap_config
= {
959 .max_register
= 0x10000,
963 static const struct qcom_cc_desc dispcc_sm7150_desc
= {
964 .config
= &dispcc_sm7150_regmap_config
,
965 .clks
= dispcc_sm7150_clocks
,
966 .num_clks
= ARRAY_SIZE(dispcc_sm7150_clocks
),
967 .gdscs
= dispcc_sm7150_gdscs
,
968 .num_gdscs
= ARRAY_SIZE(dispcc_sm7150_gdscs
),
971 static const struct of_device_id dispcc_sm7150_match_table
[] = {
972 { .compatible
= "qcom,sm7150-dispcc" },
975 MODULE_DEVICE_TABLE(of
, dispcc_sm7150_match_table
);
977 static int dispcc_sm7150_probe(struct platform_device
*pdev
)
979 struct regmap
*regmap
;
981 regmap
= qcom_cc_map(pdev
, &dispcc_sm7150_desc
);
983 return PTR_ERR(regmap
);
985 clk_fabia_pll_configure(&dispcc_pll0
, regmap
, &dispcc_pll0_config
);
986 /* Enable clock gating for DSI and MDP clocks */
987 regmap_update_bits(regmap
, 0x8000, 0x7f0, 0x7f0);
989 /* Keep some clocks always-on */
990 qcom_branch_set_clk_en(regmap
, 0x605c); /* DISPCC_XO_CLK */
992 return qcom_cc_really_probe(&pdev
->dev
, &dispcc_sm7150_desc
, regmap
);
995 static struct platform_driver dispcc_sm7150_driver
= {
996 .probe
= dispcc_sm7150_probe
,
998 .name
= "dispcc-sm7150",
999 .of_match_table
= dispcc_sm7150_match_table
,
1003 module_platform_driver(dispcc_sm7150_driver
);
1005 MODULE_DESCRIPTION("Qualcomm SM7150 Display Clock Controller");
1006 MODULE_LICENSE("GPL");