media: platform: rockchip: cif: do reset when mipi fs & fe are not paired

Signed-off-by: Allon Huang <allon.huang@rock-chips.com>
Change-Id: If22316faffcdeb5a619d214eb8b650f300d1c41c
Signed-off-by: Zefa Chen <zefa.chen@rock-chips.com>
This commit is contained in:
Allon Huang
2021-05-14 13:13:15 +08:00
committed by Zefa Chen
parent 538055d4ed
commit f5cc594e92
3 changed files with 68 additions and 5 deletions

View File

@@ -2625,6 +2625,8 @@ static int rkcif_start_streaming(struct vb2_queue *queue, unsigned int count)
goto destroy_buf;
}
stream->fs_cnt_in_single_frame = 0;
if (dev->active_sensor) {
ret = rkcif_update_sensor_info(stream);
if (ret < 0) {
@@ -2990,6 +2992,8 @@ void rkcif_stream_init(struct rkcif_device *dev, u32 id)
stream->extend_line.is_extended = false;
stream->is_dvp_yuv_addr_init = false;
stream->is_fs_fe_not_paired = false;
stream->fs_cnt_in_single_frame = 0;
}
@@ -4180,6 +4184,7 @@ static bool rkcif_is_csi2_err_trigger_reset(struct rkcif_timer *timer)
struct rkcif_device *dev = container_of(timer,
struct rkcif_device,
reset_watchdog_timer);
struct rkcif_stream *stream = &dev->stream[RKCIF_STREAM_MIPI_ID0];
bool is_triggered = false;
unsigned long lock_flags;
@@ -4195,6 +4200,16 @@ static bool rkcif_is_csi2_err_trigger_reset(struct rkcif_timer *timer)
v4l2_info(&dev->v4l2_dev, "do csi2 err reset\n");
}
/*
* when fs cnt is beyond 2, it indicates that frame end is not coming,
* or fs and fe had been not paired.
*/
if (stream->is_fs_fe_not_paired ||
stream->fs_cnt_in_single_frame > RKCIF_FS_DETECTED_NUM) {
is_triggered = true;
v4l2_info(&dev->v4l2_dev, "reset for fs & fe not paired\n");
}
spin_unlock_irqrestore(&timer->csi2_err_lock, lock_flags);
return is_triggered;
@@ -4716,7 +4731,7 @@ static int rkcif_do_reset_work(struct rkcif_device *cif_dev,
struct rkcif_sensor_info *terminal_sensor = &cif_dev->terminal_sensor;
struct rkcif_resume_info *resume_info = &cif_dev->reset_work.resume_info;
int i, j, ret = 0;
u32 on;
u32 on, sof_cnt;
mutex_lock(&cif_dev->stream_lock);
@@ -4743,10 +4758,23 @@ static int rkcif_do_reset_work(struct rkcif_device *cif_dev,
stream->stopping = false;
}
if (stream->id == RKCIF_STREAM_MIPI_ID0)
resume_info->frm_sync_seq = rkcif_get_sof(cif_dev) + 1;
if (stream->id == RKCIF_STREAM_MIPI_ID0) {
sof_cnt = rkcif_get_sof(cif_dev);
v4l2_err(&cif_dev->v4l2_dev,
"%s: stream[%d] sync frmid & csi_sof, frm_id:%d, csi_sof:%d\n",
__func__,
stream->id,
stream->frame_idx,
sof_cnt);
resume_info->frm_sync_seq = sof_cnt;
if (stream->frame_idx != sof_cnt)
stream->frame_idx = sof_cnt;
}
stream->state = RKCIF_STATE_RESET_IN_STREAMING;
stream->is_fs_fe_not_paired = false;
stream->fs_cnt_in_single_frame = 0;
resume_stream[j] = stream;
j += 1;
@@ -4797,6 +4825,7 @@ static int rkcif_do_reset_work(struct rkcif_device *cif_dev,
}
for (i = 0; i < j; i++) {
resume_stream[i]->fs_cnt_in_single_frame = 0;
ret = rkcif_csi_stream_start(resume_stream[i]);
if (ret) {
v4l2_err(&cif_dev->v4l2_dev, "%s:resume stream[%d] failed\n",
@@ -5112,8 +5141,9 @@ int rkcif_reset_notifier(struct notifier_block *nb,
void rkcif_irq_pingpong(struct rkcif_device *cif_dev)
{
struct rkcif_stream *stream;
struct rkcif_stream *detect_stream = &cif_dev->stream[0];
struct v4l2_mbus_config *mbus;
unsigned int intstat, i = 0xff;
unsigned int intstat = 0x0, i = 0xff, bak_intstat = 0x0;
if (!cif_dev->active_sensor)
return;
@@ -5156,11 +5186,23 @@ void rkcif_irq_pingpong(struct rkcif_device *cif_dev)
return;
}
if ((intstat & (CSI_FRAME0_START_ID0 | CSI_FRAME1_START_ID0)) ==
(CSI_FRAME0_START_ID0 | CSI_FRAME1_START_ID0)) {
v4l2_err(&cif_dev->v4l2_dev, "%s:ERR: double fs in one fs int\n",
__func__);
}
if (intstat & CSI_FRAME0_START_ID0) {
if (mbus->type == V4L2_MBUS_CSI2)
rkcif_csi2_event_inc_sof();
else if (mbus->type == V4L2_MBUS_CCP2)
rkcif_lvds_event_inc_sof(cif_dev);
if (detect_stream->fs_cnt_in_single_frame >= 1)
v4l2_warn(&cif_dev->v4l2_dev,
"%s:warn: fs has been incread:%d(frm0)\n",
__func__, detect_stream->fs_cnt_in_single_frame);
detect_stream->fs_cnt_in_single_frame++;
}
if (intstat & CSI_FRAME1_START_ID0) {
@@ -5168,6 +5210,11 @@ void rkcif_irq_pingpong(struct rkcif_device *cif_dev)
rkcif_csi2_event_inc_sof();
else if (mbus->type == V4L2_MBUS_CCP2)
rkcif_lvds_event_inc_sof(cif_dev);
if (detect_stream->fs_cnt_in_single_frame >= 1)
v4l2_warn(&cif_dev->v4l2_dev, "%s:warn: fs has been incread:%d(frm1)\n",
__func__, detect_stream->fs_cnt_in_single_frame);
detect_stream->fs_cnt_in_single_frame++;
}
/* if do not reach frame dma end, return irq */
@@ -5217,6 +5264,19 @@ void rkcif_irq_pingpong(struct rkcif_device *cif_dev)
rkcif_update_stream(cif_dev, stream, mipi_id);
rkcif_monitor_reset_event(cif_dev);
if (stream->id == RKCIF_STREAM_MIPI_ID0 &&
(intstat & (CSI_FRAME1_START_ID0 | CSI_FRAME0_START_ID0)) == 0 &&
detect_stream->fs_cnt_in_single_frame > 1) {
v4l2_err(&cif_dev->v4l2_dev,
"%s ERR: multi fs in oneframe, bak_int:0x%x, fs_num:%d\n",
__func__,
bak_intstat,
detect_stream->fs_cnt_in_single_frame);
detect_stream->is_fs_fe_not_paired = true;
detect_stream->fs_cnt_in_single_frame = 0;
} else {
detect_stream->fs_cnt_in_single_frame--;
}
}
cif_dev->irq_stats.all_frm_end_cnt++;
} else {

View File

@@ -65,6 +65,7 @@
#define RKCIF_DEFAULT_WIDTH 640
#define RKCIF_DEFAULT_HEIGHT 480
#define RKCIF_FS_DETECTED_NUM 2
/*
* for HDR mode sync buf
@@ -415,6 +416,8 @@ struct rkcif_stream {
struct rkcif_fps_stats fps_stats;
struct rkcif_extend_info extend_line;
bool is_dvp_yuv_addr_init;
bool is_fs_fe_not_paired;
unsigned int fs_cnt_in_single_frame;
};
struct rkcif_lvds_subdev {

View File

@@ -93,7 +93,7 @@
_IOR('V', BASE_VIDIOC_PRIVATE + 15, struct rkmodule_vicap_reset_info)
#define RKMODULE_SET_VICAP_RST_INFO \
_IOR('V', BASE_VIDIOC_PRIVATE + 16, struct rkmodule_vicap_reset_info)
_IOW('V', BASE_VIDIOC_PRIVATE + 16, struct rkmodule_vicap_reset_info)
#define RKMODULE_GET_BT656_MBUS_INFO \
_IOR('V', BASE_VIDIOC_PRIVATE + 17, struct rkmodule_bt656_mbus_info)