1 // SPDX-License-Identifier: GPL-2.0
5 * Qualcomm MSM Camera Subsystem - Core
7 * Copyright (c) 2015, The Linux Foundation. All rights reserved.
8 * Copyright (C) 2015-2018 Linaro Ltd.
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>
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>
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>
32 #define CAMSS_CLOCK_MARGIN_NUMERATOR 105
33 #define CAMSS_CLOCK_MARGIN_DENOMINATOR 100
35 static const struct camss_subdev_resources csiphy_res_8x16[] = {
39 .clock = { "top_ahb", "ispif_ahb", "ahb", "csiphy0_timer" },
40 .clock_rate = { { 0 },
43 { 100000000, 200000000 } },
44 .reg = { "csiphy0", "csiphy0_clk_mux" },
45 .interrupt = { "csiphy0" },
46 .ops = &csiphy_ops_2ph_1_0
52 .clock = { "top_ahb", "ispif_ahb", "ahb", "csiphy1_timer" },
53 .clock_rate = { { 0 },
56 { 100000000, 200000000 } },
57 .reg = { "csiphy1", "csiphy1_clk_mux" },
58 .interrupt = { "csiphy1" },
59 .ops = &csiphy_ops_2ph_1_0
63 static const struct camss_subdev_resources csid_res_8x16[] = {
66 .regulators = { "vdda" },
67 .clock = { "top_ahb", "ispif_ahb", "csi0_ahb", "ahb",
68 "csi0", "csi0_phy", "csi0_pix", "csi0_rdi" },
69 .clock_rate = { { 0 },
73 { 100000000, 200000000 },
78 .interrupt = { "csid0" },
84 .regulators = { "vdda" },
85 .clock = { "top_ahb", "ispif_ahb", "csi1_ahb", "ahb",
86 "csi1", "csi1_phy", "csi1_pix", "csi1_rdi" },
87 .clock_rate = { { 0 },
91 { 100000000, 200000000 },
96 .interrupt = { "csid1" },
101 static const struct camss_subdev_resources ispif_res_8x16 = {
103 .clock = { "top_ahb", "ahb", "ispif_ahb",
104 "csi0", "csi0_pix", "csi0_rdi",
105 "csi1", "csi1_pix", "csi1_rdi" },
106 .clock_for_reset = { "vfe0", "csi_vfe0" },
107 .reg = { "ispif", "csi_clk_mux" },
108 .interrupt = { "ispif" }
112 static const struct camss_subdev_resources vfe_res_8x16[] = {
116 .clock = { "top_ahb", "vfe0", "csi_vfe0",
117 "vfe_ahb", "vfe_axi", "ahb" },
118 .clock_rate = { { 0 },
119 { 50000000, 80000000, 100000000, 160000000,
120 177780000, 200000000, 266670000, 320000000,
121 400000000, 465000000 },
130 .interrupt = { "vfe0" },
136 static const struct camss_subdev_resources csiphy_res_8x96[] = {
140 .clock = { "top_ahb", "ispif_ahb", "ahb", "csiphy0_timer" },
141 .clock_rate = { { 0 },
144 { 100000000, 200000000, 266666667 } },
145 .reg = { "csiphy0", "csiphy0_clk_mux" },
146 .interrupt = { "csiphy0" },
147 .ops = &csiphy_ops_3ph_1_0
153 .clock = { "top_ahb", "ispif_ahb", "ahb", "csiphy1_timer" },
154 .clock_rate = { { 0 },
157 { 100000000, 200000000, 266666667 } },
158 .reg = { "csiphy1", "csiphy1_clk_mux" },
159 .interrupt = { "csiphy1" },
160 .ops = &csiphy_ops_3ph_1_0
166 .clock = { "top_ahb", "ispif_ahb", "ahb", "csiphy2_timer" },
167 .clock_rate = { { 0 },
170 { 100000000, 200000000, 266666667 } },
171 .reg = { "csiphy2", "csiphy2_clk_mux" },
172 .interrupt = { "csiphy2" },
173 .ops = &csiphy_ops_3ph_1_0
177 static const struct camss_subdev_resources csid_res_8x96[] = {
180 .regulators = { "vdda" },
181 .clock = { "top_ahb", "ispif_ahb", "csi0_ahb", "ahb",
182 "csi0", "csi0_phy", "csi0_pix", "csi0_rdi" },
183 .clock_rate = { { 0 },
187 { 100000000, 200000000, 266666667 },
192 .interrupt = { "csid0" },
193 .ops = &csid_ops_4_7,
198 .regulators = { "vdda" },
199 .clock = { "top_ahb", "ispif_ahb", "csi1_ahb", "ahb",
200 "csi1", "csi1_phy", "csi1_pix", "csi1_rdi" },
201 .clock_rate = { { 0 },
205 { 100000000, 200000000, 266666667 },
210 .interrupt = { "csid1" },
211 .ops = &csid_ops_4_7,
216 .regulators = { "vdda" },
217 .clock = { "top_ahb", "ispif_ahb", "csi2_ahb", "ahb",
218 "csi2", "csi2_phy", "csi2_pix", "csi2_rdi" },
219 .clock_rate = { { 0 },
223 { 100000000, 200000000, 266666667 },
228 .interrupt = { "csid2" },
229 .ops = &csid_ops_4_7,
234 .regulators = { "vdda" },
235 .clock = { "top_ahb", "ispif_ahb", "csi3_ahb", "ahb",
236 "csi3", "csi3_phy", "csi3_pix", "csi3_rdi" },
237 .clock_rate = { { 0 },
241 { 100000000, 200000000, 266666667 },
246 .interrupt = { "csid3" },
247 .ops = &csid_ops_4_7,
251 static const struct camss_subdev_resources ispif_res_8x96 = {
253 .clock = { "top_ahb", "ahb", "ispif_ahb",
254 "csi0", "csi0_pix", "csi0_rdi",
255 "csi1", "csi1_pix", "csi1_rdi",
256 "csi2", "csi2_pix", "csi2_rdi",
257 "csi3", "csi3_pix", "csi3_rdi" },
258 .clock_for_reset = { "vfe0", "csi_vfe0", "vfe1", "csi_vfe1" },
259 .reg = { "ispif", "csi_clk_mux" },
260 .interrupt = { "ispif" }
263 static const struct camss_subdev_resources vfe_res_8x96[] = {
267 .clock = { "top_ahb", "ahb", "vfe0", "csi_vfe0", "vfe_ahb",
268 "vfe0_ahb", "vfe_axi", "vfe0_stream"},
269 .clock_rate = { { 0 },
271 { 75000000, 100000000, 300000000,
272 320000000, 480000000, 600000000 },
279 .interrupt = { "vfe0" },
287 .clock = { "top_ahb", "ahb", "vfe1", "csi_vfe1", "vfe_ahb",
288 "vfe1_ahb", "vfe_axi", "vfe1_stream"},
289 .clock_rate = { { 0 },
291 { 75000000, 100000000, 300000000,
292 320000000, 480000000, 600000000 },
299 .interrupt = { "vfe1" },
305 static const struct camss_subdev_resources csiphy_res_660[] = {
309 .clock = { "top_ahb", "ispif_ahb", "ahb", "csiphy0_timer",
310 "csi0_phy", "csiphy_ahb2crif" },
311 .clock_rate = { { 0 },
314 { 100000000, 200000000, 269333333 },
316 .reg = { "csiphy0", "csiphy0_clk_mux" },
317 .interrupt = { "csiphy0" },
318 .ops = &csiphy_ops_3ph_1_0
324 .clock = { "top_ahb", "ispif_ahb", "ahb", "csiphy1_timer",
325 "csi1_phy", "csiphy_ahb2crif" },
326 .clock_rate = { { 0 },
329 { 100000000, 200000000, 269333333 },
331 .reg = { "csiphy1", "csiphy1_clk_mux" },
332 .interrupt = { "csiphy1" },
333 .ops = &csiphy_ops_3ph_1_0
339 .clock = { "top_ahb", "ispif_ahb", "ahb", "csiphy2_timer",
340 "csi2_phy", "csiphy_ahb2crif" },
341 .clock_rate = { { 0 },
344 { 100000000, 200000000, 269333333 },
346 .reg = { "csiphy2", "csiphy2_clk_mux" },
347 .interrupt = { "csiphy2" },
348 .ops = &csiphy_ops_3ph_1_0
352 static const struct camss_subdev_resources csid_res_660[] = {
355 .regulators = { "vdda", "vdd_sec" },
356 .clock = { "top_ahb", "ispif_ahb", "csi0_ahb", "ahb",
357 "csi0", "csi0_phy", "csi0_pix", "csi0_rdi",
359 .clock_rate = { { 0 },
363 { 100000000, 200000000, 310000000,
364 404000000, 465000000 },
370 .interrupt = { "csid0" },
371 .ops = &csid_ops_4_7,
376 .regulators = { "vdda", "vdd_sec" },
377 .clock = { "top_ahb", "ispif_ahb", "csi1_ahb", "ahb",
378 "csi1", "csi1_phy", "csi1_pix", "csi1_rdi",
380 .clock_rate = { { 0 },
384 { 100000000, 200000000, 310000000,
385 404000000, 465000000 },
391 .interrupt = { "csid1" },
392 .ops = &csid_ops_4_7,
397 .regulators = { "vdda", "vdd_sec" },
398 .clock = { "top_ahb", "ispif_ahb", "csi2_ahb", "ahb",
399 "csi2", "csi2_phy", "csi2_pix", "csi2_rdi",
401 .clock_rate = { { 0 },
405 { 100000000, 200000000, 310000000,
406 404000000, 465000000 },
412 .interrupt = { "csid2" },
413 .ops = &csid_ops_4_7,
418 .regulators = { "vdda", "vdd_sec" },
419 .clock = { "top_ahb", "ispif_ahb", "csi3_ahb", "ahb",
420 "csi3", "csi3_phy", "csi3_pix", "csi3_rdi",
422 .clock_rate = { { 0 },
426 { 100000000, 200000000, 310000000,
427 404000000, 465000000 },
433 .interrupt = { "csid3" },
434 .ops = &csid_ops_4_7,
438 static const struct camss_subdev_resources ispif_res_660 = {
440 .clock = { "top_ahb", "ahb", "ispif_ahb",
441 "csi0", "csi0_pix", "csi0_rdi",
442 "csi1", "csi1_pix", "csi1_rdi",
443 "csi2", "csi2_pix", "csi2_rdi",
444 "csi3", "csi3_pix", "csi3_rdi" },
445 .clock_for_reset = { "vfe0", "csi_vfe0", "vfe1", "csi_vfe1" },
446 .reg = { "ispif", "csi_clk_mux" },
447 .interrupt = { "ispif" }
450 static const struct camss_subdev_resources vfe_res_660[] = {
454 .clock = { "throttle_axi", "top_ahb", "ahb", "vfe0",
455 "csi_vfe0", "vfe_ahb", "vfe0_ahb", "vfe_axi",
457 .clock_rate = { { 0 },
460 { 120000000, 200000000, 256000000,
461 300000000, 404000000, 480000000,
462 540000000, 576000000 },
469 .interrupt = { "vfe0" },
477 .clock = { "throttle_axi", "top_ahb", "ahb", "vfe1",
478 "csi_vfe1", "vfe_ahb", "vfe1_ahb", "vfe_axi",
480 .clock_rate = { { 0 },
483 { 120000000, 200000000, 256000000,
484 300000000, 404000000, 480000000,
485 540000000, 576000000 },
492 .interrupt = { "vfe1" },
498 static const struct camss_subdev_resources csiphy_res_845[] = {
502 .clock = { "camnoc_axi", "soc_ahb", "slow_ahb_src",
503 "cpas_ahb", "cphy_rx_src", "csiphy0",
504 "csiphy0_timer_src", "csiphy0_timer" },
505 .clock_rate = { { 0 },
512 { 19200000, 240000000, 269333333 } },
513 .reg = { "csiphy0" },
514 .interrupt = { "csiphy0" },
515 .ops = &csiphy_ops_3ph_1_0
521 .clock = { "camnoc_axi", "soc_ahb", "slow_ahb_src",
522 "cpas_ahb", "cphy_rx_src", "csiphy1",
523 "csiphy1_timer_src", "csiphy1_timer" },
524 .clock_rate = { { 0 },
531 { 19200000, 240000000, 269333333 } },
532 .reg = { "csiphy1" },
533 .interrupt = { "csiphy1" },
534 .ops = &csiphy_ops_3ph_1_0
540 .clock = { "camnoc_axi", "soc_ahb", "slow_ahb_src",
541 "cpas_ahb", "cphy_rx_src", "csiphy2",
542 "csiphy2_timer_src", "csiphy2_timer" },
543 .clock_rate = { { 0 },
550 { 19200000, 240000000, 269333333 } },
551 .reg = { "csiphy2" },
552 .interrupt = { "csiphy2" },
553 .ops = &csiphy_ops_3ph_1_0
559 .clock = { "camnoc_axi", "soc_ahb", "slow_ahb_src",
560 "cpas_ahb", "cphy_rx_src", "csiphy3",
561 "csiphy3_timer_src", "csiphy3_timer" },
562 .clock_rate = { { 0 },
569 { 19200000, 240000000, 269333333 } },
570 .reg = { "csiphy3" },
571 .interrupt = { "csiphy3" },
572 .ops = &csiphy_ops_3ph_1_0
576 static const struct camss_subdev_resources csid_res_845[] = {
579 .regulators = { "vdda-phy", "vdda-pll" },
580 .clock = { "cpas_ahb", "cphy_rx_src", "slow_ahb_src",
581 "soc_ahb", "vfe0", "vfe0_src",
582 "vfe0_cphy_rx", "csi0",
584 .clock_rate = { { 0 },
588 { 19200000, 100000000, 320000000, 404000000, 480000000, 600000000 },
591 { 19200000, 75000000, 384000000, 538666667 },
594 .interrupt = { "csid0" },
595 .ops = &csid_ops_gen2
600 .regulators = { "vdda-phy", "vdda-pll" },
601 .clock = { "cpas_ahb", "cphy_rx_src", "slow_ahb_src",
602 "soc_ahb", "vfe1", "vfe1_src",
603 "vfe1_cphy_rx", "csi1",
605 .clock_rate = { { 0 },
609 { 19200000, 100000000, 320000000, 404000000, 480000000, 600000000 },
612 { 19200000, 75000000, 384000000, 538666667 },
615 .interrupt = { "csid1" },
616 .ops = &csid_ops_gen2
621 .regulators = { "vdda-phy", "vdda-pll" },
622 .clock = { "cpas_ahb", "cphy_rx_src", "slow_ahb_src",
623 "soc_ahb", "vfe_lite", "vfe_lite_src",
624 "vfe_lite_cphy_rx", "csi2",
626 .clock_rate = { { 0 },
630 { 19200000, 100000000, 320000000, 404000000, 480000000, 600000000 },
633 { 19200000, 75000000, 384000000, 538666667 },
636 .interrupt = { "csid2" },
637 .ops = &csid_ops_gen2
641 static const struct camss_subdev_resources vfe_res_845[] = {
645 .clock = { "camnoc_axi", "cpas_ahb", "slow_ahb_src",
646 "soc_ahb", "vfe0", "vfe0_axi",
649 .clock_rate = { { 0 },
653 { 19200000, 100000000, 320000000, 404000000, 480000000, 600000000 },
656 { 19200000, 75000000, 384000000, 538666667 },
659 .interrupt = { "vfe0" },
667 .clock = { "camnoc_axi", "cpas_ahb", "slow_ahb_src",
668 "soc_ahb", "vfe1", "vfe1_axi",
671 .clock_rate = { { 0 },
675 { 19200000, 100000000, 320000000, 404000000, 480000000, 600000000 },
678 { 19200000, 75000000, 384000000, 538666667 },
681 .interrupt = { "vfe1" },
689 .clock = { "camnoc_axi", "cpas_ahb", "slow_ahb_src",
690 "soc_ahb", "vfe_lite",
691 "vfe_lite_src", "csi2",
693 .clock_rate = { { 0 },
697 { 19200000, 100000000, 320000000, 404000000, 480000000, 600000000 },
699 { 19200000, 75000000, 384000000, 538666667 },
701 .reg = { "vfe_lite" },
702 .interrupt = { "vfe_lite" },
708 static const struct camss_subdev_resources csiphy_res_8250[] = {
712 .clock = { "csiphy0", "csiphy0_timer" },
713 .clock_rate = { { 400000000 },
715 .reg = { "csiphy0" },
716 .interrupt = { "csiphy0" },
717 .ops = &csiphy_ops_3ph_1_0
722 .clock = { "csiphy1", "csiphy1_timer" },
723 .clock_rate = { { 400000000 },
725 .reg = { "csiphy1" },
726 .interrupt = { "csiphy1" },
727 .ops = &csiphy_ops_3ph_1_0
732 .clock = { "csiphy2", "csiphy2_timer" },
733 .clock_rate = { { 400000000 },
735 .reg = { "csiphy2" },
736 .interrupt = { "csiphy2" },
737 .ops = &csiphy_ops_3ph_1_0
742 .clock = { "csiphy3", "csiphy3_timer" },
743 .clock_rate = { { 400000000 },
745 .reg = { "csiphy3" },
746 .interrupt = { "csiphy3" },
747 .ops = &csiphy_ops_3ph_1_0
752 .clock = { "csiphy4", "csiphy4_timer" },
753 .clock_rate = { { 400000000 },
755 .reg = { "csiphy4" },
756 .interrupt = { "csiphy4" },
757 .ops = &csiphy_ops_3ph_1_0
762 .clock = { "csiphy5", "csiphy5_timer" },
763 .clock_rate = { { 400000000 },
765 .reg = { "csiphy5" },
766 .interrupt = { "csiphy5" },
767 .ops = &csiphy_ops_3ph_1_0
771 static const struct camss_subdev_resources csid_res_8250[] = {
774 .regulators = { "vdda-phy", "vdda-pll" },
775 .clock = { "vfe0_csid", "vfe0_cphy_rx", "vfe0", "vfe0_areg", "vfe0_ahb" },
776 .clock_rate = { { 400000000 },
778 { 350000000, 475000000, 576000000, 720000000 },
779 { 100000000, 200000000, 300000000, 400000000 },
782 .interrupt = { "csid0" },
783 .ops = &csid_ops_gen2
787 .regulators = { "vdda-phy", "vdda-pll" },
788 .clock = { "vfe1_csid", "vfe1_cphy_rx", "vfe1", "vfe1_areg", "vfe1_ahb" },
789 .clock_rate = { { 400000000 },
791 { 350000000, 475000000, 576000000, 720000000 },
792 { 100000000, 200000000, 300000000, 400000000 },
795 .interrupt = { "csid1" },
796 .ops = &csid_ops_gen2
800 .regulators = { "vdda-phy", "vdda-pll" },
801 .clock = { "vfe_lite_csid", "vfe_lite_cphy_rx", "vfe_lite", "vfe_lite_ahb" },
802 .clock_rate = { { 400000000 },
804 { 400000000, 480000000 },
807 .interrupt = { "csid2" },
808 .ops = &csid_ops_gen2
812 .regulators = { "vdda-phy", "vdda-pll" },
813 .clock = { "vfe_lite_csid", "vfe_lite_cphy_rx", "vfe_lite", "vfe_lite_ahb" },
814 .clock_rate = { { 400000000 },
816 { 400000000, 480000000 },
819 .interrupt = { "csid3" },
820 .ops = &csid_ops_gen2
824 static const struct camss_subdev_resources vfe_res_8250[] = {
828 .clock = { "camnoc_axi_src", "slow_ahb_src", "cpas_ahb",
829 "camnoc_axi", "vfe0_ahb", "vfe0_areg", "vfe0",
830 "vfe0_axi", "cam_hf_axi" },
831 .clock_rate = { { 19200000, 300000000, 400000000, 480000000 },
832 { 19200000, 80000000 },
836 { 100000000, 200000000, 300000000, 400000000 },
837 { 350000000, 475000000, 576000000, 720000000 },
841 .interrupt = { "vfe0" },
848 .clock = { "camnoc_axi_src", "slow_ahb_src", "cpas_ahb",
849 "camnoc_axi", "vfe1_ahb", "vfe1_areg", "vfe1",
850 "vfe1_axi", "cam_hf_axi" },
851 .clock_rate = { { 19200000, 300000000, 400000000, 480000000 },
852 { 19200000, 80000000 },
856 { 100000000, 200000000, 300000000, 400000000 },
857 { 350000000, 475000000, 576000000, 720000000 },
861 .interrupt = { "vfe1" },
868 .clock = { "camnoc_axi_src", "slow_ahb_src", "cpas_ahb",
869 "camnoc_axi", "vfe_lite_ahb", "vfe_lite_axi",
870 "vfe_lite", "cam_hf_axi" },
871 .clock_rate = { { 19200000, 300000000, 400000000, 480000000 },
872 { 19200000, 80000000 },
877 { 400000000, 480000000 },
879 .reg = { "vfe_lite0" },
880 .interrupt = { "vfe_lite0" },
887 .clock = { "camnoc_axi_src", "slow_ahb_src", "cpas_ahb",
888 "camnoc_axi", "vfe_lite_ahb", "vfe_lite_axi",
889 "vfe_lite", "cam_hf_axi" },
890 .clock_rate = { { 19200000, 300000000, 400000000, 480000000 },
891 { 19200000, 80000000 },
896 { 400000000, 480000000 },
898 .reg = { "vfe_lite1" },
899 .interrupt = { "vfe_lite1" },
905 static const struct resources_icc icc_res_sm8250[] = {
908 .icc_bw_tbl.avg = 38400,
909 .icc_bw_tbl.peak = 76800,
912 .name = "cam_hf_0_mnoc",
913 .icc_bw_tbl.avg = 2097152,
914 .icc_bw_tbl.peak = 2097152,
917 .name = "cam_sf_0_mnoc",
919 .icc_bw_tbl.peak = 2097152,
922 .name = "cam_sf_icp_mnoc",
923 .icc_bw_tbl.avg = 2097152,
924 .icc_bw_tbl.peak = 2097152,
929 * camss_add_clock_margin - Add margin to clock frequency rate
930 * @rate: Clock frequency rate
932 * When making calculations with physical clock frequency values
933 * some safety margin must be added. Add it.
935 inline void camss_add_clock_margin(u64 *rate)
937 *rate *= CAMSS_CLOCK_MARGIN_NUMERATOR;
938 *rate = div_u64(*rate, CAMSS_CLOCK_MARGIN_DENOMINATOR);
942 * camss_enable_clocks - Enable multiple clocks
943 * @nclocks: Number of clocks in clock array
944 * @clock: Clock array
947 * Return 0 on success or a negative error code otherwise
949 int camss_enable_clocks(int nclocks, struct camss_clock *clock,
955 for (i = 0; i < nclocks; i++) {
956 ret = clk_prepare_enable(clock[i].clk);
958 dev_err(dev, "clock enable failed: %d\n", ret);
966 for (i--; i >= 0; i--)
967 clk_disable_unprepare(clock[i].clk);
973 * camss_disable_clocks - Disable multiple clocks
974 * @nclocks: Number of clocks in clock array
975 * @clock: Clock array
977 void camss_disable_clocks(int nclocks, struct camss_clock *clock)
981 for (i = nclocks - 1; i >= 0; i--)
982 clk_disable_unprepare(clock[i].clk);
986 * camss_find_sensor - Find a linked media entity which represents a sensor
987 * @entity: Media entity to start searching from
989 * Return a pointer to sensor media entity or NULL if not found
991 struct media_entity *camss_find_sensor(struct media_entity *entity)
993 struct media_pad *pad;
996 pad = &entity->pads[0];
997 if (!(pad->flags & MEDIA_PAD_FL_SINK))
1000 pad = media_pad_remote_pad_first(pad);
1001 if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
1004 entity = pad->entity;
1006 if (entity->function == MEDIA_ENT_F_CAM_SENSOR)
1012 * camss_get_link_freq - Get link frequency from sensor
1013 * @entity: Media entity in the current pipeline
1014 * @bpp: Number of bits per pixel for the current format
1015 * @lanes: Number of lanes in the link to the sensor
1017 * Return link frequency on success or a negative error code otherwise
1019 s64 camss_get_link_freq(struct media_entity *entity, unsigned int bpp,
1022 struct media_entity *sensor;
1023 struct v4l2_subdev *subdev;
1025 sensor = camss_find_sensor(entity);
1029 subdev = media_entity_to_v4l2_subdev(sensor);
1031 return v4l2_get_link_freq(subdev->ctrl_handler, bpp, 2 * lanes);
1035 * camss_get_pixel_clock - Get pixel clock rate from sensor
1036 * @entity: Media entity in the current pipeline
1037 * @pixel_clock: Received pixel clock value
1039 * Return 0 on success or a negative error code otherwise
1041 int camss_get_pixel_clock(struct media_entity *entity, u64 *pixel_clock)
1043 struct media_entity *sensor;
1044 struct v4l2_subdev *subdev;
1045 struct v4l2_ctrl *ctrl;
1047 sensor = camss_find_sensor(entity);
1051 subdev = media_entity_to_v4l2_subdev(sensor);
1053 ctrl = v4l2_ctrl_find(subdev->ctrl_handler, V4L2_CID_PIXEL_RATE);
1058 *pixel_clock = v4l2_ctrl_g_ctrl_int64(ctrl);
1063 int camss_pm_domain_on(struct camss *camss, int id)
1067 if (id < camss->res->vfe_num) {
1068 struct vfe_device *vfe = &camss->vfe[id];
1070 ret = vfe->ops->pm_domain_on(vfe);
1076 void camss_pm_domain_off(struct camss *camss, int id)
1078 if (id < camss->res->vfe_num) {
1079 struct vfe_device *vfe = &camss->vfe[id];
1081 vfe->ops->pm_domain_off(vfe);
1086 * camss_of_parse_endpoint_node - Parse port endpoint node
1088 * @node: Device node to be parsed
1089 * @csd: Parsed data from port endpoint node
1091 * Return 0 on success or a negative error code on failure
1093 static int camss_of_parse_endpoint_node(struct device *dev,
1094 struct device_node *node,
1095 struct camss_async_subdev *csd)
1097 struct csiphy_lanes_cfg *lncfg = &csd->interface.csi2.lane_cfg;
1098 struct v4l2_mbus_config_mipi_csi2 *mipi_csi2;
1099 struct v4l2_fwnode_endpoint vep = { { 0 } };
1102 v4l2_fwnode_endpoint_parse(of_fwnode_handle(node), &vep);
1104 csd->interface.csiphy_id = vep.base.port;
1106 mipi_csi2 = &vep.bus.mipi_csi2;
1107 lncfg->clk.pos = mipi_csi2->clock_lane;
1108 lncfg->clk.pol = mipi_csi2->lane_polarities[0];
1109 lncfg->num_data = mipi_csi2->num_data_lanes;
1111 lncfg->data = devm_kcalloc(dev,
1112 lncfg->num_data, sizeof(*lncfg->data),
1117 for (i = 0; i < lncfg->num_data; i++) {
1118 lncfg->data[i].pos = mipi_csi2->data_lanes[i];
1119 lncfg->data[i].pol = mipi_csi2->lane_polarities[i + 1];
1126 * camss_of_parse_ports - Parse ports node
1128 * @notifier: v4l2_device notifier data
1130 * Return number of "port" nodes found in "ports" node
1132 static int camss_of_parse_ports(struct camss *camss)
1134 struct device *dev = camss->dev;
1135 struct device_node *node = NULL;
1136 struct device_node *remote = NULL;
1137 int ret, num_subdevs = 0;
1139 for_each_endpoint_of_node(dev->of_node, node) {
1140 struct camss_async_subdev *csd;
1142 if (!of_device_is_available(node))
1145 remote = of_graph_get_remote_port_parent(node);
1147 dev_err(dev, "Cannot get remote parent\n");
1152 csd = v4l2_async_nf_add_fwnode(&camss->notifier,
1153 of_fwnode_handle(remote),
1154 struct camss_async_subdev);
1155 of_node_put(remote);
1161 ret = camss_of_parse_endpoint_node(dev, node, csd);
1176 * camss_init_subdevices - Initialize subdev structures and resources
1177 * @camss: CAMSS device
1179 * Return 0 on success or a negative error code on failure
1181 static int camss_init_subdevices(struct camss *camss)
1183 const struct camss_resources *res = camss->res;
1187 for (i = 0; i < camss->res->csiphy_num; i++) {
1188 ret = msm_csiphy_subdev_init(camss, &camss->csiphy[i],
1189 &res->csiphy_res[i], i);
1192 "Failed to init csiphy%d sub-device: %d\n",
1198 /* note: SM8250 requires VFE to be initialized before CSID */
1199 for (i = 0; i < camss->vfe_total_num; i++) {
1200 ret = msm_vfe_subdev_init(camss, &camss->vfe[i],
1201 &res->vfe_res[i], i);
1204 "Fail to init vfe%d sub-device: %d\n", i, ret);
1209 for (i = 0; i < camss->res->csid_num; i++) {
1210 ret = msm_csid_subdev_init(camss, &camss->csid[i],
1211 &res->csid_res[i], i);
1214 "Failed to init csid%d sub-device: %d\n",
1220 ret = msm_ispif_subdev_init(camss, res->ispif_res);
1222 dev_err(camss->dev, "Failed to init ispif sub-device: %d\n",
1231 * camss_register_entities - Register subdev nodes and create links
1232 * @camss: CAMSS device
1234 * Return 0 on success or a negative error code on failure
1236 static int camss_register_entities(struct camss *camss)
1241 for (i = 0; i < camss->res->csiphy_num; i++) {
1242 ret = msm_csiphy_register_entity(&camss->csiphy[i],
1246 "Failed to register csiphy%d entity: %d\n",
1248 goto err_reg_csiphy;
1252 for (i = 0; i < camss->res->csid_num; i++) {
1253 ret = msm_csid_register_entity(&camss->csid[i],
1257 "Failed to register csid%d entity: %d\n",
1263 ret = msm_ispif_register_entities(camss->ispif,
1266 dev_err(camss->dev, "Failed to register ispif entities: %d\n",
1271 for (i = 0; i < camss->vfe_total_num; i++) {
1272 ret = msm_vfe_register_entities(&camss->vfe[i],
1276 "Failed to register vfe%d entities: %d\n",
1282 for (i = 0; i < camss->res->csiphy_num; i++) {
1283 for (j = 0; j < camss->res->csid_num; j++) {
1284 ret = media_create_pad_link(
1285 &camss->csiphy[i].subdev.entity,
1287 &camss->csid[j].subdev.entity,
1292 "Failed to link %s->%s entities: %d\n",
1293 camss->csiphy[i].subdev.entity.name,
1294 camss->csid[j].subdev.entity.name,
1302 for (i = 0; i < camss->res->csid_num; i++) {
1303 for (j = 0; j < camss->ispif->line_num; j++) {
1304 ret = media_create_pad_link(
1305 &camss->csid[i].subdev.entity,
1307 &camss->ispif->line[j].subdev.entity,
1312 "Failed to link %s->%s entities: %d\n",
1313 camss->csid[i].subdev.entity.name,
1314 camss->ispif->line[j].subdev.entity.name,
1321 for (i = 0; i < camss->ispif->line_num; i++)
1322 for (k = 0; k < camss->res->vfe_num; k++)
1323 for (j = 0; j < camss->vfe[k].line_num; j++) {
1324 struct v4l2_subdev *ispif = &camss->ispif->line[i].subdev;
1325 struct v4l2_subdev *vfe = &camss->vfe[k].line[j].subdev;
1327 ret = media_create_pad_link(&ispif->entity,
1334 "Failed to link %s->%s entities: %d\n",
1342 for (i = 0; i < camss->res->csid_num; i++)
1343 for (k = 0; k < camss->vfe_total_num; k++)
1344 for (j = 0; j < camss->vfe[k].line_num; j++) {
1345 struct v4l2_subdev *csid = &camss->csid[i].subdev;
1346 struct v4l2_subdev *vfe = &camss->vfe[k].line[j].subdev;
1348 ret = media_create_pad_link(&csid->entity,
1349 MSM_CSID_PAD_FIRST_SRC + j,
1355 "Failed to link %s->%s entities: %d\n",
1367 i = camss->vfe_total_num;
1369 for (i--; i >= 0; i--)
1370 msm_vfe_unregister_entities(&camss->vfe[i]);
1373 msm_ispif_unregister_entities(camss->ispif);
1375 i = camss->res->csid_num;
1377 for (i--; i >= 0; i--)
1378 msm_csid_unregister_entity(&camss->csid[i]);
1380 i = camss->res->csiphy_num;
1382 for (i--; i >= 0; i--)
1383 msm_csiphy_unregister_entity(&camss->csiphy[i]);
1389 * camss_unregister_entities - Unregister subdev nodes
1390 * @camss: CAMSS device
1392 * Return 0 on success or a negative error code on failure
1394 static void camss_unregister_entities(struct camss *camss)
1398 for (i = 0; i < camss->res->csiphy_num; i++)
1399 msm_csiphy_unregister_entity(&camss->csiphy[i]);
1401 for (i = 0; i < camss->res->csid_num; i++)
1402 msm_csid_unregister_entity(&camss->csid[i]);
1404 msm_ispif_unregister_entities(camss->ispif);
1406 for (i = 0; i < camss->vfe_total_num; i++)
1407 msm_vfe_unregister_entities(&camss->vfe[i]);
1410 static int camss_subdev_notifier_bound(struct v4l2_async_notifier *async,
1411 struct v4l2_subdev *subdev,
1412 struct v4l2_async_connection *asd)
1414 struct camss *camss = container_of(async, struct camss, notifier);
1415 struct camss_async_subdev *csd =
1416 container_of(asd, struct camss_async_subdev, asd);
1417 u8 id = csd->interface.csiphy_id;
1418 struct csiphy_device *csiphy = &camss->csiphy[id];
1420 csiphy->cfg.csi2 = &csd->interface.csi2;
1421 subdev->host_priv = csiphy;
1426 static int camss_subdev_notifier_complete(struct v4l2_async_notifier *async)
1428 struct camss *camss = container_of(async, struct camss, notifier);
1429 struct v4l2_device *v4l2_dev = &camss->v4l2_dev;
1430 struct v4l2_subdev *sd;
1433 list_for_each_entry(sd, &v4l2_dev->subdevs, list) {
1434 if (sd->host_priv) {
1435 struct media_entity *sensor = &sd->entity;
1436 struct csiphy_device *csiphy =
1437 (struct csiphy_device *) sd->host_priv;
1438 struct media_entity *input = &csiphy->subdev.entity;
1441 for (i = 0; i < sensor->num_pads; i++) {
1442 if (sensor->pads[i].flags & MEDIA_PAD_FL_SOURCE)
1445 if (i == sensor->num_pads) {
1447 "No source pad in external entity\n");
1451 ret = media_create_pad_link(sensor, i,
1452 input, MSM_CSIPHY_PAD_SINK,
1453 MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED);
1456 "Failed to link %s->%s entities: %d\n",
1457 sensor->name, input->name, ret);
1463 ret = v4l2_device_register_subdev_nodes(&camss->v4l2_dev);
1467 return media_device_register(&camss->media_dev);
1470 static const struct v4l2_async_notifier_operations camss_subdev_notifier_ops = {
1471 .bound = camss_subdev_notifier_bound,
1472 .complete = camss_subdev_notifier_complete,
1475 static const struct media_device_ops camss_media_ops = {
1476 .link_notify = v4l2_pipeline_link_notify,
1479 static int camss_configure_pd(struct camss *camss)
1481 struct device *dev = camss->dev;
1485 camss->genpd_num = of_count_phandle_with_args(dev->of_node,
1487 "#power-domain-cells");
1488 if (camss->genpd_num < 0) {
1489 dev_err(dev, "Power domains are not defined for camss\n");
1490 return camss->genpd_num;
1494 * If a platform device has just one power domain, then it is attached
1495 * at platform_probe() level, thus there shall be no need and even no
1496 * option to attach it again, this is the case for CAMSS on MSM8916.
1498 if (camss->genpd_num == 1)
1501 camss->genpd = devm_kmalloc_array(dev, camss->genpd_num,
1502 sizeof(*camss->genpd), GFP_KERNEL);
1506 camss->genpd_link = devm_kmalloc_array(dev, camss->genpd_num,
1507 sizeof(*camss->genpd_link),
1509 if (!camss->genpd_link)
1513 * VFE power domains are in the beginning of the list, and while all
1514 * power domains should be attached, only if TITAN_TOP power domain is
1515 * found in the list, it should be linked over here.
1517 for (i = 0; i < camss->genpd_num; i++) {
1518 camss->genpd[i] = dev_pm_domain_attach_by_id(camss->dev, i);
1519 if (IS_ERR(camss->genpd[i])) {
1520 ret = PTR_ERR(camss->genpd[i]);
1525 if (i > camss->res->vfe_num) {
1526 camss->genpd_link[i - 1] = device_link_add(camss->dev, camss->genpd[i - 1],
1527 DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME |
1528 DL_FLAG_RPM_ACTIVE);
1529 if (!camss->genpd_link[i - 1]) {
1538 for (--i ; i >= 0; i--)
1539 dev_pm_domain_detach(camss->genpd[i], true);
1544 static int camss_icc_get(struct camss *camss)
1546 const struct resources_icc *icc_res;
1549 icc_res = camss->res->icc_res;
1551 for (i = 0; i < camss->res->icc_path_num; i++) {
1552 camss->icc_path[i] = devm_of_icc_get(camss->dev,
1554 if (IS_ERR(camss->icc_path[i]))
1555 return PTR_ERR(camss->icc_path[i]);
1561 static void camss_genpd_cleanup(struct camss *camss)
1565 if (camss->genpd_num == 1)
1568 if (camss->genpd_num > camss->res->vfe_num)
1569 device_link_del(camss->genpd_link[camss->genpd_num - 1]);
1571 for (i = 0; i < camss->genpd_num; i++)
1572 dev_pm_domain_detach(camss->genpd[i], true);
1576 * camss_probe - Probe CAMSS platform device
1577 * @pdev: Pointer to CAMSS platform device
1579 * Return 0 on success or a negative error code on failure
1581 static int camss_probe(struct platform_device *pdev)
1583 struct device *dev = &pdev->dev;
1584 struct camss *camss;
1588 camss = devm_kzalloc(dev, sizeof(*camss), GFP_KERNEL);
1592 camss->res = of_device_get_match_data(dev);
1594 atomic_set(&camss->ref_count, 0);
1596 platform_set_drvdata(pdev, camss);
1598 camss->csiphy = devm_kcalloc(dev, camss->res->csiphy_num,
1599 sizeof(*camss->csiphy), GFP_KERNEL);
1603 camss->csid = devm_kcalloc(dev, camss->res->csid_num, sizeof(*camss->csid),
1608 if (camss->res->version == CAMSS_8x16 ||
1609 camss->res->version == CAMSS_8x96) {
1610 camss->ispif = devm_kcalloc(dev, 1, sizeof(*camss->ispif), GFP_KERNEL);
1615 camss->vfe_total_num = camss->res->vfe_num + camss->res->vfe_lite_num;
1616 camss->vfe = devm_kcalloc(dev, camss->vfe_total_num,
1617 sizeof(*camss->vfe), GFP_KERNEL);
1621 ret = camss_icc_get(camss);
1625 ret = camss_configure_pd(camss);
1627 dev_err(dev, "Failed to configure power domains: %d\n", ret);
1631 ret = camss_init_subdevices(camss);
1633 goto err_genpd_cleanup;
1635 ret = dma_set_mask_and_coherent(dev, 0xffffffff);
1637 goto err_genpd_cleanup;
1639 camss->media_dev.dev = camss->dev;
1640 strscpy(camss->media_dev.model, "Qualcomm Camera Subsystem",
1641 sizeof(camss->media_dev.model));
1642 camss->media_dev.ops = &camss_media_ops;
1643 media_device_init(&camss->media_dev);
1645 camss->v4l2_dev.mdev = &camss->media_dev;
1646 ret = v4l2_device_register(camss->dev, &camss->v4l2_dev);
1648 dev_err(dev, "Failed to register V4L2 device: %d\n", ret);
1649 goto err_genpd_cleanup;
1652 v4l2_async_nf_init(&camss->notifier, &camss->v4l2_dev);
1654 num_subdevs = camss_of_parse_ports(camss);
1655 if (num_subdevs < 0) {
1657 goto err_v4l2_device_unregister;
1660 ret = camss_register_entities(camss);
1662 goto err_v4l2_device_unregister;
1665 camss->notifier.ops = &camss_subdev_notifier_ops;
1667 ret = v4l2_async_nf_register(&camss->notifier);
1670 "Failed to register async subdev nodes: %d\n",
1672 goto err_register_subdevs;
1675 ret = v4l2_device_register_subdev_nodes(&camss->v4l2_dev);
1677 dev_err(dev, "Failed to register subdev nodes: %d\n",
1679 goto err_register_subdevs;
1682 ret = media_device_register(&camss->media_dev);
1684 dev_err(dev, "Failed to register media device: %d\n",
1686 goto err_register_subdevs;
1690 pm_runtime_enable(dev);
1694 err_register_subdevs:
1695 camss_unregister_entities(camss);
1696 err_v4l2_device_unregister:
1697 v4l2_device_unregister(&camss->v4l2_dev);
1698 v4l2_async_nf_cleanup(&camss->notifier);
1700 camss_genpd_cleanup(camss);
1705 void camss_delete(struct camss *camss)
1707 v4l2_device_unregister(&camss->v4l2_dev);
1708 media_device_unregister(&camss->media_dev);
1709 media_device_cleanup(&camss->media_dev);
1711 pm_runtime_disable(camss->dev);
1715 * camss_remove - Remove CAMSS platform device
1716 * @pdev: Pointer to CAMSS platform device
1720 static void camss_remove(struct platform_device *pdev)
1722 struct camss *camss = platform_get_drvdata(pdev);
1724 v4l2_async_nf_unregister(&camss->notifier);
1725 v4l2_async_nf_cleanup(&camss->notifier);
1726 camss_unregister_entities(camss);
1728 if (atomic_read(&camss->ref_count) == 0)
1729 camss_delete(camss);
1731 camss_genpd_cleanup(camss);
1734 static const struct camss_resources msm8916_resources = {
1735 .version = CAMSS_8x16,
1736 .csiphy_res = csiphy_res_8x16,
1737 .csid_res = csid_res_8x16,
1738 .ispif_res = &ispif_res_8x16,
1739 .vfe_res = vfe_res_8x16,
1740 .csiphy_num = ARRAY_SIZE(csiphy_res_8x16),
1741 .csid_num = ARRAY_SIZE(csid_res_8x16),
1742 .vfe_num = ARRAY_SIZE(vfe_res_8x16),
1745 static const struct camss_resources msm8996_resources = {
1746 .version = CAMSS_8x96,
1747 .csiphy_res = csiphy_res_8x96,
1748 .csid_res = csid_res_8x96,
1749 .ispif_res = &ispif_res_8x96,
1750 .vfe_res = vfe_res_8x96,
1751 .csiphy_num = ARRAY_SIZE(csiphy_res_8x96),
1752 .csid_num = ARRAY_SIZE(csid_res_8x96),
1753 .vfe_num = ARRAY_SIZE(vfe_res_8x96),
1756 static const struct camss_resources sdm660_resources = {
1757 .version = CAMSS_660,
1758 .csiphy_res = csiphy_res_660,
1759 .csid_res = csid_res_660,
1760 .ispif_res = &ispif_res_660,
1761 .vfe_res = vfe_res_660,
1762 .csiphy_num = ARRAY_SIZE(csiphy_res_660),
1763 .csid_num = ARRAY_SIZE(csid_res_660),
1764 .vfe_num = ARRAY_SIZE(vfe_res_660),
1767 static const struct camss_resources sdm845_resources = {
1768 .version = CAMSS_845,
1769 .csiphy_res = csiphy_res_845,
1770 .csid_res = csid_res_845,
1771 .vfe_res = vfe_res_845,
1772 .csiphy_num = ARRAY_SIZE(csiphy_res_845),
1773 .csid_num = ARRAY_SIZE(csid_res_845),
1778 static const struct camss_resources sm8250_resources = {
1779 .version = CAMSS_8250,
1780 .csiphy_res = csiphy_res_8250,
1781 .csid_res = csid_res_8250,
1782 .vfe_res = vfe_res_8250,
1783 .icc_res = icc_res_sm8250,
1784 .icc_path_num = ARRAY_SIZE(icc_res_sm8250),
1785 .csiphy_num = ARRAY_SIZE(csiphy_res_8250),
1786 .csid_num = ARRAY_SIZE(csid_res_8250),
1791 static const struct of_device_id camss_dt_match[] = {
1792 { .compatible = "qcom,msm8916-camss", .data = &msm8916_resources },
1793 { .compatible = "qcom,msm8996-camss", .data = &msm8996_resources },
1794 { .compatible = "qcom,sdm660-camss", .data = &sdm660_resources },
1795 { .compatible = "qcom,sdm845-camss", .data = &sdm845_resources },
1796 { .compatible = "qcom,sm8250-camss", .data = &sm8250_resources },
1800 MODULE_DEVICE_TABLE(of, camss_dt_match);
1802 static int __maybe_unused camss_runtime_suspend(struct device *dev)
1804 struct camss *camss = dev_get_drvdata(dev);
1808 for (i = 0; i < camss->res->icc_path_num; i++) {
1809 ret = icc_set_bw(camss->icc_path[i], 0, 0);
1817 static int __maybe_unused camss_runtime_resume(struct device *dev)
1819 struct camss *camss = dev_get_drvdata(dev);
1820 const struct resources_icc *icc_res = camss->res->icc_res;
1824 for (i = 0; i < camss->res->icc_path_num; i++) {
1825 ret = icc_set_bw(camss->icc_path[i],
1826 icc_res[i].icc_bw_tbl.avg,
1827 icc_res[i].icc_bw_tbl.peak);
1835 static const struct dev_pm_ops camss_pm_ops = {
1836 SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
1837 pm_runtime_force_resume)
1838 SET_RUNTIME_PM_OPS(camss_runtime_suspend, camss_runtime_resume, NULL)
1841 static struct platform_driver qcom_camss_driver = {
1842 .probe = camss_probe,
1843 .remove_new = camss_remove,
1845 .name = "qcom-camss",
1846 .of_match_table = camss_dt_match,
1847 .pm = &camss_pm_ops,
1851 module_platform_driver(qcom_camss_driver);
1853 MODULE_ALIAS("platform:qcom-camss");
1854 MODULE_DESCRIPTION("Qualcomm Camera Subsystem driver");
1855 MODULE_AUTHOR("Todor Tomov <todor.tomov@linaro.org>");
1856 MODULE_LICENSE("GPL v2");