From adb720fcce2f5ae92cee9761d484039d98eb2c00 Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Mon, 3 Nov 2025 12:03:01 +0000 Subject: [PATCH] drm/vc4: plane: Swap Cb/Cr pointers for YVU formats hvs6 appears to have dropped support for the component order field in 3 plane YUV formats. Support them by swapping the Cb and Cr planes over when reading the image pointers. Signed-off-by: Dave Stevenson --- drivers/gpu/drm/vc4/vc4_plane.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c index 4eb9a63255fb12..cb57de2c66da4d 100644 --- a/drivers/gpu/drm/vc4/vc4_plane.c +++ b/drivers/gpu/drm/vc4/vc4_plane.c @@ -37,6 +37,7 @@ static const struct hvs_format { u32 pixel_order_hvs5; bool hvs5_only; bool hvs6_only; + bool hvs6_swap_chroma_pointers; } hvs_formats[] = { { .drm = DRM_FORMAT_XRGB8888, @@ -109,6 +110,7 @@ static const struct hvs_format { .hvs = HVS_PIXEL_FORMAT_YCBCR_YUV422_3PLANE, .pixel_order = HVS_PIXEL_ORDER_XYCRCB, .pixel_order_hvs5 = HVS_PIXEL_ORDER_XYCRCB, + .hvs6_swap_chroma_pointers = true, }, { .drm = DRM_FORMAT_YUV444, @@ -121,6 +123,7 @@ static const struct hvs_format { .hvs = HVS_PIXEL_FORMAT_YCBCR_YUV422_3PLANE, .pixel_order = HVS_PIXEL_ORDER_XYCRCB, .pixel_order_hvs5 = HVS_PIXEL_ORDER_XYCRCB, + .hvs6_swap_chroma_pointers = true, }, { .drm = DRM_FORMAT_YUV420, @@ -133,6 +136,7 @@ static const struct hvs_format { .hvs = HVS_PIXEL_FORMAT_YCBCR_YUV420_3PLANE, .pixel_order = HVS_PIXEL_ORDER_XYCRCB, .pixel_order_hvs5 = HVS_PIXEL_ORDER_XYCRCB, + .hvs6_swap_chroma_pointers = true, }, { .drm = DRM_FORMAT_NV12, @@ -1870,6 +1874,14 @@ static u32 vc6_plane_get_csc_mode(struct vc4_plane_state *vc4_state) return ret; } +static int vc6_get_plane_idx(const struct hvs_format *format, int plane) +{ + if (!plane || !format->hvs6_swap_chroma_pointers) + return plane; + + return (plane == 1) ? 2 : 1; +} + static int vc6_plane_mode_set(struct drm_plane *plane, struct drm_plane_state *state) { @@ -2162,7 +2174,8 @@ static int vc6_plane_mode_set(struct drm_plane *plane, * TODO: This only covers Raster Scan Order planes */ for (i = 0; i < num_planes; i++) { - struct drm_gem_dma_object *bo = drm_fb_dma_get_gem_obj(fb, i); + struct drm_gem_dma_object *bo = + drm_fb_dma_get_gem_obj(fb, vc6_get_plane_idx(format, i)); dma_addr_t paddr = bo->dma_addr + fb->offsets[i] + offsets[i]; /* Pointer Word 0 */