Эх сурвалжийг харах

msm: camera: isp: Add more deferred buf done support

The reg upd and buf done irq may be got earlier
than the request is applied and before req is
added to wait req list, then these irq will
be dropped in current logic, then the req can't
be finished. This change stores the buf done as
deferred buf done in case of missing the buf done.

CRs-Fixed: 3063894
Change-Id: If0e2dbbc1ac033c13386ef06fda51736e4dbbf3b
Signed-off-by: Depeng Shao <[email protected]>
Depeng Shao 3 жил өмнө
parent
commit
9bde405759

+ 48 - 6
drivers/cam_isp/cam_isp_context.c

@@ -1891,17 +1891,16 @@ static int __cam_isp_ctx_handle_buf_done_verify_addr(
 	struct cam_ctx_request *req;
 	struct cam_ctx_request *next_req = NULL;
 	struct cam_context *ctx = ctx_isp->base;
-	bool  req_in_wait_list = false;
+	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)) {
-			struct cam_isp_ctx_req *req_isp;
-
 			req = list_first_entry(&ctx->wait_req_list,
 				struct cam_ctx_request, list);
 
-			req_in_wait_list = true;
+			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,
@@ -1915,6 +1914,39 @@ static int __cam_isp_ctx_handle_buf_done_verify_addr(
 
 			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 =
+			__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);
+
+			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_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
@@ -1927,7 +1959,7 @@ static int __cam_isp_ctx_handle_buf_done_verify_addr(
 				ctx_isp, req, done, bubble_state, true, true);
 		}
 
-		if (!req_in_wait_list  && (ctx_isp->last_applied_req_id !=
+		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 ",
@@ -2574,6 +2606,16 @@ end:
 	return 0;
 }
 
+static int __cam_isp_ctx_buf_done_in_sof(struct cam_isp_context *ctx_isp,
+	void *evt_data)
+{
+	int rc = 0;
+	struct cam_isp_hw_done_event_data *done =
+		(struct cam_isp_hw_done_event_data *) evt_data;
+
+	rc = __cam_isp_ctx_handle_buf_done_in_activated_state(ctx_isp, done, 0);
+	return rc;
+}
 
 static int __cam_isp_ctx_buf_done_in_applied(struct cam_isp_context *ctx_isp,
 	void *evt_data)
@@ -3427,7 +3469,7 @@ static struct cam_isp_ctx_irq_ops
 			__cam_isp_ctx_reg_upd_in_sof,
 			__cam_isp_ctx_notify_sof_in_activated_state,
 			__cam_isp_ctx_notify_eof_in_activated_state,
-			NULL,
+			__cam_isp_ctx_buf_done_in_sof,
 			__cam_isp_ctx_handle_secondary_events,
 		},
 	},