aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915')
-rw-r--r--drivers/gpu/drm/i915/i915_debugfs.c4
-rw-r--r--drivers/gpu/drm/i915/i915_dma.c29
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h43
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c1
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 */
86int 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
87typedef struct _drm_i915_ring_buffer { 87typedef 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
840extern int i915_wrap_ring(struct drm_device * dev);
842extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); 841extern 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;