diff options
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.h | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem.c | 74 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem_context.c | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem_execbuffer.c | 30 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_ringbuffer.c | 49 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_ringbuffer.h | 10 |
6 files changed, 89 insertions, 82 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 47c62f5125a7..45491c1ac7de 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -1417,8 +1417,7 @@ int __must_check i915_mutex_lock_interruptible(struct drm_device *dev); | |||
1417 | int i915_gem_object_sync(struct drm_i915_gem_object *obj, | 1417 | int i915_gem_object_sync(struct drm_i915_gem_object *obj, |
1418 | struct intel_ring_buffer *to); | 1418 | struct intel_ring_buffer *to); |
1419 | void i915_gem_object_move_to_active(struct drm_i915_gem_object *obj, | 1419 | void i915_gem_object_move_to_active(struct drm_i915_gem_object *obj, |
1420 | struct intel_ring_buffer *ring, | 1420 | struct intel_ring_buffer *ring); |
1421 | u32 seqno); | ||
1422 | 1421 | ||
1423 | int i915_gem_dumb_create(struct drm_file *file_priv, | 1422 | int i915_gem_dumb_create(struct drm_file *file_priv, |
1424 | struct drm_device *dev, | 1423 | struct drm_device *dev, |
@@ -1436,7 +1435,7 @@ i915_seqno_passed(uint32_t seq1, uint32_t seq2) | |||
1436 | return (int32_t)(seq1 - seq2) >= 0; | 1435 | return (int32_t)(seq1 - seq2) >= 0; |
1437 | } | 1436 | } |
1438 | 1437 | ||
1439 | u32 i915_gem_next_request_seqno(struct intel_ring_buffer *ring); | 1438 | extern int i915_gem_get_seqno(struct drm_device *dev, u32 *seqno); |
1440 | 1439 | ||
1441 | int __must_check i915_gem_object_get_fence(struct drm_i915_gem_object *obj); | 1440 | int __must_check i915_gem_object_get_fence(struct drm_i915_gem_object *obj); |
1442 | int __must_check i915_gem_object_put_fence(struct drm_i915_gem_object *obj); | 1441 | int __must_check i915_gem_object_put_fence(struct drm_i915_gem_object *obj); |
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 9be450e7c54f..3b9b250ceac4 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -1857,11 +1857,11 @@ i915_gem_object_get_pages(struct drm_i915_gem_object *obj) | |||
1857 | 1857 | ||
1858 | void | 1858 | void |
1859 | i915_gem_object_move_to_active(struct drm_i915_gem_object *obj, | 1859 | i915_gem_object_move_to_active(struct drm_i915_gem_object *obj, |
1860 | struct intel_ring_buffer *ring, | 1860 | struct intel_ring_buffer *ring) |
1861 | u32 seqno) | ||
1862 | { | 1861 | { |
1863 | struct drm_device *dev = obj->base.dev; | 1862 | struct drm_device *dev = obj->base.dev; |
1864 | struct drm_i915_private *dev_priv = dev->dev_private; | 1863 | struct drm_i915_private *dev_priv = dev->dev_private; |
1864 | u32 seqno = intel_ring_get_seqno(ring); | ||
1865 | 1865 | ||
1866 | BUG_ON(ring == NULL); | 1866 | BUG_ON(ring == NULL); |
1867 | obj->ring = ring; | 1867 | obj->ring = ring; |
@@ -1922,26 +1922,54 @@ i915_gem_object_move_to_inactive(struct drm_i915_gem_object *obj) | |||
1922 | WARN_ON(i915_verify_lists(dev)); | 1922 | WARN_ON(i915_verify_lists(dev)); |
1923 | } | 1923 | } |
1924 | 1924 | ||
1925 | static u32 | 1925 | static int |
1926 | i915_gem_get_seqno(struct drm_device *dev) | 1926 | i915_gem_handle_seqno_wrap(struct drm_device *dev) |
1927 | { | 1927 | { |
1928 | drm_i915_private_t *dev_priv = dev->dev_private; | 1928 | struct drm_i915_private *dev_priv = dev->dev_private; |
1929 | u32 seqno = dev_priv->next_seqno; | 1929 | struct intel_ring_buffer *ring; |
1930 | int ret, i, j; | ||
1930 | 1931 | ||
1931 | /* reserve 0 for non-seqno */ | 1932 | /* The hardware uses various monotonic 32-bit counters, if we |
1932 | if (++dev_priv->next_seqno == 0) | 1933 | * detect that they will wraparound we need to idle the GPU |
1933 | dev_priv->next_seqno = 1; | 1934 | * and reset those counters. |
1935 | */ | ||
1936 | ret = 0; | ||
1937 | for_each_ring(ring, dev_priv, i) { | ||
1938 | for (j = 0; j < ARRAY_SIZE(ring->sync_seqno); j++) | ||
1939 | ret |= ring->sync_seqno[j] != 0; | ||
1940 | } | ||
1941 | if (ret == 0) | ||
1942 | return ret; | ||
1934 | 1943 | ||
1935 | return seqno; | 1944 | ret = i915_gpu_idle(dev); |
1945 | if (ret) | ||
1946 | return ret; | ||
1947 | |||
1948 | i915_gem_retire_requests(dev); | ||
1949 | for_each_ring(ring, dev_priv, i) { | ||
1950 | for (j = 0; j < ARRAY_SIZE(ring->sync_seqno); j++) | ||
1951 | ring->sync_seqno[j] = 0; | ||
1952 | } | ||
1953 | |||
1954 | return 0; | ||
1936 | } | 1955 | } |
1937 | 1956 | ||
1938 | u32 | 1957 | int |
1939 | i915_gem_next_request_seqno(struct intel_ring_buffer *ring) | 1958 | i915_gem_get_seqno(struct drm_device *dev, u32 *seqno) |
1940 | { | 1959 | { |
1941 | if (ring->outstanding_lazy_request == 0) | 1960 | struct drm_i915_private *dev_priv = dev->dev_private; |
1942 | ring->outstanding_lazy_request = i915_gem_get_seqno(ring->dev); | 1961 | |
1962 | /* reserve 0 for non-seqno */ | ||
1963 | if (dev_priv->next_seqno == 0) { | ||
1964 | int ret = i915_gem_handle_seqno_wrap(dev); | ||
1965 | if (ret) | ||
1966 | return ret; | ||
1943 | 1967 | ||
1944 | return ring->outstanding_lazy_request; | 1968 | dev_priv->next_seqno = 1; |
1969 | } | ||
1970 | |||
1971 | *seqno = dev_priv->next_seqno++; | ||
1972 | return 0; | ||
1945 | } | 1973 | } |
1946 | 1974 | ||
1947 | int | 1975 | int |
@@ -1952,7 +1980,6 @@ i915_add_request(struct intel_ring_buffer *ring, | |||
1952 | drm_i915_private_t *dev_priv = ring->dev->dev_private; | 1980 | drm_i915_private_t *dev_priv = ring->dev->dev_private; |
1953 | struct drm_i915_gem_request *request; | 1981 | struct drm_i915_gem_request *request; |
1954 | u32 request_ring_position; | 1982 | u32 request_ring_position; |
1955 | u32 seqno; | ||
1956 | int was_empty; | 1983 | int was_empty; |
1957 | int ret; | 1984 | int ret; |
1958 | 1985 | ||
@@ -1971,7 +1998,6 @@ i915_add_request(struct intel_ring_buffer *ring, | |||
1971 | if (request == NULL) | 1998 | if (request == NULL) |
1972 | return -ENOMEM; | 1999 | return -ENOMEM; |
1973 | 2000 | ||
1974 | seqno = i915_gem_next_request_seqno(ring); | ||
1975 | 2001 | ||
1976 | /* Record the position of the start of the request so that | 2002 | /* Record the position of the start of the request so that |
1977 | * should we detect the updated seqno part-way through the | 2003 | * should we detect the updated seqno part-way through the |
@@ -1980,15 +2006,13 @@ i915_add_request(struct intel_ring_buffer *ring, | |||
1980 | */ | 2006 | */ |
1981 | request_ring_position = intel_ring_get_tail(ring); | 2007 | request_ring_position = intel_ring_get_tail(ring); |
1982 | 2008 | ||
1983 | ret = ring->add_request(ring, &seqno); | 2009 | ret = ring->add_request(ring); |
1984 | if (ret) { | 2010 | if (ret) { |
1985 | kfree(request); | 2011 | kfree(request); |
1986 | return ret; | 2012 | return ret; |
1987 | } | 2013 | } |
1988 | 2014 | ||
1989 | trace_i915_gem_request_add(ring, seqno); | 2015 | request->seqno = intel_ring_get_seqno(ring); |
1990 | |||
1991 | request->seqno = seqno; | ||
1992 | request->ring = ring; | 2016 | request->ring = ring; |
1993 | request->tail = request_ring_position; | 2017 | request->tail = request_ring_position; |
1994 | request->emitted_jiffies = jiffies; | 2018 | request->emitted_jiffies = jiffies; |
@@ -2006,6 +2030,7 @@ i915_add_request(struct intel_ring_buffer *ring, | |||
2006 | spin_unlock(&file_priv->mm.lock); | 2030 | spin_unlock(&file_priv->mm.lock); |
2007 | } | 2031 | } |
2008 | 2032 | ||
2033 | trace_i915_gem_request_add(ring, request->seqno); | ||
2009 | ring->outstanding_lazy_request = 0; | 2034 | ring->outstanding_lazy_request = 0; |
2010 | 2035 | ||
2011 | if (!dev_priv->mm.suspended) { | 2036 | if (!dev_priv->mm.suspended) { |
@@ -2022,7 +2047,7 @@ i915_add_request(struct intel_ring_buffer *ring, | |||
2022 | } | 2047 | } |
2023 | 2048 | ||
2024 | if (out_seqno) | 2049 | if (out_seqno) |
2025 | *out_seqno = seqno; | 2050 | *out_seqno = request->seqno; |
2026 | return 0; | 2051 | return 0; |
2027 | } | 2052 | } |
2028 | 2053 | ||
@@ -2120,7 +2145,6 @@ void | |||
2120 | i915_gem_retire_requests_ring(struct intel_ring_buffer *ring) | 2145 | i915_gem_retire_requests_ring(struct intel_ring_buffer *ring) |
2121 | { | 2146 | { |
2122 | uint32_t seqno; | 2147 | uint32_t seqno; |
2123 | int i; | ||
2124 | 2148 | ||
2125 | if (list_empty(&ring->request_list)) | 2149 | if (list_empty(&ring->request_list)) |
2126 | return; | 2150 | return; |
@@ -2129,10 +2153,6 @@ i915_gem_retire_requests_ring(struct intel_ring_buffer *ring) | |||
2129 | 2153 | ||
2130 | seqno = ring->get_seqno(ring, true); | 2154 | seqno = ring->get_seqno(ring, true); |
2131 | 2155 | ||
2132 | for (i = 0; i < ARRAY_SIZE(ring->sync_seqno); i++) | ||
2133 | if (seqno >= ring->sync_seqno[i]) | ||
2134 | ring->sync_seqno[i] = 0; | ||
2135 | |||
2136 | while (!list_empty(&ring->request_list)) { | 2156 | while (!list_empty(&ring->request_list)) { |
2137 | struct drm_i915_gem_request *request; | 2157 | struct drm_i915_gem_request *request; |
2138 | 2158 | ||
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index 0e510df80d73..a3f06bcad551 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c | |||
@@ -410,9 +410,8 @@ static int do_switch(struct i915_hw_context *to) | |||
410 | * MI_SET_CONTEXT instead of when the next seqno has completed. | 410 | * MI_SET_CONTEXT instead of when the next seqno has completed. |
411 | */ | 411 | */ |
412 | if (from_obj != NULL) { | 412 | if (from_obj != NULL) { |
413 | u32 seqno = i915_gem_next_request_seqno(ring); | ||
414 | from_obj->base.read_domains = I915_GEM_DOMAIN_INSTRUCTION; | 413 | from_obj->base.read_domains = I915_GEM_DOMAIN_INSTRUCTION; |
415 | i915_gem_object_move_to_active(from_obj, ring, seqno); | 414 | i915_gem_object_move_to_active(from_obj, ring); |
416 | /* As long as MI_SET_CONTEXT is serializing, ie. it flushes the | 415 | /* As long as MI_SET_CONTEXT is serializing, ie. it flushes the |
417 | * whole damn pipeline, we don't need to explicitly mark the | 416 | * whole damn pipeline, we don't need to explicitly mark the |
418 | * object dirty. The only exception is that the context must be | 417 | * object dirty. The only exception is that the context must be |
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 48e4317e72dc..ee8f97f0539e 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c | |||
@@ -713,8 +713,7 @@ validate_exec_list(struct drm_i915_gem_exec_object2 *exec, | |||
713 | 713 | ||
714 | static void | 714 | static void |
715 | i915_gem_execbuffer_move_to_active(struct list_head *objects, | 715 | i915_gem_execbuffer_move_to_active(struct list_head *objects, |
716 | struct intel_ring_buffer *ring, | 716 | struct intel_ring_buffer *ring) |
717 | u32 seqno) | ||
718 | { | 717 | { |
719 | struct drm_i915_gem_object *obj; | 718 | struct drm_i915_gem_object *obj; |
720 | 719 | ||
@@ -726,10 +725,10 @@ i915_gem_execbuffer_move_to_active(struct list_head *objects, | |||
726 | obj->base.write_domain = obj->base.pending_write_domain; | 725 | obj->base.write_domain = obj->base.pending_write_domain; |
727 | obj->fenced_gpu_access = obj->pending_fenced_gpu_access; | 726 | obj->fenced_gpu_access = obj->pending_fenced_gpu_access; |
728 | 727 | ||
729 | i915_gem_object_move_to_active(obj, ring, seqno); | 728 | i915_gem_object_move_to_active(obj, ring); |
730 | if (obj->base.write_domain) { | 729 | if (obj->base.write_domain) { |
731 | obj->dirty = 1; | 730 | obj->dirty = 1; |
732 | obj->last_write_seqno = seqno; | 731 | obj->last_write_seqno = intel_ring_get_seqno(ring); |
733 | if (obj->pin_count) /* check for potential scanout */ | 732 | if (obj->pin_count) /* check for potential scanout */ |
734 | intel_mark_fb_busy(obj); | 733 | intel_mark_fb_busy(obj); |
735 | } | 734 | } |
@@ -789,7 +788,6 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, | |||
789 | struct intel_ring_buffer *ring; | 788 | struct intel_ring_buffer *ring; |
790 | u32 ctx_id = i915_execbuffer2_get_context_id(*args); | 789 | u32 ctx_id = i915_execbuffer2_get_context_id(*args); |
791 | u32 exec_start, exec_len; | 790 | u32 exec_start, exec_len; |
792 | u32 seqno; | ||
793 | u32 mask; | 791 | u32 mask; |
794 | u32 flags; | 792 | u32 flags; |
795 | int ret, mode, i; | 793 | int ret, mode, i; |
@@ -994,22 +992,6 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, | |||
994 | if (ret) | 992 | if (ret) |
995 | goto err; | 993 | goto err; |
996 | 994 | ||
997 | seqno = i915_gem_next_request_seqno(ring); | ||
998 | for (i = 0; i < ARRAY_SIZE(ring->sync_seqno); i++) { | ||
999 | if (seqno < ring->sync_seqno[i]) { | ||
1000 | /* The GPU can not handle its semaphore value wrapping, | ||
1001 | * so every billion or so execbuffers, we need to stall | ||
1002 | * the GPU in order to reset the counters. | ||
1003 | */ | ||
1004 | ret = i915_gpu_idle(dev); | ||
1005 | if (ret) | ||
1006 | goto err; | ||
1007 | i915_gem_retire_requests(dev); | ||
1008 | |||
1009 | BUG_ON(ring->sync_seqno[i]); | ||
1010 | } | ||
1011 | } | ||
1012 | |||
1013 | ret = i915_switch_context(ring, file, ctx_id); | 995 | ret = i915_switch_context(ring, file, ctx_id); |
1014 | if (ret) | 996 | if (ret) |
1015 | goto err; | 997 | goto err; |
@@ -1035,8 +1017,6 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, | |||
1035 | goto err; | 1017 | goto err; |
1036 | } | 1018 | } |
1037 | 1019 | ||
1038 | trace_i915_gem_ring_dispatch(ring, seqno, flags); | ||
1039 | |||
1040 | exec_start = batch_obj->gtt_offset + args->batch_start_offset; | 1020 | exec_start = batch_obj->gtt_offset + args->batch_start_offset; |
1041 | exec_len = args->batch_len; | 1021 | exec_len = args->batch_len; |
1042 | if (cliprects) { | 1022 | if (cliprects) { |
@@ -1060,7 +1040,9 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, | |||
1060 | goto err; | 1040 | goto err; |
1061 | } | 1041 | } |
1062 | 1042 | ||
1063 | i915_gem_execbuffer_move_to_active(&objects, ring, seqno); | 1043 | trace_i915_gem_ring_dispatch(ring, intel_ring_get_seqno(ring), flags); |
1044 | |||
1045 | i915_gem_execbuffer_move_to_active(&objects, ring); | ||
1064 | i915_gem_execbuffer_retire_commands(dev, file, ring); | 1046 | i915_gem_execbuffer_retire_commands(dev, file, ring); |
1065 | 1047 | ||
1066 | err: | 1048 | err: |
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 987eb5fdaf39..e4682cdc00b0 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c | |||
@@ -555,12 +555,11 @@ static void render_ring_cleanup(struct intel_ring_buffer *ring) | |||
555 | 555 | ||
556 | static void | 556 | static void |
557 | update_mboxes(struct intel_ring_buffer *ring, | 557 | update_mboxes(struct intel_ring_buffer *ring, |
558 | u32 seqno, | 558 | u32 mmio_offset) |
559 | u32 mmio_offset) | ||
560 | { | 559 | { |
561 | intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1)); | 560 | intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1)); |
562 | intel_ring_emit(ring, mmio_offset); | 561 | intel_ring_emit(ring, mmio_offset); |
563 | intel_ring_emit(ring, seqno); | 562 | intel_ring_emit(ring, ring->outstanding_lazy_request); |
564 | } | 563 | } |
565 | 564 | ||
566 | /** | 565 | /** |
@@ -573,8 +572,7 @@ update_mboxes(struct intel_ring_buffer *ring, | |||
573 | * This acts like a signal in the canonical semaphore. | 572 | * This acts like a signal in the canonical semaphore. |
574 | */ | 573 | */ |
575 | static int | 574 | static int |
576 | gen6_add_request(struct intel_ring_buffer *ring, | 575 | gen6_add_request(struct intel_ring_buffer *ring) |
577 | u32 *seqno) | ||
578 | { | 576 | { |
579 | u32 mbox1_reg; | 577 | u32 mbox1_reg; |
580 | u32 mbox2_reg; | 578 | u32 mbox2_reg; |
@@ -587,13 +585,11 @@ gen6_add_request(struct intel_ring_buffer *ring, | |||
587 | mbox1_reg = ring->signal_mbox[0]; | 585 | mbox1_reg = ring->signal_mbox[0]; |
588 | mbox2_reg = ring->signal_mbox[1]; | 586 | mbox2_reg = ring->signal_mbox[1]; |
589 | 587 | ||
590 | *seqno = i915_gem_next_request_seqno(ring); | 588 | update_mboxes(ring, mbox1_reg); |
591 | 589 | update_mboxes(ring, mbox2_reg); | |
592 | update_mboxes(ring, *seqno, mbox1_reg); | ||
593 | update_mboxes(ring, *seqno, mbox2_reg); | ||
594 | intel_ring_emit(ring, MI_STORE_DWORD_INDEX); | 590 | intel_ring_emit(ring, MI_STORE_DWORD_INDEX); |
595 | intel_ring_emit(ring, I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT); | 591 | intel_ring_emit(ring, I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT); |
596 | intel_ring_emit(ring, *seqno); | 592 | intel_ring_emit(ring, ring->outstanding_lazy_request); |
597 | intel_ring_emit(ring, MI_USER_INTERRUPT); | 593 | intel_ring_emit(ring, MI_USER_INTERRUPT); |
598 | intel_ring_advance(ring); | 594 | intel_ring_advance(ring); |
599 | 595 | ||
@@ -650,10 +646,8 @@ do { \ | |||
650 | } while (0) | 646 | } while (0) |
651 | 647 | ||
652 | static int | 648 | static int |
653 | pc_render_add_request(struct intel_ring_buffer *ring, | 649 | pc_render_add_request(struct intel_ring_buffer *ring) |
654 | u32 *result) | ||
655 | { | 650 | { |
656 | u32 seqno = i915_gem_next_request_seqno(ring); | ||
657 | struct pipe_control *pc = ring->private; | 651 | struct pipe_control *pc = ring->private; |
658 | u32 scratch_addr = pc->gtt_offset + 128; | 652 | u32 scratch_addr = pc->gtt_offset + 128; |
659 | int ret; | 653 | int ret; |
@@ -674,7 +668,7 @@ pc_render_add_request(struct intel_ring_buffer *ring, | |||
674 | PIPE_CONTROL_WRITE_FLUSH | | 668 | PIPE_CONTROL_WRITE_FLUSH | |
675 | PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE); | 669 | PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE); |
676 | intel_ring_emit(ring, pc->gtt_offset | PIPE_CONTROL_GLOBAL_GTT); | 670 | intel_ring_emit(ring, pc->gtt_offset | PIPE_CONTROL_GLOBAL_GTT); |
677 | intel_ring_emit(ring, seqno); | 671 | intel_ring_emit(ring, ring->outstanding_lazy_request); |
678 | intel_ring_emit(ring, 0); | 672 | intel_ring_emit(ring, 0); |
679 | PIPE_CONTROL_FLUSH(ring, scratch_addr); | 673 | PIPE_CONTROL_FLUSH(ring, scratch_addr); |
680 | scratch_addr += 128; /* write to separate cachelines */ | 674 | scratch_addr += 128; /* write to separate cachelines */ |
@@ -693,11 +687,10 @@ pc_render_add_request(struct intel_ring_buffer *ring, | |||
693 | PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE | | 687 | PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE | |
694 | PIPE_CONTROL_NOTIFY); | 688 | PIPE_CONTROL_NOTIFY); |
695 | intel_ring_emit(ring, pc->gtt_offset | PIPE_CONTROL_GLOBAL_GTT); | 689 | intel_ring_emit(ring, pc->gtt_offset | PIPE_CONTROL_GLOBAL_GTT); |
696 | intel_ring_emit(ring, seqno); | 690 | intel_ring_emit(ring, ring->outstanding_lazy_request); |
697 | intel_ring_emit(ring, 0); | 691 | intel_ring_emit(ring, 0); |
698 | intel_ring_advance(ring); | 692 | intel_ring_advance(ring); |
699 | 693 | ||
700 | *result = seqno; | ||
701 | return 0; | 694 | return 0; |
702 | } | 695 | } |
703 | 696 | ||
@@ -885,25 +878,20 @@ bsd_ring_flush(struct intel_ring_buffer *ring, | |||
885 | } | 878 | } |
886 | 879 | ||
887 | static int | 880 | static int |
888 | i9xx_add_request(struct intel_ring_buffer *ring, | 881 | i9xx_add_request(struct intel_ring_buffer *ring) |
889 | u32 *result) | ||
890 | { | 882 | { |
891 | u32 seqno; | ||
892 | int ret; | 883 | int ret; |
893 | 884 | ||
894 | ret = intel_ring_begin(ring, 4); | 885 | ret = intel_ring_begin(ring, 4); |
895 | if (ret) | 886 | if (ret) |
896 | return ret; | 887 | return ret; |
897 | 888 | ||
898 | seqno = i915_gem_next_request_seqno(ring); | ||
899 | |||
900 | intel_ring_emit(ring, MI_STORE_DWORD_INDEX); | 889 | intel_ring_emit(ring, MI_STORE_DWORD_INDEX); |
901 | intel_ring_emit(ring, I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT); | 890 | intel_ring_emit(ring, I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT); |
902 | intel_ring_emit(ring, seqno); | 891 | intel_ring_emit(ring, ring->outstanding_lazy_request); |
903 | intel_ring_emit(ring, MI_USER_INTERRUPT); | 892 | intel_ring_emit(ring, MI_USER_INTERRUPT); |
904 | intel_ring_advance(ring); | 893 | intel_ring_advance(ring); |
905 | 894 | ||
906 | *result = seqno; | ||
907 | return 0; | 895 | return 0; |
908 | } | 896 | } |
909 | 897 | ||
@@ -1110,6 +1098,7 @@ static int intel_init_ring_buffer(struct drm_device *dev, | |||
1110 | INIT_LIST_HEAD(&ring->active_list); | 1098 | INIT_LIST_HEAD(&ring->active_list); |
1111 | INIT_LIST_HEAD(&ring->request_list); | 1099 | INIT_LIST_HEAD(&ring->request_list); |
1112 | ring->size = 32 * PAGE_SIZE; | 1100 | ring->size = 32 * PAGE_SIZE; |
1101 | memset(ring->sync_seqno, 0, sizeof(ring->sync_seqno)); | ||
1113 | 1102 | ||
1114 | init_waitqueue_head(&ring->irq_queue); | 1103 | init_waitqueue_head(&ring->irq_queue); |
1115 | 1104 | ||
@@ -1338,6 +1327,15 @@ int intel_wait_ring_buffer(struct intel_ring_buffer *ring, int n) | |||
1338 | return -EBUSY; | 1327 | return -EBUSY; |
1339 | } | 1328 | } |
1340 | 1329 | ||
1330 | static int | ||
1331 | intel_ring_alloc_seqno(struct intel_ring_buffer *ring) | ||
1332 | { | ||
1333 | if (ring->outstanding_lazy_request) | ||
1334 | return 0; | ||
1335 | |||
1336 | return i915_gem_get_seqno(ring->dev, &ring->outstanding_lazy_request); | ||
1337 | } | ||
1338 | |||
1341 | int intel_ring_begin(struct intel_ring_buffer *ring, | 1339 | int intel_ring_begin(struct intel_ring_buffer *ring, |
1342 | int num_dwords) | 1340 | int num_dwords) |
1343 | { | 1341 | { |
@@ -1349,6 +1347,11 @@ int intel_ring_begin(struct intel_ring_buffer *ring, | |||
1349 | if (ret) | 1347 | if (ret) |
1350 | return ret; | 1348 | return ret; |
1351 | 1349 | ||
1350 | /* Preallocate the olr before touching the ring */ | ||
1351 | ret = intel_ring_alloc_seqno(ring); | ||
1352 | if (ret) | ||
1353 | return ret; | ||
1354 | |||
1352 | if (unlikely(ring->tail + n > ring->effective_size)) { | 1355 | if (unlikely(ring->tail + n > ring->effective_size)) { |
1353 | ret = intel_wrap_ring_buffer(ring); | 1356 | ret = intel_wrap_ring_buffer(ring); |
1354 | if (unlikely(ret)) | 1357 | if (unlikely(ret)) |
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 5af65b89765f..0e613026d003 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h | |||
@@ -70,8 +70,7 @@ struct intel_ring_buffer { | |||
70 | int __must_check (*flush)(struct intel_ring_buffer *ring, | 70 | int __must_check (*flush)(struct intel_ring_buffer *ring, |
71 | u32 invalidate_domains, | 71 | u32 invalidate_domains, |
72 | u32 flush_domains); | 72 | u32 flush_domains); |
73 | int (*add_request)(struct intel_ring_buffer *ring, | 73 | int (*add_request)(struct intel_ring_buffer *ring); |
74 | u32 *seqno); | ||
75 | /* Some chipsets are not quite as coherent as advertised and need | 74 | /* Some chipsets are not quite as coherent as advertised and need |
76 | * an expensive kick to force a true read of the up-to-date seqno. | 75 | * an expensive kick to force a true read of the up-to-date seqno. |
77 | * However, the up-to-date seqno is not always required and the last | 76 | * However, the up-to-date seqno is not always required and the last |
@@ -205,7 +204,6 @@ static inline void intel_ring_emit(struct intel_ring_buffer *ring, | |||
205 | 204 | ||
206 | void intel_ring_advance(struct intel_ring_buffer *ring); | 205 | void intel_ring_advance(struct intel_ring_buffer *ring); |
207 | 206 | ||
208 | u32 intel_ring_get_seqno(struct intel_ring_buffer *ring); | ||
209 | int intel_ring_flush_all_caches(struct intel_ring_buffer *ring); | 207 | int intel_ring_flush_all_caches(struct intel_ring_buffer *ring); |
210 | int intel_ring_invalidate_all_caches(struct intel_ring_buffer *ring); | 208 | int intel_ring_invalidate_all_caches(struct intel_ring_buffer *ring); |
211 | 209 | ||
@@ -221,6 +219,12 @@ static inline u32 intel_ring_get_tail(struct intel_ring_buffer *ring) | |||
221 | return ring->tail; | 219 | return ring->tail; |
222 | } | 220 | } |
223 | 221 | ||
222 | static inline u32 intel_ring_get_seqno(struct intel_ring_buffer *ring) | ||
223 | { | ||
224 | BUG_ON(ring->outstanding_lazy_request == 0); | ||
225 | return ring->outstanding_lazy_request; | ||
226 | } | ||
227 | |||
224 | static inline void i915_trace_irq_get(struct intel_ring_buffer *ring, u32 seqno) | 228 | static inline void i915_trace_irq_get(struct intel_ring_buffer *ring, u32 seqno) |
225 | { | 229 | { |
226 | if (ring->trace_irq_seqno == 0 && ring->irq_get(ring)) | 230 | if (ring->trace_irq_seqno == 0 && ring->irq_get(ring)) |