summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>2020-08-06 05:24:34 +0300
committerLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>2020-09-22 14:10:05 +0300
commitdc86d6bc9bc3d0080bd18b54777a22b70eae4aa6 (patch)
tree1f91fc9577d653c4f799237839697129291f485a
parentef84ad32f41c2b84560ca3577fb0cb85dd4895fb (diff)
drm: rcar-du: Fix pitch handling for fully planar YUV formats
When creating a frame buffer, the driver verifies that the pitches for the chroma planes match the luma plane. This is done incorrectly for fully planar YUV formats, without taking horizontal subsampling into account. Fix it. Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_kms.c54
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_kms.h1
2 files changed, 53 insertions, 2 deletions
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.c b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
index 482329102f19..72dda446355f 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_kms.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
@@ -40,6 +40,7 @@ static const struct rcar_du_format_info rcar_du_format_infos[] = {
.v4l2 = V4L2_PIX_FMT_RGB565,
.bpp = 16,
.planes = 1,
+ .hsub = 1,
.pnmr = PnMR_SPIM_TP | PnMR_DDDF_16BPP,
.edf = PnDDCR4_EDF_NONE,
}, {
@@ -47,6 +48,7 @@ static const struct rcar_du_format_info rcar_du_format_infos[] = {
.v4l2 = V4L2_PIX_FMT_ARGB555,
.bpp = 16,
.planes = 1,
+ .hsub = 1,
.pnmr = PnMR_SPIM_ALP | PnMR_DDDF_ARGB,
.edf = PnDDCR4_EDF_NONE,
}, {
@@ -61,6 +63,7 @@ static const struct rcar_du_format_info rcar_du_format_infos[] = {
.v4l2 = V4L2_PIX_FMT_XBGR32,
.bpp = 32,
.planes = 1,
+ .hsub = 1,
.pnmr = PnMR_SPIM_TP | PnMR_DDDF_16BPP,
.edf = PnDDCR4_EDF_RGB888,
}, {
@@ -68,6 +71,7 @@ static const struct rcar_du_format_info rcar_du_format_infos[] = {
.v4l2 = V4L2_PIX_FMT_ABGR32,
.bpp = 32,
.planes = 1,
+ .hsub = 1,
.pnmr = PnMR_SPIM_ALP | PnMR_DDDF_16BPP,
.edf = PnDDCR4_EDF_ARGB8888,
}, {
@@ -75,6 +79,7 @@ static const struct rcar_du_format_info rcar_du_format_infos[] = {
.v4l2 = V4L2_PIX_FMT_UYVY,
.bpp = 16,
.planes = 1,
+ .hsub = 2,
.pnmr = PnMR_SPIM_TP_OFF | PnMR_DDDF_YC,
.edf = PnDDCR4_EDF_NONE,
}, {
@@ -82,6 +87,7 @@ static const struct rcar_du_format_info rcar_du_format_infos[] = {
.v4l2 = V4L2_PIX_FMT_YUYV,
.bpp = 16,
.planes = 1,
+ .hsub = 2,
.pnmr = PnMR_SPIM_TP_OFF | PnMR_DDDF_YC,
.edf = PnDDCR4_EDF_NONE,
}, {
@@ -89,6 +95,7 @@ static const struct rcar_du_format_info rcar_du_format_infos[] = {
.v4l2 = V4L2_PIX_FMT_NV12M,
.bpp = 12,
.planes = 2,
+ .hsub = 2,
.pnmr = PnMR_SPIM_TP_OFF | PnMR_DDDF_YC,
.edf = PnDDCR4_EDF_NONE,
}, {
@@ -96,6 +103,7 @@ static const struct rcar_du_format_info rcar_du_format_infos[] = {
.v4l2 = V4L2_PIX_FMT_NV21M,
.bpp = 12,
.planes = 2,
+ .hsub = 2,
.pnmr = PnMR_SPIM_TP_OFF | PnMR_DDDF_YC,
.edf = PnDDCR4_EDF_NONE,
}, {
@@ -103,6 +111,7 @@ static const struct rcar_du_format_info rcar_du_format_infos[] = {
.v4l2 = V4L2_PIX_FMT_NV16M,
.bpp = 16,
.planes = 2,
+ .hsub = 2,
.pnmr = PnMR_SPIM_TP_OFF | PnMR_DDDF_YC,
.edf = PnDDCR4_EDF_NONE,
},
@@ -115,156 +124,187 @@ static const struct rcar_du_format_info rcar_du_format_infos[] = {
.v4l2 = V4L2_PIX_FMT_RGB332,
.bpp = 8,
.planes = 1,
+ .hsub = 1,
}, {
.fourcc = DRM_FORMAT_ARGB4444,
.v4l2 = V4L2_PIX_FMT_ARGB444,
.bpp = 16,
.planes = 1,
+ .hsub = 1,
}, {
.fourcc = DRM_FORMAT_XRGB4444,
.v4l2 = V4L2_PIX_FMT_XRGB444,
.bpp = 16,
.planes = 1,
+ .hsub = 1,
}, {
.fourcc = DRM_FORMAT_RGBA4444,
.v4l2 = V4L2_PIX_FMT_RGBA444,
.bpp = 16,
.planes = 1,
+ .hsub = 1,
}, {
.fourcc = DRM_FORMAT_RGBX4444,
.v4l2 = V4L2_PIX_FMT_RGBX444,
.bpp = 16,
.planes = 1,
+ .hsub = 1,
}, {
.fourcc = DRM_FORMAT_ABGR4444,
.v4l2 = V4L2_PIX_FMT_ABGR444,
.bpp = 16,
.planes = 1,
+ .hsub = 1,
}, {
.fourcc = DRM_FORMAT_XBGR4444,
.v4l2 = V4L2_PIX_FMT_XBGR444,
.bpp = 16,
.planes = 1,
+ .hsub = 1,
}, {
.fourcc = DRM_FORMAT_BGRA4444,
.v4l2 = V4L2_PIX_FMT_BGRA444,
.bpp = 16,
.planes = 1,
+ .hsub = 1,
}, {
.fourcc = DRM_FORMAT_BGRX4444,
.v4l2 = V4L2_PIX_FMT_BGRX444,
.bpp = 16,
.planes = 1,
+ .hsub = 1,
}, {
.fourcc = DRM_FORMAT_RGBA5551,
.v4l2 = V4L2_PIX_FMT_RGBA555,
.bpp = 16,
.planes = 1,
+ .hsub = 1,
}, {
.fourcc = DRM_FORMAT_RGBX5551,
.v4l2 = V4L2_PIX_FMT_RGBX555,
.bpp = 16,
.planes = 1,
+ .hsub = 1,
}, {
.fourcc = DRM_FORMAT_ABGR1555,
.v4l2 = V4L2_PIX_FMT_ABGR555,
.bpp = 16,
.planes = 1,
+ .hsub = 1,
}, {
.fourcc = DRM_FORMAT_XBGR1555,
.v4l2 = V4L2_PIX_FMT_XBGR555,
.bpp = 16,
.planes = 1,
+ .hsub = 1,
}, {
.fourcc = DRM_FORMAT_BGRA5551,
.v4l2 = V4L2_PIX_FMT_BGRA555,
.bpp = 16,
.planes = 1,
+ .hsub = 1,
}, {
.fourcc = DRM_FORMAT_BGRX5551,
.v4l2 = V4L2_PIX_FMT_BGRX555,
.bpp = 16,
.planes = 1,
+ .hsub = 1,
}, {
.fourcc = DRM_FORMAT_BGR888,
.v4l2 = V4L2_PIX_FMT_RGB24,
.bpp = 24,
.planes = 1,
+ .hsub = 1,
}, {
.fourcc = DRM_FORMAT_RGB888,
.v4l2 = V4L2_PIX_FMT_BGR24,
.bpp = 24,
.planes = 1,
+ .hsub = 1,
}, {
.fourcc = DRM_FORMAT_RGBA8888,
.v4l2 = V4L2_PIX_FMT_BGRA32,
.bpp = 32,
.planes = 1,
+ .hsub = 1,
}, {
.fourcc = DRM_FORMAT_RGBX8888,
.v4l2 = V4L2_PIX_FMT_BGRX32,
.bpp = 32,
.planes = 1,
+ .hsub = 1,
}, {
.fourcc = DRM_FORMAT_ABGR8888,
.v4l2 = V4L2_PIX_FMT_RGBA32,
.bpp = 32,
.planes = 1,
+ .hsub = 1,
}, {
.fourcc = DRM_FORMAT_XBGR8888,
.v4l2 = V4L2_PIX_FMT_RGBX32,
.bpp = 32,
.planes = 1,
+ .hsub = 1,
}, {
.fourcc = DRM_FORMAT_BGRA8888,
.v4l2 = V4L2_PIX_FMT_ARGB32,
.bpp = 32,
.planes = 1,
+ .hsub = 1,
}, {
.fourcc = DRM_FORMAT_BGRX8888,
.v4l2 = V4L2_PIX_FMT_XRGB32,
.bpp = 32,
.planes = 1,
+ .hsub = 1,
}, {
.fourcc = DRM_FORMAT_YVYU,
.v4l2 = V4L2_PIX_FMT_YVYU,
.bpp = 16,
.planes = 1,
+ .hsub = 2,
}, {
.fourcc = DRM_FORMAT_NV61,
.v4l2 = V4L2_PIX_FMT_NV61M,
.bpp = 16,
.planes = 2,
+ .hsub = 2,
}, {
.fourcc = DRM_FORMAT_YUV420,
.v4l2 = V4L2_PIX_FMT_YUV420M,
.bpp = 12,
.planes = 3,
+ .hsub = 2,
}, {
.fourcc = DRM_FORMAT_YVU420,
.v4l2 = V4L2_PIX_FMT_YVU420M,
.bpp = 12,
.planes = 3,
+ .hsub = 2,
}, {
.fourcc = DRM_FORMAT_YUV422,
.v4l2 = V4L2_PIX_FMT_YUV422M,
.bpp = 16,
.planes = 3,
+ .hsub = 2,
}, {
.fourcc = DRM_FORMAT_YVU422,
.v4l2 = V4L2_PIX_FMT_YVU422M,
.bpp = 16,
.planes = 3,
+ .hsub = 2,
}, {
.fourcc = DRM_FORMAT_YUV444,
.v4l2 = V4L2_PIX_FMT_YUV444M,
.bpp = 24,
.planes = 3,
+ .hsub = 1,
}, {
.fourcc = DRM_FORMAT_YVU444,
.v4l2 = V4L2_PIX_FMT_YVU444M,
.bpp = 24,
.planes = 3,
+ .hsub = 1,
},
};
@@ -311,6 +351,7 @@ rcar_du_fb_create(struct drm_device *dev, struct drm_file *file_priv,
{
struct rcar_du_device *rcdu = dev->dev_private;
const struct rcar_du_format_info *format;
+ unsigned int chroma_pitch;
unsigned int max_pitch;
unsigned int align;
unsigned int i;
@@ -353,10 +394,19 @@ rcar_du_fb_create(struct drm_device *dev, struct drm_file *file_priv,
return ERR_PTR(-EINVAL);
}
+ /*
+ * Calculate the chroma plane(s) pitch using the horizontal subsampling
+ * factor. For semi-planar formats, the U and V planes are combined, the
+ * pitch must thus be doubled.
+ */
+ chroma_pitch = mode_cmd->pitches[0] / format->hsub;
+ if (format->planes == 2)
+ chroma_pitch *= 2;
+
for (i = 1; i < format->planes; ++i) {
- if (mode_cmd->pitches[i] != mode_cmd->pitches[0]) {
+ if (mode_cmd->pitches[i] != chroma_pitch) {
dev_dbg(dev->dev,
- "luma and chroma pitches do not match\n");
+ "luma and chroma pitches are not compatible\n");
return ERR_PTR(-EINVAL);
}
}
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.h b/drivers/gpu/drm/rcar-du/rcar_du_kms.h
index 0346504d8c59..8f5fff176754 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_kms.h
+++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.h
@@ -22,6 +22,7 @@ struct rcar_du_format_info {
u32 v4l2;
unsigned int bpp;
unsigned int planes;
+ unsigned int hsub;
unsigned int pnmr;
unsigned int edf;
};