diff options
Diffstat (limited to 'drivers/media/platform/qcom/camss/camss.c')
| -rw-r--r-- | drivers/media/platform/qcom/camss/camss.c | 4348 |
1 files changed, 3920 insertions, 428 deletions
diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c index ef100d5f7763..fcc2b2c3cba0 100644 --- a/drivers/media/platform/qcom/camss/camss.c +++ b/drivers/media/platform/qcom/camss/camss.c @@ -8,11 +8,13 @@ * Copyright (C) 2015-2018 Linaro Ltd. */ #include <linux/clk.h> +#include <linux/interconnect.h> #include <linux/media-bus-format.h> #include <linux/media.h> #include <linux/module.h> #include <linux/platform_device.h> #include <linux/of.h> +#include <linux/of_device.h> #include <linux/of_graph.h> #include <linux/pm_runtime.h> #include <linux/pm_domain.h> @@ -30,36 +32,48 @@ #define CAMSS_CLOCK_MARGIN_NUMERATOR 105 #define CAMSS_CLOCK_MARGIN_DENOMINATOR 100 -static const struct resources csiphy_res_8x16[] = { +static const struct parent_dev_ops vfe_parent_dev_ops; + +static const struct camss_subdev_resources csiphy_res_8x16[] = { /* CSIPHY0 */ { - .regulator = { NULL }, + .regulators = {}, .clock = { "top_ahb", "ispif_ahb", "ahb", "csiphy0_timer" }, .clock_rate = { { 0 }, { 0 }, { 0 }, { 100000000, 200000000 } }, .reg = { "csiphy0", "csiphy0_clk_mux" }, - .interrupt = { "csiphy0" } + .interrupt = { "csiphy0" }, + .csiphy = { + .id = 0, + .hw_ops = &csiphy_ops_2ph_1_0, + .formats = &csiphy_formats_8x16 + } }, /* CSIPHY1 */ { - .regulator = { NULL }, + .regulators = {}, .clock = { "top_ahb", "ispif_ahb", "ahb", "csiphy1_timer" }, .clock_rate = { { 0 }, { 0 }, { 0 }, { 100000000, 200000000 } }, .reg = { "csiphy1", "csiphy1_clk_mux" }, - .interrupt = { "csiphy1" } + .interrupt = { "csiphy1" }, + .csiphy = { + .id = 1, + .hw_ops = &csiphy_ops_2ph_1_0, + .formats = &csiphy_formats_8x16 + } } }; -static const struct resources csid_res_8x16[] = { +static const struct camss_subdev_resources csid_res_8x16[] = { /* CSID0 */ { - .regulator = { "vdda" }, + .regulators = { "vdda" }, .clock = { "top_ahb", "ispif_ahb", "csi0_ahb", "ahb", "csi0", "csi0_phy", "csi0_pix", "csi0_rdi" }, .clock_rate = { { 0 }, @@ -71,12 +85,17 @@ static const struct resources csid_res_8x16[] = { { 0 }, { 0 } }, .reg = { "csid0" }, - .interrupt = { "csid0" } + .interrupt = { "csid0" }, + .csid = { + .hw_ops = &csid_ops_4_1, + .parent_dev_ops = &vfe_parent_dev_ops, + .formats = &csid_formats_4_1 + } }, /* CSID1 */ { - .regulator = { "vdda" }, + .regulators = { "vdda" }, .clock = { "top_ahb", "ispif_ahb", "csi1_ahb", "ahb", "csi1", "csi1_phy", "csi1_pix", "csi1_rdi" }, .clock_rate = { { 0 }, @@ -88,25 +107,29 @@ static const struct resources csid_res_8x16[] = { { 0 }, { 0 } }, .reg = { "csid1" }, - .interrupt = { "csid1" } + .interrupt = { "csid1" }, + .csid = { + .hw_ops = &csid_ops_4_1, + .parent_dev_ops = &vfe_parent_dev_ops, + .formats = &csid_formats_4_1 + } }, }; -static const struct resources_ispif ispif_res_8x16 = { +static const struct camss_subdev_resources ispif_res_8x16 = { /* ISPIF */ .clock = { "top_ahb", "ahb", "ispif_ahb", "csi0", "csi0_pix", "csi0_rdi", "csi1", "csi1_pix", "csi1_rdi" }, .clock_for_reset = { "vfe0", "csi_vfe0" }, .reg = { "ispif", "csi_clk_mux" }, - .interrupt = "ispif" - + .interrupt = { "ispif" }, }; -static const struct resources vfe_res_8x16[] = { +static const struct camss_subdev_resources vfe_res_8x16[] = { /* VFE0 */ { - .regulator = { NULL }, + .regulators = {}, .clock = { "top_ahb", "vfe0", "csi_vfe0", "vfe_ahb", "vfe_axi", "ahb" }, .clock_rate = { { 0 }, @@ -121,52 +144,370 @@ static const struct resources vfe_res_8x16[] = { { 0 }, { 0 } }, .reg = { "vfe0" }, - .interrupt = { "vfe0" } + .interrupt = { "vfe0" }, + .vfe = { + .line_num = 3, + .hw_ops = &vfe_ops_4_1, + .formats_rdi = &vfe_formats_rdi_8x16, + .formats_pix = &vfe_formats_pix_8x16 + } } }; -static const struct resources csiphy_res_8x96[] = { +static const struct camss_subdev_resources csiphy_res_8x39[] = { /* CSIPHY0 */ { - .regulator = { NULL }, + .regulators = { "vdda" }, + .clock = { "top_ahb", "ispif_ahb", "ahb", "csiphy0_timer" }, + .clock_rate = { { 0 }, + { 40000000, 80000000 }, + { 0 }, + { 100000000, 200000000 } }, + .reg = { "csiphy0", "csiphy0_clk_mux" }, + .interrupt = { "csiphy0" }, + .csiphy = { + .id = 0, + .hw_ops = &csiphy_ops_2ph_1_0, + .formats = &csiphy_formats_8x16 + } + }, + + /* CSIPHY1 */ + { + .regulators = { "vdda" }, + .clock = { "top_ahb", "ispif_ahb", "ahb", "csiphy1_timer" }, + .clock_rate = { { 0 }, + { 40000000, 80000000 }, + { 0 }, + { 100000000, 200000000 } }, + .reg = { "csiphy1", "csiphy1_clk_mux" }, + .interrupt = { "csiphy1" }, + .csiphy = { + .id = 1, + .hw_ops = &csiphy_ops_2ph_1_0, + .formats = &csiphy_formats_8x16 + } + } +}; + +static const struct camss_subdev_resources csid_res_8x39[] = { + /* CSID0 */ + { + .regulators = {}, + .clock = { "top_ahb", "ispif_ahb", "csi0_ahb", "ahb", + "csi0", "csi0_phy", "csi0_pix", "csi0_rdi" }, + .clock_rate = { { 0 }, + { 40000000, 80000000 }, + { 0 }, + { 0 }, + { 100000000, 200000000 }, + { 0 }, + { 0 }, + { 0 } }, + .reg = { "csid0" }, + .interrupt = { "csid0" }, + .csid = { + .hw_ops = &csid_ops_4_1, + .parent_dev_ops = &vfe_parent_dev_ops, + .formats = &csid_formats_4_1 + } + }, + + /* CSID1 */ + { + .regulators = {}, + .clock = { "top_ahb", "ispif_ahb", "csi1_ahb", "ahb", + "csi1", "csi1_phy", "csi1_pix", "csi1_rdi" }, + .clock_rate = { { 0 }, + { 40000000, 80000000 }, + { 0 }, + { 0 }, + { 100000000, 200000000 }, + { 0 }, + { 0 }, + { 0 } }, + .reg = { "csid1" }, + .interrupt = { "csid1" }, + .csid = { + .hw_ops = &csid_ops_4_1, + .parent_dev_ops = &vfe_parent_dev_ops, + .formats = &csid_formats_4_1 + } + }, + + /* CSID2 */ + { + .regulators = {}, + .clock = { "top_ahb", "ispif_ahb", "csi2_ahb", "ahb", + "csi2", "csi2_phy", "csi2_pix", "csi2_rdi" }, + .clock_rate = { { 0 }, + { 40000000, 80000000 }, + { 0 }, + { 0 }, + { 100000000, 200000000 }, + { 0 }, + { 0 }, + { 0 } }, + .reg = { "csid2" }, + .interrupt = { "csid2" }, + .csid = { + .hw_ops = &csid_ops_4_1, + .parent_dev_ops = &vfe_parent_dev_ops, + .formats = &csid_formats_4_1 + } + }, +}; + +static const struct camss_subdev_resources ispif_res_8x39 = { + /* ISPIF */ + .clock = { "top_ahb", "ispif_ahb", "ahb", + "csi0", "csi0_pix", "csi0_rdi", + "csi1", "csi1_pix", "csi1_rdi", + "csi2", "csi2_pix", "csi2_rdi" }, + .clock_for_reset = { "vfe0", "csi_vfe0" }, + .reg = { "ispif", "csi_clk_mux" }, + .interrupt = { "ispif" }, +}; + +static const struct camss_subdev_resources vfe_res_8x39[] = { + /* VFE0 */ + { + .regulators = {}, + .clock = { "top_ahb", "ispif_ahb", "vfe0", "csi_vfe0", + "vfe_ahb", "vfe_axi", "ahb" }, + .clock_rate = { { 0 }, + { 40000000, 80000000 }, + { 50000000, 80000000, 100000000, 160000000, + 177780000, 200000000, 266670000, 320000000, + 400000000, 465000000, 480000000, 600000000 }, + { 0 }, + { 0 }, + { 0 }, + { 0 } }, + .reg = { "vfe0" }, + .interrupt = { "vfe0" }, + .vfe = { + .line_num = 3, + .has_vbif = true, + .vbif_name = "vfe0_vbif", + .hw_ops = &vfe_ops_4_1, + .formats_rdi = &vfe_formats_rdi_8x16, + .formats_pix = &vfe_formats_pix_8x16 + } + } +}; + +static const struct camss_subdev_resources csid_res_8x53[] = { + /* CSID0 */ + { + .regulators = { "vdda" }, + .clock = { "top_ahb", "ispif_ahb", "csi0_ahb", "ahb", + "csi0", "csi0_phy", "csi0_pix", "csi0_rdi" }, + .clock_rate = { { 0 }, + { 0 }, + { 0 }, + { 0 }, + { 100000000, 200000000, 310000000, + 400000000, 465000000 }, + { 0 }, + { 0 }, + { 0 } }, + .reg = { "csid0" }, + .interrupt = { "csid0" }, + .csid = { + .hw_ops = &csid_ops_4_7, + .parent_dev_ops = &vfe_parent_dev_ops, + .formats = &csid_formats_4_7 + } + }, + + /* CSID1 */ + { + .regulators = { "vdda" }, + .clock = { "top_ahb", "ispif_ahb", "csi1_ahb", "ahb", + "csi1", "csi1_phy", "csi1_pix", "csi1_rdi" }, + .clock_rate = { { 0 }, + { 0 }, + { 0 }, + { 0 }, + { 100000000, 200000000, 310000000, + 400000000, 465000000 }, + { 0 }, + { 0 }, + { 0 } }, + .reg = { "csid1" }, + .interrupt = { "csid1" }, + .csid = { + .hw_ops = &csid_ops_4_7, + .parent_dev_ops = &vfe_parent_dev_ops, + .formats = &csid_formats_4_7 + } + }, + + /* CSID2 */ + { + .regulators = { "vdda" }, + .clock = { "top_ahb", "ispif_ahb", "csi2_ahb", "ahb", + "csi2", "csi2_phy", "csi2_pix", "csi2_rdi" }, + .clock_rate = { { 0 }, + { 0 }, + { 0 }, + { 0 }, + { 100000000, 200000000, 310000000, + 400000000, 465000000 }, + { 0 }, + { 0 }, + { 0 } }, + .reg = { "csid2" }, + .interrupt = { "csid2" }, + .csid = { + .hw_ops = &csid_ops_4_7, + .parent_dev_ops = &vfe_parent_dev_ops, + .formats = &csid_formats_4_7 + } + }, +}; + +static const struct camss_subdev_resources ispif_res_8x53 = { + /* ISPIF */ + .clock = { "top_ahb", "ahb", "ispif_ahb", + "csi0", "csi0_pix", "csi0_rdi", + "csi1", "csi1_pix", "csi1_rdi", + "csi2", "csi2_pix", "csi2_rdi" }, + .clock_for_reset = { "vfe0", "csi_vfe0", "vfe1", "csi_vfe1" }, + .reg = { "ispif", "csi_clk_mux" }, + .interrupt = { "ispif" }, +}; + +static const struct camss_subdev_resources vfe_res_8x53[] = { + /* VFE0 */ + { + .regulators = {}, + .clock = { "top_ahb", "ahb", "ispif_ahb", + "vfe0", "csi_vfe0", "vfe0_ahb", "vfe0_axi" }, + .clock_rate = { { 0 }, + { 0 }, + { 0 }, + { 50000000, 100000000, 133330000, + 160000000, 200000000, 266670000, + 310000000, 400000000, 465000000 }, + { 0 }, + { 0 }, + { 0 } }, + .reg = { "vfe0" }, + .interrupt = { "vfe0" }, + .vfe = { + .line_num = 3, + .has_pd = true, + .pd_name = "vfe0", + .hw_ops = &vfe_ops_4_1, + .formats_rdi = &vfe_formats_rdi_8x16, + .formats_pix = &vfe_formats_pix_8x16 + } + }, + + /* VFE1 */ + { + .regulators = {}, + .clock = { "top_ahb", "ahb", "ispif_ahb", + "vfe1", "csi_vfe1", "vfe1_ahb", "vfe1_axi" }, + .clock_rate = { { 0 }, + { 0 }, + { 0 }, + { 50000000, 100000000, 133330000, + 160000000, 200000000, 266670000, + 310000000, 400000000, 465000000 }, + { 0 }, + { 0 }, + { 0 } }, + .reg = { "vfe1" }, + .interrupt = { "vfe1" }, + .vfe = { + .line_num = 3, + .has_pd = true, + .pd_name = "vfe1", + .hw_ops = &vfe_ops_4_1, + .formats_rdi = &vfe_formats_rdi_8x16, + .formats_pix = &vfe_formats_pix_8x16 + } + } +}; + +static const struct resources_icc icc_res_8x53[] = { + { + .name = "cam_ahb", + .icc_bw_tbl.avg = 38400, + .icc_bw_tbl.peak = 76800, + }, + { + .name = "cam_vfe0_mem", + .icc_bw_tbl.avg = 939524, + .icc_bw_tbl.peak = 1342177, + }, + { + .name = "cam_vfe1_mem", + .icc_bw_tbl.avg = 939524, + .icc_bw_tbl.peak = 1342177, + }, +}; + +static const struct camss_subdev_resources csiphy_res_8x96[] = { + /* CSIPHY0 */ + { + .regulators = {}, .clock = { "top_ahb", "ispif_ahb", "ahb", "csiphy0_timer" }, .clock_rate = { { 0 }, { 0 }, { 0 }, { 100000000, 200000000, 266666667 } }, .reg = { "csiphy0", "csiphy0_clk_mux" }, - .interrupt = { "csiphy0" } + .interrupt = { "csiphy0" }, + .csiphy = { + .id = 0, + .hw_ops = &csiphy_ops_3ph_1_0, + .formats = &csiphy_formats_8x96 + } }, /* CSIPHY1 */ { - .regulator = { NULL }, + .regulators = {}, .clock = { "top_ahb", "ispif_ahb", "ahb", "csiphy1_timer" }, .clock_rate = { { 0 }, { 0 }, { 0 }, { 100000000, 200000000, 266666667 } }, .reg = { "csiphy1", "csiphy1_clk_mux" }, - .interrupt = { "csiphy1" } + .interrupt = { "csiphy1" }, + .csiphy = { + .id = 1, + .hw_ops = &csiphy_ops_3ph_1_0, + .formats = &csiphy_formats_8x96 + } }, /* CSIPHY2 */ { - .regulator = { NULL }, + .regulators = {}, .clock = { "top_ahb", "ispif_ahb", "ahb", "csiphy2_timer" }, .clock_rate = { { 0 }, { 0 }, { 0 }, { 100000000, 200000000, 266666667 } }, .reg = { "csiphy2", "csiphy2_clk_mux" }, - .interrupt = { "csiphy2" } + .interrupt = { "csiphy2" }, + .csiphy = { + .id = 2, + .hw_ops = &csiphy_ops_3ph_1_0, + .formats = &csiphy_formats_8x96 + } } }; -static const struct resources csid_res_8x96[] = { +static const struct camss_subdev_resources csid_res_8x96[] = { /* CSID0 */ { - .regulator = { "vdda" }, + .regulators = { "vdda" }, .clock = { "top_ahb", "ispif_ahb", "csi0_ahb", "ahb", "csi0", "csi0_phy", "csi0_pix", "csi0_rdi" }, .clock_rate = { { 0 }, @@ -178,12 +519,17 @@ static const struct resources csid_res_8x96[] = { { 0 }, { 0 } }, .reg = { "csid0" }, - .interrupt = { "csid0" } + .interrupt = { "csid0" }, + .csid = { + .hw_ops = &csid_ops_4_7, + .parent_dev_ops = &vfe_parent_dev_ops, + .formats = &csid_formats_4_7 + } }, /* CSID1 */ { - .regulator = { "vdda" }, + .regulators = { "vdda" }, .clock = { "top_ahb", "ispif_ahb", "csi1_ahb", "ahb", "csi1", "csi1_phy", "csi1_pix", "csi1_rdi" }, .clock_rate = { { 0 }, @@ -195,12 +541,17 @@ static const struct resources csid_res_8x96[] = { { 0 }, { 0 } }, .reg = { "csid1" }, - .interrupt = { "csid1" } + .interrupt = { "csid1" }, + .csid = { + .hw_ops = &csid_ops_4_7, + .parent_dev_ops = &vfe_parent_dev_ops, + .formats = &csid_formats_4_7 + } }, /* CSID2 */ { - .regulator = { "vdda" }, + .regulators = { "vdda" }, .clock = { "top_ahb", "ispif_ahb", "csi2_ahb", "ahb", "csi2", "csi2_phy", "csi2_pix", "csi2_rdi" }, .clock_rate = { { 0 }, @@ -212,12 +563,17 @@ static const struct resources csid_res_8x96[] = { { 0 }, { 0 } }, .reg = { "csid2" }, - .interrupt = { "csid2" } + .interrupt = { "csid2" }, + .csid = { + .hw_ops = &csid_ops_4_7, + .parent_dev_ops = &vfe_parent_dev_ops, + .formats = &csid_formats_4_7 + } }, /* CSID3 */ { - .regulator = { "vdda" }, + .regulators = { "vdda" }, .clock = { "top_ahb", "ispif_ahb", "csi3_ahb", "ahb", "csi3", "csi3_phy", "csi3_pix", "csi3_rdi" }, .clock_rate = { { 0 }, @@ -229,11 +585,16 @@ static const struct resources csid_res_8x96[] = { { 0 }, { 0 } }, .reg = { "csid3" }, - .interrupt = { "csid3" } + .interrupt = { "csid3" }, + .csid = { + .hw_ops = &csid_ops_4_7, + .parent_dev_ops = &vfe_parent_dev_ops, + .formats = &csid_formats_4_7 + } } }; -static const struct resources_ispif ispif_res_8x96 = { +static const struct camss_subdev_resources ispif_res_8x96 = { /* ISPIF */ .clock = { "top_ahb", "ahb", "ispif_ahb", "csi0", "csi0_pix", "csi0_rdi", @@ -242,13 +603,13 @@ static const struct resources_ispif ispif_res_8x96 = { "csi3", "csi3_pix", "csi3_rdi" }, .clock_for_reset = { "vfe0", "csi_vfe0", "vfe1", "csi_vfe1" }, .reg = { "ispif", "csi_clk_mux" }, - .interrupt = "ispif" + .interrupt = { "ispif" }, }; -static const struct resources vfe_res_8x96[] = { +static const struct camss_subdev_resources vfe_res_8x96[] = { /* VFE0 */ { - .regulator = { NULL }, + .regulators = {}, .clock = { "top_ahb", "ahb", "vfe0", "csi_vfe0", "vfe_ahb", "vfe0_ahb", "vfe_axi", "vfe0_stream"}, .clock_rate = { { 0 }, @@ -261,12 +622,19 @@ static const struct resources vfe_res_8x96[] = { { 0 }, { 0 } }, .reg = { "vfe0" }, - .interrupt = { "vfe0" } + .interrupt = { "vfe0" }, + .vfe = { + .line_num = 3, + .has_pd = true, + .hw_ops = &vfe_ops_4_7, + .formats_rdi = &vfe_formats_rdi_8x96, + .formats_pix = &vfe_formats_pix_8x96 + } }, /* VFE1 */ { - .regulator = { NULL }, + .regulators = {}, .clock = { "top_ahb", "ahb", "vfe1", "csi_vfe1", "vfe_ahb", "vfe1_ahb", "vfe_axi", "vfe1_stream"}, .clock_rate = { { 0 }, @@ -279,14 +647,155 @@ static const struct resources vfe_res_8x96[] = { { 0 }, { 0 } }, .reg = { "vfe1" }, - .interrupt = { "vfe1" } + .interrupt = { "vfe1" }, + .vfe = { + .line_num = 3, + .has_pd = true, + .hw_ops = &vfe_ops_4_7, + .formats_rdi = &vfe_formats_rdi_8x96, + .formats_pix = &vfe_formats_pix_8x96 + } } }; -static const struct resources csiphy_res_660[] = { +static const struct camss_subdev_resources csiphy_res_2290[] = { /* CSIPHY0 */ { - .regulator = { NULL }, + .regulators = { "vdd-csiphy-1p2", "vdd-csiphy-1p8" }, + .clock = { "top_ahb", "ahb", "csiphy0", "csiphy0_timer" }, + .clock_rate = { { 0 }, + { 0 }, + { 240000000, 341330000, 384000000 }, + { 100000000, 200000000, 268800000 } }, + .reg = { "csiphy0" }, + .interrupt = { "csiphy0" }, + .csiphy = { + .id = 0, + .hw_ops = &csiphy_ops_3ph_1_0, + .formats = &csiphy_formats_sdm845 + } + }, + + /* CSIPHY1 */ + { + .regulators = { "vdd-csiphy-1p2", "vdd-csiphy-1p8" }, + .clock = { "top_ahb", "ahb", "csiphy1", "csiphy1_timer" }, + .clock_rate = { { 0 }, + { 0 }, + { 240000000, 341330000, 384000000 }, + { 100000000, 200000000, 268800000 } }, + .reg = { "csiphy1" }, + .interrupt = { "csiphy1" }, + .csiphy = { + .id = 1, + .hw_ops = &csiphy_ops_3ph_1_0, + .formats = &csiphy_formats_sdm845 + } + } +}; + +static const struct camss_subdev_resources csid_res_2290[] = { + /* CSID0 */ + { + .regulators = {}, + .clock = { "top_ahb", "ahb", "csi0", "vfe0_cphy_rx", "vfe0" }, + .clock_rate = { { 0 }, + { 0 }, + { 192000000, 240000000, 384000000, 426400000 }, + { 0 }, + { 0 } }, + .reg = { "csid0" }, + .interrupt = { "csid0" }, + .csid = { + .hw_ops = &csid_ops_340, + .parent_dev_ops = &vfe_parent_dev_ops, + .formats = &csid_formats_gen2 + } + }, + + /* CSID1 */ + { + .regulators = {}, + .clock = { "top_ahb", "ahb", "csi1", "vfe1_cphy_rx", "vfe1" }, + .clock_rate = { { 0 }, + { 0 }, + { 192000000, 240000000, 384000000, 426400000 }, + { 0 }, + { 0 } }, + .reg = { "csid1" }, + .interrupt = { "csid1" }, + .csid = { + .hw_ops = &csid_ops_340, + .parent_dev_ops = &vfe_parent_dev_ops, + .formats = &csid_formats_gen2 + } + } +}; + +static const struct camss_subdev_resources vfe_res_2290[] = { + /* VFE0 */ + { + .regulators = {}, + .clock = { "top_ahb", "ahb", "axi", "vfe0", "camnoc_rt_axi", "camnoc_nrt_axi" }, + .clock_rate = { { 0 }, + { 0 }, + { 0 }, + { 19200000, 153600000, 192000000, 256000000, 384000000, 460800000 }, + { 0 }, + { 0 }, }, + .reg = { "vfe0" }, + .interrupt = { "vfe0" }, + .vfe = { + .line_num = 4, + .hw_ops = &vfe_ops_340, + .formats_rdi = &vfe_formats_rdi_845, + .formats_pix = &vfe_formats_pix_845 + } + }, + + /* VFE1 */ + { + .regulators = {}, + .clock = { "top_ahb", "ahb", "axi", "vfe1", "camnoc_rt_axi", "camnoc_nrt_axi" }, + .clock_rate = { { 0 }, + { 0 }, + { 0 }, + { 19200000, 153600000, 192000000, 256000000, 384000000, 460800000 }, + { 0 }, + { 0 }, }, + .reg = { "vfe1" }, + .interrupt = { "vfe1" }, + .vfe = { + .line_num = 4, + .hw_ops = &vfe_ops_340, + .formats_rdi = &vfe_formats_rdi_845, + .formats_pix = &vfe_formats_pix_845 + } + }, +}; + +static const struct resources_icc icc_res_2290[] = { + { + .name = "ahb", + .icc_bw_tbl.avg = 150000, + .icc_bw_tbl.peak = 300000, + }, + { + .name = "hf_mnoc", + .icc_bw_tbl.avg = 2097152, + .icc_bw_tbl.peak = 3000000, + }, + { + .name = "sf_mnoc", + .icc_bw_tbl.avg = 2097152, + .icc_bw_tbl.peak = 3000000, + }, +}; + +static const struct camss_subdev_resources csiphy_res_660[] = { + /* CSIPHY0 */ + { + .regulators = {}, .clock = { "top_ahb", "ispif_ahb", "ahb", "csiphy0_timer", "csi0_phy", "csiphy_ahb2crif" }, .clock_rate = { { 0 }, @@ -295,12 +804,17 @@ static const struct resources csiphy_res_660[] = { { 100000000, 200000000, 269333333 }, { 0 } }, .reg = { "csiphy0", "csiphy0_clk_mux" }, - .interrupt = { "csiphy0" } + .interrupt = { "csiphy0" }, + .csiphy = { + .id = 0, + .hw_ops = &csiphy_ops_3ph_1_0, + .formats = &csiphy_formats_8x96 + } }, /* CSIPHY1 */ { - .regulator = { NULL }, + .regulators = {}, .clock = { "top_ahb", "ispif_ahb", "ahb", "csiphy1_timer", "csi1_phy", "csiphy_ahb2crif" }, .clock_rate = { { 0 }, @@ -309,12 +823,17 @@ static const struct resources csiphy_res_660[] = { { 100000000, 200000000, 269333333 }, { 0 } }, .reg = { "csiphy1", "csiphy1_clk_mux" }, - .interrupt = { "csiphy1" } + .interrupt = { "csiphy1" }, + .csiphy = { + .id = 1, + .hw_ops = &csiphy_ops_3ph_1_0, + .formats = &csiphy_formats_8x96 + } }, /* CSIPHY2 */ { - .regulator = { NULL }, + .regulators = {}, .clock = { "top_ahb", "ispif_ahb", "ahb", "csiphy2_timer", "csi2_phy", "csiphy_ahb2crif" }, .clock_rate = { { 0 }, @@ -323,14 +842,19 @@ static const struct resources csiphy_res_660[] = { { 100000000, 200000000, 269333333 }, { 0 } }, .reg = { "csiphy2", "csiphy2_clk_mux" }, - .interrupt = { "csiphy2" } + .interrupt = { "csiphy2" }, + .csiphy = { + .id = 2, + .hw_ops = &csiphy_ops_3ph_1_0, + .formats = &csiphy_formats_8x96 + } } }; -static const struct resources csid_res_660[] = { +static const struct camss_subdev_resources csid_res_660[] = { /* CSID0 */ { - .regulator = { "vdda", "vdd_sec" }, + .regulators = { "vdda", "vdd_sec" }, .clock = { "top_ahb", "ispif_ahb", "csi0_ahb", "ahb", "csi0", "csi0_phy", "csi0_pix", "csi0_rdi", "cphy_csid0" }, @@ -345,12 +869,17 @@ static const struct resources csid_res_660[] = { { 0 }, { 0 } }, .reg = { "csid0" }, - .interrupt = { "csid0" } + .interrupt = { "csid0" }, + .csid = { + .hw_ops = &csid_ops_4_7, + .parent_dev_ops = &vfe_parent_dev_ops, + .formats = &csid_formats_4_7 + } }, /* CSID1 */ { - .regulator = { "vdda", "vdd_sec" }, + .regulators = { "vdda", "vdd_sec" }, .clock = { "top_ahb", "ispif_ahb", "csi1_ahb", "ahb", "csi1", "csi1_phy", "csi1_pix", "csi1_rdi", "cphy_csid1" }, @@ -365,12 +894,17 @@ static const struct resources csid_res_660[] = { { 0 }, { 0 } }, .reg = { "csid1" }, - .interrupt = { "csid1" } + .interrupt = { "csid1" }, + .csid = { + .hw_ops = &csid_ops_4_7, + .parent_dev_ops = &vfe_parent_dev_ops, + .formats = &csid_formats_4_7 + } }, /* CSID2 */ { - .regulator = { "vdda", "vdd_sec" }, + .regulators = { "vdda", "vdd_sec" }, .clock = { "top_ahb", "ispif_ahb", "csi2_ahb", "ahb", "csi2", "csi2_phy", "csi2_pix", "csi2_rdi", "cphy_csid2" }, @@ -385,12 +919,17 @@ static const struct resources csid_res_660[] = { { 0 }, { 0 } }, .reg = { "csid2" }, - .interrupt = { "csid2" } + .interrupt = { "csid2" }, + .csid = { + .hw_ops = &csid_ops_4_7, + .parent_dev_ops = &vfe_parent_dev_ops, + .formats = &csid_formats_4_7 + } }, /* CSID3 */ { - .regulator = { "vdda", "vdd_sec" }, + .regulators = { "vdda", "vdd_sec" }, .clock = { "top_ahb", "ispif_ahb", "csi3_ahb", "ahb", "csi3", "csi3_phy", "csi3_pix", "csi3_rdi", "cphy_csid3" }, @@ -405,11 +944,16 @@ static const struct resources csid_res_660[] = { { 0 }, { 0 } }, .reg = { "csid3" }, - .interrupt = { "csid3" } + .interrupt = { "csid3" }, + .csid = { + .hw_ops = &csid_ops_4_7, + .parent_dev_ops = &vfe_parent_dev_ops, + .formats = &csid_formats_4_7 + } } }; -static const struct resources_ispif ispif_res_660 = { +static const struct camss_subdev_resources ispif_res_660 = { /* ISPIF */ .clock = { "top_ahb", "ahb", "ispif_ahb", "csi0", "csi0_pix", "csi0_rdi", @@ -418,13 +962,13 @@ static const struct resources_ispif ispif_res_660 = { "csi3", "csi3_pix", "csi3_rdi" }, .clock_for_reset = { "vfe0", "csi_vfe0", "vfe1", "csi_vfe1" }, .reg = { "ispif", "csi_clk_mux" }, - .interrupt = "ispif" + .interrupt = { "ispif" }, }; -static const struct resources vfe_res_660[] = { +static const struct camss_subdev_resources vfe_res_660[] = { /* VFE0 */ { - .regulator = { NULL }, + .regulators = {}, .clock = { "throttle_axi", "top_ahb", "ahb", "vfe0", "csi_vfe0", "vfe_ahb", "vfe0_ahb", "vfe_axi", "vfe0_stream"}, @@ -440,12 +984,19 @@ static const struct resources vfe_res_660[] = { { 0 }, { 0 } }, .reg = { "vfe0" }, - .interrupt = { "vfe0" } + .interrupt = { "vfe0" }, + .vfe = { + .line_num = 3, + .has_pd = true, + .hw_ops = &vfe_ops_4_8, + .formats_rdi = &vfe_formats_rdi_8x96, + .formats_pix = &vfe_formats_pix_8x96 + } }, /* VFE1 */ { - .regulator = { NULL }, + .regulators = {}, .clock = { "throttle_axi", "top_ahb", "ahb", "vfe1", "csi_vfe1", "vfe_ahb", "vfe1_ahb", "vfe_axi", "vfe1_stream"}, @@ -461,14 +1012,203 @@ static const struct resources vfe_res_660[] = { { 0 }, { 0 } }, .reg = { "vfe1" }, - .interrupt = { "vfe1" } + .interrupt = { "vfe1" }, + .vfe = { + .line_num = 3, + .has_pd = true, + .hw_ops = &vfe_ops_4_8, + .formats_rdi = &vfe_formats_rdi_8x96, + .formats_pix = &vfe_formats_pix_8x96 + } + } +}; + +static const struct camss_subdev_resources csiphy_res_670[] = { + /* CSIPHY0 */ + { + .regulators = { "vdda-phy", "vdda-pll" }, + .clock = { "soc_ahb", "cpas_ahb", + "csiphy0", "csiphy0_timer" }, + .clock_rate = { { 0 }, + { 0 }, + { 0 }, + { 19200000, 240000000, 269333333 } }, + .reg = { "csiphy0" }, + .interrupt = { "csiphy0" }, + .csiphy = { + .id = 0, + .hw_ops = &csiphy_ops_3ph_1_0, + .formats = &csiphy_formats_sdm845 + } + }, + + /* CSIPHY1 */ + { + .regulators = { "vdda-phy", "vdda-pll" }, + .clock = { "soc_ahb", "cpas_ahb", + "csiphy1", "csiphy1_timer" }, + .clock_rate = { { 0 }, + { 0 }, + { 0 }, + { 19200000, 240000000, 269333333 } }, + .reg = { "csiphy1" }, + .interrupt = { "csiphy1" }, + .csiphy = { + .id = 1, + .hw_ops = &csiphy_ops_3ph_1_0, + .formats = &csiphy_formats_sdm845 + } + }, + + /* CSIPHY2 */ + { + .regulators = { "vdda-phy", "vdda-pll" }, + .clock = { "soc_ahb", "cpas_ahb", + "csiphy2", "csiphy2_timer" }, + .clock_rate = { { 0 }, + { 0 }, + { 0 }, + { 19200000, 240000000, 269333333 } }, + .reg = { "csiphy2" }, + .interrupt = { "csiphy2" }, + .csiphy = { + .id = 2, + .hw_ops = &csiphy_ops_3ph_1_0, + .formats = &csiphy_formats_sdm845 + } + } +}; + +static const struct camss_subdev_resources csid_res_670[] = { + /* CSID0 */ + { + .regulators = {}, + .clock = { "cpas_ahb", "soc_ahb", "vfe0", + "vfe0_cphy_rx", "csi0" }, + .clock_rate = { { 0 }, + { 0 }, + { 100000000, 320000000, 404000000, 480000000, 600000000 }, + { 384000000 }, + { 19200000, 75000000, 384000000, 538666667 } }, + .reg = { "csid0" }, + .interrupt = { "csid0" }, + .csid = { + .hw_ops = &csid_ops_gen2, + .parent_dev_ops = &vfe_parent_dev_ops, + .formats = &csid_formats_gen2 + } + }, + + /* CSID1 */ + { + .regulators = {}, + .clock = { "cpas_ahb", "soc_ahb", "vfe1", + "vfe1_cphy_rx", "csi1" }, + .clock_rate = { { 0 }, + { 0 }, + { 100000000, 320000000, 404000000, 480000000, 600000000 }, + { 384000000 }, + { 19200000, 75000000, 384000000, 538666667 } }, + .reg = { "csid1" }, + .interrupt = { "csid1" }, + .csid = { + .hw_ops = &csid_ops_gen2, + .parent_dev_ops = &vfe_parent_dev_ops, + .formats = &csid_formats_gen2 + } + }, + + /* CSID2 */ + { + .regulators = {}, + .clock = { "cpas_ahb", "soc_ahb", "vfe_lite", + "vfe_lite_cphy_rx", "csi2" }, + .clock_rate = { { 0 }, + { 0 }, + { 100000000, 320000000, 404000000, 480000000, 600000000 }, + { 384000000 }, + { 19200000, 75000000, 384000000, 538666667 } }, + .reg = { "csid2" }, + .interrupt = { "csid2" }, + .csid = { + .is_lite = true, + .hw_ops = &csid_ops_gen2, + .parent_dev_ops = &vfe_parent_dev_ops, + .formats = &csid_formats_gen2 + } + } +}; + +static const struct camss_subdev_resources vfe_res_670[] = { + /* VFE0 */ + { + .regulators = {}, + .clock = { "camnoc_axi", "cpas_ahb", "soc_ahb", + "vfe0", "vfe0_axi" }, + .clock_rate = { { 0 }, + { 0 }, + { 0 }, + { 100000000, 320000000, 404000000, 480000000, 600000000 }, + { 0 } }, + .reg = { "vfe0" }, + .interrupt = { "vfe0" }, + .vfe = { + .line_num = 4, + .has_pd = true, + .pd_name = "ife0", + .hw_ops = &vfe_ops_170, + .formats_rdi = &vfe_formats_rdi_845, + .formats_pix = &vfe_formats_pix_845 + } + }, + + /* VFE1 */ + { + .regulators = {}, + .clock = { "camnoc_axi", "cpas_ahb", "soc_ahb", + "vfe1", "vfe1_axi" }, + .clock_rate = { { 0 }, + { 0 }, + { 0 }, + { 100000000, 320000000, 404000000, 480000000, 600000000 }, + { 0 } }, + .reg = { "vfe1" }, + .interrupt = { "vfe1" }, + .vfe = { + .line_num = 4, + .has_pd = true, + .pd_name = "ife1", + .hw_ops = &vfe_ops_170, + .formats_rdi = &vfe_formats_rdi_845, + .formats_pix = &vfe_formats_pix_845 + } + }, + + /* VFE-lite */ + { + .regulators = {}, + .clock = { "camnoc_axi", "cpas_ahb", "soc_ahb", + "vfe_lite" }, + .clock_rate = { { 0 }, + { 0 }, + { 0 }, + { 100000000, 320000000, 404000000, 480000000, 600000000 } }, + .reg = { "vfe_lite" }, + .interrupt = { "vfe_lite" }, + .vfe = { + .is_lite = true, + .line_num = 4, + .hw_ops = &vfe_ops_170, + .formats_rdi = &vfe_formats_rdi_845, + .formats_pix = &vfe_formats_pix_845 + } } }; -static const struct resources csiphy_res_845[] = { +static const struct camss_subdev_resources csiphy_res_845[] = { /* CSIPHY0 */ { - .regulator = { NULL }, + .regulators = {}, .clock = { "camnoc_axi", "soc_ahb", "slow_ahb_src", "cpas_ahb", "cphy_rx_src", "csiphy0", "csiphy0_timer_src", "csiphy0_timer" }, @@ -481,12 +1221,17 @@ static const struct resources csiphy_res_845[] = { { 0 }, { 19200000, 240000000, 269333333 } }, .reg = { "csiphy0" }, - .interrupt = { "csiphy0" } + .interrupt = { "csiphy0" }, + .csiphy = { + .id = 0, + .hw_ops = &csiphy_ops_3ph_1_0, + .formats = &csiphy_formats_sdm845 + } }, /* CSIPHY1 */ { - .regulator = { NULL }, + .regulators = {}, .clock = { "camnoc_axi", "soc_ahb", "slow_ahb_src", "cpas_ahb", "cphy_rx_src", "csiphy1", "csiphy1_timer_src", "csiphy1_timer" }, @@ -499,12 +1244,17 @@ static const struct resources csiphy_res_845[] = { { 0 }, { 19200000, 240000000, 269333333 } }, .reg = { "csiphy1" }, - .interrupt = { "csiphy1" } + .interrupt = { "csiphy1" }, + .csiphy = { + .id = 1, + .hw_ops = &csiphy_ops_3ph_1_0, + .formats = &csiphy_formats_sdm845 + } }, /* CSIPHY2 */ { - .regulator = { NULL }, + .regulators = {}, .clock = { "camnoc_axi", "soc_ahb", "slow_ahb_src", "cpas_ahb", "cphy_rx_src", "csiphy2", "csiphy2_timer_src", "csiphy2_timer" }, @@ -517,12 +1267,17 @@ static const struct resources csiphy_res_845[] = { { 0 }, { 19200000, 240000000, 269333333 } }, .reg = { "csiphy2" }, - .interrupt = { "csiphy2" } + .interrupt = { "csiphy2" }, + .csiphy = { + .id = 2, + .hw_ops = &csiphy_ops_3ph_1_0, + .formats = &csiphy_formats_sdm845 + } }, /* CSIPHY3 */ { - .regulator = { NULL }, + .regulators = {}, .clock = { "camnoc_axi", "soc_ahb", "slow_ahb_src", "cpas_ahb", "cphy_rx_src", "csiphy3", "csiphy3_timer_src", "csiphy3_timer" }, @@ -535,14 +1290,19 @@ static const struct resources csiphy_res_845[] = { { 0 }, { 19200000, 240000000, 269333333 } }, .reg = { "csiphy3" }, - .interrupt = { "csiphy3" } + .interrupt = { "csiphy3" }, + .csiphy = { + .id = 3, + .hw_ops = &csiphy_ops_3ph_1_0, + .formats = &csiphy_formats_sdm845 + } } }; -static const struct resources csid_res_845[] = { +static const struct camss_subdev_resources csid_res_845[] = { /* CSID0 */ { - .regulator = { "vdda-csi0" }, + .regulators = { "vdda-phy", "vdda-pll" }, .clock = { "cpas_ahb", "cphy_rx_src", "slow_ahb_src", "soc_ahb", "vfe0", "vfe0_src", "vfe0_cphy_rx", "csi0", @@ -557,12 +1317,17 @@ static const struct resources csid_res_845[] = { { 19200000, 75000000, 384000000, 538666667 }, { 384000000 } }, .reg = { "csid0" }, - .interrupt = { "csid0" } + .interrupt = { "csid0" }, + .csid = { + .hw_ops = &csid_ops_gen2, + .parent_dev_ops = &vfe_parent_dev_ops, + .formats = &csid_formats_gen2 + } }, /* CSID1 */ { - .regulator = { "vdda-csi1" }, + .regulators = { "vdda-phy", "vdda-pll" }, .clock = { "cpas_ahb", "cphy_rx_src", "slow_ahb_src", "soc_ahb", "vfe1", "vfe1_src", "vfe1_cphy_rx", "csi1", @@ -577,12 +1342,17 @@ static const struct resources csid_res_845[] = { { 19200000, 75000000, 384000000, 538666667 }, { 384000000 } }, .reg = { "csid1" }, - .interrupt = { "csid1" } + .interrupt = { "csid1" }, + .csid = { + .hw_ops = &csid_ops_gen2, + .parent_dev_ops = &vfe_parent_dev_ops, + .formats = &csid_formats_gen2 + } }, /* CSID2 */ { - .regulator = { "vdda-csi2" }, + .regulators = { "vdda-phy", "vdda-pll" }, .clock = { "cpas_ahb", "cphy_rx_src", "slow_ahb_src", "soc_ahb", "vfe_lite", "vfe_lite_src", "vfe_lite_cphy_rx", "csi2", @@ -597,14 +1367,20 @@ static const struct resources csid_res_845[] = { { 19200000, 75000000, 384000000, 538666667 }, { 384000000 } }, .reg = { "csid2" }, - .interrupt = { "csid2" } + .interrupt = { "csid2" }, + .csid = { + .is_lite = true, + .hw_ops = &csid_ops_gen2, + .parent_dev_ops = &vfe_parent_dev_ops, + .formats = &csid_formats_gen2 + } } }; -static const struct resources vfe_res_845[] = { +static const struct camss_subdev_resources vfe_res_845[] = { /* VFE0 */ { - .regulator = { NULL }, + .regulators = {}, .clock = { "camnoc_axi", "cpas_ahb", "slow_ahb_src", "soc_ahb", "vfe0", "vfe0_axi", "vfe0_src", "csi0", @@ -619,12 +1395,20 @@ static const struct resources vfe_res_845[] = { { 19200000, 75000000, 384000000, 538666667 }, { 384000000 } }, .reg = { "vfe0" }, - .interrupt = { "vfe0" } + .interrupt = { "vfe0" }, + .vfe = { + .line_num = 4, + .pd_name = "ife0", + .has_pd = true, + .hw_ops = &vfe_ops_170, + .formats_rdi = &vfe_formats_rdi_845, + .formats_pix = &vfe_formats_pix_845 + } }, /* VFE1 */ { - .regulator = { NULL }, + .regulators = {}, .clock = { "camnoc_axi", "cpas_ahb", "slow_ahb_src", "soc_ahb", "vfe1", "vfe1_axi", "vfe1_src", "csi1", @@ -639,12 +1423,20 @@ static const struct resources vfe_res_845[] = { { 19200000, 75000000, 384000000, 538666667 }, { 384000000 } }, .reg = { "vfe1" }, - .interrupt = { "vfe1" } + .interrupt = { "vfe1" }, + .vfe = { + .line_num = 4, + .pd_name = "ife1", + .has_pd = true, + .hw_ops = &vfe_ops_170, + .formats_rdi = &vfe_formats_rdi_845, + .formats_pix = &vfe_formats_pix_845 + } }, /* VFE-lite */ { - .regulator = { NULL }, + .regulators = {}, .clock = { "camnoc_axi", "cpas_ahb", "slow_ahb_src", "soc_ahb", "vfe_lite", "vfe_lite_src", "csi2", @@ -658,10 +1450,2381 @@ static const struct resources vfe_res_845[] = { { 19200000, 75000000, 384000000, 538666667 }, { 384000000 } }, .reg = { "vfe_lite" }, - .interrupt = { "vfe_lite" } + .interrupt = { "vfe_lite" }, + .vfe = { + .is_lite = true, + .line_num = 4, + .hw_ops = &vfe_ops_170, + .formats_rdi = &vfe_formats_rdi_845, + .formats_pix = &vfe_formats_pix_845 + } + } +}; + +static const struct camss_subdev_resources csiphy_res_8250[] = { + /* CSIPHY0 */ + { + .regulators = { "vdda-phy", "vdda-pll" }, + .clock = { "csiphy0", "csiphy0_timer" }, + .clock_rate = { { 400000000 }, + { 300000000 } }, + .reg = { "csiphy0" }, + .interrupt = { "csiphy0" }, + .csiphy = { + .id = 0, + .hw_ops = &csiphy_ops_3ph_1_0, + .formats = &csiphy_formats_sdm845 + } + }, + /* CSIPHY1 */ + { + .regulators = { "vdda-phy", "vdda-pll" }, + .clock = { "csiphy1", "csiphy1_timer" }, + .clock_rate = { { 400000000 }, + { 300000000 } }, + .reg = { "csiphy1" }, + .interrupt = { "csiphy1" }, + .csiphy = { + .id = 1, + .hw_ops = &csiphy_ops_3ph_1_0, + .formats = &csiphy_formats_sdm845 + } + }, + /* CSIPHY2 */ + { + .regulators = { "vdda-phy", "vdda-pll" }, + .clock = { "csiphy2", "csiphy2_timer" }, + .clock_rate = { { 400000000 }, + { 300000000 } }, + .reg = { "csiphy2" }, + .interrupt = { "csiphy2" }, + .csiphy = { + .id = 2, + .hw_ops = &csiphy_ops_3ph_1_0, + .formats = &csiphy_formats_sdm845 + } + }, + /* CSIPHY3 */ + { + .regulators = { "vdda-phy", "vdda-pll" }, + .clock = { "csiphy3", "csiphy3_timer" }, + .clock_rate = { { 400000000 }, + { 300000000 } }, + .reg = { "csiphy3" }, + .interrupt = { "csiphy3" }, + .csiphy = { + .id = 3, + .hw_ops = &csiphy_ops_3ph_1_0, + .formats = &csiphy_formats_sdm845 + } + }, + /* CSIPHY4 */ + { + .regulators = { "vdda-phy", "vdda-pll" }, + .clock = { "csiphy4", "csiphy4_timer" }, + .clock_rate = { { 400000000 }, + { 300000000 } }, + .reg = { "csiphy4" }, + .interrupt = { "csiphy4" }, + .csiphy = { + .id = 4, + .hw_ops = &csiphy_ops_3ph_1_0, + .formats = &csiphy_formats_sdm845 + } + }, + /* CSIPHY5 */ + { + .regulators = { "vdda-phy", "vdda-pll" }, + .clock = { "csiphy5", "csiphy5_timer" }, + .clock_rate = { { 400000000 }, + { 300000000 } }, + .reg = { "csiphy5" }, + .interrupt = { "csiphy5" }, + .csiphy = { + .id = 5, + .hw_ops = &csiphy_ops_3ph_1_0, + .formats = &csiphy_formats_sdm845 + } + } +}; + +static const struct camss_subdev_resources csid_res_8250[] = { + /* CSID0 */ + { + .regulators = {}, + .clock = { "vfe0_csid", "vfe0_cphy_rx", "vfe0", "vfe0_areg", "vfe0_ahb" }, + .clock_rate = { { 400000000 }, + { 400000000 }, + { 350000000, 475000000, 576000000, 720000000 }, + { 100000000, 200000000, 300000000, 400000000 }, + { 0 } }, + .reg = { "csid0" }, + .interrupt = { "csid0" }, + .csid = { + .hw_ops = &csid_ops_gen2, + .parent_dev_ops = &vfe_parent_dev_ops, + .formats = &csid_formats_gen2 + } + }, + /* CSID1 */ + { + .regulators = {}, + .clock = { "vfe1_csid", "vfe1_cphy_rx", "vfe1", "vfe1_areg", "vfe1_ahb" }, + .clock_rate = { { 400000000 }, + { 400000000 }, + { 350000000, 475000000, 576000000, 720000000 }, + { 100000000, 200000000, 300000000, 400000000 }, + { 0 } }, + .reg = { "csid1" }, + .interrupt = { "csid1" }, + .csid = { + .hw_ops = &csid_ops_gen2, + .parent_dev_ops = &vfe_parent_dev_ops, + .formats = &csid_formats_gen2 + } + }, + /* CSID2 */ + { + .regulators = {}, + .clock = { "vfe_lite_csid", "vfe_lite_cphy_rx", "vfe_lite", "vfe_lite_ahb" }, + .clock_rate = { { 400000000 }, + { 400000000 }, + { 400000000, 480000000 }, + { 0 } }, + .reg = { "csid2" }, + .interrupt = { "csid2" }, + .csid = { + .is_lite = true, + .hw_ops = &csid_ops_gen2, + .parent_dev_ops = &vfe_parent_dev_ops, + .formats = &csid_formats_gen2 + } + }, + /* CSID3 */ + { + .regulators = {}, + .clock = { "vfe_lite_csid", "vfe_lite_cphy_rx", "vfe_lite", "vfe_lite_ahb" }, + .clock_rate = { { 400000000 }, + { 400000000 }, + { 400000000, 480000000 }, + { 0 } }, + .reg = { "csid3" }, + .interrupt = { "csid3" }, + .csid = { + .is_lite = true, + .hw_ops = &csid_ops_gen2, + .parent_dev_ops = &vfe_parent_dev_ops, + .formats = &csid_formats_gen2 + } } }; +static const struct camss_subdev_resources vfe_res_8250[] = { + /* VFE0 */ + { + .regulators = {}, + .clock = { "camnoc_axi_src", "slow_ahb_src", "cpas_ahb", + "camnoc_axi", "vfe0_ahb", "vfe0_areg", "vfe0", + "vfe0_axi", "cam_hf_axi" }, + .clock_rate = { { 19200000, 300000000, 400000000, 480000000 }, + { 19200000, 80000000 }, + { 19200000 }, + { 0 }, + { 0 }, + { 100000000, 200000000, 300000000, 400000000 }, + { 350000000, 475000000, 576000000, 720000000 }, + { 0 }, + { 0 } }, + .reg = { "vfe0" }, + .interrupt = { "vfe0" }, + .vfe = { + .line_num = 3, + .has_pd = true, + .pd_name = "ife0", + .hw_ops = &vfe_ops_480, + .formats_rdi = &vfe_formats_rdi_845, + .formats_pix = &vfe_formats_pix_845 + } + }, + /* VFE1 */ + { + .regulators = {}, + .clock = { "camnoc_axi_src", "slow_ahb_src", "cpas_ahb", + "camnoc_axi", "vfe1_ahb", "vfe1_areg", "vfe1", + "vfe1_axi", "cam_hf_axi" }, + .clock_rate = { { 19200000, 300000000, 400000000, 480000000 }, + { 19200000, 80000000 }, + { 19200000 }, + { 0 }, + { 0 }, + { 100000000, 200000000, 300000000, 400000000 }, + { 350000000, 475000000, 576000000, 720000000 }, + { 0 }, + { 0 } }, + .reg = { "vfe1" }, + .interrupt = { "vfe1" }, + .vfe = { + .line_num = 3, + .has_pd = true, + .pd_name = "ife1", + .hw_ops = &vfe_ops_480, + .formats_rdi = &vfe_formats_rdi_845, + .formats_pix = &vfe_formats_pix_845 + } + }, + /* VFE2 (lite) */ + { + .regulators = {}, + .clock = { "camnoc_axi_src", "slow_ahb_src", "cpas_ahb", + "camnoc_axi", "vfe_lite_ahb", "vfe_lite_axi", + "vfe_lite", "cam_hf_axi" }, + .clock_rate = { { 19200000, 300000000, 400000000, 480000000 }, + { 19200000, 80000000 }, + { 19200000 }, + { 0 }, + { 0 }, + { 0 }, + { 400000000, 480000000 }, + { 0 } }, + .reg = { "vfe_lite0" }, + .interrupt = { "vfe_lite0" }, + .vfe = { + .is_lite = true, + .line_num = 4, + .hw_ops = &vfe_ops_480, + .formats_rdi = &vfe_formats_rdi_845, + .formats_pix = &vfe_formats_pix_845 + } + }, + /* VFE3 (lite) */ + { + .regulators = {}, + .clock = { "camnoc_axi_src", "slow_ahb_src", "cpas_ahb", + "camnoc_axi", "vfe_lite_ahb", "vfe_lite_axi", + "vfe_lite", "cam_hf_axi" }, + .clock_rate = { { 19200000, 300000000, 400000000, 480000000 }, + { 19200000, 80000000 }, + { 19200000 }, + { 0 }, + { 0 }, + { 0 }, + { 400000000, 480000000 }, + { 0 } }, + .reg = { "vfe_lite1" }, + .interrupt = { "vfe_lite1" }, + .vfe = { + .is_lite = true, + .line_num = 4, + .hw_ops = &vfe_ops_480, + .formats_rdi = &vfe_formats_rdi_845, + .formats_pix = &vfe_formats_pix_845 + } + }, +}; + +static const struct resources_icc icc_res_sm8250[] = { + { + .name = "cam_ahb", + .icc_bw_tbl.avg = 38400, + .icc_bw_tbl.peak = 76800, + }, + { + .name = "cam_hf_0_mnoc", + .icc_bw_tbl.avg = 2097152, + .icc_bw_tbl.peak = 2097152, + }, + { + .name = "cam_sf_0_mnoc", + .icc_bw_tbl.avg = 0, + .icc_bw_tbl.peak = 2097152, + }, + { + .name = "cam_sf_icp_mnoc", + .icc_bw_tbl.avg = 2097152, + .icc_bw_tbl.peak = 2097152, + }, +}; + +static const struct camss_subdev_resources csiphy_res_7280[] = { + /* CSIPHY0 */ + { + .regulators = { "vdda-phy", "vdda-pll" }, + + .clock = { "csiphy0", "csiphy0_timer" }, + .clock_rate = { { 300000000, 400000000 }, + { 300000000 } }, + .reg = { "csiphy0" }, + .interrupt = { "csiphy0" }, + .csiphy = { + .id = 0, + .hw_ops = &csiphy_ops_3ph_1_0, + .formats = &csiphy_formats_sdm845, + } + }, + /* CSIPHY1 */ + { + .regulators = { "vdda-phy", "vdda-pll" }, + + .clock = { "csiphy1", "csiphy1_timer" }, + .clock_rate = { { 300000000, 400000000 }, + { 300000000 } }, + .reg = { "csiphy1" }, + .interrupt = { "csiphy1" }, + .csiphy = { + .id = 1, + .hw_ops = &csiphy_ops_3ph_1_0, + .formats = &csiphy_formats_sdm845, + } + }, + /* CSIPHY2 */ + { + .regulators = { "vdda-phy", "vdda-pll" }, + + .clock = { "csiphy2", "csiphy2_timer" }, + .clock_rate = { { 300000000, 400000000 }, + { 300000000 } }, + .reg = { "csiphy2" }, + .interrupt = { "csiphy2" }, + .csiphy = { + .id = 2, + .hw_ops = &csiphy_ops_3ph_1_0, + .formats = &csiphy_formats_sdm845, + } + }, + /* CSIPHY3 */ + { + .regulators = { "vdda-phy", "vdda-pll" }, + + .clock = { "csiphy3", "csiphy3_timer" }, + .clock_rate = { { 300000000, 400000000 }, + { 300000000 } }, + .reg = { "csiphy3" }, + .interrupt = { "csiphy3" }, + .csiphy = { + .id = 3, + .hw_ops = &csiphy_ops_3ph_1_0, + .formats = &csiphy_formats_sdm845, + } + }, + /* CSIPHY4 */ + { + .regulators = { "vdda-phy", "vdda-pll" }, + + .clock = { "csiphy4", "csiphy4_timer" }, + .clock_rate = { { 300000000, 400000000 }, + { 300000000 } }, + .reg = { "csiphy4" }, + .interrupt = { "csiphy4" }, + .csiphy = { + .id = 4, + .hw_ops = &csiphy_ops_3ph_1_0, + .formats = &csiphy_formats_sdm845, + } + }, +}; + +static const struct camss_subdev_resources csid_res_7280[] = { + /* CSID0 */ + { + .regulators = {}, + + .clock = { "vfe0_csid", "vfe0_cphy_rx", "vfe0" }, + .clock_rate = { { 300000000, 400000000 }, + { 0 }, + { 380000000, 510000000, 637000000, 760000000 } + }, + + .reg = { "csid0" }, + .interrupt = { "csid0" }, + .csid = { + .is_lite = false, + .hw_ops = &csid_ops_gen2, + .parent_dev_ops = &vfe_parent_dev_ops, + .formats = &csid_formats_gen2 + } + }, + /* CSID1 */ + { + .regulators = {}, + + .clock = { "vfe1_csid", "vfe1_cphy_rx", "vfe1" }, + .clock_rate = { { 300000000, 400000000 }, + { 0 }, + { 380000000, 510000000, 637000000, 760000000 } + }, + + .reg = { "csid1" }, + .interrupt = { "csid1" }, + .csid = { + .is_lite = false, + .hw_ops = &csid_ops_gen2, + .parent_dev_ops = &vfe_parent_dev_ops, + .formats = &csid_formats_gen2 + } + }, + /* CSID2 */ + { + .regulators = {}, + + .clock = { "vfe2_csid", "vfe2_cphy_rx", "vfe2" }, + .clock_rate = { { 300000000, 400000000 }, + { 0 }, + { 380000000, 510000000, 637000000, 760000000 } + }, + + .reg = { "csid2" }, + .interrupt = { "csid2" }, + .csid = { + .is_lite = false, + .hw_ops = &csid_ops_gen2, + .parent_dev_ops = &vfe_parent_dev_ops, + .formats = &csid_formats_gen2 + } + }, + /* CSID3 */ + { + .regulators = {}, + + .clock = { "vfe_lite0_csid", "vfe_lite0_cphy_rx", "vfe_lite0" }, + .clock_rate = { { 300000000, 400000000 }, + { 0 }, + { 320000000, 400000000, 480000000, 600000000 } + }, + + .reg = { "csid_lite0" }, + .interrupt = { "csid_lite0" }, + .csid = { + .is_lite = true, + .hw_ops = &csid_ops_gen2, + .parent_dev_ops = &vfe_parent_dev_ops, + .formats = &csid_formats_gen2 + } + }, + /* CSID4 */ + { + .regulators = {}, + + .clock = { "vfe_lite1_csid", "vfe_lite1_cphy_rx", "vfe_lite1" }, + .clock_rate = { { 300000000, 400000000 }, + { 0 }, + { 320000000, 400000000, 480000000, 600000000 } + }, + + .reg = { "csid_lite1" }, + .interrupt = { "csid_lite1" }, + .csid = { + .is_lite = true, + .hw_ops = &csid_ops_gen2, + .parent_dev_ops = &vfe_parent_dev_ops, + .formats = &csid_formats_gen2 + } + }, +}; + +static const struct camss_subdev_resources vfe_res_7280[] = { + /* VFE0 */ + { + .regulators = {}, + + .clock = { "camnoc_axi", "cpas_ahb", "icp_ahb", "vfe0", + "vfe0_axi", "gcc_axi_hf", "gcc_axi_sf" }, + .clock_rate = { { 150000000, 240000000, 320000000, 400000000, 480000000 }, + { 80000000 }, + { 0 }, + { 380000000, 510000000, 637000000, 760000000 }, + { 0 }, + { 0 }, + { 0 } }, + + .reg = { "vfe0" }, + .interrupt = { "vfe0" }, + .vfe = { + .line_num = 3, + .is_lite = false, + .has_pd = true, + .pd_name = "ife0", + .hw_ops = &vfe_ops_170, + .formats_rdi = &vfe_formats_rdi_845, + .formats_pix = &vfe_formats_pix_845 + } + }, + /* VFE1 */ + { + .regulators = {}, + + .clock = { "camnoc_axi", "cpas_ahb", "icp_ahb", "vfe1", + "vfe1_axi", "gcc_axi_hf", "gcc_axi_sf" }, + .clock_rate = { { 150000000, 240000000, 320000000, 400000000, 480000000 }, + { 80000000 }, + { 0 }, + { 380000000, 510000000, 637000000, 760000000 }, + { 0 }, + { 0 }, + { 0 } }, + + .reg = { "vfe1" }, + .interrupt = { "vfe1" }, + .vfe = { + .line_num = 3, + .is_lite = false, + .has_pd = true, + .pd_name = "ife1", + .hw_ops = &vfe_ops_170, + .formats_rdi = &vfe_formats_rdi_845, + .formats_pix = &vfe_formats_pix_845 + } + }, + /* VFE2 */ + { + .regulators = {}, + + .clock = { "camnoc_axi", "cpas_ahb", "icp_ahb", "vfe2", + "vfe2_axi", "gcc_axi_hf", "gcc_axi_sf" }, + .clock_rate = { { 150000000, 240000000, 320000000, 400000000, 480000000 }, + { 80000000 }, + { 0 }, + { 380000000, 510000000, 637000000, 760000000 }, + { 0 }, + { 0 }, + { 0 } }, + + .reg = { "vfe2" }, + .interrupt = { "vfe2" }, + .vfe = { + .line_num = 3, + .is_lite = false, + .hw_ops = &vfe_ops_170, + .has_pd = true, + .pd_name = "ife2", + .formats_rdi = &vfe_formats_rdi_845, + .formats_pix = &vfe_formats_pix_845 + } + }, + /* VFE3 (lite) */ + { + .clock = { "camnoc_axi", "cpas_ahb", "icp_ahb", + "vfe_lite0", "gcc_axi_hf", "gcc_axi_sf" }, + .clock_rate = { { 150000000, 240000000, 320000000, 400000000, 480000000 }, + { 80000000 }, + { 0 }, + { 320000000, 400000000, 480000000, 600000000 }, + { 0 }, + { 0 } }, + + .regulators = {}, + .reg = { "vfe_lite0" }, + .interrupt = { "vfe_lite0" }, + .vfe = { + .line_num = 4, + .is_lite = true, + .hw_ops = &vfe_ops_170, + .formats_rdi = &vfe_formats_rdi_845, + .formats_pix = &vfe_formats_pix_845 + } + }, + /* VFE4 (lite) */ + { + .clock = { "camnoc_axi", "cpas_ahb", "icp_ahb", + "vfe_lite1", "gcc_axi_hf", "gcc_axi_sf" }, + .clock_rate = { { 150000000, 240000000, 320000000, 400000000, 480000000 }, + { 80000000 }, + { 0 }, + { 320000000, 400000000, 480000000, 600000000 }, + { 0 }, + { 0 } }, + + .regulators = {}, + .reg = { "vfe_lite1" }, + .interrupt = { "vfe_lite1" }, + .vfe = { + .line_num = 4, + .is_lite = true, + .hw_ops = &vfe_ops_170, + .formats_rdi = &vfe_formats_rdi_845, + .formats_pix = &vfe_formats_pix_845 + } + }, +}; + +static const struct resources_icc icc_res_sc7280[] = { + { + .name = "ahb", + .icc_bw_tbl.avg = 38400, + .icc_bw_tbl.peak = 76800, + }, + { + .name = "hf_0", + .icc_bw_tbl.avg = 2097152, + .icc_bw_tbl.peak = 2097152, + }, +}; + +static const struct camss_subdev_resources csiphy_res_sc8280xp[] = { + /* CSIPHY0 */ + { + .regulators = {}, + .clock = { "csiphy0", "csiphy0_timer" }, + .clock_rate = { { 400000000 }, + { 300000000 } }, + .reg = { "csiphy0" }, + .interrupt = { "csiphy0" }, + .csiphy = { + .id = 0, + .hw_ops = &csiphy_ops_3ph_1_0, + .formats = &csiphy_formats_sdm845 + } + }, + /* CSIPHY1 */ + { + .regulators = {}, + .clock = { "csiphy1", "csiphy1_timer" }, + .clock_rate = { { 400000000 }, + { 300000000 } }, + .reg = { "csiphy1" }, + .interrupt = { "csiphy1" }, + .csiphy = { + .id = 1, + .hw_ops = &csiphy_ops_3ph_1_0, + .formats = &csiphy_formats_sdm845 + } + }, + /* CSIPHY2 */ + { + .regulators = {}, + .clock = { "csiphy2", "csiphy2_timer" }, + .clock_rate = { { 400000000 }, + { 300000000 } }, + .reg = { "csiphy2" }, + .interrupt = { "csiphy2" }, + .csiphy = { + .id = 2, + .hw_ops = &csiphy_ops_3ph_1_0, + .formats = &csiphy_formats_sdm845 + } + }, + /* CSIPHY3 */ + { + .regulators = {}, + .clock = { "csiphy3", "csiphy3_timer" }, + .clock_rate = { { 400000000 }, + { 300000000 } }, + .reg = { "csiphy3" }, + .interrupt = { "csiphy3" }, + .csiphy = { + .id = 3, + .hw_ops = &csiphy_ops_3ph_1_0, + .formats = &csiphy_formats_sdm845 + } + }, +}; + +static const struct camss_subdev_resources csid_res_sc8280xp[] = { + /* CSID0 */ + { + .regulators = { "vdda-phy", "vdda-pll" }, + .clock = { "vfe0_csid", "vfe0_cphy_rx", "vfe0", "vfe0_axi" }, + .clock_rate = { { 400000000, 480000000, 600000000 }, + { 0 }, + { 0 }, + { 0 } }, + .reg = { "csid0" }, + .interrupt = { "csid0" }, + .csid = { + .hw_ops = &csid_ops_gen2, + .parent_dev_ops = &vfe_parent_dev_ops, + .formats = &csid_formats_gen2 + } + }, + /* CSID1 */ + { + .regulators = { "vdda-phy", "vdda-pll" }, + .clock = { "vfe1_csid", "vfe1_cphy_rx", "vfe1", "vfe1_axi" }, + .clock_rate = { { 400000000, 480000000, 600000000 }, + { 0 }, + { 0 }, + { 0 } }, + .reg = { "csid1" }, + .interrupt = { "csid1" }, + .csid = { + .hw_ops = &csid_ops_gen2, + .parent_dev_ops = &vfe_parent_dev_ops, + .formats = &csid_formats_gen2 + } + }, + /* CSID2 */ + { + .regulators = { "vdda-phy", "vdda-pll" }, + .clock = { "vfe2_csid", "vfe2_cphy_rx", "vfe2", "vfe2_axi" }, + .clock_rate = { { 400000000, 480000000, 600000000 }, + { 0 }, + { 0 }, + { 0 } }, + .reg = { "csid2" }, + .interrupt = { "csid2" }, + .csid = { + .hw_ops = &csid_ops_gen2, + .parent_dev_ops = &vfe_parent_dev_ops, + .formats = &csid_formats_gen2 + } + }, + /* CSID3 */ + { + .regulators = { "vdda-phy", "vdda-pll" }, + .clock = { "vfe3_csid", "vfe3_cphy_rx", "vfe3", "vfe3_axi" }, + .clock_rate = { { 400000000, 480000000, 600000000 }, + { 0 }, + { 0 }, + { 0 } }, + .reg = { "csid3" }, + .interrupt = { "csid3" }, + .csid = { + .hw_ops = &csid_ops_gen2, + .parent_dev_ops = &vfe_parent_dev_ops, + .formats = &csid_formats_gen2 + } + }, + /* CSID_LITE0 */ + { + .regulators = { "vdda-phy", "vdda-pll" }, + .clock = { "vfe_lite0_csid", "vfe_lite0_cphy_rx", "vfe_lite0" }, + .clock_rate = { { 400000000, 480000000, 600000000 }, + { 0 }, + { 0 }, }, + .reg = { "csid0_lite" }, + .interrupt = { "csid0_lite" }, + .csid = { + .is_lite = true, + .hw_ops = &csid_ops_gen2, + .parent_dev_ops = &vfe_parent_dev_ops, + .formats = &csid_formats_gen2 + } + }, + /* CSID_LITE1 */ + { + .regulators = { "vdda-phy", "vdda-pll" }, + .clock = { "vfe_lite1_csid", "vfe_lite1_cphy_rx", "vfe_lite1" }, + .clock_rate = { { 400000000, 480000000, 600000000 }, + { 0 }, + { 0 }, }, + .reg = { "csid1_lite" }, + .interrupt = { "csid1_lite" }, + .csid = { + .is_lite = true, + .hw_ops = &csid_ops_gen2, + .parent_dev_ops = &vfe_parent_dev_ops, + .formats = &csid_formats_gen2 + } + }, + /* CSID_LITE2 */ + { + .regulators = { "vdda-phy", "vdda-pll" }, + .clock = { "vfe_lite2_csid", "vfe_lite2_cphy_rx", "vfe_lite2" }, + .clock_rate = { { 400000000, 480000000, 600000000 }, + { 0 }, + { 0 }, }, + .reg = { "csid2_lite" }, + .interrupt = { "csid2_lite" }, + .csid = { + .is_lite = true, + .hw_ops = &csid_ops_gen2, + .parent_dev_ops = &vfe_parent_dev_ops, + .formats = &csid_formats_gen2 + } + }, + /* CSID_LITE3 */ + { + .regulators = { "vdda-phy", "vdda-pll" }, + .clock = { "vfe_lite3_csid", "vfe_lite3_cphy_rx", "vfe_lite3" }, + .clock_rate = { { 400000000, 480000000, 600000000 }, + { 0 }, + { 0 }, }, + .reg = { "csid3_lite" }, + .interrupt = { "csid3_lite" }, + .csid = { + .is_lite = true, + .hw_ops = &csid_ops_gen2, + .parent_dev_ops = &vfe_parent_dev_ops, + .formats = &csid_formats_gen2 + } + } +}; + +static const struct camss_subdev_resources vfe_res_sc8280xp[] = { + /* VFE0 */ + { + .regulators = {}, + .clock = { "gcc_axi_hf", "gcc_axi_sf", "cpas_ahb", "camnoc_axi", "vfe0", "vfe0_axi" }, + .clock_rate = { { 0 }, + { 0 }, + { 19200000, 80000000}, + { 19200000, 150000000, 266666667, 320000000, 400000000, 480000000 }, + { 400000000, 558000000, 637000000, 760000000 }, + { 0 }, }, + .reg = { "vfe0" }, + .interrupt = { "vfe0" }, + .vfe = { + .line_num = 4, + .pd_name = "ife0", + .hw_ops = &vfe_ops_170, + .formats_rdi = &vfe_formats_rdi_845, + .formats_pix = &vfe_formats_pix_845 + } + }, + /* VFE1 */ + { + .regulators = {}, + .clock = { "gcc_axi_hf", "gcc_axi_sf", "cpas_ahb", "camnoc_axi", "vfe1", "vfe1_axi" }, + .clock_rate = { { 0 }, + { 0 }, + { 19200000, 80000000}, + { 19200000, 150000000, 266666667, 320000000, 400000000, 480000000 }, + { 400000000, 558000000, 637000000, 760000000 }, + { 0 }, }, + .reg = { "vfe1" }, + .interrupt = { "vfe1" }, + .vfe = { + .line_num = 4, + .pd_name = "ife1", + .hw_ops = &vfe_ops_170, + .formats_rdi = &vfe_formats_rdi_845, + .formats_pix = &vfe_formats_pix_845 + } + }, + /* VFE2 */ + { + .regulators = {}, + .clock = { "gcc_axi_hf", "gcc_axi_sf", "cpas_ahb", "camnoc_axi", "vfe2", "vfe2_axi" }, + .clock_rate = { { 0 }, + { 0 }, + { 19200000, 80000000}, + { 19200000, 150000000, 266666667, 320000000, 400000000, 480000000 }, + { 400000000, 558000000, 637000000, 760000000 }, + { 0 }, }, + .reg = { "vfe2" }, + .interrupt = { "vfe2" }, + .vfe = { + .line_num = 4, + .pd_name = "ife2", + .hw_ops = &vfe_ops_170, + .formats_rdi = &vfe_formats_rdi_845, + .formats_pix = &vfe_formats_pix_845 + } + }, + /* VFE3 */ + { + .regulators = {}, + .clock = { "gcc_axi_hf", "gcc_axi_sf", "cpas_ahb", "camnoc_axi", "vfe3", "vfe3_axi" }, + .clock_rate = { { 0 }, + { 0 }, + { 19200000, 80000000}, + { 19200000, 150000000, 266666667, 320000000, 400000000, 480000000 }, + { 400000000, 558000000, 637000000, 760000000 }, + { 0 }, }, + .reg = { "vfe3" }, + .interrupt = { "vfe3" }, + .vfe = { + .line_num = 4, + .pd_name = "ife3", + .hw_ops = &vfe_ops_170, + .formats_rdi = &vfe_formats_rdi_845, + .formats_pix = &vfe_formats_pix_845 + } + }, + /* VFE_LITE_0 */ + { + .regulators = {}, + .clock = { "gcc_axi_hf", "gcc_axi_sf", "cpas_ahb", "camnoc_axi", "vfe_lite0" }, + .clock_rate = { { 0 }, + { 0 }, + { 19200000, 80000000}, + { 19200000, 150000000, 266666667, 320000000, 400000000, 480000000 }, + { 320000000, 400000000, 480000000, 600000000 }, }, + .reg = { "vfe_lite0" }, + .interrupt = { "vfe_lite0" }, + .vfe = { + .is_lite = true, + .line_num = 4, + .hw_ops = &vfe_ops_170, + .formats_rdi = &vfe_formats_rdi_845, + .formats_pix = &vfe_formats_pix_845 + } + }, + /* VFE_LITE_1 */ + { + .regulators = {}, + .clock = { "gcc_axi_hf", "gcc_axi_sf", "cpas_ahb", "camnoc_axi", "vfe_lite1" }, + .clock_rate = { { 0 }, + { 0 }, + { 19200000, 80000000}, + { 19200000, 150000000, 266666667, 320000000, 400000000, 480000000 }, + { 320000000, 400000000, 480000000, 600000000 }, }, + .reg = { "vfe_lite1" }, + .interrupt = { "vfe_lite1" }, + .vfe = { + .is_lite = true, + .line_num = 4, + .hw_ops = &vfe_ops_170, + .formats_rdi = &vfe_formats_rdi_845, + .formats_pix = &vfe_formats_pix_845 + } + }, + /* VFE_LITE_2 */ + { + .regulators = {}, + .clock = { "gcc_axi_hf", "gcc_axi_sf", "cpas_ahb", "camnoc_axi", "vfe_lite2" }, + .clock_rate = { { 0 }, + { 0 }, + { 19200000, 80000000}, + { 19200000, 150000000, 266666667, 320000000, 400000000, 480000000 }, + { 320000000, 400000000, 480000000, 600000000, }, }, + .reg = { "vfe_lite2" }, + .interrupt = { "vfe_lite2" }, + .vfe = { + .is_lite = true, + .line_num = 4, + .hw_ops = &vfe_ops_170, + .formats_rdi = &vfe_formats_rdi_845, + .formats_pix = &vfe_formats_pix_845 + } + }, + /* VFE_LITE_3 */ + { + .regulators = {}, + .clock = { "gcc_axi_hf", "gcc_axi_sf", "cpas_ahb", "camnoc_axi", "vfe_lite3" }, + .clock_rate = { { 0 }, + { 0 }, + { 19200000, 80000000}, + { 19200000, 150000000, 266666667, 320000000, 400000000, 480000000 }, + { 320000000, 400000000, 480000000, 600000000 }, }, + .reg = { "vfe_lite3" }, + .interrupt = { "vfe_lite3" }, + .vfe = { + .is_lite = true, + .line_num = 4, + .hw_ops = &vfe_ops_170, + .formats_rdi = &vfe_formats_rdi_845, + .formats_pix = &vfe_formats_pix_845 + } + }, +}; + +static const struct resources_icc icc_res_sc8280xp[] = { + { + .name = "cam_ahb", + .icc_bw_tbl.avg = 150000, + .icc_bw_tbl.peak = 300000, + }, + { + .name = "cam_hf_mnoc", + .icc_bw_tbl.avg = 2097152, + .icc_bw_tbl.peak = 2097152, + }, + { + .name = "cam_sf_mnoc", + .icc_bw_tbl.avg = 2097152, + .icc_bw_tbl.peak = 2097152, + }, + { + .name = "cam_sf_icp_mnoc", + .icc_bw_tbl.avg = 2097152, + .icc_bw_tbl.peak = 2097152, + }, +}; + +static const struct camss_subdev_resources csiphy_res_8550[] = { + /* CSIPHY0 */ + { + .regulators = { "vdda-phy", "vdda-pll" }, + .clock = { "csiphy0", "csiphy0_timer" }, + .clock_rate = { { 400000000, 480000000 }, + { 400000000 } }, + .reg = { "csiphy0" }, + .interrupt = { "csiphy0" }, + .csiphy = { + .id = 0, + .hw_ops = &csiphy_ops_3ph_1_0, + .formats = &csiphy_formats_sdm845 + } + }, + /* CSIPHY1 */ + { + .regulators = { "vdda-phy", "vdda-pll" }, + .clock = { "csiphy1", "csiphy1_timer" }, + .clock_rate = { { 400000000, 480000000 }, + { 400000000 } }, + .reg = { "csiphy1" }, + .interrupt = { "csiphy1" }, + .csiphy = { + .id = 1, + .hw_ops = &csiphy_ops_3ph_1_0, + .formats = &csiphy_formats_sdm845 + } + }, + /* CSIPHY2 */ + { + .regulators = { "vdda-phy", "vdda-pll" }, + .clock = { "csiphy2", "csiphy2_timer" }, + .clock_rate = { { 400000000, 480000000 }, + { 400000000 } }, + .reg = { "csiphy2" }, + .interrupt = { "csiphy2" }, + .csiphy = { + .id = 2, + .hw_ops = &csiphy_ops_3ph_1_0, + .formats = &csiphy_formats_sdm845 + } + }, + /* CSIPHY3 */ + { + .regulators = { "vdda-phy", "vdda-pll" }, + .clock = { "csiphy3", "csiphy3_timer" }, + .clock_rate = { { 400000000, 480000000 }, + { 400000000 } }, + .reg = { "csiphy3" }, + .interrupt = { "csiphy3" }, + .csiphy = { + .id = 3, + .hw_ops = &csiphy_ops_3ph_1_0, + .formats = &csiphy_formats_sdm845 + } + }, + /* CSIPHY4 */ + { + .regulators = { "vdda-phy", "vdda-pll" }, + .clock = { "csiphy4", "csiphy4_timer" }, + .clock_rate = { { 400000000, 480000000 }, + { 400000000 } }, + .reg = { "csiphy4" }, + .interrupt = { "csiphy4" }, + .csiphy = { + .id = 4, + .hw_ops = &csiphy_ops_3ph_1_0, + .formats = &csiphy_formats_sdm845 + } + }, + /* CSIPHY5 */ + { + .regulators = { "vdda-phy", "vdda-pll" }, + .clock = { "csiphy5", "csiphy5_timer" }, + .clock_rate = { { 400000000, 480000000 }, + { 400000000 } }, + .reg = { "csiphy5" }, + .interrupt = { "csiphy5" }, + .csiphy = { + .id = 5, + .hw_ops = &csiphy_ops_3ph_1_0, + .formats = &csiphy_formats_sdm845 + } + }, + /* CSIPHY6 */ + { + .regulators = { "vdda-phy", "vdda-pll" }, + .clock = { "csiphy6", "csiphy6_timer" }, + .clock_rate = { { 400000000, 480000000 }, + { 400000000 } }, + .reg = { "csiphy6" }, + .interrupt = { "csiphy6" }, + .csiphy = { + .id = 6, + .hw_ops = &csiphy_ops_3ph_1_0, + .formats = &csiphy_formats_sdm845 + } + }, + /* CSIPHY7 */ + { + .regulators = { "vdda-phy", "vdda-pll" }, + .clock = { "csiphy7", "csiphy7_timer" }, + .clock_rate = { { 400000000, 480000000 }, + { 400000000 } }, + .reg = { "csiphy7" }, + .interrupt = { "csiphy7" }, + .csiphy = { + .id = 7, + .hw_ops = &csiphy_ops_3ph_1_0, + .formats = &csiphy_formats_sdm845 + } + } +}; + +static const struct resources_wrapper csid_wrapper_res_sm8550 = { + .reg = "csid_wrapper", +}; + +static const struct camss_subdev_resources csid_res_8550[] = { + /* CSID0 */ + { + .regulators = {}, + .clock = { "csid", "csiphy_rx" }, + .clock_rate = { { 400000000, 480000000 }, + { 400000000, 480000000 } }, + .reg = { "csid0" }, + .interrupt = { "csid0" }, + .csid = { + .is_lite = false, + .parent_dev_ops = &vfe_parent_dev_ops, + .hw_ops = &csid_ops_gen3, + .formats = &csid_formats_gen2 + } + }, + /* CSID1 */ + { + .regulators = {}, + .clock = { "csid", "csiphy_rx" }, + .clock_rate = { { 400000000, 480000000 }, + { 400000000, 480000000 } }, + .reg = { "csid1" }, + .interrupt = { "csid1" }, + .csid = { + .is_lite = false, + .parent_dev_ops = &vfe_parent_dev_ops, + .hw_ops = &csid_ops_gen3, + .formats = &csid_formats_gen2 + } + }, + /* CSID2 */ + { + .regulators = {}, + .clock = { "csid", "csiphy_rx" }, + .clock_rate = { { 400000000, 480000000 }, + { 400000000, 480000000 } }, + .reg = { "csid2" }, + .interrupt = { "csid2" }, + .csid = { + .is_lite = false, + .parent_dev_ops = &vfe_parent_dev_ops, + .hw_ops = &csid_ops_gen3, + .formats = &csid_formats_gen2 + } + }, + /* CSID3 */ + { + .regulators = {}, + .clock = { "vfe_lite_csid", "vfe_lite_cphy_rx" }, + .clock_rate = { { 400000000, 480000000 }, + { 400000000, 480000000 } }, + .reg = { "csid_lite0" }, + .interrupt = { "csid_lite0" }, + .csid = { + .is_lite = true, + .parent_dev_ops = &vfe_parent_dev_ops, + .hw_ops = &csid_ops_gen3, + .formats = &csid_formats_gen2 + } + }, + /* CSID4 */ + { + .regulators = {}, + .clock = { "vfe_lite_csid", "vfe_lite_cphy_rx" }, + .clock_rate = { { 400000000, 480000000 }, + { 400000000, 480000000 } }, + .reg = { "csid_lite1" }, + .interrupt = { "csid_lite1" }, + .csid = { + .is_lite = true, + .parent_dev_ops = &vfe_parent_dev_ops, + .hw_ops = &csid_ops_gen3, + .formats = &csid_formats_gen2 + } + } +}; + +static const struct camss_subdev_resources vfe_res_8550[] = { + /* VFE0 */ + { + .regulators = {}, + .clock = { "gcc_axi_hf", "cpas_ahb", "cpas_fast_ahb_clk", "vfe0_fast_ahb", + "vfe0", "cpas_vfe0", "camnoc_axi" }, + .clock_rate = { { 0 }, + { 80000000 }, + { 300000000, 400000000 }, + { 300000000, 400000000 }, + { 466000000, 594000000, 675000000, 785000000 }, + { 300000000, 400000000 }, + { 300000000, 400000000 } }, + .reg = { "vfe0" }, + .interrupt = { "vfe0" }, + .vfe = { + .line_num = 3, + .is_lite = false, + .has_pd = true, + .pd_name = "ife0", + .hw_ops = &vfe_ops_gen3, + .formats_rdi = &vfe_formats_rdi_845, + .formats_pix = &vfe_formats_pix_845 + } + }, + /* VFE1 */ + { + .regulators = {}, + .clock = { "gcc_axi_hf", "cpas_ahb", "cpas_fast_ahb_clk", "vfe1_fast_ahb", + "vfe1", "cpas_vfe1", "camnoc_axi" }, + .clock_rate = { { 0 }, + { 80000000 }, + { 300000000, 400000000 }, + { 300000000, 400000000 }, + { 466000000, 594000000, 675000000, 785000000 }, + { 300000000, 400000000 }, + { 300000000, 400000000 } }, + .reg = { "vfe1" }, + .interrupt = { "vfe1" }, + .vfe = { + .line_num = 3, + .is_lite = false, + .has_pd = true, + .pd_name = "ife1", + .hw_ops = &vfe_ops_gen3, + .formats_rdi = &vfe_formats_rdi_845, + .formats_pix = &vfe_formats_pix_845 + } + }, + /* VFE2 */ + { + .regulators = {}, + .clock = { "gcc_axi_hf", "cpas_ahb", "cpas_fast_ahb_clk", "vfe2_fast_ahb", + "vfe2", "cpas_vfe2", "camnoc_axi" }, + .clock_rate = { { 0 }, + { 80000000 }, + { 300000000, 400000000 }, + { 300000000, 400000000 }, + { 466000000, 594000000, 675000000, 785000000 }, + { 300000000, 400000000 }, + { 300000000, 400000000 } }, + .reg = { "vfe2" }, + .interrupt = { "vfe2" }, + .vfe = { + .line_num = 3, + .is_lite = false, + .has_pd = true, + .pd_name = "ife2", + .hw_ops = &vfe_ops_gen3, + .formats_rdi = &vfe_formats_rdi_845, + .formats_pix = &vfe_formats_pix_845 + } + }, + /* VFE3 lite */ + { + .regulators = {}, + .clock = { "gcc_axi_hf", "cpas_ahb", "cpas_fast_ahb_clk", "vfe_lite_ahb", + "vfe_lite", "cpas_ife_lite", "camnoc_axi" }, + .clock_rate = { { 0 }, + { 80000000 }, + { 300000000, 400000000 }, + { 300000000, 400000000 }, + { 400000000, 480000000 }, + { 300000000, 400000000 }, + { 300000000, 400000000 } }, + .reg = { "vfe_lite0" }, + .interrupt = { "vfe_lite0" }, + .vfe = { + .line_num = 4, + .is_lite = true, + .hw_ops = &vfe_ops_gen3, + .formats_rdi = &vfe_formats_rdi_845, + .formats_pix = &vfe_formats_pix_845 + } + }, + /* VFE4 lite */ + { + .regulators = {}, + .clock = { "gcc_axi_hf", "cpas_ahb", "cpas_fast_ahb_clk", "vfe_lite_ahb", + "vfe_lite", "cpas_ife_lite", "camnoc_axi" }, + .clock_rate = { { 0 }, + { 80000000 }, + { 300000000, 400000000 }, + { 300000000, 400000000 }, + { 400000000, 480000000 }, + { 300000000, 400000000 }, + { 300000000, 400000000 } }, + .reg = { "vfe_lite1" }, + .interrupt = { "vfe_lite1" }, + .vfe = { + .line_num = 4, + .is_lite = true, + .hw_ops = &vfe_ops_gen3, + .formats_rdi = &vfe_formats_rdi_845, + .formats_pix = &vfe_formats_pix_845 + } + }, +}; + +static const struct resources_icc icc_res_sm8550[] = { + { + .name = "ahb", + .icc_bw_tbl.avg = 2097152, + .icc_bw_tbl.peak = 2097152, + }, + { + .name = "hf_0_mnoc", + .icc_bw_tbl.avg = 2097152, + .icc_bw_tbl.peak = 2097152, + }, +}; + +static const struct camss_subdev_resources csiphy_res_sm8650[] = { + /* CSIPHY0 */ + { + .regulators = { "vdd-csiphy01-0p9", "vdd-csiphy01-1p2", }, + .clock = { "csiphy0", "csiphy0_timer" }, + .clock_rate = { { 400000000 }, + { 400000000 } }, + .reg = { "csiphy0" }, + .interrupt = { "csiphy0" }, + .csiphy = { + .id = 0, + .hw_ops = &csiphy_ops_3ph_1_0, + .formats = &csiphy_formats_sdm845, + }, + }, + /* CSIPHY1 */ + { + .regulators = { "vdd-csiphy01-0p9", "vdd-csiphy01-1p2", }, + .clock = { "csiphy1", "csiphy1_timer" }, + .clock_rate = { { 400000000 }, + { 400000000 } }, + .reg = { "csiphy1" }, + .interrupt = { "csiphy1" }, + .csiphy = { + .id = 1, + .hw_ops = &csiphy_ops_3ph_1_0, + .formats = &csiphy_formats_sdm845, + }, + }, + /* CSIPHY2 */ + { + .regulators = { "vdd-csiphy24-0p9", "vdd-csiphy24-1p2", }, + .clock = { "csiphy2", "csiphy2_timer" }, + .clock_rate = { { 400000000 }, + { 400000000 } }, + .reg = { "csiphy2" }, + .interrupt = { "csiphy2" }, + .csiphy = { + .id = 2, + .hw_ops = &csiphy_ops_3ph_1_0, + .formats = &csiphy_formats_sdm845, + }, + }, + /* CSIPHY3 */ + { + .regulators = { "vdd-csiphy35-0p9", "vdd-csiphy35-1p2", }, + .clock = { "csiphy3", "csiphy3_timer" }, + .clock_rate = { { 400000000 }, + { 400000000 } }, + .reg = { "csiphy3" }, + .interrupt = { "csiphy3" }, + .csiphy = { + .id = 3, + .hw_ops = &csiphy_ops_3ph_1_0, + .formats = &csiphy_formats_sdm845, + }, + }, + /* CSIPHY4 */ + { + .regulators = { "vdd-csiphy24-0p9", "vdd-csiphy24-1p2", }, + .clock = { "csiphy4", "csiphy4_timer" }, + .clock_rate = { { 400000000 }, + { 400000000 } }, + .reg = { "csiphy4" }, + .interrupt = { "csiphy4" }, + .csiphy = { + .id = 4, + .hw_ops = &csiphy_ops_3ph_1_0, + .formats = &csiphy_formats_sdm845, + }, + }, + /* CSIPHY5 */ + { + .regulators = { "vdd-csiphy35-0p9", "vdd-csiphy35-1p2", }, + .clock = { "csiphy5", "csiphy5_timer" }, + .clock_rate = { { 400000000 }, + { 400000000 } }, + .reg = { "csiphy5" }, + .interrupt = { "csiphy5" }, + .csiphy = { + .id = 5, + .hw_ops = &csiphy_ops_3ph_1_0, + .formats = &csiphy_formats_sdm845, + }, + }, +}; + +static const struct camss_subdev_resources csid_res_sm8650[] = { + /* CSID0 */ + { + .regulators = { }, + .clock = { "csid", "csiphy_rx" }, + .clock_rate = { { 400000000 }, + { 400000000, 480000000 } }, + .reg = { "csid0" }, + .interrupt = { "csid0" }, + .csid = { + .parent_dev_ops = &vfe_parent_dev_ops, + .hw_ops = &csid_ops_gen3, + .formats = &csid_formats_gen2, + }, + }, + /* CSID1 */ + { + .regulators = { }, + .clock = { "csid", "csiphy_rx" }, + .clock_rate = { { 400000000 }, + { 400000000, 480000000 } }, + .reg = { "csid1" }, + .interrupt = { "csid1" }, + .csid = { + .parent_dev_ops = &vfe_parent_dev_ops, + .hw_ops = &csid_ops_gen3, + .formats = &csid_formats_gen2, + }, + }, + /* CSID2 */ + { + .regulators = { }, + .clock = { "csid", "csiphy_rx" }, + .clock_rate = { { 400000000 }, + { 400000000, 480000000 } }, + .reg = { "csid2" }, + .interrupt = { "csid2" }, + .csid = { + .parent_dev_ops = &vfe_parent_dev_ops, + .hw_ops = &csid_ops_gen3, + .formats = &csid_formats_gen2, + }, + }, + /* CSID3 lite */ + { + .regulators = { }, + .clock = { "vfe_lite_ahb", "vfe_lite_csid", "vfe_lite_cphy_rx" }, + .clock_rate = { { 0 }, + { 400000000, 480000000 }, + { 0 } }, + .reg = { "csid_lite0" }, + .interrupt = { "csid_lite0" }, + .csid = { + .is_lite = true, + .parent_dev_ops = &vfe_parent_dev_ops, + .hw_ops = &csid_ops_gen3, + .formats = &csid_formats_gen2, + }, + }, + /* CSID4 lite */ + { + .regulators = { }, + .clock = { "vfe_lite_ahb", "vfe_lite_csid", "vfe_lite_cphy_rx" }, + .clock_rate = { { 0 }, + { 400000000, 480000000 }, + { 0 } }, + .reg = { "csid_lite1" }, + .interrupt = { "csid_lite1" }, + .csid = { + .is_lite = true, + .parent_dev_ops = &vfe_parent_dev_ops, + .hw_ops = &csid_ops_gen3, + .formats = &csid_formats_gen2, + }, + }, +}; + +static const struct camss_subdev_resources vfe_res_sm8650[] = { + /* VFE0 */ + { + .regulators = { }, + .clock = { "gcc_axi_hf", "cpas_ahb", "cpas_fast_ahb", + "camnoc_axi", "vfe0_fast_ahb", "vfe0", "cpas_vfe0", + "qdss_debug_xo", + }, + .clock_rate = { { 0 }, + { 80000000 }, + { 300000000, 400000000 }, + { 300000000, 400000000 }, + { 0 }, + { 466000000, 594000000, 675000000, 785000000 }, + { 0 }, + { 0 }, + }, + .reg = { "vfe0" }, + .interrupt = { "vfe0" }, + .vfe = { + .line_num = 3, + .has_pd = true, + .pd_name = "ife0", + .hw_ops = &vfe_ops_gen3, + .formats_rdi = &vfe_formats_rdi_845, + .formats_pix = &vfe_formats_pix_845 + }, + }, + /* VFE1 */ + { + .regulators = { }, + .clock = { "gcc_axi_hf", "cpas_ahb", "cpas_fast_ahb", + "camnoc_axi", "vfe1_fast_ahb", "vfe1", "cpas_vfe1", + "qdss_debug_xo", + }, + .clock_rate = { { 0 }, + { 80000000 }, + { 300000000, 400000000 }, + { 300000000, 400000000 }, + { 0 }, + { 466000000, 594000000, 675000000, 785000000 }, + { 0 }, + { 0 }, + }, + .reg = { "vfe1" }, + .interrupt = { "vfe1" }, + .vfe = { + .line_num = 3, + .has_pd = true, + .pd_name = "ife1", + .hw_ops = &vfe_ops_gen3, + .formats_rdi = &vfe_formats_rdi_845, + .formats_pix = &vfe_formats_pix_845 + }, + }, + /* VFE2 */ + { + .regulators = { }, + .clock = { "gcc_axi_hf", "cpas_ahb", "cpas_fast_ahb", + "camnoc_axi", "vfe2_fast_ahb", "vfe2", "cpas_vfe2", + "qdss_debug_xo", + }, + .clock_rate = { { 0 }, + { 80000000 }, + { 300000000, 400000000 }, + { 300000000, 400000000 }, + { 0 }, + { 466000000, 594000000, 675000000, 785000000 }, + { 0 }, + { 0 }, + }, + .reg = { "vfe2" }, + .interrupt = { "vfe2" }, + .vfe = { + .line_num = 3, + .has_pd = true, + .pd_name = "ife2", + .hw_ops = &vfe_ops_gen3, + .formats_rdi = &vfe_formats_rdi_845, + .formats_pix = &vfe_formats_pix_845 + }, + }, + /* VFE3 lite */ + { + .regulators = { }, + .clock = { "gcc_axi_hf", "cpas_ahb", "camnoc_axi", + "vfe_lite_ahb", "vfe_lite", "cpas_vfe_lite", + "qdss_debug_xo", + }, + .clock_rate = { { 0 }, + { 80000000 }, + { 300000000, 400000000 }, + { 0 }, + { 400000000, 480000000 }, + { 0 }, + { 0 }, + }, + .reg = { "vfe_lite0" }, + .interrupt = { "vfe_lite0" }, + .vfe = { + .line_num = 4, + .is_lite = true, + .hw_ops = &vfe_ops_gen3, + .formats_rdi = &vfe_formats_rdi_845, + .formats_pix = &vfe_formats_pix_845 + }, + }, + /* VFE4 lite */ + { + .regulators = { }, + .clock = { "gcc_axi_hf", "cpas_ahb", "camnoc_axi", + "vfe_lite_ahb", "vfe_lite", "cpas_vfe_lite", + "qdss_debug_xo", + }, + .clock_rate = { { 0 }, + { 80000000 }, + { 300000000, 400000000 }, + { 0 }, + { 400000000, 480000000 }, + { 0 }, + { 0 }, + }, + .reg = { "vfe_lite1" }, + .interrupt = { "vfe_lite1" }, + .vfe = { + .line_num = 4, + .is_lite = true, + .hw_ops = &vfe_ops_gen3, + .formats_rdi = &vfe_formats_rdi_845, + .formats_pix = &vfe_formats_pix_845 + }, + }, +}; + +static const struct resources_icc icc_res_sm8650[] = { + { + .name = "ahb", + .icc_bw_tbl.avg = 38400, + .icc_bw_tbl.peak = 76800, + }, + { + .name = "hf_mnoc", + .icc_bw_tbl.avg = 2097152, + .icc_bw_tbl.peak = 2097152, + }, +}; + +static const struct camss_subdev_resources csiphy_res_8300[] = { + /* CSIPHY0 */ + { + .regulators = { "vdda-phy", "vdda-pll" }, + + .clock = { "csiphy_rx", "csiphy0", "csiphy0_timer" }, + .clock_rate = { + { 400000000 }, + { 0 }, + { 400000000 }, + }, + .reg = { "csiphy0" }, + .interrupt = { "csiphy0" }, + .csiphy = { + .id = 0, + .hw_ops = &csiphy_ops_3ph_1_0, + .formats = &csiphy_formats_sdm845, + } + }, + /* CSIPHY1 */ + { + .regulators = { "vdda-phy", "vdda-pll" }, + + .clock = { "csiphy_rx", "csiphy1", "csiphy1_timer" }, + .clock_rate = { + { 400000000 }, + { 0 }, + { 400000000 }, + }, + .reg = { "csiphy1" }, + .interrupt = { "csiphy1" }, + .csiphy = { + .id = 1, + .hw_ops = &csiphy_ops_3ph_1_0, + .formats = &csiphy_formats_sdm845, + } + }, + /* CSIPHY2 */ + { + .regulators = { "vdda-phy", "vdda-pll" }, + + .clock = { "csiphy_rx", "csiphy2", "csiphy2_timer" }, + .clock_rate = { + { 400000000 }, + { 0 }, + { 400000000 }, + }, + .reg = { "csiphy2" }, + .interrupt = { "csiphy2" }, + .csiphy = { + .id = 2, + .hw_ops = &csiphy_ops_3ph_1_0, + .formats = &csiphy_formats_sdm845, + } + }, +}; + +static const struct camss_subdev_resources csiphy_res_8775p[] = { + /* CSIPHY0 */ + { + .regulators = { "vdda-phy", "vdda-pll" }, + .clock = { "csiphy_rx", "csiphy0", "csiphy0_timer"}, + .clock_rate = { + { 400000000 }, + { 0 }, + { 400000000 }, + }, + .reg = { "csiphy0" }, + .interrupt = { "csiphy0" }, + .csiphy = { + .id = 0, + .hw_ops = &csiphy_ops_3ph_1_0, + .formats = &csiphy_formats_sdm845 + } + }, + /* CSIPHY1 */ + { + .regulators = { "vdda-phy", "vdda-pll" }, + .clock = { "csiphy_rx", "csiphy1", "csiphy1_timer"}, + .clock_rate = { + { 400000000 }, + { 0 }, + { 400000000 }, + }, + .reg = { "csiphy1" }, + .interrupt = { "csiphy1" }, + .csiphy = { + .id = 1, + .hw_ops = &csiphy_ops_3ph_1_0, + .formats = &csiphy_formats_sdm845 + } + }, + /* CSIPHY2 */ + { + .regulators = { "vdda-phy", "vdda-pll" }, + .clock = { "csiphy_rx", "csiphy2", "csiphy2_timer"}, + .clock_rate = { + { 400000000 }, + { 0 }, + { 400000000 }, + }, + .reg = { "csiphy2" }, + .interrupt = { "csiphy2" }, + .csiphy = { + .id = 2, + .hw_ops = &csiphy_ops_3ph_1_0, + .formats = &csiphy_formats_sdm845 + } + }, + /* CSIPHY3 */ + { + .regulators = { "vdda-phy", "vdda-pll" }, + .clock = { "csiphy_rx", "csiphy3", "csiphy3_timer"}, + .clock_rate = { + { 400000000 }, + { 0 }, + { 400000000 }, + }, + .reg = { "csiphy3" }, + .interrupt = { "csiphy3" }, + .csiphy = { + .id = 3, + .hw_ops = &csiphy_ops_3ph_1_0, + .formats = &csiphy_formats_sdm845 + } + }, +}; + +static const struct camss_subdev_resources csid_res_8775p[] = { + /* CSID0 */ + { + .regulators = {}, + .clock = { "csid", "csiphy_rx"}, + .clock_rate = { + { 400000000, 400000000}, + { 400000000, 400000000} + }, + .reg = { "csid0" }, + .interrupt = { "csid0" }, + .csid = { + .is_lite = false, + .hw_ops = &csid_ops_gen3, + .parent_dev_ops = &vfe_parent_dev_ops, + .formats = &csid_formats_gen2 + } + }, + /* CSID1 */ + { + .regulators = {}, + .clock = { "csid", "csiphy_rx"}, + .clock_rate = { + { 400000000, 400000000}, + { 400000000, 400000000} + }, + .reg = { "csid1" }, + .interrupt = { "csid1" }, + .csid = { + .is_lite = false, + .hw_ops = &csid_ops_gen3, + .parent_dev_ops = &vfe_parent_dev_ops, + .formats = &csid_formats_gen2 + } + }, + + /* CSID2 (lite) */ + { + .regulators = {}, + .clock = { "cpas_vfe_lite", "vfe_lite_ahb", + "vfe_lite_csid", "vfe_lite_cphy_rx", + "vfe_lite"}, + .clock_rate = { + { 0, 0, 400000000, 400000000, 0}, + { 0, 0, 400000000, 480000000, 0} + }, + .reg = { "csid_lite0" }, + .interrupt = { "csid_lite0" }, + .csid = { + .is_lite = true, + .hw_ops = &csid_ops_gen3, + .parent_dev_ops = &vfe_parent_dev_ops, + .formats = &csid_formats_gen2 + } + }, + /* CSID3 (lite) */ + { + .regulators = {}, + .clock = { "cpas_vfe_lite", "vfe_lite_ahb", + "vfe_lite_csid", "vfe_lite_cphy_rx", + "vfe_lite"}, + .clock_rate = { + { 0, 0, 400000000, 400000000, 0}, + { 0, 0, 400000000, 480000000, 0} + }, + .reg = { "csid_lite1" }, + .interrupt = { "csid_lite1" }, + .csid = { + .is_lite = true, + .hw_ops = &csid_ops_gen3, + .parent_dev_ops = &vfe_parent_dev_ops, + .formats = &csid_formats_gen2 + } + }, + /* CSID4 (lite) */ + { + .regulators = {}, + .clock = { "cpas_vfe_lite", "vfe_lite_ahb", + "vfe_lite_csid", "vfe_lite_cphy_rx", + "vfe_lite"}, + .clock_rate = { + { 0, 0, 400000000, 400000000, 0}, + { 0, 0, 400000000, 480000000, 0} + }, + .reg = { "csid_lite2" }, + .interrupt = { "csid_lite2" }, + .csid = { + .is_lite = true, + .hw_ops = &csid_ops_gen3, + .parent_dev_ops = &vfe_parent_dev_ops, + .formats = &csid_formats_gen2 + } + }, + /* CSID5 (lite) */ + { + .regulators = {}, + .clock = { "cpas_vfe_lite", "vfe_lite_ahb", + "vfe_lite_csid", "vfe_lite_cphy_rx", + "vfe_lite"}, + .clock_rate = { + { 0, 0, 400000000, 400000000, 0}, + { 0, 0, 400000000, 480000000, 0} + }, + .reg = { "csid_lite3" }, + .interrupt = { "csid_lite3" }, + .csid = { + .is_lite = true, + .hw_ops = &csid_ops_gen3, + .parent_dev_ops = &vfe_parent_dev_ops, + .formats = &csid_formats_gen2 + } + }, + /* CSID6 (lite) */ + { + .regulators = {}, + .clock = { "cpas_vfe_lite", "vfe_lite_ahb", + "vfe_lite_csid", "vfe_lite_cphy_rx", + "vfe_lite"}, + .clock_rate = { + { 0, 0, 400000000, 400000000, 0}, + { 0, 0, 400000000, 480000000, 0} + }, + .reg = { "csid_lite4" }, + .interrupt = { "csid_lite4" }, + .csid = { + .is_lite = true, + .hw_ops = &csid_ops_gen3, + .parent_dev_ops = &vfe_parent_dev_ops, + .formats = &csid_formats_gen2 + } + }, +}; + +static const struct camss_subdev_resources vfe_res_8775p[] = { + /* VFE0 */ + { + .regulators = {}, + .clock = { "cpas_vfe0", "vfe0", "vfe0_fast_ahb", + "cpas_ahb", "gcc_axi_hf", + "cpas_fast_ahb_clk", + "camnoc_axi"}, + .clock_rate = { + { 0 }, + { 480000000 }, + { 300000000, 400000000 }, + { 300000000, 400000000 }, + { 0 }, + { 300000000, 400000000 }, + { 400000000 }, + }, + .reg = { "vfe0" }, + .interrupt = { "vfe0" }, + .vfe = { + .line_num = 3, + .is_lite = false, + .has_pd = false, + .pd_name = NULL, + .hw_ops = &vfe_ops_gen3, + .formats_rdi = &vfe_formats_rdi_845, + .formats_pix = &vfe_formats_pix_845 + } + }, + /* VFE1 */ + { + .regulators = {}, + .clock = { "cpas_vfe1", "vfe1", "vfe1_fast_ahb", + "cpas_ahb", "gcc_axi_hf", + "cpas_fast_ahb_clk", + "camnoc_axi"}, + .clock_rate = { + { 0 }, + { 480000000 }, + { 300000000, 400000000 }, + { 300000000, 400000000 }, + { 0 }, + { 300000000, 400000000 }, + { 400000000 }, + }, + .reg = { "vfe1" }, + .interrupt = { "vfe1" }, + .vfe = { + .line_num = 3, + .is_lite = false, + .has_pd = false, + .pd_name = NULL, + .hw_ops = &vfe_ops_gen3, + .formats_rdi = &vfe_formats_rdi_845, + .formats_pix = &vfe_formats_pix_845 + } + }, + /* VFE2 (lite) */ + { + .regulators = {}, + .clock = { "cpas_vfe_lite", "vfe_lite_ahb", + "vfe_lite_csid", "vfe_lite_cphy_rx", + "vfe_lite"}, + .clock_rate = { + { 0, 0, 0, 0 }, + { 300000000, 400000000, 400000000, 400000000 }, + { 400000000, 400000000, 400000000, 400000000 }, + { 400000000, 400000000, 400000000, 400000000 }, + { 480000000, 600000000, 600000000, 600000000 }, + }, + .reg = { "vfe_lite0" }, + .interrupt = { "vfe_lite0" }, + .vfe = { + .line_num = 4, + .is_lite = true, + .hw_ops = &vfe_ops_gen3, + .formats_rdi = &vfe_formats_rdi_845, + .formats_pix = &vfe_formats_pix_845 + } + }, + /* VFE3 (lite) */ + { + .regulators = {}, + .clock = { "cpas_vfe_lite", "vfe_lite_ahb", + "vfe_lite_csid", "vfe_lite_cphy_rx", + "vfe_lite"}, + .clock_rate = { + { 0, 0, 0, 0 }, + { 300000000, 400000000, 400000000, 400000000 }, + { 400000000, 400000000, 400000000, 400000000 }, + { 400000000, 400000000, 400000000, 400000000 }, + { 480000000, 600000000, 600000000, 600000000 }, + }, + .reg = { "vfe_lite1" }, + .interrupt = { "vfe_lite1" }, + .vfe = { + .line_num = 4, + .is_lite = true, + .hw_ops = &vfe_ops_gen3, + .formats_rdi = &vfe_formats_rdi_845, + .formats_pix = &vfe_formats_pix_845 + } + }, + /* VFE4 (lite) */ + { + .regulators = {}, + .clock = { "cpas_vfe_lite", "vfe_lite_ahb", + "vfe_lite_csid", "vfe_lite_cphy_rx", + "vfe_lite"}, + .clock_rate = { + { 0, 0, 0, 0 }, + { 300000000, 400000000, 400000000, 400000000 }, + { 400000000, 400000000, 400000000, 400000000 }, + { 400000000, 400000000, 400000000, 400000000 }, + { 480000000, 600000000, 600000000, 600000000 }, + }, + .reg = { "vfe_lite2" }, + .interrupt = { "vfe_lite2" }, + .vfe = { + .line_num = 4, + .is_lite = true, + .hw_ops = &vfe_ops_gen3, + .formats_rdi = &vfe_formats_rdi_845, + .formats_pix = &vfe_formats_pix_845 + } + }, + /* VFE5 (lite) */ + { + .regulators = {}, + .clock = { "cpas_vfe_lite", "vfe_lite_ahb", + "vfe_lite_csid", "vfe_lite_cphy_rx", + "vfe_lite"}, + .clock_rate = { + { 0, 0, 0, 0 }, + { 300000000, 400000000, 400000000, 400000000 }, + { 400000000, 400000000, 400000000, 400000000 }, + { 400000000, 400000000, 400000000, 400000000 }, + { 480000000, 600000000, 600000000, 600000000 }, + }, + .reg = { "vfe_lite3" }, + .interrupt = { "vfe_lite3" }, + .vfe = { + .line_num = 4, + .is_lite = true, + .hw_ops = &vfe_ops_gen3, + .formats_rdi = &vfe_formats_rdi_845, + .formats_pix = &vfe_formats_pix_845 + } + }, + /* VFE6 (lite) */ + { + .regulators = {}, + .clock = { "cpas_vfe_lite", "vfe_lite_ahb", + "vfe_lite_csid", "vfe_lite_cphy_rx", + "vfe_lite"}, + .clock_rate = { + { 0, 0, 0, 0 }, + { 300000000, 400000000, 400000000, 400000000 }, + { 400000000, 400000000, 400000000, 400000000 }, + { 400000000, 400000000, 400000000, 400000000 }, + { 480000000, 600000000, 600000000, 600000000 }, + }, + .reg = { "vfe_lite4" }, + .interrupt = { "vfe_lite4" }, + .vfe = { + .line_num = 4, + .is_lite = true, + .hw_ops = &vfe_ops_gen3, + .formats_rdi = &vfe_formats_rdi_845, + .formats_pix = &vfe_formats_pix_845 + } + }, +}; + +static const struct resources_icc icc_res_qcs8300[] = { + { + .name = "ahb", + .icc_bw_tbl.avg = 38400, + .icc_bw_tbl.peak = 76800, + }, + { + .name = "hf_0", + .icc_bw_tbl.avg = 2097152, + .icc_bw_tbl.peak = 2097152, + }, +}; + +static const struct resources_icc icc_res_sa8775p[] = { + { + .name = "ahb", + .icc_bw_tbl.avg = 38400, + .icc_bw_tbl.peak = 76800, + }, + { + .name = "hf_0", + .icc_bw_tbl.avg = 2097152, + .icc_bw_tbl.peak = 2097152, + }, +}; + +static const struct camss_subdev_resources csiphy_res_x1e80100[] = { + /* CSIPHY0 */ + { + .regulators = { "vdd-csiphy-0p8", + "vdd-csiphy-1p2" }, + .clock = { "csiphy0", "csiphy0_timer" }, + .clock_rate = { { 300000000, 400000000, 480000000 }, + { 266666667, 400000000 } }, + .reg = { "csiphy0" }, + .interrupt = { "csiphy0" }, + .csiphy = { + .id = 0, + .hw_ops = &csiphy_ops_3ph_1_0, + .formats = &csiphy_formats_sdm845 + }, + }, + /* CSIPHY1 */ + { + .regulators = { "vdd-csiphy-0p8", + "vdd-csiphy-1p2" }, + .clock = { "csiphy1", "csiphy1_timer" }, + .clock_rate = { { 300000000, 400000000, 480000000 }, + { 266666667, 400000000 } }, + .reg = { "csiphy1" }, + .interrupt = { "csiphy1" }, + .csiphy = { + .id = 1, + .hw_ops = &csiphy_ops_3ph_1_0, + .formats = &csiphy_formats_sdm845 + }, + }, + /* CSIPHY2 */ + { + .regulators = { "vdd-csiphy-0p8", + "vdd-csiphy-1p2" }, + .clock = { "csiphy2", "csiphy2_timer" }, + .clock_rate = { { 300000000, 400000000, 480000000 }, + { 266666667, 400000000 } }, + .reg = { "csiphy2" }, + .interrupt = { "csiphy2" }, + .csiphy = { + .id = 2, + .hw_ops = &csiphy_ops_3ph_1_0, + .formats = &csiphy_formats_sdm845 + }, + }, + /* CSIPHY4 */ + { + .regulators = { "vdd-csiphy-0p8", + "vdd-csiphy-1p2" }, + .clock = { "csiphy4", "csiphy4_timer" }, + .clock_rate = { { 300000000, 400000000, 480000000 }, + { 266666667, 400000000 } }, + .reg = { "csiphy4" }, + .interrupt = { "csiphy4" }, + .csiphy = { + .id = 4, + .hw_ops = &csiphy_ops_3ph_1_0, + .formats = &csiphy_formats_sdm845 + }, + }, +}; + +static const struct camss_subdev_resources csid_res_x1e80100[] = { + /* CSID0 */ + { + .regulators = {}, + .clock = { "gcc_axi_hf", "gcc_axi_sf", "cpas_ahb", + "cpas_fast_ahb", "csid", "csid_csiphy_rx" }, + .clock_rate = { { 0 }, + { 0 }, + { 64000000, 80000000 }, + { 80000000, 100000000, 200000000, + 300000000, 400000000 }, + { 300000000, 400000000, 480000000 }, + { 300000000, 400000000, 480000000 }, }, + .reg = { "csid0" }, + .interrupt = { "csid0" }, + .csid = { + .hw_ops = &csid_ops_680, + .parent_dev_ops = &vfe_parent_dev_ops, + .formats = &csid_formats_gen2 + }, + }, + /* CSID1 */ + { + .regulators = {}, + .clock = { "gcc_axi_hf", "gcc_axi_sf", "cpas_ahb", + "cpas_fast_ahb", "csid", "csid_csiphy_rx" }, + .clock_rate = { { 0 }, + { 0 }, + { 64000000, 80000000 }, + { 80000000, 100000000, 200000000, + 300000000, 400000000 }, + { 300000000, 400000000, 480000000 }, + { 300000000, 400000000, 480000000 }, }, + .reg = { "csid1" }, + .interrupt = { "csid1" }, + .csid = { + .hw_ops = &csid_ops_680, + .parent_dev_ops = &vfe_parent_dev_ops, + .formats = &csid_formats_gen2 + }, + }, + /* CSID2 */ + { + .regulators = {}, + .clock = { "gcc_axi_hf", "gcc_axi_sf", "cpas_ahb", + "cpas_fast_ahb", "csid", "csid_csiphy_rx" }, + .clock_rate = { { 0 }, + { 0 }, + { 64000000, 80000000 }, + { 80000000, 100000000, 200000000, + 300000000, 400000000 }, + { 300000000, 400000000, 480000000 }, + { 300000000, 400000000, 480000000 }, }, + .reg = { "csid2" }, + .interrupt = { "csid2" }, + .csid = { + .hw_ops = &csid_ops_680, + .parent_dev_ops = &vfe_parent_dev_ops, + .formats = &csid_formats_gen2 + }, + }, + /* CSID_LITE0 */ + { + .regulators = {}, + .clock = { "gcc_axi_hf", "gcc_axi_sf", "cpas_ahb", + "cpas_fast_ahb", "csid", "csid_csiphy_rx" }, + .clock_rate = { { 0 }, + { 0 }, + { 64000000, 80000000 }, + { 80000000, 100000000, 200000000, + 300000000, 400000000 }, + { 300000000, 400000000, 480000000 }, + { 300000000, 400000000, 480000000 }, }, + .reg = { "csid_lite0" }, + .interrupt = { "csid_lite0" }, + .csid = { + .is_lite = true, + .hw_ops = &csid_ops_680, + .parent_dev_ops = &vfe_parent_dev_ops, + .formats = &csid_formats_gen2 + } + }, + /* CSID_LITE1 */ + { + .regulators = {}, + .clock = { "gcc_axi_hf", "gcc_axi_sf", "cpas_ahb", + "cpas_fast_ahb", "csid", "csid_csiphy_rx" }, + .clock_rate = { { 0 }, + { 0 }, + { 64000000, 80000000 }, + { 80000000, 100000000, 200000000, + 300000000, 400000000 }, + { 300000000, 400000000, 480000000 }, + { 300000000, 400000000, 480000000 }, }, + + .reg = { "csid_lite1" }, + .interrupt = { "csid_lite1" }, + .csid = { + .is_lite = true, + .hw_ops = &csid_ops_680, + .parent_dev_ops = &vfe_parent_dev_ops, + .formats = &csid_formats_gen2 + } + }, +}; + +static const struct camss_subdev_resources vfe_res_x1e80100[] = { + /* IFE0 */ + { + .regulators = {}, + .clock = {"camnoc_rt_axi", "camnoc_nrt_axi", "cpas_ahb", + "cpas_fast_ahb", "cpas_vfe0", "vfe0_fast_ahb", + "vfe0" }, + .clock_rate = { { 0 }, + { 0 }, + { 0 }, + { 0 }, + { 0 }, + { 0 }, + { 345600000, 432000000, 594000000, 675000000, + 727000000 }, }, + .reg = { "vfe0" }, + .interrupt = { "vfe0" }, + .vfe = { + .line_num = 4, + .pd_name = "ife0", + .hw_ops = &vfe_ops_680, + .formats_rdi = &vfe_formats_rdi_845, + .formats_pix = &vfe_formats_pix_845 + }, + }, + /* IFE1 */ + { + .regulators = {}, + .clock = { "camnoc_rt_axi", "camnoc_nrt_axi", "cpas_ahb", + "cpas_fast_ahb", "cpas_vfe1", "vfe1_fast_ahb", + "vfe1" }, + .clock_rate = { { 0 }, + { 0 }, + { 0 }, + { 0 }, + { 0 }, + { 0 }, + { 345600000, 432000000, 594000000, 675000000, + 727000000 }, }, + .reg = { "vfe1" }, + .interrupt = { "vfe1" }, + .vfe = { + .line_num = 4, + .pd_name = "ife1", + .hw_ops = &vfe_ops_680, + .formats_rdi = &vfe_formats_rdi_845, + .formats_pix = &vfe_formats_pix_845 + }, + }, + /* IFE_LITE_0 */ + { + .regulators = {}, + .clock = { "camnoc_rt_axi", "camnoc_nrt_axi", "cpas_ahb", + "vfe_lite_ahb", "cpas_vfe_lite", "vfe_lite", + "vfe_lite_csid" }, + .clock_rate = { { 0 }, + { 0 }, + { 0 }, + { 0 }, + { 0 }, + { 266666667, 400000000, 480000000 }, + { 266666667, 400000000, 480000000 }, }, + .reg = { "vfe_lite0" }, + .interrupt = { "vfe_lite0" }, + .vfe = { + .is_lite = true, + .line_num = 4, + .hw_ops = &vfe_ops_680, + .formats_rdi = &vfe_formats_rdi_845, + .formats_pix = &vfe_formats_pix_845 + }, + }, + /* IFE_LITE_1 */ + { + .regulators = {}, + .clock = { "camnoc_rt_axi", "camnoc_nrt_axi", "cpas_ahb", + "vfe_lite_ahb", "cpas_vfe_lite", "vfe_lite", + "vfe_lite_csid" }, + .clock_rate = { { 0 }, + { 0 }, + { 0 }, + { 0 }, + { 0 }, + { 266666667, 400000000, 480000000 }, + { 266666667, 400000000, 480000000 }, }, + .reg = { "vfe_lite1" }, + .interrupt = { "vfe_lite1" }, + .vfe = { + .is_lite = true, + .line_num = 4, + .hw_ops = &vfe_ops_680, + .formats_rdi = &vfe_formats_rdi_845, + .formats_pix = &vfe_formats_pix_845 + }, + }, +}; + +static const struct resources_icc icc_res_x1e80100[] = { + { + .name = "ahb", + .icc_bw_tbl.avg = 150000, + .icc_bw_tbl.peak = 300000, + }, + { + .name = "hf_mnoc", + .icc_bw_tbl.avg = 2097152, + .icc_bw_tbl.peak = 2097152, + }, + { + .name = "sf_mnoc", + .icc_bw_tbl.avg = 2097152, + .icc_bw_tbl.peak = 2097152, + }, + { + .name = "sf_icp_mnoc", + .icc_bw_tbl.avg = 2097152, + .icc_bw_tbl.peak = 2097152, + }, +}; + +static const struct resources_wrapper csid_wrapper_res_x1e80100 = { + .reg = "csid_wrapper", +}; + /* * camss_add_clock_margin - Add margin to clock frequency rate * @rate: Clock frequency rate @@ -720,12 +3883,12 @@ void camss_disable_clocks(int nclocks, struct camss_clock *clock) } /* - * camss_find_sensor - Find a linked media entity which represents a sensor + * camss_find_sensor_pad - Find the media pad via which the sensor is linked * @entity: Media entity to start searching from * - * Return a pointer to sensor media entity or NULL if not found + * Return a pointer to sensor media pad or NULL if not found */ -struct media_entity *camss_find_sensor(struct media_entity *entity) +struct media_pad *camss_find_sensor_pad(struct media_entity *entity) { struct media_pad *pad; @@ -734,14 +3897,14 @@ struct media_entity *camss_find_sensor(struct media_entity *entity) if (!(pad->flags & MEDIA_PAD_FL_SINK)) return NULL; - pad = media_entity_remote_pad(pad); + pad = media_pad_remote_pad_first(pad); if (!pad || !is_media_entity_v4l2_subdev(pad->entity)) return NULL; entity = pad->entity; if (entity->function == MEDIA_ENT_F_CAM_SENSOR) - return entity; + return pad; } } @@ -756,16 +3919,13 @@ struct media_entity *camss_find_sensor(struct media_entity *entity) s64 camss_get_link_freq(struct media_entity *entity, unsigned int bpp, unsigned int lanes) { - struct media_entity *sensor; - struct v4l2_subdev *subdev; + struct media_pad *sensor_pad; - sensor = camss_find_sensor(entity); - if (!sensor) + sensor_pad = camss_find_sensor_pad(entity); + if (!sensor_pad) return -ENODEV; - subdev = media_entity_to_v4l2_subdev(sensor); - - return v4l2_get_link_freq(subdev->ctrl_handler, bpp, 2 * lanes); + return v4l2_get_link_freq(sensor_pad, bpp, 2 * lanes); } /* @@ -777,15 +3937,15 @@ s64 camss_get_link_freq(struct media_entity *entity, unsigned int bpp, */ int camss_get_pixel_clock(struct media_entity *entity, u64 *pixel_clock) { - struct media_entity *sensor; + struct media_pad *sensor_pad; struct v4l2_subdev *subdev; struct v4l2_ctrl *ctrl; - sensor = camss_find_sensor(entity); - if (!sensor) + sensor_pad = camss_find_sensor_pad(entity); + if (!sensor_pad) return -ENODEV; - subdev = media_entity_to_v4l2_subdev(sensor); + subdev = media_entity_to_v4l2_subdev(sensor_pad->entity); ctrl = v4l2_ctrl_find(subdev->ctrl_handler, V4L2_CID_PIXEL_RATE); @@ -801,10 +3961,10 @@ int camss_pm_domain_on(struct camss *camss, int id) { int ret = 0; - if (id < camss->vfe_num) { + if (id < camss->res->vfe_num) { struct vfe_device *vfe = &camss->vfe[id]; - ret = vfe->ops->pm_domain_on(vfe); + ret = vfe->res->hw_ops->pm_domain_on(vfe); } return ret; @@ -812,13 +3972,55 @@ int camss_pm_domain_on(struct camss *camss, int id) void camss_pm_domain_off(struct camss *camss, int id) { - if (id < camss->vfe_num) { + if (id < camss->res->vfe_num) { + struct vfe_device *vfe = &camss->vfe[id]; + + vfe->res->hw_ops->pm_domain_off(vfe); + } +} + +static int vfe_parent_dev_ops_get(struct camss *camss, int id) +{ + int ret = -EINVAL; + + if (id < camss->res->vfe_num) { + struct vfe_device *vfe = &camss->vfe[id]; + + ret = vfe_get(vfe); + } + + return ret; +} + +static int vfe_parent_dev_ops_put(struct camss *camss, int id) +{ + if (id < camss->res->vfe_num) { + struct vfe_device *vfe = &camss->vfe[id]; + + vfe_put(vfe); + } + + return 0; +} + +static void __iomem +*vfe_parent_dev_ops_get_base_address(struct camss *camss, int id) +{ + if (id < camss->res->vfe_num) { struct vfe_device *vfe = &camss->vfe[id]; - vfe->ops->pm_domain_off(vfe); + return vfe->base; } + + return NULL; } +static const struct parent_dev_ops vfe_parent_dev_ops = { + .get = vfe_parent_dev_ops_get, + .put = vfe_parent_dev_ops_put, + .get_base_address = vfe_parent_dev_ops_get_base_address +}; + /* * camss_of_parse_endpoint_node - Parse port endpoint node * @dev: Device @@ -832,11 +4034,23 @@ static int camss_of_parse_endpoint_node(struct device *dev, struct camss_async_subdev *csd) { struct csiphy_lanes_cfg *lncfg = &csd->interface.csi2.lane_cfg; - struct v4l2_fwnode_bus_mipi_csi2 *mipi_csi2; + struct v4l2_mbus_config_mipi_csi2 *mipi_csi2; struct v4l2_fwnode_endpoint vep = { { 0 } }; unsigned int i; + int ret; - v4l2_fwnode_endpoint_parse(of_fwnode_handle(node), &vep); + ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(node), &vep); + if (ret) + return ret; + + /* + * Most SoCs support both D-PHY and C-PHY standards, but currently only + * D-PHY is supported in the driver. + */ + if (vep.bus_type != V4L2_MBUS_CSI2_DPHY) { + dev_err(dev, "Unsupported bus type %d\n", vep.bus_type); + return -EINVAL; + } csd->interface.csiphy_id = vep.base.port; @@ -876,9 +4090,6 @@ static int camss_of_parse_ports(struct camss *camss) for_each_endpoint_of_node(dev->of_node, node) { struct camss_async_subdev *csd; - if (!of_device_is_available(node)) - continue; - remote = of_graph_get_remote_port_parent(node); if (!remote) { dev_err(dev, "Cannot get remote parent\n"); @@ -886,9 +4097,9 @@ static int camss_of_parse_ports(struct camss *camss) goto err_cleanup; } - csd = v4l2_async_notifier_add_fwnode_subdev( - &camss->notifier, of_fwnode_handle(remote), - struct camss_async_subdev); + csd = v4l2_async_nf_add_fwnode(&camss->notifier, + of_fwnode_handle(remote), + struct camss_async_subdev); of_node_put(remote); if (IS_ERR(csd)) { ret = PTR_ERR(csd); @@ -917,41 +4128,15 @@ err_cleanup: */ static int camss_init_subdevices(struct camss *camss) { - const struct resources *csiphy_res; - const struct resources *csid_res; - const struct resources_ispif *ispif_res; - const struct resources *vfe_res; + struct platform_device *pdev = to_platform_device(camss->dev); + const struct camss_resources *res = camss->res; unsigned int i; int ret; - if (camss->version == CAMSS_8x16) { - csiphy_res = csiphy_res_8x16; - csid_res = csid_res_8x16; - ispif_res = &ispif_res_8x16; - vfe_res = vfe_res_8x16; - } else if (camss->version == CAMSS_8x96) { - csiphy_res = csiphy_res_8x96; - csid_res = csid_res_8x96; - ispif_res = &ispif_res_8x96; - vfe_res = vfe_res_8x96; - } else if (camss->version == CAMSS_660) { - csiphy_res = csiphy_res_660; - csid_res = csid_res_660; - ispif_res = &ispif_res_660; - vfe_res = vfe_res_660; - } else if (camss->version == CAMSS_845) { - csiphy_res = csiphy_res_845; - csid_res = csid_res_845; - /* Titan VFEs don't have an ISPIF */ - ispif_res = NULL; - vfe_res = vfe_res_845; - } else { - return -EINVAL; - } - - for (i = 0; i < camss->csiphy_num; i++) { + for (i = 0; i < camss->res->csiphy_num; i++) { ret = msm_csiphy_subdev_init(camss, &camss->csiphy[i], - &csiphy_res[i], i); + &res->csiphy_res[i], + res->csiphy_res[i].csiphy.id); if (ret < 0) { dev_err(camss->dev, "Failed to init csiphy%d sub-device: %d\n", @@ -960,9 +4145,31 @@ static int camss_init_subdevices(struct camss *camss) } } - for (i = 0; i < camss->csid_num; i++) { + /* note: SM8250 requires VFE to be initialized before CSID */ + for (i = 0; i < camss->res->vfe_num; i++) { + ret = msm_vfe_subdev_init(camss, &camss->vfe[i], + &res->vfe_res[i], i); + if (ret < 0) { + dev_err(camss->dev, + "Fail to init vfe%d sub-device: %d\n", i, ret); + return ret; + } + } + + /* Get optional CSID wrapper regs shared between CSID devices */ + if (res->csid_wrapper_res) { + char *reg = res->csid_wrapper_res->reg; + void __iomem *base; + + base = devm_platform_ioremap_resource_byname(pdev, reg); + if (IS_ERR(base)) + return PTR_ERR(base); + camss->csid_wrapper_base = base; + } + + for (i = 0; i < camss->res->csid_num; i++) { ret = msm_csid_subdev_init(camss, &camss->csid[i], - &csid_res[i], i); + &res->csid_res[i], i); if (ret < 0) { dev_err(camss->dev, "Failed to init csid%d sub-device: %d\n", @@ -971,26 +4178,143 @@ static int camss_init_subdevices(struct camss *camss) } } - ret = msm_ispif_subdev_init(camss, ispif_res); + ret = msm_ispif_subdev_init(camss, res->ispif_res); if (ret < 0) { dev_err(camss->dev, "Failed to init ispif sub-device: %d\n", ret); return ret; } - for (i = 0; i < camss->vfe_num; i++) { - ret = msm_vfe_subdev_init(camss, &camss->vfe[i], - &vfe_res[i], i); - if (ret < 0) { - dev_err(camss->dev, - "Fail to init vfe%d sub-device: %d\n", i, ret); - return ret; + return 0; +} + +/* + * camss_link_err - print error in case link creation fails + * @src_name: name for source of the link + * @sink_name: name for sink of the link + */ +inline void camss_link_err(struct camss *camss, + const char *src_name, + const char *sink_name, + int ret) +{ + dev_err(camss->dev, + "Failed to link %s->%s entities: %d\n", + src_name, + sink_name, + ret); +} + +/* + * camss_link_entities - Register subdev nodes and create links + * @camss: CAMSS device + * + * Return 0 on success or a negative error code on failure + */ +static int camss_link_entities(struct camss *camss) +{ + int i, j, k; + int ret; + + for (i = 0; i < camss->res->csiphy_num; i++) { + for (j = 0; j < camss->res->csid_num; j++) { + ret = media_create_pad_link(&camss->csiphy[i].subdev.entity, + MSM_CSIPHY_PAD_SRC, + &camss->csid[j].subdev.entity, + MSM_CSID_PAD_SINK, + 0); + if (ret < 0) { + camss_link_err(camss, + camss->csiphy[i].subdev.entity.name, + camss->csid[j].subdev.entity.name, + ret); + return ret; + } } } + if (camss->ispif) { + for (i = 0; i < camss->res->csid_num; i++) { + for (j = 0; j < camss->ispif->line_num; j++) { + ret = media_create_pad_link(&camss->csid[i].subdev.entity, + MSM_CSID_PAD_SRC, + &camss->ispif->line[j].subdev.entity, + MSM_ISPIF_PAD_SINK, + 0); + if (ret < 0) { + camss_link_err(camss, + camss->csid[i].subdev.entity.name, + camss->ispif->line[j].subdev.entity.name, + ret); + return ret; + } + } + } + + for (i = 0; i < camss->ispif->line_num; i++) + for (k = 0; k < camss->res->vfe_num; k++) + for (j = 0; j < camss->vfe[k].res->line_num; j++) { + struct v4l2_subdev *ispif = &camss->ispif->line[i].subdev; + struct v4l2_subdev *vfe = &camss->vfe[k].line[j].subdev; + + ret = media_create_pad_link(&ispif->entity, + MSM_ISPIF_PAD_SRC, + &vfe->entity, + MSM_VFE_PAD_SINK, + 0); + if (ret < 0) { + camss_link_err(camss, ispif->entity.name, + vfe->entity.name, + ret); + return ret; + } + } + } else { + for (i = 0; i < camss->res->csid_num; i++) + for (k = 0; k < camss->res->vfe_num; k++) + for (j = 0; j < camss->vfe[k].res->line_num; j++) { + struct v4l2_subdev *csid = &camss->csid[i].subdev; + struct v4l2_subdev *vfe = &camss->vfe[k].line[j].subdev; + + ret = media_create_pad_link(&csid->entity, + MSM_CSID_PAD_FIRST_SRC + j, + &vfe->entity, + MSM_VFE_PAD_SINK, + 0); + if (ret < 0) { + camss_link_err(camss, csid->entity.name, + vfe->entity.name, + ret); + return ret; + } + } + } + return 0; } +void camss_reg_update(struct camss *camss, int hw_id, int port_id, bool is_clear) +{ + struct csid_device *csid; + + if (hw_id < camss->res->csid_num) { + csid = &camss->csid[hw_id]; + + csid->res->hw_ops->reg_update(csid, port_id, is_clear); + } +} + +void camss_buf_done(struct camss *camss, int hw_id, int port_id) +{ + struct vfe_device *vfe; + + if (hw_id < camss->res->vfe_num) { + vfe = &camss->vfe[hw_id]; + + vfe->res->hw_ops->vfe_buf_done(vfe, port_id); + } +} + /* * camss_register_entities - Register subdev nodes and create links * @camss: CAMSS device @@ -999,10 +4323,10 @@ static int camss_init_subdevices(struct camss *camss) */ static int camss_register_entities(struct camss *camss) { - int i, j, k; + int i; int ret; - for (i = 0; i < camss->csiphy_num; i++) { + for (i = 0; i < camss->res->csiphy_num; i++) { ret = msm_csiphy_register_entity(&camss->csiphy[i], &camss->v4l2_dev); if (ret < 0) { @@ -1013,7 +4337,7 @@ static int camss_register_entities(struct camss *camss) } } - for (i = 0; i < camss->csid_num; i++) { + for (i = 0; i < camss->res->csid_num; i++) { ret = msm_csid_register_entity(&camss->csid[i], &camss->v4l2_dev); if (ret < 0) { @@ -1027,12 +4351,11 @@ static int camss_register_entities(struct camss *camss) ret = msm_ispif_register_entities(camss->ispif, &camss->v4l2_dev); if (ret < 0) { - dev_err(camss->dev, "Failed to register ispif entities: %d\n", - ret); + dev_err(camss->dev, "Failed to register ispif entities: %d\n", ret); goto err_reg_ispif; } - for (i = 0; i < camss->vfe_num; i++) { + for (i = 0; i < camss->res->vfe_num; i++) { ret = msm_vfe_register_entities(&camss->vfe[i], &camss->v4l2_dev); if (ret < 0) { @@ -1043,92 +4366,8 @@ static int camss_register_entities(struct camss *camss) } } - for (i = 0; i < camss->csiphy_num; i++) { - for (j = 0; j < camss->csid_num; j++) { - ret = media_create_pad_link( - &camss->csiphy[i].subdev.entity, - MSM_CSIPHY_PAD_SRC, - &camss->csid[j].subdev.entity, - MSM_CSID_PAD_SINK, - 0); - if (ret < 0) { - dev_err(camss->dev, - "Failed to link %s->%s entities: %d\n", - camss->csiphy[i].subdev.entity.name, - camss->csid[j].subdev.entity.name, - ret); - goto err_link; - } - } - } - - if (camss->ispif) { - for (i = 0; i < camss->csid_num; i++) { - for (j = 0; j < camss->ispif->line_num; j++) { - ret = media_create_pad_link( - &camss->csid[i].subdev.entity, - MSM_CSID_PAD_SRC, - &camss->ispif->line[j].subdev.entity, - MSM_ISPIF_PAD_SINK, - 0); - if (ret < 0) { - dev_err(camss->dev, - "Failed to link %s->%s entities: %d\n", - camss->csid[i].subdev.entity.name, - camss->ispif->line[j].subdev.entity.name, - ret); - goto err_link; - } - } - } - - for (i = 0; i < camss->ispif->line_num; i++) - for (k = 0; k < camss->vfe_num; k++) - for (j = 0; j < camss->vfe[k].line_num; j++) { - struct v4l2_subdev *ispif = &camss->ispif->line[i].subdev; - struct v4l2_subdev *vfe = &camss->vfe[k].line[j].subdev; - - ret = media_create_pad_link(&ispif->entity, - MSM_ISPIF_PAD_SRC, - &vfe->entity, - MSM_VFE_PAD_SINK, - 0); - if (ret < 0) { - dev_err(camss->dev, - "Failed to link %s->%s entities: %d\n", - ispif->entity.name, - vfe->entity.name, - ret); - goto err_link; - } - } - } else { - for (i = 0; i < camss->csid_num; i++) - for (k = 0; k < camss->vfe_num; k++) - for (j = 0; j < camss->vfe[k].line_num; j++) { - struct v4l2_subdev *csid = &camss->csid[i].subdev; - struct v4l2_subdev *vfe = &camss->vfe[k].line[j].subdev; - - ret = media_create_pad_link(&csid->entity, - MSM_CSID_PAD_SRC, - &vfe->entity, - MSM_VFE_PAD_SINK, - 0); - if (ret < 0) { - dev_err(camss->dev, - "Failed to link %s->%s entities: %d\n", - csid->entity.name, - vfe->entity.name, - ret); - goto err_link; - } - } - } - return 0; -err_link: - i = camss->vfe_num; err_reg_vfe: for (i--; i >= 0; i--) msm_vfe_unregister_entities(&camss->vfe[i]); @@ -1136,12 +4375,12 @@ err_reg_vfe: err_reg_ispif: msm_ispif_unregister_entities(camss->ispif); - i = camss->csid_num; + i = camss->res->csid_num; err_reg_csid: for (i--; i >= 0; i--) msm_csid_unregister_entity(&camss->csid[i]); - i = camss->csiphy_num; + i = camss->res->csiphy_num; err_reg_csiphy: for (i--; i >= 0; i--) msm_csiphy_unregister_entity(&camss->csiphy[i]); @@ -1159,21 +4398,21 @@ static void camss_unregister_entities(struct camss *camss) { unsigned int i; - for (i = 0; i < camss->csiphy_num; i++) + for (i = 0; i < camss->res->csiphy_num; i++) msm_csiphy_unregister_entity(&camss->csiphy[i]); - for (i = 0; i < camss->csid_num; i++) + for (i = 0; i < camss->res->csid_num; i++) msm_csid_unregister_entity(&camss->csid[i]); msm_ispif_unregister_entities(camss->ispif); - for (i = 0; i < camss->vfe_num; i++) + for (i = 0; i < camss->res->vfe_num; i++) msm_vfe_unregister_entities(&camss->vfe[i]); } static int camss_subdev_notifier_bound(struct v4l2_async_notifier *async, struct v4l2_subdev *subdev, - struct v4l2_async_subdev *asd) + struct v4l2_async_connection *asd) { struct camss *camss = container_of(async, struct camss, notifier); struct camss_async_subdev *csd = @@ -1192,43 +4431,39 @@ static int camss_subdev_notifier_complete(struct v4l2_async_notifier *async) struct camss *camss = container_of(async, struct camss, notifier); struct v4l2_device *v4l2_dev = &camss->v4l2_dev; struct v4l2_subdev *sd; - int ret; list_for_each_entry(sd, &v4l2_dev->subdevs, list) { - if (sd->host_priv) { - struct media_entity *sensor = &sd->entity; - struct csiphy_device *csiphy = - (struct csiphy_device *) sd->host_priv; - struct media_entity *input = &csiphy->subdev.entity; - unsigned int i; - - for (i = 0; i < sensor->num_pads; i++) { - if (sensor->pads[i].flags & MEDIA_PAD_FL_SOURCE) - break; - } - if (i == sensor->num_pads) { - dev_err(camss->dev, - "No source pad in external entity\n"); - return -EINVAL; - } + struct csiphy_device *csiphy = sd->host_priv; + struct media_entity *input, *sensor; + unsigned int i; + int ret; - ret = media_create_pad_link(sensor, i, - input, MSM_CSIPHY_PAD_SINK, - MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED); - if (ret < 0) { - dev_err(camss->dev, - "Failed to link %s->%s entities: %d\n", - sensor->name, input->name, ret); - return ret; - } + if (!csiphy) + continue; + + input = &csiphy->subdev.entity; + sensor = &sd->entity; + + for (i = 0; i < sensor->num_pads; i++) { + if (sensor->pads[i].flags & MEDIA_PAD_FL_SOURCE) + break; + } + if (i == sensor->num_pads) { + dev_err(camss->dev, + "No source pad in external entity\n"); + return -EINVAL; } - } - ret = v4l2_device_register_subdev_nodes(&camss->v4l2_dev); - if (ret < 0) - return ret; + ret = media_create_pad_link(sensor, i, input, + MSM_CSIPHY_PAD_SINK, + MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED); + if (ret < 0) { + camss_link_err(camss, sensor->name, input->name, ret); + return ret; + } + } - return media_device_register(&camss->media_dev); + return v4l2_device_register_subdev_nodes(&camss->v4l2_dev); } static const struct v4l2_async_notifier_operations camss_subdev_notifier_ops = { @@ -1242,47 +4477,121 @@ static const struct media_device_ops camss_media_ops = { static int camss_configure_pd(struct camss *camss) { - int nbr_pm_domains = 0; - int last_pm_domain = 0; + const struct camss_resources *res = camss->res; + struct device *dev = camss->dev; + int vfepd_num; int i; int ret; - if (camss->version == CAMSS_8x96 || - camss->version == CAMSS_660) - nbr_pm_domains = PM_DOMAIN_GEN1_COUNT; - else if (camss->version == CAMSS_845) - nbr_pm_domains = PM_DOMAIN_GEN2_COUNT; + camss->genpd_num = of_count_phandle_with_args(dev->of_node, + "power-domains", + "#power-domain-cells"); + if (camss->genpd_num < 0) { + dev_err(dev, "Power domains are not defined for camss\n"); + return camss->genpd_num; + } - for (i = 0; i < nbr_pm_domains; i++) { - camss->genpd[i] = dev_pm_domain_attach_by_id(camss->dev, i); - if (IS_ERR(camss->genpd[i])) { - ret = PTR_ERR(camss->genpd[i]); - goto fail_pm; - } + /* + * If a platform device has just one power domain, then it is attached + * at platform_probe() level, thus there shall be no need and even no + * option to attach it again, this is the case for CAMSS on MSM8916. + */ + if (camss->genpd_num == 1) + return 0; + + /* count the # of VFEs which have flagged power-domain */ + for (vfepd_num = i = 0; i < camss->res->vfe_num; i++) { + if (res->vfe_res[i].vfe.has_pd) + vfepd_num++; + } - camss->genpd_link[i] = device_link_add(camss->dev, camss->genpd[i], - DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME | - DL_FLAG_RPM_ACTIVE); - if (!camss->genpd_link[i]) { - dev_pm_domain_detach(camss->genpd[i], true); - ret = -EINVAL; - goto fail_pm; - } + /* + * If the number of power-domains is greater than the number of VFEs + * then the additional power-domain is for the entire CAMSS block. + */ + if (!(camss->genpd_num > vfepd_num)) + return 0; + + /* + * If a power-domain name is defined try to use it. + * It is possible we are running a new kernel with an old dtb so + * fallback to indexes even if a pd_name is defined but not found. + */ + if (camss->res->pd_name) { + camss->genpd = dev_pm_domain_attach_by_name(camss->dev, + camss->res->pd_name); + if (IS_ERR(camss->genpd)) + return PTR_ERR(camss->genpd); + } - last_pm_domain = i; + if (!camss->genpd) { + /* + * Legacy magic index. TITAN_TOP GDSC must be the last + * item in the power-domain list. + */ + camss->genpd = dev_pm_domain_attach_by_id(camss->dev, + camss->genpd_num - 1); + if (IS_ERR(camss->genpd)) + return PTR_ERR(camss->genpd); + } + + if (!camss->genpd) + return -ENODEV; + + camss->genpd_link = device_link_add(camss->dev, camss->genpd, + DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME | + DL_FLAG_RPM_ACTIVE); + if (!camss->genpd_link) { + ret = -EINVAL; + goto fail_pm; } return 0; fail_pm: - for (i = 0; i < last_pm_domain; i++) { - device_link_del(camss->genpd_link[i]); - dev_pm_domain_detach(camss->genpd[i], true); - } + dev_pm_domain_detach(camss->genpd, true); return ret; } +static int camss_icc_get(struct camss *camss) +{ + const struct resources_icc *icc_res; + int i; + + icc_res = camss->res->icc_res; + + for (i = 0; i < camss->res->icc_path_num; i++) { + camss->icc_path[i] = devm_of_icc_get(camss->dev, + icc_res[i].name); + if (IS_ERR(camss->icc_path[i])) + return PTR_ERR(camss->icc_path[i]); + } + + return 0; +} + +static void camss_genpd_subdevice_cleanup(struct camss *camss) +{ + int i; + + for (i = 0; i < camss->res->vfe_num; i++) + msm_vfe_genpd_cleanup(&camss->vfe[i]); +} + +static void camss_genpd_cleanup(struct camss *camss) +{ + if (camss->genpd_num == 1) + return; + + camss_genpd_subdevice_cleanup(camss); + + if (camss->genpd_link) + device_link_del(camss->genpd_link); + + dev_pm_domain_detach(camss->genpd, true); +} + /* * camss_probe - Probe CAMSS platform device * @pdev: Pointer to CAMSS platform device @@ -1293,89 +4602,59 @@ static int camss_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct camss *camss; - int num_subdevs, ret; + int ret; - camss = kzalloc(sizeof(*camss), GFP_KERNEL); + camss = devm_kzalloc(dev, sizeof(*camss), GFP_KERNEL); if (!camss) return -ENOMEM; + camss->res = of_device_get_match_data(dev); + atomic_set(&camss->ref_count, 0); camss->dev = dev; platform_set_drvdata(pdev, camss); - if (of_device_is_compatible(dev->of_node, "qcom,msm8916-camss")) { - camss->version = CAMSS_8x16; - camss->csiphy_num = 2; - camss->csid_num = 2; - camss->vfe_num = 1; - } else if (of_device_is_compatible(dev->of_node, - "qcom,msm8996-camss")) { - camss->version = CAMSS_8x96; - camss->csiphy_num = 3; - camss->csid_num = 4; - camss->vfe_num = 2; - } else if (of_device_is_compatible(dev->of_node, - "qcom,sdm660-camss")) { - camss->version = CAMSS_660; - camss->csiphy_num = 3; - camss->csid_num = 4; - camss->vfe_num = 2; - } else if (of_device_is_compatible(dev->of_node, - "qcom,sdm845-camss")) { - camss->version = CAMSS_845; - camss->csiphy_num = 4; - camss->csid_num = 3; - camss->vfe_num = 3; - } else { - ret = -EINVAL; - goto err_free; - } - - camss->csiphy = devm_kcalloc(dev, camss->csiphy_num, + camss->csiphy = devm_kcalloc(dev, camss->res->csiphy_num, sizeof(*camss->csiphy), GFP_KERNEL); - if (!camss->csiphy) { - ret = -ENOMEM; - goto err_free; - } + if (!camss->csiphy) + return -ENOMEM; - camss->csid = devm_kcalloc(dev, camss->csid_num, sizeof(*camss->csid), + camss->csid = devm_kcalloc(dev, camss->res->csid_num, sizeof(*camss->csid), GFP_KERNEL); - if (!camss->csid) { - ret = -ENOMEM; - goto err_free; - } + if (!camss->csid) + return -ENOMEM; - if (camss->version == CAMSS_8x16 || - camss->version == CAMSS_8x96) { + if (camss->res->version == CAMSS_8x16 || + camss->res->version == CAMSS_8x39 || + camss->res->version == CAMSS_8x53 || + camss->res->version == CAMSS_8x96) { camss->ispif = devm_kcalloc(dev, 1, sizeof(*camss->ispif), GFP_KERNEL); - if (!camss->ispif) { - ret = -ENOMEM; - goto err_free; - } + if (!camss->ispif) + return -ENOMEM; } - camss->vfe = devm_kcalloc(dev, camss->vfe_num, sizeof(*camss->vfe), - GFP_KERNEL); - if (!camss->vfe) { - ret = -ENOMEM; - goto err_free; - } + camss->vfe = devm_kcalloc(dev, camss->res->vfe_num, + sizeof(*camss->vfe), GFP_KERNEL); + if (!camss->vfe) + return -ENOMEM; - v4l2_async_notifier_init(&camss->notifier); + ret = camss_icc_get(camss); + if (ret < 0) + return ret; - num_subdevs = camss_of_parse_ports(camss); - if (num_subdevs < 0) { - ret = num_subdevs; - goto err_cleanup; + ret = camss_configure_pd(camss); + if (ret < 0) { + dev_err(dev, "Failed to configure power domains: %d\n", ret); + return ret; } ret = camss_init_subdevices(camss); if (ret < 0) - goto err_cleanup; + goto err_genpd_cleanup; ret = dma_set_mask_and_coherent(dev, 0xffffffff); if (ret) - goto err_cleanup; + goto err_genpd_cleanup; camss->media_dev.dev = camss->dev; strscpy(camss->media_dev.model, "Qualcomm Camera Subsystem", @@ -1387,85 +4666,64 @@ static int camss_probe(struct platform_device *pdev) ret = v4l2_device_register(camss->dev, &camss->v4l2_dev); if (ret < 0) { dev_err(dev, "Failed to register V4L2 device: %d\n", ret); - goto err_cleanup; + goto err_media_device_cleanup; } - ret = camss_register_entities(camss); - if (ret < 0) - goto err_register_entities; + v4l2_async_nf_init(&camss->notifier, &camss->v4l2_dev); - if (num_subdevs) { - camss->notifier.ops = &camss_subdev_notifier_ops; + pm_runtime_enable(dev); - ret = v4l2_async_notifier_register(&camss->v4l2_dev, - &camss->notifier); - if (ret) { - dev_err(dev, - "Failed to register async subdev nodes: %d\n", - ret); - goto err_register_subdevs; - } - } else { - ret = v4l2_device_register_subdev_nodes(&camss->v4l2_dev); - if (ret < 0) { - dev_err(dev, "Failed to register subdev nodes: %d\n", - ret); - goto err_register_subdevs; - } + ret = camss_of_parse_ports(camss); + if (ret < 0) + goto err_v4l2_device_unregister; - ret = media_device_register(&camss->media_dev); - if (ret < 0) { - dev_err(dev, "Failed to register media device: %d\n", - ret); - goto err_register_subdevs; - } - } + ret = camss_register_entities(camss); + if (ret < 0) + goto err_v4l2_device_unregister; - ret = camss_configure_pd(camss); + ret = camss_link_entities(camss); + if (ret < 0) + goto err_register_subdevs; + + ret = media_device_register(&camss->media_dev); if (ret < 0) { - dev_err(dev, "Failed to configure power domains: %d\n", ret); - return ret; + dev_err(dev, "Failed to register media device: %d\n", ret); + goto err_register_subdevs; } - pm_runtime_enable(dev); + camss->notifier.ops = &camss_subdev_notifier_ops; + ret = v4l2_async_nf_register(&camss->notifier); + if (ret) { + dev_err(dev, + "Failed to register async subdev nodes: %d\n", ret); + goto err_media_device_unregister; + } return 0; +err_media_device_unregister: + media_device_unregister(&camss->media_dev); err_register_subdevs: camss_unregister_entities(camss); -err_register_entities: +err_v4l2_device_unregister: v4l2_device_unregister(&camss->v4l2_dev); -err_cleanup: - v4l2_async_notifier_cleanup(&camss->notifier); -err_free: - kfree(camss); + v4l2_async_nf_cleanup(&camss->notifier); + pm_runtime_disable(dev); +err_media_device_cleanup: + media_device_cleanup(&camss->media_dev); +err_genpd_cleanup: + camss_genpd_cleanup(camss); return ret; } void camss_delete(struct camss *camss) { - int nbr_pm_domains = 0; - int i; - v4l2_device_unregister(&camss->v4l2_dev); media_device_unregister(&camss->media_dev); media_device_cleanup(&camss->media_dev); pm_runtime_disable(camss->dev); - - if (camss->version == CAMSS_8x96 || - camss->version == CAMSS_660) - nbr_pm_domains = PM_DOMAIN_GEN1_COUNT; - else if (camss->version == CAMSS_845) - nbr_pm_domains = PM_DOMAIN_GEN2_COUNT; - - for (i = 0; i < nbr_pm_domains; i++) { - device_link_del(camss->genpd_link[i]); - dev_pm_domain_detach(camss->genpd[i], true); - } - - kfree(camss); } /* @@ -1474,25 +4732,237 @@ void camss_delete(struct camss *camss) * * Always returns 0. */ -static int camss_remove(struct platform_device *pdev) +static void camss_remove(struct platform_device *pdev) { struct camss *camss = platform_get_drvdata(pdev); - v4l2_async_notifier_unregister(&camss->notifier); - v4l2_async_notifier_cleanup(&camss->notifier); + v4l2_async_nf_unregister(&camss->notifier); + v4l2_async_nf_cleanup(&camss->notifier); camss_unregister_entities(camss); if (atomic_read(&camss->ref_count) == 0) camss_delete(camss); - return 0; + camss_genpd_cleanup(camss); } +static const struct camss_resources msm8916_resources = { + .version = CAMSS_8x16, + .csiphy_res = csiphy_res_8x16, + .csid_res = csid_res_8x16, + .ispif_res = &ispif_res_8x16, + .vfe_res = vfe_res_8x16, + .csiphy_num = ARRAY_SIZE(csiphy_res_8x16), + .csid_num = ARRAY_SIZE(csid_res_8x16), + .vfe_num = ARRAY_SIZE(vfe_res_8x16), +}; + +static const struct camss_resources msm8939_resources = { + .version = CAMSS_8x39, + .csiphy_res = csiphy_res_8x39, + .csid_res = csid_res_8x39, + .ispif_res = &ispif_res_8x39, + .vfe_res = vfe_res_8x39, + .csiphy_num = ARRAY_SIZE(csiphy_res_8x39), + .csid_num = ARRAY_SIZE(csid_res_8x39), + .vfe_num = ARRAY_SIZE(vfe_res_8x39), +}; + +static const struct camss_resources msm8953_resources = { + .version = CAMSS_8x53, + .icc_res = icc_res_8x53, + .icc_path_num = ARRAY_SIZE(icc_res_8x53), + .csiphy_res = csiphy_res_8x96, + .csid_res = csid_res_8x53, + .ispif_res = &ispif_res_8x53, + .vfe_res = vfe_res_8x53, + .csiphy_num = ARRAY_SIZE(csiphy_res_8x96), + .csid_num = ARRAY_SIZE(csid_res_8x53), + .vfe_num = ARRAY_SIZE(vfe_res_8x53), +}; + +static const struct camss_resources msm8996_resources = { + .version = CAMSS_8x96, + .csiphy_res = csiphy_res_8x96, + .csid_res = csid_res_8x96, + .ispif_res = &ispif_res_8x96, + .vfe_res = vfe_res_8x96, + .csiphy_num = ARRAY_SIZE(csiphy_res_8x96), + .csid_num = ARRAY_SIZE(csid_res_8x96), + .vfe_num = ARRAY_SIZE(vfe_res_8x96), +}; + +static const struct camss_resources qcm2290_resources = { + .version = CAMSS_2290, + .csiphy_res = csiphy_res_2290, + .csid_res = csid_res_2290, + .vfe_res = vfe_res_2290, + .icc_res = icc_res_2290, + .icc_path_num = ARRAY_SIZE(icc_res_2290), + .csiphy_num = ARRAY_SIZE(csiphy_res_2290), + .csid_num = ARRAY_SIZE(csid_res_2290), + .vfe_num = ARRAY_SIZE(vfe_res_2290), +}; + +static const struct camss_resources qcs8300_resources = { + .version = CAMSS_8300, + .pd_name = "top", + .csiphy_res = csiphy_res_8300, + .csid_res = csid_res_8775p, + .csid_wrapper_res = &csid_wrapper_res_sm8550, + .vfe_res = vfe_res_8775p, + .icc_res = icc_res_qcs8300, + .csiphy_num = ARRAY_SIZE(csiphy_res_8300), + .csid_num = ARRAY_SIZE(csid_res_8775p), + .vfe_num = ARRAY_SIZE(vfe_res_8775p), + .icc_path_num = ARRAY_SIZE(icc_res_qcs8300), +}; + +static const struct camss_resources sa8775p_resources = { + .version = CAMSS_8775P, + .pd_name = "top", + .csiphy_res = csiphy_res_8775p, + .csid_res = csid_res_8775p, + .csid_wrapper_res = &csid_wrapper_res_sm8550, + .vfe_res = vfe_res_8775p, + .icc_res = icc_res_sa8775p, + .csiphy_num = ARRAY_SIZE(csiphy_res_8775p), + .csid_num = ARRAY_SIZE(csid_res_8775p), + .vfe_num = ARRAY_SIZE(vfe_res_8775p), + .icc_path_num = ARRAY_SIZE(icc_res_sa8775p), +}; + +static const struct camss_resources sdm660_resources = { + .version = CAMSS_660, + .csiphy_res = csiphy_res_660, + .csid_res = csid_res_660, + .ispif_res = &ispif_res_660, + .vfe_res = vfe_res_660, + .csiphy_num = ARRAY_SIZE(csiphy_res_660), + .csid_num = ARRAY_SIZE(csid_res_660), + .vfe_num = ARRAY_SIZE(vfe_res_660), +}; + +static const struct camss_resources sdm670_resources = { + .version = CAMSS_845, + .csiphy_res = csiphy_res_670, + .csid_res = csid_res_670, + .vfe_res = vfe_res_670, + .csiphy_num = ARRAY_SIZE(csiphy_res_670), + .csid_num = ARRAY_SIZE(csid_res_670), + .vfe_num = ARRAY_SIZE(vfe_res_670), +}; + +static const struct camss_resources sdm845_resources = { + .version = CAMSS_845, + .pd_name = "top", + .csiphy_res = csiphy_res_845, + .csid_res = csid_res_845, + .vfe_res = vfe_res_845, + .csiphy_num = ARRAY_SIZE(csiphy_res_845), + .csid_num = ARRAY_SIZE(csid_res_845), + .vfe_num = ARRAY_SIZE(vfe_res_845), +}; + +static const struct camss_resources sm8250_resources = { + .version = CAMSS_8250, + .pd_name = "top", + .csiphy_res = csiphy_res_8250, + .csid_res = csid_res_8250, + .vfe_res = vfe_res_8250, + .icc_res = icc_res_sm8250, + .icc_path_num = ARRAY_SIZE(icc_res_sm8250), + .csiphy_num = ARRAY_SIZE(csiphy_res_8250), + .csid_num = ARRAY_SIZE(csid_res_8250), + .vfe_num = ARRAY_SIZE(vfe_res_8250), +}; + +static const struct camss_resources sc8280xp_resources = { + .version = CAMSS_8280XP, + .pd_name = "top", + .csiphy_res = csiphy_res_sc8280xp, + .csid_res = csid_res_sc8280xp, + .ispif_res = NULL, + .vfe_res = vfe_res_sc8280xp, + .icc_res = icc_res_sc8280xp, + .icc_path_num = ARRAY_SIZE(icc_res_sc8280xp), + .csiphy_num = ARRAY_SIZE(csiphy_res_sc8280xp), + .csid_num = ARRAY_SIZE(csid_res_sc8280xp), + .vfe_num = ARRAY_SIZE(vfe_res_sc8280xp), +}; + +static const struct camss_resources sc7280_resources = { + .version = CAMSS_7280, + .pd_name = "top", + .csiphy_res = csiphy_res_7280, + .csid_res = csid_res_7280, + .vfe_res = vfe_res_7280, + .icc_res = icc_res_sc7280, + .icc_path_num = ARRAY_SIZE(icc_res_sc7280), + .csiphy_num = ARRAY_SIZE(csiphy_res_7280), + .csid_num = ARRAY_SIZE(csid_res_7280), + .vfe_num = ARRAY_SIZE(vfe_res_7280), +}; + +static const struct camss_resources sm8550_resources = { + .version = CAMSS_8550, + .pd_name = "top", + .csiphy_res = csiphy_res_8550, + .csid_res = csid_res_8550, + .vfe_res = vfe_res_8550, + .csid_wrapper_res = &csid_wrapper_res_sm8550, + .icc_res = icc_res_sm8550, + .icc_path_num = ARRAY_SIZE(icc_res_sm8550), + .csiphy_num = ARRAY_SIZE(csiphy_res_8550), + .csid_num = ARRAY_SIZE(csid_res_8550), + .vfe_num = ARRAY_SIZE(vfe_res_8550), +}; + +static const struct camss_resources sm8650_resources = { + .version = CAMSS_8650, + .pd_name = "top", + .csiphy_res = csiphy_res_sm8650, + .csid_res = csid_res_sm8650, + .csid_wrapper_res = &csid_wrapper_res_sm8550, + .vfe_res = vfe_res_sm8650, + .icc_res = icc_res_sm8650, + .icc_path_num = ARRAY_SIZE(icc_res_sm8650), + .csiphy_num = ARRAY_SIZE(csiphy_res_sm8650), + .csid_num = ARRAY_SIZE(csid_res_sm8650), + .vfe_num = ARRAY_SIZE(vfe_res_sm8650), +}; + +static const struct camss_resources x1e80100_resources = { + .version = CAMSS_X1E80100, + .pd_name = "top", + .csiphy_res = csiphy_res_x1e80100, + .csid_res = csid_res_x1e80100, + .vfe_res = vfe_res_x1e80100, + .csid_wrapper_res = &csid_wrapper_res_x1e80100, + .icc_res = icc_res_x1e80100, + .icc_path_num = ARRAY_SIZE(icc_res_x1e80100), + .csiphy_num = ARRAY_SIZE(csiphy_res_x1e80100), + .csid_num = ARRAY_SIZE(csid_res_x1e80100), + .vfe_num = ARRAY_SIZE(vfe_res_x1e80100), +}; + static const struct of_device_id camss_dt_match[] = { - { .compatible = "qcom,msm8916-camss" }, - { .compatible = "qcom,msm8996-camss" }, - { .compatible = "qcom,sdm660-camss" }, - { .compatible = "qcom,sdm845-camss" }, + { .compatible = "qcom,msm8916-camss", .data = &msm8916_resources }, + { .compatible = "qcom,msm8939-camss", .data = &msm8939_resources }, + { .compatible = "qcom,msm8953-camss", .data = &msm8953_resources }, + { .compatible = "qcom,msm8996-camss", .data = &msm8996_resources }, + { .compatible = "qcom,qcm2290-camss", .data = &qcm2290_resources }, + { .compatible = "qcom,qcs8300-camss", .data = &qcs8300_resources }, + { .compatible = "qcom,sa8775p-camss", .data = &sa8775p_resources }, + { .compatible = "qcom,sc7280-camss", .data = &sc7280_resources }, + { .compatible = "qcom,sc8280xp-camss", .data = &sc8280xp_resources }, + { .compatible = "qcom,sdm660-camss", .data = &sdm660_resources }, + { .compatible = "qcom,sdm670-camss", .data = &sdm670_resources }, + { .compatible = "qcom,sdm845-camss", .data = &sdm845_resources }, + { .compatible = "qcom,sm8250-camss", .data = &sm8250_resources }, + { .compatible = "qcom,sm8550-camss", .data = &sm8550_resources }, + { .compatible = "qcom,sm8650-camss", .data = &sm8650_resources }, + { .compatible = "qcom,x1e80100-camss", .data = &x1e80100_resources }, { } }; @@ -1500,11 +4970,34 @@ MODULE_DEVICE_TABLE(of, camss_dt_match); static int __maybe_unused camss_runtime_suspend(struct device *dev) { + struct camss *camss = dev_get_drvdata(dev); + int i; + int ret; + + for (i = 0; i < camss->res->icc_path_num; i++) { + ret = icc_set_bw(camss->icc_path[i], 0, 0); + if (ret) + return ret; + } + return 0; } static int __maybe_unused camss_runtime_resume(struct device *dev) { + struct camss *camss = dev_get_drvdata(dev); + const struct resources_icc *icc_res = camss->res->icc_res; + int i; + int ret; + + for (i = 0; i < camss->res->icc_path_num; i++) { + ret = icc_set_bw(camss->icc_path[i], + icc_res[i].icc_bw_tbl.avg, + icc_res[i].icc_bw_tbl.peak); + if (ret) + return ret; + } + return 0; } @@ -1526,7 +5019,6 @@ static struct platform_driver qcom_camss_driver = { module_platform_driver(qcom_camss_driver); -MODULE_ALIAS("platform:qcom-camss"); MODULE_DESCRIPTION("Qualcomm Camera Subsystem driver"); MODULE_AUTHOR("Todor Tomov <todor.tomov@linaro.org>"); MODULE_LICENSE("GPL v2"); |
