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

Commit abb3248f authored by Jeyaprakash Soundrapandian's avatar Jeyaprakash Soundrapandian Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: camera: isp: clean up logic to handle bubble" into dev/msm-4.14-camx

parents 288786bc 8c8f2766
Loading
Loading
Loading
Loading
+60 −42
Original line number Diff line number Diff line
@@ -381,7 +381,7 @@ static int __cam_isp_ctx_handle_buf_done_in_activated_state(
			continue;
		}

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

@@ -437,10 +436,25 @@ static int __cam_isp_ctx_handle_buf_done_in_activated_state(
			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_add_tail(&req->list, &ctx->free_req_list);
		ctx_isp->active_req_cnt--;

		CAM_DBG(CAM_REQ,
			"Move active request %lld to free list(cnt = %d) [all fences done]",
			 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,
		list);
	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);
	if (req_isp->bubble_report && ctx->ctx_crm_intf &&
		ctx->ctx_crm_intf->notify_err) {
		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.dev_hdl = ctx->dev_hdl;
		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",
			ctx_isp->frame_id);
	} else {
		req_isp->bubble_report = 0;
	}

	/*
		 * Since can not bubble report, always move the request to
		 * active list.
	 * Always move the request to active list. Let buf done
	 * 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)",
		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) {
		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,
		list);
	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 &&
		ctx->ctx_crm_intf->notify_err) {
		struct cam_req_mgr_error_notify notify;

		list_add(&req->list, &ctx->pending_req_list);
		notify.link_hdl = ctx->link_hdl;
		notify.dev_hdl = ctx->dev_hdl;
		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",
			req->request_id, ctx_isp->frame_id);
	} else {
		req_isp->bubble_report = 0;
	}

	/*
		 * If we can not report bubble, then treat it as if no bubble
		 * report. Just move the req to active list.
	 * Always move the request to active list. Let buf done
	 * 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)",
		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->request_id > ctx_isp->reported_req_id) {
@@ -1415,6 +1429,7 @@ static int __cam_isp_ctx_flush_req_in_top_state(
		CAM_DBG(CAM_ISP, "try to flush active list");
		rc = __cam_isp_ctx_flush_req(ctx, &ctx->active_req_list,
		flush_req);
		ctx_isp->active_req_cnt = 0;
		spin_unlock_bh(&ctx->lock);

		/* Start hw */
@@ -1613,12 +1628,12 @@ static int __cam_isp_ctx_rdi_only_sof_in_bubble_applied(
	CAM_DBG(CAM_ISP, "frame id: %lld time stamp:0x%llx",
		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.
		 * 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;

		/* Send SOF event as empty frame*/
@@ -1628,9 +1643,10 @@ static int __cam_isp_ctx_rdi_only_sof_in_bubble_applied(
		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);
	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);
	if (req_isp->bubble_report && ctx->ctx_crm_intf &&
@@ -1645,17 +1661,18 @@ static int __cam_isp_ctx_rdi_only_sof_in_bubble_applied(
		CAM_DBG(CAM_ISP, "Notify CRM about Bubble frame %lld",
			ctx_isp->frame_id);
	} else {
		req_isp->bubble_report = 0;
	}

	/*
		 * Since can not bubble report, always move the request to
		 * active list.
	 * Always move the request to active list. Let buf done
	 * function handles the rest.
	 */
	ctx_isp->active_req_cnt++;
	list_del_init(&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)",
			req->request_id, ctx_isp->active_req_cnt);
		req_isp->bubble_report = 0;
	}

	if (!req_isp->bubble_report) {
		if (req->request_id > ctx_isp->reported_req_id) {
@@ -2085,6 +2102,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_in = cfg.num_in_map_entries;
	req_isp->num_acked = 0;
	req_isp->bubble_detected = false;

	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);
+1 −0
Original line number Diff line number Diff line
@@ -115,6 +115,7 @@ struct cam_isp_ctx_req {
	uint32_t                              num_acked;
	int32_t                               bubble_report;
	struct cam_isp_prepare_hw_update_data hw_update_data;
	bool                                  bubble_detected;
};

/**