mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-08 11:50:43 +09:00
drm/rockchip: vop: add x/ymirror support
Change-Id: If7d1ef5f3246f467c48895aa2f54957bd59eed18 Signed-off-by: Mark Yao <mark.yao@rock-chips.com>
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user