drm/rockchip: logo: use unique plane property logo mirror

The logo framework use state->rotation may conflict to common drm
update, cause display abnormal

Change-Id: I09b6b898a7606cd05371af1f4b25254945923d0d
Signed-off-by: Mark Yao <mark.yao@rock-chips.com>
This commit is contained in:
Mark Yao
2017-06-05 11:29:36 +08:00
committed by Huang, Tao
parent a688f6ff44
commit e6205bfe9b
5 changed files with 34 additions and 23 deletions

View File

@@ -478,7 +478,7 @@ static int update_state(struct drm_device *drm_dev,
struct rockchip_drm_mode_set *set,
unsigned int *plane_mask)
{
struct drm_mode_config *mode_config = &drm_dev->mode_config;
struct rockchip_drm_private *priv = drm_dev->dev_private;
struct drm_crtc *crtc = set->crtc;
struct drm_connector *connector = set->connector;
struct drm_display_mode *mode = set->mode;
@@ -507,7 +507,6 @@ static int update_state(struct drm_device *drm_dev,
} else {
const struct drm_encoder_helper_funcs *encoder_helper_funcs;
const struct drm_connector_helper_funcs *connector_helper_funcs;
struct rockchip_drm_private *priv = drm_dev->dev_private;
struct drm_encoder *encoder;
int pipe = drm_crtc_index(crtc);
@@ -549,8 +548,8 @@ static int update_state(struct drm_device *drm_dev,
* some vop maybe not support ymirror, but force use it now.
*/
drm_atomic_plane_set_property(crtc->primary, primary_state,
mode_config->rotation_property,
BIT(DRM_REFLECT_Y));
priv->logo_ymirror_prop,
true);
return ret;
}
@@ -636,24 +635,8 @@ static void show_loader_logo(struct drm_device *drm_dev)
drm_atomic_clean_old_fb(drm_dev, plane_mask, ret);
list_for_each_entry_safe(set, tmp, &mode_set_list, head) {
struct drm_crtc *crtc = set->crtc;
list_del(&set->head);
kfree(set);
/* FIXME:
* primary plane state rotation is not BIT(0), but we only want
* it effect on logo display, userspace may not known to clean
* this property, would get unexpect display, so force set
* primary rotation to BIT(0).
*/
if (!crtc->primary || !crtc->primary->state)
continue;
drm_atomic_plane_set_property(crtc->primary,
crtc->primary->state,
mode_config->rotation_property,
BIT(0));
}
/*

View File

@@ -120,6 +120,7 @@ struct rockchip_logo {
*/
struct rockchip_drm_private {
struct rockchip_logo *logo;
struct drm_property *logo_ymirror_prop;
struct drm_fb_helper *fbdev_helper;
struct drm_gem_object *fbdev_bo;
const struct rockchip_crtc_funcs *crtc_funcs[ROCKCHIP_MAX_CRTC];

View File

@@ -33,6 +33,13 @@ struct rockchip_drm_fb {
struct rockchip_logo *logo;
};
bool rockchip_fb_is_logo(struct drm_framebuffer *fb)
{
struct rockchip_drm_fb *rk_fb = to_rockchip_fb(fb);
return rk_fb && rk_fb->logo;
}
dma_addr_t rockchip_fb_get_dma_addr(struct drm_framebuffer *fb,
unsigned int plane)
{

View File

@@ -15,6 +15,7 @@
#ifndef _ROCKCHIP_DRM_FB_H
#define _ROCKCHIP_DRM_FB_H
bool rockchip_fb_is_logo(struct drm_framebuffer *fb);
struct drm_framebuffer *
rockchip_drm_framebuffer_init(struct drm_device *dev,
struct drm_mode_fb_cmd2 *mode_cmd,

View File

@@ -133,6 +133,7 @@ struct vop_plane_state {
struct drm_plane_state base;
int format;
int zpos;
unsigned int logo_ymirror;
struct drm_rect src;
struct drm_rect dest;
dma_addr_t yrgb_mst;
@@ -1108,7 +1109,8 @@ static int vop_plane_atomic_check(struct drm_plane *plane,
}
offset = (src->x1 >> 16) * drm_format_plane_bpp(fb->pixel_format, 0) / 8;
if (state->rotation & BIT(DRM_REFLECT_Y))
if (state->rotation & BIT(DRM_REFLECT_Y) ||
(rockchip_fb_is_logo(fb) && vop_plane_state->logo_ymirror))
offset += ((src->y2 >> 16) - 1) * fb->pitches[0];
else
offset += (src->y1 >> 16) * fb->pitches[0];
@@ -1210,7 +1212,8 @@ static void vop_plane_atomic_update(struct drm_plane *plane,
dsp_sty = dest->y1 + crtc->mode.vtotal - crtc->mode.vsync_start;
dsp_st = dsp_sty << 16 | (dsp_stx & 0xffff);
ymirror = !!(state->rotation & BIT(DRM_REFLECT_Y));
ymirror = state->rotation & BIT(DRM_REFLECT_Y) ||
(rockchip_fb_is_logo(fb) && vop_plane_state->logo_ymirror);
xmirror = !!(state->rotation & BIT(DRM_REFLECT_X));
vop = to_vop(state->crtc);
@@ -1333,6 +1336,7 @@ static int vop_atomic_plane_set_property(struct drm_plane *plane,
struct drm_property *property,
uint64_t val)
{
struct rockchip_drm_private *private = plane->dev->dev_private;
struct vop_win *win = to_vop_win(plane);
struct vop_plane_state *plane_state = to_vop_plane_state(state);
@@ -1346,6 +1350,12 @@ static int vop_atomic_plane_set_property(struct drm_plane *plane,
return 0;
}
if (property == private->logo_ymirror_prop) {
WARN_ON(!rockchip_fb_is_logo(state->fb));
plane_state->logo_ymirror = val;
return 0;
}
DRM_ERROR("failed to set vop plane property\n");
return -EINVAL;
}
@@ -2285,6 +2295,7 @@ static irqreturn_t vop_isr(int irq, void *data)
static int vop_plane_init(struct vop *vop, struct vop_win *win,
unsigned long possible_crtcs)
{
struct rockchip_drm_private *private = vop->drm_dev->dev_private;
struct drm_plane *share = NULL;
unsigned int rotations = 0;
struct drm_property *prop;
@@ -2308,9 +2319,17 @@ static int vop_plane_init(struct vop *vop, struct vop_win *win,
if (VOP_WIN_SUPPORT(vop, win, xmirror))
rotations |= BIT(DRM_REFLECT_X);
if (VOP_WIN_SUPPORT(vop, win, ymirror))
if (VOP_WIN_SUPPORT(vop, win, ymirror)) {
rotations |= BIT(DRM_REFLECT_Y);
prop = drm_property_create_bool(vop->drm_dev,
DRM_MODE_PROP_ATOMIC,
"LOGO_YMIRROR");
if (!prop)
return -ENOMEM;
private->logo_ymirror_prop = prop;
}
if (rotations) {
rotations |= BIT(DRM_ROTATE_0);
prop = drm_mode_create_rotation_property(vop->drm_dev,