From 4dd14fe6fb8119d1d8c87127ebc74c63deb2ffc8 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Fri, 21 Nov 2014 11:18:01 -0500 Subject: [PATCH] drm/msm/mdp4: fix mixer setup for multi-crtc + planes On mdp4 there is a single global LAYERMIXER_IN_CFG register. The previous logic to share that between multiple crtcs didn't actually handle plane-disable very well. Easier just to look at all of the crtcs each time. Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c | 70 +++++++++++++++++++------------- drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h | 7 ---- 2 files changed, 42 insertions(+), 35 deletions(-) diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c index fef22e8..6781aa9 100644 --- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c +++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c @@ -167,34 +167,54 @@ static bool mdp4_crtc_mode_fixup(struct drm_crtc *crtc, return true; } -static void blend_setup(struct drm_crtc *crtc) +/* statically (for now) map planes to mixer stage (z-order): */ +static const int idxs[] = { + [VG1] = 1, + [VG2] = 2, + [RGB1] = 0, + [RGB2] = 0, + [RGB3] = 0, + [VG3] = 3, + [VG4] = 4, + +}; + +/* setup mixer config, for which we need to consider all crtc's and + * the planes attached to them + * + * TODO may possibly need some extra locking here + */ +static void setup_mixer(struct mdp4_kms *mdp4_kms) { - struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc); - struct mdp4_kms *mdp4_kms = get_kms(crtc); - struct drm_plane *plane; - int i, ovlp = mdp4_crtc->ovlp; + struct drm_mode_config *config = &mdp4_kms->dev->mode_config; + struct drm_crtc *crtc; uint32_t mixer_cfg = 0; static const enum mdp_mixer_stage_id stages[] = { STAGE_BASE, STAGE0, STAGE1, STAGE2, STAGE3, }; - /* statically (for now) map planes to mixer stage (z-order): */ - static const int idxs[] = { - [VG1] = 1, - [VG2] = 2, - [RGB1] = 0, - [RGB2] = 0, - [RGB3] = 0, - [VG3] = 3, - [VG4] = 4, - }; - bool alpha[4]= { false, false, false, false }; + list_for_each_entry(crtc, &config->crtc_list, head) { + struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc); + struct drm_plane *plane; - /* Don't rely on value read back from hw, but instead use our - * own shadowed value. Possibly disable/reenable looses the - * previous value and goes back to power-on default? - */ - mixer_cfg = mdp4_kms->mixer_cfg; + for_each_plane_on_crtc(crtc, plane) { + enum mdp4_pipe pipe_id = mdp4_plane_pipe(plane); + int idx = idxs[pipe_id]; + mixer_cfg = mixercfg(mixer_cfg, mdp4_crtc->mixer, + pipe_id, stages[idx]); + } + } + + mdp4_write(mdp4_kms, REG_MDP4_LAYERMIXER_IN_CFG, mixer_cfg); +} + +static void blend_setup(struct drm_crtc *crtc) +{ + struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc); + struct mdp4_kms *mdp4_kms = get_kms(crtc); + struct drm_plane *plane; + int i, ovlp = mdp4_crtc->ovlp; + bool alpha[4]= { false, false, false, false }; mdp4_write(mdp4_kms, REG_MDP4_OVLP_TRANSP_LOW0(ovlp), 0); mdp4_write(mdp4_kms, REG_MDP4_OVLP_TRANSP_LOW1(ovlp), 0); @@ -209,13 +229,8 @@ static void blend_setup(struct drm_crtc *crtc) to_mdp_format(msm_framebuffer_format(plane->fb)); alpha[idx-1] = format->alpha_enable; } - mixer_cfg = mixercfg(mixer_cfg, mdp4_crtc->mixer, - pipe_id, stages[idx]); } - /* this shouldn't happen.. and seems to cause underflow: */ - WARN_ON(!mixer_cfg); - for (i = 0; i < 4; i++) { uint32_t op; @@ -238,8 +253,7 @@ static void blend_setup(struct drm_crtc *crtc) mdp4_write(mdp4_kms, REG_MDP4_OVLP_STAGE_TRANSP_HIGH1(ovlp, i), 0); } - mdp4_kms->mixer_cfg = mixer_cfg; - mdp4_write(mdp4_kms, REG_MDP4_LAYERMIXER_IN_CFG, mixer_cfg); + setup_mixer(mdp4_kms); } static void mdp4_crtc_mode_set_nofb(struct drm_crtc *crtc) diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h index 7706452..cbd77bc 100644 --- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h +++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h @@ -32,13 +32,6 @@ struct mdp4_kms { int rev; - /* Shadow value for MDP4_LAYERMIXER_IN_CFG.. since setup for all - * crtcs/encoders is in one shared register, we need to update it - * via read/modify/write. But to avoid getting confused by power- - * on-default values after resume, use this shadow value instead: - */ - uint32_t mixer_cfg; - /* mapper-id used to request GEM buffer mapped for scanout: */ int id; -- 2.7.4