Commit 4dd14fe6 authored by Rob Clark's avatar Rob Clark

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: default avatarRob Clark <robdclark@gmail.com>
parent d6ac4a84
...@@ -167,34 +167,54 @@ static bool mdp4_crtc_mode_fixup(struct drm_crtc *crtc, ...@@ -167,34 +167,54 @@ static bool mdp4_crtc_mode_fixup(struct drm_crtc *crtc,
return true; 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 drm_mode_config *config = &mdp4_kms->dev->mode_config;
struct mdp4_kms *mdp4_kms = get_kms(crtc); struct drm_crtc *crtc;
struct drm_plane *plane;
int i, ovlp = mdp4_crtc->ovlp;
uint32_t mixer_cfg = 0; uint32_t mixer_cfg = 0;
static const enum mdp_mixer_stage_id stages[] = { static const enum mdp_mixer_stage_id stages[] = {
STAGE_BASE, STAGE0, STAGE1, STAGE2, STAGE3, 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,
}; list_for_each_entry(crtc, &config->crtc_list, head) {
bool alpha[4]= { false, false, false, false }; 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 for_each_plane_on_crtc(crtc, plane) {
* own shadowed value. Possibly disable/reenable looses the enum mdp4_pipe pipe_id = mdp4_plane_pipe(plane);
* previous value and goes back to power-on default? int idx = idxs[pipe_id];
*/ mixer_cfg = mixercfg(mixer_cfg, mdp4_crtc->mixer,
mixer_cfg = mdp4_kms->mixer_cfg; 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_LOW0(ovlp), 0);
mdp4_write(mdp4_kms, REG_MDP4_OVLP_TRANSP_LOW1(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) ...@@ -209,13 +229,8 @@ static void blend_setup(struct drm_crtc *crtc)
to_mdp_format(msm_framebuffer_format(plane->fb)); to_mdp_format(msm_framebuffer_format(plane->fb));
alpha[idx-1] = format->alpha_enable; 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++) { for (i = 0; i < 4; i++) {
uint32_t op; uint32_t op;
...@@ -238,8 +253,7 @@ static void blend_setup(struct drm_crtc *crtc) ...@@ -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_write(mdp4_kms, REG_MDP4_OVLP_STAGE_TRANSP_HIGH1(ovlp, i), 0);
} }
mdp4_kms->mixer_cfg = mixer_cfg; setup_mixer(mdp4_kms);
mdp4_write(mdp4_kms, REG_MDP4_LAYERMIXER_IN_CFG, mixer_cfg);
} }
static void mdp4_crtc_mode_set_nofb(struct drm_crtc *crtc) static void mdp4_crtc_mode_set_nofb(struct drm_crtc *crtc)
......
...@@ -32,13 +32,6 @@ struct mdp4_kms { ...@@ -32,13 +32,6 @@ struct mdp4_kms {
int rev; 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: */ /* mapper-id used to request GEM buffer mapped for scanout: */
int id; int id;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment