drm/rockchip: logo: use unique plane property logo mirror
authorMark Yao <mark.yao@rock-chips.com>
Mon, 5 Jun 2017 03:29:36 +0000 (11:29 +0800)
committerHuang, Tao <huangtao@rock-chips.com>
Mon, 5 Jun 2017 10:35:57 +0000 (18:35 +0800)
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>
drivers/gpu/drm/rockchip/rockchip_drm_drv.c
drivers/gpu/drm/rockchip/rockchip_drm_drv.h
drivers/gpu/drm/rockchip/rockchip_drm_fb.c
drivers/gpu/drm/rockchip/rockchip_drm_fb.h
drivers/gpu/drm/rockchip/rockchip_drm_vop.c

index e7a6755b48f89c567bf985079650ea4bdc02597d..81cca3b6611edb6d7db8e7d7ddd41aa1eeb24278 100644 (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));
        }
 
        /*
index 0cb9d0962bc05221a69eb40d2da5a65a6c03c88b..7c0f742f1a0aac59d2694d3a37611d5b64944d3f 100644 (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];
index c261a166ca22277ae828ce517cac229139b75e02..15fe607f2bc1c324a46b4466a12ee023d2a9116f 100644 (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)
 {
index fe702dfc27d94744f7fcc8d60a95b0eba619a3f1..60ce2efed3a7169b829be028d74a0028b851431b 100644 (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,
index 2d08be86cad90a5e90d5899663b924008d782955..7273d3b55a89d4214fd25d68e9c67a39db5572e3 100644 (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,