|
|
|
|
@@ -25,7 +25,7 @@ static int rkvpss_stream_crop(struct rkvpss_stream *stream, bool on, bool sync);
|
|
|
|
|
static int rkvpss_stream_scale(struct rkvpss_stream *stream, bool on, bool sync);
|
|
|
|
|
static void rkvpss_stream_mf(struct rkvpss_stream *stream);
|
|
|
|
|
|
|
|
|
|
static const struct capture_fmt scl_fmts[] = {
|
|
|
|
|
static const struct capture_fmt scl0_fmts[] = {
|
|
|
|
|
{
|
|
|
|
|
.fourcc = V4L2_PIX_FMT_NV16,
|
|
|
|
|
.fmt_type = FMT_YUV,
|
|
|
|
|
@@ -89,6 +89,24 @@ static const struct capture_fmt scl_fmts[] = {
|
|
|
|
|
.swap = 0,
|
|
|
|
|
.wr_fmt = RKVPSS_MI_CHN_WR_422P,
|
|
|
|
|
.output_fmt = RKVPSS_MI_CHN_WR_OUTPUT_YUV422,
|
|
|
|
|
}, {
|
|
|
|
|
.fourcc = V4L2_PIX_FMT_TILE420,
|
|
|
|
|
.fmt_type = FMT_YUV,
|
|
|
|
|
.bpp = { 24 },
|
|
|
|
|
.cplanes = 1,
|
|
|
|
|
.mplanes = 1,
|
|
|
|
|
.swap = 0,
|
|
|
|
|
.wr_fmt = 0,
|
|
|
|
|
.output_fmt = RKVPSS_MI_CHN_WR_OUTPUT_YUV420,
|
|
|
|
|
}, {
|
|
|
|
|
.fourcc = V4L2_PIX_FMT_TILE422,
|
|
|
|
|
.fmt_type = FMT_YUV,
|
|
|
|
|
.bpp = { 32 },
|
|
|
|
|
.cplanes = 1,
|
|
|
|
|
.mplanes = 1,
|
|
|
|
|
.swap = 0,
|
|
|
|
|
.wr_fmt = 0,
|
|
|
|
|
.output_fmt = RKVPSS_MI_CHN_WR_OUTPUT_YUV422,
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
@@ -210,12 +228,98 @@ static const struct capture_fmt scl1_fmts[] = {
|
|
|
|
|
.swap = 0,
|
|
|
|
|
.wr_fmt = RKVPSS_MI_CHN_WR_422P,
|
|
|
|
|
.output_fmt = RKVPSS_MI_CHN_WR_OUTPUT_YUV422,
|
|
|
|
|
}, {
|
|
|
|
|
.fourcc = V4L2_PIX_FMT_TILE420,
|
|
|
|
|
.fmt_type = FMT_YUV,
|
|
|
|
|
.bpp = { 24 },
|
|
|
|
|
.cplanes = 1,
|
|
|
|
|
.mplanes = 1,
|
|
|
|
|
.swap = 0,
|
|
|
|
|
.wr_fmt = 0,
|
|
|
|
|
.output_fmt = RKVPSS_MI_CHN_WR_OUTPUT_YUV420,
|
|
|
|
|
}, {
|
|
|
|
|
.fourcc = V4L2_PIX_FMT_TILE422,
|
|
|
|
|
.fmt_type = FMT_YUV,
|
|
|
|
|
.bpp = { 32 },
|
|
|
|
|
.cplanes = 1,
|
|
|
|
|
.mplanes = 1,
|
|
|
|
|
.swap = 0,
|
|
|
|
|
.wr_fmt = 0,
|
|
|
|
|
.output_fmt = RKVPSS_MI_CHN_WR_OUTPUT_YUV422,
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static const struct capture_fmt scl2_3_fmts[] = {
|
|
|
|
|
{
|
|
|
|
|
.fourcc = V4L2_PIX_FMT_NV16,
|
|
|
|
|
.fmt_type = FMT_YUV,
|
|
|
|
|
.bpp = { 8, 16 },
|
|
|
|
|
.cplanes = 2,
|
|
|
|
|
.mplanes = 1,
|
|
|
|
|
.swap = 0,
|
|
|
|
|
.wr_fmt = RKVPSS_MI_CHN_WR_42XSP,
|
|
|
|
|
.output_fmt = RKVPSS_MI_CHN_WR_OUTPUT_YUV422,
|
|
|
|
|
}, {
|
|
|
|
|
.fourcc = V4L2_PIX_FMT_NV12,
|
|
|
|
|
.fmt_type = FMT_YUV,
|
|
|
|
|
.bpp = { 8, 16 },
|
|
|
|
|
.cplanes = 2,
|
|
|
|
|
.mplanes = 1,
|
|
|
|
|
.swap = 0,
|
|
|
|
|
.wr_fmt = RKVPSS_MI_CHN_WR_42XSP,
|
|
|
|
|
.output_fmt = RKVPSS_MI_CHN_WR_OUTPUT_YUV420,
|
|
|
|
|
}, {
|
|
|
|
|
.fourcc = V4L2_PIX_FMT_GREY,
|
|
|
|
|
.fmt_type = FMT_YUV,
|
|
|
|
|
.bpp = { 8 },
|
|
|
|
|
.cplanes = 1,
|
|
|
|
|
.mplanes = 1,
|
|
|
|
|
.swap = 0,
|
|
|
|
|
.wr_fmt = RKVPSS_MI_CHN_WR_42XSP,
|
|
|
|
|
.output_fmt = RKVPSS_MI_CHN_WR_OUTPUT_YUV400,
|
|
|
|
|
}, {
|
|
|
|
|
.fourcc = V4L2_PIX_FMT_UYVY,
|
|
|
|
|
.fmt_type = FMT_YUV,
|
|
|
|
|
.bpp = { 16 },
|
|
|
|
|
.cplanes = 1,
|
|
|
|
|
.mplanes = 1,
|
|
|
|
|
.swap = 0,
|
|
|
|
|
.wr_fmt = RKVPSS_MI_CHN_WR_422P,
|
|
|
|
|
.output_fmt = RKVPSS_MI_CHN_WR_OUTPUT_YUV422,
|
|
|
|
|
}, {
|
|
|
|
|
.fourcc = V4L2_PIX_FMT_NV61,
|
|
|
|
|
.fmt_type = FMT_YUV,
|
|
|
|
|
.bpp = { 8, 16 },
|
|
|
|
|
.cplanes = 2,
|
|
|
|
|
.mplanes = 1,
|
|
|
|
|
.swap = 0,
|
|
|
|
|
.wr_fmt = RKVPSS_MI_CHN_WR_42XSP,
|
|
|
|
|
.output_fmt = RKVPSS_MI_CHN_WR_OUTPUT_YUV422,
|
|
|
|
|
}, {
|
|
|
|
|
.fourcc = V4L2_PIX_FMT_NV21,
|
|
|
|
|
.fmt_type = FMT_YUV,
|
|
|
|
|
.bpp = { 8, 16 },
|
|
|
|
|
.cplanes = 2,
|
|
|
|
|
.mplanes = 1,
|
|
|
|
|
.swap = 0,
|
|
|
|
|
.wr_fmt = RKVPSS_MI_CHN_WR_42XSP,
|
|
|
|
|
.output_fmt = RKVPSS_MI_CHN_WR_OUTPUT_YUV420,
|
|
|
|
|
}, {
|
|
|
|
|
.fourcc = V4L2_PIX_FMT_VYUY,
|
|
|
|
|
.fmt_type = FMT_YUV,
|
|
|
|
|
.bpp = { 16 },
|
|
|
|
|
.cplanes = 1,
|
|
|
|
|
.mplanes = 1,
|
|
|
|
|
.swap = 0,
|
|
|
|
|
.wr_fmt = RKVPSS_MI_CHN_WR_422P,
|
|
|
|
|
.output_fmt = RKVPSS_MI_CHN_WR_OUTPUT_YUV422,
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static struct stream_config scl0_config = {
|
|
|
|
|
.fmts = scl_fmts,
|
|
|
|
|
.fmt_size = ARRAY_SIZE(scl_fmts),
|
|
|
|
|
.fmts = scl0_fmts,
|
|
|
|
|
.fmt_size = ARRAY_SIZE(scl0_fmts),
|
|
|
|
|
.frame_end_id = RKVPSS_MI_CHN0_FRM_END,
|
|
|
|
|
.crop = {
|
|
|
|
|
.ctrl = RKVPSS_CROP1_CTRL,
|
|
|
|
|
@@ -319,8 +423,8 @@ static struct stream_config scl1_config = {
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static struct stream_config scl2_config = {
|
|
|
|
|
.fmts = scl_fmts,
|
|
|
|
|
.fmt_size = ARRAY_SIZE(scl_fmts),
|
|
|
|
|
.fmts = scl2_3_fmts,
|
|
|
|
|
.fmt_size = ARRAY_SIZE(scl2_3_fmts),
|
|
|
|
|
.frame_end_id = RKVPSS_MI_CHN2_FRM_END,
|
|
|
|
|
.crop = {
|
|
|
|
|
.ctrl = RKVPSS_CROP1_CTRL,
|
|
|
|
|
@@ -389,8 +493,8 @@ static struct stream_config scl2_config = {
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static struct stream_config scl3_config = {
|
|
|
|
|
.fmts = scl_fmts,
|
|
|
|
|
.fmt_size = ARRAY_SIZE(scl_fmts),
|
|
|
|
|
.fmts = scl2_3_fmts,
|
|
|
|
|
.fmt_size = ARRAY_SIZE(scl2_3_fmts),
|
|
|
|
|
.frame_end_id = RKVPSS_MI_CHN3_FRM_END,
|
|
|
|
|
.crop = {
|
|
|
|
|
.ctrl = RKVPSS_CROP1_CTRL,
|
|
|
|
|
@@ -689,6 +793,15 @@ static void scl_config_mi(struct rkvpss_stream *stream)
|
|
|
|
|
mask = RKVPSS_MI_WR_UV_SWAP;
|
|
|
|
|
val = RKVPSS_MI_WR_UV_SWAP;
|
|
|
|
|
rkvpss_hw_set_bits(dev->hw_dev, RKVPSS_MI_WR_CTRL, mask, val);
|
|
|
|
|
break;
|
|
|
|
|
case V4L2_PIX_FMT_TILE420:
|
|
|
|
|
case V4L2_PIX_FMT_TILE422:
|
|
|
|
|
mask = RKVPSS_MI_WR_TILE_SEL(3);
|
|
|
|
|
val = RKVPSS_MI_WR_TILE_SEL(stream->id + 1);
|
|
|
|
|
rkvpss_hw_set_bits(dev->hw_dev, RKVPSS_MI_WR_CTRL, mask, val);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
stream->is_mf_upd = true;
|
|
|
|
|
@@ -1775,6 +1888,28 @@ static int rkvpss_set_fmt(struct rkvpss_stream *stream,
|
|
|
|
|
return -EINVAL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Tile4x4 writing of Channel0 and Channel1 only supports either one.*/
|
|
|
|
|
if (fmt->fourcc == V4L2_PIX_FMT_TILE420 || fmt->fourcc == V4L2_PIX_FMT_TILE422) {
|
|
|
|
|
if (stream->id == 0) {
|
|
|
|
|
if (dev->stream_vdev.stream[1].streaming &&
|
|
|
|
|
(dev->stream_vdev.stream[1].out_cap_fmt.fourcc == V4L2_PIX_FMT_TILE420 ||
|
|
|
|
|
dev->stream_vdev.stream[1].out_cap_fmt.fourcc == V4L2_PIX_FMT_TILE422)) {
|
|
|
|
|
v4l2_err(&dev->v4l2_dev,
|
|
|
|
|
"Tile4x4 writing of Ch0 and Cl1 only supports either one\n");
|
|
|
|
|
return -EINVAL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (stream->id == 1) {
|
|
|
|
|
if (dev->stream_vdev.stream[0].streaming &&
|
|
|
|
|
(dev->stream_vdev.stream[0].out_cap_fmt.fourcc == V4L2_PIX_FMT_TILE420 ||
|
|
|
|
|
dev->stream_vdev.stream[0].out_cap_fmt.fourcc == V4L2_PIX_FMT_TILE422)) {
|
|
|
|
|
v4l2_err(&dev->v4l2_dev,
|
|
|
|
|
"Tile4x4 writing of Ch0 and Cl1 only supports either one\n");
|
|
|
|
|
return -EINVAL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pixm->num_planes = fmt->mplanes;
|
|
|
|
|
pixm->field = V4L2_FIELD_NONE;
|
|
|
|
|
if (!pixm->quantization)
|
|
|
|
|
@@ -1790,10 +1925,20 @@ static int rkvpss_set_fmt(struct rkvpss_stream *stream,
|
|
|
|
|
h = pixm->height;
|
|
|
|
|
width = i ? w / xsubs : w;
|
|
|
|
|
height = i ? h / ysubs : h;
|
|
|
|
|
bytesperline = width * DIV_ROUND_UP(fmt->bpp[i], 8);
|
|
|
|
|
|
|
|
|
|
if (fmt->fourcc == V4L2_PIX_FMT_TILE420 || fmt->fourcc == V4L2_PIX_FMT_TILE422)
|
|
|
|
|
bytesperline = ALIGN(((width / 4) * fmt->bpp[i]), 16);
|
|
|
|
|
else
|
|
|
|
|
bytesperline = width * DIV_ROUND_UP(fmt->bpp[i], 8);
|
|
|
|
|
|
|
|
|
|
if (i != 0 || plane_fmt->bytesperline < bytesperline)
|
|
|
|
|
plane_fmt->bytesperline = bytesperline;
|
|
|
|
|
plane_fmt->sizeimage = plane_fmt->bytesperline * height;
|
|
|
|
|
|
|
|
|
|
if (fmt->fourcc == V4L2_PIX_FMT_TILE420 || fmt->fourcc == V4L2_PIX_FMT_TILE422)
|
|
|
|
|
plane_fmt->sizeimage = plane_fmt->bytesperline * (height / 4);
|
|
|
|
|
else
|
|
|
|
|
plane_fmt->sizeimage = plane_fmt->bytesperline * height;
|
|
|
|
|
|
|
|
|
|
imagsize += plane_fmt->sizeimage;
|
|
|
|
|
}
|
|
|
|
|
if (fmt->mplanes == 1)
|
|
|
|
|
@@ -1886,6 +2031,21 @@ static int rkvpss_enum_fmt_vid_mplane(struct file *file, void *priv,
|
|
|
|
|
fmt = &stream->config->fmts[f->index];
|
|
|
|
|
f->pixelformat = fmt->fourcc;
|
|
|
|
|
|
|
|
|
|
switch (f->pixelformat) {
|
|
|
|
|
case V4L2_PIX_FMT_TILE420:
|
|
|
|
|
strscpy(f->description,
|
|
|
|
|
"Rockchip yuv420 tile",
|
|
|
|
|
sizeof(f->description));
|
|
|
|
|
break;
|
|
|
|
|
case V4L2_PIX_FMT_TILE422:
|
|
|
|
|
strscpy(f->description,
|
|
|
|
|
"Rockchip yuv422 tile",
|
|
|
|
|
sizeof(f->description));
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -1998,6 +2158,10 @@ static void rkvpss_stream_mf(struct rkvpss_stream *stream)
|
|
|
|
|
rkvpss_unite_set_bits(dev, RKVPSS_VPSS_CTRL, mask, val);
|
|
|
|
|
}
|
|
|
|
|
mask = RKVPSS_MI_CHN_V_FLIP(stream->id);
|
|
|
|
|
/* Tile4x4 writing can't flip*/
|
|
|
|
|
if (stream->out_cap_fmt.fourcc == V4L2_PIX_FMT_TILE420 ||
|
|
|
|
|
stream->out_cap_fmt.fourcc == V4L2_PIX_FMT_TILE422)
|
|
|
|
|
stream->flip_en = false;
|
|
|
|
|
val = stream->flip_en ? mask : 0;
|
|
|
|
|
rkvpss_unite_set_bits(dev, RKVPSS_MI_WR_VFLIP_CTRL, mask, val);
|
|
|
|
|
}
|
|
|
|
|
|