diff --git a/[refs] b/[refs] index 14b2263b9dbb..d465229d74ac 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 8316f33766a82907c694267ff911e45e256f09f9 +refs/heads/master: 8c0a6bfef165ccdbf5d73afb9dd660107b0c98d5 diff --git a/trunk/drivers/gpu/drm/i915/intel_ringbuffer.c b/trunk/drivers/gpu/drm/i915/intel_ringbuffer.c index 89a65be8a3f3..31cd7e33e820 100644 --- a/trunk/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/trunk/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -696,20 +696,17 @@ int intel_wait_ring_buffer(struct drm_device *dev, drm_i915_private_t *dev_priv = dev->dev_private; u32 head; - head = intel_read_status_page(ring, 4); - if (head) { - ring->head = head & HEAD_ADDR; - ring->space = ring->head - (ring->tail + 8); - if (ring->space < 0) - ring->space += ring->size; - if (ring->space >= n) - return 0; - } - trace_i915_ring_wait_begin (dev); end = jiffies + 3 * HZ; do { - ring->head = I915_READ_HEAD(ring) & HEAD_ADDR; + /* If the reported head position has wrapped or hasn't advanced, + * fallback to the slow and accurate path. + */ + head = intel_read_status_page(ring, 4); + if (head < ring->actual_head) + head = I915_READ_HEAD(ring); + ring->actual_head = head; + ring->head = head & HEAD_ADDR; ring->space = ring->head - (ring->tail + 8); if (ring->space < 0) ring->space += ring->size; diff --git a/trunk/drivers/gpu/drm/i915/intel_ringbuffer.h b/trunk/drivers/gpu/drm/i915/intel_ringbuffer.h index 3126c2681983..d2cd0f1efeed 100644 --- a/trunk/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/trunk/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -30,8 +30,9 @@ struct intel_ring_buffer { struct drm_device *dev; struct drm_gem_object *gem_object; - unsigned int head; - unsigned int tail; + u32 actual_head; + u32 head; + u32 tail; int space; struct intel_hw_status_page status_page;