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