xref: /linux/drivers/clk/qcom/cambistmclkcc-sm8750.c (revision c17ee635fd3a482b2ad2bf5e269755c2eae5f25e)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
4  */
5 
6 #include <linux/clk-provider.h>
7 #include <linux/mod_devicetable.h>
8 #include <linux/module.h>
9 #include <linux/platform_device.h>
10 #include <linux/regmap.h>
11 
12 #include <dt-bindings/clock/qcom,sm8750-cambistmclkcc.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 "common.h"
19 #include "reset.h"
20 
21 enum {
22 	DT_IFACE,
23 	DT_BI_TCXO,
24 	DT_BI_TCXO_AO,
25 	DT_SLEEP_CLK,
26 };
27 
28 enum {
29 	P_BI_TCXO,
30 	P_CAM_BIST_MCLK_CC_PLL0_OUT_EVEN,
31 	P_CAM_BIST_MCLK_CC_PLL0_OUT_MAIN,
32 	P_SLEEP_CLK,
33 };
34 
35 static const struct pll_vco rivian_elu_vco[] = {
36 	{ 833000000, 1125000000, 0 },
37 	{ 777000000, 1062000000, 1 },
38 };
39 
40 /* 960.0 MHz Configuration */
41 static const struct alpha_pll_config cam_bist_mclk_cc_pll0_config = {
42 	.l = 0x32,
43 	.alpha = 0x0,
44 	.config_ctl_val = 0x12000000,
45 	.config_ctl_hi_val = 0x00890263,
46 	.config_ctl_hi1_val = 0x1af04237,
47 	.config_ctl_hi2_val = 0x00000000,
48 };
49 
50 static struct clk_alpha_pll cam_bist_mclk_cc_pll0 = {
51 	.offset = 0x0,
52 	.config = &cam_bist_mclk_cc_pll0_config,
53 	.vco_table = rivian_elu_vco,
54 	.num_vco = ARRAY_SIZE(rivian_elu_vco),
55 	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_RIVIAN_ELU],
56 	.clkr = {
57 		.hw.init = &(const struct clk_init_data) {
58 			.name = "cam_bist_mclk_cc_pll0",
59 			.parent_data = &(const struct clk_parent_data) {
60 				.index = DT_BI_TCXO,
61 			},
62 			.num_parents = 1,
63 			.ops = &clk_alpha_pll_rivian_elu_ops,
64 		},
65 	},
66 };
67 
68 static const struct parent_map cam_bist_mclk_cc_parent_map_0[] = {
69 	{ P_BI_TCXO, 0 },
70 	{ P_CAM_BIST_MCLK_CC_PLL0_OUT_EVEN, 3 },
71 	{ P_CAM_BIST_MCLK_CC_PLL0_OUT_MAIN, 5 },
72 };
73 
74 static const struct clk_parent_data cam_bist_mclk_cc_parent_data_0[] = {
75 	{ .index = DT_BI_TCXO },
76 	{ .hw = &cam_bist_mclk_cc_pll0.clkr.hw },
77 	{ .hw = &cam_bist_mclk_cc_pll0.clkr.hw },
78 };
79 
80 static const struct parent_map cam_bist_mclk_cc_parent_map_1[] = {
81 	{ P_SLEEP_CLK, 0 },
82 };
83 
84 static const struct clk_parent_data cam_bist_mclk_cc_parent_data_1[] = {
85 	{ .index = DT_SLEEP_CLK },
86 };
87 
88 static const struct freq_tbl ftbl_cam_bist_mclk_cc_mclk0_clk_src[] = {
89 	F(12000000, P_CAM_BIST_MCLK_CC_PLL0_OUT_EVEN, 10, 1, 8),
90 	F(19200000, P_BI_TCXO, 1, 0, 0),
91 	F(24000000, P_CAM_BIST_MCLK_CC_PLL0_OUT_EVEN, 10, 1, 4),
92 	F(68571429, P_CAM_BIST_MCLK_CC_PLL0_OUT_MAIN, 14, 0, 0),
93 	{ }
94 };
95 
96 static struct clk_rcg2 cam_bist_mclk_cc_mclk0_clk_src = {
97 	.cmd_rcgr = 0x4000,
98 	.mnd_width = 8,
99 	.hid_width = 5,
100 	.parent_map = cam_bist_mclk_cc_parent_map_0,
101 	.freq_tbl = ftbl_cam_bist_mclk_cc_mclk0_clk_src,
102 	.clkr.hw.init = &(const struct clk_init_data) {
103 		.name = "cam_bist_mclk_cc_mclk0_clk_src",
104 		.parent_data = cam_bist_mclk_cc_parent_data_0,
105 		.num_parents = ARRAY_SIZE(cam_bist_mclk_cc_parent_data_0),
106 		.flags = CLK_SET_RATE_PARENT,
107 		.ops = &clk_rcg2_shared_ops,
108 	},
109 };
110 
111 static struct clk_rcg2 cam_bist_mclk_cc_mclk1_clk_src = {
112 	.cmd_rcgr = 0x401c,
113 	.mnd_width = 8,
114 	.hid_width = 5,
115 	.parent_map = cam_bist_mclk_cc_parent_map_0,
116 	.freq_tbl = ftbl_cam_bist_mclk_cc_mclk0_clk_src,
117 	.clkr.hw.init = &(const struct clk_init_data) {
118 		.name = "cam_bist_mclk_cc_mclk1_clk_src",
119 		.parent_data = cam_bist_mclk_cc_parent_data_0,
120 		.num_parents = ARRAY_SIZE(cam_bist_mclk_cc_parent_data_0),
121 		.flags = CLK_SET_RATE_PARENT,
122 		.ops = &clk_rcg2_shared_ops,
123 	},
124 };
125 
126 static struct clk_rcg2 cam_bist_mclk_cc_mclk2_clk_src = {
127 	.cmd_rcgr = 0x4038,
128 	.mnd_width = 8,
129 	.hid_width = 5,
130 	.parent_map = cam_bist_mclk_cc_parent_map_0,
131 	.freq_tbl = ftbl_cam_bist_mclk_cc_mclk0_clk_src,
132 	.clkr.hw.init = &(const struct clk_init_data) {
133 		.name = "cam_bist_mclk_cc_mclk2_clk_src",
134 		.parent_data = cam_bist_mclk_cc_parent_data_0,
135 		.num_parents = ARRAY_SIZE(cam_bist_mclk_cc_parent_data_0),
136 		.flags = CLK_SET_RATE_PARENT,
137 		.ops = &clk_rcg2_shared_ops,
138 	},
139 };
140 
141 static struct clk_rcg2 cam_bist_mclk_cc_mclk3_clk_src = {
142 	.cmd_rcgr = 0x4054,
143 	.mnd_width = 8,
144 	.hid_width = 5,
145 	.parent_map = cam_bist_mclk_cc_parent_map_0,
146 	.freq_tbl = ftbl_cam_bist_mclk_cc_mclk0_clk_src,
147 	.clkr.hw.init = &(const struct clk_init_data) {
148 		.name = "cam_bist_mclk_cc_mclk3_clk_src",
149 		.parent_data = cam_bist_mclk_cc_parent_data_0,
150 		.num_parents = ARRAY_SIZE(cam_bist_mclk_cc_parent_data_0),
151 		.flags = CLK_SET_RATE_PARENT,
152 		.ops = &clk_rcg2_shared_ops,
153 	},
154 };
155 
156 static struct clk_rcg2 cam_bist_mclk_cc_mclk4_clk_src = {
157 	.cmd_rcgr = 0x4070,
158 	.mnd_width = 8,
159 	.hid_width = 5,
160 	.parent_map = cam_bist_mclk_cc_parent_map_0,
161 	.freq_tbl = ftbl_cam_bist_mclk_cc_mclk0_clk_src,
162 	.clkr.hw.init = &(const struct clk_init_data) {
163 		.name = "cam_bist_mclk_cc_mclk4_clk_src",
164 		.parent_data = cam_bist_mclk_cc_parent_data_0,
165 		.num_parents = ARRAY_SIZE(cam_bist_mclk_cc_parent_data_0),
166 		.flags = CLK_SET_RATE_PARENT,
167 		.ops = &clk_rcg2_shared_ops,
168 	},
169 };
170 
171 static struct clk_rcg2 cam_bist_mclk_cc_mclk5_clk_src = {
172 	.cmd_rcgr = 0x408c,
173 	.mnd_width = 8,
174 	.hid_width = 5,
175 	.parent_map = cam_bist_mclk_cc_parent_map_0,
176 	.freq_tbl = ftbl_cam_bist_mclk_cc_mclk0_clk_src,
177 	.clkr.hw.init = &(const struct clk_init_data) {
178 		.name = "cam_bist_mclk_cc_mclk5_clk_src",
179 		.parent_data = cam_bist_mclk_cc_parent_data_0,
180 		.num_parents = ARRAY_SIZE(cam_bist_mclk_cc_parent_data_0),
181 		.flags = CLK_SET_RATE_PARENT,
182 		.ops = &clk_rcg2_shared_ops,
183 	},
184 };
185 
186 static struct clk_rcg2 cam_bist_mclk_cc_mclk6_clk_src = {
187 	.cmd_rcgr = 0x40a8,
188 	.mnd_width = 8,
189 	.hid_width = 5,
190 	.parent_map = cam_bist_mclk_cc_parent_map_0,
191 	.freq_tbl = ftbl_cam_bist_mclk_cc_mclk0_clk_src,
192 	.clkr.hw.init = &(const struct clk_init_data) {
193 		.name = "cam_bist_mclk_cc_mclk6_clk_src",
194 		.parent_data = cam_bist_mclk_cc_parent_data_0,
195 		.num_parents = ARRAY_SIZE(cam_bist_mclk_cc_parent_data_0),
196 		.flags = CLK_SET_RATE_PARENT,
197 		.ops = &clk_rcg2_shared_ops,
198 	},
199 };
200 
201 static struct clk_rcg2 cam_bist_mclk_cc_mclk7_clk_src = {
202 	.cmd_rcgr = 0x40c4,
203 	.mnd_width = 8,
204 	.hid_width = 5,
205 	.parent_map = cam_bist_mclk_cc_parent_map_0,
206 	.freq_tbl = ftbl_cam_bist_mclk_cc_mclk0_clk_src,
207 	.clkr.hw.init = &(const struct clk_init_data) {
208 		.name = "cam_bist_mclk_cc_mclk7_clk_src",
209 		.parent_data = cam_bist_mclk_cc_parent_data_0,
210 		.num_parents = ARRAY_SIZE(cam_bist_mclk_cc_parent_data_0),
211 		.flags = CLK_SET_RATE_PARENT,
212 		.ops = &clk_rcg2_shared_ops,
213 	},
214 };
215 
216 static const struct freq_tbl ftbl_cam_bist_mclk_cc_sleep_clk_src[] = {
217 	F(32000, P_SLEEP_CLK, 1, 0, 0),
218 	{ }
219 };
220 
221 static struct clk_rcg2 cam_bist_mclk_cc_sleep_clk_src = {
222 	.cmd_rcgr = 0x40e0,
223 	.mnd_width = 0,
224 	.hid_width = 5,
225 	.parent_map = cam_bist_mclk_cc_parent_map_1,
226 	.freq_tbl = ftbl_cam_bist_mclk_cc_sleep_clk_src,
227 	.clkr.hw.init = &(const struct clk_init_data) {
228 		.name = "cam_bist_mclk_cc_sleep_clk_src",
229 		.parent_data = cam_bist_mclk_cc_parent_data_1,
230 		.num_parents = ARRAY_SIZE(cam_bist_mclk_cc_parent_data_1),
231 		.flags = CLK_SET_RATE_PARENT,
232 		.ops = &clk_rcg2_shared_ops,
233 	},
234 };
235 
236 static struct clk_branch cam_bist_mclk_cc_mclk0_clk = {
237 	.halt_reg = 0x4018,
238 	.halt_check = BRANCH_HALT,
239 	.clkr = {
240 		.enable_reg = 0x4018,
241 		.enable_mask = BIT(0),
242 		.hw.init = &(const struct clk_init_data) {
243 			.name = "cam_bist_mclk_cc_mclk0_clk",
244 			.parent_hws = (const struct clk_hw*[]) {
245 				&cam_bist_mclk_cc_mclk0_clk_src.clkr.hw,
246 			},
247 			.num_parents = 1,
248 			.flags = CLK_SET_RATE_PARENT,
249 			.ops = &clk_branch2_ops,
250 		},
251 	},
252 };
253 
254 static struct clk_branch cam_bist_mclk_cc_mclk1_clk = {
255 	.halt_reg = 0x4034,
256 	.halt_check = BRANCH_HALT,
257 	.clkr = {
258 		.enable_reg = 0x4034,
259 		.enable_mask = BIT(0),
260 		.hw.init = &(const struct clk_init_data) {
261 			.name = "cam_bist_mclk_cc_mclk1_clk",
262 			.parent_hws = (const struct clk_hw*[]) {
263 				&cam_bist_mclk_cc_mclk1_clk_src.clkr.hw,
264 			},
265 			.num_parents = 1,
266 			.flags = CLK_SET_RATE_PARENT,
267 			.ops = &clk_branch2_ops,
268 		},
269 	},
270 };
271 
272 static struct clk_branch cam_bist_mclk_cc_mclk2_clk = {
273 	.halt_reg = 0x4050,
274 	.halt_check = BRANCH_HALT,
275 	.clkr = {
276 		.enable_reg = 0x4050,
277 		.enable_mask = BIT(0),
278 		.hw.init = &(const struct clk_init_data) {
279 			.name = "cam_bist_mclk_cc_mclk2_clk",
280 			.parent_hws = (const struct clk_hw*[]) {
281 				&cam_bist_mclk_cc_mclk2_clk_src.clkr.hw,
282 			},
283 			.num_parents = 1,
284 			.flags = CLK_SET_RATE_PARENT,
285 			.ops = &clk_branch2_ops,
286 		},
287 	},
288 };
289 
290 static struct clk_branch cam_bist_mclk_cc_mclk3_clk = {
291 	.halt_reg = 0x406c,
292 	.halt_check = BRANCH_HALT,
293 	.clkr = {
294 		.enable_reg = 0x406c,
295 		.enable_mask = BIT(0),
296 		.hw.init = &(const struct clk_init_data) {
297 			.name = "cam_bist_mclk_cc_mclk3_clk",
298 			.parent_hws = (const struct clk_hw*[]) {
299 				&cam_bist_mclk_cc_mclk3_clk_src.clkr.hw,
300 			},
301 			.num_parents = 1,
302 			.flags = CLK_SET_RATE_PARENT,
303 			.ops = &clk_branch2_ops,
304 		},
305 	},
306 };
307 
308 static struct clk_branch cam_bist_mclk_cc_mclk4_clk = {
309 	.halt_reg = 0x4088,
310 	.halt_check = BRANCH_HALT,
311 	.clkr = {
312 		.enable_reg = 0x4088,
313 		.enable_mask = BIT(0),
314 		.hw.init = &(const struct clk_init_data) {
315 			.name = "cam_bist_mclk_cc_mclk4_clk",
316 			.parent_hws = (const struct clk_hw*[]) {
317 				&cam_bist_mclk_cc_mclk4_clk_src.clkr.hw,
318 			},
319 			.num_parents = 1,
320 			.flags = CLK_SET_RATE_PARENT,
321 			.ops = &clk_branch2_ops,
322 		},
323 	},
324 };
325 
326 static struct clk_branch cam_bist_mclk_cc_mclk5_clk = {
327 	.halt_reg = 0x40a4,
328 	.halt_check = BRANCH_HALT,
329 	.clkr = {
330 		.enable_reg = 0x40a4,
331 		.enable_mask = BIT(0),
332 		.hw.init = &(const struct clk_init_data) {
333 			.name = "cam_bist_mclk_cc_mclk5_clk",
334 			.parent_hws = (const struct clk_hw*[]) {
335 				&cam_bist_mclk_cc_mclk5_clk_src.clkr.hw,
336 			},
337 			.num_parents = 1,
338 			.flags = CLK_SET_RATE_PARENT,
339 			.ops = &clk_branch2_ops,
340 		},
341 	},
342 };
343 
344 static struct clk_branch cam_bist_mclk_cc_mclk6_clk = {
345 	.halt_reg = 0x40c0,
346 	.halt_check = BRANCH_HALT,
347 	.clkr = {
348 		.enable_reg = 0x40c0,
349 		.enable_mask = BIT(0),
350 		.hw.init = &(const struct clk_init_data) {
351 			.name = "cam_bist_mclk_cc_mclk6_clk",
352 			.parent_hws = (const struct clk_hw*[]) {
353 				&cam_bist_mclk_cc_mclk6_clk_src.clkr.hw,
354 			},
355 			.num_parents = 1,
356 			.flags = CLK_SET_RATE_PARENT,
357 			.ops = &clk_branch2_ops,
358 		},
359 	},
360 };
361 
362 static struct clk_branch cam_bist_mclk_cc_mclk7_clk = {
363 	.halt_reg = 0x40dc,
364 	.halt_check = BRANCH_HALT,
365 	.clkr = {
366 		.enable_reg = 0x40dc,
367 		.enable_mask = BIT(0),
368 		.hw.init = &(const struct clk_init_data) {
369 			.name = "cam_bist_mclk_cc_mclk7_clk",
370 			.parent_hws = (const struct clk_hw*[]) {
371 				&cam_bist_mclk_cc_mclk7_clk_src.clkr.hw,
372 			},
373 			.num_parents = 1,
374 			.flags = CLK_SET_RATE_PARENT,
375 			.ops = &clk_branch2_ops,
376 		},
377 	},
378 };
379 
380 static struct clk_regmap *cam_bist_mclk_cc_sm8750_clocks[] = {
381 	[CAM_BIST_MCLK_CC_MCLK0_CLK] = &cam_bist_mclk_cc_mclk0_clk.clkr,
382 	[CAM_BIST_MCLK_CC_MCLK0_CLK_SRC] = &cam_bist_mclk_cc_mclk0_clk_src.clkr,
383 	[CAM_BIST_MCLK_CC_MCLK1_CLK] = &cam_bist_mclk_cc_mclk1_clk.clkr,
384 	[CAM_BIST_MCLK_CC_MCLK1_CLK_SRC] = &cam_bist_mclk_cc_mclk1_clk_src.clkr,
385 	[CAM_BIST_MCLK_CC_MCLK2_CLK] = &cam_bist_mclk_cc_mclk2_clk.clkr,
386 	[CAM_BIST_MCLK_CC_MCLK2_CLK_SRC] = &cam_bist_mclk_cc_mclk2_clk_src.clkr,
387 	[CAM_BIST_MCLK_CC_MCLK3_CLK] = &cam_bist_mclk_cc_mclk3_clk.clkr,
388 	[CAM_BIST_MCLK_CC_MCLK3_CLK_SRC] = &cam_bist_mclk_cc_mclk3_clk_src.clkr,
389 	[CAM_BIST_MCLK_CC_MCLK4_CLK] = &cam_bist_mclk_cc_mclk4_clk.clkr,
390 	[CAM_BIST_MCLK_CC_MCLK4_CLK_SRC] = &cam_bist_mclk_cc_mclk4_clk_src.clkr,
391 	[CAM_BIST_MCLK_CC_MCLK5_CLK] = &cam_bist_mclk_cc_mclk5_clk.clkr,
392 	[CAM_BIST_MCLK_CC_MCLK5_CLK_SRC] = &cam_bist_mclk_cc_mclk5_clk_src.clkr,
393 	[CAM_BIST_MCLK_CC_MCLK6_CLK] = &cam_bist_mclk_cc_mclk6_clk.clkr,
394 	[CAM_BIST_MCLK_CC_MCLK6_CLK_SRC] = &cam_bist_mclk_cc_mclk6_clk_src.clkr,
395 	[CAM_BIST_MCLK_CC_MCLK7_CLK] = &cam_bist_mclk_cc_mclk7_clk.clkr,
396 	[CAM_BIST_MCLK_CC_MCLK7_CLK_SRC] = &cam_bist_mclk_cc_mclk7_clk_src.clkr,
397 	[CAM_BIST_MCLK_CC_PLL0] = &cam_bist_mclk_cc_pll0.clkr,
398 	[CAM_BIST_MCLK_CC_SLEEP_CLK_SRC] = &cam_bist_mclk_cc_sleep_clk_src.clkr,
399 };
400 
401 static struct clk_alpha_pll *cam_bist_mclk_cc_sm8750_plls[] = {
402 	&cam_bist_mclk_cc_pll0,
403 };
404 
405 static u32 cam_bist_mclk_cc_sm8750_critical_cbcrs[] = {
406 	0x40f8, /* CAM_BIST_MCLK_CC_SLEEP_CLK */
407 };
408 
409 static const struct regmap_config cam_bist_mclk_cc_sm8750_regmap_config = {
410 	.reg_bits = 32,
411 	.reg_stride = 4,
412 	.val_bits = 32,
413 	.max_register = 0x5010,
414 	.fast_io = true,
415 };
416 
417 static struct qcom_cc_driver_data cam_bist_mclk_cc_sm8750_driver_data = {
418 	.alpha_plls = cam_bist_mclk_cc_sm8750_plls,
419 	.num_alpha_plls = ARRAY_SIZE(cam_bist_mclk_cc_sm8750_plls),
420 	.clk_cbcrs = cam_bist_mclk_cc_sm8750_critical_cbcrs,
421 	.num_clk_cbcrs = ARRAY_SIZE(cam_bist_mclk_cc_sm8750_critical_cbcrs),
422 };
423 
424 static const struct qcom_cc_desc cam_bist_mclk_cc_sm8750_desc = {
425 	.config = &cam_bist_mclk_cc_sm8750_regmap_config,
426 	.clks = cam_bist_mclk_cc_sm8750_clocks,
427 	.num_clks = ARRAY_SIZE(cam_bist_mclk_cc_sm8750_clocks),
428 	.use_rpm = true,
429 	.driver_data = &cam_bist_mclk_cc_sm8750_driver_data,
430 };
431 
432 static const struct of_device_id cam_bist_mclk_cc_sm8750_match_table[] = {
433 	{ .compatible = "qcom,sm8750-cambistmclkcc" },
434 	{ }
435 };
436 MODULE_DEVICE_TABLE(of, cam_bist_mclk_cc_sm8750_match_table);
437 
438 static int cam_bist_mclk_cc_sm8750_probe(struct platform_device *pdev)
439 {
440 	return qcom_cc_probe(pdev, &cam_bist_mclk_cc_sm8750_desc);
441 }
442 
443 static struct platform_driver cam_bist_mclk_cc_sm8750_driver = {
444 	.probe = cam_bist_mclk_cc_sm8750_probe,
445 	.driver = {
446 		.name = "cambistmclkcc-sm8750",
447 		.of_match_table = cam_bist_mclk_cc_sm8750_match_table,
448 	},
449 };
450 
451 module_platform_driver(cam_bist_mclk_cc_sm8750_driver);
452 
453 MODULE_DESCRIPTION("QTI CAMBISTMCLKCC SM8750 Driver");
454 MODULE_LICENSE("GPL");
455