Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.5.6.
  1// SPDX-License-Identifier: GPL-2.0-only
  2/*
  3 * Based on dispcc-qcm2290.c
  4 * Copyright (c) 2020, The Linux Foundation. All rights reserved.
  5 * Copyright (c) 2021, Linaro Ltd.
  6 */
  7
  8#include <linux/err.h>
  9#include <linux/kernel.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,sm6115-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
 25enum {
 26	DT_BI_TCXO,
 27	DT_SLEEP_CLK,
 28	DT_DSI0_PHY_PLL_OUT_BYTECLK,
 29	DT_DSI0_PHY_PLL_OUT_DSICLK,
 30	DT_GPLL0_DISP_DIV,
 31};
 32
 33enum {
 34	P_BI_TCXO,
 35	P_DISP_CC_PLL0_OUT_MAIN,
 36	P_DSI0_PHY_PLL_OUT_BYTECLK,
 37	P_DSI0_PHY_PLL_OUT_DSICLK,
 38	P_GPLL0_OUT_MAIN,
 39	P_SLEEP_CLK,
 40};
 41
 42static const struct clk_parent_data parent_data_tcxo = { .index = DT_BI_TCXO };
 43
 44static const struct pll_vco spark_vco[] = {
 45	{ 500000000, 1000000000, 2 },
 46};
 47
 48/* 768MHz configuration */
 49static const struct alpha_pll_config disp_cc_pll0_config = {
 50	.l = 0x28,
 51	.alpha = 0x0,
 52	.alpha_en_mask = BIT(24),
 53	.vco_val = 0x2 << 20,
 54	.vco_mask = GENMASK(21, 20),
 55	.main_output_mask = BIT(0),
 56	.config_ctl_val = 0x4001055B,
 57};
 58
 59static struct clk_alpha_pll disp_cc_pll0 = {
 60	.offset = 0x0,
 61	.vco_table = spark_vco,
 62	.num_vco = ARRAY_SIZE(spark_vco),
 63	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
 64	.clkr = {
 65		.hw.init = &(struct clk_init_data){
 66			.name = "disp_cc_pll0",
 67			.parent_data = &parent_data_tcxo,
 68			.num_parents = 1,
 69			.ops = &clk_alpha_pll_ops,
 70		},
 71	},
 72};
 73
 74static const struct clk_div_table post_div_table_disp_cc_pll0_out_main[] = {
 75	{ 0x0, 1 },
 76	{ }
 77};
 78static struct clk_alpha_pll_postdiv disp_cc_pll0_out_main = {
 79	.offset = 0x0,
 80	.post_div_shift = 8,
 81	.post_div_table = post_div_table_disp_cc_pll0_out_main,
 82	.num_post_div = ARRAY_SIZE(post_div_table_disp_cc_pll0_out_main),
 83	.width = 4,
 84	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
 85	.clkr.hw.init = &(struct clk_init_data){
 86		.name = "disp_cc_pll0_out_main",
 87		.parent_hws = (const struct clk_hw*[]){
 88			&disp_cc_pll0.clkr.hw,
 89		},
 90		.num_parents = 1,
 91		.flags = CLK_SET_RATE_PARENT,
 92		.ops = &clk_alpha_pll_postdiv_ops,
 93	},
 94};
 95
 96static const struct parent_map disp_cc_parent_map_0[] = {
 97	{ P_BI_TCXO, 0 },
 98	{ P_DSI0_PHY_PLL_OUT_BYTECLK, 1 },
 99};
100
101static const struct clk_parent_data disp_cc_parent_data_0[] = {
102	{ .index = DT_BI_TCXO },
103	{ .index = DT_DSI0_PHY_PLL_OUT_BYTECLK },
104};
105
106static const struct parent_map disp_cc_parent_map_1[] = {
107	{ P_BI_TCXO, 0 },
108};
109
110static const struct clk_parent_data disp_cc_parent_data_1[] = {
111	{ .index = DT_BI_TCXO },
112};
113
114static const struct parent_map disp_cc_parent_map_2[] = {
115	{ P_BI_TCXO, 0 },
116	{ P_GPLL0_OUT_MAIN, 4 },
117};
118
119static const struct clk_parent_data disp_cc_parent_data_2[] = {
120	{ .index = DT_BI_TCXO },
121	{ .index = DT_GPLL0_DISP_DIV },
122};
123
124static const struct parent_map disp_cc_parent_map_3[] = {
125	{ P_BI_TCXO, 0 },
126	{ P_DISP_CC_PLL0_OUT_MAIN, 1 },
127};
128
129static const struct clk_parent_data disp_cc_parent_data_3[] = {
130	{ .index = DT_BI_TCXO },
131	{ .hw = &disp_cc_pll0_out_main.clkr.hw },
132};
133
134static const struct parent_map disp_cc_parent_map_4[] = {
135	{ P_BI_TCXO, 0 },
136	{ P_DSI0_PHY_PLL_OUT_DSICLK, 1 },
137};
138
139static const struct clk_parent_data disp_cc_parent_data_4[] = {
140	{ .index = DT_BI_TCXO },
141	{ .index = DT_DSI0_PHY_PLL_OUT_DSICLK },
142};
143
144static const struct parent_map disp_cc_parent_map_5[] = {
145	{ P_SLEEP_CLK, 0 },
146};
147
148static const struct clk_parent_data disp_cc_parent_data_5[] = {
149	{ .index = DT_SLEEP_CLK, },
150};
151
152static struct clk_rcg2 disp_cc_mdss_byte0_clk_src = {
153	.cmd_rcgr = 0x20bc,
154	.mnd_width = 0,
155	.hid_width = 5,
156	.parent_map = disp_cc_parent_map_0,
157	.clkr.hw.init = &(struct clk_init_data){
158		.name = "disp_cc_mdss_byte0_clk_src",
159		.parent_data = disp_cc_parent_data_0,
160		.num_parents = ARRAY_SIZE(disp_cc_parent_data_0),
161		/* For set_rate and set_parent to succeed, parent(s) must be enabled */
162		.flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE | CLK_GET_RATE_NOCACHE,
163		.ops = &clk_byte2_ops,
164	},
165};
166
167static struct clk_regmap_div disp_cc_mdss_byte0_div_clk_src = {
168	.reg = 0x20d4,
169	.shift = 0,
170	.width = 2,
171	.clkr.hw.init = &(struct clk_init_data) {
172		.name = "disp_cc_mdss_byte0_div_clk_src",
173		.parent_hws = (const struct clk_hw*[]){
174			&disp_cc_mdss_byte0_clk_src.clkr.hw,
175		},
176		.num_parents = 1,
177		.ops = &clk_regmap_div_ops,
178	},
179};
180
181static const struct freq_tbl ftbl_disp_cc_mdss_ahb_clk_src[] = {
182	F(19200000, P_BI_TCXO, 1, 0, 0),
183	F(37500000, P_GPLL0_OUT_MAIN, 8, 0, 0),
184	F(75000000, P_GPLL0_OUT_MAIN, 4, 0, 0),
185	{ }
186};
187
188static struct clk_rcg2 disp_cc_mdss_ahb_clk_src = {
189	.cmd_rcgr = 0x2154,
190	.mnd_width = 0,
191	.hid_width = 5,
192	.parent_map = disp_cc_parent_map_2,
193	.freq_tbl = ftbl_disp_cc_mdss_ahb_clk_src,
194	.clkr.hw.init = &(struct clk_init_data){
195		.name = "disp_cc_mdss_ahb_clk_src",
196		.parent_data = disp_cc_parent_data_2,
197		.num_parents = ARRAY_SIZE(disp_cc_parent_data_2),
198		.ops = &clk_rcg2_shared_ops,
199	},
200};
201
202static const struct freq_tbl ftbl_disp_cc_mdss_esc0_clk_src[] = {
203	F(19200000, P_BI_TCXO, 1, 0, 0),
204	{ }
205};
206
207static struct clk_rcg2 disp_cc_mdss_esc0_clk_src = {
208	.cmd_rcgr = 0x20d8,
209	.mnd_width = 0,
210	.hid_width = 5,
211	.parent_map = disp_cc_parent_map_0,
212	.freq_tbl = ftbl_disp_cc_mdss_esc0_clk_src,
213	.clkr.hw.init = &(struct clk_init_data){
214		.name = "disp_cc_mdss_esc0_clk_src",
215		.parent_data = disp_cc_parent_data_0,
216		.num_parents = ARRAY_SIZE(disp_cc_parent_data_0),
217		.ops = &clk_rcg2_ops,
218	},
219};
220
221static const struct freq_tbl ftbl_disp_cc_mdss_mdp_clk_src[] = {
222	F(19200000, P_BI_TCXO, 1, 0, 0),
223	F(192000000, P_DISP_CC_PLL0_OUT_MAIN, 4, 0, 0),
224	F(256000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0),
225	F(307200000, P_DISP_CC_PLL0_OUT_MAIN, 2.5, 0, 0),
226	F(384000000, P_DISP_CC_PLL0_OUT_MAIN, 2, 0, 0),
227	{ }
228};
229
230static struct clk_rcg2 disp_cc_mdss_mdp_clk_src = {
231	.cmd_rcgr = 0x2074,
232	.mnd_width = 0,
233	.hid_width = 5,
234	.parent_map = disp_cc_parent_map_3,
235	.freq_tbl = ftbl_disp_cc_mdss_mdp_clk_src,
236	.clkr.hw.init = &(struct clk_init_data){
237		.name = "disp_cc_mdss_mdp_clk_src",
238		.parent_data = disp_cc_parent_data_3,
239		.num_parents = ARRAY_SIZE(disp_cc_parent_data_3),
240		.flags = CLK_SET_RATE_PARENT,
241		.ops = &clk_rcg2_shared_ops,
242	},
243};
244
245static struct clk_rcg2 disp_cc_mdss_pclk0_clk_src = {
246	.cmd_rcgr = 0x205c,
247	.mnd_width = 8,
248	.hid_width = 5,
249	.parent_map = disp_cc_parent_map_4,
250	.clkr.hw.init = &(struct clk_init_data){
251		.name = "disp_cc_mdss_pclk0_clk_src",
252		.parent_data = disp_cc_parent_data_4,
253		.num_parents = ARRAY_SIZE(disp_cc_parent_data_4),
254		/* For set_rate and set_parent to succeed, parent(s) must be enabled */
255		.flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE | CLK_GET_RATE_NOCACHE,
256		.ops = &clk_pixel_ops,
257	},
258};
259
260static const struct freq_tbl ftbl_disp_cc_mdss_rot_clk_src[] = {
261	F(19200000, P_BI_TCXO, 1, 0, 0),
262	F(192000000, P_DISP_CC_PLL0_OUT_MAIN, 4, 0, 0),
263	F(256000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0),
264	F(307200000, P_DISP_CC_PLL0_OUT_MAIN, 2.5, 0, 0),
265	{ }
266};
267
268static struct clk_rcg2 disp_cc_mdss_rot_clk_src = {
269	.cmd_rcgr = 0x208c,
270	.mnd_width = 0,
271	.hid_width = 5,
272	.parent_map = disp_cc_parent_map_3,
273	.freq_tbl = ftbl_disp_cc_mdss_rot_clk_src,
274	.clkr.hw.init = &(struct clk_init_data){
275		.name = "disp_cc_mdss_rot_clk_src",
276		.parent_data = disp_cc_parent_data_3,
277		.num_parents = ARRAY_SIZE(disp_cc_parent_data_3),
278		.flags = CLK_SET_RATE_PARENT,
279		.ops = &clk_rcg2_shared_ops,
280	},
281};
282
283static struct clk_rcg2 disp_cc_mdss_vsync_clk_src = {
284	.cmd_rcgr = 0x20a4,
285	.mnd_width = 0,
286	.hid_width = 5,
287	.parent_map = disp_cc_parent_map_1,
288	.freq_tbl = ftbl_disp_cc_mdss_esc0_clk_src,
289	.clkr.hw.init = &(struct clk_init_data){
290		.name = "disp_cc_mdss_vsync_clk_src",
291		.parent_data = disp_cc_parent_data_1,
292		.num_parents = ARRAY_SIZE(disp_cc_parent_data_1),
293		.flags = CLK_SET_RATE_PARENT,
294		.ops = &clk_rcg2_shared_ops,
295	},
296};
297
298static const struct freq_tbl ftbl_disp_cc_sleep_clk_src[] = {
299	F(32764, P_SLEEP_CLK, 1, 0, 0),
300	{ }
301};
302
303static struct clk_rcg2 disp_cc_sleep_clk_src = {
304	.cmd_rcgr = 0x6050,
305	.mnd_width = 0,
306	.hid_width = 5,
307	.parent_map = disp_cc_parent_map_5,
308	.freq_tbl = ftbl_disp_cc_sleep_clk_src,
309	.clkr.hw.init = &(struct clk_init_data){
310		.name = "disp_cc_sleep_clk_src",
311		.parent_data = disp_cc_parent_data_5,
312		.num_parents = ARRAY_SIZE(disp_cc_parent_data_5),
313		.ops = &clk_rcg2_ops,
314	},
315};
316
317static struct clk_branch disp_cc_mdss_ahb_clk = {
318	.halt_reg = 0x2044,
319	.halt_check = BRANCH_HALT,
320	.clkr = {
321		.enable_reg = 0x2044,
322		.enable_mask = BIT(0),
323		.hw.init = &(struct clk_init_data){
324			.name = "disp_cc_mdss_ahb_clk",
325			.parent_hws = (const struct clk_hw*[]){
326				&disp_cc_mdss_ahb_clk_src.clkr.hw,
327			},
328			.num_parents = 1,
329			.flags = CLK_SET_RATE_PARENT,
330			.ops = &clk_branch2_ops,
331		},
332	},
333};
334
335static struct clk_branch disp_cc_mdss_byte0_clk = {
336	.halt_reg = 0x2024,
337	.halt_check = BRANCH_HALT,
338	.clkr = {
339		.enable_reg = 0x2024,
340		.enable_mask = BIT(0),
341		.hw.init = &(struct clk_init_data){
342			.name = "disp_cc_mdss_byte0_clk",
343			.parent_hws = (const struct clk_hw*[]){
344				&disp_cc_mdss_byte0_clk_src.clkr.hw,
345			},
346			.num_parents = 1,
347			.flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE,
348			.ops = &clk_branch2_ops,
349		},
350	},
351};
352
353static struct clk_branch disp_cc_mdss_byte0_intf_clk = {
354	.halt_reg = 0x2028,
355	.halt_check = BRANCH_HALT,
356	.clkr = {
357		.enable_reg = 0x2028,
358		.enable_mask = BIT(0),
359		.hw.init = &(struct clk_init_data){
360			.name = "disp_cc_mdss_byte0_intf_clk",
361			.parent_hws = (const struct clk_hw*[]){
362				&disp_cc_mdss_byte0_div_clk_src.clkr.hw,
363			},
364			.num_parents = 1,
365			.flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE,
366			.ops = &clk_branch2_ops,
367		},
368	},
369};
370
371static struct clk_branch disp_cc_mdss_esc0_clk = {
372	.halt_reg = 0x202c,
373	.halt_check = BRANCH_HALT,
374	.clkr = {
375		.enable_reg = 0x202c,
376		.enable_mask = BIT(0),
377		.hw.init = &(struct clk_init_data){
378			.name = "disp_cc_mdss_esc0_clk",
379			.parent_hws = (const struct clk_hw*[]){
380				&disp_cc_mdss_esc0_clk_src.clkr.hw,
381			},
382			.num_parents = 1,
383			.flags = CLK_SET_RATE_PARENT,
384			.ops = &clk_branch2_ops,
385		},
386	},
387};
388
389static struct clk_branch disp_cc_mdss_mdp_clk = {
390	.halt_reg = 0x2008,
391	.halt_check = BRANCH_HALT,
392	.clkr = {
393		.enable_reg = 0x2008,
394		.enable_mask = BIT(0),
395		.hw.init = &(struct clk_init_data){
396			.name = "disp_cc_mdss_mdp_clk",
397			.parent_hws = (const struct clk_hw*[]){
398				&disp_cc_mdss_mdp_clk_src.clkr.hw,
399			},
400			.num_parents = 1,
401			.flags = CLK_SET_RATE_PARENT,
402			.ops = &clk_branch2_ops,
403		},
404	},
405};
406
407static struct clk_branch disp_cc_mdss_mdp_lut_clk = {
408	.halt_reg = 0x2018,
409	.halt_check = BRANCH_HALT_VOTED,
410	.clkr = {
411		.enable_reg = 0x2018,
412		.enable_mask = BIT(0),
413		.hw.init = &(struct clk_init_data){
414			.name = "disp_cc_mdss_mdp_lut_clk",
415			.parent_hws = (const struct clk_hw*[]){
416				&disp_cc_mdss_mdp_clk_src.clkr.hw,
417			},
418			.num_parents = 1,
419			.flags = CLK_SET_RATE_PARENT,
420			.ops = &clk_branch2_ops,
421		},
422	},
423};
424
425static struct clk_branch disp_cc_mdss_non_gdsc_ahb_clk = {
426	.halt_reg = 0x4004,
427	.halt_check = BRANCH_HALT_VOTED,
428	.clkr = {
429		.enable_reg = 0x4004,
430		.enable_mask = BIT(0),
431		.hw.init = &(struct clk_init_data){
432			.name = "disp_cc_mdss_non_gdsc_ahb_clk",
433			.parent_hws = (const struct clk_hw*[]){
434				&disp_cc_mdss_ahb_clk_src.clkr.hw,
435			},
436			.num_parents = 1,
437			.flags = CLK_SET_RATE_PARENT,
438			.ops = &clk_branch2_ops,
439		},
440	},
441};
442
443static struct clk_branch disp_cc_mdss_pclk0_clk = {
444	.halt_reg = 0x2004,
445	.halt_check = BRANCH_HALT,
446	.clkr = {
447		.enable_reg = 0x2004,
448		.enable_mask = BIT(0),
449		.hw.init = &(struct clk_init_data){
450			.name = "disp_cc_mdss_pclk0_clk",
451			.parent_hws = (const struct clk_hw*[]){
452				&disp_cc_mdss_pclk0_clk_src.clkr.hw,
453			},
454			.num_parents = 1,
455			.flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE,
456			.ops = &clk_branch2_ops,
457		},
458	},
459};
460
461static struct clk_branch disp_cc_mdss_rot_clk = {
462	.halt_reg = 0x2010,
463	.halt_check = BRANCH_HALT,
464	.clkr = {
465		.enable_reg = 0x2010,
466		.enable_mask = BIT(0),
467		.hw.init = &(struct clk_init_data){
468			.name = "disp_cc_mdss_rot_clk",
469			.parent_hws = (const struct clk_hw*[]) {
470				&disp_cc_mdss_rot_clk_src.clkr.hw,
471			},
472			.num_parents = 1,
473			.flags = CLK_SET_RATE_PARENT,
474			.ops = &clk_branch2_ops,
475		},
476	},
477};
478
479static struct clk_branch disp_cc_mdss_vsync_clk = {
480	.halt_reg = 0x2020,
481	.halt_check = BRANCH_HALT,
482	.clkr = {
483		.enable_reg = 0x2020,
484		.enable_mask = BIT(0),
485		.hw.init = &(struct clk_init_data){
486			.name = "disp_cc_mdss_vsync_clk",
487			.parent_hws = (const struct clk_hw*[]){
488				&disp_cc_mdss_vsync_clk_src.clkr.hw,
489			},
490			.num_parents = 1,
491			.flags = CLK_SET_RATE_PARENT,
492			.ops = &clk_branch2_ops,
493		},
494	},
495};
496
497static struct clk_branch disp_cc_sleep_clk = {
498	.halt_reg = 0x6068,
499	.halt_check = BRANCH_HALT,
500	.clkr = {
501		.enable_reg = 0x6068,
502		.enable_mask = BIT(0),
503		.hw.init = &(struct clk_init_data){
504			.name = "disp_cc_sleep_clk",
505			.parent_hws = (const struct clk_hw*[]){
506				&disp_cc_sleep_clk_src.clkr.hw,
507			},
508			.num_parents = 1,
509			.flags = CLK_SET_RATE_PARENT,
510			.ops = &clk_branch2_ops,
511		},
512	},
513};
514
515static struct gdsc mdss_gdsc = {
516	.gdscr = 0x3000,
517	.pd = {
518		.name = "mdss_gdsc",
519	},
520	.pwrsts = PWRSTS_OFF_ON,
521	.flags = HW_CTRL,
522};
523
524static struct gdsc *disp_cc_sm6115_gdscs[] = {
525	[MDSS_GDSC] = &mdss_gdsc,
526};
527
528static struct clk_regmap *disp_cc_sm6115_clocks[] = {
529	[DISP_CC_PLL0] = &disp_cc_pll0.clkr,
530	[DISP_CC_PLL0_OUT_MAIN] = &disp_cc_pll0_out_main.clkr,
531	[DISP_CC_MDSS_AHB_CLK] = &disp_cc_mdss_ahb_clk.clkr,
532	[DISP_CC_MDSS_AHB_CLK_SRC] = &disp_cc_mdss_ahb_clk_src.clkr,
533	[DISP_CC_MDSS_BYTE0_CLK] = &disp_cc_mdss_byte0_clk.clkr,
534	[DISP_CC_MDSS_BYTE0_CLK_SRC] = &disp_cc_mdss_byte0_clk_src.clkr,
535	[DISP_CC_MDSS_BYTE0_DIV_CLK_SRC] = &disp_cc_mdss_byte0_div_clk_src.clkr,
536	[DISP_CC_MDSS_BYTE0_INTF_CLK] = &disp_cc_mdss_byte0_intf_clk.clkr,
537	[DISP_CC_MDSS_ESC0_CLK] = &disp_cc_mdss_esc0_clk.clkr,
538	[DISP_CC_MDSS_ESC0_CLK_SRC] = &disp_cc_mdss_esc0_clk_src.clkr,
539	[DISP_CC_MDSS_MDP_CLK] = &disp_cc_mdss_mdp_clk.clkr,
540	[DISP_CC_MDSS_MDP_CLK_SRC] = &disp_cc_mdss_mdp_clk_src.clkr,
541	[DISP_CC_MDSS_MDP_LUT_CLK] = &disp_cc_mdss_mdp_lut_clk.clkr,
542	[DISP_CC_MDSS_NON_GDSC_AHB_CLK] = &disp_cc_mdss_non_gdsc_ahb_clk.clkr,
543	[DISP_CC_MDSS_PCLK0_CLK] = &disp_cc_mdss_pclk0_clk.clkr,
544	[DISP_CC_MDSS_PCLK0_CLK_SRC] = &disp_cc_mdss_pclk0_clk_src.clkr,
545	[DISP_CC_MDSS_ROT_CLK] = &disp_cc_mdss_rot_clk.clkr,
546	[DISP_CC_MDSS_ROT_CLK_SRC] = &disp_cc_mdss_rot_clk_src.clkr,
547	[DISP_CC_MDSS_VSYNC_CLK] = &disp_cc_mdss_vsync_clk.clkr,
548	[DISP_CC_MDSS_VSYNC_CLK_SRC] = &disp_cc_mdss_vsync_clk_src.clkr,
549	[DISP_CC_SLEEP_CLK] = &disp_cc_sleep_clk.clkr,
550	[DISP_CC_SLEEP_CLK_SRC] = &disp_cc_sleep_clk_src.clkr,
551};
552
553static const struct regmap_config disp_cc_sm6115_regmap_config = {
554	.reg_bits = 32,
555	.reg_stride = 4,
556	.val_bits = 32,
557	.max_register = 0x10000,
558	.fast_io = true,
559};
560
561static const struct qcom_cc_desc disp_cc_sm6115_desc = {
562	.config = &disp_cc_sm6115_regmap_config,
563	.clks = disp_cc_sm6115_clocks,
564	.num_clks = ARRAY_SIZE(disp_cc_sm6115_clocks),
565	.gdscs = disp_cc_sm6115_gdscs,
566	.num_gdscs = ARRAY_SIZE(disp_cc_sm6115_gdscs),
567};
568
569static const struct of_device_id disp_cc_sm6115_match_table[] = {
570	{ .compatible = "qcom,sm6115-dispcc" },
571	{ }
572};
573MODULE_DEVICE_TABLE(of, disp_cc_sm6115_match_table);
574
575static int disp_cc_sm6115_probe(struct platform_device *pdev)
576{
577	struct regmap *regmap;
578	int ret;
579
580	regmap = qcom_cc_map(pdev, &disp_cc_sm6115_desc);
581	if (IS_ERR(regmap))
582		return PTR_ERR(regmap);
583
584	clk_alpha_pll_configure(&disp_cc_pll0, regmap, &disp_cc_pll0_config);
585
586	/* Keep DISP_CC_XO_CLK always-ON */
587	regmap_update_bits(regmap, 0x604c, BIT(0), BIT(0));
588
589	ret = qcom_cc_really_probe(pdev, &disp_cc_sm6115_desc, regmap);
590	if (ret) {
591		dev_err(&pdev->dev, "Failed to register DISP CC clocks\n");
592		return ret;
593	}
594
595	return ret;
596}
597
598static struct platform_driver disp_cc_sm6115_driver = {
599	.probe = disp_cc_sm6115_probe,
600	.driver = {
601		.name = "dispcc-sm6115",
602		.of_match_table = disp_cc_sm6115_match_table,
603	},
604};
605
606module_platform_driver(disp_cc_sm6115_driver);
607MODULE_DESCRIPTION("Qualcomm SM6115 Display Clock controller");
608MODULE_LICENSE("GPL");