From 5d68f46388c9813efb1a722e52f6ec9c4be8c0ce Mon Sep 17 00:00:00 2001 From: Paolo Sabatino Date: Fri, 10 Sep 2021 14:18:08 +0000 Subject: [PATCH] experimental drm patch --- drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 134 +++++++++++--------- 1 file changed, 72 insertions(+), 62 deletions(-) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c index b0832320e..a0fca8a20 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c @@ -997,25 +997,78 @@ static void vop_plane_atomic_update(struct drm_plane *plane, spin_lock(&vop->reg_lock); - if (rockchip_afbc(fb->modifier)) { - int afbc_format = vop_convert_afbc_format(fb->format->format); + if (!(vop->win_enabled & BIT(win_index))) { - VOP_AFBC_SET(vop, format, afbc_format | AFBC_TILE_16x16); - VOP_AFBC_SET(vop, hreg_block_split, 0); - VOP_AFBC_SET(vop, win_sel, VOP_WIN_TO_INDEX(vop_win)); - VOP_AFBC_SET(vop, hdr_ptr, dma_addr); - VOP_AFBC_SET(vop, pic_size, act_info); - } + if (rockchip_afbc(fb->modifier)) { + int afbc_format = vop_convert_afbc_format(fb->format->format); - VOP_WIN_SET(vop, win, format, format); - VOP_WIN_SET(vop, win, fmt_10, is_fmt_10(fb->format->format)); - VOP_WIN_SET(vop, win, yrgb_vir, DIV_ROUND_UP(fb->pitches[0], 4 >> skiplines)); - VOP_WIN_SET(vop, win, yrgb_mst, dma_addr); - VOP_WIN_YUV2YUV_SET(vop, win_yuv2yuv, y2r_en, is_yuv); - VOP_WIN_SET(vop, win, y_mir_en, - (new_state->rotation & DRM_MODE_REFLECT_Y) ? 1 : 0); - VOP_WIN_SET(vop, win, x_mir_en, - (new_state->rotation & DRM_MODE_REFLECT_X) ? 1 : 0); + VOP_AFBC_SET(vop, format, afbc_format | AFBC_TILE_16x16); + VOP_AFBC_SET(vop, hreg_block_split, 0); + VOP_AFBC_SET(vop, win_sel, VOP_WIN_TO_INDEX(vop_win)); + VOP_AFBC_SET(vop, hdr_ptr, dma_addr); + VOP_AFBC_SET(vop, pic_size, act_info); + } + + VOP_WIN_SET(vop, win, format, format); + VOP_WIN_SET(vop, win, fmt_10, is_fmt_10(fb->format->format)); + VOP_WIN_SET(vop, win, yrgb_vir, DIV_ROUND_UP(fb->pitches[0], 4 >> skiplines)); + + VOP_WIN_YUV2YUV_SET(vop, win_yuv2yuv, y2r_en, is_yuv); + VOP_WIN_SET(vop, win, y_mir_en, + (new_state->rotation & DRM_MODE_REFLECT_Y) ? 1 : 0); + VOP_WIN_SET(vop, win, x_mir_en, + (new_state->rotation & DRM_MODE_REFLECT_X) ? 1 : 0); + + if (is_yuv) { + + for (i = 0; i < NUM_YUV2YUV_COEFFICIENTS; i++) { + VOP_WIN_YUV2YUV_COEFFICIENT_SET(vop, + win_yuv2yuv, + y2r_coefficients[i], + bt601_yuv2rgb[i]); + } + } + + if (win->phy->scl) + scl_vop_cal_scl_fac(vop, win, actual_w, actual_h, + drm_rect_width(dest), drm_rect_height(dest), + fb->format); + + VOP_WIN_SET(vop, win, act_info, act_info); + VOP_WIN_SET(vop, win, dsp_info, dsp_info); + + rb_swap = has_rb_swapped(fb->format->format); + VOP_WIN_SET(vop, win, rb_swap, rb_swap); + + /* + * Blending win0 with the background color doesn't seem to work + * correctly. We only get the background color, no matter the contents + * of the win0 framebuffer. However, blending pre-multiplied color + * with the default opaque black default background color is a no-op, + * so we can just disable blending to get the correct result. + */ + if (fb->format->has_alpha && win_index > 0) { + VOP_WIN_SET(vop, win, dst_alpha_ctl, + DST_FACTOR_M0(ALPHA_SRC_INVERSE)); + val = SRC_ALPHA_EN(1) | SRC_COLOR_M0(ALPHA_SRC_PRE_MUL) | + SRC_ALPHA_M0(ALPHA_STRAIGHT) | + SRC_BLEND_M0(ALPHA_PER_PIX) | + SRC_ALPHA_CAL_M0(ALPHA_NO_SATURATION) | + SRC_FACTOR_M0(ALPHA_ONE); + VOP_WIN_SET(vop, win, src_alpha_ctl, val); + + VOP_WIN_SET(vop, win, alpha_pre_mul, ALPHA_SRC_PRE_MUL); + VOP_WIN_SET(vop, win, alpha_mode, ALPHA_PER_PIX); + VOP_WIN_SET(vop, win, alpha_en, 1); + } else { + VOP_WIN_SET(vop, win, src_alpha_ctl, SRC_ALPHA_EN(0)); + VOP_WIN_SET(vop, win, alpha_en, 0); + } + + VOP_WIN_SET(vop, win, enable, 1); + vop->win_enabled |= BIT(win_index); + + } if (is_yuv) { int hsub = fb->format->hsub; @@ -1027,7 +1080,7 @@ static void vop_plane_atomic_update(struct drm_plane *plane, if (fb->format->block_w[1]) offset = (src->x1 >> 16) * bpp / - fb->format->block_w[1] / hsub; + fb->format->block_w[1] / hsub; else offset = (src->x1 >> 16) * bpp / hsub; offset += (src->y1 >> 16) * fb->pitches[1] / vsub; @@ -1035,54 +1088,11 @@ static void vop_plane_atomic_update(struct drm_plane *plane, dma_addr = rk_uv_obj->dma_addr + offset + fb->offsets[1]; VOP_WIN_SET(vop, win, uv_vir, DIV_ROUND_UP(fb->pitches[1], 4 >> skiplines)); VOP_WIN_SET(vop, win, uv_mst, dma_addr); - - for (i = 0; i < NUM_YUV2YUV_COEFFICIENTS; i++) { - VOP_WIN_YUV2YUV_COEFFICIENT_SET(vop, - win_yuv2yuv, - y2r_coefficients[i], - bt601_yuv2rgb[i]); - } } - if (win->phy->scl) - scl_vop_cal_scl_fac(vop, win, actual_w, actual_h, - drm_rect_width(dest), drm_rect_height(dest), - fb->format); - - VOP_WIN_SET(vop, win, act_info, act_info); - VOP_WIN_SET(vop, win, dsp_info, dsp_info); + VOP_WIN_SET(vop, win, yrgb_mst, dma_addr); VOP_WIN_SET(vop, win, dsp_st, dsp_st); - rb_swap = has_rb_swapped(fb->format->format); - VOP_WIN_SET(vop, win, rb_swap, rb_swap); - - /* - * Blending win0 with the background color doesn't seem to work - * correctly. We only get the background color, no matter the contents - * of the win0 framebuffer. However, blending pre-multiplied color - * with the default opaque black default background color is a no-op, - * so we can just disable blending to get the correct result. - */ - if (fb->format->has_alpha && win_index > 0) { - VOP_WIN_SET(vop, win, dst_alpha_ctl, - DST_FACTOR_M0(ALPHA_SRC_INVERSE)); - val = SRC_ALPHA_EN(1) | SRC_COLOR_M0(ALPHA_SRC_PRE_MUL) | - SRC_ALPHA_M0(ALPHA_STRAIGHT) | - SRC_BLEND_M0(ALPHA_PER_PIX) | - SRC_ALPHA_CAL_M0(ALPHA_NO_SATURATION) | - SRC_FACTOR_M0(ALPHA_ONE); - VOP_WIN_SET(vop, win, src_alpha_ctl, val); - - VOP_WIN_SET(vop, win, alpha_pre_mul, ALPHA_SRC_PRE_MUL); - VOP_WIN_SET(vop, win, alpha_mode, ALPHA_PER_PIX); - VOP_WIN_SET(vop, win, alpha_en, 1); - } else { - VOP_WIN_SET(vop, win, src_alpha_ctl, SRC_ALPHA_EN(0)); - VOP_WIN_SET(vop, win, alpha_en, 0); - } - - VOP_WIN_SET(vop, win, enable, 1); - vop->win_enabled |= BIT(win_index); spin_unlock(&vop->reg_lock); } -- 2.25.1