From aca6aba688553268f318b2fcc07a3a082f6865b1 Mon Sep 17 00:00:00 2001 From: Sandy Huang Date: Mon, 25 Dec 2017 15:48:21 +0800 Subject: [PATCH] drm/rockchip: vop: add support px30 afbdc Px30 afbdc made some improvements base on rk3399: 1. support virth width; 2. support buffer xoffset and yoffset; Change-Id: I6d5b8bc0a66e468882998c9940da21812896b5c4 Signed-off-by: Sandy Huang --- drivers/gpu/drm/rockchip/rockchip_drm_drv.h | 3 ++ drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 50 ++++++++++++++++++++- drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 7 +-- 3 files changed, 56 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h index 86d358ded609..84d05d98349d 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h +++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h @@ -110,6 +110,9 @@ struct rockchip_crtc_state { int afbdc_win_ptr; int afbdc_win_id; int afbdc_en; + int afbdc_win_vir_width; + int afbdc_win_xoffset; + int afbdc_win_yoffset; int cabc_mode; int cabc_stage_up; int cabc_stage_down; diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c index fb86948d8124..c1a268ebd747 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c @@ -2509,6 +2509,49 @@ static int vop_afbdc_atomic_check(struct drm_crtc *crtc, win = to_vop_win(plane); src = &plane_state->src; + if (!(win->feature & WIN_FEATURE_AFBDC)) { + DRM_ERROR("win[%d] feature:0x%llx, not support afbdc\n", + win->win_id, win->feature); + return -EINVAL; + } + if (!IS_ALIGNED(fb->width, 16)) { + DRM_ERROR("win[%d] afbdc must 16 align, width: %d\n", + win->win_id, fb->width); + return -EINVAL; + } + + if (VOP_CTRL_SUPPORT(vop, afbdc_pic_vir_width)) { + u32 align_x1, align_x2, align_y1, align_y2, align_val; + + s->afbdc_win_format = afbdc_format; + s->afbdc_win_id = win->win_id; + s->afbdc_win_ptr = rockchip_fb_get_dma_addr(fb, 0); + s->afbdc_win_vir_width = fb->width; + s->afbdc_win_xoffset = (src->x1 >> 16); + s->afbdc_win_yoffset = (src->y1 >> 16); + + align_x1 = (src->x1 >> 16) - ((src->x1 >> 16) % 16); + align_y1 = (src->y1 >> 16) - ((src->y1 >> 16) % 16); + + align_val = (src->x2 >> 16) % 16; + if (align_val) + align_x2 = (src->x2 >> 16) + (16 - align_val); + else + align_x2 = src->x2 >> 16; + + align_val = (src->y2 >> 16) % 16; + if (align_val) + align_y2 = (src->y2 >> 16) + (16 - align_val); + else + align_y2 = src->y2 >> 16; + + s->afbdc_win_width = align_x2 - align_x1 - 1; + s->afbdc_win_height = align_y2 - align_y1 - 1; + + s->afbdc_en = 1; + + break; + } if (src->x1 || src->y1 || fb->offsets[0]) { DRM_ERROR("win[%d] afbdc not support offset display\n", win->win_id); @@ -2918,7 +2961,7 @@ static void vop_cfg_update(struct drm_crtc *crtc, vop_tv_config_update(crtc, old_crtc_state); if (s->afbdc_en) { - uint32_t pic_size; + u32 pic_size, pic_offset; VOP_CTRL_SET(vop, afbdc_format, s->afbdc_win_format | 1 << 4); VOP_CTRL_SET(vop, afbdc_hreg_block_split, 0); @@ -2927,6 +2970,11 @@ static void vop_cfg_update(struct drm_crtc *crtc, pic_size = (s->afbdc_win_width & 0xffff); pic_size |= s->afbdc_win_height << 16; VOP_CTRL_SET(vop, afbdc_pic_size, pic_size); + + VOP_CTRL_SET(vop, afbdc_pic_vir_width, s->afbdc_win_vir_width); + pic_offset = (s->afbdc_win_xoffset & 0xffff); + pic_offset |= s->afbdc_win_yoffset << 16; + VOP_CTRL_SET(vop, afbdc_pic_offset, pic_offset); } VOP_CTRL_SET(vop, afbdc_en, s->afbdc_en); diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c index 92c96353a479..928941c311ea 100644 --- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c +++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c @@ -1332,10 +1332,10 @@ static const struct vop_ctrl rk3366_lit_ctrl_data = { 0, 2, 6, -1), .afbdc_pic_size = VOP_REG_VER(PX30_AFBCD0_PIC_SIZE, 0xffffffff, 0, 2, 6, -1), - .afbdc_pic_offset = VOP_REG_VER(PX30_AFBCD0_PIC_SIZE, 0xffffffff, - 0, 2, 6, -1), + .afbdc_pic_offset = VOP_REG_VER(PX30_AFBCD0_PIC_OFFSET, 0xffffffff, + 0, 2, 6, -1), .afbdc_axi_ctrl = VOP_REG_VER(PX30_AFBCD0_AXI_CTRL, 0xffffffff, - 0, 2, 6, -1), + 0, 2, 6, -1), .cabc_config_mode = VOP_REG_VER(PX30_CABC_CTRL0, 0x3, 1, 2, 6, -1), .cabc_calc_pixel_num = VOP_REG_VER(PX30_CABC_CTRL0, 0x7fffff, 4, @@ -1428,6 +1428,7 @@ static const struct vop_data px30_vop_lit = { static const struct vop_data px30_vop_big = { .version = VOP_VERSION(2, 6), + .feature = VOP_FEATURE_AFBDC, .max_input = {1920, 8192}, .max_output = {1920, 1080}, .ctrl = &rk3366_lit_ctrl_data,