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