Selaa lähdekoodia

msm: camera: cdm: Remove Kernel Internal Buffer for Gen IRQ

Currently we allocate the memory for CDM GENIRQ command
within the Kernel on every stream on. Presil framework
do not have an ability to transfer the kernel only buffers
to the user daemon. For that reason we need to add support
to use the user allocated command buffer instead of the
kernel generated memory to add the GenIRQ cdm command
while submitting BLs. This change also helps to reduce
the stream on and stream off latency by not having to
allocate and free the GENIRQ memory on every stream on and
stream off respectively.

CRs-Fixed: 3115399
Change-Id: Ic159efd56fb9c4480ed1eb25cf2c058cbb914332
Signed-off-by: Jigar Agrawal <[email protected]>
Jigar Agrawal 3 vuotta sitten
vanhempi
sitoutus
3c8d5b58ea

+ 0 - 9
drivers/cam_cdm/cam_cdm.h

@@ -497,14 +497,6 @@ struct cam_cdm_hw_intf_cmd_submit_bl {
 	struct cam_cdm_bl_request *data;
 };
 
-/* struct cam_cdm_hw_mem - CDM hw memory struct */
-struct cam_cdm_hw_mem {
-	int32_t handle;
-	uint32_t vaddr;
-	uintptr_t kmdvaddr;
-	size_t size;
-};
-
 /* struct cam_cdm_bl_fifo - CDM hw memory struct */
 struct cam_cdm_bl_fifo {
 	struct completion bl_complete;
@@ -562,7 +554,6 @@ struct cam_cdm {
 	struct cam_cdm_bl_fifo bl_fifo[CAM_CDM_BL_FIFO_MAX];
 	unsigned long cdm_status;
 	uint8_t bl_tag;
-	struct cam_cdm_hw_mem gen_irq[CAM_CDM_BL_FIFO_MAX];
 	uint32_t cpas_handle;
 	enum cam_cdm_arbitration arbitration;
 	uint8_t num_active_clients;

+ 0 - 9
drivers/cam_cdm/cam_cdm_core_common.c

@@ -312,19 +312,10 @@ static int cam_cdm_stream_handle_init(void *hw_priv, bool init)
 			CAM_ERR(CAM_CDM, "CDM HW init failed");
 			return rc;
 		}
-
-		rc = cam_hw_cdm_alloc_genirq_mem(hw_priv);
-		if (rc) {
-			CAM_ERR(CAM_CDM, "Genirqalloc failed");
-			cam_hw_cdm_deinit(hw_priv, NULL, 0);
-		}
 	} else {
 		rc = cam_hw_cdm_deinit(hw_priv, NULL, 0);
 		if (rc)
 			CAM_ERR(CAM_CDM, "Deinit failed in streamoff");
-
-		if (cam_hw_cdm_release_genirq_mem(hw_priv))
-			CAM_ERR(CAM_CDM, "Genirq release fail");
 	}
 
 	return rc;

+ 0 - 2
drivers/cam_cdm/cam_cdm_core_common.h

@@ -30,8 +30,6 @@ int cam_hw_cdm_init(void *hw_priv, void *init_hw_args, uint32_t arg_size);
 int cam_hw_cdm_deinit(void *hw_priv, void *init_hw_args, uint32_t arg_size);
 int cam_hw_cdm_pf_deinit(void *hw_priv, void *init_hw_args,
 	uint32_t arg_size);
-int cam_hw_cdm_alloc_genirq_mem(void *hw_priv);
-int cam_hw_cdm_release_genirq_mem(void *hw_priv);
 int cam_cdm_get_caps(void *hw_priv, void *get_hw_cap_args, uint32_t arg_size);
 int cam_cdm_stream_ops_internal(void *hw_priv, void *start_args,
 	bool operation);

+ 111 - 161
drivers/cam_cdm/cam_cdm_hw_core.c

@@ -801,34 +801,41 @@ bool cam_hw_cdm_commit_bl_write(struct cam_hw_info *cdm_hw, uint32_t fifo_idx)
 int cam_hw_cdm_submit_gen_irq(
 	struct cam_hw_info *cdm_hw,
 	struct cam_cdm_hw_intf_cmd_submit_bl *req,
-	uint32_t fifo_idx, bool set_arb)
+	uint32_t fifo_idx)
 {
 	struct cam_cdm_bl_cb_request_entry *node;
 	struct cam_cdm *core = (struct cam_cdm *)cdm_hw->core_info;
-	uint32_t len;
+	struct cam_cdm_bl_request *cdm_cmd = req->data;
+	dma_addr_t hw_vaddr_ptr = 0;
 	int rc;
 	bool bit_wr_enable = false;
+	size_t len, genirq_cmd_size;
 
-	if (core->bl_fifo[fifo_idx].bl_tag >
-		(core->bl_fifo[fifo_idx].bl_depth - 1)) {
-		CAM_ERR(CAM_CDM,
-			"Invalid bl_tag=%d bl_depth=%d fifo_idx=%d",
+	if (core->bl_fifo[fifo_idx].bl_tag > (core->bl_fifo[fifo_idx].bl_depth - 1)) {
+		CAM_ERR(CAM_CDM, "Invalid BL Tag: %d, BL Depth: %d Fifo_idx: %d",
 			core->bl_fifo[fifo_idx].bl_tag,
 			core->bl_fifo[fifo_idx].bl_depth,
 			fifo_idx);
-		rc = -EINVAL;
-		goto end;
+		return -EINVAL;
+	}
+
+	genirq_cmd_size = 4 * core->ops->cdm_required_size_genirq();
+
+	CAM_DBG(CAM_CDM, "Last Tag: 0x%x Total BLs: %d, Cookie: %d",
+		core->bl_fifo[fifo_idx].bl_tag, cdm_cmd->cmd_arrary_count, cdm_cmd->cookie);
+
+	rc = cam_mem_get_io_buf(cdm_cmd->genirq_buff->handle, core->iommu_hdl.non_secure,
+		&hw_vaddr_ptr, &len, NULL);
+	if (rc) {
+		CAM_ERR(CAM_CDM, "Getting a hwva from mem_hdl failed. rc: %d", rc);
+		return -EINVAL;
 	}
-	CAM_DBG(CAM_CDM, "CDM write BL last cmd tag=%x total=%d cookie=%d",
-		core->bl_fifo[fifo_idx].bl_tag,
-		req->data->cmd_arrary_count,
-		req->data->cookie);
 
 	node = kzalloc(sizeof(struct cam_cdm_bl_cb_request_entry),
 			GFP_KERNEL);
 	if (!node) {
-		rc = -ENOMEM;
-		goto end;
+		CAM_ERR(CAM_CDM, "Failed while getting memory for the Node");
+		return -ENOMEM;
 	}
 
 	if (core->offsets->reg_data->num_bl_fifo > 1)
@@ -836,49 +843,48 @@ int cam_hw_cdm_submit_gen_irq(
 
 	node->request_type = CAM_HW_CDM_BL_CB_CLIENT;
 	node->client_hdl = req->handle;
-	node->cookie = req->data->cookie;
+	node->cookie = cdm_cmd->cookie;
 	node->bl_tag = core->bl_fifo[fifo_idx].bl_tag;
-	node->userdata = req->data->userdata;
+	node->userdata = cdm_cmd->userdata;
 	list_add_tail(&node->entry, &core->bl_fifo[fifo_idx].bl_request_list);
-	len = core->ops->cdm_required_size_genirq() *
-		core->bl_fifo[fifo_idx].bl_tag;
+
 	core->ops->cdm_write_genirq(
-		((uint32_t *)core->gen_irq[fifo_idx].kmdvaddr + len),
-		core->bl_fifo[fifo_idx].bl_tag,
-		bit_wr_enable, fifo_idx);
+		cdm_cmd->genirq_buff->cpu_addr + (cdm_cmd->genirq_buff->used_bytes / 4),
+		core->bl_fifo[fifo_idx].bl_tag, bit_wr_enable, fifo_idx);
 	rc = cam_hw_cdm_bl_write(cdm_hw,
-		(core->gen_irq[fifo_idx].vaddr + (4*len)),
-		((4 * core->ops->cdm_required_size_genirq()) - 1),
-		core->bl_fifo[fifo_idx].bl_tag,
-		set_arb, fifo_idx);
+		(uint32_t)(hw_vaddr_ptr + cdm_cmd->genirq_buff->offset),
+		genirq_cmd_size - 1,
+		core->bl_fifo[fifo_idx].bl_tag, cdm_cmd->gen_irq_arb, fifo_idx);
 	if (rc) {
 		CAM_ERR(CAM_CDM, "CDM hw bl write failed for gen irq bltag=%d",
 			core->bl_fifo[fifo_idx].bl_tag);
 		list_del_init(&node->entry);
 		kfree(node);
 		node = NULL;
-		rc = -EIO;
-		goto end;
+		return -EIO;
 	}
 
+	cdm_cmd->genirq_buff->used_bytes += genirq_cmd_size;
+	cdm_cmd->genirq_buff->offset += genirq_cmd_size;
+
 	if (cam_presil_mode_enabled()) {
 		CAM_DBG(CAM_PRESIL,
 			"Sending CDM gen irq cmd buffer:%d with iommu_hdl:%d",
-			core->gen_irq[fifo_idx].handle, core->iommu_hdl.non_secure);
+			cdm_cmd->genirq_buff->handle, core->iommu_hdl.non_secure);
 
 		rc = cam_mem_mgr_send_buffer_to_presil(core->iommu_hdl.non_secure,
-			core->gen_irq[fifo_idx].handle);
+			0);
 		if (rc) {
 			CAM_ERR(CAM_PRESIL,
 				"Failed to send CDM gen irq cmd buffer fifo_idx:%d mem_handle:%d rc:%d",
-				fifo_idx, core->gen_irq[fifo_idx].handle, rc);
-			goto end;
+				fifo_idx, cdm_cmd->genirq_buff->handle, rc);
+			return rc;
 		}
 	}
 
 	if (cam_hw_cdm_commit_bl_write(cdm_hw, fifo_idx)) {
 		CAM_ERR(CAM_CDM,
-			"Cannot commit the genirq BL with tag tag=%d",
+			"Cannot commit the genirq BL with Tag: %d",
 			core->bl_fifo[fifo_idx].bl_tag);
 		list_del_init(&node->entry);
 		kfree(node);
@@ -886,55 +892,74 @@ int cam_hw_cdm_submit_gen_irq(
 		rc = -EIO;
 	}
 
-	trace_cam_log_event("CDM_START", "CDM_START_IRQ", req->data->cookie, 0);
+	trace_cam_log_event("CDM_START", "CDM_START_IRQ", cdm_cmd->cookie, 0);
 
-end:
 	return rc;
 }
 
 int cam_hw_cdm_submit_debug_gen_irq(
 	struct cam_hw_info *cdm_hw,
+	struct cam_cdm_hw_intf_cmd_submit_bl *req,
 	uint32_t            fifo_idx)
 {
 	struct cam_cdm *core = (struct cam_cdm *)cdm_hw->core_info;
-	uint32_t len;
+	struct cam_cdm_bl_request *cdm_cmd = req->data;
+	dma_addr_t hw_vaddr_ptr = 0;
 	int rc;
 	bool bit_wr_enable = false;
+	size_t len, genirq_cmd_size;
 
-	CAM_DBG(CAM_CDM,
-		"CDM write BL last cmd tag=0x%x",
-		core->bl_fifo[fifo_idx].bl_tag);
+	genirq_cmd_size = 4 * core->ops->cdm_required_size_genirq();
+
+	if (core->bl_fifo[fifo_idx].bl_tag > (core->bl_fifo[fifo_idx].bl_depth - 1)) {
+		CAM_ERR(CAM_CDM, "Invalid BL Tag: %d, BL Depth: %d Fifo_idx: %d",
+			core->bl_fifo[fifo_idx].bl_tag,
+			core->bl_fifo[fifo_idx].bl_depth,
+			fifo_idx);
+		return -EINVAL;
+	}
+
+	if ((cdm_cmd->genirq_buff->size - cdm_cmd->genirq_buff->used_bytes) < genirq_cmd_size) {
+		CAM_ERR(CAM_CDM, "Insufficient memory for GenIRQ Command");
+		return -ENOMEM;
+	}
+
+	CAM_DBG(CAM_CDM, "Last Tag: 0x%x Total BLs: %d, Cookie: %d",
+		core->bl_fifo[fifo_idx].bl_tag, cdm_cmd->cmd_arrary_count, cdm_cmd->cookie);
+
+	rc = cam_mem_get_io_buf(cdm_cmd->genirq_buff->handle, core->iommu_hdl.non_secure,
+		&hw_vaddr_ptr, &len, NULL);
+	if (rc) {
+		CAM_ERR(CAM_CDM, "Getting a hwva from mem_hdl failed. rc: %d", rc);
+		return -EINVAL;
+	}
 
 	if (core->offsets->reg_data->num_bl_fifo > 1)
 		bit_wr_enable = true;
 
-	len = core->ops->cdm_required_size_genirq() *
-		core->bl_fifo[fifo_idx].bl_tag;
 	core->ops->cdm_write_genirq(
-		((uint32_t *)core->gen_irq[fifo_idx].kmdvaddr + len),
+		cdm_cmd->genirq_buff->cpu_addr + (cdm_cmd->genirq_buff->used_bytes / 4),
 		CAM_CDM_DBG_GEN_IRQ_USR_DATA, bit_wr_enable, fifo_idx);
 	rc = cam_hw_cdm_bl_write(cdm_hw,
-		(core->gen_irq[fifo_idx].vaddr + (4*len)),
-		((4 * core->ops->cdm_required_size_genirq()) - 1),
+		(uint32_t)(hw_vaddr_ptr + cdm_cmd->genirq_buff->offset),
+		genirq_cmd_size - 1,
 		core->bl_fifo[fifo_idx].bl_tag,
 		false, fifo_idx);
 	if (rc) {
-		CAM_ERR(CAM_CDM,
-			"CDM hw bl write failed for dbggenirq USRdata=%d tag 0x%x",
-			CAM_CDM_DBG_GEN_IRQ_USR_DATA,
-			core->bl_fifo[fifo_idx].bl_tag);
-		rc = -EIO;
-		goto end;
+		CAM_ERR(CAM_CDM, "CDM hw bl write failed for Debug GenIRQ USRdata: %d, Tag: 0x%x",
+			CAM_CDM_DBG_GEN_IRQ_USR_DATA, core->bl_fifo[fifo_idx].bl_tag);
+		return -EIO;
 	}
+
+	cdm_cmd->genirq_buff->used_bytes += genirq_cmd_size;
+	cdm_cmd->genirq_buff->offset += genirq_cmd_size;
+
 	if (cam_hw_cdm_commit_bl_write(cdm_hw, fifo_idx)) {
-		CAM_ERR(CAM_CDM,
-			"Cannot commit the dbggenirq BL with tag tag=0x%x",
+		CAM_ERR(CAM_CDM, "Cannot commit the Debug GenIRQ BL with Tag: 0x%x",
 			core->bl_fifo[fifo_idx].bl_tag);
-		rc = -EIO;
-		goto end;
+		return -EIO;
 	}
 
-end:
 	return rc;
 }
 
@@ -961,6 +986,13 @@ int cam_hw_cdm_submit_bl(struct cam_hw_info *cdm_hw,
 		goto end;
 	}
 
+	if ((cdm_cmd->genirq_buff->size - cdm_cmd->genirq_buff->used_bytes) <
+		(core->ops->cdm_required_size_genirq() * 4)) {
+		CAM_ERR(CAM_CDM, "Insufficient memory for GenIRQ Command");
+		rc = -ENOMEM;
+		goto end;
+	}
+
 	bl_fifo = &core->bl_fifo[fifo_idx];
 
 	if (req->data->cmd_arrary_count > bl_fifo->bl_depth) {
@@ -1104,7 +1136,7 @@ int cam_hw_cdm_submit_bl(struct cam_hw_info *cdm_hw,
 					}
 				}
 
-				rc = cam_hw_cdm_submit_debug_gen_irq(cdm_hw, fifo_idx);
+				rc = cam_hw_cdm_submit_debug_gen_irq(cdm_hw, req, fifo_idx);
 				if (!rc) {
 					CAM_DBG(CAM_CDM,
 						"Commit success for Dbg_GenIRQ_BL, Tag: %d",
@@ -1138,8 +1170,7 @@ int cam_hw_cdm_submit_bl(struct cam_hw_info *cdm_hw,
 				else
 					cdm_cmd->gen_irq_arb = false;
 
-				rc = cam_hw_cdm_submit_gen_irq(cdm_hw, req, fifo_idx,
-					cdm_cmd->gen_irq_arb);
+				rc = cam_hw_cdm_submit_gen_irq(cdm_hw, req, fifo_idx);
 				if (!rc) {
 					CAM_DBG(CAM_CDM, "Commit success for GenIRQ_BL, Tag: %d",
 						core->bl_fifo[fifo_idx].bl_tag);
@@ -1253,9 +1284,7 @@ static void cam_hw_cdm_work(struct work_struct *work)
 	if (payload->irq_status &
 		CAM_CDM_IRQ_STATUS_INLINE_IRQ_MASK) {
 		CAM_DBG(CAM_CDM, "inline IRQ data=0x%x last tag: 0x%x",
-			payload->irq_data,
-			core->bl_fifo[payload->fifo_idx]
-				.last_bl_tag_done);
+			payload->irq_data, core->bl_fifo[payload->fifo_idx].last_bl_tag_done);
 
 		if (payload->irq_data == 0xff) {
 			CAM_INFO(CAM_CDM, "%s%u Debug genirq received",
@@ -1272,53 +1301,42 @@ static void cam_hw_cdm_work(struct work_struct *work)
 		if (atomic_read(&core->bl_fifo[fifo_idx].work_record))
 			atomic_dec(&core->bl_fifo[fifo_idx].work_record);
 
-		if (list_empty(&core->bl_fifo[fifo_idx]
-				.bl_request_list)) {
-			CAM_INFO(CAM_CDM,
-				"Fifo list empty, idx %d tag %d arb %d",
-				fifo_idx, payload->irq_data,
-				core->arbitration);
-			mutex_unlock(&core->bl_fifo[fifo_idx]
-					.fifo_lock);
+		if (list_empty(&core->bl_fifo[fifo_idx].bl_request_list)) {
+			CAM_INFO(CAM_CDM, "Fifo list empty, idx %d tag %d arb %d",
+				fifo_idx, payload->irq_data, core->arbitration);
+			mutex_unlock(&core->bl_fifo[fifo_idx].fifo_lock);
 			mutex_unlock(&cdm_hw->hw_mutex);
 			return;
 		}
 
-		if (core->bl_fifo[fifo_idx].last_bl_tag_done !=
-			payload->irq_data) {
-			core->bl_fifo[fifo_idx].last_bl_tag_done =
-				payload->irq_data;
+		if (core->bl_fifo[fifo_idx].last_bl_tag_done != payload->irq_data) {
+			core->bl_fifo[fifo_idx].last_bl_tag_done = payload->irq_data;
 			list_for_each_entry_safe(node, tnode,
-				&core->bl_fifo[fifo_idx].bl_request_list,
-				entry) {
-				if (node->request_type ==
-					CAM_HW_CDM_BL_CB_CLIENT) {
+				&core->bl_fifo[fifo_idx].bl_request_list, entry) {
+				if (node->request_type == CAM_HW_CDM_BL_CB_CLIENT) {
 					cam_cdm_notify_clients(cdm_hw,
-					CAM_CDM_CB_STATUS_BL_SUCCESS,
-					(void *)node);
-				} else if (node->request_type ==
-					CAM_HW_CDM_BL_CB_INTERNAL) {
-					CAM_ERR(CAM_CDM,
-						"Invalid node=%pK %d",
-						node,
-						node->request_type);
+						CAM_CDM_CB_STATUS_BL_SUCCESS, (void *)node);
+				} else if (node->request_type == CAM_HW_CDM_BL_CB_INTERNAL) {
+					CAM_ERR(CAM_CDM, "Invalid node=%pK %d",
+						node, node->request_type);
 				}
+
 				list_del_init(&node->entry);
 				if (node->bl_tag == payload->irq_data) {
 					kfree(node);
 					node = NULL;
 					break;
 				}
+
 				kfree(node);
 				node = NULL;
 			}
 		} else {
-			CAM_INFO(CAM_CDM,
-				"Skip GenIRQ, tag 0x%x fifo %d",
+			CAM_INFO(CAM_CDM, "Skip GenIRQ, tag 0x%x fifo %d",
 				payload->irq_data, payload->fifo_idx);
 		}
-		mutex_unlock(&core->bl_fifo[payload->fifo_idx]
-			.fifo_lock);
+
+		mutex_unlock(&core->bl_fifo[payload->fifo_idx].fifo_lock);
 		mutex_unlock(&cdm_hw->hw_mutex);
 	}
 
@@ -1326,18 +1344,15 @@ static void cam_hw_cdm_work(struct work_struct *work)
 		CAM_CDM_IRQ_STATUS_BL_DONE_MASK) {
 		if (test_bit(payload->fifo_idx, &core->cdm_status)) {
 			CAM_DBG(CAM_CDM, "%s%u HW BL done IRQ",
-				cdm_hw->soc_info.label_name,
-				cdm_hw->soc_info.index);
-			complete(&core->bl_fifo[payload->fifo_idx]
-				.bl_complete);
+				cdm_hw->soc_info.label_name, cdm_hw->soc_info.index);
+			complete(&core->bl_fifo[payload->fifo_idx].bl_complete);
 		}
 	}
 	if (payload->irq_status &
 		CAM_CDM_IRQ_STATUS_ERRORS) {
 		int reset_hw_hdl = 0x0;
 
-		CAM_ERR_RATE_LIMIT(CAM_CDM,
-			"%s%u Error IRQ status %d\n",
+		CAM_ERR_RATE_LIMIT(CAM_CDM, "%s%u Error IRQ status %d\n",
 			cdm_hw->soc_info.label_name,
 			cdm_hw->soc_info.index, payload->irq_status);
 		set_bit(CAM_CDM_ERROR_HW_STATUS, &core->cdm_status);
@@ -1383,6 +1398,7 @@ static void cam_hw_cdm_work(struct work_struct *work)
 			clear_bit(CAM_CDM_ERROR_HW_STATUS,
 				&core->cdm_status);
 	}
+
 	kfree(payload);
 	payload = NULL;
 
@@ -1537,8 +1553,7 @@ irqreturn_t cam_hw_cdm_irq(int irq_num, void *data)
 			payload[i]->irq_data = (user_data >> (i * 0x8)) &
 				CAM_CDM_IRQ_STATUS_USR_DATA_MASK;
 
-			if (payload[i]->irq_data ==
-				CAM_CDM_DBG_GEN_IRQ_USR_DATA)
+			if (payload[i]->irq_data == CAM_CDM_DBG_GEN_IRQ_USR_DATA)
 				CAM_INFO(CAM_CDM, "Debug gen_irq received");
 
 			atomic_inc(&cdm_core->bl_fifo[i].work_record);
@@ -1598,71 +1613,6 @@ irqreturn_t cam_hw_cdm_irq(int irq_num, void *data)
 	return IRQ_HANDLED;
 }
 
-int cam_hw_cdm_alloc_genirq_mem(void *hw_priv)
-{
-	struct cam_hw_info *cdm_hw = hw_priv;
-	struct cam_mem_mgr_request_desc genirq_alloc_cmd;
-	struct cam_mem_mgr_memory_desc genirq_alloc_out;
-	struct cam_cdm *cdm_core = NULL;
-	int rc = -EINVAL, i;
-
-	if (!hw_priv)
-		return rc;
-
-	cdm_core = (struct cam_cdm *)cdm_hw->core_info;
-	genirq_alloc_cmd.align = 0;
-	genirq_alloc_cmd.smmu_hdl = cdm_core->iommu_hdl.non_secure;
-	genirq_alloc_cmd.flags = CAM_MEM_FLAG_HW_READ_WRITE;
-	for (i = 0; i < cdm_core->offsets->reg_data->num_bl_fifo; i++) {
-		if (!cdm_core->bl_fifo[i].bl_depth)
-			continue;
-
-		genirq_alloc_cmd.size = (8 *
-				cdm_core->bl_fifo[i].bl_depth);
-		rc = cam_mem_mgr_request_mem(&genirq_alloc_cmd,
-				&genirq_alloc_out);
-		if (rc) {
-			CAM_ERR(CAM_CDM,
-				"Failed to get genirq cmd space rc=%d",
-				rc);
-			goto end;
-		}
-		cdm_core->gen_irq[i].handle = genirq_alloc_out.mem_handle;
-		cdm_core->gen_irq[i].vaddr = (genirq_alloc_out.iova &
-			0xFFFFFFFF);
-		cdm_core->gen_irq[i].kmdvaddr = genirq_alloc_out.kva;
-		cdm_core->gen_irq[i].size = genirq_alloc_out.len;
-	}
-end:
-	return rc;
-}
-
-int cam_hw_cdm_release_genirq_mem(void *hw_priv)
-{
-	struct cam_hw_info *cdm_hw = hw_priv;
-	struct cam_cdm *cdm_core = NULL;
-	struct cam_mem_mgr_memory_desc genirq_release_cmd;
-	int rc = -EINVAL, i;
-
-	if (!hw_priv)
-		return rc;
-
-	cdm_core = (struct cam_cdm *)cdm_hw->core_info;
-	for (i = 0; i < cdm_core->offsets->reg_data->num_bl_fifo; i++) {
-		if (!cdm_core->bl_fifo[i].bl_depth)
-			continue;
-
-		genirq_release_cmd.mem_handle = cdm_core->gen_irq[i].handle;
-		rc = cam_mem_mgr_release_mem(&genirq_release_cmd);
-		if (rc)
-			CAM_ERR(CAM_CDM,
-				"Failed to put genirq cmd space for hw rc %d",
-				rc);
-	}
-
-	return rc;
-}
-
 int cam_hw_cdm_reset_hw(struct cam_hw_info *cdm_hw, uint32_t handle)
 {
 	struct cam_cdm *cdm_core = NULL;

+ 4 - 0
drivers/cam_cdm/cam_cdm_intf_api.h

@@ -1,6 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
  * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #ifndef _CAM_CDM_API_H_
@@ -9,6 +10,7 @@
 #include <media/cam_defs.h>
 #include "cam_cdm_util.h"
 #include "cam_soc_util.h"
+#include "cam_packet_util.h"
 
 #define CAM_CDM_BL_CMD_MAX  25
 
@@ -139,6 +141,7 @@ struct cam_cdm_bl_cmd {
  * @type : type of the submitted bl cmd address.
  * @cmd_arrary_count : Input number of BL commands to be submitted to CDM
  * @cookie : Cookie if the callback is gen irq status
+ * @avail_buff_size: Available buffer size in bytes
  * @bl_cmd_array     : Input payload holding the BL cmd's arrary
  *                     to be sumbitted.
  *
@@ -149,6 +152,7 @@ struct cam_cdm_bl_request {
 	void *userdata;
 	enum cam_cdm_bl_cmd_addr_type type;
 	uint32_t cmd_arrary_count;
+	struct cam_kmd_buf_info *genirq_buff;
 	uint64_t cookie;
 	struct cam_cdm_bl_cmd cmd[1];
 };

+ 26 - 22
drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c

@@ -6096,12 +6096,13 @@ static int cam_ife_mgr_config_hw(void *hw_mgr_priv,
 		ctx->ctx_index, cfg->num_hw_update_entries, cfg->request_id);
 
 	if (cfg->num_hw_update_entries > 0) {
-		cdm_cmd = ctx->cdm_cmd;
-		cdm_cmd->type = CAM_CDM_BL_CMD_TYPE_MEM_HANDLE;
-		cdm_cmd->flag = true;
-		cdm_cmd->userdata = ctx;
-		cdm_cmd->cookie = cfg->request_id;
-		cdm_cmd->gen_irq_arb = false;
+		cdm_cmd                    = ctx->cdm_cmd;
+		cdm_cmd->type              = CAM_CDM_BL_CMD_TYPE_MEM_HANDLE;
+		cdm_cmd->flag              = true;
+		cdm_cmd->userdata          = ctx;
+		cdm_cmd->cookie            = cfg->request_id;
+		cdm_cmd->gen_irq_arb       = false;
+		cdm_cmd->genirq_buff       = &hw_update_data->kmd_cmd_buff_info;
 
 		for (i = 0 ; i < cfg->num_hw_update_entries; i++) {
 			cmd = (cfg->hw_update_entries + i);
@@ -10950,7 +10951,6 @@ static int cam_ife_mgr_prepare_hw_update(void *hw_mgr_priv,
 
 	struct cam_ife_hw_mgr_ctx               *ctx;
 	struct cam_ife_hw_mgr                   *hw_mgr;
-	struct cam_kmd_buf_info                  kmd_buf;
 	uint32_t                                 i;
 	bool                                     fill_ife_fence = true;
 	bool                                     fill_sfe_fence = true;
@@ -10966,8 +10966,7 @@ static int cam_ife_mgr_prepare_hw_update(void *hw_mgr_priv,
 		return -EINVAL;
 	}
 
-	prepare_hw_data = (struct cam_isp_prepare_hw_update_data  *)
-		prepare->priv;
+	prepare_hw_data = (struct cam_isp_prepare_hw_update_data  *)prepare->priv;
 
 	ctx = (struct cam_ife_hw_mgr_ctx *) prepare->ctxt_to_hw_map;
 	hw_mgr = (struct cam_ife_hw_mgr *)hw_mgr_priv;
@@ -10976,18 +10975,17 @@ static int cam_ife_mgr_prepare_hw_update(void *hw_mgr_priv,
 	CAM_DBG(CAM_REQ, "ctx[%pK][%d] Enter for req_id %lld",
 		ctx, ctx->ctx_index, prepare->packet->header.request_id);
 
-	rc = cam_packet_util_validate_packet(prepare->packet,
-		prepare->remain_len);
+	rc = cam_packet_util_validate_packet(prepare->packet, prepare->remain_len);
 	if (rc)
 		return rc;
 
 	/* Pre parse the packet*/
-	rc = cam_packet_util_get_kmd_buffer(prepare->packet, &kmd_buf);
+	rc = cam_packet_util_get_kmd_buffer(prepare->packet, &prepare_hw_data->kmd_cmd_buff_info);
 	if (rc)
 		return rc;
 
 	if (ctx->ctx_config & CAM_IFE_CTX_CFG_FRAME_HEADER_TS) {
-		rc = cam_ife_mgr_util_insert_frame_header(&kmd_buf,
+		rc = cam_ife_mgr_util_insert_frame_header(&prepare_hw_data->kmd_cmd_buff_info,
 			prepare_hw_data);
 		if (rc)
 			return rc;
@@ -11045,7 +11043,7 @@ static int cam_ife_mgr_prepare_hw_update(void *hw_mgr_priv,
 		}
 
 		rc = cam_ife_hw_mgr_update_cmd_buffer(ctx, prepare,
-			&kmd_buf, &cmd_buf_count, i);
+			&prepare_hw_data->kmd_cmd_buff_info, &cmd_buf_count, i);
 
 		if (rc) {
 			CAM_ERR(CAM_ISP, "Add cmd buffer failed base_idx: %d hw_type %d",
@@ -11059,7 +11057,7 @@ static int cam_ife_mgr_prepare_hw_update(void *hw_mgr_priv,
 				hw_mgr->mgr_common.img_iommu_hdl,
 				hw_mgr->mgr_common.img_iommu_hdl_secure,
 				prepare, ctx->base[i].idx,
-				&kmd_buf, ctx->res_list_ife_out,
+				&prepare_hw_data->kmd_cmd_buff_info, ctx->res_list_ife_out,
 				res_list_ife_rd_tmp,
 				CAM_ISP_IFE_OUT_RES_BASE,
 				(CAM_ISP_IFE_OUT_RES_BASE + max_ife_out_res),
@@ -11071,7 +11069,7 @@ static int cam_ife_mgr_prepare_hw_update(void *hw_mgr_priv,
 				hw_mgr->mgr_common.img_iommu_hdl,
 				hw_mgr->mgr_common.img_iommu_hdl_secure,
 				prepare, ctx->base[i].idx,
-				&kmd_buf, ctx->res_list_sfe_out,
+				&prepare_hw_data->kmd_cmd_buff_info, ctx->res_list_sfe_out,
 				&ctx->res_list_ife_in_rd,
 				CAM_ISP_SFE_OUT_RES_BASE,
 				CAM_ISP_SFE_OUT_RES_MAX, fill_sfe_fence,
@@ -11100,7 +11098,7 @@ static int cam_ife_mgr_prepare_hw_update(void *hw_mgr_priv,
 
 			rc = cam_ife_hw_mgr_sfe_scratch_buf_update(
 				prepare_hw_data->packet_opcode_type,
-				i, &kmd_buf, prepare, ctx, sfe_res_info);
+				i, &prepare_hw_data->kmd_cmd_buff_info, prepare, ctx, sfe_res_info);
 			if (rc)
 				goto end;
 		}
@@ -11112,7 +11110,7 @@ static int cam_ife_mgr_prepare_hw_update(void *hw_mgr_priv,
 
 			rc = cam_ife_hw_mgr_ife_scratch_buf_update(
 				prepare_hw_data->packet_opcode_type,
-				i, &kmd_buf, prepare, ctx, ife_res_info);
+				i, &prepare_hw_data->kmd_cmd_buff_info, prepare, ctx, ife_res_info);
 			if (rc)
 				goto end;
 		}
@@ -11187,11 +11185,11 @@ static int cam_ife_mgr_prepare_hw_update(void *hw_mgr_priv,
 	/* add reg update commands */
 	if (hw_mgr->csid_rup_en)
 		rc = cam_ife_mgr_csid_add_reg_update(ctx,
-			prepare, &kmd_buf);
+			prepare, &prepare_hw_data->kmd_cmd_buff_info);
 
 	else
 		rc = cam_ife_mgr_isp_add_reg_update(ctx,
-			prepare, &kmd_buf);
+			prepare, &prepare_hw_data->kmd_cmd_buff_info);
 
 	if (rc) {
 		CAM_ERR(CAM_ISP, "Add RUP fail csid_rup_en %d",
@@ -11205,11 +11203,11 @@ static int cam_ife_mgr_prepare_hw_update(void *hw_mgr_priv,
 		ctx->flags.is_offline) {
 		if (ctx->ctx_type != CAM_IFE_CTX_TYPE_SFE)
 			rc = cam_isp_add_go_cmd(prepare, &ctx->res_list_ife_in_rd,
-				ctx->base[i].idx, &kmd_buf);
+				ctx->base[i].idx, &prepare_hw_data->kmd_cmd_buff_info);
 		else
 			rc = cam_isp_add_csid_offline_cmd(prepare,
 				&ctx->res_list_ife_csid,
-				ctx->base[i].idx, &kmd_buf);
+				ctx->base[i].idx, &prepare_hw_data->kmd_cmd_buff_info);
 		if (rc)
 			CAM_ERR(CAM_ISP,
 				"Add %s GO_CMD faled i: %d, idx: %d, rc: %d",
@@ -11218,6 +11216,12 @@ static int cam_ife_mgr_prepare_hw_update(void *hw_mgr_priv,
 				i, ctx->base[i].idx, rc);
 	}
 
+	if (prepare_hw_data->kmd_cmd_buff_info.size <=
+		prepare_hw_data->kmd_cmd_buff_info.used_bytes) {
+		CAM_ERR(CAM_ISP, "No Sufficient memory for the Gen IRQ command");
+		rc = -ENOMEM;
+	}
+
 end:
 	return rc;
 }

+ 49 - 52
drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.c

@@ -2701,39 +2701,38 @@ static int cam_tfe_mgr_config_hw(void *hw_mgr_priv,
 	cdm_cmd->userdata             = hw_update_data;
 	cdm_cmd->cookie               = cfg->request_id;
 	cdm_cmd->gen_irq_arb          = false;
+	cdm_cmd->genirq_buff          = &hw_update_data->kmd_cmd_buff_info;
 
 	for (i = 0; i < cfg->num_hw_update_entries; i++) {
 		cmd = (cfg->hw_update_entries + i);
-		if ((cfg->reapply_type == CAM_CONFIG_REAPPLY_IO) &&
-			(cmd->flags == CAM_ISP_IQ_BL)) {
+		if ((cfg->reapply_type == CAM_CONFIG_REAPPLY_IO) && (cmd->flags == CAM_ISP_IQ_BL)) {
 			skip++;
 			continue;
 		}
 
-			if (cmd->flags == CAM_ISP_UNUSED_BL ||
-				cmd->flags >= CAM_ISP_BL_MAX)
-				CAM_ERR(CAM_ISP, "Unexpected BL type %d",
-					cmd->flags);
+		if (cmd->flags == CAM_ISP_UNUSED_BL || cmd->flags >= CAM_ISP_BL_MAX)
+			CAM_ERR(CAM_ISP, "Unexpected BL type %d", cmd->flags);
 
-			cdm_cmd->cmd[i - skip].bl_addr.mem_handle = cmd->handle;
-			cdm_cmd->cmd[i - skip].offset = cmd->offset;
-			cdm_cmd->cmd[i - skip].len = cmd->len;
-			cdm_cmd->cmd[i - skip].arbitrate = false;
-		}
-		cdm_cmd->cmd_arrary_count = cfg->num_hw_update_entries - skip;
-		reinit_completion(&ctx->config_done_complete);
-		ctx->applied_req_id = cfg->request_id;
-		CAM_DBG(CAM_ISP, "Submit to CDM");
+		cdm_cmd->cmd[i - skip].bl_addr.mem_handle = cmd->handle;
+		cdm_cmd->cmd[i - skip].offset = cmd->offset;
+		cdm_cmd->cmd[i - skip].len = cmd->len;
+		cdm_cmd->cmd[i - skip].arbitrate = false;
+	}
 
-		atomic_set(&ctx->cdm_done, 0);
+	cdm_cmd->cmd_arrary_count = cfg->num_hw_update_entries - skip;
+	reinit_completion(&ctx->config_done_complete);
+	ctx->applied_req_id = cfg->request_id;
+	CAM_DBG(CAM_ISP, "Submit to CDM");
 
-		rc = cam_cdm_submit_bls(ctx->cdm_handle, cdm_cmd);
-		if (rc) {
-			CAM_ERR(CAM_ISP,
-				"Failed to apply the configs for req %llu, rc %d",
-				cfg->request_id, rc);
-			return rc;
-		}
+	atomic_set(&ctx->cdm_done, 0);
+
+	rc = cam_cdm_submit_bls(ctx->cdm_handle, cdm_cmd);
+	if (rc) {
+		CAM_ERR(CAM_ISP,
+			"Failed to apply the configs for req %llu, rc %d",
+			cfg->request_id, rc);
+		return rc;
+	}
 
 	ctx->packet = (struct cam_packet *)hw_update_data->packet;
 	ctx->last_submit_bl_cmd.bl_count = cdm_cmd->cmd_arrary_count;
@@ -2744,36 +2743,30 @@ static int cam_tfe_mgr_config_hw(void *hw_mgr_priv,
 				cdm_cmd->cmd[i].bl_addr.mem_handle;
 
 			rc = cam_mem_get_io_buf(
-			cdm_cmd->cmd[i].bl_addr.mem_handle,
-			g_tfe_hw_mgr.mgr_common.cmd_iommu_hdl,
-			&ctx->last_submit_bl_cmd.cmd[i].hw_addr,
-			&ctx->last_submit_bl_cmd.cmd[i].len, NULL);
-		} else if (cdm_cmd->type ==
-			CAM_CDM_BL_CMD_TYPE_HW_IOVA) {
+				cdm_cmd->cmd[i].bl_addr.mem_handle,
+				g_tfe_hw_mgr.mgr_common.cmd_iommu_hdl,
+				&ctx->last_submit_bl_cmd.cmd[i].hw_addr,
+				&ctx->last_submit_bl_cmd.cmd[i].len, NULL);
+		} else if (cdm_cmd->type == CAM_CDM_BL_CMD_TYPE_HW_IOVA) {
 			if (!cdm_cmd->cmd[i].bl_addr.hw_iova) {
-				CAM_ERR(CAM_CDM,
-					"Submitted Hw bl hw_iova is invalid %d:%d",
+				CAM_ERR(CAM_CDM, "Submitted Hw bl hw_iova is invalid %d:%d",
 					i, cdm_cmd->cmd_arrary_count);
 				rc = -EINVAL;
 				break;
 			}
 			rc = 0;
 			ctx->last_submit_bl_cmd.cmd[i].hw_addr =
-			(uint64_t)cdm_cmd->cmd[i].bl_addr.hw_iova;
+				(uint64_t)cdm_cmd->cmd[i].bl_addr.hw_iova;
 			ctx->last_submit_bl_cmd.cmd[i].len =
-			cdm_cmd->cmd[i].len + cdm_cmd->cmd[i].offset;
+				cdm_cmd->cmd[i].len + cdm_cmd->cmd[i].offset;
 			ctx->last_submit_bl_cmd.cmd[i].mem_handle = 0;
 		} else
-			CAM_INFO(CAM_ISP,
-				"submitted invalid bl cmd addr type :%d for Bl(%d)",
+			CAM_INFO(CAM_ISP, "submitted invalid bl cmd addr type :%d for Bl(%d)",
 				cdm_cmd->type, i);
 
-		ctx->last_submit_bl_cmd.cmd[i].offset =
-			cdm_cmd->cmd[i].offset;
-		ctx->last_submit_bl_cmd.cmd[i].type =
-			cdm_cmd->type;
-		ctx->last_submit_bl_cmd.cmd[i].input_len =
-		 cdm_cmd->cmd[i].len;
+		ctx->last_submit_bl_cmd.cmd[i].offset = cdm_cmd->cmd[i].offset;
+		ctx->last_submit_bl_cmd.cmd[i].type = cdm_cmd->type;
+		ctx->last_submit_bl_cmd.cmd[i].input_len = cdm_cmd->cmd[i].len;
 	}
 
 	if (!cfg->init_packet)
@@ -4350,7 +4343,6 @@ static int cam_tfe_mgr_prepare_hw_update(void *hw_mgr_priv,
 		(struct cam_hw_prepare_update_args *) prepare_hw_update_args;
 	struct cam_tfe_hw_mgr_ctx               *ctx;
 	struct cam_tfe_hw_mgr                   *hw_mgr;
-	struct cam_kmd_buf_info                  kmd_buf;
 	uint32_t                                 i;
 	bool                                     fill_fence = true;
 	struct cam_isp_prepare_hw_update_data   *prepare_hw_data;
@@ -4378,7 +4370,7 @@ static int cam_tfe_mgr_prepare_hw_update(void *hw_mgr_priv,
 		return rc;
 
 	/* Pre parse the packet*/
-	rc = cam_packet_util_get_kmd_buffer(prepare->packet, &kmd_buf);
+	rc = cam_packet_util_get_kmd_buffer(prepare->packet, &prepare_hw_data->kmd_cmd_buff_info);
 	if (rc)
 		return rc;
 
@@ -4407,7 +4399,7 @@ static int cam_tfe_mgr_prepare_hw_update(void *hw_mgr_priv,
 
 		/* Add change base */
 		rc = cam_isp_add_change_base(prepare, &ctx->res_list_tfe_in,
-			&change_base_info, &kmd_buf);
+			&change_base_info, &prepare_hw_data->kmd_cmd_buff_info);
 		if (rc) {
 			CAM_ERR(CAM_ISP,
 				"Failed in change base i=%d, idx=%d, rc=%d",
@@ -4418,7 +4410,8 @@ static int cam_tfe_mgr_prepare_hw_update(void *hw_mgr_priv,
 
 		/* get command buffers */
 		if (ctx->base[i].split_id != CAM_ISP_HW_SPLIT_MAX) {
-			rc = cam_tfe_add_command_buffers(prepare, &kmd_buf,
+			rc = cam_tfe_add_command_buffers(prepare,
+				&prepare_hw_data->kmd_cmd_buff_info,
 				&ctx->base[i],
 				cam_isp_tfe_packet_generic_blob_handler,
 				ctx->res_list_tfe_out, CAM_TFE_HW_OUT_RES_MAX);
@@ -4438,7 +4431,7 @@ static int cam_tfe_mgr_prepare_hw_update(void *hw_mgr_priv,
 		rc = cam_isp_add_io_buffers(hw_mgr->mgr_common.img_iommu_hdl,
 			hw_mgr->mgr_common.img_iommu_hdl_secure,
 			prepare, ctx->base[i].idx,
-			&kmd_buf, ctx->res_list_tfe_out,
+			&prepare_hw_data->kmd_cmd_buff_info, ctx->res_list_tfe_out,
 			NULL, CAM_ISP_TFE_OUT_RES_BASE,
 			CAM_TFE_HW_OUT_RES_MAX, fill_fence,
 			CAM_ISP_HW_TYPE_TFE,
@@ -4488,12 +4481,10 @@ static int cam_tfe_mgr_prepare_hw_update(void *hw_mgr_priv,
 
 		goto end;
 	} else  {
-		prepare_hw_data->packet_opcode_type =
-		CAM_ISP_TFE_PACKET_CONFIG_DEV;
+		prepare_hw_data->packet_opcode_type = CAM_ISP_TFE_PACKET_CONFIG_DEV;
 		prepare_hw_data->num_reg_dump_buf = prepare->num_reg_dump_buf;
 		if ((prepare_hw_data->num_reg_dump_buf) &&
-			(prepare_hw_data->num_reg_dump_buf <
-			CAM_REG_DUMP_MAX_BUF_ENTRIES)) {
+			(prepare_hw_data->num_reg_dump_buf < CAM_REG_DUMP_MAX_BUF_ENTRIES)) {
 			memcpy(prepare_hw_data->reg_dump_buf_desc,
 				prepare->reg_dump_buf_desc,
 				sizeof(struct cam_cmd_buf_desc) *
@@ -4507,7 +4498,7 @@ static int cam_tfe_mgr_prepare_hw_update(void *hw_mgr_priv,
 		change_base_info.cdm_id = CAM_CDM_MAX;
 		/* Add change base */
 		rc = cam_isp_add_change_base(prepare, &ctx->res_list_tfe_in,
-			&change_base_info, &kmd_buf);
+			&change_base_info, &prepare_hw_data->kmd_cmd_buff_info);
 		if (rc) {
 			CAM_ERR(CAM_ISP,
 				"Failed in change base adding reg_update cmd i=%d, idx=%d, rc=%d",
@@ -4517,7 +4508,7 @@ static int cam_tfe_mgr_prepare_hw_update(void *hw_mgr_priv,
 
 		/*Add reg update */
 		rc = cam_isp_add_reg_update(prepare, &ctx->res_list_tfe_in,
-			ctx->base[i].idx, &kmd_buf);
+			ctx->base[i].idx, &prepare_hw_data->kmd_cmd_buff_info);
 		if (rc) {
 			CAM_ERR(CAM_ISP,
 				"Add Reg_update cmd Failed i=%d, idx=%d, rc=%d",
@@ -4526,6 +4517,12 @@ static int cam_tfe_mgr_prepare_hw_update(void *hw_mgr_priv,
 		}
 	}
 
+	if (prepare_hw_data->kmd_cmd_buff_info.size <=
+		prepare_hw_data->kmd_cmd_buff_info.used_bytes) {
+		CAM_ERR(CAM_ISP, "No Sufficient memory for the Gen IRQ command");
+		rc = -ENOMEM;
+	}
+
 end:
 	return rc;
 }

+ 2 - 0
drivers/cam_isp/isp_hw_mgr/include/cam_isp_hw_mgr_intf.h

@@ -12,6 +12,7 @@
 #include <linux/list.h>
 #include <media/cam_isp.h>
 #include "cam_hw_mgr_intf.h"
+#include "cam_packet_util.h"
 
 /* MAX IFE instance */
 #define CAM_IFE_HW_NUM_MAX       8
@@ -256,6 +257,7 @@ struct cam_isp_prepare_hw_update_data {
 						CAM_REG_DUMP_MAX_BUF_ENTRIES];
 	uint32_t                              num_reg_dump_buf;
 	struct cam_packet                    *packet;
+	struct cam_kmd_buf_info               kmd_cmd_buff_info;
 	uint32_t                              mup_val;
 	uint32_t                              num_exp;
 	bool                                  mup_en;

+ 38 - 30
drivers/cam_ope/ope_hw_mgr/cam_ope_hw_mgr.c

@@ -1747,7 +1747,8 @@ int32_t cam_ope_hw_mgr_cb(uint32_t irq_status, void *data)
 static int cam_ope_mgr_create_kmd_buf(struct cam_ope_hw_mgr *hw_mgr,
 	struct cam_packet *packet,
 	struct cam_hw_prepare_update_args *prepare_args,
-	struct cam_ope_ctx *ctx_data, uint32_t req_idx,
+	struct cam_ope_ctx *ctx_data,
+	struct cam_ope_request *ope_req,
 	uintptr_t   ope_cmd_buf_addr)
 {
 	int i, rc = 0;
@@ -1757,12 +1758,12 @@ static int cam_ope_mgr_create_kmd_buf(struct cam_ope_hw_mgr *hw_mgr,
 	prepare_req.hw_mgr = hw_mgr;
 	prepare_req.packet = packet;
 	prepare_req.prepare_args = prepare_args;
-	prepare_req.req_idx = req_idx;
+	prepare_req.req_idx = ope_req->req_idx;
 	prepare_req.kmd_buf_offset = 0;
 	prepare_req.frame_process =
 		(struct ope_frame_process *)ope_cmd_buf_addr;
 
-	for (i = 0; i < ope_hw_mgr->num_ope; i++)
+	for (i = 0; i < ope_hw_mgr->num_ope; i++) {
 		rc = hw_mgr->ope_dev_intf[i]->hw_ops.process_cmd(
 			hw_mgr->ope_dev_intf[i]->hw_priv,
 			OPE_HW_PREPARE, &prepare_req, sizeof(prepare_req));
@@ -1770,6 +1771,19 @@ static int cam_ope_mgr_create_kmd_buf(struct cam_ope_hw_mgr *hw_mgr,
 			CAM_ERR(CAM_OPE, "OPE Dev prepare failed: %d", rc);
 			goto end;
 		}
+	}
+
+	ope_req->genirq_buff_info.handle         = ope_req->ope_kmd_buf.mem_handle;
+	ope_req->genirq_buff_info.cpu_addr       = (uint32_t *)ope_req->ope_kmd_buf.cpu_addr;
+	ope_req->genirq_buff_info.offset         = prepare_req.kmd_buf_offset;
+	ope_req->genirq_buff_info.used_bytes     = 0;
+	ope_req->genirq_buff_info.size           = ope_req->ope_kmd_buf.size -
+		ope_req->ope_kmd_buf.len - prepare_req.kmd_buf_offset;
+
+	if (!ope_req->genirq_buff_info.size) {
+		CAM_ERR(CAM_OPE, "Not enough memory available for CDM GenIRQ Command");
+		return -ENOMEM;
+	}
 
 end:
 	return rc;
@@ -1900,7 +1914,7 @@ static void cam_ope_mgr_print_stripe_info(uint32_t batch,
 
 static int cam_ope_mgr_process_cmd_io_buf_req(struct cam_ope_hw_mgr *hw_mgr,
 	struct cam_packet *packet, struct cam_ope_ctx *ctx_data,
-	uintptr_t frame_process_addr, size_t length, uint32_t req_idx)
+	uintptr_t frame_process_addr, size_t length, struct cam_ope_request *ope_request)
 {
 	int rc = 0;
 	int i, j, k, l;
@@ -1910,7 +1924,6 @@ static int cam_ope_mgr_process_cmd_io_buf_req(struct cam_ope_hw_mgr *hw_mgr,
 	struct ope_frame_set *in_frame_set;
 	struct ope_io_buf_info *in_io_buf;
 	struct ope_stripe_info *in_stripe_info;
-	struct cam_ope_request *ope_request;
 	struct ope_io_buf *io_buf;
 	struct ope_stripe_io *stripe_info;
 	uint32_t alignment;
@@ -1923,7 +1936,6 @@ static int cam_ope_mgr_process_cmd_io_buf_req(struct cam_ope_hw_mgr *hw_mgr,
 
 	in_frame_process = (struct ope_frame_process *)frame_process_addr;
 
-	ope_request = ctx_data->req_list[req_idx];
 	ope_request->num_batch = in_frame_process->batch_size;
 
 	for (i = 0; i < in_frame_process->batch_size; i++) {
@@ -2079,7 +2091,7 @@ static int cam_ope_mgr_process_cmd_io_buf_req(struct cam_ope_hw_mgr *hw_mgr,
 
 static int cam_ope_mgr_process_cmd_buf_req(struct cam_ope_hw_mgr *hw_mgr,
 	struct cam_packet *packet, struct cam_ope_ctx *ctx_data,
-	uintptr_t frame_process_addr, size_t length, uint32_t req_idx)
+	uintptr_t frame_process_addr, size_t length, struct cam_ope_request *ope_request)
 {
 	int rc = 0;
 	int i, j;
@@ -2089,7 +2101,6 @@ static int cam_ope_mgr_process_cmd_buf_req(struct cam_ope_hw_mgr *hw_mgr,
 	size_t len;
 	struct ope_frame_process *frame_process;
 	struct ope_cmd_buf_info *cmd_buf;
-	struct cam_ope_request *ope_request;
 	bool is_kmd_buf_valid = false;
 
 	frame_process = (struct ope_frame_process *)frame_process_addr;
@@ -2128,7 +2139,6 @@ static int cam_ope_mgr_process_cmd_buf_req(struct cam_ope_hw_mgr *hw_mgr,
 		}
 	}
 
-	ope_request = ctx_data->req_list[req_idx];
 	ope_request->num_batch = frame_process->batch_size;
 
 	for (i = 0; i < frame_process->batch_size; i++) {
@@ -2247,7 +2257,7 @@ end:
 
 static int cam_ope_mgr_process_cmd_desc(struct cam_ope_hw_mgr *hw_mgr,
 	struct cam_packet *packet, struct cam_ope_ctx *ctx_data,
-	uintptr_t *ope_cmd_buf_addr, uint32_t req_idx)
+	uintptr_t *ope_cmd_buf_addr, struct cam_ope_request *ope_request)
 {
 	int rc = 0;
 	int i;
@@ -2255,7 +2265,6 @@ static int cam_ope_mgr_process_cmd_desc(struct cam_ope_hw_mgr *hw_mgr,
 	size_t len;
 	struct cam_cmd_buf_desc *cmd_desc = NULL;
 	uintptr_t cpu_addr = 0;
-	struct cam_ope_request *ope_request;
 
 	cmd_desc = (struct cam_cmd_buf_desc *)
 		((uint32_t *) &packet->payload + packet->cmd_buf_offset/4);
@@ -2266,8 +2275,7 @@ static int cam_ope_mgr_process_cmd_desc(struct cam_ope_hw_mgr *hw_mgr,
 			cmd_desc[i].meta_data == OPE_CMD_META_GENERIC_BLOB)
 			continue;
 
-		rc = cam_mem_get_cpu_buf(cmd_desc[i].mem_handle,
-			&cpu_addr, &len);
+		rc = cam_mem_get_cpu_buf(cmd_desc[i].mem_handle, &cpu_addr, &len);
 		if (rc || !cpu_addr) {
 			CAM_ERR(CAM_OPE, "get cmd buf failed %x",
 				hw_mgr->iommu_hdl);
@@ -2290,19 +2298,17 @@ static int cam_ope_mgr_process_cmd_desc(struct cam_ope_hw_mgr *hw_mgr,
 		return -EINVAL;
 	}
 
-	ope_request = ctx_data->req_list[req_idx];
 	ope_request->request_id = packet->header.request_id;
-	ope_request->req_idx = req_idx;
 
 	rc = cam_ope_mgr_process_cmd_buf_req(hw_mgr, packet, ctx_data,
-		cpu_addr, len, req_idx);
+		cpu_addr, len, ope_request);
 	if (rc) {
 		CAM_ERR(CAM_OPE, "Process OPE cmd request is failed: %d", rc);
 		goto end;
 	}
 
 	rc = cam_ope_mgr_process_cmd_io_buf_req(hw_mgr, packet, ctx_data,
-		cpu_addr, len, req_idx);
+		cpu_addr, len, ope_request);
 	if (rc) {
 		CAM_ERR(CAM_OPE, "Process OPE cmd io request is failed: %d",
 			rc);
@@ -3240,6 +3246,7 @@ static int cam_ope_mgr_prepare_hw_update(void *hw_priv,
 	}
 
 	ope_req = ctx_data->req_list[request_idx];
+	ope_req->req_idx = request_idx;
 	ope_req->cdm_cmd =
 		kzalloc(((sizeof(struct cam_cdm_bl_request)) +
 			((OPE_MAX_CDM_BLS - 1) *
@@ -3253,7 +3260,7 @@ static int cam_ope_mgr_prepare_hw_update(void *hw_priv,
 	}
 
 	rc = cam_ope_mgr_process_cmd_desc(hw_mgr, packet,
-		ctx_data, &ope_cmd_buf_addr, request_idx);
+		ctx_data, &ope_cmd_buf_addr, ope_req);
 	if (rc) {
 		CAM_ERR(CAM_OPE,
 			"cmd desc processing failed :%d ctx: %d req_id:%d",
@@ -3271,7 +3278,7 @@ static int cam_ope_mgr_prepare_hw_update(void *hw_priv,
 	}
 
 	rc = cam_ope_mgr_create_kmd_buf(hw_mgr, packet, prepare_args,
-		ctx_data, request_idx, ope_cmd_buf_addr);
+		ctx_data, ope_req, ope_cmd_buf_addr);
 	if (rc) {
 		CAM_ERR(CAM_OPE,
 			"create kmd buf failed: %d ctx: %d request_id:%d",
@@ -3287,17 +3294,19 @@ static int cam_ope_mgr_prepare_hw_update(void *hw_priv,
 			request_idx);
 		goto end;
 	}
-	prepare_args->num_hw_update_entries = 1;
-	prepare_args->hw_update_entries[0].addr =
-		(uintptr_t)ctx_data->req_list[request_idx]->cdm_cmd;
-	prepare_args->priv = ctx_data->req_list[request_idx];
-	prepare_args->pf_data->packet = packet;
-	prepare_args->pf_data->req    = ope_req;
+
+	ope_req->cdm_cmd->genirq_buff             = &ope_req->genirq_buff_info;
+	ope_req->hang_data.packet                 = packet;
+	prepare_args->num_hw_update_entries       = 1;
+	prepare_args->hw_update_entries[0].addr   = (uintptr_t)ope_req->cdm_cmd;
+	prepare_args->priv                        = ope_req;
+	prepare_args->pf_data->packet             = packet;
+	prepare_args->pf_data->req                = ope_req;
+
 	CAM_INFO(CAM_REQ, "OPE req %x num_batch %d", ope_req, ope_req->num_batch);
-	ope_req->hang_data.packet = packet;
+
 	ktime_get_boottime_ts64(&ts);
-	ctx_data->last_req_time = (uint64_t)((ts.tv_sec * 1000000000) +
-		ts.tv_nsec);
+	ctx_data->last_req_time = (uint64_t)((ts.tv_sec * 1000000000) + ts.tv_nsec);
 	CAM_DBG(CAM_REQ, "req_id= %llu ctx_id= %d lrt=%llu",
 		packet->header.request_id, ctx_data->ctx_id,
 		ctx_data->last_req_time);
@@ -3415,8 +3424,7 @@ static int cam_ope_mgr_config_hw(void *hw_priv, void *hw_config_args)
 	}
 
 	ope_req = config_args->priv;
-	cdm_cmd = (struct cam_cdm_bl_request *)
-		config_args->hw_update_entries->addr;
+	cdm_cmd = (struct cam_cdm_bl_request *) config_args->hw_update_entries->addr;
 	cdm_cmd->cookie = ope_req->req_idx;
 
 	cam_ope_mgr_ope_clk_update(hw_mgr, ctx_data, ope_req->req_idx);

+ 2 - 0
drivers/cam_ope/ope_hw_mgr/cam_ope_hw_mgr.h

@@ -1,6 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
  * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #ifndef CAM_OPE_HW_MGR_H
@@ -405,6 +406,7 @@ struct cam_ope_request {
 	uint8_t num_stripe_cmd_bufs[OPE_MAX_BATCH_SIZE][OPE_MAX_STRIPES];
 	struct ope_kmd_buffer ope_kmd_buf;
 	struct ope_debug_buffer ope_debug_buf;
+	struct cam_kmd_buf_info genirq_buff_info;
 	struct ope_io_buf *io_buf[OPE_MAX_BATCH_SIZE][OPE_MAX_IO_BUFS];
 	struct cam_cdm_bl_request *cdm_cmd;
 	struct cam_ope_clk_bw_request clk_info;

+ 16 - 17
drivers/cam_ope/ope_hw_mgr/ope_hw/ope_core.c

@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
  * Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <linux/of.h>
@@ -389,10 +390,8 @@ static int cam_ope_dev_prepare_cdm_request(
 	cdm_cmd->gen_irq_arb = true;
 
 	i = cdm_cmd->cmd_arrary_count;
-	cdm_cmd->cmd[i].bl_addr.mem_handle =
-		ope_request->ope_kmd_buf.mem_handle;
-	cdm_cmd->cmd[i].offset = kmd_buf_offset +
-		ope_request->ope_kmd_buf.offset;
+	cdm_cmd->cmd[i].bl_addr.mem_handle = ope_request->ope_kmd_buf.mem_handle;
+	cdm_cmd->cmd[i].offset = kmd_buf_offset + ope_request->ope_kmd_buf.offset;
 	cdm_cmd->cmd[i].len = len;
 	cdm_cmd->cmd[i].arbitrate = arbitrate;
 	cdm_cmd->cmd[i].enable_debug_gen_irq = false;
@@ -1219,7 +1218,6 @@ end:
 static int cam_ope_dev_create_kmd_buf_nrt(struct cam_ope_hw_mgr *hw_mgr,
 	struct cam_hw_prepare_update_args *prepare_args,
 	struct cam_ope_ctx *ctx_data, uint32_t req_idx,
-	uint32_t kmd_buf_offset,
 	struct cam_ope_dev_prepare_req *ope_dev_prepare_req)
 {
 	int rc = 0;
@@ -1231,11 +1229,12 @@ static int cam_ope_dev_create_kmd_buf_nrt(struct cam_ope_hw_mgr *hw_mgr,
 	struct ope_bus_rd_io_port_cdm_info *rd_cdm_info;
 	struct ope_frame_process *frm_proc;
 	struct cam_cdm_utils_ops *cdm_ops;
+	uint32_t kmd_buff_offset = ope_dev_prepare_req->kmd_buf_offset;
 
 	frm_proc = ope_dev_prepare_req->frame_process;
 	ope_request = ctx_data->req_list[req_idx];
 	kmd_buf = (uint32_t *)ope_request->ope_kmd_buf.cpu_addr +
-		(kmd_buf_offset / sizeof(len));
+		(ope_dev_prepare_req->kmd_buf_offset / sizeof(len));
 	cdm_kmd_start_addr = kmd_buf;
 	wr_cdm_info =
 		&ope_dev_prepare_req->wr_cdm_batch->io_port_cdm[0];
@@ -1285,7 +1284,7 @@ static int cam_ope_dev_create_kmd_buf_nrt(struct cam_ope_hw_mgr *hw_mgr,
 
 	/* Stripes */
 	kmd_buf = ope_create_stripes_nrt(hw_mgr, ctx_data, req_idx, kmd_buf,
-		ope_dev_prepare_req, &kmd_buf_offset, &cdm_kmd_start_addr);
+		ope_dev_prepare_req, &kmd_buff_offset, &cdm_kmd_start_addr);
 	if (!kmd_buf) {
 		rc = -EINVAL;
 		goto end;
@@ -1301,8 +1300,10 @@ static int cam_ope_dev_create_kmd_buf_nrt(struct cam_ope_hw_mgr *hw_mgr,
 	cam_ope_dev_prepare_cdm_request(ope_dev_prepare_req->hw_mgr,
 		ope_dev_prepare_req->prepare_args,
 		ope_dev_prepare_req->ctx_data, ope_dev_prepare_req->req_idx,
-		kmd_buf_offset, ope_dev_prepare_req,
+		ope_dev_prepare_req->kmd_buf_offset, ope_dev_prepare_req,
 		len, false);
+
+	ope_dev_prepare_req->kmd_buf_offset += len;
 end:
 	return rc;
 }
@@ -1310,7 +1311,6 @@ end:
 static int cam_ope_dev_create_kmd_buf_batch(struct cam_ope_hw_mgr *hw_mgr,
 	struct cam_hw_prepare_update_args *prepare_args,
 	struct cam_ope_ctx *ctx_data, uint32_t req_idx,
-	uint32_t kmd_buf_offset,
 	struct cam_ope_dev_prepare_req *ope_dev_prepare_req)
 {
 	int rc = 0, i;
@@ -1326,7 +1326,7 @@ static int cam_ope_dev_create_kmd_buf_batch(struct cam_ope_hw_mgr *hw_mgr,
 	frm_proc = ope_dev_prepare_req->frame_process;
 	ope_request = ctx_data->req_list[req_idx];
 	kmd_buf = (uint32_t *)ope_request->ope_kmd_buf.cpu_addr +
-		(kmd_buf_offset / sizeof(len));
+		(ope_dev_prepare_req->kmd_buf_offset / sizeof(len));
 	cdm_kmd_start_addr = kmd_buf;
 	cdm_ops = ctx_data->ope_cdm.cdm_ops;
 	kmd_buf = cdm_ops->cdm_write_clear_comp_event(kmd_buf,
@@ -1401,9 +1401,11 @@ static int cam_ope_dev_create_kmd_buf_batch(struct cam_ope_hw_mgr *hw_mgr,
 	cam_ope_dev_prepare_cdm_request(ope_dev_prepare_req->hw_mgr,
 		ope_dev_prepare_req->prepare_args,
 		ope_dev_prepare_req->ctx_data, ope_dev_prepare_req->req_idx,
-		kmd_buf_offset, ope_dev_prepare_req,
+		ope_dev_prepare_req->kmd_buf_offset, ope_dev_prepare_req,
 		len, false);
 
+	ope_dev_prepare_req->kmd_buf_offset += len;
+
 end:
 	return rc;
 }
@@ -1411,7 +1413,6 @@ end:
 static int cam_ope_dev_create_kmd_buf(struct cam_ope_hw_mgr *hw_mgr,
 	struct cam_hw_prepare_update_args *prepare_args,
 	struct cam_ope_ctx *ctx_data, uint32_t req_idx,
-	uint32_t kmd_buf_offset,
 	struct cam_ope_dev_prepare_req *ope_dev_prepare_req)
 {
 	int rc = 0;
@@ -1430,7 +1431,6 @@ static int cam_ope_dev_create_kmd_buf(struct cam_ope_hw_mgr *hw_mgr,
 			ope_dev_prepare_req->prepare_args,
 			ope_dev_prepare_req->ctx_data,
 			ope_dev_prepare_req->req_idx,
-			ope_dev_prepare_req->kmd_buf_offset,
 			ope_dev_prepare_req);
 	}
 
@@ -1440,13 +1440,12 @@ static int cam_ope_dev_create_kmd_buf(struct cam_ope_hw_mgr *hw_mgr,
 		ope_dev_prepare_req->prepare_args,
 		ope_dev_prepare_req->ctx_data,
 		ope_dev_prepare_req->req_idx,
-		ope_dev_prepare_req->kmd_buf_offset,
 		ope_dev_prepare_req);
 	}
 
 	ope_request = ctx_data->req_list[req_idx];
 	kmd_buf = (uint32_t *)ope_request->ope_kmd_buf.cpu_addr +
-		(kmd_buf_offset / sizeof(len));
+		(ope_dev_prepare_req->kmd_buf_offset / sizeof(len));
 	cdm_kmd_start_addr = kmd_buf;
 	cdm_ops = ctx_data->ope_cdm.cdm_ops;
 	wr_cdm_info =
@@ -1456,7 +1455,7 @@ static int cam_ope_dev_create_kmd_buf(struct cam_ope_hw_mgr *hw_mgr,
 
 
 	CAM_DBG(CAM_OPE, "kmd_buf:%x req_idx:%d req_id:%lld offset:%d",
-		kmd_buf, req_idx, ope_request->request_id, kmd_buf_offset);
+		kmd_buf, req_idx, ope_request->request_id, ope_dev_prepare_req->kmd_buf_offset);
 
 	kmd_buf = cdm_ops->cdm_write_clear_comp_event(kmd_buf,
 				OPE_WAIT_COMP_IDLE|OPE_WAIT_COMP_RUP, 0x0);
@@ -1522,6 +1521,7 @@ static int cam_ope_dev_create_kmd_buf(struct cam_ope_hw_mgr *hw_mgr,
 		ope_dev_prepare_req->kmd_buf_offset,
 		ope_dev_prepare_req,
 		len, false);
+	ope_dev_prepare_req->kmd_buf_offset += len;
 end:
 	return rc;
 }
@@ -1554,7 +1554,6 @@ static int cam_ope_dev_process_prepare(struct ope_hw *ope_hw, void *cmd_args)
 			ope_dev_prepare_req->prepare_args,
 			ope_dev_prepare_req->ctx_data,
 			ope_dev_prepare_req->req_idx,
-			ope_dev_prepare_req->kmd_buf_offset,
 			ope_dev_prepare_req);
 
 end:

+ 1 - 1
drivers/cam_utils/cam_packet_util.h

@@ -15,7 +15,7 @@
  * @handle:                Memory handle
  * @cpu_addr:              Cpu address
  * @offset:                Offset from the start of the buffer
- * @size:                  Size of the buffer
+ * @size:                  Size of the buffer in bytes
  * @used_bytes:            Used memory in bytes
  *
  */