From ccc60a624971b61ccbe2780289b39fae1c2e88d2 Mon Sep 17 00:00:00 2001 From: Zefa Chen Date: Fri, 21 Jul 2023 20:53:14 +0800 Subject: [PATCH] media: rockchip: vicap support to do reset in online mode Signed-off-by: Zefa Chen Change-Id: Ibea46658e5d9a41b4f5685838230321e9b71032e Signed-off-by: Mingwei Yan --- drivers/media/platform/rockchip/cif/capture.c | 29 ++++++++++++++++++- drivers/media/platform/rockchip/cif/dev.c | 2 ++ drivers/media/platform/rockchip/cif/dev.h | 1 + .../media/platform/rockchip/cif/subdev-itf.c | 9 ++++++ include/uapi/linux/rk-camera-module.h | 1 + 5 files changed, 41 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/rockchip/cif/capture.c b/drivers/media/platform/rockchip/cif/capture.c index 325430e03f11..113ce878134f 100644 --- a/drivers/media/platform/rockchip/cif/capture.c +++ b/drivers/media/platform/rockchip/cif/capture.c @@ -9075,6 +9075,15 @@ static void rkcif_set_sof(struct rkcif_device *cif_dev, u32 seq) } } +static void rkcif_toisp_set_stream(struct rkcif_device *dev, int on) +{ + struct v4l2_subdev *sd = get_rkisp_sd(dev->sditf[0]); + + if (sd) + v4l2_subdev_call(sd, core, ioctl, + RKISP_VICAP_CMD_SET_STREAM, &on); +} + static int rkcif_do_reset_work(struct rkcif_device *cif_dev, enum rkmodule_reset_src reset_src) { @@ -9181,6 +9190,9 @@ static int rkcif_do_reset_work(struct rkcif_device *cif_dev, } } + if (priv && priv->mode.rdbk_mode == RKISP_VICAP_ONLINE) + rkcif_toisp_set_stream(cif_dev, 1); + for (i = 0; i < j; i++) { stream = resume_stream[i]; stream->fs_cnt_in_single_frame = 0; @@ -9428,6 +9440,7 @@ static void rkcif_init_reset_work(struct rkcif_timer *timer) timer->csi2_err_cnt_even = 0; timer->csi2_err_fs_fe_cnt = 0; timer->notifer_called_cnt = 0; + dev->is_toisp_reset = false; for (i = 0; i < dev->num_channels; i++) { stream = &dev->stream[i]; if (stream->state == RKCIF_STATE_STREAMING) @@ -9437,10 +9450,10 @@ static void rkcif_init_reset_work(struct rkcif_timer *timer) if (timer->is_ctrl_by_user) { rkcif_send_reset_event(dev, timer->reset_src); } else { + dev->reset_work.reset_src = timer->reset_src; if (!schedule_work(&dev->reset_work.work)) v4l2_info(&dev->v4l2_dev, "schedule reset work failed\n"); - dev->reset_work.reset_src = timer->reset_src; } } @@ -9455,6 +9468,15 @@ static int rkcif_detect_reset_event(struct rkcif_stream *stream, int ret, is_reset = 0; struct rkmodule_vicap_reset_info rst_info; + if (dev->is_toisp_reset) { + is_reset = 1; + timer->reset_src = RKCIF_RESET_SRC_ERR_ISP; + } + if (is_reset) { + rkcif_init_reset_work(timer); + return is_reset; + } + if (timer->last_buf_wakeup_cnt[stream->id] < stream->buf_wake_up_cnt && check_cnt == 0) { @@ -10056,6 +10078,11 @@ static void rkcif_toisp_check_stop_status(struct sditf_priv *priv, cur_time = ktime_get_ns(); stream->readout.readout_time = cur_time - stream->readout.fs_timestamp; stream->readout.fs_timestamp = cur_time; + stream->buf_wake_up_cnt++; + if (stream->frame_idx % 2) + stream->fps_stats.frm0_timestamp = ktime_get_ns(); + else + stream->fps_stats.frm1_timestamp = ktime_get_ns(); if (stream->cifdev->rdbk_debug && stream->frame_idx < 15) v4l2_info(&priv->cif_dev->v4l2_dev, diff --git a/drivers/media/platform/rockchip/cif/dev.c b/drivers/media/platform/rockchip/cif/dev.c index dc0d863826ea..c2ad6c305095 100644 --- a/drivers/media/platform/rockchip/cif/dev.c +++ b/drivers/media/platform/rockchip/cif/dev.c @@ -1134,6 +1134,7 @@ static int rkcif_pipeline_set_stream(struct rkcif_pipeline *p, bool on) cif_dev->reset_watchdog_timer.is_triggered = false; cif_dev->reset_watchdog_timer.is_running = false; cif_dev->err_state_work.last_timestamp = 0; + cif_dev->is_toisp_reset = false; for (i = 0; i < cif_dev->num_channels; i++) cif_dev->reset_watchdog_timer.last_buf_wakeup_cnt[i] = 0; cif_dev->reset_watchdog_timer.run_cnt = 0; @@ -1218,6 +1219,7 @@ static int rkcif_pipeline_set_stream(struct rkcif_pipeline *p, bool on) cif_dev->is_start_hdr = true; cif_dev->reset_watchdog_timer.is_triggered = false; cif_dev->reset_watchdog_timer.is_running = false; + cif_dev->is_toisp_reset = false; for (i = 0; i < cif_dev->num_channels; i++) cif_dev->reset_watchdog_timer.last_buf_wakeup_cnt[i] = 0; cif_dev->reset_watchdog_timer.run_cnt = 0; diff --git a/drivers/media/platform/rockchip/cif/dev.h b/drivers/media/platform/rockchip/cif/dev.h index cf689c99d259..5122ec706f16 100644 --- a/drivers/media/platform/rockchip/cif/dev.h +++ b/drivers/media/platform/rockchip/cif/dev.h @@ -883,6 +883,7 @@ struct rkcif_device { bool is_support_tools; bool is_rtt_suspend; bool sensor_state_change; + bool is_toisp_reset; int rdbk_debug; struct rkcif_sync_cfg sync_cfg; int sditf_cnt; diff --git a/drivers/media/platform/rockchip/cif/subdev-itf.c b/drivers/media/platform/rockchip/cif/subdev-itf.c index 60021b069097..7ebeebde495c 100644 --- a/drivers/media/platform/rockchip/cif/subdev-itf.c +++ b/drivers/media/platform/rockchip/cif/subdev-itf.c @@ -383,6 +383,12 @@ static long sditf_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) rkcif_stream_suspend(cif_dev, RKCIF_RESUME_ISP); } break; + case RKISP_VICAP_CMD_SET_RESET: + if (priv->mode.rdbk_mode == RKISP_VICAP_ONLINE) { + cif_dev->is_toisp_reset = true; + return 0; + } + break; default: break; } @@ -440,6 +446,9 @@ static long sditf_compat_ioctl32(struct v4l2_subdev *sd, return -EFAULT; ret = sditf_ioctl(sd, cmd, &on); return ret; + case RKISP_VICAP_CMD_SET_RESET: + ret = sditf_ioctl(sd, cmd, NULL); + return ret; default: break; } diff --git a/include/uapi/linux/rk-camera-module.h b/include/uapi/linux/rk-camera-module.h index 7a825afaa279..68e57c0a9e41 100644 --- a/include/uapi/linux/rk-camera-module.h +++ b/include/uapi/linux/rk-camera-module.h @@ -638,6 +638,7 @@ enum rkmodule_reset_src { RKICF_RESET_SRC_ERR_CUTOFF, RKCIF_RESET_SRC_ERR_HOTPLUG, RKCIF_RESET_SRC_ERR_APP, + RKCIF_RESET_SRC_ERR_ISP, }; struct rkmodule_vicap_reset_info {