1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Copyright (c) 2021, The Linux Foundation. All rights reserved.
4 * Copyright (c) 2021, Konrad Dybcio <konrad.dybcio@somainline.org>
5 */
6
7#include <linux/clk-provider.h>
8#include <linux/module.h>
9#include <linux/platform_device.h>
10#include <linux/regmap.h>
11
12#include <dt-bindings/clock/qcom,dispcc-sm6350.h>
13
14#include "clk-alpha-pll.h"
15#include "clk-branch.h"
16#include "clk-rcg.h"
17#include "clk-regmap.h"
18#include "clk-regmap-divider.h"
19#include "common.h"
20#include "gdsc.h"
21#include "reset.h"
22
23enum {
24	P_BI_TCXO,
25	P_DISP_CC_PLL0_OUT_EVEN,
26	P_DISP_CC_PLL0_OUT_MAIN,
27	P_DP_PHY_PLL_LINK_CLK,
28	P_DP_PHY_PLL_VCO_DIV_CLK,
29	P_DSI0_PHY_PLL_OUT_BYTECLK,
30	P_DSI0_PHY_PLL_OUT_DSICLK,
31	P_GCC_DISP_GPLL0_CLK,
32};
33
34static struct pll_vco fabia_vco[] = {
35	{ 249600000, 2000000000, 0 },
36};
37
38static const struct alpha_pll_config disp_cc_pll0_config = {
39	.l = 0x3a,
40	.alpha = 0x5555,
41	.config_ctl_val = 0x20485699,
42	.config_ctl_hi_val = 0x00002067,
43	.test_ctl_val = 0x40000000,
44	.test_ctl_hi_val = 0x00000002,
45	.user_ctl_val = 0x00000000,
46	.user_ctl_hi_val = 0x00004805,
47};
48
49static struct clk_alpha_pll disp_cc_pll0 = {
50	.offset = 0x0,
51	.vco_table = fabia_vco,
52	.num_vco = ARRAY_SIZE(fabia_vco),
53	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
54	.clkr = {
55		.hw.init = &(struct clk_init_data){
56			.name = "disp_cc_pll0",
57			.parent_data = &(const struct clk_parent_data){
58				.fw_name = "bi_tcxo",
59			},
60			.num_parents = 1,
61			.ops = &clk_alpha_pll_fabia_ops,
62		},
63	},
64};
65
66static const struct parent_map disp_cc_parent_map_0[] = {
67	{ P_BI_TCXO, 0 },
68	{ P_DP_PHY_PLL_LINK_CLK, 1 },
69	{ P_DP_PHY_PLL_VCO_DIV_CLK, 2 },
70};
71
72static const struct clk_parent_data disp_cc_parent_data_0[] = {
73	{ .fw_name = "bi_tcxo" },
74	{ .fw_name = "dp_phy_pll_link_clk" },
75	{ .fw_name = "dp_phy_pll_vco_div_clk" },
76};
77
78static const struct parent_map disp_cc_parent_map_1[] = {
79	{ P_BI_TCXO, 0 },
80	{ P_DSI0_PHY_PLL_OUT_BYTECLK, 1 },
81};
82
83static const struct clk_parent_data disp_cc_parent_data_1[] = {
84	{ .fw_name = "bi_tcxo" },
85	{ .fw_name = "dsi0_phy_pll_out_byteclk" },
86};
87
88static const struct parent_map disp_cc_parent_map_3[] = {
89	{ P_BI_TCXO, 0 },
90	{ P_DISP_CC_PLL0_OUT_MAIN, 1 },
91	{ P_GCC_DISP_GPLL0_CLK, 4 },
92	{ P_DISP_CC_PLL0_OUT_EVEN, 5 },
93};
94
95static const struct clk_parent_data disp_cc_parent_data_3[] = {
96	{ .fw_name = "bi_tcxo" },
97	{ .hw = &disp_cc_pll0.clkr.hw },
98	{ .fw_name = "gcc_disp_gpll0_clk" },
99	{ .hw = &disp_cc_pll0.clkr.hw },
100};
101
102static const struct parent_map disp_cc_parent_map_4[] = {
103	{ P_BI_TCXO, 0 },
104	{ P_GCC_DISP_GPLL0_CLK, 4 },
105};
106
107static const struct clk_parent_data disp_cc_parent_data_4[] = {
108	{ .fw_name = "bi_tcxo" },
109	{ .fw_name = "gcc_disp_gpll0_clk" },
110};
111
112static const struct parent_map disp_cc_parent_map_5[] = {
113	{ P_BI_TCXO, 0 },
114	{ P_DSI0_PHY_PLL_OUT_DSICLK, 1 },
115};
116
117static const struct clk_parent_data disp_cc_parent_data_5[] = {
118	{ .fw_name = "bi_tcxo" },
119	{ .fw_name = "dsi0_phy_pll_out_dsiclk" },
120};
121
122static const struct parent_map disp_cc_parent_map_6[] = {
123	{ P_BI_TCXO, 0 },
124};
125
126static const struct clk_parent_data disp_cc_parent_data_6[] = {
127	{ .fw_name = "bi_tcxo" },
128};
129
130static const struct freq_tbl ftbl_disp_cc_mdss_ahb_clk_src[] = {
131	F(19200000, P_BI_TCXO, 1, 0, 0),
132	F(37500000, P_GCC_DISP_GPLL0_CLK, 16, 0, 0),
133	F(75000000, P_GCC_DISP_GPLL0_CLK, 8, 0, 0),
134	{ }
135};
136
137static struct clk_rcg2 disp_cc_mdss_ahb_clk_src = {
138	.cmd_rcgr = 0x115c,
139	.mnd_width = 0,
140	.hid_width = 5,
141	.parent_map = disp_cc_parent_map_4,
142	.freq_tbl = ftbl_disp_cc_mdss_ahb_clk_src,
143	.clkr.hw.init = &(struct clk_init_data){
144		.name = "disp_cc_mdss_ahb_clk_src",
145		.parent_data = disp_cc_parent_data_4,
146		.num_parents = ARRAY_SIZE(disp_cc_parent_data_4),
147		.flags = CLK_SET_RATE_PARENT,
148		.ops = &clk_rcg2_ops,
149	},
150};
151
152static struct clk_rcg2 disp_cc_mdss_byte0_clk_src = {
153	.cmd_rcgr = 0x10c4,
154	.mnd_width = 0,
155	.hid_width = 5,
156	.parent_map = disp_cc_parent_map_1,
157	.clkr.hw.init = &(struct clk_init_data){
158		.name = "disp_cc_mdss_byte0_clk_src",
159		.parent_data = disp_cc_parent_data_1,
160		.num_parents = ARRAY_SIZE(disp_cc_parent_data_1),
161		.flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE,
162		.ops = &clk_byte2_ops,
163	},
164};
165
166static struct clk_regmap_div disp_cc_mdss_byte0_div_clk_src = {
167	.reg = 0x10dc,
168	.shift = 0,
169	.width = 2,
170	.clkr.hw.init = &(struct clk_init_data) {
171		.name = "disp_cc_mdss_byte0_div_clk_src",
172		.parent_hws = (const struct clk_hw*[]){
173			&disp_cc_mdss_byte0_clk_src.clkr.hw,
174		},
175		.num_parents = 1,
176		.flags = CLK_GET_RATE_NOCACHE,
177		.ops = &clk_regmap_div_ro_ops,
178	},
179};
180
181static const struct freq_tbl ftbl_disp_cc_mdss_dp_aux_clk_src[] = {
182	F(19200000, P_BI_TCXO, 1, 0, 0),
183	{ }
184};
185
186static struct clk_rcg2 disp_cc_mdss_dp_aux_clk_src = {
187	.cmd_rcgr = 0x1144,
188	.mnd_width = 0,
189	.hid_width = 5,
190	.freq_tbl = ftbl_disp_cc_mdss_dp_aux_clk_src,
191	.clkr.hw.init = &(struct clk_init_data){
192		.name = "disp_cc_mdss_dp_aux_clk_src",
193		.parent_data = &(const struct clk_parent_data){
194			.fw_name = "bi_tcxo",
195		},
196		.num_parents = 1,
197		.ops = &clk_rcg2_ops,
198	},
199};
200
201static const struct freq_tbl ftbl_disp_cc_mdss_dp_crypto_clk_src[] = {
202	F(108000, P_DP_PHY_PLL_LINK_CLK, 3, 0, 0),
203	F(180000, P_DP_PHY_PLL_LINK_CLK, 3, 0, 0),
204	F(360000, P_DP_PHY_PLL_LINK_CLK, 1.5, 0, 0),
205	F(540000, P_DP_PHY_PLL_LINK_CLK, 1.5, 0, 0),
206	{ }
207};
208
209static struct clk_rcg2 disp_cc_mdss_dp_crypto_clk_src = {
210	.cmd_rcgr = 0x1114,
211	.mnd_width = 0,
212	.hid_width = 5,
213	.parent_map = disp_cc_parent_map_0,
214	.freq_tbl = ftbl_disp_cc_mdss_dp_crypto_clk_src,
215	.clkr.hw.init = &(struct clk_init_data){
216		.name = "disp_cc_mdss_dp_crypto_clk_src",
217		.parent_data = disp_cc_parent_data_0,
218		.num_parents = ARRAY_SIZE(disp_cc_parent_data_0),
219		.flags = CLK_GET_RATE_NOCACHE,
220		.ops = &clk_rcg2_ops,
221	},
222};
223
224static const struct freq_tbl ftbl_disp_cc_mdss_dp_link_clk_src[] = {
225	F(162000, P_DP_PHY_PLL_LINK_CLK, 1, 0, 0),
226	F(270000, P_DP_PHY_PLL_LINK_CLK, 1, 0, 0),
227	F(540000, P_DP_PHY_PLL_LINK_CLK, 1, 0, 0),
228	F(810000, P_DP_PHY_PLL_LINK_CLK, 1, 0, 0),
229	{ }
230};
231
232static struct clk_rcg2 disp_cc_mdss_dp_link_clk_src = {
233	.cmd_rcgr = 0x10f8,
234	.mnd_width = 0,
235	.hid_width = 5,
236	.parent_map = disp_cc_parent_map_0,
237	.freq_tbl = ftbl_disp_cc_mdss_dp_link_clk_src,
238	.clkr.hw.init = &(struct clk_init_data){
239		.name = "disp_cc_mdss_dp_link_clk_src",
240		.parent_data = disp_cc_parent_data_0,
241		.num_parents = ARRAY_SIZE(disp_cc_parent_data_0),
242		.flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE,
243		.ops = &clk_rcg2_ops,
244	},
245};
246
247static struct clk_rcg2 disp_cc_mdss_dp_pixel_clk_src = {
248	.cmd_rcgr = 0x112c,
249	.mnd_width = 16,
250	.hid_width = 5,
251	.parent_map = disp_cc_parent_map_0,
252	.clkr.hw.init = &(struct clk_init_data){
253		.name = "disp_cc_mdss_dp_pixel_clk_src",
254		.parent_data = disp_cc_parent_data_0,
255		.num_parents = ARRAY_SIZE(disp_cc_parent_data_0),
256		.flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE,
257		.ops = &clk_dp_ops,
258	},
259};
260
261static struct clk_rcg2 disp_cc_mdss_esc0_clk_src = {
262	.cmd_rcgr = 0x10e0,
263	.mnd_width = 0,
264	.hid_width = 5,
265	.parent_map = disp_cc_parent_map_1,
266	.freq_tbl = ftbl_disp_cc_mdss_dp_aux_clk_src,
267	.clkr.hw.init = &(struct clk_init_data){
268		.name = "disp_cc_mdss_esc0_clk_src",
269		.parent_data = disp_cc_parent_data_1,
270		.num_parents = ARRAY_SIZE(disp_cc_parent_data_1),
271		.ops = &clk_rcg2_ops,
272	},
273};
274
275static const struct freq_tbl ftbl_disp_cc_mdss_mdp_clk_src[] = {
276	F(19200000, P_BI_TCXO, 1, 0, 0),
277	F(200000000, P_GCC_DISP_GPLL0_CLK, 3, 0, 0),
278	F(300000000, P_GCC_DISP_GPLL0_CLK, 2, 0, 0),
279	F(373333333, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0),
280	F(448000000, P_DISP_CC_PLL0_OUT_MAIN, 2.5, 0, 0),
281	F(560000000, P_DISP_CC_PLL0_OUT_MAIN, 2, 0, 0),
282	{ }
283};
284
285static struct clk_rcg2 disp_cc_mdss_mdp_clk_src = {
286	.cmd_rcgr = 0x107c,
287	.mnd_width = 0,
288	.hid_width = 5,
289	.parent_map = disp_cc_parent_map_3,
290	.freq_tbl = ftbl_disp_cc_mdss_mdp_clk_src,
291	.clkr.hw.init = &(struct clk_init_data){
292		.name = "disp_cc_mdss_mdp_clk_src",
293		.parent_data = disp_cc_parent_data_3,
294		.num_parents = ARRAY_SIZE(disp_cc_parent_data_3),
295		.flags = CLK_SET_RATE_PARENT,
296		.ops = &clk_rcg2_ops,
297	},
298};
299
300static struct clk_rcg2 disp_cc_mdss_pclk0_clk_src = {
301	.cmd_rcgr = 0x1064,
302	.mnd_width = 8,
303	.hid_width = 5,
304	.parent_map = disp_cc_parent_map_5,
305	.clkr.hw.init = &(struct clk_init_data){
306		.name = "disp_cc_mdss_pclk0_clk_src",
307		.parent_data = disp_cc_parent_data_5,
308		.num_parents = ARRAY_SIZE(disp_cc_parent_data_5),
309		.flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE | CLK_OPS_PARENT_ENABLE,
310		.ops = &clk_pixel_ops,
311	},
312};
313
314static struct clk_rcg2 disp_cc_mdss_rot_clk_src = {
315	.cmd_rcgr = 0x1094,
316	.mnd_width = 0,
317	.hid_width = 5,
318	.parent_map = disp_cc_parent_map_3,
319	.freq_tbl = ftbl_disp_cc_mdss_mdp_clk_src,
320	.clkr.hw.init = &(struct clk_init_data){
321		.name = "disp_cc_mdss_rot_clk_src",
322		.parent_data = disp_cc_parent_data_3,
323		.num_parents = ARRAY_SIZE(disp_cc_parent_data_3),
324		.flags = CLK_SET_RATE_PARENT,
325		.ops = &clk_rcg2_ops,
326	},
327};
328
329static struct clk_rcg2 disp_cc_mdss_vsync_clk_src = {
330	.cmd_rcgr = 0x10ac,
331	.mnd_width = 0,
332	.hid_width = 5,
333	.parent_map = disp_cc_parent_map_6,
334	.freq_tbl = ftbl_disp_cc_mdss_dp_aux_clk_src,
335	.clkr.hw.init = &(struct clk_init_data){
336		.name = "disp_cc_mdss_vsync_clk_src",
337		.parent_data = disp_cc_parent_data_6,
338		.num_parents = ARRAY_SIZE(disp_cc_parent_data_6),
339		.ops = &clk_rcg2_ops,
340	},
341};
342
343static struct clk_regmap_div disp_cc_mdss_dp_link_div_clk_src = {
344	.reg = 0x1110,
345	.shift = 0,
346	.width = 2,
347	.clkr.hw.init = &(struct clk_init_data) {
348		.name = "disp_cc_mdss_dp_link_div_clk_src",
349		.parent_hws = (const struct clk_hw*[]){
350			&disp_cc_mdss_dp_link_clk_src.clkr.hw,
351		},
352		.num_parents = 1,
353		.flags = CLK_GET_RATE_NOCACHE,
354		.ops = &clk_regmap_div_ro_ops,
355	},
356};
357
358static struct clk_branch disp_cc_mdss_ahb_clk = {
359	.halt_reg = 0x104c,
360	.halt_check = BRANCH_HALT,
361	.clkr = {
362		.enable_reg = 0x104c,
363		.enable_mask = BIT(0),
364		.hw.init = &(struct clk_init_data){
365			.name = "disp_cc_mdss_ahb_clk",
366			.parent_hws = (const struct clk_hw*[]){
367				&disp_cc_mdss_ahb_clk_src.clkr.hw,
368			},
369			.num_parents = 1,
370			.flags = CLK_SET_RATE_PARENT,
371			.ops = &clk_branch2_ops,
372		},
373	},
374};
375
376static struct clk_branch disp_cc_mdss_byte0_clk = {
377	.halt_reg = 0x102c,
378	.halt_check = BRANCH_HALT,
379	.clkr = {
380		.enable_reg = 0x102c,
381		.enable_mask = BIT(0),
382		.hw.init = &(struct clk_init_data){
383			.name = "disp_cc_mdss_byte0_clk",
384			.parent_hws = (const struct clk_hw*[]){
385				&disp_cc_mdss_byte0_clk_src.clkr.hw,
386			},
387			.num_parents = 1,
388			.flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE | CLK_OPS_PARENT_ENABLE,
389			.ops = &clk_branch2_ops,
390		},
391	},
392};
393
394static struct clk_branch disp_cc_mdss_byte0_intf_clk = {
395	.halt_reg = 0x1030,
396	.halt_check = BRANCH_HALT,
397	.clkr = {
398		.enable_reg = 0x1030,
399		.enable_mask = BIT(0),
400		.hw.init = &(struct clk_init_data){
401			.name = "disp_cc_mdss_byte0_intf_clk",
402			.parent_hws = (const struct clk_hw*[]){
403				&disp_cc_mdss_byte0_div_clk_src.clkr.hw,
404			},
405			.num_parents = 1,
406			.flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE,
407			.ops = &clk_branch2_ops,
408		},
409	},
410};
411
412static struct clk_branch disp_cc_mdss_dp_aux_clk = {
413	.halt_reg = 0x1048,
414	.halt_check = BRANCH_HALT,
415	.clkr = {
416		.enable_reg = 0x1048,
417		.enable_mask = BIT(0),
418		.hw.init = &(struct clk_init_data){
419			.name = "disp_cc_mdss_dp_aux_clk",
420			.parent_hws = (const struct clk_hw*[]){
421				&disp_cc_mdss_dp_aux_clk_src.clkr.hw,
422			},
423			.num_parents = 1,
424			.flags = CLK_SET_RATE_PARENT,
425			.ops = &clk_branch2_ops,
426		},
427	},
428};
429
430static struct clk_branch disp_cc_mdss_dp_crypto_clk = {
431	.halt_reg = 0x1040,
432	.halt_check = BRANCH_HALT,
433	.clkr = {
434		.enable_reg = 0x1040,
435		.enable_mask = BIT(0),
436		.hw.init = &(struct clk_init_data){
437			.name = "disp_cc_mdss_dp_crypto_clk",
438			.parent_hws = (const struct clk_hw*[]){
439				&disp_cc_mdss_dp_crypto_clk_src.clkr.hw,
440			},
441			.num_parents = 1,
442			.flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE,
443			.ops = &clk_branch2_ops,
444		},
445	},
446};
447
448static struct clk_branch disp_cc_mdss_dp_link_clk = {
449	.halt_reg = 0x1038,
450	.halt_check = BRANCH_HALT,
451	.clkr = {
452		.enable_reg = 0x1038,
453		.enable_mask = BIT(0),
454		.hw.init = &(struct clk_init_data){
455			.name = "disp_cc_mdss_dp_link_clk",
456			.parent_hws = (const struct clk_hw*[]){
457				&disp_cc_mdss_dp_link_clk_src.clkr.hw,
458			},
459			.num_parents = 1,
460			.flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE,
461			.ops = &clk_branch2_ops,
462		},
463	},
464};
465
466static struct clk_branch disp_cc_mdss_dp_link_intf_clk = {
467	.halt_reg = 0x103c,
468	.halt_check = BRANCH_HALT,
469	.clkr = {
470		.enable_reg = 0x103c,
471		.enable_mask = BIT(0),
472		.hw.init = &(struct clk_init_data){
473			.name = "disp_cc_mdss_dp_link_intf_clk",
474			.parent_hws = (const struct clk_hw*[]){
475				&disp_cc_mdss_dp_link_div_clk_src.clkr.hw,
476			},
477			.num_parents = 1,
478			.flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE,
479			.ops = &clk_branch2_ops,
480		},
481	},
482};
483
484static struct clk_branch disp_cc_mdss_dp_pixel_clk = {
485	.halt_reg = 0x1044,
486	.halt_check = BRANCH_HALT,
487	.clkr = {
488		.enable_reg = 0x1044,
489		.enable_mask = BIT(0),
490		.hw.init = &(struct clk_init_data){
491			.name = "disp_cc_mdss_dp_pixel_clk",
492			.parent_hws = (const struct clk_hw*[]){
493				&disp_cc_mdss_dp_pixel_clk_src.clkr.hw,
494			},
495			.num_parents = 1,
496			.flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE,
497			.ops = &clk_branch2_ops,
498		},
499	},
500};
501
502static struct clk_branch disp_cc_mdss_esc0_clk = {
503	.halt_reg = 0x1034,
504	.halt_check = BRANCH_HALT,
505	.clkr = {
506		.enable_reg = 0x1034,
507		.enable_mask = BIT(0),
508		.hw.init = &(struct clk_init_data){
509			.name = "disp_cc_mdss_esc0_clk",
510			.parent_hws = (const struct clk_hw*[]){
511				&disp_cc_mdss_esc0_clk_src.clkr.hw,
512			},
513			.num_parents = 1,
514			.flags = CLK_SET_RATE_PARENT,
515			.ops = &clk_branch2_ops,
516		},
517	},
518};
519
520static struct clk_branch disp_cc_mdss_mdp_clk = {
521	.halt_reg = 0x1010,
522	.halt_check = BRANCH_HALT,
523	.clkr = {
524		.enable_reg = 0x1010,
525		.enable_mask = BIT(0),
526		.hw.init = &(struct clk_init_data){
527			.name = "disp_cc_mdss_mdp_clk",
528			.parent_hws = (const struct clk_hw*[]){
529				&disp_cc_mdss_mdp_clk_src.clkr.hw,
530			},
531			.num_parents = 1,
532			.flags = CLK_SET_RATE_PARENT,
533			.ops = &clk_branch2_ops,
534		},
535	},
536};
537
538static struct clk_branch disp_cc_mdss_mdp_lut_clk = {
539	.halt_reg = 0x1020,
540	.halt_check = BRANCH_HALT_VOTED,
541	.clkr = {
542		.enable_reg = 0x1020,
543		.enable_mask = BIT(0),
544		.hw.init = &(struct clk_init_data){
545			.name = "disp_cc_mdss_mdp_lut_clk",
546			.parent_hws = (const struct clk_hw*[]){
547				&disp_cc_mdss_mdp_clk_src.clkr.hw,
548			},
549			.num_parents = 1,
550			.flags = CLK_SET_RATE_PARENT,
551			.ops = &clk_branch2_ops,
552		},
553	},
554};
555
556static struct clk_branch disp_cc_mdss_non_gdsc_ahb_clk = {
557	.halt_reg = 0x2004,
558	.halt_check = BRANCH_HALT_VOTED,
559	.clkr = {
560		.enable_reg = 0x2004,
561		.enable_mask = BIT(0),
562		.hw.init = &(struct clk_init_data){
563			.name = "disp_cc_mdss_non_gdsc_ahb_clk",
564			.parent_hws = (const struct clk_hw*[]){
565				&disp_cc_mdss_ahb_clk_src.clkr.hw,
566			},
567			.num_parents = 1,
568			.flags = CLK_SET_RATE_PARENT,
569			.ops = &clk_branch2_ops,
570		},
571	},
572};
573
574static struct clk_branch disp_cc_mdss_pclk0_clk = {
575	.halt_reg = 0x100c,
576	.halt_check = BRANCH_HALT,
577	.clkr = {
578		.enable_reg = 0x100c,
579		.enable_mask = BIT(0),
580		.hw.init = &(struct clk_init_data){
581			.name = "disp_cc_mdss_pclk0_clk",
582			.parent_hws = (const struct clk_hw*[]){
583				&disp_cc_mdss_pclk0_clk_src.clkr.hw,
584			},
585			.num_parents = 1,
586			.flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE,
587			.ops = &clk_branch2_ops,
588		},
589	},
590};
591
592static struct clk_branch disp_cc_mdss_rot_clk = {
593	.halt_reg = 0x1018,
594	.halt_check = BRANCH_HALT,
595	.clkr = {
596		.enable_reg = 0x1018,
597		.enable_mask = BIT(0),
598		.hw.init = &(struct clk_init_data){
599			.name = "disp_cc_mdss_rot_clk",
600			.parent_hws = (const struct clk_hw*[]){
601				&disp_cc_mdss_rot_clk_src.clkr.hw,
602			},
603			.num_parents = 1,
604			.flags = CLK_SET_RATE_PARENT,
605			.ops = &clk_branch2_ops,
606		},
607	},
608};
609
610static struct clk_branch disp_cc_mdss_rscc_ahb_clk = {
611	.halt_reg = 0x200c,
612	.halt_check = BRANCH_HALT,
613	.clkr = {
614		.enable_reg = 0x200c,
615		.enable_mask = BIT(0),
616		.hw.init = &(struct clk_init_data){
617			.name = "disp_cc_mdss_rscc_ahb_clk",
618			.parent_hws = (const struct clk_hw*[]){
619				&disp_cc_mdss_ahb_clk_src.clkr.hw,
620			},
621			.num_parents = 1,
622			.flags = CLK_SET_RATE_PARENT,
623			.ops = &clk_branch2_ops,
624		},
625	},
626};
627
628static struct clk_branch disp_cc_mdss_rscc_vsync_clk = {
629	.halt_reg = 0x2008,
630	.halt_check = BRANCH_HALT,
631	.clkr = {
632		.enable_reg = 0x2008,
633		.enable_mask = BIT(0),
634		.hw.init = &(struct clk_init_data){
635			.name = "disp_cc_mdss_rscc_vsync_clk",
636			.parent_hws = (const struct clk_hw*[]){
637				&disp_cc_mdss_vsync_clk_src.clkr.hw,
638			},
639			.num_parents = 1,
640			.flags = CLK_SET_RATE_PARENT,
641			.ops = &clk_branch2_ops,
642		},
643	},
644};
645
646static struct clk_branch disp_cc_mdss_vsync_clk = {
647	.halt_reg = 0x1028,
648	.halt_check = BRANCH_HALT,
649	.clkr = {
650		.enable_reg = 0x1028,
651		.enable_mask = BIT(0),
652		.hw.init = &(struct clk_init_data){
653			.name = "disp_cc_mdss_vsync_clk",
654			.parent_hws = (const struct clk_hw*[]){
655				&disp_cc_mdss_vsync_clk_src.clkr.hw,
656			},
657			.num_parents = 1,
658			.flags = CLK_SET_RATE_PARENT,
659			.ops = &clk_branch2_ops,
660		},
661	},
662};
663
664static struct clk_branch disp_cc_sleep_clk = {
665	.halt_reg = 0x5004,
666	.halt_check = BRANCH_HALT,
667	.clkr = {
668		.enable_reg = 0x5004,
669		.enable_mask = BIT(0),
670		.hw.init = &(struct clk_init_data){
671			.name = "disp_cc_sleep_clk",
672			.ops = &clk_branch2_ops,
673		},
674	},
675};
676
677static struct clk_branch disp_cc_xo_clk = {
678	.halt_reg = 0x5008,
679	.halt_check = BRANCH_HALT,
680	.clkr = {
681		.enable_reg = 0x5008,
682		.enable_mask = BIT(0),
683		.hw.init = &(struct clk_init_data){
684			.name = "disp_cc_xo_clk",
685			.flags = CLK_IS_CRITICAL,
686			.ops = &clk_branch2_ops,
687		},
688	},
689};
690
691static struct gdsc mdss_gdsc = {
692	.gdscr = 0x1004,
693	.pd = {
694		.name = "mdss_gdsc",
695	},
696	.pwrsts = PWRSTS_OFF_ON,
697	.flags = RETAIN_FF_ENABLE,
698};
699
700static struct clk_regmap *disp_cc_sm6350_clocks[] = {
701	[DISP_CC_MDSS_AHB_CLK] = &disp_cc_mdss_ahb_clk.clkr,
702	[DISP_CC_MDSS_AHB_CLK_SRC] = &disp_cc_mdss_ahb_clk_src.clkr,
703	[DISP_CC_MDSS_BYTE0_CLK] = &disp_cc_mdss_byte0_clk.clkr,
704	[DISP_CC_MDSS_BYTE0_CLK_SRC] = &disp_cc_mdss_byte0_clk_src.clkr,
705	[DISP_CC_MDSS_BYTE0_DIV_CLK_SRC] = &disp_cc_mdss_byte0_div_clk_src.clkr,
706	[DISP_CC_MDSS_BYTE0_INTF_CLK] = &disp_cc_mdss_byte0_intf_clk.clkr,
707	[DISP_CC_MDSS_DP_AUX_CLK] = &disp_cc_mdss_dp_aux_clk.clkr,
708	[DISP_CC_MDSS_DP_AUX_CLK_SRC] = &disp_cc_mdss_dp_aux_clk_src.clkr,
709	[DISP_CC_MDSS_DP_CRYPTO_CLK] = &disp_cc_mdss_dp_crypto_clk.clkr,
710	[DISP_CC_MDSS_DP_CRYPTO_CLK_SRC] = &disp_cc_mdss_dp_crypto_clk_src.clkr,
711	[DISP_CC_MDSS_DP_LINK_CLK] = &disp_cc_mdss_dp_link_clk.clkr,
712	[DISP_CC_MDSS_DP_LINK_CLK_SRC] = &disp_cc_mdss_dp_link_clk_src.clkr,
713	[DISP_CC_MDSS_DP_LINK_DIV_CLK_SRC] =
714		&disp_cc_mdss_dp_link_div_clk_src.clkr,
715	[DISP_CC_MDSS_DP_LINK_INTF_CLK] = &disp_cc_mdss_dp_link_intf_clk.clkr,
716	[DISP_CC_MDSS_DP_PIXEL_CLK] = &disp_cc_mdss_dp_pixel_clk.clkr,
717	[DISP_CC_MDSS_DP_PIXEL_CLK_SRC] = &disp_cc_mdss_dp_pixel_clk_src.clkr,
718	[DISP_CC_MDSS_ESC0_CLK] = &disp_cc_mdss_esc0_clk.clkr,
719	[DISP_CC_MDSS_ESC0_CLK_SRC] = &disp_cc_mdss_esc0_clk_src.clkr,
720	[DISP_CC_MDSS_MDP_CLK] = &disp_cc_mdss_mdp_clk.clkr,
721	[DISP_CC_MDSS_MDP_CLK_SRC] = &disp_cc_mdss_mdp_clk_src.clkr,
722	[DISP_CC_MDSS_MDP_LUT_CLK] = &disp_cc_mdss_mdp_lut_clk.clkr,
723	[DISP_CC_MDSS_NON_GDSC_AHB_CLK] = &disp_cc_mdss_non_gdsc_ahb_clk.clkr,
724	[DISP_CC_MDSS_PCLK0_CLK] = &disp_cc_mdss_pclk0_clk.clkr,
725	[DISP_CC_MDSS_PCLK0_CLK_SRC] = &disp_cc_mdss_pclk0_clk_src.clkr,
726	[DISP_CC_MDSS_ROT_CLK] = &disp_cc_mdss_rot_clk.clkr,
727	[DISP_CC_MDSS_ROT_CLK_SRC] = &disp_cc_mdss_rot_clk_src.clkr,
728	[DISP_CC_MDSS_RSCC_AHB_CLK] = &disp_cc_mdss_rscc_ahb_clk.clkr,
729	[DISP_CC_MDSS_RSCC_VSYNC_CLK] = &disp_cc_mdss_rscc_vsync_clk.clkr,
730	[DISP_CC_MDSS_VSYNC_CLK] = &disp_cc_mdss_vsync_clk.clkr,
731	[DISP_CC_MDSS_VSYNC_CLK_SRC] = &disp_cc_mdss_vsync_clk_src.clkr,
732	[DISP_CC_PLL0] = &disp_cc_pll0.clkr,
733	[DISP_CC_SLEEP_CLK] = &disp_cc_sleep_clk.clkr,
734	[DISP_CC_XO_CLK] = &disp_cc_xo_clk.clkr,
735};
736
737static struct gdsc *disp_cc_sm6350_gdscs[] = {
738	[MDSS_GDSC] = &mdss_gdsc,
739};
740
741static const struct regmap_config disp_cc_sm6350_regmap_config = {
742	.reg_bits = 32,
743	.reg_stride = 4,
744	.val_bits = 32,
745	.max_register = 0x10000,
746	.fast_io = true,
747};
748
749static const struct qcom_cc_desc disp_cc_sm6350_desc = {
750	.config = &disp_cc_sm6350_regmap_config,
751	.clks = disp_cc_sm6350_clocks,
752	.num_clks = ARRAY_SIZE(disp_cc_sm6350_clocks),
753	.gdscs = disp_cc_sm6350_gdscs,
754	.num_gdscs = ARRAY_SIZE(disp_cc_sm6350_gdscs),
755};
756
757static const struct of_device_id disp_cc_sm6350_match_table[] = {
758	{ .compatible = "qcom,sm6350-dispcc" },
759	{ }
760};
761MODULE_DEVICE_TABLE(of, disp_cc_sm6350_match_table);
762
763static int disp_cc_sm6350_probe(struct platform_device *pdev)
764{
765	struct regmap *regmap;
766
767	regmap = qcom_cc_map(pdev, &disp_cc_sm6350_desc);
768	if (IS_ERR(regmap))
769		return PTR_ERR(regmap);
770
771	clk_fabia_pll_configure(&disp_cc_pll0, regmap, &disp_cc_pll0_config);
772
773	return qcom_cc_really_probe(pdev, &disp_cc_sm6350_desc, regmap);
774}
775
776static struct platform_driver disp_cc_sm6350_driver = {
777	.probe = disp_cc_sm6350_probe,
778	.driver = {
779		.name = "disp_cc-sm6350",
780		.of_match_table = disp_cc_sm6350_match_table,
781	},
782};
783
784static int __init disp_cc_sm6350_init(void)
785{
786	return platform_driver_register(&disp_cc_sm6350_driver);
787}
788subsys_initcall(disp_cc_sm6350_init);
789
790static void __exit disp_cc_sm6350_exit(void)
791{
792	platform_driver_unregister(&disp_cc_sm6350_driver);
793}
794module_exit(disp_cc_sm6350_exit);
795
796MODULE_DESCRIPTION("QTI DISP_CC SM6350 Driver");
797MODULE_LICENSE("GPL v2");
798