aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/omapdrm/omap_crtc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/omapdrm/omap_crtc.c')
-rw-r--r--drivers/gpu/drm/omapdrm/omap_crtc.c21
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
269static void omap_crtc_apply_irq(struct omap_drm_irq *irq, uint32_t irqstatus) 277static 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;