Hi Jonas, On Thu, 2023-10-26 at 19:14 +0000, Jonas Karlman wrote: > Use of DRM_FORMAT_RGB888 and DRM_FORMAT_BGR888 on e.g. RK3288, RK3328 > and RK3399 result in wrong colors being displayed. > > The issue can be observed using modetest: > > modetest -s <connector_id>@<crtc_id>:1920x1080-60@RG24 > modetest -s <connector_id>@<crtc_id>:1920x1080-60@BG24 > > Vendor 4.4 kernel apply an inverted rb swap for these formats on VOP > full framework (IP version 3.x) compared to VOP little framework (2.x). > > Fix colors by applying different rb swap for VOP full framework (3.x) > and VOP little framework (2.x) similar to vendor 4.4 kernel. > > Fixes: 85a359f25388 ("drm/rockchip: Add BGR formats to VOP") > Signed-off-by: Jonas Karlman <jonas@xxxxxxxxx> Reviewed-by: Christopher Obbard <chris.obbard@xxxxxxxxxxxxx> Tested-by: Christopher Obbard <chris.obbard@xxxxxxxxxxxxx> Since you missed adding my *-by tags in v2. > --- > Changes in v2: > - Add comment about different rb swap for IP version 3.x and 2.x > - Add fixes tag > > drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 14 +++++++++++--- > 1 file changed, 11 insertions(+), 3 deletions(-) > > diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c > b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c > index b3d0b6ae9294..ed2ed25959a2 100644 > --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c > +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c > @@ -247,14 +247,22 @@ static inline void vop_cfg_done(struct vop *vop) > VOP_REG_SET(vop, common, cfg_done, 1); > } > > -static bool has_rb_swapped(uint32_t format) > +static bool has_rb_swapped(uint32_t version, uint32_t format) > { > switch (format) { > case DRM_FORMAT_XBGR8888: > case DRM_FORMAT_ABGR8888: > - case DRM_FORMAT_BGR888: > case DRM_FORMAT_BGR565: > return true; > + /* > + * full framework (IP version 3.x) only need rb swapped for RGB888 > and > + * little framework (IP version 2.x) only need rb swapped for > BGR888, > + * check for 3.x to also only rb swap BGR888 for unknown vop > version > + */ > + case DRM_FORMAT_RGB888: > + return VOP_MAJOR(version) == 3; > + case DRM_FORMAT_BGR888: > + return VOP_MAJOR(version) != 3; > default: > return false; > } > @@ -1035,7 +1043,7 @@ static void vop_plane_atomic_update(struct drm_plane > *plane, > VOP_WIN_SET(vop, win, dsp_info, dsp_info); > VOP_WIN_SET(vop, win, dsp_st, dsp_st); > > - rb_swap = has_rb_swapped(fb->format->format); > + rb_swap = has_rb_swapped(vop->data->version, fb->format->format); > VOP_WIN_SET(vop, win, rb_swap, rb_swap); > > /*