]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
drm/vc4: plane: Add support for YUV444 formats
authorDom Cobley <popcornmix@gmail.com>
Fri, 21 Jun 2024 15:20:29 +0000 (16:20 +0100)
committerDave Stevenson <dave.stevenson@raspberrypi.com>
Mon, 9 Sep 2024 12:02:52 +0000 (13:02 +0100)
Support displaying DRM_FORMAT_YUV444 and DRM_FORMAT_YVU444 formats.
Tested with kmstest and kodi. e.g.

kmstest -r 1920x1080@60 -f 400x300-YU24

Note: without the shift of width, only half the chroma is fetched,
resulting in correct left half of image and corrupt colours on right half.

The increase in width shouldn't affect fetching of Y data,
as the hardware will clamp at dest width.

Signed-off-by: Dom Cobley <popcornmix@gmail.com>
Reviewed-by: Maxime Ripard <mripard@kernel.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20240621152055.4180873-6-dave.stevenson@raspberrypi.com
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
drivers/gpu/drm/vc4/vc4_plane.c

index b8c68d4688c8b60186e5cc557de06742d4855a22..978433554f3d9ce8e27848cd46641c2f364b1af3 100644 (file)
@@ -109,6 +109,18 @@ static const struct hvs_format {
                .pixel_order = HVS_PIXEL_ORDER_XYCRCB,
                .pixel_order_hvs5 = HVS_PIXEL_ORDER_XYCRCB,
        },
+       {
+               .drm = DRM_FORMAT_YUV444,
+               .hvs = HVS_PIXEL_FORMAT_YCBCR_YUV422_3PLANE,
+               .pixel_order = HVS_PIXEL_ORDER_XYCBCR,
+               .pixel_order_hvs5 = HVS_PIXEL_ORDER_XYCBCR,
+       },
+       {
+               .drm = DRM_FORMAT_YVU444,
+               .hvs = HVS_PIXEL_FORMAT_YCBCR_YUV422_3PLANE,
+               .pixel_order = HVS_PIXEL_ORDER_XYCRCB,
+               .pixel_order_hvs5 = HVS_PIXEL_ORDER_XYCRCB,
+       },
        {
                .drm = DRM_FORMAT_YUV420,
                .hvs = HVS_PIXEL_FORMAT_YCBCR_YUV420_3PLANE,
@@ -1117,6 +1129,12 @@ static int vc4_plane_mode_set(struct drm_plane *plane,
            vc4_state->src_y + vc4_state->src_h[0] < (state->fb->height << 16))
                height++;
 
+       /* For YUV444 the hardware wants double the width, otherwise it doesn't
+        * fetch full width of chroma
+        */
+       if (format->drm == DRM_FORMAT_YUV444 || format->drm == DRM_FORMAT_YVU444)
+               width <<= 1;
+
        /* Don't waste cycles mixing with plane alpha if the set alpha
         * is opaque or there is no per-pixel alpha information.
         * In any case we use the alpha property value as the fixed alpha.