diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c index 070fe496879b..afb8d552cfc3 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c @@ -126,6 +126,8 @@ #define VOP2_SYS_AXI_BUS_NUM 2 +#define VOP2_CLUSTER_YUV444_10 0x12 + enum vop2_data_format { VOP2_FMT_ARGB8888 = 0, VOP2_FMT_RGB888, @@ -1739,6 +1741,18 @@ static void vop2_plane_atomic_update(struct drm_plane *plane, struct drm_plane_s stride = (fb->pitches[0] << 3) / bpp; 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 + * and Esmart/Smart use different format configuration map: + * YUV420_10BIT: 0x10 for Cluster, 0x14 for Esmart/Smart. + * + * This is one thing we can make the convert simple: + * AFBCD decode all the YUV data to YUV444. So we just + * set all the yuv 10 bit to YUV444_10. + */ + if (fb->format->is_yuv && (bpp == 10)) + format = VOP2_CLUSTER_YUV444_10; + afbc_half_block_en = vop2_afbc_half_block_enable(vpstate); VOP_AFBC_SET(vop2, win, enable, 1); VOP_AFBC_SET(vop2, win, format, afbc_format);