From 760e1d61b30d3050e50e93c72a464b51f97c9012 Mon Sep 17 00:00:00 2001 From: Zefa Chen Date: Tue, 30 Aug 2022 14:42:53 +0800 Subject: [PATCH] media: rockchip: vicap move s_power out of start/stop stream when switching resolutions, the switching speed can be improved Signed-off-by: Zefa Chen Change-Id: I4b31894274dc3238675ece907ba1682d965e71bf --- drivers/media/platform/rockchip/cif/capture.c | 63 ++++++++----------- .../media/platform/rockchip/cif/subdev-itf.c | 8 ++- 2 files changed, 32 insertions(+), 39 deletions(-) diff --git a/drivers/media/platform/rockchip/cif/capture.c b/drivers/media/platform/rockchip/cif/capture.c index 61cd50d2c259..5e33907697c4 100644 --- a/drivers/media/platform/rockchip/cif/capture.c +++ b/drivers/media/platform/rockchip/cif/capture.c @@ -3988,18 +3988,6 @@ void rkcif_do_stop_stream(struct rkcif_stream *stream, ret = dev->pipe.close(&dev->pipe); if (ret < 0) v4l2_err(v4l2_dev, "pipeline close failed error:%d\n", ret); - pm_runtime_put_sync(dev->dev); - v4l2_pipeline_pm_put(&node->vdev.entity); - if (dev->sditf_cnt > 1) { - for (i = 0; i < dev->sditf_cnt; i++) - ret |= v4l2_subdev_call(dev->sditf[i]->sensor_sd, - core, - s_power, - 0); - if (ret < 0) - v4l2_err(v4l2_dev, "set power off fail, ret %d\n", - ret); - } if (dev->hdr.hdr_mode == HDR_X2) { if (dev->stream[RKCIF_STREAM_MIPI_ID0].state == RKCIF_STATE_READY && dev->stream[RKCIF_STREAM_MIPI_ID1].state == RKCIF_STATE_READY) { @@ -4949,7 +4937,6 @@ int rkcif_do_start_stream(struct rkcif_stream *stream, unsigned int mode) struct rkmodule_hdr_cfg hdr_cfg; int rkmodule_stream_seq = RKMODULE_START_STREAM_DEFAULT; int ret; - int i = 0; v4l2_info(&dev->v4l2_dev, "stream[%d] start streaming\n", stream->id); @@ -5018,29 +5005,6 @@ int rkcif_do_start_stream(struct rkcif_stream *stream, unsigned int mode) } if (stream->cur_stream_mode == RKCIF_STREAM_MODE_NONE) { - /* enable clocks/power-domains */ - ret = pm_runtime_resume_and_get(dev->dev); - if (ret < 0) { - v4l2_err(v4l2_dev, "Failed to get runtime pm, %d\n", - ret); - goto destroy_buf; - } - ret = v4l2_pipeline_pm_get(&node->vdev.entity); - if (ret < 0) { - v4l2_err(v4l2_dev, "cif pipeline_pm_get fail %d\n", - ret); - goto destroy_buf; - } - if (dev->sditf_cnt > 1) { - for (i = 0; i < dev->sditf_cnt; i++) - ret |= v4l2_subdev_call(dev->sditf[i]->sensor_sd, - core, - s_power, - 1); - if (ret < 0) - v4l2_err(v4l2_dev, "set power on fail, ret %d\n", - ret); - } ret = dev->pipe.open(&dev->pipe, &node->vdev.entity, true); if (ret < 0) { v4l2_err(v4l2_dev, "open cif pipeline failed %d\n", @@ -5438,6 +5402,7 @@ static int rkcif_fh_open(struct file *filp) struct rkcif_stream *stream = to_rkcif_stream(vnode); struct rkcif_device *cifdev = stream->cifdev; int ret; + int i = 0; ret = rkcif_attach_hw(cifdev); if (ret) @@ -5466,7 +5431,18 @@ static int rkcif_fh_open(struct file *filp) if (ret < 0) vb2_fop_release(filp); } - + if (cifdev->sditf_cnt > 1) { + for (i = 0; i < cifdev->sditf_cnt; i++) { + if (cifdev->sditf[i]->sensor_sd) + ret |= v4l2_subdev_call(cifdev->sditf[i]->sensor_sd, + core, + s_power, + 1); + } + if (ret < 0) + v4l2_err(vdev, "set sensor power on fail, ret %d\n", + ret); + } return ret; } @@ -5477,12 +5453,25 @@ static int rkcif_fh_release(struct file *filp) struct rkcif_stream *stream = to_rkcif_stream(vnode); struct rkcif_device *cifdev = stream->cifdev; int ret = 0; + int i = 0; ret = vb2_fop_release(filp); if (!ret) v4l2_pipeline_pm_put(&vnode->vdev.entity); pm_runtime_put_sync(cifdev->dev); + if (cifdev->sditf_cnt > 1) { + for (i = 0; i < cifdev->sditf_cnt; i++) { + if (cifdev->sditf[i]->sensor_sd) + ret |= v4l2_subdev_call(cifdev->sditf[i]->sensor_sd, + core, + s_power, + 0); + } + if (ret < 0) + v4l2_err(vdev, "set sensor power on fail, ret %d\n", + ret); + } return ret; } diff --git a/drivers/media/platform/rockchip/cif/subdev-itf.c b/drivers/media/platform/rockchip/cif/subdev-itf.c index 7075a19b70d4..0d192ee18caa 100644 --- a/drivers/media/platform/rockchip/cif/subdev-itf.c +++ b/drivers/media/platform/rockchip/cif/subdev-itf.c @@ -622,6 +622,7 @@ static int sditf_s_power(struct v4l2_subdev *sd, int on) { struct sditf_priv *priv = to_sditf_priv(sd); struct rkcif_device *cif_dev = priv->cif_dev; + struct rkcif_vdev_node *node = &cif_dev->stream[0].vnode; int ret = 0; if (!on && atomic_dec_return(&priv->power_cnt)) @@ -634,10 +635,13 @@ static int sditf_s_power(struct v4l2_subdev *sd, int on) v4l2_dbg(3, rkcif_debug, &cif_dev->v4l2_dev, "%s, toisp mode %d, hdr %d, set power %d\n", __func__, priv->toisp_inf.link_mode, priv->hdr_cfg.hdr_mode, on); - if (on) + if (on) { ret = pm_runtime_resume_and_get(cif_dev->dev); - else + ret |= v4l2_pipeline_pm_get(&node->vdev.entity); + } else { + v4l2_pipeline_pm_put(&node->vdev.entity); pm_runtime_put_sync(cif_dev->dev); + } } return ret; }