Procházet zdrojové kódy

msm: camera: jpeg: Add Support for JPEG retry mechanism

Add support for JPEG Thumbnail retry mechanism. Restructure
the command buffer arrangement, add JPEG generic blob functionality
and add support to notify user when the JPEG Thumbnail encoder
size increases than the threshold size received through blob.

CRs-Fixed: 2999106
Change-Id: Ica74f934939b562a3a88af551bfb5de79399e247
Signed-off-by: Jigar Agrawal <[email protected]>
Jigar Agrawal před 4 roky
rodič
revize
e8f91ce471

+ 1 - 0
drivers/cam_core/cam_context_utils.c

@@ -477,6 +477,7 @@ int32_t cam_context_prepare_dev_to_hw(struct cam_context *ctx,
 	cfg.max_in_map_entries = ctx->max_in_map_entries;
 	cfg.in_map_entries = req->in_map_entries;
 	cfg.pf_data = &(req->pf_data);
+	cfg.priv = req->req_priv;
 
 	rc = ctx->hw_mgr_intf->hw_prepare_update(
 		ctx->hw_mgr_intf->hw_mgr_priv, &cfg);

+ 1 - 1
drivers/cam_jpeg/cam_jpeg_context.c

@@ -198,7 +198,7 @@ int cam_jpeg_context_init(struct cam_jpeg_context *ctx,
 	ctx->base = ctx_base;
 
 	for (i = 0; i < CAM_CTX_REQ_MAX; i++)
-		ctx->req_base[i].req_priv = ctx;
+		ctx->req_base[i].req_priv = &ctx->jpeg_req[i];
 
 	rc = cam_context_init(ctx_base, jpeg_dev_name, CAM_JPEG, ctx_id,
 		NULL, hw_intf, ctx->req_base, CAM_CTX_REQ_MAX);

+ 4 - 2
drivers/cam_jpeg/cam_jpeg_context.h

@@ -15,11 +15,13 @@
 
 /**
  * struct cam_jpeg_context - Jpeg context
- * @base: Base jpeg cam context object
- * @req_base: Common request structure
+ * @base      : Base jpeg cam context object
+ * @jpeg_req  : Jpeg reguest data stored during prepare update
+ * @req_base  : Common request structure
  */
 struct cam_jpeg_context {
 	struct cam_context *base;
+	struct cam_jpeg_request_data jpeg_req[CAM_CTX_REQ_MAX];
 	struct cam_ctx_request req_base[CAM_CTX_REQ_MAX];
 };
 

+ 378 - 218
drivers/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c

@@ -18,6 +18,8 @@
 
 #include "cam_packet_util.h"
 #include "cam_hw.h"
+#include "cam_jpeg_context.h"
+#include "cam_req_mgr_dev.h"
 #include "cam_hw_mgr_intf.h"
 #include "cam_jpeg_hw_mgr_intf.h"
 #include "cam_jpeg_hw_mgr.h"
@@ -29,27 +31,184 @@
 #include "cam_debug_util.h"
 #include "cam_common_util.h"
 #include "cam_cpas_api.h"
+#include "cam_sync_api.h"
 
-#define CAM_JPEG_HW_ENTRIES_MAX  20
-#define CAM_JPEG_CHBASE          0
-#define CAM_JPEG_CFG             1
-#define CAM_JPEG_PARAM           2
+#define CAM_JPEG_HW_ENTRIES_MAX                       20
+
+#define CAM_JPEG_MAX_NUM_CMD_BUFFS                    5
+
+#define CAM_JPEG_CHBASE_CMD_BUFF_IDX                  0
+#define CAM_JPEG_CFG_CMD_BUFF_IDX                     1
+#define CAM_JPEG_PARAM_CMD_BUFF_IDX                   2
+#define CAM_JPEG_THUBMNAIL_SIZE_CMD_BUFF_IDX          3
 
 static struct cam_jpeg_hw_mgr g_jpeg_hw_mgr;
 
-static int32_t cam_jpeg_hw_mgr_cb(uint32_t irq_status,
+static int32_t cam_jpeg_hw_mgr_sched_bottom_half(uint32_t irq_status,
 	int32_t result_size, void *data);
-static int cam_jpeg_mgr_process_cmd(void *priv, void *data);
+static int cam_jpeg_mgr_process_hw_update_entries(void *priv, void *data);
 static int cam_jpeg_insert_cdm_change_base(
 	struct cam_hw_config_args *config_args,
 	struct cam_jpeg_hw_ctx_data *ctx_data,
 	struct cam_jpeg_hw_mgr *hw_mgr);
 
+static int cam_jpeg_generic_blob_handler(void *user_data,
+	uint32_t blob_type, uint32_t blob_size, uint8_t *blob_data)
+{
+	if (!blob_data || !user_data || !blob_size) {
+		CAM_ERR(CAM_JPEG, "Invalid arguments. blob_data: %p user_data: %p blob_size: %u",
+			blob_data, user_data, blob_size);
+		return -EINVAL;
+	}
+
+	CAM_DBG(CAM_JPEG, "blob_type: %u, blob_size: %u", blob_type, blob_size);
+
+	switch(blob_type) {
+	case CAM_JPEG_THUMBNAIL_SIZE_BLOB:
+		*((uint32_t *)user_data) = (uint32_t) *((uint32_t *)blob_data);
+		CAM_DBG(CAM_JPEG, "Thumbnail max size: %u bytes", *((uint32_t *)user_data));
+		break;
+	default:
+		CAM_ERR(CAM_JPEG, "Invalid blob_tye: %u", blob_type);
+		break;
+	}
+
+	return 0;
+}
+
+static int cam_jpeg_add_command_buffers(struct cam_packet *packet,
+	struct cam_hw_prepare_update_args *prepare_args,
+	struct cam_jpeg_hw_ctx_data *ctx_data)
+{
+	struct cam_cmd_buf_desc                          *cmd_desc = NULL;
+	struct cam_jpeg_request_data                     *jpeg_request_data;
+	struct cam_kmd_buf_info                           kmd_buf;
+	struct cam_jpeg_config_inout_param_info          *inout_params;
+	uint32_t                                         *cmd_buf_kaddr;
+	uintptr_t                                         kaddr;
+	size_t                                            len;
+	unsigned int                                      num_entry = 0;
+	unsigned int                                      i;
+	int                                               rc;
+
+	if (!packet || !prepare_args || !ctx_data) {
+		CAM_ERR(CAM_JPEG, "Invalid args: packet: 0x%p, prepare_args: 0x%p, ctx_data: 0x%p",
+			packet, prepare_args, ctx_data);
+		return -EINVAL;
+	}
+
+	jpeg_request_data = (struct cam_jpeg_request_data *) prepare_args->priv;
+
+	if (!jpeg_request_data) {
+		CAM_ERR(CAM_JPEG, "prepare_args private is null");
+		return -EINVAL;
+	}
+
+	cmd_desc = (struct cam_cmd_buf_desc *)
+		((uint32_t *)&packet->payload + (packet->cmd_buf_offset / 4));
+
+	CAM_DBG(CAM_JPEG,
+		"Pkt: %pK req_id: %u cmd_desc: %pK Size: %lu, num_cmd_buffs: %d dev_type: %u",
+		(void *)packet,
+		packet->header.request_id,
+		(void *)cmd_desc,
+		sizeof(struct cam_cmd_buf_desc),
+		packet->num_cmd_buf,
+		ctx_data->jpeg_dev_acquire_info.dev_type);
+
+	num_entry = prepare_args->num_hw_update_entries;
+
+	rc = cam_packet_util_get_kmd_buffer(packet, &kmd_buf);
+	if (rc) {
+		CAM_ERR(CAM_JPEG, "get kmd buf failed %d", rc);
+		return rc;
+	}
+
+	CAM_DBG(CAM_JPEG, "KMD Buffer: used_bytes: %u handle: 0x%x offset: 0x%x",
+		kmd_buf.used_bytes, kmd_buf.handle, kmd_buf.offset);
+
+	/* fill kmd buf info into 1st hw update entry for change base*/
+	prepare_args->hw_update_entries[num_entry].len = (uint32_t)kmd_buf.used_bytes;
+	prepare_args->hw_update_entries[num_entry].handle = (uint32_t)kmd_buf.handle;
+	prepare_args->hw_update_entries[num_entry].offset = (uint32_t)kmd_buf.offset;
+	num_entry++;
+
+	jpeg_request_data->dev_type = ctx_data->jpeg_dev_acquire_info.dev_type;
+	jpeg_request_data->encode_size_buffer_ptr = NULL;
+	jpeg_request_data->request_id = packet->header.request_id;
+	jpeg_request_data->thumbnail_threshold_size = 0;
+
+	CAM_DBG(CAM_JPEG,
+		"Change_Base HW_Entry. Offset: 0x%x Length: %u mem_handle: 0x%x num_entry: %d",
+		prepare_args->hw_update_entries[num_entry].offset,
+		prepare_args->hw_update_entries[num_entry].len,
+		prepare_args->hw_update_entries[num_entry].handle,
+		num_entry);
+
+	for (i = 0; i < packet->num_cmd_buf; i++) {
+		CAM_DBG(CAM_JPEG,
+			"Metadata: %u Offset: 0x%x Length: %u mem_handle: 0x%x num_entry: %d",
+			cmd_desc[i].meta_data, cmd_desc[i].offset,
+			cmd_desc[i].length, cmd_desc[i].mem_handle,
+			num_entry);
+
+		switch(cmd_desc[i].meta_data) {
+		case CAM_JPEG_ENC_PACKET_CONFIG_DATA:
+		case CAM_JPEG_DMA_PACKET_PLANE0_CONFIG_DATA:
+		case CAM_JPEG_DMA_PACKET_PLANE1_CONFIG_DATA:
+			prepare_args->hw_update_entries[num_entry].len =
+				(uint32_t)cmd_desc[i].length;
+			prepare_args->hw_update_entries[num_entry].handle =
+				(uint32_t)cmd_desc[i].mem_handle;
+			prepare_args->hw_update_entries[num_entry].offset =
+				(uint32_t)cmd_desc[i].offset;
+
+			num_entry++;
+			break;
+		case CAM_JPEG_PACKET_INOUT_PARAM:
+			rc = cam_mem_get_cpu_buf(cmd_desc[i].mem_handle,
+				(uintptr_t *)&kaddr, &len);
+			if (rc) {
+				CAM_ERR(CAM_JPEG, "unable to get info for cmd buf: %x %d");
+				return rc;
+			}
+
+			cmd_buf_kaddr = (uint32_t *)kaddr;
+
+			if ((cmd_desc[i].offset / sizeof(uint32_t)) >= len) {
+				CAM_ERR(CAM_JPEG, "Invalid offset: %u cmd buf len: %zu",
+					cmd_desc[i].offset, len);
+				return -EINVAL;
+			}
+
+			cmd_buf_kaddr += (cmd_desc[i].offset / sizeof(uint32_t));
+
+			inout_params = (struct cam_jpeg_config_inout_param_info *)cmd_buf_kaddr;
+			jpeg_request_data->encode_size_buffer_ptr = &inout_params->output_size;
+			CAM_DBG(CAM_JPEG, "encode_size_buf_ptr: 0x%p",
+				jpeg_request_data->encode_size_buffer_ptr);
+			break;
+		case CAM_JPEG_PACKET_GENERIC_BLOB:
+			rc = cam_packet_util_process_generic_cmd_buffer(&cmd_desc[i],
+				&cam_jpeg_generic_blob_handler,
+				(void *)&jpeg_request_data->thumbnail_threshold_size);
+			break;
+		default:
+			CAM_ERR(CAM_JPEG, "Invalid metadata");
+			return -EINVAL;
+		}
+	}
+
+	CAM_DBG(CAM_JPEG, "num_entry: %u", num_entry);
+	prepare_args->num_hw_update_entries = num_entry;
+
+	return rc;
+}
+
 static int cam_jpeg_process_next_hw_update(void *priv, void *data,
 	struct cam_hw_done_event_data *buf_data)
 {
 	int rc;
-	int i = 0;
 	struct cam_jpeg_hw_mgr *hw_mgr = priv;
 	struct cam_hw_update_entry *cmd;
 	struct cam_cdm_bl_request *cdm_cmd;
@@ -103,12 +262,12 @@ static int cam_jpeg_process_next_hw_update(void *priv, void *data,
 
 	/* insert next cdm payload at index */
 	/* for enc or dma 1st pass at index 1 */
-	/* for dma 2nd pass at index 2, for 3rd at 4 */
+	/* for dma 2nd pass at index 2*/
 	if (p_cfg_req->num_hw_entry_processed == 0) {
-		cdm_cfg_to_insert = CAM_JPEG_CFG;
+		cdm_cfg_to_insert = CAM_JPEG_CFG_CMD_BUFF_IDX;
 		pass_num = 1;
 	} else {
-		cdm_cfg_to_insert = p_cfg_req->num_hw_entry_processed + 2;
+		cdm_cfg_to_insert = p_cfg_req->num_hw_entry_processed + 1;
 		pass_num = 2;
 	}
 
@@ -125,8 +284,11 @@ static int cam_jpeg_process_next_hw_update(void *priv, void *data,
 		cmd->offset;
 	cdm_cmd->cmd[cdm_cmd->cmd_arrary_count].len =
 		cmd->len;
-	CAM_DBG(CAM_JPEG, "i %d entry h %d o %d l %d",
-		i, cmd->handle, cmd->offset, cmd->len);
+	CAM_DBG(CAM_JPEG, "Entry: %d, hdl: 0x%x, offset: 0x%x, len: %d",
+		cdm_cmd->cmd_arrary_count,
+		cmd->handle,
+		cmd->offset,
+		cmd->len);
 	cdm_cmd->cmd_arrary_count++;
 
 	rc = cam_cdm_submit_bls(
@@ -166,24 +328,22 @@ end_error:
 	return rc;
 }
 
-static int cam_jpeg_mgr_process_irq(void *priv, void *data)
+static int cam_jpeg_mgr_bottom_half_irq(void *priv, void *data)
 {
-	int rc = 0;
-	int mem_hdl = 0;
-	struct cam_jpeg_process_irq_work_data_t *task_data;
-	struct cam_jpeg_hw_mgr *hw_mgr;
-	int32_t i;
-	struct cam_jpeg_hw_ctx_data *ctx_data = NULL;
-	struct cam_hw_done_event_data buf_data;
-	struct cam_jpeg_set_irq_cb irq_cb;
-	uintptr_t dev_type = 0;
-	uintptr_t kaddr;
-	uint32_t *cmd_buf_kaddr;
-	size_t cmd_buf_len;
-	struct cam_jpeg_config_inout_param_info *p_params;
-	struct cam_jpeg_hw_cfg_req *p_cfg_req = NULL;
-	struct crm_workq_task *task;
-	struct cam_jpeg_process_frame_work_data_t *wq_task_data;
+	int                                                      rc = 0;
+	int32_t                                                  i;
+	uintptr_t                                                dev_type = 0;
+	struct cam_jpeg_process_irq_work_data_t                 *task_data;
+	struct cam_jpeg_hw_ctx_data                             *ctx_data = NULL;
+	struct cam_context                                      *cam_ctx = NULL;
+	struct cam_hw_done_event_data                            buf_data;
+	struct cam_jpeg_set_irq_cb                               irq_cb;
+	struct cam_jpeg_irq_cb_data                             *irq_cb_data;
+	struct cam_jpeg_hw_cfg_req                              *p_cfg_req = NULL;
+	struct crm_workq_task                                   *task;
+	struct cam_jpeg_process_frame_work_data_t               *wq_task_data;
+	struct cam_jpeg_request_data                            *jpeg_req;
+	struct cam_req_mgr_message                               v4l2_msg = {0};
 
 	if (!data || !priv) {
 		CAM_ERR(CAM_JPEG, "Invalid data");
@@ -191,21 +351,28 @@ static int cam_jpeg_mgr_process_irq(void *priv, void *data)
 	}
 
 	task_data = data;
-	hw_mgr = &g_jpeg_hw_mgr;
 
-	ctx_data = (struct cam_jpeg_hw_ctx_data *)task_data->data;
+	irq_cb_data = (struct cam_jpeg_irq_cb_data *)task_data->data;
+
+	ctx_data = (struct cam_jpeg_hw_ctx_data *)irq_cb_data->private_data;
 	if (!ctx_data->in_use) {
 		CAM_ERR(CAM_JPEG, "ctx is not in use");
 		return -EINVAL;
 	}
 
+	cam_ctx = (struct cam_context *) ctx_data->context_priv;
+	if (!cam_ctx) {
+		CAM_ERR(CAM_JPEG, "cam_ctx is null");
+		return -EINVAL;
+	}
+
 	dev_type = ctx_data->jpeg_dev_acquire_info.dev_type;
 
 	mutex_lock(&g_jpeg_hw_mgr.hw_mgr_mutex);
 
-	p_cfg_req = hw_mgr->dev_hw_cfg_args[dev_type][0];
+	p_cfg_req = g_jpeg_hw_mgr.dev_hw_cfg_args[dev_type][0];
 
-	if (hw_mgr->device_in_use[dev_type][0] == false ||
+	if (g_jpeg_hw_mgr.device_in_use[dev_type][0] == false ||
 		p_cfg_req == NULL) {
 		CAM_ERR(CAM_JPEG, "irq for old request %d", rc);
 		mutex_unlock(&g_jpeg_hw_mgr.hw_mgr_mutex);
@@ -213,148 +380,157 @@ static int cam_jpeg_mgr_process_irq(void *priv, void *data)
 	}
 
 	p_cfg_req->num_hw_entry_processed++;
-	CAM_DBG(CAM_JPEG, "hw entry processed %d",
+	CAM_DBG(CAM_JPEG, "dev_type: %u, hw_entry_processed %d",
+		dev_type,
 		p_cfg_req->num_hw_entry_processed);
 
-	if ((task_data->result_size > 0) &&
-		(p_cfg_req->num_hw_entry_processed <
-			p_cfg_req->hw_cfg_args.num_hw_update_entries - 2)) {
-		/* start processing next entry before marking device free */
-		rc  = cam_jpeg_process_next_hw_update(priv, ctx_data,
-			&buf_data);
-		if (!rc) {
-			mutex_unlock(&g_jpeg_hw_mgr.hw_mgr_mutex);
-			return 0;
+	/* If we have processed just plane 1 for jpeg dma,
+	 * send the configuration data for plane 1 as well.*/
+	if (dev_type == CAM_JPEG_RES_TYPE_DMA) {
+		if ((task_data->u.is_dma_frame_done) && (p_cfg_req->num_hw_entry_processed < 2)) {
+			/* Processes next entry before freeing the device */
+			rc  = cam_jpeg_process_next_hw_update(priv, ctx_data,
+				&buf_data);
+			if (!rc) {
+				mutex_unlock(&g_jpeg_hw_mgr.hw_mgr_mutex);
+				return 0;
+			}
+		}
+	}
+
+	jpeg_req = irq_cb_data->jpeg_req;
+
+	if (jpeg_req->dev_type == CAM_JPEG_RES_TYPE_ENC) {
+		if (jpeg_req->encode_size_buffer_ptr)
+			*jpeg_req->encode_size_buffer_ptr = task_data->u.output_encode_size;
+		else
+			CAM_ERR(CAM_JPEG, "Buffer pointer for inout param is null");
+
+		CAM_DBG(CAM_JPEG, "Encoded Size %d Thresold Size: %u",
+			task_data->u.output_encode_size,
+			jpeg_req->thumbnail_threshold_size);
+
+		if (jpeg_req->thumbnail_threshold_size) {
+			if (task_data->u.output_encode_size > jpeg_req->thumbnail_threshold_size) {
+				CAM_DBG(CAM_JPEG, "Thumbnail max size: %u dev_type: %u",
+					jpeg_req->thumbnail_threshold_size, jpeg_req->dev_type);
+				v4l2_msg.session_hdl = cam_ctx->session_hdl;
+				v4l2_msg.u.node_msg.request_id = jpeg_req->request_id;
+				v4l2_msg.u.node_msg.link_hdl = cam_ctx->link_hdl;
+				v4l2_msg.u.node_msg.device_hdl = cam_ctx->dev_hdl;
+				v4l2_msg.u.node_msg.event_type = CAM_REQ_MGR_RETRY_EVENT;
+				v4l2_msg.u.node_msg.event_cause =
+					CAM_REQ_MGR_JPEG_THUBNAIL_SIZE_ERROR;
+				cam_req_mgr_notify_message(&v4l2_msg,
+					V4L_EVENT_CAM_REQ_MGR_NODE_EVENT,
+					V4L_EVENT_CAM_REQ_MGR_EVENT);
+
+				for (i = 0; i < p_cfg_req->hw_cfg_args.num_out_map_entries; i++) {
+					cam_sync_put_obj_ref(
+						p_cfg_req->hw_cfg_args.out_map_entries[i].sync_id);
+				}
+
+				goto exit;
+			}
 		}
 	}
 
-	irq_cb.jpeg_hw_mgr_cb = cam_jpeg_hw_mgr_cb;
-	irq_cb.data = NULL;
+	buf_data.num_handles = p_cfg_req->hw_cfg_args.num_out_map_entries;
+	for (i = 0; i < buf_data.num_handles; i++) {
+		buf_data.resource_handle[i] =
+			p_cfg_req->hw_cfg_args.out_map_entries[i].resource_handle;
+	}
+
+	buf_data.request_id = jpeg_req->request_id;
+	ctx_data->ctxt_event_cb(ctx_data->context_priv, CAM_CTX_EVT_ID_SUCCESS,
+		&buf_data);
+
+exit:
+	irq_cb.jpeg_hw_mgr_cb = cam_jpeg_hw_mgr_sched_bottom_half;
+	irq_cb.irq_cb_data.private_data = NULL;
+	irq_cb.irq_cb_data.jpeg_req = NULL;
 	irq_cb.b_set_cb = false;
-	if (!hw_mgr->devices[dev_type][0]->hw_ops.process_cmd) {
-		CAM_ERR(CAM_JPEG, "process_cmd null ");
-		mutex_unlock(&g_jpeg_hw_mgr.hw_mgr_mutex);
-		return -EINVAL;
+
+	if (!g_jpeg_hw_mgr.devices[dev_type][0]->hw_ops.process_cmd) {
+		CAM_ERR(CAM_JPEG, "process_cmd null");
+		rc = -EINVAL;
+		goto err;
 	}
-	rc = hw_mgr->devices[dev_type][0]->hw_ops.process_cmd(
-		hw_mgr->devices[dev_type][0]->hw_priv,
+	rc = g_jpeg_hw_mgr.devices[dev_type][0]->hw_ops.process_cmd(
+		g_jpeg_hw_mgr.devices[dev_type][0]->hw_priv,
 		CAM_JPEG_CMD_SET_IRQ_CB,
 		&irq_cb, sizeof(irq_cb));
 	if (rc) {
 		CAM_ERR(CAM_JPEG, "CMD_SET_IRQ_CB failed %d", rc);
-		mutex_unlock(&g_jpeg_hw_mgr.hw_mgr_mutex);
-		return rc;
+		goto err;
 	}
 
-	if (hw_mgr->devices[dev_type][0]->hw_ops.deinit) {
-		rc = hw_mgr->devices[dev_type][0]->hw_ops.deinit(
-			hw_mgr->devices[dev_type][0]->hw_priv, NULL, 0);
+	if (g_jpeg_hw_mgr.devices[dev_type][0]->hw_ops.deinit) {
+		rc = g_jpeg_hw_mgr.devices[dev_type][0]->hw_ops.deinit(
+			g_jpeg_hw_mgr.devices[dev_type][0]->hw_priv, NULL, 0);
 		if (rc)
 			CAM_ERR(CAM_JPEG, "Failed to Deinit %lu HW", dev_type);
 	}
 
-	hw_mgr->device_in_use[dev_type][0] = false;
-	hw_mgr->dev_hw_cfg_args[dev_type][0] = NULL;
-	mutex_unlock(&g_jpeg_hw_mgr.hw_mgr_mutex);
+	g_jpeg_hw_mgr.device_in_use[dev_type][0] = false;
+	g_jpeg_hw_mgr.dev_hw_cfg_args[dev_type][0] = NULL;
 
-	task = cam_req_mgr_workq_get_task(
-		g_jpeg_hw_mgr.work_process_frame);
+	task = cam_req_mgr_workq_get_task(g_jpeg_hw_mgr.work_process_frame);
 	if (!task) {
 		CAM_ERR(CAM_JPEG, "no empty task");
-		return -EINVAL;
+		rc = -EINVAL;
+		goto err;
 	}
 
-	wq_task_data = (struct cam_jpeg_process_frame_work_data_t *)
-		task->payload;
+	wq_task_data = (struct cam_jpeg_process_frame_work_data_t *)task->payload;
 	if (!task_data) {
 		CAM_ERR(CAM_JPEG, "task_data is NULL");
-		return -EINVAL;
+		rc = -EINVAL;
+		goto err;
 	}
-	wq_task_data->data = (void *)dev_type;
+
+	wq_task_data->data = NULL;
 	wq_task_data->request_id = 0;
 	wq_task_data->type = CAM_JPEG_WORKQ_TASK_CMD_TYPE;
-	task->process_cb = cam_jpeg_mgr_process_cmd;
+	task->process_cb = cam_jpeg_mgr_process_hw_update_entries;
 	rc = cam_req_mgr_workq_enqueue_task(task, &g_jpeg_hw_mgr,
 		CRM_TASK_PRIORITY_0);
 	if (rc) {
 		CAM_ERR(CAM_JPEG, "could not enque task %d", rc);
-		return rc;
-	}
-
-	mem_hdl =
-		p_cfg_req->hw_cfg_args.hw_update_entries[CAM_JPEG_PARAM].handle;
-	rc = cam_mem_get_cpu_buf(mem_hdl, &kaddr, &cmd_buf_len);
-	if (rc) {
-		CAM_ERR(CAM_JPEG, "unable to get info for cmd buf: %x %d",
-			hw_mgr->iommu_hdl, rc);
-		return rc;
-	}
-
-	cmd_buf_kaddr = (uint32_t *)kaddr;
-
-	if ((p_cfg_req->hw_cfg_args.hw_update_entries[CAM_JPEG_PARAM].offset /
-			sizeof(uint32_t)) >= cmd_buf_len) {
-		CAM_ERR(CAM_JPEG, "Invalid offset: %u cmd buf len: %zu",
-			p_cfg_req->hw_cfg_args.hw_update_entries[
-			CAM_JPEG_PARAM].offset, cmd_buf_len);
-		return -EINVAL;
-	}
-
-	cmd_buf_kaddr =
-		(cmd_buf_kaddr +
-		(p_cfg_req->hw_cfg_args.hw_update_entries[CAM_JPEG_PARAM].offset
-			/ sizeof(uint32_t)));
-
-	p_params = (struct cam_jpeg_config_inout_param_info *)cmd_buf_kaddr;
-
-	p_params->output_size = task_data->result_size;
-	CAM_DBG(CAM_JPEG, "Encoded Size %d", task_data->result_size);
-
-	buf_data.num_handles =
-		p_cfg_req->hw_cfg_args.num_out_map_entries;
-	for (i = 0; i < buf_data.num_handles; i++) {
-		buf_data.resource_handle[i] =
-		p_cfg_req->hw_cfg_args.out_map_entries[i].resource_handle;
+		goto err;
 	}
-	buf_data.request_id =
-		PTR_TO_U64(p_cfg_req->hw_cfg_args.priv);
-	ctx_data->ctxt_event_cb(ctx_data->context_priv, CAM_CTX_EVT_ID_SUCCESS,
-		&buf_data);
 
-	mutex_lock(&g_jpeg_hw_mgr.hw_mgr_mutex);
-	list_add_tail(&p_cfg_req->list, &hw_mgr->free_req_list);
+	list_add_tail(&p_cfg_req->list, &g_jpeg_hw_mgr.free_req_list);
+err:
 	mutex_unlock(&g_jpeg_hw_mgr.hw_mgr_mutex);
 	return rc;
 }
 
-static int cam_jpeg_hw_mgr_cb(
-	uint32_t irq_status, int32_t result_size, void *data)
+static int cam_jpeg_hw_mgr_sched_bottom_half(uint32_t irq_status, int32_t irq_data, void *data)
 {
 	int32_t rc;
 	unsigned long flags;
-	struct cam_jpeg_hw_mgr *hw_mgr = &g_jpeg_hw_mgr;
 	struct crm_workq_task *task;
 	struct cam_jpeg_process_irq_work_data_t *task_data;
 
-	spin_lock_irqsave(&hw_mgr->hw_mgr_lock, flags);
-	task = cam_req_mgr_workq_get_task(
-		g_jpeg_hw_mgr.work_process_irq_cb);
+	spin_lock_irqsave(&g_jpeg_hw_mgr.hw_mgr_lock, flags);
+	task = cam_req_mgr_workq_get_task(g_jpeg_hw_mgr.work_process_irq_cb);
 	if (!task) {
 		CAM_ERR(CAM_JPEG, "no empty task");
-		spin_unlock_irqrestore(&hw_mgr->hw_mgr_lock, flags);
+		spin_unlock_irqrestore(&g_jpeg_hw_mgr.hw_mgr_lock, flags);
 		return -ENOMEM;
 	}
 
 	task_data = (struct cam_jpeg_process_irq_work_data_t *)task->payload;
 	task_data->data = data;
 	task_data->irq_status = irq_status;
-	task_data->result_size = result_size;
+	task_data->u.irq_data = irq_data;
 	task_data->type = CAM_JPEG_WORKQ_TASK_MSG_TYPE;
-	task->process_cb = cam_jpeg_mgr_process_irq;
+	task->process_cb = cam_jpeg_mgr_bottom_half_irq;
 
 	rc = cam_req_mgr_workq_enqueue_task(task, &g_jpeg_hw_mgr,
 		CRM_TASK_PRIORITY_0);
-	spin_unlock_irqrestore(&hw_mgr->hw_mgr_lock, flags);
+	spin_unlock_irqrestore(&g_jpeg_hw_mgr.hw_mgr_lock, flags);
 
 	return rc;
 }
@@ -414,7 +590,7 @@ static int cam_jpeg_insert_cdm_change_base(
 	size_t ch_base_len;
 
 	rc = cam_mem_get_cpu_buf(
-		config_args->hw_update_entries[CAM_JPEG_CHBASE].handle,
+		config_args->hw_update_entries[CAM_JPEG_CHBASE_CMD_BUFF_IDX].handle,
 		&iova_addr, &ch_base_len);
 	if (rc) {
 		CAM_ERR(CAM_JPEG,
@@ -422,19 +598,17 @@ static int cam_jpeg_insert_cdm_change_base(
 		return rc;
 	}
 
-	if (config_args->hw_update_entries[CAM_JPEG_CHBASE].offset >=
+	if (config_args->hw_update_entries[CAM_JPEG_CHBASE_CMD_BUFF_IDX].offset >=
 		ch_base_len) {
 		CAM_ERR(CAM_JPEG, "Not enough buf offset %d len %d",
-			config_args->hw_update_entries[CAM_JPEG_CHBASE].offset,
+			config_args->hw_update_entries[CAM_JPEG_CHBASE_CMD_BUFF_IDX].offset,
 			ch_base_len);
 		return -EINVAL;
 	}
-	CAM_DBG(CAM_JPEG, "iova %pK len %zu offset %d",
-		(void *)iova_addr, ch_base_len,
-		config_args->hw_update_entries[CAM_JPEG_CHBASE].offset);
+
 	ch_base_iova_addr = (uint32_t *)iova_addr;
 	ch_base_iova_addr = (ch_base_iova_addr +
-		(config_args->hw_update_entries[CAM_JPEG_CHBASE].offset /
+		(config_args->hw_update_entries[CAM_JPEG_CHBASE_CMD_BUFF_IDX].offset /
 		sizeof(uint32_t)));
 
 	dev_type = ctx_data->jpeg_dev_acquire_info.dev_type;
@@ -446,10 +620,16 @@ static int cam_jpeg_insert_cdm_change_base(
 
 	cdm_cmd = ctx_data->cdm_cmd;
 	cdm_cmd->cmd[cdm_cmd->cmd_arrary_count].bl_addr.mem_handle =
-		config_args->hw_update_entries[CAM_JPEG_CHBASE].handle;
+		config_args->hw_update_entries[CAM_JPEG_CHBASE_CMD_BUFF_IDX].handle;
 	cdm_cmd->cmd[cdm_cmd->cmd_arrary_count].offset =
-		config_args->hw_update_entries[CAM_JPEG_CHBASE].offset;
+		config_args->hw_update_entries[CAM_JPEG_CHBASE_CMD_BUFF_IDX].offset;
 	cdm_cmd->cmd[cdm_cmd->cmd_arrary_count].len = size * sizeof(uint32_t);
+	CAM_DBG(CAM_JPEG, "Entry: %d, hdl: 0x%x, offset: 0x%x, len: %d, addr: 0x%p",
+		cdm_cmd->cmd_arrary_count,
+		cdm_cmd->cmd[cdm_cmd->cmd_arrary_count].bl_addr.mem_handle,
+		cdm_cmd->cmd[cdm_cmd->cmd_arrary_count].offset,
+		cdm_cmd->cmd[cdm_cmd->cmd_arrary_count].len,
+		(void *)iova_addr);
 	cdm_cmd->cmd_arrary_count++;
 	cdm_cmd->gen_irq_arb = false;
 
@@ -461,22 +641,22 @@ static int cam_jpeg_insert_cdm_change_base(
 	return rc;
 }
 
-static int cam_jpeg_mgr_process_cmd(void *priv, void *data)
+static int cam_jpeg_mgr_process_hw_update_entries(void *priv, void *data)
 {
-	int rc;
-	int i = 0;
-	struct cam_jpeg_hw_mgr *hw_mgr = priv;
-	struct cam_hw_config_args *config_args = NULL;
-	struct cam_jpeg_hw_ctx_data *ctx_data = NULL;
-	uintptr_t request_id = 0;
-	struct cam_jpeg_process_frame_work_data_t *task_data =
-		(struct cam_jpeg_process_frame_work_data_t *)data;
-	uint32_t dev_type;
-	struct cam_jpeg_set_irq_cb irq_cb;
-	struct cam_jpeg_hw_cfg_req *p_cfg_req = NULL;
-	struct cam_hw_done_event_data buf_data;
-	struct cam_hw_config_args *hw_cfg_args = NULL;
-
+	int                                                        rc;
+	int                                                        i = 0;
+	uintptr_t                                                  request_id = 0;
+	uint32_t                                                   dev_type;
+	struct cam_jpeg_hw_mgr                                    *hw_mgr = priv;
+	struct cam_hw_config_args                                 *config_args = NULL;
+	struct cam_jpeg_hw_ctx_data                               *ctx_data = NULL;
+	struct cam_jpeg_request_data                              *jpeg_req;
+	struct cam_jpeg_process_frame_work_data_t                 *task_data;
+	struct cam_jpeg_set_irq_cb                                 irq_cb;
+	struct cam_jpeg_hw_cfg_req                                *p_cfg_req = NULL;
+	struct cam_hw_done_event_data                              buf_data;
+
+	task_data = (struct cam_jpeg_process_frame_work_data_t *)data;
 	if (!hw_mgr || !task_data) {
 		CAM_ERR(CAM_JPEG, "Invalid arguments %pK %pK",
 			hw_mgr, task_data);
@@ -511,9 +691,10 @@ static int cam_jpeg_mgr_process_cmd(void *priv, void *data)
 
 	config_args = (struct cam_hw_config_args *)&p_cfg_req->hw_cfg_args;
 	request_id = task_data->request_id;
-	if (request_id != (uintptr_t)config_args->priv) {
-		CAM_DBG(CAM_JPEG, "not a recent req %zd %zd",
-			request_id, (uintptr_t)config_args->priv);
+	jpeg_req = (struct cam_jpeg_request_data *)config_args->priv;
+	if (request_id != (uintptr_t)jpeg_req->request_id) {
+		CAM_DBG(CAM_JPEG, "Probably received req from Bottom half. req %zd %zd",
+			request_id, (uintptr_t)jpeg_req->request_id);
 	}
 
 	if (!config_args->num_hw_update_entries) {
@@ -533,6 +714,9 @@ static int cam_jpeg_mgr_process_cmd(void *priv, void *data)
 
 	dev_type = ctx_data->jpeg_dev_acquire_info.dev_type;
 
+	CAM_DBG(CAM_JPEG, "req_id: %u, dev_type: %u",
+		request_id, dev_type);
+
 	if (dev_type != p_cfg_req->dev_type)
 		CAM_WARN(CAM_JPEG, "dev types not same something wrong");
 
@@ -550,8 +734,9 @@ static int cam_jpeg_mgr_process_cmd(void *priv, void *data)
 		goto end;
 	}
 
-	irq_cb.jpeg_hw_mgr_cb = cam_jpeg_hw_mgr_cb;
-	irq_cb.data = (void *)ctx_data;
+	irq_cb.jpeg_hw_mgr_cb = cam_jpeg_hw_mgr_sched_bottom_half;
+	irq_cb.irq_cb_data.private_data = (void *)ctx_data;
+	irq_cb.irq_cb_data.jpeg_req = jpeg_req;
 	irq_cb.b_set_cb = true;
 	if (!hw_mgr->devices[dev_type][0]->hw_ops.process_cmd) {
 		CAM_ERR(CAM_JPEG, "op process_cmd null ");
@@ -584,15 +769,13 @@ static int cam_jpeg_mgr_process_cmd(void *priv, void *data)
 end_callcb:
 	mutex_unlock(&hw_mgr->hw_mgr_mutex);
 	if (p_cfg_req) {
-		hw_cfg_args = &p_cfg_req->hw_cfg_args;
 		buf_data.num_handles =
-			hw_cfg_args->num_out_map_entries;
+			config_args->num_out_map_entries;
 		for (i = 0; i < buf_data.num_handles; i++) {
 			buf_data.resource_handle[i] =
-			hw_cfg_args->out_map_entries[i].resource_handle;
+			config_args->out_map_entries[i].resource_handle;
 		}
-		buf_data.request_id =
-			(uintptr_t)p_cfg_req->hw_cfg_args.priv;
+		buf_data.request_id = (uintptr_t)jpeg_req->request_id;
 		ctx_data->ctxt_event_cb(ctx_data->context_priv,
 			CAM_CTX_EVT_ID_ERROR, &buf_data);
 	}
@@ -608,15 +791,15 @@ end:
 
 static int cam_jpeg_mgr_config_hw(void *hw_mgr_priv, void *config_hw_args)
 {
-	int rc;
-	struct cam_jpeg_hw_mgr *hw_mgr = hw_mgr_priv;
-	struct cam_hw_config_args *config_args = config_hw_args;
-	struct cam_jpeg_hw_ctx_data *ctx_data = NULL;
-	uintptr_t request_id = 0;
-	struct cam_hw_update_entry *hw_update_entries;
-	struct crm_workq_task *task;
-	struct cam_jpeg_process_frame_work_data_t *task_data;
-	struct cam_jpeg_hw_cfg_req *p_cfg_req = NULL;
+	struct cam_jpeg_hw_mgr                             *hw_mgr = hw_mgr_priv;
+	struct cam_hw_config_args                          *config_args = config_hw_args;
+	struct cam_jpeg_hw_ctx_data                        *ctx_data = NULL;
+	struct cam_jpeg_request_data                       *jpeg_req;
+	struct cam_hw_update_entry                         *hw_update_entries;
+	struct crm_workq_task                              *task;
+	struct cam_jpeg_process_frame_work_data_t          *task_data;
+	struct cam_jpeg_hw_cfg_req                         *p_cfg_req = NULL;
+	int                                                 rc;
 
 	if (!hw_mgr || !config_args) {
 		CAM_ERR(CAM_JPEG, "Invalid arguments %pK %pK",
@@ -652,12 +835,12 @@ static int cam_jpeg_mgr_config_hw(void *hw_mgr_priv, void *config_hw_args)
 	p_cfg_req->hw_cfg_args = *config_args;
 	p_cfg_req->dev_type = ctx_data->jpeg_dev_acquire_info.dev_type;
 
-	request_id = (uintptr_t)config_args->priv;
-	p_cfg_req->req_id = request_id;
+	jpeg_req = (struct cam_jpeg_request_data *)config_args->priv;
+	p_cfg_req->req_id = (uintptr_t)jpeg_req->request_id;
 	p_cfg_req->num_hw_entry_processed = 0;
 	hw_update_entries = config_args->hw_update_entries;
-	CAM_DBG(CAM_JPEG, "ctx_data = %pK req_id = %lld %zd",
-		ctx_data, request_id, (uintptr_t)config_args->priv);
+	CAM_DBG(CAM_JPEG, "req_id: %u, dev_type: %d",
+		p_cfg_req->req_id, ctx_data->jpeg_dev_acquire_info.dev_type);
 	task = cam_req_mgr_workq_get_task(g_jpeg_hw_mgr.work_process_frame);
 	if (!task) {
 		CAM_ERR(CAM_JPEG, "no empty task");
@@ -666,7 +849,6 @@ static int cam_jpeg_mgr_config_hw(void *hw_mgr_priv, void *config_hw_args)
 		goto err_after_dq_free_list;
 	}
 
-
 	task_data = (struct cam_jpeg_process_frame_work_data_t *)
 		task->payload;
 	if (!task_data) {
@@ -682,10 +864,10 @@ static int cam_jpeg_mgr_config_hw(void *hw_mgr_priv, void *config_hw_args)
 	list_add_tail(&p_cfg_req->list, &hw_mgr->hw_config_req_list);
 	mutex_unlock(&hw_mgr->hw_mgr_mutex);
 
-	task_data->data = (void *)(uintptr_t)p_cfg_req->dev_type;
-	task_data->request_id = request_id;
+	task_data->data = config_args->priv;
+	task_data->request_id = (uintptr_t)jpeg_req->request_id;
 	task_data->type = CAM_JPEG_WORKQ_TASK_CMD_TYPE;
-	task->process_cb = cam_jpeg_mgr_process_cmd;
+	task->process_cb = cam_jpeg_mgr_process_hw_update_entries;
 
 	rc = cam_req_mgr_workq_enqueue_task(task, &g_jpeg_hw_mgr,
 		CRM_TASK_PRIORITY_0);
@@ -713,9 +895,7 @@ static int cam_jpeg_mgr_prepare_hw_update(void *hw_mgr_priv,
 	struct cam_jpeg_hw_mgr *hw_mgr = hw_mgr_priv;
 	struct cam_jpeg_hw_ctx_data *ctx_data = NULL;
 	struct cam_packet *packet = NULL;
-	struct cam_cmd_buf_desc *cmd_desc = NULL;
 	struct cam_buf_io_cfg *io_cfg_ptr = NULL;
-	struct cam_kmd_buf_info kmd_buf;
 
 	if (!prepare_args || !hw_mgr) {
 		CAM_ERR(CAM_JPEG, "Invalid args %pK %pK",
@@ -752,7 +932,7 @@ static int cam_jpeg_mgr_prepare_hw_update(void *hw_mgr_priv,
 		return rc;
 	}
 
-	if ((packet->num_cmd_buf > 5) || !packet->num_patches ||
+	if ((packet->num_cmd_buf > CAM_JPEG_MAX_NUM_CMD_BUFFS) || !packet->num_patches ||
 		!packet->num_io_configs) {
 		CAM_ERR(CAM_JPEG, "wrong number of cmd/patch info: %u %u",
 			packet->num_cmd_buf,
@@ -760,13 +940,6 @@ static int cam_jpeg_mgr_prepare_hw_update(void *hw_mgr_priv,
 		return -EINVAL;
 	}
 
-	cmd_desc = (struct cam_cmd_buf_desc *)
-		((uint32_t *)&packet->payload +
-		(packet->cmd_buf_offset / 4));
-	CAM_DBG(CAM_JPEG, "packet = %pK cmd_desc = %pK size = %lu",
-		(void *)packet, (void *)cmd_desc,
-		sizeof(struct cam_cmd_buf_desc));
-
 	rc = cam_packet_util_process_patches(packet, hw_mgr->iommu_hdl, -1);
 	if (rc) {
 		CAM_ERR(CAM_JPEG, "Patch processing failed %d", rc);
@@ -775,9 +948,12 @@ static int cam_jpeg_mgr_prepare_hw_update(void *hw_mgr_priv,
 
 	io_cfg_ptr = (struct cam_buf_io_cfg *)((uint32_t *)&packet->payload +
 		packet->io_configs_offset / 4);
-	CAM_DBG(CAM_JPEG, "packet = %pK io_cfg_ptr = %pK size = %lu",
-		(void *)packet, (void *)io_cfg_ptr,
-		sizeof(struct cam_buf_io_cfg));
+	CAM_DBG(CAM_JPEG, "Packet: %pK, io_cfg_ptr: %pK size: %lu req_id: %u dev_type: %d",
+		(void *)packet,
+		(void *)io_cfg_ptr,
+		sizeof(struct cam_buf_io_cfg),
+		packet->header.request_id,
+		ctx_data->jpeg_dev_acquire_info.dev_type);
 	prepare_args->pf_data->packet = packet;
 
 	prepare_args->num_out_map_entries = 0;
@@ -800,33 +976,7 @@ static int cam_jpeg_mgr_prepare_hw_update(void *hw_mgr_priv,
 			i, io_cfg_ptr[i].direction, io_cfg_ptr[i].fence);
 	}
 
-	CAM_DBG(CAM_JPEG, "received num cmd buf %d", packet->num_cmd_buf);
-
-	j = prepare_args->num_hw_update_entries;
-	rc = cam_packet_util_get_kmd_buffer(packet, &kmd_buf);
-	if (rc) {
-		CAM_ERR(CAM_JPEG, "get kmd buf failed %d", rc);
-		return rc;
-	}
-	/* fill kmd buf info into 1st hw update entry */
-	prepare_args->hw_update_entries[j].len =
-		(uint32_t)kmd_buf.used_bytes;
-	prepare_args->hw_update_entries[j].handle =
-		(uint32_t)kmd_buf.handle;
-	prepare_args->hw_update_entries[j].offset =
-		(uint32_t)kmd_buf.offset;
-	j++;
-
-	for (i = 0; i < packet->num_cmd_buf;  i++, j++) {
-		prepare_args->hw_update_entries[j].len =
-			(uint32_t)cmd_desc[i].length;
-		prepare_args->hw_update_entries[j].handle =
-			(uint32_t)cmd_desc[i].mem_handle;
-		prepare_args->hw_update_entries[j].offset =
-			(uint32_t)cmd_desc[i].offset;
-	}
-	prepare_args->num_hw_update_entries = j;
-	prepare_args->priv = (void *)(uintptr_t)packet->header.request_id;
+	rc = cam_jpeg_add_command_buffers(packet, prepare_args, ctx_data);
 
 	CAM_DBG(CAM_JPEG, "will wait on input sync sync_id %d",
 		prepare_args->in_map_entries[0].sync_id);
@@ -841,8 +991,9 @@ static void cam_jpeg_mgr_stop_deinit_dev(struct cam_jpeg_hw_mgr *hw_mgr,
 	struct cam_jpeg_set_irq_cb irq_cb;
 
 	/* stop reset Unregister CB and deinit */
-	irq_cb.jpeg_hw_mgr_cb = cam_jpeg_hw_mgr_cb;
-	irq_cb.data = NULL;
+	irq_cb.jpeg_hw_mgr_cb = cam_jpeg_hw_mgr_sched_bottom_half;
+	irq_cb.irq_cb_data.private_data = NULL;
+	irq_cb.irq_cb_data.jpeg_req = NULL;
 	irq_cb.b_set_cb = false;
 	if (hw_mgr->devices[dev_type][0]->hw_ops.process_cmd) {
 		rc = hw_mgr->devices[dev_type][0]->hw_ops.process_cmd(
@@ -929,10 +1080,11 @@ static int cam_jpeg_mgr_flush_req(void *hw_mgr_priv,
 	struct cam_jpeg_hw_ctx_data *ctx_data,
 	struct cam_hw_flush_args *flush_args)
 {
-	struct cam_jpeg_hw_mgr *hw_mgr = hw_mgr_priv;
-	struct cam_jpeg_hw_cfg_req *cfg_req = NULL;
-	struct cam_jpeg_hw_cfg_req *req_temp = NULL;
-	long request_id = 0;
+	struct cam_jpeg_hw_mgr                                   *hw_mgr = hw_mgr_priv;
+	struct cam_jpeg_hw_cfg_req                               *cfg_req = NULL;
+	struct cam_jpeg_hw_cfg_req                               *req_temp = NULL;
+	struct cam_jpeg_request_data                             *jpeg_req;
+	uintptr_t                                                 request_id = 0;
 	uint32_t dev_type;
 	struct cam_jpeg_hw_cfg_req *p_cfg_req = NULL;
 	bool b_req_found = false;
@@ -947,7 +1099,13 @@ static int cam_jpeg_mgr_flush_req(void *hw_mgr_priv,
 	if (flush_args->num_req_pending)
 		return 0;
 
-	request_id = (uintptr_t)flush_args->flush_req_active[0];
+	jpeg_req = (struct cam_jpeg_request_data *)flush_args->flush_req_active[0];
+	if (!jpeg_req) {
+		CAM_ERR(CAM_JPEG, "Request data is null");
+		return -EINVAL;
+	}
+
+	request_id = (uintptr_t)jpeg_req->request_id;
 
 	if (!flush_args->num_req_active)
 		return 0;
@@ -1196,6 +1354,8 @@ static int cam_jpeg_mgr_acquire_hw(void *hw_mgr_priv, void *acquire_hw_args)
 		goto acq_cdm_hdl_failed;
 	}
 	dev_type = ctx_data->jpeg_dev_acquire_info.dev_type;
+	CAM_DBG(CAM_JPEG, "ctx_id: %u, dev_type: %u",
+		ctx_id, dev_type);
 	if (!hw_mgr->cdm_info[dev_type][0].ref_cnt) {
 
 		if (dev_type == CAM_JPEG_RES_TYPE_ENC) {

+ 17 - 12
drivers/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.h

@@ -16,10 +16,10 @@
 #include "cam_req_mgr_workq.h"
 #include "cam_mem_mgr.h"
 
-#define CAM_JPEG_WORKQ_NUM_TASK      30
-#define CAM_JPEG_WORKQ_TASK_CMD_TYPE 1
-#define CAM_JPEG_WORKQ_TASK_MSG_TYPE 2
-#define CAM_JPEG_HW_CFG_Q_MAX        50
+#define CAM_JPEG_WORKQ_NUM_TASK             30
+#define CAM_JPEG_WORKQ_TASK_CMD_TYPE        1
+#define CAM_JPEG_WORKQ_TASK_MSG_TYPE        2
+#define CAM_JPEG_HW_CFG_Q_MAX               50
 
 /*
  * Response time threshold in ms beyond which a request is not expected
@@ -43,16 +43,21 @@ struct cam_jpeg_process_frame_work_data_t {
 /**
  * struct cam_jpeg_process_irq_work_data_t
  *
- * @type: Task type
- * @data: Pointer to message data
- * @result_size: Result size of enc/dma
- * @irq_status: IRQ status
+ * @type                   : Task type
+ * @output_encode_size     : Result size of encoder
+ * @is_dma_frame_done      : Flag to indicate whther the dma fram done was recived or not.
+ * @irq_status             : IRQ status
+ * @data                   : Pointer to message data
  */
 struct cam_jpeg_process_irq_work_data_t {
-	uint32_t type;
-	void *data;
-	int32_t result_size;
-	uint32_t irq_status;
+	uint32_t       type;
+	union core_data {
+		int32_t        output_encode_size;
+		int32_t        is_dma_frame_done;
+		int32_t        irq_data;
+	} u;
+	uint32_t       irq_status;
+	void          *data;
 };
 
 /**

+ 11 - 6
drivers/cam_jpeg/jpeg_hw/include/cam_jpeg_hw_intf.h

@@ -19,15 +19,20 @@
 #define CAM_JPEG_HW_DUMP_NUM_WORDS   5
 #define CAM_JPEG_HW_MAX_NUM_PID      2
 
-enum cam_jpeg_hw_type {
-	CAM_JPEG_DEV_ENC,
-	CAM_JPEG_DEV_DMA,
+
+/**
+ * struct cam_jpeg_irq_cb_data - Data that gets passed from IRQ when the cb function is called
+ * @private_data      : Void * for privat data
+ * @jpeg_req          : Jpeg reguest data stored during prepare update
+ */
+struct cam_jpeg_irq_cb_data {
+	void                         *private_data;
+	struct cam_jpeg_request_data *jpeg_req;
 };
 
 struct cam_jpeg_set_irq_cb {
-	int32_t (*jpeg_hw_mgr_cb)(uint32_t irq_status,
-		int32_t result_size, void *data);
-	void *data;
+	int32_t (*jpeg_hw_mgr_cb)(uint32_t irq_status, int32_t result_size, void *data);
+	struct cam_jpeg_irq_cb_data irq_cb_data;
 	uint32_t b_set_cb;
 };
 

+ 22 - 1
drivers/cam_jpeg/jpeg_hw/include/cam_jpeg_hw_mgr_intf.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-2021, The Linux Foundation. All rights reserved.
  */
 
 #ifndef CAM_JPEG_HW_MGR_INTF_H
@@ -12,6 +12,27 @@
 
 #define CAM_JPEG_CTX_MAX        16
 
+enum cam_jpeg_hw_type {
+	CAM_JPEG_DEV_ENC,
+	CAM_JPEG_DEV_DMA,
+	CAM_JPEG_DEV_MAX,
+};
+
+/**
+ * struct cam_jpeg_request_data - Jpeg request data received from command buffers
+ * @dev_type                 : Jpeg device type(ENC vs DMA)
+ * @request_id               : Request ID
+ * @encode_size_buffer_ptr   : Pointer to the buffer location for storing the encode
+                              size of the result
+ * @thumbnail_threshold_size : Threshold size for thumbnail image
+ */
+struct cam_jpeg_request_data {
+	uint32_t                            dev_type;
+	uint64_t                            request_id;
+	uint32_t                           *encode_size_buffer_ptr;
+	uint32_t                            thumbnail_threshold_size;
+};
+
 int cam_jpeg_hw_mgr_init(struct device_node *of_node,
 	uint64_t *hw_mgr_hdl, int *iommu_hdl);
 

+ 16 - 18
drivers/cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_core.c

@@ -177,17 +177,14 @@ irqreturn_t cam_jpeg_dma_irq(int irq_num, void *data)
 	cam_io_w_mb(irq_status,
 		soc_info->reg_map[0].mem_base +
 		core_info->jpeg_dma_hw_info->reg_offset.int_clr);
-	CAM_DBG(CAM_JPEG, "irq_num %d  irq_status = %x , core_state %d",
+	CAM_DBG(CAM_JPEG, "irq_num: %d  irq_status: 0x%x , core_state: %d",
 		irq_num, irq_status, core_info->core_state);
 	if (CAM_JPEG_HW_IRQ_IS_FRAME_DONE(irq_status, hw_info)) {
 		spin_lock(&jpeg_dma_dev->hw_lock);
 		if (core_info->core_state == CAM_JPEG_DMA_CORE_READY) {
 			CAM_TRACE(CAM_JPEG, "DMA FrameDone IRQ");
-			core_info->result_size = 1;
-			CAM_DBG(CAM_JPEG, "result_size %d",
-				core_info->result_size);
-			core_info->core_state =
-				CAM_JPEG_DMA_CORE_RESETTING_ON_DONE;
+			CAM_DBG(CAM_JPEG, "frane_done");
+			core_info->core_state = CAM_JPEG_DMA_CORE_RESETTING_ON_DONE;
 			cam_io_w_mb(hw_info->reg_val.reset_cmd,
 				mem_base + hw_info->reg_offset.reset_cmd);
 		} else {
@@ -201,33 +198,29 @@ irqreturn_t cam_jpeg_dma_irq(int irq_num, void *data)
 		spin_lock(&jpeg_dma_dev->hw_lock);
 		if (core_info->core_state == CAM_JPEG_DMA_CORE_RESETTING) {
 			core_info->core_state = CAM_JPEG_DMA_CORE_READY;
-			core_info->result_size = -1;
 			complete(&jpeg_dma_dev->hw_complete);
-		} else if (core_info->core_state ==
-			CAM_JPEG_DMA_CORE_RESETTING_ON_DONE) {
+		} else if (core_info->core_state == CAM_JPEG_DMA_CORE_RESETTING_ON_DONE) {
 			if (core_info->irq_cb.jpeg_hw_mgr_cb) {
-				core_info->irq_cb.jpeg_hw_mgr_cb(irq_status,
-					core_info->result_size,
-					core_info->irq_cb.data);
+				core_info->irq_cb.jpeg_hw_mgr_cb(irq_status, 1,
+					(void *)&core_info->irq_cb.irq_cb_data);
 			} else {
 				CAM_WARN(CAM_JPEG, "unexpected frame done");
 			}
-			core_info->result_size = -1;
 			core_info->core_state = CAM_JPEG_DMA_CORE_NOT_READY;
 		} else {
 			CAM_ERR(CAM_JPEG, "unexpected reset irq");
 		}
 		spin_unlock(&jpeg_dma_dev->hw_lock);
 	}
+
 	if (CAM_JPEG_HW_IRQ_IS_STOP_DONE(irq_status, hw_info)) {
 		spin_lock(&jpeg_dma_dev->hw_lock);
 		if (core_info->core_state == CAM_JPEG_DMA_CORE_ABORTING) {
 			core_info->core_state = CAM_JPEG_DMA_CORE_NOT_READY;
 			complete(&jpeg_dma_dev->hw_complete);
 			if (core_info->irq_cb.jpeg_hw_mgr_cb) {
-				core_info->irq_cb.jpeg_hw_mgr_cb(irq_status,
-					-1,
-					core_info->irq_cb.data);
+				core_info->irq_cb.jpeg_hw_mgr_cb(irq_status, 0,
+					(void *)&core_info->irq_cb.irq_cb_data);
 			}
 		} else {
 			CAM_ERR(CAM_JPEG, "unexpected abort irq");
@@ -402,18 +395,23 @@ int cam_jpeg_dma_process_cmd(void *device_priv, uint32_t cmd_type,
 	case CAM_JPEG_CMD_SET_IRQ_CB:
 	{
 		struct cam_jpeg_set_irq_cb *irq_cb = cmd_args;
+		struct cam_jpeg_irq_cb_data *irq_cb_data;
 
 		if (!cmd_args) {
 			CAM_ERR(CAM_JPEG, "cmd args NULL");
 			return -EINVAL;
 		}
+
+		irq_cb_data = &irq_cb->irq_cb_data;
 		if (irq_cb->b_set_cb) {
 			core_info->irq_cb.jpeg_hw_mgr_cb =
 				irq_cb->jpeg_hw_mgr_cb;
-			core_info->irq_cb.data = irq_cb->data;
+			core_info->irq_cb.irq_cb_data.jpeg_req = irq_cb_data->jpeg_req;
+			core_info->irq_cb.irq_cb_data.private_data = irq_cb_data->private_data;
 		} else {
 			core_info->irq_cb.jpeg_hw_mgr_cb = NULL;
-			core_info->irq_cb.data = NULL;
+			core_info->irq_cb.irq_cb_data.jpeg_req = NULL;
+			core_info->irq_cb.irq_cb_data.private_data = NULL;
 		}
 		rc = 0;
 		break;

+ 0 - 1
drivers/cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_core.h

@@ -62,7 +62,6 @@ struct cam_jpeg_dma_device_core_info {
 	struct cam_jpeg_set_irq_cb irq_cb;
 	int32_t ref_count;
 	struct mutex core_mutex;
-	int32_t result_size;
 	uint32_t num_pid;
 	uint32_t pid[CAM_JPEG_HW_MAX_NUM_PID];
 	uint32_t rd_mid;

+ 17 - 13
drivers/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_core.c

@@ -197,19 +197,20 @@ irqreturn_t cam_jpeg_enc_irq(int irq_num, void *data)
 		core_info->jpeg_enc_hw_info->reg_offset.int_clr);
 	spin_unlock(&jpeg_enc_dev->hw_lock);
 
-	CAM_DBG(CAM_JPEG, "irq_num %d  irq_status = %x , core_state %d",
+	CAM_DBG(CAM_JPEG, "irq_num: %d  irq_status: 0x%x , core_state: %d",
 		irq_num, irq_status, core_info->core_state);
 
 	if (CAM_JPEG_HW_IRQ_IS_FRAME_DONE(irq_status, hw_info)) {
 		spin_lock(&jpeg_enc_dev->hw_lock);
 		if (core_info->core_state == CAM_JPEG_ENC_CORE_READY) {
-			CAM_TRACE(CAM_JPEG, "Ctx %lld ENC FrameDone IRQ", core_info->irq_cb.data);
+			CAM_TRACE(CAM_JPEG, "Ctx %lld ENC FrameDone IRQ",
+				core_info->irq_cb.irq_cb_data.private_data);
 			encoded_size = cam_io_r_mb(mem_base +
 			core_info->jpeg_enc_hw_info->reg_offset.encode_size);
 			if (core_info->irq_cb.jpeg_hw_mgr_cb) {
 				core_info->irq_cb.jpeg_hw_mgr_cb(irq_status,
 					encoded_size,
-					core_info->irq_cb.data);
+					(void *)&core_info->irq_cb.irq_cb_data);
 			} else {
 				CAM_ERR(CAM_JPEG, "unexpected done, no cb");
 			}
@@ -236,9 +237,8 @@ irqreturn_t cam_jpeg_enc_irq(int irq_num, void *data)
 			core_info->core_state = CAM_JPEG_ENC_CORE_NOT_READY;
 			complete(&jpeg_enc_dev->hw_complete);
 			if (core_info->irq_cb.jpeg_hw_mgr_cb) {
-				core_info->irq_cb.jpeg_hw_mgr_cb(irq_status,
-					-1,
-					core_info->irq_cb.data);
+				core_info->irq_cb.jpeg_hw_mgr_cb(irq_status, -1,
+					(void *)&core_info->irq_cb.irq_cb_data);
 			}
 		} else {
 			CAM_ERR(CAM_JPEG, "unexpected abort irq");
@@ -254,9 +254,8 @@ irqreturn_t cam_jpeg_enc_irq(int irq_num, void *data)
 			irq_num, irq_status, core_info->core_state);
 
 		if (core_info->irq_cb.jpeg_hw_mgr_cb) {
-			core_info->irq_cb.jpeg_hw_mgr_cb(irq_status,
-				-1,
-				core_info->irq_cb.data);
+			core_info->irq_cb.jpeg_hw_mgr_cb(irq_status, -1,
+				(void *)&core_info->irq_cb.irq_cb_data);
 		}
 		spin_unlock(&jpeg_enc_dev->hw_lock);
 	}
@@ -523,18 +522,23 @@ int cam_jpeg_enc_process_cmd(void *device_priv, uint32_t cmd_type,
 	case CAM_JPEG_CMD_SET_IRQ_CB:
 	{
 		struct cam_jpeg_set_irq_cb *irq_cb = cmd_args;
+		struct cam_jpeg_irq_cb_data *irq_cb_data;
 
 		if (!cmd_args) {
 			CAM_ERR(CAM_JPEG, "cmd args NULL");
 			return -EINVAL;
 		}
+
+		irq_cb_data = &irq_cb->irq_cb_data;
+
 		if (irq_cb->b_set_cb) {
-			core_info->irq_cb.jpeg_hw_mgr_cb =
-				irq_cb->jpeg_hw_mgr_cb;
-			core_info->irq_cb.data = irq_cb->data;
+			core_info->irq_cb.jpeg_hw_mgr_cb = irq_cb->jpeg_hw_mgr_cb;
+			core_info->irq_cb.irq_cb_data.private_data = irq_cb_data->private_data;
+			core_info->irq_cb.irq_cb_data.jpeg_req = irq_cb_data->jpeg_req;
 		} else {
 			core_info->irq_cb.jpeg_hw_mgr_cb = NULL;
-			core_info->irq_cb.data = NULL;
+			core_info->irq_cb.irq_cb_data.private_data = NULL;
+			core_info->irq_cb.irq_cb_data.jpeg_req = NULL;
 		}
 		rc = 0;
 		break;

+ 10 - 0
drivers/cam_req_mgr/cam_req_mgr_dev.c

@@ -256,6 +256,16 @@ static void cam_v4l2_event_queue_notify_error(const struct v4l2_event *old,
 			ev_header->u.err_msg.error_type,
 			ev_header->u.err_msg.error_code);
 		break;
+	case V4L_EVENT_CAM_REQ_MGR_NODE_EVENT:
+		CAM_ERR_RATE_LIMIT(CAM_CRM,
+			"Failed to notify node event. Sess 0x%x ReqId %d Lnk 0x%x dev_hdl: %d evt_type: %u evt_cause: %u",
+			ev_header->session_hdl,
+			ev_header->u.node_msg.request_id,
+			ev_header->u.node_msg.link_hdl,
+			ev_header->u.node_msg.device_hdl,
+			ev_header->u.node_msg.event_type,
+			ev_header->u.node_msg.event_cause);
+		break;
 	default:
 		CAM_ERR(CAM_CRM, "Failed to notify crm event id %d",
 			old->id);