Browse Source

UPSTREAM: 11/22/19: Merge 'quic/camera-kernel.lnx.1.0' into 'quic/camera-kernel.lnx.4.0'

* quic/camera-kernel.lnx.1.0::
  msm: camera: sensor: Support for read operation
  msm: camera: req_mgr: Fix kmem_cache definition
  msm: camera: custom: Add support for acquire_hw_v1
  msm: camera: core: Prevent crash on kref_put
  msm: camera: isp: csid hw register reset with IRQ
  msm: camera: isp: Reset overflow pending flag in start hw
  msm: camera: icp: Increase MAX_PKT_SIZE_MSGQ for ICP
  msm: camera: icp: icp debug improvement
  msm: camera: reqmgr: Improve master slave sync
  msm: camera: isp: Notify CRM to pause SOF timer after flush
  msm: camera: csiphy: Fix csiphy v1.2 skew calibration settings
  msm: camera: csiphy: Update reset sequence for csiphy v1.2
  msm: camera: csiphy: Update registers for CSIPHY v1.2
  msm: camera: reqmgr: Change v4l2 notify error log type
  msm: camera: isp: Set device enable flag after enable csid hardware

Change-Id: I52c682b36583436425d157c8927e6fbcf5bf32eb
Signed-off-by: Abhijit Trivedi <[email protected]>
Abhijit Trivedi 5 years ago
parent
commit
a15be98002
26 changed files with 1154 additions and 345 deletions
  1. 6 1
      drivers/cam_core/cam_context.c
  2. 211 20
      drivers/cam_cust/cam_custom_context.c
  3. 2 0
      drivers/cam_cust/cam_custom_context.h
  4. 104 145
      drivers/cam_cust/cam_custom_hw_mgr/cam_custom_hw_mgr.c
  5. 1 1
      drivers/cam_icp/fw_inc/hfi_reg.h
  6. 4 0
      drivers/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c
  7. 9 0
      drivers/cam_isp/cam_isp_context.c
  8. 25 10
      drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c
  9. 101 56
      drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c
  10. 1 0
      drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.h
  11. 1 1
      drivers/cam_req_mgr/Makefile
  12. 71 5
      drivers/cam_req_mgr/cam_req_mgr_core.c
  13. 30 18
      drivers/cam_req_mgr/cam_req_mgr_dev.c
  14. 16 0
      drivers/cam_req_mgr/cam_req_mgr_interface.h
  15. 3 1
      drivers/cam_req_mgr/cam_req_mgr_timer.c
  16. 7 6
      drivers/cam_req_mgr/cam_req_mgr_timer.h
  17. 65 3
      drivers/cam_sensor_module/cam_actuator/cam_actuator_core.c
  18. 50 61
      drivers/cam_sensor_module/cam_csiphy/include/cam_csiphy_1_2_hwreg.h
  19. 3 3
      drivers/cam_sensor_module/cam_flash/cam_flash_core.c
  20. 64 3
      drivers/cam_sensor_module/cam_ois/cam_ois_core.c
  21. 41 1
      drivers/cam_sensor_module/cam_sensor/cam_sensor_core.c
  22. 3 1
      drivers/cam_sensor_module/cam_sensor/cam_sensor_dev.c
  23. 10 3
      drivers/cam_sensor_module/cam_sensor_utils/cam_sensor_cmn_header.h
  24. 303 5
      drivers/cam_sensor_module/cam_sensor_utils/cam_sensor_util.c
  25. 6 1
      drivers/cam_sensor_module/cam_sensor_utils/cam_sensor_util.h
  26. 17 0
      include/uapi/camera/media/cam_custom.h

+ 6 - 1
drivers/cam_core/cam_context.c

@@ -597,7 +597,12 @@ int cam_context_deinit(struct cam_context *ctx)
 
 void cam_context_putref(struct cam_context *ctx)
 {
-	kref_put(&ctx->refcount, cam_node_put_ctxt_to_free_list);
+	if (kref_read(&ctx->refcount))
+		kref_put(&ctx->refcount, cam_node_put_ctxt_to_free_list);
+	else
+		WARN(1, "ctx %s %d state %d devhdl %X\n", ctx->dev_name,
+			ctx->ctx_id, ctx->state, ctx->dev_hdl);
+
 	CAM_DBG(CAM_CORE,
 		"ctx device hdl %ld, ref count %d, dev_name %s",
 		ctx->dev_hdl, refcount_read(&(ctx->refcount.refcount)),

+ 211 - 20
drivers/cam_cust/cam_custom_context.c

@@ -19,7 +19,7 @@
 #include "cam_custom_context.h"
 #include "cam_common_util.h"
 
-static const char custom_dev_name[] = "custom hw";
+static const char custom_dev_name[] = "cam-custom";
 
 static int __cam_custom_ctx_handle_irq_in_activated(
 	void *context, uint32_t evt_id, void *evt_data);
@@ -275,6 +275,67 @@ static int __cam_custom_stop_dev_in_activated(struct cam_context *ctx,
 	return 0;
 }
 
+static int __cam_custom_ctx_release_hw_in_top_state(
+	struct cam_context *ctx, void *cmd)
+{
+	int rc = 0;
+	struct cam_hw_release_args        rel_arg;
+	struct cam_req_mgr_flush_request  flush_req;
+	struct cam_custom_context        *custom_ctx =
+		(struct cam_custom_context *) ctx->ctx_priv;
+
+	if (custom_ctx->hw_ctx) {
+		rel_arg.ctxt_to_hw_map = custom_ctx->hw_ctx;
+		rc = ctx->hw_mgr_intf->hw_release(ctx->hw_mgr_intf->hw_mgr_priv,
+			&rel_arg);
+		custom_ctx->hw_ctx = NULL;
+		if (rc)
+			CAM_ERR(CAM_CUSTOM,
+				"Failed to release HW for ctx:%u", ctx->ctx_id);
+	} else {
+		CAM_ERR(CAM_CUSTOM, "No HW resources acquired for this ctx");
+	}
+
+	ctx->last_flush_req = 0;
+	custom_ctx->frame_id = 0;
+	custom_ctx->active_req_cnt = 0;
+	custom_ctx->hw_acquired = false;
+	custom_ctx->init_received = false;
+
+	/* check for active requests as well */
+	flush_req.type = CAM_REQ_MGR_FLUSH_TYPE_ALL;
+	flush_req.link_hdl = ctx->link_hdl;
+	flush_req.dev_hdl = ctx->dev_hdl;
+
+	CAM_DBG(CAM_CUSTOM, "try to flush pending list");
+	spin_lock_bh(&ctx->lock);
+	rc = __cam_custom_ctx_flush_req(ctx, &ctx->pending_req_list,
+		&flush_req);
+	spin_unlock_bh(&ctx->lock);
+	ctx->state = CAM_CTX_ACQUIRED;
+
+	CAM_DBG(CAM_CUSTOM, "Release HW success[%u] next state %d",
+		ctx->ctx_id, ctx->state);
+
+	return rc;
+}
+
+static int __cam_custom_ctx_release_hw_in_activated_state(
+	struct cam_context *ctx, void *cmd)
+{
+	int rc = 0;
+
+	rc = __cam_custom_stop_dev_in_activated(ctx, NULL);
+	if (rc)
+		CAM_ERR(CAM_CUSTOM, "Stop device failed rc=%d", rc);
+
+	rc = __cam_custom_ctx_release_hw_in_top_state(ctx, cmd);
+	if (rc)
+		CAM_ERR(CAM_CUSTOM, "Release hw failed rc=%d", rc);
+
+	return rc;
+}
+
 static int __cam_custom_release_dev_in_acquired(struct cam_context *ctx,
 	struct cam_release_dev_cmd *cmd)
 {
@@ -283,14 +344,16 @@ static int __cam_custom_release_dev_in_acquired(struct cam_context *ctx,
 		(struct cam_custom_context *) ctx->ctx_priv;
 	struct cam_req_mgr_flush_request flush_req;
 
-	rc = cam_context_release_dev_to_hw(ctx, cmd);
-	if (rc)
-		CAM_ERR(CAM_CUSTOM, "Unable to release device");
+	if (cmd && ctx_custom->hw_ctx) {
+		CAM_ERR(CAM_CUSTOM, "releasing hw");
+		__cam_custom_ctx_release_hw_in_top_state(ctx, NULL);
+	}
 
 	ctx->ctx_crm_intf = NULL;
 	ctx->last_flush_req = 0;
 	ctx_custom->frame_id = 0;
 	ctx_custom->active_req_cnt = 0;
+	ctx_custom->hw_acquired = false;
 	ctx_custom->init_received = false;
 
 	if (!list_empty(&ctx->active_req_list))
@@ -381,33 +444,128 @@ end:
 	return rc;
 }
 
-static int __cam_custom_ctx_acquire_dev_in_available(struct cam_context *ctx,
-	struct cam_acquire_dev_cmd *cmd)
+static int __cam_custom_ctx_acquire_hw_v1(
+	struct cam_context *ctx, void *args)
 {
-	int rc;
-	struct cam_custom_context *custom_ctx;
+	int rc = 0;
+	struct cam_acquire_hw_cmd_v1 *cmd =
+		(struct cam_acquire_hw_cmd_v1 *)args;
+	struct cam_hw_acquire_args         param;
+	struct cam_custom_context         *ctx_custom =
+		(struct cam_custom_context *)  ctx->ctx_priv;
+	struct cam_custom_acquire_hw_info *acquire_hw_info = NULL;
+
+	if (!ctx->hw_mgr_intf) {
+		CAM_ERR(CAM_CUSTOM, "HW interface is not ready");
+		rc = -EFAULT;
+		goto end;
+	}
 
-	custom_ctx = (struct cam_custom_context *) ctx->ctx_priv;
+	CAM_DBG(CAM_CUSTOM,
+		"session_hdl 0x%x, hdl type %d, res %lld",
+		cmd->session_handle, cmd->handle_type, cmd->resource_hdl);
 
-	if (cmd->num_resources > CAM_CUSTOM_DEV_CTX_RES_MAX) {
-		CAM_ERR(CAM_CUSTOM, "Too much resources in the acquire");
+	if (cmd->handle_type != 1)  {
+		CAM_ERR(CAM_CUSTOM, "Only user pointer is supported");
+		rc = -EINVAL;
+		goto end;
+	}
+
+	if (cmd->data_size < sizeof(*acquire_hw_info)) {
+		CAM_ERR(CAM_CUSTOM, "data_size is not a valid value");
+		goto end;
+	}
+
+	acquire_hw_info = kzalloc(cmd->data_size, GFP_KERNEL);
+	if (!acquire_hw_info) {
 		rc = -ENOMEM;
-		return rc;
+		goto end;
 	}
 
-	if (cmd->handle_type != 1)	{
-		CAM_ERR(CAM_CUSTOM, "Only user pointer is supported");
-		rc = -EINVAL;
+	CAM_DBG(CAM_CUSTOM, "start copy resources from user");
+
+	if (copy_from_user(acquire_hw_info, (void __user *)cmd->resource_hdl,
+		cmd->data_size)) {
+		rc = -EFAULT;
+		goto free_res;
+	}
+
+	memset(&param, 0, sizeof(param));
+	param.context_data = ctx;
+	param.event_cb = ctx->irq_cb_intf;
+	param.acquire_info_size = cmd->data_size;
+	param.acquire_info = (uint64_t) acquire_hw_info;
+
+	/* call HW manager to reserve the resource */
+	rc = ctx->hw_mgr_intf->hw_acquire(ctx->hw_mgr_intf->hw_mgr_priv,
+		&param);
+	if (rc != 0) {
+		CAM_ERR(CAM_CUSTOM, "Acquire HW failed");
+		goto free_res;
+	}
+
+	ctx_custom->hw_ctx = param.ctxt_to_hw_map;
+	ctx_custom->hw_acquired = true;
+	ctx->ctxt_to_hw_map = param.ctxt_to_hw_map;
+
+	CAM_DBG(CAM_CUSTOM,
+		"Acquire HW success on session_hdl 0x%xs for ctx_id %u",
+		ctx->session_hdl, ctx->ctx_id);
+
+	kfree(acquire_hw_info);
+	return rc;
+
+free_res:
+	kfree(acquire_hw_info);
+end:
+	return rc;
+}
+
+static int __cam_custom_ctx_acquire_dev_in_available(
+	struct cam_context *ctx, struct cam_acquire_dev_cmd *cmd)
+{
+	int rc = 0;
+	struct cam_create_dev_hdl  req_hdl_param;
+
+	if (!ctx->hw_mgr_intf) {
+		CAM_ERR(CAM_CUSTOM, "HW interface is not ready");
+		rc = -EFAULT;
 		return rc;
 	}
 
-	rc = cam_context_acquire_dev_to_hw(ctx, cmd);
-	if (!rc) {
-		ctx->state = CAM_CTX_ACQUIRED;
-		custom_ctx->hw_ctx = ctx->ctxt_to_hw_map;
+	CAM_DBG(CAM_CUSTOM,
+		"session_hdl 0x%x, num_resources %d, hdl type %d, res %lld",
+		cmd->session_handle, cmd->num_resources,
+		cmd->handle_type, cmd->resource_hdl);
+
+	if (cmd->num_resources != CAM_API_COMPAT_CONSTANT) {
+		CAM_ERR(CAM_CUSTOM, "Invalid num_resources 0x%x",
+			cmd->num_resources);
+		return -EINVAL;
 	}
 
-	CAM_DBG(CAM_CUSTOM, "Acquire done %d", ctx->ctx_id);
+	req_hdl_param.session_hdl = cmd->session_handle;
+	req_hdl_param.v4l2_sub_dev_flag = 0;
+	req_hdl_param.media_entity_flag = 0;
+	req_hdl_param.ops = ctx->crm_ctx_intf;
+	req_hdl_param.priv = ctx;
+
+	CAM_DBG(CAM_CUSTOM, "get device handle from bridge");
+	ctx->dev_hdl = cam_create_device_hdl(&req_hdl_param);
+	if (ctx->dev_hdl <= 0) {
+		rc = -EFAULT;
+		CAM_ERR(CAM_CUSTOM, "Can not create device handle");
+		return rc;
+	}
+
+	cmd->dev_handle = ctx->dev_hdl;
+	ctx->session_hdl = cmd->session_handle;
+	ctx->state = CAM_CTX_ACQUIRED;
+
+	CAM_DBG(CAM_CUSTOM,
+		"Acquire dev success on session_hdl 0x%x for ctx %u",
+		cmd->session_handle, ctx->ctx_id);
+
 	return rc;
 }
 
@@ -642,6 +800,13 @@ static int __cam_custom_ctx_config_dev_in_acquired(struct cam_context *ctx,
 	struct cam_config_dev_cmd *cmd)
 {
 	int rc = 0;
+	struct cam_custom_context        *ctx_custom =
+		(struct cam_custom_context *) ctx->ctx_priv;
+
+	if (!ctx_custom->hw_acquired) {
+		CAM_ERR(CAM_CUSTOM, "HW not acquired, reject config packet");
+		return -EAGAIN;
+	}
 
 	rc = __cam_custom_ctx_config_dev(ctx, cmd);
 
@@ -826,6 +991,27 @@ static int __cam_custom_ctx_handle_irq_in_activated(void *context,
 	return rc;
 }
 
+static int __cam_custom_ctx_acquire_hw_in_acquired(
+	struct cam_context *ctx, void *args)
+{
+	int rc = -EINVAL;
+	uint32_t api_version;
+
+	if (!ctx || !args) {
+		CAM_ERR(CAM_CUSTOM, "Invalid input pointer");
+		return rc;
+	}
+
+	api_version = *((uint32_t *)args);
+	if (api_version == 1)
+		rc = __cam_custom_ctx_acquire_hw_v1(ctx, args);
+	else
+		CAM_ERR(CAM_CUSTOM, "Unsupported api version %d",
+			api_version);
+
+	return rc;
+}
+
 /* top state machine */
 static struct cam_ctx_ops
 	cam_custom_dev_ctx_top_state_machine[CAM_CTX_STATE_MAX] = {
@@ -847,8 +1033,10 @@ static struct cam_ctx_ops
 	/* Acquired */
 	{
 		.ioctl_ops = {
+			.acquire_hw = __cam_custom_ctx_acquire_hw_in_acquired,
 			.release_dev = __cam_custom_release_dev_in_acquired,
 			.config_dev = __cam_custom_ctx_config_dev_in_acquired,
+			.release_hw = __cam_custom_ctx_release_hw_in_top_state,
 		},
 		.crm_ops = {
 			.link = __cam_custom_ctx_link_in_acquired,
@@ -866,6 +1054,7 @@ static struct cam_ctx_ops
 			.start_dev = __cam_custom_ctx_start_dev_in_ready,
 			.release_dev = __cam_custom_release_dev_in_acquired,
 			.config_dev = __cam_custom_ctx_config_dev,
+			.release_hw = __cam_custom_ctx_release_hw_in_top_state,
 		},
 		.crm_ops = {
 			.unlink = __cam_custom_ctx_unlink_in_ready,
@@ -883,6 +1072,8 @@ static struct cam_ctx_ops
 			.release_dev =
 				__cam_custom_ctx_release_dev_in_activated,
 			.config_dev = __cam_custom_ctx_config_dev,
+			.release_hw =
+				__cam_custom_ctx_release_hw_in_activated_state,
 		},
 		.crm_ops = {
 			.unlink = __cam_custom_ctx_unlink_in_activated,

+ 2 - 0
drivers/cam_cust/cam_custom_context.h

@@ -68,6 +68,7 @@ struct cam_custom_dev_ctx_req {
  *                   custom HW will invoke CRM cb at those event.
  * @active_req_cnt: Counter for the active request
  * @frame_id: Frame id tracking for the custom context
+ * @hw_acquired: Flag to indicate if HW is acquired for this context
  * @req_base: common request structure
  * @req_custom: custom request structure
  *
@@ -81,6 +82,7 @@ struct cam_custom_context {
 	uint32_t                      subscribe_event;
 	uint32_t                      active_req_cnt;
 	int64_t                       frame_id;
+	bool                          hw_acquired;
 	struct cam_ctx_request        req_base[CAM_CTX_REQ_MAX];
 	struct cam_custom_dev_ctx_req req_custom[CAM_CTX_REQ_MAX];
 };

+ 104 - 145
drivers/cam_cust/cam_custom_hw_mgr/cam_custom_hw_mgr.c

@@ -382,7 +382,7 @@ static int cam_custom_mgr_start_hw(void *hw_mgr_priv,
 		&ctx->res_list_custom_cid, list) {
 		rc = cam_custom_hw_mgr_init_hw_res(hw_mgr_res);
 		if (rc) {
-			CAM_ERR(CAM_ISP, "Can not INIT CID(id :%d)",
+			CAM_ERR(CAM_CUSTOM, "Can not INIT CID(id :%d)",
 				hw_mgr_res->res_id);
 			goto deinit_hw;
 		}
@@ -393,7 +393,7 @@ static int cam_custom_mgr_start_hw(void *hw_mgr_priv,
 		&ctx->res_list_custom_csid, list) {
 		rc = cam_custom_hw_mgr_init_hw_res(hw_mgr_res);
 		if (rc) {
-			CAM_ERR(CAM_ISP, "Can not INIT CSID(id :%d)",
+			CAM_ERR(CAM_CUSTOM, "Can not INIT CSID(id :%d)",
 				hw_mgr_res->res_id);
 			goto deinit_hw;
 		}
@@ -413,7 +413,7 @@ static int cam_custom_mgr_start_hw(void *hw_mgr_priv,
 		&ctx->res_list_custom_csid, list) {
 		rc = cam_custom_hw_mgr_start_hw_res(hw_mgr_res);
 		if (rc) {
-			CAM_ERR(CAM_ISP, "Can not START CSID(id :%d)",
+			CAM_ERR(CAM_CUSTOM, "Can not START CSID(id :%d)",
 				hw_mgr_res->res_id);
 			goto err;
 		}
@@ -424,7 +424,7 @@ static int cam_custom_mgr_start_hw(void *hw_mgr_priv,
 		&ctx->res_list_custom_cid, list) {
 		rc = cam_custom_hw_mgr_start_hw_res(hw_mgr_res);
 		if (rc) {
-			CAM_ERR(CAM_ISP, "Can not START CID(id :%d)",
+			CAM_ERR(CAM_CUSTOM, "Can not START CID(id :%d)",
 				hw_mgr_res->res_id);
 			goto err;
 		}
@@ -762,7 +762,7 @@ static int cam_custom_hw_mgr_release_hw_for_ctx(
 		&custom_ctx->res_list_custom_cid, list) {
 		rc = cam_custom_hw_mgr_free_hw_res(hw_mgr_res);
 		if (rc)
-			CAM_ERR(CAM_ISP, "Can not release CID(id :%d)",
+			CAM_ERR(CAM_CUSTOM, "Can not release CID(id :%d)",
 				hw_mgr_res->res_id);
 		cam_custom_hw_mgr_put_res(
 			&custom_ctx->free_res_list, &hw_mgr_res);
@@ -773,7 +773,7 @@ static int cam_custom_hw_mgr_release_hw_for_ctx(
 		&custom_ctx->res_list_custom_csid, list) {
 		rc = cam_custom_hw_mgr_free_hw_res(hw_mgr_res);
 		if (rc)
-			CAM_ERR(CAM_ISP, "Can not release CSID(id :%d)",
+			CAM_ERR(CAM_CUSTOM, "Can not release CSID(id :%d)",
 				hw_mgr_res->res_id);
 		cam_custom_hw_mgr_put_res(
 			&custom_ctx->free_res_list, &hw_mgr_res);
@@ -813,41 +813,82 @@ static int cam_custom_mgr_release_hw(void *hw_mgr_priv,
 	return rc;
 }
 
-static void cam_custom_hw_mgr_acquire_get_unified_dev_str(
-	struct cam_custom_in_port_info *in,
-	struct cam_isp_in_port_generic_info *gen_port_info)
+static int cam_custom_hw_mgr_acquire_get_unified_dev_str(
+	struct cam_custom_acquire_hw_info *acquire_hw_info,
+	uint32_t *input_size,
+	struct cam_isp_in_port_generic_info **gen_port_info)
 {
-	int i;
+	int32_t rc = 0, i;
+	uint32_t in_port_length = 0;
+	struct cam_custom_in_port_info *in = NULL;
+	struct cam_isp_in_port_generic_info *port_info = NULL;
+
+	in = (struct cam_custom_in_port_info *)
+		((uint8_t *)&acquire_hw_info->data +
+		 acquire_hw_info->input_info_offset + *input_size);
+
+	in_port_length = sizeof(struct cam_custom_in_port_info) +
+		(in->num_out_res - 1) *
+		sizeof(struct cam_custom_out_port_info);
+
+	*input_size += in_port_length;
+
+	if ((*input_size) > acquire_hw_info->input_info_size) {
+		CAM_ERR(CAM_CUSTOM, "Input is not proper");
+		rc = -EINVAL;
+		return rc;
+	}
+
+	port_info = kzalloc(
+		sizeof(struct cam_isp_in_port_generic_info), GFP_KERNEL);
+
+	if (!port_info)
+		return -ENOMEM;
 
-	gen_port_info->res_type        =  in->res_type +
+	port_info->res_type        =  in->res_type +
 		CAM_ISP_IFE_IN_RES_BASE - CAM_CUSTOM_IN_RES_BASE;
-	gen_port_info->lane_type       =  in->lane_type;
-	gen_port_info->lane_num        =  in->lane_num;
-	gen_port_info->lane_cfg        =  in->lane_cfg;
-	gen_port_info->vc[0]           =  in->vc[0];
-	gen_port_info->dt[0]           =  in->dt[0];
-	gen_port_info->num_valid_vc_dt =  in->num_valid_vc_dt;
-	gen_port_info->format          =  in->format;
-	gen_port_info->test_pattern    =  in->test_pattern;
-	gen_port_info->usage_type      =  in->usage_type;
-	gen_port_info->left_start      =  in->left_start;
-	gen_port_info->left_stop       =  in->left_stop;
-	gen_port_info->left_width      =  in->left_width;
-	gen_port_info->right_start     =  in->right_start;
-	gen_port_info->right_stop      =  in->right_stop;
-	gen_port_info->right_width     =  in->right_width;
-	gen_port_info->line_start      =  in->line_start;
-	gen_port_info->line_stop       =  in->line_stop;
-	gen_port_info->height          =  in->height;
-	gen_port_info->pixel_clk       =  in->pixel_clk;
-	gen_port_info->cust_node       =  1;
-	gen_port_info->num_out_res     =  in->num_out_res;
-	gen_port_info->num_bytes_out   =  in->num_bytes_out;
+	port_info->lane_type       =  in->lane_type;
+	port_info->lane_num        =  in->lane_num;
+	port_info->lane_cfg        =  in->lane_cfg;
+	port_info->vc[0]           =  in->vc[0];
+	port_info->dt[0]           =  in->dt[0];
+	port_info->num_valid_vc_dt =  in->num_valid_vc_dt;
+	port_info->format          =  in->format;
+	port_info->test_pattern    =  in->test_pattern;
+	port_info->usage_type      =  in->usage_type;
+	port_info->left_start      =  in->left_start;
+	port_info->left_stop       =  in->left_stop;
+	port_info->left_width      =  in->left_width;
+	port_info->right_start     =  in->right_start;
+	port_info->right_stop      =  in->right_stop;
+	port_info->right_width     =  in->right_width;
+	port_info->line_start      =  in->line_start;
+	port_info->line_stop       =  in->line_stop;
+	port_info->height          =  in->height;
+	port_info->pixel_clk       =  in->pixel_clk;
+	port_info->cust_node       =  1;
+	port_info->num_out_res     =  in->num_out_res;
+	port_info->num_bytes_out   =  in->num_bytes_out;
+
+	port_info->data = kcalloc(in->num_out_res,
+		sizeof(struct cam_isp_out_port_generic_info),
+		GFP_KERNEL);
+	if (port_info->data == NULL) {
+		rc = -ENOMEM;
+		goto release_port_mem;
+	}
 
 	for (i = 0; i < in->num_out_res; i++) {
-		gen_port_info->data[i].res_type     = in->data[i].res_type;
-		gen_port_info->data[i].format       = in->data[i].format;
+		port_info->data[i].res_type     = in->data[i].res_type;
+		port_info->data[i].format       = in->data[i].format;
 	}
+
+	*gen_port_info = port_info;
+	return 0;
+
+release_port_mem:
+	kfree(port_info);
+	return rc;
 }
 
 static int cam_custom_mgr_acquire_hw_for_ctx(
@@ -898,18 +939,16 @@ static int cam_custom_mgr_acquire_hw(
 	void *hw_mgr_priv,
 	void *acquire_hw_args)
 {
-	int rc = -1;
-	int32_t i;
-	uint32_t                             in_port_length;
+	int rc = -1, i;
+	uint32_t                             input_size = 0;
 	struct cam_custom_hw_mgr_ctx        *custom_ctx;
 	struct cam_custom_hw_mgr            *custom_hw_mgr;
-	struct cam_hw_acquire_args          *acquire_args =
-		(struct cam_hw_acquire_args *)  acquire_hw_args;
-	struct cam_custom_in_port_info      *in_port_info;
-	struct cam_custom_resource          *custom_rsrc;
+	struct cam_custom_acquire_hw_info   *acquire_hw_info = NULL;
 	struct cam_isp_in_port_generic_info *gen_port_info = NULL;
+	struct cam_hw_acquire_args          *acquire_args =
+		(struct cam_hw_acquire_args *)acquire_hw_args;
 
-	if (!hw_mgr_priv || !acquire_args || (acquire_args->num_acq <= 0)) {
+	if (!hw_mgr_priv || !acquire_args) {
 		CAM_ERR(CAM_CUSTOM, "Invalid params");
 		return -EINVAL;
 	}
@@ -925,127 +964,47 @@ static int cam_custom_mgr_acquire_hw(
 	}
 	mutex_unlock(&g_custom_hw_mgr.ctx_mutex);
 
-	/* Handle Acquire Here */
 	custom_ctx->hw_mgr = custom_hw_mgr;
 	custom_ctx->cb_priv = acquire_args->context_data;
 	custom_ctx->event_cb = acquire_args->event_cb;
 
-	custom_rsrc = kcalloc(acquire_args->num_acq,
-		sizeof(*custom_rsrc), GFP_KERNEL);
-	if (!custom_rsrc) {
-		rc = -ENOMEM;
-		goto free_ctx;
-	}
-
-	CAM_DBG(CAM_CUSTOM, "start copy %d resources from user",
-		acquire_args->num_acq);
+	acquire_hw_info =
+		(struct cam_custom_acquire_hw_info *)acquire_args->acquire_info;
 
-	if (copy_from_user(custom_rsrc,
-		(void __user *)acquire_args->acquire_info,
-		((sizeof(*custom_rsrc)) * acquire_args->num_acq))) {
-		rc = -EFAULT;
-		goto free_ctx;
-	}
+	for (i = 0; i < acquire_hw_info->num_inputs; i++) {
+		rc = cam_custom_hw_mgr_acquire_get_unified_dev_str(
+			acquire_hw_info, &input_size, &gen_port_info);
 
-	for (i = 0; i < acquire_args->num_acq; i++) {
-		if (custom_rsrc[i].resource_id != CAM_CUSTOM_RES_ID_PORT)
-			continue;
-
-		CAM_DBG(CAM_CUSTOM, "acquire no = %d total = %d", i,
-			acquire_args->num_acq);
-
-		CAM_DBG(CAM_CUSTOM,
-			"start copy from user handle %lld with len = %d",
-			custom_rsrc[i].res_hdl,
-			custom_rsrc[i].length);
-
-		in_port_length = sizeof(struct cam_custom_in_port_info);
-		if (in_port_length > custom_rsrc[i].length) {
-			CAM_ERR(CAM_CUSTOM, "buffer size is not enough");
-			rc = -EINVAL;
+		if (rc < 0) {
+			CAM_ERR(CAM_CUSTOM, "Failed in parsing: %d", rc);
 			goto free_res;
 		}
 
-		in_port_info = memdup_user(
-			u64_to_user_ptr(custom_rsrc[i].res_hdl),
-			custom_rsrc[i].length);
-
-		if (!IS_ERR(in_port_info)) {
-			if (in_port_info->num_out_res >
-				CAM_CUSTOM_HW_OUT_RES_MAX) {
-				CAM_ERR(CAM_CUSTOM, "too many output res %d",
-					in_port_info->num_out_res);
-				rc = -EINVAL;
-				kfree(in_port_info);
-				goto free_res;
-			}
-
-			in_port_length =
-				sizeof(struct cam_custom_in_port_info) +
-				(in_port_info->num_out_res - 1) *
-				sizeof(struct cam_custom_out_port_info);
-
-			if (in_port_length > custom_rsrc[i].length) {
-				CAM_ERR(CAM_CUSTOM,
-					"buffer size is not enough");
-				rc = -EINVAL;
-				kfree(in_port_info);
-				goto free_res;
-			}
-
-			gen_port_info = kzalloc(
-				sizeof(struct cam_isp_in_port_generic_info),
-				GFP_KERNEL);
-			if (gen_port_info == NULL) {
-				rc = -ENOMEM;
-				goto free_res;
-			}
-
-			gen_port_info->data = kcalloc(
-				sizeof(struct cam_isp_out_port_generic_info),
-				in_port_info->num_out_res, GFP_KERNEL);
-			if (gen_port_info->data == NULL) {
-				kfree(gen_port_info);
-				gen_port_info = NULL;
-				rc = -ENOMEM;
-				goto free_res;
-			}
-
-			cam_custom_hw_mgr_acquire_get_unified_dev_str(
-				in_port_info, gen_port_info);
-
-			rc = cam_custom_mgr_acquire_hw_for_ctx(custom_ctx,
-				gen_port_info, &acquire_args->acquired_hw_id[i],
-				acquire_args->acquired_hw_path[i]);
-
-			kfree(in_port_info);
-			if (gen_port_info != NULL) {
-				kfree(gen_port_info->data);
-				kfree(gen_port_info);
-				gen_port_info = NULL;
-			}
-
-			if (rc) {
-				CAM_ERR(CAM_CUSTOM, "can not acquire resource");
-				goto free_res;
-			}
-	} else {
-		CAM_ERR(CAM_CUSTOM,
-			"Copy from user failed with in_port = %pK",
-			in_port_info);
-			rc = -EFAULT;
-			goto free_res;
+		CAM_DBG(CAM_CUSTOM, "in_res_type %x", gen_port_info->res_type);
+		rc = cam_custom_mgr_acquire_hw_for_ctx(custom_ctx,
+			gen_port_info, &acquire_args->acquired_hw_id[i],
+			acquire_args->acquired_hw_path[i]);
+		if (rc) {
+			CAM_ERR(CAM_CUSTOM, "can not acquire resource");
+			goto free_mem;
 		}
+
+		kfree(gen_port_info->data);
+		kfree(gen_port_info);
+		gen_port_info = NULL;
 	}
 
 	custom_ctx->ctx_in_use = 1;
 	acquire_args->ctxt_to_hw_map = custom_ctx;
+	cam_custom_hw_mgr_put_ctx(&custom_hw_mgr->used_ctx_list, &custom_ctx);
 	CAM_DBG(CAM_CUSTOM, "Exit...(success)");
 	return 0;
 
+free_mem:
+	kfree(gen_port_info->data);
+	kfree(gen_port_info);
 free_res:
 	cam_custom_hw_mgr_release_hw_for_ctx(custom_ctx);
-free_ctx:
 	cam_custom_hw_mgr_put_ctx(&custom_hw_mgr->free_ctx_list, &custom_ctx);
 err:
 	CAM_DBG(CAM_CUSTOM, "Exit...(rc=%d)", rc);

+ 1 - 1
drivers/cam_icp/fw_inc/hfi_reg.h

@@ -74,7 +74,7 @@
 #define ICP_SHARED_MEM_IN_BYTES                 (1024 * 1024)
 #define ICP_UNCACHED_HEAP_SIZE_IN_BYTES         (2 * 1024 * 1024)
 #define ICP_HFI_MAX_PKT_SIZE_IN_WORDS           25600
-#define ICP_HFI_MAX_PKT_SIZE_MSGQ_IN_WORDS      256
+#define ICP_HFI_MAX_PKT_SIZE_MSGQ_IN_WORDS      1024
 
 #define ICP_HFI_QTBL_HOSTID1                    0x01000000
 #define ICP_HFI_QTBL_STATUS_ENABLED             0x00000001

+ 4 - 0
drivers/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c

@@ -2361,6 +2361,10 @@ static int cam_icp_mgr_process_fatal_error(
 
 	if (event_notify->event_id == HFI_EVENT_SYS_ERROR) {
 		CAM_INFO(CAM_ICP, "received HFI_EVENT_SYS_ERROR");
+		if (event_notify->event_data1 == HFI_ERR_SYS_FATAL) {
+			CAM_ERR(CAM_ICP, "received HFI_ERR_SYS_FATAL");
+			BUG();
+		}
 		rc = cam_icp_mgr_trigger_recovery(hw_mgr);
 		cam_icp_mgr_process_dbg_buf(icp_hw_mgr.a5_dbg_lvl);
 	}

+ 9 - 0
drivers/cam_isp/cam_isp_context.c

@@ -2165,6 +2165,7 @@ static int __cam_isp_ctx_flush_req_in_top_state(
 	struct cam_hw_stop_args           stop_args;
 	struct cam_hw_reset_args          reset_args;
 	struct cam_hw_cmd_args            hw_cmd_args;
+	struct cam_req_mgr_timer_notify    timer;
 
 	ctx_isp = (struct cam_isp_context *) ctx->ctx_priv;
 
@@ -2210,6 +2211,14 @@ static int __cam_isp_ctx_flush_req_in_top_state(
 
 		CAM_INFO(CAM_ISP, "Stop HW complete. Reset HW next.");
 		CAM_DBG(CAM_ISP, "Flush wait and active lists");
+
+		if (ctx->ctx_crm_intf && ctx->ctx_crm_intf->notify_timer) {
+			timer.link_hdl = ctx->link_hdl;
+			timer.dev_hdl = ctx->dev_hdl;
+			timer.state = false;
+			ctx->ctx_crm_intf->notify_timer(&timer);
+		}
+
 		spin_lock_bh(&ctx->lock);
 		if (!list_empty(&ctx->wait_req_list))
 			rc = __cam_isp_ctx_flush_req(ctx, &ctx->wait_req_list,

+ 25 - 10
drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c

@@ -3360,9 +3360,10 @@ static int cam_ife_mgr_config_hw(void *hw_mgr_priv,
 	struct cam_ife_hw_mgr_ctx *ctx;
 	struct cam_isp_prepare_hw_update_data *hw_update_data;
 
-	CAM_DBG(CAM_ISP, "Enter");
 	if (!hw_mgr_priv || !config_hw_args) {
-		CAM_ERR(CAM_ISP, "Invalid arguments");
+		CAM_ERR(CAM_ISP,
+			"Invalid arguments, hw_mgr_priv=%pK, config_hw_args=%pK",
+			hw_mgr_priv, config_hw_args);
 		return -EINVAL;
 	}
 
@@ -3370,21 +3371,28 @@ static int cam_ife_mgr_config_hw(void *hw_mgr_priv,
 	ctx = (struct cam_ife_hw_mgr_ctx *)cfg->ctxt_to_hw_map;
 	if (!ctx) {
 		CAM_ERR(CAM_ISP, "Invalid context is used");
-		return -EPERM;
+		return -EINVAL;
 	}
 
 	if (!ctx->ctx_in_use || !ctx->cdm_cmd) {
-		CAM_ERR(CAM_ISP, "Invalid context parameters");
+		CAM_ERR(CAM_ISP,
+			"Invalid context parameters : ctx_in_use=%d, cdm_cmd=%pK",
+			ctx->ctx_in_use, ctx->cdm_cmd);
+		return -EPERM;
+	}
+
+	if (atomic_read(&ctx->overflow_pending)) {
+		CAM_DBG(CAM_ISP,
+			"Ctx[%pK][%d] Overflow pending, cannot apply req %llu",
+			ctx, ctx->ctx_index, cfg->request_id);
 		return -EPERM;
 	}
-	if (atomic_read(&ctx->overflow_pending))
-		return -EINVAL;
 
 	hw_update_data = (struct cam_isp_prepare_hw_update_data  *) cfg->priv;
 	hw_update_data->ife_mgr_ctx = ctx;
 
-	CAM_DBG(CAM_ISP, "Ctx[%pK][%d] : Applying Req %lld",
-		ctx, ctx->ctx_index, cfg->request_id);
+	CAM_DBG(CAM_ISP, "Ctx[%pK][%d] : Applying Req %lld, init_packet=%d",
+		ctx, ctx->ctx_index, cfg->request_id, cfg->init_packet);
 
 	for (i = 0; i < CAM_IFE_HW_NUM_MAX; i++) {
 		if (hw_update_data->bw_config_valid[i] == true) {
@@ -3456,7 +3464,9 @@ static int cam_ife_mgr_config_hw(void *hw_mgr_priv,
 		atomic_set(&ctx->cdm_done, 0);
 		rc = cam_cdm_submit_bls(ctx->cdm_handle, cdm_cmd);
 		if (rc) {
-			CAM_ERR(CAM_ISP, "Failed to apply the configs");
+			CAM_ERR(CAM_ISP,
+				"Failed to apply the configs for req %llu, rc %d",
+				cfg->request_id, rc);
 			return rc;
 		}
 
@@ -3956,11 +3966,16 @@ static int cam_ife_mgr_start_hw(void *hw_mgr_priv, void *start_hw_args)
 	}
 
 start_only:
+
+	atomic_set(&ctx->overflow_pending, 0);
+
 	/* Apply initial configuration */
 	CAM_DBG(CAM_ISP, "Config HW");
 	rc = cam_ife_mgr_config_hw(hw_mgr_priv, &start_isp->hw_config);
 	if (rc) {
-		CAM_ERR(CAM_ISP, "Config HW failed");
+		CAM_ERR(CAM_ISP,
+			"Config HW failed, start_only=%d, rc=%d",
+			start_isp->start_only, rc);
 		goto cdm_streamoff;
 	}
 

+ 101 - 56
drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c

@@ -44,6 +44,8 @@
 /* Max CSI Rx irq error count threshold value */
 #define CAM_IFE_CSID_MAX_IRQ_ERROR_COUNT               100
 
+static int cam_ife_csid_reset_regs(
+	struct cam_ife_csid_hw *csid_hw, bool reset_hw);
 static int cam_ife_csid_is_ipp_ppp_format_supported(
 	uint32_t in_format)
 {
@@ -420,7 +422,7 @@ static int cam_ife_csid_global_reset(struct cam_ife_csid_hw *csid_hw)
 	const struct cam_ife_csid_reg_offset  *csid_reg;
 	int rc = 0;
 	uint32_t val = 0, i;
-	uint32_t status;
+	unsigned long flags;
 
 	soc_info = &csid_hw->hw_info->soc_info;
 	csid_reg = csid_hw->csid_info->csid_reg;
@@ -435,6 +437,8 @@ static int cam_ife_csid_global_reset(struct cam_ife_csid_hw *csid_hw)
 	CAM_DBG(CAM_ISP, "CSID:%d Csid reset",
 		csid_hw->hw_intf->hw_idx);
 
+	spin_lock_irqsave(&csid_hw->hw_info->hw_lock, flags);
+
 	/* Mask all interrupts */
 	cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
 		csid_reg->csi2_reg->csid_csi2_rx_irq_mask_addr);
@@ -482,6 +486,8 @@ static int cam_ife_csid_global_reset(struct cam_ife_csid_hw *csid_hw)
 	cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
 		csid_reg->cmn_reg->csid_irq_cmd_addr);
 
+	spin_unlock_irqrestore(&csid_hw->hw_info->hw_lock, flags);
+
 	cam_io_w_mb(0x80, soc_info->reg_map[0].mem_base +
 		csid_hw->csid_info->csid_reg->csi2_reg->csid_csi2_rx_cfg1_addr);
 
@@ -498,37 +504,14 @@ static int cam_ife_csid_global_reset(struct cam_ife_csid_hw *csid_hw)
 		cam_io_w_mb(0x2, soc_info->reg_map[0].mem_base +
 			csid_reg->rdi_reg[i]->csid_rdi_cfg0_addr);
 
-	/* perform the top CSID HW registers reset */
-	cam_io_w_mb(csid_reg->cmn_reg->csid_rst_stb,
-		soc_info->reg_map[0].mem_base +
-		csid_reg->cmn_reg->csid_rst_strobes_addr);
-
-	rc = readl_poll_timeout(soc_info->reg_map[0].mem_base +
-		csid_reg->cmn_reg->csid_top_irq_status_addr,
-			status, (status & 0x1) == 0x1,
-		CAM_IFE_CSID_TIMEOUT_SLEEP_US, CAM_IFE_CSID_TIMEOUT_ALL_US);
-	if (rc < 0) {
-		CAM_ERR(CAM_ISP, "CSID:%d csid_reset fail rc = %d",
-			  csid_hw->hw_intf->hw_idx, rc);
-		rc = -ETIMEDOUT;
-	}
-
-	/* perform the SW registers reset */
-	cam_io_w_mb(csid_reg->cmn_reg->csid_reg_rst_stb,
-		soc_info->reg_map[0].mem_base +
-		csid_reg->cmn_reg->csid_rst_strobes_addr);
-
-	rc = readl_poll_timeout(soc_info->reg_map[0].mem_base +
-		csid_reg->cmn_reg->csid_top_irq_status_addr,
-			status, (status & 0x1) == 0x1,
-		CAM_IFE_CSID_TIMEOUT_SLEEP_US, CAM_IFE_CSID_TIMEOUT_ALL_US);
-	if (rc < 0) {
-		CAM_ERR(CAM_ISP, "CSID:%d csid_reset fail rc = %d",
-			  csid_hw->hw_intf->hw_idx, rc);
-		rc = -ETIMEDOUT;
-	}
+	/* reset HW regs first, then SW */
+	rc = cam_ife_csid_reset_regs(csid_hw, true);
+	if (rc < 0)
+		goto end;
+	rc = cam_ife_csid_reset_regs(csid_hw, false);
+	if (rc < 0)
+		goto end;
 
-	usleep_range(3000, 3010);
 	val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
 		csid_reg->csi2_reg->csid_csi2_rx_irq_mask_addr);
 	if (val != 0)
@@ -537,6 +520,7 @@ static int cam_ife_csid_global_reset(struct cam_ife_csid_hw *csid_hw)
 	csid_hw->error_irq_count = 0;
 	csid_hw->prev_boot_timestamp = 0;
 
+end:
 	return rc;
 }
 
@@ -656,7 +640,7 @@ static int cam_ife_csid_path_reset(struct cam_ife_csid_hw *csid_hw,
 		return -EINVAL;
 	}
 
-	init_completion(complete);
+	reinit_completion(complete);
 	reset_strb_val = csid_reg->cmn_reg->path_rst_stb_all;
 
 	/* Reset the corresponding ife csid path */
@@ -1196,6 +1180,7 @@ static int cam_ife_csid_enable_hw(struct cam_ife_csid_hw  *csid_hw)
 	struct cam_hw_soc_info                 *soc_info;
 	uint32_t                               i, val;
 	int                                    clk_lvl;
+	unsigned long                          flags;
 
 	csid_reg = csid_hw->csid_info->csid_reg;
 	soc_info = &csid_hw->hw_info->soc_info;
@@ -1240,6 +1225,8 @@ static int cam_ife_csid_enable_hw(struct cam_ife_csid_hw  *csid_hw)
 	if (rc)
 		goto disable_soc;
 
+	spin_lock_irqsave(&csid_hw->hw_info->hw_lock, flags);
+
 	/* clear all interrupts */
 	cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
 		csid_reg->cmn_reg->csid_top_irq_clear_addr);
@@ -1271,11 +1258,17 @@ static int cam_ife_csid_enable_hw(struct cam_ife_csid_hw  *csid_hw)
 	cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
 		csid_reg->cmn_reg->csid_irq_cmd_addr);
 
+	spin_unlock_irqrestore(&csid_hw->hw_info->hw_lock, flags);
+
 	val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
 			csid_reg->cmn_reg->csid_hw_version_addr);
 	CAM_DBG(CAM_ISP, "CSID:%d CSID HW version: 0x%x",
 		csid_hw->hw_intf->hw_idx, val);
 
+	spin_lock_irqsave(&csid_hw->lock_state, flags);
+	csid_hw->device_enabled = 1;
+	spin_unlock_irqrestore(&csid_hw->lock_state, flags);
+
 	return 0;
 
 disable_soc:
@@ -1560,7 +1553,7 @@ static int cam_ife_csid_enable_csi2(
 		}
 	}
 
-	/*Enable the CSI2 rx inerrupts */
+	/*Enable the CSI2 rx interrupts */
 	val = CSID_CSI2_RX_INFO_RST_DONE |
 		CSID_CSI2_RX_ERROR_TG_FIFO_OVERFLOW |
 		CSID_CSI2_RX_ERROR_LANE0_FIFO_OVERFLOW |
@@ -3089,6 +3082,7 @@ int cam_ife_csid_reset(void *hw_priv,
 	csid_hw = (struct cam_ife_csid_hw   *)csid_hw_info->core_info;
 	reset   = (struct cam_csid_reset_cfg_args  *)reset_args;
 
+	mutex_lock(&csid_hw->hw_info->hw_mutex);
 	switch (reset->reset_type) {
 	case CAM_IFE_CSID_RESET_GLOBAL:
 		rc = cam_ife_csid_global_reset(csid_hw);
@@ -3102,6 +3096,7 @@ int cam_ife_csid_reset(void *hw_priv,
 		rc = -EINVAL;
 		break;
 	}
+	mutex_unlock(&csid_hw->hw_info->hw_mutex);
 
 	return rc;
 }
@@ -3226,43 +3221,86 @@ end:
 	return rc;
 }
 
-static int cam_ife_csid_reset_retain_sw_reg(
-	struct cam_ife_csid_hw *csid_hw)
+static int cam_ife_csid_reset_regs(
+	struct cam_ife_csid_hw *csid_hw, bool reset_hw)
 {
 	int rc = 0;
-	uint32_t status;
 	const struct cam_ife_csid_reg_offset *csid_reg =
 		csid_hw->csid_info->csid_reg;
 	struct cam_hw_soc_info          *soc_info;
+	uint32_t val = 0;
+	unsigned long flags;
 
 	soc_info = &csid_hw->hw_info->soc_info;
+
+	reinit_completion(&csid_hw->csid_top_complete);
+
+	spin_lock_irqsave(&csid_hw->hw_info->hw_lock, flags);
+
 	/* clear the top interrupt first */
 	cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
 		csid_reg->cmn_reg->csid_top_irq_clear_addr);
 	cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
 		csid_reg->cmn_reg->csid_irq_cmd_addr);
 
-	cam_io_w_mb(csid_reg->cmn_reg->csid_rst_stb,
+	if (reset_hw) {
+		/* enable top reset complete IRQ */
+		cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
+			csid_reg->cmn_reg->csid_top_irq_mask_addr);
+		cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
+			csid_reg->cmn_reg->csid_irq_cmd_addr);
+	}
+
+	/* perform the top CSID registers reset */
+	val = reset_hw ? csid_reg->cmn_reg->csid_rst_stb :
+		csid_reg->cmn_reg->csid_reg_rst_stb;
+	cam_io_w_mb(val,
 		soc_info->reg_map[0].mem_base +
 		csid_reg->cmn_reg->csid_rst_strobes_addr);
-	rc = readl_poll_timeout(soc_info->reg_map[0].mem_base +
-		csid_reg->cmn_reg->csid_top_irq_status_addr,
-			status, (status & 0x1) == 0x1,
-		CAM_IFE_CSID_TIMEOUT_SLEEP_US, CAM_IFE_CSID_TIMEOUT_ALL_US);
-	if (rc < 0) {
-		CAM_ERR(CAM_ISP, "CSID:%d csid_reset fail rc = %d",
-			  csid_hw->hw_intf->hw_idx, rc);
+
+	/*
+	 * for SW reset, we enable the IRQ after since the mask
+	 * register has been reset
+	 */
+	if (!reset_hw) {
+		/* enable top reset complete IRQ */
+		cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
+			csid_reg->cmn_reg->csid_top_irq_mask_addr);
+		cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
+			csid_reg->cmn_reg->csid_irq_cmd_addr);
+	}
+
+	spin_unlock_irqrestore(&csid_hw->hw_info->hw_lock, flags);
+	CAM_DBG(CAM_ISP, "CSID reset start");
+	rc = wait_for_completion_timeout(&csid_hw->csid_top_complete,
+		msecs_to_jiffies(IFE_CSID_TIMEOUT));
+	if (rc <= 0) {
+		val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
+			csid_reg->cmn_reg->csid_top_irq_status_addr);
+		if (val & 0x1) {
+			/* clear top reset IRQ */
+			cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
+				csid_reg->cmn_reg->csid_top_irq_clear_addr);
+			cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
+				csid_reg->cmn_reg->csid_irq_cmd_addr);
+			CAM_DBG(CAM_ISP, "CSID:%d %s reset completed %d",
+				csid_hw->hw_intf->hw_idx,
+				reset_hw ? "hw" : "sw",
+				rc);
+			rc = 0;
+			goto end;
+		}
+		CAM_ERR(CAM_ISP, "CSID:%d csid_reset %s fail rc = %d",
+			csid_hw->hw_intf->hw_idx, reset_hw ? "hw" : "sw", rc);
 		rc = -ETIMEDOUT;
+		goto end;
 	} else {
-		CAM_DBG(CAM_ISP, "CSID:%d hw reset completed %d",
-			csid_hw->hw_intf->hw_idx, rc);
+		CAM_DBG(CAM_ISP, "CSID:%d %s reset completed %d",
+			csid_hw->hw_intf->hw_idx, reset_hw ? "hw" : "sw", rc);
 		rc = 0;
 	}
-	cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
-		csid_reg->cmn_reg->csid_top_irq_clear_addr);
-	cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
-		csid_reg->cmn_reg->csid_irq_cmd_addr);
 
+end:
 	return rc;
 }
 
@@ -3274,7 +3312,6 @@ int cam_ife_csid_init_hw(void *hw_priv,
 	struct cam_hw_info                     *csid_hw_info;
 	struct cam_isp_resource_node           *res;
 	const struct cam_ife_csid_reg_offset   *csid_reg;
-	unsigned long                           flags;
 
 	if (!hw_priv || !init_args ||
 		(arg_size != sizeof(struct cam_isp_resource_node))) {
@@ -3348,16 +3385,13 @@ int cam_ife_csid_init_hw(void *hw_priv,
 		break;
 	}
 
-	rc = cam_ife_csid_reset_retain_sw_reg(csid_hw);
+	rc = cam_ife_csid_reset_regs(csid_hw, true);
 	if (rc < 0)
-		CAM_ERR(CAM_ISP, "CSID: Failed in SW reset");
+		CAM_ERR(CAM_ISP, "CSID: Failed in HW reset");
 
 	if (rc)
 		cam_ife_csid_disable_hw(csid_hw);
 
-	spin_lock_irqsave(&csid_hw->lock_state, flags);
-	csid_hw->device_enabled = 1;
-	spin_unlock_irqrestore(&csid_hw->lock_state, flags);
 end:
 	mutex_unlock(&csid_hw->hw_info->hw_mutex);
 	return rc;
@@ -3830,7 +3864,11 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data)
 		}
 	}
 
+	spin_lock_irqsave(&csid_hw->hw_info->hw_lock, flags);
 	/* clear */
+	cam_io_w_mb(irq_status_top, soc_info->reg_map[0].mem_base +
+		csid_reg->cmn_reg->csid_top_irq_clear_addr);
+
 	cam_io_w_mb(irq_status_rx, soc_info->reg_map[0].mem_base +
 		csid_reg->csi2_reg->csid_csi2_rx_irq_clear_addr);
 	if (csid_reg->cmn_reg->num_pix)
@@ -3860,6 +3898,8 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data)
 	cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
 		csid_reg->cmn_reg->csid_irq_cmd_addr);
 
+	spin_unlock_irqrestore(&csid_hw->hw_info->hw_lock, flags);
+
 	CAM_DBG(CAM_ISP, "irq_status_top = 0x%x", irq_status_top);
 	CAM_DBG(CAM_ISP, "irq_status_rx = 0x%x", irq_status_rx);
 	CAM_DBG(CAM_ISP, "irq_status_ipp = 0x%x", irq_status_ipp);
@@ -3871,6 +3911,11 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data)
 		"irq_status_udi0= 0x%x irq_status_udi1= 0x%x irq_status_udi2= 0x%x",
 		irq_status_udi[0], irq_status_udi[1], irq_status_udi[2]);
 
+	if (irq_status_top & CSID_TOP_IRQ_DONE) {
+		CAM_DBG(CAM_ISP, "csid top reset complete");
+		complete(&csid_hw->csid_top_complete);
+	}
+
 	if (irq_status_rx & BIT(csid_reg->csi2_reg->csi2_rst_done_shift_val)) {
 		CAM_DBG(CAM_ISP, "csi rx reset complete");
 		complete(&csid_hw->csid_csi2_complete);

+ 1 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.h

@@ -40,6 +40,7 @@
 #define CSID_CSI2_RX_ERROR_TG_FIFO_OVERFLOW       BIT(26)
 #define CSID_CSI2_RX_INFO_RST_DONE                BIT(27)
 
+#define CSID_TOP_IRQ_DONE                         BIT(0)
 #define CSID_PATH_INFO_RST_DONE                   BIT(1)
 #define CSID_PATH_ERROR_FIFO_OVERFLOW             BIT(2)
 #define CSID_PATH_INFO_SUBSAMPLED_EOF             BIT(3)

+ 1 - 1
drivers/cam_req_mgr/Makefile

@@ -3,7 +3,7 @@
 ccflags-y += -I$(srctree)/techpack/camera/drivers/cam_core
 ccflags-y += -I$(srctree)/techpack/camera/drivers/cam_smmu/
 ccflags-y += -I$(srctree)/techpack/camera/drivers/cam_utils
-ccflags-y += -I$(src)
+ccflags-y += -I$(srctree)/
 
 obj-$(CONFIG_SPECTRA_CAMERA) += cam_req_mgr_core.o\
 				cam_req_mgr_dev.o \

+ 71 - 5
drivers/cam_req_mgr/cam_req_mgr_core.c

@@ -1106,6 +1106,8 @@ static int __cam_req_mgr_check_sync_req_is_ready(
 	int sync_slot_idx = 0, sync_rd_idx = 0, rc = 0;
 	int32_t sync_num_slots = 0;
 	uint64_t sync_frame_duration = 0;
+	uint64_t sof_timestamp_delta = 0;
+	uint64_t master_slave_diff = 0;
 	bool ready = true, sync_ready = true;
 
 	if (!link->sync_link) {
@@ -1139,6 +1141,11 @@ static int __cam_req_mgr_check_sync_req_is_ready(
 	else
 		sync_frame_duration = DEFAULT_FRAME_DURATION;
 
+	sof_timestamp_delta =
+		link->sof_timestamp >= sync_link->sof_timestamp
+		? link->sof_timestamp - sync_link->sof_timestamp
+		: sync_link->sof_timestamp - link->sof_timestamp;
+
 	CAM_DBG(CAM_CRM,
 		"sync link %x last frame_duration is %d ns",
 		sync_link->link_hdl, sync_frame_duration);
@@ -1260,11 +1267,10 @@ static int __cam_req_mgr_check_sync_req_is_ready(
 	 * difference of two SOF timestamp less than
 	 * (sync_frame_duration / 5).
 	 */
-	do_div(sync_frame_duration, 5);
-	if ((link->sof_timestamp > sync_link->sof_timestamp) &&
-		(sync_link->sof_timestamp > 0) &&
-		(link->sof_timestamp - sync_link->sof_timestamp <
-		sync_frame_duration) &&
+	master_slave_diff = sync_frame_duration;
+	do_div(master_slave_diff, 5);
+	if ((sync_link->sof_timestamp > 0) &&
+		(sof_timestamp_delta < master_slave_diff) &&
 		(sync_rd_slot->sync_mode == CAM_REQ_MGR_SYNC_MODE_SYNC)) {
 
 		/*
@@ -1287,6 +1293,11 @@ static int __cam_req_mgr_check_sync_req_is_ready(
 				"sync link %x too quickly, skip next frame of sync link",
 				sync_link->link_hdl);
 			link->sync_link_sof_skip = true;
+		} else if (sync_link->req.in_q->slot[sync_slot_idx].status !=
+			CRM_SLOT_STATUS_REQ_APPLIED) {
+			CAM_DBG(CAM_CRM,
+				"link %x other not applied", link->link_hdl);
+			return -EAGAIN;
 		}
 	}
 
@@ -1744,6 +1755,10 @@ static void __cam_req_mgr_sof_freeze(struct timer_list *timer_data)
 	}
 
 	link = (struct cam_req_mgr_core_link *)timer->parent;
+
+	if (link->watchdog->pause_timer)
+		return;
+
 	task = cam_req_mgr_workq_get_task(link->workq);
 	if (!task) {
 		CAM_ERR(CAM_CRM, "No empty task");
@@ -2643,6 +2658,52 @@ end:
 	return rc;
 }
 
+/**
+ * cam_req_mgr_cb_notify_timer()
+ *
+ * @brief      : Notify SOF timer to pause after flush
+ * @timer_data : contains information about frame_id, link etc.
+ *
+ * @return  : 0 on success
+ *
+ */
+static int cam_req_mgr_cb_notify_timer(
+	struct cam_req_mgr_timer_notify *timer_data)
+{
+	int                              rc = 0;
+	struct cam_req_mgr_core_link    *link = NULL;
+
+	if (!timer_data) {
+		CAM_ERR(CAM_CRM, "timer data  is NULL");
+		rc = -EINVAL;
+		goto end;
+	}
+
+	link = (struct cam_req_mgr_core_link *)
+		cam_get_device_priv(timer_data->link_hdl);
+	if (!link) {
+		CAM_DBG(CAM_CRM, "link ptr NULL %x", timer_data->link_hdl);
+		rc = -EINVAL;
+		goto end;
+	}
+
+	spin_lock_bh(&link->link_state_spin_lock);
+	if (link->state < CAM_CRM_LINK_STATE_READY) {
+		CAM_WARN(CAM_CRM, "invalid link state:%d", link->state);
+		spin_unlock_bh(&link->link_state_spin_lock);
+		rc = -EPERM;
+		goto end;
+	}
+	spin_unlock_bh(&link->link_state_spin_lock);
+
+
+	if (!timer_data->state)
+		link->watchdog->pause_timer = true;
+
+end:
+	return rc;
+}
+
 /**
  * cam_req_mgr_cb_notify_trigger()
  *
@@ -2682,6 +2743,10 @@ static int cam_req_mgr_cb_notify_trigger(
 		rc = -EPERM;
 		goto end;
 	}
+
+	if (link->watchdog->pause_timer)
+		link->watchdog->pause_timer = false;
+
 	crm_timer_reset(link->watchdog);
 	spin_unlock_bh(&link->link_state_spin_lock);
 
@@ -2711,6 +2776,7 @@ static struct cam_req_mgr_crm_cb cam_req_mgr_ops = {
 	.notify_trigger = cam_req_mgr_cb_notify_trigger,
 	.notify_err     = cam_req_mgr_cb_notify_err,
 	.add_req        = cam_req_mgr_cb_add_req,
+	.notify_timer   = cam_req_mgr_cb_notify_timer,
 };
 
 /**

+ 30 - 18
drivers/cam_req_mgr/cam_req_mgr_dev.c

@@ -6,12 +6,17 @@
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/platform_device.h>
+#include <linux/highmem.h>
+
+#include <mm/slab.h>
+
 #include <media/v4l2-fh.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-event.h>
 #include <media/v4l2-ioctl.h>
 #include <media/cam_req_mgr.h>
 #include <media/cam_defs.h>
+
 #include "cam_req_mgr_dev.h"
 #include "cam_req_mgr_util.h"
 #include "cam_req_mgr_core.h"
@@ -19,7 +24,6 @@
 #include "cam_mem_mgr.h"
 #include "cam_debug_util.h"
 #include "cam_common_util.h"
-#include <linux/slub_def.h>
 
 #define CAM_REQ_MGR_EVENT_MAX 30
 
@@ -204,31 +208,39 @@ static void cam_v4l2_event_queue_notify_error(const struct v4l2_event *old,
 
 	ev_header = CAM_REQ_MGR_GET_PAYLOAD_PTR((*old),
 		struct cam_req_mgr_message);
+
 	switch (old->id) {
 	case V4L_EVENT_CAM_REQ_MGR_SOF:
-		CAM_ERR(CAM_CRM, "Failed to notify SOF event");
-		CAM_ERR(CAM_CRM, "Sess %X FrameId %lld ReqId %lld link %X",
-			ev_header->session_hdl,
-			ev_header->u.frame_msg.frame_id,
-			ev_header->u.frame_msg.request_id,
-			ev_header->u.frame_msg.link_hdl);
+	case V4L_EVENT_CAM_REQ_MGR_SOF_BOOT_TS:
+		if (ev_header->u.frame_msg.request_id)
+			CAM_ERR(CAM_CRM,
+				"Failed to notify %s Sess %X FrameId %lld FrameMeta %d ReqId %lld link %X",
+				((old->id == V4L_EVENT_CAM_REQ_MGR_SOF) ?
+				"SOF_TS" : "BOOT_TS"),
+				ev_header->session_hdl,
+				ev_header->u.frame_msg.frame_id,
+				ev_header->u.frame_msg.frame_id_meta,
+				ev_header->u.frame_msg.request_id,
+				ev_header->u.frame_msg.link_hdl);
+		else
+			CAM_WARN_RATE_LIMIT_CUSTOM(CAM_CRM, 5, 1,
+				"Failed to notify %s Sess %X FrameId %lld FrameMeta %d ReqId %lld link %X",
+				((old->id == V4L_EVENT_CAM_REQ_MGR_SOF) ?
+				"SOF_TS" : "BOOT_TS"),
+				ev_header->session_hdl,
+				ev_header->u.frame_msg.frame_id,
+				ev_header->u.frame_msg.frame_id_meta,
+				ev_header->u.frame_msg.request_id,
+				ev_header->u.frame_msg.link_hdl);
 		break;
 	case V4L_EVENT_CAM_REQ_MGR_ERROR:
-		CAM_ERR(CAM_CRM, "Failed to notify ERROR");
-		CAM_ERR(CAM_CRM, "Sess %X ReqId %d Link %X Type %d",
-			ev_header->u.err_msg.error_type,
+		CAM_ERR(CAM_CRM,
+			"Failed to notify ERROR Sess %X ReqId %d Link %X Type %d",
+			ev_header->session_hdl,
 			ev_header->u.err_msg.request_id,
 			ev_header->u.err_msg.link_hdl,
 			ev_header->u.err_msg.error_type);
 		break;
-	case V4L_EVENT_CAM_REQ_MGR_SOF_BOOT_TS:
-		CAM_ERR(CAM_CRM, "Failed to notify BOOT_TS event");
-		CAM_ERR(CAM_CRM, "Sess %X FrameId %lld ReqId %lld link %X",
-			ev_header->session_hdl,
-			ev_header->u.frame_msg.frame_id,
-			ev_header->u.frame_msg.request_id,
-			ev_header->u.frame_msg.link_hdl);
-		break;
 	default:
 		CAM_ERR(CAM_CRM, "Failed to notify crm event id %d",
 			old->id);

+ 16 - 0
drivers/cam_req_mgr/cam_req_mgr_interface.h

@@ -14,6 +14,7 @@
 struct cam_req_mgr_trigger_notify;
 struct cam_req_mgr_error_notify;
 struct cam_req_mgr_add_request;
+struct cam_req_mgr_timer_notify;
 struct cam_req_mgr_device_info;
 struct cam_req_mgr_core_dev_link_setup;
 struct cam_req_mgr_apply_request;
@@ -35,6 +36,7 @@ typedef int (*cam_req_mgr_notify_trigger)(
 	struct cam_req_mgr_trigger_notify *);
 typedef int (*cam_req_mgr_notify_err)(struct cam_req_mgr_error_notify *);
 typedef int (*cam_req_mgr_add_req)(struct cam_req_mgr_add_request *);
+typedef int (*cam_req_mgr_notify_timer)(struct cam_req_mgr_timer_notify *);
 
 /**
  * @brief: cam req mgr to camera device drivers
@@ -64,6 +66,7 @@ struct cam_req_mgr_crm_cb {
 	cam_req_mgr_notify_trigger  notify_trigger;
 	cam_req_mgr_notify_err      notify_err;
 	cam_req_mgr_add_req         add_req;
+	cam_req_mgr_notify_timer    notify_timer;
 };
 
 /**
@@ -206,6 +209,19 @@ struct cam_req_mgr_trigger_notify {
 	uint64_t sof_timestamp_val;
 };
 
+/**
+ * struct cam_req_mgr_timer_notify
+ * @link_hdl : link identifier
+ * @dev_hdl  : device handle which has sent this req id
+ * @frame_id : frame id for internal tracking
+ * @state    : timer state i.e ON or OFF
+ */
+struct cam_req_mgr_timer_notify {
+	int32_t  link_hdl;
+	int32_t  dev_hdl;
+	bool     state;
+};
+
 /**
  * struct cam_req_mgr_error_notify
  * @link_hdl : link identifier

+ 3 - 1
drivers/cam_req_mgr/cam_req_mgr_timer.c

@@ -1,11 +1,13 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved.
  */
 
 #include "cam_req_mgr_timer.h"
 #include "cam_debug_util.h"
 
+extern struct kmem_cache *g_cam_req_mgr_timer_cachep;
+
 void crm_timer_reset(struct cam_req_mgr_timer *crm_timer)
 {
 	if (!crm_timer)

+ 7 - 6
drivers/cam_req_mgr/cam_req_mgr_timer.h

@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
- * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved.
  */
 
 #ifndef _CAM_REQ_MGR_TIMER_H_
@@ -12,16 +12,18 @@
 #include "cam_req_mgr_core_defs.h"
 
 /** struct cam_req_mgr_timer
- * @expires   : timeout value for timer
- * @sys_timer : system timer variable
- * @parent    : priv data - link pointer
- * @timer_cb  : callback func which will be called when timeout expires
+ * @expires      : timeout value for timer
+ * @sys_timer    : system timer variable
+ * @parent       : priv data - link pointer
+ * @timer_cb     : callback func which will be called when timeout expires
+ * @pause_timer  : flag to pause SOF timer
  */
 struct cam_req_mgr_timer {
 	int32_t            expires;
 	struct timer_list  sys_timer;
 	void               *parent;
 	void               (*timer_cb)(struct timer_list *timer_data);
+	bool                pause_timer;
 };
 
 /**
@@ -60,5 +62,4 @@ int crm_timer_init(struct cam_req_mgr_timer **timer,
  */
 void crm_timer_exit(struct cam_req_mgr_timer **timer);
 
-extern struct kmem_cache *g_cam_req_mgr_timer_cachep;
 #endif

+ 65 - 3
drivers/cam_sensor_module/cam_actuator/cam_actuator_core.c

@@ -554,7 +554,7 @@ int32_t cam_actuator_i2c_pkt_parse(struct cam_actuator_ctrl_t *a_ctrl,
 				rc = cam_sensor_i2c_command_parser(
 					&a_ctrl->io_master_info,
 					i2c_reg_settings,
-					&cmd_desc[i], 1);
+					&cmd_desc[i], 1, NULL);
 				if (rc < 0) {
 					CAM_ERR(CAM_ACTUATOR,
 					"Failed:parse init settings: %d",
@@ -612,7 +612,7 @@ int32_t cam_actuator_i2c_pkt_parse(struct cam_actuator_ctrl_t *a_ctrl,
 		rc = cam_sensor_i2c_command_parser(
 			&a_ctrl->io_master_info,
 			i2c_reg_settings,
-			cmd_desc, 1);
+			cmd_desc, 1, NULL);
 		if (rc < 0) {
 			CAM_ERR(CAM_ACTUATOR,
 				"Auto move lens parsing failed: %d", rc);
@@ -643,7 +643,7 @@ int32_t cam_actuator_i2c_pkt_parse(struct cam_actuator_ctrl_t *a_ctrl,
 		rc = cam_sensor_i2c_command_parser(
 			&a_ctrl->io_master_info,
 			i2c_reg_settings,
-			cmd_desc, 1);
+			cmd_desc, 1, NULL);
 		if (rc < 0) {
 			CAM_ERR(CAM_ACTUATOR,
 				"Manual move lens parsing failed: %d", rc);
@@ -662,6 +662,68 @@ int32_t cam_actuator_i2c_pkt_parse(struct cam_actuator_ctrl_t *a_ctrl,
 		}
 		cam_actuator_update_req_mgr(a_ctrl, csl_packet);
 		break;
+	case CAM_ACTUATOR_PACKET_OPCODE_READ: {
+		struct cam_buf_io_cfg *io_cfg;
+		struct i2c_settings_array i2c_read_settings;
+
+		if (a_ctrl->cam_act_state < CAM_ACTUATOR_CONFIG) {
+			rc = -EINVAL;
+			CAM_WARN(CAM_ACTUATOR,
+				"Not in right state to read actuator: %d",
+				a_ctrl->cam_act_state);
+			goto end;
+		}
+		CAM_DBG(CAM_ACTUATOR, "number of I/O configs: %d:",
+			csl_packet->num_io_configs);
+		if (csl_packet->num_io_configs == 0) {
+			CAM_ERR(CAM_ACTUATOR, "No I/O configs to process");
+			rc = -EINVAL;
+			goto end;
+		}
+
+		INIT_LIST_HEAD(&(i2c_read_settings.list_head));
+
+		io_cfg = (struct cam_buf_io_cfg *) ((uint8_t *)
+			&csl_packet->payload +
+			csl_packet->io_configs_offset);
+
+		if (io_cfg == NULL) {
+			CAM_ERR(CAM_ACTUATOR, "I/O config is invalid(NULL)");
+			rc = -EINVAL;
+			goto end;
+		}
+
+		offset = (uint32_t *)&csl_packet->payload;
+		offset += (csl_packet->cmd_buf_offset / sizeof(uint32_t));
+		cmd_desc = (struct cam_cmd_buf_desc *)(offset);
+		i2c_read_settings.is_settings_valid = 1;
+		i2c_read_settings.request_id = 0;
+		rc = cam_sensor_i2c_command_parser(&a_ctrl->io_master_info,
+			&i2c_read_settings,
+			cmd_desc, 1, io_cfg);
+		if (rc < 0) {
+			CAM_ERR(CAM_ACTUATOR,
+				"actuator read pkt parsing failed: %d", rc);
+			goto end;
+		}
+
+		rc = cam_sensor_i2c_read_data(
+			&i2c_read_settings,
+			&a_ctrl->io_master_info);
+		if (rc < 0) {
+			CAM_ERR(CAM_ACTUATOR, "cannot read data, rc:%d", rc);
+			delete_request(&i2c_read_settings);
+			goto end;
+		}
+
+		rc = delete_request(&i2c_read_settings);
+		if (rc < 0) {
+			CAM_ERR(CAM_ACTUATOR,
+				"Failed in deleting the read settings");
+			goto end;
+		}
+		break;
+		}
 	default:
 		CAM_ERR(CAM_ACTUATOR, "Wrong Opcode: %d",
 			csl_packet->header.op_code & 0xFFFFFF);

+ 50 - 61
drivers/cam_sensor_module/cam_csiphy/include/cam_csiphy_1_2_hwreg.h

@@ -12,9 +12,9 @@ struct csiphy_reg_parms_t csiphy_v1_2 = {
 	.mipi_csiphy_interrupt_status0_addr = 0x8B0,
 	.mipi_csiphy_interrupt_clear0_addr = 0x858,
 	.mipi_csiphy_glbl_irq_cmd_addr = 0x828,
-	.csiphy_common_array_size = 5,
-	.csiphy_reset_array_size = 4,
-	.csiphy_2ph_config_array_size = 19,
+	.csiphy_common_array_size = 6,
+	.csiphy_reset_array_size = 5,
+	.csiphy_2ph_config_array_size = 18,
 	.csiphy_3ph_config_array_size = 33,
 	.csiphy_2ph_clock_lane = 0x1,
 	.csiphy_2ph_combo_ck_ln = 0x10,
@@ -23,15 +23,17 @@ struct csiphy_reg_parms_t csiphy_v1_2 = {
 struct csiphy_reg_t csiphy_common_reg_1_2[] = {
 	{0x0814, 0xd5, 0x00, CSIPHY_LANE_ENABLE},
 	{0x0818, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
-	{0x081C, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS},
+	{0x081C, 0x5A, 0x00, CSIPHY_DEFAULT_PARAMS},
 	{0x0800, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS},
 	{0x0884, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
+	{0x0824, 0x72, 0x00, CSIPHY_2PH_REGS},
 };
 
 struct csiphy_reg_t csiphy_reset_reg_1_2[] = {
 	{0x0814, 0x00, 0x05, CSIPHY_LANE_ENABLE},
 	{0x0818, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
 	{0x081C, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
+	{0x0800, 0x01, 0x01, CSIPHY_DEFAULT_PARAMS},
 	{0x0800, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
 };
 
@@ -55,39 +57,37 @@ csiphy_reg_t csiphy_2ph_v1_2_reg[MAX_LANES][MAX_SETTINGS_PER_LANE] = {
 		{0x0030, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x002C, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0034, 0x0F, 0x00, CSIPHY_DEFAULT_PARAMS},
-		{0x0010, 0x50, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0010, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x001C, 0x0A, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0014, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0028, 0x00, 0x00, CSIPHY_DNP_PARAMS},
 		{0x003C, 0xB8, 0x00, CSIPHY_DEFAULT_PARAMS},
-		{0x0000, 0xD4, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0000, 0x91, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0004, 0x0C, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0020, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0024, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0008, 0x10, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
 		{0x000c, 0x00, 0x00, CSIPHY_DNP_PARAMS},
-		{0x0010, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0038, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x005C, 0xC0, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0060, 0x0D, 0x00, CSIPHY_DEFAULT_PARAMS},
-		{0x0060, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0064, 0x7F, 0x00, CSIPHY_DNP_PARAMS},
 	},
 	{
 		{0x0730, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x072C, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0734, 0x0F, 0x00, CSIPHY_DEFAULT_PARAMS},
-		{0x0710, 0x50, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0710, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x071C, 0x0A, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0714, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0728, 0x04, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x073C, 0xB8, 0x00, CSIPHY_DEFAULT_PARAMS},
-		{0x0700, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0700, 0x80, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0704, 0x0C, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0720, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0724, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0708, 0x10, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
-		{0x070c, 0xA5, 0x00, CSIPHY_DEFAULT_PARAMS},
-		{0x0710, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x070c, 0xFF, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0738, 0x1F, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0000, 0x00, 0x00, CSIPHY_DNP_PARAMS},
 		{0x0000, 0x00, 0x00, CSIPHY_DNP_PARAMS},
@@ -97,106 +97,101 @@ csiphy_reg_t csiphy_2ph_v1_2_reg[MAX_LANES][MAX_SETTINGS_PER_LANE] = {
 		{0x0230, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x022C, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0234, 0x0F, 0x00, CSIPHY_DEFAULT_PARAMS},
-		{0x0210, 0x50, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0210, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x021C, 0x0A, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0214, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0228, 0x00, 0x00, CSIPHY_DNP_PARAMS},
 		{0x023C, 0xB8, 0x00, CSIPHY_DEFAULT_PARAMS},
-		{0x0200, 0xD4, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0200, 0x91, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0204, 0x0C, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0220, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0224, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0208, 0x10, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
 		{0x020c, 0x00, 0x00, CSIPHY_DNP_PARAMS},
-		{0x0210, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0238, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x025C, 0xC0, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0260, 0x0D, 0x00, CSIPHY_DEFAULT_PARAMS},
-		{0x0260, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0264, 0x7F, 0x00, CSIPHY_DNP_PARAMS},
 	},
 	{
 		{0x0430, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x042C, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0434, 0x0F, 0x00, CSIPHY_DEFAULT_PARAMS},
-		{0x0410, 0x50, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0410, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x041C, 0x0A, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0414, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0428, 0x00, 0x00, CSIPHY_DNP_PARAMS},
 		{0x043C, 0xB8, 0x00, CSIPHY_DEFAULT_PARAMS},
-		{0x0400, 0xD4, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0400, 0x91, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0404, 0x0C, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0420, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0424, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0408, 0x10, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
 		{0x040c, 0x00, 0x00, CSIPHY_DNP_PARAMS},
-		{0x0410, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0438, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x045C, 0xC0, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0460, 0x0D, 0x00, CSIPHY_DEFAULT_PARAMS},
-		{0x0460, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0464, 0x7F, 0x00, CSIPHY_DNP_PARAMS},
 	},
 	{
 		{0x0630, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x062C, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0634, 0x0F, 0x00, CSIPHY_DEFAULT_PARAMS},
-		{0x0610, 0x50, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0610, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x061C, 0x0A, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0614, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0628, 0x00, 0x00, CSIPHY_DNP_PARAMS},
 		{0x063C, 0xB8, 0x00, CSIPHY_DEFAULT_PARAMS},
-		{0x0600, 0xD4, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0600, 0x91, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0604, 0x0C, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0620, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0624, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0608, 0x10, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
 		{0x060c, 0x00, 0x00, CSIPHY_DNP_PARAMS},
-		{0x0610, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0638, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x065C, 0xC0, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0660, 0x0D, 0x00, CSIPHY_DEFAULT_PARAMS},
-		{0x0660, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0664, 0x7F, 0x00, CSIPHY_DNP_PARAMS},
 	},
 };
 
 struct csiphy_reg_t
-	csiphy_2ph_v1_2_combo_mode_reg[MAX_LANES][MAX_SETTINGS_PER_LANE] = {
+csiphy_2ph_v1_2_combo_mode_reg[MAX_LANES][MAX_SETTINGS_PER_LANE] = {
 	{
 		{0x0030, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x002C, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0034, 0x0F, 0x00, CSIPHY_DEFAULT_PARAMS},
-		{0x0010, 0x50, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0010, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x001C, 0x0A, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0014, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0028, 0x00, 0x00, CSIPHY_DNP_PARAMS},
 		{0x003C, 0xB8, 0x00, CSIPHY_DEFAULT_PARAMS},
-		{0x0000, 0xD4, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0000, 0x91, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0004, 0x0C, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0020, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0024, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0008, 0x10, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
-		{0x000C, 0x00, 0x00, CSIPHY_DNP_PARAMS},
-		{0x0010, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0038, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x005C, 0xC0, 0x00, CSIPHY_DEFAULT_PARAMS},
-		{0x0060, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0060, 0x0D, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0064, 0x7F, 0x00, CSIPHY_DNP_PARAMS},
 		{0x0800, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
 	},
 	{
 		{0x0730, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x072C, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0734, 0x0F, 0x00, CSIPHY_DEFAULT_PARAMS},
-		{0x0710, 0x50, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0710, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x071C, 0x0A, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0714, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0728, 0x04, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x073C, 0xB8, 0x00, CSIPHY_DEFAULT_PARAMS},
-		{0x0700, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0700, 0x80, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0704, 0x0C, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0720, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0724, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0708, 0x10, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
-		{0x070C, 0xA5, 0x00, CSIPHY_DEFAULT_PARAMS},
-		{0x0710, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x070C, 0xFF, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0738, 0x1F, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0800, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0000, 0x00, 0x00, CSIPHY_DNP_PARAMS},
@@ -206,60 +201,57 @@ struct csiphy_reg_t
 		{0x0230, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x022C, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0234, 0x0F, 0x00, CSIPHY_DEFAULT_PARAMS},
-		{0x0210, 0x50, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0210, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x021C, 0x0A, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0214, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0228, 0x00, 0x00, CSIPHY_DNP_PARAMS},
 		{0x023C, 0xB8, 0x00, CSIPHY_DEFAULT_PARAMS},
-		{0x0200, 0xD4, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0200, 0x91, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0204, 0x0C, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0220, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0224, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0208, 0x10, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
-		{0x020C, 0x00, 0x00, CSIPHY_DNP_PARAMS},
-		{0x0210, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0238, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x025C, 0xC0, 0x00, CSIPHY_DEFAULT_PARAMS},
-		{0x0260, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0260, 0x0D, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0264, 0x7F, 0x00, CSIPHY_DNP_PARAMS},
 		{0x0800, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
 	},
 	{
 		{0x0430, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x042C, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0434, 0x0F, 0x00, CSIPHY_DEFAULT_PARAMS},
-		{0x0410, 0x50, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0410, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x041C, 0x0A, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0414, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0428, 0x0A, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x043C, 0xB8, 0x00, CSIPHY_DEFAULT_PARAMS},
-		{0x0400, 0xD4, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0400, 0x91, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0404, 0x0C, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0420, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0424, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0408, 0x10, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
-		{0x040C, 0x00, 0x00, CSIPHY_DNP_PARAMS},
-		{0x0410, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0438, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x045C, 0xC0, 0x00, CSIPHY_DEFAULT_PARAMS},
-		{0x0460, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0460, 0x0D, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0464, 0x7F, 0x00, CSIPHY_DNP_PARAMS},
 		{0x0800, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
 	},
 	{
 		{0x0630, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x062C, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0634, 0x0F, 0x00, CSIPHY_DEFAULT_PARAMS},
-		{0x0610, 0x50, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0610, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x061C, 0x0A, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0614, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0628, 0x0E, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x063C, 0xB8, 0x00, CSIPHY_DEFAULT_PARAMS},
-		{0x0600, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0600, 0x80, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0604, 0x0C, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0620, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0624, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0608, 0x10, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
-		{0x060C, 0xA5, 0x00, CSIPHY_DEFAULT_PARAMS},
-		{0x0610, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x060C, 0xFF, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0638, 0x1F, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0800, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0000, 0x00, 0x00, CSIPHY_DNP_PARAMS},
@@ -382,14 +374,11 @@ struct data_rate_settings_t data_rate_delta_table_1_2 = {
 		{
 			/* (2.5 * 10**3 * 2.28) rounded value*/
 			.bandwidth = 5700000000,
-			.data_rate_reg_array_size = 6,
+			.data_rate_reg_array_size = 3,
 			.csiphy_data_rate_regs = {
 				{0x144, 0x22, 0x00, CSIPHY_DEFAULT_PARAMS},
 				{0x344, 0x22, 0x00, CSIPHY_DEFAULT_PARAMS},
 				{0x544, 0x22, 0x00, CSIPHY_DEFAULT_PARAMS},
-				{0x16C, 0x25, 0x00, CSIPHY_DEFAULT_PARAMS},
-				{0x36C, 0x25, 0x00, CSIPHY_DEFAULT_PARAMS},
-				{0x56C, 0x25, 0x00, CSIPHY_DEFAULT_PARAMS},
 			}
 		},
 		{
@@ -397,12 +386,12 @@ struct data_rate_settings_t data_rate_delta_table_1_2 = {
 			.bandwidth = 7980000000,
 			.data_rate_reg_array_size = 15,
 			.csiphy_data_rate_regs = {
+				{0x9B4, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS},
+				{0xAB4, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS},
+				{0xBB4, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS},
 				{0x144, 0xB2, 0x00, CSIPHY_DEFAULT_PARAMS},
 				{0x344, 0xB2, 0x00, CSIPHY_DEFAULT_PARAMS},
 				{0x544, 0xB2, 0x00, CSIPHY_DEFAULT_PARAMS},
-				{0x16C, 0x2D, 0x00, CSIPHY_DEFAULT_PARAMS},
-				{0x36C, 0x2D, 0x00, CSIPHY_DEFAULT_PARAMS},
-				{0x56C, 0x2D, 0x00, CSIPHY_DEFAULT_PARAMS},
 				{0x988, 0x05, 0x00, CSIPHY_DEFAULT_PARAMS},
 				{0x980, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS},
 				{0xA88, 0x05, 0x00, CSIPHY_DEFAULT_PARAMS},
@@ -419,21 +408,21 @@ struct data_rate_settings_t data_rate_delta_table_1_2 = {
 			.bandwidth = 10260000000,
 			.data_rate_reg_array_size = 15,
 			.csiphy_data_rate_regs = {
+				{0x9B4, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS},
+				{0xAB4, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS},
+				{0xBB4, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS},
 				{0x144, 0xB2, 0x00, CSIPHY_DEFAULT_PARAMS},
 				{0x344, 0xB2, 0x00, CSIPHY_DEFAULT_PARAMS},
 				{0x544, 0xB2, 0x00, CSIPHY_DEFAULT_PARAMS},
-				{0x16C, 0x25, 0x00, CSIPHY_DEFAULT_PARAMS},
-				{0x36C, 0x25, 0x00, CSIPHY_DEFAULT_PARAMS},
-				{0x56C, 0x25, 0x00, CSIPHY_DEFAULT_PARAMS},
 				{0x988, 0x05, 0x00, CSIPHY_DEFAULT_PARAMS},
 				{0x980, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS},
 				{0xA88, 0x05, 0x00, CSIPHY_DEFAULT_PARAMS},
 				{0xA80, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS},
 				{0xB88, 0x05, 0x00, CSIPHY_DEFAULT_PARAMS},
 				{0xB80, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS},
-				{0x10C, 0x0B, 0x00, CSIPHY_DEFAULT_PARAMS},
-				{0x30C, 0x0B, 0x00, CSIPHY_DEFAULT_PARAMS},
-				{0x50C, 0x0B, 0x00, CSIPHY_DEFAULT_PARAMS},
+				{0x10C, 0x08, 0x00, CSIPHY_DEFAULT_PARAMS},
+				{0x30C, 0x08, 0x00, CSIPHY_DEFAULT_PARAMS},
+				{0x50C, 0x08, 0x00, CSIPHY_DEFAULT_PARAMS},
 			},
 		}
 	}

+ 3 - 3
drivers/cam_sensor_module/cam_flash/cam_flash_core.c

@@ -1070,7 +1070,7 @@ int cam_flash_i2c_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg)
 				rc = cam_sensor_i2c_command_parser(
 					&fctrl->io_master_info,
 					i2c_reg_settings,
-					&cmd_desc[i], 1);
+					&cmd_desc[i], 1, NULL);
 				if (rc < 0) {
 					CAM_ERR(CAM_FLASH,
 					"pkt parsing failed: %d", rc);
@@ -1150,7 +1150,7 @@ int cam_flash_i2c_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg)
 		cmd_desc = (struct cam_cmd_buf_desc *)(offset);
 		rc = cam_sensor_i2c_command_parser(
 			&fctrl->io_master_info,
-			i2c_reg_settings, cmd_desc, 1);
+			i2c_reg_settings, cmd_desc, 1, NULL);
 		if (rc) {
 			CAM_ERR(CAM_FLASH,
 			"Failed in parsing i2c packets");
@@ -1181,7 +1181,7 @@ int cam_flash_i2c_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg)
 		cmd_desc = (struct cam_cmd_buf_desc *)(offset);
 		rc = cam_sensor_i2c_command_parser(
 			&fctrl->io_master_info,
-			i2c_reg_settings, cmd_desc, 1);
+			i2c_reg_settings, cmd_desc, 1, NULL);
 		if (rc) {
 			CAM_ERR(CAM_FLASH,
 			"Failed in parsing i2c NRT packets");

+ 64 - 3
drivers/cam_sensor_module/cam_ois/cam_ois_core.c

@@ -540,7 +540,7 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg)
 				rc = cam_sensor_i2c_command_parser(
 					&o_ctrl->io_master_info,
 					i2c_reg_settings,
-					&cmd_desc[i], 1);
+					&cmd_desc[i], 1, NULL);
 				if (rc < 0) {
 					CAM_ERR(CAM_OIS,
 					"init parsing failed: %d", rc);
@@ -557,7 +557,7 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg)
 				rc = cam_sensor_i2c_command_parser(
 					&o_ctrl->io_master_info,
 					i2c_reg_settings,
-					&cmd_desc[i], 1);
+					&cmd_desc[i], 1, NULL);
 				if (rc < 0) {
 					CAM_ERR(CAM_OIS,
 						"Calib parsing failed: %d", rc);
@@ -629,7 +629,7 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg)
 		i2c_reg_settings->request_id = 0;
 		rc = cam_sensor_i2c_command_parser(&o_ctrl->io_master_info,
 			i2c_reg_settings,
-			cmd_desc, 1);
+			cmd_desc, 1, NULL);
 		if (rc < 0) {
 			CAM_ERR(CAM_OIS, "OIS pkt parsing failed: %d", rc);
 			return rc;
@@ -648,6 +648,67 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg)
 			return rc;
 		}
 		break;
+	case CAM_OIS_PACKET_OPCODE_READ: {
+		struct cam_buf_io_cfg *io_cfg;
+		struct i2c_settings_array i2c_read_settings;
+
+		if (o_ctrl->cam_ois_state < CAM_OIS_CONFIG) {
+			rc = -EINVAL;
+			CAM_WARN(CAM_OIS,
+				"Not in right state to read OIS: %d",
+				o_ctrl->cam_ois_state);
+			return rc;
+		}
+		CAM_DBG(CAM_OIS, "number of I/O configs: %d:",
+			csl_packet->num_io_configs);
+		if (csl_packet->num_io_configs == 0) {
+			CAM_ERR(CAM_OIS, "No I/O configs to process");
+			rc = -EINVAL;
+			return rc;
+		}
+
+		INIT_LIST_HEAD(&(i2c_read_settings.list_head));
+
+		io_cfg = (struct cam_buf_io_cfg *) ((uint8_t *)
+			&csl_packet->payload +
+			csl_packet->io_configs_offset);
+
+		if (io_cfg == NULL) {
+			CAM_ERR(CAM_OIS, "I/O config is invalid(NULL)");
+			rc = -EINVAL;
+			return rc;
+		}
+
+		offset = (uint32_t *)&csl_packet->payload;
+		offset += (csl_packet->cmd_buf_offset / sizeof(uint32_t));
+		cmd_desc = (struct cam_cmd_buf_desc *)(offset);
+		i2c_read_settings.is_settings_valid = 1;
+		i2c_read_settings.request_id = 0;
+		rc = cam_sensor_i2c_command_parser(&o_ctrl->io_master_info,
+			&i2c_read_settings,
+			cmd_desc, 1, io_cfg);
+		if (rc < 0) {
+			CAM_ERR(CAM_OIS, "OIS read pkt parsing failed: %d", rc);
+			return rc;
+		}
+
+		rc = cam_sensor_i2c_read_data(
+			&i2c_read_settings,
+			&o_ctrl->io_master_info);
+		if (rc < 0) {
+			CAM_ERR(CAM_OIS, "cannot read data rc: %d", rc);
+			delete_request(&i2c_read_settings);
+			return rc;
+		}
+
+		rc = delete_request(&i2c_read_settings);
+		if (rc < 0) {
+			CAM_ERR(CAM_OIS,
+				"Failed in deleting the read settings");
+			return rc;
+		}
+		break;
+	}
 	default:
 		CAM_ERR(CAM_OIS, "Invalid Opcode: %d",
 			(csl_packet->header.op_code & 0xFFFFFF));

+ 41 - 1
drivers/cam_sensor_module/cam_sensor/cam_sensor_core.c

@@ -87,6 +87,7 @@ static int32_t cam_sensor_i2c_pkt_parse(struct cam_sensor_ctrl_t *s_ctrl,
 	struct cam_control *ioctl_ctrl = NULL;
 	struct cam_packet *csl_packet = NULL;
 	struct cam_cmd_buf_desc *cmd_desc = NULL;
+	struct cam_buf_io_cfg *io_cfg = NULL;
 	struct i2c_settings_array *i2c_reg_settings = NULL;
 	size_t len_of_buff = 0;
 	size_t remain_len = 0;
@@ -187,7 +188,28 @@ static int32_t cam_sensor_i2c_pkt_parse(struct cam_sensor_ctrl_t *s_ctrl,
 		i2c_reg_settings->is_settings_valid = 1;
 		break;
 	}
+	case CAM_SENSOR_PACKET_OPCODE_SENSOR_READ: {
+		i2c_reg_settings = &(i2c_data->read_settings);
+		i2c_reg_settings->request_id = 0;
+		i2c_reg_settings->is_settings_valid = 1;
+
+		CAM_DBG(CAM_SENSOR, "number of IO configs: %d:",
+			csl_packet->num_io_configs);
+		if (csl_packet->num_io_configs == 0) {
+			CAM_ERR(CAM_SENSOR, "No I/O configs to process");
+			goto end;
+		}
 
+		io_cfg = (struct cam_buf_io_cfg *) ((uint8_t *)
+			&csl_packet->payload +
+			csl_packet->io_configs_offset);
+
+		if (io_cfg == NULL) {
+			CAM_ERR(CAM_SENSOR, "I/O config is invalid(NULL)");
+			goto end;
+		}
+		break;
+	}
 	case CAM_SENSOR_PACKET_OPCODE_SENSOR_UPDATE: {
 		if ((s_ctrl->sensor_state == CAM_SENSOR_INIT) ||
 			(s_ctrl->sensor_state == CAM_SENSOR_ACQUIRE)) {
@@ -239,7 +261,7 @@ static int32_t cam_sensor_i2c_pkt_parse(struct cam_sensor_ctrl_t *s_ctrl,
 	cmd_desc = (struct cam_cmd_buf_desc *)(offset);
 
 	rc = cam_sensor_i2c_command_parser(&s_ctrl->io_master_info,
-			i2c_reg_settings, cmd_desc, 1);
+			i2c_reg_settings, cmd_desc, 1, io_cfg);
 	if (rc < 0) {
 		CAM_ERR(CAM_SENSOR, "Fail parsing I2C Pkt: %d", rc);
 		goto end;
@@ -951,6 +973,24 @@ int32_t cam_sensor_driver_cmd(struct cam_sensor_ctrl_t *s_ctrl,
 			}
 			s_ctrl->sensor_state = CAM_SENSOR_CONFIG;
 		}
+
+		if (s_ctrl->i2c_data.read_settings.is_settings_valid) {
+			rc = cam_sensor_i2c_read_data(
+				&s_ctrl->i2c_data.read_settings,
+				&s_ctrl->io_master_info);
+			if (rc < 0) {
+				CAM_ERR(CAM_SENSOR, "cannot read data: %d", rc);
+				delete_request(&s_ctrl->i2c_data.read_settings);
+				goto release_mutex;
+			}
+			rc = delete_request(
+				&s_ctrl->i2c_data.read_settings);
+			if (rc < 0) {
+				CAM_ERR(CAM_SENSOR,
+					"Fail in deleting the read settings");
+				goto release_mutex;
+			}
+		}
 	}
 		break;
 	default:

+ 3 - 1
drivers/cam_sensor_module/cam_sensor/cam_sensor_dev.c

@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
  */
 
 #include "cam_sensor_dev.h"
@@ -179,6 +179,7 @@ static int32_t cam_sensor_driver_i2c_probe(struct i2c_client *client,
 	INIT_LIST_HEAD(&(s_ctrl->i2c_data.config_settings.list_head));
 	INIT_LIST_HEAD(&(s_ctrl->i2c_data.streamon_settings.list_head));
 	INIT_LIST_HEAD(&(s_ctrl->i2c_data.streamoff_settings.list_head));
+	INIT_LIST_HEAD(&(s_ctrl->i2c_data.read_settings.list_head));
 
 	for (i = 0; i < MAX_PER_FRAME_ARRAY; i++)
 		INIT_LIST_HEAD(&(s_ctrl->i2c_data.per_frame[i].list_head));
@@ -314,6 +315,7 @@ static int32_t cam_sensor_driver_platform_probe(
 	INIT_LIST_HEAD(&(s_ctrl->i2c_data.config_settings.list_head));
 	INIT_LIST_HEAD(&(s_ctrl->i2c_data.streamon_settings.list_head));
 	INIT_LIST_HEAD(&(s_ctrl->i2c_data.streamoff_settings.list_head));
+	INIT_LIST_HEAD(&(s_ctrl->i2c_data.read_settings.list_head));
 
 	for (i = 0; i < MAX_PER_FRAME_ARRAY; i++)
 		INIT_LIST_HEAD(&(s_ctrl->i2c_data.per_frame[i].list_head));

+ 10 - 3
drivers/cam_sensor_module/cam_sensor_utils/cam_sensor_cmn_header.h

@@ -152,13 +152,15 @@ enum cam_sensor_packet_opcodes {
 	CAM_SENSOR_PACKET_OPCODE_SENSOR_PROBE,
 	CAM_SENSOR_PACKET_OPCODE_SENSOR_CONFIG,
 	CAM_SENSOR_PACKET_OPCODE_SENSOR_STREAMOFF,
+	CAM_SENSOR_PACKET_OPCODE_SENSOR_READ,
 	CAM_SENSOR_PACKET_OPCODE_SENSOR_NOP = 127
 };
 
 enum cam_actuator_packet_opcodes {
 	CAM_ACTUATOR_PACKET_OPCODE_INIT,
 	CAM_ACTUATOR_PACKET_AUTO_MOVE_LENS,
-	CAM_ACTUATOR_PACKET_MANUAL_MOVE_LENS
+	CAM_ACTUATOR_PACKET_MANUAL_MOVE_LENS,
+	CAM_ACTUATOR_PACKET_OPCODE_READ
 };
 
 enum cam_eeprom_packet_opcodes {
@@ -168,7 +170,8 @@ enum cam_eeprom_packet_opcodes {
 
 enum cam_ois_packet_opcodes {
 	CAM_OIS_PACKET_OPCODE_INIT,
-	CAM_OIS_PACKET_OPCODE_OIS_CONTROL
+	CAM_OIS_PACKET_OPCODE_OIS_CONTROL,
+	CAM_OIS_PACKET_OPCODE_READ
 };
 
 enum msm_bus_perf_setting {
@@ -218,7 +221,8 @@ enum cam_sensor_i2c_cmd_type {
 	CAM_SENSOR_I2C_WRITE_RANDOM,
 	CAM_SENSOR_I2C_WRITE_BURST,
 	CAM_SENSOR_I2C_WRITE_SEQ,
-	CAM_SENSOR_I2C_READ,
+	CAM_SENSOR_I2C_READ_RANDOM,
+	CAM_SENSOR_I2C_READ_SEQ,
 	CAM_SENSOR_I2C_POLL
 };
 
@@ -270,6 +274,8 @@ struct cam_sensor_i2c_reg_setting {
 	enum camera_sensor_i2c_type addr_type;
 	enum camera_sensor_i2c_type data_type;
 	unsigned short delay;
+	uint8_t *read_buff;
+	uint32_t read_buff_len;
 };
 
 struct cam_sensor_i2c_seq_reg {
@@ -297,6 +303,7 @@ struct i2c_data_settings {
 	struct i2c_settings_array config_settings;
 	struct i2c_settings_array streamon_settings;
 	struct i2c_settings_array streamoff_settings;
+	struct i2c_settings_array read_settings;
 	struct i2c_settings_array *per_frame;
 };
 

+ 303 - 5
drivers/cam_sensor_module/cam_sensor_utils/cam_sensor_util.c

@@ -233,6 +233,134 @@ static int32_t cam_sensor_handle_continuous_write(
 	return rc;
 }
 
+static int32_t cam_sensor_get_io_buffer(
+	struct cam_buf_io_cfg *io_cfg,
+	struct cam_sensor_i2c_reg_setting *i2c_settings)
+{
+	uintptr_t buf_addr = 0x0;
+	size_t buf_size = 0;
+	int32_t rc = 0;
+
+	if (io_cfg->direction == CAM_BUF_OUTPUT) {
+		rc = cam_mem_get_cpu_buf(io_cfg->mem_handle[0],
+			&buf_addr, &buf_size);
+		if ((rc < 0) || (!buf_addr)) {
+			CAM_ERR(CAM_SENSOR,
+				"invalid buffer, rc: %d, buf_addr: %pK",
+				rc, buf_addr);
+			return -EINVAL;
+		}
+		CAM_DBG(CAM_SENSOR,
+			"buf_addr: %pK, buf_size: %zu, offsetsize: %d",
+			(void *)buf_addr, buf_size, io_cfg->offsets[0]);
+		if (io_cfg->offsets[0] >= buf_size) {
+			CAM_ERR(CAM_SENSOR,
+				"invalid size:io_cfg->offsets[0]: %d, buf_size: %d",
+				io_cfg->offsets[0], buf_size);
+			return -EINVAL;
+		}
+		i2c_settings->read_buff =
+			 (uint8_t *)buf_addr + io_cfg->offsets[0];
+		i2c_settings->read_buff_len =
+			buf_size - io_cfg->offsets[0];
+	} else {
+		CAM_ERR(CAM_SENSOR, "Invalid direction: %d",
+			io_cfg->direction);
+		rc = -EINVAL;
+	}
+	return rc;
+}
+
+static int32_t cam_sensor_handle_random_read(
+	struct cam_cmd_i2c_random_rd *cmd_i2c_random_rd,
+	struct i2c_settings_array *i2c_reg_settings,
+	uint16_t *cmd_length_in_bytes,
+	int32_t *offset,
+	struct list_head **list,
+	struct cam_buf_io_cfg *io_cfg)
+{
+	struct i2c_settings_list *i2c_list;
+	int32_t rc = 0, cnt = 0;
+
+	i2c_list = cam_sensor_get_i2c_ptr(i2c_reg_settings,
+		cmd_i2c_random_rd->header.count);
+	if ((i2c_list == NULL) ||
+		(i2c_list->i2c_settings.reg_setting == NULL)) {
+		CAM_ERR(CAM_SENSOR,
+			"Failed in allocating i2c_list: %pK",
+			i2c_list);
+		return -ENOMEM;
+	}
+
+	rc = cam_sensor_get_io_buffer(io_cfg, &(i2c_list->i2c_settings));
+	if (rc) {
+		CAM_ERR(CAM_SENSOR, "Failed to get read buffer: %d", rc);
+	} else {
+		*cmd_length_in_bytes = sizeof(struct i2c_rdwr_header) +
+			(sizeof(struct cam_cmd_read) *
+			(cmd_i2c_random_rd->header.count));
+		i2c_list->op_code = CAM_SENSOR_I2C_READ_RANDOM;
+		i2c_list->i2c_settings.addr_type =
+			cmd_i2c_random_rd->header.addr_type;
+		i2c_list->i2c_settings.data_type =
+			cmd_i2c_random_rd->header.data_type;
+		i2c_list->i2c_settings.size =
+			cmd_i2c_random_rd->header.count;
+
+		for (cnt = 0; cnt < (cmd_i2c_random_rd->header.count);
+			cnt++) {
+			i2c_list->i2c_settings.reg_setting[cnt].reg_addr =
+				cmd_i2c_random_rd->data_read[cnt].reg_data;
+		}
+		*offset = cnt;
+		*list = &(i2c_list->list);
+	}
+
+	return rc;
+}
+
+static int32_t cam_sensor_handle_continuous_read(
+	struct cam_cmd_i2c_continuous_rd *cmd_i2c_continuous_rd,
+	struct i2c_settings_array *i2c_reg_settings,
+	uint16_t *cmd_length_in_bytes, int32_t *offset,
+	struct list_head **list,
+	struct cam_buf_io_cfg *io_cfg)
+{
+	struct i2c_settings_list *i2c_list;
+	int32_t rc = 0, cnt = 0;
+
+	i2c_list = cam_sensor_get_i2c_ptr(i2c_reg_settings, 1);
+	if ((i2c_list == NULL) ||
+		(i2c_list->i2c_settings.reg_setting == NULL)) {
+		CAM_ERR(CAM_SENSOR,
+			"Failed in allocating i2c_list: %pK",
+			i2c_list);
+		return -ENOMEM;
+	}
+
+	rc = cam_sensor_get_io_buffer(io_cfg, &(i2c_list->i2c_settings));
+	if (rc) {
+		CAM_ERR(CAM_SENSOR, "Failed to get read buffer: %d", rc);
+	} else {
+		*cmd_length_in_bytes = sizeof(struct cam_cmd_i2c_continuous_rd);
+		i2c_list->op_code = CAM_SENSOR_I2C_READ_SEQ;
+
+		i2c_list->i2c_settings.addr_type =
+			cmd_i2c_continuous_rd->header.addr_type;
+		i2c_list->i2c_settings.data_type =
+			cmd_i2c_continuous_rd->header.data_type;
+		i2c_list->i2c_settings.size =
+			cmd_i2c_continuous_rd->header.count;
+		i2c_list->i2c_settings.reg_setting[0].reg_addr =
+			cmd_i2c_continuous_rd->reg_addr;
+
+		*offset = cnt;
+		*list = &(i2c_list->list);
+	}
+
+	return rc;
+}
+
 static int cam_sensor_handle_slave_info(
 	struct camera_io_master *io_master,
 	uint32_t *cmd_buf)
@@ -271,8 +399,11 @@ static int cam_sensor_handle_slave_info(
 /**
  * Name : cam_sensor_i2c_command_parser
  * Description : Parse CSL CCI packet and apply register settings
- * Parameters :  s_ctrl  input/output    sub_device
- *              arg     input           cam_control
+ * Parameters :  io_master        input  master information
+ *               i2c_reg_settings output register settings to fill
+ *               cmd_desc         input  command description
+ *               num_cmd_buffers  input  number of command buffers to process
+ *               io_cfg           input  buffer details for read operation only
  * Description :
  * Handle multiple I2C RD/WR and WAIT cmd formats in one command
  * buffer, for example, a command buffer of m x RND_WR + 1 x HW_
@@ -283,11 +414,12 @@ int cam_sensor_i2c_command_parser(
 	struct camera_io_master *io_master,
 	struct i2c_settings_array *i2c_reg_settings,
 	struct cam_cmd_buf_desc   *cmd_desc,
-	int32_t num_cmd_buffers)
+	int32_t num_cmd_buffers,
+	struct cam_buf_io_cfg *io_cfg)
 {
 	int16_t                   rc = 0, i = 0;
 	size_t                    len_of_buff = 0;
-	uintptr_t                  generic_ptr;
+	uintptr_t                 generic_ptr;
 	uint16_t                  cmd_length_in_bytes = 0;
 	size_t                    remain_len = 0;
 	size_t                    tot_size = 0;
@@ -472,7 +604,7 @@ int cam_sensor_i2c_command_parser(
 			}
 			case CAMERA_SENSOR_CMD_TYPE_I2C_INFO: {
 				if (remain_len - byte_cnt <
-				    sizeof(struct cam_cmd_i2c_info)) {
+					sizeof(struct cam_cmd_i2c_info)) {
 					CAM_ERR(CAM_SENSOR,
 						"Not enough buffer space");
 					rc = -EINVAL;
@@ -493,6 +625,88 @@ int cam_sensor_i2c_command_parser(
 				byte_cnt += cmd_length_in_bytes;
 				break;
 			}
+			case CAMERA_SENSOR_CMD_TYPE_I2C_RNDM_RD: {
+				uint16_t cmd_length_in_bytes   = 0;
+				struct cam_cmd_i2c_random_rd *i2c_random_rd =
+				(struct cam_cmd_i2c_random_rd *)cmd_buf;
+
+				if (remain_len - byte_cnt <
+					sizeof(struct cam_cmd_i2c_random_rd)) {
+					CAM_ERR(CAM_SENSOR,
+						"Not enough buffer space");
+					rc = -EINVAL;
+					goto end;
+				}
+
+				tot_size = sizeof(struct i2c_rdwr_header) +
+					(sizeof(struct cam_cmd_read) *
+					i2c_random_rd->header.count);
+
+				if (tot_size > (remain_len - byte_cnt)) {
+					CAM_ERR(CAM_SENSOR,
+						"Not enough buffer provided %d, %d, %d",
+						tot_size, remain_len, byte_cnt);
+					rc = -EINVAL;
+					goto end;
+				}
+
+				rc = cam_sensor_handle_random_read(
+					i2c_random_rd,
+					i2c_reg_settings,
+					&cmd_length_in_bytes, &j, &list,
+					io_cfg);
+				if (rc < 0) {
+					CAM_ERR(CAM_SENSOR,
+					"Failed in random read %d", rc);
+					goto end;
+				}
+
+				cmd_buf += cmd_length_in_bytes /
+					sizeof(uint32_t);
+				byte_cnt += cmd_length_in_bytes;
+				break;
+			}
+			case CAMERA_SENSOR_CMD_TYPE_I2C_CONT_RD: {
+				uint16_t cmd_length_in_bytes   = 0;
+				struct cam_cmd_i2c_continuous_rd
+				*i2c_continuous_rd =
+				(struct cam_cmd_i2c_continuous_rd *)cmd_buf;
+
+				if (remain_len - byte_cnt <
+				    sizeof(struct cam_cmd_i2c_continuous_rd)) {
+					CAM_ERR(CAM_SENSOR,
+						"Not enough buffer space");
+					rc = -EINVAL;
+					goto end;
+				}
+
+				tot_size =
+				sizeof(struct cam_cmd_i2c_continuous_rd);
+
+				if (tot_size > (remain_len - byte_cnt)) {
+					CAM_ERR(CAM_SENSOR,
+						"Not enough buffer provided %d, %d, %d",
+						tot_size, remain_len, byte_cnt);
+					rc = -EINVAL;
+					goto end;
+				}
+
+				rc = cam_sensor_handle_continuous_read(
+					i2c_continuous_rd,
+					i2c_reg_settings,
+					&cmd_length_in_bytes, &j, &list,
+					io_cfg);
+				if (rc < 0) {
+					CAM_ERR(CAM_SENSOR,
+					"Failed in continuous read %d", rc);
+					goto end;
+				}
+
+				cmd_buf += cmd_length_in_bytes /
+					sizeof(uint32_t);
+				byte_cnt += cmd_length_in_bytes;
+				break;
+			}
 			default:
 				CAM_ERR(CAM_SENSOR, "Invalid Command Type:%d",
 					 cmm_hdr->cmd_type);
@@ -576,6 +790,90 @@ int cam_sensor_util_i2c_apply_setting(
 	return rc;
 }
 
+int32_t cam_sensor_i2c_read_data(
+	struct i2c_settings_array *i2c_settings,
+	struct camera_io_master *io_master_info)
+{
+	int32_t                   rc = 0;
+	struct i2c_settings_list  *i2c_list;
+	uint32_t                  cnt = 0;
+	uint8_t                   *read_buff = NULL;
+	uint32_t                  buff_length = 0;
+	uint32_t                  read_length = 0;
+
+	list_for_each_entry(i2c_list,
+		&(i2c_settings->list_head), list) {
+		read_buff = i2c_list->i2c_settings.read_buff;
+		buff_length = i2c_list->i2c_settings.read_buff_len;
+		if ((read_buff == NULL) || (buff_length == 0)) {
+			CAM_ERR(CAM_SENSOR,
+				"Invalid input buffer, buffer: %pK, length: %d",
+				read_buff, buff_length);
+			return -EINVAL;
+		}
+
+		if (i2c_list->op_code == CAM_SENSOR_I2C_READ_RANDOM) {
+			read_length = i2c_list->i2c_settings.data_type *
+				i2c_list->i2c_settings.size;
+			if ((read_length > buff_length) ||
+				(read_length < i2c_list->i2c_settings.size)) {
+				CAM_ERR(CAM_SENSOR,
+				"Invalid size, readLen:%d, bufLen:%d, size: %d",
+				read_length, buff_length,
+				i2c_list->i2c_settings.size);
+				return -EINVAL;
+			}
+			for (cnt = 0; cnt < (i2c_list->i2c_settings.size);
+				cnt++) {
+				struct cam_sensor_i2c_reg_array *reg_setting =
+				&(i2c_list->i2c_settings.reg_setting[cnt]);
+				rc = camera_io_dev_read(io_master_info,
+					reg_setting->reg_addr,
+					&reg_setting->reg_data,
+					i2c_list->i2c_settings.addr_type,
+					i2c_list->i2c_settings.data_type);
+				if (rc < 0) {
+					CAM_ERR(CAM_SENSOR,
+					"Failed: random read I2C settings: %d",
+					rc);
+					return rc;
+				}
+				if (i2c_list->i2c_settings.data_type <
+					CAMERA_SENSOR_I2C_TYPE_MAX) {
+					memcpy(read_buff,
+					&reg_setting->reg_data,
+					i2c_list->i2c_settings.data_type);
+					read_buff +=
+					i2c_list->i2c_settings.data_type;
+				}
+			}
+		} else if (i2c_list->op_code == CAM_SENSOR_I2C_READ_SEQ) {
+			read_length = i2c_list->i2c_settings.size;
+			if (read_length > buff_length) {
+				CAM_ERR(CAM_SENSOR,
+				"Invalid buffer size, readLen: %d, bufLen: %d",
+				read_length, buff_length);
+				return -EINVAL;
+			}
+			rc = camera_io_dev_read_seq(
+				io_master_info,
+				i2c_list->i2c_settings.reg_setting[0].reg_addr,
+				read_buff,
+				i2c_list->i2c_settings.addr_type,
+				i2c_list->i2c_settings.data_type,
+				i2c_list->i2c_settings.size);
+			if (rc < 0) {
+				CAM_ERR(CAM_SENSOR,
+					"failed: seq read I2C settings: %d",
+					rc);
+				return rc;
+			}
+		}
+	}
+
+	return rc;
+}
+
 int32_t msm_camera_fill_vreg_params(
 	struct cam_hw_soc_info *soc_info,
 	struct cam_sensor_power_setting *power_setting,

+ 6 - 1
drivers/cam_sensor_module/cam_sensor_utils/cam_sensor_util.h

@@ -30,11 +30,16 @@ int msm_camera_pinctrl_init
 
 int cam_sensor_i2c_command_parser(struct camera_io_master *io_master,
 	struct i2c_settings_array *i2c_reg_settings,
-	struct cam_cmd_buf_desc *cmd_desc, int32_t num_cmd_buffers);
+	struct cam_cmd_buf_desc *cmd_desc, int32_t num_cmd_buffers,
+	struct cam_buf_io_cfg *io_cfg);
 
 int cam_sensor_util_i2c_apply_setting(struct camera_io_master *io_master_info,
 	struct i2c_settings_list *i2c_list);
 
+int32_t cam_sensor_i2c_read_data(
+	struct i2c_settings_array *i2c_settings,
+	struct camera_io_master *io_master_info);
+
 int32_t delete_request(struct i2c_settings_array *i2c_array);
 int cam_sensor_util_request_gpio_table(
 	struct cam_hw_soc_info *soc_info, int gpio_en);

+ 17 - 0
include/uapi/camera/media/cam_custom.h

@@ -170,6 +170,23 @@ struct cam_custom_resource {
 	uint64_t                       res_hdl;
 };
 
+/**
+ * struct cam_custom_acquire_hw_info - Custom acquire HW params
+ *
+ * @num_inputs           : Number of inputs
+ * @input_info_size      : Size of input info struct used
+ * @input_info_offset    : Offset of input info from start of data
+ * @reserved             : reserved
+ * @data                 : Start of data region
+ */
+struct cam_custom_acquire_hw_info {
+	uint32_t                num_inputs;
+	uint32_t                input_info_size;
+	uint32_t                input_info_offset;
+	uint32_t                reserved;
+	uint64_t                data;
+};
+
 /**
  * struct cam_custom_cmd_buf_type_1 - cmd buf type 1
  *