mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-05 18:41:58 +09:00
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:
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user