From a5f5019da03355481db696d224fa746f5e12c7b4 Mon Sep 17 00:00:00 2001 From: Zefa Chen Date: Wed, 1 Dec 2021 18:59:29 +0800 Subject: [PATCH] media: rockchip: cif: if it is streaming, configure register of scale at the end of the frame Signed-off-by: Zefa Chen Change-Id: Iad5547949ac0ab83611908b2cc28bb51516bccf6 --- drivers/media/platform/rockchip/cif/capture.c | 26 +++++++++++++++---- .../media/platform/rockchip/cif/cif-scale.c | 21 ++++++++++----- drivers/media/platform/rockchip/cif/dev.h | 5 +++- 3 files changed, 39 insertions(+), 13 deletions(-) diff --git a/drivers/media/platform/rockchip/cif/capture.c b/drivers/media/platform/rockchip/cif/capture.c index f3c3b4127b24..f09bba9c78e0 100644 --- a/drivers/media/platform/rockchip/cif/capture.c +++ b/drivers/media/platform/rockchip/cif/capture.c @@ -4175,7 +4175,7 @@ static int rkcif_init_vb2_queue(struct vb2_queue *q, return vb2_queue_init(q); } -void rkcif_set_fmt(struct rkcif_stream *stream, +int rkcif_set_fmt(struct rkcif_stream *stream, struct v4l2_pix_format_mplane *pixm, bool try) { @@ -4204,6 +4204,10 @@ void rkcif_set_fmt(struct rkcif_stream *stream, &input_rect, stream->id, &dev->channels[stream->id]); stream->cif_fmt_in = cif_fmt_in; + } else { + v4l2_err(&stream->cifdev->v4l2_dev, + "terminal subdev does not exist\n"); + return -EINVAL; } if (dev->terminal_sensor.sd) { @@ -4321,6 +4325,7 @@ void rkcif_set_fmt(struct rkcif_stream *stream, pixm->width, pixm->height, stream->pixm.width, stream->pixm.height); } + return 0; } void rkcif_stream_init(struct rkcif_device *dev, u32 id) @@ -4394,6 +4399,7 @@ void rkcif_stream_init(struct rkcif_device *dev, u32 id) stream->dma_en = 0; stream->to_en_dma = 0; stream->to_stop_dma = 0; + stream->to_en_scale = false; } @@ -4494,10 +4500,11 @@ static int rkcif_try_fmt_vid_cap_mplane(struct file *file, void *fh, struct v4l2_format *f) { struct rkcif_stream *stream = video_drvdata(file); + int ret = 0; - rkcif_set_fmt(stream, &f->fmt.pix_mp, true); + ret = rkcif_set_fmt(stream, &f->fmt.pix_mp, true); - return 0; + return ret; } static int rkcif_enum_framesizes(struct file *file, void *prov, @@ -4591,15 +4598,16 @@ static int rkcif_s_fmt_vid_cap_mplane(struct file *file, { struct rkcif_stream *stream = video_drvdata(file); struct rkcif_device *dev = stream->cifdev; + int ret = 0; if (vb2_is_busy(&stream->vnode.buf_queue)) { v4l2_err(&dev->v4l2_dev, "%s queue busy\n", __func__); return -EBUSY; } - rkcif_set_fmt(stream, &f->fmt.pix_mp, false); + ret = rkcif_set_fmt(stream, &f->fmt.pix_mp, false); - return 0; + return ret; } static int rkcif_g_fmt_vid_cap_mplane(struct file *file, void *fh, @@ -7070,6 +7078,10 @@ static void rkcif_toisp_check_stop_status(struct sditf_priv *priv, } if (stream->to_en_dma) rkcif_enable_dma_capture(stream); + if (stream->to_en_scale) { + stream->to_en_scale = false; + rkcif_scale_start(stream->scale_vdev); + } switch (ch) { case RKCIF_TOISP_CH0: val = TOISP_END_CH0(index); @@ -7300,6 +7312,10 @@ void rkcif_irq_pingpong_v1(struct rkcif_device *cif_dev) rkcif_stop_dma_capture(stream); wake_up(&stream->wq_stopped); } + if (stream->to_en_scale) { + stream->to_en_scale = false; + rkcif_scale_start(stream->scale_vdev); + } rkcif_detect_wake_up_mode_change(stream); if (mipi_id == RKCIF_STREAM_MIPI_ID0) { if ((intstat & (CSI_FRAME1_START_ID0 | CSI_FRAME0_START_ID0)) == 0 && diff --git a/drivers/media/platform/rockchip/cif/cif-scale.c b/drivers/media/platform/rockchip/cif/cif-scale.c index cba63306c976..b46dc86bb98d 100644 --- a/drivers/media/platform/rockchip/cif/cif-scale.c +++ b/drivers/media/platform/rockchip/cif/cif-scale.c @@ -296,10 +296,11 @@ static int rkcif_scale_try_fmt_vid_cap_mplane(struct file *file, void *fh, struct v4l2_format *f) { struct rkcif_scale_vdev *scale_vdev = video_drvdata(file); + int ret = 0; - rkcif_scale_set_fmt(scale_vdev, &f->fmt.pix_mp, true); + ret = rkcif_scale_set_fmt(scale_vdev, &f->fmt.pix_mp, true); - return 0; + return ret; } static int rkcif_scale_enum_frameintervals(struct file *file, void *fh, @@ -830,7 +831,7 @@ static int rkcif_scale_channel_set(struct rkcif_scale_vdev *scale_vdev) } -static int rkcif_scale_start(struct rkcif_scale_vdev *scale_vdev) +int rkcif_scale_start(struct rkcif_scale_vdev *scale_vdev) { int ret = 0; struct rkcif_device *dev = scale_vdev->cifdev; @@ -879,9 +880,13 @@ rkcif_scale_vb2_start_streaming(struct vb2_queue *queue, struct rkcif_stream *stream = scale_vdev->stream; int ret = 0; - ret = rkcif_scale_start(scale_vdev); - if (ret) - return ret; + if (stream->state == RKCIF_STATE_STREAMING) { + stream->to_en_scale = true; + } else { + ret = rkcif_scale_start(scale_vdev); + if (ret) + return ret; + } rkcif_do_start_stream(stream, RKCIF_STREAM_MODE_TOSCALE); return 0; @@ -1054,12 +1059,14 @@ void rkcif_irq_handle_scale(struct rkcif_device *cif_dev, unsigned int intstat_g void rkcif_init_scale_vdev(struct rkcif_device *cif_dev, u32 ch) { struct rkcif_scale_vdev *scale_vdev = &cif_dev->scale_vdev[ch]; + struct rkcif_stream *stream = &cif_dev->stream[ch]; struct v4l2_pix_format_mplane pixm; memset(scale_vdev, 0, sizeof(*scale_vdev)); memset(&pixm, 0, sizeof(pixm)); scale_vdev->cifdev = cif_dev; - scale_vdev->stream = &cif_dev->stream[ch]; + scale_vdev->stream = stream; + stream->scale_vdev = scale_vdev; scale_vdev->ch = ch; scale_vdev->ch_src = 0; scale_vdev->frame_idx = 0; diff --git a/drivers/media/platform/rockchip/cif/dev.h b/drivers/media/platform/rockchip/cif/dev.h index af0f83eab170..a6f210bd8166 100644 --- a/drivers/media/platform/rockchip/cif/dev.h +++ b/drivers/media/platform/rockchip/cif/dev.h @@ -496,6 +496,7 @@ struct rkcif_stream { bool is_can_stop; bool is_buf_active; bool is_high_align; + bool to_en_scale; }; struct rkcif_lvds_subdev { @@ -721,6 +722,8 @@ void rkcif_do_stop_stream(struct rkcif_stream *stream, void rkcif_irq_handle_scale(struct rkcif_device *cif_dev, unsigned int intstat_glb); +int rkcif_scale_start(struct rkcif_scale_vdev *scale_vdev); + const struct cif_input_fmt *get_input_fmt(struct v4l2_subdev *sd, struct v4l2_rect *rect, @@ -771,7 +774,7 @@ void rkcif_reset_work(struct work_struct *work); int rkcif_init_rx_buf(struct rkcif_stream *stream, int buf_num); void rkcif_free_rx_buf(struct rkcif_stream *stream, int buf_num); -void rkcif_set_fmt(struct rkcif_stream *stream, +int rkcif_set_fmt(struct rkcif_stream *stream, struct v4l2_pix_format_mplane *pixm, bool try); void rkcif_enable_dma_capture(struct rkcif_stream *stream);