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_670[] = {
742 /* CSIPHY0 */
743 {
744 .regulators = { "vdda-phy", "vdda-pll" },
745 .clock = { "soc_ahb", "cpas_ahb",
746 "csiphy0", "csiphy0_timer" },
747 .clock_rate = { { 0 },
748 { 0 },
749 { 0 },
750 { 19200000, 240000000, 269333333 } },
751 .reg = { "csiphy0" },
752 .interrupt = { "csiphy0" },
753 .csiphy = {
754 .hw_ops = &csiphy_ops_3ph_1_0,
755 .formats = &csiphy_formats_sdm845
756 }
757 },
758
759 /* CSIPHY1 */
760 {
761 .regulators = { "vdda-phy", "vdda-pll" },
762 .clock = { "soc_ahb", "cpas_ahb",
763 "csiphy1", "csiphy1_timer" },
764 .clock_rate = { { 0 },
765 { 0 },
766 { 0 },
767 { 19200000, 240000000, 269333333 } },
768 .reg = { "csiphy1" },
769 .interrupt = { "csiphy1" },
770 .csiphy = {
771 .hw_ops = &csiphy_ops_3ph_1_0,
772 .formats = &csiphy_formats_sdm845
773 }
774 },
775
776 /* CSIPHY2 */
777 {
778 .regulators = { "vdda-phy", "vdda-pll" },
779 .clock = { "soc_ahb", "cpas_ahb",
780 "csiphy2", "csiphy2_timer" },
781 .clock_rate = { { 0 },
782 { 0 },
783 { 0 },
784 { 19200000, 240000000, 269333333 } },
785 .reg = { "csiphy2" },
786 .interrupt = { "csiphy2" },
787 .csiphy = {
788 .hw_ops = &csiphy_ops_3ph_1_0,
789 .formats = &csiphy_formats_sdm845
790 }
791 }
792 };
793
794 static const struct camss_subdev_resources csid_res_670[] = {
795 /* CSID0 */
796 {
797 .regulators = {},
798 .clock = { "cpas_ahb", "soc_ahb", "vfe0",
799 "vfe0_cphy_rx", "csi0" },
800 .clock_rate = { { 0 },
801 { 0 },
802 { 100000000, 320000000, 404000000, 480000000, 600000000 },
803 { 384000000 },
804 { 19200000, 75000000, 384000000, 538666667 } },
805 .reg = { "csid0" },
806 .interrupt = { "csid0" },
807 .csid = {
808 .hw_ops = &csid_ops_gen2,
809 .parent_dev_ops = &vfe_parent_dev_ops,
810 .formats = &csid_formats_gen2
811 }
812 },
813
814 /* CSID1 */
815 {
816 .regulators = {},
817 .clock = { "cpas_ahb", "soc_ahb", "vfe1",
818 "vfe1_cphy_rx", "csi1" },
819 .clock_rate = { { 0 },
820 { 0 },
821 { 100000000, 320000000, 404000000, 480000000, 600000000 },
822 { 384000000 },
823 { 19200000, 75000000, 384000000, 538666667 } },
824 .reg = { "csid1" },
825 .interrupt = { "csid1" },
826 .csid = {
827 .hw_ops = &csid_ops_gen2,
828 .parent_dev_ops = &vfe_parent_dev_ops,
829 .formats = &csid_formats_gen2
830 }
831 },
832
833 /* CSID2 */
834 {
835 .regulators = {},
836 .clock = { "cpas_ahb", "soc_ahb", "vfe_lite",
837 "vfe_lite_cphy_rx", "csi2" },
838 .clock_rate = { { 0 },
839 { 0 },
840 { 100000000, 320000000, 404000000, 480000000, 600000000 },
841 { 384000000 },
842 { 19200000, 75000000, 384000000, 538666667 } },
843 .reg = { "csid2" },
844 .interrupt = { "csid2" },
845 .csid = {
846 .is_lite = true,
847 .hw_ops = &csid_ops_gen2,
848 .parent_dev_ops = &vfe_parent_dev_ops,
849 .formats = &csid_formats_gen2
850 }
851 }
852 };
853
854 static const struct camss_subdev_resources vfe_res_670[] = {
855 /* VFE0 */
856 {
857 .regulators = {},
858 .clock = { "camnoc_axi", "cpas_ahb", "soc_ahb",
859 "vfe0", "vfe0_axi" },
860 .clock_rate = { { 0 },
861 { 0 },
862 { 0 },
863 { 100000000, 320000000, 404000000, 480000000, 600000000 },
864 { 0 } },
865 .reg = { "vfe0" },
866 .interrupt = { "vfe0" },
867 .vfe = {
868 .line_num = 4,
869 .has_pd = true,
870 .pd_name = "ife0",
871 .hw_ops = &vfe_ops_170,
872 .formats_rdi = &vfe_formats_rdi_845,
873 .formats_pix = &vfe_formats_pix_845
874 }
875 },
876
877 /* VFE1 */
878 {
879 .regulators = {},
880 .clock = { "camnoc_axi", "cpas_ahb", "soc_ahb",
881 "vfe1", "vfe1_axi" },
882 .clock_rate = { { 0 },
883 { 0 },
884 { 0 },
885 { 100000000, 320000000, 404000000, 480000000, 600000000 },
886 { 0 } },
887 .reg = { "vfe1" },
888 .interrupt = { "vfe1" },
889 .vfe = {
890 .line_num = 4,
891 .has_pd = true,
892 .pd_name = "ife1",
893 .hw_ops = &vfe_ops_170,
894 .formats_rdi = &vfe_formats_rdi_845,
895 .formats_pix = &vfe_formats_pix_845
896 }
897 },
898
899 /* VFE-lite */
900 {
901 .regulators = {},
902 .clock = { "camnoc_axi", "cpas_ahb", "soc_ahb",
903 "vfe_lite" },
904 .clock_rate = { { 0 },
905 { 0 },
906 { 0 },
907 { 100000000, 320000000, 404000000, 480000000, 600000000 } },
908 .reg = { "vfe_lite" },
909 .interrupt = { "vfe_lite" },
910 .vfe = {
911 .is_lite = true,
912 .line_num = 4,
913 .hw_ops = &vfe_ops_170,
914 .formats_rdi = &vfe_formats_rdi_845,
915 .formats_pix = &vfe_formats_pix_845
916 }
917 }
918 };
919
920 static const struct camss_subdev_resources csiphy_res_845[] = {
921 /* CSIPHY0 */
922 {
923 .regulators = {},
924 .clock = { "camnoc_axi", "soc_ahb", "slow_ahb_src",
925 "cpas_ahb", "cphy_rx_src", "csiphy0",
926 "csiphy0_timer_src", "csiphy0_timer" },
927 .clock_rate = { { 0 },
928 { 0 },
929 { 0 },
930 { 0 },
931 { 0 },
932 { 0 },
933 { 0 },
934 { 19200000, 240000000, 269333333 } },
935 .reg = { "csiphy0" },
936 .interrupt = { "csiphy0" },
937 .csiphy = {
938 .hw_ops = &csiphy_ops_3ph_1_0,
939 .formats = &csiphy_formats_sdm845
940 }
941 },
942
943 /* CSIPHY1 */
944 {
945 .regulators = {},
946 .clock = { "camnoc_axi", "soc_ahb", "slow_ahb_src",
947 "cpas_ahb", "cphy_rx_src", "csiphy1",
948 "csiphy1_timer_src", "csiphy1_timer" },
949 .clock_rate = { { 0 },
950 { 0 },
951 { 0 },
952 { 0 },
953 { 0 },
954 { 0 },
955 { 0 },
956 { 19200000, 240000000, 269333333 } },
957 .reg = { "csiphy1" },
958 .interrupt = { "csiphy1" },
959 .csiphy = {
960 .hw_ops = &csiphy_ops_3ph_1_0,
961 .formats = &csiphy_formats_sdm845
962 }
963 },
964
965 /* CSIPHY2 */
966 {
967 .regulators = {},
968 .clock = { "camnoc_axi", "soc_ahb", "slow_ahb_src",
969 "cpas_ahb", "cphy_rx_src", "csiphy2",
970 "csiphy2_timer_src", "csiphy2_timer" },
971 .clock_rate = { { 0 },
972 { 0 },
973 { 0 },
974 { 0 },
975 { 0 },
976 { 0 },
977 { 0 },
978 { 19200000, 240000000, 269333333 } },
979 .reg = { "csiphy2" },
980 .interrupt = { "csiphy2" },
981 .csiphy = {
982 .hw_ops = &csiphy_ops_3ph_1_0,
983 .formats = &csiphy_formats_sdm845
984 }
985 },
986
987 /* CSIPHY3 */
988 {
989 .regulators = {},
990 .clock = { "camnoc_axi", "soc_ahb", "slow_ahb_src",
991 "cpas_ahb", "cphy_rx_src", "csiphy3",
992 "csiphy3_timer_src", "csiphy3_timer" },
993 .clock_rate = { { 0 },
994 { 0 },
995 { 0 },
996 { 0 },
997 { 0 },
998 { 0 },
999 { 0 },
1000 { 19200000, 240000000, 269333333 } },
1001 .reg = { "csiphy3" },
1002 .interrupt = { "csiphy3" },
1003 .csiphy = {
1004 .hw_ops = &csiphy_ops_3ph_1_0,
1005 .formats = &csiphy_formats_sdm845
1006 }
1007 }
1008 };
1009
1010 static const struct camss_subdev_resources csid_res_845[] = {
1011 /* CSID0 */
1012 {
1013 .regulators = { "vdda-phy", "vdda-pll" },
1014 .clock = { "cpas_ahb", "cphy_rx_src", "slow_ahb_src",
1015 "soc_ahb", "vfe0", "vfe0_src",
1016 "vfe0_cphy_rx", "csi0",
1017 "csi0_src" },
1018 .clock_rate = { { 0 },
1019 { 384000000 },
1020 { 80000000 },
1021 { 0 },
1022 { 19200000, 100000000, 320000000, 404000000, 480000000, 600000000 },
1023 { 320000000 },
1024 { 0 },
1025 { 19200000, 75000000, 384000000, 538666667 },
1026 { 384000000 } },
1027 .reg = { "csid0" },
1028 .interrupt = { "csid0" },
1029 .csid = {
1030 .hw_ops = &csid_ops_gen2,
1031 .parent_dev_ops = &vfe_parent_dev_ops,
1032 .formats = &csid_formats_gen2
1033 }
1034 },
1035
1036 /* CSID1 */
1037 {
1038 .regulators = { "vdda-phy", "vdda-pll" },
1039 .clock = { "cpas_ahb", "cphy_rx_src", "slow_ahb_src",
1040 "soc_ahb", "vfe1", "vfe1_src",
1041 "vfe1_cphy_rx", "csi1",
1042 "csi1_src" },
1043 .clock_rate = { { 0 },
1044 { 384000000 },
1045 { 80000000 },
1046 { 0 },
1047 { 19200000, 100000000, 320000000, 404000000, 480000000, 600000000 },
1048 { 320000000 },
1049 { 0 },
1050 { 19200000, 75000000, 384000000, 538666667 },
1051 { 384000000 } },
1052 .reg = { "csid1" },
1053 .interrupt = { "csid1" },
1054 .csid = {
1055 .hw_ops = &csid_ops_gen2,
1056 .parent_dev_ops = &vfe_parent_dev_ops,
1057 .formats = &csid_formats_gen2
1058 }
1059 },
1060
1061 /* CSID2 */
1062 {
1063 .regulators = { "vdda-phy", "vdda-pll" },
1064 .clock = { "cpas_ahb", "cphy_rx_src", "slow_ahb_src",
1065 "soc_ahb", "vfe_lite", "vfe_lite_src",
1066 "vfe_lite_cphy_rx", "csi2",
1067 "csi2_src" },
1068 .clock_rate = { { 0 },
1069 { 384000000 },
1070 { 80000000 },
1071 { 0 },
1072 { 19200000, 100000000, 320000000, 404000000, 480000000, 600000000 },
1073 { 320000000 },
1074 { 0 },
1075 { 19200000, 75000000, 384000000, 538666667 },
1076 { 384000000 } },
1077 .reg = { "csid2" },
1078 .interrupt = { "csid2" },
1079 .csid = {
1080 .is_lite = true,
1081 .hw_ops = &csid_ops_gen2,
1082 .parent_dev_ops = &vfe_parent_dev_ops,
1083 .formats = &csid_formats_gen2
1084 }
1085 }
1086 };
1087
1088 static const struct camss_subdev_resources vfe_res_845[] = {
1089 /* VFE0 */
1090 {
1091 .regulators = {},
1092 .clock = { "camnoc_axi", "cpas_ahb", "slow_ahb_src",
1093 "soc_ahb", "vfe0", "vfe0_axi",
1094 "vfe0_src", "csi0",
1095 "csi0_src"},
1096 .clock_rate = { { 0 },
1097 { 0 },
1098 { 80000000 },
1099 { 0 },
1100 { 19200000, 100000000, 320000000, 404000000, 480000000, 600000000 },
1101 { 0 },
1102 { 320000000 },
1103 { 19200000, 75000000, 384000000, 538666667 },
1104 { 384000000 } },
1105 .reg = { "vfe0" },
1106 .interrupt = { "vfe0" },
1107 .vfe = {
1108 .line_num = 4,
1109 .pd_name = "ife0",
1110 .has_pd = true,
1111 .hw_ops = &vfe_ops_170,
1112 .formats_rdi = &vfe_formats_rdi_845,
1113 .formats_pix = &vfe_formats_pix_845
1114 }
1115 },
1116
1117 /* VFE1 */
1118 {
1119 .regulators = {},
1120 .clock = { "camnoc_axi", "cpas_ahb", "slow_ahb_src",
1121 "soc_ahb", "vfe1", "vfe1_axi",
1122 "vfe1_src", "csi1",
1123 "csi1_src"},
1124 .clock_rate = { { 0 },
1125 { 0 },
1126 { 80000000 },
1127 { 0 },
1128 { 19200000, 100000000, 320000000, 404000000, 480000000, 600000000 },
1129 { 0 },
1130 { 320000000 },
1131 { 19200000, 75000000, 384000000, 538666667 },
1132 { 384000000 } },
1133 .reg = { "vfe1" },
1134 .interrupt = { "vfe1" },
1135 .vfe = {
1136 .line_num = 4,
1137 .pd_name = "ife1",
1138 .has_pd = true,
1139 .hw_ops = &vfe_ops_170,
1140 .formats_rdi = &vfe_formats_rdi_845,
1141 .formats_pix = &vfe_formats_pix_845
1142 }
1143 },
1144
1145 /* VFE-lite */
1146 {
1147 .regulators = {},
1148 .clock = { "camnoc_axi", "cpas_ahb", "slow_ahb_src",
1149 "soc_ahb", "vfe_lite",
1150 "vfe_lite_src", "csi2",
1151 "csi2_src"},
1152 .clock_rate = { { 0 },
1153 { 0 },
1154 { 80000000 },
1155 { 0 },
1156 { 19200000, 100000000, 320000000, 404000000, 480000000, 600000000 },
1157 { 320000000 },
1158 { 19200000, 75000000, 384000000, 538666667 },
1159 { 384000000 } },
1160 .reg = { "vfe_lite" },
1161 .interrupt = { "vfe_lite" },
1162 .vfe = {
1163 .is_lite = true,
1164 .line_num = 4,
1165 .hw_ops = &vfe_ops_170,
1166 .formats_rdi = &vfe_formats_rdi_845,
1167 .formats_pix = &vfe_formats_pix_845
1168 }
1169 }
1170 };
1171
1172 static const struct camss_subdev_resources csiphy_res_8250[] = {
1173 /* CSIPHY0 */
1174 {
1175 .regulators = { "vdda-phy", "vdda-pll" },
1176 .clock = { "csiphy0", "csiphy0_timer" },
1177 .clock_rate = { { 400000000 },
1178 { 300000000 } },
1179 .reg = { "csiphy0" },
1180 .interrupt = { "csiphy0" },
1181 .csiphy = {
1182 .hw_ops = &csiphy_ops_3ph_1_0,
1183 .formats = &csiphy_formats_sdm845
1184 }
1185 },
1186 /* CSIPHY1 */
1187 {
1188 .regulators = { "vdda-phy", "vdda-pll" },
1189 .clock = { "csiphy1", "csiphy1_timer" },
1190 .clock_rate = { { 400000000 },
1191 { 300000000 } },
1192 .reg = { "csiphy1" },
1193 .interrupt = { "csiphy1" },
1194 .csiphy = {
1195 .hw_ops = &csiphy_ops_3ph_1_0,
1196 .formats = &csiphy_formats_sdm845
1197 }
1198 },
1199 /* CSIPHY2 */
1200 {
1201 .regulators = { "vdda-phy", "vdda-pll" },
1202 .clock = { "csiphy2", "csiphy2_timer" },
1203 .clock_rate = { { 400000000 },
1204 { 300000000 } },
1205 .reg = { "csiphy2" },
1206 .interrupt = { "csiphy2" },
1207 .csiphy = {
1208 .hw_ops = &csiphy_ops_3ph_1_0,
1209 .formats = &csiphy_formats_sdm845
1210 }
1211 },
1212 /* CSIPHY3 */
1213 {
1214 .regulators = { "vdda-phy", "vdda-pll" },
1215 .clock = { "csiphy3", "csiphy3_timer" },
1216 .clock_rate = { { 400000000 },
1217 { 300000000 } },
1218 .reg = { "csiphy3" },
1219 .interrupt = { "csiphy3" },
1220 .csiphy = {
1221 .hw_ops = &csiphy_ops_3ph_1_0,
1222 .formats = &csiphy_formats_sdm845
1223 }
1224 },
1225 /* CSIPHY4 */
1226 {
1227 .regulators = { "vdda-phy", "vdda-pll" },
1228 .clock = { "csiphy4", "csiphy4_timer" },
1229 .clock_rate = { { 400000000 },
1230 { 300000000 } },
1231 .reg = { "csiphy4" },
1232 .interrupt = { "csiphy4" },
1233 .csiphy = {
1234 .hw_ops = &csiphy_ops_3ph_1_0,
1235 .formats = &csiphy_formats_sdm845
1236 }
1237 },
1238 /* CSIPHY5 */
1239 {
1240 .regulators = { "vdda-phy", "vdda-pll" },
1241 .clock = { "csiphy5", "csiphy5_timer" },
1242 .clock_rate = { { 400000000 },
1243 { 300000000 } },
1244 .reg = { "csiphy5" },
1245 .interrupt = { "csiphy5" },
1246 .csiphy = {
1247 .hw_ops = &csiphy_ops_3ph_1_0,
1248 .formats = &csiphy_formats_sdm845
1249 }
1250 }
1251 };
1252
1253 static const struct camss_subdev_resources csid_res_8250[] = {
1254 /* CSID0 */
1255 {
1256 .regulators = {},
1257 .clock = { "vfe0_csid", "vfe0_cphy_rx", "vfe0", "vfe0_areg", "vfe0_ahb" },
1258 .clock_rate = { { 400000000 },
1259 { 400000000 },
1260 { 350000000, 475000000, 576000000, 720000000 },
1261 { 100000000, 200000000, 300000000, 400000000 },
1262 { 0 } },
1263 .reg = { "csid0" },
1264 .interrupt = { "csid0" },
1265 .csid = {
1266 .hw_ops = &csid_ops_gen2,
1267 .parent_dev_ops = &vfe_parent_dev_ops,
1268 .formats = &csid_formats_gen2
1269 }
1270 },
1271 /* CSID1 */
1272 {
1273 .regulators = {},
1274 .clock = { "vfe1_csid", "vfe1_cphy_rx", "vfe1", "vfe1_areg", "vfe1_ahb" },
1275 .clock_rate = { { 400000000 },
1276 { 400000000 },
1277 { 350000000, 475000000, 576000000, 720000000 },
1278 { 100000000, 200000000, 300000000, 400000000 },
1279 { 0 } },
1280 .reg = { "csid1" },
1281 .interrupt = { "csid1" },
1282 .csid = {
1283 .hw_ops = &csid_ops_gen2,
1284 .parent_dev_ops = &vfe_parent_dev_ops,
1285 .formats = &csid_formats_gen2
1286 }
1287 },
1288 /* CSID2 */
1289 {
1290 .regulators = {},
1291 .clock = { "vfe_lite_csid", "vfe_lite_cphy_rx", "vfe_lite", "vfe_lite_ahb" },
1292 .clock_rate = { { 400000000 },
1293 { 400000000 },
1294 { 400000000, 480000000 },
1295 { 0 } },
1296 .reg = { "csid2" },
1297 .interrupt = { "csid2" },
1298 .csid = {
1299 .is_lite = true,
1300 .hw_ops = &csid_ops_gen2,
1301 .parent_dev_ops = &vfe_parent_dev_ops,
1302 .formats = &csid_formats_gen2
1303 }
1304 },
1305 /* CSID3 */
1306 {
1307 .regulators = {},
1308 .clock = { "vfe_lite_csid", "vfe_lite_cphy_rx", "vfe_lite", "vfe_lite_ahb" },
1309 .clock_rate = { { 400000000 },
1310 { 400000000 },
1311 { 400000000, 480000000 },
1312 { 0 } },
1313 .reg = { "csid3" },
1314 .interrupt = { "csid3" },
1315 .csid = {
1316 .is_lite = true,
1317 .hw_ops = &csid_ops_gen2,
1318 .parent_dev_ops = &vfe_parent_dev_ops,
1319 .formats = &csid_formats_gen2
1320 }
1321 }
1322 };
1323
1324 static const struct camss_subdev_resources vfe_res_8250[] = {
1325 /* VFE0 */
1326 {
1327 .regulators = {},
1328 .clock = { "camnoc_axi_src", "slow_ahb_src", "cpas_ahb",
1329 "camnoc_axi", "vfe0_ahb", "vfe0_areg", "vfe0",
1330 "vfe0_axi", "cam_hf_axi" },
1331 .clock_rate = { { 19200000, 300000000, 400000000, 480000000 },
1332 { 19200000, 80000000 },
1333 { 19200000 },
1334 { 0 },
1335 { 0 },
1336 { 100000000, 200000000, 300000000, 400000000 },
1337 { 350000000, 475000000, 576000000, 720000000 },
1338 { 0 },
1339 { 0 } },
1340 .reg = { "vfe0" },
1341 .interrupt = { "vfe0" },
1342 .vfe = {
1343 .line_num = 3,
1344 .has_pd = true,
1345 .pd_name = "ife0",
1346 .hw_ops = &vfe_ops_480,
1347 .formats_rdi = &vfe_formats_rdi_845,
1348 .formats_pix = &vfe_formats_pix_845
1349 }
1350 },
1351 /* VFE1 */
1352 {
1353 .regulators = {},
1354 .clock = { "camnoc_axi_src", "slow_ahb_src", "cpas_ahb",
1355 "camnoc_axi", "vfe1_ahb", "vfe1_areg", "vfe1",
1356 "vfe1_axi", "cam_hf_axi" },
1357 .clock_rate = { { 19200000, 300000000, 400000000, 480000000 },
1358 { 19200000, 80000000 },
1359 { 19200000 },
1360 { 0 },
1361 { 0 },
1362 { 100000000, 200000000, 300000000, 400000000 },
1363 { 350000000, 475000000, 576000000, 720000000 },
1364 { 0 },
1365 { 0 } },
1366 .reg = { "vfe1" },
1367 .interrupt = { "vfe1" },
1368 .vfe = {
1369 .line_num = 3,
1370 .has_pd = true,
1371 .pd_name = "ife1",
1372 .hw_ops = &vfe_ops_480,
1373 .formats_rdi = &vfe_formats_rdi_845,
1374 .formats_pix = &vfe_formats_pix_845
1375 }
1376 },
1377 /* VFE2 (lite) */
1378 {
1379 .regulators = {},
1380 .clock = { "camnoc_axi_src", "slow_ahb_src", "cpas_ahb",
1381 "camnoc_axi", "vfe_lite_ahb", "vfe_lite_axi",
1382 "vfe_lite", "cam_hf_axi" },
1383 .clock_rate = { { 19200000, 300000000, 400000000, 480000000 },
1384 { 19200000, 80000000 },
1385 { 19200000 },
1386 { 0 },
1387 { 0 },
1388 { 0 },
1389 { 400000000, 480000000 },
1390 { 0 } },
1391 .reg = { "vfe_lite0" },
1392 .interrupt = { "vfe_lite0" },
1393 .vfe = {
1394 .is_lite = true,
1395 .line_num = 4,
1396 .hw_ops = &vfe_ops_480,
1397 .formats_rdi = &vfe_formats_rdi_845,
1398 .formats_pix = &vfe_formats_pix_845
1399 }
1400 },
1401 /* VFE3 (lite) */
1402 {
1403 .regulators = {},
1404 .clock = { "camnoc_axi_src", "slow_ahb_src", "cpas_ahb",
1405 "camnoc_axi", "vfe_lite_ahb", "vfe_lite_axi",
1406 "vfe_lite", "cam_hf_axi" },
1407 .clock_rate = { { 19200000, 300000000, 400000000, 480000000 },
1408 { 19200000, 80000000 },
1409 { 19200000 },
1410 { 0 },
1411 { 0 },
1412 { 0 },
1413 { 400000000, 480000000 },
1414 { 0 } },
1415 .reg = { "vfe_lite1" },
1416 .interrupt = { "vfe_lite1" },
1417 .vfe = {
1418 .is_lite = true,
1419 .line_num = 4,
1420 .hw_ops = &vfe_ops_480,
1421 .formats_rdi = &vfe_formats_rdi_845,
1422 .formats_pix = &vfe_formats_pix_845
1423 }
1424 },
1425 };
1426
1427 static const struct resources_icc icc_res_sm8250[] = {
1428 {
1429 .name = "cam_ahb",
1430 .icc_bw_tbl.avg = 38400,
1431 .icc_bw_tbl.peak = 76800,
1432 },
1433 {
1434 .name = "cam_hf_0_mnoc",
1435 .icc_bw_tbl.avg = 2097152,
1436 .icc_bw_tbl.peak = 2097152,
1437 },
1438 {
1439 .name = "cam_sf_0_mnoc",
1440 .icc_bw_tbl.avg = 0,
1441 .icc_bw_tbl.peak = 2097152,
1442 },
1443 {
1444 .name = "cam_sf_icp_mnoc",
1445 .icc_bw_tbl.avg = 2097152,
1446 .icc_bw_tbl.peak = 2097152,
1447 },
1448 };
1449
1450 static const struct camss_subdev_resources csiphy_res_7280[] = {
1451 /* CSIPHY0 */
1452 {
1453 .regulators = { "vdda-phy", "vdda-pll" },
1454
1455 .clock = { "csiphy0", "csiphy0_timer" },
1456 .clock_rate = { { 300000000, 400000000 },
1457 { 300000000 } },
1458 .reg = { "csiphy0" },
1459 .interrupt = { "csiphy0" },
1460 .csiphy = {
1461 .hw_ops = &csiphy_ops_3ph_1_0,
1462 .formats = &csiphy_formats_sc7280
1463 }
1464 },
1465 /* CSIPHY1 */
1466 {
1467 .regulators = { "vdda-phy", "vdda-pll" },
1468
1469 .clock = { "csiphy1", "csiphy1_timer" },
1470 .clock_rate = { { 300000000, 400000000 },
1471 { 300000000 } },
1472 .reg = { "csiphy1" },
1473 .interrupt = { "csiphy1" },
1474 .csiphy = {
1475 .hw_ops = &csiphy_ops_3ph_1_0,
1476 .formats = &csiphy_formats_sc7280
1477 }
1478 },
1479 /* CSIPHY2 */
1480 {
1481 .regulators = { "vdda-phy", "vdda-pll" },
1482
1483 .clock = { "csiphy2", "csiphy2_timer" },
1484 .clock_rate = { { 300000000, 400000000 },
1485 { 300000000 } },
1486 .reg = { "csiphy2" },
1487 .interrupt = { "csiphy2" },
1488 .csiphy = {
1489 .hw_ops = &csiphy_ops_3ph_1_0,
1490 .formats = &csiphy_formats_sc7280
1491 }
1492 },
1493 /* CSIPHY3 */
1494 {
1495 .regulators = { "vdda-phy", "vdda-pll" },
1496
1497 .clock = { "csiphy3", "csiphy3_timer" },
1498 .clock_rate = { { 300000000, 400000000 },
1499 { 300000000 } },
1500 .reg = { "csiphy3" },
1501 .interrupt = { "csiphy3" },
1502 .csiphy = {
1503 .hw_ops = &csiphy_ops_3ph_1_0,
1504 .formats = &csiphy_formats_sc7280
1505 }
1506 },
1507 /* CSIPHY4 */
1508 {
1509 .regulators = { "vdda-phy", "vdda-pll" },
1510
1511 .clock = { "csiphy4", "csiphy4_timer" },
1512 .clock_rate = { { 300000000, 400000000 },
1513 { 300000000 } },
1514 .reg = { "csiphy4" },
1515 .interrupt = { "csiphy4" },
1516 .csiphy = {
1517 .hw_ops = &csiphy_ops_3ph_1_0,
1518 .formats = &csiphy_formats_sc7280
1519 }
1520 },
1521 };
1522
1523 static const struct camss_subdev_resources csid_res_7280[] = {
1524 /* CSID0 */
1525 {
1526 .regulators = {},
1527
1528 .clock = { "vfe0_csid", "vfe0_cphy_rx", "vfe0" },
1529 .clock_rate = { { 300000000, 400000000 },
1530 { 0 },
1531 { 380000000, 510000000, 637000000, 760000000 }
1532 },
1533
1534 .reg = { "csid0" },
1535 .interrupt = { "csid0" },
1536 .csid = {
1537 .is_lite = false,
1538 .hw_ops = &csid_ops_gen2,
1539 .parent_dev_ops = &vfe_parent_dev_ops,
1540 .formats = &csid_formats_gen2
1541 }
1542 },
1543 /* CSID1 */
1544 {
1545 .regulators = {},
1546
1547 .clock = { "vfe1_csid", "vfe1_cphy_rx", "vfe1" },
1548 .clock_rate = { { 300000000, 400000000 },
1549 { 0 },
1550 { 380000000, 510000000, 637000000, 760000000 }
1551 },
1552
1553 .reg = { "csid1" },
1554 .interrupt = { "csid1" },
1555 .csid = {
1556 .is_lite = false,
1557 .hw_ops = &csid_ops_gen2,
1558 .parent_dev_ops = &vfe_parent_dev_ops,
1559 .formats = &csid_formats_gen2
1560 }
1561 },
1562 /* CSID2 */
1563 {
1564 .regulators = {},
1565
1566 .clock = { "vfe2_csid", "vfe2_cphy_rx", "vfe2" },
1567 .clock_rate = { { 300000000, 400000000 },
1568 { 0 },
1569 { 380000000, 510000000, 637000000, 760000000 }
1570 },
1571
1572 .reg = { "csid2" },
1573 .interrupt = { "csid2" },
1574 .csid = {
1575 .is_lite = false,
1576 .hw_ops = &csid_ops_gen2,
1577 .parent_dev_ops = &vfe_parent_dev_ops,
1578 .formats = &csid_formats_gen2
1579 }
1580 },
1581 /* CSID3 */
1582 {
1583 .regulators = {},
1584
1585 .clock = { "vfe_lite0_csid", "vfe_lite0_cphy_rx", "vfe_lite0" },
1586 .clock_rate = { { 300000000, 400000000 },
1587 { 0 },
1588 { 320000000, 400000000, 480000000, 600000000 }
1589 },
1590
1591 .reg = { "csid_lite0" },
1592 .interrupt = { "csid_lite0" },
1593 .csid = {
1594 .is_lite = true,
1595 .hw_ops = &csid_ops_gen2,
1596 .parent_dev_ops = &vfe_parent_dev_ops,
1597 .formats = &csid_formats_gen2
1598 }
1599 },
1600 /* CSID4 */
1601 {
1602 .regulators = {},
1603
1604 .clock = { "vfe_lite1_csid", "vfe_lite1_cphy_rx", "vfe_lite1" },
1605 .clock_rate = { { 300000000, 400000000 },
1606 { 0 },
1607 { 320000000, 400000000, 480000000, 600000000 }
1608 },
1609
1610 .reg = { "csid_lite1" },
1611 .interrupt = { "csid_lite1" },
1612 .csid = {
1613 .is_lite = true,
1614 .hw_ops = &csid_ops_gen2,
1615 .parent_dev_ops = &vfe_parent_dev_ops,
1616 .formats = &csid_formats_gen2
1617 }
1618 },
1619 };
1620
1621 static const struct camss_subdev_resources vfe_res_7280[] = {
1622 /* VFE0 */
1623 {
1624 .regulators = {},
1625
1626 .clock = { "camnoc_axi", "cpas_ahb", "icp_ahb", "vfe0",
1627 "vfe0_axi", "gcc_axi_hf", "gcc_axi_sf" },
1628 .clock_rate = { { 150000000, 240000000, 320000000, 400000000, 480000000 },
1629 { 80000000 },
1630 { 0 },
1631 { 380000000, 510000000, 637000000, 760000000 },
1632 { 0 },
1633 { 0 },
1634 { 0 } },
1635
1636 .reg = { "vfe0" },
1637 .interrupt = { "vfe0" },
1638 .vfe = {
1639 .line_num = 3,
1640 .is_lite = false,
1641 .has_pd = true,
1642 .pd_name = "ife0",
1643 .hw_ops = &vfe_ops_170,
1644 .formats_rdi = &vfe_formats_rdi_845,
1645 .formats_pix = &vfe_formats_pix_845
1646 }
1647 },
1648 /* VFE1 */
1649 {
1650 .regulators = {},
1651
1652 .clock = { "camnoc_axi", "cpas_ahb", "icp_ahb", "vfe1",
1653 "vfe1_axi", "gcc_axi_hf", "gcc_axi_sf" },
1654 .clock_rate = { { 150000000, 240000000, 320000000, 400000000, 480000000 },
1655 { 80000000 },
1656 { 0 },
1657 { 380000000, 510000000, 637000000, 760000000 },
1658 { 0 },
1659 { 0 },
1660 { 0 } },
1661
1662 .reg = { "vfe1" },
1663 .interrupt = { "vfe1" },
1664 .vfe = {
1665 .line_num = 3,
1666 .is_lite = false,
1667 .has_pd = true,
1668 .pd_name = "ife1",
1669 .hw_ops = &vfe_ops_170,
1670 .formats_rdi = &vfe_formats_rdi_845,
1671 .formats_pix = &vfe_formats_pix_845
1672 }
1673 },
1674 /* VFE2 */
1675 {
1676 .regulators = {},
1677
1678 .clock = { "camnoc_axi", "cpas_ahb", "icp_ahb", "vfe2",
1679 "vfe2_axi", "gcc_axi_hf", "gcc_axi_sf" },
1680 .clock_rate = { { 150000000, 240000000, 320000000, 400000000, 480000000 },
1681 { 80000000 },
1682 { 0 },
1683 { 380000000, 510000000, 637000000, 760000000 },
1684 { 0 },
1685 { 0 },
1686 { 0 } },
1687
1688 .reg = { "vfe2" },
1689 .interrupt = { "vfe2" },
1690 .vfe = {
1691 .line_num = 3,
1692 .is_lite = false,
1693 .hw_ops = &vfe_ops_170,
1694 .has_pd = true,
1695 .pd_name = "ife2",
1696 .formats_rdi = &vfe_formats_rdi_845,
1697 .formats_pix = &vfe_formats_pix_845
1698 }
1699 },
1700 /* VFE3 (lite) */
1701 {
1702 .clock = { "camnoc_axi", "cpas_ahb", "icp_ahb",
1703 "vfe_lite0", "gcc_axi_hf", "gcc_axi_sf" },
1704 .clock_rate = { { 150000000, 240000000, 320000000, 400000000, 480000000 },
1705 { 80000000 },
1706 { 0 },
1707 { 320000000, 400000000, 480000000, 600000000 },
1708 { 0 },
1709 { 0 } },
1710
1711 .regulators = {},
1712 .reg = { "vfe_lite0" },
1713 .interrupt = { "vfe_lite0" },
1714 .vfe = {
1715 .line_num = 4,
1716 .is_lite = true,
1717 .hw_ops = &vfe_ops_170,
1718 .formats_rdi = &vfe_formats_rdi_845,
1719 .formats_pix = &vfe_formats_pix_845
1720 }
1721 },
1722 /* VFE4 (lite) */
1723 {
1724 .clock = { "camnoc_axi", "cpas_ahb", "icp_ahb",
1725 "vfe_lite1", "gcc_axi_hf", "gcc_axi_sf" },
1726 .clock_rate = { { 150000000, 240000000, 320000000, 400000000, 480000000 },
1727 { 80000000 },
1728 { 0 },
1729 { 320000000, 400000000, 480000000, 600000000 },
1730 { 0 },
1731 { 0 } },
1732
1733 .regulators = {},
1734 .reg = { "vfe_lite1" },
1735 .interrupt = { "vfe_lite1" },
1736 .vfe = {
1737 .line_num = 4,
1738 .is_lite = true,
1739 .hw_ops = &vfe_ops_170,
1740 .formats_rdi = &vfe_formats_rdi_845,
1741 .formats_pix = &vfe_formats_pix_845
1742 }
1743 },
1744 };
1745
1746 static const struct resources_icc icc_res_sc7280[] = {
1747 {
1748 .name = "ahb",
1749 .icc_bw_tbl.avg = 38400,
1750 .icc_bw_tbl.peak = 76800,
1751 },
1752 {
1753 .name = "hf_0",
1754 .icc_bw_tbl.avg = 2097152,
1755 .icc_bw_tbl.peak = 2097152,
1756 },
1757 };
1758
1759 static const struct camss_subdev_resources csiphy_res_sc8280xp[] = {
1760 /* CSIPHY0 */
1761 {
1762 .regulators = {},
1763 .clock = { "csiphy0", "csiphy0_timer" },
1764 .clock_rate = { { 400000000 },
1765 { 300000000 } },
1766 .reg = { "csiphy0" },
1767 .interrupt = { "csiphy0" },
1768 .csiphy = {
1769 .hw_ops = &csiphy_ops_3ph_1_0,
1770 .formats = &csiphy_formats_sdm845
1771 }
1772 },
1773 /* CSIPHY1 */
1774 {
1775 .regulators = {},
1776 .clock = { "csiphy1", "csiphy1_timer" },
1777 .clock_rate = { { 400000000 },
1778 { 300000000 } },
1779 .reg = { "csiphy1" },
1780 .interrupt = { "csiphy1" },
1781 .csiphy = {
1782 .hw_ops = &csiphy_ops_3ph_1_0,
1783 .formats = &csiphy_formats_sdm845
1784 }
1785 },
1786 /* CSIPHY2 */
1787 {
1788 .regulators = {},
1789 .clock = { "csiphy2", "csiphy2_timer" },
1790 .clock_rate = { { 400000000 },
1791 { 300000000 } },
1792 .reg = { "csiphy2" },
1793 .interrupt = { "csiphy2" },
1794 .csiphy = {
1795 .hw_ops = &csiphy_ops_3ph_1_0,
1796 .formats = &csiphy_formats_sdm845
1797 }
1798 },
1799 /* CSIPHY3 */
1800 {
1801 .regulators = {},
1802 .clock = { "csiphy3", "csiphy3_timer" },
1803 .clock_rate = { { 400000000 },
1804 { 300000000 } },
1805 .reg = { "csiphy3" },
1806 .interrupt = { "csiphy3" },
1807 .csiphy = {
1808 .hw_ops = &csiphy_ops_3ph_1_0,
1809 .formats = &csiphy_formats_sdm845
1810 }
1811 },
1812 };
1813
1814 static const struct camss_subdev_resources csid_res_sc8280xp[] = {
1815 /* CSID0 */
1816 {
1817 .regulators = { "vdda-phy", "vdda-pll" },
1818 .clock = { "vfe0_csid", "vfe0_cphy_rx", "vfe0", "vfe0_axi" },
1819 .clock_rate = { { 400000000, 480000000, 600000000 },
1820 { 0 },
1821 { 0 },
1822 { 0 } },
1823 .reg = { "csid0" },
1824 .interrupt = { "csid0" },
1825 .csid = {
1826 .hw_ops = &csid_ops_gen2,
1827 .parent_dev_ops = &vfe_parent_dev_ops,
1828 .formats = &csid_formats_gen2
1829 }
1830 },
1831 /* CSID1 */
1832 {
1833 .regulators = { "vdda-phy", "vdda-pll" },
1834 .clock = { "vfe1_csid", "vfe1_cphy_rx", "vfe1", "vfe1_axi" },
1835 .clock_rate = { { 400000000, 480000000, 600000000 },
1836 { 0 },
1837 { 0 },
1838 { 0 } },
1839 .reg = { "csid1" },
1840 .interrupt = { "csid1" },
1841 .csid = {
1842 .hw_ops = &csid_ops_gen2,
1843 .parent_dev_ops = &vfe_parent_dev_ops,
1844 .formats = &csid_formats_gen2
1845 }
1846 },
1847 /* CSID2 */
1848 {
1849 .regulators = { "vdda-phy", "vdda-pll" },
1850 .clock = { "vfe2_csid", "vfe2_cphy_rx", "vfe2", "vfe2_axi" },
1851 .clock_rate = { { 400000000, 480000000, 600000000 },
1852 { 0 },
1853 { 0 },
1854 { 0 } },
1855 .reg = { "csid2" },
1856 .interrupt = { "csid2" },
1857 .csid = {
1858 .hw_ops = &csid_ops_gen2,
1859 .parent_dev_ops = &vfe_parent_dev_ops,
1860 .formats = &csid_formats_gen2
1861 }
1862 },
1863 /* CSID3 */
1864 {
1865 .regulators = { "vdda-phy", "vdda-pll" },
1866 .clock = { "vfe3_csid", "vfe3_cphy_rx", "vfe3", "vfe3_axi" },
1867 .clock_rate = { { 400000000, 480000000, 600000000 },
1868 { 0 },
1869 { 0 },
1870 { 0 } },
1871 .reg = { "csid3" },
1872 .interrupt = { "csid3" },
1873 .csid = {
1874 .hw_ops = &csid_ops_gen2,
1875 .parent_dev_ops = &vfe_parent_dev_ops,
1876 .formats = &csid_formats_gen2
1877 }
1878 },
1879 /* CSID_LITE0 */
1880 {
1881 .regulators = { "vdda-phy", "vdda-pll" },
1882 .clock = { "vfe_lite0_csid", "vfe_lite0_cphy_rx", "vfe_lite0" },
1883 .clock_rate = { { 400000000, 480000000, 600000000 },
1884 { 0 },
1885 { 0 }, },
1886 .reg = { "csid0_lite" },
1887 .interrupt = { "csid0_lite" },
1888 .csid = {
1889 .is_lite = true,
1890 .hw_ops = &csid_ops_gen2,
1891 .parent_dev_ops = &vfe_parent_dev_ops,
1892 .formats = &csid_formats_gen2
1893 }
1894 },
1895 /* CSID_LITE1 */
1896 {
1897 .regulators = { "vdda-phy", "vdda-pll" },
1898 .clock = { "vfe_lite1_csid", "vfe_lite1_cphy_rx", "vfe_lite1" },
1899 .clock_rate = { { 400000000, 480000000, 600000000 },
1900 { 0 },
1901 { 0 }, },
1902 .reg = { "csid1_lite" },
1903 .interrupt = { "csid1_lite" },
1904 .csid = {
1905 .is_lite = true,
1906 .hw_ops = &csid_ops_gen2,
1907 .parent_dev_ops = &vfe_parent_dev_ops,
1908 .formats = &csid_formats_gen2
1909 }
1910 },
1911 /* CSID_LITE2 */
1912 {
1913 .regulators = { "vdda-phy", "vdda-pll" },
1914 .clock = { "vfe_lite2_csid", "vfe_lite2_cphy_rx", "vfe_lite2" },
1915 .clock_rate = { { 400000000, 480000000, 600000000 },
1916 { 0 },
1917 { 0 }, },
1918 .reg = { "csid2_lite" },
1919 .interrupt = { "csid2_lite" },
1920 .csid = {
1921 .is_lite = true,
1922 .hw_ops = &csid_ops_gen2,
1923 .parent_dev_ops = &vfe_parent_dev_ops,
1924 .formats = &csid_formats_gen2
1925 }
1926 },
1927 /* CSID_LITE3 */
1928 {
1929 .regulators = { "vdda-phy", "vdda-pll" },
1930 .clock = { "vfe_lite3_csid", "vfe_lite3_cphy_rx", "vfe_lite3" },
1931 .clock_rate = { { 400000000, 480000000, 600000000 },
1932 { 0 },
1933 { 0 }, },
1934 .reg = { "csid3_lite" },
1935 .interrupt = { "csid3_lite" },
1936 .csid = {
1937 .is_lite = true,
1938 .hw_ops = &csid_ops_gen2,
1939 .parent_dev_ops = &vfe_parent_dev_ops,
1940 .formats = &csid_formats_gen2
1941 }
1942 }
1943 };
1944
1945 static const struct camss_subdev_resources vfe_res_sc8280xp[] = {
1946 /* VFE0 */
1947 {
1948 .regulators = {},
1949 .clock = { "gcc_axi_hf", "gcc_axi_sf", "cpas_ahb", "camnoc_axi", "vfe0", "vfe0_axi" },
1950 .clock_rate = { { 0 },
1951 { 0 },
1952 { 19200000, 80000000},
1953 { 19200000, 150000000, 266666667, 320000000, 400000000, 480000000 },
1954 { 400000000, 558000000, 637000000, 760000000 },
1955 { 0 }, },
1956 .reg = { "vfe0" },
1957 .interrupt = { "vfe0" },
1958 .vfe = {
1959 .line_num = 4,
1960 .pd_name = "ife0",
1961 .hw_ops = &vfe_ops_170,
1962 .formats_rdi = &vfe_formats_rdi_845,
1963 .formats_pix = &vfe_formats_pix_845
1964 }
1965 },
1966 /* VFE1 */
1967 {
1968 .regulators = {},
1969 .clock = { "gcc_axi_hf", "gcc_axi_sf", "cpas_ahb", "camnoc_axi", "vfe1", "vfe1_axi" },
1970 .clock_rate = { { 0 },
1971 { 0 },
1972 { 19200000, 80000000},
1973 { 19200000, 150000000, 266666667, 320000000, 400000000, 480000000 },
1974 { 400000000, 558000000, 637000000, 760000000 },
1975 { 0 }, },
1976 .reg = { "vfe1" },
1977 .interrupt = { "vfe1" },
1978 .vfe = {
1979 .line_num = 4,
1980 .pd_name = "ife1",
1981 .hw_ops = &vfe_ops_170,
1982 .formats_rdi = &vfe_formats_rdi_845,
1983 .formats_pix = &vfe_formats_pix_845
1984 }
1985 },
1986 /* VFE2 */
1987 {
1988 .regulators = {},
1989 .clock = { "gcc_axi_hf", "gcc_axi_sf", "cpas_ahb", "camnoc_axi", "vfe2", "vfe2_axi" },
1990 .clock_rate = { { 0 },
1991 { 0 },
1992 { 19200000, 80000000},
1993 { 19200000, 150000000, 266666667, 320000000, 400000000, 480000000 },
1994 { 400000000, 558000000, 637000000, 760000000 },
1995 { 0 }, },
1996 .reg = { "vfe2" },
1997 .interrupt = { "vfe2" },
1998 .vfe = {
1999 .line_num = 4,
2000 .pd_name = "ife2",
2001 .hw_ops = &vfe_ops_170,
2002 .formats_rdi = &vfe_formats_rdi_845,
2003 .formats_pix = &vfe_formats_pix_845
2004 }
2005 },
2006 /* VFE3 */
2007 {
2008 .regulators = {},
2009 .clock = { "gcc_axi_hf", "gcc_axi_sf", "cpas_ahb", "camnoc_axi", "vfe3", "vfe3_axi" },
2010 .clock_rate = { { 0 },
2011 { 0 },
2012 { 19200000, 80000000},
2013 { 19200000, 150000000, 266666667, 320000000, 400000000, 480000000 },
2014 { 400000000, 558000000, 637000000, 760000000 },
2015 { 0 }, },
2016 .reg = { "vfe3" },
2017 .interrupt = { "vfe3" },
2018 .vfe = {
2019 .line_num = 4,
2020 .pd_name = "ife3",
2021 .hw_ops = &vfe_ops_170,
2022 .formats_rdi = &vfe_formats_rdi_845,
2023 .formats_pix = &vfe_formats_pix_845
2024 }
2025 },
2026 /* VFE_LITE_0 */
2027 {
2028 .regulators = {},
2029 .clock = { "gcc_axi_hf", "gcc_axi_sf", "cpas_ahb", "camnoc_axi", "vfe_lite0" },
2030 .clock_rate = { { 0 },
2031 { 0 },
2032 { 19200000, 80000000},
2033 { 19200000, 150000000, 266666667, 320000000, 400000000, 480000000 },
2034 { 320000000, 400000000, 480000000, 600000000 }, },
2035 .reg = { "vfe_lite0" },
2036 .interrupt = { "vfe_lite0" },
2037 .vfe = {
2038 .is_lite = true,
2039 .line_num = 4,
2040 .hw_ops = &vfe_ops_170,
2041 .formats_rdi = &vfe_formats_rdi_845,
2042 .formats_pix = &vfe_formats_pix_845
2043 }
2044 },
2045 /* VFE_LITE_1 */
2046 {
2047 .regulators = {},
2048 .clock = { "gcc_axi_hf", "gcc_axi_sf", "cpas_ahb", "camnoc_axi", "vfe_lite1" },
2049 .clock_rate = { { 0 },
2050 { 0 },
2051 { 19200000, 80000000},
2052 { 19200000, 150000000, 266666667, 320000000, 400000000, 480000000 },
2053 { 320000000, 400000000, 480000000, 600000000 }, },
2054 .reg = { "vfe_lite1" },
2055 .interrupt = { "vfe_lite1" },
2056 .vfe = {
2057 .is_lite = true,
2058 .line_num = 4,
2059 .hw_ops = &vfe_ops_170,
2060 .formats_rdi = &vfe_formats_rdi_845,
2061 .formats_pix = &vfe_formats_pix_845
2062 }
2063 },
2064 /* VFE_LITE_2 */
2065 {
2066 .regulators = {},
2067 .clock = { "gcc_axi_hf", "gcc_axi_sf", "cpas_ahb", "camnoc_axi", "vfe_lite2" },
2068 .clock_rate = { { 0 },
2069 { 0 },
2070 { 19200000, 80000000},
2071 { 19200000, 150000000, 266666667, 320000000, 400000000, 480000000 },
2072 { 320000000, 400000000, 480000000, 600000000, }, },
2073 .reg = { "vfe_lite2" },
2074 .interrupt = { "vfe_lite2" },
2075 .vfe = {
2076 .is_lite = true,
2077 .line_num = 4,
2078 .hw_ops = &vfe_ops_170,
2079 .formats_rdi = &vfe_formats_rdi_845,
2080 .formats_pix = &vfe_formats_pix_845
2081 }
2082 },
2083 /* VFE_LITE_3 */
2084 {
2085 .regulators = {},
2086 .clock = { "gcc_axi_hf", "gcc_axi_sf", "cpas_ahb", "camnoc_axi", "vfe_lite3" },
2087 .clock_rate = { { 0 },
2088 { 0 },
2089 { 19200000, 80000000},
2090 { 19200000, 150000000, 266666667, 320000000, 400000000, 480000000 },
2091 { 320000000, 400000000, 480000000, 600000000 }, },
2092 .reg = { "vfe_lite3" },
2093 .interrupt = { "vfe_lite3" },
2094 .vfe = {
2095 .is_lite = true,
2096 .line_num = 4,
2097 .hw_ops = &vfe_ops_170,
2098 .formats_rdi = &vfe_formats_rdi_845,
2099 .formats_pix = &vfe_formats_pix_845
2100 }
2101 },
2102 };
2103
2104 static const struct resources_icc icc_res_sc8280xp[] = {
2105 {
2106 .name = "cam_ahb",
2107 .icc_bw_tbl.avg = 150000,
2108 .icc_bw_tbl.peak = 300000,
2109 },
2110 {
2111 .name = "cam_hf_mnoc",
2112 .icc_bw_tbl.avg = 2097152,
2113 .icc_bw_tbl.peak = 2097152,
2114 },
2115 {
2116 .name = "cam_sf_mnoc",
2117 .icc_bw_tbl.avg = 2097152,
2118 .icc_bw_tbl.peak = 2097152,
2119 },
2120 {
2121 .name = "cam_sf_icp_mnoc",
2122 .icc_bw_tbl.avg = 2097152,
2123 .icc_bw_tbl.peak = 2097152,
2124 },
2125 };
2126
2127 static const struct camss_subdev_resources csiphy_res_8550[] = {
2128 /* CSIPHY0 */
2129 {
2130 .regulators = { "vdda-phy", "vdda-pll" },
2131 .clock = { "csiphy0", "csiphy0_timer" },
2132 .clock_rate = { { 400000000, 480000000 },
2133 { 400000000 } },
2134 .reg = { "csiphy0" },
2135 .interrupt = { "csiphy0" },
2136 .csiphy = {
2137 .hw_ops = &csiphy_ops_3ph_1_0,
2138 .formats = &csiphy_formats_sdm845
2139 }
2140 },
2141 /* CSIPHY1 */
2142 {
2143 .regulators = { "vdda-phy", "vdda-pll" },
2144 .clock = { "csiphy1", "csiphy1_timer" },
2145 .clock_rate = { { 400000000, 480000000 },
2146 { 400000000 } },
2147 .reg = { "csiphy1" },
2148 .interrupt = { "csiphy1" },
2149 .csiphy = {
2150 .hw_ops = &csiphy_ops_3ph_1_0,
2151 .formats = &csiphy_formats_sdm845
2152 }
2153 },
2154 /* CSIPHY2 */
2155 {
2156 .regulators = { "vdda-phy", "vdda-pll" },
2157 .clock = { "csiphy2", "csiphy2_timer" },
2158 .clock_rate = { { 400000000, 480000000 },
2159 { 400000000 } },
2160 .reg = { "csiphy2" },
2161 .interrupt = { "csiphy2" },
2162 .csiphy = {
2163 .hw_ops = &csiphy_ops_3ph_1_0,
2164 .formats = &csiphy_formats_sdm845
2165 }
2166 },
2167 /* CSIPHY3 */
2168 {
2169 .regulators = { "vdda-phy", "vdda-pll" },
2170 .clock = { "csiphy3", "csiphy3_timer" },
2171 .clock_rate = { { 400000000, 480000000 },
2172 { 400000000 } },
2173 .reg = { "csiphy3" },
2174 .interrupt = { "csiphy3" },
2175 .csiphy = {
2176 .hw_ops = &csiphy_ops_3ph_1_0,
2177 .formats = &csiphy_formats_sdm845
2178 }
2179 },
2180 /* CSIPHY4 */
2181 {
2182 .regulators = { "vdda-phy", "vdda-pll" },
2183 .clock = { "csiphy4", "csiphy4_timer" },
2184 .clock_rate = { { 400000000, 480000000 },
2185 { 400000000 } },
2186 .reg = { "csiphy4" },
2187 .interrupt = { "csiphy4" },
2188 .csiphy = {
2189 .hw_ops = &csiphy_ops_3ph_1_0,
2190 .formats = &csiphy_formats_sdm845
2191 }
2192 },
2193 /* CSIPHY5 */
2194 {
2195 .regulators = { "vdda-phy", "vdda-pll" },
2196 .clock = { "csiphy5", "csiphy5_timer" },
2197 .clock_rate = { { 400000000, 480000000 },
2198 { 400000000 } },
2199 .reg = { "csiphy5" },
2200 .interrupt = { "csiphy5" },
2201 .csiphy = {
2202 .hw_ops = &csiphy_ops_3ph_1_0,
2203 .formats = &csiphy_formats_sdm845
2204 }
2205 },
2206 /* CSIPHY6 */
2207 {
2208 .regulators = { "vdda-phy", "vdda-pll" },
2209 .clock = { "csiphy6", "csiphy6_timer" },
2210 .clock_rate = { { 400000000, 480000000 },
2211 { 400000000 } },
2212 .reg = { "csiphy6" },
2213 .interrupt = { "csiphy6" },
2214 .csiphy = {
2215 .hw_ops = &csiphy_ops_3ph_1_0,
2216 .formats = &csiphy_formats_sdm845
2217 }
2218 },
2219 /* CSIPHY7 */
2220 {
2221 .regulators = { "vdda-phy", "vdda-pll" },
2222 .clock = { "csiphy7", "csiphy7_timer" },
2223 .clock_rate = { { 400000000, 480000000 },
2224 { 400000000 } },
2225 .reg = { "csiphy7" },
2226 .interrupt = { "csiphy7" },
2227 .csiphy = {
2228 .hw_ops = &csiphy_ops_3ph_1_0,
2229 .formats = &csiphy_formats_sdm845
2230 }
2231 }
2232 };
2233
2234 static const struct resources_wrapper csid_wrapper_res_sm8550 = {
2235 .reg = "csid_wrapper",
2236 };
2237
2238 static const struct camss_subdev_resources csid_res_8550[] = {
2239 /* CSID0 */
2240 {
2241 .regulators = {},
2242 .clock = { "csid", "csiphy_rx" },
2243 .clock_rate = { { 400000000, 480000000 },
2244 { 400000000, 480000000 } },
2245 .reg = { "csid0" },
2246 .interrupt = { "csid0" },
2247 .csid = {
2248 .is_lite = false,
2249 .parent_dev_ops = &vfe_parent_dev_ops,
2250 .hw_ops = &csid_ops_780,
2251 .formats = &csid_formats_gen2
2252 }
2253 },
2254 /* CSID1 */
2255 {
2256 .regulators = {},
2257 .clock = { "csid", "csiphy_rx" },
2258 .clock_rate = { { 400000000, 480000000 },
2259 { 400000000, 480000000 } },
2260 .reg = { "csid1" },
2261 .interrupt = { "csid1" },
2262 .csid = {
2263 .is_lite = false,
2264 .parent_dev_ops = &vfe_parent_dev_ops,
2265 .hw_ops = &csid_ops_780,
2266 .formats = &csid_formats_gen2
2267 }
2268 },
2269 /* CSID2 */
2270 {
2271 .regulators = {},
2272 .clock = { "csid", "csiphy_rx" },
2273 .clock_rate = { { 400000000, 480000000 },
2274 { 400000000, 480000000 } },
2275 .reg = { "csid2" },
2276 .interrupt = { "csid2" },
2277 .csid = {
2278 .is_lite = false,
2279 .parent_dev_ops = &vfe_parent_dev_ops,
2280 .hw_ops = &csid_ops_780,
2281 .formats = &csid_formats_gen2
2282 }
2283 },
2284 /* CSID3 */
2285 {
2286 .regulators = {},
2287 .clock = { "vfe_lite_csid", "vfe_lite_cphy_rx" },
2288 .clock_rate = { { 400000000, 480000000 },
2289 { 400000000, 480000000 } },
2290 .reg = { "csid_lite0" },
2291 .interrupt = { "csid_lite0" },
2292 .csid = {
2293 .is_lite = true,
2294 .parent_dev_ops = &vfe_parent_dev_ops,
2295 .hw_ops = &csid_ops_780,
2296 .formats = &csid_formats_gen2
2297 }
2298 },
2299 /* CSID4 */
2300 {
2301 .regulators = {},
2302 .clock = { "vfe_lite_csid", "vfe_lite_cphy_rx" },
2303 .clock_rate = { { 400000000, 480000000 },
2304 { 400000000, 480000000 } },
2305 .reg = { "csid_lite1" },
2306 .interrupt = { "csid_lite1" },
2307 .csid = {
2308 .is_lite = true,
2309 .parent_dev_ops = &vfe_parent_dev_ops,
2310 .hw_ops = &csid_ops_780,
2311 .formats = &csid_formats_gen2
2312 }
2313 }
2314 };
2315
2316 static const struct camss_subdev_resources vfe_res_8550[] = {
2317 /* VFE0 */
2318 {
2319 .regulators = {},
2320 .clock = { "gcc_axi_hf", "cpas_ahb", "cpas_fast_ahb_clk", "vfe0_fast_ahb",
2321 "vfe0", "cpas_vfe0", "camnoc_axi" },
2322 .clock_rate = { { 0 },
2323 { 80000000 },
2324 { 300000000, 400000000 },
2325 { 300000000, 400000000 },
2326 { 466000000, 594000000, 675000000, 785000000 },
2327 { 300000000, 400000000 },
2328 { 300000000, 400000000 } },
2329 .reg = { "vfe0" },
2330 .interrupt = { "vfe0" },
2331 .vfe = {
2332 .line_num = 3,
2333 .is_lite = false,
2334 .has_pd = true,
2335 .pd_name = "ife0",
2336 .hw_ops = &vfe_ops_780,
2337 .formats_rdi = &vfe_formats_rdi_845,
2338 .formats_pix = &vfe_formats_pix_845
2339 }
2340 },
2341 /* VFE1 */
2342 {
2343 .regulators = {},
2344 .clock = { "gcc_axi_hf", "cpas_ahb", "cpas_fast_ahb_clk", "vfe1_fast_ahb",
2345 "vfe1", "cpas_vfe1", "camnoc_axi" },
2346 .clock_rate = { { 0 },
2347 { 80000000 },
2348 { 300000000, 400000000 },
2349 { 300000000, 400000000 },
2350 { 466000000, 594000000, 675000000, 785000000 },
2351 { 300000000, 400000000 },
2352 { 300000000, 400000000 } },
2353 .reg = { "vfe1" },
2354 .interrupt = { "vfe1" },
2355 .vfe = {
2356 .line_num = 3,
2357 .is_lite = false,
2358 .has_pd = true,
2359 .pd_name = "ife1",
2360 .hw_ops = &vfe_ops_780,
2361 .formats_rdi = &vfe_formats_rdi_845,
2362 .formats_pix = &vfe_formats_pix_845
2363 }
2364 },
2365 /* VFE2 */
2366 {
2367 .regulators = {},
2368 .clock = { "gcc_axi_hf", "cpas_ahb", "cpas_fast_ahb_clk", "vfe2_fast_ahb",
2369 "vfe2", "cpas_vfe2", "camnoc_axi" },
2370 .clock_rate = { { 0 },
2371 { 80000000 },
2372 { 300000000, 400000000 },
2373 { 300000000, 400000000 },
2374 { 466000000, 594000000, 675000000, 785000000 },
2375 { 300000000, 400000000 },
2376 { 300000000, 400000000 } },
2377 .reg = { "vfe2" },
2378 .interrupt = { "vfe2" },
2379 .vfe = {
2380 .line_num = 3,
2381 .is_lite = false,
2382 .has_pd = true,
2383 .pd_name = "ife2",
2384 .hw_ops = &vfe_ops_780,
2385 .formats_rdi = &vfe_formats_rdi_845,
2386 .formats_pix = &vfe_formats_pix_845
2387 }
2388 },
2389 /* VFE3 lite */
2390 {
2391 .regulators = {},
2392 .clock = { "gcc_axi_hf", "cpas_ahb", "cpas_fast_ahb_clk", "vfe_lite_ahb",
2393 "vfe_lite", "cpas_ife_lite", "camnoc_axi" },
2394 .clock_rate = { { 0 },
2395 { 80000000 },
2396 { 300000000, 400000000 },
2397 { 300000000, 400000000 },
2398 { 400000000, 480000000 },
2399 { 300000000, 400000000 },
2400 { 300000000, 400000000 } },
2401 .reg = { "vfe_lite0" },
2402 .interrupt = { "vfe_lite0" },
2403 .vfe = {
2404 .line_num = 4,
2405 .is_lite = true,
2406 .hw_ops = &vfe_ops_780,
2407 .formats_rdi = &vfe_formats_rdi_845,
2408 .formats_pix = &vfe_formats_pix_845
2409 }
2410 },
2411 /* VFE4 lite */
2412 {
2413 .regulators = {},
2414 .clock = { "gcc_axi_hf", "cpas_ahb", "cpas_fast_ahb_clk", "vfe_lite_ahb",
2415 "vfe_lite", "cpas_ife_lite", "camnoc_axi" },
2416 .clock_rate = { { 0 },
2417 { 80000000 },
2418 { 300000000, 400000000 },
2419 { 300000000, 400000000 },
2420 { 400000000, 480000000 },
2421 { 300000000, 400000000 },
2422 { 300000000, 400000000 } },
2423 .reg = { "vfe_lite1" },
2424 .interrupt = { "vfe_lite1" },
2425 .vfe = {
2426 .line_num = 4,
2427 .is_lite = true,
2428 .hw_ops = &vfe_ops_780,
2429 .formats_rdi = &vfe_formats_rdi_845,
2430 .formats_pix = &vfe_formats_pix_845
2431 }
2432 },
2433 };
2434
2435 static const struct resources_icc icc_res_sm8550[] = {
2436 {
2437 .name = "ahb",
2438 .icc_bw_tbl.avg = 2097152,
2439 .icc_bw_tbl.peak = 2097152,
2440 },
2441 {
2442 .name = "hf_0_mnoc",
2443 .icc_bw_tbl.avg = 2097152,
2444 .icc_bw_tbl.peak = 2097152,
2445 },
2446 };
2447
2448 /*
2449 * camss_add_clock_margin - Add margin to clock frequency rate
2450 * @rate: Clock frequency rate
2451 *
2452 * When making calculations with physical clock frequency values
2453 * some safety margin must be added. Add it.
2454 */
camss_add_clock_margin(u64 * rate)2455 inline void camss_add_clock_margin(u64 *rate)
2456 {
2457 *rate *= CAMSS_CLOCK_MARGIN_NUMERATOR;
2458 *rate = div_u64(*rate, CAMSS_CLOCK_MARGIN_DENOMINATOR);
2459 }
2460
2461 /*
2462 * camss_enable_clocks - Enable multiple clocks
2463 * @nclocks: Number of clocks in clock array
2464 * @clock: Clock array
2465 * @dev: Device
2466 *
2467 * Return 0 on success or a negative error code otherwise
2468 */
camss_enable_clocks(int nclocks,struct camss_clock * clock,struct device * dev)2469 int camss_enable_clocks(int nclocks, struct camss_clock *clock,
2470 struct device *dev)
2471 {
2472 int ret;
2473 int i;
2474
2475 for (i = 0; i < nclocks; i++) {
2476 ret = clk_prepare_enable(clock[i].clk);
2477 if (ret) {
2478 dev_err(dev, "clock enable failed: %d\n", ret);
2479 goto error;
2480 }
2481 }
2482
2483 return 0;
2484
2485 error:
2486 for (i--; i >= 0; i--)
2487 clk_disable_unprepare(clock[i].clk);
2488
2489 return ret;
2490 }
2491
2492 /*
2493 * camss_disable_clocks - Disable multiple clocks
2494 * @nclocks: Number of clocks in clock array
2495 * @clock: Clock array
2496 */
camss_disable_clocks(int nclocks,struct camss_clock * clock)2497 void camss_disable_clocks(int nclocks, struct camss_clock *clock)
2498 {
2499 int i;
2500
2501 for (i = nclocks - 1; i >= 0; i--)
2502 clk_disable_unprepare(clock[i].clk);
2503 }
2504
2505 /*
2506 * camss_find_sensor_pad - Find the media pad via which the sensor is linked
2507 * @entity: Media entity to start searching from
2508 *
2509 * Return a pointer to sensor media pad or NULL if not found
2510 */
camss_find_sensor_pad(struct media_entity * entity)2511 struct media_pad *camss_find_sensor_pad(struct media_entity *entity)
2512 {
2513 struct media_pad *pad;
2514
2515 while (1) {
2516 pad = &entity->pads[0];
2517 if (!(pad->flags & MEDIA_PAD_FL_SINK))
2518 return NULL;
2519
2520 pad = media_pad_remote_pad_first(pad);
2521 if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
2522 return NULL;
2523
2524 entity = pad->entity;
2525
2526 if (entity->function == MEDIA_ENT_F_CAM_SENSOR)
2527 return pad;
2528 }
2529 }
2530
2531 /**
2532 * camss_get_link_freq - Get link frequency from sensor
2533 * @entity: Media entity in the current pipeline
2534 * @bpp: Number of bits per pixel for the current format
2535 * @lanes: Number of lanes in the link to the sensor
2536 *
2537 * Return link frequency on success or a negative error code otherwise
2538 */
camss_get_link_freq(struct media_entity * entity,unsigned int bpp,unsigned int lanes)2539 s64 camss_get_link_freq(struct media_entity *entity, unsigned int bpp,
2540 unsigned int lanes)
2541 {
2542 struct media_pad *sensor_pad;
2543
2544 sensor_pad = camss_find_sensor_pad(entity);
2545 if (!sensor_pad)
2546 return -ENODEV;
2547
2548 return v4l2_get_link_freq(sensor_pad, bpp, 2 * lanes);
2549 }
2550
2551 /*
2552 * camss_get_pixel_clock - Get pixel clock rate from sensor
2553 * @entity: Media entity in the current pipeline
2554 * @pixel_clock: Received pixel clock value
2555 *
2556 * Return 0 on success or a negative error code otherwise
2557 */
camss_get_pixel_clock(struct media_entity * entity,u64 * pixel_clock)2558 int camss_get_pixel_clock(struct media_entity *entity, u64 *pixel_clock)
2559 {
2560 struct media_pad *sensor_pad;
2561 struct v4l2_subdev *subdev;
2562 struct v4l2_ctrl *ctrl;
2563
2564 sensor_pad = camss_find_sensor_pad(entity);
2565 if (!sensor_pad)
2566 return -ENODEV;
2567
2568 subdev = media_entity_to_v4l2_subdev(sensor_pad->entity);
2569
2570 ctrl = v4l2_ctrl_find(subdev->ctrl_handler, V4L2_CID_PIXEL_RATE);
2571
2572 if (!ctrl)
2573 return -EINVAL;
2574
2575 *pixel_clock = v4l2_ctrl_g_ctrl_int64(ctrl);
2576
2577 return 0;
2578 }
2579
camss_pm_domain_on(struct camss * camss,int id)2580 int camss_pm_domain_on(struct camss *camss, int id)
2581 {
2582 int ret = 0;
2583
2584 if (id < camss->res->vfe_num) {
2585 struct vfe_device *vfe = &camss->vfe[id];
2586
2587 ret = vfe->res->hw_ops->pm_domain_on(vfe);
2588 }
2589
2590 return ret;
2591 }
2592
camss_pm_domain_off(struct camss * camss,int id)2593 void camss_pm_domain_off(struct camss *camss, int id)
2594 {
2595 if (id < camss->res->vfe_num) {
2596 struct vfe_device *vfe = &camss->vfe[id];
2597
2598 vfe->res->hw_ops->pm_domain_off(vfe);
2599 }
2600 }
2601
vfe_parent_dev_ops_get(struct camss * camss,int id)2602 static int vfe_parent_dev_ops_get(struct camss *camss, int id)
2603 {
2604 int ret = -EINVAL;
2605
2606 if (id < camss->res->vfe_num) {
2607 struct vfe_device *vfe = &camss->vfe[id];
2608
2609 ret = vfe_get(vfe);
2610 }
2611
2612 return ret;
2613 }
2614
vfe_parent_dev_ops_put(struct camss * camss,int id)2615 static int vfe_parent_dev_ops_put(struct camss *camss, int id)
2616 {
2617 if (id < camss->res->vfe_num) {
2618 struct vfe_device *vfe = &camss->vfe[id];
2619
2620 vfe_put(vfe);
2621 }
2622
2623 return 0;
2624 }
2625
2626 static void __iomem
vfe_parent_dev_ops_get_base_address(struct camss * camss,int id)2627 *vfe_parent_dev_ops_get_base_address(struct camss *camss, int id)
2628 {
2629 if (id < camss->res->vfe_num) {
2630 struct vfe_device *vfe = &camss->vfe[id];
2631
2632 return vfe->base;
2633 }
2634
2635 return NULL;
2636 }
2637
2638 static const struct parent_dev_ops vfe_parent_dev_ops = {
2639 .get = vfe_parent_dev_ops_get,
2640 .put = vfe_parent_dev_ops_put,
2641 .get_base_address = vfe_parent_dev_ops_get_base_address
2642 };
2643
2644 /*
2645 * camss_of_parse_endpoint_node - Parse port endpoint node
2646 * @dev: Device
2647 * @node: Device node to be parsed
2648 * @csd: Parsed data from port endpoint node
2649 *
2650 * Return 0 on success or a negative error code on failure
2651 */
camss_of_parse_endpoint_node(struct device * dev,struct device_node * node,struct camss_async_subdev * csd)2652 static int camss_of_parse_endpoint_node(struct device *dev,
2653 struct device_node *node,
2654 struct camss_async_subdev *csd)
2655 {
2656 struct csiphy_lanes_cfg *lncfg = &csd->interface.csi2.lane_cfg;
2657 struct v4l2_mbus_config_mipi_csi2 *mipi_csi2;
2658 struct v4l2_fwnode_endpoint vep = { { 0 } };
2659 unsigned int i;
2660 int ret;
2661
2662 ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(node), &vep);
2663 if (ret)
2664 return ret;
2665
2666 csd->interface.csiphy_id = vep.base.port;
2667
2668 mipi_csi2 = &vep.bus.mipi_csi2;
2669 lncfg->clk.pos = mipi_csi2->clock_lane;
2670 lncfg->clk.pol = mipi_csi2->lane_polarities[0];
2671 lncfg->num_data = mipi_csi2->num_data_lanes;
2672
2673 lncfg->data = devm_kcalloc(dev,
2674 lncfg->num_data, sizeof(*lncfg->data),
2675 GFP_KERNEL);
2676 if (!lncfg->data)
2677 return -ENOMEM;
2678
2679 for (i = 0; i < lncfg->num_data; i++) {
2680 lncfg->data[i].pos = mipi_csi2->data_lanes[i];
2681 lncfg->data[i].pol = mipi_csi2->lane_polarities[i + 1];
2682 }
2683
2684 return 0;
2685 }
2686
2687 /*
2688 * camss_of_parse_ports - Parse ports node
2689 * @dev: Device
2690 * @notifier: v4l2_device notifier data
2691 *
2692 * Return number of "port" nodes found in "ports" node
2693 */
camss_of_parse_ports(struct camss * camss)2694 static int camss_of_parse_ports(struct camss *camss)
2695 {
2696 struct device *dev = camss->dev;
2697 struct device_node *node = NULL;
2698 struct device_node *remote = NULL;
2699 int ret, num_subdevs = 0;
2700
2701 for_each_endpoint_of_node(dev->of_node, node) {
2702 struct camss_async_subdev *csd;
2703
2704 if (!of_device_is_available(node))
2705 continue;
2706
2707 remote = of_graph_get_remote_port_parent(node);
2708 if (!remote) {
2709 dev_err(dev, "Cannot get remote parent\n");
2710 ret = -EINVAL;
2711 goto err_cleanup;
2712 }
2713
2714 csd = v4l2_async_nf_add_fwnode(&camss->notifier,
2715 of_fwnode_handle(remote),
2716 struct camss_async_subdev);
2717 of_node_put(remote);
2718 if (IS_ERR(csd)) {
2719 ret = PTR_ERR(csd);
2720 goto err_cleanup;
2721 }
2722
2723 ret = camss_of_parse_endpoint_node(dev, node, csd);
2724 if (ret < 0)
2725 goto err_cleanup;
2726
2727 num_subdevs++;
2728 }
2729
2730 return num_subdevs;
2731
2732 err_cleanup:
2733 of_node_put(node);
2734 return ret;
2735 }
2736
2737 /*
2738 * camss_init_subdevices - Initialize subdev structures and resources
2739 * @camss: CAMSS device
2740 *
2741 * Return 0 on success or a negative error code on failure
2742 */
camss_init_subdevices(struct camss * camss)2743 static int camss_init_subdevices(struct camss *camss)
2744 {
2745 struct platform_device *pdev = to_platform_device(camss->dev);
2746 const struct camss_resources *res = camss->res;
2747 unsigned int i;
2748 int ret;
2749
2750 for (i = 0; i < camss->res->csiphy_num; i++) {
2751 ret = msm_csiphy_subdev_init(camss, &camss->csiphy[i],
2752 &res->csiphy_res[i], i);
2753 if (ret < 0) {
2754 dev_err(camss->dev,
2755 "Failed to init csiphy%d sub-device: %d\n",
2756 i, ret);
2757 return ret;
2758 }
2759 }
2760
2761 /* note: SM8250 requires VFE to be initialized before CSID */
2762 for (i = 0; i < camss->res->vfe_num; i++) {
2763 ret = msm_vfe_subdev_init(camss, &camss->vfe[i],
2764 &res->vfe_res[i], i);
2765 if (ret < 0) {
2766 dev_err(camss->dev,
2767 "Fail to init vfe%d sub-device: %d\n", i, ret);
2768 return ret;
2769 }
2770 }
2771
2772 /* Get optional CSID wrapper regs shared between CSID devices */
2773 if (res->csid_wrapper_res) {
2774 char *reg = res->csid_wrapper_res->reg;
2775 void __iomem *base;
2776
2777 base = devm_platform_ioremap_resource_byname(pdev, reg);
2778 if (IS_ERR(base))
2779 return PTR_ERR(base);
2780 camss->csid_wrapper_base = base;
2781 }
2782
2783 for (i = 0; i < camss->res->csid_num; i++) {
2784 ret = msm_csid_subdev_init(camss, &camss->csid[i],
2785 &res->csid_res[i], i);
2786 if (ret < 0) {
2787 dev_err(camss->dev,
2788 "Failed to init csid%d sub-device: %d\n",
2789 i, ret);
2790 return ret;
2791 }
2792 }
2793
2794 ret = msm_ispif_subdev_init(camss, res->ispif_res);
2795 if (ret < 0) {
2796 dev_err(camss->dev, "Failed to init ispif sub-device: %d\n",
2797 ret);
2798 return ret;
2799 }
2800
2801 return 0;
2802 }
2803
2804 /*
2805 * camss_link_entities - Register subdev nodes and create links
2806 * camss_link_err - print error in case link creation fails
2807 * @src_name: name for source of the link
2808 * @sink_name: name for sink of the link
2809 */
camss_link_err(struct camss * camss,const char * src_name,const char * sink_name,int ret)2810 inline void camss_link_err(struct camss *camss,
2811 const char *src_name,
2812 const char *sink_name,
2813 int ret)
2814 {
2815 dev_err(camss->dev,
2816 "Failed to link %s->%s entities: %d\n",
2817 src_name,
2818 sink_name,
2819 ret);
2820 }
2821
2822 /*
2823 * camss_link_entities - Register subdev nodes and create links
2824 * @camss: CAMSS device
2825 *
2826 * Return 0 on success or a negative error code on failure
2827 */
camss_link_entities(struct camss * camss)2828 static int camss_link_entities(struct camss *camss)
2829 {
2830 int i, j, k;
2831 int ret;
2832
2833 for (i = 0; i < camss->res->csiphy_num; i++) {
2834 for (j = 0; j < camss->res->csid_num; j++) {
2835 ret = media_create_pad_link(&camss->csiphy[i].subdev.entity,
2836 MSM_CSIPHY_PAD_SRC,
2837 &camss->csid[j].subdev.entity,
2838 MSM_CSID_PAD_SINK,
2839 0);
2840 if (ret < 0) {
2841 camss_link_err(camss,
2842 camss->csiphy[i].subdev.entity.name,
2843 camss->csid[j].subdev.entity.name,
2844 ret);
2845 return ret;
2846 }
2847 }
2848 }
2849
2850 if (camss->ispif) {
2851 for (i = 0; i < camss->res->csid_num; i++) {
2852 for (j = 0; j < camss->ispif->line_num; j++) {
2853 ret = media_create_pad_link(&camss->csid[i].subdev.entity,
2854 MSM_CSID_PAD_SRC,
2855 &camss->ispif->line[j].subdev.entity,
2856 MSM_ISPIF_PAD_SINK,
2857 0);
2858 if (ret < 0) {
2859 camss_link_err(camss,
2860 camss->csid[i].subdev.entity.name,
2861 camss->ispif->line[j].subdev.entity.name,
2862 ret);
2863 return ret;
2864 }
2865 }
2866 }
2867
2868 for (i = 0; i < camss->ispif->line_num; i++)
2869 for (k = 0; k < camss->res->vfe_num; k++)
2870 for (j = 0; j < camss->vfe[k].res->line_num; j++) {
2871 struct v4l2_subdev *ispif = &camss->ispif->line[i].subdev;
2872 struct v4l2_subdev *vfe = &camss->vfe[k].line[j].subdev;
2873
2874 ret = media_create_pad_link(&ispif->entity,
2875 MSM_ISPIF_PAD_SRC,
2876 &vfe->entity,
2877 MSM_VFE_PAD_SINK,
2878 0);
2879 if (ret < 0) {
2880 camss_link_err(camss, ispif->entity.name,
2881 vfe->entity.name,
2882 ret);
2883 return ret;
2884 }
2885 }
2886 } else {
2887 for (i = 0; i < camss->res->csid_num; i++)
2888 for (k = 0; k < camss->res->vfe_num; k++)
2889 for (j = 0; j < camss->vfe[k].res->line_num; j++) {
2890 struct v4l2_subdev *csid = &camss->csid[i].subdev;
2891 struct v4l2_subdev *vfe = &camss->vfe[k].line[j].subdev;
2892
2893 ret = media_create_pad_link(&csid->entity,
2894 MSM_CSID_PAD_FIRST_SRC + j,
2895 &vfe->entity,
2896 MSM_VFE_PAD_SINK,
2897 0);
2898 if (ret < 0) {
2899 camss_link_err(camss, csid->entity.name,
2900 vfe->entity.name,
2901 ret);
2902 return ret;
2903 }
2904 }
2905 }
2906
2907 return 0;
2908 }
2909
camss_reg_update(struct camss * camss,int hw_id,int port_id,bool is_clear)2910 void camss_reg_update(struct camss *camss, int hw_id, int port_id, bool is_clear)
2911 {
2912 struct csid_device *csid;
2913
2914 if (hw_id < camss->res->csid_num) {
2915 csid = &camss->csid[hw_id];
2916
2917 csid->res->hw_ops->reg_update(csid, port_id, is_clear);
2918 }
2919 }
2920
camss_buf_done(struct camss * camss,int hw_id,int port_id)2921 void camss_buf_done(struct camss *camss, int hw_id, int port_id)
2922 {
2923 struct vfe_device *vfe;
2924
2925 if (hw_id < camss->res->vfe_num) {
2926 vfe = &camss->vfe[hw_id];
2927
2928 vfe->res->hw_ops->vfe_buf_done(vfe, port_id);
2929 }
2930 }
2931
2932 /*
2933 * camss_register_entities - Register subdev nodes and create links
2934 * @camss: CAMSS device
2935 *
2936 * Return 0 on success or a negative error code on failure
2937 */
camss_register_entities(struct camss * camss)2938 static int camss_register_entities(struct camss *camss)
2939 {
2940 int i;
2941 int ret;
2942
2943 for (i = 0; i < camss->res->csiphy_num; i++) {
2944 ret = msm_csiphy_register_entity(&camss->csiphy[i],
2945 &camss->v4l2_dev);
2946 if (ret < 0) {
2947 dev_err(camss->dev,
2948 "Failed to register csiphy%d entity: %d\n",
2949 i, ret);
2950 goto err_reg_csiphy;
2951 }
2952 }
2953
2954 for (i = 0; i < camss->res->csid_num; i++) {
2955 ret = msm_csid_register_entity(&camss->csid[i],
2956 &camss->v4l2_dev);
2957 if (ret < 0) {
2958 dev_err(camss->dev,
2959 "Failed to register csid%d entity: %d\n",
2960 i, ret);
2961 goto err_reg_csid;
2962 }
2963 }
2964
2965 ret = msm_ispif_register_entities(camss->ispif,
2966 &camss->v4l2_dev);
2967 if (ret < 0) {
2968 dev_err(camss->dev, "Failed to register ispif entities: %d\n", ret);
2969 goto err_reg_ispif;
2970 }
2971
2972 for (i = 0; i < camss->res->vfe_num; i++) {
2973 ret = msm_vfe_register_entities(&camss->vfe[i],
2974 &camss->v4l2_dev);
2975 if (ret < 0) {
2976 dev_err(camss->dev,
2977 "Failed to register vfe%d entities: %d\n",
2978 i, ret);
2979 goto err_reg_vfe;
2980 }
2981 }
2982
2983 return 0;
2984
2985 err_reg_vfe:
2986 for (i--; i >= 0; i--)
2987 msm_vfe_unregister_entities(&camss->vfe[i]);
2988
2989 err_reg_ispif:
2990 msm_ispif_unregister_entities(camss->ispif);
2991
2992 i = camss->res->csid_num;
2993 err_reg_csid:
2994 for (i--; i >= 0; i--)
2995 msm_csid_unregister_entity(&camss->csid[i]);
2996
2997 i = camss->res->csiphy_num;
2998 err_reg_csiphy:
2999 for (i--; i >= 0; i--)
3000 msm_csiphy_unregister_entity(&camss->csiphy[i]);
3001
3002 return ret;
3003 }
3004
3005 /*
3006 * camss_unregister_entities - Unregister subdev nodes
3007 * @camss: CAMSS device
3008 *
3009 * Return 0 on success or a negative error code on failure
3010 */
camss_unregister_entities(struct camss * camss)3011 static void camss_unregister_entities(struct camss *camss)
3012 {
3013 unsigned int i;
3014
3015 for (i = 0; i < camss->res->csiphy_num; i++)
3016 msm_csiphy_unregister_entity(&camss->csiphy[i]);
3017
3018 for (i = 0; i < camss->res->csid_num; i++)
3019 msm_csid_unregister_entity(&camss->csid[i]);
3020
3021 msm_ispif_unregister_entities(camss->ispif);
3022
3023 for (i = 0; i < camss->res->vfe_num; i++)
3024 msm_vfe_unregister_entities(&camss->vfe[i]);
3025 }
3026
camss_subdev_notifier_bound(struct v4l2_async_notifier * async,struct v4l2_subdev * subdev,struct v4l2_async_connection * asd)3027 static int camss_subdev_notifier_bound(struct v4l2_async_notifier *async,
3028 struct v4l2_subdev *subdev,
3029 struct v4l2_async_connection *asd)
3030 {
3031 struct camss *camss = container_of(async, struct camss, notifier);
3032 struct camss_async_subdev *csd =
3033 container_of(asd, struct camss_async_subdev, asd);
3034 u8 id = csd->interface.csiphy_id;
3035 struct csiphy_device *csiphy = &camss->csiphy[id];
3036
3037 csiphy->cfg.csi2 = &csd->interface.csi2;
3038 subdev->host_priv = csiphy;
3039
3040 return 0;
3041 }
3042
camss_subdev_notifier_complete(struct v4l2_async_notifier * async)3043 static int camss_subdev_notifier_complete(struct v4l2_async_notifier *async)
3044 {
3045 struct camss *camss = container_of(async, struct camss, notifier);
3046 struct v4l2_device *v4l2_dev = &camss->v4l2_dev;
3047 struct v4l2_subdev *sd;
3048 int ret;
3049
3050 list_for_each_entry(sd, &v4l2_dev->subdevs, list) {
3051 if (sd->host_priv) {
3052 struct media_entity *sensor = &sd->entity;
3053 struct csiphy_device *csiphy =
3054 (struct csiphy_device *) sd->host_priv;
3055 struct media_entity *input = &csiphy->subdev.entity;
3056 unsigned int i;
3057
3058 for (i = 0; i < sensor->num_pads; i++) {
3059 if (sensor->pads[i].flags & MEDIA_PAD_FL_SOURCE)
3060 break;
3061 }
3062 if (i == sensor->num_pads) {
3063 dev_err(camss->dev,
3064 "No source pad in external entity\n");
3065 return -EINVAL;
3066 }
3067
3068 ret = media_create_pad_link(sensor, i,
3069 input, MSM_CSIPHY_PAD_SINK,
3070 MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED);
3071 if (ret < 0) {
3072 camss_link_err(camss, sensor->name,
3073 input->name,
3074 ret);
3075 return ret;
3076 }
3077 }
3078 }
3079
3080 ret = v4l2_device_register_subdev_nodes(&camss->v4l2_dev);
3081 if (ret < 0)
3082 return ret;
3083
3084 return media_device_register(&camss->media_dev);
3085 }
3086
3087 static const struct v4l2_async_notifier_operations camss_subdev_notifier_ops = {
3088 .bound = camss_subdev_notifier_bound,
3089 .complete = camss_subdev_notifier_complete,
3090 };
3091
3092 static const struct media_device_ops camss_media_ops = {
3093 .link_notify = v4l2_pipeline_link_notify,
3094 };
3095
camss_configure_pd(struct camss * camss)3096 static int camss_configure_pd(struct camss *camss)
3097 {
3098 const struct camss_resources *res = camss->res;
3099 struct device *dev = camss->dev;
3100 int vfepd_num;
3101 int i;
3102 int ret;
3103
3104 camss->genpd_num = of_count_phandle_with_args(dev->of_node,
3105 "power-domains",
3106 "#power-domain-cells");
3107 if (camss->genpd_num < 0) {
3108 dev_err(dev, "Power domains are not defined for camss\n");
3109 return camss->genpd_num;
3110 }
3111
3112 /*
3113 * If a platform device has just one power domain, then it is attached
3114 * at platform_probe() level, thus there shall be no need and even no
3115 * option to attach it again, this is the case for CAMSS on MSM8916.
3116 */
3117 if (camss->genpd_num == 1)
3118 return 0;
3119
3120 /* count the # of VFEs which have flagged power-domain */
3121 for (vfepd_num = i = 0; i < camss->res->vfe_num; i++) {
3122 if (res->vfe_res[i].vfe.has_pd)
3123 vfepd_num++;
3124 }
3125
3126 /*
3127 * If the number of power-domains is greater than the number of VFEs
3128 * then the additional power-domain is for the entire CAMSS block.
3129 */
3130 if (!(camss->genpd_num > vfepd_num))
3131 return 0;
3132
3133 /*
3134 * If a power-domain name is defined try to use it.
3135 * It is possible we are running a new kernel with an old dtb so
3136 * fallback to indexes even if a pd_name is defined but not found.
3137 */
3138 if (camss->res->pd_name) {
3139 camss->genpd = dev_pm_domain_attach_by_name(camss->dev,
3140 camss->res->pd_name);
3141 if (IS_ERR(camss->genpd))
3142 return PTR_ERR(camss->genpd);
3143 }
3144
3145 if (!camss->genpd) {
3146 /*
3147 * Legacy magic index. TITAN_TOP GDSC must be the last
3148 * item in the power-domain list.
3149 */
3150 camss->genpd = dev_pm_domain_attach_by_id(camss->dev,
3151 camss->genpd_num - 1);
3152 if (IS_ERR(camss->genpd))
3153 return PTR_ERR(camss->genpd);
3154 }
3155
3156 if (!camss->genpd)
3157 return -ENODEV;
3158
3159 camss->genpd_link = device_link_add(camss->dev, camss->genpd,
3160 DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME |
3161 DL_FLAG_RPM_ACTIVE);
3162 if (!camss->genpd_link) {
3163 ret = -EINVAL;
3164 goto fail_pm;
3165 }
3166
3167 return 0;
3168
3169 fail_pm:
3170 dev_pm_domain_detach(camss->genpd, true);
3171
3172 return ret;
3173 }
3174
camss_icc_get(struct camss * camss)3175 static int camss_icc_get(struct camss *camss)
3176 {
3177 const struct resources_icc *icc_res;
3178 int i;
3179
3180 icc_res = camss->res->icc_res;
3181
3182 for (i = 0; i < camss->res->icc_path_num; i++) {
3183 camss->icc_path[i] = devm_of_icc_get(camss->dev,
3184 icc_res[i].name);
3185 if (IS_ERR(camss->icc_path[i]))
3186 return PTR_ERR(camss->icc_path[i]);
3187 }
3188
3189 return 0;
3190 }
3191
camss_genpd_subdevice_cleanup(struct camss * camss)3192 static void camss_genpd_subdevice_cleanup(struct camss *camss)
3193 {
3194 int i;
3195
3196 for (i = 0; i < camss->res->vfe_num; i++)
3197 msm_vfe_genpd_cleanup(&camss->vfe[i]);
3198 }
3199
camss_genpd_cleanup(struct camss * camss)3200 static void camss_genpd_cleanup(struct camss *camss)
3201 {
3202 if (camss->genpd_num == 1)
3203 return;
3204
3205 camss_genpd_subdevice_cleanup(camss);
3206
3207 if (camss->genpd_link)
3208 device_link_del(camss->genpd_link);
3209
3210 dev_pm_domain_detach(camss->genpd, true);
3211 }
3212
3213 /*
3214 * camss_probe - Probe CAMSS platform device
3215 * @pdev: Pointer to CAMSS platform device
3216 *
3217 * Return 0 on success or a negative error code on failure
3218 */
camss_probe(struct platform_device * pdev)3219 static int camss_probe(struct platform_device *pdev)
3220 {
3221 struct device *dev = &pdev->dev;
3222 struct camss *camss;
3223 int num_subdevs;
3224 int ret;
3225
3226 camss = devm_kzalloc(dev, sizeof(*camss), GFP_KERNEL);
3227 if (!camss)
3228 return -ENOMEM;
3229
3230 camss->res = of_device_get_match_data(dev);
3231
3232 atomic_set(&camss->ref_count, 0);
3233 camss->dev = dev;
3234 platform_set_drvdata(pdev, camss);
3235
3236 camss->csiphy = devm_kcalloc(dev, camss->res->csiphy_num,
3237 sizeof(*camss->csiphy), GFP_KERNEL);
3238 if (!camss->csiphy)
3239 return -ENOMEM;
3240
3241 camss->csid = devm_kcalloc(dev, camss->res->csid_num, sizeof(*camss->csid),
3242 GFP_KERNEL);
3243 if (!camss->csid)
3244 return -ENOMEM;
3245
3246 if (camss->res->version == CAMSS_8x16 ||
3247 camss->res->version == CAMSS_8x53 ||
3248 camss->res->version == CAMSS_8x96) {
3249 camss->ispif = devm_kcalloc(dev, 1, sizeof(*camss->ispif), GFP_KERNEL);
3250 if (!camss->ispif)
3251 return -ENOMEM;
3252 }
3253
3254 camss->vfe = devm_kcalloc(dev, camss->res->vfe_num,
3255 sizeof(*camss->vfe), GFP_KERNEL);
3256 if (!camss->vfe)
3257 return -ENOMEM;
3258
3259 ret = camss_icc_get(camss);
3260 if (ret < 0)
3261 return ret;
3262
3263 ret = camss_configure_pd(camss);
3264 if (ret < 0) {
3265 dev_err(dev, "Failed to configure power domains: %d\n", ret);
3266 return ret;
3267 }
3268
3269 ret = camss_init_subdevices(camss);
3270 if (ret < 0)
3271 goto err_genpd_cleanup;
3272
3273 ret = dma_set_mask_and_coherent(dev, 0xffffffff);
3274 if (ret)
3275 goto err_genpd_cleanup;
3276
3277 camss->media_dev.dev = camss->dev;
3278 strscpy(camss->media_dev.model, "Qualcomm Camera Subsystem",
3279 sizeof(camss->media_dev.model));
3280 camss->media_dev.ops = &camss_media_ops;
3281 media_device_init(&camss->media_dev);
3282
3283 camss->v4l2_dev.mdev = &camss->media_dev;
3284 ret = v4l2_device_register(camss->dev, &camss->v4l2_dev);
3285 if (ret < 0) {
3286 dev_err(dev, "Failed to register V4L2 device: %d\n", ret);
3287 goto err_genpd_cleanup;
3288 }
3289
3290 v4l2_async_nf_init(&camss->notifier, &camss->v4l2_dev);
3291
3292 pm_runtime_enable(dev);
3293
3294 num_subdevs = camss_of_parse_ports(camss);
3295 if (num_subdevs < 0) {
3296 ret = num_subdevs;
3297 goto err_v4l2_device_unregister;
3298 }
3299
3300 ret = camss_register_entities(camss);
3301 if (ret < 0)
3302 goto err_v4l2_device_unregister;
3303
3304 ret = camss->res->link_entities(camss);
3305 if (ret < 0)
3306 goto err_register_subdevs;
3307
3308 if (num_subdevs) {
3309 camss->notifier.ops = &camss_subdev_notifier_ops;
3310
3311 ret = v4l2_async_nf_register(&camss->notifier);
3312 if (ret) {
3313 dev_err(dev,
3314 "Failed to register async subdev nodes: %d\n",
3315 ret);
3316 goto err_register_subdevs;
3317 }
3318 } else {
3319 ret = v4l2_device_register_subdev_nodes(&camss->v4l2_dev);
3320 if (ret < 0) {
3321 dev_err(dev, "Failed to register subdev nodes: %d\n",
3322 ret);
3323 goto err_register_subdevs;
3324 }
3325
3326 ret = media_device_register(&camss->media_dev);
3327 if (ret < 0) {
3328 dev_err(dev, "Failed to register media device: %d\n",
3329 ret);
3330 goto err_register_subdevs;
3331 }
3332 }
3333
3334 return 0;
3335
3336 err_register_subdevs:
3337 camss_unregister_entities(camss);
3338 err_v4l2_device_unregister:
3339 v4l2_device_unregister(&camss->v4l2_dev);
3340 v4l2_async_nf_cleanup(&camss->notifier);
3341 pm_runtime_disable(dev);
3342 err_genpd_cleanup:
3343 camss_genpd_cleanup(camss);
3344
3345 return ret;
3346 }
3347
camss_delete(struct camss * camss)3348 void camss_delete(struct camss *camss)
3349 {
3350 v4l2_device_unregister(&camss->v4l2_dev);
3351 media_device_unregister(&camss->media_dev);
3352 media_device_cleanup(&camss->media_dev);
3353
3354 pm_runtime_disable(camss->dev);
3355 }
3356
3357 /*
3358 * camss_remove - Remove CAMSS platform device
3359 * @pdev: Pointer to CAMSS platform device
3360 *
3361 * Always returns 0.
3362 */
camss_remove(struct platform_device * pdev)3363 static void camss_remove(struct platform_device *pdev)
3364 {
3365 struct camss *camss = platform_get_drvdata(pdev);
3366
3367 v4l2_async_nf_unregister(&camss->notifier);
3368 v4l2_async_nf_cleanup(&camss->notifier);
3369 camss_unregister_entities(camss);
3370
3371 if (atomic_read(&camss->ref_count) == 0)
3372 camss_delete(camss);
3373
3374 camss_genpd_cleanup(camss);
3375 }
3376
3377 static const struct camss_resources msm8916_resources = {
3378 .version = CAMSS_8x16,
3379 .csiphy_res = csiphy_res_8x16,
3380 .csid_res = csid_res_8x16,
3381 .ispif_res = &ispif_res_8x16,
3382 .vfe_res = vfe_res_8x16,
3383 .csiphy_num = ARRAY_SIZE(csiphy_res_8x16),
3384 .csid_num = ARRAY_SIZE(csid_res_8x16),
3385 .vfe_num = ARRAY_SIZE(vfe_res_8x16),
3386 .link_entities = camss_link_entities
3387 };
3388
3389 static const struct camss_resources msm8953_resources = {
3390 .version = CAMSS_8x53,
3391 .icc_res = icc_res_8x53,
3392 .icc_path_num = ARRAY_SIZE(icc_res_8x53),
3393 .csiphy_res = csiphy_res_8x96,
3394 .csid_res = csid_res_8x53,
3395 .ispif_res = &ispif_res_8x53,
3396 .vfe_res = vfe_res_8x53,
3397 .csiphy_num = ARRAY_SIZE(csiphy_res_8x96),
3398 .csid_num = ARRAY_SIZE(csid_res_8x53),
3399 .vfe_num = ARRAY_SIZE(vfe_res_8x53),
3400 .link_entities = camss_link_entities
3401 };
3402
3403 static const struct camss_resources msm8996_resources = {
3404 .version = CAMSS_8x96,
3405 .csiphy_res = csiphy_res_8x96,
3406 .csid_res = csid_res_8x96,
3407 .ispif_res = &ispif_res_8x96,
3408 .vfe_res = vfe_res_8x96,
3409 .csiphy_num = ARRAY_SIZE(csiphy_res_8x96),
3410 .csid_num = ARRAY_SIZE(csid_res_8x96),
3411 .vfe_num = ARRAY_SIZE(vfe_res_8x96),
3412 .link_entities = camss_link_entities
3413 };
3414
3415 static const struct camss_resources sdm660_resources = {
3416 .version = CAMSS_660,
3417 .csiphy_res = csiphy_res_660,
3418 .csid_res = csid_res_660,
3419 .ispif_res = &ispif_res_660,
3420 .vfe_res = vfe_res_660,
3421 .csiphy_num = ARRAY_SIZE(csiphy_res_660),
3422 .csid_num = ARRAY_SIZE(csid_res_660),
3423 .vfe_num = ARRAY_SIZE(vfe_res_660),
3424 .link_entities = camss_link_entities
3425 };
3426
3427 static const struct camss_resources sdm670_resources = {
3428 .version = CAMSS_845,
3429 .csiphy_res = csiphy_res_670,
3430 .csid_res = csid_res_670,
3431 .vfe_res = vfe_res_670,
3432 .csiphy_num = ARRAY_SIZE(csiphy_res_670),
3433 .csid_num = ARRAY_SIZE(csid_res_670),
3434 .vfe_num = ARRAY_SIZE(vfe_res_670),
3435 .link_entities = camss_link_entities
3436 };
3437
3438 static const struct camss_resources sdm845_resources = {
3439 .version = CAMSS_845,
3440 .pd_name = "top",
3441 .csiphy_res = csiphy_res_845,
3442 .csid_res = csid_res_845,
3443 .vfe_res = vfe_res_845,
3444 .csiphy_num = ARRAY_SIZE(csiphy_res_845),
3445 .csid_num = ARRAY_SIZE(csid_res_845),
3446 .vfe_num = ARRAY_SIZE(vfe_res_845),
3447 .link_entities = camss_link_entities
3448 };
3449
3450 static const struct camss_resources sm8250_resources = {
3451 .version = CAMSS_8250,
3452 .pd_name = "top",
3453 .csiphy_res = csiphy_res_8250,
3454 .csid_res = csid_res_8250,
3455 .vfe_res = vfe_res_8250,
3456 .icc_res = icc_res_sm8250,
3457 .icc_path_num = ARRAY_SIZE(icc_res_sm8250),
3458 .csiphy_num = ARRAY_SIZE(csiphy_res_8250),
3459 .csid_num = ARRAY_SIZE(csid_res_8250),
3460 .vfe_num = ARRAY_SIZE(vfe_res_8250),
3461 .link_entities = camss_link_entities
3462 };
3463
3464 static const struct camss_resources sc8280xp_resources = {
3465 .version = CAMSS_8280XP,
3466 .pd_name = "top",
3467 .csiphy_res = csiphy_res_sc8280xp,
3468 .csid_res = csid_res_sc8280xp,
3469 .ispif_res = NULL,
3470 .vfe_res = vfe_res_sc8280xp,
3471 .icc_res = icc_res_sc8280xp,
3472 .icc_path_num = ARRAY_SIZE(icc_res_sc8280xp),
3473 .csiphy_num = ARRAY_SIZE(csiphy_res_sc8280xp),
3474 .csid_num = ARRAY_SIZE(csid_res_sc8280xp),
3475 .vfe_num = ARRAY_SIZE(vfe_res_sc8280xp),
3476 .link_entities = camss_link_entities
3477 };
3478
3479 static const struct camss_resources sc7280_resources = {
3480 .version = CAMSS_7280,
3481 .pd_name = "top",
3482 .csiphy_res = csiphy_res_7280,
3483 .csid_res = csid_res_7280,
3484 .vfe_res = vfe_res_7280,
3485 .icc_res = icc_res_sc7280,
3486 .icc_path_num = ARRAY_SIZE(icc_res_sc7280),
3487 .csiphy_num = ARRAY_SIZE(csiphy_res_7280),
3488 .csid_num = ARRAY_SIZE(csid_res_7280),
3489 .vfe_num = ARRAY_SIZE(vfe_res_7280),
3490 .link_entities = camss_link_entities
3491 };
3492
3493 static const struct camss_resources sm8550_resources = {
3494 .version = CAMSS_8550,
3495 .pd_name = "top",
3496 .csiphy_res = csiphy_res_8550,
3497 .csid_res = csid_res_8550,
3498 .vfe_res = vfe_res_8550,
3499 .csid_wrapper_res = &csid_wrapper_res_sm8550,
3500 .icc_res = icc_res_sm8550,
3501 .icc_path_num = ARRAY_SIZE(icc_res_sm8550),
3502 .csiphy_num = ARRAY_SIZE(csiphy_res_8550),
3503 .csid_num = ARRAY_SIZE(csid_res_8550),
3504 .vfe_num = ARRAY_SIZE(vfe_res_8550),
3505 .link_entities = camss_link_entities
3506 };
3507
3508 static const struct of_device_id camss_dt_match[] = {
3509 { .compatible = "qcom,msm8916-camss", .data = &msm8916_resources },
3510 { .compatible = "qcom,msm8953-camss", .data = &msm8953_resources },
3511 { .compatible = "qcom,msm8996-camss", .data = &msm8996_resources },
3512 { .compatible = "qcom,sc7280-camss", .data = &sc7280_resources },
3513 { .compatible = "qcom,sc8280xp-camss", .data = &sc8280xp_resources },
3514 { .compatible = "qcom,sdm660-camss", .data = &sdm660_resources },
3515 { .compatible = "qcom,sdm670-camss", .data = &sdm670_resources },
3516 { .compatible = "qcom,sdm845-camss", .data = &sdm845_resources },
3517 { .compatible = "qcom,sm8250-camss", .data = &sm8250_resources },
3518 { .compatible = "qcom,sm8550-camss", .data = &sm8550_resources },
3519 { }
3520 };
3521
3522 MODULE_DEVICE_TABLE(of, camss_dt_match);
3523
camss_runtime_suspend(struct device * dev)3524 static int __maybe_unused camss_runtime_suspend(struct device *dev)
3525 {
3526 struct camss *camss = dev_get_drvdata(dev);
3527 int i;
3528 int ret;
3529
3530 for (i = 0; i < camss->res->icc_path_num; i++) {
3531 ret = icc_set_bw(camss->icc_path[i], 0, 0);
3532 if (ret)
3533 return ret;
3534 }
3535
3536 return 0;
3537 }
3538
camss_runtime_resume(struct device * dev)3539 static int __maybe_unused camss_runtime_resume(struct device *dev)
3540 {
3541 struct camss *camss = dev_get_drvdata(dev);
3542 const struct resources_icc *icc_res = camss->res->icc_res;
3543 int i;
3544 int ret;
3545
3546 for (i = 0; i < camss->res->icc_path_num; i++) {
3547 ret = icc_set_bw(camss->icc_path[i],
3548 icc_res[i].icc_bw_tbl.avg,
3549 icc_res[i].icc_bw_tbl.peak);
3550 if (ret)
3551 return ret;
3552 }
3553
3554 return 0;
3555 }
3556
3557 static const struct dev_pm_ops camss_pm_ops = {
3558 SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
3559 pm_runtime_force_resume)
3560 SET_RUNTIME_PM_OPS(camss_runtime_suspend, camss_runtime_resume, NULL)
3561 };
3562
3563 static struct platform_driver qcom_camss_driver = {
3564 .probe = camss_probe,
3565 .remove = camss_remove,
3566 .driver = {
3567 .name = "qcom-camss",
3568 .of_match_table = camss_dt_match,
3569 .pm = &camss_pm_ops,
3570 },
3571 };
3572
3573 module_platform_driver(qcom_camss_driver);
3574
3575 MODULE_ALIAS("platform:qcom-camss");
3576 MODULE_DESCRIPTION("Qualcomm Camera Subsystem driver");
3577 MODULE_AUTHOR("Todor Tomov <todor.tomov@linaro.org>");
3578 MODULE_LICENSE("GPL v2");
3579