From 6de4fa2ed806e919cd4aea103d1a758dbb3ddf0c Mon Sep 17 00:00:00 2001 From: Jigar Agrawal Date: Mon, 8 Jun 2020 14:15:12 -0700 Subject: [PATCH] msm: camera: ife: Add support to provide IFE count in Query caps IFE Query cap currently gives only IFE Full Information. Update the code to return IFE Full, IFE lite, full IFE-CSID and IFE-CSID lite information in return of the IFE Query cap command. CRs-Fixed: 2647995 Change-Id: I84cf5b766ce191aacad4a1de478c6eebafe917b3 Signed-off-by: Jigar Agrawal --- drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c | 104 ++++++++++++++++-- .../isp_hw/ife_csid_hw/cam_ife_csid_core.c | 28 ++++- .../isp_hw/ife_csid_hw/cam_ife_csid_core.h | 2 + .../isp_hw/ife_csid_hw/cam_ife_csid_soc.c | 13 ++- .../isp_hw/ife_csid_hw/cam_ife_csid_soc.h | 4 +- .../isp_hw/include/cam_ife_csid_hw_intf.h | 3 +- .../isp_hw/include/cam_vfe_hw_intf.h | 17 +-- .../vfe_hw/vfe_top/cam_vfe_top_common.h | 1 + .../isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.c | 39 ++++++- .../isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver3.c | 38 ++++++- include/uapi/camera/media/cam_isp.h | 10 +- 11 files changed, 225 insertions(+), 34 deletions(-) diff --git a/drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c b/drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c index 17aa1ff4f2..dfe8a9ceaf 100644 --- a/drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c +++ b/drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c @@ -182,6 +182,11 @@ static int cam_ife_mgr_get_hw_caps(void *hw_mgr_priv, struct cam_ife_hw_mgr *hw_mgr = hw_mgr_priv; struct cam_query_cap_cmd *query = hw_caps_args; struct cam_isp_query_cap_cmd query_isp; + struct cam_isp_dev_cap_info *ife_full_hw_info = NULL; + struct cam_isp_dev_cap_info *ife_lite_hw_info = NULL; + struct cam_isp_dev_cap_info *csid_full_hw_info = NULL; + struct cam_isp_dev_cap_info *csid_lite_hw_info = NULL; + struct cam_ife_csid_hw_caps *ife_csid_caps = {0}; CAM_DBG(CAM_ISP, "enter"); @@ -196,13 +201,98 @@ static int cam_ife_mgr_get_hw_caps(void *hw_mgr_priv, query_isp.device_iommu.secure = hw_mgr->mgr_common.img_iommu_hdl_secure; query_isp.cdm_iommu.non_secure = hw_mgr->mgr_common.cmd_iommu_hdl; query_isp.cdm_iommu.secure = hw_mgr->mgr_common.cmd_iommu_hdl_secure; - query_isp.num_dev = 2; - for (i = 0; i < query_isp.num_dev; i++) { - query_isp.dev_caps[i].hw_type = CAM_ISP_HW_IFE; - query_isp.dev_caps[i].hw_version.major = 1; - query_isp.dev_caps[i].hw_version.minor = 7; - query_isp.dev_caps[i].hw_version.incr = 0; - query_isp.dev_caps[i].hw_version.reserved = 0; + query_isp.num_dev = 0; + + for (i = 0; i < CAM_IFE_HW_NUM_MAX; i++) { + if (!hw_mgr->ife_devices[i]) + continue; + + if (hw_mgr->ife_dev_caps[i].is_lite) { + if (ife_lite_hw_info == NULL) { + ife_lite_hw_info = + &query_isp.dev_caps[query_isp.num_dev]; + query_isp.num_dev++; + + ife_lite_hw_info->hw_type = CAM_ISP_HW_IFE_LITE; + ife_lite_hw_info->hw_version.major = + hw_mgr->ife_dev_caps[i].major; + ife_lite_hw_info->hw_version.minor = + hw_mgr->ife_dev_caps[i].minor; + ife_lite_hw_info->hw_version.incr = + hw_mgr->ife_dev_caps[i].incr; + ife_lite_hw_info->hw_version.reserved = 0; + ife_lite_hw_info->num_hw = 0; + } + + ife_lite_hw_info->num_hw++; + + } else { + if (ife_full_hw_info == NULL) { + ife_full_hw_info = + &query_isp.dev_caps[query_isp.num_dev]; + query_isp.num_dev++; + + ife_full_hw_info->hw_type = CAM_ISP_HW_IFE; + ife_full_hw_info->hw_version.major = + hw_mgr->ife_dev_caps[i].major; + ife_full_hw_info->hw_version.minor = + hw_mgr->ife_dev_caps[i].minor; + ife_full_hw_info->hw_version.incr = + hw_mgr->ife_dev_caps[i].incr; + ife_full_hw_info->hw_version.reserved = 0; + ife_full_hw_info->num_hw = 0; + } + + ife_full_hw_info->num_hw++; + } + } + + for (i = 0; i < CAM_IFE_CSID_HW_NUM_MAX; i++) { + if (!hw_mgr->csid_devices[i]) + continue; + + ife_csid_caps = (struct cam_ife_csid_hw_caps *) + &hw_mgr->ife_csid_dev_caps[i]; + + if (ife_csid_caps->is_lite) { + if (csid_lite_hw_info == NULL) { + csid_lite_hw_info = + &query_isp.dev_caps[query_isp.num_dev]; + query_isp.num_dev++; + + csid_lite_hw_info->hw_type = + CAM_ISP_HW_CSID_LITE; + csid_lite_hw_info->hw_version.major = + ife_csid_caps->major_version; + csid_lite_hw_info->hw_version.minor = + ife_csid_caps->minor_version; + csid_lite_hw_info->hw_version.incr = + ife_csid_caps->version_incr; + csid_lite_hw_info->hw_version.reserved = 0; + csid_lite_hw_info->num_hw = 0; + } + + csid_lite_hw_info->num_hw++; + + } else { + if (csid_full_hw_info == NULL) { + csid_full_hw_info = + &query_isp.dev_caps[query_isp.num_dev]; + query_isp.num_dev++; + + csid_full_hw_info->hw_type = CAM_ISP_HW_CSID; + csid_full_hw_info->hw_version.major = + ife_csid_caps->major_version; + csid_full_hw_info->hw_version.minor = + ife_csid_caps->minor_version; + csid_full_hw_info->hw_version.incr = + ife_csid_caps->version_incr; + csid_full_hw_info->hw_version.reserved = 0; + csid_full_hw_info->num_hw = 0; + } + + csid_full_hw_info->num_hw++; + } } if (copy_to_user(u64_to_user_ptr(query->caps_handle), diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c index 66803e4310..54b441424c 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c @@ -1223,7 +1223,7 @@ static int cam_ife_csid_enable_hw(struct cam_ife_csid_hw *csid_hw) int rc = 0; const struct cam_ife_csid_reg_offset *csid_reg; struct cam_hw_soc_info *soc_info; - uint32_t i, val; + uint32_t i; int clk_lvl; unsigned long flags; @@ -1305,10 +1305,12 @@ static int cam_ife_csid_enable_hw(struct cam_ife_csid_hw *csid_hw) spin_unlock_irqrestore(&csid_hw->hw_info->hw_lock, flags); - val = cam_io_r_mb(soc_info->reg_map[0].mem_base + + csid_hw->csid_info->hw_reg_version = + cam_io_r_mb(soc_info->reg_map[0].mem_base + csid_reg->cmn_reg->csid_hw_version_addr); CAM_DBG(CAM_ISP, "CSID:%d CSID HW version: 0x%x", - csid_hw->hw_intf->hw_idx, val); + csid_hw->hw_intf->hw_idx, + csid_hw->csid_info->hw_reg_version); spin_lock_irqsave(&csid_hw->lock_state, flags); csid_hw->device_enabled = 1; @@ -3102,6 +3104,7 @@ int cam_ife_csid_get_hw_caps(void *hw_priv, struct cam_ife_csid_hw *csid_hw; struct cam_hw_info *csid_hw_info; const struct cam_ife_csid_reg_offset *csid_reg; + struct cam_csid_soc_private *soc_priv = NULL; if (!hw_priv || !get_hw_cap_args) { CAM_ERR(CAM_ISP, "CSID: Invalid args"); @@ -3116,9 +3119,22 @@ int cam_ife_csid_get_hw_caps(void *hw_priv, hw_caps->num_rdis = csid_reg->cmn_reg->num_rdis; hw_caps->num_pix = csid_reg->cmn_reg->num_pix; hw_caps->num_ppp = csid_reg->cmn_reg->num_ppp; - hw_caps->major_version = csid_reg->cmn_reg->major_version; - hw_caps->minor_version = csid_reg->cmn_reg->minor_version; - hw_caps->version_incr = csid_reg->cmn_reg->version_incr; + + /* NOTE: HW version is not correct since we dont enable + * the soc resources in the probe for CSID, instead we + * when the camera actually runs + */ + hw_caps->version_incr = + csid_hw->csid_info->hw_reg_version & 0x00ffff; + hw_caps->minor_version = + (csid_hw->csid_info->hw_reg_version >> 16) & 0x0fff; + hw_caps->major_version = + (csid_hw->csid_info->hw_reg_version >> 28) & 0x000f; + + soc_priv = (struct cam_csid_soc_private *) + (csid_hw_info->soc_info.soc_private); + + hw_caps->is_lite = soc_priv->is_ife_csid_lite; CAM_DBG(CAM_ISP, "CSID:%d No rdis:%d, no pix:%d, major:%d minor:%d ver :%d", diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.h b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.h index f75b97224e..819e91bc0b 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.h +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.h @@ -402,12 +402,14 @@ struct cam_ife_csid_reg_offset { * * @csid_reg: csid register offsets * @hw_dts_version: HW DTS version + * @hw_reg_version: HW Version read from register * @csid_max_clk: maximim csid clock * */ struct cam_ife_csid_hw_info { const struct cam_ife_csid_reg_offset *csid_reg; uint32_t hw_dts_version; + uint32_t hw_reg_version; uint32_t csid_max_clk; }; diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_soc.c b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_soc.c index 7abcc64068..49c81fd303 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_soc.c +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_soc.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. */ #include #include "cam_ife_csid_soc.h" @@ -10,16 +10,23 @@ static int cam_ife_csid_get_dt_properties(struct cam_hw_soc_info *soc_info) { struct device_node *of_node = NULL; - struct csid_device_soc_info *csid_soc_info = NULL; + struct cam_csid_soc_private *soc_private = NULL; int rc = 0; of_node = soc_info->pdev->dev.of_node; - csid_soc_info = (struct csid_device_soc_info *)soc_info->soc_private; rc = cam_soc_util_get_dt_properties(soc_info); if (rc) return rc; + soc_private = (struct cam_csid_soc_private *)soc_info->soc_private; + + soc_private->is_ife_csid_lite = false; + if (strnstr(soc_info->compatible, "lite", + strlen(soc_info->compatible)) != NULL) { + soc_private->is_ife_csid_lite = true; + } + return rc; } diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_soc.h b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_soc.h index 4f76d084fb..3391bcaf46 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_soc.h +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_soc.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. */ #ifndef _CAM_IFE_CSID_SOC_H_ @@ -16,9 +16,11 @@ * @cpas_handle: Handle returned on registering with CPAS driver. * This handle is used for all further interface * with CPAS. + * @is_ife_csid_lite: Flag to indicate Whether a full csid or a Lite csid */ struct cam_csid_soc_private { uint32_t cpas_handle; + bool is_ife_csid_lite; }; /** diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_ife_csid_hw_intf.h b/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_ife_csid_hw_intf.h index 78c457b6a7..9d15a8bbed 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_ife_csid_hw_intf.h +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_ife_csid_hw_intf.h @@ -49,7 +49,7 @@ enum cam_ife_cid_res_id { * @major_version : major version * @minor_version: minor version * @version_incr: version increment - * + * @is_lite: is the ife_csid lite */ struct cam_ife_csid_hw_caps { uint32_t num_rdis; @@ -58,6 +58,7 @@ struct cam_ife_csid_hw_caps { uint32_t major_version; uint32_t minor_version; uint32_t version_incr; + bool is_lite; }; struct cam_isp_out_port_generic_info { diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_vfe_hw_intf.h b/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_vfe_hw_intf.h index 531e695583..41c4564eb3 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_vfe_hw_intf.h +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_vfe_hw_intf.h @@ -90,16 +90,17 @@ enum cam_vfe_reset_type { /* * struct cam_vfe_hw_get_hw_cap: * - * @max_width: Max width supported by HW - * @max_height: Max height supported by HW - * @max_pixel_num: Max Pixel channels available - * @max_rdi_num: Max Raw channels available + * @Brief: Argument type for fetching the hw information for Query caps + * @major: Major revision number + * @minor: Minor revision number + * @incr: Increment revision number + * @is_lite: Flag to indicate Whether a full vfe or a Lite vfe */ struct cam_vfe_hw_get_hw_cap { - uint32_t max_width; - uint32_t max_height; - uint32_t max_pixel_num; - uint32_t max_rdi_num; + uint32_t major; + uint32_t minor; + uint32_t incr; + bool is_lite; }; /* diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_common.h b/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_common.h index 55607b6d88..9078ec9995 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_common.h +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_common.h @@ -27,6 +27,7 @@ struct cam_vfe_top_priv_common { CAM_VFE_DELAY_BW_REDUCTION_NUM_FRAMES]; uint32_t last_counter; uint64_t total_bw_applied; + uint32_t hw_version; enum cam_vfe_bw_control_action axi_vote_control[CAM_VFE_TOP_MUX_MAX]; }; diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.c b/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.c index 044a024680..6e1ae838bc 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.c +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.c @@ -282,9 +282,39 @@ static int cam_vfe_top_get_data( } int cam_vfe_top_get_hw_caps(void *device_priv, - void *get_hw_cap_args, uint32_t arg_size) + void *args, uint32_t arg_size) { - return -EPERM; + struct cam_vfe_hw_get_hw_cap *vfe_cap_info = NULL; + struct cam_vfe_top_ver2_priv *vfe_top_prv = NULL; + struct cam_vfe_soc_private *vfe_soc_private = NULL; + + if (!device_priv || !args) { + CAM_ERR(CAM_ISP, + "Invalid arguments device_priv:%p, args:%p", + device_priv, args); + return -EINVAL; + } + + vfe_cap_info = (struct cam_vfe_hw_get_hw_cap *)args; + vfe_top_prv = (struct cam_vfe_top_ver2_priv *)device_priv; + + if (!vfe_top_prv->common_data.soc_info) { + CAM_ERR(CAM_ISP, "soc_info is null"); + return -EFAULT; + } + + vfe_soc_private = (struct cam_vfe_soc_private *) + vfe_top_prv->common_data.soc_info->soc_private; + + vfe_cap_info->is_lite = (vfe_soc_private->is_ife_lite) ? true : false; + vfe_cap_info->incr = + (vfe_top_prv->top_common.hw_version) & 0x00ffff; + vfe_cap_info->minor = + ((vfe_top_prv->top_common.hw_version) >> 16) & 0x0fff; + vfe_cap_info->major = + ((vfe_top_prv->top_common.hw_version) >> 28) & 0x000f; + + return 0; } static int cam_vfe_hw_dump( @@ -425,9 +455,14 @@ int cam_vfe_top_init_hw(void *device_priv, void *init_hw_args, uint32_t arg_size) { struct cam_vfe_top_ver2_priv *top_priv = device_priv; + struct cam_vfe_top_ver2_common_data common_data = top_priv->common_data; top_priv->hw_clk_rate = 0; + top_priv->top_common.hw_version = + cam_io_r_mb(common_data.soc_info->reg_map[0].mem_base + + common_data.common_reg->hw_version); + return 0; } diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver3.c b/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver3.c index 087a6bbf22..6a66955ed2 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver3.c +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver3.c @@ -323,9 +323,39 @@ static int cam_vfe_top_ver3_get_data( } int cam_vfe_top_ver3_get_hw_caps(void *device_priv, - void *get_hw_cap_args, uint32_t arg_size) + void *args, uint32_t arg_size) { - return -EPERM; + struct cam_vfe_hw_get_hw_cap *vfe_cap_info = NULL; + struct cam_vfe_top_ver3_priv *vfe_top_prv = NULL; + struct cam_vfe_soc_private *vfe_soc_private = NULL; + + if (!device_priv || !args) { + CAM_ERR(CAM_ISP, + "Invalid arguments device_priv:%p, args:%p", + device_priv, args); + return -EINVAL; + } + + vfe_cap_info = (struct cam_vfe_hw_get_hw_cap *)args; + vfe_top_prv = (struct cam_vfe_top_ver3_priv *)device_priv; + + if (!vfe_top_prv->common_data.soc_info) { + CAM_ERR(CAM_ISP, "soc_info is null"); + return -EFAULT; + } + + vfe_soc_private = (struct cam_vfe_soc_private *) + vfe_top_prv->common_data.soc_info->soc_private; + + vfe_cap_info->is_lite = (vfe_soc_private->is_ife_lite) ? true : false; + vfe_cap_info->incr = + (vfe_top_prv->top_common.hw_version) & 0x00ffff; + vfe_cap_info->minor = + ((vfe_top_prv->top_common.hw_version) >> 16) & 0x0fff; + vfe_cap_info->major = + ((vfe_top_prv->top_common.hw_version) >> 28) & 0x000f; + + return 0; } int cam_vfe_top_ver3_init_hw(void *device_priv, @@ -354,6 +384,10 @@ int cam_vfe_top_ver3_init_hw(void *device_priv, cam_soc_util_w_mb(common_data.soc_info, VFE_CORE_BASE_IDX, common_data.common_reg->noc_cgc_ovd, 0x0); + top_priv->top_common.hw_version = + cam_io_r_mb(common_data.soc_info->reg_map[0].mem_base + + common_data.common_reg->hw_version); + return 0; } diff --git a/include/uapi/camera/media/cam_isp.h b/include/uapi/camera/media/cam_isp.h index c3126dac8e..82e5ebe814 100644 --- a/include/uapi/camera/media/cam_isp.h +++ b/include/uapi/camera/media/cam_isp.h @@ -20,7 +20,9 @@ #define CAM_ISP_HW_VFE 2 #define CAM_ISP_HW_IFE 3 #define CAM_ISP_HW_ISPIF 4 -#define CAM_ISP_HW_MAX 5 +#define CAM_ISP_HW_IFE_LITE 5 +#define CAM_ISP_HW_CSID_LITE 6 +#define CAM_ISP_HW_MAX 7 /* Color Pattern */ #define CAM_ISP_PATTERN_BAYER_RGRGRG 0 @@ -140,13 +142,13 @@ * struct cam_isp_dev_cap_info - A cap info for particular hw type * * @hw_type: Hardware type for the cap info - * @reserved: reserved field for alignment + * @num_hw: Number of HW of type @hw_type * @hw_version: Hardware version * */ struct cam_isp_dev_cap_info { - __u32 hw_type; - __u32 reserved; + __u32 hw_type; + __u32 num_hw; struct cam_hw_version hw_version; };