media: rockchip: vpss: online support tile write

Signed-off-by: Mingwei Yan <mingwei.yan@rock-chips.com>
Change-Id: Iab4ca3d82315222543c5f98b5adb8847ed872b3b
This commit is contained in:
Mingwei Yan
2024-10-22 17:39:59 +08:00
committed by Tao Huang
parent 22ff58327e
commit 46b9b70ded

View File

@@ -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);
}