1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved.
4 * Copyright (c) 2025, Luca Weiss <luca.weiss@fairphone.com>
5 */
6
7 #include <linux/clk.h>
8 #include <linux/clk-provider.h>
9 #include <linux/err.h>
10 #include <linux/kernel.h>
11 #include <linux/module.h>
12 #include <linux/of.h>
13 #include <linux/platform_device.h>
14 #include <linux/regmap.h>
15
16 #include <dt-bindings/clock/qcom,milos-dispcc.h>
17
18 #include "common.h"
19 #include "clk-alpha-pll.h"
20 #include "clk-branch.h"
21 #include "clk-pll.h"
22 #include "clk-rcg.h"
23 #include "clk-regmap.h"
24 #include "clk-regmap-divider.h"
25 #include "clk-regmap-mux.h"
26 #include "reset.h"
27 #include "gdsc.h"
28
29 /* Need to match the order of clocks in DT binding */
30 enum {
31 DT_BI_TCXO,
32 DT_SLEEP_CLK,
33 DT_AHB_CLK,
34 DT_GCC_DISP_GPLL0_CLK,
35 DT_DSI0_PHY_PLL_OUT_BYTECLK,
36 DT_DSI0_PHY_PLL_OUT_DSICLK,
37 DT_DP0_PHY_PLL_LINK_CLK,
38 DT_DP0_PHY_PLL_VCO_DIV_CLK,
39 };
40
41 #define DISP_CC_MISC_CMD 0xF000
42
43 enum {
44 P_BI_TCXO,
45 P_DISP_CC_PLL0_OUT_EVEN,
46 P_DISP_CC_PLL0_OUT_MAIN,
47 P_DP0_PHY_PLL_LINK_CLK,
48 P_DP0_PHY_PLL_VCO_DIV_CLK,
49 P_DSI0_PHY_PLL_OUT_BYTECLK,
50 P_DSI0_PHY_PLL_OUT_DSICLK,
51 P_GCC_DISP_GPLL0_CLK,
52 P_SLEEP_CLK,
53 };
54
55 static const struct pll_vco lucid_ole_vco[] = {
56 { 249600000, 2300000000, 0 },
57 };
58
59 /* 257.142858 MHz Configuration */
60 static const struct alpha_pll_config disp_cc_pll0_config = {
61 .l = 0xd,
62 .alpha = 0x6492,
63 .config_ctl_val = 0x20485699,
64 .config_ctl_hi_val = 0x00182261,
65 .config_ctl_hi1_val = 0x82aa299c,
66 .test_ctl_val = 0x00000000,
67 .test_ctl_hi_val = 0x00000003,
68 .test_ctl_hi1_val = 0x00009000,
69 .test_ctl_hi2_val = 0x00000034,
70 .user_ctl_val = 0x00000000,
71 .user_ctl_hi_val = 0x00000005,
72 };
73
74 static struct clk_alpha_pll disp_cc_pll0 = {
75 .offset = 0x0,
76 .config = &disp_cc_pll0_config,
77 .vco_table = lucid_ole_vco,
78 .num_vco = ARRAY_SIZE(lucid_ole_vco),
79 .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE],
80 .clkr = {
81 .hw.init = &(const struct clk_init_data) {
82 .name = "disp_cc_pll0",
83 .parent_data = &(const struct clk_parent_data) {
84 .index = DT_BI_TCXO,
85 },
86 .num_parents = 1,
87 .ops = &clk_alpha_pll_lucid_evo_ops,
88 },
89 },
90 };
91
92 static const struct parent_map disp_cc_parent_map_0[] = {
93 { P_BI_TCXO, 0 },
94 };
95
96 static const struct clk_parent_data disp_cc_parent_data_0[] = {
97 { .index = DT_BI_TCXO },
98 };
99
100 static const struct parent_map disp_cc_parent_map_1[] = {
101 { P_BI_TCXO, 0 },
102 { P_DSI0_PHY_PLL_OUT_DSICLK, 1 },
103 { P_DSI0_PHY_PLL_OUT_BYTECLK, 2 },
104 };
105
106 static const struct clk_parent_data disp_cc_parent_data_1[] = {
107 { .index = DT_BI_TCXO },
108 { .index = DT_DSI0_PHY_PLL_OUT_DSICLK },
109 { .index = DT_DSI0_PHY_PLL_OUT_BYTECLK },
110 };
111
112 static const struct parent_map disp_cc_parent_map_2[] = {
113 { P_BI_TCXO, 0 },
114 { P_DP0_PHY_PLL_LINK_CLK, 1 },
115 { P_DP0_PHY_PLL_VCO_DIV_CLK, 2 },
116 };
117
118 static const struct clk_parent_data disp_cc_parent_data_2[] = {
119 { .index = DT_BI_TCXO },
120 { .index = DT_DP0_PHY_PLL_LINK_CLK },
121 { .index = DT_DP0_PHY_PLL_VCO_DIV_CLK },
122 };
123
124 static const struct parent_map disp_cc_parent_map_3[] = {
125 { P_BI_TCXO, 0 },
126 { P_GCC_DISP_GPLL0_CLK, 4 },
127 };
128
129 static const struct clk_parent_data disp_cc_parent_data_3[] = {
130 { .index = DT_BI_TCXO },
131 { .index = DT_GCC_DISP_GPLL0_CLK },
132 };
133
134 static const struct parent_map disp_cc_parent_map_4[] = {
135 { P_BI_TCXO, 0 },
136 { P_DP0_PHY_PLL_LINK_CLK, 1 },
137 };
138
139 static const struct clk_parent_data disp_cc_parent_data_4[] = {
140 { .index = DT_BI_TCXO },
141 { .index = DT_DP0_PHY_PLL_LINK_CLK },
142 };
143
144 static const struct parent_map disp_cc_parent_map_5[] = {
145 { P_BI_TCXO, 0 },
146 { P_DSI0_PHY_PLL_OUT_BYTECLK, 2 },
147 };
148
149 static const struct clk_parent_data disp_cc_parent_data_5[] = {
150 { .index = DT_BI_TCXO },
151 { .index = DT_DSI0_PHY_PLL_OUT_BYTECLK },
152 };
153
154 static const struct parent_map disp_cc_parent_map_6[] = {
155 { P_BI_TCXO, 0 },
156 { P_DISP_CC_PLL0_OUT_MAIN, 1 },
157 { P_GCC_DISP_GPLL0_CLK, 4 },
158 { P_DISP_CC_PLL0_OUT_EVEN, 6 },
159 };
160
161 static const struct clk_parent_data disp_cc_parent_data_6[] = {
162 { .index = DT_BI_TCXO },
163 { .hw = &disp_cc_pll0.clkr.hw },
164 { .index = DT_GCC_DISP_GPLL0_CLK },
165 { .hw = &disp_cc_pll0.clkr.hw },
166 };
167
168 static const struct parent_map disp_cc_parent_map_7[] = {
169 { P_SLEEP_CLK, 0 },
170 };
171
172 static const struct clk_parent_data disp_cc_parent_data_7_ao[] = {
173 { .index = DT_SLEEP_CLK },
174 };
175
176 static const struct freq_tbl ftbl_disp_cc_mdss_ahb_clk_src[] = {
177 F(19200000, P_BI_TCXO, 1, 0, 0),
178 F(37500000, P_GCC_DISP_GPLL0_CLK, 8, 0, 0),
179 F(75000000, P_GCC_DISP_GPLL0_CLK, 4, 0, 0),
180 { }
181 };
182
183 static struct clk_rcg2 disp_cc_mdss_ahb_clk_src = {
184 .cmd_rcgr = 0x8130,
185 .mnd_width = 0,
186 .hid_width = 5,
187 .parent_map = disp_cc_parent_map_3,
188 .freq_tbl = ftbl_disp_cc_mdss_ahb_clk_src,
189 .clkr.hw.init = &(const struct clk_init_data) {
190 .name = "disp_cc_mdss_ahb_clk_src",
191 .parent_data = disp_cc_parent_data_3,
192 .num_parents = ARRAY_SIZE(disp_cc_parent_data_3),
193 .flags = CLK_SET_RATE_PARENT,
194 .ops = &clk_rcg2_shared_ops,
195 },
196 };
197
198 static struct clk_rcg2 disp_cc_mdss_byte0_clk_src = {
199 .cmd_rcgr = 0x8098,
200 .mnd_width = 0,
201 .hid_width = 5,
202 .parent_map = disp_cc_parent_map_1,
203 .clkr.hw.init = &(const struct clk_init_data) {
204 .name = "disp_cc_mdss_byte0_clk_src",
205 .parent_data = disp_cc_parent_data_1,
206 .num_parents = ARRAY_SIZE(disp_cc_parent_data_1),
207 .flags = CLK_SET_RATE_PARENT,
208 .ops = &clk_byte2_ops,
209 },
210 };
211
212 static const struct freq_tbl ftbl_disp_cc_mdss_dptx0_aux_clk_src[] = {
213 F(19200000, P_BI_TCXO, 1, 0, 0),
214 { }
215 };
216
217 static struct clk_rcg2 disp_cc_mdss_dptx0_aux_clk_src = {
218 .cmd_rcgr = 0x8118,
219 .mnd_width = 0,
220 .hid_width = 5,
221 .parent_map = disp_cc_parent_map_0,
222 .freq_tbl = ftbl_disp_cc_mdss_dptx0_aux_clk_src,
223 .clkr.hw.init = &(const struct clk_init_data) {
224 .name = "disp_cc_mdss_dptx0_aux_clk_src",
225 .parent_data = disp_cc_parent_data_0,
226 .num_parents = ARRAY_SIZE(disp_cc_parent_data_0),
227 .flags = CLK_SET_RATE_PARENT,
228 .ops = &clk_rcg2_ops,
229 },
230 };
231
232 static struct clk_rcg2 disp_cc_mdss_dptx0_link_clk_src = {
233 .cmd_rcgr = 0x80cc,
234 .mnd_width = 0,
235 .hid_width = 5,
236 .parent_map = disp_cc_parent_map_4,
237 .clkr.hw.init = &(const struct clk_init_data) {
238 .name = "disp_cc_mdss_dptx0_link_clk_src",
239 .parent_data = disp_cc_parent_data_4,
240 .num_parents = ARRAY_SIZE(disp_cc_parent_data_4),
241 .flags = CLK_SET_RATE_PARENT,
242 .ops = &clk_byte2_ops,
243 },
244 };
245
246 static struct clk_rcg2 disp_cc_mdss_dptx0_pixel0_clk_src = {
247 .cmd_rcgr = 0x80e8,
248 .mnd_width = 16,
249 .hid_width = 5,
250 .parent_map = disp_cc_parent_map_2,
251 .clkr.hw.init = &(const struct clk_init_data) {
252 .name = "disp_cc_mdss_dptx0_pixel0_clk_src",
253 .parent_data = disp_cc_parent_data_2,
254 .num_parents = ARRAY_SIZE(disp_cc_parent_data_2),
255 .flags = CLK_SET_RATE_PARENT,
256 .ops = &clk_dp_ops,
257 },
258 };
259
260 static struct clk_rcg2 disp_cc_mdss_dptx0_pixel1_clk_src = {
261 .cmd_rcgr = 0x8100,
262 .mnd_width = 16,
263 .hid_width = 5,
264 .parent_map = disp_cc_parent_map_2,
265 .clkr.hw.init = &(const struct clk_init_data) {
266 .name = "disp_cc_mdss_dptx0_pixel1_clk_src",
267 .parent_data = disp_cc_parent_data_2,
268 .num_parents = ARRAY_SIZE(disp_cc_parent_data_2),
269 .flags = CLK_SET_RATE_PARENT,
270 .ops = &clk_dp_ops,
271 },
272 };
273
274 static const struct freq_tbl ftbl_disp_cc_mdss_esc0_clk_src[] = {
275 F(9600000, P_BI_TCXO, 2, 0, 0),
276 F(12800000, P_BI_TCXO, 1.5, 0, 0),
277 F(19200000, P_BI_TCXO, 1, 0, 0),
278 { }
279 };
280 static struct clk_rcg2 disp_cc_mdss_esc0_clk_src = {
281 .cmd_rcgr = 0x80b4,
282 .mnd_width = 0,
283 .hid_width = 5,
284 .parent_map = disp_cc_parent_map_5,
285 .freq_tbl = ftbl_disp_cc_mdss_esc0_clk_src,
286 .clkr.hw.init = &(const struct clk_init_data) {
287 .name = "disp_cc_mdss_esc0_clk_src",
288 .parent_data = disp_cc_parent_data_5,
289 .num_parents = ARRAY_SIZE(disp_cc_parent_data_5),
290 .flags = CLK_SET_RATE_PARENT,
291 .ops = &clk_rcg2_ops,
292 },
293 };
294
295 static const struct freq_tbl ftbl_disp_cc_mdss_mdp_clk_src[] = {
296 F(19200000, P_BI_TCXO, 1, 0, 0),
297 F(85714286, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0),
298 F(100000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0),
299 F(200000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0),
300 F(342000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0),
301 F(402000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0),
302 F(535000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0),
303 F(600000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0),
304 F(630000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0),
305 { }
306 };
307
308 static struct clk_rcg2 disp_cc_mdss_mdp_clk_src = {
309 .cmd_rcgr = 0x8068,
310 .mnd_width = 0,
311 .hid_width = 5,
312 .parent_map = disp_cc_parent_map_6,
313 .freq_tbl = ftbl_disp_cc_mdss_mdp_clk_src,
314 .clkr.hw.init = &(const struct clk_init_data) {
315 .name = "disp_cc_mdss_mdp_clk_src",
316 .parent_data = disp_cc_parent_data_6,
317 .num_parents = ARRAY_SIZE(disp_cc_parent_data_6),
318 .flags = CLK_SET_RATE_PARENT,
319 .ops = &clk_rcg2_shared_ops,
320 },
321 };
322
323 static struct clk_rcg2 disp_cc_mdss_pclk0_clk_src = {
324 .cmd_rcgr = 0x8050,
325 .mnd_width = 8,
326 .hid_width = 5,
327 .parent_map = disp_cc_parent_map_1,
328 .clkr.hw.init = &(const struct clk_init_data) {
329 .name = "disp_cc_mdss_pclk0_clk_src",
330 .parent_data = disp_cc_parent_data_1,
331 .num_parents = ARRAY_SIZE(disp_cc_parent_data_1),
332 .flags = CLK_SET_RATE_PARENT,
333 .ops = &clk_pixel_ops,
334 },
335 };
336
337 static struct clk_rcg2 disp_cc_mdss_vsync_clk_src = {
338 .cmd_rcgr = 0x8080,
339 .mnd_width = 0,
340 .hid_width = 5,
341 .parent_map = disp_cc_parent_map_0,
342 .freq_tbl = ftbl_disp_cc_mdss_dptx0_aux_clk_src,
343 .clkr.hw.init = &(const struct clk_init_data) {
344 .name = "disp_cc_mdss_vsync_clk_src",
345 .parent_data = disp_cc_parent_data_0,
346 .num_parents = ARRAY_SIZE(disp_cc_parent_data_0),
347 .flags = CLK_SET_RATE_PARENT,
348 .ops = &clk_rcg2_ops,
349 },
350 };
351
352 static const struct freq_tbl ftbl_disp_cc_sleep_clk_src[] = {
353 F(32000, P_SLEEP_CLK, 1, 0, 0),
354 { }
355 };
356
357 static struct clk_rcg2 disp_cc_sleep_clk_src = {
358 .cmd_rcgr = 0xe054,
359 .mnd_width = 0,
360 .hid_width = 5,
361 .parent_map = disp_cc_parent_map_7,
362 .freq_tbl = ftbl_disp_cc_sleep_clk_src,
363 .clkr.hw.init = &(const struct clk_init_data) {
364 .name = "disp_cc_sleep_clk_src",
365 .parent_data = disp_cc_parent_data_7_ao,
366 .num_parents = ARRAY_SIZE(disp_cc_parent_data_7_ao),
367 .flags = CLK_SET_RATE_PARENT,
368 .ops = &clk_rcg2_ops,
369 },
370 };
371
372 static struct clk_rcg2 disp_cc_xo_clk_src = {
373 .cmd_rcgr = 0xe034,
374 .mnd_width = 0,
375 .hid_width = 5,
376 .parent_map = disp_cc_parent_map_0,
377 .freq_tbl = ftbl_disp_cc_mdss_dptx0_aux_clk_src,
378 .clkr.hw.init = &(const struct clk_init_data) {
379 .name = "disp_cc_xo_clk_src",
380 .parent_data = disp_cc_parent_data_0,
381 .num_parents = ARRAY_SIZE(disp_cc_parent_data_0),
382 .flags = CLK_SET_RATE_PARENT,
383 .ops = &clk_rcg2_ops,
384 },
385 };
386
387 static struct clk_regmap_div disp_cc_mdss_byte0_div_clk_src = {
388 .reg = 0x80b0,
389 .shift = 0,
390 .width = 4,
391 .clkr.hw.init = &(const struct clk_init_data) {
392 .name = "disp_cc_mdss_byte0_div_clk_src",
393 .parent_hws = (const struct clk_hw*[]) {
394 &disp_cc_mdss_byte0_clk_src.clkr.hw,
395 },
396 .num_parents = 1,
397 .flags = CLK_SET_RATE_PARENT,
398 .ops = &clk_regmap_div_ops,
399 },
400 };
401
402 static struct clk_regmap_div disp_cc_mdss_dptx0_link_div_clk_src = {
403 .reg = 0x80e4,
404 .shift = 0,
405 .width = 4,
406 .clkr.hw.init = &(const struct clk_init_data) {
407 .name = "disp_cc_mdss_dptx0_link_div_clk_src",
408 .parent_hws = (const struct clk_hw*[]) {
409 &disp_cc_mdss_dptx0_link_clk_src.clkr.hw,
410 },
411 .num_parents = 1,
412 .flags = CLK_SET_RATE_PARENT,
413 .ops = &clk_regmap_div_ro_ops,
414 },
415 };
416
417 static struct clk_branch disp_cc_mdss_accu_clk = {
418 .halt_reg = 0xe050,
419 .halt_check = BRANCH_HALT_VOTED,
420 .clkr = {
421 .enable_reg = 0xe050,
422 .enable_mask = BIT(0),
423 .hw.init = &(const struct clk_init_data) {
424 .name = "disp_cc_mdss_accu_clk",
425 .parent_hws = (const struct clk_hw*[]) {
426 &disp_cc_xo_clk_src.clkr.hw,
427 },
428 .num_parents = 1,
429 .flags = CLK_SET_RATE_PARENT,
430 .ops = &clk_branch2_ops,
431 },
432 },
433 };
434
435 static struct clk_branch disp_cc_mdss_ahb1_clk = {
436 .halt_reg = 0xa020,
437 .halt_check = BRANCH_HALT,
438 .clkr = {
439 .enable_reg = 0xa020,
440 .enable_mask = BIT(0),
441 .hw.init = &(const struct clk_init_data) {
442 .name = "disp_cc_mdss_ahb1_clk",
443 .parent_hws = (const struct clk_hw*[]) {
444 &disp_cc_mdss_ahb_clk_src.clkr.hw,
445 },
446 .num_parents = 1,
447 .flags = CLK_SET_RATE_PARENT,
448 .ops = &clk_branch2_ops,
449 },
450 },
451 };
452
453 static struct clk_branch disp_cc_mdss_ahb_clk = {
454 .halt_reg = 0x804c,
455 .halt_check = BRANCH_HALT,
456 .clkr = {
457 .enable_reg = 0x804c,
458 .enable_mask = BIT(0),
459 .hw.init = &(const struct clk_init_data) {
460 .name = "disp_cc_mdss_ahb_clk",
461 .parent_hws = (const struct clk_hw*[]) {
462 &disp_cc_mdss_ahb_clk_src.clkr.hw,
463 },
464 .num_parents = 1,
465 .flags = CLK_SET_RATE_PARENT,
466 .ops = &clk_branch2_ops,
467 },
468 },
469 };
470
471 static struct clk_branch disp_cc_mdss_byte0_clk = {
472 .halt_reg = 0x8024,
473 .halt_check = BRANCH_HALT,
474 .clkr = {
475 .enable_reg = 0x8024,
476 .enable_mask = BIT(0),
477 .hw.init = &(const struct clk_init_data) {
478 .name = "disp_cc_mdss_byte0_clk",
479 .parent_hws = (const struct clk_hw*[]) {
480 &disp_cc_mdss_byte0_clk_src.clkr.hw,
481 },
482 .num_parents = 1,
483 .flags = CLK_SET_RATE_PARENT,
484 .ops = &clk_branch2_ops,
485 },
486 },
487 };
488
489 static struct clk_branch disp_cc_mdss_byte0_intf_clk = {
490 .halt_reg = 0x8028,
491 .halt_check = BRANCH_HALT,
492 .clkr = {
493 .enable_reg = 0x8028,
494 .enable_mask = BIT(0),
495 .hw.init = &(const struct clk_init_data) {
496 .name = "disp_cc_mdss_byte0_intf_clk",
497 .parent_hws = (const struct clk_hw*[]) {
498 &disp_cc_mdss_byte0_div_clk_src.clkr.hw,
499 },
500 .num_parents = 1,
501 .flags = CLK_SET_RATE_PARENT,
502 .ops = &clk_branch2_ops,
503 },
504 },
505 };
506
507 static struct clk_branch disp_cc_mdss_dptx0_aux_clk = {
508 .halt_reg = 0x8048,
509 .halt_check = BRANCH_HALT,
510 .clkr = {
511 .enable_reg = 0x8048,
512 .enable_mask = BIT(0),
513 .hw.init = &(const struct clk_init_data) {
514 .name = "disp_cc_mdss_dptx0_aux_clk",
515 .parent_hws = (const struct clk_hw*[]) {
516 &disp_cc_mdss_dptx0_aux_clk_src.clkr.hw,
517 },
518 .num_parents = 1,
519 .flags = CLK_SET_RATE_PARENT,
520 .ops = &clk_branch2_ops,
521 },
522 },
523 };
524
525 static struct clk_branch disp_cc_mdss_dptx0_crypto_clk = {
526 .halt_reg = 0x803c,
527 .halt_check = BRANCH_HALT,
528 .clkr = {
529 .enable_reg = 0x803c,
530 .enable_mask = BIT(0),
531 .hw.init = &(const struct clk_init_data) {
532 .name = "disp_cc_mdss_dptx0_crypto_clk",
533 .parent_hws = (const struct clk_hw*[]) {
534 &disp_cc_mdss_dptx0_link_clk_src.clkr.hw,
535 },
536 .num_parents = 1,
537 .flags = CLK_SET_RATE_PARENT,
538 .ops = &clk_branch2_ops,
539 },
540 },
541 };
542
543 static struct clk_branch disp_cc_mdss_dptx0_link_clk = {
544 .halt_reg = 0x8030,
545 .halt_check = BRANCH_HALT,
546 .clkr = {
547 .enable_reg = 0x8030,
548 .enable_mask = BIT(0),
549 .hw.init = &(const struct clk_init_data) {
550 .name = "disp_cc_mdss_dptx0_link_clk",
551 .parent_hws = (const struct clk_hw*[]) {
552 &disp_cc_mdss_dptx0_link_clk_src.clkr.hw,
553 },
554 .num_parents = 1,
555 .flags = CLK_SET_RATE_PARENT,
556 .ops = &clk_branch2_ops,
557 },
558 },
559 };
560
561 static struct clk_branch disp_cc_mdss_dptx0_link_intf_clk = {
562 .halt_reg = 0x8038,
563 .halt_check = BRANCH_HALT,
564 .clkr = {
565 .enable_reg = 0x8038,
566 .enable_mask = BIT(0),
567 .hw.init = &(const struct clk_init_data) {
568 .name = "disp_cc_mdss_dptx0_link_intf_clk",
569 .parent_hws = (const struct clk_hw*[]) {
570 &disp_cc_mdss_dptx0_link_div_clk_src.clkr.hw,
571 },
572 .num_parents = 1,
573 .flags = CLK_SET_RATE_PARENT,
574 .ops = &clk_branch2_ops,
575 },
576 },
577 };
578
579 static struct clk_branch disp_cc_mdss_dptx0_pixel0_clk = {
580 .halt_reg = 0x8040,
581 .halt_check = BRANCH_HALT,
582 .clkr = {
583 .enable_reg = 0x8040,
584 .enable_mask = BIT(0),
585 .hw.init = &(const struct clk_init_data) {
586 .name = "disp_cc_mdss_dptx0_pixel0_clk",
587 .parent_hws = (const struct clk_hw*[]) {
588 &disp_cc_mdss_dptx0_pixel0_clk_src.clkr.hw,
589 },
590 .num_parents = 1,
591 .flags = CLK_SET_RATE_PARENT,
592 .ops = &clk_branch2_ops,
593 },
594 },
595 };
596
597 static struct clk_branch disp_cc_mdss_dptx0_pixel1_clk = {
598 .halt_reg = 0x8044,
599 .halt_check = BRANCH_HALT,
600 .clkr = {
601 .enable_reg = 0x8044,
602 .enable_mask = BIT(0),
603 .hw.init = &(const struct clk_init_data) {
604 .name = "disp_cc_mdss_dptx0_pixel1_clk",
605 .parent_hws = (const struct clk_hw*[]) {
606 &disp_cc_mdss_dptx0_pixel1_clk_src.clkr.hw,
607 },
608 .num_parents = 1,
609 .flags = CLK_SET_RATE_PARENT,
610 .ops = &clk_branch2_ops,
611 },
612 },
613 };
614
615 static struct clk_branch disp_cc_mdss_dptx0_usb_router_link_intf_clk = {
616 .halt_reg = 0x8034,
617 .halt_check = BRANCH_HALT,
618 .clkr = {
619 .enable_reg = 0x8034,
620 .enable_mask = BIT(0),
621 .hw.init = &(const struct clk_init_data) {
622 .name = "disp_cc_mdss_dptx0_usb_router_link_intf_clk",
623 .parent_hws = (const struct clk_hw*[]) {
624 &disp_cc_mdss_dptx0_link_div_clk_src.clkr.hw,
625 },
626 .num_parents = 1,
627 .flags = CLK_SET_RATE_PARENT,
628 .ops = &clk_branch2_ops,
629 },
630 },
631 };
632
633 static struct clk_branch disp_cc_mdss_esc0_clk = {
634 .halt_reg = 0x802c,
635 .halt_check = BRANCH_HALT,
636 .clkr = {
637 .enable_reg = 0x802c,
638 .enable_mask = BIT(0),
639 .hw.init = &(const struct clk_init_data) {
640 .name = "disp_cc_mdss_esc0_clk",
641 .parent_hws = (const struct clk_hw*[]) {
642 &disp_cc_mdss_esc0_clk_src.clkr.hw,
643 },
644 .num_parents = 1,
645 .flags = CLK_SET_RATE_PARENT,
646 .ops = &clk_branch2_ops,
647 },
648 },
649 };
650
651 static struct clk_branch disp_cc_mdss_mdp1_clk = {
652 .halt_reg = 0xa004,
653 .halt_check = BRANCH_HALT,
654 .clkr = {
655 .enable_reg = 0xa004,
656 .enable_mask = BIT(0),
657 .hw.init = &(const struct clk_init_data) {
658 .name = "disp_cc_mdss_mdp1_clk",
659 .parent_hws = (const struct clk_hw*[]) {
660 &disp_cc_mdss_mdp_clk_src.clkr.hw,
661 },
662 .num_parents = 1,
663 .flags = CLK_SET_RATE_PARENT,
664 .ops = &clk_branch2_ops,
665 },
666 },
667 };
668
669 static struct clk_branch disp_cc_mdss_mdp_clk = {
670 .halt_reg = 0x8008,
671 .halt_check = BRANCH_HALT,
672 .clkr = {
673 .enable_reg = 0x8008,
674 .enable_mask = BIT(0),
675 .hw.init = &(const struct clk_init_data) {
676 .name = "disp_cc_mdss_mdp_clk",
677 .parent_hws = (const struct clk_hw*[]) {
678 &disp_cc_mdss_mdp_clk_src.clkr.hw,
679 },
680 .num_parents = 1,
681 .flags = CLK_SET_RATE_PARENT,
682 .ops = &clk_branch2_ops,
683 },
684 },
685 };
686
687 static struct clk_branch disp_cc_mdss_mdp_lut1_clk = {
688 .halt_reg = 0xa010,
689 .halt_check = BRANCH_HALT,
690 .clkr = {
691 .enable_reg = 0xa010,
692 .enable_mask = BIT(0),
693 .hw.init = &(const struct clk_init_data) {
694 .name = "disp_cc_mdss_mdp_lut1_clk",
695 .parent_hws = (const struct clk_hw*[]) {
696 &disp_cc_mdss_mdp_clk_src.clkr.hw,
697 },
698 .num_parents = 1,
699 .flags = CLK_SET_RATE_PARENT,
700 .ops = &clk_branch2_ops,
701 },
702 },
703 };
704
705 static struct clk_branch disp_cc_mdss_mdp_lut_clk = {
706 .halt_reg = 0x8014,
707 .halt_check = BRANCH_HALT_VOTED,
708 .clkr = {
709 .enable_reg = 0x8014,
710 .enable_mask = BIT(0),
711 .hw.init = &(const struct clk_init_data) {
712 .name = "disp_cc_mdss_mdp_lut_clk",
713 .parent_hws = (const struct clk_hw*[]) {
714 &disp_cc_mdss_mdp_clk_src.clkr.hw,
715 },
716 .num_parents = 1,
717 .flags = CLK_SET_RATE_PARENT,
718 .ops = &clk_branch2_ops,
719 },
720 },
721 };
722
723 static struct clk_branch disp_cc_mdss_non_gdsc_ahb_clk = {
724 .halt_reg = 0xc004,
725 .halt_check = BRANCH_HALT_VOTED,
726 .clkr = {
727 .enable_reg = 0xc004,
728 .enable_mask = BIT(0),
729 .hw.init = &(const struct clk_init_data) {
730 .name = "disp_cc_mdss_non_gdsc_ahb_clk",
731 .parent_hws = (const struct clk_hw*[]) {
732 &disp_cc_mdss_ahb_clk_src.clkr.hw,
733 },
734 .num_parents = 1,
735 .flags = CLK_SET_RATE_PARENT,
736 .ops = &clk_branch2_ops,
737 },
738 },
739 };
740
741 static struct clk_branch disp_cc_mdss_pclk0_clk = {
742 .halt_reg = 0x8004,
743 .halt_check = BRANCH_HALT,
744 .clkr = {
745 .enable_reg = 0x8004,
746 .enable_mask = BIT(0),
747 .hw.init = &(const struct clk_init_data) {
748 .name = "disp_cc_mdss_pclk0_clk",
749 .parent_hws = (const struct clk_hw*[]) {
750 &disp_cc_mdss_pclk0_clk_src.clkr.hw,
751 },
752 .num_parents = 1,
753 .flags = CLK_SET_RATE_PARENT,
754 .ops = &clk_branch2_ops,
755 },
756 },
757 };
758
759 static struct clk_branch disp_cc_mdss_rscc_ahb_clk = {
760 .halt_reg = 0xc00c,
761 .halt_check = BRANCH_HALT,
762 .clkr = {
763 .enable_reg = 0xc00c,
764 .enable_mask = BIT(0),
765 .hw.init = &(const struct clk_init_data) {
766 .name = "disp_cc_mdss_rscc_ahb_clk",
767 .parent_hws = (const struct clk_hw*[]) {
768 &disp_cc_mdss_ahb_clk_src.clkr.hw,
769 },
770 .num_parents = 1,
771 .flags = CLK_SET_RATE_PARENT,
772 .ops = &clk_branch2_ops,
773 },
774 },
775 };
776
777 static struct clk_branch disp_cc_mdss_rscc_vsync_clk = {
778 .halt_reg = 0xc008,
779 .halt_check = BRANCH_HALT,
780 .clkr = {
781 .enable_reg = 0xc008,
782 .enable_mask = BIT(0),
783 .hw.init = &(const struct clk_init_data) {
784 .name = "disp_cc_mdss_rscc_vsync_clk",
785 .parent_hws = (const struct clk_hw*[]) {
786 &disp_cc_mdss_vsync_clk_src.clkr.hw,
787 },
788 .num_parents = 1,
789 .flags = CLK_SET_RATE_PARENT,
790 .ops = &clk_branch2_ops,
791 },
792 },
793 };
794
795 static struct clk_branch disp_cc_mdss_vsync1_clk = {
796 .halt_reg = 0xa01c,
797 .halt_check = BRANCH_HALT,
798 .clkr = {
799 .enable_reg = 0xa01c,
800 .enable_mask = BIT(0),
801 .hw.init = &(const struct clk_init_data) {
802 .name = "disp_cc_mdss_vsync1_clk",
803 .parent_hws = (const struct clk_hw*[]) {
804 &disp_cc_mdss_vsync_clk_src.clkr.hw,
805 },
806 .num_parents = 1,
807 .flags = CLK_SET_RATE_PARENT,
808 .ops = &clk_branch2_ops,
809 },
810 },
811 };
812
813 static struct clk_branch disp_cc_mdss_vsync_clk = {
814 .halt_reg = 0x8020,
815 .halt_check = BRANCH_HALT,
816 .clkr = {
817 .enable_reg = 0x8020,
818 .enable_mask = BIT(0),
819 .hw.init = &(const struct clk_init_data) {
820 .name = "disp_cc_mdss_vsync_clk",
821 .parent_hws = (const struct clk_hw*[]) {
822 &disp_cc_mdss_vsync_clk_src.clkr.hw,
823 },
824 .num_parents = 1,
825 .flags = CLK_SET_RATE_PARENT,
826 .ops = &clk_branch2_ops,
827 },
828 },
829 };
830
831 static struct gdsc disp_cc_mdss_core_gdsc = {
832 .gdscr = 0x9000,
833 .en_rest_wait_val = 0x2,
834 .en_few_wait_val = 0x2,
835 .clk_dis_wait_val = 0xf,
836 .pd = {
837 .name = "disp_cc_mdss_core_gdsc",
838 },
839 .pwrsts = PWRSTS_OFF_ON,
840 .flags = POLL_CFG_GDSCR | HW_CTRL | RETAIN_FF_ENABLE,
841 };
842
843 static struct gdsc disp_cc_mdss_core_int2_gdsc = {
844 .gdscr = 0xb000,
845 .en_rest_wait_val = 0x2,
846 .en_few_wait_val = 0x2,
847 .clk_dis_wait_val = 0xf,
848 .pd = {
849 .name = "disp_cc_mdss_core_int2_gdsc",
850 },
851 .pwrsts = PWRSTS_OFF_ON,
852 .flags = POLL_CFG_GDSCR | HW_CTRL | RETAIN_FF_ENABLE,
853 };
854
855 static struct clk_regmap *disp_cc_milos_clocks[] = {
856 [DISP_CC_MDSS_ACCU_CLK] = &disp_cc_mdss_accu_clk.clkr,
857 [DISP_CC_MDSS_AHB1_CLK] = &disp_cc_mdss_ahb1_clk.clkr,
858 [DISP_CC_MDSS_AHB_CLK] = &disp_cc_mdss_ahb_clk.clkr,
859 [DISP_CC_MDSS_AHB_CLK_SRC] = &disp_cc_mdss_ahb_clk_src.clkr,
860 [DISP_CC_MDSS_BYTE0_CLK] = &disp_cc_mdss_byte0_clk.clkr,
861 [DISP_CC_MDSS_BYTE0_CLK_SRC] = &disp_cc_mdss_byte0_clk_src.clkr,
862 [DISP_CC_MDSS_BYTE0_DIV_CLK_SRC] = &disp_cc_mdss_byte0_div_clk_src.clkr,
863 [DISP_CC_MDSS_BYTE0_INTF_CLK] = &disp_cc_mdss_byte0_intf_clk.clkr,
864 [DISP_CC_MDSS_DPTX0_AUX_CLK] = &disp_cc_mdss_dptx0_aux_clk.clkr,
865 [DISP_CC_MDSS_DPTX0_AUX_CLK_SRC] = &disp_cc_mdss_dptx0_aux_clk_src.clkr,
866 [DISP_CC_MDSS_DPTX0_CRYPTO_CLK] = &disp_cc_mdss_dptx0_crypto_clk.clkr,
867 [DISP_CC_MDSS_DPTX0_LINK_CLK] = &disp_cc_mdss_dptx0_link_clk.clkr,
868 [DISP_CC_MDSS_DPTX0_LINK_CLK_SRC] = &disp_cc_mdss_dptx0_link_clk_src.clkr,
869 [DISP_CC_MDSS_DPTX0_LINK_DIV_CLK_SRC] = &disp_cc_mdss_dptx0_link_div_clk_src.clkr,
870 [DISP_CC_MDSS_DPTX0_LINK_INTF_CLK] = &disp_cc_mdss_dptx0_link_intf_clk.clkr,
871 [DISP_CC_MDSS_DPTX0_PIXEL0_CLK] = &disp_cc_mdss_dptx0_pixel0_clk.clkr,
872 [DISP_CC_MDSS_DPTX0_PIXEL0_CLK_SRC] = &disp_cc_mdss_dptx0_pixel0_clk_src.clkr,
873 [DISP_CC_MDSS_DPTX0_PIXEL1_CLK] = &disp_cc_mdss_dptx0_pixel1_clk.clkr,
874 [DISP_CC_MDSS_DPTX0_PIXEL1_CLK_SRC] = &disp_cc_mdss_dptx0_pixel1_clk_src.clkr,
875 [DISP_CC_MDSS_DPTX0_USB_ROUTER_LINK_INTF_CLK] =
876 &disp_cc_mdss_dptx0_usb_router_link_intf_clk.clkr,
877 [DISP_CC_MDSS_ESC0_CLK] = &disp_cc_mdss_esc0_clk.clkr,
878 [DISP_CC_MDSS_ESC0_CLK_SRC] = &disp_cc_mdss_esc0_clk_src.clkr,
879 [DISP_CC_MDSS_MDP1_CLK] = &disp_cc_mdss_mdp1_clk.clkr,
880 [DISP_CC_MDSS_MDP_CLK] = &disp_cc_mdss_mdp_clk.clkr,
881 [DISP_CC_MDSS_MDP_CLK_SRC] = &disp_cc_mdss_mdp_clk_src.clkr,
882 [DISP_CC_MDSS_MDP_LUT1_CLK] = &disp_cc_mdss_mdp_lut1_clk.clkr,
883 [DISP_CC_MDSS_MDP_LUT_CLK] = &disp_cc_mdss_mdp_lut_clk.clkr,
884 [DISP_CC_MDSS_NON_GDSC_AHB_CLK] = &disp_cc_mdss_non_gdsc_ahb_clk.clkr,
885 [DISP_CC_MDSS_PCLK0_CLK] = &disp_cc_mdss_pclk0_clk.clkr,
886 [DISP_CC_MDSS_PCLK0_CLK_SRC] = &disp_cc_mdss_pclk0_clk_src.clkr,
887 [DISP_CC_MDSS_RSCC_AHB_CLK] = &disp_cc_mdss_rscc_ahb_clk.clkr,
888 [DISP_CC_MDSS_RSCC_VSYNC_CLK] = &disp_cc_mdss_rscc_vsync_clk.clkr,
889 [DISP_CC_MDSS_VSYNC1_CLK] = &disp_cc_mdss_vsync1_clk.clkr,
890 [DISP_CC_MDSS_VSYNC_CLK] = &disp_cc_mdss_vsync_clk.clkr,
891 [DISP_CC_MDSS_VSYNC_CLK_SRC] = &disp_cc_mdss_vsync_clk_src.clkr,
892 [DISP_CC_PLL0] = &disp_cc_pll0.clkr,
893 [DISP_CC_SLEEP_CLK_SRC] = &disp_cc_sleep_clk_src.clkr,
894 [DISP_CC_XO_CLK_SRC] = &disp_cc_xo_clk_src.clkr,
895 };
896
897 static const struct qcom_reset_map disp_cc_milos_resets[] = {
898 [DISP_CC_MDSS_CORE_BCR] = { 0x8000 },
899 [DISP_CC_MDSS_CORE_INT2_BCR] = { 0xa000 },
900 [DISP_CC_MDSS_RSCC_BCR] = { 0xc000 },
901 };
902
903 static struct gdsc *disp_cc_milos_gdscs[] = {
904 [DISP_CC_MDSS_CORE_GDSC] = &disp_cc_mdss_core_gdsc,
905 [DISP_CC_MDSS_CORE_INT2_GDSC] = &disp_cc_mdss_core_int2_gdsc,
906 };
907
908 static struct clk_alpha_pll *disp_cc_milos_plls[] = {
909 &disp_cc_pll0,
910 };
911
912 static u32 disp_cc_milos_critical_cbcrs[] = {
913 0xe06c, /* DISP_CC_SLEEP_CLK */
914 0xe04c, /* DISP_CC_XO_CLK */
915 };
916
917 static const struct regmap_config disp_cc_milos_regmap_config = {
918 .reg_bits = 32,
919 .reg_stride = 4,
920 .val_bits = 32,
921 .max_register = 0x11008,
922 .fast_io = true,
923 };
924
disp_cc_milos_clk_regs_configure(struct device * dev,struct regmap * regmap)925 static void disp_cc_milos_clk_regs_configure(struct device *dev, struct regmap *regmap)
926 {
927 /* Enable clock gating for MDP clocks */
928 regmap_update_bits(regmap, DISP_CC_MISC_CMD, 0x10, 0x10);
929 }
930
931
932 static struct qcom_cc_driver_data disp_cc_milos_driver_data = {
933 .alpha_plls = disp_cc_milos_plls,
934 .num_alpha_plls = ARRAY_SIZE(disp_cc_milos_plls),
935 .clk_cbcrs = disp_cc_milos_critical_cbcrs,
936 .num_clk_cbcrs = ARRAY_SIZE(disp_cc_milos_critical_cbcrs),
937 .clk_regs_configure = disp_cc_milos_clk_regs_configure,
938 };
939
940 static const struct qcom_cc_desc disp_cc_milos_desc = {
941 .config = &disp_cc_milos_regmap_config,
942 .clks = disp_cc_milos_clocks,
943 .num_clks = ARRAY_SIZE(disp_cc_milos_clocks),
944 .resets = disp_cc_milos_resets,
945 .num_resets = ARRAY_SIZE(disp_cc_milos_resets),
946 .gdscs = disp_cc_milos_gdscs,
947 .num_gdscs = ARRAY_SIZE(disp_cc_milos_gdscs),
948 .use_rpm = true,
949 .driver_data = &disp_cc_milos_driver_data,
950 };
951
952 static const struct of_device_id disp_cc_milos_match_table[] = {
953 { .compatible = "qcom,milos-dispcc" },
954 { }
955 };
956 MODULE_DEVICE_TABLE(of, disp_cc_milos_match_table);
957
disp_cc_milos_probe(struct platform_device * pdev)958 static int disp_cc_milos_probe(struct platform_device *pdev)
959 {
960 return qcom_cc_probe(pdev, &disp_cc_milos_desc);
961 }
962
963 static struct platform_driver disp_cc_milos_driver = {
964 .probe = disp_cc_milos_probe,
965 .driver = {
966 .name = "disp_cc-milos",
967 .of_match_table = disp_cc_milos_match_table,
968 },
969 };
970
971 module_platform_driver(disp_cc_milos_driver);
972
973 MODULE_DESCRIPTION("QTI DISP_CC Milos Driver");
974 MODULE_LICENSE("GPL");
975