aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/omapdrm/omap_crtc.c33
1 files changed, 22 insertions, 11 deletions
diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c
index 7b67ecb02b74..827ac46a6d5e 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -69,6 +69,19 @@ enum omap_channel omap_crtc_channel(struct drm_crtc *crtc)
69 return omap_crtc->channel; 69 return omap_crtc->channel;
70} 70}
71 71
72static bool omap_crtc_is_pending(struct drm_crtc *crtc)
73{
74 struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
75 unsigned long flags;
76 bool pending;
77
78 spin_lock_irqsave(&crtc->dev->event_lock, flags);
79 pending = omap_crtc->pending;
80 spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
81
82 return pending;
83}
84
72int omap_crtc_wait_pending(struct drm_crtc *crtc) 85int omap_crtc_wait_pending(struct drm_crtc *crtc)
73{ 86{
74 struct omap_crtc *omap_crtc = to_omap_crtc(crtc); 87 struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
@@ -78,7 +91,7 @@ int omap_crtc_wait_pending(struct drm_crtc *crtc)
78 * a single frame refresh even on slower displays. 91 * a single frame refresh even on slower displays.
79 */ 92 */
80 return wait_event_timeout(omap_crtc->pending_wait, 93 return wait_event_timeout(omap_crtc->pending_wait,
81 !omap_crtc->pending, 94 !omap_crtc_is_pending(crtc),
82 msecs_to_jiffies(250)); 95 msecs_to_jiffies(250));
83} 96}
84 97
@@ -296,6 +309,7 @@ static void omap_crtc_vblank_irq(struct omap_drm_irq *irq, uint32_t irqstatus)
296 struct omap_crtc *omap_crtc = 309 struct omap_crtc *omap_crtc =
297 container_of(irq, struct omap_crtc, vblank_irq); 310 container_of(irq, struct omap_crtc, vblank_irq);
298 struct drm_device *dev = omap_crtc->base.dev; 311 struct drm_device *dev = omap_crtc->base.dev;
312 struct drm_crtc *crtc = &omap_crtc->base;
299 313
300 if (dispc_mgr_go_busy(omap_crtc->channel)) 314 if (dispc_mgr_go_busy(omap_crtc->channel))
301 return; 315 return;
@@ -304,10 +318,10 @@ static void omap_crtc_vblank_irq(struct omap_drm_irq *irq, uint32_t irqstatus)
304 318
305 __omap_irq_unregister(dev, &omap_crtc->vblank_irq); 319 __omap_irq_unregister(dev, &omap_crtc->vblank_irq);
306 320
307 rmb(); 321 spin_lock(&crtc->dev->event_lock);
308 WARN_ON(!omap_crtc->pending); 322 WARN_ON(!omap_crtc->pending);
309 omap_crtc->pending = false; 323 omap_crtc->pending = false;
310 wmb(); 324 spin_unlock(&crtc->dev->event_lock);
311 325
312 /* wake up userspace */ 326 /* wake up userspace */
313 omap_crtc_complete_page_flip(&omap_crtc->base); 327 omap_crtc_complete_page_flip(&omap_crtc->base);
@@ -339,10 +353,10 @@ static void omap_crtc_enable(struct drm_crtc *crtc)
339 353
340 DBG("%s", omap_crtc->name); 354 DBG("%s", omap_crtc->name);
341 355
342 rmb(); 356 spin_lock_irq(&crtc->dev->event_lock);
343 WARN_ON(omap_crtc->pending); 357 WARN_ON(omap_crtc->pending);
344 omap_crtc->pending = true; 358 omap_crtc->pending = true;
345 wmb(); 359 spin_unlock_irq(&crtc->dev->event_lock);
346 360
347 omap_irq_register(crtc->dev, &omap_crtc->vblank_irq); 361 omap_irq_register(crtc->dev, &omap_crtc->vblank_irq);
348 362
@@ -427,16 +441,13 @@ static void omap_crtc_atomic_flush(struct drm_crtc *crtc,
427 441
428 DBG("%s: GO", omap_crtc->name); 442 DBG("%s: GO", omap_crtc->name);
429 443
430 rmb(); 444 spin_lock_irq(&crtc->dev->event_lock);
431 WARN_ON(omap_crtc->pending); 445 WARN_ON(omap_crtc->pending);
432 omap_crtc->pending = true; 446 omap_crtc->pending = true;
433 wmb();
434 447
435 if (crtc->state->event) { 448 if (crtc->state->event)
436 spin_lock_irq(&crtc->dev->event_lock);
437 omap_crtc->event = crtc->state->event; 449 omap_crtc->event = crtc->state->event;
438 spin_unlock_irq(&crtc->dev->event_lock); 450 spin_unlock_irq(&crtc->dev->event_lock);
439 }
440 451
441 dispc_mgr_go(omap_crtc->channel); 452 dispc_mgr_go(omap_crtc->channel);
442 omap_irq_register(crtc->dev, &omap_crtc->vblank_irq); 453 omap_irq_register(crtc->dev, &omap_crtc->vblank_irq);