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