File Index
Files and directories
Sign in
FILE

dispcc-sm4450.c

File preview with syntax highlighting.

linux-6.19.14/drivers/clk/qcom/dispcc-sm4450.c C
  1// SPDX-License-Identifier: GPL-2.0-only
  2/*
  3 * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved.
  4 */
  5
  6#include <linux/clk-provider.h>
  7#include <linux/module.h>
  8#include <linux/mod_devicetable.h>
  9#include <linux/platform_device.h>
 10#include <linux/regmap.h>
 11
 12#include <dt-bindings/clock/qcom,sm4450-dispcc.h>
 13
 14#include "clk-alpha-pll.h"
 15#include "clk-branch.h"
 16#include "clk-pll.h"
 17#include "clk-rcg.h"
 18#include "clk-regmap.h"
 19#include "clk-regmap-divider.h"
 20#include "common.h"
 21#include "gdsc.h"
 22#include "reset.h"
 23
 24enum {
 25	DT_BI_TCXO,
 26	DT_BI_TCXO_AO,
 27	DT_AHB_CLK,
 28	DT_SLEEP_CLK,
 29
 30	DT_DSI0_PHY_PLL_OUT_BYTECLK,
 31	DT_DSI0_PHY_PLL_OUT_DSICLK,
 32};
 33
 34enum {
 35	P_BI_TCXO,
 36	P_DISP_CC_PLL0_OUT_MAIN,
 37	P_DISP_CC_PLL1_OUT_EVEN,
 38	P_DISP_CC_PLL1_OUT_MAIN,
 39	P_DSI0_PHY_PLL_OUT_BYTECLK,
 40	P_DSI0_PHY_PLL_OUT_DSICLK,
 41	P_SLEEP_CLK,
 42};
 43
 44static const struct pll_vco lucid_evo_vco[] = {
 45	{ 249600000, 2020000000, 0 },
 46};
 47
 48/* 600.0 MHz Configuration */
 49static const struct alpha_pll_config disp_cc_pll0_config = {
 50	.l = 0x1f,
 51	.alpha = 0x4000,
 52	.config_ctl_val = 0x20485699,
 53	.config_ctl_hi_val = 0x00182261,
 54	.config_ctl_hi1_val = 0x32aa299c,
 55	.user_ctl_val = 0x00000000,
 56	.user_ctl_hi_val = 0x00000805,
 57};
 58
 59static struct clk_alpha_pll disp_cc_pll0 = {
 60	.offset = 0x0,
 61	.vco_table = lucid_evo_vco,
 62	.num_vco = ARRAY_SIZE(lucid_evo_vco),
 63	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_EVO],
 64	.clkr = {
 65		.hw.init = &(const struct clk_init_data) {
 66			.name = "disp_cc_pll0",
 67			.parent_data = &(const struct clk_parent_data) {
 68				.index = DT_BI_TCXO,
 69			},
 70			.num_parents = 1,
 71			.ops = &clk_alpha_pll_lucid_evo_ops,
 72		},
 73	},
 74};
 75
 76static struct clk_alpha_pll disp_cc_pll1 = {
 77	.offset = 0x1000,
 78	.vco_table = lucid_evo_vco,
 79	.num_vco = ARRAY_SIZE(lucid_evo_vco),
 80	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_EVO],
 81	.clkr = {
 82		.hw.init = &(const struct clk_init_data) {
 83			.name = "disp_cc_pll1",
 84			.parent_data = &(const struct clk_parent_data) {
 85				.index = DT_BI_TCXO,
 86			},
 87			.num_parents = 1,
 88			.ops = &clk_alpha_pll_lucid_evo_ops,
 89		},
 90	},
 91};
 92
 93static const struct parent_map disp_cc_parent_map_0[] = {
 94	{ P_BI_TCXO, 0 },
 95	{ P_DSI0_PHY_PLL_OUT_DSICLK, 1 },
 96	{ P_DSI0_PHY_PLL_OUT_BYTECLK, 2 },
 97};
 98
 99static const struct clk_parent_data disp_cc_parent_data_0[] = {
100	{ .index = DT_BI_TCXO },
101	{ .index = DT_DSI0_PHY_PLL_OUT_DSICLK },
102	{ .index = DT_DSI0_PHY_PLL_OUT_BYTECLK },
103};
104
105static const struct parent_map disp_cc_parent_map_1[] = {
106	{ P_BI_TCXO, 0 },
107	{ P_DISP_CC_PLL0_OUT_MAIN, 1 },
108	{ P_DISP_CC_PLL1_OUT_MAIN, 4 },
109	{ P_DISP_CC_PLL1_OUT_EVEN, 6 },
110};
111
112static const struct clk_parent_data disp_cc_parent_data_1[] = {
113	{ .index = DT_BI_TCXO },
114	{ .hw = &disp_cc_pll0.clkr.hw },
115	{ .hw = &disp_cc_pll1.clkr.hw },
116	{ .hw = &disp_cc_pll1.clkr.hw },
117};
118
119static const struct parent_map disp_cc_parent_map_2[] = {
120	{ P_BI_TCXO, 0 },
121};
122
123static const struct clk_parent_data disp_cc_parent_data_2[] = {
124	{ .index = DT_BI_TCXO },
125};
126
127static const struct clk_parent_data disp_cc_parent_data_2_ao[] = {
128	{ .index = DT_BI_TCXO_AO },
129};
130
131static const struct parent_map disp_cc_parent_map_3[] = {
132	{ P_BI_TCXO, 0 },
133	{ P_DISP_CC_PLL1_OUT_MAIN, 4 },
134	{ P_DISP_CC_PLL1_OUT_EVEN, 6 },
135};
136
137static const struct clk_parent_data disp_cc_parent_data_3[] = {
138	{ .index = DT_BI_TCXO },
139	{ .hw = &disp_cc_pll1.clkr.hw },
140	{ .hw = &disp_cc_pll1.clkr.hw },
141};
142
143static const struct parent_map disp_cc_parent_map_4[] = {
144	{ P_BI_TCXO, 0 },
145	{ P_DSI0_PHY_PLL_OUT_BYTECLK, 2 },
146};
147
148static const struct clk_parent_data disp_cc_parent_data_4[] = {
149	{ .index = DT_BI_TCXO },
150	{ .index = DT_DSI0_PHY_PLL_OUT_BYTECLK },
151};
152
153static const struct parent_map disp_cc_parent_map_5[] = {
154	{ P_SLEEP_CLK, 0 },
155};
156
157static const struct clk_parent_data disp_cc_parent_data_5[] = {
158	{ .index = DT_SLEEP_CLK },
159};
160
161static const struct freq_tbl ftbl_disp_cc_mdss_ahb_clk_src[] = {
162	F(19200000, P_BI_TCXO, 1, 0, 0),
163	F(37500000, P_DISP_CC_PLL1_OUT_MAIN, 16, 0, 0),
164	F(75000000, P_DISP_CC_PLL1_OUT_MAIN, 8, 0, 0),
165	{ }
166};
167
168static struct clk_rcg2 disp_cc_mdss_ahb_clk_src = {
169	.cmd_rcgr = 0x82a4,
170	.mnd_width = 0,
171	.hid_width = 5,
172	.parent_map = disp_cc_parent_map_3,
173	.freq_tbl = ftbl_disp_cc_mdss_ahb_clk_src,
174	.clkr.hw.init = &(const struct clk_init_data) {
175		.name = "disp_cc_mdss_ahb_clk_src",
176		.parent_data = disp_cc_parent_data_3,
177		.num_parents = ARRAY_SIZE(disp_cc_parent_data_3),
178		.flags = CLK_SET_RATE_PARENT,
179		.ops = &clk_rcg2_shared_ops,
180	},
181};
182
183static const struct freq_tbl ftbl_disp_cc_mdss_byte0_clk_src[] = {
184	F(19200000, P_BI_TCXO, 1, 0, 0),
185	{ }
186};
187
188static struct clk_rcg2 disp_cc_mdss_byte0_clk_src = {
189	.cmd_rcgr = 0x80f8,
190	.mnd_width = 0,
191	.hid_width = 5,
192	.parent_map = disp_cc_parent_map_0,
193	.freq_tbl = ftbl_disp_cc_mdss_byte0_clk_src,
194	.clkr.hw.init = &(const struct clk_init_data) {
195		.name = "disp_cc_mdss_byte0_clk_src",
196		.parent_data = disp_cc_parent_data_0,
197		.num_parents = ARRAY_SIZE(disp_cc_parent_data_0),
198		.flags = CLK_SET_RATE_PARENT,
199		.ops = &clk_byte2_ops,
200	},
201};
202
203static struct clk_rcg2 disp_cc_mdss_esc0_clk_src = {
204	.cmd_rcgr = 0x8114,
205	.mnd_width = 0,
206	.hid_width = 5,
207	.parent_map = disp_cc_parent_map_4,
208	.freq_tbl = ftbl_disp_cc_mdss_byte0_clk_src,
209	.clkr.hw.init = &(const struct clk_init_data) {
210		.name = "disp_cc_mdss_esc0_clk_src",
211		.parent_data = disp_cc_parent_data_4,
212		.num_parents = ARRAY_SIZE(disp_cc_parent_data_4),
213		.flags = CLK_SET_RATE_PARENT,
214		.ops = &clk_rcg2_shared_ops,
215	},
216};
217
218static const struct freq_tbl ftbl_disp_cc_mdss_mdp_clk_src[] = {
219	F(200000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0),
220	F(325000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0),
221	F(380000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0),
222	F(506000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0),
223	F(608000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0),
224	{ }
225};
226
227static struct clk_rcg2 disp_cc_mdss_mdp_clk_src = {
228	.cmd_rcgr = 0x80b0,
229	.mnd_width = 0,
230	.hid_width = 5,
231	.parent_map = disp_cc_parent_map_1,
232	.freq_tbl = ftbl_disp_cc_mdss_mdp_clk_src,
233	.clkr.hw.init = &(const struct clk_init_data) {
234		.name = "disp_cc_mdss_mdp_clk_src",
235		.parent_data = disp_cc_parent_data_1,
236		.num_parents = ARRAY_SIZE(disp_cc_parent_data_1),
237		.flags = CLK_SET_RATE_PARENT,
238		.ops = &clk_rcg2_shared_ops,
239	},
240};
241
242static struct clk_rcg2 disp_cc_mdss_pclk0_clk_src = {
243	.cmd_rcgr = 0x8098,
244	.mnd_width = 8,
245	.hid_width = 5,
246	.parent_map = disp_cc_parent_map_0,
247	.freq_tbl = ftbl_disp_cc_mdss_byte0_clk_src,
248	.clkr.hw.init = &(const struct clk_init_data) {
249		.name = "disp_cc_mdss_pclk0_clk_src",
250		.parent_data = disp_cc_parent_data_0,
251		.num_parents = ARRAY_SIZE(disp_cc_parent_data_0),
252		.flags = CLK_SET_RATE_PARENT,
253		.ops = &clk_pixel_ops,
254	},
255};
256
257static const struct freq_tbl ftbl_disp_cc_mdss_rot_clk_src[] = {
258	F(200000000, P_DISP_CC_PLL1_OUT_MAIN, 3, 0, 0),
259	F(300000000, P_DISP_CC_PLL1_OUT_MAIN, 2, 0, 0),
260	{ }
261};
262
263static struct clk_rcg2 disp_cc_mdss_rot_clk_src = {
264	.cmd_rcgr = 0x80c8,
265	.mnd_width = 0,
266	.hid_width = 5,
267	.parent_map = disp_cc_parent_map_1,
268	.freq_tbl = ftbl_disp_cc_mdss_rot_clk_src,
269	.clkr.hw.init = &(const struct clk_init_data) {
270		.name = "disp_cc_mdss_rot_clk_src",
271		.parent_data = disp_cc_parent_data_1,
272		.num_parents = ARRAY_SIZE(disp_cc_parent_data_1),
273		.flags = CLK_SET_RATE_PARENT,
274		.ops = &clk_rcg2_shared_ops,
275	},
276};
277
278static struct clk_rcg2 disp_cc_mdss_vsync_clk_src = {
279	.cmd_rcgr = 0x80e0,
280	.mnd_width = 0,
281	.hid_width = 5,
282	.parent_map = disp_cc_parent_map_2,
283	.freq_tbl = ftbl_disp_cc_mdss_byte0_clk_src,
284	.clkr.hw.init = &(const struct clk_init_data) {
285		.name = "disp_cc_mdss_vsync_clk_src",
286		.parent_data = disp_cc_parent_data_2,
287		.num_parents = ARRAY_SIZE(disp_cc_parent_data_2),
288		.flags = CLK_SET_RATE_PARENT,
289		.ops = &clk_rcg2_shared_ops,
290	},
291};
292
293static const struct freq_tbl ftbl_disp_cc_sleep_clk_src[] = {
294	F(32000, P_SLEEP_CLK, 1, 0, 0),
295	{ }
296};
297
298static struct clk_rcg2 disp_cc_sleep_clk_src = {
299	.cmd_rcgr = 0xe058,
300	.mnd_width = 0,
301	.hid_width = 5,
302	.parent_map = disp_cc_parent_map_5,
303	.freq_tbl = ftbl_disp_cc_sleep_clk_src,
304	.clkr.hw.init = &(const struct clk_init_data) {
305		.name = "disp_cc_sleep_clk_src",
306		.parent_data = disp_cc_parent_data_5,
307		.num_parents = ARRAY_SIZE(disp_cc_parent_data_5),
308		.flags = CLK_SET_RATE_PARENT,
309		.ops = &clk_rcg2_shared_ops,
310	},
311};
312
313static struct clk_rcg2 disp_cc_xo_clk_src = {
314	.cmd_rcgr = 0xe03c,
315	.mnd_width = 0,
316	.hid_width = 5,
317	.parent_map = disp_cc_parent_map_2,
318	.freq_tbl = ftbl_disp_cc_mdss_byte0_clk_src,
319	.clkr.hw.init = &(const struct clk_init_data) {
320		.name = "disp_cc_xo_clk_src",
321		.parent_data = disp_cc_parent_data_2_ao,
322		.num_parents = ARRAY_SIZE(disp_cc_parent_data_2_ao),
323		.flags = CLK_SET_RATE_PARENT,
324		.ops = &clk_rcg2_shared_ops,
325	},
326};
327
328static struct clk_regmap_div disp_cc_mdss_byte0_div_clk_src = {
329	.reg = 0x8110,
330	.shift = 0,
331	.width = 4,
332	.clkr.hw.init = &(const struct clk_init_data) {
333		.name = "disp_cc_mdss_byte0_div_clk_src",
334		.parent_hws = (const struct clk_hw*[]) {
335			&disp_cc_mdss_byte0_clk_src.clkr.hw,
336		},
337		.num_parents = 1,
338		.flags = CLK_SET_RATE_PARENT,
339		.ops = &clk_regmap_div_ops,
340	},
341};
342
343static struct clk_branch disp_cc_mdss_ahb1_clk = {
344	.halt_reg = 0xa020,
345	.halt_check = BRANCH_HALT,
346	.clkr = {
347		.enable_reg = 0xa020,
348		.enable_mask = BIT(0),
349		.hw.init = &(const struct clk_init_data) {
350			.name = "disp_cc_mdss_ahb1_clk",
351			.parent_hws = (const struct clk_hw*[]) {
352				&disp_cc_mdss_ahb_clk_src.clkr.hw,
353			},
354			.num_parents = 1,
355			.flags = CLK_SET_RATE_PARENT,
356			.ops = &clk_branch2_ops,
357		},
358	},
359};
360
361static struct clk_branch disp_cc_mdss_ahb_clk = {
362	.halt_reg = 0x8094,
363	.halt_check = BRANCH_HALT,
364	.clkr = {
365		.enable_reg = 0x8094,
366		.enable_mask = BIT(0),
367		.hw.init = &(const struct clk_init_data) {
368			.name = "disp_cc_mdss_ahb_clk",
369			.parent_hws = (const struct clk_hw*[]) {
370				&disp_cc_mdss_ahb_clk_src.clkr.hw,
371			},
372			.num_parents = 1,
373			.flags = CLK_SET_RATE_PARENT,
374			.ops = &clk_branch2_ops,
375		},
376	},
377};
378
379static struct clk_branch disp_cc_mdss_byte0_clk = {
380	.halt_reg = 0x8024,
381	.halt_check = BRANCH_HALT,
382	.clkr = {
383		.enable_reg = 0x8024,
384		.enable_mask = BIT(0),
385		.hw.init = &(const struct clk_init_data) {
386			.name = "disp_cc_mdss_byte0_clk",
387			.parent_hws = (const struct clk_hw*[]) {
388				&disp_cc_mdss_byte0_clk_src.clkr.hw,
389			},
390			.num_parents = 1,
391			.flags = CLK_SET_RATE_PARENT,
392			.ops = &clk_branch2_ops,
393		},
394	},
395};
396
397static struct clk_branch disp_cc_mdss_byte0_intf_clk = {
398	.halt_reg = 0x8028,
399	.halt_check = BRANCH_HALT,
400	.clkr = {
401		.enable_reg = 0x8028,
402		.enable_mask = BIT(0),
403		.hw.init = &(const struct clk_init_data) {
404			.name = "disp_cc_mdss_byte0_intf_clk",
405			.parent_hws = (const struct clk_hw*[]) {
406				&disp_cc_mdss_byte0_div_clk_src.clkr.hw,
407			},
408			.num_parents = 1,
409			.flags = CLK_SET_RATE_PARENT,
410			.ops = &clk_branch2_ops,
411		},
412	},
413};
414
415static struct clk_branch disp_cc_mdss_esc0_clk = {
416	.halt_reg = 0x802c,
417	.halt_check = BRANCH_HALT,
418	.clkr = {
419		.enable_reg = 0x802c,
420		.enable_mask = BIT(0),
421		.hw.init = &(const struct clk_init_data) {
422			.name = "disp_cc_mdss_esc0_clk",
423			.parent_hws = (const struct clk_hw*[]) {
424				&disp_cc_mdss_esc0_clk_src.clkr.hw,
425			},
426			.num_parents = 1,
427			.flags = CLK_SET_RATE_PARENT,
428			.ops = &clk_branch2_ops,
429		},
430	},
431};
432
433static struct clk_branch disp_cc_mdss_mdp1_clk = {
434	.halt_reg = 0xa004,
435	.halt_check = BRANCH_HALT,
436	.clkr = {
437		.enable_reg = 0xa004,
438		.enable_mask = BIT(0),
439		.hw.init = &(const struct clk_init_data) {
440			.name = "disp_cc_mdss_mdp1_clk",
441			.parent_hws = (const struct clk_hw*[]) {
442				&disp_cc_mdss_mdp_clk_src.clkr.hw,
443			},
444			.num_parents = 1,
445			.flags = CLK_SET_RATE_PARENT,
446			.ops = &clk_branch2_ops,
447		},
448	},
449};
450
451static struct clk_branch disp_cc_mdss_mdp_clk = {
452	.halt_reg = 0x8008,
453	.halt_check = BRANCH_HALT,
454	.clkr = {
455		.enable_reg = 0x8008,
456		.enable_mask = BIT(0),
457		.hw.init = &(const struct clk_init_data) {
458			.name = "disp_cc_mdss_mdp_clk",
459			.parent_hws = (const struct clk_hw*[]) {
460				&disp_cc_mdss_mdp_clk_src.clkr.hw,
461			},
462			.num_parents = 1,
463			.flags = CLK_SET_RATE_PARENT,
464			.ops = &clk_branch2_ops,
465		},
466	},
467};
468
469static struct clk_branch disp_cc_mdss_mdp_lut1_clk = {
470	.halt_reg = 0xa014,
471	.halt_check = BRANCH_HALT,
472	.clkr = {
473		.enable_reg = 0xa014,
474		.enable_mask = BIT(0),
475		.hw.init = &(const struct clk_init_data) {
476			.name = "disp_cc_mdss_mdp_lut1_clk",
477			.parent_hws = (const struct clk_hw*[]) {
478				&disp_cc_mdss_mdp_clk_src.clkr.hw,
479			},
480			.num_parents = 1,
481			.flags = CLK_SET_RATE_PARENT,
482			.ops = &clk_branch2_ops,
483		},
484	},
485};
486
487static struct clk_branch disp_cc_mdss_mdp_lut_clk = {
488	.halt_reg = 0x8018,
489	.halt_check = BRANCH_HALT_VOTED,
490	.clkr = {
491		.enable_reg = 0x8018,
492		.enable_mask = BIT(0),
493		.hw.init = &(const struct clk_init_data) {
494			.name = "disp_cc_mdss_mdp_lut_clk",
495			.parent_hws = (const struct clk_hw*[]) {
496				&disp_cc_mdss_mdp_clk_src.clkr.hw,
497			},
498			.num_parents = 1,
499			.flags = CLK_SET_RATE_PARENT,
500			.ops = &clk_branch2_ops,
501		},
502	},
503};
504
505static struct clk_branch disp_cc_mdss_non_gdsc_ahb_clk = {
506	.halt_reg = 0xc004,
507	.halt_check = BRANCH_HALT_VOTED,
508	.clkr = {
509		.enable_reg = 0xc004,
510		.enable_mask = BIT(0),
511		.hw.init = &(const struct clk_init_data) {
512			.name = "disp_cc_mdss_non_gdsc_ahb_clk",
513			.parent_hws = (const struct clk_hw*[]) {
514				&disp_cc_mdss_ahb_clk_src.clkr.hw,
515			},
516			.num_parents = 1,
517			.flags = CLK_SET_RATE_PARENT,
518			.ops = &clk_branch2_ops,
519		},
520	},
521};
522
523static struct clk_branch disp_cc_mdss_pclk0_clk = {
524	.halt_reg = 0x8004,
525	.halt_check = BRANCH_HALT,
526	.clkr = {
527		.enable_reg = 0x8004,
528		.enable_mask = BIT(0),
529		.hw.init = &(const struct clk_init_data) {
530			.name = "disp_cc_mdss_pclk0_clk",
531			.parent_hws = (const struct clk_hw*[]) {
532				&disp_cc_mdss_pclk0_clk_src.clkr.hw,
533			},
534			.num_parents = 1,
535			.flags = CLK_SET_RATE_PARENT,
536			.ops = &clk_branch2_ops,
537		},
538	},
539};
540
541static struct clk_branch disp_cc_mdss_rot1_clk = {
542	.halt_reg = 0xa00c,
543	.halt_check = BRANCH_HALT,
544	.clkr = {
545		.enable_reg = 0xa00c,
546		.enable_mask = BIT(0),
547		.hw.init = &(const struct clk_init_data) {
548			.name = "disp_cc_mdss_rot1_clk",
549			.parent_hws = (const struct clk_hw*[]) {
550				&disp_cc_mdss_rot_clk_src.clkr.hw,
551			},
552			.num_parents = 1,
553			.flags = CLK_SET_RATE_PARENT,
554			.ops = &clk_branch2_ops,
555		},
556	},
557};
558
559static struct clk_branch disp_cc_mdss_rot_clk = {
560	.halt_reg = 0x8010,
561	.halt_check = BRANCH_HALT,
562	.clkr = {
563		.enable_reg = 0x8010,
564		.enable_mask = BIT(0),
565		.hw.init = &(const struct clk_init_data) {
566			.name = "disp_cc_mdss_rot_clk",
567			.parent_hws = (const struct clk_hw*[]) {
568				&disp_cc_mdss_rot_clk_src.clkr.hw,
569			},
570			.num_parents = 1,
571			.flags = CLK_SET_RATE_PARENT,
572			.ops = &clk_branch2_ops,
573		},
574	},
575};
576
577static struct clk_branch disp_cc_mdss_rscc_ahb_clk = {
578	.halt_reg = 0xc00c,
579	.halt_check = BRANCH_HALT,
580	.clkr = {
581		.enable_reg = 0xc00c,
582		.enable_mask = BIT(0),
583		.hw.init = &(const struct clk_init_data) {
584			.name = "disp_cc_mdss_rscc_ahb_clk",
585			.parent_hws = (const struct clk_hw*[]) {
586				&disp_cc_mdss_ahb_clk_src.clkr.hw,
587			},
588			.num_parents = 1,
589			.flags = CLK_SET_RATE_PARENT,
590			.ops = &clk_branch2_ops,
591		},
592	},
593};
594
595static struct clk_branch disp_cc_mdss_rscc_vsync_clk = {
596	.halt_reg = 0xc008,
597	.halt_check = BRANCH_HALT,
598	.clkr = {
599		.enable_reg = 0xc008,
600		.enable_mask = BIT(0),
601		.hw.init = &(const struct clk_init_data) {
602			.name = "disp_cc_mdss_rscc_vsync_clk",
603			.parent_hws = (const struct clk_hw*[]) {
604				&disp_cc_mdss_vsync_clk_src.clkr.hw,
605			},
606			.num_parents = 1,
607			.flags = CLK_SET_RATE_PARENT,
608			.ops = &clk_branch2_ops,
609		},
610	},
611};
612
613static struct clk_branch disp_cc_mdss_vsync1_clk = {
614	.halt_reg = 0xa01c,
615	.halt_check = BRANCH_HALT,
616	.clkr = {
617		.enable_reg = 0xa01c,
618		.enable_mask = BIT(0),
619		.hw.init = &(const struct clk_init_data) {
620			.name = "disp_cc_mdss_vsync1_clk",
621			.parent_hws = (const struct clk_hw*[]) {
622				&disp_cc_mdss_vsync_clk_src.clkr.hw,
623			},
624			.num_parents = 1,
625			.flags = CLK_SET_RATE_PARENT,
626			.ops = &clk_branch2_ops,
627		},
628	},
629};
630
631static struct clk_branch disp_cc_mdss_vsync_clk = {
632	.halt_reg = 0x8020,
633	.halt_check = BRANCH_HALT,
634	.clkr = {
635		.enable_reg = 0x8020,
636		.enable_mask = BIT(0),
637		.hw.init = &(const struct clk_init_data) {
638			.name = "disp_cc_mdss_vsync_clk",
639			.parent_hws = (const struct clk_hw*[]) {
640				&disp_cc_mdss_vsync_clk_src.clkr.hw,
641			},
642			.num_parents = 1,
643			.flags = CLK_SET_RATE_PARENT,
644			.ops = &clk_branch2_ops,
645		},
646	},
647};
648
649static struct gdsc disp_cc_mdss_core_gdsc = {
650	.gdscr = 0x9000,
651	.en_rest_wait_val = 0x2,
652	.en_few_wait_val = 0x2,
653	.clk_dis_wait_val = 0xf,
654	.pd = {
655		.name = "disp_cc_mdss_core_gdsc",
656	},
657	.pwrsts = PWRSTS_OFF_ON,
658	.flags = HW_CTRL | POLL_CFG_GDSCR | RETAIN_FF_ENABLE,
659};
660
661static struct gdsc disp_cc_mdss_core_int2_gdsc = {
662	.gdscr = 0xb000,
663	.en_rest_wait_val = 0x2,
664	.en_few_wait_val = 0x2,
665	.clk_dis_wait_val = 0xf,
666	.pd = {
667		.name = "disp_cc_mdss_core_int2_gdsc",
668	},
669	.pwrsts = PWRSTS_OFF_ON,
670	.flags = HW_CTRL | POLL_CFG_GDSCR | RETAIN_FF_ENABLE,
671};
672
673static struct clk_regmap *disp_cc_sm4450_clocks[] = {
674	[DISP_CC_MDSS_AHB1_CLK] = &disp_cc_mdss_ahb1_clk.clkr,
675	[DISP_CC_MDSS_AHB_CLK] = &disp_cc_mdss_ahb_clk.clkr,
676	[DISP_CC_MDSS_AHB_CLK_SRC] = &disp_cc_mdss_ahb_clk_src.clkr,
677	[DISP_CC_MDSS_BYTE0_CLK] = &disp_cc_mdss_byte0_clk.clkr,
678	[DISP_CC_MDSS_BYTE0_CLK_SRC] = &disp_cc_mdss_byte0_clk_src.clkr,
679	[DISP_CC_MDSS_BYTE0_DIV_CLK_SRC] = &disp_cc_mdss_byte0_div_clk_src.clkr,
680	[DISP_CC_MDSS_BYTE0_INTF_CLK] = &disp_cc_mdss_byte0_intf_clk.clkr,
681	[DISP_CC_MDSS_ESC0_CLK] = &disp_cc_mdss_esc0_clk.clkr,
682	[DISP_CC_MDSS_ESC0_CLK_SRC] = &disp_cc_mdss_esc0_clk_src.clkr,
683	[DISP_CC_MDSS_MDP1_CLK] = &disp_cc_mdss_mdp1_clk.clkr,
684	[DISP_CC_MDSS_MDP_CLK] = &disp_cc_mdss_mdp_clk.clkr,
685	[DISP_CC_MDSS_MDP_CLK_SRC] = &disp_cc_mdss_mdp_clk_src.clkr,
686	[DISP_CC_MDSS_MDP_LUT1_CLK] = &disp_cc_mdss_mdp_lut1_clk.clkr,
687	[DISP_CC_MDSS_MDP_LUT_CLK] = &disp_cc_mdss_mdp_lut_clk.clkr,
688	[DISP_CC_MDSS_NON_GDSC_AHB_CLK] = &disp_cc_mdss_non_gdsc_ahb_clk.clkr,
689	[DISP_CC_MDSS_PCLK0_CLK] = &disp_cc_mdss_pclk0_clk.clkr,
690	[DISP_CC_MDSS_PCLK0_CLK_SRC] = &disp_cc_mdss_pclk0_clk_src.clkr,
691	[DISP_CC_MDSS_ROT1_CLK] = &disp_cc_mdss_rot1_clk.clkr,
692	[DISP_CC_MDSS_ROT_CLK] = &disp_cc_mdss_rot_clk.clkr,
693	[DISP_CC_MDSS_ROT_CLK_SRC] = &disp_cc_mdss_rot_clk_src.clkr,
694	[DISP_CC_MDSS_RSCC_AHB_CLK] = &disp_cc_mdss_rscc_ahb_clk.clkr,
695	[DISP_CC_MDSS_RSCC_VSYNC_CLK] = &disp_cc_mdss_rscc_vsync_clk.clkr,
696	[DISP_CC_MDSS_VSYNC1_CLK] = &disp_cc_mdss_vsync1_clk.clkr,
697	[DISP_CC_MDSS_VSYNC_CLK] = &disp_cc_mdss_vsync_clk.clkr,
698	[DISP_CC_MDSS_VSYNC_CLK_SRC] = &disp_cc_mdss_vsync_clk_src.clkr,
699	[DISP_CC_PLL0] = &disp_cc_pll0.clkr,
700	[DISP_CC_PLL1] = &disp_cc_pll1.clkr,
701	[DISP_CC_SLEEP_CLK_SRC] = &disp_cc_sleep_clk_src.clkr,
702	[DISP_CC_XO_CLK_SRC] = &disp_cc_xo_clk_src.clkr,
703};
704
705static struct gdsc *disp_cc_sm4450_gdscs[] = {
706	[DISP_CC_MDSS_CORE_GDSC] = &disp_cc_mdss_core_gdsc,
707	[DISP_CC_MDSS_CORE_INT2_GDSC] = &disp_cc_mdss_core_int2_gdsc,
708};
709
710static const struct qcom_reset_map disp_cc_sm4450_resets[] = {
711	[DISP_CC_MDSS_CORE_BCR] = { 0x8000 },
712	[DISP_CC_MDSS_CORE_INT2_BCR] = { 0xa000 },
713	[DISP_CC_MDSS_RSCC_BCR] = { 0xc000 },
714};
715
716static const struct regmap_config disp_cc_sm4450_regmap_config = {
717	.reg_bits = 32,
718	.reg_stride = 4,
719	.val_bits = 32,
720	.max_register = 0x11008,
721	.fast_io = true,
722};
723
724static const struct qcom_cc_desc disp_cc_sm4450_desc = {
725	.config = &disp_cc_sm4450_regmap_config,
726	.clks = disp_cc_sm4450_clocks,
727	.num_clks = ARRAY_SIZE(disp_cc_sm4450_clocks),
728	.resets = disp_cc_sm4450_resets,
729	.num_resets = ARRAY_SIZE(disp_cc_sm4450_resets),
730	.gdscs = disp_cc_sm4450_gdscs,
731	.num_gdscs = ARRAY_SIZE(disp_cc_sm4450_gdscs),
732};
733
734static const struct of_device_id disp_cc_sm4450_match_table[] = {
735	{ .compatible = "qcom,sm4450-dispcc" },
736	{ }
737};
738MODULE_DEVICE_TABLE(of, disp_cc_sm4450_match_table);
739
740static int disp_cc_sm4450_probe(struct platform_device *pdev)
741{
742	struct regmap *regmap;
743
744	regmap = qcom_cc_map(pdev, &disp_cc_sm4450_desc);
745	if (IS_ERR(regmap))
746		return PTR_ERR(regmap);
747
748	clk_lucid_evo_pll_configure(&disp_cc_pll0, regmap, &disp_cc_pll0_config);
749	clk_lucid_evo_pll_configure(&disp_cc_pll1, regmap, &disp_cc_pll0_config);
750
751	/* Keep some clocks always enabled */
752	qcom_branch_set_clk_en(regmap, 0xe070); /* DISP_CC_SLEEP_CLK */
753	qcom_branch_set_clk_en(regmap, 0xe054); /* DISP_CC_XO_CLK */
754
755	return qcom_cc_really_probe(&pdev->dev, &disp_cc_sm4450_desc, regmap);
756}
757
758static struct platform_driver disp_cc_sm4450_driver = {
759	.probe = disp_cc_sm4450_probe,
760	.driver = {
761		.name = "dispcc-sm4450",
762		.of_match_table = disp_cc_sm4450_match_table,
763	},
764};
765
766module_platform_driver(disp_cc_sm4450_driver);
767
768MODULE_DESCRIPTION("QTI DISPCC SM4450 Driver");
769MODULE_LICENSE("GPL");
~/ Read-only file preview.