diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2010-11-05 04:56:38 -0400 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2010-11-08 04:21:47 -0500 |
commit | 08deebf98783d3de553eed2c9b6b8dcc7e168567 (patch) | |
tree | c47353e5384038c34614cd8c00025976a8de5b28 /drivers/gpu | |
parent | b47b30ccdaad5f2fc39a1a65921bffd150574a91 (diff) |
drm/i915/ringbuffer: Use the HEAD auto-reporting mechanism
My Sandybridge only reports 0 for the ring buffer registers, causing it
to hang as soon as we exhaust the available ring. As a workaround, take
advantage of our huge ring buffers and use the auto-reporting mechanism
to update the status page with the HEAD location every 64 KiB.
Cherry-picked from 6aa56062eaba67adfb247cded244fd877329588d.
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=31404
Tested-by: Zhao Jian <jian.j.zhao@intel.com>
Cc: stable@kernel.org
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/i915/intel_ringbuffer.c | 13 |
1 files changed, 12 insertions, 1 deletions
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 7c1f3ff2f788..b83306f9244b 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c | |||
@@ -177,7 +177,7 @@ static int init_ring_common(struct drm_device *dev, | |||
177 | 177 | ||
178 | I915_WRITE_CTL(ring, | 178 | I915_WRITE_CTL(ring, |
179 | ((ring->gem_object->size - PAGE_SIZE) & RING_NR_PAGES) | 179 | ((ring->gem_object->size - PAGE_SIZE) & RING_NR_PAGES) |
180 | | RING_NO_REPORT | RING_VALID); | 180 | | RING_REPORT_64K | RING_VALID); |
181 | 181 | ||
182 | head = I915_READ_HEAD(ring) & HEAD_ADDR; | 182 | head = I915_READ_HEAD(ring) & HEAD_ADDR; |
183 | /* If the head is still not zero, the ring is dead */ | 183 | /* If the head is still not zero, the ring is dead */ |
@@ -692,6 +692,17 @@ int intel_wait_ring_buffer(struct drm_device *dev, | |||
692 | { | 692 | { |
693 | unsigned long end; | 693 | unsigned long end; |
694 | drm_i915_private_t *dev_priv = dev->dev_private; | 694 | drm_i915_private_t *dev_priv = dev->dev_private; |
695 | u32 head; | ||
696 | |||
697 | head = intel_read_status_page(ring, 4); | ||
698 | if (head) { | ||
699 | ring->head = head & HEAD_ADDR; | ||
700 | ring->space = ring->head - (ring->tail + 8); | ||
701 | if (ring->space < 0) | ||
702 | ring->space += ring->size; | ||
703 | if (ring->space >= n) | ||
704 | return 0; | ||
705 | } | ||
695 | 706 | ||
696 | trace_i915_ring_wait_begin (dev); | 707 | trace_i915_ring_wait_begin (dev); |
697 | end = jiffies + 3 * HZ; | 708 | end = jiffies + 3 * HZ; |