From dc990ffab18cfb44073055e49f881597d553588a Mon Sep 17 00:00:00 2001 From: Zefa Chen Date: Fri, 24 Nov 2023 11:08:33 +0800 Subject: [PATCH] media: rockchip: vicap support resume mode of oneframe without rtt Signed-off-by: Zefa Chen Change-Id: Ia3afbabcfcc6fdca263c8e41c9e2bf403a49ce42 --- drivers/media/platform/rockchip/cif/capture.c | 91 +++++++++++++++---- .../media/platform/rockchip/cif/subdev-itf.c | 16 ++-- 2 files changed, 83 insertions(+), 24 deletions(-) diff --git a/drivers/media/platform/rockchip/cif/capture.c b/drivers/media/platform/rockchip/cif/capture.c index 985388049b83..0f49a7c767df 100644 --- a/drivers/media/platform/rockchip/cif/capture.c +++ b/drivers/media/platform/rockchip/cif/capture.c @@ -1945,6 +1945,26 @@ static void rkcif_assign_new_buffer_init_toisp(struct rkcif_stream *stream, stream->buf_owner = RKCIF_DMAEN_BY_ISP; } +static void rkcif_dphy_quick_stream(struct rkcif_device *dev, int on) +{ + struct rkcif_pipeline *p = NULL; + int j = 0; + + if (dev->active_sensor->mbus.type == V4L2_MBUS_CSI2_DPHY || + dev->active_sensor->mbus.type == V4L2_MBUS_CSI2_CPHY || + dev->active_sensor->mbus.type == V4L2_MBUS_CCP2) { + p = &dev->pipe; + for (j = 0; j < p->num_subdevs; j++) { + if (p->subdevs[j] != dev->terminal_sensor.sd && + p->subdevs[j] != dev->active_sensor->sd) { + v4l2_subdev_call(p->subdevs[j], core, ioctl, + RKMODULE_SET_QUICK_STREAM, &on); + break; + } + } + } +} + static int rkcif_assign_new_buffer_update_toisp(struct rkcif_stream *stream, int channel_id) { @@ -1956,6 +1976,7 @@ static int rkcif_assign_new_buffer_update_toisp(struct rkcif_stream *stream, struct sditf_priv *priv = dev->sditf[0]; u32 frm_addr_y, buff_addr_y; unsigned long flags; + int on = 0; if (mbus_cfg->type == V4L2_MBUS_CSI2_DPHY || mbus_cfg->type == V4L2_MBUS_CSI2_CPHY || @@ -2036,17 +2057,6 @@ static int rkcif_assign_new_buffer_update_toisp(struct rkcif_stream *stream, } if (stream->lack_buf_cnt) stream->lack_buf_cnt--; - if (stream->lack_buf_cnt == 2 || stream->is_single_cap) { - stream->to_stop_dma = RKCIF_DMAEN_BY_ISP; - rkcif_stop_dma_capture(stream); - stream->is_single_cap = false; - if ((dev->hdr.hdr_mode == NO_HDR && atomic_read(&dev->streamoff_cnt) == 1) || - (dev->hdr.hdr_mode == HDR_X2 && atomic_read(&dev->streamoff_cnt) == 2) || - (dev->hdr.hdr_mode == HDR_X3 && atomic_read(&dev->streamoff_cnt) == 3)) { - dev->sensor_work.on = 0; - schedule_work(&dev->sensor_work.work); - } - } } else { if (priv->mode.rdbk_mode == RKISP_VICAP_ONLINE) goto out_get_buf; @@ -2119,7 +2129,18 @@ static int rkcif_assign_new_buffer_update_toisp(struct rkcif_stream *stream, if (dev->is_support_tools && stream->tools_vdev && active_buf) rkcif_rdbk_with_tools(stream, active_buf); } - + if (stream->is_single_cap) { + stream->to_stop_dma = RKCIF_DMAEN_BY_ISP; + rkcif_stop_dma_capture(stream); + rkcif_dphy_quick_stream(stream->cifdev, on); + stream->is_single_cap = false; + if ((dev->hdr.hdr_mode == NO_HDR && atomic_read(&dev->streamoff_cnt) == 1) || + (dev->hdr.hdr_mode == HDR_X2 && atomic_read(&dev->streamoff_cnt) == 2) || + (dev->hdr.hdr_mode == HDR_X3 && atomic_read(&dev->streamoff_cnt) == 3)) { + dev->sensor_work.on = 0; + schedule_work(&dev->sensor_work.work); + } + } out_get_buf: stream->frame_phase_cache = stream->frame_phase; if (buffer) { @@ -2543,6 +2564,7 @@ static int rkcif_assign_new_buffer_update(struct rkcif_stream *stream, int ret = 0; u32 buff_addr_y, buff_addr_cbcr; unsigned long flags; + int on = 0; if (mbus_cfg->type == V4L2_MBUS_CSI2_DPHY || mbus_cfg->type == V4L2_MBUS_CSI2_CPHY || @@ -2641,6 +2663,18 @@ static int rkcif_assign_new_buffer_update(struct rkcif_stream *stream, } } stream->frame_phase_cache = stream->frame_phase; + if (stream->is_single_cap) { + stream->to_stop_dma = RKCIF_DMAEN_BY_VICAP; + rkcif_stop_dma_capture(stream); + rkcif_dphy_quick_stream(stream->cifdev, on); + stream->is_single_cap = false; + if ((dev->hdr.hdr_mode == NO_HDR && atomic_read(&dev->streamoff_cnt) == 1) || + (dev->hdr.hdr_mode == HDR_X2 && atomic_read(&dev->streamoff_cnt) == 2) || + (dev->hdr.hdr_mode == HDR_X3 && atomic_read(&dev->streamoff_cnt) == 3)) { + dev->sensor_work.on = on; + schedule_work(&dev->sensor_work.work); + } + } if (buffer) { buff_addr_y = buffer->buff_addr[RKCIF_PLANE_Y]; @@ -7357,7 +7391,7 @@ static long rkcif_ioctl_default(struct file *file, void *fh, stream->to_en_dma = RKCIF_DMAEN_BY_ISP; rkcif_enable_dma_capture(stream, true); } - + rkcif_dphy_quick_stream(dev, on); v4l2_subdev_call(dev->terminal_sensor.sd, core, ioctl, RKMODULE_SET_QUICK_STREAM, &on); } else { @@ -10067,6 +10101,7 @@ static void rkcif_toisp_check_stop_status(struct sditf_priv *priv, int i = 0; u32 val = 0; u64 cur_time = 0; + int on = 0; for (i = 0; i < TOISP_CH_MAX; i++) { ch = rkcif_g_toisp_ch(intstat_glb, index); @@ -10085,10 +10120,17 @@ static void rkcif_toisp_check_stop_status(struct sditf_priv *priv, wake_up(&stream->wq_stopped); } if (stream->cifdev->sensor_state_change) { + rkcif_dphy_quick_stream(stream->cifdev, on); stream->cifdev->sensor_work.on = stream->cifdev->sensor_state; schedule_work(&stream->cifdev->sensor_work.work); stream->cifdev->sensor_state_change = false; } + if (stream->is_single_cap) { + rkcif_dphy_quick_stream(stream->cifdev, on); + stream->cifdev->sensor_work.on = 0; + schedule_work(&stream->cifdev->sensor_work.work); + stream->is_single_cap = false; + } if (stream->cifdev->chip_id >= CHIP_RV1106_CIF) rkcif_modify_frame_skip_config(stream); if (stream->cifdev->rdbk_debug && @@ -10601,11 +10643,21 @@ int rkcif_stream_resume(struct rkcif_device *cif_dev, int mode) mutex_lock(&cif_dev->stream_lock); rkcif_get_resmem_head(cif_dev); + cif_dev->resume_mode = RKISP_RTT_MODE_ONE_FRAME; is_single_dev = rkcif_check_single_dev_stream_on(cif_dev->hw_dev); if (cif_dev->resume_mode == RKISP_RTT_MODE_ONE_FRAME) { - capture_mode = RKCIF_STREAM_MODE_TOISP_RDBK; - if (priv) - priv->mode.rdbk_mode = RKISP_VICAP_RDBK_AUTO; + if (cif_dev->is_rtt_suspend) { + capture_mode = RKCIF_STREAM_MODE_TOISP_RDBK; + if (priv) + priv->mode.rdbk_mode = RKISP_VICAP_RDBK_AUTO; + } else { + if (priv && priv->mode.rdbk_mode == RKISP_VICAP_ONLINE) + capture_mode = RKCIF_STREAM_MODE_TOISP; + else if (priv && priv->mode.rdbk_mode == RKISP_VICAP_RDBK_AUTO) + capture_mode = RKCIF_STREAM_MODE_TOISP_RDBK; + else + capture_mode = RKCIF_STREAM_MODE_CAPTURE; + } } else if (cif_dev->resume_mode == RKISP_RTT_MODE_MULTI_FRAME) { if (is_single_dev) { capture_mode = RKCIF_STREAM_MODE_TOISP; @@ -10995,11 +11047,14 @@ void rkcif_irq_pingpong_v1(struct rkcif_device *cif_dev) } spin_lock_irqsave(&stream->vbq_lock, flags); - if (!(stream->cur_stream_mode & RKCIF_STREAM_MODE_TOISP) && stream->lack_buf_cnt == 2) { + if (stream->lack_buf_cnt == 2) { v4l2_dbg(4, rkcif_debug, &cif_dev->v4l2_dev, "stream[%d] to stop dma, lack_buf_cnt %d\n", stream->id, stream->lack_buf_cnt); - stream->to_stop_dma = RKCIF_DMAEN_BY_VICAP; + if (stream->cur_stream_mode & RKCIF_STREAM_MODE_TOISP) + stream->to_stop_dma = RKCIF_DMAEN_BY_ISP; + else + stream->to_stop_dma = RKCIF_DMAEN_BY_VICAP; rkcif_stop_dma_capture(stream); } spin_unlock_irqrestore(&stream->vbq_lock, flags); diff --git a/drivers/media/platform/rockchip/cif/subdev-itf.c b/drivers/media/platform/rockchip/cif/subdev-itf.c index 10298a6c21e8..f0ab3e854032 100644 --- a/drivers/media/platform/rockchip/cif/subdev-itf.c +++ b/drivers/media/platform/rockchip/cif/subdev-itf.c @@ -499,9 +499,9 @@ static int sditf_channel_enable(struct sditf_priv *priv, int user) ch0 = 24;//dvp ctrl_val = (ch0 << 3) | 0x1; if (user == 0) - int_en = CIF_TOISP0_FS(0); + int_en = CIF_TOISP0_FS(0) | CIF_TOISP0_FE(0); else - int_en = CIF_TOISP1_FS(0); + int_en = CIF_TOISP1_FS(0) | CIF_TOISP1_FE(0); priv->toisp_inf.ch_info[0].is_valid = true; priv->toisp_inf.ch_info[0].id = ch0; } else if (priv->hdr_cfg.hdr_mode == HDR_X2) { @@ -510,9 +510,11 @@ static int sditf_channel_enable(struct sditf_priv *priv, int user) ctrl_val = (ch0 << 3) | 0x1; ctrl_val |= (ch1 << 11) | 0x100; if (user == 0) - int_en = CIF_TOISP0_FS(0) | CIF_TOISP0_FS(1); + int_en = CIF_TOISP0_FS(0) | CIF_TOISP0_FS(1) | + CIF_TOISP0_FE(0) | CIF_TOISP0_FE(1); else - int_en = CIF_TOISP1_FS(0) | CIF_TOISP1_FS(1); + int_en = CIF_TOISP1_FS(0) | CIF_TOISP1_FS(1) | + CIF_TOISP1_FE(0) | CIF_TOISP1_FE(1); priv->toisp_inf.ch_info[0].is_valid = true; priv->toisp_inf.ch_info[0].id = ch0; priv->toisp_inf.ch_info[1].is_valid = true; @@ -525,9 +527,11 @@ static int sditf_channel_enable(struct sditf_priv *priv, int user) ctrl_val |= (ch1 << 11) | 0x100; ctrl_val |= (ch2 << 19) | 0x10000; if (user == 0) - int_en = CIF_TOISP0_FS(0) | CIF_TOISP0_FS(1) | CIF_TOISP0_FS(2); + int_en = CIF_TOISP0_FS(0) | CIF_TOISP0_FS(1) | CIF_TOISP0_FS(2) | + CIF_TOISP0_FE(0) | CIF_TOISP0_FE(1) | CIF_TOISP0_FE(2); else - int_en = CIF_TOISP1_FS(0) | CIF_TOISP1_FS(1) | CIF_TOISP1_FS(2); + int_en = CIF_TOISP1_FS(0) | CIF_TOISP1_FS(1) | CIF_TOISP1_FS(2) | + CIF_TOISP1_FE(0) | CIF_TOISP1_FE(1) | CIF_TOISP1_FE(2); priv->toisp_inf.ch_info[0].is_valid = true; priv->toisp_inf.ch_info[0].id = ch0; priv->toisp_inf.ch_info[1].is_valid = true;