xref: /linux/drivers/media/platform/qcom/camss/camss.c (revision 7f71507851fc7764b36a3221839607d3a45c2025)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * camss.c
4  *
5  * Qualcomm MSM Camera Subsystem - Core
6  *
7  * Copyright (c) 2015, The Linux Foundation. All rights reserved.
8  * Copyright (C) 2015-2018 Linaro Ltd.
9  */
10 #include <linux/clk.h>
11 #include <linux/interconnect.h>
12 #include <linux/media-bus-format.h>
13 #include <linux/media.h>
14 #include <linux/module.h>
15 #include <linux/platform_device.h>
16 #include <linux/of.h>
17 #include <linux/of_device.h>
18 #include <linux/of_graph.h>
19 #include <linux/pm_runtime.h>
20 #include <linux/pm_domain.h>
21 #include <linux/slab.h>
22 #include <linux/videodev2.h>
23 
24 #include <media/media-device.h>
25 #include <media/v4l2-async.h>
26 #include <media/v4l2-device.h>
27 #include <media/v4l2-mc.h>
28 #include <media/v4l2-fwnode.h>
29 
30 #include "camss.h"
31 
32 #define CAMSS_CLOCK_MARGIN_NUMERATOR 105
33 #define CAMSS_CLOCK_MARGIN_DENOMINATOR 100
34 
35 static const struct parent_dev_ops vfe_parent_dev_ops;
36 
37 static const struct camss_subdev_resources csiphy_res_8x16[] = {
38 	/* CSIPHY0 */
39 	{
40 		.regulators = {},
41 		.clock = { "top_ahb", "ispif_ahb", "ahb", "csiphy0_timer" },
42 		.clock_rate = { { 0 },
43 				{ 0 },
44 				{ 0 },
45 				{ 100000000, 200000000 } },
46 		.reg = { "csiphy0", "csiphy0_clk_mux" },
47 		.interrupt = { "csiphy0" },
48 		.csiphy = {
49 			.hw_ops = &csiphy_ops_2ph_1_0,
50 			.formats = &csiphy_formats_8x16
51 		}
52 	},
53 
54 	/* CSIPHY1 */
55 	{
56 		.regulators = {},
57 		.clock = { "top_ahb", "ispif_ahb", "ahb", "csiphy1_timer" },
58 		.clock_rate = { { 0 },
59 				{ 0 },
60 				{ 0 },
61 				{ 100000000, 200000000 } },
62 		.reg = { "csiphy1", "csiphy1_clk_mux" },
63 		.interrupt = { "csiphy1" },
64 		.csiphy = {
65 			.hw_ops = &csiphy_ops_2ph_1_0,
66 			.formats = &csiphy_formats_8x16
67 		}
68 	}
69 };
70 
71 static const struct camss_subdev_resources csid_res_8x16[] = {
72 	/* CSID0 */
73 	{
74 		.regulators = { "vdda" },
75 		.clock = { "top_ahb", "ispif_ahb", "csi0_ahb", "ahb",
76 			   "csi0", "csi0_phy", "csi0_pix", "csi0_rdi" },
77 		.clock_rate = { { 0 },
78 				{ 0 },
79 				{ 0 },
80 				{ 0 },
81 				{ 100000000, 200000000 },
82 				{ 0 },
83 				{ 0 },
84 				{ 0 } },
85 		.reg = { "csid0" },
86 		.interrupt = { "csid0" },
87 		.csid = {
88 			.hw_ops = &csid_ops_4_1,
89 			.parent_dev_ops = &vfe_parent_dev_ops,
90 			.formats = &csid_formats_4_1
91 		}
92 	},
93 
94 	/* CSID1 */
95 	{
96 		.regulators = { "vdda" },
97 		.clock = { "top_ahb", "ispif_ahb", "csi1_ahb", "ahb",
98 			   "csi1", "csi1_phy", "csi1_pix", "csi1_rdi" },
99 		.clock_rate = { { 0 },
100 				{ 0 },
101 				{ 0 },
102 				{ 0 },
103 				{ 100000000, 200000000 },
104 				{ 0 },
105 				{ 0 },
106 				{ 0 } },
107 		.reg = { "csid1" },
108 		.interrupt = { "csid1" },
109 		.csid = {
110 			.hw_ops = &csid_ops_4_1,
111 			.parent_dev_ops = &vfe_parent_dev_ops,
112 			.formats = &csid_formats_4_1
113 		}
114 	},
115 };
116 
117 static const struct camss_subdev_resources ispif_res_8x16 = {
118 	/* ISPIF */
119 	.clock = { "top_ahb", "ahb", "ispif_ahb",
120 		   "csi0", "csi0_pix", "csi0_rdi",
121 		   "csi1", "csi1_pix", "csi1_rdi" },
122 	.clock_for_reset = { "vfe0", "csi_vfe0" },
123 	.reg = { "ispif", "csi_clk_mux" },
124 	.interrupt = { "ispif" },
125 };
126 
127 static const struct camss_subdev_resources vfe_res_8x16[] = {
128 	/* VFE0 */
129 	{
130 		.regulators = {},
131 		.clock = { "top_ahb", "vfe0", "csi_vfe0",
132 			   "vfe_ahb", "vfe_axi", "ahb" },
133 		.clock_rate = { { 0 },
134 				{ 50000000, 80000000, 100000000, 160000000,
135 				  177780000, 200000000, 266670000, 320000000,
136 				  400000000, 465000000 },
137 				{ 0 },
138 				{ 0 },
139 				{ 0 },
140 				{ 0 },
141 				{ 0 },
142 				{ 0 },
143 				{ 0 } },
144 		.reg = { "vfe0" },
145 		.interrupt = { "vfe0" },
146 		.vfe = {
147 			.line_num = 3,
148 			.hw_ops = &vfe_ops_4_1,
149 			.formats_rdi = &vfe_formats_rdi_8x16,
150 			.formats_pix = &vfe_formats_pix_8x16
151 		}
152 	}
153 };
154 
155 static const struct camss_subdev_resources csid_res_8x53[] = {
156 	/* CSID0 */
157 	{
158 		.regulators = { "vdda" },
159 		.clock = { "top_ahb", "ispif_ahb", "csi0_ahb", "ahb",
160 			   "csi0", "csi0_phy", "csi0_pix", "csi0_rdi" },
161 		.clock_rate = { { 0 },
162 				{ 0 },
163 				{ 0 },
164 				{ 0 },
165 				{ 100000000, 200000000, 310000000,
166 				  400000000, 465000000 },
167 				{ 0 },
168 				{ 0 },
169 				{ 0 } },
170 		.reg = { "csid0" },
171 		.interrupt = { "csid0" },
172 		.csid = {
173 			.hw_ops = &csid_ops_4_7,
174 			.parent_dev_ops = &vfe_parent_dev_ops,
175 			.formats = &csid_formats_4_7
176 		}
177 	},
178 
179 	/* CSID1 */
180 	{
181 		.regulators = { "vdda" },
182 		.clock = { "top_ahb", "ispif_ahb", "csi1_ahb", "ahb",
183 			   "csi1", "csi1_phy", "csi1_pix", "csi1_rdi" },
184 		.clock_rate = { { 0 },
185 				{ 0 },
186 				{ 0 },
187 				{ 0 },
188 				{ 100000000, 200000000, 310000000,
189 				  400000000, 465000000 },
190 				{ 0 },
191 				{ 0 },
192 				{ 0 } },
193 		.reg = { "csid1" },
194 		.interrupt = { "csid1" },
195 		.csid = {
196 			.hw_ops = &csid_ops_4_7,
197 			.parent_dev_ops = &vfe_parent_dev_ops,
198 			.formats = &csid_formats_4_7
199 		}
200 	},
201 
202 	/* CSID2 */
203 	{
204 		.regulators = { "vdda" },
205 		.clock = { "top_ahb", "ispif_ahb", "csi2_ahb", "ahb",
206 			   "csi2", "csi2_phy", "csi2_pix", "csi2_rdi" },
207 		.clock_rate = { { 0 },
208 				{ 0 },
209 				{ 0 },
210 				{ 0 },
211 				{ 100000000, 200000000, 310000000,
212 				  400000000, 465000000 },
213 				{ 0 },
214 				{ 0 },
215 				{ 0 } },
216 		.reg = { "csid2" },
217 		.interrupt = { "csid2" },
218 		.csid = {
219 			.hw_ops = &csid_ops_4_7,
220 			.parent_dev_ops = &vfe_parent_dev_ops,
221 			.formats = &csid_formats_4_7
222 		}
223 	},
224 };
225 
226 static const struct camss_subdev_resources ispif_res_8x53 = {
227 	/* ISPIF */
228 	.clock = { "top_ahb", "ahb", "ispif_ahb",
229 		   "csi0", "csi0_pix", "csi0_rdi",
230 		   "csi1", "csi1_pix", "csi1_rdi",
231 		   "csi2", "csi2_pix", "csi2_rdi" },
232 	.clock_for_reset = { "vfe0", "csi_vfe0", "vfe1", "csi_vfe1" },
233 	.reg = { "ispif", "csi_clk_mux" },
234 	.interrupt = { "ispif" },
235 };
236 
237 static const struct camss_subdev_resources vfe_res_8x53[] = {
238 	/* VFE0 */
239 	{
240 		.regulators = {},
241 		.clock = { "top_ahb", "ahb", "ispif_ahb",
242 			   "vfe0", "csi_vfe0", "vfe0_ahb", "vfe0_axi" },
243 		.clock_rate = { { 0 },
244 				{ 0 },
245 				{ 0 },
246 				{ 50000000, 100000000, 133330000,
247 				  160000000, 200000000, 266670000,
248 				  310000000, 400000000, 465000000 },
249 				{ 0 },
250 				{ 0 },
251 				{ 0 } },
252 		.reg = { "vfe0" },
253 		.interrupt = { "vfe0" },
254 		.vfe = {
255 			.line_num = 3,
256 			.has_pd = true,
257 			.pd_name = "vfe0",
258 			.hw_ops = &vfe_ops_4_1,
259 			.formats_rdi = &vfe_formats_rdi_8x16,
260 			.formats_pix = &vfe_formats_pix_8x16
261 		}
262 	},
263 
264 	/* VFE1 */
265 	{
266 		.regulators = {},
267 		.clock = { "top_ahb", "ahb", "ispif_ahb",
268 			   "vfe1", "csi_vfe1", "vfe1_ahb", "vfe1_axi" },
269 		.clock_rate = { { 0 },
270 				{ 0 },
271 				{ 0 },
272 				{ 50000000, 100000000, 133330000,
273 				  160000000, 200000000, 266670000,
274 				  310000000, 400000000, 465000000 },
275 				{ 0 },
276 				{ 0 },
277 				{ 0 } },
278 		.reg = { "vfe1" },
279 		.interrupt = { "vfe1" },
280 		.vfe = {
281 			.line_num = 3,
282 			.has_pd = true,
283 			.pd_name = "vfe1",
284 			.hw_ops = &vfe_ops_4_1,
285 			.formats_rdi = &vfe_formats_rdi_8x16,
286 			.formats_pix = &vfe_formats_pix_8x16
287 		}
288 	}
289 };
290 
291 static const struct resources_icc icc_res_8x53[] = {
292 	{
293 		.name = "cam_ahb",
294 		.icc_bw_tbl.avg = 38400,
295 		.icc_bw_tbl.peak = 76800,
296 	},
297 	{
298 		.name = "cam_vfe0_mem",
299 		.icc_bw_tbl.avg = 939524,
300 		.icc_bw_tbl.peak = 1342177,
301 	},
302 	{
303 		.name = "cam_vfe1_mem",
304 		.icc_bw_tbl.avg = 939524,
305 		.icc_bw_tbl.peak = 1342177,
306 	},
307 };
308 
309 static const struct camss_subdev_resources csiphy_res_8x96[] = {
310 	/* CSIPHY0 */
311 	{
312 		.regulators = {},
313 		.clock = { "top_ahb", "ispif_ahb", "ahb", "csiphy0_timer" },
314 		.clock_rate = { { 0 },
315 				{ 0 },
316 				{ 0 },
317 				{ 100000000, 200000000, 266666667 } },
318 		.reg = { "csiphy0", "csiphy0_clk_mux" },
319 		.interrupt = { "csiphy0" },
320 		.csiphy = {
321 			.hw_ops = &csiphy_ops_3ph_1_0,
322 			.formats = &csiphy_formats_8x96
323 		}
324 	},
325 
326 	/* CSIPHY1 */
327 	{
328 		.regulators = {},
329 		.clock = { "top_ahb", "ispif_ahb", "ahb", "csiphy1_timer" },
330 		.clock_rate = { { 0 },
331 				{ 0 },
332 				{ 0 },
333 				{ 100000000, 200000000, 266666667 } },
334 		.reg = { "csiphy1", "csiphy1_clk_mux" },
335 		.interrupt = { "csiphy1" },
336 		.csiphy = {
337 			.hw_ops = &csiphy_ops_3ph_1_0,
338 			.formats = &csiphy_formats_8x96
339 		}
340 	},
341 
342 	/* CSIPHY2 */
343 	{
344 		.regulators = {},
345 		.clock = { "top_ahb", "ispif_ahb", "ahb", "csiphy2_timer" },
346 		.clock_rate = { { 0 },
347 				{ 0 },
348 				{ 0 },
349 				{ 100000000, 200000000, 266666667 } },
350 		.reg = { "csiphy2", "csiphy2_clk_mux" },
351 		.interrupt = { "csiphy2" },
352 		.csiphy = {
353 			.hw_ops = &csiphy_ops_3ph_1_0,
354 			.formats = &csiphy_formats_8x96
355 		}
356 	}
357 };
358 
359 static const struct camss_subdev_resources csid_res_8x96[] = {
360 	/* CSID0 */
361 	{
362 		.regulators = { "vdda" },
363 		.clock = { "top_ahb", "ispif_ahb", "csi0_ahb", "ahb",
364 			   "csi0", "csi0_phy", "csi0_pix", "csi0_rdi" },
365 		.clock_rate = { { 0 },
366 				{ 0 },
367 				{ 0 },
368 				{ 0 },
369 				{ 100000000, 200000000, 266666667 },
370 				{ 0 },
371 				{ 0 },
372 				{ 0 } },
373 		.reg = { "csid0" },
374 		.interrupt = { "csid0" },
375 		.csid = {
376 			.hw_ops = &csid_ops_4_7,
377 			.parent_dev_ops = &vfe_parent_dev_ops,
378 			.formats = &csid_formats_4_7
379 		}
380 	},
381 
382 	/* CSID1 */
383 	{
384 		.regulators = { "vdda" },
385 		.clock = { "top_ahb", "ispif_ahb", "csi1_ahb", "ahb",
386 			   "csi1", "csi1_phy", "csi1_pix", "csi1_rdi" },
387 		.clock_rate = { { 0 },
388 				{ 0 },
389 				{ 0 },
390 				{ 0 },
391 				{ 100000000, 200000000, 266666667 },
392 				{ 0 },
393 				{ 0 },
394 				{ 0 } },
395 		.reg = { "csid1" },
396 		.interrupt = { "csid1" },
397 		.csid = {
398 			.hw_ops = &csid_ops_4_7,
399 			.parent_dev_ops = &vfe_parent_dev_ops,
400 			.formats = &csid_formats_4_7
401 		}
402 	},
403 
404 	/* CSID2 */
405 	{
406 		.regulators = { "vdda" },
407 		.clock = { "top_ahb", "ispif_ahb", "csi2_ahb", "ahb",
408 			   "csi2", "csi2_phy", "csi2_pix", "csi2_rdi" },
409 		.clock_rate = { { 0 },
410 				{ 0 },
411 				{ 0 },
412 				{ 0 },
413 				{ 100000000, 200000000, 266666667 },
414 				{ 0 },
415 				{ 0 },
416 				{ 0 } },
417 		.reg = { "csid2" },
418 		.interrupt = { "csid2" },
419 		.csid = {
420 			.hw_ops = &csid_ops_4_7,
421 			.parent_dev_ops = &vfe_parent_dev_ops,
422 			.formats = &csid_formats_4_7
423 		}
424 	},
425 
426 	/* CSID3 */
427 	{
428 		.regulators = { "vdda" },
429 		.clock = { "top_ahb", "ispif_ahb", "csi3_ahb", "ahb",
430 			   "csi3", "csi3_phy", "csi3_pix", "csi3_rdi" },
431 		.clock_rate = { { 0 },
432 				{ 0 },
433 				{ 0 },
434 				{ 0 },
435 				{ 100000000, 200000000, 266666667 },
436 				{ 0 },
437 				{ 0 },
438 				{ 0 } },
439 		.reg = { "csid3" },
440 		.interrupt = { "csid3" },
441 		.csid = {
442 			.hw_ops = &csid_ops_4_7,
443 			.parent_dev_ops = &vfe_parent_dev_ops,
444 			.formats = &csid_formats_4_7
445 		}
446 	}
447 };
448 
449 static const struct camss_subdev_resources ispif_res_8x96 = {
450 	/* ISPIF */
451 	.clock = { "top_ahb", "ahb", "ispif_ahb",
452 		   "csi0", "csi0_pix", "csi0_rdi",
453 		   "csi1", "csi1_pix", "csi1_rdi",
454 		   "csi2", "csi2_pix", "csi2_rdi",
455 		   "csi3", "csi3_pix", "csi3_rdi" },
456 	.clock_for_reset = { "vfe0", "csi_vfe0", "vfe1", "csi_vfe1" },
457 	.reg = { "ispif", "csi_clk_mux" },
458 	.interrupt = { "ispif" },
459 };
460 
461 static const struct camss_subdev_resources vfe_res_8x96[] = {
462 	/* VFE0 */
463 	{
464 		.regulators = {},
465 		.clock = { "top_ahb", "ahb", "vfe0", "csi_vfe0", "vfe_ahb",
466 			   "vfe0_ahb", "vfe_axi", "vfe0_stream"},
467 		.clock_rate = { { 0 },
468 				{ 0 },
469 				{ 75000000, 100000000, 300000000,
470 				  320000000, 480000000, 600000000 },
471 				{ 0 },
472 				{ 0 },
473 				{ 0 },
474 				{ 0 },
475 				{ 0 } },
476 		.reg = { "vfe0" },
477 		.interrupt = { "vfe0" },
478 		.vfe = {
479 			.line_num = 3,
480 			.has_pd = true,
481 			.hw_ops = &vfe_ops_4_7,
482 			.formats_rdi = &vfe_formats_rdi_8x96,
483 			.formats_pix = &vfe_formats_pix_8x96
484 		}
485 	},
486 
487 	/* VFE1 */
488 	{
489 		.regulators = {},
490 		.clock = { "top_ahb", "ahb", "vfe1", "csi_vfe1", "vfe_ahb",
491 			   "vfe1_ahb", "vfe_axi", "vfe1_stream"},
492 		.clock_rate = { { 0 },
493 				{ 0 },
494 				{ 75000000, 100000000, 300000000,
495 				  320000000, 480000000, 600000000 },
496 				{ 0 },
497 				{ 0 },
498 				{ 0 },
499 				{ 0 },
500 				{ 0 } },
501 		.reg = { "vfe1" },
502 		.interrupt = { "vfe1" },
503 		.vfe = {
504 			.line_num = 3,
505 			.has_pd = true,
506 			.hw_ops = &vfe_ops_4_7,
507 			.formats_rdi = &vfe_formats_rdi_8x96,
508 			.formats_pix = &vfe_formats_pix_8x96
509 		}
510 	}
511 };
512 
513 static const struct camss_subdev_resources csiphy_res_660[] = {
514 	/* CSIPHY0 */
515 	{
516 		.regulators = {},
517 		.clock = { "top_ahb", "ispif_ahb", "ahb", "csiphy0_timer",
518 			   "csi0_phy", "csiphy_ahb2crif" },
519 		.clock_rate = { { 0 },
520 				{ 0 },
521 				{ 0 },
522 				{ 100000000, 200000000, 269333333 },
523 				{ 0 } },
524 		.reg = { "csiphy0", "csiphy0_clk_mux" },
525 		.interrupt = { "csiphy0" },
526 		.csiphy = {
527 			.hw_ops = &csiphy_ops_3ph_1_0,
528 			.formats = &csiphy_formats_8x96
529 		}
530 	},
531 
532 	/* CSIPHY1 */
533 	{
534 		.regulators = {},
535 		.clock = { "top_ahb", "ispif_ahb", "ahb", "csiphy1_timer",
536 			   "csi1_phy", "csiphy_ahb2crif" },
537 		.clock_rate = { { 0 },
538 				{ 0 },
539 				{ 0 },
540 				{ 100000000, 200000000, 269333333 },
541 				{ 0 } },
542 		.reg = { "csiphy1", "csiphy1_clk_mux" },
543 		.interrupt = { "csiphy1" },
544 		.csiphy = {
545 			.hw_ops = &csiphy_ops_3ph_1_0,
546 			.formats = &csiphy_formats_8x96
547 		}
548 	},
549 
550 	/* CSIPHY2 */
551 	{
552 		.regulators = {},
553 		.clock = { "top_ahb", "ispif_ahb", "ahb", "csiphy2_timer",
554 			   "csi2_phy", "csiphy_ahb2crif" },
555 		.clock_rate = { { 0 },
556 				{ 0 },
557 				{ 0 },
558 				{ 100000000, 200000000, 269333333 },
559 				{ 0 } },
560 		.reg = { "csiphy2", "csiphy2_clk_mux" },
561 		.interrupt = { "csiphy2" },
562 		.csiphy = {
563 			.hw_ops = &csiphy_ops_3ph_1_0,
564 			.formats = &csiphy_formats_8x96
565 		}
566 	}
567 };
568 
569 static const struct camss_subdev_resources csid_res_660[] = {
570 	/* CSID0 */
571 	{
572 		.regulators = { "vdda", "vdd_sec" },
573 		.clock = { "top_ahb", "ispif_ahb", "csi0_ahb", "ahb",
574 			   "csi0", "csi0_phy", "csi0_pix", "csi0_rdi",
575 			   "cphy_csid0" },
576 		.clock_rate = { { 0 },
577 				{ 0 },
578 				{ 0 },
579 				{ 0 },
580 				{ 100000000, 200000000, 310000000,
581 				  404000000, 465000000 },
582 				{ 0 },
583 				{ 0 },
584 				{ 0 },
585 				{ 0 } },
586 		.reg = { "csid0" },
587 		.interrupt = { "csid0" },
588 		.csid = {
589 			.hw_ops = &csid_ops_4_7,
590 			.parent_dev_ops = &vfe_parent_dev_ops,
591 			.formats = &csid_formats_4_7
592 		}
593 	},
594 
595 	/* CSID1 */
596 	{
597 		.regulators = { "vdda", "vdd_sec" },
598 		.clock = { "top_ahb", "ispif_ahb", "csi1_ahb", "ahb",
599 			   "csi1", "csi1_phy", "csi1_pix", "csi1_rdi",
600 			   "cphy_csid1" },
601 		.clock_rate = { { 0 },
602 				{ 0 },
603 				{ 0 },
604 				{ 0 },
605 				{ 100000000, 200000000, 310000000,
606 				  404000000, 465000000 },
607 				{ 0 },
608 				{ 0 },
609 				{ 0 },
610 				{ 0 } },
611 		.reg = { "csid1" },
612 		.interrupt = { "csid1" },
613 		.csid = {
614 			.hw_ops = &csid_ops_4_7,
615 			.parent_dev_ops = &vfe_parent_dev_ops,
616 			.formats = &csid_formats_4_7
617 		}
618 	},
619 
620 	/* CSID2 */
621 	{
622 		.regulators = { "vdda", "vdd_sec" },
623 		.clock = { "top_ahb", "ispif_ahb", "csi2_ahb", "ahb",
624 			   "csi2", "csi2_phy", "csi2_pix", "csi2_rdi",
625 			   "cphy_csid2" },
626 		.clock_rate = { { 0 },
627 				{ 0 },
628 				{ 0 },
629 				{ 0 },
630 				{ 100000000, 200000000, 310000000,
631 				  404000000, 465000000 },
632 				{ 0 },
633 				{ 0 },
634 				{ 0 },
635 				{ 0 } },
636 		.reg = { "csid2" },
637 		.interrupt = { "csid2" },
638 		.csid = {
639 			.hw_ops = &csid_ops_4_7,
640 			.parent_dev_ops = &vfe_parent_dev_ops,
641 			.formats = &csid_formats_4_7
642 		}
643 	},
644 
645 	/* CSID3 */
646 	{
647 		.regulators = { "vdda", "vdd_sec" },
648 		.clock = { "top_ahb", "ispif_ahb", "csi3_ahb", "ahb",
649 			   "csi3", "csi3_phy", "csi3_pix", "csi3_rdi",
650 			   "cphy_csid3" },
651 		.clock_rate = { { 0 },
652 				{ 0 },
653 				{ 0 },
654 				{ 0 },
655 				{ 100000000, 200000000, 310000000,
656 				  404000000, 465000000 },
657 				{ 0 },
658 				{ 0 },
659 				{ 0 },
660 				{ 0 } },
661 		.reg = { "csid3" },
662 		.interrupt = { "csid3" },
663 		.csid = {
664 			.hw_ops = &csid_ops_4_7,
665 			.parent_dev_ops = &vfe_parent_dev_ops,
666 			.formats = &csid_formats_4_7
667 		}
668 	}
669 };
670 
671 static const struct camss_subdev_resources ispif_res_660 = {
672 	/* ISPIF */
673 	.clock = { "top_ahb", "ahb", "ispif_ahb",
674 		   "csi0", "csi0_pix", "csi0_rdi",
675 		   "csi1", "csi1_pix", "csi1_rdi",
676 		   "csi2", "csi2_pix", "csi2_rdi",
677 		   "csi3", "csi3_pix", "csi3_rdi" },
678 	.clock_for_reset = { "vfe0", "csi_vfe0", "vfe1", "csi_vfe1" },
679 	.reg = { "ispif", "csi_clk_mux" },
680 	.interrupt = { "ispif" },
681 };
682 
683 static const struct camss_subdev_resources vfe_res_660[] = {
684 	/* VFE0 */
685 	{
686 		.regulators = {},
687 		.clock = { "throttle_axi", "top_ahb", "ahb", "vfe0",
688 			   "csi_vfe0", "vfe_ahb", "vfe0_ahb", "vfe_axi",
689 			   "vfe0_stream"},
690 		.clock_rate = { { 0 },
691 				{ 0 },
692 				{ 0 },
693 				{ 120000000, 200000000, 256000000,
694 				  300000000, 404000000, 480000000,
695 				  540000000, 576000000 },
696 				{ 0 },
697 				{ 0 },
698 				{ 0 },
699 				{ 0 },
700 				{ 0 } },
701 		.reg = { "vfe0" },
702 		.interrupt = { "vfe0" },
703 		.vfe = {
704 			.line_num = 3,
705 			.has_pd = true,
706 			.hw_ops = &vfe_ops_4_8,
707 			.formats_rdi = &vfe_formats_rdi_8x96,
708 			.formats_pix = &vfe_formats_pix_8x96
709 		}
710 	},
711 
712 	/* VFE1 */
713 	{
714 		.regulators = {},
715 		.clock = { "throttle_axi", "top_ahb", "ahb", "vfe1",
716 			   "csi_vfe1", "vfe_ahb", "vfe1_ahb", "vfe_axi",
717 			   "vfe1_stream"},
718 		.clock_rate = { { 0 },
719 				{ 0 },
720 				{ 0 },
721 				{ 120000000, 200000000, 256000000,
722 				  300000000, 404000000, 480000000,
723 				  540000000, 576000000 },
724 				{ 0 },
725 				{ 0 },
726 				{ 0 },
727 				{ 0 },
728 				{ 0 } },
729 		.reg = { "vfe1" },
730 		.interrupt = { "vfe1" },
731 		.vfe = {
732 			.line_num = 3,
733 			.has_pd = true,
734 			.hw_ops = &vfe_ops_4_8,
735 			.formats_rdi = &vfe_formats_rdi_8x96,
736 			.formats_pix = &vfe_formats_pix_8x96
737 		}
738 	}
739 };
740 
741 static const struct camss_subdev_resources csiphy_res_845[] = {
742 	/* CSIPHY0 */
743 	{
744 		.regulators = {},
745 		.clock = { "camnoc_axi", "soc_ahb", "slow_ahb_src",
746 				"cpas_ahb", "cphy_rx_src", "csiphy0",
747 				"csiphy0_timer_src", "csiphy0_timer" },
748 		.clock_rate = { { 0 },
749 				{ 0 },
750 				{ 0 },
751 				{ 0 },
752 				{ 0 },
753 				{ 0 },
754 				{ 0 },
755 				{ 19200000, 240000000, 269333333 } },
756 		.reg = { "csiphy0" },
757 		.interrupt = { "csiphy0" },
758 		.csiphy = {
759 			.hw_ops = &csiphy_ops_3ph_1_0,
760 			.formats = &csiphy_formats_sdm845
761 		}
762 	},
763 
764 	/* CSIPHY1 */
765 	{
766 		.regulators = {},
767 		.clock = { "camnoc_axi", "soc_ahb", "slow_ahb_src",
768 				"cpas_ahb", "cphy_rx_src", "csiphy1",
769 				"csiphy1_timer_src", "csiphy1_timer" },
770 		.clock_rate = { { 0 },
771 				{ 0 },
772 				{ 0 },
773 				{ 0 },
774 				{ 0 },
775 				{ 0 },
776 				{ 0 },
777 				{ 19200000, 240000000, 269333333 } },
778 		.reg = { "csiphy1" },
779 		.interrupt = { "csiphy1" },
780 		.csiphy = {
781 			.hw_ops = &csiphy_ops_3ph_1_0,
782 			.formats = &csiphy_formats_sdm845
783 		}
784 	},
785 
786 	/* CSIPHY2 */
787 	{
788 		.regulators = {},
789 		.clock = { "camnoc_axi", "soc_ahb", "slow_ahb_src",
790 				"cpas_ahb", "cphy_rx_src", "csiphy2",
791 				"csiphy2_timer_src", "csiphy2_timer" },
792 		.clock_rate = { { 0 },
793 				{ 0 },
794 				{ 0 },
795 				{ 0 },
796 				{ 0 },
797 				{ 0 },
798 				{ 0 },
799 				{ 19200000, 240000000, 269333333 } },
800 		.reg = { "csiphy2" },
801 		.interrupt = { "csiphy2" },
802 		.csiphy = {
803 			.hw_ops = &csiphy_ops_3ph_1_0,
804 			.formats = &csiphy_formats_sdm845
805 		}
806 	},
807 
808 	/* CSIPHY3 */
809 	{
810 		.regulators = {},
811 		.clock = { "camnoc_axi", "soc_ahb", "slow_ahb_src",
812 				"cpas_ahb", "cphy_rx_src", "csiphy3",
813 				"csiphy3_timer_src", "csiphy3_timer" },
814 		.clock_rate = { { 0 },
815 				{ 0 },
816 				{ 0 },
817 				{ 0 },
818 				{ 0 },
819 				{ 0 },
820 				{ 0 },
821 				{ 19200000, 240000000, 269333333 } },
822 		.reg = { "csiphy3" },
823 		.interrupt = { "csiphy3" },
824 		.csiphy = {
825 			.hw_ops = &csiphy_ops_3ph_1_0,
826 			.formats = &csiphy_formats_sdm845
827 		}
828 	}
829 };
830 
831 static const struct camss_subdev_resources csid_res_845[] = {
832 	/* CSID0 */
833 	{
834 		.regulators = { "vdda-phy", "vdda-pll" },
835 		.clock = { "cpas_ahb", "cphy_rx_src", "slow_ahb_src",
836 				"soc_ahb", "vfe0", "vfe0_src",
837 				"vfe0_cphy_rx", "csi0",
838 				"csi0_src" },
839 		.clock_rate = { { 0 },
840 				{ 384000000 },
841 				{ 80000000 },
842 				{ 0 },
843 				{ 19200000, 100000000, 320000000, 404000000, 480000000, 600000000 },
844 				{ 320000000 },
845 				{ 0 },
846 				{ 19200000, 75000000, 384000000, 538666667 },
847 				{ 384000000 } },
848 		.reg = { "csid0" },
849 		.interrupt = { "csid0" },
850 		.csid = {
851 			.hw_ops = &csid_ops_gen2,
852 			.parent_dev_ops = &vfe_parent_dev_ops,
853 			.formats = &csid_formats_gen2
854 		}
855 	},
856 
857 	/* CSID1 */
858 	{
859 		.regulators = { "vdda-phy", "vdda-pll" },
860 		.clock = { "cpas_ahb", "cphy_rx_src", "slow_ahb_src",
861 				"soc_ahb", "vfe1", "vfe1_src",
862 				"vfe1_cphy_rx", "csi1",
863 				"csi1_src" },
864 		.clock_rate = { { 0 },
865 				{ 384000000 },
866 				{ 80000000 },
867 				{ 0 },
868 				{ 19200000, 100000000, 320000000, 404000000, 480000000, 600000000 },
869 				{ 320000000 },
870 				{ 0 },
871 				{ 19200000, 75000000, 384000000, 538666667 },
872 				{ 384000000 } },
873 		.reg = { "csid1" },
874 		.interrupt = { "csid1" },
875 		.csid = {
876 			.hw_ops = &csid_ops_gen2,
877 			.parent_dev_ops = &vfe_parent_dev_ops,
878 			.formats = &csid_formats_gen2
879 		}
880 	},
881 
882 	/* CSID2 */
883 	{
884 		.regulators = { "vdda-phy", "vdda-pll" },
885 		.clock = { "cpas_ahb", "cphy_rx_src", "slow_ahb_src",
886 				"soc_ahb", "vfe_lite", "vfe_lite_src",
887 				"vfe_lite_cphy_rx", "csi2",
888 				"csi2_src" },
889 		.clock_rate = { { 0 },
890 				{ 384000000 },
891 				{ 80000000 },
892 				{ 0 },
893 				{ 19200000, 100000000, 320000000, 404000000, 480000000, 600000000 },
894 				{ 320000000 },
895 				{ 0 },
896 				{ 19200000, 75000000, 384000000, 538666667 },
897 				{ 384000000 } },
898 		.reg = { "csid2" },
899 		.interrupt = { "csid2" },
900 		.csid = {
901 			.is_lite = true,
902 			.hw_ops = &csid_ops_gen2,
903 			.parent_dev_ops = &vfe_parent_dev_ops,
904 			.formats = &csid_formats_gen2
905 		}
906 	}
907 };
908 
909 static const struct camss_subdev_resources vfe_res_845[] = {
910 	/* VFE0 */
911 	{
912 		.regulators = {},
913 		.clock = { "camnoc_axi", "cpas_ahb", "slow_ahb_src",
914 				"soc_ahb", "vfe0", "vfe0_axi",
915 				"vfe0_src", "csi0",
916 				"csi0_src"},
917 		.clock_rate = { { 0 },
918 				{ 0 },
919 				{ 80000000 },
920 				{ 0 },
921 				{ 19200000, 100000000, 320000000, 404000000, 480000000, 600000000 },
922 				{ 0 },
923 				{ 320000000 },
924 				{ 19200000, 75000000, 384000000, 538666667 },
925 				{ 384000000 } },
926 		.reg = { "vfe0" },
927 		.interrupt = { "vfe0" },
928 		.vfe = {
929 			.line_num = 4,
930 			.has_pd = true,
931 			.hw_ops = &vfe_ops_170,
932 			.formats_rdi = &vfe_formats_rdi_845,
933 			.formats_pix = &vfe_formats_pix_845
934 		}
935 	},
936 
937 	/* VFE1 */
938 	{
939 		.regulators = {},
940 		.clock = { "camnoc_axi", "cpas_ahb", "slow_ahb_src",
941 				"soc_ahb", "vfe1", "vfe1_axi",
942 				"vfe1_src", "csi1",
943 				"csi1_src"},
944 		.clock_rate = { { 0 },
945 				{ 0 },
946 				{ 80000000 },
947 				{ 0 },
948 				{ 19200000, 100000000, 320000000, 404000000, 480000000, 600000000 },
949 				{ 0 },
950 				{ 320000000 },
951 				{ 19200000, 75000000, 384000000, 538666667 },
952 				{ 384000000 } },
953 		.reg = { "vfe1" },
954 		.interrupt = { "vfe1" },
955 		.vfe = {
956 			.line_num = 4,
957 			.has_pd = true,
958 			.hw_ops = &vfe_ops_170,
959 			.formats_rdi = &vfe_formats_rdi_845,
960 			.formats_pix = &vfe_formats_pix_845
961 		}
962 	},
963 
964 	/* VFE-lite */
965 	{
966 		.regulators = {},
967 		.clock = { "camnoc_axi", "cpas_ahb", "slow_ahb_src",
968 				"soc_ahb", "vfe_lite",
969 				"vfe_lite_src", "csi2",
970 				"csi2_src"},
971 		.clock_rate = { { 0 },
972 				{ 0 },
973 				{ 80000000 },
974 				{ 0 },
975 				{ 19200000, 100000000, 320000000, 404000000, 480000000, 600000000 },
976 				{ 320000000 },
977 				{ 19200000, 75000000, 384000000, 538666667 },
978 				{ 384000000 } },
979 		.reg = { "vfe_lite" },
980 		.interrupt = { "vfe_lite" },
981 		.vfe = {
982 			.is_lite = true,
983 			.line_num = 4,
984 			.hw_ops = &vfe_ops_170,
985 			.formats_rdi = &vfe_formats_rdi_845,
986 			.formats_pix = &vfe_formats_pix_845
987 		}
988 	}
989 };
990 
991 static const struct camss_subdev_resources csiphy_res_8250[] = {
992 	/* CSIPHY0 */
993 	{
994 		.regulators = { "vdda-phy", "vdda-pll" },
995 		.clock = { "csiphy0", "csiphy0_timer" },
996 		.clock_rate = { { 400000000 },
997 				{ 300000000 } },
998 		.reg = { "csiphy0" },
999 		.interrupt = { "csiphy0" },
1000 		.csiphy = {
1001 			.hw_ops = &csiphy_ops_3ph_1_0,
1002 			.formats = &csiphy_formats_sdm845
1003 		}
1004 	},
1005 	/* CSIPHY1 */
1006 	{
1007 		.regulators = { "vdda-phy", "vdda-pll" },
1008 		.clock = { "csiphy1", "csiphy1_timer" },
1009 		.clock_rate = { { 400000000 },
1010 				{ 300000000 } },
1011 		.reg = { "csiphy1" },
1012 		.interrupt = { "csiphy1" },
1013 		.csiphy = {
1014 			.hw_ops = &csiphy_ops_3ph_1_0,
1015 			.formats = &csiphy_formats_sdm845
1016 		}
1017 	},
1018 	/* CSIPHY2 */
1019 	{
1020 		.regulators = { "vdda-phy", "vdda-pll" },
1021 		.clock = { "csiphy2", "csiphy2_timer" },
1022 		.clock_rate = { { 400000000 },
1023 				{ 300000000 } },
1024 		.reg = { "csiphy2" },
1025 		.interrupt = { "csiphy2" },
1026 		.csiphy = {
1027 			.hw_ops = &csiphy_ops_3ph_1_0,
1028 			.formats = &csiphy_formats_sdm845
1029 		}
1030 	},
1031 	/* CSIPHY3 */
1032 	{
1033 		.regulators = { "vdda-phy", "vdda-pll" },
1034 		.clock = { "csiphy3", "csiphy3_timer" },
1035 		.clock_rate = { { 400000000 },
1036 				{ 300000000 } },
1037 		.reg = { "csiphy3" },
1038 		.interrupt = { "csiphy3" },
1039 		.csiphy = {
1040 			.hw_ops = &csiphy_ops_3ph_1_0,
1041 			.formats = &csiphy_formats_sdm845
1042 		}
1043 	},
1044 	/* CSIPHY4 */
1045 	{
1046 		.regulators = { "vdda-phy", "vdda-pll" },
1047 		.clock = { "csiphy4", "csiphy4_timer" },
1048 		.clock_rate = { { 400000000 },
1049 				{ 300000000 } },
1050 		.reg = { "csiphy4" },
1051 		.interrupt = { "csiphy4" },
1052 		.csiphy = {
1053 			.hw_ops = &csiphy_ops_3ph_1_0,
1054 			.formats = &csiphy_formats_sdm845
1055 		}
1056 	},
1057 	/* CSIPHY5 */
1058 	{
1059 		.regulators = { "vdda-phy", "vdda-pll" },
1060 		.clock = { "csiphy5", "csiphy5_timer" },
1061 		.clock_rate = { { 400000000 },
1062 				{ 300000000 } },
1063 		.reg = { "csiphy5" },
1064 		.interrupt = { "csiphy5" },
1065 		.csiphy = {
1066 			.hw_ops = &csiphy_ops_3ph_1_0,
1067 			.formats = &csiphy_formats_sdm845
1068 		}
1069 	}
1070 };
1071 
1072 static const struct camss_subdev_resources csid_res_8250[] = {
1073 	/* CSID0 */
1074 	{
1075 		.regulators = {},
1076 		.clock = { "vfe0_csid", "vfe0_cphy_rx", "vfe0", "vfe0_areg", "vfe0_ahb" },
1077 		.clock_rate = { { 400000000 },
1078 				{ 400000000 },
1079 				{ 350000000, 475000000, 576000000, 720000000 },
1080 				{ 100000000, 200000000, 300000000, 400000000 },
1081 				{ 0 } },
1082 		.reg = { "csid0" },
1083 		.interrupt = { "csid0" },
1084 		.csid = {
1085 			.hw_ops = &csid_ops_gen2,
1086 			.parent_dev_ops = &vfe_parent_dev_ops,
1087 			.formats = &csid_formats_gen2
1088 		}
1089 	},
1090 	/* CSID1 */
1091 	{
1092 		.regulators = {},
1093 		.clock = { "vfe1_csid", "vfe1_cphy_rx", "vfe1", "vfe1_areg", "vfe1_ahb" },
1094 		.clock_rate = { { 400000000 },
1095 				{ 400000000 },
1096 				{ 350000000, 475000000, 576000000, 720000000 },
1097 				{ 100000000, 200000000, 300000000, 400000000 },
1098 				{ 0 } },
1099 		.reg = { "csid1" },
1100 		.interrupt = { "csid1" },
1101 		.csid = {
1102 			.hw_ops = &csid_ops_gen2,
1103 			.parent_dev_ops = &vfe_parent_dev_ops,
1104 			.formats = &csid_formats_gen2
1105 		}
1106 	},
1107 	/* CSID2 */
1108 	{
1109 		.regulators = {},
1110 		.clock = { "vfe_lite_csid", "vfe_lite_cphy_rx", "vfe_lite",  "vfe_lite_ahb" },
1111 		.clock_rate = { { 400000000 },
1112 				{ 400000000 },
1113 				{ 400000000, 480000000 },
1114 				{ 0 } },
1115 		.reg = { "csid2" },
1116 		.interrupt = { "csid2" },
1117 		.csid = {
1118 			.is_lite = true,
1119 			.hw_ops = &csid_ops_gen2,
1120 			.parent_dev_ops = &vfe_parent_dev_ops,
1121 			.formats = &csid_formats_gen2
1122 		}
1123 	},
1124 	/* CSID3 */
1125 	{
1126 		.regulators = {},
1127 		.clock = { "vfe_lite_csid", "vfe_lite_cphy_rx", "vfe_lite",  "vfe_lite_ahb" },
1128 		.clock_rate = { { 400000000 },
1129 				{ 400000000 },
1130 				{ 400000000, 480000000 },
1131 				{ 0 } },
1132 		.reg = { "csid3" },
1133 		.interrupt = { "csid3" },
1134 		.csid = {
1135 			.is_lite = true,
1136 			.hw_ops = &csid_ops_gen2,
1137 			.parent_dev_ops = &vfe_parent_dev_ops,
1138 			.formats = &csid_formats_gen2
1139 		}
1140 	}
1141 };
1142 
1143 static const struct camss_subdev_resources vfe_res_8250[] = {
1144 	/* VFE0 */
1145 	{
1146 		.regulators = {},
1147 		.clock = { "camnoc_axi_src", "slow_ahb_src", "cpas_ahb",
1148 			   "camnoc_axi", "vfe0_ahb", "vfe0_areg", "vfe0",
1149 			   "vfe0_axi", "cam_hf_axi" },
1150 		.clock_rate = { { 19200000, 300000000, 400000000, 480000000 },
1151 				{ 19200000, 80000000 },
1152 				{ 19200000 },
1153 				{ 0 },
1154 				{ 0 },
1155 				{ 100000000, 200000000, 300000000, 400000000 },
1156 				{ 350000000, 475000000, 576000000, 720000000 },
1157 				{ 0 },
1158 				{ 0 } },
1159 		.reg = { "vfe0" },
1160 		.interrupt = { "vfe0" },
1161 		.vfe = {
1162 			.line_num = 3,
1163 			.has_pd = true,
1164 			.pd_name = "ife0",
1165 			.hw_ops = &vfe_ops_480,
1166 			.formats_rdi = &vfe_formats_rdi_845,
1167 			.formats_pix = &vfe_formats_pix_845
1168 		}
1169 	},
1170 	/* VFE1 */
1171 	{
1172 		.regulators = {},
1173 		.clock = { "camnoc_axi_src", "slow_ahb_src", "cpas_ahb",
1174 			   "camnoc_axi", "vfe1_ahb", "vfe1_areg", "vfe1",
1175 			   "vfe1_axi", "cam_hf_axi" },
1176 		.clock_rate = { { 19200000, 300000000, 400000000, 480000000 },
1177 				{ 19200000, 80000000 },
1178 				{ 19200000 },
1179 				{ 0 },
1180 				{ 0 },
1181 				{ 100000000, 200000000, 300000000, 400000000 },
1182 				{ 350000000, 475000000, 576000000, 720000000 },
1183 				{ 0 },
1184 				{ 0 } },
1185 		.reg = { "vfe1" },
1186 		.interrupt = { "vfe1" },
1187 		.vfe = {
1188 			.line_num = 3,
1189 			.has_pd = true,
1190 			.pd_name = "ife1",
1191 			.hw_ops = &vfe_ops_480,
1192 			.formats_rdi = &vfe_formats_rdi_845,
1193 			.formats_pix = &vfe_formats_pix_845
1194 		}
1195 	},
1196 	/* VFE2 (lite) */
1197 	{
1198 		.regulators = {},
1199 		.clock = { "camnoc_axi_src", "slow_ahb_src", "cpas_ahb",
1200 			   "camnoc_axi", "vfe_lite_ahb", "vfe_lite_axi",
1201 			   "vfe_lite", "cam_hf_axi" },
1202 		.clock_rate = { { 19200000, 300000000, 400000000, 480000000 },
1203 				{ 19200000, 80000000 },
1204 				{ 19200000 },
1205 				{ 0 },
1206 				{ 0 },
1207 				{ 0 },
1208 				{ 400000000, 480000000 },
1209 				{ 0 } },
1210 		.reg = { "vfe_lite0" },
1211 		.interrupt = { "vfe_lite0" },
1212 		.vfe = {
1213 			.is_lite = true,
1214 			.line_num = 4,
1215 			.hw_ops = &vfe_ops_480,
1216 			.formats_rdi = &vfe_formats_rdi_845,
1217 			.formats_pix = &vfe_formats_pix_845
1218 		}
1219 	},
1220 	/* VFE3 (lite) */
1221 	{
1222 		.regulators = {},
1223 		.clock = { "camnoc_axi_src", "slow_ahb_src", "cpas_ahb",
1224 			   "camnoc_axi", "vfe_lite_ahb", "vfe_lite_axi",
1225 			   "vfe_lite", "cam_hf_axi" },
1226 		.clock_rate = { { 19200000, 300000000, 400000000, 480000000 },
1227 				{ 19200000, 80000000 },
1228 				{ 19200000 },
1229 				{ 0 },
1230 				{ 0 },
1231 				{ 0 },
1232 				{ 400000000, 480000000 },
1233 				{ 0 } },
1234 		.reg = { "vfe_lite1" },
1235 		.interrupt = { "vfe_lite1" },
1236 		.vfe = {
1237 			.is_lite = true,
1238 			.line_num = 4,
1239 			.hw_ops = &vfe_ops_480,
1240 			.formats_rdi = &vfe_formats_rdi_845,
1241 			.formats_pix = &vfe_formats_pix_845
1242 		}
1243 	},
1244 };
1245 
1246 static const struct resources_icc icc_res_sm8250[] = {
1247 	{
1248 		.name = "cam_ahb",
1249 		.icc_bw_tbl.avg = 38400,
1250 		.icc_bw_tbl.peak = 76800,
1251 	},
1252 	{
1253 		.name = "cam_hf_0_mnoc",
1254 		.icc_bw_tbl.avg = 2097152,
1255 		.icc_bw_tbl.peak = 2097152,
1256 	},
1257 	{
1258 		.name = "cam_sf_0_mnoc",
1259 		.icc_bw_tbl.avg = 0,
1260 		.icc_bw_tbl.peak = 2097152,
1261 	},
1262 	{
1263 		.name = "cam_sf_icp_mnoc",
1264 		.icc_bw_tbl.avg = 2097152,
1265 		.icc_bw_tbl.peak = 2097152,
1266 	},
1267 };
1268 
1269 static const struct camss_subdev_resources csiphy_res_sc8280xp[] = {
1270 	/* CSIPHY0 */
1271 	{
1272 		.regulators = {},
1273 		.clock = { "csiphy0", "csiphy0_timer" },
1274 		.clock_rate = { { 400000000 },
1275 				{ 300000000 } },
1276 		.reg = { "csiphy0" },
1277 		.interrupt = { "csiphy0" },
1278 		.csiphy = {
1279 			.hw_ops = &csiphy_ops_3ph_1_0,
1280 			.formats = &csiphy_formats_sdm845
1281 		}
1282 	},
1283 	/* CSIPHY1 */
1284 	{
1285 		.regulators = {},
1286 		.clock = { "csiphy1", "csiphy1_timer" },
1287 		.clock_rate = { { 400000000 },
1288 				{ 300000000 } },
1289 		.reg = { "csiphy1" },
1290 		.interrupt = { "csiphy1" },
1291 		.csiphy = {
1292 			.hw_ops = &csiphy_ops_3ph_1_0,
1293 			.formats = &csiphy_formats_sdm845
1294 		}
1295 	},
1296 	/* CSIPHY2 */
1297 	{
1298 		.regulators = {},
1299 		.clock = { "csiphy2", "csiphy2_timer" },
1300 		.clock_rate = { { 400000000 },
1301 				{ 300000000 } },
1302 		.reg = { "csiphy2" },
1303 		.interrupt = { "csiphy2" },
1304 		.csiphy = {
1305 			.hw_ops = &csiphy_ops_3ph_1_0,
1306 			.formats = &csiphy_formats_sdm845
1307 		}
1308 	},
1309 	/* CSIPHY3 */
1310 	{
1311 		.regulators = {},
1312 		.clock = { "csiphy3", "csiphy3_timer" },
1313 		.clock_rate = { { 400000000 },
1314 				{ 300000000 } },
1315 		.reg = { "csiphy3" },
1316 		.interrupt = { "csiphy3" },
1317 		.csiphy = {
1318 			.hw_ops = &csiphy_ops_3ph_1_0,
1319 			.formats = &csiphy_formats_sdm845
1320 		}
1321 	},
1322 };
1323 
1324 static const struct camss_subdev_resources csid_res_sc8280xp[] = {
1325 	/* CSID0 */
1326 	{
1327 		.regulators = { "vdda-phy", "vdda-pll" },
1328 		.clock = { "vfe0_csid", "vfe0_cphy_rx", "vfe0", "vfe0_axi" },
1329 		.clock_rate = { { 400000000, 480000000, 600000000 },
1330 				{ 0 },
1331 				{ 0 },
1332 				{ 0 } },
1333 		.reg = { "csid0" },
1334 		.interrupt = { "csid0" },
1335 		.csid = {
1336 			.hw_ops = &csid_ops_gen2,
1337 			.parent_dev_ops = &vfe_parent_dev_ops,
1338 			.formats = &csid_formats_gen2
1339 		}
1340 	},
1341 	/* CSID1 */
1342 	{
1343 		.regulators = { "vdda-phy", "vdda-pll" },
1344 		.clock = { "vfe1_csid", "vfe1_cphy_rx", "vfe1", "vfe1_axi" },
1345 		.clock_rate = { { 400000000, 480000000, 600000000 },
1346 				{ 0 },
1347 				{ 0 },
1348 				{ 0 } },
1349 		.reg = { "csid1" },
1350 		.interrupt = { "csid1" },
1351 		.csid = {
1352 			.hw_ops = &csid_ops_gen2,
1353 			.parent_dev_ops = &vfe_parent_dev_ops,
1354 			.formats = &csid_formats_gen2
1355 		}
1356 	},
1357 	/* CSID2 */
1358 	{
1359 		.regulators = { "vdda-phy", "vdda-pll" },
1360 		.clock = { "vfe2_csid", "vfe2_cphy_rx", "vfe2", "vfe2_axi" },
1361 		.clock_rate = { { 400000000, 480000000, 600000000 },
1362 				{ 0 },
1363 				{ 0 },
1364 				{ 0 } },
1365 		.reg = { "csid2" },
1366 		.interrupt = { "csid2" },
1367 		.csid = {
1368 			.hw_ops = &csid_ops_gen2,
1369 			.parent_dev_ops = &vfe_parent_dev_ops,
1370 			.formats = &csid_formats_gen2
1371 		}
1372 	},
1373 	/* CSID3 */
1374 	{
1375 		.regulators = { "vdda-phy", "vdda-pll" },
1376 		.clock = { "vfe3_csid", "vfe3_cphy_rx", "vfe3", "vfe3_axi" },
1377 		.clock_rate = { { 400000000, 480000000, 600000000 },
1378 				{ 0 },
1379 				{ 0 },
1380 				{ 0 } },
1381 		.reg = { "csid3" },
1382 		.interrupt = { "csid3" },
1383 		.csid = {
1384 			.hw_ops = &csid_ops_gen2,
1385 			.parent_dev_ops = &vfe_parent_dev_ops,
1386 			.formats = &csid_formats_gen2
1387 		}
1388 	},
1389 	/* CSID_LITE0 */
1390 	{
1391 		.regulators = { "vdda-phy", "vdda-pll" },
1392 		.clock = { "vfe_lite0_csid", "vfe_lite0_cphy_rx", "vfe_lite0" },
1393 		.clock_rate = { { 400000000, 480000000, 600000000 },
1394 				{ 0 },
1395 				{ 0 }, },
1396 		.reg = { "csid0_lite" },
1397 		.interrupt = { "csid0_lite" },
1398 		.csid = {
1399 			.is_lite = true,
1400 			.hw_ops = &csid_ops_gen2,
1401 			.parent_dev_ops = &vfe_parent_dev_ops,
1402 			.formats = &csid_formats_gen2
1403 		}
1404 	},
1405 	/* CSID_LITE1 */
1406 	{
1407 		.regulators = { "vdda-phy", "vdda-pll" },
1408 		.clock = { "vfe_lite1_csid", "vfe_lite1_cphy_rx", "vfe_lite1" },
1409 		.clock_rate = { { 400000000, 480000000, 600000000 },
1410 				{ 0 },
1411 				{ 0 }, },
1412 		.reg = { "csid1_lite" },
1413 		.interrupt = { "csid1_lite" },
1414 		.csid = {
1415 			.is_lite = true,
1416 			.hw_ops = &csid_ops_gen2,
1417 			.parent_dev_ops = &vfe_parent_dev_ops,
1418 			.formats = &csid_formats_gen2
1419 		}
1420 	},
1421 	/* CSID_LITE2 */
1422 	{
1423 		.regulators = { "vdda-phy", "vdda-pll" },
1424 		.clock = { "vfe_lite2_csid", "vfe_lite2_cphy_rx", "vfe_lite2" },
1425 		.clock_rate = { { 400000000, 480000000, 600000000 },
1426 				{ 0 },
1427 				{ 0 }, },
1428 		.reg = { "csid2_lite" },
1429 		.interrupt = { "csid2_lite" },
1430 		.csid = {
1431 			.is_lite = true,
1432 			.hw_ops = &csid_ops_gen2,
1433 			.parent_dev_ops = &vfe_parent_dev_ops,
1434 			.formats = &csid_formats_gen2
1435 		}
1436 	},
1437 	/* CSID_LITE3 */
1438 	{
1439 		.regulators = { "vdda-phy", "vdda-pll" },
1440 		.clock = { "vfe_lite3_csid", "vfe_lite3_cphy_rx", "vfe_lite3" },
1441 		.clock_rate = { { 400000000, 480000000, 600000000 },
1442 				{ 0 },
1443 				{ 0 }, },
1444 		.reg = { "csid3_lite" },
1445 		.interrupt = { "csid3_lite" },
1446 		.csid = {
1447 			.is_lite = true,
1448 			.hw_ops = &csid_ops_gen2,
1449 			.parent_dev_ops = &vfe_parent_dev_ops,
1450 			.formats = &csid_formats_gen2
1451 		}
1452 	}
1453 };
1454 
1455 static const struct camss_subdev_resources vfe_res_sc8280xp[] = {
1456 	/* VFE0 */
1457 	{
1458 		.regulators = {},
1459 		.clock = { "gcc_axi_hf", "gcc_axi_sf", "cpas_ahb", "camnoc_axi", "vfe0", "vfe0_axi" },
1460 		.clock_rate = { { 0 },
1461 				{ 0 },
1462 				{ 19200000, 80000000},
1463 				{ 19200000, 150000000, 266666667, 320000000, 400000000, 480000000 },
1464 				{ 400000000, 558000000, 637000000, 760000000 },
1465 				{ 0 }, },
1466 		.reg = { "vfe0" },
1467 		.interrupt = { "vfe0" },
1468 		.vfe = {
1469 			.line_num = 4,
1470 			.pd_name = "ife0",
1471 			.hw_ops = &vfe_ops_170,
1472 			.formats_rdi = &vfe_formats_rdi_845,
1473 			.formats_pix = &vfe_formats_pix_845
1474 		}
1475 	},
1476 	/* VFE1 */
1477 	{
1478 		.regulators = {},
1479 		.clock = { "gcc_axi_hf", "gcc_axi_sf", "cpas_ahb", "camnoc_axi", "vfe1", "vfe1_axi" },
1480 		.clock_rate = { { 0 },
1481 				{ 0 },
1482 				{ 19200000, 80000000},
1483 				{ 19200000, 150000000, 266666667, 320000000, 400000000, 480000000 },
1484 				{ 400000000, 558000000, 637000000, 760000000 },
1485 				{ 0 }, },
1486 		.reg = { "vfe1" },
1487 		.interrupt = { "vfe1" },
1488 		.vfe = {
1489 			.line_num = 4,
1490 			.pd_name = "ife1",
1491 			.hw_ops = &vfe_ops_170,
1492 			.formats_rdi = &vfe_formats_rdi_845,
1493 			.formats_pix = &vfe_formats_pix_845
1494 		}
1495 	},
1496 	/* VFE2 */
1497 	{
1498 		.regulators = {},
1499 		.clock = { "gcc_axi_hf", "gcc_axi_sf", "cpas_ahb", "camnoc_axi", "vfe2", "vfe2_axi" },
1500 		.clock_rate = { { 0 },
1501 				{ 0 },
1502 				{ 19200000, 80000000},
1503 				{ 19200000, 150000000, 266666667, 320000000, 400000000, 480000000 },
1504 				{ 400000000, 558000000, 637000000, 760000000 },
1505 				{ 0 }, },
1506 		.reg = { "vfe2" },
1507 		.interrupt = { "vfe2" },
1508 		.vfe = {
1509 			.line_num = 4,
1510 			.pd_name = "ife2",
1511 			.hw_ops = &vfe_ops_170,
1512 			.formats_rdi = &vfe_formats_rdi_845,
1513 			.formats_pix = &vfe_formats_pix_845
1514 		}
1515 	},
1516 	/* VFE3 */
1517 	{
1518 		.regulators = {},
1519 		.clock = { "gcc_axi_hf", "gcc_axi_sf", "cpas_ahb", "camnoc_axi", "vfe3", "vfe3_axi" },
1520 		.clock_rate = { { 0 },
1521 				{ 0 },
1522 				{ 19200000, 80000000},
1523 				{ 19200000, 150000000, 266666667, 320000000, 400000000, 480000000 },
1524 				{ 400000000, 558000000, 637000000, 760000000 },
1525 				{ 0 }, },
1526 		.reg = { "vfe3" },
1527 		.interrupt = { "vfe3" },
1528 		.vfe = {
1529 			.line_num = 4,
1530 			.pd_name = "ife3",
1531 			.hw_ops = &vfe_ops_170,
1532 			.formats_rdi = &vfe_formats_rdi_845,
1533 			.formats_pix = &vfe_formats_pix_845
1534 		}
1535 	},
1536 	/* VFE_LITE_0 */
1537 	{
1538 		.regulators = {},
1539 		.clock = { "gcc_axi_hf", "gcc_axi_sf", "cpas_ahb", "camnoc_axi", "vfe_lite0" },
1540 		.clock_rate = { { 0 },
1541 				{ 0 },
1542 				{ 19200000, 80000000},
1543 				{ 19200000, 150000000, 266666667, 320000000, 400000000, 480000000 },
1544 				{ 320000000, 400000000, 480000000, 600000000 }, },
1545 		.reg = { "vfe_lite0" },
1546 		.interrupt = { "vfe_lite0" },
1547 		.vfe = {
1548 			.is_lite = true,
1549 			.line_num = 4,
1550 			.hw_ops = &vfe_ops_170,
1551 			.formats_rdi = &vfe_formats_rdi_845,
1552 			.formats_pix = &vfe_formats_pix_845
1553 		}
1554 	},
1555 	/* VFE_LITE_1 */
1556 	{
1557 		.regulators = {},
1558 		.clock = { "gcc_axi_hf", "gcc_axi_sf", "cpas_ahb", "camnoc_axi", "vfe_lite1" },
1559 		.clock_rate = { { 0 },
1560 				{ 0 },
1561 				{ 19200000, 80000000},
1562 				{ 19200000, 150000000, 266666667, 320000000, 400000000, 480000000 },
1563 				{ 320000000, 400000000, 480000000, 600000000 }, },
1564 		.reg = { "vfe_lite1" },
1565 		.interrupt = { "vfe_lite1" },
1566 		.vfe = {
1567 			.is_lite = true,
1568 			.line_num = 4,
1569 			.hw_ops = &vfe_ops_170,
1570 			.formats_rdi = &vfe_formats_rdi_845,
1571 			.formats_pix = &vfe_formats_pix_845
1572 		}
1573 	},
1574 	/* VFE_LITE_2 */
1575 	{
1576 		.regulators = {},
1577 		.clock = { "gcc_axi_hf", "gcc_axi_sf", "cpas_ahb", "camnoc_axi", "vfe_lite2" },
1578 		.clock_rate = { { 0 },
1579 				{ 0 },
1580 				{ 19200000, 80000000},
1581 				{ 19200000, 150000000, 266666667, 320000000, 400000000, 480000000 },
1582 				{ 320000000, 400000000, 480000000, 600000000, }, },
1583 		.reg = { "vfe_lite2" },
1584 		.interrupt = { "vfe_lite2" },
1585 		.vfe = {
1586 			.is_lite = true,
1587 			.line_num = 4,
1588 			.hw_ops = &vfe_ops_170,
1589 			.formats_rdi = &vfe_formats_rdi_845,
1590 			.formats_pix = &vfe_formats_pix_845
1591 		}
1592 	},
1593 	/* VFE_LITE_3 */
1594 	{
1595 		.regulators = {},
1596 		.clock = { "gcc_axi_hf", "gcc_axi_sf", "cpas_ahb", "camnoc_axi", "vfe_lite3" },
1597 		.clock_rate = { { 0 },
1598 				{ 0 },
1599 				{ 19200000, 80000000},
1600 				{ 19200000, 150000000, 266666667, 320000000, 400000000, 480000000 },
1601 				{ 320000000, 400000000, 480000000, 600000000 }, },
1602 		.reg = { "vfe_lite3" },
1603 		.interrupt = { "vfe_lite3" },
1604 		.vfe = {
1605 			.is_lite = true,
1606 			.line_num = 4,
1607 			.hw_ops = &vfe_ops_170,
1608 			.formats_rdi = &vfe_formats_rdi_845,
1609 			.formats_pix = &vfe_formats_pix_845
1610 		}
1611 	},
1612 };
1613 
1614 static const struct resources_icc icc_res_sc8280xp[] = {
1615 	{
1616 		.name = "cam_ahb",
1617 		.icc_bw_tbl.avg = 150000,
1618 		.icc_bw_tbl.peak = 300000,
1619 	},
1620 	{
1621 		.name = "cam_hf_mnoc",
1622 		.icc_bw_tbl.avg = 2097152,
1623 		.icc_bw_tbl.peak = 2097152,
1624 	},
1625 	{
1626 		.name = "cam_sf_mnoc",
1627 		.icc_bw_tbl.avg = 2097152,
1628 		.icc_bw_tbl.peak = 2097152,
1629 	},
1630 	{
1631 		.name = "cam_sf_icp_mnoc",
1632 		.icc_bw_tbl.avg = 2097152,
1633 		.icc_bw_tbl.peak = 2097152,
1634 	},
1635 };
1636 
1637 /*
1638  * camss_add_clock_margin - Add margin to clock frequency rate
1639  * @rate: Clock frequency rate
1640  *
1641  * When making calculations with physical clock frequency values
1642  * some safety margin must be added. Add it.
1643  */
1644 inline void camss_add_clock_margin(u64 *rate)
1645 {
1646 	*rate *= CAMSS_CLOCK_MARGIN_NUMERATOR;
1647 	*rate = div_u64(*rate, CAMSS_CLOCK_MARGIN_DENOMINATOR);
1648 }
1649 
1650 /*
1651  * camss_enable_clocks - Enable multiple clocks
1652  * @nclocks: Number of clocks in clock array
1653  * @clock: Clock array
1654  * @dev: Device
1655  *
1656  * Return 0 on success or a negative error code otherwise
1657  */
1658 int camss_enable_clocks(int nclocks, struct camss_clock *clock,
1659 			struct device *dev)
1660 {
1661 	int ret;
1662 	int i;
1663 
1664 	for (i = 0; i < nclocks; i++) {
1665 		ret = clk_prepare_enable(clock[i].clk);
1666 		if (ret) {
1667 			dev_err(dev, "clock enable failed: %d\n", ret);
1668 			goto error;
1669 		}
1670 	}
1671 
1672 	return 0;
1673 
1674 error:
1675 	for (i--; i >= 0; i--)
1676 		clk_disable_unprepare(clock[i].clk);
1677 
1678 	return ret;
1679 }
1680 
1681 /*
1682  * camss_disable_clocks - Disable multiple clocks
1683  * @nclocks: Number of clocks in clock array
1684  * @clock: Clock array
1685  */
1686 void camss_disable_clocks(int nclocks, struct camss_clock *clock)
1687 {
1688 	int i;
1689 
1690 	for (i = nclocks - 1; i >= 0; i--)
1691 		clk_disable_unprepare(clock[i].clk);
1692 }
1693 
1694 /*
1695  * camss_find_sensor - Find a linked media entity which represents a sensor
1696  * @entity: Media entity to start searching from
1697  *
1698  * Return a pointer to sensor media entity or NULL if not found
1699  */
1700 struct media_entity *camss_find_sensor(struct media_entity *entity)
1701 {
1702 	struct media_pad *pad;
1703 
1704 	while (1) {
1705 		pad = &entity->pads[0];
1706 		if (!(pad->flags & MEDIA_PAD_FL_SINK))
1707 			return NULL;
1708 
1709 		pad = media_pad_remote_pad_first(pad);
1710 		if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
1711 			return NULL;
1712 
1713 		entity = pad->entity;
1714 
1715 		if (entity->function == MEDIA_ENT_F_CAM_SENSOR)
1716 			return entity;
1717 	}
1718 }
1719 
1720 /**
1721  * camss_get_link_freq - Get link frequency from sensor
1722  * @entity: Media entity in the current pipeline
1723  * @bpp: Number of bits per pixel for the current format
1724  * @lanes: Number of lanes in the link to the sensor
1725  *
1726  * Return link frequency on success or a negative error code otherwise
1727  */
1728 s64 camss_get_link_freq(struct media_entity *entity, unsigned int bpp,
1729 			unsigned int lanes)
1730 {
1731 	struct media_entity *sensor;
1732 	struct v4l2_subdev *subdev;
1733 
1734 	sensor = camss_find_sensor(entity);
1735 	if (!sensor)
1736 		return -ENODEV;
1737 
1738 	subdev = media_entity_to_v4l2_subdev(sensor);
1739 
1740 	return v4l2_get_link_freq(subdev->ctrl_handler, bpp, 2 * lanes);
1741 }
1742 
1743 /*
1744  * camss_get_pixel_clock - Get pixel clock rate from sensor
1745  * @entity: Media entity in the current pipeline
1746  * @pixel_clock: Received pixel clock value
1747  *
1748  * Return 0 on success or a negative error code otherwise
1749  */
1750 int camss_get_pixel_clock(struct media_entity *entity, u64 *pixel_clock)
1751 {
1752 	struct media_entity *sensor;
1753 	struct v4l2_subdev *subdev;
1754 	struct v4l2_ctrl *ctrl;
1755 
1756 	sensor = camss_find_sensor(entity);
1757 	if (!sensor)
1758 		return -ENODEV;
1759 
1760 	subdev = media_entity_to_v4l2_subdev(sensor);
1761 
1762 	ctrl = v4l2_ctrl_find(subdev->ctrl_handler, V4L2_CID_PIXEL_RATE);
1763 
1764 	if (!ctrl)
1765 		return -EINVAL;
1766 
1767 	*pixel_clock = v4l2_ctrl_g_ctrl_int64(ctrl);
1768 
1769 	return 0;
1770 }
1771 
1772 int camss_pm_domain_on(struct camss *camss, int id)
1773 {
1774 	int ret = 0;
1775 
1776 	if (id < camss->res->vfe_num) {
1777 		struct vfe_device *vfe = &camss->vfe[id];
1778 
1779 		ret = vfe->res->hw_ops->pm_domain_on(vfe);
1780 	}
1781 
1782 	return ret;
1783 }
1784 
1785 void camss_pm_domain_off(struct camss *camss, int id)
1786 {
1787 	if (id < camss->res->vfe_num) {
1788 		struct vfe_device *vfe = &camss->vfe[id];
1789 
1790 		vfe->res->hw_ops->pm_domain_off(vfe);
1791 	}
1792 }
1793 
1794 static int vfe_parent_dev_ops_get(struct camss *camss, int id)
1795 {
1796 	int ret = -EINVAL;
1797 
1798 	if (id < camss->res->vfe_num) {
1799 		struct vfe_device *vfe = &camss->vfe[id];
1800 
1801 		ret = vfe_get(vfe);
1802 	}
1803 
1804 	return ret;
1805 }
1806 
1807 static int vfe_parent_dev_ops_put(struct camss *camss, int id)
1808 {
1809 	if (id < camss->res->vfe_num) {
1810 		struct vfe_device *vfe = &camss->vfe[id];
1811 
1812 		vfe_put(vfe);
1813 	}
1814 
1815 	return 0;
1816 }
1817 
1818 static void __iomem
1819 *vfe_parent_dev_ops_get_base_address(struct camss *camss, int id)
1820 {
1821 	if (id < camss->res->vfe_num) {
1822 		struct vfe_device *vfe = &camss->vfe[id];
1823 
1824 		return vfe->base;
1825 	}
1826 
1827 	return NULL;
1828 }
1829 
1830 static const struct parent_dev_ops vfe_parent_dev_ops = {
1831 	.get = vfe_parent_dev_ops_get,
1832 	.put = vfe_parent_dev_ops_put,
1833 	.get_base_address = vfe_parent_dev_ops_get_base_address
1834 };
1835 
1836 /*
1837  * camss_of_parse_endpoint_node - Parse port endpoint node
1838  * @dev: Device
1839  * @node: Device node to be parsed
1840  * @csd: Parsed data from port endpoint node
1841  *
1842  * Return 0 on success or a negative error code on failure
1843  */
1844 static int camss_of_parse_endpoint_node(struct device *dev,
1845 					struct device_node *node,
1846 					struct camss_async_subdev *csd)
1847 {
1848 	struct csiphy_lanes_cfg *lncfg = &csd->interface.csi2.lane_cfg;
1849 	struct v4l2_mbus_config_mipi_csi2 *mipi_csi2;
1850 	struct v4l2_fwnode_endpoint vep = { { 0 } };
1851 	unsigned int i;
1852 	int ret;
1853 
1854 	ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(node), &vep);
1855 	if (ret)
1856 		return ret;
1857 
1858 	csd->interface.csiphy_id = vep.base.port;
1859 
1860 	mipi_csi2 = &vep.bus.mipi_csi2;
1861 	lncfg->clk.pos = mipi_csi2->clock_lane;
1862 	lncfg->clk.pol = mipi_csi2->lane_polarities[0];
1863 	lncfg->num_data = mipi_csi2->num_data_lanes;
1864 
1865 	lncfg->data = devm_kcalloc(dev,
1866 				   lncfg->num_data, sizeof(*lncfg->data),
1867 				   GFP_KERNEL);
1868 	if (!lncfg->data)
1869 		return -ENOMEM;
1870 
1871 	for (i = 0; i < lncfg->num_data; i++) {
1872 		lncfg->data[i].pos = mipi_csi2->data_lanes[i];
1873 		lncfg->data[i].pol = mipi_csi2->lane_polarities[i + 1];
1874 	}
1875 
1876 	return 0;
1877 }
1878 
1879 /*
1880  * camss_of_parse_ports - Parse ports node
1881  * @dev: Device
1882  * @notifier: v4l2_device notifier data
1883  *
1884  * Return number of "port" nodes found in "ports" node
1885  */
1886 static int camss_of_parse_ports(struct camss *camss)
1887 {
1888 	struct device *dev = camss->dev;
1889 	struct device_node *node = NULL;
1890 	struct device_node *remote = NULL;
1891 	int ret, num_subdevs = 0;
1892 
1893 	for_each_endpoint_of_node(dev->of_node, node) {
1894 		struct camss_async_subdev *csd;
1895 
1896 		if (!of_device_is_available(node))
1897 			continue;
1898 
1899 		remote = of_graph_get_remote_port_parent(node);
1900 		if (!remote) {
1901 			dev_err(dev, "Cannot get remote parent\n");
1902 			ret = -EINVAL;
1903 			goto err_cleanup;
1904 		}
1905 
1906 		csd = v4l2_async_nf_add_fwnode(&camss->notifier,
1907 					       of_fwnode_handle(remote),
1908 					       struct camss_async_subdev);
1909 		of_node_put(remote);
1910 		if (IS_ERR(csd)) {
1911 			ret = PTR_ERR(csd);
1912 			goto err_cleanup;
1913 		}
1914 
1915 		ret = camss_of_parse_endpoint_node(dev, node, csd);
1916 		if (ret < 0)
1917 			goto err_cleanup;
1918 
1919 		num_subdevs++;
1920 	}
1921 
1922 	return num_subdevs;
1923 
1924 err_cleanup:
1925 	of_node_put(node);
1926 	return ret;
1927 }
1928 
1929 /*
1930  * camss_init_subdevices - Initialize subdev structures and resources
1931  * @camss: CAMSS device
1932  *
1933  * Return 0 on success or a negative error code on failure
1934  */
1935 static int camss_init_subdevices(struct camss *camss)
1936 {
1937 	struct platform_device *pdev = to_platform_device(camss->dev);
1938 	const struct camss_resources *res = camss->res;
1939 	unsigned int i;
1940 	int ret;
1941 
1942 	for (i = 0; i < camss->res->csiphy_num; i++) {
1943 		ret = msm_csiphy_subdev_init(camss, &camss->csiphy[i],
1944 					     &res->csiphy_res[i], i);
1945 		if (ret < 0) {
1946 			dev_err(camss->dev,
1947 				"Failed to init csiphy%d sub-device: %d\n",
1948 				i, ret);
1949 			return ret;
1950 		}
1951 	}
1952 
1953 	/* note: SM8250 requires VFE to be initialized before CSID */
1954 	for (i = 0; i < camss->res->vfe_num; i++) {
1955 		ret = msm_vfe_subdev_init(camss, &camss->vfe[i],
1956 					  &res->vfe_res[i], i);
1957 		if (ret < 0) {
1958 			dev_err(camss->dev,
1959 				"Fail to init vfe%d sub-device: %d\n", i, ret);
1960 			return ret;
1961 		}
1962 	}
1963 
1964 	/* Get optional CSID wrapper regs shared between CSID devices */
1965 	if (res->csid_wrapper_res) {
1966 		char *reg = res->csid_wrapper_res->reg;
1967 		void __iomem *base;
1968 
1969 		base = devm_platform_ioremap_resource_byname(pdev, reg);
1970 		if (IS_ERR(base))
1971 			return PTR_ERR(base);
1972 		camss->csid_wrapper_base = base;
1973 	}
1974 
1975 	for (i = 0; i < camss->res->csid_num; i++) {
1976 		ret = msm_csid_subdev_init(camss, &camss->csid[i],
1977 					   &res->csid_res[i], i);
1978 		if (ret < 0) {
1979 			dev_err(camss->dev,
1980 				"Failed to init csid%d sub-device: %d\n",
1981 				i, ret);
1982 			return ret;
1983 		}
1984 	}
1985 
1986 	ret = msm_ispif_subdev_init(camss, res->ispif_res);
1987 	if (ret < 0) {
1988 		dev_err(camss->dev, "Failed to init ispif sub-device: %d\n",
1989 		ret);
1990 		return ret;
1991 	}
1992 
1993 	return 0;
1994 }
1995 
1996 /*
1997  * camss_link_entities - Register subdev nodes and create links
1998  * @camss: CAMSS device
1999  *
2000  * Return 0 on success or a negative error code on failure
2001  */
2002 static int camss_link_entities(struct camss *camss)
2003 {
2004 	int i, j, k;
2005 	int ret;
2006 
2007 	for (i = 0; i < camss->res->csiphy_num; i++) {
2008 		for (j = 0; j < camss->res->csid_num; j++) {
2009 			ret = media_create_pad_link(&camss->csiphy[i].subdev.entity,
2010 						    MSM_CSIPHY_PAD_SRC,
2011 						    &camss->csid[j].subdev.entity,
2012 						    MSM_CSID_PAD_SINK,
2013 						    0);
2014 			if (ret < 0) {
2015 				dev_err(camss->dev,
2016 					"Failed to link %s->%s entities: %d\n",
2017 					camss->csiphy[i].subdev.entity.name,
2018 					camss->csid[j].subdev.entity.name,
2019 					ret);
2020 				return ret;
2021 			}
2022 		}
2023 	}
2024 
2025 	if (camss->ispif) {
2026 		for (i = 0; i < camss->res->csid_num; i++) {
2027 			for (j = 0; j < camss->ispif->line_num; j++) {
2028 				ret = media_create_pad_link(&camss->csid[i].subdev.entity,
2029 							    MSM_CSID_PAD_SRC,
2030 							    &camss->ispif->line[j].subdev.entity,
2031 							    MSM_ISPIF_PAD_SINK,
2032 							    0);
2033 				if (ret < 0) {
2034 					dev_err(camss->dev,
2035 						"Failed to link %s->%s entities: %d\n",
2036 						camss->csid[i].subdev.entity.name,
2037 						camss->ispif->line[j].subdev.entity.name,
2038 						ret);
2039 					return ret;
2040 				}
2041 			}
2042 		}
2043 
2044 		for (i = 0; i < camss->ispif->line_num; i++)
2045 			for (k = 0; k < camss->res->vfe_num; k++)
2046 				for (j = 0; j < camss->vfe[k].res->line_num; j++) {
2047 					struct v4l2_subdev *ispif = &camss->ispif->line[i].subdev;
2048 					struct v4l2_subdev *vfe = &camss->vfe[k].line[j].subdev;
2049 
2050 					ret = media_create_pad_link(&ispif->entity,
2051 								    MSM_ISPIF_PAD_SRC,
2052 								    &vfe->entity,
2053 								    MSM_VFE_PAD_SINK,
2054 								    0);
2055 					if (ret < 0) {
2056 						dev_err(camss->dev,
2057 							"Failed to link %s->%s entities: %d\n",
2058 							ispif->entity.name,
2059 							vfe->entity.name,
2060 							ret);
2061 						return ret;
2062 					}
2063 				}
2064 	} else {
2065 		for (i = 0; i < camss->res->csid_num; i++)
2066 			for (k = 0; k < camss->res->vfe_num; k++)
2067 				for (j = 0; j < camss->vfe[k].res->line_num; j++) {
2068 					struct v4l2_subdev *csid = &camss->csid[i].subdev;
2069 					struct v4l2_subdev *vfe = &camss->vfe[k].line[j].subdev;
2070 
2071 					ret = media_create_pad_link(&csid->entity,
2072 								    MSM_CSID_PAD_FIRST_SRC + j,
2073 								    &vfe->entity,
2074 								    MSM_VFE_PAD_SINK,
2075 								    0);
2076 					if (ret < 0) {
2077 						dev_err(camss->dev,
2078 							"Failed to link %s->%s entities: %d\n",
2079 							csid->entity.name,
2080 							vfe->entity.name,
2081 							ret);
2082 						return ret;
2083 					}
2084 				}
2085 	}
2086 
2087 	return 0;
2088 }
2089 
2090 /*
2091  * camss_register_entities - Register subdev nodes and create links
2092  * @camss: CAMSS device
2093  *
2094  * Return 0 on success or a negative error code on failure
2095  */
2096 static int camss_register_entities(struct camss *camss)
2097 {
2098 	int i;
2099 	int ret;
2100 
2101 	for (i = 0; i < camss->res->csiphy_num; i++) {
2102 		ret = msm_csiphy_register_entity(&camss->csiphy[i],
2103 						 &camss->v4l2_dev);
2104 		if (ret < 0) {
2105 			dev_err(camss->dev,
2106 				"Failed to register csiphy%d entity: %d\n",
2107 				i, ret);
2108 			goto err_reg_csiphy;
2109 		}
2110 	}
2111 
2112 	for (i = 0; i < camss->res->csid_num; i++) {
2113 		ret = msm_csid_register_entity(&camss->csid[i],
2114 					       &camss->v4l2_dev);
2115 		if (ret < 0) {
2116 			dev_err(camss->dev,
2117 				"Failed to register csid%d entity: %d\n",
2118 				i, ret);
2119 			goto err_reg_csid;
2120 		}
2121 	}
2122 
2123 	ret = msm_ispif_register_entities(camss->ispif,
2124 					  &camss->v4l2_dev);
2125 	if (ret < 0) {
2126 		dev_err(camss->dev, "Failed to register ispif entities: %d\n", ret);
2127 		goto err_reg_ispif;
2128 	}
2129 
2130 	for (i = 0; i < camss->res->vfe_num; i++) {
2131 		ret = msm_vfe_register_entities(&camss->vfe[i],
2132 						&camss->v4l2_dev);
2133 		if (ret < 0) {
2134 			dev_err(camss->dev,
2135 				"Failed to register vfe%d entities: %d\n",
2136 				i, ret);
2137 			goto err_reg_vfe;
2138 		}
2139 	}
2140 
2141 	return 0;
2142 
2143 err_reg_vfe:
2144 	for (i--; i >= 0; i--)
2145 		msm_vfe_unregister_entities(&camss->vfe[i]);
2146 
2147 err_reg_ispif:
2148 	msm_ispif_unregister_entities(camss->ispif);
2149 
2150 	i = camss->res->csid_num;
2151 err_reg_csid:
2152 	for (i--; i >= 0; i--)
2153 		msm_csid_unregister_entity(&camss->csid[i]);
2154 
2155 	i = camss->res->csiphy_num;
2156 err_reg_csiphy:
2157 	for (i--; i >= 0; i--)
2158 		msm_csiphy_unregister_entity(&camss->csiphy[i]);
2159 
2160 	return ret;
2161 }
2162 
2163 /*
2164  * camss_unregister_entities - Unregister subdev nodes
2165  * @camss: CAMSS device
2166  *
2167  * Return 0 on success or a negative error code on failure
2168  */
2169 static void camss_unregister_entities(struct camss *camss)
2170 {
2171 	unsigned int i;
2172 
2173 	for (i = 0; i < camss->res->csiphy_num; i++)
2174 		msm_csiphy_unregister_entity(&camss->csiphy[i]);
2175 
2176 	for (i = 0; i < camss->res->csid_num; i++)
2177 		msm_csid_unregister_entity(&camss->csid[i]);
2178 
2179 	msm_ispif_unregister_entities(camss->ispif);
2180 
2181 	for (i = 0; i < camss->res->vfe_num; i++)
2182 		msm_vfe_unregister_entities(&camss->vfe[i]);
2183 }
2184 
2185 static int camss_subdev_notifier_bound(struct v4l2_async_notifier *async,
2186 				       struct v4l2_subdev *subdev,
2187 				       struct v4l2_async_connection *asd)
2188 {
2189 	struct camss *camss = container_of(async, struct camss, notifier);
2190 	struct camss_async_subdev *csd =
2191 		container_of(asd, struct camss_async_subdev, asd);
2192 	u8 id = csd->interface.csiphy_id;
2193 	struct csiphy_device *csiphy = &camss->csiphy[id];
2194 
2195 	csiphy->cfg.csi2 = &csd->interface.csi2;
2196 	subdev->host_priv = csiphy;
2197 
2198 	return 0;
2199 }
2200 
2201 static int camss_subdev_notifier_complete(struct v4l2_async_notifier *async)
2202 {
2203 	struct camss *camss = container_of(async, struct camss, notifier);
2204 	struct v4l2_device *v4l2_dev = &camss->v4l2_dev;
2205 	struct v4l2_subdev *sd;
2206 	int ret;
2207 
2208 	list_for_each_entry(sd, &v4l2_dev->subdevs, list) {
2209 		if (sd->host_priv) {
2210 			struct media_entity *sensor = &sd->entity;
2211 			struct csiphy_device *csiphy =
2212 					(struct csiphy_device *) sd->host_priv;
2213 			struct media_entity *input = &csiphy->subdev.entity;
2214 			unsigned int i;
2215 
2216 			for (i = 0; i < sensor->num_pads; i++) {
2217 				if (sensor->pads[i].flags & MEDIA_PAD_FL_SOURCE)
2218 					break;
2219 			}
2220 			if (i == sensor->num_pads) {
2221 				dev_err(camss->dev,
2222 					"No source pad in external entity\n");
2223 				return -EINVAL;
2224 			}
2225 
2226 			ret = media_create_pad_link(sensor, i,
2227 				input, MSM_CSIPHY_PAD_SINK,
2228 				MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED);
2229 			if (ret < 0) {
2230 				dev_err(camss->dev,
2231 					"Failed to link %s->%s entities: %d\n",
2232 					sensor->name, input->name, ret);
2233 				return ret;
2234 			}
2235 		}
2236 	}
2237 
2238 	ret = v4l2_device_register_subdev_nodes(&camss->v4l2_dev);
2239 	if (ret < 0)
2240 		return ret;
2241 
2242 	return media_device_register(&camss->media_dev);
2243 }
2244 
2245 static const struct v4l2_async_notifier_operations camss_subdev_notifier_ops = {
2246 	.bound = camss_subdev_notifier_bound,
2247 	.complete = camss_subdev_notifier_complete,
2248 };
2249 
2250 static const struct media_device_ops camss_media_ops = {
2251 	.link_notify = v4l2_pipeline_link_notify,
2252 };
2253 
2254 static int camss_configure_pd(struct camss *camss)
2255 {
2256 	const struct camss_resources *res = camss->res;
2257 	struct device *dev = camss->dev;
2258 	int vfepd_num;
2259 	int i;
2260 	int ret;
2261 
2262 	camss->genpd_num = of_count_phandle_with_args(dev->of_node,
2263 						      "power-domains",
2264 						      "#power-domain-cells");
2265 	if (camss->genpd_num < 0) {
2266 		dev_err(dev, "Power domains are not defined for camss\n");
2267 		return camss->genpd_num;
2268 	}
2269 
2270 	/*
2271 	 * If a platform device has just one power domain, then it is attached
2272 	 * at platform_probe() level, thus there shall be no need and even no
2273 	 * option to attach it again, this is the case for CAMSS on MSM8916.
2274 	 */
2275 	if (camss->genpd_num == 1)
2276 		return 0;
2277 
2278 	/* count the # of VFEs which have flagged power-domain */
2279 	for (vfepd_num = i = 0; i < camss->res->vfe_num; i++) {
2280 		if (res->vfe_res[i].vfe.has_pd)
2281 			vfepd_num++;
2282 	}
2283 
2284 	/*
2285 	 * If the number of power-domains is greater than the number of VFEs
2286 	 * then the additional power-domain is for the entire CAMSS block.
2287 	 */
2288 	if (!(camss->genpd_num > vfepd_num))
2289 		return 0;
2290 
2291 	/*
2292 	 * If a power-domain name is defined try to use it.
2293 	 * It is possible we are running a new kernel with an old dtb so
2294 	 * fallback to indexes even if a pd_name is defined but not found.
2295 	 */
2296 	if (camss->res->pd_name) {
2297 		camss->genpd = dev_pm_domain_attach_by_name(camss->dev,
2298 							    camss->res->pd_name);
2299 		if (IS_ERR(camss->genpd))
2300 			return PTR_ERR(camss->genpd);
2301 	}
2302 
2303 	if (!camss->genpd) {
2304 		/*
2305 		 * Legacy magic index. TITAN_TOP GDSC must be the last
2306 		 * item in the power-domain list.
2307 		 */
2308 		camss->genpd = dev_pm_domain_attach_by_id(camss->dev,
2309 							  camss->genpd_num - 1);
2310 		if (IS_ERR(camss->genpd))
2311 			return PTR_ERR(camss->genpd);
2312 	}
2313 
2314 	if (!camss->genpd)
2315 		return -ENODEV;
2316 
2317 	camss->genpd_link = device_link_add(camss->dev, camss->genpd,
2318 					    DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME |
2319 					    DL_FLAG_RPM_ACTIVE);
2320 	if (!camss->genpd_link) {
2321 		ret = -EINVAL;
2322 		goto fail_pm;
2323 	}
2324 
2325 	return 0;
2326 
2327 fail_pm:
2328 	dev_pm_domain_detach(camss->genpd, true);
2329 
2330 	return ret;
2331 }
2332 
2333 static int camss_icc_get(struct camss *camss)
2334 {
2335 	const struct resources_icc *icc_res;
2336 	int i;
2337 
2338 	icc_res = camss->res->icc_res;
2339 
2340 	for (i = 0; i < camss->res->icc_path_num; i++) {
2341 		camss->icc_path[i] = devm_of_icc_get(camss->dev,
2342 						     icc_res[i].name);
2343 		if (IS_ERR(camss->icc_path[i]))
2344 			return PTR_ERR(camss->icc_path[i]);
2345 	}
2346 
2347 	return 0;
2348 }
2349 
2350 static void camss_genpd_subdevice_cleanup(struct camss *camss)
2351 {
2352 	int i;
2353 
2354 	for (i = 0; i < camss->res->vfe_num; i++)
2355 		msm_vfe_genpd_cleanup(&camss->vfe[i]);
2356 }
2357 
2358 static void camss_genpd_cleanup(struct camss *camss)
2359 {
2360 	if (camss->genpd_num == 1)
2361 		return;
2362 
2363 	camss_genpd_subdevice_cleanup(camss);
2364 
2365 	if (camss->genpd_link)
2366 		device_link_del(camss->genpd_link);
2367 
2368 	dev_pm_domain_detach(camss->genpd, true);
2369 }
2370 
2371 /*
2372  * camss_probe - Probe CAMSS platform device
2373  * @pdev: Pointer to CAMSS platform device
2374  *
2375  * Return 0 on success or a negative error code on failure
2376  */
2377 static int camss_probe(struct platform_device *pdev)
2378 {
2379 	struct device *dev = &pdev->dev;
2380 	struct camss *camss;
2381 	int num_subdevs;
2382 	int ret;
2383 
2384 	camss = devm_kzalloc(dev, sizeof(*camss), GFP_KERNEL);
2385 	if (!camss)
2386 		return -ENOMEM;
2387 
2388 	camss->res = of_device_get_match_data(dev);
2389 
2390 	atomic_set(&camss->ref_count, 0);
2391 	camss->dev = dev;
2392 	platform_set_drvdata(pdev, camss);
2393 
2394 	camss->csiphy = devm_kcalloc(dev, camss->res->csiphy_num,
2395 				     sizeof(*camss->csiphy), GFP_KERNEL);
2396 	if (!camss->csiphy)
2397 		return -ENOMEM;
2398 
2399 	camss->csid = devm_kcalloc(dev, camss->res->csid_num, sizeof(*camss->csid),
2400 				   GFP_KERNEL);
2401 	if (!camss->csid)
2402 		return -ENOMEM;
2403 
2404 	if (camss->res->version == CAMSS_8x16 ||
2405 	    camss->res->version == CAMSS_8x53 ||
2406 	    camss->res->version == CAMSS_8x96) {
2407 		camss->ispif = devm_kcalloc(dev, 1, sizeof(*camss->ispif), GFP_KERNEL);
2408 		if (!camss->ispif)
2409 			return -ENOMEM;
2410 	}
2411 
2412 	camss->vfe = devm_kcalloc(dev, camss->res->vfe_num,
2413 				  sizeof(*camss->vfe), GFP_KERNEL);
2414 	if (!camss->vfe)
2415 		return -ENOMEM;
2416 
2417 	ret = camss_icc_get(camss);
2418 	if (ret < 0)
2419 		return ret;
2420 
2421 	ret = camss_configure_pd(camss);
2422 	if (ret < 0) {
2423 		dev_err(dev, "Failed to configure power domains: %d\n", ret);
2424 		return ret;
2425 	}
2426 
2427 	ret = camss_init_subdevices(camss);
2428 	if (ret < 0)
2429 		goto err_genpd_cleanup;
2430 
2431 	ret = dma_set_mask_and_coherent(dev, 0xffffffff);
2432 	if (ret)
2433 		goto err_genpd_cleanup;
2434 
2435 	camss->media_dev.dev = camss->dev;
2436 	strscpy(camss->media_dev.model, "Qualcomm Camera Subsystem",
2437 		sizeof(camss->media_dev.model));
2438 	camss->media_dev.ops = &camss_media_ops;
2439 	media_device_init(&camss->media_dev);
2440 
2441 	camss->v4l2_dev.mdev = &camss->media_dev;
2442 	ret = v4l2_device_register(camss->dev, &camss->v4l2_dev);
2443 	if (ret < 0) {
2444 		dev_err(dev, "Failed to register V4L2 device: %d\n", ret);
2445 		goto err_genpd_cleanup;
2446 	}
2447 
2448 	v4l2_async_nf_init(&camss->notifier, &camss->v4l2_dev);
2449 
2450 	pm_runtime_enable(dev);
2451 
2452 	num_subdevs = camss_of_parse_ports(camss);
2453 	if (num_subdevs < 0) {
2454 		ret = num_subdevs;
2455 		goto err_v4l2_device_unregister;
2456 	}
2457 
2458 	ret = camss_register_entities(camss);
2459 	if (ret < 0)
2460 		goto err_v4l2_device_unregister;
2461 
2462 	ret = camss->res->link_entities(camss);
2463 	if (ret < 0)
2464 		goto err_register_subdevs;
2465 
2466 	if (num_subdevs) {
2467 		camss->notifier.ops = &camss_subdev_notifier_ops;
2468 
2469 		ret = v4l2_async_nf_register(&camss->notifier);
2470 		if (ret) {
2471 			dev_err(dev,
2472 				"Failed to register async subdev nodes: %d\n",
2473 				ret);
2474 			goto err_register_subdevs;
2475 		}
2476 	} else {
2477 		ret = v4l2_device_register_subdev_nodes(&camss->v4l2_dev);
2478 		if (ret < 0) {
2479 			dev_err(dev, "Failed to register subdev nodes: %d\n",
2480 				ret);
2481 			goto err_register_subdevs;
2482 		}
2483 
2484 		ret = media_device_register(&camss->media_dev);
2485 		if (ret < 0) {
2486 			dev_err(dev, "Failed to register media device: %d\n",
2487 				ret);
2488 			goto err_register_subdevs;
2489 		}
2490 	}
2491 
2492 	return 0;
2493 
2494 err_register_subdevs:
2495 	camss_unregister_entities(camss);
2496 err_v4l2_device_unregister:
2497 	v4l2_device_unregister(&camss->v4l2_dev);
2498 	v4l2_async_nf_cleanup(&camss->notifier);
2499 	pm_runtime_disable(dev);
2500 err_genpd_cleanup:
2501 	camss_genpd_cleanup(camss);
2502 
2503 	return ret;
2504 }
2505 
2506 void camss_delete(struct camss *camss)
2507 {
2508 	v4l2_device_unregister(&camss->v4l2_dev);
2509 	media_device_unregister(&camss->media_dev);
2510 	media_device_cleanup(&camss->media_dev);
2511 
2512 	pm_runtime_disable(camss->dev);
2513 }
2514 
2515 /*
2516  * camss_remove - Remove CAMSS platform device
2517  * @pdev: Pointer to CAMSS platform device
2518  *
2519  * Always returns 0.
2520  */
2521 static void camss_remove(struct platform_device *pdev)
2522 {
2523 	struct camss *camss = platform_get_drvdata(pdev);
2524 
2525 	v4l2_async_nf_unregister(&camss->notifier);
2526 	v4l2_async_nf_cleanup(&camss->notifier);
2527 	camss_unregister_entities(camss);
2528 
2529 	if (atomic_read(&camss->ref_count) == 0)
2530 		camss_delete(camss);
2531 
2532 	camss_genpd_cleanup(camss);
2533 }
2534 
2535 static const struct camss_resources msm8916_resources = {
2536 	.version = CAMSS_8x16,
2537 	.csiphy_res = csiphy_res_8x16,
2538 	.csid_res = csid_res_8x16,
2539 	.ispif_res = &ispif_res_8x16,
2540 	.vfe_res = vfe_res_8x16,
2541 	.csiphy_num = ARRAY_SIZE(csiphy_res_8x16),
2542 	.csid_num = ARRAY_SIZE(csid_res_8x16),
2543 	.vfe_num = ARRAY_SIZE(vfe_res_8x16),
2544 	.link_entities = camss_link_entities
2545 };
2546 
2547 static const struct camss_resources msm8953_resources = {
2548 	.version = CAMSS_8x53,
2549 	.icc_res = icc_res_8x53,
2550 	.icc_path_num = ARRAY_SIZE(icc_res_8x53),
2551 	.csiphy_res = csiphy_res_8x96,
2552 	.csid_res = csid_res_8x53,
2553 	.ispif_res = &ispif_res_8x53,
2554 	.vfe_res = vfe_res_8x53,
2555 	.csiphy_num = ARRAY_SIZE(csiphy_res_8x96),
2556 	.csid_num = ARRAY_SIZE(csid_res_8x53),
2557 	.vfe_num = ARRAY_SIZE(vfe_res_8x53),
2558 	.link_entities = camss_link_entities
2559 };
2560 
2561 static const struct camss_resources msm8996_resources = {
2562 	.version = CAMSS_8x96,
2563 	.csiphy_res = csiphy_res_8x96,
2564 	.csid_res = csid_res_8x96,
2565 	.ispif_res = &ispif_res_8x96,
2566 	.vfe_res = vfe_res_8x96,
2567 	.csiphy_num = ARRAY_SIZE(csiphy_res_8x96),
2568 	.csid_num = ARRAY_SIZE(csid_res_8x96),
2569 	.vfe_num = ARRAY_SIZE(vfe_res_8x96),
2570 	.link_entities = camss_link_entities
2571 };
2572 
2573 static const struct camss_resources sdm660_resources = {
2574 	.version = CAMSS_660,
2575 	.csiphy_res = csiphy_res_660,
2576 	.csid_res = csid_res_660,
2577 	.ispif_res = &ispif_res_660,
2578 	.vfe_res = vfe_res_660,
2579 	.csiphy_num = ARRAY_SIZE(csiphy_res_660),
2580 	.csid_num = ARRAY_SIZE(csid_res_660),
2581 	.vfe_num = ARRAY_SIZE(vfe_res_660),
2582 	.link_entities = camss_link_entities
2583 };
2584 
2585 static const struct camss_resources sdm845_resources = {
2586 	.version = CAMSS_845,
2587 	.csiphy_res = csiphy_res_845,
2588 	.csid_res = csid_res_845,
2589 	.vfe_res = vfe_res_845,
2590 	.csiphy_num = ARRAY_SIZE(csiphy_res_845),
2591 	.csid_num = ARRAY_SIZE(csid_res_845),
2592 	.vfe_num = ARRAY_SIZE(vfe_res_845),
2593 	.link_entities = camss_link_entities
2594 };
2595 
2596 static const struct camss_resources sm8250_resources = {
2597 	.version = CAMSS_8250,
2598 	.pd_name = "top",
2599 	.csiphy_res = csiphy_res_8250,
2600 	.csid_res = csid_res_8250,
2601 	.vfe_res = vfe_res_8250,
2602 	.icc_res = icc_res_sm8250,
2603 	.icc_path_num = ARRAY_SIZE(icc_res_sm8250),
2604 	.csiphy_num = ARRAY_SIZE(csiphy_res_8250),
2605 	.csid_num = ARRAY_SIZE(csid_res_8250),
2606 	.vfe_num = ARRAY_SIZE(vfe_res_8250),
2607 	.link_entities = camss_link_entities
2608 };
2609 
2610 static const struct camss_resources sc8280xp_resources = {
2611 	.version = CAMSS_8280XP,
2612 	.pd_name = "top",
2613 	.csiphy_res = csiphy_res_sc8280xp,
2614 	.csid_res = csid_res_sc8280xp,
2615 	.ispif_res = NULL,
2616 	.vfe_res = vfe_res_sc8280xp,
2617 	.icc_res = icc_res_sc8280xp,
2618 	.icc_path_num = ARRAY_SIZE(icc_res_sc8280xp),
2619 	.csiphy_num = ARRAY_SIZE(csiphy_res_sc8280xp),
2620 	.csid_num = ARRAY_SIZE(csid_res_sc8280xp),
2621 	.vfe_num = ARRAY_SIZE(vfe_res_sc8280xp),
2622 	.link_entities = camss_link_entities
2623 };
2624 
2625 static const struct of_device_id camss_dt_match[] = {
2626 	{ .compatible = "qcom,msm8916-camss", .data = &msm8916_resources },
2627 	{ .compatible = "qcom,msm8953-camss", .data = &msm8953_resources },
2628 	{ .compatible = "qcom,msm8996-camss", .data = &msm8996_resources },
2629 	{ .compatible = "qcom,sdm660-camss", .data = &sdm660_resources },
2630 	{ .compatible = "qcom,sdm845-camss", .data = &sdm845_resources },
2631 	{ .compatible = "qcom,sm8250-camss", .data = &sm8250_resources },
2632 	{ .compatible = "qcom,sc8280xp-camss", .data = &sc8280xp_resources },
2633 	{ }
2634 };
2635 
2636 MODULE_DEVICE_TABLE(of, camss_dt_match);
2637 
2638 static int __maybe_unused camss_runtime_suspend(struct device *dev)
2639 {
2640 	struct camss *camss = dev_get_drvdata(dev);
2641 	int i;
2642 	int ret;
2643 
2644 	for (i = 0; i < camss->res->icc_path_num; i++) {
2645 		ret = icc_set_bw(camss->icc_path[i], 0, 0);
2646 		if (ret)
2647 			return ret;
2648 	}
2649 
2650 	return 0;
2651 }
2652 
2653 static int __maybe_unused camss_runtime_resume(struct device *dev)
2654 {
2655 	struct camss *camss = dev_get_drvdata(dev);
2656 	const struct resources_icc *icc_res = camss->res->icc_res;
2657 	int i;
2658 	int ret;
2659 
2660 	for (i = 0; i < camss->res->icc_path_num; i++) {
2661 		ret = icc_set_bw(camss->icc_path[i],
2662 				 icc_res[i].icc_bw_tbl.avg,
2663 				 icc_res[i].icc_bw_tbl.peak);
2664 		if (ret)
2665 			return ret;
2666 	}
2667 
2668 	return 0;
2669 }
2670 
2671 static const struct dev_pm_ops camss_pm_ops = {
2672 	SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
2673 				pm_runtime_force_resume)
2674 	SET_RUNTIME_PM_OPS(camss_runtime_suspend, camss_runtime_resume, NULL)
2675 };
2676 
2677 static struct platform_driver qcom_camss_driver = {
2678 	.probe = camss_probe,
2679 	.remove = camss_remove,
2680 	.driver = {
2681 		.name = "qcom-camss",
2682 		.of_match_table = camss_dt_match,
2683 		.pm = &camss_pm_ops,
2684 	},
2685 };
2686 
2687 module_platform_driver(qcom_camss_driver);
2688 
2689 MODULE_ALIAS("platform:qcom-camss");
2690 MODULE_DESCRIPTION("Qualcomm Camera Subsystem driver");
2691 MODULE_AUTHOR("Todor Tomov <todor.tomov@linaro.org>");
2692 MODULE_LICENSE("GPL v2");
2693