drm/msm/mdp5: Configure COLOR3_OUT propagation
authorArchit Taneja <architt@codeaurora.org>
Mon, 19 Dec 2016 08:04:11 +0000 (13:34 +0530)
committerRob Clark <robdclark@gmail.com>
Mon, 6 Feb 2017 16:28:44 +0000 (11:28 -0500)
In MDP5 Layer Mixer HW, the blender output is only the blended color
components (i.e R, G and B, or COLOR0/1/2 in MDP5 HW terminology). This
is fed to the BG input of the next blender. We also need to provide an
alpha (COLOR3) value for the BG input at the next stage.

This is configured via using the REG_MDP5_LM_BLEND_COLOR_OUT register.
For each stage, we can propagate either the BG or FG alpha to the next
stage.

The approach taken by the driver is to propagate FG alpha, if the plane
staged on that blender has an alpha. If it doesn't, we try to propagate
the base layer's alpha.

This is borrowed from downstream MDP5 kernel driver. Without this, we
don't see any cursor plane content.

Signed-off-by: Archit Taneja <architt@codeaurora.org>
Signed-off-by: Rob Clark <robdclark@gmail.com>
drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c

index 7a47209b0c6f122b87792c64408b0c0dc50c4625..fec966293f9aaf46a44d56b6d037de7983b5f01e 100644 (file)
@@ -177,6 +177,21 @@ static void mdp5_crtc_destroy(struct drm_crtc *crtc)
        kfree(mdp5_crtc);
 }
 
+static inline u32 mdp5_lm_use_fg_alpha_mask(enum mdp_mixer_stage_id stage)
+{
+       switch (stage) {
+       case STAGE0: return MDP5_LM_BLEND_COLOR_OUT_STAGE0_FG_ALPHA;
+       case STAGE1: return MDP5_LM_BLEND_COLOR_OUT_STAGE1_FG_ALPHA;
+       case STAGE2: return MDP5_LM_BLEND_COLOR_OUT_STAGE2_FG_ALPHA;
+       case STAGE3: return MDP5_LM_BLEND_COLOR_OUT_STAGE3_FG_ALPHA;
+       case STAGE4: return MDP5_LM_BLEND_COLOR_OUT_STAGE4_FG_ALPHA;
+       case STAGE5: return MDP5_LM_BLEND_COLOR_OUT_STAGE5_FG_ALPHA;
+       case STAGE6: return MDP5_LM_BLEND_COLOR_OUT_STAGE6_FG_ALPHA;
+       default:
+               return 0;
+       }
+}
+
 /*
  * blend_setup() - blend all the planes of a CRTC
  *
@@ -197,6 +212,8 @@ static void blend_setup(struct drm_crtc *crtc)
        unsigned long flags;
        enum mdp5_pipe stage[STAGE_MAX + 1] = { SSPP_NONE };
        int i, plane_cnt = 0;
+       bool bg_alpha_enabled = false;
+       u32 mixer_op_mode = 0;
 #define blender(stage) ((stage) - STAGE0)
 
        hw_cfg = mdp5_cfg_get_hw_config(mdp5_kms->cfg);
@@ -218,6 +235,11 @@ static void blend_setup(struct drm_crtc *crtc)
        if (!pstates[STAGE_BASE]) {
                ctl_blend_flags |= MDP5_CTL_BLEND_OP_FLAG_BORDER_OUT;
                DBG("Border Color is enabled");
+       } else if (plane_cnt) {
+               format = to_mdp_format(msm_framebuffer_format(pstates[STAGE_BASE]->base.fb));
+
+               if (format->alpha_enable)
+                       bg_alpha_enabled = true;
        }
 
        /* The reset for blending */
@@ -232,6 +254,12 @@ static void blend_setup(struct drm_crtc *crtc)
                        MDP5_LM_BLEND_OP_MODE_BG_ALPHA(BG_CONST);
                fg_alpha = pstates[i]->alpha;
                bg_alpha = 0xFF - pstates[i]->alpha;
+
+               if (!format->alpha_enable && bg_alpha_enabled)
+                       mixer_op_mode = 0;
+               else
+                       mixer_op_mode |= mdp5_lm_use_fg_alpha_mask(i);
+
                DBG("Stage %d fg_alpha %x bg_alpha %x", i, fg_alpha, bg_alpha);
 
                if (format->alpha_enable && pstates[i]->premultiplied) {
@@ -268,6 +296,8 @@ static void blend_setup(struct drm_crtc *crtc)
                                blender(i)), bg_alpha);
        }
 
+       mdp5_write(mdp5_kms, REG_MDP5_LM_BLEND_COLOR_OUT(lm), mixer_op_mode);
+
        mdp5_ctl_blend(mdp5_crtc->ctl, stage, plane_cnt, ctl_blend_flags);
 
 out: