summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Gray <jsg@jsg.id.au>2013-03-04 18:59:38 +1100
committerJonathan Gray <jsg@jsg.id.au>2013-03-04 18:59:38 +1100
commit6390f59468cfa465f83be1e2bdb5548a436d4cf8 (patch)
tree340cd15446b6b6f437783f3bb81352d2402765db
parent15052a6e2a7efa642198f94959f759183b2e58ef (diff)
move the page flip sleep/wakeup handling a bit closer to linux
-rw-r--r--sys/dev/pci/drm/drm_atomic.h10
-rw-r--r--sys/dev/pci/drm/i915_drv.h1
-rw-r--r--sys/dev/pci/drm/intel_display.c15
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);
}