diff options
Diffstat (limited to 'drivers/gpu/drm/i915')
-rw-r--r-- | drivers/gpu/drm/i915/i915_debugfs.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_dma.c | 29 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.h | 43 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem.c | 1 |
4 files changed, 50 insertions, 27 deletions
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 8f28325bc5ef..1e3bdcee863c 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c | |||
@@ -333,15 +333,13 @@ static int i915_ringbuffer_info(struct seq_file *m, void *data) | |||
333 | struct drm_info_node *node = (struct drm_info_node *) m->private; | 333 | struct drm_info_node *node = (struct drm_info_node *) m->private; |
334 | struct drm_device *dev = node->minor->dev; | 334 | struct drm_device *dev = node->minor->dev; |
335 | drm_i915_private_t *dev_priv = dev->dev_private; | 335 | drm_i915_private_t *dev_priv = dev->dev_private; |
336 | unsigned int head, tail, mask; | 336 | unsigned int head, tail; |
337 | 337 | ||
338 | head = I915_READ(PRB0_HEAD) & HEAD_ADDR; | 338 | head = I915_READ(PRB0_HEAD) & HEAD_ADDR; |
339 | tail = I915_READ(PRB0_TAIL) & TAIL_ADDR; | 339 | tail = I915_READ(PRB0_TAIL) & TAIL_ADDR; |
340 | mask = dev_priv->ring.tail_mask; | ||
341 | 340 | ||
342 | seq_printf(m, "RingHead : %08x\n", head); | 341 | seq_printf(m, "RingHead : %08x\n", head); |
343 | seq_printf(m, "RingTail : %08x\n", tail); | 342 | seq_printf(m, "RingTail : %08x\n", tail); |
344 | seq_printf(m, "RingMask : %08x\n", mask); | ||
345 | seq_printf(m, "RingSize : %08lx\n", dev_priv->ring.Size); | 343 | seq_printf(m, "RingSize : %08lx\n", dev_priv->ring.Size); |
346 | seq_printf(m, "Acthd : %08x\n", I915_READ(IS_I965G(dev) ? ACTHD_I965 : ACTHD)); | 344 | seq_printf(m, "Acthd : %08x\n", I915_READ(IS_I965G(dev) ? ACTHD_I965 : ACTHD)); |
347 | 345 | ||
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 50d1f782768c..f135bdcc6d5b 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c | |||
@@ -80,6 +80,34 @@ int i915_wait_ring(struct drm_device * dev, int n, const char *caller) | |||
80 | return -EBUSY; | 80 | return -EBUSY; |
81 | } | 81 | } |
82 | 82 | ||
83 | /* As a ringbuffer is only allowed to wrap between instructions, fill | ||
84 | * the tail with NOOPs. | ||
85 | */ | ||
86 | int i915_wrap_ring(struct drm_device *dev) | ||
87 | { | ||
88 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
89 | volatile unsigned int *virt; | ||
90 | int rem; | ||
91 | |||
92 | rem = dev_priv->ring.Size - dev_priv->ring.tail; | ||
93 | if (dev_priv->ring.space < rem) { | ||
94 | int ret = i915_wait_ring(dev, rem, __func__); | ||
95 | if (ret) | ||
96 | return ret; | ||
97 | } | ||
98 | dev_priv->ring.space -= rem; | ||
99 | |||
100 | virt = (unsigned int *) | ||
101 | (dev_priv->ring.virtual_start + dev_priv->ring.tail); | ||
102 | rem /= 4; | ||
103 | while (rem--) | ||
104 | *virt++ = MI_NOOP; | ||
105 | |||
106 | dev_priv->ring.tail = 0; | ||
107 | |||
108 | return 0; | ||
109 | } | ||
110 | |||
83 | /** | 111 | /** |
84 | * Sets up the hardware status page for devices that need a physical address | 112 | * Sets up the hardware status page for devices that need a physical address |
85 | * in the register. | 113 | * in the register. |
@@ -200,7 +228,6 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init) | |||
200 | } | 228 | } |
201 | 229 | ||
202 | dev_priv->ring.Size = init->ring_size; | 230 | dev_priv->ring.Size = init->ring_size; |
203 | dev_priv->ring.tail_mask = dev_priv->ring.Size - 1; | ||
204 | 231 | ||
205 | dev_priv->ring.map.offset = init->ring_start; | 232 | dev_priv->ring.map.offset = init->ring_start; |
206 | dev_priv->ring.map.size = init->ring_size; | 233 | dev_priv->ring.map.size = init->ring_size; |
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 76914ae65c31..2d5bce643e6a 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -85,7 +85,6 @@ struct drm_i915_gem_phys_object { | |||
85 | }; | 85 | }; |
86 | 86 | ||
87 | typedef struct _drm_i915_ring_buffer { | 87 | typedef struct _drm_i915_ring_buffer { |
88 | int tail_mask; | ||
89 | unsigned long Size; | 88 | unsigned long Size; |
90 | u8 *virtual_start; | 89 | u8 *virtual_start; |
91 | int head; | 90 | int head; |
@@ -790,33 +789,32 @@ extern void intel_modeset_cleanup(struct drm_device *dev); | |||
790 | 789 | ||
791 | #define I915_VERBOSE 0 | 790 | #define I915_VERBOSE 0 |
792 | 791 | ||
793 | #define RING_LOCALS unsigned int outring, ringmask, outcount; \ | 792 | #define RING_LOCALS volatile unsigned int *ring_virt__; |
794 | volatile char *virt; | 793 | |
795 | 794 | #define BEGIN_LP_RING(n) do { \ | |
796 | #define BEGIN_LP_RING(n) do { \ | 795 | int bytes__ = 4*(n); \ |
797 | if (I915_VERBOSE) \ | 796 | if (I915_VERBOSE) DRM_DEBUG("BEGIN_LP_RING(%d)\n", (n)); \ |
798 | DRM_DEBUG("BEGIN_LP_RING(%d)\n", (n)); \ | 797 | /* a wrap must occur between instructions so pad beforehand */ \ |
799 | if (dev_priv->ring.space < (n)*4) \ | 798 | if (unlikely (dev_priv->ring.tail + bytes__ > dev_priv->ring.Size)) \ |
800 | i915_wait_ring(dev, (n)*4, __func__); \ | 799 | i915_wrap_ring(dev); \ |
801 | outcount = 0; \ | 800 | if (unlikely (dev_priv->ring.space < bytes__)) \ |
802 | outring = dev_priv->ring.tail; \ | 801 | i915_wait_ring(dev, bytes__, __func__); \ |
803 | ringmask = dev_priv->ring.tail_mask; \ | 802 | ring_virt__ = (unsigned int *) \ |
804 | virt = dev_priv->ring.virtual_start; \ | 803 | (dev_priv->ring.virtual_start + dev_priv->ring.tail); \ |
804 | dev_priv->ring.tail += bytes__; \ | ||
805 | dev_priv->ring.tail &= dev_priv->ring.Size - 1; \ | ||
806 | dev_priv->ring.space -= bytes__; \ | ||
805 | } while (0) | 807 | } while (0) |
806 | 808 | ||
807 | #define OUT_RING(n) do { \ | 809 | #define OUT_RING(n) do { \ |
808 | if (I915_VERBOSE) DRM_DEBUG(" OUT_RING %x\n", (int)(n)); \ | 810 | if (I915_VERBOSE) DRM_DEBUG(" OUT_RING %x\n", (int)(n)); \ |
809 | *(volatile unsigned int *)(virt + outring) = (n); \ | 811 | *ring_virt__++ = (n); \ |
810 | outcount++; \ | ||
811 | outring += 4; \ | ||
812 | outring &= ringmask; \ | ||
813 | } while (0) | 812 | } while (0) |
814 | 813 | ||
815 | #define ADVANCE_LP_RING() do { \ | 814 | #define ADVANCE_LP_RING() do { \ |
816 | if (I915_VERBOSE) DRM_DEBUG("ADVANCE_LP_RING %x\n", outring); \ | 815 | if (I915_VERBOSE) \ |
817 | dev_priv->ring.tail = outring; \ | 816 | DRM_DEBUG("ADVANCE_LP_RING %x\n", dev_priv->ring.tail); \ |
818 | dev_priv->ring.space -= outcount * 4; \ | 817 | I915_WRITE(PRB0_TAIL, dev_priv->ring.tail); \ |
819 | I915_WRITE(PRB0_TAIL, outring); \ | ||
820 | } while(0) | 818 | } while(0) |
821 | 819 | ||
822 | /** | 820 | /** |
@@ -839,6 +837,7 @@ extern void intel_modeset_cleanup(struct drm_device *dev); | |||
839 | #define I915_GEM_HWS_INDEX 0x20 | 837 | #define I915_GEM_HWS_INDEX 0x20 |
840 | #define I915_BREADCRUMB_INDEX 0x21 | 838 | #define I915_BREADCRUMB_INDEX 0x21 |
841 | 839 | ||
840 | extern int i915_wrap_ring(struct drm_device * dev); | ||
842 | extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); | 841 | extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); |
843 | 842 | ||
844 | #define IS_I830(dev) ((dev)->pci_device == 0x3577) | 843 | #define IS_I830(dev) ((dev)->pci_device == 0x3577) |
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 73b58193afed..076752112a39 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -4099,7 +4099,6 @@ i915_gem_init_ringbuffer(struct drm_device *dev) | |||
4099 | 4099 | ||
4100 | /* Set up the kernel mapping for the ring. */ | 4100 | /* Set up the kernel mapping for the ring. */ |
4101 | ring->Size = obj->size; | 4101 | ring->Size = obj->size; |
4102 | ring->tail_mask = obj->size - 1; | ||
4103 | 4102 | ||
4104 | ring->map.offset = dev->agp->base + obj_priv->gtt_offset; | 4103 | ring->map.offset = dev->agp->base + obj_priv->gtt_offset; |
4105 | ring->map.size = obj->size; | 4104 | ring->map.size = obj->size; |