Blend pipes by left and right. The first 2 pipes are for
left half screen and the later 2 pipes are for right in quad
pipe case.

Signed-off-by: Jun Nie <jun....@linaro.org>
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c    | 13 +++++++++++--
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 10 +++++++---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c  | 19 +++++++++++++++++--
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h  |  4 +++-
 4 files changed, 38 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index 3b3cd17976082..8fd56f8f2851f 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -574,8 +574,17 @@ static void _dpu_crtc_blend_setup(struct drm_crtc *crtc)
                        mixer[i].mixer_op_mode,
                        ctl->idx - CTL_0);
 
-               ctl->ops.setup_blendstage(ctl, mixer[i].hw_lm->idx,
-                       &stage_cfg);
+               /*
+                * call dpu_hw_ctl_setup_blendstage() to blend layers per stage 
cfg.
+                * There is 4 mixers at most. The first 2 are for the left 
half, and
+                * the later 2 are for the right half.
+                */
+               if (cstate->num_mixers == 4 && i >= 2)
+                       ctl->ops.setup_blendstage(ctl, mixer[i].hw_lm->idx,
+                               &stage_cfg, true);
+               else
+                       ctl->ops.setup_blendstage(ctl, mixer[i].hw_lm->idx,
+                               &stage_cfg, false);
        }
 }
 
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 76793201b984e..5d927f23e35b2 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -2049,9 +2049,13 @@ static void dpu_encoder_helper_reset_mixers(struct 
dpu_encoder_phys *phys_enc)
                if (phys_enc->hw_ctl->ops.update_pending_flush_mixer)
                        phys_enc->hw_ctl->ops.update_pending_flush_mixer(ctl, 
hw_mixer[i]->idx);
 
-               /* clear all blendstages */
-               if (phys_enc->hw_ctl->ops.setup_blendstage)
-                       phys_enc->hw_ctl->ops.setup_blendstage(ctl, 
hw_mixer[i]->idx, NULL);
+               /* clear all blendstages in both left and right */
+               if (phys_enc->hw_ctl->ops.setup_blendstage) {
+                       phys_enc->hw_ctl->ops.setup_blendstage(ctl,
+                               hw_mixer[i]->idx, NULL, false);
+                       phys_enc->hw_ctl->ops.setup_blendstage(ctl,
+                               hw_mixer[i]->idx, NULL, true);
+               }
        }
 }
 
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
index 602dfad127c2a..2072d18520326 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
@@ -478,12 +478,13 @@ static const struct ctl_blend_config 
ctl_blend_config[][2] = {
 };
 
 static void dpu_hw_ctl_setup_blendstage(struct dpu_hw_ctl *ctx,
-       enum dpu_lm lm, struct dpu_hw_stage_cfg *stage_cfg)
+       enum dpu_lm lm, struct dpu_hw_stage_cfg *stage_cfg, bool right)
 {
        struct dpu_hw_blk_reg_map *c = &ctx->hw;
        u32 mix, ext, mix_ext;
        u32 mixercfg[5] = { 0 };
        int i, j;
+       int pipe_start, pipe_end;
        int stages;
        int pipes_per_stage;
 
@@ -502,13 +503,27 @@ static void dpu_hw_ctl_setup_blendstage(struct dpu_hw_ctl 
*ctx,
        if (!stage_cfg)
                goto exit;
 
+       /*
+        * For quad pipe case, blend pipes in right side separately. Otherwise,
+        * all content is on the left half by defaut (no splitting case).
+        */
+       if (!right) {
+               pipe_start = 0;
+               pipe_end = pipes_per_stage == PIPES_PER_STAGE ? 2 : 1;
+       } else {
+               pipe_start = 2;
+               pipe_end = PIPES_PER_STAGE;
+       }
+
+       DRM_DEBUG_ATOMIC("blend lm %d on the %s side\n", lm - LM_0,
+                        right ? "right" : "left");
        for (i = 0; i <= stages; i++) {
                /* overflow to ext register if 'i + 1 > 7' */
                mix = (i + 1) & 0x7;
                ext = i >= 7;
                mix_ext = (i + 1) & 0xf;
 
-               for (j = 0 ; j < pipes_per_stage; j++) {
+               for (j = pipe_start; j < pipe_end; j++) {
                        enum dpu_sspp_multirect_index rect_index =
                                stage_cfg->multirect_index[i][j];
                        enum dpu_sspp pipe = stage_cfg->stage[i][j];
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h
index 557ec9a924f81..2dac7885fc5e7 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h
@@ -25,6 +25,8 @@ struct dpu_hw_ctl;
 /**
  * struct dpu_hw_stage_cfg - blending stage cfg
  * @stage : SSPP_ID at each stage
+ *          The first 2 in PIPES_PER_STAGE(4) are for the first SSPP.
+ *          The 3rd/4th in PIPES_PER_STAGE(4) are for the 2nd SSPP.
  * @multirect_index: index of the rectangle of SSPP.
  */
 struct dpu_hw_stage_cfg {
@@ -243,7 +245,7 @@ struct dpu_hw_ctl_ops {
         * @cfg       : blend stage configuration
         */
        void (*setup_blendstage)(struct dpu_hw_ctl *ctx,
-               enum dpu_lm lm, struct dpu_hw_stage_cfg *cfg);
+               enum dpu_lm lm, struct dpu_hw_stage_cfg *cfg, bool right);
 
        void (*set_active_pipes)(struct dpu_hw_ctl *ctx,
                unsigned long *fetch_active);

-- 
2.34.1

Reply via email to