aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/i915_dma.c
diff options
context:
space:
mode:
authorZou Nan hai <nanhai.zou@intel.com>2010-05-20 21:08:55 -0400
committerEric Anholt <eric@anholt.net>2010-05-26 16:24:49 -0400
commit8187a2b70e34c727a06617441f74f202b6fefaf9 (patch)
tree48622c6f95282dc0a0fa668110aac4efa6e89066 /drivers/gpu/drm/i915/i915_dma.c
parentd3301d86b4bf2bcf649982ae464211d8bcf9575a (diff)
drm/i915: introduce intel_ring_buffer structure (V2)
Introduces a more complete intel_ring_buffer structure with callbacks for setup and management of a particular ringbuffer, and converts the render ring buffer consumers to use it. Signed-off-by: Zou Nan hai <nanhai.zou@intel.com> Signed-off-by: Xiang Hai hao <haihao.xiang@intel.com> [anholt: Fixed up whitespace fail and rebased against prep patches] Signed-off-by: Eric Anholt <eric@anholt.net>
Diffstat (limited to 'drivers/gpu/drm/i915/i915_dma.c')
-rw-r--r--drivers/gpu/drm/i915/i915_dma.c58
1 files changed, 25 insertions, 33 deletions
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index 6de7eace4319..2541428b2fe5 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -40,7 +40,6 @@
40#include <linux/vga_switcheroo.h> 40#include <linux/vga_switcheroo.h>
41#include <linux/slab.h> 41#include <linux/slab.h>
42 42
43
44/** 43/**
45 * Sets up the hardware status page for devices that need a physical address 44 * Sets up the hardware status page for devices that need a physical address
46 * in the register. 45 * in the register.
@@ -56,10 +55,11 @@ static int i915_init_phys_hws(struct drm_device *dev)
56 DRM_ERROR("Can not allocate hardware status page\n"); 55 DRM_ERROR("Can not allocate hardware status page\n");
57 return -ENOMEM; 56 return -ENOMEM;
58 } 57 }
59 dev_priv->hw_status_page = dev_priv->status_page_dmah->vaddr; 58 dev_priv->render_ring.status_page.page_addr
59 = dev_priv->status_page_dmah->vaddr;
60 dev_priv->dma_status_page = dev_priv->status_page_dmah->busaddr; 60 dev_priv->dma_status_page = dev_priv->status_page_dmah->busaddr;
61 61
62 memset(dev_priv->hw_status_page, 0, PAGE_SIZE); 62 memset(dev_priv->render_ring.status_page.page_addr, 0, PAGE_SIZE);
63 63
64 if (IS_I965G(dev)) 64 if (IS_I965G(dev))
65 dev_priv->dma_status_page |= (dev_priv->dma_status_page >> 28) & 65 dev_priv->dma_status_page |= (dev_priv->dma_status_page >> 28) &
@@ -95,7 +95,7 @@ void i915_kernel_lost_context(struct drm_device * dev)
95{ 95{
96 drm_i915_private_t *dev_priv = dev->dev_private; 96 drm_i915_private_t *dev_priv = dev->dev_private;
97 struct drm_i915_master_private *master_priv; 97 struct drm_i915_master_private *master_priv;
98 drm_i915_ring_buffer_t *ring = &(dev_priv->render_ring); 98 struct intel_ring_buffer *ring = &dev_priv->render_ring;
99 99
100 /* 100 /*
101 * We should never lose context on the ring with modesetting 101 * We should never lose context on the ring with modesetting
@@ -108,7 +108,7 @@ void i915_kernel_lost_context(struct drm_device * dev)
108 ring->tail = I915_READ(PRB0_TAIL) & TAIL_ADDR; 108 ring->tail = I915_READ(PRB0_TAIL) & TAIL_ADDR;
109 ring->space = ring->head - (ring->tail + 8); 109 ring->space = ring->head - (ring->tail + 8);
110 if (ring->space < 0) 110 if (ring->space < 0)
111 ring->space += ring->Size; 111 ring->space += ring->size;
112 112
113 if (!dev->primary->master) 113 if (!dev->primary->master)
114 return; 114 return;
@@ -128,12 +128,7 @@ static int i915_dma_cleanup(struct drm_device * dev)
128 if (dev->irq_enabled) 128 if (dev->irq_enabled)
129 drm_irq_uninstall(dev); 129 drm_irq_uninstall(dev);
130 130
131 if (dev_priv->render_ring.virtual_start) { 131 intel_cleanup_ring_buffer(dev, &dev_priv->render_ring);
132 drm_core_ioremapfree(&dev_priv->render_ring.map, dev);
133 dev_priv->render_ring.virtual_start = NULL;
134 dev_priv->render_ring.map.handle = NULL;
135 dev_priv->render_ring.map.size = 0;
136 }
137 132
138 /* Clear the HWS virtual address at teardown */ 133 /* Clear the HWS virtual address at teardown */
139 if (I915_NEED_GFX_HWS(dev)) 134 if (I915_NEED_GFX_HWS(dev))
@@ -156,14 +151,14 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init)
156 } 151 }
157 152
158 if (init->ring_size != 0) { 153 if (init->ring_size != 0) {
159 if (dev_priv->render_ring.ring_obj != NULL) { 154 if (dev_priv->render_ring.gem_object != NULL) {
160 i915_dma_cleanup(dev); 155 i915_dma_cleanup(dev);
161 DRM_ERROR("Client tried to initialize ringbuffer in " 156 DRM_ERROR("Client tried to initialize ringbuffer in "
162 "GEM mode\n"); 157 "GEM mode\n");
163 return -EINVAL; 158 return -EINVAL;
164 } 159 }
165 160
166 dev_priv->render_ring.Size = init->ring_size; 161 dev_priv->render_ring.size = init->ring_size;
167 162
168 dev_priv->render_ring.map.offset = init->ring_start; 163 dev_priv->render_ring.map.offset = init->ring_start;
169 dev_priv->render_ring.map.size = init->ring_size; 164 dev_priv->render_ring.map.size = init->ring_size;
@@ -201,26 +196,29 @@ static int i915_dma_resume(struct drm_device * dev)
201{ 196{
202 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 197 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
203 198
199 struct intel_ring_buffer *ring;
204 DRM_DEBUG_DRIVER("%s\n", __func__); 200 DRM_DEBUG_DRIVER("%s\n", __func__);
205 201
206 if (dev_priv->render_ring.map.handle == NULL) { 202 ring = &dev_priv->render_ring;
203
204 if (ring->map.handle == NULL) {
207 DRM_ERROR("can not ioremap virtual address for" 205 DRM_ERROR("can not ioremap virtual address for"
208 " ring buffer\n"); 206 " ring buffer\n");
209 return -ENOMEM; 207 return -ENOMEM;
210 } 208 }
211 209
212 /* Program Hardware Status Page */ 210 /* Program Hardware Status Page */
213 if (!dev_priv->hw_status_page) { 211 if (!ring->status_page.page_addr) {
214 DRM_ERROR("Can not find hardware status page\n"); 212 DRM_ERROR("Can not find hardware status page\n");
215 return -EINVAL; 213 return -EINVAL;
216 } 214 }
217 DRM_DEBUG_DRIVER("hw status page @ %p\n", 215 DRM_DEBUG_DRIVER("hw status page @ %p\n",
218 dev_priv->hw_status_page); 216 ring->status_page.page_addr);
219 217 if (ring->status_page.gfx_addr != 0)
220 if (dev_priv->status_gfx_addr != 0) 218 ring->setup_status_page(dev, ring);
221 I915_WRITE(HWS_PGA, dev_priv->status_gfx_addr);
222 else 219 else
223 I915_WRITE(HWS_PGA, dev_priv->dma_status_page); 220 I915_WRITE(HWS_PGA, dev_priv->dma_status_page);
221
224 DRM_DEBUG_DRIVER("Enabled hardware status page\n"); 222 DRM_DEBUG_DRIVER("Enabled hardware status page\n");
225 223
226 return 0; 224 return 0;
@@ -330,9 +328,8 @@ static int i915_emit_cmds(struct drm_device * dev, int *buffer, int dwords)
330{ 328{
331 drm_i915_private_t *dev_priv = dev->dev_private; 329 drm_i915_private_t *dev_priv = dev->dev_private;
332 int i; 330 int i;
333 RING_LOCALS;
334 331
335 if ((dwords+1) * sizeof(int) >= dev_priv->render_ring.Size - 8) 332 if ((dwords+1) * sizeof(int) >= dev_priv->render_ring.size - 8)
336 return -EINVAL; 333 return -EINVAL;
337 334
338 BEGIN_LP_RING((dwords+1)&~1); 335 BEGIN_LP_RING((dwords+1)&~1);
@@ -365,9 +362,7 @@ i915_emit_box(struct drm_device *dev,
365 struct drm_clip_rect *boxes, 362 struct drm_clip_rect *boxes,
366 int i, int DR1, int DR4) 363 int i, int DR1, int DR4)
367{ 364{
368 drm_i915_private_t *dev_priv = dev->dev_private;
369 struct drm_clip_rect box = boxes[i]; 365 struct drm_clip_rect box = boxes[i];
370 RING_LOCALS;
371 366
372 if (box.y2 <= box.y1 || box.x2 <= box.x1 || box.y2 <= 0 || box.x2 <= 0) { 367 if (box.y2 <= box.y1 || box.x2 <= box.x1 || box.y2 <= 0 || box.x2 <= 0) {
373 DRM_ERROR("Bad box %d,%d..%d,%d\n", 368 DRM_ERROR("Bad box %d,%d..%d,%d\n",
@@ -404,7 +399,6 @@ static void i915_emit_breadcrumb(struct drm_device *dev)
404{ 399{
405 drm_i915_private_t *dev_priv = dev->dev_private; 400 drm_i915_private_t *dev_priv = dev->dev_private;
406 struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv; 401 struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv;
407 RING_LOCALS;
408 402
409 dev_priv->counter++; 403 dev_priv->counter++;
410 if (dev_priv->counter > 0x7FFFFFFFUL) 404 if (dev_priv->counter > 0x7FFFFFFFUL)
@@ -458,10 +452,8 @@ static int i915_dispatch_batchbuffer(struct drm_device * dev,
458 drm_i915_batchbuffer_t * batch, 452 drm_i915_batchbuffer_t * batch,
459 struct drm_clip_rect *cliprects) 453 struct drm_clip_rect *cliprects)
460{ 454{
461 drm_i915_private_t *dev_priv = dev->dev_private;
462 int nbox = batch->num_cliprects; 455 int nbox = batch->num_cliprects;
463 int i = 0, count; 456 int i = 0, count;
464 RING_LOCALS;
465 457
466 if ((batch->start | batch->used) & 0x7) { 458 if ((batch->start | batch->used) & 0x7) {
467 DRM_ERROR("alignment"); 459 DRM_ERROR("alignment");
@@ -510,7 +502,6 @@ static int i915_dispatch_flip(struct drm_device * dev)
510 drm_i915_private_t *dev_priv = dev->dev_private; 502 drm_i915_private_t *dev_priv = dev->dev_private;
511 struct drm_i915_master_private *master_priv = 503 struct drm_i915_master_private *master_priv =
512 dev->primary->master->driver_priv; 504 dev->primary->master->driver_priv;
513 RING_LOCALS;
514 505
515 if (!master_priv->sarea_priv) 506 if (!master_priv->sarea_priv)
516 return -EINVAL; 507 return -EINVAL;
@@ -563,7 +554,8 @@ static int i915_quiescent(struct drm_device * dev)
563 drm_i915_private_t *dev_priv = dev->dev_private; 554 drm_i915_private_t *dev_priv = dev->dev_private;
564 555
565 i915_kernel_lost_context(dev); 556 i915_kernel_lost_context(dev);
566 return i915_wait_ring(dev, dev_priv->render_ring.Size - 8, __func__); 557 return intel_wait_ring_buffer(dev, &dev_priv->render_ring,
558 dev_priv->render_ring.size - 8);
567} 559}
568 560
569static int i915_flush_ioctl(struct drm_device *dev, void *data, 561static int i915_flush_ioctl(struct drm_device *dev, void *data,
@@ -805,6 +797,7 @@ static int i915_set_status_page(struct drm_device *dev, void *data,
805{ 797{
806 drm_i915_private_t *dev_priv = dev->dev_private; 798 drm_i915_private_t *dev_priv = dev->dev_private;
807 drm_i915_hws_addr_t *hws = data; 799 drm_i915_hws_addr_t *hws = data;
800 struct intel_ring_buffer *ring = &dev_priv->render_ring;
808 801
809 if (!I915_NEED_GFX_HWS(dev)) 802 if (!I915_NEED_GFX_HWS(dev))
810 return -EINVAL; 803 return -EINVAL;
@@ -821,7 +814,7 @@ static int i915_set_status_page(struct drm_device *dev, void *data,
821 814
822 DRM_DEBUG_DRIVER("set status page addr 0x%08x\n", (u32)hws->addr); 815 DRM_DEBUG_DRIVER("set status page addr 0x%08x\n", (u32)hws->addr);
823 816
824 dev_priv->status_gfx_addr = hws->addr & (0x1ffff<<12); 817 ring->status_page.gfx_addr = hws->addr & (0x1ffff<<12);
825 818
826 dev_priv->hws_map.offset = dev->agp->base + hws->addr; 819 dev_priv->hws_map.offset = dev->agp->base + hws->addr;
827 dev_priv->hws_map.size = 4*1024; 820 dev_priv->hws_map.size = 4*1024;
@@ -837,10 +830,10 @@ static int i915_set_status_page(struct drm_device *dev, void *data,
837 " G33 hw status page\n"); 830 " G33 hw status page\n");
838 return -ENOMEM; 831 return -ENOMEM;
839 } 832 }
840 dev_priv->hw_status_page = dev_priv->hws_map.handle; 833 ring->status_page.page_addr = dev_priv->hws_map.handle;
834 memset(ring->status_page.page_addr, 0, PAGE_SIZE);
835 I915_WRITE(HWS_PGA, ring->status_page.gfx_addr);
841 836
842 memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
843 I915_WRITE(HWS_PGA, dev_priv->status_gfx_addr);
844 DRM_DEBUG_DRIVER("load hws HWS_PGA with gfx mem 0x%x\n", 837 DRM_DEBUG_DRIVER("load hws HWS_PGA with gfx mem 0x%x\n",
845 dev_priv->status_gfx_addr); 838 dev_priv->status_gfx_addr);
846 DRM_DEBUG_DRIVER("load hws at %p\n", 839 DRM_DEBUG_DRIVER("load hws at %p\n",
@@ -1639,7 +1632,6 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
1639 1632
1640 spin_lock_init(&dev_priv->user_irq_lock); 1633 spin_lock_init(&dev_priv->user_irq_lock);
1641 spin_lock_init(&dev_priv->error_lock); 1634 spin_lock_init(&dev_priv->error_lock);
1642 dev_priv->user_irq_refcount = 0;
1643 dev_priv->trace_irq_seqno = 0; 1635 dev_priv->trace_irq_seqno = 0;
1644 1636
1645 ret = drm_vblank_init(dev, I915_NUM_PIPE); 1637 ret = drm_vblank_init(dev, I915_NUM_PIPE);