From: Mark Yao Date: Fri, 8 Jul 2016 09:24:36 +0000 (+0800) Subject: drm/rockchip: vop: add x/ymirror support X-Git-Tag: firefly_0821_release~2183 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=4712c74b71d8a19cd9d061cb39b6a6dfe5c08c7c;p=firefly-linux-kernel-4.4.55.git drm/rockchip: vop: add x/ymirror support Change-Id: If7d1ef5f3246f467c48895aa2f54957bd59eed18 Signed-off-by: Mark Yao --- diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c index 6de51ffda32d..bee7049ebe1d 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c @@ -88,6 +88,9 @@ #define VOP_WIN_GET_YRGBADDR(vop, win) \ vop_readl(vop, win->offset + VOP_WIN_NAME(win, yrgb_mst).offset) +#define VOP_WIN_SUPPORT(win, name) \ + (win->phy->name.mask ? true : false) + #define to_vop(x) container_of(x, struct vop, crtc) #define to_vop_win(x) container_of(x, struct vop_win, base) #define to_vop_plane_state(x) container_of(x, struct vop_plane_state, base) @@ -120,6 +123,7 @@ struct vop_win { uint32_t nformats; struct vop *vop; + struct drm_property *rotation_prop; struct vop_plane_state state; }; @@ -721,6 +725,7 @@ static void vop_plane_atomic_update(struct drm_plane *plane, struct rockchip_gem_object *rk_obj, *rk_uv_obj; unsigned long offset; dma_addr_t dma_addr; + int ymirror, xmirror; uint32_t val; bool rb_swap; @@ -753,11 +758,19 @@ static void vop_plane_atomic_update(struct drm_plane *plane, dsp_st = dsp_sty << 16 | (dsp_stx & 0xffff); offset = (src->x1 >> 16) * drm_format_plane_cpp(fb->pixel_format, 0); - offset += (src->y1 >> 16) * fb->pitches[0]; + if (state->rotation & BIT(DRM_REFLECT_Y)) + offset += ((src->y2 >> 16) - 1) * fb->pitches[0]; + else + offset += (src->y1 >> 16) * fb->pitches[0]; vop_plane_state->yrgb_mst = rk_obj->dma_addr + offset + fb->offsets[0]; + ymirror = !!(state->rotation & BIT(DRM_REFLECT_Y)); + xmirror = !!(state->rotation & BIT(DRM_REFLECT_X)); + spin_lock(&vop->reg_lock); + VOP_WIN_SET(vop, win, xmirror, xmirror); + VOP_WIN_SET(vop, win, ymirror, ymirror); VOP_WIN_SET(vop, win, format, vop_plane_state->format); VOP_WIN_SET(vop, win, yrgb_vir, fb->pitches[0] >> 2); VOP_WIN_SET(vop, win, yrgb_mst, vop_plane_state->yrgb_mst); @@ -877,6 +890,11 @@ static int vop_atomic_plane_set_property(struct drm_plane *plane, return 0; } + if (property == win->rotation_prop) { + state->rotation = val; + return 0; + } + DRM_ERROR("failed to set vop plane property\n"); return -EINVAL; } @@ -894,6 +912,11 @@ static int vop_atomic_plane_get_property(struct drm_plane *plane, return 0; } + if (property == win->rotation_prop) { + *val = state->rotation; + return 0; + } + DRM_ERROR("failed to get vop plane property\n"); return -EINVAL; } @@ -1332,6 +1355,8 @@ static int vop_plane_init(struct vop *vop, struct vop_win *win, unsigned long possible_crtcs) { struct drm_plane *share = NULL; + unsigned int rotations = 0; + struct drm_property *prop; int ret; if (win->parent) @@ -1347,6 +1372,26 @@ static int vop_plane_init(struct vop *vop, struct vop_win *win, drm_plane_helper_add(&win->base, &plane_helper_funcs); drm_object_attach_property(&win->base.base, vop->plane_zpos_prop, win->win_id); + + if (VOP_WIN_SUPPORT(win, xmirror)) + rotations |= BIT(DRM_REFLECT_X); + + if (VOP_WIN_SUPPORT(win, ymirror)) + rotations |= BIT(DRM_REFLECT_Y); + + if (rotations) { + rotations |= BIT(DRM_ROTATE_0); + prop = drm_mode_create_rotation_property(vop->drm_dev, + rotations); + if (!prop) { + DRM_ERROR("failed to create zpos property\n"); + return -EINVAL; + } + drm_object_attach_property(&win->base.base, prop, + BIT(DRM_ROTATE_0)); + win->rotation_prop = prop; + } + return 0; } diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h index fec8e1d688c5..7ae3947ef01f 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h @@ -113,6 +113,8 @@ struct vop_win_phy { struct vop_reg enable; struct vop_reg format; + struct vop_reg xmirror; + struct vop_reg ymirror; struct vop_reg rb_swap; struct vop_reg act_info; struct vop_reg dsp_info; diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c index 48ec5706e0cf..187a478ebea4 100644 --- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c +++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c @@ -293,11 +293,32 @@ static const struct vop_reg_data rk3399_init_reg_table[] = { {RK3399_WIN3_CTRL0, 0x00000001}, }; +static const struct vop_win_phy rk3399_win01_data = { + .scl = &rk3288_win_full_scl, + .data_formats = formats_win_full, + .nformats = ARRAY_SIZE(formats_win_full), + .enable = VOP_REG(RK3399_WIN0_CTRL0, 0x1, 0), + .format = VOP_REG(RK3399_WIN0_CTRL0, 0x7, 1), + .xmirror = VOP_REG(RK3399_WIN0_CTRL0, 0x1, 21), + .ymirror = VOP_REG(RK3399_WIN0_CTRL0, 0x1, 22), + .rb_swap = VOP_REG(RK3399_WIN0_CTRL0, 0x1, 12), + .act_info = VOP_REG(RK3399_WIN0_ACT_INFO, 0x1fff1fff, 0), + .dsp_info = VOP_REG(RK3399_WIN0_DSP_INFO, 0x0fff0fff, 0), + .dsp_st = VOP_REG(RK3399_WIN0_DSP_ST, 0x1fff1fff, 0), + .yrgb_mst = VOP_REG(RK3399_WIN0_YRGB_MST, 0xffffffff, 0), + .uv_mst = VOP_REG(RK3399_WIN0_CBR_MST, 0xffffffff, 0), + .yrgb_vir = VOP_REG(RK3399_WIN0_VIR, 0x3fff, 0), + .uv_vir = VOP_REG(RK3399_WIN0_VIR, 0x3fff, 16), + .src_alpha_ctl = VOP_REG(RK3399_WIN0_SRC_ALPHA_CTRL, 0xff, 0), + .dst_alpha_ctl = VOP_REG(RK3399_WIN0_DST_ALPHA_CTRL, 0xff, 0), +}; + static const struct vop_win_phy rk3399_win23_data = { .data_formats = formats_win_lite, .nformats = ARRAY_SIZE(formats_win_lite), .enable = VOP_REG(RK3399_WIN2_CTRL0, 0x1, 4), .format = VOP_REG(RK3399_WIN2_CTRL0, 0x3, 5), + .ymirror = VOP_REG(RK3399_WIN2_CTRL1, 0x1, 15), .rb_swap = VOP_REG(RK3399_WIN2_CTRL0, 0x1, 20), .dsp_info = VOP_REG(RK3399_WIN2_DSP_INFO0, 0x0fff0fff, 0), .dsp_st = VOP_REG(RK3399_WIN2_DSP_ST0, 0x1fff1fff, 0), @@ -344,9 +365,9 @@ static const struct vop_win_phy *rk3399_area_data[] = { }; static const struct vop_win_data rk3399_vop_win_data[] = { - { .base = 0x00, .phy = &rk3288_win01_data, + { .base = 0x00, .phy = &rk3399_win01_data, .type = DRM_PLANE_TYPE_PRIMARY }, - { .base = 0x40, .phy = &rk3288_win01_data, + { .base = 0x40, .phy = &rk3399_win01_data, .type = DRM_PLANE_TYPE_OVERLAY }, { .base = 0x00, .phy = &rk3399_win23_data, .type = DRM_PLANE_TYPE_OVERLAY, @@ -372,7 +393,7 @@ static const struct vop_data rk3399_vop_big = { }; static const struct vop_win_data rk3399_vop_lit_win_data[] = { - { .base = 0x00, .phy = &rk3288_win01_data, + { .base = 0x00, .phy = &rk3399_win01_data, .type = DRM_PLANE_TYPE_PRIMARY }, { .phy = NULL }, { .base = 0x00, .phy = &rk3288_win23_data,