diff options
-rw-r--r-- | drivers/gpu/drm/i915/intel_ringbuffer.c | 40 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_ringbuffer.h | 1 |
2 files changed, 24 insertions, 17 deletions
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 51fbc5e33c55..6218fa97aa1e 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c | |||
@@ -34,6 +34,14 @@ | |||
34 | #include "i915_trace.h" | 34 | #include "i915_trace.h" |
35 | #include "intel_drv.h" | 35 | #include "intel_drv.h" |
36 | 36 | ||
37 | static inline int ring_space(struct intel_ring_buffer *ring) | ||
38 | { | ||
39 | int space = (ring->head & HEAD_ADDR) - (ring->tail + 8); | ||
40 | if (space < 0) | ||
41 | space += ring->size; | ||
42 | return space; | ||
43 | } | ||
44 | |||
37 | static u32 i915_gem_get_seqno(struct drm_device *dev) | 45 | static u32 i915_gem_get_seqno(struct drm_device *dev) |
38 | { | 46 | { |
39 | drm_i915_private_t *dev_priv = dev->dev_private; | 47 | drm_i915_private_t *dev_priv = dev->dev_private; |
@@ -204,11 +212,9 @@ static int init_ring_common(struct intel_ring_buffer *ring) | |||
204 | if (!drm_core_check_feature(ring->dev, DRIVER_MODESET)) | 212 | if (!drm_core_check_feature(ring->dev, DRIVER_MODESET)) |
205 | i915_kernel_lost_context(ring->dev); | 213 | i915_kernel_lost_context(ring->dev); |
206 | else { | 214 | else { |
207 | ring->head = I915_READ_HEAD(ring) & HEAD_ADDR; | 215 | ring->head = I915_READ_HEAD(ring); |
208 | ring->tail = I915_READ_TAIL(ring) & TAIL_ADDR; | 216 | ring->tail = I915_READ_TAIL(ring) & TAIL_ADDR; |
209 | ring->space = ring->head - (ring->tail + 8); | 217 | ring->space = ring_space(ring); |
210 | if (ring->space < 0) | ||
211 | ring->space += ring->size; | ||
212 | } | 218 | } |
213 | 219 | ||
214 | return 0; | 220 | return 0; |
@@ -921,7 +927,7 @@ static int intel_wrap_ring_buffer(struct intel_ring_buffer *ring) | |||
921 | } | 927 | } |
922 | 928 | ||
923 | ring->tail = 0; | 929 | ring->tail = 0; |
924 | ring->space = ring->head - 8; | 930 | ring->space = ring_space(ring); |
925 | 931 | ||
926 | return 0; | 932 | return 0; |
927 | } | 933 | } |
@@ -933,20 +939,22 @@ int intel_wait_ring_buffer(struct intel_ring_buffer *ring, int n) | |||
933 | unsigned long end; | 939 | unsigned long end; |
934 | u32 head; | 940 | u32 head; |
935 | 941 | ||
942 | /* If the reported head position has wrapped or hasn't advanced, | ||
943 | * fallback to the slow and accurate path. | ||
944 | */ | ||
945 | head = intel_read_status_page(ring, 4); | ||
946 | if (head > ring->head) { | ||
947 | ring->head = head; | ||
948 | ring->space = ring_space(ring); | ||
949 | if (ring->space >= n) | ||
950 | return 0; | ||
951 | } | ||
952 | |||
936 | trace_i915_ring_wait_begin (dev); | 953 | trace_i915_ring_wait_begin (dev); |
937 | end = jiffies + 3 * HZ; | 954 | end = jiffies + 3 * HZ; |
938 | do { | 955 | do { |
939 | /* If the reported head position has wrapped or hasn't advanced, | 956 | ring->head = I915_READ_HEAD(ring); |
940 | * fallback to the slow and accurate path. | 957 | ring->space = ring_space(ring); |
941 | */ | ||
942 | head = intel_read_status_page(ring, 4); | ||
943 | if (head < ring->actual_head) | ||
944 | head = I915_READ_HEAD(ring); | ||
945 | ring->actual_head = head; | ||
946 | ring->head = head & HEAD_ADDR; | ||
947 | ring->space = ring->head - (ring->tail + 8); | ||
948 | if (ring->space < 0) | ||
949 | ring->space += ring->size; | ||
950 | if (ring->space >= n) { | 958 | if (ring->space >= n) { |
951 | trace_i915_ring_wait_end(dev); | 959 | trace_i915_ring_wait_end(dev); |
952 | return 0; | 960 | return 0; |
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 61d5220c4b58..6d6fde85a636 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h | |||
@@ -47,7 +47,6 @@ struct intel_ring_buffer { | |||
47 | struct drm_device *dev; | 47 | struct drm_device *dev; |
48 | struct drm_i915_gem_object *obj; | 48 | struct drm_i915_gem_object *obj; |
49 | 49 | ||
50 | u32 actual_head; | ||
51 | u32 head; | 50 | u32 head; |
52 | u32 tail; | 51 | u32 tail; |
53 | int space; | 52 | int space; |