1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
4 */
5
6#include <linux/clk-provider.h>
7#include <linux/module.h>
8#include <linux/platform_device.h>
9#include <linux/regmap.h>
10#include <linux/reset-controller.h>
11
12#include <dt-bindings/clock/qcom,dispcc-sdm845.h>
13
14#include "clk-alpha-pll.h"
15#include "clk-branch.h"
16#include "clk-rcg.h"
17#include "clk-regmap-divider.h"
18#include "common.h"
19#include "gdsc.h"
20#include "reset.h"
21
22enum {
23	P_BI_TCXO,
24	P_CORE_BI_PLL_TEST_SE,
25	P_DISP_CC_PLL0_OUT_MAIN,
26	P_DSI0_PHY_PLL_OUT_BYTECLK,
27	P_DSI0_PHY_PLL_OUT_DSICLK,
28	P_DSI1_PHY_PLL_OUT_BYTECLK,
29	P_DSI1_PHY_PLL_OUT_DSICLK,
30	P_GPLL0_OUT_MAIN,
31	P_GPLL0_OUT_MAIN_DIV,
32	P_DP_PHY_PLL_LINK_CLK,
33	P_DP_PHY_PLL_VCO_DIV_CLK,
34};
35
36static const struct parent_map disp_cc_parent_map_0[] = {
37	{ P_BI_TCXO, 0 },
38	{ P_DSI0_PHY_PLL_OUT_BYTECLK, 1 },
39	{ P_DSI1_PHY_PLL_OUT_BYTECLK, 2 },
40	{ P_CORE_BI_PLL_TEST_SE, 7 },
41};
42
43static const char * const disp_cc_parent_names_0[] = {
44	"bi_tcxo",
45	"dsi0_phy_pll_out_byteclk",
46	"dsi1_phy_pll_out_byteclk",
47	"core_bi_pll_test_se",
48};
49
50static const struct parent_map disp_cc_parent_map_1[] = {
51	{ P_BI_TCXO, 0 },
52	{ P_DP_PHY_PLL_LINK_CLK, 1 },
53	{ P_DP_PHY_PLL_VCO_DIV_CLK, 2 },
54	{ P_CORE_BI_PLL_TEST_SE, 7 },
55};
56
57static const char * const disp_cc_parent_names_1[] = {
58	"bi_tcxo",
59	"dp_link_clk_divsel_ten",
60	"dp_vco_divided_clk_src_mux",
61	"core_bi_pll_test_se",
62};
63
64static const struct parent_map disp_cc_parent_map_2[] = {
65	{ P_BI_TCXO, 0 },
66	{ P_CORE_BI_PLL_TEST_SE, 7 },
67};
68
69static const char * const disp_cc_parent_names_2[] = {
70	"bi_tcxo",
71	"core_bi_pll_test_se",
72};
73
74static const struct parent_map disp_cc_parent_map_3[] = {
75	{ P_BI_TCXO, 0 },
76	{ P_DISP_CC_PLL0_OUT_MAIN, 1 },
77	{ P_GPLL0_OUT_MAIN, 4 },
78	{ P_GPLL0_OUT_MAIN_DIV, 5 },
79	{ P_CORE_BI_PLL_TEST_SE, 7 },
80};
81
82static const char * const disp_cc_parent_names_3[] = {
83	"bi_tcxo",
84	"disp_cc_pll0",
85	"gcc_disp_gpll0_clk_src",
86	"gcc_disp_gpll0_div_clk_src",
87	"core_bi_pll_test_se",
88};
89
90static const struct parent_map disp_cc_parent_map_4[] = {
91	{ P_BI_TCXO, 0 },
92	{ P_DSI0_PHY_PLL_OUT_DSICLK, 1 },
93	{ P_DSI1_PHY_PLL_OUT_DSICLK, 2 },
94	{ P_CORE_BI_PLL_TEST_SE, 7 },
95};
96
97static const char * const disp_cc_parent_names_4[] = {
98	"bi_tcxo",
99	"dsi0_phy_pll_out_dsiclk",
100	"dsi1_phy_pll_out_dsiclk",
101	"core_bi_pll_test_se",
102};
103
104static struct clk_alpha_pll disp_cc_pll0 = {
105	.offset = 0x0,
106	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
107	.clkr = {
108		.hw.init = &(struct clk_init_data){
109			.name = "disp_cc_pll0",
110			.parent_names = (const char *[]){ "bi_tcxo" },
111			.num_parents = 1,
112			.ops = &clk_alpha_pll_fabia_ops,
113		},
114	},
115};
116
117/* Return the HW recalc rate for idle use case */
118static struct clk_rcg2 disp_cc_mdss_byte0_clk_src = {
119	.cmd_rcgr = 0x20d0,
120	.mnd_width = 0,
121	.hid_width = 5,
122	.parent_map = disp_cc_parent_map_0,
123	.clkr.hw.init = &(struct clk_init_data){
124		.name = "disp_cc_mdss_byte0_clk_src",
125		.parent_names = disp_cc_parent_names_0,
126		.num_parents = 4,
127		.flags = CLK_SET_RATE_PARENT,
128		.ops = &clk_byte2_ops,
129	},
130};
131
132/* Return the HW recalc rate for idle use case */
133static struct clk_rcg2 disp_cc_mdss_byte1_clk_src = {
134	.cmd_rcgr = 0x20ec,
135	.mnd_width = 0,
136	.hid_width = 5,
137	.parent_map = disp_cc_parent_map_0,
138	.clkr.hw.init = &(struct clk_init_data){
139		.name = "disp_cc_mdss_byte1_clk_src",
140		.parent_names = disp_cc_parent_names_0,
141		.num_parents = 4,
142		.flags = CLK_SET_RATE_PARENT,
143		.ops = &clk_byte2_ops,
144	},
145};
146
147static const struct freq_tbl ftbl_disp_cc_mdss_dp_aux_clk_src[] = {
148	F(19200000, P_BI_TCXO, 1, 0, 0),
149	{ }
150};
151
152static struct clk_rcg2 disp_cc_mdss_dp_aux_clk_src = {
153	.cmd_rcgr = 0x219c,
154	.mnd_width = 0,
155	.hid_width = 5,
156	.parent_map = disp_cc_parent_map_2,
157	.freq_tbl = ftbl_disp_cc_mdss_dp_aux_clk_src,
158	.clkr.hw.init = &(struct clk_init_data){
159		.name = "disp_cc_mdss_dp_aux_clk_src",
160		.parent_names = disp_cc_parent_names_2,
161		.num_parents = 2,
162		.flags = CLK_SET_RATE_PARENT,
163		.ops = &clk_rcg2_ops,
164	},
165};
166
167static struct clk_rcg2 disp_cc_mdss_dp_crypto_clk_src = {
168	.cmd_rcgr = 0x2154,
169	.mnd_width = 0,
170	.hid_width = 5,
171	.parent_map = disp_cc_parent_map_1,
172	.clkr.hw.init = &(struct clk_init_data){
173		.name = "disp_cc_mdss_dp_crypto_clk_src",
174		.parent_names = disp_cc_parent_names_1,
175		.num_parents = 4,
176		.ops = &clk_byte2_ops,
177	},
178};
179
180static struct clk_rcg2 disp_cc_mdss_dp_link_clk_src = {
181	.cmd_rcgr = 0x2138,
182	.mnd_width = 0,
183	.hid_width = 5,
184	.parent_map = disp_cc_parent_map_1,
185	.clkr.hw.init = &(struct clk_init_data){
186		.name = "disp_cc_mdss_dp_link_clk_src",
187		.parent_names = disp_cc_parent_names_1,
188		.num_parents = 4,
189		.flags = CLK_SET_RATE_PARENT,
190		.ops = &clk_byte2_ops,
191	},
192};
193
194static struct clk_rcg2 disp_cc_mdss_dp_pixel1_clk_src = {
195	.cmd_rcgr = 0x2184,
196	.mnd_width = 16,
197	.hid_width = 5,
198	.parent_map = disp_cc_parent_map_1,
199	.clkr.hw.init = &(struct clk_init_data){
200		.name = "disp_cc_mdss_dp_pixel1_clk_src",
201		.parent_names = disp_cc_parent_names_1,
202		.num_parents = 4,
203		.flags = CLK_SET_RATE_PARENT,
204		.ops = &clk_dp_ops,
205	},
206};
207
208static struct clk_rcg2 disp_cc_mdss_dp_pixel_clk_src = {
209	.cmd_rcgr = 0x216c,
210	.mnd_width = 16,
211	.hid_width = 5,
212	.parent_map = disp_cc_parent_map_1,
213	.clkr.hw.init = &(struct clk_init_data){
214		.name = "disp_cc_mdss_dp_pixel_clk_src",
215		.parent_names = disp_cc_parent_names_1,
216		.num_parents = 4,
217		.flags = CLK_SET_RATE_PARENT,
218		.ops = &clk_dp_ops,
219	},
220};
221
222static const struct freq_tbl ftbl_disp_cc_mdss_esc0_clk_src[] = {
223	F(19200000, P_BI_TCXO, 1, 0, 0),
224	{ }
225};
226
227static struct clk_rcg2 disp_cc_mdss_esc0_clk_src = {
228	.cmd_rcgr = 0x2108,
229	.mnd_width = 0,
230	.hid_width = 5,
231	.parent_map = disp_cc_parent_map_0,
232	.freq_tbl = ftbl_disp_cc_mdss_esc0_clk_src,
233	.clkr.hw.init = &(struct clk_init_data){
234		.name = "disp_cc_mdss_esc0_clk_src",
235		.parent_names = disp_cc_parent_names_0,
236		.num_parents = 4,
237		.ops = &clk_rcg2_ops,
238	},
239};
240
241static struct clk_rcg2 disp_cc_mdss_esc1_clk_src = {
242	.cmd_rcgr = 0x2120,
243	.mnd_width = 0,
244	.hid_width = 5,
245	.parent_map = disp_cc_parent_map_0,
246	.freq_tbl = ftbl_disp_cc_mdss_esc0_clk_src,
247	.clkr.hw.init = &(struct clk_init_data){
248		.name = "disp_cc_mdss_esc1_clk_src",
249		.parent_names = disp_cc_parent_names_0,
250		.num_parents = 4,
251		.ops = &clk_rcg2_ops,
252	},
253};
254
255static const struct freq_tbl ftbl_disp_cc_mdss_mdp_clk_src[] = {
256	F(19200000, P_BI_TCXO, 1, 0, 0),
257	F(85714286, P_GPLL0_OUT_MAIN, 7, 0, 0),
258	F(100000000, P_GPLL0_OUT_MAIN, 6, 0, 0),
259	F(150000000, P_GPLL0_OUT_MAIN, 4, 0, 0),
260	F(171428571, P_GPLL0_OUT_MAIN, 3.5, 0, 0),
261	F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0),
262	F(300000000, P_GPLL0_OUT_MAIN, 2, 0, 0),
263	F(344000000, P_DISP_CC_PLL0_OUT_MAIN, 2.5, 0, 0),
264	F(430000000, P_DISP_CC_PLL0_OUT_MAIN, 2, 0, 0),
265	{ }
266};
267
268static struct clk_rcg2 disp_cc_mdss_mdp_clk_src = {
269	.cmd_rcgr = 0x2088,
270	.mnd_width = 0,
271	.hid_width = 5,
272	.parent_map = disp_cc_parent_map_3,
273	.freq_tbl = ftbl_disp_cc_mdss_mdp_clk_src,
274	.clkr.hw.init = &(struct clk_init_data){
275		.name = "disp_cc_mdss_mdp_clk_src",
276		.parent_names = disp_cc_parent_names_3,
277		.num_parents = 5,
278		.ops = &clk_rcg2_shared_ops,
279	},
280};
281
282/* Return the HW recalc rate for idle use case */
283static struct clk_rcg2 disp_cc_mdss_pclk0_clk_src = {
284	.cmd_rcgr = 0x2058,
285	.mnd_width = 8,
286	.hid_width = 5,
287	.parent_map = disp_cc_parent_map_4,
288	.clkr.hw.init = &(struct clk_init_data){
289		.name = "disp_cc_mdss_pclk0_clk_src",
290		.parent_names = disp_cc_parent_names_4,
291		.num_parents = 4,
292		.flags = CLK_SET_RATE_PARENT,
293		.ops = &clk_pixel_ops,
294	},
295};
296
297/* Return the HW recalc rate for idle use case */
298static struct clk_rcg2 disp_cc_mdss_pclk1_clk_src = {
299	.cmd_rcgr = 0x2070,
300	.mnd_width = 8,
301	.hid_width = 5,
302	.parent_map = disp_cc_parent_map_4,
303	.clkr.hw.init = &(struct clk_init_data){
304		.name = "disp_cc_mdss_pclk1_clk_src",
305		.parent_names = disp_cc_parent_names_4,
306		.num_parents = 4,
307		.flags = CLK_SET_RATE_PARENT,
308		.ops = &clk_pixel_ops,
309	},
310};
311
312static const struct freq_tbl ftbl_disp_cc_mdss_rot_clk_src[] = {
313	F(19200000, P_BI_TCXO, 1, 0, 0),
314	F(171428571, P_GPLL0_OUT_MAIN, 3.5, 0, 0),
315	F(300000000, P_GPLL0_OUT_MAIN, 2, 0, 0),
316	F(344000000, P_DISP_CC_PLL0_OUT_MAIN, 2.5, 0, 0),
317	F(430000000, P_DISP_CC_PLL0_OUT_MAIN, 2, 0, 0),
318	{ }
319};
320
321static struct clk_rcg2 disp_cc_mdss_rot_clk_src = {
322	.cmd_rcgr = 0x20a0,
323	.mnd_width = 0,
324	.hid_width = 5,
325	.parent_map = disp_cc_parent_map_3,
326	.freq_tbl = ftbl_disp_cc_mdss_rot_clk_src,
327	.clkr.hw.init = &(struct clk_init_data){
328		.name = "disp_cc_mdss_rot_clk_src",
329		.parent_names = disp_cc_parent_names_3,
330		.num_parents = 5,
331		.ops = &clk_rcg2_shared_ops,
332	},
333};
334
335static struct clk_rcg2 disp_cc_mdss_vsync_clk_src = {
336	.cmd_rcgr = 0x20b8,
337	.mnd_width = 0,
338	.hid_width = 5,
339	.parent_map = disp_cc_parent_map_2,
340	.freq_tbl = ftbl_disp_cc_mdss_esc0_clk_src,
341	.clkr.hw.init = &(struct clk_init_data){
342		.name = "disp_cc_mdss_vsync_clk_src",
343		.parent_names = disp_cc_parent_names_2,
344		.num_parents = 2,
345		.ops = &clk_rcg2_ops,
346	},
347};
348
349static struct clk_branch disp_cc_mdss_ahb_clk = {
350	.halt_reg = 0x4004,
351	.halt_check = BRANCH_HALT,
352	.clkr = {
353		.enable_reg = 0x4004,
354		.enable_mask = BIT(0),
355		.hw.init = &(struct clk_init_data){
356			.name = "disp_cc_mdss_ahb_clk",
357			.ops = &clk_branch2_ops,
358		},
359	},
360};
361
362static struct clk_branch disp_cc_mdss_axi_clk = {
363	.halt_reg = 0x4008,
364	.halt_check = BRANCH_HALT,
365	.clkr = {
366		.enable_reg = 0x4008,
367		.enable_mask = BIT(0),
368		.hw.init = &(struct clk_init_data){
369			.name = "disp_cc_mdss_axi_clk",
370			.ops = &clk_branch2_ops,
371		},
372	},
373};
374
375/* Return the HW recalc rate for idle use case */
376static struct clk_branch disp_cc_mdss_byte0_clk = {
377	.halt_reg = 0x2028,
378	.halt_check = BRANCH_HALT,
379	.clkr = {
380		.enable_reg = 0x2028,
381		.enable_mask = BIT(0),
382		.hw.init = &(struct clk_init_data){
383			.name = "disp_cc_mdss_byte0_clk",
384			.parent_names = (const char *[]){
385				"disp_cc_mdss_byte0_clk_src",
386			},
387			.num_parents = 1,
388			.flags = CLK_SET_RATE_PARENT,
389			.ops = &clk_branch2_ops,
390		},
391	},
392};
393
394/* Return the HW recalc rate for idle use case */
395static struct clk_regmap_div disp_cc_mdss_byte0_div_clk_src = {
396	.reg = 0x20e8,
397	.shift = 0,
398	.width = 2,
399	.clkr = {
400		.hw.init = &(struct clk_init_data){
401			.name = "disp_cc_mdss_byte0_div_clk_src",
402			.parent_names = (const char *[]){
403				"disp_cc_mdss_byte0_clk_src",
404			},
405			.num_parents = 1,
406			.ops = &clk_regmap_div_ops,
407		},
408	},
409};
410
411/* Return the HW recalc rate for idle use case */
412static struct clk_branch disp_cc_mdss_byte0_intf_clk = {
413	.halt_reg = 0x202c,
414	.halt_check = BRANCH_HALT,
415	.clkr = {
416		.enable_reg = 0x202c,
417		.enable_mask = BIT(0),
418		.hw.init = &(struct clk_init_data){
419			.name = "disp_cc_mdss_byte0_intf_clk",
420			.parent_names = (const char *[]){
421				"disp_cc_mdss_byte0_div_clk_src",
422			},
423			.num_parents = 1,
424			.flags = CLK_SET_RATE_PARENT,
425			.ops = &clk_branch2_ops,
426		},
427	},
428};
429
430/* Return the HW recalc rate for idle use case */
431static struct clk_branch disp_cc_mdss_byte1_clk = {
432	.halt_reg = 0x2030,
433	.halt_check = BRANCH_HALT,
434	.clkr = {
435		.enable_reg = 0x2030,
436		.enable_mask = BIT(0),
437		.hw.init = &(struct clk_init_data){
438			.name = "disp_cc_mdss_byte1_clk",
439			.parent_names = (const char *[]){
440				"disp_cc_mdss_byte1_clk_src",
441			},
442			.num_parents = 1,
443			.flags = CLK_SET_RATE_PARENT,
444			.ops = &clk_branch2_ops,
445		},
446	},
447};
448
449/* Return the HW recalc rate for idle use case */
450static struct clk_regmap_div disp_cc_mdss_byte1_div_clk_src = {
451	.reg = 0x2104,
452	.shift = 0,
453	.width = 2,
454	.clkr = {
455		.hw.init = &(struct clk_init_data){
456			.name = "disp_cc_mdss_byte1_div_clk_src",
457			.parent_names = (const char *[]){
458				"disp_cc_mdss_byte1_clk_src",
459			},
460			.num_parents = 1,
461			.ops = &clk_regmap_div_ops,
462		},
463	},
464};
465
466/* Return the HW recalc rate for idle use case */
467static struct clk_branch disp_cc_mdss_byte1_intf_clk = {
468	.halt_reg = 0x2034,
469	.halt_check = BRANCH_HALT,
470	.clkr = {
471		.enable_reg = 0x2034,
472		.enable_mask = BIT(0),
473		.hw.init = &(struct clk_init_data){
474			.name = "disp_cc_mdss_byte1_intf_clk",
475			.parent_names = (const char *[]){
476				"disp_cc_mdss_byte1_div_clk_src",
477			},
478			.num_parents = 1,
479			.flags = CLK_SET_RATE_PARENT,
480			.ops = &clk_branch2_ops,
481		},
482	},
483};
484
485static struct clk_branch disp_cc_mdss_dp_aux_clk = {
486	.halt_reg = 0x2054,
487	.halt_check = BRANCH_HALT,
488	.clkr = {
489		.enable_reg = 0x2054,
490		.enable_mask = BIT(0),
491		.hw.init = &(struct clk_init_data){
492			.name = "disp_cc_mdss_dp_aux_clk",
493			.parent_names = (const char *[]){
494				"disp_cc_mdss_dp_aux_clk_src",
495			},
496			.num_parents = 1,
497			.flags = CLK_SET_RATE_PARENT,
498			.ops = &clk_branch2_ops,
499		},
500	},
501};
502
503static struct clk_branch disp_cc_mdss_dp_crypto_clk = {
504	.halt_reg = 0x2048,
505	.halt_check = BRANCH_HALT,
506	.clkr = {
507		.enable_reg = 0x2048,
508		.enable_mask = BIT(0),
509		.hw.init = &(struct clk_init_data){
510			.name = "disp_cc_mdss_dp_crypto_clk",
511			.parent_names = (const char *[]){
512				"disp_cc_mdss_dp_crypto_clk_src",
513			},
514			.num_parents = 1,
515			.flags = CLK_SET_RATE_PARENT,
516			.ops = &clk_branch2_ops,
517		},
518	},
519};
520
521static struct clk_branch disp_cc_mdss_dp_link_clk = {
522	.halt_reg = 0x2040,
523	.halt_check = BRANCH_HALT,
524	.clkr = {
525		.enable_reg = 0x2040,
526		.enable_mask = BIT(0),
527		.hw.init = &(struct clk_init_data){
528			.name = "disp_cc_mdss_dp_link_clk",
529			.parent_names = (const char *[]){
530				"disp_cc_mdss_dp_link_clk_src",
531			},
532			.num_parents = 1,
533			.flags = CLK_SET_RATE_PARENT,
534			.ops = &clk_branch2_ops,
535		},
536	},
537};
538
539/* reset state of disp_cc_mdss_dp_link_div_clk_src divider is 0x3 (div 4) */
540static struct clk_branch disp_cc_mdss_dp_link_intf_clk = {
541	.halt_reg = 0x2044,
542	.halt_check = BRANCH_HALT,
543	.clkr = {
544		.enable_reg = 0x2044,
545		.enable_mask = BIT(0),
546		.hw.init = &(struct clk_init_data){
547			.name = "disp_cc_mdss_dp_link_intf_clk",
548			.parent_names = (const char *[]){
549				"disp_cc_mdss_dp_link_clk_src",
550			},
551			.num_parents = 1,
552			.ops = &clk_branch2_ops,
553		},
554	},
555};
556
557static struct clk_branch disp_cc_mdss_dp_pixel1_clk = {
558	.halt_reg = 0x2050,
559	.halt_check = BRANCH_HALT,
560	.clkr = {
561		.enable_reg = 0x2050,
562		.enable_mask = BIT(0),
563		.hw.init = &(struct clk_init_data){
564			.name = "disp_cc_mdss_dp_pixel1_clk",
565			.parent_names = (const char *[]){
566				"disp_cc_mdss_dp_pixel1_clk_src",
567			},
568			.num_parents = 1,
569			.flags = CLK_SET_RATE_PARENT,
570			.ops = &clk_branch2_ops,
571		},
572	},
573};
574
575static struct clk_branch disp_cc_mdss_dp_pixel_clk = {
576	.halt_reg = 0x204c,
577	.halt_check = BRANCH_HALT,
578	.clkr = {
579		.enable_reg = 0x204c,
580		.enable_mask = BIT(0),
581		.hw.init = &(struct clk_init_data){
582			.name = "disp_cc_mdss_dp_pixel_clk",
583			.parent_names = (const char *[]){
584				"disp_cc_mdss_dp_pixel_clk_src",
585			},
586			.num_parents = 1,
587			.flags = CLK_SET_RATE_PARENT,
588			.ops = &clk_branch2_ops,
589		},
590	},
591};
592
593static struct clk_branch disp_cc_mdss_esc0_clk = {
594	.halt_reg = 0x2038,
595	.halt_check = BRANCH_HALT,
596	.clkr = {
597		.enable_reg = 0x2038,
598		.enable_mask = BIT(0),
599		.hw.init = &(struct clk_init_data){
600			.name = "disp_cc_mdss_esc0_clk",
601			.parent_names = (const char *[]){
602				"disp_cc_mdss_esc0_clk_src",
603			},
604			.num_parents = 1,
605			.flags = CLK_SET_RATE_PARENT,
606			.ops = &clk_branch2_ops,
607		},
608	},
609};
610
611static struct clk_branch disp_cc_mdss_esc1_clk = {
612	.halt_reg = 0x203c,
613	.halt_check = BRANCH_HALT,
614	.clkr = {
615		.enable_reg = 0x203c,
616		.enable_mask = BIT(0),
617		.hw.init = &(struct clk_init_data){
618			.name = "disp_cc_mdss_esc1_clk",
619			.parent_names = (const char *[]){
620				"disp_cc_mdss_esc1_clk_src",
621			},
622			.num_parents = 1,
623			.flags = CLK_SET_RATE_PARENT,
624			.ops = &clk_branch2_ops,
625		},
626	},
627};
628
629static struct clk_branch disp_cc_mdss_mdp_clk = {
630	.halt_reg = 0x200c,
631	.halt_check = BRANCH_HALT,
632	.clkr = {
633		.enable_reg = 0x200c,
634		.enable_mask = BIT(0),
635		.hw.init = &(struct clk_init_data){
636			.name = "disp_cc_mdss_mdp_clk",
637			.parent_names = (const char *[]){
638				"disp_cc_mdss_mdp_clk_src",
639			},
640			.num_parents = 1,
641			.flags = CLK_SET_RATE_PARENT,
642			.ops = &clk_branch2_ops,
643		},
644	},
645};
646
647static struct clk_branch disp_cc_mdss_mdp_lut_clk = {
648	.halt_reg = 0x201c,
649	.halt_check = BRANCH_HALT,
650	.clkr = {
651		.enable_reg = 0x201c,
652		.enable_mask = BIT(0),
653		.hw.init = &(struct clk_init_data){
654			.name = "disp_cc_mdss_mdp_lut_clk",
655			.parent_names = (const char *[]){
656				"disp_cc_mdss_mdp_clk_src",
657			},
658			.num_parents = 1,
659			.ops = &clk_branch2_ops,
660		},
661	},
662};
663
664/* Return the HW recalc rate for idle use case */
665static struct clk_branch disp_cc_mdss_pclk0_clk = {
666	.halt_reg = 0x2004,
667	.halt_check = BRANCH_HALT,
668	.clkr = {
669		.enable_reg = 0x2004,
670		.enable_mask = BIT(0),
671		.hw.init = &(struct clk_init_data){
672			.name = "disp_cc_mdss_pclk0_clk",
673			.parent_names = (const char *[]){
674				"disp_cc_mdss_pclk0_clk_src",
675			},
676			.num_parents = 1,
677			.flags = CLK_SET_RATE_PARENT,
678			.ops = &clk_branch2_ops,
679		},
680	},
681};
682
683/* Return the HW recalc rate for idle use case */
684static struct clk_branch disp_cc_mdss_pclk1_clk = {
685	.halt_reg = 0x2008,
686	.halt_check = BRANCH_HALT,
687	.clkr = {
688		.enable_reg = 0x2008,
689		.enable_mask = BIT(0),
690		.hw.init = &(struct clk_init_data){
691			.name = "disp_cc_mdss_pclk1_clk",
692			.parent_names = (const char *[]){
693				"disp_cc_mdss_pclk1_clk_src",
694			},
695			.num_parents = 1,
696			.flags = CLK_SET_RATE_PARENT,
697			.ops = &clk_branch2_ops,
698		},
699	},
700};
701
702static struct clk_branch disp_cc_mdss_rot_clk = {
703	.halt_reg = 0x2014,
704	.halt_check = BRANCH_HALT,
705	.clkr = {
706		.enable_reg = 0x2014,
707		.enable_mask = BIT(0),
708		.hw.init = &(struct clk_init_data){
709			.name = "disp_cc_mdss_rot_clk",
710			.parent_names = (const char *[]){
711				"disp_cc_mdss_rot_clk_src",
712			},
713			.num_parents = 1,
714			.flags = CLK_SET_RATE_PARENT,
715			.ops = &clk_branch2_ops,
716		},
717	},
718};
719
720static struct clk_branch disp_cc_mdss_rscc_ahb_clk = {
721	.halt_reg = 0x5004,
722	.halt_check = BRANCH_HALT,
723	.clkr = {
724		.enable_reg = 0x5004,
725		.enable_mask = BIT(0),
726		.hw.init = &(struct clk_init_data){
727			.name = "disp_cc_mdss_rscc_ahb_clk",
728			.ops = &clk_branch2_ops,
729		},
730	},
731};
732
733static struct clk_branch disp_cc_mdss_rscc_vsync_clk = {
734	.halt_reg = 0x5008,
735	.halt_check = BRANCH_HALT,
736	.clkr = {
737		.enable_reg = 0x5008,
738		.enable_mask = BIT(0),
739		.hw.init = &(struct clk_init_data){
740			.name = "disp_cc_mdss_rscc_vsync_clk",
741			.parent_names = (const char *[]){
742				"disp_cc_mdss_vsync_clk_src",
743			},
744			.num_parents = 1,
745			.flags = CLK_SET_RATE_PARENT,
746			.ops = &clk_branch2_ops,
747		},
748	},
749};
750
751static struct clk_branch disp_cc_mdss_vsync_clk = {
752	.halt_reg = 0x2024,
753	.halt_check = BRANCH_HALT,
754	.clkr = {
755		.enable_reg = 0x2024,
756		.enable_mask = BIT(0),
757		.hw.init = &(struct clk_init_data){
758			.name = "disp_cc_mdss_vsync_clk",
759			.parent_names = (const char *[]){
760				"disp_cc_mdss_vsync_clk_src",
761			},
762			.num_parents = 1,
763			.flags = CLK_SET_RATE_PARENT,
764			.ops = &clk_branch2_ops,
765		},
766	},
767};
768
769static struct gdsc mdss_gdsc = {
770	.gdscr = 0x3000,
771	.pd = {
772		.name = "mdss_gdsc",
773	},
774	.pwrsts = PWRSTS_OFF_ON,
775	.flags = HW_CTRL | POLL_CFG_GDSCR,
776};
777
778static struct clk_regmap *disp_cc_sdm845_clocks[] = {
779	[DISP_CC_MDSS_AHB_CLK] = &disp_cc_mdss_ahb_clk.clkr,
780	[DISP_CC_MDSS_AXI_CLK] = &disp_cc_mdss_axi_clk.clkr,
781	[DISP_CC_MDSS_BYTE0_CLK] = &disp_cc_mdss_byte0_clk.clkr,
782	[DISP_CC_MDSS_BYTE0_CLK_SRC] = &disp_cc_mdss_byte0_clk_src.clkr,
783	[DISP_CC_MDSS_BYTE0_INTF_CLK] = &disp_cc_mdss_byte0_intf_clk.clkr,
784	[DISP_CC_MDSS_BYTE0_DIV_CLK_SRC] =
785					&disp_cc_mdss_byte0_div_clk_src.clkr,
786	[DISP_CC_MDSS_BYTE1_CLK] = &disp_cc_mdss_byte1_clk.clkr,
787	[DISP_CC_MDSS_BYTE1_CLK_SRC] = &disp_cc_mdss_byte1_clk_src.clkr,
788	[DISP_CC_MDSS_BYTE1_INTF_CLK] = &disp_cc_mdss_byte1_intf_clk.clkr,
789	[DISP_CC_MDSS_BYTE1_DIV_CLK_SRC] =
790					&disp_cc_mdss_byte1_div_clk_src.clkr,
791	[DISP_CC_MDSS_DP_AUX_CLK] = &disp_cc_mdss_dp_aux_clk.clkr,
792	[DISP_CC_MDSS_DP_AUX_CLK_SRC] = &disp_cc_mdss_dp_aux_clk_src.clkr,
793	[DISP_CC_MDSS_DP_CRYPTO_CLK] = &disp_cc_mdss_dp_crypto_clk.clkr,
794	[DISP_CC_MDSS_DP_CRYPTO_CLK_SRC] =
795					&disp_cc_mdss_dp_crypto_clk_src.clkr,
796	[DISP_CC_MDSS_DP_LINK_CLK] = &disp_cc_mdss_dp_link_clk.clkr,
797	[DISP_CC_MDSS_DP_LINK_CLK_SRC] = &disp_cc_mdss_dp_link_clk_src.clkr,
798	[DISP_CC_MDSS_DP_LINK_INTF_CLK] = &disp_cc_mdss_dp_link_intf_clk.clkr,
799	[DISP_CC_MDSS_DP_PIXEL1_CLK] = &disp_cc_mdss_dp_pixel1_clk.clkr,
800	[DISP_CC_MDSS_DP_PIXEL1_CLK_SRC] =
801					&disp_cc_mdss_dp_pixel1_clk_src.clkr,
802	[DISP_CC_MDSS_DP_PIXEL_CLK] = &disp_cc_mdss_dp_pixel_clk.clkr,
803	[DISP_CC_MDSS_DP_PIXEL_CLK_SRC] = &disp_cc_mdss_dp_pixel_clk_src.clkr,
804	[DISP_CC_MDSS_ESC0_CLK] = &disp_cc_mdss_esc0_clk.clkr,
805	[DISP_CC_MDSS_ESC0_CLK_SRC] = &disp_cc_mdss_esc0_clk_src.clkr,
806	[DISP_CC_MDSS_ESC1_CLK] = &disp_cc_mdss_esc1_clk.clkr,
807	[DISP_CC_MDSS_ESC1_CLK_SRC] = &disp_cc_mdss_esc1_clk_src.clkr,
808	[DISP_CC_MDSS_MDP_CLK] = &disp_cc_mdss_mdp_clk.clkr,
809	[DISP_CC_MDSS_MDP_CLK_SRC] = &disp_cc_mdss_mdp_clk_src.clkr,
810	[DISP_CC_MDSS_MDP_LUT_CLK] = &disp_cc_mdss_mdp_lut_clk.clkr,
811	[DISP_CC_MDSS_PCLK0_CLK] = &disp_cc_mdss_pclk0_clk.clkr,
812	[DISP_CC_MDSS_PCLK0_CLK_SRC] = &disp_cc_mdss_pclk0_clk_src.clkr,
813	[DISP_CC_MDSS_PCLK1_CLK] = &disp_cc_mdss_pclk1_clk.clkr,
814	[DISP_CC_MDSS_PCLK1_CLK_SRC] = &disp_cc_mdss_pclk1_clk_src.clkr,
815	[DISP_CC_MDSS_ROT_CLK] = &disp_cc_mdss_rot_clk.clkr,
816	[DISP_CC_MDSS_ROT_CLK_SRC] = &disp_cc_mdss_rot_clk_src.clkr,
817	[DISP_CC_MDSS_RSCC_AHB_CLK] = &disp_cc_mdss_rscc_ahb_clk.clkr,
818	[DISP_CC_MDSS_RSCC_VSYNC_CLK] = &disp_cc_mdss_rscc_vsync_clk.clkr,
819	[DISP_CC_MDSS_VSYNC_CLK] = &disp_cc_mdss_vsync_clk.clkr,
820	[DISP_CC_MDSS_VSYNC_CLK_SRC] = &disp_cc_mdss_vsync_clk_src.clkr,
821	[DISP_CC_PLL0] = &disp_cc_pll0.clkr,
822};
823
824static const struct qcom_reset_map disp_cc_sdm845_resets[] = {
825	[DISP_CC_MDSS_RSCC_BCR] = { 0x5000 },
826};
827
828static struct gdsc *disp_cc_sdm845_gdscs[] = {
829	[MDSS_GDSC] = &mdss_gdsc,
830};
831
832static const struct regmap_config disp_cc_sdm845_regmap_config = {
833	.reg_bits	= 32,
834	.reg_stride	= 4,
835	.val_bits	= 32,
836	.max_register	= 0x10000,
837	.fast_io	= true,
838};
839
840static const struct qcom_cc_desc disp_cc_sdm845_desc = {
841	.config = &disp_cc_sdm845_regmap_config,
842	.clks = disp_cc_sdm845_clocks,
843	.num_clks = ARRAY_SIZE(disp_cc_sdm845_clocks),
844	.resets = disp_cc_sdm845_resets,
845	.num_resets = ARRAY_SIZE(disp_cc_sdm845_resets),
846	.gdscs = disp_cc_sdm845_gdscs,
847	.num_gdscs = ARRAY_SIZE(disp_cc_sdm845_gdscs),
848};
849
850static const struct of_device_id disp_cc_sdm845_match_table[] = {
851	{ .compatible = "qcom,sdm845-dispcc" },
852	{ }
853};
854MODULE_DEVICE_TABLE(of, disp_cc_sdm845_match_table);
855
856static int disp_cc_sdm845_probe(struct platform_device *pdev)
857{
858	struct regmap *regmap;
859	struct alpha_pll_config disp_cc_pll0_config = {};
860
861	regmap = qcom_cc_map(pdev, &disp_cc_sdm845_desc);
862	if (IS_ERR(regmap))
863		return PTR_ERR(regmap);
864
865	disp_cc_pll0_config.l = 0x2c;
866	disp_cc_pll0_config.alpha = 0xcaaa;
867
868	clk_fabia_pll_configure(&disp_cc_pll0, regmap, &disp_cc_pll0_config);
869
870	/* Enable hardware clock gating for DSI and MDP clocks */
871	regmap_update_bits(regmap, 0x8000, 0x7f0, 0x7f0);
872
873	return qcom_cc_really_probe(pdev, &disp_cc_sdm845_desc, regmap);
874}
875
876static struct platform_driver disp_cc_sdm845_driver = {
877	.probe		= disp_cc_sdm845_probe,
878	.driver		= {
879		.name	= "disp_cc-sdm845",
880		.of_match_table = disp_cc_sdm845_match_table,
881	},
882};
883
884static int __init disp_cc_sdm845_init(void)
885{
886	return platform_driver_register(&disp_cc_sdm845_driver);
887}
888subsys_initcall(disp_cc_sdm845_init);
889
890static void __exit disp_cc_sdm845_exit(void)
891{
892	platform_driver_unregister(&disp_cc_sdm845_driver);
893}
894module_exit(disp_cc_sdm845_exit);
895
896MODULE_LICENSE("GPL v2");
897MODULE_DESCRIPTION("QTI DISPCC SDM845 Driver");
898