Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 09820a70 authored by Junzhe Zou's avatar Junzhe Zou
Browse files

msm: camera: isp: clean up logic to handle bubble



Move request to active list whenever bubble is detected and wait for
buf done. Remove the request from active list after buf done from all
the ports are returned.

Change-Id: Ic9e3b0d28ab8beef7018b781fbcfcba83add8281
Signed-off-by: default avatarJunzhe Zou <jnzhezou@codeaurora.org>
parent ff850b06
Loading
Loading
Loading
Loading
+60 −42
Original line number Original line Diff line number Diff line
@@ -381,7 +381,7 @@ static int __cam_isp_ctx_handle_buf_done_in_activated_state(
			continue;
			continue;
		}
		}


		if (!bubble_state) {
		if (!req_isp->bubble_detected) {
			CAM_DBG(CAM_ISP,
			CAM_DBG(CAM_ISP,
				"Sync with success: req %lld res 0x%x fd 0x%x",
				"Sync with success: req %lld res 0x%x fd 0x%x",
				req->request_id,
				req->request_id,
@@ -408,15 +408,14 @@ static int __cam_isp_ctx_handle_buf_done_in_activated_state(
		} else {
		} else {
			/*
			/*
			 * Ignore the buffer done if bubble detect is on
			 * Ignore the buffer done if bubble detect is on
			 * In most case, active list should be empty when
			 * Increment the ack number here, and queue the
			 * bubble detects. But for safety, we just move the
			 * request back to pending list whenever all the
			 * current active request to the pending list here.
			 * buffers are done.
			 */
			 */
			req_isp->num_acked++;
			CAM_DBG(CAM_ISP,
			CAM_DBG(CAM_ISP,
				"buf done with bubble state %d recovery %d",
				"buf done with bubble state %d recovery %d",
				bubble_state, req_isp->bubble_report);
				bubble_state, req_isp->bubble_report);
			list_del_init(&req->list);
			list_add(&req->list, &ctx->pending_req_list);
			continue;
			continue;
		}
		}


@@ -437,10 +436,25 @@ static int __cam_isp_ctx_handle_buf_done_in_activated_state(
			req_isp->num_fence_map_out);
			req_isp->num_fence_map_out);
		WARN_ON(req_isp->num_acked > req_isp->num_fence_map_out);
		WARN_ON(req_isp->num_acked > req_isp->num_fence_map_out);
	}
	}
	if (req_isp->num_acked == req_isp->num_fence_map_out) {

	if (req_isp->num_acked != req_isp->num_fence_map_out)
		return rc;

	ctx_isp->active_req_cnt--;

	if (req_isp->bubble_detected && req_isp->bubble_report) {
		req_isp->num_acked = 0;
		req_isp->bubble_detected = false;
		list_del_init(&req->list);
		list_add(&req->list, &ctx->pending_req_list);

		CAM_DBG(CAM_REQ,
			"Move active request %lld to pending list(cnt = %d) [bubble recovery]",
			 req->request_id, ctx_isp->active_req_cnt);
	} else {
		list_del_init(&req->list);
		list_del_init(&req->list);
		list_add_tail(&req->list, &ctx->free_req_list);
		list_add_tail(&req->list, &ctx->free_req_list);
		ctx_isp->active_req_cnt--;

		CAM_DBG(CAM_REQ,
		CAM_DBG(CAM_REQ,
			"Move active request %lld to free list(cnt = %d) [all fences done]",
			"Move active request %lld to free list(cnt = %d) [all fences done]",
			 req->request_id, ctx_isp->active_req_cnt);
			 req->request_id, ctx_isp->active_req_cnt);
@@ -738,15 +752,13 @@ static int __cam_isp_ctx_epoch_in_applied(struct cam_isp_context *ctx_isp,
	req = list_first_entry(&ctx->wait_req_list, struct cam_ctx_request,
	req = list_first_entry(&ctx->wait_req_list, struct cam_ctx_request,
		list);
		list);
	req_isp = (struct cam_isp_ctx_req *)req->req_priv;
	req_isp = (struct cam_isp_ctx_req *)req->req_priv;
	req_isp->bubble_detected = true;


	CAM_DBG(CAM_ISP, "Report Bubble flag %d", req_isp->bubble_report);
	CAM_DBG(CAM_ISP, "Report Bubble flag %d", req_isp->bubble_report);
	if (req_isp->bubble_report && ctx->ctx_crm_intf &&
	if (req_isp->bubble_report && ctx->ctx_crm_intf &&
		ctx->ctx_crm_intf->notify_err) {
		ctx->ctx_crm_intf->notify_err) {
		struct cam_req_mgr_error_notify notify;
		struct cam_req_mgr_error_notify notify;


		list_del_init(&req->list);
		list_add(&req->list, &ctx->pending_req_list);

		notify.link_hdl = ctx->link_hdl;
		notify.link_hdl = ctx->link_hdl;
		notify.dev_hdl = ctx->dev_hdl;
		notify.dev_hdl = ctx->dev_hdl;
		notify.req_id = req->request_id;
		notify.req_id = req->request_id;
@@ -755,17 +767,18 @@ static int __cam_isp_ctx_epoch_in_applied(struct cam_isp_context *ctx_isp,
		CAM_DBG(CAM_ISP, "Notify CRM about Bubble frame %lld",
		CAM_DBG(CAM_ISP, "Notify CRM about Bubble frame %lld",
			ctx_isp->frame_id);
			ctx_isp->frame_id);
	} else {
	} else {
		req_isp->bubble_report = 0;
	}

	/*
	/*
		 * Since can not bubble report, always move the request to
	 * Always move the request to active list. Let buf done
		 * active list.
	 * function handles the rest.
	 */
	 */
		list_del_init(&req->list);
		list_add_tail(&req->list, &ctx->active_req_list);
		ctx_isp->active_req_cnt++;
	CAM_DBG(CAM_REQ, "move request %lld to active list(cnt = %d)",
	CAM_DBG(CAM_REQ, "move request %lld to active list(cnt = %d)",
		req->request_id, ctx_isp->active_req_cnt);
		req->request_id, ctx_isp->active_req_cnt);
		req_isp->bubble_report = 0;
	ctx_isp->active_req_cnt++;
	}
	list_del_init(&req->list);
	list_add_tail(&req->list, &ctx->active_req_list);


	if (req->request_id > ctx_isp->reported_req_id) {
	if (req->request_id > ctx_isp->reported_req_id) {
		request_id = req->request_id;
		request_id = req->request_id;
@@ -888,13 +901,12 @@ static int __cam_isp_ctx_epoch_in_bubble_applied(
	req = list_first_entry(&ctx->wait_req_list, struct cam_ctx_request,
	req = list_first_entry(&ctx->wait_req_list, struct cam_ctx_request,
		list);
		list);
	req_isp = (struct cam_isp_ctx_req *)req->req_priv;
	req_isp = (struct cam_isp_ctx_req *)req->req_priv;
	list_del_init(&req->list);
	req_isp->bubble_detected = true;


	if (req_isp->bubble_report && ctx->ctx_crm_intf &&
	if (req_isp->bubble_report && ctx->ctx_crm_intf &&
		ctx->ctx_crm_intf->notify_err) {
		ctx->ctx_crm_intf->notify_err) {
		struct cam_req_mgr_error_notify notify;
		struct cam_req_mgr_error_notify notify;


		list_add(&req->list, &ctx->pending_req_list);
		notify.link_hdl = ctx->link_hdl;
		notify.link_hdl = ctx->link_hdl;
		notify.dev_hdl = ctx->dev_hdl;
		notify.dev_hdl = ctx->dev_hdl;
		notify.req_id = req->request_id;
		notify.req_id = req->request_id;
@@ -904,16 +916,18 @@ static int __cam_isp_ctx_epoch_in_bubble_applied(
			"Notify CRM about Bubble req_id %llu frame %lld",
			"Notify CRM about Bubble req_id %llu frame %lld",
			req->request_id, ctx_isp->frame_id);
			req->request_id, ctx_isp->frame_id);
	} else {
	} else {
		req_isp->bubble_report = 0;
	}

	/*
	/*
		 * If we can not report bubble, then treat it as if no bubble
	 * Always move the request to active list. Let buf done
		 * report. Just move the req to active list.
	 * function handles the rest.
	 */
	 */
		list_add_tail(&req->list, &ctx->active_req_list);
		ctx_isp->active_req_cnt++;
	CAM_DBG(CAM_ISP, "move request %lld to active list(cnt = %d)",
	CAM_DBG(CAM_ISP, "move request %lld to active list(cnt = %d)",
		req->request_id, ctx_isp->active_req_cnt);
		req->request_id, ctx_isp->active_req_cnt);
		req_isp->bubble_report = 0;
	ctx_isp->active_req_cnt++;
	}
	list_del_init(&req->list);
	list_add_tail(&req->list, &ctx->active_req_list);


	if (!req_isp->bubble_report) {
	if (!req_isp->bubble_report) {
		if (req->request_id > ctx_isp->reported_req_id) {
		if (req->request_id > ctx_isp->reported_req_id) {
@@ -1417,6 +1431,7 @@ static int __cam_isp_ctx_flush_req_in_top_state(
		CAM_DBG(CAM_ISP, "try to flush active list");
		CAM_DBG(CAM_ISP, "try to flush active list");
		rc = __cam_isp_ctx_flush_req(ctx, &ctx->active_req_list,
		rc = __cam_isp_ctx_flush_req(ctx, &ctx->active_req_list,
		flush_req);
		flush_req);
		ctx_isp->active_req_cnt = 0;
		spin_unlock_bh(&ctx->lock);
		spin_unlock_bh(&ctx->lock);


		/* Start hw */
		/* Start hw */
@@ -1615,12 +1630,12 @@ static int __cam_isp_ctx_rdi_only_sof_in_bubble_applied(
	CAM_DBG(CAM_ISP, "frame id: %lld time stamp:0x%llx",
	CAM_DBG(CAM_ISP, "frame id: %lld time stamp:0x%llx",
		ctx_isp->frame_id, ctx_isp->sof_timestamp_val);
		ctx_isp->frame_id, ctx_isp->sof_timestamp_val);


	if (list_empty(&ctx->pending_req_list)) {
	if (list_empty(&ctx->wait_req_list)) {
		/*
		/*
		 * If no pending req in epoch, this is an error case.
		 * If no pending req in epoch, this is an error case.
		 * The recovery is to go back to sof state
		 * The recovery is to go back to sof state
		 */
		 */
		CAM_ERR(CAM_ISP, "No pending request");
		CAM_ERR(CAM_ISP, "No wait request");
		ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_SOF;
		ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_SOF;


		/* Send SOF event as empty frame*/
		/* Send SOF event as empty frame*/
@@ -1630,9 +1645,10 @@ static int __cam_isp_ctx_rdi_only_sof_in_bubble_applied(
		goto end;
		goto end;
	}
	}


	req = list_first_entry(&ctx->pending_req_list, struct cam_ctx_request,
	req = list_first_entry(&ctx->wait_req_list, struct cam_ctx_request,
		list);
		list);
	req_isp = (struct cam_isp_ctx_req *)req->req_priv;
	req_isp = (struct cam_isp_ctx_req *)req->req_priv;
	req_isp->bubble_detected = true;


	CAM_DBG(CAM_ISP, "Report Bubble flag %d", req_isp->bubble_report);
	CAM_DBG(CAM_ISP, "Report Bubble flag %d", req_isp->bubble_report);
	if (req_isp->bubble_report && ctx->ctx_crm_intf &&
	if (req_isp->bubble_report && ctx->ctx_crm_intf &&
@@ -1647,17 +1663,18 @@ static int __cam_isp_ctx_rdi_only_sof_in_bubble_applied(
		CAM_DBG(CAM_ISP, "Notify CRM about Bubble frame %lld",
		CAM_DBG(CAM_ISP, "Notify CRM about Bubble frame %lld",
			ctx_isp->frame_id);
			ctx_isp->frame_id);
	} else {
	} else {
		req_isp->bubble_report = 0;
	}

	/*
	/*
		 * Since can not bubble report, always move the request to
	 * Always move the request to active list. Let buf done
		 * active list.
	 * function handles the rest.
	 */
	 */
	ctx_isp->active_req_cnt++;
	list_del_init(&req->list);
	list_del_init(&req->list);
	list_add_tail(&req->list, &ctx->active_req_list);
	list_add_tail(&req->list, &ctx->active_req_list);
		ctx_isp->active_req_cnt++;
	CAM_DBG(CAM_ISP, "move request %lld to active list(cnt = %d)",
	CAM_DBG(CAM_ISP, "move request %lld to active list(cnt = %d)",
			req->request_id, ctx_isp->active_req_cnt);
			req->request_id, ctx_isp->active_req_cnt);
		req_isp->bubble_report = 0;
	}


	if (!req_isp->bubble_report) {
	if (!req_isp->bubble_report) {
		if (req->request_id > ctx_isp->reported_req_id) {
		if (req->request_id > ctx_isp->reported_req_id) {
@@ -2087,6 +2104,7 @@ static int __cam_isp_ctx_config_dev_in_top_state(
	req_isp->num_fence_map_out = cfg.num_out_map_entries;
	req_isp->num_fence_map_out = cfg.num_out_map_entries;
	req_isp->num_fence_map_in = cfg.num_in_map_entries;
	req_isp->num_fence_map_in = cfg.num_in_map_entries;
	req_isp->num_acked = 0;
	req_isp->num_acked = 0;
	req_isp->bubble_detected = false;


	for (i = 0; i < req_isp->num_fence_map_out; i++) {
	for (i = 0; i < req_isp->num_fence_map_out; i++) {
		rc = cam_sync_get_obj_ref(req_isp->fence_map_out[i].sync_id);
		rc = cam_sync_get_obj_ref(req_isp->fence_map_out[i].sync_id);
+1 −0
Original line number Original line Diff line number Diff line
@@ -115,6 +115,7 @@ struct cam_isp_ctx_req {
	uint32_t                              num_acked;
	uint32_t                              num_acked;
	int32_t                               bubble_report;
	int32_t                               bubble_report;
	struct cam_isp_prepare_hw_update_data hw_update_data;
	struct cam_isp_prepare_hw_update_data hw_update_data;
	bool                                  bubble_detected;
};
};


/**
/**