From 7d73deedd31c9ac26c2ac6161844bf837f0ea5a2 Mon Sep 17 00:00:00 2001 From: Allon Huang Date: Wed, 26 May 2021 15:47:58 +0800 Subject: [PATCH] media: platform: rockchip: cif: add keeping time to csi2 err for resetting Signed-off-by: Allon Huang Change-Id: I0ecd5aad0a91553b8a978c23aceae8c5451892f5 Signed-off-by: Zefa Chen --- drivers/media/platform/rockchip/cif/capture.c | 41 ++++++++++++++++--- drivers/media/platform/rockchip/cif/dev.c | 2 + drivers/media/platform/rockchip/cif/dev.h | 4 +- drivers/media/platform/rockchip/cif/version.h | 1 + 4 files changed, 42 insertions(+), 6 deletions(-) diff --git a/drivers/media/platform/rockchip/cif/capture.c b/drivers/media/platform/rockchip/cif/capture.c index f8758af72d10..8e778eabe0be 100644 --- a/drivers/media/platform/rockchip/cif/capture.c +++ b/drivers/media/platform/rockchip/cif/capture.c @@ -4214,19 +4214,49 @@ static bool rkcif_is_csi2_err_trigger_reset(struct rkcif_timer *timer) struct rkcif_device, reset_watchdog_timer); struct rkcif_stream *stream = &dev->stream[RKCIF_STREAM_MIPI_ID0]; - - bool is_triggered = false; + bool is_triggered = false, is_assign_triggered = false, is_first_err = false; unsigned long flags; + u64 cur_time, diff_time; spin_lock_irqsave(&timer->csi2_err_lock, flags); if (timer->csi2_err_cnt_even != 0 && timer->csi2_err_cnt_odd != 0) { - is_triggered = true; timer->csi2_err_cnt_odd = 0; timer->csi2_err_cnt_even = 0; timer->reset_src = RKCIF_RESET_SRC_ERR_CSI2; - v4l2_info(&dev->v4l2_dev, "do csi2 err reset\n"); + timer->csi2_err_triggered_cnt++; + if (timer->csi2_err_triggered_cnt == 1) { + is_first_err = true; + timer->csi2_first_err_timestamp = ktime_get_ns(); + } + + is_assign_triggered = true; + + v4l2_info(&dev->v4l2_dev, + "find csi2 err cnt is:%d\n", + timer->csi2_err_triggered_cnt); + } + + if (!is_first_err) { + if (timer->csi2_err_triggered_cnt >= 1) { + cur_time = ktime_get_ns(); + diff_time = cur_time - timer->csi2_first_err_timestamp; + diff_time = div_u64(diff_time, 1000000); + if (diff_time >= timer->err_time_interval) { + is_triggered = true; + v4l2_info(&dev->v4l2_dev, "trigger reset for time out of csi err\n"); + goto end_judge; + } + + if (!is_assign_triggered && + (timer->csi2_err_cnt_odd == 0 || + timer->csi2_err_cnt_even == 0)) { + is_triggered = true; + v4l2_info(&dev->v4l2_dev, "trigger reset for csi err\n"); + goto end_judge; + } + } } /* @@ -4238,7 +4268,7 @@ static bool rkcif_is_csi2_err_trigger_reset(struct rkcif_timer *timer) is_triggered = true; v4l2_info(&dev->v4l2_dev, "reset for fs & fe not paired\n"); } - +end_judge: spin_unlock_irqrestore(&timer->csi2_err_lock, flags); return is_triggered; @@ -4999,6 +5029,7 @@ static int rkcif_do_reset_work(struct rkcif_device *cif_dev, rkcif_start_luma(&cif_dev->luma_vdev, cif_dev->stream[RKCIF_STREAM_MIPI_ID0].cif_fmt_in); + timer->csi2_err_triggered_cnt = 0; rkcif_monitor_reset_event(cif_dev); v4l2_dbg(1, rkcif_debug, &cif_dev->v4l2_dev, "do rkcif reset successfully!\n"); diff --git a/drivers/media/platform/rockchip/cif/dev.c b/drivers/media/platform/rockchip/cif/dev.c index d1d8d0b0261d..ef6f0b556835 100644 --- a/drivers/media/platform/rockchip/cif/dev.c +++ b/drivers/media/platform/rockchip/cif/dev.c @@ -1035,6 +1035,8 @@ static void rkcif_init_reset_monitor(struct rkcif_device *dev) timer->csi2_err_cnt_odd = 0; timer->csi2_err_fs_fe_cnt = 0; timer->csi2_err_fs_fe_detect_cnt = 0; + timer->csi2_err_triggered_cnt = 0; + timer->csi2_first_err_timestamp = 0; timer_setup(&timer->timer, rkcif_reset_watchdog_timer_handler, 0); diff --git a/drivers/media/platform/rockchip/cif/dev.h b/drivers/media/platform/rockchip/cif/dev.h index e2f3e8e30d14..57e88e6cbb8c 100644 --- a/drivers/media/platform/rockchip/cif/dev.h +++ b/drivers/media/platform/rockchip/cif/dev.h @@ -370,8 +370,10 @@ struct rkcif_timer { unsigned int raw_height; /* unit: ms */ unsigned int err_time_interval; - unsigned long frame_end_cycle_us; + unsigned int csi2_err_triggered_cnt; unsigned int notifer_called_cnt; + unsigned long frame_end_cycle_us; + u64 csi2_first_err_timestamp; bool is_triggered; bool is_buf_stop_update; bool is_running; diff --git a/drivers/media/platform/rockchip/cif/version.h b/drivers/media/platform/rockchip/cif/version.h index 7cd2f711a3de..743732aa67d3 100644 --- a/drivers/media/platform/rockchip/cif/version.h +++ b/drivers/media/platform/rockchip/cif/version.h @@ -64,6 +64,7 @@ *4. register cif itf dev when clear unready subdev *5. mipi csi host add cru rst *6. support wake up mode with mipi + *7. add keepint time to csi2 err for resetting */ #define RKCIF_DRIVER_VERSION RKCIF_API_VERSION