diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c b/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c index 11f499be8d46..97c2f52c9a70 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c @@ -545,8 +545,8 @@ static int msm_isp_get_buf(struct msm_isp_buf_mgr *buf_mgr, uint32_t id, list_count = 0; list_for_each_entry(temp_buf_info, &bufq->share_head, share_list) { - if (!temp_buf_info->buf_used[id]) { - temp_buf_info->buf_used[id] = 1; + if ((temp_buf_info->get_buf_mask & (1 << id)) == 0) { + temp_buf_info->get_buf_mask |= (1 << id); temp_buf_info->buf_get_count++; *buf_cnt = temp_buf_info->buf_get_count; if (temp_buf_info->buf_get_count == @@ -564,7 +564,7 @@ static int msm_isp_get_buf(struct msm_isp_buf_mgr *buf_mgr, uint32_t id, spin_unlock_irqrestore( &bufq->bufq_lock, flags); return rc; - } else if (temp_buf_info->buf_used[id] && + } else if ((temp_buf_info->get_buf_mask & (1 << id)) && temp_buf_info->buf_reuse_flag) { spin_unlock_irqrestore( &bufq->bufq_lock, flags); @@ -648,7 +648,7 @@ static int msm_isp_get_buf(struct msm_isp_buf_mgr *buf_mgr, uint32_t id, sizeof(struct msm_isp_buffer), GFP_ATOMIC); if (temp_buf_info) { temp_buf_info->buf_reuse_flag = 1; - temp_buf_info->buf_used[id] = 1; + temp_buf_info->get_buf_mask |= (1 << id); temp_buf_info->buf_get_count = 1; list_add_tail(&temp_buf_info->share_list, &bufq->share_head); @@ -680,11 +680,10 @@ static int msm_isp_get_buf(struct msm_isp_buf_mgr *buf_mgr, uint32_t id, return -EFAULT; } } - memset((*buf_info)->buf_used, 0, - sizeof(uint8_t) * bufq->buf_client_count); - (*buf_info)->buf_used[id] = 1; + (*buf_info)->get_buf_mask = (1 << id); (*buf_info)->buf_get_count = 1; (*buf_info)->buf_put_count = 0; + (*buf_info)->put_buf_mask = 0; (*buf_info)->buf_reuse_flag = 0; if (!list_empty(&(*buf_info)->share_list)) { spin_unlock_irqrestore(&bufq->bufq_lock, flags); @@ -795,7 +794,8 @@ static int msm_isp_put_buf(struct msm_isp_buf_mgr *buf_mgr, buf_info->buf_get_count = 0; buf_info->buf_put_count = 0; - memset(buf_info->buf_used, 0, sizeof(buf_info->buf_used)); + buf_info->get_buf_mask = 0; + buf_info->put_buf_mask = 0; rc = msm_isp_put_buf_unsafe(buf_mgr, bufq_handle, buf_index); @@ -804,15 +804,15 @@ static int msm_isp_put_buf(struct msm_isp_buf_mgr *buf_mgr, return rc; } -static int msm_isp_update_put_buf_cnt(struct msm_isp_buf_mgr *buf_mgr, - uint32_t bufq_handle, uint32_t buf_index, struct timeval *tv, - uint32_t frame_id) +static int msm_isp_update_put_buf_cnt_unsafe( + struct msm_isp_buf_mgr *buf_mgr, + uint32_t id, uint32_t bufq_handle, uint32_t buf_index, + struct timeval *tv, uint32_t frame_id, unsigned long *flags) { int rc = -1; struct msm_isp_bufq *bufq = NULL; struct msm_isp_buffer *buf_info = NULL; enum msm_isp_buffer_state state; - unsigned long flags; bufq = msm_isp_get_bufq(buf_mgr, bufq_handle); if (!bufq) { @@ -826,27 +826,28 @@ static int msm_isp_update_put_buf_cnt(struct msm_isp_buf_mgr *buf_mgr, return rc; } - spin_lock_irqsave(&bufq->bufq_lock, flags); if (bufq->buf_type != ISP_SHARE_BUF || - buf_info->buf_put_count == 0) { + buf_info->put_buf_mask == 0) { buf_info->frame_id = frame_id; } state = buf_info->state; if (state == MSM_ISP_BUFFER_STATE_DEQUEUED) { - if (bufq->buf_type == ISP_SHARE_BUF) { + if (bufq->buf_type == ISP_SHARE_BUF && + ((buf_info->put_buf_mask & (1 << id)) == 0)) { + buf_info->put_buf_mask |= (1 << id); buf_info->buf_put_count++; if (buf_info->buf_put_count != ISP_SHARE_BUF_CLIENT) { rc = buf_info->buf_put_count; - spin_unlock_irqrestore(&bufq->bufq_lock, flags); return rc; } } } else { pr_warn("%s: Invalid state, stream id %x, state %d\n", __func__, bufq->stream_id, state); - spin_unlock_irqrestore(&bufq->bufq_lock, flags); + spin_unlock_irqrestore(&bufq->bufq_lock, *flags); dump_stack(); + spin_lock_irqsave(&bufq->bufq_lock, *flags); return rc; } @@ -854,10 +855,30 @@ static int msm_isp_update_put_buf_cnt(struct msm_isp_buf_mgr *buf_mgr, buf_info->state = MSM_ISP_BUFFER_STATE_DIVERTED; buf_info->tv = tv; } - spin_unlock_irqrestore(&bufq->bufq_lock, flags); return 0; } +static int msm_isp_update_put_buf_cnt(struct msm_isp_buf_mgr *buf_mgr, + uint32_t id, uint32_t bufq_handle, uint32_t buf_index, + struct timeval *tv, uint32_t frame_id) +{ + int rc = -1; + struct msm_isp_bufq *bufq = NULL; + unsigned long flags; + + bufq = msm_isp_get_bufq(buf_mgr, bufq_handle); + if (!bufq) { + pr_err("Invalid bufq\n"); + return rc; + } + + spin_lock_irqsave(&bufq->bufq_lock, flags); + rc = msm_isp_update_put_buf_cnt_unsafe(buf_mgr, id, bufq_handle, + buf_index, tv, frame_id, &flags); + spin_unlock_irqrestore(&bufq->bufq_lock, flags); + return rc; +} + static int msm_isp_buf_done(struct msm_isp_buf_mgr *buf_mgr, uint32_t bufq_handle, uint32_t buf_index, struct timeval *tv, uint32_t frame_id, uint32_t output_format) @@ -915,8 +936,9 @@ done: return rc; } -static int msm_isp_flush_buf(struct msm_isp_buf_mgr *buf_mgr, - uint32_t bufq_handle, enum msm_isp_buffer_flush_t flush_type) +static int msm_isp_flush_buf(struct msm_isp_buf_mgr *buf_mgr, uint32_t id, + uint32_t bufq_handle, enum msm_isp_buffer_flush_t flush_type, + struct timeval *tv, uint32_t frame_id) { int rc = -1, i; struct msm_isp_bufq *bufq = NULL; diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.h b/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.h index 1d4951b069bd..b3b03cd6d205 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.h +++ b/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.h @@ -101,7 +101,8 @@ struct msm_isp_buffer { /*Share buffer cache state*/ struct list_head share_list; - uint8_t buf_used[ISP_SHARE_BUF_CLIENT]; + uint8_t get_buf_mask; + uint8_t put_buf_mask; uint8_t buf_get_count; uint8_t buf_put_count; uint8_t buf_reuse_flag; @@ -158,8 +159,9 @@ struct msm_isp_buf_ops { int (*put_buf)(struct msm_isp_buf_mgr *buf_mgr, uint32_t bufq_handle, uint32_t buf_index); - int (*flush_buf)(struct msm_isp_buf_mgr *buf_mgr, - uint32_t bufq_handle, enum msm_isp_buffer_flush_t flush_type); + int (*flush_buf)(struct msm_isp_buf_mgr *buf_mgr, uint32_t id, + uint32_t bufq_handle, enum msm_isp_buffer_flush_t flush_type, + struct timeval *tv, uint32_t frame_id); int (*buf_done)(struct msm_isp_buf_mgr *buf_mgr, uint32_t bufq_handle, uint32_t buf_index, @@ -175,9 +177,8 @@ struct msm_isp_buf_ops { struct msm_isp_bufq * (*get_bufq)(struct msm_isp_buf_mgr *buf_mgr, uint32_t bufq_handle); int (*update_put_buf_cnt)(struct msm_isp_buf_mgr *buf_mgr, - uint32_t bufq_handle, uint32_t buf_index, - struct timeval *tv, - uint32_t frame_id); + uint32_t id, uint32_t bufq_handle, uint32_t buf_index, + struct timeval *tv, uint32_t frame_id); }; struct msm_isp_buf_mgr { diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c index f3709b6a0d43..4489305210b8 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c @@ -795,7 +795,7 @@ void msm_isp_notify(struct vfe_device *vfe_dev, uint32_t event_type, vfe_dev->common_data->dual_vfe_res-> axi_data[1]-> src_info[VFE_PIX_0].frame_id) { - pr_err_ratelimited("%s: Error! 2 VFE out of sync vfe0 frame_id %u vfe1 %u\n", + pr_debug("%s: Error! 2 VFE out of sync vfe0 frame_id %u vfe1 %u\n", __func__, vfe_dev->common_data->dual_vfe_res-> axi_data[0]-> @@ -1749,7 +1749,8 @@ static void msm_isp_process_done_buf(struct vfe_device *vfe_dev, } rc = vfe_dev->buf_mgr->ops->update_put_buf_cnt(vfe_dev->buf_mgr, - buf->bufq_handle, buf->buf_idx, time_stamp, frame_id); + vfe_dev->pdev->id, buf->bufq_handle, buf->buf_idx, + time_stamp, frame_id); /* Buf divert return value represent whether the buf * can be diverted. A positive return value means @@ -1912,7 +1913,8 @@ int msm_isp_drop_frame(struct vfe_device *vfe_dev, if (done_buf) { rc = vfe_dev->buf_mgr->ops->update_put_buf_cnt(vfe_dev->buf_mgr, - done_buf->bufq_handle, done_buf->buf_idx, 0, frame_id); + vfe_dev->pdev->id, done_buf->bufq_handle, + done_buf->buf_idx, 0, frame_id); if (rc == 0) { done_buf->buf_debug.put_state[ done_buf->buf_debug.put_state_last] = @@ -2187,6 +2189,7 @@ int msm_isp_axi_reset(struct vfe_device *vfe_dev, struct msm_vfe_axi_stream *stream_info; struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data; uint32_t bufq_handle = 0, bufq_id = 0; + struct msm_isp_timestamp timestamp; if (!reset_cmd) { pr_err("%s: NULL pointer reset cmd %p\n", __func__, reset_cmd); @@ -2197,6 +2200,8 @@ int msm_isp_axi_reset(struct vfe_device *vfe_dev, rc = vfe_dev->hw_info->vfe_ops.core_ops.reset_hw(vfe_dev, 0, reset_cmd->blocking); + msm_isp_get_timestamp(×tamp); + for (i = 0, j = 0; j < axi_data->num_active_stream && i < VFE_AXI_SRC_MAX; i++, j++) { stream_info = &axi_data->stream_info[i]; @@ -2217,8 +2222,9 @@ int msm_isp_axi_reset(struct vfe_device *vfe_dev, continue; rc = vfe_dev->buf_mgr->ops->flush_buf( - vfe_dev->buf_mgr, bufq_handle, - MSM_ISP_BUFFER_FLUSH_ALL); + vfe_dev->buf_mgr, vfe_dev->pdev->id, + bufq_handle, MSM_ISP_BUFFER_FLUSH_ALL, + ×tamp.buf_time, reset_cmd->frame_id); if (rc == -EFAULT) { msm_isp_halt_send_error(vfe_dev, ISP_EVENT_BUF_FATAL_ERROR); @@ -2227,7 +2233,7 @@ int msm_isp_axi_reset(struct vfe_device *vfe_dev, memset(&stream_info->buf, 0, sizeof(stream_info->buf)); axi_data->src_info[SRC_TO_INTF(stream_info-> - stream_src)]. frame_id = reset_cmd->frame_id; + stream_src)].frame_id = reset_cmd->frame_id; msm_isp_reset_burst_count_and_frame_drop(vfe_dev, stream_info); } @@ -2607,11 +2613,14 @@ static int msm_isp_stop_axi_stream(struct vfe_device *vfe_dev, (axi_data->src_info[VFE_PIX_0].input_mux == EXTERNAL_READ); uint32_t src_mask = 0, intf, bufq_id = 0, bufq_handle = 0; unsigned long flags; + struct msm_isp_timestamp timestamp; if (stream_cfg_cmd->num_streams > MAX_NUM_STREAM || stream_cfg_cmd->num_streams == 0) return -EINVAL; + msm_isp_get_timestamp(×tamp); + for (i = 0; i < stream_cfg_cmd->num_streams; i++) { if (HANDLE_TO_IDX(stream_cfg_cmd->stream_handle[i]) >= VFE_AXI_SRC_MAX) { @@ -2754,8 +2763,9 @@ static int msm_isp_stop_axi_stream(struct vfe_device *vfe_dev, continue; rc = vfe_dev->buf_mgr->ops->flush_buf( - vfe_dev->buf_mgr, bufq_handle, - MSM_ISP_BUFFER_FLUSH_ALL); + vfe_dev->buf_mgr, vfe_dev->pdev->id, + bufq_handle, MSM_ISP_BUFFER_FLUSH_ALL, + ×tamp.buf_time, 0); if (rc == -EFAULT) { msm_isp_halt_send_error(vfe_dev, ISP_EVENT_BUF_FATAL_ERROR); @@ -2876,7 +2886,7 @@ static int msm_isp_return_empty_buffer(struct vfe_device *vfe_dev, msm_isp_get_timestamp(×tamp); rc = vfe_dev->buf_mgr->ops->update_put_buf_cnt(vfe_dev->buf_mgr, - buf->bufq_handle, buf->buf_idx, 0, frame_id); + vfe_dev->pdev->id, buf->bufq_handle, buf->buf_idx, 0, frame_id); if (rc == 0) { buf->buf_debug.put_state[buf->buf_debug.put_state_last] = MSM_ISP_BUFFER_STATE_DROP_REG; @@ -3120,6 +3130,8 @@ int msm_isp_update_axi_stream(struct vfe_device *vfe_dev, void *arg) struct msm_vfe_axi_stream_cfg_update_info *update_info; struct msm_isp_sw_framskip *sw_skip_info = NULL; unsigned long flags; + struct msm_isp_timestamp timestamp; + uint32_t frame_id; /*num_stream is uint32 and update_info[] bound by MAX_NUM_STREAM*/ if (update_cmd->num_streams > MAX_NUM_STREAM) @@ -3168,9 +3180,14 @@ int msm_isp_update_axi_stream(struct vfe_device *vfe_dev, void *arg) break; case DISABLE_STREAM_BUF_DIVERT: stream_info->buf_divert = 0; + msm_isp_get_timestamp(×tamp); + frame_id = vfe_dev->axi_data.src_info[ + SRC_TO_INTF(stream_info->stream_src)].frame_id; rc = vfe_dev->buf_mgr->ops->flush_buf(vfe_dev->buf_mgr, + vfe_dev->pdev->id, stream_info->bufq_handle[VFE_BUF_QUEUE_DEFAULT], - MSM_ISP_BUFFER_FLUSH_DIVERTED); + MSM_ISP_BUFFER_FLUSH_DIVERTED, + ×tamp.buf_time, frame_id); if (rc == -EFAULT) { msm_isp_halt_send_error(vfe_dev, ISP_EVENT_BUF_FATAL_ERROR); diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.c index 06e35fbeae2b..148e6e226bd7 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.c @@ -140,7 +140,7 @@ static int32_t msm_isp_stats_buf_divert(struct vfe_device *vfe_dev, } rc = vfe_dev->buf_mgr->ops->update_put_buf_cnt( - vfe_dev->buf_mgr, done_buf->bufq_handle, + vfe_dev->buf_mgr, vfe_dev->pdev->id, done_buf->bufq_handle, done_buf->buf_idx, &ts->buf_time, frame_id); if (rc != 0) { @@ -568,6 +568,9 @@ int msm_isp_stats_reset(struct vfe_device *vfe_dev) int i = 0, rc = 0; struct msm_vfe_stats_stream *stream_info = NULL; struct msm_vfe_stats_shared_data *stats_data = &vfe_dev->stats_data; + struct msm_isp_timestamp timestamp; + + msm_isp_get_timestamp(×tamp); for (i = 0; i < MSM_ISP_STATS_MAX; i++) { stream_info = &stats_data->stream_info[i]; @@ -575,8 +578,9 @@ int msm_isp_stats_reset(struct vfe_device *vfe_dev) continue; rc = vfe_dev->buf_mgr->ops->flush_buf(vfe_dev->buf_mgr, - stream_info->bufq_handle, - MSM_ISP_BUFFER_FLUSH_ALL); + vfe_dev->pdev->id, stream_info->bufq_handle, + MSM_ISP_BUFFER_FLUSH_ALL, ×tamp.buf_time, + vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id); if (rc == -EFAULT) { msm_isp_halt_send_error(vfe_dev, ISP_EVENT_BUF_FATAL_ERROR); @@ -688,6 +692,10 @@ static int msm_isp_stop_stats_stream(struct vfe_device *vfe_dev, uint32_t num_stats_comp_mask = 0; struct msm_vfe_stats_stream *stream_info; struct msm_vfe_stats_shared_data *stats_data = &vfe_dev->stats_data; + struct msm_isp_timestamp timestamp; + + msm_isp_get_timestamp(×tamp); + num_stats_comp_mask = vfe_dev->hw_info->stats_hw_info->num_stats_comp_mask; @@ -754,8 +762,9 @@ static int msm_isp_stop_stats_stream(struct vfe_device *vfe_dev, stream_info = &stats_data->stream_info[idx]; rc = vfe_dev->buf_mgr->ops->flush_buf(vfe_dev->buf_mgr, - stream_info->bufq_handle, - MSM_ISP_BUFFER_FLUSH_ALL); + vfe_dev->pdev->id, stream_info->bufq_handle, + MSM_ISP_BUFFER_FLUSH_ALL, ×tamp.buf_time, + vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id); if (rc == -EFAULT) { msm_isp_halt_send_error(vfe_dev, ISP_EVENT_BUF_FATAL_ERROR);