diff options
author | Zou Nan hai <nanhai.zou@intel.com> | 2010-05-20 21:08:55 -0400 |
---|---|---|
committer | Eric Anholt <eric@anholt.net> | 2010-05-26 16:24:49 -0400 |
commit | 8187a2b70e34c727a06617441f74f202b6fefaf9 (patch) | |
tree | 48622c6f95282dc0a0fa668110aac4efa6e89066 /drivers/gpu/drm/i915/i915_dma.c | |
parent | d3301d86b4bf2bcf649982ae464211d8bcf9575a (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.c | 58 |
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 | ||
569 | static int i915_flush_ioctl(struct drm_device *dev, void *data, | 561 | static 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); |