Commit 9b744a3e authored by Niklas Söderlund's avatar Niklas Söderlund Committed by Mauro Carvalho Chehab

media: rcar-vin: Add support for outputting NV12

Most Gen3 boards can output frames in NV12 format, add support for this
with a runtime check that the running hardware supports it.
Signed-off-by: default avatarNiklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
Reviewed-by: default avatarSimon Horman <horms+renesas@verge.net.au>
Signed-off-by: default avatarHans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@kernel.org>
parent f8fe466a
...@@ -118,6 +118,7 @@ ...@@ -118,6 +118,7 @@
#define VNDMR_ABIT (1 << 2) #define VNDMR_ABIT (1 << 2)
#define VNDMR_DTMD_YCSEP (1 << 1) #define VNDMR_DTMD_YCSEP (1 << 1)
#define VNDMR_DTMD_ARGB (1 << 0) #define VNDMR_DTMD_ARGB (1 << 0)
#define VNDMR_DTMD_YCSEP_420 (3 << 0)
/* Video n Data Mode Register 2 bits */ /* Video n Data Mode Register 2 bits */
#define VNDMR2_VPS (1 << 30) #define VNDMR2_VPS (1 << 30)
...@@ -701,11 +702,13 @@ static int rvin_setup(struct rvin_dev *vin) ...@@ -701,11 +702,13 @@ static int rvin_setup(struct rvin_dev *vin)
* Output format * Output format
*/ */
switch (vin->format.pixelformat) { switch (vin->format.pixelformat) {
case V4L2_PIX_FMT_NV12:
case V4L2_PIX_FMT_NV16: case V4L2_PIX_FMT_NV16:
rvin_write(vin, rvin_write(vin,
ALIGN(vin->format.bytesperline * vin->format.height, ALIGN(vin->format.bytesperline * vin->format.height,
0x80), VNUVAOF_REG); 0x80), VNUVAOF_REG);
dmr = VNDMR_DTMD_YCSEP; dmr = vin->format.pixelformat == V4L2_PIX_FMT_NV12 ?
VNDMR_DTMD_YCSEP_420 : VNDMR_DTMD_YCSEP;
output_is_yuv = true; output_is_yuv = true;
break; break;
case V4L2_PIX_FMT_YUYV: case V4L2_PIX_FMT_YUYV:
......
...@@ -30,6 +30,10 @@ ...@@ -30,6 +30,10 @@
*/ */
static const struct rvin_video_format rvin_formats[] = { static const struct rvin_video_format rvin_formats[] = {
{
.fourcc = V4L2_PIX_FMT_NV12,
.bpp = 1,
},
{ {
.fourcc = V4L2_PIX_FMT_NV16, .fourcc = V4L2_PIX_FMT_NV16,
.bpp = 1, .bpp = 1,
...@@ -72,6 +76,9 @@ const struct rvin_video_format *rvin_format_from_pixel(struct rvin_dev *vin, ...@@ -72,6 +76,9 @@ const struct rvin_video_format *rvin_format_from_pixel(struct rvin_dev *vin,
if (vin->info->model == RCAR_M1 && pixelformat == V4L2_PIX_FMT_XBGR32) if (vin->info->model == RCAR_M1 && pixelformat == V4L2_PIX_FMT_XBGR32)
return NULL; return NULL;
if (pixelformat == V4L2_PIX_FMT_NV12 && !vin->info->nv12)
return NULL;
for (i = 0; i < ARRAY_SIZE(rvin_formats); i++) for (i = 0; i < ARRAY_SIZE(rvin_formats); i++)
if (rvin_formats[i].fourcc == pixelformat) if (rvin_formats[i].fourcc == pixelformat)
return rvin_formats + i; return rvin_formats + i;
...@@ -90,17 +97,29 @@ static u32 rvin_format_bytesperline(struct rvin_dev *vin, ...@@ -90,17 +97,29 @@ static u32 rvin_format_bytesperline(struct rvin_dev *vin,
if (WARN_ON(!fmt)) if (WARN_ON(!fmt))
return -EINVAL; return -EINVAL;
align = pix->pixelformat == V4L2_PIX_FMT_NV16 ? 0x20 : 0x10; switch (pix->pixelformat) {
case V4L2_PIX_FMT_NV12:
case V4L2_PIX_FMT_NV16:
align = 0x20;
break;
default:
align = 0x10;
break;
}
return ALIGN(pix->width, align) * fmt->bpp; return ALIGN(pix->width, align) * fmt->bpp;
} }
static u32 rvin_format_sizeimage(struct v4l2_pix_format *pix) static u32 rvin_format_sizeimage(struct v4l2_pix_format *pix)
{ {
if (pix->pixelformat == V4L2_PIX_FMT_NV16) switch (pix->pixelformat) {
case V4L2_PIX_FMT_NV12:
return pix->bytesperline * pix->height * 3 / 2;
case V4L2_PIX_FMT_NV16:
return pix->bytesperline * pix->height * 2; return pix->bytesperline * pix->height * 2;
default:
return pix->bytesperline * pix->height; return pix->bytesperline * pix->height;
}
} }
static void rvin_format_align(struct rvin_dev *vin, struct v4l2_pix_format *pix) static void rvin_format_align(struct rvin_dev *vin, struct v4l2_pix_format *pix)
...@@ -124,8 +143,16 @@ static void rvin_format_align(struct rvin_dev *vin, struct v4l2_pix_format *pix) ...@@ -124,8 +143,16 @@ static void rvin_format_align(struct rvin_dev *vin, struct v4l2_pix_format *pix)
break; break;
} }
/* HW limit width to a multiple of 32 (2^5) for NV16 else 2 (2^1) */ /* HW limit width to a multiple of 32 (2^5) for NV12/16 else 2 (2^1) */
walign = vin->format.pixelformat == V4L2_PIX_FMT_NV16 ? 5 : 1; switch (vin->format.pixelformat) {
case V4L2_PIX_FMT_NV12:
case V4L2_PIX_FMT_NV16:
walign = 5;
break;
default:
walign = 1;
break;
}
/* Limit to VIN capabilities */ /* Limit to VIN capabilities */
v4l_bound_align_image(&pix->width, 2, vin->info->max_width, walign, v4l_bound_align_image(&pix->width, 2, vin->info->max_width, walign,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment