diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c index fe9656c75a38..fe5db9f009e9 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c @@ -1867,6 +1867,68 @@ static void vop_plane_atomic_disable(struct drm_plane *plane, spin_unlock(&vop->reg_lock); } +static void vop_plane_setup_color_key(struct drm_plane *plane) +{ + struct drm_plane_state *pstate = plane->state; + struct vop_plane_state *vpstate = to_vop_plane_state(pstate); + struct drm_framebuffer *fb = pstate->fb; + struct vop_win *win = to_vop_win(plane); + struct vop *vop = win->vop; + uint32_t color_key_en = 0; + uint32_t color_key; + uint32_t r = 0; + uint32_t g = 0; + uint32_t b = 0; + + if (!(vpstate->color_key & VOP_COLOR_KEY_MASK) || fb->format->is_yuv) { + VOP_WIN_SET(vop, win, color_key_en, 0); + return; + } + + switch (fb->format->format) { + case DRM_FORMAT_RGB565: + case DRM_FORMAT_BGR565: + r = (vpstate->color_key & 0xf800) >> 11; + g = (vpstate->color_key & 0x7e0) >> 5; + b = (vpstate->color_key & 0x1f); + if (VOP_WIN_SUPPORT(vop, win, fmt_10)) { + r <<= 5; + g <<= 4; + b <<= 5; + } else { + r <<= 3; + g <<= 2; + b <<= 3; + } + color_key_en = 1; + break; + case DRM_FORMAT_XRGB8888: + case DRM_FORMAT_ARGB8888: + case DRM_FORMAT_XBGR8888: + case DRM_FORMAT_ABGR8888: + case DRM_FORMAT_RGB888: + case DRM_FORMAT_BGR888: + r = (vpstate->color_key & 0xff0000) >> 16; + g = (vpstate->color_key & 0xff00) >> 8; + b = (vpstate->color_key & 0xff); + if (VOP_WIN_SUPPORT(vop, win, fmt_10)) { + r <<= 2; + g <<= 2; + b <<= 2; + } + color_key_en = 1; + break; + } + + if (VOP_WIN_SUPPORT(vop, win, fmt_10)) + color_key = (r << 20) | (g << 10) | b; + else + color_key = (r << 16) | (g << 8) | b; + + VOP_WIN_SET(vop, win, color_key_en, color_key_en); + VOP_WIN_SET(vop, win, color_key, color_key); +} + static void vop_plane_atomic_update(struct drm_plane *plane, struct drm_plane_state *old_state) { @@ -1987,6 +2049,9 @@ static void vop_plane_atomic_update(struct drm_plane *plane, drm_rect_width(dest), drm_rect_height(dest), fb->format->format); + if (VOP_WIN_SUPPORT(vop, win, color_key)) + vop_plane_setup_color_key(&win->base); + VOP_WIN_SET(vop, win, act_info, act_info); VOP_WIN_SET(vop, win, dsp_info, dsp_info); VOP_WIN_SET(vop, win, dsp_st, dsp_st); @@ -4408,8 +4473,9 @@ static int vop_plane_init(struct vop *vop, struct vop_win *win, * Bit 31 is used as a flag to disable (0) or enable * color keying (1). */ - win->color_key_prop = drm_property_create_range(vop->drm_dev, 0, - "colorkey", 0, 0x80ffffff); + if (VOP_WIN_SUPPORT(vop, win, color_key)) + win->color_key_prop = drm_property_create_range(vop->drm_dev, 0, + "colorkey", 0, 0x80ffffff); if (!win->input_width_prop || !win->input_height_prop || !win->scale_prop || !win->color_key_prop) { DRM_ERROR("failed to create property\n"); diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h index 238bf65eab1e..90ff4d24f3cb 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h @@ -534,8 +534,8 @@ struct vop_win_phy { struct vop_reg alpha_en; struct vop_reg alpha_pre_mul; struct vop_reg global_alpha_val; - struct vop_reg key_color; - struct vop_reg key_en; + struct vop_reg color_key; + struct vop_reg color_key_en; }; struct vop_win_data { diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c index 9462223ca3bd..dd04c1f3e834 100644 --- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c +++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c @@ -464,6 +464,8 @@ static const struct vop_win_phy rk3368_win23_data = { .src_alpha_ctl = VOP_REG(RK3368_WIN2_SRC_ALPHA_CTRL, 0xffff, 0), .global_alpha_val = VOP_REG(RK3368_WIN2_SRC_ALPHA_CTRL, 0xff, 16), .dst_alpha_ctl = VOP_REG(RK3368_WIN2_DST_ALPHA_CTRL, 0xffffffff, 0), + .color_key = VOP_REG(RK3368_WIN2_COLOR_KEY, 0xffffff, 0), + .color_key_en = VOP_REG(RK3368_WIN2_COLOR_KEY, 0x1, 24), }; static const struct vop_win_phy rk3368_area1_data = { @@ -679,6 +681,8 @@ static const struct vop_win_phy rk3399_win01_data = { .global_alpha_val = VOP_REG(RK3288_WIN0_SRC_ALPHA_CTRL, 0xff, 16), .dst_alpha_ctl = VOP_REG(RK3288_WIN0_DST_ALPHA_CTRL, 0xffffffff, 0), .channel = VOP_REG_VER(RK3288_WIN0_CTRL2, 0xff, 0, 3, 8, 8), + .color_key = VOP_REG(RK3288_WIN0_COLOR_KEY, 0x3fffffff, 0), + .color_key_en = VOP_REG(RK3288_WIN0_COLOR_KEY, 0x1, 31), }; static const struct vop_win_data rk3399_vop_win_data[] = { @@ -1423,8 +1427,8 @@ static const struct vop_win_phy rk3366_lit_win0_data = { .alpha_mode = VOP_REG(RK3366_LIT_WIN0_ALPHA_CTRL, 0x1, 1), .alpha_en = VOP_REG(RK3366_LIT_WIN0_ALPHA_CTRL, 0x1, 0), .global_alpha_val = VOP_REG(RK3366_LIT_WIN0_ALPHA_CTRL, 0xff, 4), - .key_color = VOP_REG(RK3366_LIT_WIN0_COLOR_KEY, 0xffffff, 0), - .key_en = VOP_REG(RK3366_LIT_WIN0_COLOR_KEY, 0x1, 24), + .color_key = VOP_REG(RK3366_LIT_WIN0_COLOR_KEY, 0xffffff, 0), + .color_key_en = VOP_REG(RK3366_LIT_WIN0_COLOR_KEY, 0x1, 24), }; static const struct vop_win_phy rk3366_lit_win1_data = { @@ -1444,8 +1448,8 @@ static const struct vop_win_phy rk3366_lit_win1_data = { .alpha_mode = VOP_REG(RK3366_LIT_WIN1_ALPHA_CTRL, 0x1, 1), .alpha_en = VOP_REG(RK3366_LIT_WIN1_ALPHA_CTRL, 0x1, 0), .global_alpha_val = VOP_REG(RK3366_LIT_WIN1_ALPHA_CTRL, 0xff, 4), - .key_color = VOP_REG(RK3366_LIT_WIN1_COLOR_KEY, 0xffffff, 0), - .key_en = VOP_REG(RK3366_LIT_WIN1_COLOR_KEY, 0x1, 24), + .color_key = VOP_REG(RK3366_LIT_WIN1_COLOR_KEY, 0xffffff, 0), + .color_key_en = VOP_REG(RK3366_LIT_WIN1_COLOR_KEY, 0x1, 24), }; static const struct vop_win_data rk3366_vop_lit_win_data[] = {