Ver Fonte

Merge "msm: camera: cpas: read and pass fuse information to user space" into camera-kernel.lnx.4.0

Camera Software Integration há 4 anos atrás
pai
commit
e955d3dc2e

+ 9 - 1
drivers/cam_cpas/cam_cpas_hw.c

@@ -1747,6 +1747,7 @@ static int cam_cpas_hw_get_hw_info(void *hw_priv,
 	struct cam_hw_info *cpas_hw;
 	struct cam_cpas *cpas_core;
 	struct cam_cpas_hw_caps *hw_caps;
+	struct cam_cpas_private_soc *soc_private;
 
 	if (!hw_priv || !get_hw_cap_args) {
 		CAM_ERR(CAM_CPAS, "Invalid arguments %pK %pK",
@@ -1763,9 +1764,16 @@ static int cam_cpas_hw_get_hw_info(void *hw_priv,
 	cpas_hw = (struct cam_hw_info *)hw_priv;
 	cpas_core = (struct cam_cpas *) cpas_hw->core_info;
 	hw_caps = (struct cam_cpas_hw_caps *)get_hw_cap_args;
-
 	*hw_caps = cpas_core->hw_caps;
 
+	/*Extract Fuse Info*/
+	soc_private = (struct cam_cpas_private_soc *)
+		cpas_hw->soc_info.soc_private;
+
+	hw_caps->fuse_info = soc_private->fuse_info;
+	CAM_INFO(CAM_CPAS, "fuse info->num_fuses %d",
+		hw_caps->fuse_info.num_fuses);
+
 	return 0;
 }
 

+ 2 - 0
drivers/cam_cpas/cam_cpas_hw_intf.h

@@ -114,6 +114,7 @@ struct cam_cpas_hw_cmd_stop {
  * @camera_version: Camera version
  * @cpas_version: CPAS version
  * @camera_capability: Camera hw capabilities
+ * @fuse_info: Fuse information
  *
  */
 struct cam_cpas_hw_caps {
@@ -121,6 +122,7 @@ struct cam_cpas_hw_caps {
 	struct cam_hw_version camera_version;
 	struct cam_hw_version cpas_version;
 	uint32_t camera_capability;
+	struct cam_cpas_fuse_info fuse_info;
 };
 
 int cam_cpas_hw_probe(struct platform_device *pdev,

+ 38 - 5
drivers/cam_cpas/cam_cpas_intf.c

@@ -173,7 +173,8 @@ int cam_cpas_get_cpas_hw_version(uint32_t *hw_version)
 int cam_cpas_get_hw_info(uint32_t *camera_family,
 	struct cam_hw_version *camera_version,
 	struct cam_hw_version *cpas_version,
-	uint32_t *cam_caps)
+	uint32_t *cam_caps,
+	struct cam_cpas_fuse_info *cam_fuse_info)
 {
 	if (!CAM_CPAS_INTF_INITIALIZED()) {
 		CAM_ERR(CAM_CPAS, "cpas intf not initialized");
@@ -186,10 +187,16 @@ int cam_cpas_get_hw_info(uint32_t *camera_family,
 		return -EINVAL;
 	}
 
-	*camera_family = g_cpas_intf->hw_caps.camera_family;
+	*camera_family  = g_cpas_intf->hw_caps.camera_family;
 	*camera_version = g_cpas_intf->hw_caps.camera_version;
-	*cpas_version = g_cpas_intf->hw_caps.cpas_version;
-	*cam_caps = g_cpas_intf->hw_caps.camera_capability;
+	*cpas_version   = g_cpas_intf->hw_caps.cpas_version;
+	*cam_caps       = g_cpas_intf->hw_caps.camera_capability;
+	if (cam_fuse_info)
+		*cam_fuse_info  = g_cpas_intf->hw_caps.fuse_info;
+
+	CAM_DBG(CAM_CPAS, "Family %d, version %d.%d cam_caps %d",
+		*camera_family, camera_version->major,
+		camera_version->minor, *cam_caps);
 
 	return 0;
 }
@@ -529,7 +536,32 @@ int cam_cpas_subdev_cmd(struct cam_cpas_intf *cpas_intf,
 
 		rc = cam_cpas_get_hw_info(&query.camera_family,
 			&query.camera_version, &query.cpas_version,
-			&query.reserved);
+			&query.reserved, NULL);
+		if (rc)
+			break;
+
+		rc = copy_to_user(u64_to_user_ptr(cmd->handle), &query,
+			sizeof(query));
+		if (rc)
+			CAM_ERR(CAM_CPAS, "Failed in copy to user, rc=%d", rc);
+
+		break;
+	}
+	case CAM_QUERY_CAP_V2: {
+		struct cam_cpas_query_cap_v2 query;
+
+		rc = copy_from_user(&query, u64_to_user_ptr(cmd->handle),
+			sizeof(query));
+		if (rc) {
+			CAM_ERR(CAM_CPAS, "Failed in copy from user, rc=%d",
+				rc);
+			break;
+		}
+
+		rc = cam_cpas_get_hw_info(&query.camera_family,
+			&query.camera_version, &query.cpas_version,
+			&query.reserved,
+			&query.fuse_info);
 		if (rc)
 			break;
 
@@ -729,6 +761,7 @@ static int cam_cpas_dev_component_bind(struct device *dev,
 
 	hw_intf = g_cpas_intf->hw_intf;
 	hw_caps = &g_cpas_intf->hw_caps;
+
 	if (hw_intf->hw_ops.get_hw_caps) {
 		rc = hw_intf->hw_ops.get_hw_caps(hw_intf->hw_priv,
 			hw_caps, sizeof(struct cam_cpas_hw_caps));

+ 46 - 1
drivers/cam_cpas/cam_cpas_soc.c

@@ -18,7 +18,6 @@
 static uint cpas_dump;
 module_param(cpas_dump, uint, 0644);
 
-
 void cam_cpas_dump_axi_vote_info(
 	const struct cam_cpas_client *cpas_client,
 	const char *identifier,
@@ -467,6 +466,51 @@ static int cam_cpas_parse_node_tree(struct cam_cpas *cpas_core,
 	return 0;
 }
 
+int cam_cpas_get_hw_fuse(struct platform_device *pdev,
+	struct cam_cpas_private_soc *soc_private)
+{
+	struct device_node *of_node;
+	void *fuse;
+	uint32_t fuse_addr, fuse_bit;
+	uint32_t fuse_val = 0, feature_bit_pos;
+	int count = 0, i = 0;
+
+	memset(&soc_private->fuse_info, 0, sizeof(soc_private->fuse_info));
+
+	of_node = pdev->dev.of_node;
+	count   = of_property_count_u32_elems(of_node, "cam_hw_fuse");
+	if (count <= 0) {
+		CAM_INFO(CAM_CPAS, "no or invalid fuse enrties %d", count);
+		return 0;
+	} else if (count%3 != 0) {
+		CAM_INFO(CAM_CPAS, "fuse entries should be multiple of 3 %d",
+			count);
+		return -EINVAL;
+	}
+
+	for (i = 0; i < count; i = i + 3) {
+		of_property_read_u32_index(of_node, "cam_hw_fuse", i,
+				&feature_bit_pos);
+		of_property_read_u32_index(of_node, "cam_hw_fuse", i + 1,
+				&fuse_addr);
+		of_property_read_u32_index(of_node, "cam_hw_fuse", i + 2,
+				&fuse_bit);
+		CAM_INFO(CAM_CPAS, "feature_bit 0x%x addr 0x%x, bit %d",
+			feature_bit_pos, fuse_addr, fuse_bit);
+		fuse = ioremap(fuse_addr, 4);
+		if (fuse) {
+			fuse_val = cam_io_r(fuse);
+			soc_private->fuse_info.fuse_val[i].fuse_id = fuse_addr;
+			soc_private->fuse_info.fuse_val[i].fuse_val = fuse_val;
+		}
+		CAM_INFO(CAM_CPAS, "fuse_addr 0x%x, fuse_val %x",
+			fuse_addr, fuse_val);
+		soc_private->fuse_info.num_fuses++;
+		iounmap(fuse);
+	}
+
+	return 0;
+}
 
 int cam_cpas_get_hw_features(struct platform_device *pdev,
 	struct cam_cpas_private_soc *soc_private)
@@ -532,6 +576,7 @@ int cam_cpas_get_custom_dt_info(struct cam_hw_info *cpas_hw,
 	}
 
 	cam_cpas_get_hw_features(pdev, soc_private);
+	cam_cpas_get_hw_fuse(pdev, soc_private);
 
 	soc_private->camnoc_axi_min_ib_bw = 0;
 	rc = of_property_read_u64(of_node,

+ 2 - 0
drivers/cam_cpas/cam_cpas_soc.h

@@ -91,6 +91,7 @@ struct cam_cpas_tree_node {
  *      camnoc axi clock
  * @camnoc_axi_min_ib_bw: Min camnoc BW which varies based on target
  * @feature_mask: feature mask value for hw supported features
+ * @fuse_info: fuse information
  *
  */
 struct cam_cpas_private_soc {
@@ -109,6 +110,7 @@ struct cam_cpas_private_soc {
 	uint32_t camnoc_axi_clk_bw_margin;
 	uint64_t camnoc_axi_min_ib_bw;
 	uint32_t feature_mask;
+	struct cam_cpas_fuse_info fuse_info;
 };
 
 void cam_cpas_util_debug_parse_data(struct cam_cpas_private_soc *soc_private);

+ 6 - 4
drivers/cam_cpas/include/cam_cpas_api.h

@@ -575,15 +575,17 @@ int cam_cpas_reg_read(
  * @camera_version : Camera platform version
  * @cpas_version   : Camera cpas version
  * @cam_caps       : Camera capability
+ * @cam_fuse_info  : Camera fuse info
  *
  * @return 0 on success.
  *
  */
 int cam_cpas_get_hw_info(
-	uint32_t                 *camera_family,
-	struct cam_hw_version    *camera_version,
-	struct cam_hw_version    *cpas_version,
-	uint32_t                 *cam_caps);
+	uint32_t                  *camera_family,
+	struct cam_hw_version     *camera_version,
+	struct cam_hw_version     *cpas_version,
+	uint32_t                  *cam_caps,
+	struct cam_cpas_fuse_info *cam_fuse_info);
 
 /**
  * cam_cpas_get_cpas_hw_version()

+ 2 - 1
drivers/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c

@@ -6093,7 +6093,8 @@ int cam_icp_hw_mgr_init(struct device_node *of_node, uint64_t *hw_mgr_hdl,
 		mutex_init(&icp_hw_mgr.ctx_data[i].ctx_mutex);
 
 	rc = cam_cpas_get_hw_info(&query.camera_family,
-			&query.camera_version, &query.cpas_version, &cam_caps);
+			&query.camera_version, &query.cpas_version,
+			&cam_caps, NULL);
 	if (rc) {
 		CAM_ERR(CAM_ICP, "failed to get hw info rc=%d", rc);
 		goto destroy_mutex;

+ 2 - 1
drivers/cam_icp/icp_hw/ipe_hw/ipe_dev.c

@@ -77,7 +77,8 @@ static int cam_ipe_component_bind(struct device *dev,
 		"cell-index", &hw_idx);
 
 	rc = cam_cpas_get_hw_info(&query.camera_family,
-			&query.camera_version, &query.cpas_version, &cam_caps);
+			&query.camera_version, &query.cpas_version,
+			&cam_caps, NULL);
 	if (rc) {
 		CAM_ERR(CAM_ICP, "failed to get hw info rc=%d", rc);
 		return rc;

+ 42 - 1
include/uapi/camera/media/cam_cpas.h

@@ -61,7 +61,30 @@
 #define CAM_AXI_PATH_DATA_OPE_MAX_OFFSET \
 	(CAM_AXI_PATH_DATA_OPE_START_OFFSET + 31)
 
-#define CAM_AXI_PATH_DATA_ALL              256
+#define CAM_AXI_PATH_DATA_ALL  256
+#define CAM_CPAS_FUSES_MAX     32
+
+/**
+ * struct cam_cpas_fuse_value - CPAS fuse value
+ *
+ * @fuse_id     : Camera fuse identification
+ * @fuse_val    : Camera Fuse Value
+ */
+struct cam_cpas_fuse_value {
+	__u32 fuse_id;
+	__u32 fuse_val;
+};
+
+/**
+ * struct cam_cpas_fuse_info - CPAS fuse info
+ *
+ * @num_fuses     : Number of fuses
+ * @fuse_val      : Array of different fuse info.
+ */
+struct cam_cpas_fuse_info {
+	__u32  num_fuses;
+	struct cam_cpas_fuse_value fuse_val[CAM_CPAS_FUSES_MAX];
+};
 
 /**
  * struct cam_cpas_query_cap - CPAS query device capability payload
@@ -79,6 +102,24 @@ struct cam_cpas_query_cap {
 	struct cam_hw_version cpas_version;
 };
 
+/**
+ * struct cam_cpas_query_cap - CPAS query device capability payload
+ *
+ * @camera_family     : Camera family type
+ * @reserved          : Reserved field for alignment
+ * @camera_version    : Camera platform version
+ * @cpas_version      : Camera CPAS version within camera platform
+ * @fuse_info         : Camera fuse info
+ *
+ */
+struct cam_cpas_query_cap_v2 {
+	__u32                     camera_family;
+	__u32                     reserved;
+	struct cam_hw_version     camera_version;
+	struct cam_hw_version     cpas_version;
+	struct cam_cpas_fuse_info fuse_info;
+};
+
 /**
  * struct cam_axi_per_path_bw_vote - Per path bandwidth vote information
  *

+ 2 - 1
include/uapi/camera/media/cam_defs.h

@@ -21,7 +21,8 @@
 #define CAM_RELEASE_DEV                         (CAM_COMMON_OPCODE_BASE + 0x6)
 #define CAM_SD_SHUTDOWN                         (CAM_COMMON_OPCODE_BASE + 0x7)
 #define CAM_FLUSH_REQ                           (CAM_COMMON_OPCODE_BASE + 0x8)
-#define CAM_COMMON_OPCODE_MAX                   (CAM_COMMON_OPCODE_BASE + 0x9)
+#define CAM_QUERY_CAP_V2                        (CAM_COMMON_OPCODE_BASE + 0x9)
+#define CAM_COMMON_OPCODE_MAX                   (CAM_COMMON_OPCODE_BASE + 0xa)
 
 #define CAM_COMMON_OPCODE_BASE_v2           0x150
 #define CAM_ACQUIRE_HW                      (CAM_COMMON_OPCODE_BASE_v2 + 0x1)