diff options
| author | Abhijit Kulkarni <kabhijit@codeaurora.org> | 2016-06-24 18:36:28 -0400 |
|---|---|---|
| committer | Dhaval Patel <pdhaval@codeaurora.org> | 2016-08-01 11:58:08 -0700 |
| commit | 066cba337c43d9637ea57f9fefdcacbdc5dcc3fe (patch) | |
| tree | 62b92fabed01b33de2d7c5368fe0fe57d545caa0 /drivers/gpu | |
| parent | c7b9250a6b52981c4f954a071c21e6cbdf8bf73f (diff) | |
drm/msm/sde: add blending support for more use cases
Update mixer/blending configuration to support different
use cases, opaque blending, and alpha blending configs. Also
fixes layer mixer hw programming offsets to support these.
Change-Id: I0073a98740f23370da704f7ddc4642ad7fd10551
Signed-off-by: Abhijit Kulkarni <kabhijit@codeaurora.org>
Diffstat (limited to 'drivers/gpu')
| -rw-r--r-- | drivers/gpu/drm/msm/sde/sde_crtc.c | 88 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/sde/sde_hw_lm.c | 18 |
2 files changed, 51 insertions, 55 deletions
diff --git a/drivers/gpu/drm/msm/sde/sde_crtc.c b/drivers/gpu/drm/msm/sde/sde_crtc.c index 296d101e62a4..2ebdfe83c5ed 100644 --- a/drivers/gpu/drm/msm/sde/sde_crtc.c +++ b/drivers/gpu/drm/msm/sde/sde_crtc.c @@ -155,14 +155,7 @@ static void sde_crtc_mode_set_nofb(struct drm_crtc *crtc) mode = &crtc->state->adjusted_mode; - DBG("%s: set mode: %d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x", - sde_crtc->name, mode->base.id, mode->name, - mode->vrefresh, mode->clock, - mode->hdisplay, mode->hsync_start, - mode->hsync_end, mode->htotal, - mode->vdisplay, mode->vsync_start, - mode->vsync_end, mode->vtotal, - mode->type, mode->flags); + drm_mode_debug_printmodeline(mode); /* * reserve mixer(s) if not already avaialable @@ -207,8 +200,7 @@ static void sde_crtc_get_blend_cfg(struct sde_hw_blend_cfg *cfg, msm_framebuffer_format(pstate->base.fb)); plane = pstate->base.plane; - cfg->fg.alpha_sel = ALPHA_FG_CONST; - cfg->bg.alpha_sel = ALPHA_BG_CONST; + memset(cfg, 0, sizeof(*cfg)); cfg->fg.const_alpha = pstate->property_values[PLANE_PROP_ALPHA]; cfg->bg.const_alpha = 0xFF - cfg->fg.const_alpha; @@ -237,6 +229,13 @@ static void sde_crtc_get_blend_cfg(struct sde_hw_blend_cfg *cfg, } else { cfg->bg.inv_mode_alpha = 1; } + } else { + /* opaque blending */ + cfg->fg.alpha_sel = ALPHA_FG_CONST; + cfg->bg.alpha_sel = ALPHA_BG_CONST; + cfg->bg.inv_alpha_sel = 1; + cfg->fg.const_alpha = 0xFF; + cfg->bg.const_alpha = 0x00; } } @@ -245,14 +244,15 @@ static void blend_setup(struct drm_crtc *crtc) struct sde_crtc *sde_crtc = to_sde_crtc(crtc); struct sde_crtc_mixer *mixer = sde_crtc->mixer; struct drm_plane *plane; - struct sde_plane_state *pstate, *pstates[SDE_STAGE_MAX] = {0}; + struct sde_plane_state *pstate; struct sde_hw_stage_cfg stage_cfg; struct sde_hw_blend_cfg blend; struct sde_hw_ctl *ctl; struct sde_hw_mixer *lm; + struct sde_hw_color3_cfg alpha_out; u32 flush_mask = 0; unsigned long flags; - int i, j, plane_cnt = 0; + int i, plane_cnt = 0; DBG(""); spin_lock_irqsave(&sde_crtc->lm_lock, flags); @@ -263,16 +263,24 @@ static void blend_setup(struct drm_crtc *crtc) /* initialize stage cfg */ memset(&stage_cfg, 0, sizeof(stage_cfg)); - memset(&blend, 0, sizeof(blend)); - - /* Collect all plane information */ - drm_atomic_crtc_for_each_plane(plane, crtc) { - pstate = to_sde_plane_state(plane->state); - pstates[pstate->stage] = pstate; - plane_cnt++; - for (i = 0; i < sde_crtc->num_mixers; i++) { + + for (i = 0; i < sde_crtc->num_mixers; i++) { + if ((!mixer[i].hw_lm) || (!mixer[i].hw_ctl)) + continue; + + ctl = mixer[i].hw_ctl; + lm = mixer[i].hw_lm; + memset(&alpha_out, 0, sizeof(alpha_out)); + + drm_atomic_crtc_for_each_plane(plane, crtc) { + pstate = to_sde_plane_state(plane->state); stage_cfg.stage[pstate->stage][i] = sde_plane_pipe(plane); + DBG(" crtc_id %d, layer %d, at stage %d\n", + sde_crtc->id, + sde_plane_pipe(plane), + pstate->stage); + plane_cnt++; /* Cache the flushmask for this layer * sourcesplit is always enabled, so this layer will @@ -281,7 +289,19 @@ static void blend_setup(struct drm_crtc *crtc) ctl = mixer[i].hw_ctl; ctl->ops.get_bitmask_sspp(ctl, &flush_mask, sde_plane_pipe(plane)); + + /* blend config */ + sde_crtc_get_blend_cfg(&blend, pstate); + lm->ops.setup_blend_config(lm, pstate->stage, &blend); + alpha_out.keep_fg[pstate->stage] = 1; } + lm->ops.setup_alpha_out(lm, &alpha_out); + + /* stage config flush mask */ + mixer[i].flush_mask = flush_mask; + /* get the flush mask for mixer */ + ctl->ops.get_bitmask_mixer(ctl, &mixer[i].flush_mask, + mixer[i].hw_lm->idx); } /* @@ -294,12 +314,9 @@ static void blend_setup(struct drm_crtc *crtc) DBG("Border Color is enabled\n"); } - /* Program hw */ - for (i = 0; i < sde_crtc->num_mixers; i++) { - if (!mixer[i].hw_lm) - continue; - - if (!mixer[i].hw_ctl) + /* Program ctl_paths */ + for (i = 0; i < sde_crtc->num_ctls; i++) { + if ((!mixer[i].hw_lm) || (!mixer[i].hw_ctl)) continue; ctl = mixer[i].hw_ctl; @@ -308,25 +325,6 @@ static void blend_setup(struct drm_crtc *crtc) /* stage config */ ctl->ops.setup_blendstage(ctl, mixer[i].hw_lm->idx, &stage_cfg); - /* stage config flush mask */ - mixer[i].flush_mask = flush_mask; - /* get the flush mask for mixer */ - ctl->ops.get_bitmask_mixer(ctl, &mixer[i].flush_mask, - mixer[i].hw_lm->idx); - - /* blend config */ - for (j = SDE_STAGE_0; j < SDE_STAGE_MAX; j++) { - if (!pstates[j]) - continue; - sde_crtc_get_blend_cfg(&blend, pstates[j]); - blend.fg.alpha_sel = ALPHA_FG_CONST; - blend.bg.alpha_sel = ALPHA_BG_CONST; - blend.fg.const_alpha = - (u32)pstate->property_values[PLANE_PROP_ALPHA]; - blend.bg.const_alpha = 0xFF - - (u32)pstate->property_values[PLANE_PROP_ALPHA]; - lm->ops.setup_blend_config(lm, j, &blend); - } } out: spin_unlock_irqrestore(&sde_crtc->lm_lock, flags); diff --git a/drivers/gpu/drm/msm/sde/sde_hw_lm.c b/drivers/gpu/drm/msm/sde/sde_hw_lm.c index 97f5645a6f39..0591d89fc84b 100644 --- a/drivers/gpu/drm/msm/sde/sde_hw_lm.c +++ b/drivers/gpu/drm/msm/sde/sde_hw_lm.c @@ -120,14 +120,12 @@ static void sde_hw_lm_setup_blendcfg(struct sde_hw_mixer *ctx, /* bg */ blend_op |= (bg->alpha_sel & 3) << 8; - blend_op |= (bg->inv_alpha_sel & 1) << 2; - blend_op |= (bg->mod_alpha & 1) << 3; - blend_op |= (bg->inv_mode_alpha & 1) << 4; - - SDE_REG_WRITE(c, LM_BLEND0_FG_ALPHA + stage_off, - fg->const_alpha); - SDE_REG_WRITE(c, LM_BLEND0_BG_ALPHA + stage_off, - bg->const_alpha); + blend_op |= (bg->inv_alpha_sel & 1) << 10; + blend_op |= (bg->mod_alpha & 1) << 11; + blend_op |= (bg->inv_mode_alpha & 1) << 12; + + SDE_REG_WRITE(c, LM_BLEND0_FG_ALPHA + stage_off, fg->const_alpha); + SDE_REG_WRITE(c, LM_BLEND0_BG_ALPHA + stage_off, bg->const_alpha); SDE_REG_WRITE(c, LM_BLEND0_OP + stage_off, blend_op); } @@ -142,8 +140,8 @@ static void sde_hw_lm_setup_color3(struct sde_hw_mixer *ctx, /* read the existing op_mode configuration */ op_mode = SDE_REG_READ(c, LM_OP_MODE); - for (i = 0; i < maxblendstages; i++) - op_mode |= ((cfg->keep_fg[i] & 0x1) << i); + for (i = SDE_STAGE_0; i <= maxblendstages; i++) + op_mode |= (cfg->keep_fg[i]) ? (1 << i) : 0; SDE_REG_WRITE(c, LM_OP_MODE, op_mode); } |
