xref: /linux/drivers/clk/qcom/dispcc-milos.c (revision 8d2b0853add1d7534dc0794e3c8e0b9e8c4ec640)
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 
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 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 
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