From 6390f59468cfa465f83be1e2bdb5548a436d4cf8 Mon Sep 17 00:00:00 2001 From: Jonathan Gray Date: Mon, 4 Mar 2013 18:59:38 +1100 Subject: move the page flip sleep/wakeup handling a bit closer to linux --- sys/dev/pci/drm/drm_atomic.h | 10 ++++++++++ sys/dev/pci/drm/i915_drv.h | 1 + sys/dev/pci/drm/intel_display.c | 15 +++++++-------- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/sys/dev/pci/drm/drm_atomic.h b/sys/dev/pci/drm/drm_atomic.h index 07df9a8739a..80080970551 100644 --- a/sys/dev/pci/drm/drm_atomic.h +++ b/sys/dev/pci/drm/drm_atomic.h @@ -60,6 +60,16 @@ atomic_add_return(int n, atomic_t *p) return (*p); } +static inline int +atomic_inc_not_zero(atomic_t *p) +{ + if (*p == 0) + return (0); + + *(p) += 1; + return (*p); +} + #define atomic_sub(n, p) (*(p) -= (n)) /* FIXME */ #define atomic_add_int(p, v) *(p) += v diff --git a/sys/dev/pci/drm/i915_drv.h b/sys/dev/pci/drm/i915_drv.h index 5d6b81839b5..efc187c058c 100644 --- a/sys/dev/pci/drm/i915_drv.h +++ b/sys/dev/pci/drm/i915_drv.h @@ -734,6 +734,7 @@ struct inteldrm_softc { struct drm_crtc *plane_to_crtc_mapping[3]; struct drm_crtc *pipe_to_crtc_mapping[3]; + int pending_flip_queue; bool flip_pending_is_done; diff --git a/sys/dev/pci/drm/intel_display.c b/sys/dev/pci/drm/intel_display.c index 9a88f3fe332..23d2d7c445e 100644 --- a/sys/dev/pci/drm/intel_display.c +++ b/sys/dev/pci/drm/intel_display.c @@ -2723,7 +2723,7 @@ intel_finish_fb(struct drm_framebuffer *old_fb) mtx_enter(&dev->event_lock); while(!atomic_read(&dev_priv->mm.wedged) && atomic_read(&obj->pending_flip) != 0) { - msleep(&obj->pending_flip, &dev->event_lock, + msleep(&dev_priv->pending_flip_queue, &dev->event_lock, 0, "915flp", 0); } mtx_leave(&dev->event_lock); @@ -3441,14 +3441,15 @@ intel_crtc_wait_for_pending_flips(struct drm_crtc *crtc) { struct drm_i915_gem_object *obj; struct drm_device *dev = crtc->dev; + struct inteldrm_softc *dev_priv = dev->dev_private; if (crtc->fb == NULL) return; obj = to_intel_framebuffer(crtc->fb)->obj; mtx_enter(&dev->event_lock); - while (atomic_read(&obj->pending_flip) != 0) - msleep(&obj->pending_flip, &dev->event_lock, 0, "915wfl", 0); + while (intel_crtc_has_pending_flip(crtc)) + msleep(&dev_priv->pending_flip_queue, &dev->event_lock, 0, "915wfl", 0); mtx_leave(&dev->event_lock); DRM_LOCK(); @@ -7679,7 +7680,7 @@ void do_intel_finish_page_flip(struct drm_device *dev, struct drm_crtc *crtc) { -// drm_i915_private_t *dev_priv = dev->dev_private; + drm_i915_private_t *dev_priv = dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct intel_unpin_work *work; struct drm_i915_gem_object *obj; @@ -7714,8 +7715,7 @@ do_intel_finish_page_flip(struct drm_device *dev, obj = work->old_fb_obj; atomic_clear_int(&obj->pending_flip, 1 << intel_crtc->plane); - if (atomic_read(&obj->pending_flip) == 0) - wakeup(&obj->pending_flip); + wakeup(&dev_priv->pending_flip_queue); workq_queue_task(NULL, &work->task, 0, intel_unpin_work_fn, work, NULL); @@ -7753,8 +7753,7 @@ intel_prepare_page_flip(struct drm_device *dev, int plane) */ mtx_enter(&dev->event_lock); if (intel_crtc->unpin_work) - if ((++intel_crtc->unpin_work->pending) > 1) - DRM_ERROR("Prepared flip multiple times\n"); + atomic_inc_not_zero(&intel_crtc->unpin_work->pending); mtx_leave(&dev->event_lock); } -- cgit v1.2.3