From ebce6934858d9a3bb9138c8f97716ed46b87ed37 Mon Sep 17 00:00:00 2001 From: Zefa Chen Date: Fri, 8 Sep 2023 15:13:24 +0800 Subject: [PATCH] media: rockchip: vicap support to set quick stream Signed-off-by: Zefa Chen Change-Id: Idbf038d79080b394c5bb614a0b04039964624ab5 --- drivers/media/platform/rockchip/cif/capture.c | 59 ++++++++++++++++++- drivers/media/platform/rockchip/cif/dev.c | 2 +- drivers/media/platform/rockchip/cif/dev.h | 3 +- .../media/platform/rockchip/cif/subdev-itf.c | 27 ++++----- 4 files changed, 74 insertions(+), 17 deletions(-) diff --git a/drivers/media/platform/rockchip/cif/capture.c b/drivers/media/platform/rockchip/cif/capture.c index 539380e6af4f..325430e03f11 100644 --- a/drivers/media/platform/rockchip/cif/capture.c +++ b/drivers/media/platform/rockchip/cif/capture.c @@ -2037,6 +2037,17 @@ 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; @@ -7209,6 +7220,7 @@ void rkcif_set_fps(struct rkcif_stream *stream, struct rkcif_fps *fps) static int rkcif_do_reset_work(struct rkcif_device *cif_dev, enum rkmodule_reset_src reset_src); +static bool rkcif_check_single_dev_stream_on(struct rkcif_hw *hw); static long rkcif_ioctl_default(struct file *file, void *fh, bool valid_prio, unsigned int cmd, void *arg) @@ -7220,6 +7232,10 @@ static long rkcif_ioctl_default(struct file *file, void *fh, struct csi_channel_info csi_info; struct rkcif_fps fps; int reset_src; + int on = 0; + bool is_single_dev = false; + struct v4l2_subdev *sd; + int ret = -EINVAL; switch (cmd) { case RKCIF_CMD_GET_CSI_MEMORY_MODE: @@ -7268,6 +7284,43 @@ static long rkcif_ioctl_default(struct file *file, void *fh, case RKCIF_CMD_SET_RESET: reset_src = *(int *)arg; return rkcif_do_reset_work(dev, reset_src); + case RKCIF_CMD_SET_QUICK_STREAM: + on = *(int *)arg; + if (!dev->sditf[0]) + return -EINVAL; + if (on) { + is_single_dev = rkcif_check_single_dev_stream_on(dev->hw_dev); + if (is_single_dev) { + dev->sditf[0]->mode.rdbk_mode = RKISP_VICAP_ONLINE; + sditf_change_to_online(dev->sditf[0]); + sd = get_rkisp_sd(dev->sditf[0]); + if (sd) + ret = v4l2_subdev_call(sd, core, ioctl, + RKISP_VICAP_CMD_MODE, &dev->sditf[0]->mode); + if (ret) { + v4l2_err(&dev->v4l2_dev, "set isp work mode online fail\n"); + return -EINVAL; + } + } else { + dev->sditf[0]->mode.rdbk_mode = RKISP_VICAP_RDBK_AUTO; + sditf_disable_immediately(dev->sditf[0]); + stream->to_en_dma = RKCIF_DMAEN_BY_ISP; + rkcif_enable_dma_capture(stream, true); + } + + v4l2_subdev_call(dev->terminal_sensor.sd, core, ioctl, + RKMODULE_SET_QUICK_STREAM, &on); + } else { + if (dev->sditf[0]->mode.rdbk_mode == RKISP_VICAP_RDBK_AUTO) { + stream->to_stop_dma = RKCIF_DMAEN_BY_ISP; + } else if (dev->sditf[0]->mode.rdbk_mode == RKISP_VICAP_RDBK_AIQ) { + stream->to_stop_dma = RKCIF_DMAEN_BY_VICAP; + } else { + stream->cifdev->sensor_state = 0; + stream->cifdev->sensor_state_change = true; + } + } + break; default: return -EINVAL; } @@ -9959,7 +10012,11 @@ static void rkcif_toisp_check_stop_status(struct sditf_priv *priv, stream->stopping = false; wake_up(&stream->wq_stopped); } - + if (stream->cifdev->sensor_state_change) { + stream->cifdev->sensor_work.on = stream->cifdev->sensor_state; + schedule_work(&stream->cifdev->sensor_work.work); + stream->cifdev->sensor_state_change = false; + } if (stream->cifdev->chip_id >= CHIP_RV1106_CIF) rkcif_modify_frame_skip_config(stream); if (stream->cifdev->rdbk_debug && diff --git a/drivers/media/platform/rockchip/cif/dev.c b/drivers/media/platform/rockchip/cif/dev.c index df28f35d70ad..dc0d863826ea 100644 --- a/drivers/media/platform/rockchip/cif/dev.c +++ b/drivers/media/platform/rockchip/cif/dev.c @@ -2160,7 +2160,7 @@ static int rkcif_get_reserved_mem(struct rkcif_device *cif_dev) if (device_property_read_bool(dev, "rtt-suspend")) cif_dev->is_rtt_suspend = true; - else + if (IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP)) cif_dev->is_thunderboot = true; dev_info(dev, "Allocated reserved memory, paddr: 0x%x, size 0x%x\n", (u32)cif_dev->resmem_pa, diff --git a/drivers/media/platform/rockchip/cif/dev.h b/drivers/media/platform/rockchip/cif/dev.h index 193931cdfbef..cf689c99d259 100644 --- a/drivers/media/platform/rockchip/cif/dev.h +++ b/drivers/media/platform/rockchip/cif/dev.h @@ -882,7 +882,7 @@ struct rkcif_device { bool is_rdbk_to_online; bool is_support_tools; bool is_rtt_suspend; - + bool sensor_state_change; int rdbk_debug; struct rkcif_sync_cfg sync_cfg; int sditf_cnt; @@ -893,6 +893,7 @@ struct rkcif_device { struct rkcif_err_state_work err_state_work; struct rkcif_sensor_work sensor_work; int resume_mode; + int sensor_state; }; extern struct platform_driver rkcif_plat_drv; diff --git a/drivers/media/platform/rockchip/cif/subdev-itf.c b/drivers/media/platform/rockchip/cif/subdev-itf.c index 85384fa7d2a7..60021b069097 100644 --- a/drivers/media/platform/rockchip/cif/subdev-itf.c +++ b/drivers/media/platform/rockchip/cif/subdev-itf.c @@ -668,39 +668,36 @@ static int sditf_start_stream(struct sditf_priv *priv) struct rkcif_device *cif_dev = priv->cif_dev; struct v4l2_subdev_format fmt; unsigned int mode = RKCIF_STREAM_MODE_TOISP; - int ret = 0; sditf_check_capture_mode(cif_dev); sditf_get_set_fmt(&priv->sd, NULL, &fmt); if (priv->mode.rdbk_mode == RKISP_VICAP_ONLINE) { if (priv->toisp_inf.link_mode == TOISP0) { - ret = sditf_channel_enable(priv, 0); + sditf_channel_enable(priv, 0); } else if (priv->toisp_inf.link_mode == TOISP1) { - ret = sditf_channel_enable(priv, 1); + sditf_channel_enable(priv, 1); } else if (priv->toisp_inf.link_mode == TOISP_UNITE) { - ret = sditf_channel_enable(priv, 0); - ret |= sditf_channel_enable(priv, 1); + sditf_channel_enable(priv, 0); + sditf_channel_enable(priv, 1); } mode = RKCIF_STREAM_MODE_TOISP; } else if (priv->mode.rdbk_mode == RKISP_VICAP_RDBK_AUTO) { mode = RKCIF_STREAM_MODE_TOISP_RDBK; } - if (ret) - return ret; if (priv->hdr_cfg.hdr_mode == NO_HDR || priv->hdr_cfg.hdr_mode == HDR_COMPR) { - ret = rkcif_do_start_stream(&cif_dev->stream[0], mode); + rkcif_do_start_stream(&cif_dev->stream[0], mode); } else if (priv->hdr_cfg.hdr_mode == HDR_X2) { - ret = rkcif_do_start_stream(&cif_dev->stream[0], mode); - ret |= rkcif_do_start_stream(&cif_dev->stream[1], mode); + rkcif_do_start_stream(&cif_dev->stream[0], mode); + rkcif_do_start_stream(&cif_dev->stream[1], mode); } else if (priv->hdr_cfg.hdr_mode == HDR_X3) { - ret = rkcif_do_start_stream(&cif_dev->stream[0], mode); - ret |= rkcif_do_start_stream(&cif_dev->stream[1], mode); - ret |= rkcif_do_start_stream(&cif_dev->stream[2], mode); + rkcif_do_start_stream(&cif_dev->stream[0], mode); + rkcif_do_start_stream(&cif_dev->stream[1], mode); + rkcif_do_start_stream(&cif_dev->stream[2], mode); } INIT_LIST_HEAD(&priv->buf_free_list); - return ret; + return 0; } static int sditf_stop_stream(struct sditf_priv *priv) @@ -873,6 +870,8 @@ static int sditf_s_rx_buffer(struct v4l2_subdev *sd, if (!stream->dma_en && cif_dev->resume_mode != RKISP_RTT_MODE_ONE_FRAME) { stream->to_en_dma = RKCIF_DMAEN_BY_ISP; rkcif_enable_dma_capture(stream, true); + cif_dev->sensor_work.on = 1; + schedule_work(&cif_dev->sensor_work.work); } if (cif_dev->rdbk_debug) { u32 offset = 0;