#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)
uint32_t nformats;
struct vop *vop;
+ struct drm_property *rotation_prop;
struct vop_plane_state state;
};
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;
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);
return 0;
}
+ if (property == win->rotation_prop) {
+ state->rotation = val;
+ return 0;
+ }
+
DRM_ERROR("failed to set vop plane property\n");
return -EINVAL;
}
return 0;
}
+ if (property == win->rotation_prop) {
+ *val = state->rotation;
+ return 0;
+ }
+
DRM_ERROR("failed to get vop plane property\n");
return -EINVAL;
}
unsigned long possible_crtcs)
{
struct drm_plane *share = NULL;
+ unsigned int rotations = 0;
+ struct drm_property *prop;
int ret;
if (win->parent)
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;
}
{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),
};
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,
};
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,