mirror of
https://github.com/torvalds/linux.git
synced 2026-06-03 03:53:37 +02:00
media: rockchip: vicap fixes error buffer state when lack buffer equal 2
Signed-off-by: Zefa Chen <zefa.chen@rock-chips.com> Change-Id: Ib44c1180298af20b03e68fedcd0819fbd9fe55db
This commit is contained in:
parent
d636b7a6d6
commit
c5df770b4a
|
|
@ -2158,14 +2158,19 @@ static int rkcif_assign_new_buffer_update(struct rkcif_stream *stream,
|
|||
get_dvp_reg_index_of_frm1_uv_addr(channel_id);
|
||||
}
|
||||
|
||||
if (dev->hdr.hdr_mode != NO_HDR && stream->id != 0 && (!dev->rdbk_buf[RDBK_L]))
|
||||
if (dev->hdr.hdr_mode != NO_HDR && stream->id != 0 && (!dev->rdbk_buf[RDBK_L])) {
|
||||
v4l2_dbg(3, rkcif_debug, &dev->v4l2_dev, "%s %d\n", __func__, __LINE__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (stream->to_stop_dma) {
|
||||
if (stream->dma_en & RKCIF_DMAEN_BY_ISP)
|
||||
if (stream->dma_en & RKCIF_DMAEN_BY_ISP) {
|
||||
v4l2_dbg(3, rkcif_debug, &dev->v4l2_dev, "%s %d\n", __func__, __LINE__);
|
||||
goto stop_dma;
|
||||
else
|
||||
} else {
|
||||
v4l2_dbg(3, rkcif_debug, &dev->v4l2_dev, "%s %d\n", __func__, __LINE__);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&stream->vbq_lock, flags);
|
||||
|
|
@ -2236,6 +2241,8 @@ static int rkcif_assign_new_buffer_update(struct rkcif_stream *stream,
|
|||
if (stream->lack_buf_cnt < 2)
|
||||
stream->lack_buf_cnt++;
|
||||
} else {
|
||||
stream->curr_buf = NULL;
|
||||
stream->next_buf = NULL;
|
||||
if (stream->lack_buf_cnt < 2)
|
||||
stream->lack_buf_cnt++;
|
||||
}
|
||||
|
|
@ -2314,6 +2321,8 @@ static int rkcif_assign_new_buffer_update(struct rkcif_stream *stream,
|
|||
dev->irq_stats.not_active_buf_cnt[stream->id]++;
|
||||
} else {
|
||||
ret = -EINVAL;
|
||||
stream->curr_buf = NULL;
|
||||
stream->next_buf = NULL;
|
||||
dev->err_state |= (RKCIF_ERR_ID0_NOT_BUF << stream->id);
|
||||
dev->irq_stats.not_active_buf_cnt[stream->id]++;
|
||||
}
|
||||
|
|
@ -3804,9 +3813,12 @@ static void rkcif_check_buffer_update_pingpong(struct rkcif_stream *stream,
|
|||
struct v4l2_mbus_config *mbus_cfg = &dev->active_sensor->mbus;
|
||||
struct rkcif_buffer *buffer = NULL;
|
||||
struct rkcif_dummy_buffer *dummy_buf = &dev->hw_dev->dummy_buf;
|
||||
u32 frm_addr_y, frm_addr_uv;
|
||||
u32 frm_addr_y = 0, frm_addr_uv = 0;
|
||||
u32 frm0_addr_y = 0, frm0_addr_uv = 0;
|
||||
u32 frm1_addr_y = 0, frm1_addr_uv = 0;
|
||||
unsigned long flags;
|
||||
int frame_phase = 0;
|
||||
bool is_dual_update_buf = false;
|
||||
|
||||
spin_lock_irqsave(&stream->vbq_lock, flags);
|
||||
if (stream->state == RKCIF_STATE_STREAMING &&
|
||||
|
|
@ -3815,29 +3827,31 @@ static void rkcif_check_buffer_update_pingpong(struct rkcif_stream *stream,
|
|||
(!dummy_buf->vaddr)) ||
|
||||
stream->curr_buf == NULL ||
|
||||
stream->next_buf == NULL)) {
|
||||
if (!stream->dma_en)
|
||||
frame_phase = CIF_CSI_FRAME0_READY;
|
||||
else
|
||||
frame_phase = stream->frame_phase_cache;
|
||||
frame_phase = stream->frame_phase_cache;
|
||||
if (!stream->is_line_wake_up ||
|
||||
(stream->is_line_wake_up && stream->frame_idx < 2)) {
|
||||
if (mbus_cfg->type == V4L2_MBUS_CSI2_DPHY ||
|
||||
mbus_cfg->type == V4L2_MBUS_CSI2_CPHY ||
|
||||
mbus_cfg->type == V4L2_MBUS_CCP2) {
|
||||
frm_addr_y = frame_phase & CIF_CSI_FRAME0_READY ?
|
||||
get_reg_index_of_frm0_y_addr(channel_id) :
|
||||
get_reg_index_of_frm1_y_addr(channel_id);
|
||||
frm_addr_uv = frame_phase & CIF_CSI_FRAME0_READY ?
|
||||
get_reg_index_of_frm0_uv_addr(channel_id) :
|
||||
get_reg_index_of_frm1_uv_addr(channel_id);
|
||||
frm0_addr_y = get_reg_index_of_frm0_y_addr(channel_id);
|
||||
frm1_addr_y = get_reg_index_of_frm1_y_addr(channel_id);
|
||||
frm0_addr_uv = get_reg_index_of_frm0_uv_addr(channel_id);
|
||||
frm1_addr_uv = get_reg_index_of_frm1_uv_addr(channel_id);
|
||||
} else {
|
||||
frm_addr_y = frame_phase & CIF_CSI_FRAME0_READY ?
|
||||
get_dvp_reg_index_of_frm0_y_addr(channel_id) :
|
||||
get_dvp_reg_index_of_frm1_y_addr(channel_id);
|
||||
frm_addr_uv = frame_phase & CIF_CSI_FRAME0_READY ?
|
||||
get_dvp_reg_index_of_frm0_uv_addr(channel_id) :
|
||||
get_dvp_reg_index_of_frm1_uv_addr(channel_id);
|
||||
frm0_addr_y = get_dvp_reg_index_of_frm0_y_addr(channel_id);
|
||||
frm1_addr_y = get_dvp_reg_index_of_frm1_y_addr(channel_id);
|
||||
frm0_addr_uv = get_dvp_reg_index_of_frm0_uv_addr(channel_id);
|
||||
frm1_addr_uv = get_dvp_reg_index_of_frm1_uv_addr(channel_id);
|
||||
}
|
||||
if (frame_phase & CIF_CSI_FRAME0_READY) {
|
||||
frm_addr_y = frm0_addr_y;
|
||||
frm_addr_uv = frm0_addr_uv;
|
||||
} else {
|
||||
frm_addr_y = frm1_addr_y;
|
||||
frm_addr_uv = frm1_addr_uv;
|
||||
}
|
||||
if (!stream->dma_en && stream->curr_buf == NULL && stream->next_buf == NULL)
|
||||
is_dual_update_buf = true;
|
||||
if (!list_empty(&stream->buf_head)) {
|
||||
if (frame_phase == CIF_CSI_FRAME0_READY) {
|
||||
stream->curr_buf = list_first_entry(&stream->buf_head,
|
||||
|
|
@ -3846,6 +3860,8 @@ static void rkcif_check_buffer_update_pingpong(struct rkcif_stream *stream,
|
|||
list_del(&stream->curr_buf->queue);
|
||||
buffer = stream->curr_buf;
|
||||
}
|
||||
if (buffer && is_dual_update_buf)
|
||||
stream->next_buf = buffer;
|
||||
} else if (frame_phase == CIF_CSI_FRAME1_READY) {
|
||||
if (stream->next_buf == NULL &&
|
||||
stream->cif_fmt_in->field == V4L2_FIELD_INTERLACED) {
|
||||
|
|
@ -3857,17 +3873,37 @@ static void rkcif_check_buffer_update_pingpong(struct rkcif_stream *stream,
|
|||
list_del(&stream->next_buf->queue);
|
||||
buffer = stream->next_buf;
|
||||
}
|
||||
if (buffer && is_dual_update_buf)
|
||||
stream->curr_buf = buffer;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
v4l2_info(&dev->v4l2_dev, "%s %d\n", __func__, __LINE__);
|
||||
}
|
||||
if (buffer) {
|
||||
rkcif_write_register(dev, frm_addr_y,
|
||||
buffer->buff_addr[RKCIF_PLANE_Y]);
|
||||
if (stream->cif_fmt_out->fmt_type != CIF_FMT_TYPE_RAW)
|
||||
rkcif_write_register(dev, frm_addr_uv,
|
||||
buffer->buff_addr[RKCIF_PLANE_CBCR]);
|
||||
if (is_dual_update_buf) {
|
||||
rkcif_write_register(dev, frm0_addr_y,
|
||||
buffer->buff_addr[RKCIF_PLANE_Y]);
|
||||
if (stream->cif_fmt_out->fmt_type != CIF_FMT_TYPE_RAW)
|
||||
rkcif_write_register(dev, frm0_addr_uv,
|
||||
buffer->buff_addr[RKCIF_PLANE_CBCR]);
|
||||
rkcif_write_register(dev, frm1_addr_y,
|
||||
buffer->buff_addr[RKCIF_PLANE_Y]);
|
||||
if (stream->cif_fmt_out->fmt_type != CIF_FMT_TYPE_RAW)
|
||||
rkcif_write_register(dev, frm1_addr_uv,
|
||||
buffer->buff_addr[RKCIF_PLANE_CBCR]);
|
||||
} else {
|
||||
rkcif_write_register(dev, frm_addr_y,
|
||||
buffer->buff_addr[RKCIF_PLANE_Y]);
|
||||
if (stream->cif_fmt_out->fmt_type != CIF_FMT_TYPE_RAW)
|
||||
rkcif_write_register(dev, frm_addr_uv,
|
||||
buffer->buff_addr[RKCIF_PLANE_CBCR]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
v4l2_dbg(3, rkcif_debug, &stream->cifdev->v4l2_dev,
|
||||
"%s %d, is_wake_up %d, frame_idx %d\n",
|
||||
__func__, __LINE__, stream->is_line_wake_up, stream->frame_idx);
|
||||
if (stream->curr_buf == stream->next_buf) {
|
||||
if (stream->frame_phase_cache == CIF_CSI_FRAME0_READY) {
|
||||
stream->curr_buf = list_first_entry(&stream->buf_head,
|
||||
|
|
@ -3894,10 +3930,20 @@ static void rkcif_check_buffer_update_pingpong(struct rkcif_stream *stream,
|
|||
wake_up(&stream->wq_stopped);
|
||||
} else {
|
||||
stream->to_en_dma = RKCIF_DMAEN_BY_VICAP;
|
||||
v4l2_dbg(3, rkcif_debug, &stream->cifdev->v4l2_dev,
|
||||
"%s stream[%d] start dma capture, frame cnt %d\n",
|
||||
__func__, stream->id, stream->frame_idx);
|
||||
}
|
||||
} else {
|
||||
v4l2_dbg(3, rkcif_debug, &stream->cifdev->v4l2_dev,
|
||||
"%s %d, dma_en 0x%x, frame cnt %d\n",
|
||||
__func__, __LINE__, stream->dma_en, stream->frame_idx);
|
||||
}
|
||||
if (stream->lack_buf_cnt)
|
||||
stream->lack_buf_cnt--;
|
||||
} else {
|
||||
v4l2_info(&dev->v4l2_dev, "%s %d, state %d, curr_buf %p, next_buf %p\n",
|
||||
__func__, __LINE__, stream->state, stream->curr_buf, stream->next_buf);
|
||||
}
|
||||
spin_unlock_irqrestore(&stream->vbq_lock, flags);
|
||||
if (stream->to_en_dma)
|
||||
|
|
@ -8166,11 +8212,11 @@ static void rkcif_update_stream(struct rkcif_device *cif_dev,
|
|||
ret = rkcif_assign_new_buffer_pingpong(stream,
|
||||
RKCIF_YUV_ADDR_STATE_UPDATE,
|
||||
mipi_id);
|
||||
if (ret && cif_dev->chip_id != CHIP_RV1106_CIF)
|
||||
if (ret && cif_dev->chip_id < CHIP_RK3588_CIF)
|
||||
return;
|
||||
} else {
|
||||
ret = rkcif_update_new_buffer_wake_up_mode(stream);
|
||||
if (ret && cif_dev->chip_id != CHIP_RV1106_CIF)
|
||||
if (ret && cif_dev->chip_id < CHIP_RK3588_CIF)
|
||||
return;
|
||||
}
|
||||
if (!stream->is_line_wake_up && stream->dma_en & RKCIF_DMAEN_BY_VICAP)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user