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:
Zefa Chen 2023-05-08 21:21:12 +08:00 committed by Tao Huang
parent d636b7a6d6
commit c5df770b4a

View File

@ -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)