summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_ringbuffer.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2010-12-22 15:04:47 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2011-01-11 21:35:41 +0100
commit55249baaa5cd188ebd9acdb047eeaed8092e4a93 (patch)
treeec52e1bdb516ce0bd259614b3c068960450b9236 /drivers/gpu/drm/i915/intel_ringbuffer.c
parentdrm/i915: Use the mappable sizes determined by GTT for consistency. (diff)
downloadlinux-55249baaa5cd188ebd9acdb047eeaed8092e4a93.tar.xz
linux-55249baaa5cd188ebd9acdb047eeaed8092e4a93.zip
drm/i915: Workaround erratum on i830 for TAIL pointer within last 2 cachelines
On i830 if the tail pointer is set to within 2 cachelines of the end of the buffer, the chip may hang. So instead if the tail were to land in that location, we pad the end of the buffer with NOPs, and start again at the beginning. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'drivers/gpu/drm/i915/intel_ringbuffer.c')
-rw-r--r--drivers/gpu/drm/i915/intel_ringbuffer.c13
1 files changed, 10 insertions, 3 deletions
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index 56bc95c056dd..2de0e45464c5 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -785,6 +785,14 @@ int intel_init_ring_buffer(struct drm_device *dev,
if (ret)
goto err_unmap;
+ /* Workaround an erratum on the i830 which causes a hang if
+ * the TAIL pointer points to within the last 2 cachelines
+ * of the buffer.
+ */
+ ring->effective_size = ring->size;
+ if (IS_I830(ring->dev))
+ ring->effective_size -= 128;
+
return 0;
err_unmap:
@@ -827,8 +835,7 @@ void intel_cleanup_ring_buffer(struct intel_ring_buffer *ring)
static int intel_wrap_ring_buffer(struct intel_ring_buffer *ring)
{
unsigned int *virt;
- int rem;
- rem = ring->size - ring->tail;
+ int rem = ring->size - ring->tail;
if (ring->space < rem) {
int ret = intel_wait_ring_buffer(ring, rem);
@@ -895,7 +902,7 @@ int intel_ring_begin(struct intel_ring_buffer *ring,
int n = 4*num_dwords;
int ret;
- if (unlikely(ring->tail + n > ring->size)) {
+ if (unlikely(ring->tail + n > ring->effective_size)) {
ret = intel_wrap_ring_buffer(ring);
if (unlikely(ret))
return ret;