Pārlūkot izejas kodu

Merge "msm: camera: icp: Use blob to pass presil hangdump buffer info" into camera-kernel.lnx.6.0

Camera Software Integration 3 gadi atpakaļ
vecāks
revīzija
7d3c727286

+ 91 - 3
drivers/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c

@@ -2096,6 +2096,7 @@ static int cam_icp_mgr_handle_frame_process(uint32_t *msg_ptr, int flag)
 	struct cam_hw_done_event_data buf_data;
 	uint32_t clk_type;
 	uint32_t event_id;
+	struct cam_hangdump_mem_regions *mem_regions = NULL;
 
 	ioconfig_ack = (struct hfi_msg_ipebps_async_ack *)msg_ptr;
 	request_id = ioconfig_ack->user_data2;
@@ -2160,6 +2161,23 @@ static int cam_icp_mgr_handle_frame_process(uint32_t *msg_ptr, int flag)
 		event_id = CAM_CTX_EVT_ID_SUCCESS;
 	}
 
+	if (cam_presil_mode_enabled()) {
+		mem_regions = &hfi_frame_process->hangdump_mem_regions[idx];
+		CAM_INFO(CAM_ICP, "Hangdump Num Regions %d",
+			mem_regions->num_mem_regions);
+		for (i = 0; i < mem_regions->num_mem_regions; i++) {
+			CAM_INFO(CAM_PRESIL, "Hangdump Mem %d handle 0x%08x offset 0x%08x len %u",
+				i, mem_regions->mem_info_array[i].mem_handle,
+				mem_regions->mem_info_array[i].offset,
+				mem_regions->mem_info_array[i].size);
+			cam_mem_mgr_retrieve_buffer_from_presil(
+				mem_regions->mem_info_array[i].mem_handle,
+				mem_regions->mem_info_array[i].size,
+				mem_regions->mem_info_array[i].offset,
+				icp_hw_mgr.iommu_hdl);
+		}
+	}
+
 	buf_data.request_id = hfi_frame_process->request_id[idx];
 	ctx_data->ctxt_event_cb(ctx_data->context_priv, event_id, &buf_data);
 	hfi_frame_process->request_id[idx] = 0;
@@ -4860,6 +4878,48 @@ end:
 	return rc;
 }
 
+static int cam_icp_process_presil_hangdump_info(
+	struct cam_icp_hw_ctx_data *ctx_data,
+	struct cam_cmd_mem_regions *cmd_mem_regions,
+	uint32_t index)
+{
+	int i = 0;
+	struct cam_hangdump_mem_regions *mem_regions = NULL;
+
+	if (!ctx_data || !cmd_mem_regions) {
+		CAM_ERR(CAM_ICP, "Invalid hangdump info blob ctx %pK mem_region %pK",
+			ctx_data, cmd_mem_regions);
+		return -EINVAL;
+	}
+
+	if ((cmd_mem_regions->num_regions == 0) ||
+		(cmd_mem_regions->num_regions > HANG_DUMP_REGIONS_MAX)) {
+		CAM_ERR(CAM_ICP, "Invalid num hangdump mem regions %d ",
+			cmd_mem_regions->num_regions);
+		return -EINVAL;
+	}
+
+	mem_regions = &ctx_data->hfi_frame_process.hangdump_mem_regions[index];
+	CAM_INFO(CAM_ICP, "Hangdump Mem Num Regions %d index %d  mem_regions 0x%pK",
+		cmd_mem_regions->num_regions, index, mem_regions);
+
+	for (i = 0; i < cmd_mem_regions->num_regions; i++) {
+		mem_regions->mem_info_array[i].mem_handle =
+			cmd_mem_regions->map_info_array[i].mem_handle;
+		mem_regions->mem_info_array[i].offset =
+			cmd_mem_regions->map_info_array[i].offset;
+		mem_regions->mem_info_array[i].size =
+			cmd_mem_regions->map_info_array[i].size;
+		CAM_INFO(CAM_ICP, "Hangdump Mem Region %u mem_handle 0x%08x iova 0x%08x len %u",
+			i, cmd_mem_regions->map_info_array[i].mem_handle,
+			(uint32_t)cmd_mem_regions->map_info_array[i].offset,
+			(uint32_t)cmd_mem_regions->map_info_array[i].size);
+	}
+	mem_regions->num_mem_regions = cmd_mem_regions->num_regions;
+
+	return 0;
+}
+
 static int cam_icp_packet_generic_blob_handler(void *user_data,
 	uint32_t blob_type, uint32_t blob_size, uint8_t *blob_data)
 {
@@ -5056,6 +5116,21 @@ static int cam_icp_packet_generic_blob_handler(void *user_data,
 		}
 		break;
 
+	case CAM_ICP_CMD_GENERIC_BLOB_PRESIL_HANGDUMP:
+		if (cam_presil_mode_enabled()) {
+			cmd_mem_regions = (struct cam_cmd_mem_regions *)blob_data;
+			if (cmd_mem_regions->num_regions <= 0) {
+				CAM_INFO(CAM_ICP, "Pre-sil Hangdump disabled %u",
+					cmd_mem_regions->num_regions);
+			} else {
+				CAM_INFO(CAM_ICP, "Pre-sil Hangdump enabled %u entries index %d",
+					cmd_mem_regions->num_regions, index);
+				rc = cam_icp_process_presil_hangdump_info(ctx_data,
+					cmd_mem_regions, index);
+			}
+		}
+		break;
+
 	default:
 		CAM_WARN(CAM_ICP, "Invalid blob type %d", blob_type);
 		break;
@@ -6564,6 +6639,7 @@ int cam_icp_hw_mgr_init(struct device_node *of_node, uint64_t *hw_mgr_hdl,
 	struct cam_hw_mgr_intf *hw_mgr_intf;
 	struct cam_cpas_query_cap query;
 	uint32_t cam_caps, camera_hw_version;
+	uint32_t size = 0;
 
 	hw_mgr_intf = (struct cam_hw_mgr_intf *)hw_mgr_hdl;
 	if (!of_node || !hw_mgr_intf) {
@@ -6591,8 +6667,14 @@ int cam_icp_hw_mgr_init(struct device_node *of_node, uint64_t *hw_mgr_hdl,
 	mutex_init(&icp_hw_mgr.hw_mgr_mutex);
 	spin_lock_init(&icp_hw_mgr.hw_mgr_lock);
 
-	for (i = 0; i < CAM_ICP_CTX_MAX; i++)
+	for (i = 0; i < CAM_ICP_CTX_MAX; i++) {
 		mutex_init(&icp_hw_mgr.ctx_data[i].ctx_mutex);
+		if (cam_presil_mode_enabled()) {
+			size = CAM_FRAME_CMD_MAX * sizeof(struct cam_hangdump_mem_regions);
+			icp_hw_mgr.ctx_data[i].hfi_frame_process.hangdump_mem_regions =
+				kzalloc(size, GFP_KERNEL);
+		}
+	}
 
 	rc = cam_cpas_get_hw_info(&query.camera_family,
 			&query.camera_version, &query.cpas_version,
@@ -6670,8 +6752,11 @@ icp_get_hdl_failed:
 	cam_icp_mgr_free_devs();
 destroy_mutex:
 	mutex_destroy(&icp_hw_mgr.hw_mgr_mutex);
-	for (i = 0; i < CAM_ICP_CTX_MAX; i++)
+	for (i = 0; i < CAM_ICP_CTX_MAX; i++) {
 		mutex_destroy(&icp_hw_mgr.ctx_data[i].ctx_mutex);
+		if (cam_presil_mode_enabled())
+			kfree(icp_hw_mgr.ctx_data[i].hfi_frame_process.hangdump_mem_regions);
+	}
 
 	return rc;
 }
@@ -6685,6 +6770,9 @@ void cam_icp_hw_mgr_deinit(void)
 	cam_icp_mgr_destroy_wq();
 	cam_icp_mgr_free_devs();
 	mutex_destroy(&icp_hw_mgr.hw_mgr_mutex);
-	for (i = 0; i < CAM_ICP_CTX_MAX; i++)
+	for (i = 0; i < CAM_ICP_CTX_MAX; i++) {
 		mutex_destroy(&icp_hw_mgr.ctx_data[i].ctx_mutex);
+		if (cam_presil_mode_enabled())
+			kfree(icp_hw_mgr.ctx_data[i].hfi_frame_process.hangdump_mem_regions);
+	}
 }

+ 18 - 0
drivers/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.h

@@ -173,6 +173,21 @@ struct cam_icp_clk_bw_req_internal_v2 {
 	struct cam_axi_per_path_bw_vote axi_path[CAM_ICP_MAX_PER_PATH_VOTES];
 };
 
+#define HANG_DUMP_REGIONS_MAX 10
+
+/**
+ * struct cam_hangdump_mem_regions -
+ *        List of multiple memory descriptors of different
+ *        regions
+ *
+ * @num_regions    : Number of regions
+ * @map_info_array : Array of all the regions
+ */
+struct cam_hangdump_mem_regions {
+	uint32_t num_mem_regions;
+	struct cam_cmd_mem_region_info mem_info_array[HANG_DUMP_REGIONS_MAX];
+};
+
 /**
  * struct hfi_frame_process_info
  * @hfi_frame_cmd: Frame process command info
@@ -187,6 +202,7 @@ struct cam_icp_clk_bw_req_internal_v2 {
  * @clk_info_v2: Clock info for AXI bw voting v2
  * @frame_info: information needed to process request
  * @submit_timestamp: Submit timestamp to hw
+ * @hangdump_mem_regions: Mem regions for hangdump
  */
 struct hfi_frame_process_info {
 	struct hfi_cmd_ipebps_async hfi_frame_cmd[CAM_FRAME_CMD_MAX];
@@ -203,6 +219,7 @@ struct hfi_frame_process_info {
 	struct cam_icp_clk_bw_req_internal_v2 clk_info_v2[CAM_FRAME_CMD_MAX];
 	struct icp_frame_info frame_info[CAM_FRAME_CMD_MAX];
 	ktime_t submit_timestamp[CAM_FRAME_CMD_MAX];
+	struct cam_hangdump_mem_regions *hangdump_mem_regions;
 };
 
 /**
@@ -230,6 +247,7 @@ struct cam_ctx_clk_info {
 	struct cam_axi_per_path_bw_vote axi_path[CAM_ICP_MAX_PER_PATH_VOTES];
 	bool bw_included;
 };
+
 /**
  * struct cam_icp_hw_ctx_data
  * @context_priv: Context private data

+ 6 - 5
include/uapi/camera/media/cam_icp.h

@@ -74,11 +74,12 @@
 #define CAM_ICP_CMD_META_GENERIC_BLOB           0x1
 
 /* Generic blob types */
-#define CAM_ICP_CMD_GENERIC_BLOB_CLK            0x1
-#define CAM_ICP_CMD_GENERIC_BLOB_CFG_IO         0x2
-#define CAM_ICP_CMD_GENERIC_BLOB_FW_MEM_MAP     0x3
-#define CAM_ICP_CMD_GENERIC_BLOB_FW_MEM_UNMAP   0x4
-#define CAM_ICP_CMD_GENERIC_BLOB_CLK_V2         0x5
+#define CAM_ICP_CMD_GENERIC_BLOB_CLK              0x1
+#define CAM_ICP_CMD_GENERIC_BLOB_CFG_IO           0x2
+#define CAM_ICP_CMD_GENERIC_BLOB_FW_MEM_MAP       0x3
+#define CAM_ICP_CMD_GENERIC_BLOB_FW_MEM_UNMAP     0x4
+#define CAM_ICP_CMD_GENERIC_BLOB_CLK_V2           0x5
+#define CAM_ICP_CMD_GENERIC_BLOB_PRESIL_HANGDUMP  0x6
 
 /**
  * struct cam_icp_clk_bw_request_v2