diff options
Diffstat (limited to 'drivers/gpu/drm/omapdrm/omap_crtc.c')
-rw-r--r-- | drivers/gpu/drm/omapdrm/omap_crtc.c | 21 |
1 files changed, 13 insertions, 8 deletions
diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c index e91687fe41be..c5c21776131a 100644 --- a/drivers/gpu/drm/omapdrm/omap_crtc.c +++ b/drivers/gpu/drm/omapdrm/omap_crtc.c | |||
@@ -72,6 +72,8 @@ struct omap_crtc { | |||
72 | * XXX maybe fold into apply_work?? | 72 | * XXX maybe fold into apply_work?? |
73 | */ | 73 | */ |
74 | struct work_struct page_flip_work; | 74 | struct work_struct page_flip_work; |
75 | |||
76 | bool ignore_digit_sync_lost; | ||
75 | }; | 77 | }; |
76 | 78 | ||
77 | /* ----------------------------------------------------------------------------- | 79 | /* ----------------------------------------------------------------------------- |
@@ -157,7 +159,7 @@ static void omap_crtc_set_enabled(struct drm_crtc *crtc, bool enable) | |||
157 | * Digit output produces some sync lost interrupts during the first | 159 | * Digit output produces some sync lost interrupts during the first |
158 | * frame when enabling, so we need to ignore those. | 160 | * frame when enabling, so we need to ignore those. |
159 | */ | 161 | */ |
160 | omap_irq_unregister(crtc->dev, &omap_crtc->error_irq); | 162 | omap_crtc->ignore_digit_sync_lost = true; |
161 | 163 | ||
162 | framedone_irq = dispc_mgr_get_framedone_irq(channel); | 164 | framedone_irq = dispc_mgr_get_framedone_irq(channel); |
163 | vsync_irq = dispc_mgr_get_vsync_irq(channel); | 165 | vsync_irq = dispc_mgr_get_vsync_irq(channel); |
@@ -188,7 +190,9 @@ static void omap_crtc_set_enabled(struct drm_crtc *crtc, bool enable) | |||
188 | omap_crtc->name, enable ? "enable" : "disable"); | 190 | omap_crtc->name, enable ? "enable" : "disable"); |
189 | } | 191 | } |
190 | 192 | ||
191 | omap_irq_register(crtc->dev, &omap_crtc->error_irq); | 193 | omap_crtc->ignore_digit_sync_lost = false; |
194 | /* make sure the irq handler sees the value above */ | ||
195 | mb(); | ||
192 | } | 196 | } |
193 | 197 | ||
194 | 198 | ||
@@ -260,10 +264,14 @@ static void omap_crtc_error_irq(struct omap_drm_irq *irq, uint32_t irqstatus) | |||
260 | { | 264 | { |
261 | struct omap_crtc *omap_crtc = | 265 | struct omap_crtc *omap_crtc = |
262 | container_of(irq, struct omap_crtc, error_irq); | 266 | container_of(irq, struct omap_crtc, error_irq); |
263 | struct drm_crtc *crtc = &omap_crtc->base; | 267 | |
268 | if (omap_crtc->ignore_digit_sync_lost) { | ||
269 | irqstatus &= ~DISPC_IRQ_SYNC_LOST_DIGIT; | ||
270 | if (!irqstatus) | ||
271 | return; | ||
272 | } | ||
273 | |||
264 | DRM_ERROR_RATELIMITED("%s: errors: %08x\n", omap_crtc->name, irqstatus); | 274 | DRM_ERROR_RATELIMITED("%s: errors: %08x\n", omap_crtc->name, irqstatus); |
265 | /* avoid getting in a flood, unregister the irq until next vblank */ | ||
266 | __omap_irq_unregister(crtc->dev, &omap_crtc->error_irq); | ||
267 | } | 275 | } |
268 | 276 | ||
269 | static void omap_crtc_apply_irq(struct omap_drm_irq *irq, uint32_t irqstatus) | 277 | static void omap_crtc_apply_irq(struct omap_drm_irq *irq, uint32_t irqstatus) |
@@ -272,9 +280,6 @@ static void omap_crtc_apply_irq(struct omap_drm_irq *irq, uint32_t irqstatus) | |||
272 | container_of(irq, struct omap_crtc, apply_irq); | 280 | container_of(irq, struct omap_crtc, apply_irq); |
273 | struct drm_crtc *crtc = &omap_crtc->base; | 281 | struct drm_crtc *crtc = &omap_crtc->base; |
274 | 282 | ||
275 | if (!omap_crtc->error_irq.registered) | ||
276 | __omap_irq_register(crtc->dev, &omap_crtc->error_irq); | ||
277 | |||
278 | if (!dispc_mgr_go_busy(omap_crtc->channel)) { | 283 | if (!dispc_mgr_go_busy(omap_crtc->channel)) { |
279 | struct omap_drm_private *priv = | 284 | struct omap_drm_private *priv = |
280 | crtc->dev->dev_private; | 285 | crtc->dev->dev_private; |