Skip to content

Commit

Permalink
drm/msm/mdp5: update irqs on crtc<->encoder link change
Browse files Browse the repository at this point in the history
If crtc <-> encoder linkage changes, we could end up with the CRTC
listening for the wrong error or vsync irqs.  Generally this problem
would correct itself relatively quickly, since we update the global
irqmask after dispatching irqs, but to be sure let the CRTC trigger
update_irq().

Signed-off-by: Rob Clark <robdclark@gmail.com>
  • Loading branch information
Rob Clark committed Dec 18, 2014
1 parent f86afec commit 8bc1fe9
Show file tree
Hide file tree
Showing 4 changed files with 9 additions and 19 deletions.
5 changes: 1 addition & 4 deletions drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c
Original file line number Diff line number Diff line change
Expand Up @@ -455,10 +455,7 @@ void mdp5_crtc_set_intf(struct drm_crtc *crtc, int intf,
/* now that we know what irq's we want: */
mdp5_crtc->err.irqmask = intf2err(intf);
mdp5_crtc->vblank.irqmask = intf2vblank(intf);

/* when called from modeset_init(), skip the rest until later: */
if (!mdp5_kms)
return;
mdp_irq_update(&mdp5_kms->base);

spin_lock_irqsave(&mdp5_kms->resource_lock, flags);
intf_sel = mdp5_read(mdp5_kms, REG_MDP5_DISP_INTF_SEL);
Expand Down
12 changes: 1 addition & 11 deletions drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
Original file line number Diff line number Diff line change
Expand Up @@ -216,17 +216,7 @@ static int modeset_init(struct mdp5_kms *mdp5_kms)
goto fail;
}

/* NOTE: the vsync and error irq's are actually associated with
* the INTF/encoder.. the easiest way to deal with this (ie. what
* we do now) is assume a fixed relationship between crtc's and
* encoders. I'm not sure if there is ever a need to more freely
* assign crtcs to encoders, but if there is then we need to take
* care of error and vblank irq's that the crtc has registered,
* and also update user-requested vblank_mask.
*/
encoder->possible_crtcs = BIT(0);
mdp5_crtc_set_intf(priv->crtcs[0], 3, INTF_HDMI);

encoder->possible_crtcs = (1 << priv->num_crtcs) - 1;;
priv->encoders[priv->num_encoders++] = encoder;

/* Construct bridge/connector for HDMI: */
Expand Down
9 changes: 6 additions & 3 deletions drivers/gpu/drm/msm/mdp/mdp_kms.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,10 @@ static void update_irq(struct mdp_kms *mdp_kms)
mdp_kms->funcs->set_irqmask(mdp_kms, irqmask);
}

static void update_irq_unlocked(struct mdp_kms *mdp_kms)
/* if an mdp_irq's irqmask has changed, such as when mdp5 crtc<->encoder
* link changes, this must be called to figure out the new global irqmask
*/
void mdp_irq_update(struct mdp_kms *mdp_kms)
{
unsigned long flags;
spin_lock_irqsave(&list_lock, flags);
Expand Down Expand Up @@ -122,7 +125,7 @@ void mdp_irq_register(struct mdp_kms *mdp_kms, struct mdp_irq *irq)
spin_unlock_irqrestore(&list_lock, flags);

if (needs_update)
update_irq_unlocked(mdp_kms);
mdp_irq_update(mdp_kms);
}

void mdp_irq_unregister(struct mdp_kms *mdp_kms, struct mdp_irq *irq)
Expand All @@ -141,5 +144,5 @@ void mdp_irq_unregister(struct mdp_kms *mdp_kms, struct mdp_irq *irq)
spin_unlock_irqrestore(&list_lock, flags);

if (needs_update)
update_irq_unlocked(mdp_kms);
mdp_irq_update(mdp_kms);
}
2 changes: 1 addition & 1 deletion drivers/gpu/drm/msm/mdp/mdp_kms.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ void mdp_update_vblank_mask(struct mdp_kms *mdp_kms, uint32_t mask, bool enable)
void mdp_irq_wait(struct mdp_kms *mdp_kms, uint32_t irqmask);
void mdp_irq_register(struct mdp_kms *mdp_kms, struct mdp_irq *irq);
void mdp_irq_unregister(struct mdp_kms *mdp_kms, struct mdp_irq *irq);

void mdp_irq_update(struct mdp_kms *mdp_kms);

/*
* pixel format helpers:
Expand Down

0 comments on commit 8bc1fe9

Please sign in to comment.