Browse Source

Merge "msm: camera: ife: Add support to provide IFE count in Query caps" into camera-kernel.lnx.4.0

Camera Software Integration 5 years ago
parent
commit
c651d58e4f

+ 97 - 7
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),

+ 22 - 6
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",

+ 2 - 0
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;
 
 };

+ 10 - 3
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 <linux/slab.h>
 #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;
 }
 

+ 3 - 1
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;
 };
 
 /**

+ 2 - 1
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 {

+ 9 - 8
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;
 };
 
 /*

+ 1 - 0
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];
 };
 

+ 37 - 2
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;
 }
 

+ 36 - 2
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;
 }
 

+ 6 - 4
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;
 };