瀏覽代碼

Merge "msm: camera: cre: Updated FE/WE configuration" into camera-kernel.lnx.5.0

Camera Software Integration 4 年之前
父節點
當前提交
0087db80cc

+ 7 - 9
drivers/cam_cre/cam_cre_context.c

@@ -238,36 +238,34 @@ static struct cam_ctx_ops
 };
 
 int cam_cre_context_init(struct cam_cre_context *ctx,
-	struct cam_context *ctx_base,
 	struct cam_hw_mgr_intf *hw_intf,
 	uint32_t ctx_id)
 {
 	int rc;
 	int i;
 
-	if (!ctx || !ctx_base) {
+	if (!ctx || !ctx->base) {
 		CAM_ERR(CAM_CRE, "Invalid Context");
 		rc = -EFAULT;
 		goto err;
 	}
 
-	memset(ctx, 0, sizeof(*ctx));
-
-	ctx->base = ctx_base;
-
 	for (i = 0; i < CAM_CTX_REQ_MAX; i++)
 		ctx->req_base[i].req_priv = ctx;
 
-	rc = cam_context_init(ctx_base, cre_dev_name, CAM_CRE, ctx_id,
+	rc = cam_context_init(ctx->base, cre_dev_name, CAM_CRE, ctx_id,
 		NULL, hw_intf, ctx->req_base, CAM_CTX_REQ_MAX);
 	if (rc) {
 		CAM_ERR(CAM_CRE, "Camera Context Base init failed");
 		goto err;
 	}
 
-	ctx_base->state_machine = cam_cre_ctx_state_machine;
-	ctx_base->ctx_priv = ctx;
+	ctx->base->state_machine = cam_cre_ctx_state_machine;
+	ctx->base->ctx_priv = ctx;
 
+	ctx->base->max_hw_update_entries = CAM_CTX_CFG_MAX;
+	ctx->base->max_in_map_entries = CAM_CTX_CFG_MAX;
+	ctx->base->max_out_map_entries = CAM_CTX_CFG_MAX;
 err:
 	return rc;
 }

+ 0 - 2
drivers/cam_cre/cam_cre_context.h

@@ -44,13 +44,11 @@ struct cam_cre_ctx_irq_ops {
  * @brief: Initialization function for the CRE context
  *
  * @ctx: CRE context obj to be initialized
- * @ctx_base: Context base from cam_context
  * @hw_intf: CRE hw manager interface
  * @ctx_id: ID for this context
  *
  */
 int cam_cre_context_init(struct cam_cre_context *ctx,
-	struct cam_context *ctx_base,
 	struct cam_hw_mgr_intf *hw_intf,
 	uint32_t ctx_id);
 

+ 27 - 22
drivers/cam_cre/cam_cre_dev.c

@@ -109,14 +109,14 @@ static const struct v4l2_subdev_internal_ops cam_cre_subdev_internal_ops = {
 static int cam_cre_subdev_component_bind(struct device *dev,
 	struct device *master_dev, void *data)
 {
-	int rc;
 	int i;
-	struct cam_hw_mgr_intf hw_mgr_intf;
+	int rc = 0;
+	struct cam_hw_mgr_intf *hw_mgr_intf;
 	struct cam_node *node;
 	int iommu_hdl = -1;
 	struct platform_device *pdev = to_platform_device(dev);
 
-	CAM_DBG(CAM_CRE, "CRE Subdev Component bind");
+	g_cre_dev.sd.pdev = pdev;
 	g_cre_dev.sd.internal_ops = &cam_cre_subdev_internal_ops;
 	rc = cam_subdev_probe(&g_cre_dev.sd, pdev, CAM_CRE_DEV_NAME,
 		CAM_CRE_DEVICE_TYPE);
@@ -126,18 +126,25 @@ static int cam_cre_subdev_component_bind(struct device *dev,
 	}
 	node = (struct cam_node *)g_cre_dev.sd.token;
 
-	rc = cam_cre_hw_mgr_init(pdev->dev.of_node,
-		(uint64_t *)&hw_mgr_intf, &iommu_hdl);
+	hw_mgr_intf = kzalloc(sizeof(*hw_mgr_intf), GFP_KERNEL);
+	if (!hw_mgr_intf) {
+		CAM_ERR(CAM_CRE, "Error allocating memory");
+		rc = -ENOMEM;
+		goto hw_alloc_fail;
+	}
+
+	rc = cam_cre_hw_mgr_init(pdev->dev.of_node, hw_mgr_intf,
+		&iommu_hdl);
 	if (rc) {
 		CAM_ERR(CAM_CRE, "Can not initialize CRE HWmanager %d", rc);
-		goto unregister;
+		goto hw_init_fail;
 	}
 
+	memset(g_cre_dev.ctx_cre, 0,  sizeof(g_cre_dev.ctx_cre));
 	for (i = 0; i < CAM_CRE_CTX_MAX; i++) {
+		g_cre_dev.ctx_cre[i].base = &g_cre_dev.ctx[i];
 		rc = cam_cre_context_init(&g_cre_dev.ctx_cre[i],
-			&g_cre_dev.ctx[i],
-			&node->hw_mgr_intf,
-			i);
+			hw_mgr_intf, i);
 		if (rc) {
 			CAM_ERR(CAM_CRE, "CRE context init failed %d %d",
 				i, rc);
@@ -145,8 +152,8 @@ static int cam_cre_subdev_component_bind(struct device *dev,
 		}
 	}
 
-	rc = cam_node_init(node, &hw_mgr_intf, g_cre_dev.ctx, CAM_CRE_CTX_MAX,
-		CAM_CRE_DEV_NAME);
+	rc = cam_node_init(node, hw_mgr_intf, g_cre_dev.ctx,
+		CAM_CRE_CTX_MAX, CAM_CRE_DEV_NAME);
 	if (rc) {
 		CAM_ERR(CAM_CRE, "CRE node init failed %d", rc);
 		goto ctx_init_fail;
@@ -156,6 +163,7 @@ static int cam_cre_subdev_component_bind(struct device *dev,
 	cam_smmu_set_client_page_fault_handler(iommu_hdl,
 		cam_cre_dev_iommu_fault_handler, node);
 
+	g_cre_dev.open_cnt = 0;
 	mutex_init(&g_cre_dev.cre_lock);
 
 	CAM_DBG(CAM_CRE, "Component bound successfully");
@@ -166,7 +174,9 @@ ctx_init_fail:
 	for (--i; i >= 0; i--)
 		if (cam_cre_context_deinit(&g_cre_dev.ctx_cre[i]))
 			CAM_ERR(CAM_CRE, "deinit fail %d %d", i, rc);
-unregister:
+hw_init_fail:
+	kfree(hw_mgr_intf);
+hw_alloc_fail:
 	if (cam_subdev_remove(&g_cre_dev.sd))
 		CAM_ERR(CAM_CRE, "remove fail %d", rc);
 err:
@@ -176,19 +186,14 @@ err:
 static void cam_cre_subdev_component_unbind(struct device *dev,
 	struct device *master_dev, void *data)
 {
-	int rc;
 	int i;
 
-	for (i = 0; i < CAM_CTX_MAX; i++) {
-		rc = cam_cre_context_deinit(&g_cre_dev.ctx_cre[i]);
-		if (rc)
-			CAM_ERR(CAM_CRE, "CRE context %d deinit failed %d",
-				i, rc);
-	}
+	for (i = 0; i < CRE_CTX_MAX; i++)
+		cam_cre_context_deinit(&g_cre_dev.ctx_cre[i]);
 
-	rc = cam_subdev_remove(&g_cre_dev.sd);
-	if (rc)
-		CAM_ERR(CAM_CRE, "Unregister failed %d", rc);
+	cam_node_deinit(g_cre_dev.node);
+	cam_subdev_remove(&g_cre_dev.sd);
+	mutex_destroy(&g_cre_dev.cre_lock);
 }
 
 const static struct component_ops cam_cre_subdev_component_ops = {

+ 463 - 145
drivers/cam_cre/cam_cre_hw_mgr/cam_cre_hw_mgr.c

@@ -2,12 +2,6 @@
 /*
  * Copyright (c) 2021, The Linux Foundation. All rights reserved.
  */
-#include <linux/uaccess.h>
-#include <linux/slab.h>
-#include <linux/of.h>
-#include <linux/io.h>
-#include <linux/of_platform.h>
-#include <linux/platform_device.h>
 #include <linux/mutex.h>
 #include <linux/spinlock.h>
 #include <linux/workqueue.h>
@@ -37,9 +31,6 @@
 #include "cre_dev_intf.h"
 #include "cam_compat.h"
 
-#define CAM_CRE_FE_IRQ 0x4
-#define CAM_CRE_WE_IRQ 0x2
-
 static struct cam_cre_hw_mgr *cre_hw_mgr;
 
 static struct cam_cre_io_buf_info *cam_cre_mgr_get_rsc(
@@ -131,6 +122,7 @@ static int cam_cre_mgr_process_cmd_io_buf_req(struct cam_cre_hw_mgr *hw_mgr,
 
 	cre_request = ctx_data->req_list[req_idx];
 	cre_request->num_batch = ctx_data->cre_acquire.batch_size;
+	CAM_DBG(CAM_CRE, "num_io_configs %d", packet->num_io_configs);
 
 	for (i = 0; i < cre_request->num_batch; i++) {
 		for (j = 0; j < packet->num_io_configs; j++) {
@@ -154,9 +146,15 @@ static int cam_cre_mgr_process_cmd_io_buf_req(struct cam_cre_hw_mgr *hw_mgr,
 			io_buf->num_planes = acq_io_buf->num_planes;
 			io_buf->resource_type = acq_io_buf->res_id;
 			io_buf->direction = acq_io_buf->direction;
-			io_buf->fence = acq_io_buf->fence;
 			io_buf->format = acq_io_buf->format;
+
 			alignment = acq_io_buf->alignment;
+			io_buf->fence = io_cfg_ptr[j].fence;
+
+			CAM_DBG(CAM_CRE,
+				"i %d j %d Number of planes %d res_type %d dir %d, fence %d format %d align %d",
+				i, j, io_buf->num_planes, io_buf->resource_type,
+				io_buf->direction, io_buf->fence, io_buf->format, alignment);
 
 			for (k = 0; k < io_buf->num_planes; k++) {
 				is_secure = cam_mem_is_secure_buf(
@@ -180,21 +178,27 @@ static int cam_cre_mgr_process_cmd_io_buf_req(struct cam_cre_hw_mgr *hw_mgr,
 				iova_addr += io_cfg_ptr[j].offsets[k];
 				plane_info = &io_buf->p_info[k];
 
-				plane_info->offset    = io_cfg_ptr[j].offsets[k];
-				plane_info->format    = io_buf->format;
-				/*
-				 * TODO: Confirm if the calculation for batch frame offset
-				 * is correct with some experiment in TFE.
-				 */
+				plane_info->offset = io_cfg_ptr[j].offsets[k];
+				plane_info->format = acq_io_buf->format;
 				plane_info->iova_addr = iova_addr +
 					((io_cfg_ptr[j].planes[k].plane_stride *
-					  io_cfg_ptr[j].planes[k].slice_height) * i);
-				plane_info->width     =
-					io_cfg_ptr[j].planes[k].width;
-				plane_info->height    =
-					io_cfg_ptr[j].planes[k].height;
+					  io_cfg_ptr[j].planes[k].slice_height) * k);
+
 				plane_info->stride    =
 					io_cfg_ptr[j].planes[k].plane_stride;
+
+				/* Width for WE has to be updated in number of pixels */
+				if (acq_io_buf->direction == CAM_BUF_OUTPUT) {
+					/* PLAIN 128/8 = 16 Bytes per pixel */
+					plane_info->width =
+						io_cfg_ptr[j].planes[k].plane_stride/16;
+				} else {
+					/* FE width should be in bytes */
+					plane_info->width     =
+						io_cfg_ptr[j].planes[k].plane_stride;
+				}
+				plane_info->height    =
+					io_cfg_ptr[j].planes[k].height;
 				plane_info->len       = len;
 				plane_info->alignment = alignment;
 			}
@@ -233,47 +237,27 @@ static int cam_cre_mgr_reset_hw(void)
 }
 
 
-static void cam_cre_ctx_wait_for_idle_irq(struct cam_cre_ctx *ctx,
-		struct cam_cre_request *cre_req, uint32_t cookie)
+static void cam_cre_ctx_wait_for_idle_irq(struct cam_cre_ctx *ctx)
 {
 	int rc;
 
 	if (ctx->ctx_state != CRE_CTX_STATE_ACQUIRED) {
 		CAM_ERR(CAM_CRE, "ctx %u is in %d state",
 			ctx->ctx_id, ctx->ctx_state);
-		mutex_unlock(&ctx->ctx_mutex);
 		return;
 	}
 
-	rc = wait_for_completion_timeout(
-		&ctx->cre_top->idle_done, msecs_to_jiffies(30000));
+	rc = cam_common_wait_for_completion_timeout(
+		&ctx->cre_top->idle_done,
+		msecs_to_jiffies(CAM_CRE_RESPONSE_TIME_THRESHOLD));
 	if (!rc) {
 		cam_cre_device_timer_reset(cre_hw_mgr);
 	} else {
-		CAM_INFO(CAM_CRE, "After reset of CRE, reapply req");
-		rc = cam_cre_mgr_reset_hw();
-	}
-
-	if (!test_bit(cookie, ctx->bitmap)) {
-		CAM_ERR(CAM_CRE, "Req not present reqIdx = %d for ctx_id = %d",
-			cookie, ctx->ctx_id);
-		goto end;
+		CAM_DBG(CAM_CRE, "IDLE done for req idx %d",
+			ctx->last_req_idx);
 	}
-	CAM_DBG(CAM_REQ, "req_id= %llu ctx_id= %d lcb=%llu",
-		cre_req->request_id, ctx->ctx_id);
-
-	ctx->req_cnt--;
-
-	cre_req->request_id = 0;
-	cam_cre_free_io_config(ctx->req_list[cookie]);
-	cam_free_clear((void *)ctx->req_list[cookie]);
-	ctx->req_list[cookie] = NULL;
-	clear_bit(cookie, ctx->bitmap);
-end:
-	mutex_unlock(&ctx->ctx_mutex);
 }
 
-
 static int cam_cre_mgr_create_cre_reg_buf(struct cam_cre_hw_mgr *hw_mgr,
 	struct cam_packet *packet,
 	struct cam_hw_prepare_update_args *prepare_args,
@@ -570,16 +554,16 @@ static int cam_cre_mgr_handle_config_err(
 	struct cam_hw_config_args *config_args,
 	struct cam_cre_ctx *ctx_data)
 {
-	struct cam_hw_done_event_data buf_data;
+	struct cam_hw_done_event_data err_data;
 	struct cam_cre_request *cre_req;
 	uint32_t req_idx;
 
 	cre_req = config_args->priv;
 
-	buf_data.request_id = cre_req->request_id;
-	buf_data.evt_param = CAM_SYNC_CRE_EVENT_CONFIG_ERR;
+	err_data.request_id = cre_req->request_id;
+	err_data.evt_param = CAM_SYNC_CRE_EVENT_CONFIG_ERR;
 	ctx_data->ctxt_event_cb(ctx_data->context_priv, CAM_CTX_EVT_ID_ERROR,
-		&buf_data);
+		&err_data);
 
 	req_idx = cre_req->req_idx;
 	cre_req->request_id = 0;
@@ -684,7 +668,7 @@ static int32_t cam_cre_deinit_idle_clk(void *priv, void *data)
 
 	CAM_DBG(CAM_CRE, "Disable %d", clk_info->hw_type);
 
-	dev_intf->hw_ops.process_cmd(dev_intf->hw_priv, id,	NULL, 0);
+	dev_intf->hw_ops.process_cmd(dev_intf->hw_priv, id, NULL, 0);
 
 done:
 	mutex_unlock(&hw_mgr->hw_mgr_mutex);
@@ -719,19 +703,14 @@ static void cam_cre_device_timer_cb(struct timer_list *timer_data)
 static int cam_cre_device_timer_start(struct cam_cre_hw_mgr *hw_mgr)
 {
 	int rc = 0;
-	int i;
-
-	for (i = 0; i < CLK_HW_MAX; i++)  {
-		if (!hw_mgr->clk_info.watch_dog) {
-			rc = crm_timer_init(&hw_mgr->clk_info.watch_dog,
-				CRE_DEVICE_IDLE_TIMEOUT, &hw_mgr->clk_info,
-				&cam_cre_device_timer_cb);
-
-			if (rc)
-				CAM_ERR(CAM_CRE, "Failed to start timer %d", i);
 
-			hw_mgr->clk_info.watch_dog_reset_counter = 0;
-		}
+	if (!hw_mgr->clk_info.watch_dog) {
+		rc = crm_timer_init(&hw_mgr->clk_info.watch_dog,
+			CRE_DEVICE_IDLE_TIMEOUT, &hw_mgr->clk_info,
+			&cam_cre_device_timer_cb);
+		if (rc)
+			CAM_ERR(CAM_CRE, "Failed to start timer");
+		hw_mgr->clk_info.watch_dog_reset_counter = 0;
 	}
 
 	return rc;
@@ -753,7 +732,7 @@ static int cam_cre_mgr_process_cmd(void *priv, void *data)
 	struct cam_cre_ctx *ctx_data;
 	struct cam_cre_request *cre_req;
 	struct cam_cre_hw_mgr *hw_mgr = cre_hw_mgr;
-	uint32_t active_req_idx;
+	uint32_t num_batch;
 
 	if (!data || !priv) {
 		CAM_ERR(CAM_CRE, "Invalid params%pK %pK", data, priv);
@@ -772,12 +751,10 @@ static int cam_cre_mgr_process_cmd(void *priv, void *data)
 		return -EINVAL;
 	}
 
-	active_req_idx = task_data->req_idx;
-
-	if (active_req_idx >= CAM_CTX_REQ_MAX) {
+	if (task_data->req_idx >= CAM_CTX_REQ_MAX) {
 		mutex_unlock(&hw_mgr->hw_mgr_mutex);
 		CAM_ERR(CAM_CRE, "Invalid reqIdx = %llu",
-				active_req_idx);
+				task_data->req_idx);
 		return -EINVAL;
 	}
 
@@ -799,15 +776,34 @@ static int cam_cre_mgr_process_cmd(void *priv, void *data)
 		mutex_unlock(&hw_mgr->hw_mgr_mutex);
 		return -EINVAL;
 	}
-
 	hw_mgr = task_data->data;
-	ctx_data->active_req = cre_req;
-	for (i = 0; i < cre_req->num_batch; i++) {
-		cam_cre_mgr_update_reg_set(hw_mgr, cre_req);
-		cam_cre_ctx_wait_for_idle_irq(ctx_data, cre_req,
-			active_req_idx);
-	}
+	num_batch = cre_req->num_batch;
+
+	CAM_DBG(CAM_CRE,
+		"Going to configure cre for req %d, req_idx %d num_batch %d",
+		cre_req->request_id, cre_req->req_idx, num_batch);
+
+	for (i = 0; i < num_batch; i++) {
+		if (i != 0) {
+			rc = cam_common_wait_for_completion_timeout(
+					&ctx_data->cre_top->bufdone,
+					msecs_to_jiffies(100));
+			if (!rc) {
+				cam_cre_device_timer_reset(cre_hw_mgr);
+				CAM_ERR(CAM_CRE,
+					"Timedout waiting for bufdone on last frame");
+				return -ETIMEDOUT;
+			} else {
+				reinit_completion(&ctx_data->cre_top->bufdone);
+				CAM_INFO(CAM_CRE,
+					"done for frame %d in batch of %d",
+					i-1, num_batch);
+			}
+		}
 
+		cam_cre_mgr_update_reg_set(hw_mgr, cre_req, i);
+		cam_cre_ctx_wait_for_idle_irq(ctx_data);
+	}
 	mutex_unlock(&hw_mgr->hw_mgr_mutex);
 
 	return rc;
@@ -835,9 +831,11 @@ static int32_t cam_cre_mgr_process_msg(void *priv, void *data)
 	struct cam_hw_done_event_data buf_data;
 	struct cam_cre_hw_mgr *hw_mgr;
 	struct cam_cre_ctx *ctx;
+	struct cam_cre_request *active_req;
 	struct cam_cre_irq_data irq_data;
 	int32_t ctx_id;
 	uint32_t evt_id;
+	uint32_t active_req_idx;
 	int rc = 0;
 
 	if (!data || !priv) {
@@ -864,31 +862,325 @@ static int32_t cam_cre_mgr_process_msg(void *priv, void *data)
 		return -EINVAL;
 	}
 
+	active_req_idx = find_next_bit(ctx->bitmap, ctx->bits, ctx->last_done_req_idx);
+	CAM_DBG(CAM_CRE, "active_req_idx %d last_done_req_idx %d",
+		active_req_idx, ctx->last_done_req_idx);
+
+	active_req = ctx->req_list[active_req_idx];
+	if (!active_req)
+		CAM_ERR(CAM_CRE, "Active req cannot be null");
+
 	if (irq_data.error) {
 		evt_id = CAM_CTX_EVT_ID_ERROR;
 		buf_data.evt_param = CAM_SYNC_CRE_EVENT_HW_ERR;
-		buf_data.request_id = ctx->active_req->request_id;
+		buf_data.request_id = active_req->request_id;
 		ctx->ctxt_event_cb(ctx->context_priv, evt_id, &buf_data);
 		rc = cam_cre_mgr_reset_hw();
-	} else if ((irq_data.top_irq_status & CAM_CRE_WE_IRQ)
-		&& (irq_data.wr_buf_done)) {
+		clear_bit(active_req_idx, ctx->bitmap);
+		cam_cre_free_io_config(active_req);
+		cam_free_clear((void *)active_req);
+		ctx->req_cnt--;
+		ctx->req_list[active_req_idx] = NULL;
+	} else if (irq_data.wr_buf_done) {
 		/* Signal Buf done */
-		ctx->active_req->frames_done++;
-		if (ctx->active_req->frames_done == ctx->active_req->num_batch) {
+		active_req->frames_done++;
+		CAM_DBG(CAM_CRE, "Received frames_done %d num_batch %d req id %d",
+			active_req->frames_done, active_req->num_batch,
+			active_req->request_id);
+		complete(&ctx->cre_top->bufdone);
+		if (active_req->frames_done == active_req->num_batch) {
+			ctx->last_done_req_idx = active_req_idx;
+			CAM_DBG(CAM_CRE, "signaling buff done for req %d",
+				active_req->request_id);
 			evt_id = CAM_CTX_EVT_ID_SUCCESS;
 			buf_data.evt_param = CAM_SYNC_COMMON_EVENT_SUCCESS;
-			buf_data.request_id = ctx->active_req->request_id;
+			buf_data.request_id = active_req->request_id;
 			ctx->ctxt_event_cb(ctx->context_priv, evt_id, &buf_data);
+			clear_bit(active_req_idx, ctx->bitmap);
+			cam_cre_free_io_config(active_req);
+			cam_free_clear((void *)active_req);
+			ctx->req_cnt--;
+			ctx->req_list[active_req_idx] = NULL;
 		}
 	}
 	mutex_unlock(&ctx->ctx_mutex);
 	return rc;
 }
 
+static int cam_cre_get_actual_clk_rate_idx(
+	struct cam_cre_ctx *ctx_data, uint32_t base_clk)
+{
+	int i;
+
+	for (i = 0; i < CAM_MAX_VOTE; i++)
+		if (ctx_data->clk_info.clk_rate[i] >= base_clk)
+			return i;
+
+	/*
+	 * Caller has to ensure returned index is within array
+	 * size bounds while accessing that index.
+	 */
+
+	return i;
+}
+
+static bool cam_cre_is_over_clk(struct cam_cre_hw_mgr *hw_mgr,
+	struct cam_cre_ctx *ctx_data,
+	struct cam_cre_clk_info *hw_mgr_clk_info)
+{
+	int base_clk_idx;
+	int curr_clk_idx;
+
+	base_clk_idx = cam_cre_get_actual_clk_rate_idx(ctx_data,
+		hw_mgr_clk_info->base_clk);
+
+	curr_clk_idx = cam_cre_get_actual_clk_rate_idx(ctx_data,
+		hw_mgr_clk_info->curr_clk);
+
+	CAM_DBG(CAM_CRE, "bc_idx = %d cc_idx = %d %d %d",
+		base_clk_idx, curr_clk_idx, hw_mgr_clk_info->base_clk,
+		hw_mgr_clk_info->curr_clk);
+
+	if (curr_clk_idx > base_clk_idx)
+		return true;
+
+	return false;
+}
+
+static int cam_cre_get_lower_clk_rate(struct cam_cre_hw_mgr *hw_mgr,
+	struct cam_cre_ctx *ctx_data, uint32_t base_clk)
+{
+	int i;
+
+	i = cam_cre_get_actual_clk_rate_idx(ctx_data, base_clk);
+
+	while (i > 0) {
+		if (ctx_data->clk_info.clk_rate[i - 1])
+			return ctx_data->clk_info.clk_rate[i - 1];
+		i--;
+	}
+
+	CAM_DBG(CAM_CRE, "Already clk at lower level");
+
+	return base_clk;
+}
+
+static int cam_cre_get_next_clk_rate(struct cam_cre_hw_mgr *hw_mgr,
+	struct cam_cre_ctx *ctx_data, uint32_t base_clk)
+{
+	int i;
+
+	i = cam_cre_get_actual_clk_rate_idx(ctx_data, base_clk);
+
+	while (i < CAM_MAX_VOTE - 1) {
+		if (ctx_data->clk_info.clk_rate[i + 1])
+			return ctx_data->clk_info.clk_rate[i + 1];
+		i++;
+	}
+
+	CAM_DBG(CAM_CRE, "Already clk at higher level");
+	return base_clk;
+}
+
+static bool cam_cre_update_clk_overclk_free(struct cam_cre_hw_mgr *hw_mgr,
+	struct cam_cre_ctx *ctx_data,
+	struct cam_cre_clk_info *hw_mgr_clk_info,
+	struct cam_cre_clk_bw_request *clk_info,
+	uint32_t base_clk)
+{
+	int rc = false;
+
+	/*
+	 * In caseof no pending packets case
+	 *    1. In caseof overclk cnt is less than threshold, increase
+	 *       overclk count and no update in the clock rate
+	 *    2. In caseof overclk cnt is greater than or equal to threshold
+	 *       then lower clock rate by one level and update hw_mgr current
+	 *       clock value.
+	 *        a. In case of new clock rate greater than sum of clock
+	 *           rates, reset overclk count value to zero if it is
+	 *           overclock
+	 *        b. if it is less than sum of base clocks then go to next
+	 *           level of clock and make overclk count to zero
+	 *        c. if it is same as sum of base clock rates update overclock
+	 *           cnt to 0
+	 */
+	if (hw_mgr_clk_info->over_clked < hw_mgr_clk_info->threshold) {
+		hw_mgr_clk_info->over_clked++;
+		rc = false;
+	} else {
+		hw_mgr_clk_info->curr_clk =
+			cam_cre_get_lower_clk_rate(hw_mgr, ctx_data,
+			hw_mgr_clk_info->curr_clk);
+		if (hw_mgr_clk_info->curr_clk > hw_mgr_clk_info->base_clk) {
+			if (cam_cre_is_over_clk(hw_mgr, ctx_data,
+				hw_mgr_clk_info))
+				hw_mgr_clk_info->over_clked = 0;
+		} else if (hw_mgr_clk_info->curr_clk <
+			hw_mgr_clk_info->base_clk) {
+			hw_mgr_clk_info->curr_clk =
+			cam_cre_get_next_clk_rate(hw_mgr, ctx_data,
+				hw_mgr_clk_info->curr_clk);
+				hw_mgr_clk_info->over_clked = 0;
+		} else if (hw_mgr_clk_info->curr_clk ==
+			hw_mgr_clk_info->base_clk) {
+			hw_mgr_clk_info->over_clked = 0;
+		}
+		rc = true;
+	}
+
+	return rc;
+}
+
+static int cam_cre_calc_total_clk(struct cam_cre_hw_mgr *hw_mgr,
+	struct cam_cre_clk_info *hw_mgr_clk_info, uint32_t dev_type)
+{
+	int i;
+	struct cam_cre_ctx *ctx_data;
+
+	hw_mgr_clk_info->base_clk = 0;
+	for (i = 0; i < CRE_CTX_MAX; i++) {
+		ctx_data = &hw_mgr->ctx[i];
+		if (ctx_data->ctx_state == CRE_CTX_STATE_ACQUIRED)
+			hw_mgr_clk_info->base_clk +=
+				ctx_data->clk_info.base_clk;
+	}
+
+	return 0;
+}
+
+static int cam_cre_get_actual_clk_rate(struct cam_cre_hw_mgr *hw_mgr,
+	struct cam_cre_ctx *ctx_data, uint32_t base_clk)
+{
+	int i;
+
+	for (i = 0; i < CAM_MAX_VOTE; i++)
+		if (ctx_data->clk_info.clk_rate[i] >= base_clk)
+			return ctx_data->clk_info.clk_rate[i];
+
+	return base_clk;
+}
+
+static bool cam_cre_update_clk_busy(struct cam_cre_hw_mgr *hw_mgr,
+	struct cam_cre_ctx *ctx_data,
+	struct cam_cre_clk_info *hw_mgr_clk_info,
+	struct cam_cre_clk_bw_request *clk_info,
+	uint32_t base_clk)
+{
+	uint32_t next_clk_level;
+	uint32_t actual_clk;
+	bool rc = false;
+
+	/* 1. if current request frame cycles(fc) are more than previous
+	 *      frame fc
+	 *      Calculate the new base clock.
+	 *      if sum of base clocks are more than next available clk level
+	 *       Update clock rate, change curr_clk_rate to sum of base clock
+	 *       rates and make over_clked to zero
+	 *      else
+	 *       Update clock rate to next level, update curr_clk_rate and make
+	 *       overclked cnt to zero
+	 * 2. if current fc is less than or equal to previous  frame fc
+	 *      Still Bump up the clock to next available level
+	 *      if it is available, then update clock, make overclk cnt to
+	 *      zero. If the clock is already at highest clock rate then
+	 *      no need to update the clock
+	 */
+	ctx_data->clk_info.base_clk = base_clk;
+	hw_mgr_clk_info->over_clked = 0;
+	if (clk_info->frame_cycles > ctx_data->clk_info.curr_fc) {
+		cam_cre_calc_total_clk(hw_mgr, hw_mgr_clk_info,
+			ctx_data->cre_acquire.dev_type);
+		actual_clk = cam_cre_get_actual_clk_rate(hw_mgr,
+			ctx_data, base_clk);
+		if (hw_mgr_clk_info->base_clk > actual_clk) {
+			hw_mgr_clk_info->curr_clk = hw_mgr_clk_info->base_clk;
+		} else {
+			next_clk_level = cam_cre_get_next_clk_rate(hw_mgr,
+				ctx_data, hw_mgr_clk_info->curr_clk);
+			hw_mgr_clk_info->curr_clk = next_clk_level;
+		}
+		rc = true;
+	} else {
+		next_clk_level =
+			cam_cre_get_next_clk_rate(hw_mgr, ctx_data,
+				hw_mgr_clk_info->curr_clk);
+		if (hw_mgr_clk_info->curr_clk < next_clk_level) {
+			hw_mgr_clk_info->curr_clk = next_clk_level;
+			rc = true;
+		}
+	}
+	ctx_data->clk_info.curr_fc = clk_info->frame_cycles;
+
+	return rc;
+}
+
+static bool cam_cre_update_clk_free(struct cam_cre_hw_mgr *hw_mgr,
+	struct cam_cre_ctx *ctx_data,
+	struct cam_cre_clk_info *hw_mgr_clk_info,
+	struct cam_cre_clk_bw_request *clk_info,
+	uint32_t base_clk)
+{
+	int rc = false;
+	bool over_clocked = false;
+
+	ctx_data->clk_info.curr_fc = clk_info->frame_cycles;
+	ctx_data->clk_info.base_clk = base_clk;
+	cam_cre_calc_total_clk(hw_mgr, hw_mgr_clk_info,
+		ctx_data->cre_acquire.dev_type);
+
+	/*
+	 * Current clock is not always sum of base clocks, due to
+	 * clock scales update to next higher or lower levels, it
+	 * equals to one of discrete clock values supported by hardware.
+	 * So even current clock is higher than sum of base clocks, we
+	 * can not consider it is over clocked. if it is greater than
+	 * discrete clock level then only it is considered as over clock.
+	 * 1. Handle over clock case
+	 * 2. If current clock is less than sum of base clocks
+	 *    update current clock
+	 * 3. If current clock is same as sum of base clocks no action
+	 */
+
+	over_clocked = cam_cre_is_over_clk(hw_mgr, ctx_data,
+		hw_mgr_clk_info);
+
+	if (hw_mgr_clk_info->curr_clk > hw_mgr_clk_info->base_clk &&
+		over_clocked) {
+		rc = cam_cre_update_clk_overclk_free(hw_mgr, ctx_data,
+			hw_mgr_clk_info, clk_info, base_clk);
+	} else if (hw_mgr_clk_info->curr_clk > hw_mgr_clk_info->base_clk) {
+		hw_mgr_clk_info->over_clked = 0;
+		rc = false;
+	}  else if (hw_mgr_clk_info->curr_clk < hw_mgr_clk_info->base_clk) {
+		hw_mgr_clk_info->curr_clk = cam_cre_get_actual_clk_rate(hw_mgr,
+			ctx_data, hw_mgr_clk_info->base_clk);
+		rc = true;
+	}
+
+	return rc;
+}
+
+static uint32_t cam_cre_mgr_calc_base_clk(uint32_t frame_cycles,
+	uint64_t budget)
+{
+	uint64_t mul = 1000000000;
+	uint64_t base_clk = frame_cycles * mul;
+
+	do_div(base_clk, budget);
+
+	CAM_DBG(CAM_CRE, "budget = %lld fc = %d ib = %lld base_clk = %lld",
+		budget, frame_cycles,
+		(long long)(frame_cycles * mul), base_clk);
+
+	return base_clk;
+}
+
 static bool cam_cre_check_clk_update(struct cam_cre_hw_mgr *hw_mgr,
 	struct cam_cre_ctx *ctx_data, int idx)
 {
-	bool rc = false;
+	bool busy = false, rc = false;
+	uint64_t base_clk;
 	struct cam_cre_clk_bw_request *clk_info;
 	uint64_t req_id;
 	struct cam_cre_clk_info *hw_mgr_clk_info;
@@ -896,14 +1188,29 @@ static bool cam_cre_check_clk_update(struct cam_cre_hw_mgr *hw_mgr,
 	cam_cre_device_timer_reset(hw_mgr);
 	hw_mgr_clk_info = &hw_mgr->clk_info;
 	req_id = ctx_data->req_list[idx]->request_id;
+	if (ctx_data->req_cnt > 1)
+		busy = true;
 
-	CAM_DBG(CAM_CRE, "req_id = %lld", req_id);
+	CAM_DBG(CAM_CRE, "busy = %d req_id = %lld", busy, req_id);
 
 	clk_info = &ctx_data->req_list[idx]->clk_info;
 
 	/* Calculate base clk rate */
+	base_clk = cam_cre_mgr_calc_base_clk(
+		clk_info->frame_cycles, clk_info->budget_ns);
 	ctx_data->clk_info.rt_flag = clk_info->rt_flag;
 
+	if (busy)
+		rc = cam_cre_update_clk_busy(hw_mgr, ctx_data,
+			hw_mgr_clk_info, clk_info, base_clk);
+	else
+		rc = cam_cre_update_clk_free(hw_mgr, ctx_data,
+			hw_mgr_clk_info, clk_info, base_clk);
+
+	CAM_DBG(CAM_CRE, "bc = %d cc = %d busy = %d overclk = %d uc = %d",
+		hw_mgr_clk_info->base_clk, hw_mgr_clk_info->curr_clk,
+		busy, hw_mgr_clk_info->over_clked, rc);
+
 	return rc;
 }
 
@@ -1020,7 +1327,8 @@ static int cam_cre_mgr_process_io_cfg(struct cam_cre_hw_mgr *hw_mgr,
 	prep_arg->num_out_map_entries = 0;
 	prep_arg->num_in_map_entries = 0;
 
-	CAM_DBG(CAM_CRE, "E: req_idx = %u %x", req_idx, packet);
+	CAM_DBG(CAM_CRE, "E: req_idx = %u %x num batch%d",
+			req_idx, packet, cre_request->num_batch);
 
 	for (i = 0; i < cre_request->num_batch; i++) {
 		for (l = 0; l < cre_request->num_io_bufs[i]; l++) {
@@ -1050,13 +1358,10 @@ static int cam_cre_mgr_process_io_cfg(struct cam_cre_hw_mgr *hw_mgr,
 					prep_arg->num_out_map_entries++;
 				}
 			}
-			CAM_DBG(CAM_REQ,
+			CAM_DBG(CAM_CRE,
 				"ctx_id: %u req_id: %llu dir[%d] %u, fence: %d",
 				ctx_data->ctx_id, packet->header.request_id, i,
 				io_buf->direction, io_buf->fence);
-			CAM_DBG(CAM_REQ, "rsc_type = %u fmt = %d",
-				io_buf->resource_type,
-				io_buf->format);
 		}
 	}
 
@@ -1080,16 +1385,16 @@ static int cam_cre_mgr_process_io_cfg(struct cam_cre_hw_mgr *hw_mgr,
 
 		prep_arg->in_map_entries[0].sync_id = merged_sync_in_obj;
 		prep_arg->num_in_map_entries = 1;
-		CAM_DBG(CAM_REQ, "ctx_id: %u req_id: %llu Merged Sync obj: %d",
+		CAM_DBG(CAM_CRE, "ctx_id: %u req_id: %llu Merged Sync obj: %d",
 			ctx_data->ctx_id, packet->header.request_id,
 			merged_sync_in_obj);
 	} else if (prep_arg->num_in_map_entries == 1) {
 		prep_arg->in_map_entries[0].sync_id = sync_in_obj[0];
 		prep_arg->num_in_map_entries = 1;
 		cre_request->in_resource = 0;
-		CAM_DBG(CAM_CRE, "fence = %d", sync_in_obj[0]);
 	} else {
-		CAM_DBG(CAM_CRE, "Invalid count of input fences, count: %d",
+		CAM_ERR(CAM_CRE,
+			"Invalid count of input fences, count: %d",
 			prep_arg->num_in_map_entries);
 		prep_arg->num_in_map_entries = 0;
 		cre_request->in_resource = 0;
@@ -1203,48 +1508,42 @@ static int cam_cre_validate_acquire_res_info(
 		return -EINVAL;
 	}
 
-	if (cre_acquire->dev_type >= CRE_DEV_MAX) {
+	if (cre_acquire->dev_type >= CAM_CRE_DEV_TYPE_MAX) {
 		CAM_ERR(CAM_CRE, "Invalid device type: %d",
 			cre_acquire->dev_type);
-		return -EFAULT;
+		return -EINVAL;
 	}
 
-	/*
-	 * TODO: Confirm this with CRE HW folks
-	 * Reffering CRE HPG supported input formats are
-	 * CAM_FORMAT_MIPI_RAW_10
-	 * CAM_FORMAT_MIPI_RAW_12
-	 * CAM_FORMAT_MIPI_RAW_14
-	 * CAM_FORMAT_MIPI_RAW_16
-	 * CAM_FORMAT_MIPI_RAW_20
-	 */
 	for (i = 0; i < cre_acquire->num_in_res; i++) {
-		if ((cre_acquire->in_res[i].format <
-			CAM_FORMAT_MIPI_RAW_10) ||
-			(cre_acquire->in_res[i].format >
-			 CAM_FORMAT_MIPI_RAW_20)) {
-			CAM_ERR(CAM_CRE, "Invalid Input format");
-			return -EINVAL;
+		switch (cre_acquire->in_res[i].format) {
+			case CAM_FORMAT_MIPI_RAW_10:
+			case CAM_FORMAT_MIPI_RAW_12:
+			case CAM_FORMAT_MIPI_RAW_14:
+			case CAM_FORMAT_MIPI_RAW_20:
+			case CAM_FORMAT_PLAIN1128:
+				break;
+			default:
+				CAM_ERR(CAM_CRE, "Invalid input format %d",
+					cre_acquire->in_res[i].format);
+				return -EINVAL;
 		}
 	}
 
-	/*
-	 * TODO: Confirm this with CRE HW folks
-	 * Reffering CRE HPG supported output formats are
-	 * CAM_FORMAT_PLAIN16_8
-	 * CAM_FORMAT_PLAIN16_10
-	 * CAM_FORMAT_PLAIN16_12
-	 * CAM_FORMAT_PLAIN16_14
-	 * CAM_FORMAT_PLAIN16_16
-	 * CAM_FORMAT_PLAIN32_20
-	 */
 	for (i = 0; i < cre_acquire->num_out_res; i++) {
-		if ((cre_acquire->out_res[i].format <
-			CAM_FORMAT_PLAIN16_8) ||
-			(cre_acquire->out_res[i].format >
-			 CAM_FORMAT_PLAIN32_20)) {
-			CAM_ERR(CAM_CRE, "Invalid output format");
-			return -EINVAL;
+		switch (cre_acquire->out_res[i].format) {
+			case CAM_FORMAT_PLAIN16_8:
+			case CAM_FORMAT_PLAIN16_10:
+			case CAM_FORMAT_PLAIN16_12:
+			case CAM_FORMAT_PLAIN16_14:
+			case CAM_FORMAT_PLAIN16_16:
+			case CAM_FORMAT_PLAIN32_20:
+			case CAM_FORMAT_PLAIN32:
+			case CAM_FORMAT_PLAIN1128:
+				break;
+			default:
+				CAM_ERR(CAM_CRE, "Invalid output format %d",
+					cre_acquire->out_res[i].format);
+				return -EINVAL;
 		}
 	}
 
@@ -1270,9 +1569,6 @@ static int cam_cre_get_acquire_info(struct cam_cre_hw_mgr *hw_mgr,
 		return -EFAULT;
 	}
 
-	if (cam_cre_validate_acquire_res_info(&ctx->cre_acquire))
-		return -EINVAL;
-
 	CAM_DBG(CAM_CRE, "top: %u %s %u %u %u",
 		ctx->cre_acquire.dev_type,
 		ctx->cre_acquire.dev_name,
@@ -1295,6 +1591,9 @@ static int cam_cre_get_acquire_info(struct cam_cre_hw_mgr *hw_mgr,
 		ctx->cre_acquire.out_res[i].format);
 	}
 
+	if (cam_cre_validate_acquire_res_info(&ctx->cre_acquire))
+		return -EINVAL;
+
 	return 0;
 }
 
@@ -1626,6 +1925,8 @@ static int cam_cre_mgr_release_ctx(struct cam_cre_hw_mgr *hw_mgr, int ctx_id)
 
 	hw_mgr->ctx[ctx_id].req_cnt = 0;
 	hw_mgr->ctx[ctx_id].last_flush_req = 0;
+	hw_mgr->ctx[ctx_id].last_req_idx = 0;
+	hw_mgr->ctx[ctx_id].last_done_req_idx = 0;
 	cam_cre_put_free_ctx(hw_mgr, ctx_id);
 
 	rc = cam_cre_mgr_cre_clk_remove(hw_mgr, ctx_id);
@@ -1888,12 +2189,16 @@ static int cam_cre_mgr_prepare_hw_update(void *hw_priv,
 		return rc;
 	}
 
-	request_idx  = find_first_zero_bit(ctx_data->bitmap, ctx_data->bits);
+	request_idx  = find_next_zero_bit(ctx_data->bitmap,
+			ctx_data->bits, ctx_data->last_req_idx);
 	if (request_idx >= CAM_CTX_REQ_MAX || request_idx < 0) {
 		mutex_unlock(&ctx_data->ctx_mutex);
 		CAM_ERR(CAM_CRE, "Invalid ctx req slot = %d", request_idx);
 		return -EINVAL;
 	}
+	CAM_DBG(CAM_CRE, "req_idx %d last_req_idx %d bitmap size in bits %d",
+		request_idx, ctx_data->last_req_idx, ctx_data->bits);
+	ctx_data->last_req_idx = request_idx;
 
 	ctx_data->req_list[request_idx] =
 		kzalloc(sizeof(struct cam_cre_request), GFP_KERNEL);
@@ -1903,8 +2208,13 @@ static int cam_cre_mgr_prepare_hw_update(void *hw_priv,
 		rc = -ENOMEM;
 		goto req_mem_alloc_failed;
 	}
+	memset(ctx_data->req_list[request_idx], 0,
+			sizeof(struct cam_cre_request));
 
 	cre_req = ctx_data->req_list[request_idx];
+	cre_req->request_id = packet->header.request_id;
+	cre_req->frames_done = 0;
+	cre_req->req_idx = request_idx;
 
 	rc = cam_cre_mgr_process_io_cfg(hw_mgr, packet, ctx_data,
 			request_idx, prepare_args);
@@ -1987,8 +2297,13 @@ static int cam_cre_mgr_enqueue_config(struct cam_cre_hw_mgr *hw_mgr,
 	task_data->req_idx = cre_req->req_idx;
 	task_data->type = CRE_WORKQ_TASK_CMD_TYPE;
 	task->process_cb = cam_cre_mgr_process_cmd;
-	rc = cam_req_mgr_workq_enqueue_task(task, ctx_data,
-		CRM_TASK_PRIORITY_0);
+
+	if (ctx_data->cre_acquire.dev_type == CAM_CRE_DEV_TYPE_RT)
+		rc = cam_req_mgr_workq_enqueue_task(task, ctx_data,
+			CRM_TASK_PRIORITY_0);
+	else
+		rc = cam_req_mgr_workq_enqueue_task(task, ctx_data,
+			CRM_TASK_PRIORITY_1);
 
 	return rc;
 }
@@ -2057,7 +2372,7 @@ static void cam_cre_mgr_print_io_bufs(struct cam_packet *packet,
 	int32_t iommu_hdl, int32_t sec_mmu_hdl, uint32_t pf_buf_info,
 	bool *mem_found)
 {
-	dma_addr_t   iova_addr;
+	dma_addr_t iova_addr;
 	size_t     src_buf_size;
 	int        i;
 	int        j;
@@ -2158,6 +2473,8 @@ static int cam_cre_mgr_flush_req(struct cam_cre_ctx *ctx_data,
 {
 	int idx;
 	int64_t request_id;
+	uint32_t evt_id;
+	struct cam_hw_done_event_data buf_data;
 
 	request_id = *(int64_t *)flush_args->flush_req_pending[0];
 	for (idx = 0; idx < CAM_CTX_REQ_MAX; idx++) {
@@ -2167,6 +2484,10 @@ static int cam_cre_mgr_flush_req(struct cam_cre_ctx *ctx_data,
 		if (ctx_data->req_list[idx]->request_id != request_id)
 			continue;
 
+		evt_id = CAM_CTX_EVT_ID_ERROR;
+		buf_data.evt_param = CAM_SYNC_CRE_EVENT_HW_ERR;
+		buf_data.request_id = ctx_data->req_list[idx]->request_id;
+		ctx_data->ctxt_event_cb(ctx_data->context_priv, evt_id, &buf_data);
 		ctx_data->req_list[idx]->request_id = 0;
 		cam_cre_free_io_config(ctx_data->req_list[idx]);
 		cam_free_clear(ctx_data->req_list[idx]);
@@ -2181,6 +2502,8 @@ static int cam_cre_mgr_flush_all(struct cam_cre_ctx *ctx_data,
 	struct cam_hw_flush_args *flush_args)
 {
 	int i, rc;
+	uint32_t evt_id;
+	struct cam_hw_done_event_data buf_data;
 
 	mutex_lock(&ctx_data->ctx_mutex);
 	rc = cam_cre_mgr_reset_hw();
@@ -2189,6 +2512,10 @@ static int cam_cre_mgr_flush_all(struct cam_cre_ctx *ctx_data,
 		if (!ctx_data->req_list[i])
 			continue;
 
+		evt_id = CAM_CTX_EVT_ID_ERROR;
+		buf_data.evt_param = CAM_SYNC_CRE_EVENT_HW_ERR;
+		buf_data.request_id = ctx_data->req_list[i]->request_id;
+		ctx_data->ctxt_event_cb(ctx_data->context_priv, evt_id, &buf_data);
 		ctx_data->req_list[i]->request_id = 0;
 		cam_cre_free_io_config(ctx_data->req_list[i]);
 		cam_free_clear(ctx_data->req_list[i]);
@@ -2533,15 +2860,6 @@ static int cam_cre_create_debug_fs(void)
 		return -ENOMEM;
 	}
 
-	if (!debugfs_create_bool("frame_dump_enable",
-		0644,
-		cre_hw_mgr->dentry,
-		&cre_hw_mgr->frame_dump_enable)) {
-		CAM_ERR(CAM_CRE,
-			"failed to create dump_enable_debug");
-		goto err;
-	}
-
 	if (!debugfs_create_bool("dump_req_data_enable",
 		0644,
 		cre_hw_mgr->dentry,
@@ -2557,18 +2875,18 @@ err:
 	return -ENOMEM;
 }
 
-int cam_cre_hw_mgr_init(struct device_node *of_node, uint64_t *hw_mgr_hdl,
+int cam_cre_hw_mgr_init(struct device_node *of_node, void *hw_mgr,
 	int *iommu_hdl)
 {
 	int i, rc = 0, j;
 	struct cam_hw_mgr_intf *hw_mgr_intf;
 
-	if (!of_node || !hw_mgr_hdl) {
+	if (!of_node || !hw_mgr) {
 		CAM_ERR(CAM_CRE, "Invalid args of_node %pK hw_mgr %pK",
-			of_node, hw_mgr_hdl);
+			of_node, hw_mgr);
 		return -EINVAL;
 	}
-	hw_mgr_intf = (struct cam_hw_mgr_intf *)hw_mgr_hdl;
+	hw_mgr_intf = (struct cam_hw_mgr_intf *)hw_mgr;
 
 	cre_hw_mgr = kzalloc(sizeof(struct cam_cre_hw_mgr), GFP_KERNEL);
 	if (!cre_hw_mgr) {

+ 44 - 77
drivers/cam_cre/cam_cre_hw_mgr/cam_cre_hw_mgr.h

@@ -19,20 +19,12 @@
 #include "cre_top.h"
 
 #define CRE_CTX_MAX                  32
-#define CAM_FRAME_CMD_MAX            20
 
-#define CRE_WORKQ_NUM_TASK           100
+#define CRE_WORKQ_NUM_TASK           64
 #define CRE_WORKQ_TASK_CMD_TYPE      1
 #define CRE_WORKQ_TASK_MSG_TYPE      2
 
-#define CRE_PACKET_SIZE              0
-#define CRE_PACKET_TYPE              1
-#define CRE_PACKET_OPCODE            2
-
-#define CRE_PACKET_MAX_CMD_BUFS      4
-
-#define CRE_FRAME_PROCESS_SUCCESS    0
-#define CRE_FRAME_PROCESS_FAILURE    1
+#define CRE_PACKET_MAX_CMD_BUFS      1
 
 #define CRE_CTX_STATE_FREE           0
 #define CRE_CTX_STATE_IN_USE         1
@@ -46,22 +38,18 @@
 #define CAM_CRE_BW_CONFIG_UNKNOWN    0
 #define CAM_CRE_BW_CONFIG_V2         2
 
-#define CRE_DEV_MAX                  1
-#define CLK_HW_CRE                   0x0
-#define CLK_HW_MAX                   0x1
-
 #define CRE_DEVICE_IDLE_TIMEOUT      400
 #define CRE_REQUEST_TIMEOUT          200
 
-#define CAM_CRE_HW_CFG_Q_MAX         50
-
 #define CAM_CRE_MAX_PER_PATH_VOTES   6
 #define CAM_CRE_MAX_REG_SET          32
+
+#define CAM_CRE_MAX_ACTIVE           8
 /*
  * Response time threshold in ms beyond which a request is not expected
  * to be with CRE hw
  */
-#define CAM_CRE_RESPONSE_TIME_THRESHOLD   100000
+#define CAM_CRE_RESPONSE_TIME_THRESHOLD   300
 
 /*
  * struct cam_cre_irq_data
@@ -187,23 +175,6 @@ struct cre_clk_work_data {
 	void *data;
 };
 
-/**
- * struct cre_debug_buffer
- *
- * @cpu_addr:         CPU address
- * @iova_addr:        IOVA address
- * @len:              Buffer length
- * @size:             Buffer Size
- * @offset:	      buffer offset
- */
-struct cre_debug_buffer {
-	uintptr_t cpu_addr;
-	dma_addr_t iova_addr;
-	size_t len;
-	uint32_t size;
-	uint32_t offset;
-};
-
 struct plane_info {
 	uintptr_t  cpu_addr;
 	dma_addr_t iova_addr;
@@ -213,7 +184,6 @@ struct plane_info {
 	uint32_t   format;
 	uint32_t   alignment;
 	uint32_t   offset;
-	uint32_t   x_init;
 	size_t     len;
 };
 
@@ -222,9 +192,10 @@ struct plane_info {
  *
  * @direction:     Direction of a buffer
  * @resource_type: Resource type of IO Buffer
- * @format:        Format
+ * @format:     Format
  * @fence:         Fence
  * @num_planes:    Number of planes
+ * p_info:         per plane info
  */
 struct cre_io_buf {
 	uint32_t direction;
@@ -310,7 +281,6 @@ struct cam_cre_request {
 	uint32_t  num_io_bufs[CRE_MAX_BATCH_SIZE];
 	uint32_t  in_resource;
 	struct    cre_reg_buffer cre_reg_buf[CRE_MAX_BATCH_SIZE];
-	struct    cre_debug_buffer cre_debug_buf;
 	struct    cre_io_buf *io_buf[CRE_MAX_BATCH_SIZE][CRE_MAX_IO_BUFS];
 	struct    cam_cre_clk_bw_request clk_info;
 	struct    cam_cre_clk_bw_req_internal_v2 clk_info_v2;
@@ -321,54 +291,54 @@ struct cam_cre_request {
 /**
  * struct cam_cre_ctx
  *
- * @context_priv:    Private data of context
- * @bitmap:          Context bit map
- * @bitmap_size:     Context bit map size
- * @bits:            Context bit map bits
- * @ctx_id:          Context ID
- * @ctx_state:       State of a context
- * @req_cnt:         Requests count
- * @ctx_mutex:       Mutex for context
- * @acquire_dev_cmd: Cam acquire command
- * @cre_acquire:     CRE acquire command
- * @ctxt_event_cb:   Callback of a context
- * @req_list:        Request List
- * @last_req_time:   Timestamp of last request
- * @req_watch_dog:   Watchdog for requests
- * @req_watch_dog_reset_counter: Request reset counter
- * @clk_info:        CRE Ctx clock info
- * @clk_watch_dog:   Clock watchdog
- * @clk_watch_dog_reset_counter: Reset counter
- * @last_flush_req: last flush req for this ctx
+ * @ctx_id:            Context ID
+ * @ctx_state:         State of a context
+ * @req_cnt:           Requests count
+ * @last_flush_req:    last flush req for this ctx
+ * @last_req_time:     Timestamp of last request
+ * @last_req_idx:      Last submitted req index
+ * @last_done_req_idx: Last done req index
+ * @bitmap:            Context bit map
+ * @bitmap_size:       Context bit map size
+ * @bits:              Context bit map bits
+ * @context_priv:      Private data of context
+ * @iommu_hdl:         smmu handle
+ * @ctx_mutex:         Mutex for context
+ * @acquire_dev_cmd:   Cam acquire command
+ * @cre_acquire:       CRE acquire command
+ * @clk_info:          CRE Ctx clock info
+ * @packet:            Current packet to process
+ * @cre_top:           Pointer to CRE top data structure
+ * @req_list:          Request List
+ * @ctxt_event_cb:     Callback of a context
  */
 struct cam_cre_ctx {
-	void *context_priv;
-	size_t bitmap_size;
-	void *bitmap;
-	size_t bits;
 	uint32_t ctx_id;
 	uint32_t ctx_state;
 	uint32_t req_cnt;
-	struct mutex ctx_mutex;
-	struct cam_acquire_dev_cmd acquire_dev_cmd;
-	struct cam_cre_acquire_dev_info cre_acquire;
-	cam_hw_event_cb_func ctxt_event_cb;
-	struct cam_cre_request *req_list[CAM_CTX_REQ_MAX];
-	struct cam_cre_request *active_req;
-	uint64_t last_req_time;
-	struct cam_req_mgr_timer *req_watch_dog;
-	uint32_t req_watch_dog_reset_counter;
-	struct cam_cre_ctx_clk_info clk_info;
-	struct cam_req_mgr_timer *clk_watch_dog;
-	struct cre_top *cre_top;
-	uint32_t clk_watch_dog_reset_counter;
 	uint64_t last_flush_req;
+	uint64_t last_req_time;
+	uint64_t last_req_idx;
+	uint64_t last_done_req_idx;
+	void    *bitmap;
+	size_t   bitmap_size;
+	size_t   bits;
+	void    *context_priv;
+	int      iommu_hdl;
+
+	struct mutex                     ctx_mutex;
+	struct cam_acquire_dev_cmd       acquire_dev_cmd;
+	struct cam_cre_acquire_dev_info  cre_acquire;
+	struct cam_cre_ctx_clk_info      clk_info;
+	struct cre_top                  *cre_top;
+	struct cam_packet               *packet;
+	struct cam_cre_request          *req_list[CAM_CTX_REQ_MAX];
+	cam_hw_event_cb_func ctxt_event_cb;
 };
 
 /**
  * struct cam_cre_hw_mgr
  *
- * @cren_cnt:          CRE device cren count
  * @cre_ctx_cnt:       Open context count
  * @hw_mgr_mutex:      Mutex for HW manager
  * @hw_mgr_lock:       Spinlock for HW manager
@@ -391,11 +361,9 @@ struct cam_cre_ctx {
  * @cre_dev_intf:      CRE device interface
  * @clk_info:          CRE clock Info for HW manager
  * @dentry:            Pointer to CRE debugfs directory
- * @frame_dump_enable: CRE frame setting dump enablement
  * @dump_req_data_enable: CRE hang dump enablement
  */
 struct cam_cre_hw_mgr {
-	int32_t       cren_cnt;
 	uint32_t      cre_ctx_cnt;
 	struct mutex  hw_mgr_mutex;
 	spinlock_t    hw_mgr_lock;
@@ -420,7 +388,6 @@ struct cam_cre_hw_mgr {
 	struct cam_soc_reg_map *reg_map[CRE_DEV_MAX][CRE_BASE_MAX];
 	struct cam_cre_clk_info clk_info;
 	struct dentry *dentry;
-	bool   frame_dump_enable;
 	bool   dump_req_data_enable;
 };
 

+ 103 - 90
drivers/cam_cre/cam_cre_hw_mgr/cre_hw/bus_rd/cre_bus_rd.c

@@ -2,30 +2,17 @@
 /*
  * Copyright (c) 2021, The Linux Foundation. All rights reserved.
  */
-
-#include <linux/of.h>
-#include <linux/debugfs.h>
-#include <linux/videodev2.h>
-#include <linux/uaccess.h>
-#include <linux/platform_device.h>
-#include <linux/firmware.h>
 #include <linux/delay.h>
-#include <linux/timer.h>
-#include <linux/iopoll.h>
-#include <media/cam_cre.h>
-#include "cam_io_util.h"
 #include "cam_hw.h"
 #include "cam_hw_intf.h"
-#include "cre_core.h"
-#include "cre_soc.h"
-#include "cam_soc_util.h"
 #include "cam_io_util.h"
-#include "cam_cpas_api.h"
 #include "cam_debug_util.h"
+#include "cam_common_util.h"
+#include "cre_core.h"
 #include "cre_hw.h"
 #include "cre_dev_intf.h"
 #include "cre_bus_rd.h"
-#include "cam_common_util.h"
+#include <media/cam_cre.h>
 
 static struct cre_bus_rd *bus_rd;
 
@@ -36,6 +23,55 @@ static struct cre_bus_rd *bus_rd;
 		cre_reg_buf->num_rd_reg_set++; \
 	} while (0)
 
+static int cam_cre_bus_rd_in_port_idx(uint32_t input_port_id)
+{
+	int i;
+
+	for (i = 0; i < CRE_MAX_IN_RES; i++)
+		if (bus_rd->in_port_to_rm[i].input_port_id ==
+			input_port_id)
+			return i;
+
+	return -EINVAL;
+}
+
+static void cam_cre_update_read_reg_val(struct plane_info p_info,
+	struct cam_cre_bus_rd_client_reg_val *rd_client_reg_val)
+{
+	switch (p_info.format) {
+		case CAM_FORMAT_MIPI_RAW_10:
+			rd_client_reg_val->format = 0xd;
+			break;
+		case CAM_FORMAT_MIPI_RAW_12:
+			rd_client_reg_val->format = 0xe;
+			break;
+		case CAM_FORMAT_MIPI_RAW_14:
+			rd_client_reg_val->format = 0xf;
+			break;
+		case CAM_FORMAT_MIPI_RAW_20:
+			rd_client_reg_val->format = 0x13;
+			break;
+		case CAM_FORMAT_PLAIN128:
+			rd_client_reg_val->format = 0x0;
+			break;
+		default:
+			CAM_ERR(CAM_CRE, "Unsupported read format");
+			return;
+	}
+
+	CAM_DBG(CAM_CRE,
+		"format %d width(in bytes) %d height %d stride(in byte) %d",
+		p_info.format, p_info.width, p_info.height, p_info.stride);
+	CAM_DBG(CAM_CRE, "alignment 0x%x",
+		p_info.alignment);
+
+	/* Fetch engine width has to be updated in number of bytes */
+	rd_client_reg_val->img_width  = p_info.stride;
+	rd_client_reg_val->stride     = p_info.stride;
+	rd_client_reg_val->img_height = p_info.height;
+	rd_client_reg_val->alignment  = p_info.alignment;
+}
+
 static int cam_cre_bus_rd_release(struct cam_cre_hw *cam_cre_hw_info,
 	int32_t ctx_id, void *data)
 {
@@ -54,22 +90,17 @@ static int cam_cre_bus_rd_update(struct cam_cre_hw *cam_cre_hw_info,
 	int32_t ctx_id, struct cre_reg_buffer *cre_reg_buf, int batch_idx,
 	int io_idx, struct cam_cre_dev_prepare_req *prepare)
 {
-	int k;
-	uint32_t req_idx, temp;
-	uint32_t rm_id;
-	uint32_t rsc_type;
+	int k, in_port_idx;
+	uint32_t req_idx, val;
 	uint32_t iova_base, iova_offset;
 	struct cam_hw_prepare_update_args *prepare_args;
 	struct cam_cre_ctx *ctx_data;
 	struct cam_cre_request *cre_request;
 	struct cre_io_buf *io_buf;
-	struct cre_bus_rd_ctx *bus_rd_ctx;
 	struct cam_cre_bus_rd_reg *rd_reg;
 	struct cam_cre_bus_rd_client_reg *rd_reg_client;
 	struct cam_cre_bus_rd_reg_val *rd_reg_val;
-	struct cam_cre_bus_rd_client_reg_val *rd_res_val_client;
-	struct cre_bus_in_port_to_rm *in_port_to_rm;
-	struct cre_bus_rd_io_port_info *io_port_info;
+	struct cam_cre_bus_rd_client_reg_val *rd_client_reg_val;
 
 	if (ctx_id < 0 || !prepare) {
 		CAM_ERR(CAM_CRE, "Invalid data: %d %x", ctx_id, prepare);
@@ -93,8 +124,6 @@ static int cam_cre_bus_rd_update(struct cam_cre_hw *cam_cre_hw_info,
 	cre_request = ctx_data->req_list[req_idx];
 	CAM_DBG(CAM_CRE, "req_idx = %d req_id = %lld",
 		req_idx, cre_request->request_id);
-	bus_rd_ctx = bus_rd->bus_rd_ctx[ctx_id];
-	io_port_info = &bus_rd_ctx->io_port_info;
 	rd_reg = cam_cre_hw_info->bus_rd_reg_offset;
 	rd_reg_val = cam_cre_hw_info->bus_rd_reg_val;
 	io_buf = cre_request->io_buf[batch_idx][io_idx];
@@ -106,15 +135,13 @@ static int cam_cre_bus_rd_update(struct cam_cre_hw *cam_cre_hw_info,
 	CAM_DBG(CAM_CRE, "batch:%d iobuf:%d direction:%d",
 		batch_idx, io_idx, io_buf->direction);
 
-	in_port_to_rm =
-	&bus_rd->in_port_to_rm[io_buf->resource_type - 1];
+	in_port_idx =
+	cam_cre_bus_rd_in_port_idx(io_buf->resource_type);
 
+	CAM_DBG(CAM_CRE, "in_port_idx %d", in_port_idx);
 	for (k = 0; k < io_buf->num_planes; k++) {
-		rsc_type = io_buf->resource_type - 1;
-		/* frame level info */
-		rm_id = in_port_to_rm->rm_port_id[k];
-		rd_reg_client = &rd_reg->rd_clients[rm_id];
-		rd_res_val_client = &rd_reg_val->rd_clients[rm_id];
+		rd_reg_client = &rd_reg->rd_clients[in_port_idx];
+		rd_client_reg_val = &rd_reg_val->rd_clients[in_port_idx];
 
 		/* security cfg */
 		update_cre_reg_set(cre_reg_buf,
@@ -127,11 +154,9 @@ static int cam_cre_bus_rd_update(struct cam_cre_hw *cam_cre_hw_info,
 			1);
 
 		/* ccif meta data */
-		temp = 0;
 		update_cre_reg_set(cre_reg_buf,
 			(rd_reg->offset + rd_reg_client->ccif_meta_data),
-			temp);
-
+			0);
 		/*
 		 * As CRE have 36 Bit addressing support Image Address
 		 * register will have 28 bit MSB of 36 bit iova.
@@ -148,40 +173,39 @@ static int cam_cre_bus_rd_update(struct cam_cre_hw *cam_cre_hw_info,
 			rd_reg->offset + rd_reg_client->addr_cfg,
 			iova_offset);
 
+		cam_cre_update_read_reg_val(io_buf->p_info[k],
+			rd_client_reg_val);
+
 		/* Buffer size */
 		update_cre_reg_set(cre_reg_buf,
 			rd_reg->offset + rd_reg_client->rd_width,
-			io_buf->p_info[k].width);
+			rd_client_reg_val->img_width);
 		update_cre_reg_set(cre_reg_buf,
 			rd_reg->offset + rd_reg_client->rd_height,
-			io_buf->p_info[k].height);
+			rd_client_reg_val->img_height);
 
 		/* stride */
 		update_cre_reg_set(cre_reg_buf,
 			rd_reg->offset + rd_reg_client->rd_stride,
-			io_buf->p_info[k].stride);
-
-		/* unpacker cfg : Mode and alignment */
-		temp = 0;
-		temp |= (io_buf->p_info[k].format &
-			rd_res_val_client->mode_mask) <<
-			rd_res_val_client->mode_shift;
-		temp |= (io_buf->p_info[k].alignment &
-			rd_res_val_client->alignment_mask) <<
-			rd_res_val_client->alignment_shift;
+			rd_client_reg_val->stride);
+
+		val = 0;
+		val |= (rd_client_reg_val->format &
+			rd_client_reg_val->format_mask) <<
+			rd_client_reg_val->format_shift;
+		val |= (rd_client_reg_val->alignment &
+			rd_client_reg_val->alignment_mask) <<
+			rd_client_reg_val->alignment_shift;
+		/* unpacker cfg : format and alignment */
 		update_cre_reg_set(cre_reg_buf,
-				rd_reg->offset + rd_reg_client->unpacker_cfg,
-				temp);
+			rd_reg->offset + rd_reg_client->unpacker_cfg,
+			val);
 
-		/* latency buffer allocation */
-		update_cre_reg_set(cre_reg_buf,
-				rd_reg->offset + rd_reg_client->latency_buf_allocation,
-				io_port_info->latency_buf_size);
 		/* Enable Debug cfg */
-		temp = 0xFFFF;
+		val = 0xFFFF;
 		update_cre_reg_set(cre_reg_buf,
-				rd_reg->offset + rd_reg_client->debug_status_cfg,
-				temp);
+			rd_reg->offset + rd_reg_client->debug_status_cfg,
+			val);
 	}
 
 	return 0;
@@ -197,12 +221,11 @@ static int cam_cre_bus_rd_prepare(struct cam_cre_hw *cam_cre_hw_info,
 	struct cam_cre_ctx *ctx_data;
 	struct cam_cre_request *cre_request;
 	struct cre_io_buf *io_buf;
-	struct cre_bus_rd_ctx *bus_rd_ctx;
 	struct cam_cre_bus_rd_reg *rd_reg;
 	struct cam_cre_bus_rd_reg_val *rd_reg_val;
 	struct cre_reg_buffer *cre_reg_buf;
 
-	int temp;
+	int val;
 
 	if (ctx_id < 0 || !data) {
 		CAM_ERR(CAM_CRE, "Invalid data: %d %x", ctx_id, data);
@@ -217,7 +240,6 @@ static int cam_cre_bus_rd_prepare(struct cam_cre_hw *cam_cre_hw_info,
 
 	CAM_DBG(CAM_CRE, "req_idx = %d req_id = %lld",
 		req_idx, cre_request->request_id);
-	bus_rd_ctx = bus_rd->bus_rd_ctx[ctx_id];
 	rd_reg = cam_cre_hw_info->bus_rd_reg_offset;
 	rd_reg_val = cam_cre_hw_info->bus_rd_reg_val;
 
@@ -238,29 +260,23 @@ static int cam_cre_bus_rd_prepare(struct cam_cre_hw *cam_cre_hw_info,
 		}
 
 		/* Go command */
-		temp = 0;
-		temp |= rd_reg_val->go_cmd;
-		temp |= rd_reg_val->static_prg & rd_reg_val->static_prg_mask;
+		val = 0;
+		val |= rd_reg_val->go_cmd;
+		val |= rd_reg_val->static_prg & rd_reg_val->static_prg_mask;
 		update_cre_reg_set(cre_reg_buf,
 			rd_reg->offset + rd_reg->input_if_cmd,
-			temp);
+			val);
+	}
+
+	for (i = 0; i < cre_reg_buf->num_rd_reg_set; i++) {
+		CAM_DBG(CAM_CRE, "CRE value 0x%x offset 0x%x",
+				cre_reg_buf->rd_reg_set[i].value,
+				cre_reg_buf->rd_reg_set[i].offset);
 	}
 end:
 	return 0;
 }
 
-static int cam_cre_bus_rd_in_port_idx(uint32_t input_port_id)
-{
-	int i;
-
-	for (i = 0; i < CRE_MAX_IN_RES; i++)
-		if (bus_rd->in_port_to_rm[i].input_port_id ==
-			input_port_id)
-			return i;
-
-	return -EINVAL;
-}
-
 static int cam_cre_bus_rd_acquire(struct cam_cre_hw *cam_cre_hw_info,
 	int32_t ctx_id, void *data)
 {
@@ -271,7 +287,6 @@ static int cam_cre_bus_rd_acquire(struct cam_cre_hw *cam_cre_hw_info,
 	struct cam_cre_bus_rd_reg_val *bus_rd_reg_val;
 	int in_port_idx;
 
-
 	if (ctx_id < 0 || !data || !cam_cre_hw_info || ctx_id >= CRE_CTX_MAX) {
 		CAM_ERR(CAM_CRE, "Invalid data: %d %x %x",
 			ctx_id, data, cam_cre_hw_info);
@@ -295,12 +310,14 @@ static int cam_cre_bus_rd_acquire(struct cam_cre_hw *cam_cre_hw_info,
 		if (!in_acquire->in_res[i].width)
 			continue;
 
-		CAM_DBG(CAM_CRE, "i = %d format = %u width = %x height = %x",
+		CAM_DBG(CAM_CRE, "i = %d format = %u width = 0x%x height = 0x%x res id %d",
 			i, in_acquire->in_res[i].format,
 			in_acquire->in_res[i].width,
-			in_acquire->in_res[i].height);
+			in_acquire->in_res[i].height,
+			in_acquire->in_res[i].res_id);
 
-		in_port_idx = cam_cre_bus_rd_in_port_idx(i + 1);
+		in_port_idx =
+		cam_cre_bus_rd_in_port_idx(in_acquire->in_res[i].res_id);
 		if (in_port_idx < 0) {
 			CAM_ERR(CAM_CRE, "Invalid in_port_idx: %d", i + 1);
 			rc = -EINVAL;
@@ -308,21 +325,15 @@ static int cam_cre_bus_rd_acquire(struct cam_cre_hw *cam_cre_hw_info,
 		}
 
 		in_port_to_rm = &bus_rd->in_port_to_rm[in_port_idx];
-
 		if (!in_port_to_rm->num_rm) {
 			CAM_ERR(CAM_CRE, "Invalid format for Input port");
 			rc = -EINVAL;
 			goto end;
 		}
 
-		bus_rd_ctx->io_port_info.input_port_id[i] =
-			in_acquire->in_res[i].res_id;
-		bus_rd_ctx->io_port_info.input_format_type[i] =
-			in_acquire->in_res[i].format;
-
 		CAM_DBG(CAM_CRE, "i:%d port_id = %u format %u",
-			i, bus_rd_ctx->io_port_info.input_port_id[i],
-			bus_rd_ctx->io_port_info.input_format_type[i]);
+			i, in_acquire->in_res[i].res_id,
+			in_acquire->in_res[i].format);
 	}
 
 end:
@@ -342,6 +353,9 @@ static int cam_cre_bus_rd_reg_set_update(struct cam_cre_hw *cam_cre_hw_info,
 	rd_reg_set = reg_set_upd_cmd->cre_reg_buf.rd_reg_set;
 
 	for (i = 0; i < num_reg_set; i++) {
+		CAM_DBG(CAM_CRE, "base 0x%x CRE value 0x%x offset 0x%x",
+			cam_cre_hw_info->bus_rd_reg_offset->base,
+			rd_reg_set[i].value, rd_reg_set[i].offset);
 		cam_io_w_mb(rd_reg_set[i].value,
 			cam_cre_hw_info->bus_rd_reg_offset->base + rd_reg_set[i].offset);
 	}
@@ -397,7 +411,7 @@ static int cam_cre_bus_rd_probe(struct cam_cre_hw *cam_cre_hw_info,
 
 	for (i = 0; i < bus_rd_reg_val->num_clients; i++) {
 		input_port_idx =
-			bus_rd_reg_val->rd_clients[i].input_port_id - 1;
+			bus_rd_reg_val->rd_clients[i].rm_port_id;
 		in_port_to_rm = &bus_rd->in_port_to_rm[input_port_idx];
 
 		rm_idx = in_port_to_rm->num_rm;
@@ -439,7 +453,6 @@ static int cam_cre_bus_rd_isr(struct cam_cre_hw *cam_cre_hw_info,
 		return -EINVAL;
 	}
 
-	CAM_DBG(CAM_CRE, "error 0x%x", irq_data->error);
 	bus_rd_reg = cam_cre_hw_info->bus_rd_reg_offset;
 	bus_rd_reg_val = cam_cre_hw_info->bus_rd_reg_val;
 

+ 0 - 41
drivers/cam_cre/cam_cre_hw_mgr/cre_hw/bus_rd/cre_bus_rd.h

@@ -15,58 +15,17 @@
 #include "cam_soc_util.h"
 #include "cam_cre_hw_mgr.h"
 
-/**
- * struct cre_bus_rd_io_port_info
- *
- * @pixel_pattern:      Pixel pattern
- * @input_port_id:      Port Id
- * @input_format_type:  Format type
- * @latency_buf_size:   Latency buffer size
- */
-struct cre_bus_rd_io_port_info {
-	uint32_t pixel_pattern[CRE_MAX_IN_RES];
-	uint32_t input_port_id[CRE_MAX_IN_RES];
-	uint32_t input_format_type[CRE_MAX_IN_RES];
-	uint32_t latency_buf_size;
-};
-
-/**
- * struct cre_bus_rd_io_port_batch
- *
- * num_batch:   Number of batches
- * io_port: CDM IO Port Info
- */
-struct cre_bus_rd_io_port_batch {
-	uint32_t num_batch;
-	struct cre_bus_rd_io_port_info io_port[CRE_MAX_BATCH_SIZE];
-};
-
-/**
- * struct cre_bus_rd_rm
- *
- * @rm_port_id:  RM port ID
- * @format_type: Format type
- */
-struct cre_bus_rd_rm {
-	uint32_t rm_port_id;
-	uint32_t format_type;
-};
-
 /**
  * struct cre_bus_rd_ctx
  *
  * @cre_acquire:    CRE acquire structure
  * @security_flag:  security flag
  * @num_in_ports:   Number of in ports
- * @io_port_info:   IO port info
- * @io_port_batch:  IO port info
  */
 struct cre_bus_rd_ctx {
 	struct cam_cre_acquire_dev_info *cre_acquire;
 	bool security_flag;
 	uint32_t num_in_ports;
-	struct cre_bus_rd_io_port_info io_port_info;
-	struct cre_bus_rd_io_port_batch io_port_batch;
 };
 
 /**

+ 105 - 91
drivers/cam_cre/cam_cre_hw_mgr/cre_hw/bus_wr/cre_bus_wr.c

@@ -2,32 +2,19 @@
 /*
  * Copyright (c) 2021, The Linux Foundation. All rights reserved.
  */
-
-#include <linux/of.h>
-#include <linux/debugfs.h>
-#include <linux/videodev2.h>
-#include <linux/uaccess.h>
-#include <linux/platform_device.h>
-#include <linux/firmware.h>
 #include <linux/delay.h>
-#include <linux/timer.h>
-#include <linux/iopoll.h>
-#include <media/cam_cre.h>
 #include "cam_io_util.h"
-#include "cam_hw.h"
 #include "cam_hw_intf.h"
-#include "cre_core.h"
-#include "cre_soc.h"
-#include "cam_soc_util.h"
-#include "cam_io_util.h"
-#include "cam_cpas_api.h"
 #include "cam_debug_util.h"
+#include "cam_common_util.h"
+#include "cre_core.h"
 #include "cre_hw.h"
 #include "cre_dev_intf.h"
 #include "cre_bus_wr.h"
-#include "cam_common_util.h"
+#include <media/cam_cre.h>
 
 static struct cre_bus_wr *wr_info;
+
 #define update_cre_reg_set(cre_reg_buf, off, val) \
 	do {                                           \
 		cre_reg_buf->wr_reg_set[cre_reg_buf->num_wr_reg_set].offset = (off); \
@@ -35,6 +22,30 @@ static struct cre_bus_wr *wr_info;
 		cre_reg_buf->num_wr_reg_set++; \
 	} while (0)
 
+static int cam_cre_translate_write_format(struct plane_info p_info,
+	struct cam_cre_bus_wr_client_reg_val *wr_client_reg_val)
+{
+	CAM_DBG(CAM_CRE, "width 0x%x, height 0x%x stride 0x%x alignment 0x%x",
+		p_info.width, p_info.height, p_info.stride, p_info.alignment);
+
+	/* Number of output pixels */
+	wr_client_reg_val->width     = p_info.width;
+	/* Number of output bytes */
+	wr_client_reg_val->stride    = p_info.stride;
+	/* Number of output lines */
+	wr_client_reg_val->height    = p_info.height;
+	wr_client_reg_val->alignment = p_info.alignment;
+
+	/*
+	 * Update packer format to zero irrespective of output format
+	 * This is as per the recomendation from CRE HW team for CRE 1.0
+	 * This logic has to be updated for CRE 1.1
+	 */
+	wr_client_reg_val->format = 0;
+
+	return 0;
+}
+
 static int cam_cre_bus_wr_out_port_idx(uint32_t output_port_id)
 {
 	int i;
@@ -59,6 +70,9 @@ static int cam_cre_bus_wr_reg_set_update(struct cam_cre_hw *cam_cre_hw_info,
 	wr_reg_set = reg_set_upd_cmd->cre_reg_buf.wr_reg_set;
 
 	for (i = 0; i < num_reg_set; i++) {
+		CAM_DBG(CAM_CRE, "base 0x%x CRE value 0x%x offset 0x%x",
+				cam_cre_hw_info->bus_wr_reg_offset->base,
+				wr_reg_set[i].value, wr_reg_set[i].offset);
 		cam_io_w_mb(wr_reg_set[i].value,
 			cam_cre_hw_info->bus_wr_reg_offset->base + wr_reg_set[i].offset);
 	}
@@ -84,23 +98,18 @@ static int cam_cre_bus_wr_update(struct cam_cre_hw *cam_cre_hw_info,
 	int batch_idx, int io_idx,
 	struct cre_reg_buffer *cre_reg_buf)
 {
-	int k, out_port_idx;
-	uint32_t num_wm_ports;
-	uint32_t comb_idx = 0;
+	int rc, k, out_port_idx;
 	uint32_t req_idx;
-	uint32_t temp = 0;
-	uint32_t wm_port_id;
+	uint32_t val = 0;
 	uint32_t iova_base, iova_offset;
 	struct cam_hw_prepare_update_args *prepare_args;
 	struct cam_cre_ctx *ctx_data;
 	struct cam_cre_request *cre_request;
 	struct cre_io_buf *io_buf;
-	struct cre_bus_wr_ctx *bus_wr_ctx;
 	struct cam_cre_bus_wr_reg *wr_reg;
 	struct cam_cre_bus_wr_client_reg *wr_reg_client;
 	struct cam_cre_bus_wr_reg_val *wr_reg_val;
-	struct cam_cre_bus_wr_client_reg_val *wr_res_val_client;
-	struct cre_bus_out_port_to_wm *out_port_to_wm;
+	struct cam_cre_bus_wr_client_reg_val *wr_client_reg_val;
 
 	if (ctx_id < 0 || !prepare) {
 		CAM_ERR(CAM_CRE, "Invalid data: %d %x", ctx_id, prepare);
@@ -122,11 +131,10 @@ static int cam_cre_bus_wr_update(struct cam_cre_hw *cam_cre_hw_info,
 	req_idx = prepare->req_idx;
 
 	cre_request = ctx_data->req_list[req_idx];
-	bus_wr_ctx = wr_info->bus_wr_ctx[ctx_id];
 	wr_reg = cam_cre_hw_info->bus_wr_reg_offset;
 	wr_reg_val = cam_cre_hw_info->bus_wr_reg_val;
 
-	CAM_DBG(CAM_CRE, "req_idx = %d req_id = %lld offset = %d",
+	CAM_DBG(CAM_CRE, "req_idx = %d req_id = %lld",
 		req_idx, cre_request->request_id);
 
 	io_buf = cre_request->io_buf[batch_idx][io_idx];
@@ -140,25 +148,26 @@ static int cam_cre_bus_wr_update(struct cam_cre_hw *cam_cre_hw_info,
 			io_buf->resource_type);
 		return -EINVAL;
 	}
-	out_port_to_wm = &wr_info->out_port_to_wm[out_port_idx];
-	num_wm_ports = out_port_to_wm->num_wm;
+
+	CAM_DBG(CAM_CRE, "out_port_idx = %d", out_port_idx);
 
 	for (k = 0; k < io_buf->num_planes; k++) {
-		CAM_DBG(CAM_CRE, "comb_idx = %d p_idx = %d",
-			comb_idx, k);
-		/* frame level info */
-		wm_port_id = out_port_to_wm->wm_port_id[k];
-		wr_reg_client = &wr_reg->wr_clients[wm_port_id];
-		wr_res_val_client = &wr_reg_val->wr_clients[wm_port_id];
+		wr_reg_client = &wr_reg->wr_clients[out_port_idx];
+		wr_client_reg_val = &wr_reg_val->wr_clients[out_port_idx];
+
+		CAM_DBG(CAM_CRE, "wr_reg_client %x wr_client_reg_val %x",
+				wr_reg_client, wr_client_reg_val, wr_client_reg_val);
 
 		/* Core cfg: enable, Mode */
-		temp = 0;
-		temp |= ((wr_res_val_client->mode &
-			wr_res_val_client->mode_mask) <<
-			wr_res_val_client->mode_shift);
+		val = 0;
+		val |= ((wr_client_reg_val->mode &
+			wr_client_reg_val->mode_mask) <<
+			wr_client_reg_val->mode_shift);
+		val |= wr_client_reg_val->client_en;
+
 		update_cre_reg_set(cre_reg_buf,
 			wr_reg->offset + wr_reg_client->client_cfg,
-			temp);
+			val);
 
 		/*
 		 * As CRE have 36 Bit addressing support Image Address
@@ -174,41 +183,43 @@ static int cam_cre_bus_wr_update(struct cam_cre_hw *cam_cre_hw_info,
 			wr_reg->offset + wr_reg_client->addr_cfg,
 			iova_offset);
 
+		rc = cam_cre_translate_write_format(io_buf->p_info[k],
+				wr_client_reg_val);
+		if (rc < 0)
+			return -EINVAL;
+
 		/* Buffer size */
-		temp = 0;
-		temp = io_buf->p_info[k].width;
-		temp |= (io_buf->p_info[k].height &
-				wr_res_val_client->height_mask) <<
-				wr_res_val_client->height_shift;
+		val = 0;
+		val = wr_client_reg_val->width;
+		val |= (wr_client_reg_val->height &
+				wr_client_reg_val->height_mask) <<
+				wr_client_reg_val->height_shift;
 		update_cre_reg_set(cre_reg_buf,
 			wr_reg->offset + wr_reg_client->img_cfg_0,
-			temp);
-
-		update_cre_reg_set(cre_reg_buf,
-			wr_reg->offset + wr_reg_client->img_cfg_1,
-			io_buf->p_info[k].x_init);
+			val);
 
 		/* stride */
 		update_cre_reg_set(cre_reg_buf,
 			wr_reg->offset + wr_reg_client->img_cfg_2,
-			io_buf->p_info[k].stride);
-
+			wr_client_reg_val->stride);
+
+		val = 0;
+		val |= ((wr_client_reg_val->format &
+			wr_client_reg_val->format_mask) <<
+			wr_client_reg_val->format_shift);
+		val |= ((wr_client_reg_val->alignment &
+			wr_client_reg_val->alignment_mask) <<
+			wr_client_reg_val->alignment_shift);
 		/* pack cfg : Format and alignment */
-		temp = 0;
-		temp |= ((io_buf->p_info[k].format &
-			wr_res_val_client->format_mask) <<
-			wr_res_val_client->format_shift);
-		temp |= ((io_buf->p_info[k].alignment &
-			wr_res_val_client->alignment_mask) <<
-			wr_res_val_client->alignment_shift);
 		update_cre_reg_set(cre_reg_buf,
 			wr_reg->offset + wr_reg_client->packer_cfg,
-			temp);
+			val);
+
 		/* Upadte debug status CFG*/
-		temp = 0xFFFF;
+		val = 0xFFFF;
 		update_cre_reg_set(cre_reg_buf,
 			wr_reg->offset + wr_reg_client->debug_status_cfg,
-			temp);
+			val);
 	}
 
 	return 0;
@@ -224,7 +235,6 @@ static int cam_cre_bus_wr_prepare(struct cam_cre_hw *cam_cre_hw_info,
 	struct cam_cre_ctx *ctx_data;
 	struct cam_cre_request *cre_request;
 	struct cre_io_buf *io_buf;
-	struct cre_bus_wr_ctx *bus_wr_ctx;
 	struct cre_reg_buffer *cre_reg_buf;
 
 	if (ctx_id < 0 || !data) {
@@ -234,7 +244,6 @@ static int cam_cre_bus_wr_prepare(struct cam_cre_hw *cam_cre_hw_info,
 	prepare = data;
 	ctx_data = prepare->ctx_data;
 	req_idx = prepare->req_idx;
-	bus_wr_ctx = wr_info->bus_wr_ctx[ctx_id];
 
 	cre_request = ctx_data->req_list[req_idx];
 
@@ -245,8 +254,8 @@ static int cam_cre_bus_wr_prepare(struct cam_cre_hw *cam_cre_hw_info,
 		cre_reg_buf = &cre_request->cre_reg_buf[i];
 		for (j = 0; j < cre_request->num_io_bufs[i]; j++) {
 			io_buf = cre_request->io_buf[i][j];
-			CAM_DBG(CAM_CRE, "batch = %d io buf num = %d dir = %d",
-				i, j, io_buf->direction);
+			CAM_DBG(CAM_CRE, "batch = %d io buf num = %d",
+				i, j);
 			if (io_buf->direction != CAM_BUF_OUTPUT)
 				continue;
 
@@ -292,10 +301,11 @@ static int cam_cre_bus_wr_acquire(struct cam_cre_hw *cam_cre_hw_info,
 		if (!in_acquire->out_res[i].width)
 			continue;
 
-		CAM_DBG(CAM_CRE, "i = %d format = %u width = %x height = %x",
+		CAM_DBG(CAM_CRE, "i = %d format = %u width = 0x%x height = 0x%x res_id %d",
 			i, in_acquire->out_res[i].format,
 			in_acquire->out_res[i].width,
-			in_acquire->out_res[i].height);
+			in_acquire->out_res[i].height,
+			in_acquire->in_res[i].res_id);
 
 		out_port_idx =
 		cam_cre_bus_wr_out_port_idx(in_acquire->out_res[i].res_id);
@@ -306,20 +316,12 @@ static int cam_cre_bus_wr_acquire(struct cam_cre_hw *cam_cre_hw_info,
 			goto end;
 		}
 		CAM_DBG(CAM_CRE, "out_port_idx %d", out_port_idx);
-		out_port_to_wr = &wr_info->out_port_to_wm[out_port_idx - 1];
+		out_port_to_wr = &wr_info->out_port_to_wm[out_port_idx];
 		if (!out_port_to_wr->num_wm) {
 			CAM_DBG(CAM_CRE, "Invalid format for Input port");
 			rc = -EINVAL;
 			goto end;
 		}
-
-		bus_wr_ctx->io_port_info.output_port_id[i] =
-			in_acquire->out_res[i].res_id;
-		bus_wr_ctx->io_port_info.output_format_type[i] =
-			in_acquire->out_res[i].format;
-
-		CAM_DBG(CAM_CRE, "i:%d port_id = %u",
-			i, bus_wr_ctx->io_port_info.output_port_id[i]);
 	}
 
 end:
@@ -343,12 +345,12 @@ static int cam_cre_bus_wr_init(struct cam_cre_hw *cam_cre_hw_info,
 	bus_wr_reg = cam_cre_hw_info->bus_wr_reg_offset;
 	bus_wr_reg->base = dev_init->core_info->cre_hw_info->cre_bus_wr_base;
 
+	CAM_DBG(CAM_CRE, "bus_wr_reg->base 0x%x", bus_wr_reg->base);
+
 	cam_io_w_mb(bus_wr_reg_val->irq_mask_0,
-		cam_cre_hw_info->bus_wr_reg_offset->base +
-		bus_wr_reg->irq_mask_0);
+		bus_wr_reg->base + bus_wr_reg->irq_mask_0);
 	cam_io_w_mb(bus_wr_reg_val->irq_mask_1,
-		cam_cre_hw_info->bus_wr_reg_offset->base +
-		bus_wr_reg->irq_mask_1);
+		bus_wr_reg->base + bus_wr_reg->irq_mask_1);
 
 	return 0;
 }
@@ -377,7 +379,7 @@ static int cam_cre_bus_wr_probe(struct cam_cre_hw *cam_cre_hw_info,
 
 	for (i = 0; i < bus_wr_reg_val->num_clients; i++) {
 		output_port_idx =
-			bus_wr_reg_val->wr_clients[i].output_port_id - 1;
+			bus_wr_reg_val->wr_clients[i].wm_port_id;
 		out_port_to_wm = &wr_info->out_port_to_wm[output_port_idx];
 		wm_idx = out_port_to_wm->num_wm;
 		out_port_to_wm->output_port_id =
@@ -391,12 +393,12 @@ static int cam_cre_bus_wr_probe(struct cam_cre_hw *cam_cre_hw_info,
 		out_port_to_wm = &wr_info->out_port_to_wm[i];
 		CAM_DBG(CAM_CRE, "output port id = %d",
 			out_port_to_wm->output_port_id);
-			CAM_DBG(CAM_CRE, "num_wms = %d",
-				out_port_to_wm->num_wm);
-			for (k = 0; k < out_port_to_wm->num_wm; k++) {
-				CAM_DBG(CAM_CRE, "wm port id = %d",
-					out_port_to_wm->wm_port_id[k]);
-			}
+		CAM_DBG(CAM_CRE, "num_wms = %d",
+			out_port_to_wm->num_wm);
+		for (k = 0; k < out_port_to_wm->num_wm; k++) {
+			CAM_DBG(CAM_CRE, "wm port id = %d",
+				out_port_to_wm->wm_port_id[k]);
+		}
 	}
 
 	return 0;
@@ -413,6 +415,7 @@ static int cam_cre_bus_wr_isr(struct cam_cre_hw *cam_cre_hw_info,
 	uint32_t debug_status_1;
 	uint32_t img_violation_status;
 	uint32_t violation_status;
+	int i;
 
 	if (!cam_cre_hw_info || !irq_data) {
 		CAM_ERR(CAM_CRE, "Invalid cam_cre_hw_info");
@@ -425,6 +428,10 @@ static int cam_cre_bus_wr_isr(struct cam_cre_hw *cam_cre_hw_info,
 	/* Read and Clear Top Interrupt status */
 	irq_status_0 = cam_io_r_mb(bus_wr_reg->base + bus_wr_reg->irq_status_0);
 	irq_status_1 = cam_io_r_mb(bus_wr_reg->base + bus_wr_reg->irq_status_1);
+
+	CAM_DBG(CAM_CRE, "BUS irq_status_0 0x%x irq_status_1 0x%x",
+		irq_status_0, irq_status_1);
+
 	cam_io_w_mb(irq_status_0,
 		bus_wr_reg->base + bus_wr_reg->irq_clear_0);
 	cam_io_w_mb(irq_status_1,
@@ -439,7 +446,8 @@ static int cam_cre_bus_wr_isr(struct cam_cre_hw *cam_cre_hw_info,
 	}
 
 	if ((irq_status_0 & bus_wr_reg_val->violation) ||
-		(irq_status_0 & bus_wr_reg_val->img_size_violation)) {
+		(irq_status_0 & bus_wr_reg_val->img_size_violation) ||
+		(irq_status_0 & bus_wr_reg_val->cons_violation)) {
 		irq_data->error = 1;
 		img_violation_status = cam_io_r_mb(bus_wr_reg->base +
 			bus_wr_reg->image_size_violation_status);
@@ -456,8 +464,14 @@ static int cam_cre_bus_wr_isr(struct cam_cre_hw *cam_cre_hw_info,
 			debug_status_0, debug_status_1);
 	}
 
-	if (irq_status_1 & bus_wr_reg_val->client_buf_done)
-		CAM_INFO(CAM_CRE, "Cleint 0 Buff done");
+	if (irq_status_0 & bus_wr_reg_val->comp_buf_done) {
+		for (i = 0; i < bus_wr_reg_val->num_clients; i++) {
+			if (irq_status_1 & bus_wr_reg_val->
+				wr_clients[i].client_buf_done)
+				CAM_INFO(CAM_CRE, "Cleint %d Buff done", i);
+				irq_data->wr_buf_done = 1 << i;
+		}
+	}
 
 	return 0;
 }

+ 0 - 41
drivers/cam_cre/cam_cre_hw_mgr/cre_hw/bus_wr/cre_bus_wr.h

@@ -15,43 +15,6 @@
 #include "cam_soc_util.h"
 #include "cam_cre_hw_mgr.h"
 
-/**
- * struct cre_bus_wr_io_port_info
- *
- * @num_frames_cmds: Number of frame commands
- * @go_cmd_addr:     GO command address
- * @go_cmd_len:      GO command length
- */
-struct cre_bus_wr_io_port_info {
-	uint32_t  num_frames_cmds;
-	uint32_t *go_cmd_addr;
-	uint32_t  go_cmd_len;
-	uint32_t  output_port_id[CRE_MAX_OUT_RES];
-	uint32_t  output_format_type[CRE_MAX_OUT_RES];
-};
-
-/**
- * struct cre_bus_wr_io_port_batch
- *
- * num_batch:   Number of batches
- * io_port: CDM IO Port Info
- */
-struct cre_bus_wr_io_port_batch {
-	uint32_t num_batch;
-	struct cre_bus_wr_io_port_info io_port[CRE_MAX_BATCH_SIZE];
-};
-
-/**
- * struct cre_bus_wr_wm
- *
- * @wm_port_id:  WM port ID
- * @format_type: Format type
- */
-struct cre_bus_wr_wm {
-	uint32_t wm_port_id;
-	uint32_t format_type;
-};
-
 /**
  * struct cre_bus_out_port_to_wm
  *
@@ -72,14 +35,11 @@ struct cre_bus_out_port_to_wm {
  * @cre_acquire:       CRE acquire structure
  * @security_flag:     security flag
  * @num_out_ports:     Number of out ports
- * @io_port_info:      IO port info
  */
 struct cre_bus_wr_ctx {
 	struct cam_cre_acquire_dev_info *cre_acquire;
 	bool security_flag;
 	uint32_t num_out_ports;
-	struct cre_bus_wr_io_port_info io_port_info;
-	struct cre_bus_wr_io_port_batch io_port_batch;
 };
 
 /**
@@ -94,5 +54,4 @@ struct cre_bus_wr {
 	struct cre_bus_out_port_to_wm out_port_to_wm[CRE_MAX_OUT_RES];
 	struct cre_bus_wr_ctx *bus_wr_ctx[CRE_CTX_MAX];
 };
-
 #endif /* CRE_BUS_WR_H */

+ 4 - 9
drivers/cam_cre/cam_cre_hw_mgr/cre_hw/cre_core.c

@@ -4,9 +4,6 @@
  */
 
 #include <linux/of.h>
-#include <linux/debugfs.h>
-#include <linux/videodev2.h>
-#include <linux/uaccess.h>
 #include <linux/platform_device.h>
 #include <linux/delay.h>
 #include <linux/timer.h>
@@ -29,9 +26,6 @@
 
 #define CAM_CRE_RESET_TIMEOUT msecs_to_jiffies(500)
 
-#define CAM_CRE_FE_IRQ 0x4
-#define CAM_CRE_WE_IRQ 0x2
-
 struct cam_cre_irq_data irq_data;
 
 static int cam_cre_caps_vote(struct cam_cre_device_core_info *core_info,
@@ -558,6 +552,7 @@ irqreturn_t cam_cre_irq(int irq_num, void *data)
 	cre_hw = core_info->cre_hw_info->cre_hw;
 
 	irq_data.error = 0;
+	irq_data.wr_buf_done = 0;
 
 	cam_cre_top_process(cre_hw, 0, CRE_HW_ISR, &irq_data);
 
@@ -567,10 +562,10 @@ irqreturn_t cam_cre_irq(int irq_num, void *data)
 		cam_cre_bus_rd_process(cre_hw, 0, CRE_HW_ISR, &irq_data);
 
 	spin_lock(&cre_dev->hw_lock);
+	CAM_DBG(CAM_CRE, "core_info->irq_cb.cre_hw_mgr_cb %x core_info->irq_cb.data %x",
+			core_info->irq_cb.cre_hw_mgr_cb, core_info->irq_cb.data);
 	if (core_info->irq_cb.cre_hw_mgr_cb && core_info->irq_cb.data)
-		if (irq_data.error ||
-			((irq_data.top_irq_status & CAM_CRE_WE_IRQ) &&
-			 irq_data.wr_buf_done))
+		if (irq_data.error || irq_data.wr_buf_done)
 			core_info->irq_cb.cre_hw_mgr_cb(&irq_data,
 				sizeof(struct cam_hw_info),
 				core_info->irq_cb.data);

+ 5 - 0
drivers/cam_cre/cam_cre_hw_mgr/cre_hw/cre_core.h

@@ -16,6 +16,11 @@
 #include "cre_hw.h"
 #include "cam_cre_hw_intf.h"
 
+#define CAM_CRE_IDLE_IRQ  0x8
+#define CAM_CRE_FE_IRQ 0x4
+#define CAM_CRE_WE_IRQ 0x2
+#define CAM_CRE_RESET_IRQ 0x1
+
 /**
  * struct cam_cre_cpas_vote
  * @ahb_vote: AHB vote info

+ 0 - 2
drivers/cam_cre/cam_cre_hw_mgr/cre_hw/cre_dev.c

@@ -3,8 +3,6 @@
  * Copyright (c) 2021, The Linux Foundation. All rights reserved.
  */
 #include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/mod_devicetable.h>
 #include <linux/of_device.h>
 #include <linux/timer.h>
 

+ 8 - 9
drivers/cam_cre/cam_cre_hw_mgr/cre_hw/cre_hw.h

@@ -14,11 +14,10 @@
 #define MAX_CRE_RD_CLIENTS   1
 #define MAX_CRE_WR_CLIENTS   1
 
-#define CRE_TOP_BASE     0x1
-#define CRE_QOS_BASE     0x2
-#define CRE_BUS_RD       0x3
-#define CRE_BUS_WR       0x4
-#define CRE_BASE_MAX     0x5
+#define CRE_TOP_BASE     0x0
+#define CRE_BUS_RD       0x1
+#define CRE_BUS_WR       0x2
+#define CRE_BASE_MAX     0x3
 
 #define CRE_WAIT_BUS_WR_RUP    0x1
 #define CRE_WAIT_BUS_WR_DONE   0x2
@@ -133,9 +132,9 @@ struct cam_cre_bus_rd_client_reg_val {
 	uint32_t alignment;
 	uint32_t alignment_mask;
 	uint32_t alignment_shift;
-	uint32_t mode;
-	uint32_t mode_mask;
-	uint32_t mode_shift;
+	uint32_t format;
+	uint32_t format_mask;
+	uint32_t format_shift;
 	uint32_t latency_buf_size;
 	uint32_t latency_buf_size_mask;
 	uint32_t misr_cfg_en;
@@ -258,6 +257,7 @@ struct cam_cre_bus_wr_client_reg_val {
 	uint32_t x_init_mask;
 	uint32_t stride;
 	uint32_t stride_mask;
+	uint32_t client_buf_done;
 	uint32_t format;
 	uint32_t format_mask;
 	uint32_t format_shift;
@@ -291,7 +291,6 @@ struct cam_cre_bus_wr_reg_val {
 	uint32_t irq_status_1;
 	uint32_t irq_cmd_set;
 	uint32_t irq_cmd_clear;
-	uint32_t client_buf_done;
 	uint32_t frame_header_cfg_0;
 	uint32_t local_frame_header_cfg_0;
 	uint32_t iso_en;

+ 91 - 91
drivers/cam_cre/cam_cre_hw_mgr/cre_hw/cre_hw_100.h

@@ -12,22 +12,22 @@
 #define CRE_BUS_WR_TYPE            0x2
 
 static struct cam_cre_top_reg top_reg = {
-	.hw_version            =  0xFA000,
-	.hw_cap                =  0xFA004,
-	.debug_0               =  0xFA080,
-	.debug_1               =  0xFA084,
-	.debug_cfg             =  0xFA0DC,
-	.testbus_ctrl          =  0xFA1F4,
-	.scratch_0             =  0xFA1F8,
-	.irq_status            =  0xFA00C,
-	.irq_mask              =  0xFA010,
-	.irq_clear             =  0xFA014,
-	.irq_set               =  0xFA018,
-	.irq_cmd               =  0xFA01C,
-	.reset_cmd             =  0xFA008,
-	.core_clk_cfg_ctrl_0   =  0xFA020,
-	.core_clk_cfg_ctrl_1   =  0xFA024,
-	.top_spare             =  0xFA1FC,
+	.hw_version            =  0x000,
+	.hw_cap                =  0x004,
+	.debug_0               =  0x080,
+	.debug_1               =  0x084,
+	.debug_cfg             =  0x0DC,
+	.testbus_ctrl          =  0x1F4,
+	.scratch_0             =  0x1F8,
+	.irq_status            =  0x00C,
+	.irq_mask              =  0x010,
+	.irq_clear             =  0x014,
+	.irq_set               =  0x018,
+	.irq_cmd               =  0x01C,
+	.reset_cmd             =  0x008,
+	.core_clk_cfg_ctrl_0   =  0x020,
+	.core_clk_cfg_ctrl_1   =  0x024,
+	.top_spare             =  0x1FC,
 };
 
 struct cam_cre_top_reg_val top_reg_value = {
@@ -47,38 +47,38 @@ struct cam_cre_top_reg_val top_reg_value = {
 };
 
 struct cam_cre_bus_rd_reg bus_rd_reg = {
-	.hw_version     = 0xFA400,
-	.irq_mask       = 0xFA404,
-	.irq_clear      = 0xFA408,
-	.irq_cmd        = 0xFA40C,
-	.irq_status     = 0xFA410,
-	.input_if_cmd   = 0xFA414,
-	.irq_set        = 0xFA418,
-	.misr_reset     = 0xFA41C,
-	.security_cfg   = 0xFA420,
-	.iso_cfg        = 0xFA424,
-	.iso_seed       = 0xFA428,
-	.test_bus_ctrl  = 0xFA42C,
+	.hw_version     = 0x00,
+	.irq_mask       = 0x04,
+	.irq_clear      = 0x08,
+	.irq_cmd        = 0x0C,
+	.irq_status     = 0x10,
+	.input_if_cmd   = 0x14,
+	.irq_set        = 0x18,
+	.misr_reset     = 0x1C,
+	.security_cfg   = 0x20,
+	.iso_cfg        = 0x24,
+	.iso_seed       = 0x28,
+	.test_bus_ctrl  = 0x2C,
 	.num_clients    = 1,
 	.rd_clients[0]  = {
-		.core_cfg               = 0xFA450,
-		.ccif_meta_data         = 0xFA454,
-		.img_addr               = 0xFA458,
-		.rd_width               = 0xFA45C,
-		.rd_height              = 0xFA460,
-		.rd_stride              = 0xFA464,
-		.unpacker_cfg           = 0xFA468,
-		.latency_buf_allocation = 0xFA47C,
-		.misr_cfg_0             = 0xFA484,
-		.misr_cfg_1             = 0xFA488,
-		.misr_rd_val            = 0xFA48C,
-		.debug_status_cfg       = 0xFA490,
-		.debug_status_0         = 0xFA494,
-		.debug_status_1         = 0xFA498,
-		.read_buff_cfg          = 0xFA4A0,
-		.addr_cfg               = 0xFA4A4,
-		.spare                  = 0xFA430,
-		.cons_violation         = 0xFA434,
+		.core_cfg               = 0x50,
+		.ccif_meta_data         = 0x54,
+		.img_addr               = 0x58,
+		.rd_width               = 0x5C,
+		.rd_height              = 0x60,
+		.rd_stride              = 0x64,
+		.unpacker_cfg           = 0x68,
+		.latency_buf_allocation = 0x7C,
+		.misr_cfg_0             = 0x84,
+		.misr_cfg_1             = 0x88,
+		.misr_rd_val            = 0x8C,
+		.debug_status_cfg       = 0x90,
+		.debug_status_0         = 0x94,
+		.debug_status_1         = 0x98,
+		.read_buff_cfg          = 0xA0,
+		.addr_cfg               = 0xA4,
+		.spare                  = 0x30,
+		.cons_violation         = 0x34,
 	},
 };
 
@@ -99,7 +99,6 @@ struct cam_cre_bus_wr_reg_val bus_wr_reg_value = {
 	.irq_status_1                 = 0x1,
 	.irq_cmd_set                  = 0x10,
 	.irq_cmd_clear                = 0x1,
-	.client_buf_done              = 0x1,
 	.iso_en                       = 0x1,
 	.iso_en_mask                  = 0x1,
 	.misr_0_en                    = 0x1,
@@ -132,14 +131,15 @@ struct cam_cre_bus_wr_reg_val bus_wr_reg_value = {
 		.bw_limit_en              = 0x1,
 		.bw_limit_en_mask         = 0x1,
 		.bw_limit_counter_mask    = 0x1fe,
+	        .client_buf_done          = 0x1,
 		.output_port_id           = CAM_CRE_OUTPUT_IMAGE,
-		.wm_port_id               = 1,
+		.wm_port_id               = 0,
 	},
 };
 
 struct cam_cre_bus_rd_reg_val bus_rd_reg_value = {
 	.hw_version              = 0x30000000,
-	.irq_mask                = 0x7,
+	.irq_mask                = 0x1, /* INFO_CONS_VIOLATION */
 	.rd_buf_done             = 0x4,
 	.rup_done                = 0x2,
 	.cons_violation          = 0x1,
@@ -171,8 +171,8 @@ struct cam_cre_bus_rd_reg_val bus_rd_reg_value = {
 		.stripe_location_shift   = 0x0,
 		.alignment_mask          = 0x1,
 		.alignment_shift         = 0x5,
-		.mode_mask               = 0x1f,
-		.mode_shift              = 0x0,
+		.format_mask             = 0x1f,
+		.format_shift            = 0x0,
 		.latency_buf_size_mask   = 0xffff,
 		.misr_cfg_en_mask        = 0x4,
 		.misr_cfg_samp_mode_mask = 0x3,
@@ -184,48 +184,48 @@ struct cam_cre_bus_rd_reg_val bus_rd_reg_value = {
 };
 
 struct cam_cre_bus_wr_reg bus_wr_reg = {
-	.hw_version                   = 0xFA700,
-	.cgc_override                 = 0xFA708,
-	.irq_mask_0                   = 0xFA718,
-	.irq_mask_1                   = 0xFA71C,
-	.irq_clear_0                  = 0xFA720,
-	.irq_clear_1                  = 0xFA724,
-	.irq_status_0                 = 0xFA728,
-	.irq_status_1                 = 0xFA72C,
-	.irq_cmd                      = 0xFA730,
+	.hw_version                   = 0x00,
+	.cgc_override                 = 0x08,
+	.irq_mask_0                   = 0x18,
+	.irq_mask_1                   = 0x1C,
+	.irq_clear_0                  = 0x20,
+	.irq_clear_1                  = 0x24,
+	.irq_status_0                 = 0x28,
+	.irq_status_1                 = 0x2C,
+	.irq_cmd                      = 0x30,
 	.frame_header_cfg_0           = 0x0,
-	.local_frame_header_cfg_0     = 0xFA74C,
-	.irq_set_0                    = 0xFA750,
-	.irq_set_1                    = 0xFA754,
-	.iso_cfg                      = 0xFA75C,
-	.violation_status             = 0xFA764,
-	.image_size_violation_status  = 0xFA770,
-	.perf_count_cfg_0             = 0xFA774,
-	.perf_count_cfg_1             = 0xFA778,
-	.perf_count_cfg_2             = 0xFA77C,
-	.perf_count_cfg_3             = 0xFA780,
-	.perf_count_val_0             = 0xFA794,
-	.perf_count_val_1             = 0xFA798,
-	.perf_count_val_2             = 0xFA79C,
-	.perf_count_val_3             = 0xFA7A0,
-	.perf_count_status            = 0xFA7B4,
-	.misr_cfg_0                   = 0xFA7B8,
-	.misr_cfg_1                   = 0xFA7BC,
-	.misr_rd_sel                  = 0xFA7C8,
-	.misr_reset                   = 0xFA7CC,
-	.misr_val                     = 0xFA7D0,
+	.local_frame_header_cfg_0     = 0x4C,
+	.irq_set_0                    = 0x50,
+	.irq_set_1                    = 0x54,
+	.iso_cfg                      = 0x5C,
+	.violation_status             = 0x64,
+	.image_size_violation_status  = 0x70,
+	.perf_count_cfg_0             = 0x74,
+	.perf_count_cfg_1             = 0x78,
+	.perf_count_cfg_2             = 0x7C,
+	.perf_count_cfg_3             = 0x80,
+	.perf_count_val_0             = 0x94,
+	.perf_count_val_1             = 0x98,
+	.perf_count_val_2             = 0x9C,
+	.perf_count_val_3             = 0xA0,
+	.perf_count_status            = 0xB4,
+	.misr_cfg_0                   = 0xB8,
+	.misr_cfg_1                   = 0xBC,
+	.misr_rd_sel                  = 0xC8,
+	.misr_reset                   = 0xCC,
+	.misr_val                     = 0xD0,
 	.wr_clients[0]             = {
-		.client_cfg           = 0xFA900,
-		.img_addr             = 0xFA904,
-		.img_cfg_0            = 0xFA90C,
-		.img_cfg_1            = 0xFA910,
-		.img_cfg_2            = 0xFA914,
-		.bw_limit             = 0xFA918,
-		.packer_cfg           = 0xFA91C,
-		.addr_cfg             = 0xFA970,
-		.debug_status_cfg     = 0xFA984,
-		.debug_status_0       = 0xFA988,
-		.debug_status_1       = 0xFA98C,
+		.client_cfg           = 0x200,
+		.img_addr             = 0x204,
+		.img_cfg_0            = 0x20C,
+		.img_cfg_1            = 0x210,
+		.img_cfg_2            = 0x214,
+		.packer_cfg           = 0x218,
+		.bw_limit             = 0x21C,
+		.addr_cfg             = 0x270,
+		.debug_status_cfg     = 0x284,
+		.debug_status_0       = 0x288,
+		.debug_status_1       = 0x28C,
 	},
 };
 

+ 1 - 1
drivers/cam_cre/cam_cre_hw_mgr/cre_hw/include/cam_cre_hw_mgr_intf.h

@@ -13,6 +13,6 @@
 #define CAM_CRE_CTX_MAX        16
 
 int cam_cre_hw_mgr_init(struct device_node *of_node,
-	uint64_t *hw_mgr_hdl, int *iommu_hdl);
+	void *hw_mgr, int *iommu_hdl);
 
 #endif /* CAM_CRE_HW_MGR_INTF_H */

+ 1 - 8
drivers/cam_cre/cam_cre_hw_mgr/cre_hw/top/cre_top.c

@@ -2,16 +2,9 @@
 /*
  * Copyright (c) 2021, The Linux Foundation. All rights reserved.
  */
-
-#include <linux/of.h>
-#include <linux/debugfs.h>
-#include <linux/videodev2.h>
-#include <linux/uaccess.h>
 #include <linux/platform_device.h>
-#include <linux/firmware.h>
 #include <linux/delay.h>
 #include <linux/timer.h>
-#include <linux/iopoll.h>
 #include <linux/completion.h>
 #include <media/cam_cre.h>
 #include "cam_io_util.h"
@@ -21,7 +14,6 @@
 #include "cre_soc.h"
 #include "cam_soc_util.h"
 #include "cam_io_util.h"
-#include "cam_cpas_api.h"
 #include "cam_debug_util.h"
 #include "cre_hw.h"
 #include "cre_dev_intf.h"
@@ -155,6 +147,7 @@ static int cam_cre_top_init(struct cam_cre_hw *cre_hw_info,
 	/* CRE SW RESET */
 	init_completion(&cre_top_info.reset_complete);
 	init_completion(&cre_top_info.idle_done);
+	init_completion(&cre_top_info.bufdone);
 
 	/* enable interrupt mask */
 	cam_io_w_mb(top_reg_val->irq_mask,

+ 1 - 0
drivers/cam_cre/cam_cre_hw_mgr/cre_hw/top/cre_top.h

@@ -40,6 +40,7 @@ struct cre_top {
 	struct cre_top_ctx top_ctx[CAM_CRE_CTX_MAX];
 	struct completion reset_complete;
 	struct completion idle_done;
+	struct completion bufdone;
 	struct mutex      cre_hw_mutex;
 	spinlock_t        hw_lock;
 };