mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-10 04:48:04 +09:00
media: rockchip: isp: add link state for stream
Disable mp/sp link and enable mpfbc default for isp2.0. Using ispp video to capture image, or disable mpfbc then to use mp/sp. Change-Id: I5d21cdaf212cdf77fb3c052e9ad77d1c1166ce0d Signed-off-by: Cai YiWei <cyw@rock-chips.com>
This commit is contained in:
@@ -2045,6 +2045,9 @@ static void rkisp_stop_streaming(struct vb2_queue *queue)
|
||||
v4l2_dbg(1, rkisp_debug, &dev->v4l2_dev,
|
||||
"%s %d\n", __func__, stream->id);
|
||||
|
||||
if (!stream->streaming)
|
||||
return;
|
||||
|
||||
rkisp_stream_stop(stream);
|
||||
if (stream->id == RKISP_STREAM_MP ||
|
||||
stream->id == RKISP_STREAM_SP) {
|
||||
@@ -2116,6 +2119,11 @@ rkisp_start_streaming(struct vb2_queue *queue, unsigned int count)
|
||||
v4l2_dbg(1, rkisp_debug, &dev->v4l2_dev,
|
||||
"%s %d\n", __func__, stream->id);
|
||||
|
||||
if (!stream->linked) {
|
||||
v4l2_err(v4l2_dev, "link stream first\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (WARN_ON(stream->streaming))
|
||||
return -EBUSY;
|
||||
|
||||
@@ -2727,25 +2735,14 @@ static int rkisp_register_stream_vdev(struct rkisp_stream *stream)
|
||||
|
||||
source = &dev->csi_dev.sd.entity;
|
||||
switch (stream->id) {
|
||||
case RKISP_STREAM_DMATX0:
|
||||
pad = CSI_SRC_CH1;
|
||||
dev->csi_dev.sink[1].linked = true;
|
||||
dev->csi_dev.sink[1].index = BIT(1);
|
||||
break;
|
||||
case RKISP_STREAM_DMATX1:
|
||||
pad = CSI_SRC_CH2;
|
||||
dev->csi_dev.sink[2].linked = true;
|
||||
dev->csi_dev.sink[2].index = BIT(2);
|
||||
break;
|
||||
case RKISP_STREAM_DMATX2:
|
||||
pad = CSI_SRC_CH3;
|
||||
dev->csi_dev.sink[3].linked = true;
|
||||
dev->csi_dev.sink[3].index = BIT(3);
|
||||
break;
|
||||
case RKISP_STREAM_DMATX3:
|
||||
pad = CSI_SRC_CH4;
|
||||
dev->csi_dev.sink[4].linked = true;
|
||||
dev->csi_dev.sink[4].index = BIT(4);
|
||||
case RKISP_STREAM_DMATX0://CSI_SRC_CH1
|
||||
case RKISP_STREAM_DMATX1://CSI_SRC_CH2
|
||||
case RKISP_STREAM_DMATX2://CSI_SRC_CH3
|
||||
case RKISP_STREAM_DMATX3://CSI_SRC_CH4
|
||||
pad = stream->id;
|
||||
stream->linked = true;
|
||||
dev->csi_dev.sink[pad - 1].linked = true;
|
||||
dev->csi_dev.sink[pad - 1].index = BIT(pad - 1);
|
||||
break;
|
||||
default:
|
||||
source = &dev->isp_sdev.sd.entity;
|
||||
@@ -2753,7 +2750,7 @@ static int rkisp_register_stream_vdev(struct rkisp_stream *stream)
|
||||
}
|
||||
sink = &vdev->entity;
|
||||
ret = media_create_pad_link(source, pad,
|
||||
sink, 0, MEDIA_LNK_FL_ENABLED);
|
||||
sink, 0, stream->linked);
|
||||
if (ret < 0)
|
||||
goto unreg;
|
||||
return 0;
|
||||
@@ -2779,6 +2776,11 @@ static int rkisp_stream_init(struct rkisp_device *dev, u32 id)
|
||||
init_waitqueue_head(&stream->done);
|
||||
spin_lock_init(&stream->vbq_lock);
|
||||
|
||||
/* isp2 disable MP/SP, enable MPFBC default */
|
||||
if ((id == RKISP_STREAM_SP || id == RKISP_STREAM_MP) &&
|
||||
dev->isp_ver == ISP_V20)
|
||||
stream->linked = false;
|
||||
|
||||
switch (id) {
|
||||
case RKISP_STREAM_SP:
|
||||
strlcpy(vdev->name, SP_VDEV_NAME,
|
||||
|
||||
@@ -187,6 +187,7 @@ struct streams_ops {
|
||||
* rkisp use shadowsock registers, so it need two buffer at a time
|
||||
* @curr_buf: the buffer used for current frame
|
||||
* @next_buf: the buffer used for next frame
|
||||
* @linked: stream link to isp
|
||||
* @done: wait frame end event queue
|
||||
* @burst: burst length for Y and CB/CR
|
||||
* @sequence: damtx video frame sequence
|
||||
@@ -209,6 +210,7 @@ struct rkisp_stream {
|
||||
bool streaming;
|
||||
bool stopping;
|
||||
bool frame_end;
|
||||
bool linked;
|
||||
wait_queue_head_t done;
|
||||
unsigned int burst;
|
||||
atomic_t sequence;
|
||||
|
||||
@@ -68,6 +68,7 @@ static int rkisp_csi_link_setup(struct media_entity *entity,
|
||||
{
|
||||
struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
|
||||
struct rkisp_csi_device *csi;
|
||||
struct rkisp_stream *stream = NULL;
|
||||
int ret = 0;
|
||||
u8 id;
|
||||
|
||||
@@ -77,6 +78,8 @@ static int rkisp_csi_link_setup(struct media_entity *entity,
|
||||
csi = v4l2_get_subdevdata(sd);
|
||||
if (local->flags & MEDIA_PAD_FL_SOURCE) {
|
||||
id = local->index - 1;
|
||||
if (id && id < RKISP_STREAM_DMATX3)
|
||||
stream = &csi->ispdev->cap_dev.stream[id + 1];
|
||||
if (flags & MEDIA_LNK_FL_ENABLED) {
|
||||
if (csi->sink[id].linked) {
|
||||
ret = -EBUSY;
|
||||
@@ -88,7 +91,10 @@ static int rkisp_csi_link_setup(struct media_entity *entity,
|
||||
csi->sink[id].linked = false;
|
||||
csi->sink[id].index = 0;
|
||||
}
|
||||
if (stream)
|
||||
stream->linked = csi->sink[id].linked;
|
||||
}
|
||||
|
||||
return 0;
|
||||
out:
|
||||
v4l2_err(sd, "pad%d is already linked\n", local->index);
|
||||
|
||||
@@ -37,7 +37,7 @@ enum hdr_op_mode {
|
||||
};
|
||||
|
||||
enum rkisp_csi_pad {
|
||||
CSI_SINK,
|
||||
CSI_SINK = 0,
|
||||
CSI_SRC_CH0,
|
||||
CSI_SRC_CH1,
|
||||
CSI_SRC_CH2,
|
||||
|
||||
@@ -523,6 +523,9 @@ static void dmarx_stop_streaming(struct vb2_queue *queue)
|
||||
{
|
||||
struct rkisp_stream *stream = queue->drv_priv;
|
||||
|
||||
if (!stream->streaming)
|
||||
return;
|
||||
|
||||
dmarx_stop(stream);
|
||||
destroy_buf_queue(stream, VB2_BUF_STATE_ERROR);
|
||||
}
|
||||
@@ -535,6 +538,11 @@ static int dmarx_start_streaming(struct vb2_queue *queue,
|
||||
struct v4l2_device *v4l2_dev = &dev->v4l2_dev;
|
||||
int ret = -1;
|
||||
|
||||
if (!stream->linked) {
|
||||
v4l2_err(v4l2_dev, "link stream first\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (WARN_ON(stream->streaming))
|
||||
return -EBUSY;
|
||||
|
||||
@@ -872,6 +880,7 @@ static int dmarx_init(struct rkisp_device *dev, u32 id)
|
||||
stream->id = id;
|
||||
stream->ispdev = dev;
|
||||
vdev = &stream->vnode.vdev;
|
||||
stream->linked = false;
|
||||
|
||||
switch (id) {
|
||||
case RKISP_STREAM_DMARX:
|
||||
@@ -910,7 +919,7 @@ static int dmarx_init(struct rkisp_device *dev, u32 id)
|
||||
source = &vdev->entity;
|
||||
sink = &dev->isp_sdev.sd.entity;
|
||||
return media_create_pad_link(source, 0, sink,
|
||||
RKISP_ISP_PAD_SINK, 0);
|
||||
RKISP_ISP_PAD_SINK, stream->linked);
|
||||
}
|
||||
|
||||
u32 rkisp_dmarx_get_frame_id(struct rkisp_device *dev)
|
||||
|
||||
@@ -185,8 +185,13 @@ static int mpfbc_start_stream(struct v4l2_subdev *sd)
|
||||
struct rkisp_device *dev = mpfbc_dev->ispdev;
|
||||
int ret;
|
||||
|
||||
if (WARN_ON(mpfbc_dev->en) ||
|
||||
!dev->isp_inp)
|
||||
if (!mpfbc_dev->linked || !dev->isp_inp) {
|
||||
v4l2_err(&dev->v4l2_dev,
|
||||
"mpfbc no linked or isp inval input\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (WARN_ON(mpfbc_dev->en))
|
||||
return -EBUSY;
|
||||
|
||||
if (dev->isp_inp & INP_CSI ||
|
||||
@@ -354,10 +359,11 @@ int rkisp_register_mpfbc_subdev(struct rkisp_device *dev,
|
||||
}
|
||||
|
||||
/* mpfbc links */
|
||||
mpfbc_dev->linked = true;
|
||||
source = &dev->isp_sdev.sd.entity;
|
||||
sink = &sd->entity;
|
||||
ret = media_create_pad_link(source, RKISP_ISP_PAD_SOURCE_PATH,
|
||||
sink, 0, MEDIA_LNK_FL_ENABLED);
|
||||
sink, 0, mpfbc_dev->linked);
|
||||
|
||||
init_waitqueue_head(&mpfbc_dev->done);
|
||||
return ret;
|
||||
|
||||
@@ -28,6 +28,7 @@ struct rkisp_mpfbc_device {
|
||||
u8 pingpong;
|
||||
u8 stopping;
|
||||
u8 en;
|
||||
bool linked;
|
||||
};
|
||||
|
||||
int rkisp_register_mpfbc_subdev(struct rkisp_device *dev,
|
||||
|
||||
@@ -1557,12 +1557,14 @@ static int rkisp_subdev_link_setup(struct media_entity *entity,
|
||||
{
|
||||
struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
|
||||
struct rkisp_device *dev;
|
||||
struct rkisp_stream *stream = NULL;
|
||||
u8 rawrd = INP_RAWRD0 | INP_RAWRD1 | INP_RAWRD2;
|
||||
|
||||
if (!sd)
|
||||
return -ENODEV;
|
||||
dev = sd_to_isp_dev(sd);
|
||||
if (!strcmp(remote->entity->name, DMA_VDEV_NAME)) {
|
||||
stream = &dev->dmarx_dev.stream[RKISP_STREAM_DMARX];
|
||||
if (flags & MEDIA_LNK_FL_ENABLED) {
|
||||
if (dev->isp_inp)
|
||||
goto err;
|
||||
@@ -1581,6 +1583,7 @@ static int rkisp_subdev_link_setup(struct media_entity *entity,
|
||||
dev->isp_inp &= ~INP_CSI;
|
||||
}
|
||||
} else if (!strcmp(remote->entity->name, DMARX0_VDEV_NAME)) {
|
||||
stream = &dev->dmarx_dev.stream[RKISP_STREAM_RAWRD0];
|
||||
if (flags & MEDIA_LNK_FL_ENABLED) {
|
||||
if (dev->isp_inp == INP_DMARX_ISP)
|
||||
goto err;
|
||||
@@ -1589,6 +1592,7 @@ static int rkisp_subdev_link_setup(struct media_entity *entity,
|
||||
dev->isp_inp &= ~INP_RAWRD0;
|
||||
}
|
||||
} else if (!strcmp(remote->entity->name, DMARX1_VDEV_NAME)) {
|
||||
stream = &dev->dmarx_dev.stream[RKISP_STREAM_RAWRD1];
|
||||
if (flags & MEDIA_LNK_FL_ENABLED) {
|
||||
if (dev->isp_inp == INP_DMARX_ISP)
|
||||
goto err;
|
||||
@@ -1597,6 +1601,7 @@ static int rkisp_subdev_link_setup(struct media_entity *entity,
|
||||
dev->isp_inp &= ~INP_RAWRD1;
|
||||
}
|
||||
} else if (!strcmp(remote->entity->name, DMARX2_VDEV_NAME)) {
|
||||
stream = &dev->dmarx_dev.stream[RKISP_STREAM_RAWRD2];
|
||||
if (flags & MEDIA_LNK_FL_ENABLED) {
|
||||
if (dev->isp_inp == INP_DMARX_ISP)
|
||||
goto err;
|
||||
@@ -1604,6 +1609,22 @@ static int rkisp_subdev_link_setup(struct media_entity *entity,
|
||||
} else {
|
||||
dev->isp_inp &= ~INP_RAWRD2;
|
||||
}
|
||||
} else if (!strcmp(remote->entity->name, SP_VDEV_NAME)) {
|
||||
stream = &dev->cap_dev.stream[RKISP_STREAM_SP];
|
||||
if (flags & MEDIA_LNK_FL_ENABLED &&
|
||||
dev->mpfbc_dev.linked)
|
||||
goto err;
|
||||
} else if (!strcmp(remote->entity->name, MP_VDEV_NAME)) {
|
||||
stream = &dev->cap_dev.stream[RKISP_STREAM_MP];
|
||||
if (flags & MEDIA_LNK_FL_ENABLED &&
|
||||
dev->mpfbc_dev.linked)
|
||||
goto err;
|
||||
} else if (!strcmp(remote->entity->name, MPFBC_DEV_NAME)) {
|
||||
if (flags & MEDIA_LNK_FL_ENABLED &&
|
||||
(dev->cap_dev.stream[RKISP_STREAM_SP].linked ||
|
||||
dev->cap_dev.stream[RKISP_STREAM_MP].linked))
|
||||
goto err;
|
||||
dev->mpfbc_dev.linked = flags & MEDIA_LNK_FL_ENABLED;
|
||||
} else {
|
||||
if (flags & MEDIA_LNK_FL_ENABLED) {
|
||||
if (dev->isp_inp & ~(INP_DVP | rawrd))
|
||||
@@ -1614,6 +1635,8 @@ static int rkisp_subdev_link_setup(struct media_entity *entity,
|
||||
}
|
||||
}
|
||||
|
||||
if (stream)
|
||||
stream->linked = flags & MEDIA_LNK_FL_ENABLED;
|
||||
if (dev->isp_inp & rawrd)
|
||||
dev->dmarx_dev.trigger = T_MANUAL;
|
||||
else
|
||||
@@ -1623,8 +1646,11 @@ static int rkisp_subdev_link_setup(struct media_entity *entity,
|
||||
"isp input:0x%x\n", dev->isp_inp);
|
||||
return 0;
|
||||
err:
|
||||
v4l2_err(sd, "dmaread can't work with other input\n"
|
||||
"csi dvp can't work together\n");
|
||||
v4l2_err(sd, "link error %s -> %s\n"
|
||||
"\tdmaread can't work with other input\n"
|
||||
"\tcsi dvp can't work together\n"
|
||||
"\tmpfbc can't work with mainpath/selfpath\n",
|
||||
local->entity->name, remote->entity->name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user