瀏覽代碼

msm: camera: isp: Add unhandled buf done to deferred list

Some unhandled buf dones belong to next req, we need
to add them to deferred buf done list and process it
in future.

CRs-Fixed: 3197114
Change-Id: I5489cb6faacf2b6c9018b3b660a1df2ee6ac9564
Signed-off-by: Depeng Shao <[email protected]>
Depeng Shao 3 年之前
父節點
當前提交
61d3d3f5d9
共有 1 個文件被更改,包括 96 次插入66 次删除
  1. 96 66
      drivers/cam_isp/cam_isp_context.c

+ 96 - 66
drivers/cam_isp/cam_isp_context.c

@@ -49,6 +49,11 @@ static const char *__cam_isp_hw_evt_val_to_type(
 static const char *__cam_isp_ctx_substate_val_to_type(
 	enum cam_isp_ctx_activated_substate type);
 
+static int __cam_isp_ctx_check_deferred_buf_done(
+	struct cam_isp_context *ctx_isp,
+	struct cam_isp_hw_done_event_data *done,
+	uint32_t bubble_state);
+
 static const char *__cam_isp_evt_val_to_type(
 	uint32_t evt_id)
 {
@@ -1848,6 +1853,7 @@ static int __cam_isp_ctx_handle_buf_done_for_request_verify_addr(
 	struct cam_context *ctx = ctx_isp->base;
 	const char *handle_type;
 	uint32_t cmp_addr = 0;
+	struct cam_isp_hw_done_event_data unhandled_done = {0};
 
 	trace_cam_buf_done("ISP", ctx, req);
 
@@ -1863,6 +1869,8 @@ static int __cam_isp_ctx_handle_buf_done_for_request_verify_addr(
 		return -EINVAL;
 	}
 
+	unhandled_done.timestamp = done->timestamp;
+
 	for (i = 0; i < done->num_handles; i++) {
 		for (j = 0; j < req_isp->num_fence_map_out; j++) {
 			cmp_addr = cam_smmu_is_expanded_memory() ? CAM_36BIT_INTF_GET_IOVA_BASE(
@@ -1888,6 +1896,11 @@ static int __cam_isp_ctx_handle_buf_done_for_request_verify_addr(
 				__cam_isp_resource_handle_id_to_type(
 				ctx_isp->isp_device_type, done->resource_handle[i]),
 				req->request_id);
+			unhandled_done.resource_handle[unhandled_done.num_handles] =
+				done->resource_handle[i];
+			unhandled_done.last_consumed_addr[unhandled_done.num_handles] =
+				done->last_consumed_addr[i];
+			unhandled_done.num_handles++;
 			continue;
 		}
 
@@ -2037,6 +2050,10 @@ static int __cam_isp_ctx_handle_buf_done_for_request_verify_addr(
 				req->request_id, CAM_REQ_MGR_SOF_EVENT_SUCCESS);
 	}
 
+	if ((unhandled_done.num_handles > 0) && (!defer_buf_done))
+		__cam_isp_ctx_check_deferred_buf_done(
+			ctx_isp, &unhandled_done, bubble_state);
+
 	if (req_isp->num_acked > req_isp->num_fence_map_out) {
 		/* Should not happen */
 		CAM_ERR(CAM_ISP,
@@ -2154,93 +2171,106 @@ static void __cam_isp_ctx_buf_done_match_req(
 		"irq_delay_detected %d", *irq_delay_detected);
 }
 
-static int __cam_isp_ctx_handle_buf_done_verify_addr(
+static int __cam_isp_ctx_check_deferred_buf_done(
 	struct cam_isp_context *ctx_isp,
 	struct cam_isp_hw_done_event_data *done,
 	uint32_t bubble_state)
 {
 	int rc = 0;
-	bool irq_delay_detected = false;
 	struct cam_ctx_request *req;
-	struct cam_ctx_request *next_req = NULL;
 	struct cam_context *ctx = ctx_isp->base;
 	struct cam_isp_ctx_req *req_isp;
 	bool  req_in_pending_wait_list = false;
 
-	if (list_empty(&ctx->active_req_list)) {
-
-		if (!list_empty(&ctx->wait_req_list)) {
-			req = list_first_entry(&ctx->wait_req_list,
-				struct cam_ctx_request, list);
+	if (!list_empty(&ctx->wait_req_list)) {
+		req = list_first_entry(&ctx->wait_req_list,
+			struct cam_ctx_request, list);
 
-			req_in_pending_wait_list = true;
-			if (ctx_isp->last_applied_req_id !=
-				ctx_isp->last_bufdone_err_apply_req_id) {
-				CAM_WARN(CAM_ISP,
-					"Buf done with no active request but with req in wait list, req %llu last apply id:%lld last err id:%lld",
-					req->request_id,
-					ctx_isp->last_applied_req_id,
-					ctx_isp->last_bufdone_err_apply_req_id);
-				ctx_isp->last_bufdone_err_apply_req_id =
-					ctx_isp->last_applied_req_id;
-			}
+		req_in_pending_wait_list = true;
+		if (ctx_isp->last_applied_req_id !=
+			ctx_isp->last_bufdone_err_apply_req_id) {
+			CAM_INFO(CAM_ISP,
+				"Buf done with no active request but with req in wait list, req %llu last apply id:%lld last err id:%lld",
+				req->request_id,
+				ctx_isp->last_applied_req_id,
+				ctx_isp->last_bufdone_err_apply_req_id);
+			ctx_isp->last_bufdone_err_apply_req_id =
+				ctx_isp->last_applied_req_id;
+		}
 
-			req_isp = (struct cam_isp_ctx_req *) req->req_priv;
+		req_isp = (struct cam_isp_ctx_req *) req->req_priv;
 
-			/*
-			 * Verify consumed address for this request to make sure
-			 * we are handling the buf_done for the correct
-			 * buffer. Also defer actual buf_done handling, i.e
-			 * do not signal the fence as this request may go into
-			 * Bubble state eventully.
-			 */
-			rc =
+		/*
+		 * Verify consumed address for this request to make sure
+		 * we are handling the buf_done for the correct
+		 * buffer. Also defer actual buf_done handling, i.e
+		 * do not signal the fence as this request may go into
+		 * Bubble state eventully.
+		 */
+		rc =
 			__cam_isp_ctx_handle_buf_done_for_request_verify_addr(
 				ctx_isp, req, done, bubble_state, true, true);
-		} else if (!list_empty(&ctx->pending_req_list)) {
-			/*
-			 * We saw the case that the hw config is blocked due to
-			 * some reason, the we get the reg upd and buf done before
-			 * the req is added to wait req list.
-			 */
-			req = list_first_entry(&ctx->pending_req_list,
-				struct cam_ctx_request, list);
+	} else if (!list_empty(&ctx->pending_req_list)) {
+		/*
+		 * We saw the case that the hw config is blocked due to
+		 * some reason, the we get the reg upd and buf done before
+		 * the req is added to wait req list.
+		 */
+		req = list_first_entry(&ctx->pending_req_list,
+			struct cam_ctx_request, list);
 
-			req_in_pending_wait_list = true;
-			if (ctx_isp->last_applied_req_id !=
-				ctx_isp->last_bufdone_err_apply_req_id) {
-				CAM_WARN(CAM_ISP,
-					"Buf done with no active request but with req in pending list, req %llu last apply id:%lld last err id:%lld",
-					req->request_id,
-					ctx_isp->last_applied_req_id,
-					ctx_isp->last_bufdone_err_apply_req_id);
-				ctx_isp->last_bufdone_err_apply_req_id =
-					ctx_isp->last_applied_req_id;
-			}
+		req_in_pending_wait_list = true;
+		if (ctx_isp->last_applied_req_id !=
+			ctx_isp->last_bufdone_err_apply_req_id) {
+			CAM_INFO(CAM_ISP,
+				"Buf done with no active request but with req in pending list, req %llu last apply id:%lld last err id:%lld",
+				req->request_id,
+				ctx_isp->last_applied_req_id,
+				ctx_isp->last_bufdone_err_apply_req_id);
+			ctx_isp->last_bufdone_err_apply_req_id =
+				ctx_isp->last_applied_req_id;
+		}
 
-			req_isp = (struct cam_isp_ctx_req *) req->req_priv;
+		req_isp = (struct cam_isp_ctx_req *) req->req_priv;
 
-			/*
-			 * Verify consumed address for this request to make sure
-			 * we are handling the buf_done for the correct
-			 * buffer. Also defer actual buf_done handling, i.e
-			 * do not signal the fence as this request may go into
-			 * Bubble state eventully.
-			 */
-			rc =
+		/*
+		 * Verify consumed address for this request to make sure
+		 * we are handling the buf_done for the correct
+		 * buffer. Also defer actual buf_done handling, i.e
+		 * do not signal the fence as this request may go into
+		 * Bubble state eventully.
+		 */
+		rc =
 			__cam_isp_ctx_handle_buf_done_for_request_verify_addr(
 				ctx_isp, req, done, bubble_state, true, true);
-		}
+	}
 
-		if (!req_in_pending_wait_list  && (ctx_isp->last_applied_req_id !=
-			ctx_isp->last_bufdone_err_apply_req_id)) {
-			CAM_WARN(CAM_ISP,
-				"Buf done with no active request bubble_state=%d last_applied_req_id:%lld ",
-				bubble_state, ctx_isp->last_applied_req_id);
-			ctx_isp->last_bufdone_err_apply_req_id =
-					ctx_isp->last_applied_req_id;
-		}
-		return 0;
+	if (!req_in_pending_wait_list  && (ctx_isp->last_applied_req_id !=
+		ctx_isp->last_bufdone_err_apply_req_id)) {
+		CAM_WARN(CAM_ISP,
+			"Buf done with no active request bubble_state=%d last_applied_req_id:%lld ",
+			bubble_state, ctx_isp->last_applied_req_id);
+		ctx_isp->last_bufdone_err_apply_req_id =
+				ctx_isp->last_applied_req_id;
+	}
+
+	return rc;
+}
+
+static int __cam_isp_ctx_handle_buf_done_verify_addr(
+	struct cam_isp_context *ctx_isp,
+	struct cam_isp_hw_done_event_data *done,
+	uint32_t bubble_state)
+{
+	int rc = 0;
+	bool irq_delay_detected = false;
+	struct cam_ctx_request *req;
+	struct cam_ctx_request *next_req = NULL;
+	struct cam_context *ctx = ctx_isp->base;
+
+	if (list_empty(&ctx->active_req_list)) {
+		return __cam_isp_ctx_check_deferred_buf_done(
+			ctx_isp, done, bubble_state);
 	}
 
 	req = list_first_entry(&ctx->active_req_list,