YUV444 (aka YCbCr444) output isn't working quite right on RK3588. The
resulting image on the display, while identifying itself as YUV444, has
some components swapped, even after adding the necessary DRM formats to
the conversion functions.
Judging by downstream, this is because YUV444 also needs an rb swap
performed in the AFBC case.
Add the DRM formats to the appropriate switch statements, and add a
function for checking whether an rb swap needs to be performed in the
AFBC case.
Fixes: 604be85547ce ("drm/rockchip: Add VOP2 driver")
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
---
drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index 498df0ce4680..f1252d1f06e9 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -176,6 +176,7 @@ static enum vop2_data_format vop2_convert_format(u32 format)
case DRM_FORMAT_ARGB2101010:
case DRM_FORMAT_XBGR2101010:
case DRM_FORMAT_ABGR2101010:
+ case DRM_FORMAT_VUY101010:
return VOP2_FMT_XRGB101010;
case DRM_FORMAT_XRGB8888:
case DRM_FORMAT_ARGB8888:
@@ -184,6 +185,7 @@ static enum vop2_data_format vop2_convert_format(u32 format)
return VOP2_FMT_ARGB8888;
case DRM_FORMAT_RGB888:
case DRM_FORMAT_BGR888:
+ case DRM_FORMAT_VUY888:
return VOP2_FMT_RGB888;
case DRM_FORMAT_RGB565:
case DRM_FORMAT_BGR565:
@@ -225,6 +227,7 @@ static enum vop2_afbc_format vop2_convert_afbc_format(u32 format)
case DRM_FORMAT_ARGB2101010:
case DRM_FORMAT_XBGR2101010:
case DRM_FORMAT_ABGR2101010:
+ case DRM_FORMAT_VUY101010:
return VOP2_AFBC_FMT_ARGB2101010;
case DRM_FORMAT_XRGB8888:
case DRM_FORMAT_ARGB8888:
@@ -233,6 +236,7 @@ static enum vop2_afbc_format vop2_convert_afbc_format(u32 format)
return VOP2_AFBC_FMT_ARGB8888;
case DRM_FORMAT_RGB888:
case DRM_FORMAT_BGR888:
+ case DRM_FORMAT_VUY888:
return VOP2_AFBC_FMT_RGB888;
case DRM_FORMAT_RGB565:
case DRM_FORMAT_BGR565:
@@ -270,6 +274,19 @@ static bool vop2_win_rb_swap(u32 format)
}
}
+static bool vop2_afbc_rb_swap(u32 format)
+{
+ switch (format) {
+ case DRM_FORMAT_NV24:
+ case DRM_FORMAT_NV30:
+ case DRM_FORMAT_VUY888:
+ case DRM_FORMAT_VUY101010:
+ return true;
+ default:
+ return false;
+ }
+}
+
static bool vop2_afbc_uv_swap(u32 format)
{
switch (format) {
@@ -1304,6 +1321,7 @@ static void vop2_plane_atomic_update(struct drm_plane *plane,
/* It's for head stride, each head size is 16 byte */
stride = ALIGN(stride, block_w) / block_w * 16;
+ rb_swap = vop2_afbc_rb_swap(fb->format->format);
uv_swap = vop2_afbc_uv_swap(fb->format->format);
/*
* This is a workaround for crazy IC design, Cluster
@@ -1321,6 +1339,7 @@ static void vop2_plane_atomic_update(struct drm_plane *plane,
vop2_win_write(win, VOP2_WIN_AFBC_ENABLE, 1);
vop2_win_write(win, VOP2_WIN_AFBC_FORMAT, afbc_format);
vop2_win_write(win, VOP2_WIN_AFBC_UV_SWAP, uv_swap);
+ vop2_win_write(win, VOP2_WIN_AFBC_RB_SWAP, rb_swap);
/*
* On rk3566/8, this bit is auto gating enable,
* but this function is not work well so we need
--
2.52.0