xref: /linux/drivers/clk/qcom/videocc-milos.c (revision 8d2b0853add1d7534dc0794e3c8e0b9e8c4ec640)
1*633a81beSLuca Weiss // SPDX-License-Identifier: GPL-2.0-only
2*633a81beSLuca Weiss /*
3*633a81beSLuca Weiss  * Copyright (c) 2023, Qualcomm Innovation Center, Inc. All rights reserved.
4*633a81beSLuca Weiss  * Copyright (c) 2025, Luca Weiss <luca.weiss@fairphone.com>
5*633a81beSLuca Weiss  */
6*633a81beSLuca Weiss 
7*633a81beSLuca Weiss #include <linux/clk-provider.h>
8*633a81beSLuca Weiss #include <linux/mod_devicetable.h>
9*633a81beSLuca Weiss #include <linux/module.h>
10*633a81beSLuca Weiss #include <linux/platform_device.h>
11*633a81beSLuca Weiss #include <linux/regmap.h>
12*633a81beSLuca Weiss 
13*633a81beSLuca Weiss #include <dt-bindings/clock/qcom,milos-videocc.h>
14*633a81beSLuca Weiss 
15*633a81beSLuca Weiss #include "clk-alpha-pll.h"
16*633a81beSLuca Weiss #include "clk-branch.h"
17*633a81beSLuca Weiss #include "clk-rcg.h"
18*633a81beSLuca Weiss #include "clk-regmap.h"
19*633a81beSLuca Weiss #include "clk-regmap-divider.h"
20*633a81beSLuca Weiss #include "common.h"
21*633a81beSLuca Weiss #include "gdsc.h"
22*633a81beSLuca Weiss #include "reset.h"
23*633a81beSLuca Weiss 
24*633a81beSLuca Weiss /* Need to match the order of clocks in DT binding */
25*633a81beSLuca Weiss enum {
26*633a81beSLuca Weiss 	DT_BI_TCXO,
27*633a81beSLuca Weiss 	DT_BI_TCXO_AO,
28*633a81beSLuca Weiss 	DT_SLEEP_CLK,
29*633a81beSLuca Weiss 	DT_IFACE,
30*633a81beSLuca Weiss };
31*633a81beSLuca Weiss 
32*633a81beSLuca Weiss enum {
33*633a81beSLuca Weiss 	P_BI_TCXO,
34*633a81beSLuca Weiss 	P_SLEEP_CLK,
35*633a81beSLuca Weiss 	P_VIDEO_CC_PLL0_OUT_MAIN,
36*633a81beSLuca Weiss };
37*633a81beSLuca Weiss 
38*633a81beSLuca Weiss static const struct pll_vco lucid_ole_vco[] = {
39*633a81beSLuca Weiss 	{ 249600000, 2300000000, 0 },
40*633a81beSLuca Weiss };
41*633a81beSLuca Weiss 
42*633a81beSLuca Weiss /* 604.8 MHz Configuration */
43*633a81beSLuca Weiss static const struct alpha_pll_config video_cc_pll0_config = {
44*633a81beSLuca Weiss 	.l = 0x1f,
45*633a81beSLuca Weiss 	.alpha = 0x8000,
46*633a81beSLuca Weiss 	.config_ctl_val = 0x20485699,
47*633a81beSLuca Weiss 	.config_ctl_hi_val = 0x00182261,
48*633a81beSLuca Weiss 	.config_ctl_hi1_val = 0x82aa299c,
49*633a81beSLuca Weiss 	.test_ctl_val = 0x00000000,
50*633a81beSLuca Weiss 	.test_ctl_hi_val = 0x00000003,
51*633a81beSLuca Weiss 	.test_ctl_hi1_val = 0x00009000,
52*633a81beSLuca Weiss 	.test_ctl_hi2_val = 0x00000034,
53*633a81beSLuca Weiss 	.user_ctl_val = 0x00000000,
54*633a81beSLuca Weiss 	.user_ctl_hi_val = 0x00000005,
55*633a81beSLuca Weiss };
56*633a81beSLuca Weiss 
57*633a81beSLuca Weiss static struct clk_alpha_pll video_cc_pll0 = {
58*633a81beSLuca Weiss 	.offset = 0x0,
59*633a81beSLuca Weiss 	.config = &video_cc_pll0_config,
60*633a81beSLuca Weiss 	.vco_table = lucid_ole_vco,
61*633a81beSLuca Weiss 	.num_vco = ARRAY_SIZE(lucid_ole_vco),
62*633a81beSLuca Weiss 	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE],
63*633a81beSLuca Weiss 	.clkr = {
64*633a81beSLuca Weiss 		.hw.init = &(const struct clk_init_data) {
65*633a81beSLuca Weiss 			.name = "video_cc_pll0",
66*633a81beSLuca Weiss 			.parent_data = &(const struct clk_parent_data) {
67*633a81beSLuca Weiss 				.index = DT_BI_TCXO,
68*633a81beSLuca Weiss 			},
69*633a81beSLuca Weiss 			.num_parents = 1,
70*633a81beSLuca Weiss 			.ops = &clk_alpha_pll_lucid_evo_ops,
71*633a81beSLuca Weiss 		},
72*633a81beSLuca Weiss 	},
73*633a81beSLuca Weiss };
74*633a81beSLuca Weiss 
75*633a81beSLuca Weiss static const struct parent_map video_cc_parent_map_0[] = {
76*633a81beSLuca Weiss 	{ P_BI_TCXO, 0 },
77*633a81beSLuca Weiss };
78*633a81beSLuca Weiss 
79*633a81beSLuca Weiss static const struct clk_parent_data video_cc_parent_data_0[] = {
80*633a81beSLuca Weiss 	{ .index = DT_BI_TCXO },
81*633a81beSLuca Weiss };
82*633a81beSLuca Weiss 
83*633a81beSLuca Weiss static const struct clk_parent_data video_cc_parent_data_0_ao[] = {
84*633a81beSLuca Weiss 	{ .index = DT_BI_TCXO_AO },
85*633a81beSLuca Weiss };
86*633a81beSLuca Weiss 
87*633a81beSLuca Weiss static const struct parent_map video_cc_parent_map_1[] = {
88*633a81beSLuca Weiss 	{ P_BI_TCXO, 0 },
89*633a81beSLuca Weiss 	{ P_VIDEO_CC_PLL0_OUT_MAIN, 1 },
90*633a81beSLuca Weiss };
91*633a81beSLuca Weiss 
92*633a81beSLuca Weiss static const struct clk_parent_data video_cc_parent_data_1[] = {
93*633a81beSLuca Weiss 	{ .index = DT_BI_TCXO },
94*633a81beSLuca Weiss 	{ .hw = &video_cc_pll0.clkr.hw },
95*633a81beSLuca Weiss };
96*633a81beSLuca Weiss 
97*633a81beSLuca Weiss static const struct parent_map video_cc_parent_map_2[] = {
98*633a81beSLuca Weiss 	{ P_SLEEP_CLK, 0 },
99*633a81beSLuca Weiss };
100*633a81beSLuca Weiss 
101*633a81beSLuca Weiss static const struct clk_parent_data video_cc_parent_data_2_ao[] = {
102*633a81beSLuca Weiss 	{ .index = DT_SLEEP_CLK },
103*633a81beSLuca Weiss };
104*633a81beSLuca Weiss 
105*633a81beSLuca Weiss static const struct freq_tbl ftbl_video_cc_ahb_clk_src[] = {
106*633a81beSLuca Weiss 	F(19200000, P_BI_TCXO, 1, 0, 0),
107*633a81beSLuca Weiss 	{ }
108*633a81beSLuca Weiss };
109*633a81beSLuca Weiss 
110*633a81beSLuca Weiss static struct clk_rcg2 video_cc_ahb_clk_src = {
111*633a81beSLuca Weiss 	.cmd_rcgr = 0x8030,
112*633a81beSLuca Weiss 	.mnd_width = 0,
113*633a81beSLuca Weiss 	.hid_width = 5,
114*633a81beSLuca Weiss 	.parent_map = video_cc_parent_map_0,
115*633a81beSLuca Weiss 	.freq_tbl = ftbl_video_cc_ahb_clk_src,
116*633a81beSLuca Weiss 	.clkr.hw.init = &(const struct clk_init_data) {
117*633a81beSLuca Weiss 		.name = "video_cc_ahb_clk_src",
118*633a81beSLuca Weiss 		.parent_data = video_cc_parent_data_0_ao,
119*633a81beSLuca Weiss 		.num_parents = ARRAY_SIZE(video_cc_parent_data_0_ao),
120*633a81beSLuca Weiss 		.flags = CLK_SET_RATE_PARENT,
121*633a81beSLuca Weiss 		.ops = &clk_rcg2_shared_ops,
122*633a81beSLuca Weiss 	},
123*633a81beSLuca Weiss };
124*633a81beSLuca Weiss 
125*633a81beSLuca Weiss static const struct freq_tbl ftbl_video_cc_mvs0_clk_src[] = {
126*633a81beSLuca Weiss 	F(604800000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0),
127*633a81beSLuca Weiss 	F(720000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0),
128*633a81beSLuca Weiss 	F(1014000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0),
129*633a81beSLuca Weiss 	F(1098000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0),
130*633a81beSLuca Weiss 	F(1332000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0),
131*633a81beSLuca Weiss 	F(1656000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0),
132*633a81beSLuca Weiss 	{ }
133*633a81beSLuca Weiss };
134*633a81beSLuca Weiss 
135*633a81beSLuca Weiss static struct clk_rcg2 video_cc_mvs0_clk_src = {
136*633a81beSLuca Weiss 	.cmd_rcgr = 0x8000,
137*633a81beSLuca Weiss 	.mnd_width = 0,
138*633a81beSLuca Weiss 	.hid_width = 5,
139*633a81beSLuca Weiss 	.parent_map = video_cc_parent_map_1,
140*633a81beSLuca Weiss 	.freq_tbl = ftbl_video_cc_mvs0_clk_src,
141*633a81beSLuca Weiss 	.clkr.hw.init = &(const struct clk_init_data) {
142*633a81beSLuca Weiss 		.name = "video_cc_mvs0_clk_src",
143*633a81beSLuca Weiss 		.parent_data = video_cc_parent_data_1,
144*633a81beSLuca Weiss 		.num_parents = ARRAY_SIZE(video_cc_parent_data_1),
145*633a81beSLuca Weiss 		.flags = CLK_SET_RATE_PARENT,
146*633a81beSLuca Weiss 		.ops = &clk_rcg2_shared_ops,
147*633a81beSLuca Weiss 	},
148*633a81beSLuca Weiss };
149*633a81beSLuca Weiss 
150*633a81beSLuca Weiss static const struct freq_tbl ftbl_video_cc_sleep_clk_src[] = {
151*633a81beSLuca Weiss 	F(32000, P_SLEEP_CLK, 1, 0, 0),
152*633a81beSLuca Weiss 	{ }
153*633a81beSLuca Weiss };
154*633a81beSLuca Weiss 
155*633a81beSLuca Weiss static struct clk_rcg2 video_cc_sleep_clk_src = {
156*633a81beSLuca Weiss 	.cmd_rcgr = 0x8128,
157*633a81beSLuca Weiss 	.mnd_width = 0,
158*633a81beSLuca Weiss 	.hid_width = 5,
159*633a81beSLuca Weiss 	.parent_map = video_cc_parent_map_2,
160*633a81beSLuca Weiss 	.freq_tbl = ftbl_video_cc_sleep_clk_src,
161*633a81beSLuca Weiss 	.clkr.hw.init = &(const struct clk_init_data) {
162*633a81beSLuca Weiss 		.name = "video_cc_sleep_clk_src",
163*633a81beSLuca Weiss 		.parent_data = video_cc_parent_data_2_ao,
164*633a81beSLuca Weiss 		.num_parents = ARRAY_SIZE(video_cc_parent_data_2_ao),
165*633a81beSLuca Weiss 		.flags = CLK_SET_RATE_PARENT,
166*633a81beSLuca Weiss 		.ops = &clk_rcg2_ops,
167*633a81beSLuca Weiss 	},
168*633a81beSLuca Weiss };
169*633a81beSLuca Weiss 
170*633a81beSLuca Weiss static struct clk_rcg2 video_cc_xo_clk_src = {
171*633a81beSLuca Weiss 	.cmd_rcgr = 0x810c,
172*633a81beSLuca Weiss 	.mnd_width = 0,
173*633a81beSLuca Weiss 	.hid_width = 5,
174*633a81beSLuca Weiss 	.parent_map = video_cc_parent_map_0,
175*633a81beSLuca Weiss 	.freq_tbl = ftbl_video_cc_ahb_clk_src,
176*633a81beSLuca Weiss 	.clkr.hw.init = &(const struct clk_init_data) {
177*633a81beSLuca Weiss 		.name = "video_cc_xo_clk_src",
178*633a81beSLuca Weiss 		.parent_data = video_cc_parent_data_0,
179*633a81beSLuca Weiss 		.num_parents = ARRAY_SIZE(video_cc_parent_data_0),
180*633a81beSLuca Weiss 		.flags = CLK_SET_RATE_PARENT,
181*633a81beSLuca Weiss 		.ops = &clk_rcg2_ops,
182*633a81beSLuca Weiss 	},
183*633a81beSLuca Weiss };
184*633a81beSLuca Weiss 
185*633a81beSLuca Weiss static struct clk_regmap_div video_cc_mvs0_div_clk_src = {
186*633a81beSLuca Weiss 	.reg = 0x80c4,
187*633a81beSLuca Weiss 	.shift = 0,
188*633a81beSLuca Weiss 	.width = 4,
189*633a81beSLuca Weiss 	.clkr.hw.init = &(const struct clk_init_data) {
190*633a81beSLuca Weiss 		.name = "video_cc_mvs0_div_clk_src",
191*633a81beSLuca Weiss 		.parent_hws = (const struct clk_hw*[]) {
192*633a81beSLuca Weiss 			&video_cc_mvs0_clk_src.clkr.hw,
193*633a81beSLuca Weiss 		},
194*633a81beSLuca Weiss 		.num_parents = 1,
195*633a81beSLuca Weiss 		.flags = CLK_SET_RATE_PARENT,
196*633a81beSLuca Weiss 		.ops = &clk_regmap_div_ro_ops,
197*633a81beSLuca Weiss 	},
198*633a81beSLuca Weiss };
199*633a81beSLuca Weiss 
200*633a81beSLuca Weiss static struct clk_regmap_div video_cc_mvs0c_div2_div_clk_src = {
201*633a81beSLuca Weiss 	.reg = 0x8070,
202*633a81beSLuca Weiss 	.shift = 0,
203*633a81beSLuca Weiss 	.width = 4,
204*633a81beSLuca Weiss 	.clkr.hw.init = &(const struct clk_init_data) {
205*633a81beSLuca Weiss 		.name = "video_cc_mvs0c_div2_div_clk_src",
206*633a81beSLuca Weiss 		.parent_hws = (const struct clk_hw*[]) {
207*633a81beSLuca Weiss 			&video_cc_mvs0_clk_src.clkr.hw,
208*633a81beSLuca Weiss 		},
209*633a81beSLuca Weiss 		.num_parents = 1,
210*633a81beSLuca Weiss 		.flags = CLK_SET_RATE_PARENT,
211*633a81beSLuca Weiss 		.ops = &clk_regmap_div_ro_ops,
212*633a81beSLuca Weiss 	},
213*633a81beSLuca Weiss };
214*633a81beSLuca Weiss 
215*633a81beSLuca Weiss static struct clk_branch video_cc_mvs0_clk = {
216*633a81beSLuca Weiss 	.halt_reg = 0x80b8,
217*633a81beSLuca Weiss 	.halt_check = BRANCH_HALT_VOTED,
218*633a81beSLuca Weiss 	.hwcg_reg = 0x80b8,
219*633a81beSLuca Weiss 	.hwcg_bit = 1,
220*633a81beSLuca Weiss 	.clkr = {
221*633a81beSLuca Weiss 		.enable_reg = 0x80b8,
222*633a81beSLuca Weiss 		.enable_mask = BIT(0),
223*633a81beSLuca Weiss 		.hw.init = &(const struct clk_init_data) {
224*633a81beSLuca Weiss 			.name = "video_cc_mvs0_clk",
225*633a81beSLuca Weiss 			.parent_hws = (const struct clk_hw*[]) {
226*633a81beSLuca Weiss 				&video_cc_mvs0_div_clk_src.clkr.hw,
227*633a81beSLuca Weiss 			},
228*633a81beSLuca Weiss 			.num_parents = 1,
229*633a81beSLuca Weiss 			.flags = CLK_SET_RATE_PARENT,
230*633a81beSLuca Weiss 			.ops = &clk_branch2_ops,
231*633a81beSLuca Weiss 		},
232*633a81beSLuca Weiss 	},
233*633a81beSLuca Weiss };
234*633a81beSLuca Weiss 
235*633a81beSLuca Weiss static struct clk_branch video_cc_mvs0_shift_clk = {
236*633a81beSLuca Weiss 	.halt_reg = 0x8144,
237*633a81beSLuca Weiss 	.halt_check = BRANCH_HALT_VOTED,
238*633a81beSLuca Weiss 	.hwcg_reg = 0x8144,
239*633a81beSLuca Weiss 	.hwcg_bit = 1,
240*633a81beSLuca Weiss 	.clkr = {
241*633a81beSLuca Weiss 		.enable_reg = 0x8144,
242*633a81beSLuca Weiss 		.enable_mask = BIT(0),
243*633a81beSLuca Weiss 		.hw.init = &(const struct clk_init_data) {
244*633a81beSLuca Weiss 			.name = "video_cc_mvs0_shift_clk",
245*633a81beSLuca Weiss 			.parent_hws = (const struct clk_hw*[]) {
246*633a81beSLuca Weiss 				&video_cc_xo_clk_src.clkr.hw,
247*633a81beSLuca Weiss 			},
248*633a81beSLuca Weiss 			.num_parents = 1,
249*633a81beSLuca Weiss 			.flags = CLK_SET_RATE_PARENT,
250*633a81beSLuca Weiss 			.ops = &clk_branch2_ops,
251*633a81beSLuca Weiss 		},
252*633a81beSLuca Weiss 	},
253*633a81beSLuca Weiss };
254*633a81beSLuca Weiss 
255*633a81beSLuca Weiss static struct clk_branch video_cc_mvs0c_clk = {
256*633a81beSLuca Weiss 	.halt_reg = 0x8064,
257*633a81beSLuca Weiss 	.halt_check = BRANCH_HALT,
258*633a81beSLuca Weiss 	.clkr = {
259*633a81beSLuca Weiss 		.enable_reg = 0x8064,
260*633a81beSLuca Weiss 		.enable_mask = BIT(0),
261*633a81beSLuca Weiss 		.hw.init = &(const struct clk_init_data) {
262*633a81beSLuca Weiss 			.name = "video_cc_mvs0c_clk",
263*633a81beSLuca Weiss 			.parent_hws = (const struct clk_hw*[]) {
264*633a81beSLuca Weiss 				&video_cc_mvs0c_div2_div_clk_src.clkr.hw,
265*633a81beSLuca Weiss 			},
266*633a81beSLuca Weiss 			.num_parents = 1,
267*633a81beSLuca Weiss 			.flags = CLK_SET_RATE_PARENT,
268*633a81beSLuca Weiss 			.ops = &clk_branch2_ops,
269*633a81beSLuca Weiss 		},
270*633a81beSLuca Weiss 	},
271*633a81beSLuca Weiss };
272*633a81beSLuca Weiss 
273*633a81beSLuca Weiss static struct clk_branch video_cc_mvs0c_shift_clk = {
274*633a81beSLuca Weiss 	.halt_reg = 0x8148,
275*633a81beSLuca Weiss 	.halt_check = BRANCH_HALT_VOTED,
276*633a81beSLuca Weiss 	.hwcg_reg = 0x8148,
277*633a81beSLuca Weiss 	.hwcg_bit = 1,
278*633a81beSLuca Weiss 	.clkr = {
279*633a81beSLuca Weiss 		.enable_reg = 0x8148,
280*633a81beSLuca Weiss 		.enable_mask = BIT(0),
281*633a81beSLuca Weiss 		.hw.init = &(const struct clk_init_data) {
282*633a81beSLuca Weiss 			.name = "video_cc_mvs0c_shift_clk",
283*633a81beSLuca Weiss 			.parent_hws = (const struct clk_hw*[]) {
284*633a81beSLuca Weiss 				&video_cc_xo_clk_src.clkr.hw,
285*633a81beSLuca Weiss 			},
286*633a81beSLuca Weiss 			.num_parents = 1,
287*633a81beSLuca Weiss 			.flags = CLK_SET_RATE_PARENT,
288*633a81beSLuca Weiss 			.ops = &clk_branch2_ops,
289*633a81beSLuca Weiss 		},
290*633a81beSLuca Weiss 	},
291*633a81beSLuca Weiss };
292*633a81beSLuca Weiss 
293*633a81beSLuca Weiss static struct gdsc video_cc_mvs0c_gdsc = {
294*633a81beSLuca Weiss 	.gdscr = 0x804c,
295*633a81beSLuca Weiss 	.en_rest_wait_val = 0x2,
296*633a81beSLuca Weiss 	.en_few_wait_val = 0x2,
297*633a81beSLuca Weiss 	.clk_dis_wait_val = 0x6,
298*633a81beSLuca Weiss 	.pd = {
299*633a81beSLuca Weiss 		.name = "video_cc_mvs0c_gdsc",
300*633a81beSLuca Weiss 	},
301*633a81beSLuca Weiss 	.pwrsts = PWRSTS_OFF_ON,
302*633a81beSLuca Weiss 	.flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE,
303*633a81beSLuca Weiss };
304*633a81beSLuca Weiss 
305*633a81beSLuca Weiss static struct gdsc video_cc_mvs0_gdsc = {
306*633a81beSLuca Weiss 	.gdscr = 0x80a4,
307*633a81beSLuca Weiss 	.en_rest_wait_val = 0x2,
308*633a81beSLuca Weiss 	.en_few_wait_val = 0x2,
309*633a81beSLuca Weiss 	.clk_dis_wait_val = 0x6,
310*633a81beSLuca Weiss 	.pd = {
311*633a81beSLuca Weiss 		.name = "video_cc_mvs0_gdsc",
312*633a81beSLuca Weiss 	},
313*633a81beSLuca Weiss 	.pwrsts = PWRSTS_OFF_ON,
314*633a81beSLuca Weiss 	.parent = &video_cc_mvs0c_gdsc.pd,
315*633a81beSLuca Weiss 	.flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE | HW_CTRL_TRIGGER,
316*633a81beSLuca Weiss };
317*633a81beSLuca Weiss 
318*633a81beSLuca Weiss static struct clk_regmap *video_cc_milos_clocks[] = {
319*633a81beSLuca Weiss 	[VIDEO_CC_AHB_CLK_SRC] = &video_cc_ahb_clk_src.clkr,
320*633a81beSLuca Weiss 	[VIDEO_CC_MVS0_CLK] = &video_cc_mvs0_clk.clkr,
321*633a81beSLuca Weiss 	[VIDEO_CC_MVS0_CLK_SRC] = &video_cc_mvs0_clk_src.clkr,
322*633a81beSLuca Weiss 	[VIDEO_CC_MVS0_DIV_CLK_SRC] = &video_cc_mvs0_div_clk_src.clkr,
323*633a81beSLuca Weiss 	[VIDEO_CC_MVS0_SHIFT_CLK] = &video_cc_mvs0_shift_clk.clkr,
324*633a81beSLuca Weiss 	[VIDEO_CC_MVS0C_CLK] = &video_cc_mvs0c_clk.clkr,
325*633a81beSLuca Weiss 	[VIDEO_CC_MVS0C_DIV2_DIV_CLK_SRC] = &video_cc_mvs0c_div2_div_clk_src.clkr,
326*633a81beSLuca Weiss 	[VIDEO_CC_MVS0C_SHIFT_CLK] = &video_cc_mvs0c_shift_clk.clkr,
327*633a81beSLuca Weiss 	[VIDEO_CC_PLL0] = &video_cc_pll0.clkr,
328*633a81beSLuca Weiss 	[VIDEO_CC_SLEEP_CLK_SRC] = &video_cc_sleep_clk_src.clkr,
329*633a81beSLuca Weiss 	[VIDEO_CC_XO_CLK_SRC] = &video_cc_xo_clk_src.clkr,
330*633a81beSLuca Weiss };
331*633a81beSLuca Weiss 
332*633a81beSLuca Weiss static struct gdsc *video_cc_milos_gdscs[] = {
333*633a81beSLuca Weiss 	[VIDEO_CC_MVS0C_GDSC] = &video_cc_mvs0c_gdsc,
334*633a81beSLuca Weiss 	[VIDEO_CC_MVS0_GDSC] = &video_cc_mvs0_gdsc,
335*633a81beSLuca Weiss };
336*633a81beSLuca Weiss 
337*633a81beSLuca Weiss static const struct qcom_reset_map video_cc_milos_resets[] = {
338*633a81beSLuca Weiss 	[VIDEO_CC_INTERFACE_BCR] = { 0x80f0 },
339*633a81beSLuca Weiss 	[VIDEO_CC_MVS0_BCR] = { 0x80a0 },
340*633a81beSLuca Weiss 	[VIDEO_CC_MVS0C_CLK_ARES] = { 0x8064, 2 },
341*633a81beSLuca Weiss 	[VIDEO_CC_MVS0C_BCR] = { 0x8048 },
342*633a81beSLuca Weiss };
343*633a81beSLuca Weiss 
344*633a81beSLuca Weiss static struct clk_alpha_pll *video_cc_milos_plls[] = {
345*633a81beSLuca Weiss 	&video_cc_pll0,
346*633a81beSLuca Weiss };
347*633a81beSLuca Weiss 
348*633a81beSLuca Weiss static u32 video_cc_milos_critical_cbcrs[] = {
349*633a81beSLuca Weiss 	0x80f4, /* VIDEO_CC_AHB_CLK */
350*633a81beSLuca Weiss 	0x8140, /* VIDEO_CC_SLEEP_CLK */
351*633a81beSLuca Weiss 	0x8124, /* VIDEO_CC_XO_CLK */
352*633a81beSLuca Weiss };
353*633a81beSLuca Weiss 
354*633a81beSLuca Weiss static const struct regmap_config video_cc_milos_regmap_config = {
355*633a81beSLuca Weiss 	.reg_bits = 32,
356*633a81beSLuca Weiss 	.reg_stride = 4,
357*633a81beSLuca Weiss 	.val_bits = 32,
358*633a81beSLuca Weiss 	.max_register = 0x9f50,
359*633a81beSLuca Weiss 	.fast_io = true,
360*633a81beSLuca Weiss };
361*633a81beSLuca Weiss 
362*633a81beSLuca Weiss static struct qcom_cc_driver_data video_cc_milos_driver_data = {
363*633a81beSLuca Weiss 	.alpha_plls = video_cc_milos_plls,
364*633a81beSLuca Weiss 	.num_alpha_plls = ARRAY_SIZE(video_cc_milos_plls),
365*633a81beSLuca Weiss 	.clk_cbcrs = video_cc_milos_critical_cbcrs,
366*633a81beSLuca Weiss 	.num_clk_cbcrs = ARRAY_SIZE(video_cc_milos_critical_cbcrs),
367*633a81beSLuca Weiss };
368*633a81beSLuca Weiss 
369*633a81beSLuca Weiss static struct qcom_cc_desc video_cc_milos_desc = {
370*633a81beSLuca Weiss 	.config = &video_cc_milos_regmap_config,
371*633a81beSLuca Weiss 	.clks = video_cc_milos_clocks,
372*633a81beSLuca Weiss 	.num_clks = ARRAY_SIZE(video_cc_milos_clocks),
373*633a81beSLuca Weiss 	.resets = video_cc_milos_resets,
374*633a81beSLuca Weiss 	.num_resets = ARRAY_SIZE(video_cc_milos_resets),
375*633a81beSLuca Weiss 	.gdscs = video_cc_milos_gdscs,
376*633a81beSLuca Weiss 	.num_gdscs = ARRAY_SIZE(video_cc_milos_gdscs),
377*633a81beSLuca Weiss 	.use_rpm = true,
378*633a81beSLuca Weiss 	.driver_data = &video_cc_milos_driver_data,
379*633a81beSLuca Weiss };
380*633a81beSLuca Weiss 
381*633a81beSLuca Weiss static const struct of_device_id video_cc_milos_match_table[] = {
382*633a81beSLuca Weiss 	{ .compatible = "qcom,milos-videocc" },
383*633a81beSLuca Weiss 	{ }
384*633a81beSLuca Weiss };
385*633a81beSLuca Weiss MODULE_DEVICE_TABLE(of, video_cc_milos_match_table);
386*633a81beSLuca Weiss 
387*633a81beSLuca Weiss static int video_cc_milos_probe(struct platform_device *pdev)
388*633a81beSLuca Weiss {
389*633a81beSLuca Weiss 	return qcom_cc_probe(pdev, &video_cc_milos_desc);
390*633a81beSLuca Weiss }
391*633a81beSLuca Weiss 
392*633a81beSLuca Weiss static struct platform_driver video_cc_milos_driver = {
393*633a81beSLuca Weiss 	.probe = video_cc_milos_probe,
394*633a81beSLuca Weiss 	.driver = {
395*633a81beSLuca Weiss 		.name = "video_cc-milos",
396*633a81beSLuca Weiss 		.of_match_table = video_cc_milos_match_table,
397*633a81beSLuca Weiss 	},
398*633a81beSLuca Weiss };
399*633a81beSLuca Weiss 
400*633a81beSLuca Weiss module_platform_driver(video_cc_milos_driver);
401*633a81beSLuca Weiss 
402*633a81beSLuca Weiss MODULE_DESCRIPTION("QTI VIDEO_CC Milos Driver");
403*633a81beSLuca Weiss MODULE_LICENSE("GPL");
404