Pārlūkot izejas kodu

Merge "msm: camera: req_mgr: Re-design CRM to support multi links in sync mode" into camera-kernel.lnx.5.0

Camera Software Integration 4 gadi atpakaļ
vecāks
revīzija
bc895d1ad5

+ 28 - 1
drivers/cam_core/cam_context.c

@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
  */
 
 #include <linux/slab.h>
@@ -182,6 +182,33 @@ int cam_context_handle_crm_apply_req(struct cam_context *ctx,
 	return rc;
 }
 
+int cam_context_handle_crm_state_change(struct cam_context *ctx,
+	struct cam_req_mgr_request_change_state *state_info)
+{
+	int rc;
+
+	if (!ctx->state_machine) {
+		CAM_ERR(CAM_CORE, "Context is not ready");
+		return -EINVAL;
+	}
+
+	if (!state_info) {
+		CAM_ERR(CAM_CORE, "Invalid change state payload");
+		return -EINVAL;
+	}
+
+	if (ctx->state_machine[ctx->state].crm_ops.change_state) {
+		rc = ctx->state_machine[ctx->state].crm_ops.change_state(ctx,
+			state_info);
+	} else {
+		CAM_ERR(CAM_CORE, "No crm change state req in dev %d, state %d",
+			ctx->dev_hdl, ctx->state);
+		rc = -EPROTO;
+	}
+
+	return rc;
+}
+
 int cam_context_handle_crm_notify_frame_skip(
 	struct cam_context *ctx,
 	struct cam_req_mgr_apply_request *apply)

+ 15 - 0
drivers/cam_core/cam_context.h

@@ -129,6 +129,7 @@ struct cam_ctx_ioctl_ops {
  * @flush_req:             Flush request to remove request ids
  * @process_evt:           Handle event notification from CRM.(optional)
  * @dump_req:              Dump information for the issue request
+ * @change_state:          Change sub-state of hw context layer to bubble
  *
  */
 struct cam_ctx_crm_ops {
@@ -148,6 +149,8 @@ struct cam_ctx_crm_ops {
 			struct cam_req_mgr_link_evt_data *evt_data);
 	int (*dump_req)(struct cam_context *ctx,
 			struct cam_req_mgr_dump_info *dump);
+	int (*change_state)(struct cam_context *ctx,
+			struct cam_req_mgr_request_change_state *change_state);
 };
 
 
@@ -327,6 +330,18 @@ int cam_context_handle_crm_unlink(struct cam_context *ctx,
 int cam_context_handle_crm_apply_req(struct cam_context *ctx,
 		struct cam_req_mgr_apply_request *apply);
 
+/**
+ * cam_context_handle_crm_state_change()
+ *
+ * @brief:        Handle state change request
+ *
+ * @ctx:          Object pointer for cam_context
+ * @state_info:   State change request command payload
+ *
+ */
+int cam_context_handle_crm_state_change(struct cam_context *ctx,
+		struct cam_req_mgr_request_change_state *state_info);
+
 /**
  * cam_context_handle_crm_notify_frame_skip()
  *

+ 19 - 0
drivers/cam_core/cam_node.c

@@ -619,6 +619,24 @@ static int __cam_node_crm_flush_req(struct cam_req_mgr_flush_request *flush)
 	return cam_context_handle_crm_flush_req(ctx, flush);
 }
 
+static int __cam_node_crm_state_change_req(
+	struct cam_req_mgr_request_change_state *state_info)
+{
+	struct cam_context *ctx = NULL;
+
+	if (!state_info)
+		return -EINVAL;
+
+	ctx = (struct cam_context *) cam_get_device_priv(state_info->dev_hdl);
+	if (!ctx) {
+		CAM_ERR(CAM_CORE, "Can not get context for handle %d",
+			state_info->dev_hdl);
+		return -EINVAL;
+	}
+
+	return cam_context_handle_crm_state_change(ctx, state_info);
+}
+
 static int __cam_node_crm_process_evt(
 	struct cam_req_mgr_link_evt_data *evt_data)
 {
@@ -715,6 +733,7 @@ int cam_node_init(struct cam_node *node, struct cam_hw_mgr_intf *hw_mgr_intf,
 	node->crm_node_intf.dump_req = __cam_node_crm_dump_req;
 	node->crm_node_intf.notify_frame_skip =
 		__cam_node_crm_notify_frame_skip;
+	node->crm_node_intf.change_state = __cam_node_crm_state_change_req;
 
 	mutex_init(&node->list_mutex);
 	INIT_LIST_HEAD(&node->free_ctx_list);

+ 1 - 0
drivers/cam_cust/cam_custom_context.c

@@ -549,6 +549,7 @@ static int __cam_custom_ctx_get_dev_info_in_acquired(struct cam_context *ctx,
 	dev_info->dev_id = CAM_REQ_MGR_DEVICE_CUSTOM_HW;
 	dev_info->p_delay = 1;
 	dev_info->trigger = CAM_TRIGGER_POINT_SOF;
+	dev_info->sof_ts_cb = NULL;
 
 	return 0;
 }

+ 186 - 16
drivers/cam_isp/cam_isp_context.c

@@ -749,8 +749,8 @@ static void __cam_isp_ctx_send_sof_timestamp(
 	req_msg.u.frame_msg.frame_id_meta = ctx_isp->frame_id_meta;
 
 	CAM_DBG(CAM_ISP,
-		"request id:%lld frame number:%lld SOF time stamp:0x%llx status:%u",
-		 request_id, ctx_isp->frame_id,
+		"link hdl 0x%x request id:%lld frame number:%lld SOF time stamp:%lld status:%u",
+		ctx_isp->base->link_hdl, request_id, ctx_isp->frame_id,
 		ctx_isp->sof_timestamp_val, sof_event_status);
 
 	if (cam_req_mgr_notify_message(&req_msg,
@@ -1677,6 +1677,7 @@ static int __cam_isp_ctx_reg_upd_in_applied_state(
 	}
 	req = list_first_entry(&ctx->wait_req_list,
 			struct cam_ctx_request, list);
+
 	list_del_init(&req->list);
 
 	req_isp = (struct cam_isp_ctx_req *) req->req_priv;
@@ -1685,8 +1686,9 @@ static int __cam_isp_ctx_reg_upd_in_applied_state(
 		ctx_isp->active_req_cnt++;
 		request_id = req->request_id;
 		CAM_DBG(CAM_REQ,
-			"move request %lld to active list(cnt = %d), ctx %u",
-			req->request_id, ctx_isp->active_req_cnt, ctx->ctx_id);
+			"move request %lld to active list(cnt = %d), ctx %u link %x",
+			req->request_id, ctx_isp->active_req_cnt,
+			ctx->ctx_id, ctx->link_hdl);
 		__cam_isp_ctx_update_event_record(ctx_isp,
 			CAM_ISP_CTX_EVENT_RUP, req);
 	} else {
@@ -1828,6 +1830,7 @@ notify_only:
 			notify.trigger = CAM_TRIGGER_POINT_SOF;
 			notify.req_id = ctx_isp->req_info.last_bufdone_req_id;
 			notify.sof_timestamp_val = ctx_isp->sof_timestamp_val;
+			notify.sof_boottime = ctx_isp->boot_timestamp;
 			notify.trigger_id = ctx_isp->trigger_id;
 
 			ctx->ctx_crm_intf->notify_trigger(&notify);
@@ -1949,8 +1952,9 @@ static int __cam_isp_ctx_sof_in_activated_state(
 	__cam_isp_ctx_update_state_monitor_array(ctx_isp,
 		CAM_ISP_STATE_CHANGE_TRIGGER_SOF, request_id);
 
-	CAM_DBG(CAM_ISP, "frame id: %lld time stamp:0x%llx, ctx %u",
-		ctx_isp->frame_id, ctx_isp->sof_timestamp_val, ctx->ctx_id);
+	CAM_DBG(CAM_ISP, "frame id: %lld time stamp:0x%llx, ctx %u link %x",
+		ctx_isp->frame_id, ctx_isp->sof_timestamp_val,
+		ctx->ctx_id, ctx->link_hdl);
 
 	return rc;
 }
@@ -1995,6 +1999,7 @@ end:
 static int __cam_isp_ctx_epoch_in_applied(struct cam_isp_context *ctx_isp,
 	void *evt_data)
 {
+	bool rc = false;
 	uint64_t request_id = 0;
 	uint32_t sof_event_status = CAM_REQ_MGR_SOF_EVENT_SUCCESS;
 	struct cam_req_mgr_trigger_notify   notify;
@@ -2036,8 +2041,9 @@ static int __cam_isp_ctx_epoch_in_applied(struct cam_isp_context *ctx_isp,
 	req_isp->reapply = true;
 	req_isp->cdm_reset_before_apply = false;
 
-	CAM_INFO_RATE_LIMIT(CAM_ISP, "ctx:%d Report Bubble flag %d req id:%lld",
-		ctx->ctx_id, req_isp->bubble_report, req->request_id);
+	CAM_INFO_RATE_LIMIT(CAM_ISP, "ctx:%d link %x  Report Bubble flag %d req id:%lld",
+		ctx->ctx_id, ctx->link_hdl,
+		req_isp->bubble_report, req->request_id);
 	if (req_isp->bubble_report && ctx->ctx_crm_intf &&
 		ctx->ctx_crm_intf->notify_err) {
 		struct cam_req_mgr_error_notify notify;
@@ -2051,12 +2057,25 @@ static int __cam_isp_ctx_epoch_in_applied(struct cam_isp_context *ctx_isp,
 			notify.trigger = CAM_TRIGGER_POINT_SOF;
 		notify.frame_id = ctx_isp->frame_id;
 		notify.sof_timestamp_val = ctx_isp->sof_timestamp_val;
+		notify.sof_boottime_val = ctx_isp->boot_timestamp;
+		notify.need_recovery = true;
 		CAM_WARN_RATE_LIMIT(CAM_ISP,
 			"Notify CRM about Bubble req %lld frame %lld, ctx %u",
 			req->request_id, ctx_isp->frame_id, ctx->ctx_id);
 		trace_cam_log_event("Bubble", "Rcvd epoch in applied state",
 			req->request_id, ctx->ctx_id);
-		ctx->ctx_crm_intf->notify_err(&notify);
+		rc = ctx->ctx_crm_intf->notify_err(&notify);
+
+		CAM_DBG(CAM_CRM, "Need bubble recovery %d", rc);
+
+		if (rc) {
+			req_isp->bubble_detected = false;
+			req_isp->reapply = false;
+			CAM_DBG(CAM_ISP, "Disable bubble for ctx %d link %d",
+				ctx->ctx_id, ctx->link_hdl);
+			return 0;
+		}
+
 		atomic_set(&ctx_isp->process_bubble, 1);
 	} else {
 		req_isp->bubble_report = 0;
@@ -2230,6 +2249,7 @@ static int __cam_isp_ctx_buf_done_in_bubble(
 static int __cam_isp_ctx_epoch_in_bubble_applied(
 	struct cam_isp_context *ctx_isp, void *evt_data)
 {
+	int rc = 0;
 	uint64_t  request_id = 0;
 	struct cam_req_mgr_trigger_notify   notify;
 	struct cam_ctx_request             *req;
@@ -2287,10 +2307,17 @@ static int __cam_isp_ctx_epoch_in_bubble_applied(
 			notify.trigger = CAM_TRIGGER_POINT_SOF;
 		notify.frame_id = ctx_isp->frame_id;
 		notify.sof_timestamp_val = ctx_isp->sof_timestamp_val;
+		notify.sof_boottime_val = ctx_isp->boot_timestamp;
+		notify.need_recovery = true;
 		CAM_WARN_RATE_LIMIT(CAM_REQ,
 			"Notify CRM about Bubble req_id %llu frame %lld, ctx %u",
 			req->request_id, ctx_isp->frame_id, ctx->ctx_id);
-		ctx->ctx_crm_intf->notify_err(&notify);
+		rc = ctx->ctx_crm_intf->notify_err(&notify);
+		if (rc) {
+			req_isp->bubble_detected = false;
+			req_isp->reapply = false;
+			return 0;
+		}
 		atomic_set(&ctx_isp->process_bubble, 1);
 	} else {
 		req_isp->bubble_report = 0;
@@ -3167,10 +3194,10 @@ static int __cam_isp_ctx_apply_req_in_activated_state(
 		goto end;
 	}
 
-	CAM_DBG(CAM_REQ, "Apply request %lld in Substate[%s] ctx %u",
+	CAM_DBG(CAM_REQ, "Apply request %lld in Substate[%s] ctx %u link %x",
 		req->request_id,
 		__cam_isp_ctx_substate_val_to_type(ctx_isp->substate_activated),
-		ctx->ctx_id);
+		ctx->ctx_id, ctx->link_hdl);
 	req_isp = (struct cam_isp_ctx_req *) req->req_priv;
 
 	if (ctx_isp->active_req_cnt >=  2) {
@@ -3253,6 +3280,81 @@ end:
 	return rc;
 }
 
+static int __cam_isp_ctx_change_substate(
+	struct cam_context *ctx,
+	struct cam_req_mgr_request_change_state *state_info)
+{
+	int                        rc = 0;
+	uint64_t                   request_id = 0;
+	struct cam_ctx_request    *req = NULL;
+	struct cam_ctx_request    *req_temp = NULL;
+	struct cam_ctx_request    *bubble_req = NULL;
+	struct cam_isp_ctx_req    *req_isp = NULL;
+	struct cam_isp_context    *ctx_isp =
+				    (struct cam_isp_context *) ctx->ctx_priv;
+
+	if (!list_empty(&ctx->wait_req_list)) {
+		req = list_first_entry(&ctx->wait_req_list,
+			struct cam_ctx_request,
+			list);
+		if (req->request_id == state_info->req_id) {
+			req_isp = (struct cam_isp_ctx_req *)req->req_priv;
+			req_isp->bubble_detected = true;
+			req_isp->reapply = true;
+			bubble_req = req;
+			list_del_init(&req->list);
+			list_add_tail(&req->list, &ctx->active_req_list);
+			goto end;
+		}
+	} else {
+		CAM_ERR(CAM_ISP, "Ctx:%d No wait request", ctx->ctx_id);
+	}
+
+	if (!bubble_req) {
+		list_for_each_entry_safe(req, req_temp,
+			&ctx->active_req_list, list) {
+			if (req->request_id == state_info->req_id) {
+				req_isp =
+					(struct cam_isp_ctx_req *)req->req_priv;
+				req_isp->bubble_detected = true;
+				req_isp->reapply = true;
+				bubble_req = req;
+				break;
+			}
+		}
+	}
+
+	if (!bubble_req) {
+		CAM_ERR(CAM_ISP, "Req %lld not in active list ctx : %d",
+			state_info->req_id,
+			ctx->ctx_id);
+		goto done;
+	}
+
+end:
+
+	if (req_isp->bubble_report)
+		atomic_set(&ctx_isp->process_bubble, 1);
+
+	if ((req->request_id > ctx_isp->reported_req_id)
+		&& !req_isp->bubble_report) {
+		request_id = req->request_id;
+		ctx_isp->reported_req_id = request_id;
+	}
+
+	__cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id,
+		CAM_REQ_MGR_SOF_EVENT_ERROR);
+
+	ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_BUBBLE;
+
+	CAM_DBG(CAM_ISP, "next Substate[%s] ctx : %d",
+		__cam_isp_ctx_substate_val_to_type(
+		ctx_isp->substate_activated), ctx->ctx_id);
+
+done:
+	return rc;
+}
+
 static int __cam_isp_ctx_apply_req_in_sof(
 	struct cam_context *ctx, struct cam_req_mgr_apply_request *apply)
 {
@@ -3313,8 +3415,8 @@ static int __cam_isp_ctx_apply_req_in_bubble(
 		ctx_isp->substate_activated));
 	rc = __cam_isp_ctx_apply_req_in_activated_state(ctx, apply,
 		CAM_ISP_CTX_ACTIVATED_BUBBLE_APPLIED);
-	CAM_DBG(CAM_ISP, "new Substate[%s]",
-		__cam_isp_ctx_substate_val_to_type(
+	CAM_DBG(CAM_ISP, "ctx %d link %x new Substate[%s]",
+		ctx->ctx_id, ctx->link_hdl, __cam_isp_ctx_substate_val_to_type(
 		ctx_isp->substate_activated));
 
 	if (rc)
@@ -3704,6 +3806,7 @@ static int __cam_isp_ctx_flush_req_in_top_state(
 				flush_req);
 
 		ctx_isp->active_req_cnt = 0;
+
 		spin_unlock_bh(&ctx->lock);
 
 		reset_args.ctxt_to_hw_map = ctx_isp->hw_ctx;
@@ -3753,13 +3856,16 @@ static struct cam_ctx_ops
 			.apply_req = __cam_isp_ctx_apply_req_in_sof,
 			.notify_frame_skip =
 				__cam_isp_ctx_apply_default_req_settings,
+			.change_state = __cam_isp_ctx_change_substate,
 		},
 		.irq_ops = NULL,
 	},
 	/* APPLIED */
 	{
 		.ioctl_ops = {},
-		.crm_ops = {},
+		.crm_ops = {
+			.change_state = __cam_isp_ctx_change_substate,
+		},
 		.irq_ops = NULL,
 	},
 	/* EPOCH */
@@ -3769,6 +3875,7 @@ static struct cam_ctx_ops
 			.apply_req = __cam_isp_ctx_apply_req_in_epoch,
 			.notify_frame_skip =
 				__cam_isp_ctx_apply_default_req_settings,
+			.change_state = __cam_isp_ctx_change_substate,
 		},
 		.irq_ops = NULL,
 	},
@@ -3779,13 +3886,16 @@ static struct cam_ctx_ops
 			.apply_req = __cam_isp_ctx_apply_req_in_bubble,
 			.notify_frame_skip =
 				__cam_isp_ctx_apply_default_req_settings,
+			.change_state = __cam_isp_ctx_change_substate,
 		},
 		.irq_ops = NULL,
 	},
 	/* Bubble Applied */
 	{
 		.ioctl_ops = {},
-		.crm_ops = {},
+		.crm_ops = {
+			.change_state = __cam_isp_ctx_change_substate,
+		},
 		.irq_ops = NULL,
 	},
 	/* HW ERROR */
@@ -5506,6 +5616,33 @@ static int __cam_isp_ctx_unlink_in_acquired(struct cam_context *ctx,
 	return rc;
 }
 
+static int __cam_isp_ctx_get_isp_info(int32_t dev_hdl, void *data)
+{
+	int rc = 0;
+	struct cam_context               *ctx;
+	struct cam_req_mgr_dev_info      *isp_dev = data;
+	struct cam_isp_context           *isp_ctx = NULL;
+
+	ctx = (struct cam_context *)cam_get_device_priv(dev_hdl);
+
+	isp_ctx = (struct cam_isp_context *)ctx->ctx_priv;
+
+	isp_dev->state = isp_ctx->substate_activated;
+	isp_dev->timestamp = isp_ctx->sof_timestamp_val;
+	isp_dev->boot_time = isp_ctx->boot_timestamp;
+	isp_dev->frame_id = isp_ctx->frame_id;
+
+	if ((isp_ctx->substate_activated ==
+		CAM_ISP_CTX_ACTIVATED_APPLIED) ||
+		(isp_ctx->substate_activated ==
+		CAM_ISP_CTX_ACTIVATED_BUBBLE_APPLIED))
+		isp_dev->is_applied = true;
+	else
+		isp_dev->is_applied = false;
+
+	return rc;
+}
+
 static int __cam_isp_ctx_get_dev_info_in_acquired(struct cam_context *ctx,
 	struct cam_req_mgr_device_info *dev_info)
 {
@@ -5517,6 +5654,7 @@ static int __cam_isp_ctx_get_dev_info_in_acquired(struct cam_context *ctx,
 	dev_info->p_delay = 1;
 	dev_info->trigger = CAM_TRIGGER_POINT_SOF;
 	dev_info->trigger_on = true;
+	dev_info->sof_ts_cb = &__cam_isp_ctx_get_isp_info;
 
 	return rc;
 }
@@ -5574,6 +5712,8 @@ static int __cam_isp_ctx_start_dev_in_ready(struct cam_context *ctx,
 	atomic_set(&ctx_isp->process_bubble, 0);
 	atomic_set(&ctx_isp->rxd_epoch, 0);
 	ctx_isp->frame_id = 0;
+	ctx_isp->sof_timestamp_val = 0;
+	ctx_isp->boot_timestamp = 0;
 	ctx_isp->active_req_cnt = 0;
 	ctx_isp->reported_req_id = 0;
 	ctx_isp->bubble_frame_cnt = 0;
@@ -5923,6 +6063,33 @@ static int __cam_isp_ctx_unlink_in_activated(struct cam_context *ctx,
 	return rc;
 }
 
+static int __cam_isp_ctx_change_state_req(struct cam_context *ctx,
+	struct cam_req_mgr_request_change_state *state_info)
+{
+	int rc = 0;
+	struct cam_ctx_ops *ctx_ops = NULL;
+	struct cam_isp_context *ctx_isp =
+		(struct cam_isp_context *) ctx->ctx_priv;
+
+	CAM_DBG(CAM_ISP, "Enter: changes state ctx id %d link 0x%x",
+		ctx->ctx_id, ctx->link_hdl);
+	ctx_ops = &ctx_isp->substate_machine[ctx_isp->substate_activated];
+	if (ctx_ops->crm_ops.change_state) {
+		rc = ctx_ops->crm_ops.change_state(ctx, state_info);
+	} else {
+		CAM_WARN_RATE_LIMIT(CAM_ISP,
+		"No handle function in activated Substate[%s]",
+			__cam_isp_ctx_substate_val_to_type(
+			ctx_isp->substate_activated));
+		rc = -EFAULT;
+	}
+
+	if (rc)
+		CAM_WARN_RATE_LIMIT(CAM_ISP,
+			"changes state failed");
+	return rc;
+}
+
 static int __cam_isp_ctx_apply_req(struct cam_context *ctx,
 	struct cam_req_mgr_apply_request *apply)
 {
@@ -6109,6 +6276,7 @@ static struct cam_ctx_ops
 			.flush_req = __cam_isp_ctx_flush_req_in_top_state,
 			.process_evt = __cam_isp_ctx_process_evt,
 			.dump_req = __cam_isp_ctx_dump_in_top_state,
+			.change_state = __cam_isp_ctx_change_state_req,
 		},
 		.irq_ops = __cam_isp_ctx_handle_irq_in_activated,
 		.pagefault_ops = cam_isp_context_dump_requests,
@@ -6305,6 +6473,8 @@ int cam_isp_context_init(struct cam_isp_context *ctx,
 
 	ctx->base = ctx_base;
 	ctx->frame_id = 0;
+	ctx->sof_timestamp_val = 0;
+	ctx->boot_timestamp = 0;
 	ctx->custom_enabled = false;
 	ctx->use_frame_header_ts = false;
 	ctx->use_default_apply = false;

+ 6 - 4
drivers/cam_isp/isp_hw_mgr/include/cam_isp_hw_mgr_intf.h

@@ -284,15 +284,17 @@ enum cam_isp_ctx_type {
  * @ctx_type:              RDI_ONLY, PIX and RDI, or FS2
  * @packet_op_code:        Packet opcode
  * @last_cdm_done:         Last cdm done request
+ * @cam_isp_hw_sof_event_data  sof event timestamp
  */
 struct cam_isp_hw_cmd_args {
 	uint32_t                          cmd_type;
 	void                             *cmd_data;
 	union {
-		uint32_t                      sof_irq_enable;
-		uint32_t                      ctx_type;
-		uint32_t                      packet_op_code;
-		uint64_t                      last_cdm_done;
+		uint32_t                          sof_irq_enable;
+		uint32_t                          ctx_type;
+		uint32_t                          packet_op_code;
+		uint64_t                          last_cdm_done;
+		struct cam_isp_hw_sof_event_data  sof_done_event_data;
 	} u;
 };
 

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 282 - 538
drivers/cam_req_mgr/cam_req_mgr_core.c


+ 47 - 8
drivers/cam_req_mgr/cam_req_mgr_core.h

@@ -263,7 +263,8 @@ struct cam_req_mgr_req_tbl {
  * - members updated due to external events
  * @recover            : if user enabled recovery for this request.
  * @req_id             : mask tracking which all devices have request ready
- * @sync_mode          : Sync mode in which req id in this slot has to applied
+ * @sync_mode          : Modified sync mode in which req id in this slot has to applied
+ * @real_sync_mode     : Actual sync mode in which req id in this slot has to applied
  * @additional_timeout : Adjusted watchdog timeout value associated with
  * this request
  */
@@ -274,6 +275,7 @@ struct cam_req_mgr_slot {
 	int32_t               recover;
 	int64_t               req_id;
 	int32_t               sync_mode;
+	int32_t               real_sync_mode;
 	int32_t               additional_timeout;
 };
 
@@ -356,7 +358,7 @@ struct cam_req_mgr_connected_device {
  * @lock                 : mutex lock to guard link data operations
  * @link_state_spin_lock : spin lock to protect link state variable
  * @sync_link            : array of pointer to the sync link for synchronization
- * @num_sync_links       : num of links sync associated with this link
+ * @num_sync_link        : total number of sync links
  * @sync_link_sof_skip   : flag determines if a pkt is not available for a given
  *                         frame in a particular link skip corresponding
  *                         frame in sync link as well.
@@ -366,11 +368,14 @@ struct cam_req_mgr_connected_device {
  * @is_used              : 1 if link is in use else 0
  * @is_master            : Based on pd among links, the link with the highest pd
  *                         is assigned as master
- * @initial_skip         : Flag to determine if slave has started streaming in
- *                         master-slave sync
+ * @initial_skip         : Flag to determine if initial req need to skip for
+ *                         diff pd
+ * @is_sync_req          : flag used for deciding sync and non-sync
  * @in_msync_mode        : Flag to determine if a link is in master-slave mode
  * @initial_sync_req     : The initial req which is required to sync with the
  *                         other link
+ * @modified_init_sync_req : Modified initial req which is required to sync
+ *                          with the other link
  * @retry_cnt            : Counter that tracks number of attempts to apply
  *                         the same req
  * @is_shutdown          : Flag to indicate if link needs to be disconnected
@@ -385,6 +390,10 @@ struct cam_req_mgr_connected_device {
  *                         case of long exposure use case
  * @last_sof_trigger_jiffies : Record the jiffies of last sof trigger jiffies
  * @wq_congestion        : Indicates if WQ congestion is detected or not
+ * @activate_seq         : sequence in which link is activated
+ * @frame_id             : current frame id
+ * @sync_frame_id        : current frame id of sync link
+ * @bubble_skip          : req to skip on bubble
  */
 struct cam_req_mgr_core_link {
 	int32_t                              link_hdl;
@@ -401,19 +410,22 @@ struct cam_req_mgr_core_link {
 	void                                *parent;
 	struct mutex                         lock;
 	spinlock_t                           link_state_spin_lock;
-	struct cam_req_mgr_core_link
-			*sync_link[MAXIMUM_LINKS_PER_SESSION - 1];
-	int32_t                              num_sync_links;
+	struct cam_req_mgr_core_link        *sync_link[
+						MAXIMUM_LINKS_PER_SESSION];
+	int32_t                              num_sync_link;
 	bool                                 sync_link_sof_skip;
 	uint32_t                             open_req_cnt;
 	uint32_t                             last_flush_id;
 	atomic_t                             is_used;
 	bool                                 is_master;
-	bool                                 initial_skip;
+	uint32_t                             initial_skip;
+	bool                                 is_sync_req;
 	bool                                 in_msync_mode;
 	int64_t                              initial_sync_req;
+	int64_t                              modified_init_sync_req;
 	uint32_t                             retry_cnt;
 	bool                                 is_shutdown;
+	uint64_t                             sof_boottime;
 	uint64_t                             sof_timestamp;
 	uint64_t                             prev_sof_timestamp;
 	bool                                 dual_trigger;
@@ -422,6 +434,11 @@ struct cam_req_mgr_core_link {
 	bool                                 skip_init_frame;
 	uint64_t                             last_sof_trigger_jiffies;
 	bool                                 wq_congestion;
+	int32_t                              activate_seq;
+	uint64_t                             frame_id;
+	uint64_t                             sync_frame_id;
+	int32_t                              bubble_skip;
+	bool                                 skip_sync_apply;
 };
 
 /**
@@ -455,11 +472,33 @@ struct cam_req_mgr_core_session {
  * @session_head : list head holding sessions
  * @crm_lock     : mutex lock to protect session creation & destruction
  * @recovery_on_apply_fail : Recovery on apply failure using debugfs.
+ * @bitmap       : bitmap to store index of link
+ * @max_delay    : max pipeline delay in a session
  */
 struct cam_req_mgr_core_device {
 	struct list_head             session_head;
 	struct mutex                 crm_lock;
 	bool                         recovery_on_apply_fail;
+	DECLARE_BITMAP(bitmap, MAXIMUM_LINKS_PER_SESSION);
+	uint32_t                     max_delay;
+};
+
+/**
+ * struct cam_req_mgr_dump_link_data
+ * - Dump data
+ * @m_link          : master link handle
+ * @s_link          : slave link handle
+ * @m_req_id        : master req id
+ * @s_req_id        : slave req id
+ * @dev_info        : current timing data of slave link
+ *
+ */
+struct cam_req_mgr_dump_link_data {
+	struct cam_req_mgr_core_link      *m_link;
+	struct cam_req_mgr_core_link      *s_link;
+	uint64_t                           m_req_id;
+	uint64_t                           s_req_id;
+	struct cam_req_mgr_dev_info        dev_data;
 };
 
 /**

+ 57 - 9
drivers/cam_req_mgr/cam_req_mgr_interface.h

@@ -22,6 +22,7 @@ struct cam_req_mgr_apply_request;
 struct cam_req_mgr_flush_request;
 struct cam_req_mgr_link_evt_data;
 struct cam_req_mgr_dump_info;
+struct cam_req_mgr_request_change_state;
 
 /* Request Manager -- camera device driver interface */
 /**
@@ -33,8 +34,9 @@ struct cam_req_mgr_dump_info;
  *                              userspace
  * @cam_req_mgr_notify_timer  : start the timer
  */
-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_notify_trigger)(
+	struct cam_req_mgr_trigger_notify *);
+typedef bool (*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 *);
 typedef int (*cam_req_mgr_notify_stop)(struct cam_req_mgr_notify_stop *);
@@ -48,8 +50,9 @@ typedef int (*cam_req_mgr_notify_stop)(struct cam_req_mgr_notify_stop *);
  * @cam_req_mgr_notify_frame_skip: CRM asks device to apply setting for
  *                                 frame skip
  * @cam_req_mgr_flush_req        : Flush or cancel request
- * cam_req_mgr_process_evt       : generic events
+ * @cam_req_mgr_process_evt      : generic events
  * @cam_req_mgr_dump_req         : dump request
+ * @cam_req_mgr_change_state     : CRM asks device to change its state
  */
 typedef int (*cam_req_mgr_get_dev_info) (struct cam_req_mgr_device_info *);
 typedef int (*cam_req_mgr_link_setup)(struct cam_req_mgr_core_dev_link_setup *);
@@ -59,6 +62,8 @@ typedef int (*cam_req_mgr_notify_frame_skip)(
 typedef int (*cam_req_mgr_flush_req)(struct cam_req_mgr_flush_request *);
 typedef int (*cam_req_mgr_process_evt)(struct cam_req_mgr_link_evt_data *);
 typedef int (*cam_req_mgr_dump_req)(struct cam_req_mgr_dump_info *);
+typedef int (*cam_req_mgr_change_state)(
+	struct cam_req_mgr_request_change_state *);
 
 /**
  * @brief          : cam_req_mgr_crm_cb - func table
@@ -87,15 +92,17 @@ struct cam_req_mgr_crm_cb {
  * @flush_req        : payload to flush request
  * @process_evt      : payload to generic event
  * @dump_req         : payload to dump request
+ * @change_state     : payload to change state
  */
 struct cam_req_mgr_kmd_ops {
-	cam_req_mgr_get_dev_info      get_dev_info;
-	cam_req_mgr_link_setup        link_setup;
-	cam_req_mgr_apply_req         apply_req;
+	cam_req_mgr_get_dev_info     get_dev_info;
+	cam_req_mgr_link_setup       link_setup;
+	cam_req_mgr_apply_req        apply_req;
 	cam_req_mgr_notify_frame_skip notify_frame_skip;
-	cam_req_mgr_flush_req         flush_req;
-	cam_req_mgr_process_evt       process_evt;
-	cam_req_mgr_dump_req          dump_req;
+	cam_req_mgr_flush_req        flush_req;
+	cam_req_mgr_process_evt      process_evt;
+	cam_req_mgr_dump_req         dump_req;
+	cam_req_mgr_change_state     change_state;
 };
 
 /**
@@ -216,6 +223,7 @@ enum cam_req_mgr_link_evt_type {
  * @trigger  : trigger point of this notification, CRM will send apply
  *             only to the devices which subscribe to this point.
  * @sof_timestamp_val: Captured time stamp value at sof hw event
+ * @sof_boottime : Captured boot time stamp value at sof hw event
  * @req_id   : req id which returned buf_done
  * @trigger_id: ID to differentiate between the trigger devices
  */
@@ -225,6 +233,7 @@ struct cam_req_mgr_trigger_notify {
 	int64_t  frame_id;
 	uint32_t trigger;
 	uint64_t sof_timestamp_val;
+	uint64_t sof_boottime;
 	uint64_t req_id;
 	int32_t  trigger_id;
 };
@@ -249,6 +258,8 @@ struct cam_req_mgr_timer_notify {
  * @frame_id : frame id for internal tracking
  * @trigger  : trigger point of this notification, CRM will send apply
  * @sof_timestamp_val : Captured time stamp value at sof hw event
+ * @sof_boottime_val  : Captured boottime stamp value at sof hw event
+ * @need_recovery     : flag to check if recovery is needed
  * @error    : what error device hit while processing this req
  */
 struct cam_req_mgr_error_notify {
@@ -258,6 +269,8 @@ struct cam_req_mgr_error_notify {
 	int64_t  frame_id;
 	uint32_t trigger;
 	uint64_t sof_timestamp_val;
+	uint64_t sof_boottime_val;
+	bool     need_recovery;
 	enum cam_req_mgr_device_error error;
 };
 
@@ -302,6 +315,7 @@ struct cam_req_mgr_notify_stop {
  * @p_delay : delay between time settings applied and take effect
  * @trigger : Trigger point for the client
  * @trigger_on : This device provides trigger
+ * @sof_ts_cb  : callback to real time drivers
  */
 struct cam_req_mgr_device_info {
 	int32_t                     dev_hdl;
@@ -310,6 +324,7 @@ struct cam_req_mgr_device_info {
 	enum cam_pipeline_delay     p_delay;
 	uint32_t                    trigger;
 	bool                        trigger_on;
+	int32_t                     (*sof_ts_cb)(int32_t dev_hdl, void *data);
 };
 
 /**
@@ -408,4 +423,37 @@ struct cam_req_mgr_dump_info {
 	int32_t     link_hdl;
 	int32_t     dev_hdl;
 };
+
+/**
+ * struct cam_req_mgr_dev_info
+ * @link_hdl    : link identifier
+ * @state       : Current substate for the activated state.
+ * @timestamp   : time stamp for the sof event
+ * @boot_time   : boot time stamp for the sof event
+ * @frame_id    : frame id
+ * @is_applied  : if ISP is in applied state
+ *
+ */
+struct cam_req_mgr_dev_info {
+	int32_t     link_hdl;
+	uint32_t    state;
+	uint64_t    timestamp;
+	uint64_t    boot_time;
+	uint64_t    frame_id;
+	bool        is_applied;
+};
+
+/**
+ * struct cam_req_mgr_request_change_state
+ * @link_hdl    : link identifier
+ * @dev_hdl     : device handle or identifier
+ * @req_id      : request id
+ *
+ */
+struct cam_req_mgr_request_change_state {
+	int32_t    link_hdl;
+	int32_t    dev_hdl;
+	uint64_t   req_id;
+};
+
 #endif

+ 1 - 0
drivers/cam_sensor_module/cam_actuator/cam_actuator_core.c

@@ -410,6 +410,7 @@ int32_t cam_actuator_publish_dev_info(struct cam_req_mgr_device_info *info)
 	strlcpy(info->name, CAM_ACTUATOR_NAME, sizeof(info->name));
 	info->p_delay = 1;
 	info->trigger = CAM_TRIGGER_POINT_SOF;
+	info->sof_ts_cb = NULL;
 
 	return 0;
 }

+ 2 - 0
drivers/cam_sensor_module/cam_flash/cam_flash_core.c

@@ -1784,6 +1784,8 @@ int cam_flash_publish_dev_info(struct cam_req_mgr_device_info *info)
 	strlcpy(info->name, CAM_FLASH_NAME, sizeof(info->name));
 	info->p_delay = CAM_FLASH_PIPELINE_DELAY;
 	info->trigger = CAM_TRIGGER_POINT_SOF;
+	info->sof_ts_cb = NULL;
+
 	return 0;
 }
 

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

@@ -1216,6 +1216,7 @@ int cam_sensor_publish_dev_info(struct cam_req_mgr_device_info *info)
 	else
 		info->p_delay = 2;
 	info->trigger = CAM_TRIGGER_POINT_SOF;
+	info->sof_ts_cb = NULL;
 
 	return rc;
 }

Daži faili netika attēloti, jo izmaiņu fails ir pārāk liels