aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_ringbuffer.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/intel_ringbuffer.c')
-rw-r--r--drivers/gpu/drm/i915/intel_ringbuffer.c103
1 files changed, 58 insertions, 45 deletions
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index 26362f8495a8..51e9c9e718c4 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -33,18 +33,35 @@
33#include "i915_drm.h" 33#include "i915_drm.h"
34#include "i915_trace.h" 34#include "i915_trace.h"
35 35
36static u32 i915_gem_get_seqno(struct drm_device *dev)
37{
38 drm_i915_private_t *dev_priv = dev->dev_private;
39 u32 seqno;
40
41 seqno = dev_priv->next_seqno;
42
43 /* reserve 0 for non-seqno */
44 if (++dev_priv->next_seqno == 0)
45 dev_priv->next_seqno = 1;
46
47 return seqno;
48}
49
36static void 50static void
37render_ring_flush(struct drm_device *dev, 51render_ring_flush(struct drm_device *dev,
38 struct intel_ring_buffer *ring, 52 struct intel_ring_buffer *ring,
39 u32 invalidate_domains, 53 u32 invalidate_domains,
40 u32 flush_domains) 54 u32 flush_domains)
41{ 55{
56 drm_i915_private_t *dev_priv = dev->dev_private;
57 u32 cmd;
58
42#if WATCH_EXEC 59#if WATCH_EXEC
43 DRM_INFO("%s: invalidate %08x flush %08x\n", __func__, 60 DRM_INFO("%s: invalidate %08x flush %08x\n", __func__,
44 invalidate_domains, flush_domains); 61 invalidate_domains, flush_domains);
45#endif 62#endif
46 u32 cmd; 63
47 trace_i915_gem_request_flush(dev, ring->next_seqno, 64 trace_i915_gem_request_flush(dev, dev_priv->next_seqno,
48 invalidate_domains, flush_domains); 65 invalidate_domains, flush_domains);
49 66
50 if ((invalidate_domains | flush_domains) & I915_GEM_GPU_DOMAINS) { 67 if ((invalidate_domains | flush_domains) & I915_GEM_GPU_DOMAINS) {
@@ -233,9 +250,10 @@ render_ring_add_request(struct drm_device *dev,
233 struct drm_file *file_priv, 250 struct drm_file *file_priv,
234 u32 flush_domains) 251 u32 flush_domains)
235{ 252{
236 u32 seqno;
237 drm_i915_private_t *dev_priv = dev->dev_private; 253 drm_i915_private_t *dev_priv = dev->dev_private;
238 seqno = intel_ring_get_seqno(dev, ring); 254 u32 seqno;
255
256 seqno = i915_gem_get_seqno(dev);
239 257
240 if (IS_GEN6(dev)) { 258 if (IS_GEN6(dev)) {
241 BEGIN_LP_RING(6); 259 BEGIN_LP_RING(6);
@@ -405,7 +423,9 @@ bsd_ring_add_request(struct drm_device *dev,
405 u32 flush_domains) 423 u32 flush_domains)
406{ 424{
407 u32 seqno; 425 u32 seqno;
408 seqno = intel_ring_get_seqno(dev, ring); 426
427 seqno = i915_gem_get_seqno(dev);
428
409 intel_ring_begin(dev, ring, 4); 429 intel_ring_begin(dev, ring, 4);
410 intel_ring_emit(dev, ring, MI_STORE_DWORD_INDEX); 430 intel_ring_emit(dev, ring, MI_STORE_DWORD_INDEX);
411 intel_ring_emit(dev, ring, 431 intel_ring_emit(dev, ring,
@@ -479,7 +499,7 @@ render_ring_dispatch_gem_execbuffer(struct drm_device *dev,
479 exec_start = (uint32_t) exec_offset + exec->batch_start_offset; 499 exec_start = (uint32_t) exec_offset + exec->batch_start_offset;
480 exec_len = (uint32_t) exec->batch_len; 500 exec_len = (uint32_t) exec->batch_len;
481 501
482 trace_i915_gem_request_submit(dev, dev_priv->mm.next_gem_seqno + 1); 502 trace_i915_gem_request_submit(dev, dev_priv->next_seqno + 1);
483 503
484 count = nbox ? nbox : 1; 504 count = nbox ? nbox : 1;
485 505
@@ -515,7 +535,16 @@ render_ring_dispatch_gem_execbuffer(struct drm_device *dev,
515 intel_ring_advance(dev, ring); 535 intel_ring_advance(dev, ring);
516 } 536 }
517 537
538 if (IS_G4X(dev) || IS_IRONLAKE(dev)) {
539 intel_ring_begin(dev, ring, 2);
540 intel_ring_emit(dev, ring, MI_FLUSH |
541 MI_NO_WRITE_FLUSH |
542 MI_INVALIDATE_ISP );
543 intel_ring_emit(dev, ring, MI_NOOP);
544 intel_ring_advance(dev, ring);
545 }
518 /* XXX breadcrumb */ 546 /* XXX breadcrumb */
547
519 return 0; 548 return 0;
520} 549}
521 550
@@ -588,9 +617,10 @@ err:
588int intel_init_ring_buffer(struct drm_device *dev, 617int intel_init_ring_buffer(struct drm_device *dev,
589 struct intel_ring_buffer *ring) 618 struct intel_ring_buffer *ring)
590{ 619{
591 int ret;
592 struct drm_i915_gem_object *obj_priv; 620 struct drm_i915_gem_object *obj_priv;
593 struct drm_gem_object *obj; 621 struct drm_gem_object *obj;
622 int ret;
623
594 ring->dev = dev; 624 ring->dev = dev;
595 625
596 if (I915_NEED_GFX_HWS(dev)) { 626 if (I915_NEED_GFX_HWS(dev)) {
@@ -603,16 +633,14 @@ int intel_init_ring_buffer(struct drm_device *dev,
603 if (obj == NULL) { 633 if (obj == NULL) {
604 DRM_ERROR("Failed to allocate ringbuffer\n"); 634 DRM_ERROR("Failed to allocate ringbuffer\n");
605 ret = -ENOMEM; 635 ret = -ENOMEM;
606 goto cleanup; 636 goto err_hws;
607 } 637 }
608 638
609 ring->gem_object = obj; 639 ring->gem_object = obj;
610 640
611 ret = i915_gem_object_pin(obj, ring->alignment); 641 ret = i915_gem_object_pin(obj, ring->alignment);
612 if (ret != 0) { 642 if (ret)
613 drm_gem_object_unreference(obj); 643 goto err_unref;
614 goto cleanup;
615 }
616 644
617 obj_priv = to_intel_bo(obj); 645 obj_priv = to_intel_bo(obj);
618 ring->map.size = ring->size; 646 ring->map.size = ring->size;
@@ -624,18 +652,14 @@ int intel_init_ring_buffer(struct drm_device *dev,
624 drm_core_ioremap_wc(&ring->map, dev); 652 drm_core_ioremap_wc(&ring->map, dev);
625 if (ring->map.handle == NULL) { 653 if (ring->map.handle == NULL) {
626 DRM_ERROR("Failed to map ringbuffer.\n"); 654 DRM_ERROR("Failed to map ringbuffer.\n");
627 i915_gem_object_unpin(obj);
628 drm_gem_object_unreference(obj);
629 ret = -EINVAL; 655 ret = -EINVAL;
630 goto cleanup; 656 goto err_unpin;
631 } 657 }
632 658
633 ring->virtual_start = ring->map.handle; 659 ring->virtual_start = ring->map.handle;
634 ret = ring->init(dev, ring); 660 ret = ring->init(dev, ring);
635 if (ret != 0) { 661 if (ret)
636 intel_cleanup_ring_buffer(dev, ring); 662 goto err_unmap;
637 return ret;
638 }
639 663
640 if (!drm_core_check_feature(dev, DRIVER_MODESET)) 664 if (!drm_core_check_feature(dev, DRIVER_MODESET))
641 i915_kernel_lost_context(dev); 665 i915_kernel_lost_context(dev);
@@ -649,7 +673,15 @@ int intel_init_ring_buffer(struct drm_device *dev,
649 INIT_LIST_HEAD(&ring->active_list); 673 INIT_LIST_HEAD(&ring->active_list);
650 INIT_LIST_HEAD(&ring->request_list); 674 INIT_LIST_HEAD(&ring->request_list);
651 return ret; 675 return ret;
652cleanup: 676
677err_unmap:
678 drm_core_ioremapfree(&ring->map, dev);
679err_unpin:
680 i915_gem_object_unpin(obj);
681err_unref:
682 drm_gem_object_unreference(obj);
683 ring->gem_object = NULL;
684err_hws:
653 cleanup_status_page(dev, ring); 685 cleanup_status_page(dev, ring);
654 return ret; 686 return ret;
655} 687}
@@ -682,9 +714,11 @@ int intel_wrap_ring_buffer(struct drm_device *dev,
682 } 714 }
683 715
684 virt = (unsigned int *)(ring->virtual_start + ring->tail); 716 virt = (unsigned int *)(ring->virtual_start + ring->tail);
685 rem /= 4; 717 rem /= 8;
686 while (rem--) 718 while (rem--) {
719 *virt++ = MI_NOOP;
687 *virt++ = MI_NOOP; 720 *virt++ = MI_NOOP;
721 }
688 722
689 ring->tail = 0; 723 ring->tail = 0;
690 ring->space = ring->head - 8; 724 ring->space = ring->head - 8;
@@ -729,21 +763,14 @@ void intel_ring_begin(struct drm_device *dev,
729 intel_wrap_ring_buffer(dev, ring); 763 intel_wrap_ring_buffer(dev, ring);
730 if (unlikely(ring->space < n)) 764 if (unlikely(ring->space < n))
731 intel_wait_ring_buffer(dev, ring, n); 765 intel_wait_ring_buffer(dev, ring, n);
732}
733 766
734void intel_ring_emit(struct drm_device *dev, 767 ring->space -= n;
735 struct intel_ring_buffer *ring, unsigned int data)
736{
737 unsigned int *virt = ring->virtual_start + ring->tail;
738 *virt = data;
739 ring->tail += 4;
740 ring->tail &= ring->size - 1;
741 ring->space -= 4;
742} 768}
743 769
744void intel_ring_advance(struct drm_device *dev, 770void intel_ring_advance(struct drm_device *dev,
745 struct intel_ring_buffer *ring) 771 struct intel_ring_buffer *ring)
746{ 772{
773 ring->tail &= ring->size - 1;
747 ring->advance_ring(dev, ring); 774 ring->advance_ring(dev, ring);
748} 775}
749 776
@@ -762,18 +789,6 @@ void intel_fill_struct(struct drm_device *dev,
762 intel_ring_advance(dev, ring); 789 intel_ring_advance(dev, ring);
763} 790}
764 791
765u32 intel_ring_get_seqno(struct drm_device *dev,
766 struct intel_ring_buffer *ring)
767{
768 u32 seqno;
769 seqno = ring->next_seqno;
770
771 /* reserve 0 for non-seqno */
772 if (++ring->next_seqno == 0)
773 ring->next_seqno = 1;
774 return seqno;
775}
776
777struct intel_ring_buffer render_ring = { 792struct intel_ring_buffer render_ring = {
778 .name = "render ring", 793 .name = "render ring",
779 .regs = { 794 .regs = {
@@ -791,7 +806,6 @@ struct intel_ring_buffer render_ring = {
791 .head = 0, 806 .head = 0,
792 .tail = 0, 807 .tail = 0,
793 .space = 0, 808 .space = 0,
794 .next_seqno = 1,
795 .user_irq_refcount = 0, 809 .user_irq_refcount = 0,
796 .irq_gem_seqno = 0, 810 .irq_gem_seqno = 0,
797 .waiting_gem_seqno = 0, 811 .waiting_gem_seqno = 0,
@@ -830,7 +844,6 @@ struct intel_ring_buffer bsd_ring = {
830 .head = 0, 844 .head = 0,
831 .tail = 0, 845 .tail = 0,
832 .space = 0, 846 .space = 0,
833 .next_seqno = 1,
834 .user_irq_refcount = 0, 847 .user_irq_refcount = 0,
835 .irq_gem_seqno = 0, 848 .irq_gem_seqno = 0,
836 .waiting_gem_seqno = 0, 849 .waiting_gem_seqno = 0,