MLK-16953: drm: imx: dcss: Add propriety to change global alpha priority
authorLaurentiu Palcu <laurentiu.palcu@nxp.com>
Fri, 24 Nov 2017 14:59:20 +0000 (16:59 +0200)
committerLeonard Crestez <leonard.crestez@nxp.com>
Wed, 17 Apr 2019 23:51:34 +0000 (02:51 +0300)
This patch adds 'use_global_alpha' property to the primary plane, so that
one can choose whether to use global alpha instead of per-pixel alpha,
when the framebuffer has per-pixel alpha.

Framebuffers that do not have per-pixel alpha will always use global
alpha.

Signed-off-by: Laurentiu Palcu <laurentiu.palcu@nxp.com>
drivers/gpu/drm/imx/dcss/dcss-crtc.c
drivers/gpu/drm/imx/dcss/dcss-plane.c
drivers/gpu/drm/imx/dcss/dcss-plane.h
drivers/gpu/imx/dcss/dcss-dtg.c
include/video/imx-dcss.h

index e2d110f..910e678 100644 (file)
@@ -35,6 +35,7 @@ struct dcss_crtc {
        int                     irq;
 
        struct drm_property *alpha;
+       struct drm_property *use_global;
 
        struct completion disable_completion;
 };
@@ -269,11 +270,22 @@ static int dcss_crtc_init(struct dcss_crtc *crtc,
                return -ENOMEM;
        }
 
+       crtc->use_global = drm_property_create_range(drm, 0,
+                                                    "use_global_alpha", 0, 1);
+       if (!crtc->use_global) {
+               dev_err(crtc->dev, "cannot create use_global property\n");
+               return -ENOMEM;
+       }
+
        /* attach alpha property to channel 0 */
        drm_object_attach_property(&crtc->plane[0]->base.base,
                                   crtc->alpha, 255);
        crtc->plane[0]->alpha_prop = crtc->alpha;
 
+       drm_object_attach_property(&crtc->plane[0]->base.base,
+                                  crtc->use_global, 0);
+       crtc->plane[0]->use_global_prop = crtc->use_global;
+
        crtc->irq = dcss_vblank_irq_get(dcss);
        if (crtc->irq < 0) {
                dev_err(crtc->dev, "unable to get vblank interrupt\n");
index 7da8a86..b0e8e26 100644 (file)
@@ -80,6 +80,8 @@ static int dcss_plane_atomic_set_property(struct drm_plane *plane,
 
        if (property == dcss_plane->alpha_prop)
                dcss_plane->alpha_val = val;
+       else if (property == dcss_plane->use_global_prop)
+               dcss_plane->use_global_val = val;
        else
                return -EINVAL;
 
@@ -95,6 +97,8 @@ static int dcss_plane_atomic_get_property(struct drm_plane *plane,
 
        if (property == dcss_plane->alpha_prop)
                *val = dcss_plane->alpha_val;
+       else if (property == dcss_plane->use_global_prop)
+               *val = dcss_plane->use_global_val;
        else
                return -EINVAL;
 
@@ -204,8 +208,8 @@ static void dcss_plane_atomic_update(struct drm_plane *plane,
        if (old_state->fb && !drm_atomic_crtc_needs_modeset(crtc_state) &&
            !dcss_plane_needs_setup(state, old_state) &&
            !dcss_dtg_global_alpha_changed(dcss_plane->dcss, dcss_plane->ch_num,
-                                          pixel_format,
-                                          dcss_plane->alpha_val)) {
+                                          pixel_format, dcss_plane->alpha_val,
+                                          dcss_plane->use_global_val)) {
                dcss_plane_atomic_set_base(dcss_plane);
                return;
        }
@@ -234,7 +238,8 @@ static void dcss_plane_atomic_update(struct drm_plane *plane,
                               state->crtc_x, state->crtc_y,
                               state->crtc_w, state->crtc_h);
        dcss_dtg_plane_alpha_set(dcss_plane->dcss, dcss_plane->ch_num,
-                                pixel_format, dcss_plane->alpha_val);
+                                pixel_format, dcss_plane->alpha_val,
+                                dcss_plane->use_global_val);
 
        dcss_dpr_enable(dcss_plane->dcss, dcss_plane->ch_num, true);
        dcss_scaler_enable(dcss_plane->dcss, dcss_plane->ch_num, true);
index 56e51d9..3f04385 100644 (file)
@@ -10,6 +10,9 @@ struct dcss_plane {
        int alpha_val;
        struct drm_property *alpha_prop;
 
+       int use_global_val;
+       struct drm_property *use_global_prop;
+
        int ch_num;
 };
 
index 5e3d51d..0c1c9d1 100644 (file)
@@ -134,6 +134,7 @@ struct dcss_dtg_priv {
 
        u32 control_status;
        u32 alpha;
+       u32 use_global;
 
        /*
         * This will be passed on by DRM CRTC so that we can signal when DTG has
@@ -192,6 +193,7 @@ int dcss_dtg_init(struct dcss_soc *dcss, unsigned long dtg_base)
 #endif
 
        dtg->alpha = 255;
+       dtg->use_global = 0;
 
        dtg->control_status |= OVL_DATA_MODE | BLENDER_VIDEO_ALPHA_SEL |
                ((0x5 << CSS_PIX_COMP_SWAP_POS) & CSS_PIX_COMP_SWAP_MASK) |
@@ -301,19 +303,21 @@ static bool dcss_dtg_global_alpha_needed(u32 pix_format)
 }
 
 bool dcss_dtg_global_alpha_changed(struct dcss_soc *dcss, int ch_num,
-                                  u32 pix_format, int alpha)
+                                  u32 pix_format, int alpha,
+                                  int use_global_alpha)
 {
        struct dcss_dtg_priv *dtg = dcss->dtg_priv;
 
        if (ch_num)
                return false;
 
-       return dcss_dtg_global_alpha_needed(pix_format) && alpha != dtg->alpha;
+       return dcss_dtg_global_alpha_needed(pix_format) &&
+              (alpha != dtg->alpha || use_global_alpha != dtg->use_global);
 }
 EXPORT_SYMBOL(dcss_dtg_global_alpha_changed);
 
 void dcss_dtg_plane_alpha_set(struct dcss_soc *dcss, int ch_num,
-                             u32 pix_format, int alpha)
+                             u32 pix_format, int alpha, bool use_global_alpha)
 {
        struct dcss_dtg_priv *dtg = dcss->dtg_priv;
        u32 alpha_val;
@@ -324,7 +328,11 @@ void dcss_dtg_plane_alpha_set(struct dcss_soc *dcss, int ch_num,
 
        alpha_val = (alpha << DEFAULT_FG_ALPHA_POS) & DEFAULT_FG_ALPHA_MASK;
 
-       if (dcss_dtg_global_alpha_needed(pix_format)) {
+       /*
+        * Use global alpha if pixel format does not have alpha channel or the
+        * user explicitly chose to use global alpha.
+        */
+       if (dcss_dtg_global_alpha_needed(pix_format) || use_global_alpha) {
                dtg->control_status &= ~(CH1_ALPHA_SEL | DEFAULT_FG_ALPHA_MASK);
                dtg->control_status |= alpha_val;
        } else {
@@ -332,6 +340,7 @@ void dcss_dtg_plane_alpha_set(struct dcss_soc *dcss, int ch_num,
        }
 
        dtg->alpha = alpha;
+       dtg->use_global = use_global_alpha;
 }
 EXPORT_SYMBOL(dcss_dtg_plane_alpha_set);
 
index fb1f6ae..75db61f 100644 (file)
@@ -63,9 +63,10 @@ void dcss_dtg_enable(struct dcss_soc *dcss, bool en,
 bool dcss_dtg_is_enabled(struct dcss_soc *dcss);
 void dcss_dtg_ch_enable(struct dcss_soc *dcss, int ch_num, bool en);
 void dcss_dtg_plane_alpha_set(struct dcss_soc *dcss, int ch_num,
-                             u32 pix_format, int alpha);
+                             u32 pix_format, int alpha, bool use_global_alpha);
 bool dcss_dtg_global_alpha_changed(struct dcss_soc *dcss, int ch_num,
-                                  u32 pix_format, int alpha);
+                                  u32 pix_format, int alpha,
+                                  int use_global_alpha);
 
 /* SUBSAM */
 void dcss_ss_sync_set(struct dcss_soc *dcss, struct videomode *vm,