|
|
|
|
@@ -555,6 +555,19 @@ static const struct cif_input_fmt in_fmts[] = {
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static inline int rkcif_get_interlace_mode(struct rkcif_stream *stream)
|
|
|
|
|
{
|
|
|
|
|
if (stream->cif_fmt_in->field == V4L2_FIELD_INTERLACED) {
|
|
|
|
|
if (stream->cifdev->use_hw_interlace)
|
|
|
|
|
return RKCIF_INTERLACE_HW;
|
|
|
|
|
else if (stream->cifdev->chip_id >= CHIP_RK3568_CIF)
|
|
|
|
|
return RKCIF_INTERLACE_SOFT_AUTO;
|
|
|
|
|
else
|
|
|
|
|
return RKCIF_INTERLACE_SOFT;
|
|
|
|
|
}
|
|
|
|
|
return RKCIF_INTERLACE_NONE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int rkcif_output_fmt_check(struct rkcif_stream *stream,
|
|
|
|
|
const struct cif_output_fmt *output_fmt)
|
|
|
|
|
{
|
|
|
|
|
@@ -2411,7 +2424,7 @@ static void rkcif_assign_new_buffer_init(struct rkcif_stream *stream,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (stream->cif_fmt_in->field == V4L2_FIELD_INTERLACED) {
|
|
|
|
|
if (rkcif_get_interlace_mode(stream) == RKCIF_INTERLACE_SOFT) {
|
|
|
|
|
stream->next_buf = stream->curr_buf;
|
|
|
|
|
if (stream->next_buf) {
|
|
|
|
|
buff_addr_y = stream->next_buf->buff_addr[RKCIF_PLANE_Y];
|
|
|
|
|
@@ -2557,7 +2570,7 @@ static int rkcif_assign_new_buffer_update(struct rkcif_stream *stream,
|
|
|
|
|
|
|
|
|
|
if (!dummy_buf->vaddr &&
|
|
|
|
|
stream->curr_buf == stream->next_buf &&
|
|
|
|
|
stream->cif_fmt_in->field != V4L2_FIELD_INTERLACED)
|
|
|
|
|
rkcif_get_interlace_mode(stream) != RKCIF_INTERLACE_SOFT)
|
|
|
|
|
ret = -EINVAL;
|
|
|
|
|
|
|
|
|
|
if (stream->frame_phase == CIF_CSI_FRAME0_READY) {
|
|
|
|
|
@@ -2575,7 +2588,7 @@ static int rkcif_assign_new_buffer_update(struct rkcif_stream *stream,
|
|
|
|
|
} else if (stream->frame_phase == CIF_CSI_FRAME1_READY) {
|
|
|
|
|
if (!stream->next_buf)
|
|
|
|
|
ret = -EINVAL;
|
|
|
|
|
if (stream->cif_fmt_in->field == V4L2_FIELD_INTERLACED) {
|
|
|
|
|
if (rkcif_get_interlace_mode(stream) == RKCIF_INTERLACE_SOFT) {
|
|
|
|
|
if (stream->next_buf != stream->curr_buf) {
|
|
|
|
|
stream->next_buf = stream->curr_buf;
|
|
|
|
|
buffer = stream->next_buf;
|
|
|
|
|
@@ -2601,7 +2614,7 @@ static int rkcif_assign_new_buffer_update(struct rkcif_stream *stream,
|
|
|
|
|
if (stream->frame_phase == CIF_CSI_FRAME0_READY) {
|
|
|
|
|
stream->curr_buf = NULL;
|
|
|
|
|
} else if (stream->frame_phase == CIF_CSI_FRAME1_READY) {
|
|
|
|
|
if (stream->cif_fmt_in->field == V4L2_FIELD_INTERLACED) {
|
|
|
|
|
if (rkcif_get_interlace_mode(stream) == RKCIF_INTERLACE_SOFT) {
|
|
|
|
|
stream->next_buf = stream->curr_buf;
|
|
|
|
|
buffer = stream->next_buf;
|
|
|
|
|
} else {
|
|
|
|
|
@@ -2630,7 +2643,7 @@ static int rkcif_assign_new_buffer_update(struct rkcif_stream *stream,
|
|
|
|
|
if (buffer) {
|
|
|
|
|
buff_addr_y = buffer->buff_addr[RKCIF_PLANE_Y];
|
|
|
|
|
buff_addr_cbcr = buffer->buff_addr[RKCIF_PLANE_CBCR];
|
|
|
|
|
if (stream->cif_fmt_in->field == V4L2_FIELD_INTERLACED &&
|
|
|
|
|
if (rkcif_get_interlace_mode(stream) == RKCIF_INTERLACE_SOFT &&
|
|
|
|
|
stream->frame_phase == CIF_CSI_FRAME1_READY) {
|
|
|
|
|
if (channel->capture_info.mode == RKMODULE_MULTI_DEV_COMBINE_ONE) {
|
|
|
|
|
rkcif_write_buff_addr_multi_dev_combine(stream,
|
|
|
|
|
@@ -3042,7 +3055,8 @@ static void rkcif_assign_new_buffer_init_rockit(struct rkcif_stream *stream,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (stream->cif_fmt_in->field == V4L2_FIELD_INTERLACED) {
|
|
|
|
|
if (rkcif_get_interlace_mode(stream) == RKCIF_INTERLACE_SOFT ||
|
|
|
|
|
rkcif_get_interlace_mode(stream) == RKCIF_INTERLACE_SOFT_AUTO) {
|
|
|
|
|
stream->next_buf_rockit = stream->curr_buf_rockit;
|
|
|
|
|
if (stream->next_buf_rockit) {
|
|
|
|
|
rkcif_write_register(dev, frm1_addr_y,
|
|
|
|
|
@@ -3152,7 +3166,8 @@ static int rkcif_assign_new_buffer_update_rockit(struct rkcif_stream *stream,
|
|
|
|
|
|
|
|
|
|
if (!dummy_buf->vaddr &&
|
|
|
|
|
stream->curr_buf_rockit == stream->next_buf_rockit &&
|
|
|
|
|
stream->cif_fmt_in->field != V4L2_FIELD_INTERLACED)
|
|
|
|
|
(rkcif_get_interlace_mode(stream) != RKCIF_INTERLACE_SOFT ||
|
|
|
|
|
rkcif_get_interlace_mode(stream) == RKCIF_INTERLACE_SOFT_AUTO))
|
|
|
|
|
ret = -EINVAL;
|
|
|
|
|
|
|
|
|
|
if (stream->frame_phase == CIF_CSI_FRAME0_READY) {
|
|
|
|
|
@@ -3167,7 +3182,8 @@ static int rkcif_assign_new_buffer_update_rockit(struct rkcif_stream *stream,
|
|
|
|
|
} else if (stream->frame_phase == CIF_CSI_FRAME1_READY) {
|
|
|
|
|
if (!stream->next_buf_rockit)
|
|
|
|
|
ret = -EINVAL;
|
|
|
|
|
if (stream->cif_fmt_in->field == V4L2_FIELD_INTERLACED) {
|
|
|
|
|
if (rkcif_get_interlace_mode(stream) == RKCIF_INTERLACE_SOFT ||
|
|
|
|
|
rkcif_get_interlace_mode(stream) == RKCIF_INTERLACE_SOFT_AUTO) {
|
|
|
|
|
if (stream->next_buf_rockit != stream->curr_buf_rockit) {
|
|
|
|
|
stream->next_buf_rockit = stream->curr_buf_rockit;
|
|
|
|
|
buffer = stream->next_buf_rockit;
|
|
|
|
|
@@ -3190,7 +3206,8 @@ static int rkcif_assign_new_buffer_update_rockit(struct rkcif_stream *stream,
|
|
|
|
|
if (stream->frame_phase == CIF_CSI_FRAME0_READY) {
|
|
|
|
|
stream->curr_buf_rockit = NULL;
|
|
|
|
|
} else if (stream->frame_phase == CIF_CSI_FRAME1_READY) {
|
|
|
|
|
if (stream->cif_fmt_in->field == V4L2_FIELD_INTERLACED) {
|
|
|
|
|
if (rkcif_get_interlace_mode(stream) == RKCIF_INTERLACE_SOFT ||
|
|
|
|
|
rkcif_get_interlace_mode(stream) == RKCIF_INTERLACE_SOFT_AUTO) {
|
|
|
|
|
stream->next_buf_rockit = stream->curr_buf_rockit;
|
|
|
|
|
buffer = stream->next_buf_rockit;
|
|
|
|
|
} else {
|
|
|
|
|
@@ -3216,7 +3233,8 @@ static int rkcif_assign_new_buffer_update_rockit(struct rkcif_stream *stream,
|
|
|
|
|
stream->frame_phase_cache = stream->frame_phase;
|
|
|
|
|
|
|
|
|
|
if (buffer) {
|
|
|
|
|
if (stream->cif_fmt_in->field == V4L2_FIELD_INTERLACED &&
|
|
|
|
|
if ((rkcif_get_interlace_mode(stream) == RKCIF_INTERLACE_SOFT ||
|
|
|
|
|
rkcif_get_interlace_mode(stream) == RKCIF_INTERLACE_SOFT_AUTO) &&
|
|
|
|
|
stream->frame_phase == CIF_CSI_FRAME1_READY) {
|
|
|
|
|
rkcif_write_register(dev, frm_addr_y,
|
|
|
|
|
buffer->buff_addr[RKCIF_PLANE_Y] + (channel->virtual_width / 2));
|
|
|
|
|
@@ -3441,7 +3459,8 @@ static int rkcif_csi_channel_init(struct rkcif_stream *stream,
|
|
|
|
|
if (channel->capture_info.mode == RKMODULE_MULTI_DEV_COMBINE_ONE)
|
|
|
|
|
channel->left_virtual_width *= 2;
|
|
|
|
|
}
|
|
|
|
|
if (stream->cif_fmt_in->field == V4L2_FIELD_INTERLACED) {
|
|
|
|
|
if (rkcif_get_interlace_mode(stream) == RKCIF_INTERLACE_SOFT ||
|
|
|
|
|
rkcif_get_interlace_mode(stream) == RKCIF_INTERLACE_SOFT_AUTO) {
|
|
|
|
|
channel->virtual_width *= 2;
|
|
|
|
|
channel->height /= 2;
|
|
|
|
|
}
|
|
|
|
|
@@ -3474,6 +3493,73 @@ static int rkcif_csi_channel_init(struct rkcif_stream *stream,
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void rkcif_write_buffer(struct rkcif_stream *stream, struct rkcif_buffer *buffer,
|
|
|
|
|
int frame_phase, int even_offset)
|
|
|
|
|
{
|
|
|
|
|
struct rkcif_device *dev = stream->cifdev;
|
|
|
|
|
struct rkcif_dummy_buffer *dummy_buf = &dev->hw_dev->dummy_buf;
|
|
|
|
|
u32 frm_addr_y, frm_addr_uv;
|
|
|
|
|
struct csi_channel_info *channel = &dev->channels[stream->id];
|
|
|
|
|
|
|
|
|
|
if (frame_phase == CIF_CSI_FRAME0_READY) {
|
|
|
|
|
frm_addr_y = get_reg_index_of_frm0_y_addr(stream->id);
|
|
|
|
|
frm_addr_uv = get_reg_index_of_frm0_uv_addr(stream->id);
|
|
|
|
|
} else {
|
|
|
|
|
frm_addr_y = get_reg_index_of_frm1_y_addr(stream->id);
|
|
|
|
|
frm_addr_uv = get_reg_index_of_frm1_uv_addr(stream->id);
|
|
|
|
|
}
|
|
|
|
|
if (buffer) {
|
|
|
|
|
rkcif_write_register(dev, frm_addr_y,
|
|
|
|
|
buffer->buff_addr[RKCIF_PLANE_Y] + even_offset *
|
|
|
|
|
(channel->virtual_width / 2));
|
|
|
|
|
if (stream->cif_fmt_out->fmt_type != CIF_FMT_TYPE_RAW)
|
|
|
|
|
rkcif_write_register(dev, frm_addr_uv,
|
|
|
|
|
buffer->buff_addr[RKCIF_PLANE_CBCR] +
|
|
|
|
|
even_offset * (channel->virtual_width / 2));
|
|
|
|
|
} else if (dummy_buf->vaddr) {
|
|
|
|
|
rkcif_write_register(dev, frm_addr_y, dummy_buf->dma_addr);
|
|
|
|
|
if (stream->cif_fmt_out->fmt_type != CIF_FMT_TYPE_RAW)
|
|
|
|
|
rkcif_write_register(dev, frm_addr_uv, dummy_buf->dma_addr);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void rkcif_buf_init_interlace(struct rkcif_stream *stream, int channel_id)
|
|
|
|
|
{
|
|
|
|
|
struct rkcif_device *dev = stream->cifdev;
|
|
|
|
|
unsigned long flags;
|
|
|
|
|
struct rkcif_dummy_buffer *dummy_buf = &dev->hw_dev->dummy_buf;
|
|
|
|
|
int buf_offset = 0;
|
|
|
|
|
|
|
|
|
|
spin_lock_irqsave(&stream->vbq_lock, flags);
|
|
|
|
|
if (!stream->curr_buf) {
|
|
|
|
|
if (!list_empty(&stream->buf_head)) {
|
|
|
|
|
stream->curr_buf = list_first_entry(&stream->buf_head,
|
|
|
|
|
struct rkcif_buffer,
|
|
|
|
|
queue);
|
|
|
|
|
list_del(&stream->curr_buf->queue);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
spin_unlock_irqrestore(&stream->vbq_lock, flags);
|
|
|
|
|
|
|
|
|
|
if (!stream->odd_frame_first)
|
|
|
|
|
buf_offset = 1;
|
|
|
|
|
|
|
|
|
|
if (stream->curr_buf) {
|
|
|
|
|
rkcif_write_buffer(stream, stream->curr_buf, CIF_CSI_FRAME0_READY, buf_offset);
|
|
|
|
|
rkcif_write_buffer(stream, stream->curr_buf, CIF_CSI_FRAME1_READY, buf_offset);
|
|
|
|
|
} else {
|
|
|
|
|
if (dummy_buf->vaddr) {
|
|
|
|
|
rkcif_write_buffer(stream, NULL, CIF_CSI_FRAME0_READY, 0);
|
|
|
|
|
rkcif_write_buffer(stream, NULL, CIF_CSI_FRAME1_READY, 0);
|
|
|
|
|
} else {
|
|
|
|
|
v4l2_err(&dev->v4l2_dev,
|
|
|
|
|
"stream[%d] mipi interlace not buf, if cap_en, may cause system death\n",
|
|
|
|
|
stream->id);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int rkcif_csi_channel_set(struct rkcif_stream *stream,
|
|
|
|
|
struct csi_channel_info *channel,
|
|
|
|
|
enum v4l2_mbus_type mbus_type)
|
|
|
|
|
@@ -3557,7 +3643,10 @@ static int rkcif_csi_channel_set(struct rkcif_stream *stream,
|
|
|
|
|
channel->crop_st_y << 16 | channel->crop_st_x);
|
|
|
|
|
|
|
|
|
|
/* Set up an buffer for the next frame */
|
|
|
|
|
rkcif_assign_new_buffer_pingpong(stream,
|
|
|
|
|
if (rkcif_get_interlace_mode(stream) == RKCIF_INTERLACE_SOFT_AUTO)
|
|
|
|
|
rkcif_buf_init_interlace(stream, channel->id);
|
|
|
|
|
else
|
|
|
|
|
rkcif_assign_new_buffer_pingpong(stream,
|
|
|
|
|
RKCIF_YUV_ADDR_STATE_INIT,
|
|
|
|
|
channel->id);
|
|
|
|
|
|
|
|
|
|
@@ -3875,19 +3964,23 @@ static int rkcif_csi_channel_set_v1(struct rkcif_stream *stream,
|
|
|
|
|
rkcif_write_register(dev, get_reg_index_of_id_crop_start(channel->id),
|
|
|
|
|
channel->crop_st_y << 16 | channel->crop_st_x);
|
|
|
|
|
|
|
|
|
|
if (mode == RKCIF_STREAM_MODE_CAPTURE)
|
|
|
|
|
rkcif_assign_new_buffer_pingpong(stream,
|
|
|
|
|
RKCIF_YUV_ADDR_STATE_INIT,
|
|
|
|
|
channel->id);
|
|
|
|
|
else if (mode == RKCIF_STREAM_MODE_TOISP ||
|
|
|
|
|
mode == RKCIF_STREAM_MODE_TOISP_RDBK)
|
|
|
|
|
if (mode == RKCIF_STREAM_MODE_CAPTURE) {
|
|
|
|
|
if (rkcif_get_interlace_mode(stream) == RKCIF_INTERLACE_SOFT_AUTO)
|
|
|
|
|
rkcif_buf_init_interlace(stream, channel->id);
|
|
|
|
|
else
|
|
|
|
|
rkcif_assign_new_buffer_pingpong(stream,
|
|
|
|
|
RKCIF_YUV_ADDR_STATE_INIT,
|
|
|
|
|
channel->id);
|
|
|
|
|
} else if (mode == RKCIF_STREAM_MODE_TOISP ||
|
|
|
|
|
mode == RKCIF_STREAM_MODE_TOISP_RDBK) {
|
|
|
|
|
rkcif_assign_new_buffer_pingpong_toisp(stream,
|
|
|
|
|
RKCIF_YUV_ADDR_STATE_INIT,
|
|
|
|
|
channel->id);
|
|
|
|
|
else if (mode == RKCIF_STREAM_MODE_ROCKIT)
|
|
|
|
|
} else if (mode == RKCIF_STREAM_MODE_ROCKIT) {
|
|
|
|
|
rkcif_assign_new_buffer_pingpong_rockit(stream,
|
|
|
|
|
RKCIF_YUV_ADDR_STATE_INIT,
|
|
|
|
|
channel->id);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (capture_info->mode == RKMODULE_MULTI_DEV_COMBINE_ONE &&
|
|
|
|
|
index == (capture_info->multi_dev.dev_num - 1) &&
|
|
|
|
|
@@ -4000,6 +4093,9 @@ static int rkcif_csi_stream_start(struct rkcif_stream *stream, unsigned int mode
|
|
|
|
|
stream->is_in_vblank = false;
|
|
|
|
|
stream->is_change_toisp = false;
|
|
|
|
|
}
|
|
|
|
|
stream->interlaced_bad_frame = false;
|
|
|
|
|
stream->last_fs_interlaced_phase = 0;
|
|
|
|
|
stream->last_fe_interlaced_phase = 0;
|
|
|
|
|
|
|
|
|
|
channel = &dev->channels[stream->id];
|
|
|
|
|
channel->id = stream->id;
|
|
|
|
|
@@ -4235,7 +4331,6 @@ static void rkcif_check_buffer_update_pingpong(struct rkcif_stream *stream,
|
|
|
|
|
struct rkcif_device *dev = stream->cifdev;
|
|
|
|
|
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 = 0, frm_addr_uv = 0;
|
|
|
|
|
u32 frm0_addr_y = 0, frm0_addr_uv = 0;
|
|
|
|
|
u32 frm1_addr_y = 0, frm1_addr_uv = 0;
|
|
|
|
|
@@ -4245,13 +4340,15 @@ static void rkcif_check_buffer_update_pingpong(struct rkcif_stream *stream,
|
|
|
|
|
int frame_phase = 0;
|
|
|
|
|
bool is_dual_update_buf = false;
|
|
|
|
|
|
|
|
|
|
if (stream->state != RKCIF_STATE_STREAMING ||
|
|
|
|
|
rkcif_get_interlace_mode(stream) == RKCIF_INTERLACE_SOFT ||
|
|
|
|
|
rkcif_get_interlace_mode(stream) == RKCIF_INTERLACE_SOFT_AUTO)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
spin_lock_irqsave(&stream->vbq_lock, flags);
|
|
|
|
|
if (stream->state == RKCIF_STATE_STREAMING &&
|
|
|
|
|
((stream->curr_buf == stream->next_buf &&
|
|
|
|
|
stream->cif_fmt_in->field != V4L2_FIELD_INTERLACED &&
|
|
|
|
|
(!dummy_buf->vaddr)) ||
|
|
|
|
|
stream->curr_buf == NULL ||
|
|
|
|
|
stream->next_buf == NULL)) {
|
|
|
|
|
if (stream->curr_buf == stream->next_buf ||
|
|
|
|
|
stream->curr_buf == NULL ||
|
|
|
|
|
stream->next_buf == NULL) {
|
|
|
|
|
frame_phase = stream->frame_phase_cache;
|
|
|
|
|
if (!stream->is_line_wake_up ||
|
|
|
|
|
(stream->is_line_wake_up && stream->frame_idx < 2)) {
|
|
|
|
|
@@ -4288,19 +4385,14 @@ static void rkcif_check_buffer_update_pingpong(struct rkcif_stream *stream,
|
|
|
|
|
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) {
|
|
|
|
|
stream->next_buf = stream->curr_buf;
|
|
|
|
|
} else {
|
|
|
|
|
stream->next_buf = list_first_entry(&stream->buf_head,
|
|
|
|
|
struct rkcif_buffer, queue);
|
|
|
|
|
if (stream->next_buf) {
|
|
|
|
|
list_del(&stream->next_buf->queue);
|
|
|
|
|
buffer = stream->next_buf;
|
|
|
|
|
}
|
|
|
|
|
if (buffer && is_dual_update_buf)
|
|
|
|
|
stream->curr_buf = buffer;
|
|
|
|
|
stream->next_buf = list_first_entry(&stream->buf_head,
|
|
|
|
|
struct rkcif_buffer, queue);
|
|
|
|
|
if (stream->next_buf) {
|
|
|
|
|
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__);
|
|
|
|
|
@@ -8703,7 +8795,8 @@ static void rkcif_buf_done_prepare(struct rkcif_stream *stream,
|
|
|
|
|
stream->readout.wk_timestamp = vb_done->vb2_buf.timestamp;
|
|
|
|
|
spin_unlock_irqrestore(&stream->fps_lock, flags);
|
|
|
|
|
}
|
|
|
|
|
if (stream->cif_fmt_in->field == V4L2_FIELD_INTERLACED)
|
|
|
|
|
if (rkcif_get_interlace_mode(stream) == RKCIF_INTERLACE_SOFT ||
|
|
|
|
|
rkcif_get_interlace_mode(stream) == RKCIF_INTERLACE_SOFT_AUTO)
|
|
|
|
|
vb_done->sequence /= 2;
|
|
|
|
|
if (stream->cur_skip_frame) {
|
|
|
|
|
rkcif_buf_queue(&active_buf->vb.vb2_buf);
|
|
|
|
|
@@ -8721,9 +8814,9 @@ static void rkcif_buf_done_prepare(struct rkcif_stream *stream,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (cif_dev->hdr.hdr_mode == NO_HDR || cif_dev->hdr.hdr_mode == HDR_COMPR) {
|
|
|
|
|
if (stream->cif_fmt_in->field == V4L2_FIELD_INTERLACED) {
|
|
|
|
|
if (rkcif_get_interlace_mode(stream) == RKCIF_INTERLACE_SOFT ||
|
|
|
|
|
rkcif_get_interlace_mode(stream) == RKCIF_INTERLACE_SOFT_AUTO) {
|
|
|
|
|
if (stream->frame_phase == CIF_CSI_FRAME1_READY && active_buf) {
|
|
|
|
|
|
|
|
|
|
if (cif_dev->is_support_tools && stream->tools_vdev)
|
|
|
|
|
rkcif_buf_done_with_tools(stream, active_buf);
|
|
|
|
|
else
|
|
|
|
|
@@ -8803,6 +8896,69 @@ static void rkcif_buf_done_prepare(struct rkcif_stream *stream,
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void rkcif_line_wake_up_interlace(struct rkcif_stream *stream,
|
|
|
|
|
int mipi_id)
|
|
|
|
|
{
|
|
|
|
|
struct rkcif_device *cif_dev = stream->cifdev;
|
|
|
|
|
struct rkcif_buffer *active_buf = NULL;
|
|
|
|
|
struct rkcif_dummy_buffer *dummy_buf = &cif_dev->hw_dev->dummy_buf;
|
|
|
|
|
int frame_id = 0;
|
|
|
|
|
int fe_interlaced_phase = 0;
|
|
|
|
|
|
|
|
|
|
if (stream->id == 0)
|
|
|
|
|
frame_id = rkcif_read_register(cif_dev, CIF_REG_MIPI_FRAME_NUM_VC0);
|
|
|
|
|
else if (stream->id == 1)
|
|
|
|
|
frame_id = rkcif_read_register(cif_dev, CIF_REG_MIPI_FRAME_NUM_VC1);
|
|
|
|
|
else if (stream->id == 2)
|
|
|
|
|
frame_id = rkcif_read_register(cif_dev, CIF_REG_MIPI_FRAME_NUM_VC2);
|
|
|
|
|
else if (stream->id == 3)
|
|
|
|
|
frame_id = rkcif_read_register(cif_dev, CIF_REG_MIPI_FRAME_NUM_VC3);
|
|
|
|
|
|
|
|
|
|
if ((frame_id & 0xffff) % 2 == stream->odd_frame_id) {
|
|
|
|
|
//odd frame
|
|
|
|
|
if (stream->odd_frame_first)
|
|
|
|
|
fe_interlaced_phase = CIF_CSI_FRAME0_READY;
|
|
|
|
|
else
|
|
|
|
|
fe_interlaced_phase = CIF_CSI_FRAME1_READY;
|
|
|
|
|
} else {
|
|
|
|
|
//even frame
|
|
|
|
|
if (stream->odd_frame_first)
|
|
|
|
|
fe_interlaced_phase = CIF_CSI_FRAME1_READY;
|
|
|
|
|
else
|
|
|
|
|
fe_interlaced_phase = CIF_CSI_FRAME0_READY;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
v4l2_dbg(rkcif_debug, 3, &cif_dev->v4l2_dev,
|
|
|
|
|
"stream[%d] mipi fe interlace phase %d, frame num 0x%x\n",
|
|
|
|
|
stream->id, fe_interlaced_phase, frame_id);
|
|
|
|
|
|
|
|
|
|
if (fe_interlaced_phase == CIF_CSI_FRAME1_READY &&
|
|
|
|
|
stream->last_fe_interlaced_phase == CIF_CSI_FRAME0_READY) {
|
|
|
|
|
if (dummy_buf->vaddr || stream->next_buf) {
|
|
|
|
|
active_buf = stream->curr_buf;
|
|
|
|
|
if (active_buf) {
|
|
|
|
|
active_buf->vb.vb2_buf.timestamp = stream->readout.fs_timestamp;
|
|
|
|
|
active_buf->vb.sequence = (stream->frame_idx - 1) / 2;
|
|
|
|
|
if (stream->interlaced_bad_frame) {
|
|
|
|
|
stream->interlaced_bad_frame = false;
|
|
|
|
|
rkcif_buf_queue(&active_buf->vb.vb2_buf);
|
|
|
|
|
v4l2_dbg(rkcif_debug, 3, &cif_dev->v4l2_dev,
|
|
|
|
|
"stream[%d] mipi fe interlace bad frame queue, phase %d, line %d\n",
|
|
|
|
|
stream->id, fe_interlaced_phase, __LINE__);
|
|
|
|
|
} else {
|
|
|
|
|
rkcif_vb_done_tasklet(stream, active_buf);
|
|
|
|
|
}
|
|
|
|
|
stream->curr_buf = stream->next_buf;
|
|
|
|
|
stream->next_buf = NULL;
|
|
|
|
|
} else {
|
|
|
|
|
stream->curr_buf = stream->next_buf;
|
|
|
|
|
stream->next_buf = NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
stream->last_fe_interlaced_phase = fe_interlaced_phase;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void rkcif_line_wake_up(struct rkcif_stream *stream, int mipi_id)
|
|
|
|
|
{
|
|
|
|
|
u32 mode;
|
|
|
|
|
@@ -8984,6 +9140,82 @@ static void rkcif_deal_readout_time(struct rkcif_stream *stream)
|
|
|
|
|
spin_unlock_irqrestore(&stream->fps_lock, flags);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void rkcif_update_stream_interlace(struct rkcif_device *cif_dev,
|
|
|
|
|
struct rkcif_stream *stream,
|
|
|
|
|
int mipi_id)
|
|
|
|
|
{
|
|
|
|
|
struct rkcif_buffer *active_buf = NULL;
|
|
|
|
|
struct rkcif_dummy_buffer *dummy_buf = &cif_dev->hw_dev->dummy_buf;
|
|
|
|
|
unsigned long flags;
|
|
|
|
|
int frame_id = 0;
|
|
|
|
|
int fe_interlaced_phase = 0;
|
|
|
|
|
|
|
|
|
|
if (stream->id == 0)
|
|
|
|
|
frame_id = rkcif_read_register(cif_dev, CIF_REG_MIPI_FRAME_NUM_VC0);
|
|
|
|
|
else if (stream->id == 1)
|
|
|
|
|
frame_id = rkcif_read_register(cif_dev, CIF_REG_MIPI_FRAME_NUM_VC1);
|
|
|
|
|
else if (stream->id == 2)
|
|
|
|
|
frame_id = rkcif_read_register(cif_dev, CIF_REG_MIPI_FRAME_NUM_VC2);
|
|
|
|
|
else if (stream->id == 3)
|
|
|
|
|
frame_id = rkcif_read_register(cif_dev, CIF_REG_MIPI_FRAME_NUM_VC3);
|
|
|
|
|
|
|
|
|
|
if ((frame_id & 0xffff) % 2 == stream->odd_frame_id) {
|
|
|
|
|
//odd frame
|
|
|
|
|
if (stream->odd_frame_first)
|
|
|
|
|
fe_interlaced_phase = CIF_CSI_FRAME0_READY;
|
|
|
|
|
else
|
|
|
|
|
fe_interlaced_phase = CIF_CSI_FRAME1_READY;
|
|
|
|
|
} else {
|
|
|
|
|
//even frame
|
|
|
|
|
if (stream->odd_frame_first)
|
|
|
|
|
fe_interlaced_phase = CIF_CSI_FRAME1_READY;
|
|
|
|
|
else
|
|
|
|
|
fe_interlaced_phase = CIF_CSI_FRAME0_READY;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
v4l2_dbg(rkcif_debug, 3, &cif_dev->v4l2_dev,
|
|
|
|
|
"stream[%d] mipi fe interlace phase %d, frame num 0x%x\n",
|
|
|
|
|
stream->id, fe_interlaced_phase, frame_id);
|
|
|
|
|
|
|
|
|
|
if (!stream->is_line_wake_up) {
|
|
|
|
|
spin_lock_irqsave(&stream->fps_lock, flags);
|
|
|
|
|
if (stream->frame_phase & CIF_CSI_FRAME0_READY)
|
|
|
|
|
stream->fps_stats.frm0_timestamp = ktime_get_ns();
|
|
|
|
|
else if (stream->frame_phase & CIF_CSI_FRAME1_READY)
|
|
|
|
|
stream->fps_stats.frm1_timestamp = ktime_get_ns();
|
|
|
|
|
spin_unlock_irqrestore(&stream->fps_lock, flags);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!stream->is_line_wake_up) {
|
|
|
|
|
if (fe_interlaced_phase == CIF_CSI_FRAME1_READY &&
|
|
|
|
|
stream->last_fe_interlaced_phase == CIF_CSI_FRAME0_READY) {
|
|
|
|
|
if (dummy_buf->vaddr || stream->next_buf) {
|
|
|
|
|
active_buf = stream->curr_buf;
|
|
|
|
|
if (active_buf) {
|
|
|
|
|
active_buf->vb.vb2_buf.timestamp = stream->readout.fs_timestamp;
|
|
|
|
|
active_buf->vb.sequence = (stream->frame_idx - 1) / 2;
|
|
|
|
|
if (stream->interlaced_bad_frame) {
|
|
|
|
|
stream->interlaced_bad_frame = false;
|
|
|
|
|
rkcif_buf_queue(&active_buf->vb.vb2_buf);
|
|
|
|
|
v4l2_dbg(rkcif_debug, 3, &cif_dev->v4l2_dev,
|
|
|
|
|
"stream[%d] mipi fe interlace bad frame queue, phase %d, line %d\n",
|
|
|
|
|
stream->id, fe_interlaced_phase, __LINE__);
|
|
|
|
|
} else {
|
|
|
|
|
rkcif_vb_done_tasklet(stream, active_buf);
|
|
|
|
|
}
|
|
|
|
|
stream->curr_buf = stream->next_buf;
|
|
|
|
|
stream->next_buf = NULL;
|
|
|
|
|
} else {
|
|
|
|
|
stream->curr_buf = stream->next_buf;
|
|
|
|
|
stream->next_buf = NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
rkcif_deal_readout_time(stream);
|
|
|
|
|
stream->last_fe_interlaced_phase = fe_interlaced_phase;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void rkcif_update_stream(struct rkcif_device *cif_dev,
|
|
|
|
|
struct rkcif_stream *stream,
|
|
|
|
|
int mipi_id)
|
|
|
|
|
@@ -9267,7 +9499,8 @@ static int rkcif_do_reset_work(struct rkcif_device *cif_dev,
|
|
|
|
|
for (i = 0; i < j; i++) {
|
|
|
|
|
stream = resume_stream[i];
|
|
|
|
|
stream->fs_cnt_in_single_frame = 0;
|
|
|
|
|
if (stream->cif_fmt_in->field == V4L2_FIELD_INTERLACED) {
|
|
|
|
|
if (rkcif_get_interlace_mode(stream) == RKCIF_INTERLACE_SOFT ||
|
|
|
|
|
rkcif_get_interlace_mode(stream) == RKCIF_INTERLACE_SOFT_AUTO) {
|
|
|
|
|
if (stream->curr_buf == stream->next_buf) {
|
|
|
|
|
if (stream->curr_buf)
|
|
|
|
|
list_add_tail(&stream->curr_buf->queue, &stream->buf_head);
|
|
|
|
|
@@ -10709,7 +10942,8 @@ int rkcif_stream_resume(struct rkcif_device *cif_dev, int mode)
|
|
|
|
|
stream->is_single_cap = true;
|
|
|
|
|
spin_lock_irqsave(&stream->vbq_lock, flags);
|
|
|
|
|
if (!priv || priv->mode.rdbk_mode == RKISP_VICAP_RDBK_AIQ) {
|
|
|
|
|
if (stream->cif_fmt_in->field == V4L2_FIELD_INTERLACED) {
|
|
|
|
|
if (rkcif_get_interlace_mode(stream) == RKCIF_INTERLACE_SOFT ||
|
|
|
|
|
rkcif_get_interlace_mode(stream) == RKCIF_INTERLACE_SOFT_AUTO) {
|
|
|
|
|
if (stream->curr_buf == stream->next_buf) {
|
|
|
|
|
if (stream->curr_buf)
|
|
|
|
|
list_add_tail(&stream->curr_buf->queue, &stream->buf_head);
|
|
|
|
|
@@ -10921,6 +11155,151 @@ void rkcif_err_print_work(struct work_struct *work)
|
|
|
|
|
intstat, lastline);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void rkcif_check_mipi_interlaced_frame_id(struct rkcif_stream *stream)
|
|
|
|
|
{
|
|
|
|
|
struct rkcif_device *dev = stream->cifdev;
|
|
|
|
|
struct rkcif_buffer *buffer = NULL;
|
|
|
|
|
struct rkcif_dummy_buffer *dummy_buf = &dev->hw_dev->dummy_buf;
|
|
|
|
|
int frame_id = 0;
|
|
|
|
|
int fs_interlaced_phase = 0;
|
|
|
|
|
unsigned long flags;
|
|
|
|
|
int buf_offset = 0;
|
|
|
|
|
|
|
|
|
|
if (stream->id == 0)
|
|
|
|
|
frame_id = rkcif_read_register(dev, CIF_REG_MIPI_FRAME_NUM_VC0);
|
|
|
|
|
else if (stream->id == 1)
|
|
|
|
|
frame_id = rkcif_read_register(dev, CIF_REG_MIPI_FRAME_NUM_VC1);
|
|
|
|
|
else if (stream->id == 2)
|
|
|
|
|
frame_id = rkcif_read_register(dev, CIF_REG_MIPI_FRAME_NUM_VC2);
|
|
|
|
|
else if (stream->id == 3)
|
|
|
|
|
frame_id = rkcif_read_register(dev, CIF_REG_MIPI_FRAME_NUM_VC3);
|
|
|
|
|
|
|
|
|
|
if ((frame_id & 0xffff) % 2 == stream->odd_frame_id) {
|
|
|
|
|
//odd frame
|
|
|
|
|
if (stream->odd_frame_first) {
|
|
|
|
|
fs_interlaced_phase = CIF_CSI_FRAME0_READY;
|
|
|
|
|
buf_offset = 1;
|
|
|
|
|
} else {
|
|
|
|
|
fs_interlaced_phase = CIF_CSI_FRAME1_READY;
|
|
|
|
|
buf_offset = 1;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
//even frame
|
|
|
|
|
if (stream->odd_frame_first) {
|
|
|
|
|
fs_interlaced_phase = CIF_CSI_FRAME1_READY;
|
|
|
|
|
buf_offset = 0;
|
|
|
|
|
} else {
|
|
|
|
|
fs_interlaced_phase = CIF_CSI_FRAME0_READY;
|
|
|
|
|
buf_offset = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
v4l2_dbg(rkcif_debug, 3, &dev->v4l2_dev,
|
|
|
|
|
"stream[%d] mipi fs interlace phase %d, frame num 0x%x\n",
|
|
|
|
|
stream->id, fs_interlaced_phase, frame_id);
|
|
|
|
|
if (stream->last_fs_interlaced_phase == 0) {
|
|
|
|
|
buffer = stream->curr_buf;
|
|
|
|
|
rkcif_write_buffer(stream, buffer, CIF_CSI_FRAME0_READY, buf_offset);
|
|
|
|
|
rkcif_write_buffer(stream, buffer, CIF_CSI_FRAME1_READY, buf_offset);
|
|
|
|
|
} else {
|
|
|
|
|
if (fs_interlaced_phase == CIF_CSI_FRAME0_READY) {
|
|
|
|
|
buffer = stream->curr_buf;
|
|
|
|
|
if (stream->last_fs_interlaced_phase == CIF_CSI_FRAME1_READY) {
|
|
|
|
|
if (stream->last_fe_interlaced_phase == CIF_CSI_FRAME0_READY) {
|
|
|
|
|
if (buffer)
|
|
|
|
|
rkcif_buf_queue(&buffer->vb.vb2_buf);
|
|
|
|
|
stream->curr_buf = stream->next_buf;
|
|
|
|
|
stream->next_buf = NULL;
|
|
|
|
|
buffer = stream->curr_buf;
|
|
|
|
|
stream->last_fe_interlaced_phase = CIF_CSI_FRAME1_READY;
|
|
|
|
|
v4l2_dbg(rkcif_debug, 3, &dev->v4l2_dev,
|
|
|
|
|
"stream[%d] mipi fs interlace bad frame queue, phase %d, line %d\n",
|
|
|
|
|
stream->id, fs_interlaced_phase, __LINE__);
|
|
|
|
|
}
|
|
|
|
|
rkcif_write_buffer(stream, buffer, CIF_CSI_FRAME0_READY, buf_offset);
|
|
|
|
|
rkcif_write_buffer(stream, buffer, CIF_CSI_FRAME1_READY, buf_offset);
|
|
|
|
|
} else if (stream->last_fs_interlaced_phase == CIF_CSI_FRAME0_READY) {
|
|
|
|
|
stream->interlaced_bad_frame = true;
|
|
|
|
|
rkcif_write_buffer(stream, buffer, CIF_CSI_FRAME0_READY, buf_offset);
|
|
|
|
|
rkcif_write_buffer(stream, buffer, CIF_CSI_FRAME1_READY, buf_offset);
|
|
|
|
|
v4l2_dbg(rkcif_debug, 3, &dev->v4l2_dev,
|
|
|
|
|
"stream[%d] mipi fs interlace bad frame, phase %d, line %d\n",
|
|
|
|
|
stream->id, fs_interlaced_phase, __LINE__);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if (stream->last_fs_interlaced_phase == CIF_CSI_FRAME0_READY) {
|
|
|
|
|
if (stream->next_buf) {
|
|
|
|
|
if (stream->curr_buf) {
|
|
|
|
|
rkcif_buf_queue(&stream->curr_buf->vb.vb2_buf);
|
|
|
|
|
stream->curr_buf = stream->next_buf;
|
|
|
|
|
stream->next_buf = NULL;
|
|
|
|
|
}
|
|
|
|
|
stream->interlaced_bad_frame = true;
|
|
|
|
|
v4l2_dbg(rkcif_debug, 3, &dev->v4l2_dev,
|
|
|
|
|
"stream[%d] mipi fs interlace bad frame, phase %d\n",
|
|
|
|
|
stream->id, fs_interlaced_phase);
|
|
|
|
|
}
|
|
|
|
|
spin_lock_irqsave(&stream->vbq_lock, flags);
|
|
|
|
|
if (!list_empty(&stream->buf_head)) {
|
|
|
|
|
buffer = list_first_entry(&stream->buf_head,
|
|
|
|
|
struct rkcif_buffer, queue);
|
|
|
|
|
list_del(&buffer->queue);
|
|
|
|
|
stream->next_buf = buffer;
|
|
|
|
|
}
|
|
|
|
|
spin_unlock_irqrestore(&stream->vbq_lock, flags);
|
|
|
|
|
if (buffer) {
|
|
|
|
|
rkcif_write_buffer(stream, buffer, CIF_CSI_FRAME0_READY, buf_offset);
|
|
|
|
|
rkcif_write_buffer(stream, buffer, CIF_CSI_FRAME1_READY, buf_offset);
|
|
|
|
|
} else if (dummy_buf->vaddr) {
|
|
|
|
|
stream->interlaced_bad_frame = true;
|
|
|
|
|
rkcif_write_buffer(stream, NULL, CIF_CSI_FRAME0_READY, buf_offset);
|
|
|
|
|
rkcif_write_buffer(stream, NULL, CIF_CSI_FRAME1_READY, buf_offset);
|
|
|
|
|
v4l2_dbg(rkcif_debug, 3, &dev->v4l2_dev,
|
|
|
|
|
"stream[%d] mipi interlace not buf, use dummy buf, line %d\n",
|
|
|
|
|
stream->id, __LINE__);
|
|
|
|
|
} else {
|
|
|
|
|
v4l2_dbg(rkcif_debug, 3, &dev->v4l2_dev,
|
|
|
|
|
"stream[%d] mipi interlace not buf, may overwrite buf, line %d\n",
|
|
|
|
|
stream->id, __LINE__);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if (stream->last_fe_interlaced_phase != CIF_CSI_FRAME1_READY) {
|
|
|
|
|
buffer = stream->curr_buf;
|
|
|
|
|
if (buffer)
|
|
|
|
|
rkcif_buf_queue(&buffer->vb.vb2_buf);
|
|
|
|
|
stream->curr_buf = stream->next_buf;
|
|
|
|
|
stream->next_buf = NULL;
|
|
|
|
|
stream->last_fe_interlaced_phase = CIF_CSI_FRAME1_READY;
|
|
|
|
|
v4l2_dbg(rkcif_debug, 3, &dev->v4l2_dev,
|
|
|
|
|
"stream[%d] mipi fs interlace bad frame queue, phase %d, line %d\n",
|
|
|
|
|
stream->id, fs_interlaced_phase, __LINE__);
|
|
|
|
|
}
|
|
|
|
|
if (stream->next_buf) {
|
|
|
|
|
buffer = stream->next_buf;
|
|
|
|
|
rkcif_write_buffer(stream, buffer, CIF_CSI_FRAME0_READY, buf_offset);
|
|
|
|
|
rkcif_write_buffer(stream, buffer, CIF_CSI_FRAME1_READY, buf_offset);
|
|
|
|
|
} else if (stream->curr_buf) {
|
|
|
|
|
buffer = stream->curr_buf;
|
|
|
|
|
rkcif_write_buffer(stream, buffer, CIF_CSI_FRAME0_READY, buf_offset);
|
|
|
|
|
rkcif_write_buffer(stream, buffer, CIF_CSI_FRAME1_READY, buf_offset);
|
|
|
|
|
} else if (dummy_buf->vaddr) {
|
|
|
|
|
rkcif_write_buffer(stream, NULL, CIF_CSI_FRAME0_READY, buf_offset);
|
|
|
|
|
rkcif_write_buffer(stream, NULL, CIF_CSI_FRAME1_READY, buf_offset);
|
|
|
|
|
stream->interlaced_bad_frame = true;
|
|
|
|
|
v4l2_dbg(rkcif_debug, 3, &dev->v4l2_dev,
|
|
|
|
|
"stream[%d] mipi interlace not buf, use dummy buf, line %d\n",
|
|
|
|
|
stream->id, __LINE__);
|
|
|
|
|
} else {
|
|
|
|
|
v4l2_dbg(rkcif_debug, 3, &dev->v4l2_dev,
|
|
|
|
|
"stream[%d] mipi interlace not buf, may overwrite buf, line %d\n",
|
|
|
|
|
stream->id, __LINE__);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
stream->last_fs_interlaced_phase = fs_interlaced_phase;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* pingpong irq for rk3588 and next */
|
|
|
|
|
void rkcif_irq_pingpong_v1(struct rkcif_device *cif_dev)
|
|
|
|
|
{
|
|
|
|
|
@@ -11068,8 +11447,12 @@ void rkcif_irq_pingpong_v1(struct rkcif_device *cif_dev)
|
|
|
|
|
v4l2_dbg(4, rkcif_debug, &cif_dev->v4l2_dev,
|
|
|
|
|
"dma capture by vicap, is_updata %d, group mode %d, dma_en %d\n",
|
|
|
|
|
is_update, cif_dev->sync_cfg.type, stream->dma_en);
|
|
|
|
|
if (is_update)
|
|
|
|
|
rkcif_update_stream(cif_dev, stream, mipi_id);
|
|
|
|
|
if (is_update) {
|
|
|
|
|
if (rkcif_get_interlace_mode(stream) == RKCIF_INTERLACE_SOFT_AUTO)
|
|
|
|
|
rkcif_update_stream_interlace(cif_dev, stream, mipi_id);
|
|
|
|
|
else
|
|
|
|
|
rkcif_update_stream(cif_dev, stream, mipi_id);
|
|
|
|
|
}
|
|
|
|
|
} else if (stream->dma_en & RKCIF_DMAEN_BY_ISP) {
|
|
|
|
|
v4l2_dbg(4, rkcif_debug, &cif_dev->v4l2_dev,
|
|
|
|
|
"dma capture by isp, dma_en 0x%x\n",
|
|
|
|
|
@@ -11173,6 +11556,8 @@ void rkcif_irq_pingpong_v1(struct rkcif_device *cif_dev)
|
|
|
|
|
if (stream->to_en_dma)
|
|
|
|
|
rkcif_enable_dma_capture(stream, false);
|
|
|
|
|
spin_unlock_irqrestore(&stream->vbq_lock, flags);
|
|
|
|
|
if (rkcif_get_interlace_mode(stream) == RKCIF_INTERLACE_SOFT_AUTO)
|
|
|
|
|
rkcif_check_mipi_interlaced_frame_id(stream);
|
|
|
|
|
}
|
|
|
|
|
if (intstat & CSI_LINE_INTSTAT_V1(i)) {
|
|
|
|
|
stream = &cif_dev->stream[i];
|
|
|
|
|
@@ -11186,6 +11571,8 @@ void rkcif_irq_pingpong_v1(struct rkcif_device *cif_dev)
|
|
|
|
|
if (cif_dev->sditf[0] && (cif_dev->sditf[0]->mode.rdbk_mode == RKISP_VICAP_RDBK_AUTO ||
|
|
|
|
|
cif_dev->sditf[0]->mode.rdbk_mode == RKISP_VICAP_RDBK_AUTO_ONE_FRAME))
|
|
|
|
|
rkcif_line_wake_up_rdbk(stream, stream->id);
|
|
|
|
|
else if (rkcif_get_interlace_mode(stream) == RKCIF_INTERLACE_SOFT_AUTO)
|
|
|
|
|
rkcif_line_wake_up_interlace(stream, stream->id);
|
|
|
|
|
else
|
|
|
|
|
rkcif_line_wake_up(stream, stream->id);
|
|
|
|
|
rkcif_modify_line_int(stream, false);
|
|
|
|
|
@@ -11388,7 +11775,10 @@ void rkcif_irq_pingpong(struct rkcif_device *cif_dev)
|
|
|
|
|
if (stream->crop_dyn_en)
|
|
|
|
|
rkcif_dynamic_crop(stream);
|
|
|
|
|
|
|
|
|
|
rkcif_update_stream(cif_dev, stream, mipi_id);
|
|
|
|
|
if (rkcif_get_interlace_mode(stream) == RKCIF_INTERLACE_SOFT_AUTO)
|
|
|
|
|
rkcif_update_stream_interlace(cif_dev, stream, mipi_id);
|
|
|
|
|
else
|
|
|
|
|
rkcif_update_stream(cif_dev, stream, mipi_id);
|
|
|
|
|
rkcif_detect_wake_up_mode_change(stream);
|
|
|
|
|
rkcif_monitor_reset_event(cif_dev);
|
|
|
|
|
if (mipi_id == RKCIF_STREAM_MIPI_ID0) {
|
|
|
|
|
@@ -11416,12 +11806,17 @@ void rkcif_irq_pingpong(struct rkcif_device *cif_dev)
|
|
|
|
|
spin_unlock_irqrestore(&stream->fps_lock, flags);
|
|
|
|
|
}
|
|
|
|
|
stream->is_in_vblank = false;
|
|
|
|
|
if (rkcif_get_interlace_mode(stream) == RKCIF_INTERLACE_SOFT_AUTO)
|
|
|
|
|
rkcif_check_mipi_interlaced_frame_id(stream);
|
|
|
|
|
}
|
|
|
|
|
if (intstat & CSI_LINE_INTSTAT(i)) {
|
|
|
|
|
stream = &cif_dev->stream[i];
|
|
|
|
|
if (stream->is_line_inten) {
|
|
|
|
|
stream->line_int_cnt++;
|
|
|
|
|
rkcif_line_wake_up(stream, stream->id);
|
|
|
|
|
if (rkcif_get_interlace_mode(stream) == RKCIF_INTERLACE_SOFT_AUTO)
|
|
|
|
|
rkcif_line_wake_up_interlace(stream, stream->id);
|
|
|
|
|
else
|
|
|
|
|
rkcif_line_wake_up(stream, stream->id);
|
|
|
|
|
rkcif_modify_line_int(stream, false);
|
|
|
|
|
stream->is_line_inten = false;
|
|
|
|
|
}
|
|
|
|
|
|