1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
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>
6 */
7
8 #include <linux/clk-provider.h>
9 #include <linux/mod_devicetable.h>
10 #include <linux/module.h>
11 #include <linux/of.h>
12 #include <linux/platform_device.h>
13 #include <linux/regmap.h>
14
15 #include <dt-bindings/clock/qcom,sm7150-dispcc.h>
16
17 #include "clk-alpha-pll.h"
18 #include "clk-branch.h"
19 #include "clk-rcg.h"
20 #include "clk-regmap.h"
21 #include "clk-regmap-divider.h"
22 #include "common.h"
23 #include "gdsc.h"
24
25 enum {
26 DT_BI_TCXO,
27 DT_BI_TCXO_AO,
28 DT_GCC_DISP_GPLL0_CLK,
29 DT_CHIP_SLEEP_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,
36 };
37
38 enum {
39 P_BI_TCXO,
40 P_CHIP_SLEEP_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,
49 P_GCC_DISP_GPLL0_CLK,
50 };
51
52 static const struct pll_vco fabia_vco[] = {
53 { 249600000, 2000000000, 0 },
54 { 125000000, 1000000000, 1 },
55 };
56
57 /* 860MHz configuration */
58 static const struct alpha_pll_config dispcc_pll0_config = {
59 .l = 0x2c,
60 .alpha = 0xcaaa,
61 .test_ctl_val = 0x40000000,
62 };
63
64 static struct clk_alpha_pll dispcc_pll0 = {
65 .offset = 0x0,
66 .vco_table = fabia_vco,
67 .num_vco = ARRAY_SIZE(fabia_vco),
68 .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
69 .clkr = {
70 .hw.init = &(const struct clk_init_data) {
71 .name = "dispcc_pll0",
72 .parent_data = &(const struct clk_parent_data) {
73 .index = DT_BI_TCXO,
74 },
75 .num_parents = 1,
76 .ops = &clk_alpha_pll_fabia_ops,
77 },
78 },
79 };
80
81 static const struct parent_map dispcc_parent_map_0[] = {
82 { P_BI_TCXO, 0 },
83 { P_DSI0_PHY_PLL_OUT_BYTECLK, 1 },
84 { P_DSI1_PHY_PLL_OUT_BYTECLK, 2 },
85 };
86
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 },
91 };
92
93 static const struct parent_map dispcc_parent_map_1[] = {
94 { P_BI_TCXO, 0 },
95 { P_DP_PHY_PLL_LINK_CLK, 1 },
96 { P_DP_PHY_PLL_VCO_DIV_CLK, 2 },
97 };
98
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 },
103 };
104
105 static const struct parent_map dispcc_parent_map_2[] = {
106 { P_BI_TCXO, 0 },
107 };
108
109 static const struct clk_parent_data dispcc_parent_data_2[] = {
110 { .index = DT_BI_TCXO },
111 };
112
113 static const struct clk_parent_data dispcc_parent_data_2_ao[] = {
114 { .index = DT_BI_TCXO_AO },
115 };
116
117 static const struct parent_map dispcc_parent_map_3[] = {
118 { P_BI_TCXO, 0 },
119 { P_DISPCC_PLL0_OUT_MAIN, 1 },
120 { P_GCC_DISP_GPLL0_CLK, 4 },
121 { P_DISPCC_PLL0_OUT_EVEN, 5 },
122 };
123
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 },
129 };
130
131 static const struct parent_map dispcc_parent_map_4[] = {
132 { P_BI_TCXO, 0 },
133 { P_DSI0_PHY_PLL_OUT_DSICLK, 1 },
134 { P_DSI1_PHY_PLL_OUT_DSICLK, 2 },
135 };
136
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 },
141 };
142
143 static const struct parent_map dispcc_parent_map_5[] = {
144 { P_BI_TCXO, 0 },
145 { P_GCC_DISP_GPLL0_CLK, 4 },
146 };
147
148 static const struct clk_parent_data dispcc_parent_data_5[] = {
149 { .index = DT_BI_TCXO },
150 { .index = DT_GCC_DISP_GPLL0_CLK },
151 };
152
153 static const struct parent_map dispcc_parent_map_6[] = {
154 { P_CHIP_SLEEP_CLK, 0 },
155 };
156
157 static const struct clk_parent_data dispcc_parent_data_6[] = {
158 { .index = DT_CHIP_SLEEP_CLK },
159 };
160
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),
165 { }
166 };
167
168 static struct clk_rcg2 dispcc_mdss_ahb_clk_src = {
169 .cmd_rcgr = 0x22bc,
170 .mnd_width = 0,
171 .hid_width = 5,
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,
180 },
181 };
182
183 static const struct freq_tbl ftbl_dispcc_mdss_byte0_clk_src[] = {
184 F(19200000, P_BI_TCXO, 1, 0, 0),
185 { }
186 };
187
188 static struct clk_rcg2 dispcc_mdss_byte0_clk_src = {
189 .cmd_rcgr = 0x2110,
190 .mnd_width = 0,
191 .hid_width = 5,
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,
199 },
200 };
201
202 static struct clk_rcg2 dispcc_mdss_byte1_clk_src = {
203 .cmd_rcgr = 0x212c,
204 .mnd_width = 0,
205 .hid_width = 5,
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,
213 },
214 };
215
216 static struct clk_rcg2 dispcc_mdss_dp_aux_clk_src = {
217 .cmd_rcgr = 0x21dc,
218 .mnd_width = 0,
219 .hid_width = 5,
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,
227 },
228 };
229
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),
235 { }
236 };
237
238 static struct clk_rcg2 dispcc_mdss_dp_crypto_clk_src = {
239 .cmd_rcgr = 0x2194,
240 .mnd_width = 0,
241 .hid_width = 5,
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,
249 },
250 };
251
252 static struct clk_rcg2 dispcc_mdss_dp_link_clk_src = {
253 .cmd_rcgr = 0x2178,
254 .mnd_width = 0,
255 .hid_width = 5,
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,
263 },
264 };
265
266 static struct clk_rcg2 dispcc_mdss_dp_pixel1_clk_src = {
267 .cmd_rcgr = 0x21c4,
268 .mnd_width = 16,
269 .hid_width = 5,
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,
276 .ops = &clk_dp_ops,
277 },
278 };
279
280 static struct clk_rcg2 dispcc_mdss_dp_pixel_clk_src = {
281 .cmd_rcgr = 0x21ac,
282 .mnd_width = 16,
283 .hid_width = 5,
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,
290 .ops = &clk_dp_ops,
291 },
292 };
293
294 static struct clk_rcg2 dispcc_mdss_esc0_clk_src = {
295 .cmd_rcgr = 0x2148,
296 .mnd_width = 0,
297 .hid_width = 5,
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,
305 },
306 };
307
308 static struct clk_rcg2 dispcc_mdss_esc1_clk_src = {
309 .cmd_rcgr = 0x2160,
310 .mnd_width = 0,
311 .hid_width = 5,
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,
319 },
320 };
321
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),
333 { }
334 };
335
336 static struct clk_rcg2 dispcc_mdss_mdp_clk_src = {
337 .cmd_rcgr = 0x20c8,
338 .mnd_width = 0,
339 .hid_width = 5,
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,
348 },
349 };
350
351 static struct clk_rcg2 dispcc_mdss_pclk0_clk_src = {
352 .cmd_rcgr = 0x2098,
353 .mnd_width = 8,
354 .hid_width = 5,
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,
362 },
363 };
364
365 static struct clk_rcg2 dispcc_mdss_pclk1_clk_src = {
366 .cmd_rcgr = 0x20b0,
367 .mnd_width = 8,
368 .hid_width = 5,
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,
376 },
377 };
378
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),
386 { }
387 };
388
389 static struct clk_rcg2 dispcc_mdss_rot_clk_src = {
390 .cmd_rcgr = 0x20e0,
391 .mnd_width = 0,
392 .hid_width = 5,
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,
400 },
401 };
402
403 static struct clk_rcg2 dispcc_mdss_vsync_clk_src = {
404 .cmd_rcgr = 0x20f8,
405 .mnd_width = 0,
406 .hid_width = 5,
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,
414 },
415 };
416
417 static const struct freq_tbl ftbl_dispcc_sleep_clk_src[] = {
418 F(32000, P_CHIP_SLEEP_CLK, 1, 0, 0),
419 { }
420 };
421
422 static struct clk_rcg2 dispcc_sleep_clk_src = {
423 .cmd_rcgr = 0x6060,
424 .mnd_width = 0,
425 .hid_width = 5,
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,
433 },
434 };
435
436 static struct clk_rcg2 dispcc_xo_clk_src = {
437 .cmd_rcgr = 0x6044,
438 .mnd_width = 0,
439 .hid_width = 5,
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,
447 },
448 };
449
450 static struct clk_branch dispcc_mdss_ahb_clk = {
451 .halt_reg = 0x2080,
452 .halt_check = BRANCH_HALT,
453 .clkr = {
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,
460 },
461 .num_parents = 1,
462 .flags = CLK_SET_RATE_PARENT,
463 .ops = &clk_branch2_ops,
464 },
465 },
466 };
467
468 static struct clk_branch dispcc_mdss_byte0_clk = {
469 .halt_reg = 0x2028,
470 .halt_check = BRANCH_HALT,
471 .clkr = {
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,
478 },
479 .num_parents = 1,
480 .flags = CLK_SET_RATE_PARENT,
481 .ops = &clk_branch2_ops,
482 },
483 },
484 };
485
486 static struct clk_regmap_div dispcc_mdss_byte0_div_clk_src = {
487 .reg = 0x2128,
488 .shift = 0,
489 .width = 2,
490 .clkr = {
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,
495 },
496 .num_parents = 1,
497 .ops = &clk_regmap_div_ops,
498 },
499 },
500 };
501
502 static struct clk_branch dispcc_mdss_byte0_intf_clk = {
503 .halt_reg = 0x202c,
504 .halt_check = BRANCH_HALT,
505 .clkr = {
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,
512 },
513 .num_parents = 1,
514 .ops = &clk_branch2_ops,
515 },
516 },
517 };
518
519 static struct clk_branch dispcc_mdss_byte1_clk = {
520 .halt_reg = 0x2030,
521 .halt_check = BRANCH_HALT,
522 .clkr = {
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,
529 },
530 .num_parents = 1,
531 .flags = CLK_SET_RATE_PARENT,
532 .ops = &clk_branch2_ops,
533 },
534 },
535 };
536
537 static struct clk_regmap_div dispcc_mdss_byte1_div_clk_src = {
538 .reg = 0x2144,
539 .shift = 0,
540 .width = 2,
541 .clkr = {
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,
546 },
547 .num_parents = 1,
548 .ops = &clk_regmap_div_ops,
549 },
550 },
551 };
552
553 static struct clk_branch dispcc_mdss_byte1_intf_clk = {
554 .halt_reg = 0x2034,
555 .halt_check = BRANCH_HALT,
556 .clkr = {
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,
563 },
564 .num_parents = 1,
565 .flags = CLK_SET_RATE_PARENT,
566 .ops = &clk_branch2_ops,
567 },
568 },
569 };
570
571 static struct clk_branch dispcc_mdss_dp_aux_clk = {
572 .halt_reg = 0x2054,
573 .halt_check = BRANCH_HALT,
574 .clkr = {
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,
581 },
582 .num_parents = 1,
583 .flags = CLK_SET_RATE_PARENT,
584 .ops = &clk_branch2_ops,
585 },
586 },
587 };
588
589 static struct clk_branch dispcc_mdss_dp_crypto_clk = {
590 .halt_reg = 0x2048,
591 .halt_check = BRANCH_HALT,
592 .clkr = {
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,
599 },
600 .num_parents = 1,
601 .flags = CLK_SET_RATE_PARENT,
602 .ops = &clk_branch2_ops,
603 },
604 },
605 };
606
607 static struct clk_branch dispcc_mdss_dp_link_clk = {
608 .halt_reg = 0x2040,
609 .halt_check = BRANCH_HALT,
610 .clkr = {
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,
617 },
618 .num_parents = 1,
619 .flags = CLK_SET_RATE_PARENT,
620 .ops = &clk_branch2_ops,
621 },
622 },
623 };
624
625 static struct clk_branch dispcc_mdss_dp_link_intf_clk = {
626 .halt_reg = 0x2044,
627 .halt_check = BRANCH_HALT,
628 .clkr = {
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,
635 },
636 .num_parents = 1,
637 .ops = &clk_branch2_ops,
638 },
639 },
640 };
641
642 static struct clk_branch dispcc_mdss_dp_pixel1_clk = {
643 .halt_reg = 0x2050,
644 .halt_check = BRANCH_HALT,
645 .clkr = {
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,
652 },
653 .num_parents = 1,
654 .flags = CLK_SET_RATE_PARENT,
655 .ops = &clk_branch2_ops,
656 },
657 },
658 };
659
660 static struct clk_branch dispcc_mdss_dp_pixel_clk = {
661 .halt_reg = 0x204c,
662 .halt_check = BRANCH_HALT,
663 .clkr = {
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,
670 },
671 .num_parents = 1,
672 .flags = CLK_SET_RATE_PARENT,
673 .ops = &clk_branch2_ops,
674 },
675 },
676 };
677
678 static struct clk_branch dispcc_mdss_esc0_clk = {
679 .halt_reg = 0x2038,
680 .halt_check = BRANCH_HALT,
681 .clkr = {
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,
688 },
689 .num_parents = 1,
690 .flags = CLK_SET_RATE_PARENT,
691 .ops = &clk_branch2_ops,
692 },
693 },
694 };
695
696 static struct clk_branch dispcc_mdss_esc1_clk = {
697 .halt_reg = 0x203c,
698 .halt_check = BRANCH_HALT,
699 .clkr = {
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,
706 },
707 .num_parents = 1,
708 .flags = CLK_SET_RATE_PARENT,
709 .ops = &clk_branch2_ops,
710 },
711 },
712 };
713
714 static struct clk_branch dispcc_mdss_mdp_clk = {
715 .halt_reg = 0x200c,
716 .halt_check = BRANCH_HALT,
717 .clkr = {
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,
724 },
725 .num_parents = 1,
726 .flags = CLK_SET_RATE_PARENT,
727 .ops = &clk_branch2_ops,
728 },
729 },
730 };
731
732 static struct clk_branch dispcc_mdss_mdp_lut_clk = {
733 .halt_reg = 0x201c,
734 .halt_check = BRANCH_VOTED,
735 .clkr = {
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,
742 },
743 .num_parents = 1,
744 .ops = &clk_branch2_ops,
745 },
746 },
747 };
748
749 static struct clk_branch dispcc_mdss_non_gdsc_ahb_clk = {
750 .halt_reg = 0x4004,
751 .halt_check = BRANCH_VOTED,
752 .clkr = {
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,
759 },
760 .num_parents = 1,
761 .flags = CLK_SET_RATE_PARENT,
762 .ops = &clk_branch2_ops,
763 },
764 },
765 };
766
767 static struct clk_branch dispcc_mdss_pclk0_clk = {
768 .halt_reg = 0x2004,
769 .halt_check = BRANCH_HALT,
770 .clkr = {
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,
777 },
778 .num_parents = 1,
779 .flags = CLK_SET_RATE_PARENT,
780 .ops = &clk_branch2_ops,
781 },
782 },
783 };
784
785 static struct clk_branch dispcc_mdss_pclk1_clk = {
786 .halt_reg = 0x2008,
787 .halt_check = BRANCH_HALT,
788 .clkr = {
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,
795 },
796 .num_parents = 1,
797 .flags = CLK_SET_RATE_PARENT,
798 .ops = &clk_branch2_ops,
799 },
800 },
801 };
802
803 static struct clk_branch dispcc_mdss_rot_clk = {
804 .halt_reg = 0x2014,
805 .halt_check = BRANCH_HALT,
806 .clkr = {
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,
813 },
814 .num_parents = 1,
815 .flags = CLK_SET_RATE_PARENT,
816 .ops = &clk_branch2_ops,
817 },
818 },
819 };
820
821 static struct clk_branch dispcc_mdss_rscc_ahb_clk = {
822 .halt_reg = 0x400c,
823 .halt_check = BRANCH_HALT,
824 .clkr = {
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",
831 },
832 .num_parents = 1,
833 .flags = CLK_SET_RATE_PARENT,
834 .ops = &clk_branch2_ops,
835 },
836 },
837 };
838
839 static struct clk_branch dispcc_mdss_rscc_vsync_clk = {
840 .halt_reg = 0x4008,
841 .halt_check = BRANCH_HALT,
842 .clkr = {
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,
849 },
850 .num_parents = 1,
851 .flags = CLK_SET_RATE_PARENT,
852 .ops = &clk_branch2_ops,
853 },
854 },
855 };
856
857 static struct clk_branch dispcc_mdss_vsync_clk = {
858 .halt_reg = 0x2024,
859 .halt_check = BRANCH_HALT,
860 .clkr = {
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,
867 },
868 .num_parents = 1,
869 .flags = CLK_SET_RATE_PARENT,
870 .ops = &clk_branch2_ops,
871 },
872 },
873 };
874
875 static struct clk_branch dispcc_sleep_clk = {
876 .halt_reg = 0x6078,
877 .halt_check = BRANCH_HALT,
878 .clkr = {
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",
885 },
886 .num_parents = 1,
887 .flags = CLK_SET_RATE_PARENT,
888 .ops = &clk_branch2_ops,
889 },
890 },
891 };
892
893 static struct gdsc mdss_gdsc = {
894 .gdscr = 0x3000,
895 .en_rest_wait_val = 0x2,
896 .en_few_wait_val = 0x2,
897 .clk_dis_wait_val = 0xf,
898 .pd = {
899 .name = "mdss_gdsc",
900 },
901 .pwrsts = PWRSTS_OFF_ON,
902 .flags = HW_CTRL,
903 };
904
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,
949 };
950
951 static struct gdsc *dispcc_sm7150_gdscs[] = {
952 [MDSS_GDSC] = &mdss_gdsc,
953 };
954
955 static const struct regmap_config dispcc_sm7150_regmap_config = {
956 .reg_bits = 32,
957 .reg_stride = 4,
958 .val_bits = 32,
959 .max_register = 0x10000,
960 .fast_io = true,
961 };
962
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),
969 };
970
971 static const struct of_device_id dispcc_sm7150_match_table[] = {
972 { .compatible = "qcom,sm7150-dispcc" },
973 { }
974 };
975 MODULE_DEVICE_TABLE(of, dispcc_sm7150_match_table);
976
dispcc_sm7150_probe(struct platform_device * pdev)977 static int dispcc_sm7150_probe(struct platform_device *pdev)
978 {
979 struct regmap *regmap;
980
981 regmap = qcom_cc_map(pdev, &dispcc_sm7150_desc);
982 if (IS_ERR(regmap))
983 return PTR_ERR(regmap);
984
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);
988
989 /* Keep some clocks always-on */
990 qcom_branch_set_clk_en(regmap, 0x605c); /* DISPCC_XO_CLK */
991
992 return qcom_cc_really_probe(&pdev->dev, &dispcc_sm7150_desc, regmap);
993 }
994
995 static struct platform_driver dispcc_sm7150_driver = {
996 .probe = dispcc_sm7150_probe,
997 .driver = {
998 .name = "dispcc-sm7150",
999 .of_match_table = dispcc_sm7150_match_table,
1000 },
1001 };
1002
1003 module_platform_driver(dispcc_sm7150_driver);
1004
1005 MODULE_DESCRIPTION("Qualcomm SM7150 Display Clock Controller");
1006 MODULE_LICENSE("GPL");
1007