Loading drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c +60 −42 Original line number Diff line number Diff line Loading @@ -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, Loading @@ -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; } Loading @@ -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); Loading Loading @@ -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; Loading @@ -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; Loading Loading @@ -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; Loading @@ -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) { Loading Loading @@ -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 */ Loading Loading @@ -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*/ Loading @@ -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 && Loading @@ -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) { Loading Loading @@ -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); Loading drivers/media/platform/msm/camera/cam_isp/cam_isp_context.h +1 −0 Original line number Diff line number Diff line Loading @@ -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; }; /** Loading Loading
drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c +60 −42 Original line number Diff line number Diff line Loading @@ -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, Loading @@ -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; } Loading @@ -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); Loading Loading @@ -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; Loading @@ -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; Loading Loading @@ -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; Loading @@ -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) { Loading Loading @@ -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 */ Loading Loading @@ -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*/ Loading @@ -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 && Loading @@ -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) { Loading Loading @@ -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); Loading
drivers/media/platform/msm/camera/cam_isp/cam_isp_context.h +1 −0 Original line number Diff line number Diff line Loading @@ -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; }; /** Loading