msm: camera: isp: Track put_buf per VFE
Update bit mask per VFE for put_buf instead of only count. In flush buf update put buf mask first and put buffer if put_mask is same as get_mask Change-Id: I8b128094e4ae62e5676a46e6a4624e4933234266 Signed-off-by: Harsh Shah <harshs@codeaurora.org> Signed-off-by: Jing Zhou <jzhou70@codeaurora.org>
This commit is contained in:
parent
cc999c3a99
commit
725a1ccf1f
4 changed files with 90 additions and 41 deletions
|
@ -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;
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Reference in a new issue