media: platform: rockchip: cif: fix pipeline power management

Fixes: 99b3695fef ("media: rockchip: cif: add pipeline power management")
Signed-off-by: Allon Huang <allon.huang@rock-chips.com>
Change-Id: I30308d3ffd91992addbc8466a9d36bd0c7719cc8
This commit is contained in:
Allon Huang
2020-04-08 11:42:14 +08:00
committed by Tao Huang
parent aec5601a93
commit b8a24e8c5d
2 changed files with 37 additions and 52 deletions

View File

@@ -563,7 +563,7 @@ static void rkcif_assign_new_buffer_oneframe(struct rkcif_stream *stream,
buffer = stream->curr_buf;
}
if (stream->frame_phase == CIF_CSI_FRAME1_READY ) {
if (stream->frame_phase == CIF_CSI_FRAME1_READY) {
stream->next_buf = list_first_entry(&stream->buf_head,
struct rkcif_buffer, queue);
list_del(&stream->next_buf->queue);
@@ -1094,7 +1094,7 @@ static void rkcif_stop_streaming(struct vb2_queue *queue)
if (ret < 0)
v4l2_err(v4l2_dev, "pipeline close failed error:%d\n",
ret);
/* rkcif_soft_reset(dev, false); */
/*rkcif_soft_reset(dev, false);*/
pm_runtime_put(dev->dev);
}
@@ -1376,6 +1376,7 @@ static int rkcif_start_streaming(struct vb2_queue *queue, unsigned int count)
struct rkcif_vdev_node *node = &stream->vnode;
struct rkcif_device *dev = stream->cifdev;
struct v4l2_device *v4l2_dev = &dev->v4l2_dev;
struct rkcif_sensor_info *sensor_info = dev->active_sensor;
/* struct v4l2_subdev *sd; */
int ret;
@@ -1420,6 +1421,18 @@ static int rkcif_start_streaming(struct vb2_queue *queue, unsigned int count)
goto destroy_buf;
}
/*
* start sub-devices
* When use bt601, the sampling edge of cif is random,
* can be rising or fallling after powering on cif.
* To keep the coherence of edge, open sensor in advance.
*/
if (sensor_info->mbus.type == V4L2_MBUS_PARALLEL) {
ret = dev->pipe.set_stream(&dev->pipe, true);
if (ret < 0)
goto runtime_put;
}
if (dev->chip_id == CHIP_RK1808_CIF) {
if (dev->active_sensor->mbus.type == V4L2_MBUS_CSI2)
ret = rkcif_csi_stream_start(stream);
@@ -1431,10 +1444,12 @@ static int rkcif_start_streaming(struct vb2_queue *queue, unsigned int count)
if (ret < 0)
goto runtime_put;
/* start sub-devices */
ret = dev->pipe.set_stream(&dev->pipe, true);
if (ret < 0)
goto stop_stream;
if (sensor_info->mbus.type != V4L2_MBUS_PARALLEL) {
ret = dev->pipe.set_stream(&dev->pipe, true);
if (ret < 0)
goto stop_stream;
}
ret = media_pipeline_start(&node->vdev.entity, &dev->pipe.pipe);
if (ret < 0) {
@@ -1645,7 +1660,14 @@ static int rkcif_fh_open(struct file *filp)
rkcif_soft_reset(cifdev, true);
}
return v4l2_fh_open(filp);
ret = v4l2_fh_open(filp);
if (!ret) {
ret = v4l2_pipeline_pm_use(&vnode->vdev.entity, 1);
if (ret < 0)
vb2_fop_release(filp);
}
return ret;
}
static int rkcif_fh_release(struct file *filp)
@@ -1657,6 +1679,12 @@ static int rkcif_fh_release(struct file *filp)
int ret = 0;
ret = vb2_fop_release(filp);
if (!ret) {
ret = v4l2_pipeline_pm_use(&vnode->vdev.entity, 0);
if (ret < 0)
v4l2_err(&cifdev->v4l2_dev,
"set pipeline power failed %d\n", ret);
}
mutex_lock(&cifdev->stream_lock);
if (!atomic_dec_return(&cifdev->fh_cnt))

View File

@@ -86,41 +86,6 @@ static int __cif_pipeline_prepare(struct rkcif_pipeline *p,
return 0;
}
static int __subdev_set_power(struct v4l2_subdev *sd, int on)
{
int ret;
if (!sd)
return -ENXIO;
ret = v4l2_subdev_call(sd, core, s_power, on);
return ret != -ENOIOCTLCMD ? ret : 0;
}
static int __cif_pipeline_s_power(struct rkcif_pipeline *p, bool on)
{
int i, ret;
if (on) {
for (i = p->num_subdevs - 1; i >= 0; --i) {
ret = __subdev_set_power(p->subdevs[i], true);
if (ret < 0 && ret != -ENXIO)
goto err_power_off;
}
} else {
for (i = 0; i < p->num_subdevs; ++i)
__subdev_set_power(p->subdevs[i], false);
}
return 0;
err_power_off:
for (++i; i < p->num_subdevs; ++i)
__subdev_set_power(p->subdevs[i], false);
return ret;
}
static int __cif_pipeline_s_cif_clk(struct rkcif_pipeline *p)
{
return 0;
@@ -148,22 +113,14 @@ static int rkcif_pipeline_open(struct rkcif_pipeline *p,
if (ret < 0)
return ret;
ret = __cif_pipeline_s_power(p, 1);
if (ret < 0)
return ret;
return 0;
}
static int rkcif_pipeline_close(struct rkcif_pipeline *p)
{
int ret;
atomic_dec_return(&p->power_cnt);
if (atomic_dec_return(&p->power_cnt) > 0)
return 0;
ret = __cif_pipeline_s_power(p, 0);
return ret == -ENXIO ? 0 : ret;
return 0;
}
/*