aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon
diff options
context:
space:
mode:
authorChristian König <christian.koenig@amd.com>2014-09-04 14:01:53 -0400
committerAlex Deucher <alexander.deucher@amd.com>2014-09-11 10:46:01 -0400
commit57d20a43c9b30663bdbacde8294a902edef35a84 (patch)
tree1a2ab2ad48988611c498f8e8c202a6a90b1598da /drivers/gpu/drm/radeon
parentae9c0af2c0ea92e57013ab2dd7271ba7d6b2a833 (diff)
drm/radeon: add the infrastructure for concurrent buffer access
This allows us to specify if we want to sync to the shared fences of a reservation object or not. Signed-off-by: Christian König <christian.koenig@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/radeon')
-rw-r--r--drivers/gpu/drm/radeon/cik.c25
-rw-r--r--drivers/gpu/drm/radeon/cik_sdma.c25
-rw-r--r--drivers/gpu/drm/radeon/evergreen_dma.c24
-rw-r--r--drivers/gpu/drm/radeon/r100.c21
-rw-r--r--drivers/gpu/drm/radeon/r200.c21
-rw-r--r--drivers/gpu/drm/radeon/r600.c23
-rw-r--r--drivers/gpu/drm/radeon/r600_dma.c25
-rw-r--r--drivers/gpu/drm/radeon/radeon.h43
-rw-r--r--drivers/gpu/drm/radeon/radeon_asic.h74
-rw-r--r--drivers/gpu/drm/radeon/radeon_benchmark.c30
-rw-r--r--drivers/gpu/drm/radeon/radeon_cs.c8
-rw-r--r--drivers/gpu/drm/radeon/radeon_ib.c2
-rw-r--r--drivers/gpu/drm/radeon/radeon_semaphore.c38
-rw-r--r--drivers/gpu/drm/radeon/radeon_test.c24
-rw-r--r--drivers/gpu/drm/radeon/radeon_ttm.c12
-rw-r--r--drivers/gpu/drm/radeon/radeon_vm.c16
-rw-r--r--drivers/gpu/drm/radeon/rv770_dma.c25
-rw-r--r--drivers/gpu/drm/radeon/si_dma.c25
18 files changed, 253 insertions, 208 deletions
diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c
index 1f598ab3b9a7..0b5a230d8b96 100644
--- a/drivers/gpu/drm/radeon/cik.c
+++ b/drivers/gpu/drm/radeon/cik.c
@@ -3959,18 +3959,19 @@ bool cik_semaphore_ring_emit(struct radeon_device *rdev,
3959 * @src_offset: src GPU address 3959 * @src_offset: src GPU address
3960 * @dst_offset: dst GPU address 3960 * @dst_offset: dst GPU address
3961 * @num_gpu_pages: number of GPU pages to xfer 3961 * @num_gpu_pages: number of GPU pages to xfer
3962 * @fence: radeon fence object 3962 * @resv: reservation object to sync to
3963 * 3963 *
3964 * Copy GPU paging using the CP DMA engine (CIK+). 3964 * Copy GPU paging using the CP DMA engine (CIK+).
3965 * Used by the radeon ttm implementation to move pages if 3965 * Used by the radeon ttm implementation to move pages if
3966 * registered as the asic copy callback. 3966 * registered as the asic copy callback.
3967 */ 3967 */
3968int cik_copy_cpdma(struct radeon_device *rdev, 3968struct radeon_fence *cik_copy_cpdma(struct radeon_device *rdev,
3969 uint64_t src_offset, uint64_t dst_offset, 3969 uint64_t src_offset, uint64_t dst_offset,
3970 unsigned num_gpu_pages, 3970 unsigned num_gpu_pages,
3971 struct radeon_fence **fence) 3971 struct reservation_object *resv)
3972{ 3972{
3973 struct radeon_semaphore *sem = NULL; 3973 struct radeon_semaphore *sem = NULL;
3974 struct radeon_fence *fence;
3974 int ring_index = rdev->asic->copy.blit_ring_index; 3975 int ring_index = rdev->asic->copy.blit_ring_index;
3975 struct radeon_ring *ring = &rdev->ring[ring_index]; 3976 struct radeon_ring *ring = &rdev->ring[ring_index];
3976 u32 size_in_bytes, cur_size_in_bytes, control; 3977 u32 size_in_bytes, cur_size_in_bytes, control;
@@ -3980,7 +3981,7 @@ int cik_copy_cpdma(struct radeon_device *rdev,
3980 r = radeon_semaphore_create(rdev, &sem); 3981 r = radeon_semaphore_create(rdev, &sem);
3981 if (r) { 3982 if (r) {
3982 DRM_ERROR("radeon: moving bo (%d).\n", r); 3983 DRM_ERROR("radeon: moving bo (%d).\n", r);
3983 return r; 3984 return ERR_PTR(r);
3984 } 3985 }
3985 3986
3986 size_in_bytes = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT); 3987 size_in_bytes = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT);
@@ -3989,10 +3990,10 @@ int cik_copy_cpdma(struct radeon_device *rdev,
3989 if (r) { 3990 if (r) {
3990 DRM_ERROR("radeon: moving bo (%d).\n", r); 3991 DRM_ERROR("radeon: moving bo (%d).\n", r);
3991 radeon_semaphore_free(rdev, &sem, NULL); 3992 radeon_semaphore_free(rdev, &sem, NULL);
3992 return r; 3993 return ERR_PTR(r);
3993 } 3994 }
3994 3995
3995 radeon_semaphore_sync_to(sem, *fence); 3996 radeon_semaphore_sync_resv(sem, resv, false);
3996 radeon_semaphore_sync_rings(rdev, sem, ring->idx); 3997 radeon_semaphore_sync_rings(rdev, sem, ring->idx);
3997 3998
3998 for (i = 0; i < num_loops; i++) { 3999 for (i = 0; i < num_loops; i++) {
@@ -4014,17 +4015,17 @@ int cik_copy_cpdma(struct radeon_device *rdev,
4014 dst_offset += cur_size_in_bytes; 4015 dst_offset += cur_size_in_bytes;
4015 } 4016 }
4016 4017
4017 r = radeon_fence_emit(rdev, fence, ring->idx); 4018 r = radeon_fence_emit(rdev, &fence, ring->idx);
4018 if (r) { 4019 if (r) {
4019 radeon_ring_unlock_undo(rdev, ring); 4020 radeon_ring_unlock_undo(rdev, ring);
4020 radeon_semaphore_free(rdev, &sem, NULL); 4021 radeon_semaphore_free(rdev, &sem, NULL);
4021 return r; 4022 return ERR_PTR(r);
4022 } 4023 }
4023 4024
4024 radeon_ring_unlock_commit(rdev, ring, false); 4025 radeon_ring_unlock_commit(rdev, ring, false);
4025 radeon_semaphore_free(rdev, &sem, *fence); 4026 radeon_semaphore_free(rdev, &sem, fence);
4026 4027
4027 return r; 4028 return fence;
4028} 4029}
4029 4030
4030/* 4031/*
diff --git a/drivers/gpu/drm/radeon/cik_sdma.c b/drivers/gpu/drm/radeon/cik_sdma.c
index 192278bc993c..c01a6100c318 100644
--- a/drivers/gpu/drm/radeon/cik_sdma.c
+++ b/drivers/gpu/drm/radeon/cik_sdma.c
@@ -537,18 +537,19 @@ void cik_sdma_fini(struct radeon_device *rdev)
537 * @src_offset: src GPU address 537 * @src_offset: src GPU address
538 * @dst_offset: dst GPU address 538 * @dst_offset: dst GPU address
539 * @num_gpu_pages: number of GPU pages to xfer 539 * @num_gpu_pages: number of GPU pages to xfer
540 * @fence: radeon fence object 540 * @resv: reservation object to sync to
541 * 541 *
542 * Copy GPU paging using the DMA engine (CIK). 542 * Copy GPU paging using the DMA engine (CIK).
543 * Used by the radeon ttm implementation to move pages if 543 * Used by the radeon ttm implementation to move pages if
544 * registered as the asic copy callback. 544 * registered as the asic copy callback.
545 */ 545 */
546int cik_copy_dma(struct radeon_device *rdev, 546struct radeon_fence *cik_copy_dma(struct radeon_device *rdev,
547 uint64_t src_offset, uint64_t dst_offset, 547 uint64_t src_offset, uint64_t dst_offset,
548 unsigned num_gpu_pages, 548 unsigned num_gpu_pages,
549 struct radeon_fence **fence) 549 struct reservation_object *resv)
550{ 550{
551 struct radeon_semaphore *sem = NULL; 551 struct radeon_semaphore *sem = NULL;
552 struct radeon_fence *fence;
552 int ring_index = rdev->asic->copy.dma_ring_index; 553 int ring_index = rdev->asic->copy.dma_ring_index;
553 struct radeon_ring *ring = &rdev->ring[ring_index]; 554 struct radeon_ring *ring = &rdev->ring[ring_index];
554 u32 size_in_bytes, cur_size_in_bytes; 555 u32 size_in_bytes, cur_size_in_bytes;
@@ -558,7 +559,7 @@ int cik_copy_dma(struct radeon_device *rdev,
558 r = radeon_semaphore_create(rdev, &sem); 559 r = radeon_semaphore_create(rdev, &sem);
559 if (r) { 560 if (r) {
560 DRM_ERROR("radeon: moving bo (%d).\n", r); 561 DRM_ERROR("radeon: moving bo (%d).\n", r);
561 return r; 562 return ERR_PTR(r);
562 } 563 }
563 564
564 size_in_bytes = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT); 565 size_in_bytes = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT);
@@ -567,10 +568,10 @@ int cik_copy_dma(struct radeon_device *rdev,
567 if (r) { 568 if (r) {
568 DRM_ERROR("radeon: moving bo (%d).\n", r); 569 DRM_ERROR("radeon: moving bo (%d).\n", r);
569 radeon_semaphore_free(rdev, &sem, NULL); 570 radeon_semaphore_free(rdev, &sem, NULL);
570 return r; 571 return ERR_PTR(r);
571 } 572 }
572 573
573 radeon_semaphore_sync_to(sem, *fence); 574 radeon_semaphore_sync_resv(sem, resv, false);
574 radeon_semaphore_sync_rings(rdev, sem, ring->idx); 575 radeon_semaphore_sync_rings(rdev, sem, ring->idx);
575 576
576 for (i = 0; i < num_loops; i++) { 577 for (i = 0; i < num_loops; i++) {
@@ -589,17 +590,17 @@ int cik_copy_dma(struct radeon_device *rdev,
589 dst_offset += cur_size_in_bytes; 590 dst_offset += cur_size_in_bytes;
590 } 591 }
591 592
592 r = radeon_fence_emit(rdev, fence, ring->idx); 593 r = radeon_fence_emit(rdev, &fence, ring->idx);
593 if (r) { 594 if (r) {
594 radeon_ring_unlock_undo(rdev, ring); 595 radeon_ring_unlock_undo(rdev, ring);
595 radeon_semaphore_free(rdev, &sem, NULL); 596 radeon_semaphore_free(rdev, &sem, NULL);
596 return r; 597 return ERR_PTR(r);
597 } 598 }
598 599
599 radeon_ring_unlock_commit(rdev, ring, false); 600 radeon_ring_unlock_commit(rdev, ring, false);
600 radeon_semaphore_free(rdev, &sem, *fence); 601 radeon_semaphore_free(rdev, &sem, fence);
601 602
602 return r; 603 return fence;
603} 604}
604 605
605/** 606/**
diff --git a/drivers/gpu/drm/radeon/evergreen_dma.c b/drivers/gpu/drm/radeon/evergreen_dma.c
index afaba388c36d..946f37d0b469 100644
--- a/drivers/gpu/drm/radeon/evergreen_dma.c
+++ b/drivers/gpu/drm/radeon/evergreen_dma.c
@@ -104,12 +104,14 @@ void evergreen_dma_ring_ib_execute(struct radeon_device *rdev,
104 * Used by the radeon ttm implementation to move pages if 104 * Used by the radeon ttm implementation to move pages if
105 * registered as the asic copy callback. 105 * registered as the asic copy callback.
106 */ 106 */
107int evergreen_copy_dma(struct radeon_device *rdev, 107struct radeon_fence *evergreen_copy_dma(struct radeon_device *rdev,
108 uint64_t src_offset, uint64_t dst_offset, 108 uint64_t src_offset,
109 unsigned num_gpu_pages, 109 uint64_t dst_offset,
110 struct radeon_fence **fence) 110 unsigned num_gpu_pages,
111 struct reservation_object *resv)
111{ 112{
112 struct radeon_semaphore *sem = NULL; 113 struct radeon_semaphore *sem = NULL;
114 struct radeon_fence *fence;
113 int ring_index = rdev->asic->copy.dma_ring_index; 115 int ring_index = rdev->asic->copy.dma_ring_index;
114 struct radeon_ring *ring = &rdev->ring[ring_index]; 116 struct radeon_ring *ring = &rdev->ring[ring_index];
115 u32 size_in_dw, cur_size_in_dw; 117 u32 size_in_dw, cur_size_in_dw;
@@ -119,7 +121,7 @@ int evergreen_copy_dma(struct radeon_device *rdev,
119 r = radeon_semaphore_create(rdev, &sem); 121 r = radeon_semaphore_create(rdev, &sem);
120 if (r) { 122 if (r) {
121 DRM_ERROR("radeon: moving bo (%d).\n", r); 123 DRM_ERROR("radeon: moving bo (%d).\n", r);
122 return r; 124 return ERR_PTR(r);
123 } 125 }
124 126
125 size_in_dw = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT) / 4; 127 size_in_dw = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT) / 4;
@@ -128,10 +130,10 @@ int evergreen_copy_dma(struct radeon_device *rdev,
128 if (r) { 130 if (r) {
129 DRM_ERROR("radeon: moving bo (%d).\n", r); 131 DRM_ERROR("radeon: moving bo (%d).\n", r);
130 radeon_semaphore_free(rdev, &sem, NULL); 132 radeon_semaphore_free(rdev, &sem, NULL);
131 return r; 133 return ERR_PTR(r);
132 } 134 }
133 135
134 radeon_semaphore_sync_to(sem, *fence); 136 radeon_semaphore_sync_resv(sem, resv, false);
135 radeon_semaphore_sync_rings(rdev, sem, ring->idx); 137 radeon_semaphore_sync_rings(rdev, sem, ring->idx);
136 138
137 for (i = 0; i < num_loops; i++) { 139 for (i = 0; i < num_loops; i++) {
@@ -148,17 +150,17 @@ int evergreen_copy_dma(struct radeon_device *rdev,
148 dst_offset += cur_size_in_dw * 4; 150 dst_offset += cur_size_in_dw * 4;
149 } 151 }
150 152
151 r = radeon_fence_emit(rdev, fence, ring->idx); 153 r = radeon_fence_emit(rdev, &fence, ring->idx);
152 if (r) { 154 if (r) {
153 radeon_ring_unlock_undo(rdev, ring); 155 radeon_ring_unlock_undo(rdev, ring);
154 radeon_semaphore_free(rdev, &sem, NULL); 156 radeon_semaphore_free(rdev, &sem, NULL);
155 return r; 157 return ERR_PTR(r);
156 } 158 }
157 159
158 radeon_ring_unlock_commit(rdev, ring, false); 160 radeon_ring_unlock_commit(rdev, ring, false);
159 radeon_semaphore_free(rdev, &sem, *fence); 161 radeon_semaphore_free(rdev, &sem, fence);
160 162
161 return r; 163 return fence;
162} 164}
163 165
164/** 166/**
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
index 4c5ec44ff328..c6b486f888d5 100644
--- a/drivers/gpu/drm/radeon/r100.c
+++ b/drivers/gpu/drm/radeon/r100.c
@@ -855,13 +855,14 @@ bool r100_semaphore_ring_emit(struct radeon_device *rdev,
855 return false; 855 return false;
856} 856}
857 857
858int r100_copy_blit(struct radeon_device *rdev, 858struct radeon_fence *r100_copy_blit(struct radeon_device *rdev,
859 uint64_t src_offset, 859 uint64_t src_offset,
860 uint64_t dst_offset, 860 uint64_t dst_offset,
861 unsigned num_gpu_pages, 861 unsigned num_gpu_pages,
862 struct radeon_fence **fence) 862 struct reservation_object *resv)
863{ 863{
864 struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; 864 struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
865 struct radeon_fence *fence;
865 uint32_t cur_pages; 866 uint32_t cur_pages;
866 uint32_t stride_bytes = RADEON_GPU_PAGE_SIZE; 867 uint32_t stride_bytes = RADEON_GPU_PAGE_SIZE;
867 uint32_t pitch; 868 uint32_t pitch;
@@ -882,7 +883,7 @@ int r100_copy_blit(struct radeon_device *rdev,
882 r = radeon_ring_lock(rdev, ring, ndw); 883 r = radeon_ring_lock(rdev, ring, ndw);
883 if (r) { 884 if (r) {
884 DRM_ERROR("radeon: moving bo (%d) asking for %u dw.\n", r, ndw); 885 DRM_ERROR("radeon: moving bo (%d) asking for %u dw.\n", r, ndw);
885 return -EINVAL; 886 return ERR_PTR(-EINVAL);
886 } 887 }
887 while (num_gpu_pages > 0) { 888 while (num_gpu_pages > 0) {
888 cur_pages = num_gpu_pages; 889 cur_pages = num_gpu_pages;
@@ -922,11 +923,13 @@ int r100_copy_blit(struct radeon_device *rdev,
922 RADEON_WAIT_2D_IDLECLEAN | 923 RADEON_WAIT_2D_IDLECLEAN |
923 RADEON_WAIT_HOST_IDLECLEAN | 924 RADEON_WAIT_HOST_IDLECLEAN |
924 RADEON_WAIT_DMA_GUI_IDLE); 925 RADEON_WAIT_DMA_GUI_IDLE);
925 if (fence) { 926 r = radeon_fence_emit(rdev, &fence, RADEON_RING_TYPE_GFX_INDEX);
926 r = radeon_fence_emit(rdev, fence, RADEON_RING_TYPE_GFX_INDEX); 927 if (r) {
928 radeon_ring_unlock_undo(rdev, ring);
929 return ERR_PTR(r);
927 } 930 }
928 radeon_ring_unlock_commit(rdev, ring, false); 931 radeon_ring_unlock_commit(rdev, ring, false);
929 return r; 932 return fence;
930} 933}
931 934
932static int r100_cp_wait_for_idle(struct radeon_device *rdev) 935static int r100_cp_wait_for_idle(struct radeon_device *rdev)
diff --git a/drivers/gpu/drm/radeon/r200.c b/drivers/gpu/drm/radeon/r200.c
index 67780374a652..732d4938aab7 100644
--- a/drivers/gpu/drm/radeon/r200.c
+++ b/drivers/gpu/drm/radeon/r200.c
@@ -80,13 +80,14 @@ static int r200_get_vtx_size_0(uint32_t vtx_fmt_0)
80 return vtx_size; 80 return vtx_size;
81} 81}
82 82
83int r200_copy_dma(struct radeon_device *rdev, 83struct radeon_fence *r200_copy_dma(struct radeon_device *rdev,
84 uint64_t src_offset, 84 uint64_t src_offset,
85 uint64_t dst_offset, 85 uint64_t dst_offset,
86 unsigned num_gpu_pages, 86 unsigned num_gpu_pages,
87 struct radeon_fence **fence) 87 struct reservation_object *resv)
88{ 88{
89 struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; 89 struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
90 struct radeon_fence *fence;
90 uint32_t size; 91 uint32_t size;
91 uint32_t cur_size; 92 uint32_t cur_size;
92 int i, num_loops; 93 int i, num_loops;
@@ -98,7 +99,7 @@ int r200_copy_dma(struct radeon_device *rdev,
98 r = radeon_ring_lock(rdev, ring, num_loops * 4 + 64); 99 r = radeon_ring_lock(rdev, ring, num_loops * 4 + 64);
99 if (r) { 100 if (r) {
100 DRM_ERROR("radeon: moving bo (%d).\n", r); 101 DRM_ERROR("radeon: moving bo (%d).\n", r);
101 return r; 102 return ERR_PTR(r);
102 } 103 }
103 /* Must wait for 2D idle & clean before DMA or hangs might happen */ 104 /* Must wait for 2D idle & clean before DMA or hangs might happen */
104 radeon_ring_write(ring, PACKET0(RADEON_WAIT_UNTIL, 0)); 105 radeon_ring_write(ring, PACKET0(RADEON_WAIT_UNTIL, 0));
@@ -118,11 +119,13 @@ int r200_copy_dma(struct radeon_device *rdev,
118 } 119 }
119 radeon_ring_write(ring, PACKET0(RADEON_WAIT_UNTIL, 0)); 120 radeon_ring_write(ring, PACKET0(RADEON_WAIT_UNTIL, 0));
120 radeon_ring_write(ring, RADEON_WAIT_DMA_GUI_IDLE); 121 radeon_ring_write(ring, RADEON_WAIT_DMA_GUI_IDLE);
121 if (fence) { 122 r = radeon_fence_emit(rdev, &fence, RADEON_RING_TYPE_GFX_INDEX);
122 r = radeon_fence_emit(rdev, fence, RADEON_RING_TYPE_GFX_INDEX); 123 if (r) {
124 radeon_ring_unlock_undo(rdev, ring);
125 return ERR_PTR(r);
123 } 126 }
124 radeon_ring_unlock_commit(rdev, ring, false); 127 radeon_ring_unlock_commit(rdev, ring, false);
125 return r; 128 return fence;
126} 129}
127 130
128 131
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index a95ced569d84..5e9146b968b9 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -2894,12 +2894,13 @@ bool r600_semaphore_ring_emit(struct radeon_device *rdev,
2894 * Used by the radeon ttm implementation to move pages if 2894 * Used by the radeon ttm implementation to move pages if
2895 * registered as the asic copy callback. 2895 * registered as the asic copy callback.
2896 */ 2896 */
2897int r600_copy_cpdma(struct radeon_device *rdev, 2897struct radeon_fence *r600_copy_cpdma(struct radeon_device *rdev,
2898 uint64_t src_offset, uint64_t dst_offset, 2898 uint64_t src_offset, uint64_t dst_offset,
2899 unsigned num_gpu_pages, 2899 unsigned num_gpu_pages,
2900 struct radeon_fence **fence) 2900 struct reservation_object *resv)
2901{ 2901{
2902 struct radeon_semaphore *sem = NULL; 2902 struct radeon_semaphore *sem = NULL;
2903 struct radeon_fence *fence;
2903 int ring_index = rdev->asic->copy.blit_ring_index; 2904 int ring_index = rdev->asic->copy.blit_ring_index;
2904 struct radeon_ring *ring = &rdev->ring[ring_index]; 2905 struct radeon_ring *ring = &rdev->ring[ring_index];
2905 u32 size_in_bytes, cur_size_in_bytes, tmp; 2906 u32 size_in_bytes, cur_size_in_bytes, tmp;
@@ -2909,7 +2910,7 @@ int r600_copy_cpdma(struct radeon_device *rdev,
2909 r = radeon_semaphore_create(rdev, &sem); 2910 r = radeon_semaphore_create(rdev, &sem);
2910 if (r) { 2911 if (r) {
2911 DRM_ERROR("radeon: moving bo (%d).\n", r); 2912 DRM_ERROR("radeon: moving bo (%d).\n", r);
2912 return r; 2913 return ERR_PTR(r);
2913 } 2914 }
2914 2915
2915 size_in_bytes = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT); 2916 size_in_bytes = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT);
@@ -2918,10 +2919,10 @@ int r600_copy_cpdma(struct radeon_device *rdev,
2918 if (r) { 2919 if (r) {
2919 DRM_ERROR("radeon: moving bo (%d).\n", r); 2920 DRM_ERROR("radeon: moving bo (%d).\n", r);
2920 radeon_semaphore_free(rdev, &sem, NULL); 2921 radeon_semaphore_free(rdev, &sem, NULL);
2921 return r; 2922 return ERR_PTR(r);
2922 } 2923 }
2923 2924
2924 radeon_semaphore_sync_to(sem, *fence); 2925 radeon_semaphore_sync_resv(sem, resv, false);
2925 radeon_semaphore_sync_rings(rdev, sem, ring->idx); 2926 radeon_semaphore_sync_rings(rdev, sem, ring->idx);
2926 2927
2927 radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1)); 2928 radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1));
@@ -2948,17 +2949,17 @@ int r600_copy_cpdma(struct radeon_device *rdev,
2948 radeon_ring_write(ring, (WAIT_UNTIL - PACKET3_SET_CONFIG_REG_OFFSET) >> 2); 2949 radeon_ring_write(ring, (WAIT_UNTIL - PACKET3_SET_CONFIG_REG_OFFSET) >> 2);
2949 radeon_ring_write(ring, WAIT_CP_DMA_IDLE_bit); 2950 radeon_ring_write(ring, WAIT_CP_DMA_IDLE_bit);
2950 2951
2951 r = radeon_fence_emit(rdev, fence, ring->idx); 2952 r = radeon_fence_emit(rdev, &fence, ring->idx);
2952 if (r) { 2953 if (r) {
2953 radeon_ring_unlock_undo(rdev, ring); 2954 radeon_ring_unlock_undo(rdev, ring);
2954 radeon_semaphore_free(rdev, &sem, NULL); 2955 radeon_semaphore_free(rdev, &sem, NULL);
2955 return r; 2956 return ERR_PTR(r);
2956 } 2957 }
2957 2958
2958 radeon_ring_unlock_commit(rdev, ring, false); 2959 radeon_ring_unlock_commit(rdev, ring, false);
2959 radeon_semaphore_free(rdev, &sem, *fence); 2960 radeon_semaphore_free(rdev, &sem, fence);
2960 2961
2961 return r; 2962 return fence;
2962} 2963}
2963 2964
2964int r600_set_surface_reg(struct radeon_device *rdev, int reg, 2965int r600_set_surface_reg(struct radeon_device *rdev, int reg,
diff --git a/drivers/gpu/drm/radeon/r600_dma.c b/drivers/gpu/drm/radeon/r600_dma.c
index 51fd98553eaf..fc54224ce87b 100644
--- a/drivers/gpu/drm/radeon/r600_dma.c
+++ b/drivers/gpu/drm/radeon/r600_dma.c
@@ -436,18 +436,19 @@ void r600_dma_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib)
436 * @src_offset: src GPU address 436 * @src_offset: src GPU address
437 * @dst_offset: dst GPU address 437 * @dst_offset: dst GPU address
438 * @num_gpu_pages: number of GPU pages to xfer 438 * @num_gpu_pages: number of GPU pages to xfer
439 * @fence: radeon fence object 439 * @resv: reservation object to sync to
440 * 440 *
441 * Copy GPU paging using the DMA engine (r6xx). 441 * Copy GPU paging using the DMA engine (r6xx).
442 * Used by the radeon ttm implementation to move pages if 442 * Used by the radeon ttm implementation to move pages if
443 * registered as the asic copy callback. 443 * registered as the asic copy callback.
444 */ 444 */
445int r600_copy_dma(struct radeon_device *rdev, 445struct radeon_fence *r600_copy_dma(struct radeon_device *rdev,
446 uint64_t src_offset, uint64_t dst_offset, 446 uint64_t src_offset, uint64_t dst_offset,
447 unsigned num_gpu_pages, 447 unsigned num_gpu_pages,
448 struct radeon_fence **fence) 448 struct reservation_object *resv)
449{ 449{
450 struct radeon_semaphore *sem = NULL; 450 struct radeon_semaphore *sem = NULL;
451 struct radeon_fence *fence;
451 int ring_index = rdev->asic->copy.dma_ring_index; 452 int ring_index = rdev->asic->copy.dma_ring_index;
452 struct radeon_ring *ring = &rdev->ring[ring_index]; 453 struct radeon_ring *ring = &rdev->ring[ring_index];
453 u32 size_in_dw, cur_size_in_dw; 454 u32 size_in_dw, cur_size_in_dw;
@@ -457,7 +458,7 @@ int r600_copy_dma(struct radeon_device *rdev,
457 r = radeon_semaphore_create(rdev, &sem); 458 r = radeon_semaphore_create(rdev, &sem);
458 if (r) { 459 if (r) {
459 DRM_ERROR("radeon: moving bo (%d).\n", r); 460 DRM_ERROR("radeon: moving bo (%d).\n", r);
460 return r; 461 return ERR_PTR(r);
461 } 462 }
462 463
463 size_in_dw = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT) / 4; 464 size_in_dw = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT) / 4;
@@ -466,10 +467,10 @@ int r600_copy_dma(struct radeon_device *rdev,
466 if (r) { 467 if (r) {
467 DRM_ERROR("radeon: moving bo (%d).\n", r); 468 DRM_ERROR("radeon: moving bo (%d).\n", r);
468 radeon_semaphore_free(rdev, &sem, NULL); 469 radeon_semaphore_free(rdev, &sem, NULL);
469 return r; 470 return ERR_PTR(r);
470 } 471 }
471 472
472 radeon_semaphore_sync_to(sem, *fence); 473 radeon_semaphore_sync_resv(sem, resv, false);
473 radeon_semaphore_sync_rings(rdev, sem, ring->idx); 474 radeon_semaphore_sync_rings(rdev, sem, ring->idx);
474 475
475 for (i = 0; i < num_loops; i++) { 476 for (i = 0; i < num_loops; i++) {
@@ -486,15 +487,15 @@ int r600_copy_dma(struct radeon_device *rdev,
486 dst_offset += cur_size_in_dw * 4; 487 dst_offset += cur_size_in_dw * 4;
487 } 488 }
488 489
489 r = radeon_fence_emit(rdev, fence, ring->idx); 490 r = radeon_fence_emit(rdev, &fence, ring->idx);
490 if (r) { 491 if (r) {
491 radeon_ring_unlock_undo(rdev, ring); 492 radeon_ring_unlock_undo(rdev, ring);
492 radeon_semaphore_free(rdev, &sem, NULL); 493 radeon_semaphore_free(rdev, &sem, NULL);
493 return r; 494 return ERR_PTR(r);
494 } 495 }
495 496
496 radeon_ring_unlock_commit(rdev, ring, false); 497 radeon_ring_unlock_commit(rdev, ring, false);
497 radeon_semaphore_free(rdev, &sem, *fence); 498 radeon_semaphore_free(rdev, &sem, fence);
498 499
499 return r; 500 return fence;
500} 501}
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 79c988db79ad..2e41dc12cd00 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -585,8 +585,11 @@ bool radeon_semaphore_emit_signal(struct radeon_device *rdev, int ring,
585 struct radeon_semaphore *semaphore); 585 struct radeon_semaphore *semaphore);
586bool radeon_semaphore_emit_wait(struct radeon_device *rdev, int ring, 586bool radeon_semaphore_emit_wait(struct radeon_device *rdev, int ring,
587 struct radeon_semaphore *semaphore); 587 struct radeon_semaphore *semaphore);
588void radeon_semaphore_sync_to(struct radeon_semaphore *semaphore, 588void radeon_semaphore_sync_fence(struct radeon_semaphore *semaphore,
589 struct radeon_fence *fence); 589 struct radeon_fence *fence);
590void radeon_semaphore_sync_resv(struct radeon_semaphore *semaphore,
591 struct reservation_object *resv,
592 bool shared);
590int radeon_semaphore_sync_rings(struct radeon_device *rdev, 593int radeon_semaphore_sync_rings(struct radeon_device *rdev,
591 struct radeon_semaphore *semaphore, 594 struct radeon_semaphore *semaphore,
592 int waiting_ring); 595 int waiting_ring);
@@ -1855,24 +1858,24 @@ struct radeon_asic {
1855 } display; 1858 } display;
1856 /* copy functions for bo handling */ 1859 /* copy functions for bo handling */
1857 struct { 1860 struct {
1858 int (*blit)(struct radeon_device *rdev, 1861 struct radeon_fence *(*blit)(struct radeon_device *rdev,
1859 uint64_t src_offset, 1862 uint64_t src_offset,
1860 uint64_t dst_offset, 1863 uint64_t dst_offset,
1861 unsigned num_gpu_pages, 1864 unsigned num_gpu_pages,
1862 struct radeon_fence **fence); 1865 struct reservation_object *resv);
1863 u32 blit_ring_index; 1866 u32 blit_ring_index;
1864 int (*dma)(struct radeon_device *rdev, 1867 struct radeon_fence *(*dma)(struct radeon_device *rdev,
1865 uint64_t src_offset, 1868 uint64_t src_offset,
1866 uint64_t dst_offset, 1869 uint64_t dst_offset,
1867 unsigned num_gpu_pages, 1870 unsigned num_gpu_pages,
1868 struct radeon_fence **fence); 1871 struct reservation_object *resv);
1869 u32 dma_ring_index; 1872 u32 dma_ring_index;
1870 /* method used for bo copy */ 1873 /* method used for bo copy */
1871 int (*copy)(struct radeon_device *rdev, 1874 struct radeon_fence *(*copy)(struct radeon_device *rdev,
1872 uint64_t src_offset, 1875 uint64_t src_offset,
1873 uint64_t dst_offset, 1876 uint64_t dst_offset,
1874 unsigned num_gpu_pages, 1877 unsigned num_gpu_pages,
1875 struct radeon_fence **fence); 1878 struct reservation_object *resv);
1876 /* ring used for bo copies */ 1879 /* ring used for bo copies */
1877 u32 copy_ring_index; 1880 u32 copy_ring_index;
1878 } copy; 1881 } copy;
@@ -2833,9 +2836,9 @@ static inline void radeon_ring_write(struct radeon_ring *ring, uint32_t v)
2833#define radeon_hdmi_setmode(rdev, e, m) (rdev)->asic->display.hdmi_setmode((e), (m)) 2836#define radeon_hdmi_setmode(rdev, e, m) (rdev)->asic->display.hdmi_setmode((e), (m))
2834#define radeon_fence_ring_emit(rdev, r, fence) (rdev)->asic->ring[(r)]->emit_fence((rdev), (fence)) 2837#define radeon_fence_ring_emit(rdev, r, fence) (rdev)->asic->ring[(r)]->emit_fence((rdev), (fence))
2835#define radeon_semaphore_ring_emit(rdev, r, cp, semaphore, emit_wait) (rdev)->asic->ring[(r)]->emit_semaphore((rdev), (cp), (semaphore), (emit_wait)) 2838#define radeon_semaphore_ring_emit(rdev, r, cp, semaphore, emit_wait) (rdev)->asic->ring[(r)]->emit_semaphore((rdev), (cp), (semaphore), (emit_wait))
2836#define radeon_copy_blit(rdev, s, d, np, f) (rdev)->asic->copy.blit((rdev), (s), (d), (np), (f)) 2839#define radeon_copy_blit(rdev, s, d, np, resv) (rdev)->asic->copy.blit((rdev), (s), (d), (np), (resv))
2837#define radeon_copy_dma(rdev, s, d, np, f) (rdev)->asic->copy.dma((rdev), (s), (d), (np), (f)) 2840#define radeon_copy_dma(rdev, s, d, np, resv) (rdev)->asic->copy.dma((rdev), (s), (d), (np), (resv))
2838#define radeon_copy(rdev, s, d, np, f) (rdev)->asic->copy.copy((rdev), (s), (d), (np), (f)) 2841#define radeon_copy(rdev, s, d, np, resv) (rdev)->asic->copy.copy((rdev), (s), (d), (np), (resv))
2839#define radeon_copy_blit_ring_index(rdev) (rdev)->asic->copy.blit_ring_index 2842#define radeon_copy_blit_ring_index(rdev) (rdev)->asic->copy.blit_ring_index
2840#define radeon_copy_dma_ring_index(rdev) (rdev)->asic->copy.dma_ring_index 2843#define radeon_copy_dma_ring_index(rdev) (rdev)->asic->copy.dma_ring_index
2841#define radeon_copy_ring_index(rdev) (rdev)->asic->copy.copy_ring_index 2844#define radeon_copy_ring_index(rdev) (rdev)->asic->copy.copy_ring_index
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h
index 987a3b713e06..ca01bb8ea217 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.h
+++ b/drivers/gpu/drm/radeon/radeon_asic.h
@@ -81,11 +81,11 @@ bool r100_semaphore_ring_emit(struct radeon_device *rdev,
81int r100_cs_parse(struct radeon_cs_parser *p); 81int r100_cs_parse(struct radeon_cs_parser *p);
82void r100_pll_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); 82void r100_pll_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v);
83uint32_t r100_pll_rreg(struct radeon_device *rdev, uint32_t reg); 83uint32_t r100_pll_rreg(struct radeon_device *rdev, uint32_t reg);
84int r100_copy_blit(struct radeon_device *rdev, 84struct radeon_fence *r100_copy_blit(struct radeon_device *rdev,
85 uint64_t src_offset, 85 uint64_t src_offset,
86 uint64_t dst_offset, 86 uint64_t dst_offset,
87 unsigned num_gpu_pages, 87 unsigned num_gpu_pages,
88 struct radeon_fence **fence); 88 struct reservation_object *resv);
89int r100_set_surface_reg(struct radeon_device *rdev, int reg, 89int r100_set_surface_reg(struct radeon_device *rdev, int reg,
90 uint32_t tiling_flags, uint32_t pitch, 90 uint32_t tiling_flags, uint32_t pitch,
91 uint32_t offset, uint32_t obj_size); 91 uint32_t offset, uint32_t obj_size);
@@ -153,11 +153,11 @@ void r100_ring_hdp_flush(struct radeon_device *rdev,
153/* 153/*
154 * r200,rv250,rs300,rv280 154 * r200,rv250,rs300,rv280
155 */ 155 */
156extern int r200_copy_dma(struct radeon_device *rdev, 156struct radeon_fence *r200_copy_dma(struct radeon_device *rdev,
157 uint64_t src_offset, 157 uint64_t src_offset,
158 uint64_t dst_offset, 158 uint64_t dst_offset,
159 unsigned num_gpu_pages, 159 unsigned num_gpu_pages,
160 struct radeon_fence **fence); 160 struct reservation_object *resv);
161void r200_set_safe_registers(struct radeon_device *rdev); 161void r200_set_safe_registers(struct radeon_device *rdev);
162 162
163/* 163/*
@@ -341,12 +341,14 @@ int r600_dma_ib_test(struct radeon_device *rdev, struct radeon_ring *ring);
341void r600_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib); 341void r600_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib);
342int r600_ring_test(struct radeon_device *rdev, struct radeon_ring *cp); 342int r600_ring_test(struct radeon_device *rdev, struct radeon_ring *cp);
343int r600_dma_ring_test(struct radeon_device *rdev, struct radeon_ring *cp); 343int r600_dma_ring_test(struct radeon_device *rdev, struct radeon_ring *cp);
344int r600_copy_cpdma(struct radeon_device *rdev, 344struct radeon_fence *r600_copy_cpdma(struct radeon_device *rdev,
345 uint64_t src_offset, uint64_t dst_offset, 345 uint64_t src_offset, uint64_t dst_offset,
346 unsigned num_gpu_pages, struct radeon_fence **fence); 346 unsigned num_gpu_pages,
347int r600_copy_dma(struct radeon_device *rdev, 347 struct reservation_object *resv);
348 uint64_t src_offset, uint64_t dst_offset, 348struct radeon_fence *r600_copy_dma(struct radeon_device *rdev,
349 unsigned num_gpu_pages, struct radeon_fence **fence); 349 uint64_t src_offset, uint64_t dst_offset,
350 unsigned num_gpu_pages,
351 struct reservation_object *resv);
350void r600_hpd_init(struct radeon_device *rdev); 352void r600_hpd_init(struct radeon_device *rdev);
351void r600_hpd_fini(struct radeon_device *rdev); 353void r600_hpd_fini(struct radeon_device *rdev);
352bool r600_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd); 354bool r600_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd);
@@ -462,10 +464,10 @@ bool rv770_page_flip_pending(struct radeon_device *rdev, int crtc);
462void r700_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc); 464void r700_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc);
463void r700_cp_stop(struct radeon_device *rdev); 465void r700_cp_stop(struct radeon_device *rdev);
464void r700_cp_fini(struct radeon_device *rdev); 466void r700_cp_fini(struct radeon_device *rdev);
465int rv770_copy_dma(struct radeon_device *rdev, 467struct radeon_fence *rv770_copy_dma(struct radeon_device *rdev,
466 uint64_t src_offset, uint64_t dst_offset, 468 uint64_t src_offset, uint64_t dst_offset,
467 unsigned num_gpu_pages, 469 unsigned num_gpu_pages,
468 struct radeon_fence **fence); 470 struct reservation_object *resv);
469u32 rv770_get_xclk(struct radeon_device *rdev); 471u32 rv770_get_xclk(struct radeon_device *rdev);
470int rv770_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk); 472int rv770_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk);
471int rv770_get_temp(struct radeon_device *rdev); 473int rv770_get_temp(struct radeon_device *rdev);
@@ -536,10 +538,10 @@ void evergreen_dma_fence_ring_emit(struct radeon_device *rdev,
536 struct radeon_fence *fence); 538 struct radeon_fence *fence);
537void evergreen_dma_ring_ib_execute(struct radeon_device *rdev, 539void evergreen_dma_ring_ib_execute(struct radeon_device *rdev,
538 struct radeon_ib *ib); 540 struct radeon_ib *ib);
539int evergreen_copy_dma(struct radeon_device *rdev, 541struct radeon_fence *evergreen_copy_dma(struct radeon_device *rdev,
540 uint64_t src_offset, uint64_t dst_offset, 542 uint64_t src_offset, uint64_t dst_offset,
541 unsigned num_gpu_pages, 543 unsigned num_gpu_pages,
542 struct radeon_fence **fence); 544 struct reservation_object *resv);
543void evergreen_hdmi_enable(struct drm_encoder *encoder, bool enable); 545void evergreen_hdmi_enable(struct drm_encoder *encoder, bool enable);
544void evergreen_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mode); 546void evergreen_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mode);
545int evergreen_get_temp(struct radeon_device *rdev); 547int evergreen_get_temp(struct radeon_device *rdev);
@@ -701,10 +703,10 @@ int si_vm_init(struct radeon_device *rdev);
701void si_vm_fini(struct radeon_device *rdev); 703void si_vm_fini(struct radeon_device *rdev);
702void si_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm); 704void si_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm);
703int si_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib); 705int si_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib);
704int si_copy_dma(struct radeon_device *rdev, 706struct radeon_fence *si_copy_dma(struct radeon_device *rdev,
705 uint64_t src_offset, uint64_t dst_offset, 707 uint64_t src_offset, uint64_t dst_offset,
706 unsigned num_gpu_pages, 708 unsigned num_gpu_pages,
707 struct radeon_fence **fence); 709 struct reservation_object *resv);
708 710
709void si_dma_vm_copy_pages(struct radeon_device *rdev, 711void si_dma_vm_copy_pages(struct radeon_device *rdev,
710 struct radeon_ib *ib, 712 struct radeon_ib *ib,
@@ -760,14 +762,14 @@ bool cik_sdma_semaphore_ring_emit(struct radeon_device *rdev,
760 struct radeon_semaphore *semaphore, 762 struct radeon_semaphore *semaphore,
761 bool emit_wait); 763 bool emit_wait);
762void cik_sdma_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib); 764void cik_sdma_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib);
763int cik_copy_dma(struct radeon_device *rdev, 765struct radeon_fence *cik_copy_dma(struct radeon_device *rdev,
764 uint64_t src_offset, uint64_t dst_offset, 766 uint64_t src_offset, uint64_t dst_offset,
765 unsigned num_gpu_pages, 767 unsigned num_gpu_pages,
766 struct radeon_fence **fence); 768 struct reservation_object *resv);
767int cik_copy_cpdma(struct radeon_device *rdev, 769struct radeon_fence *cik_copy_cpdma(struct radeon_device *rdev,
768 uint64_t src_offset, uint64_t dst_offset, 770 uint64_t src_offset, uint64_t dst_offset,
769 unsigned num_gpu_pages, 771 unsigned num_gpu_pages,
770 struct radeon_fence **fence); 772 struct reservation_object *resv);
771int cik_sdma_ring_test(struct radeon_device *rdev, struct radeon_ring *ring); 773int cik_sdma_ring_test(struct radeon_device *rdev, struct radeon_ring *ring);
772int cik_sdma_ib_test(struct radeon_device *rdev, struct radeon_ring *ring); 774int cik_sdma_ib_test(struct radeon_device *rdev, struct radeon_ring *ring);
773bool cik_sdma_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring); 775bool cik_sdma_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring);
diff --git a/drivers/gpu/drm/radeon/radeon_benchmark.c b/drivers/gpu/drm/radeon/radeon_benchmark.c
index 69f5695bdab9..1e8855060fc7 100644
--- a/drivers/gpu/drm/radeon/radeon_benchmark.c
+++ b/drivers/gpu/drm/radeon/radeon_benchmark.c
@@ -45,33 +45,29 @@ static int radeon_benchmark_do_move(struct radeon_device *rdev, unsigned size,
45 for (i = 0; i < n; i++) { 45 for (i = 0; i < n; i++) {
46 switch (flag) { 46 switch (flag) {
47 case RADEON_BENCHMARK_COPY_DMA: 47 case RADEON_BENCHMARK_COPY_DMA:
48 r = radeon_copy_dma(rdev, saddr, daddr, 48 fence = radeon_copy_dma(rdev, saddr, daddr,
49 size / RADEON_GPU_PAGE_SIZE, 49 size / RADEON_GPU_PAGE_SIZE,
50 &fence); 50 NULL);
51 break; 51 break;
52 case RADEON_BENCHMARK_COPY_BLIT: 52 case RADEON_BENCHMARK_COPY_BLIT:
53 r = radeon_copy_blit(rdev, saddr, daddr, 53 fence = radeon_copy_blit(rdev, saddr, daddr,
54 size / RADEON_GPU_PAGE_SIZE, 54 size / RADEON_GPU_PAGE_SIZE,
55 &fence); 55 NULL);
56 break; 56 break;
57 default: 57 default:
58 DRM_ERROR("Unknown copy method\n"); 58 DRM_ERROR("Unknown copy method\n");
59 r = -EINVAL; 59 return -EINVAL;
60 } 60 }
61 if (r) 61 if (IS_ERR(fence))
62 goto exit_do_move; 62 return PTR_ERR(fence);
63
63 r = radeon_fence_wait(fence, false); 64 r = radeon_fence_wait(fence, false);
64 if (r)
65 goto exit_do_move;
66 radeon_fence_unref(&fence); 65 radeon_fence_unref(&fence);
66 if (r)
67 return r;
67 } 68 }
68 end_jiffies = jiffies; 69 end_jiffies = jiffies;
69 r = jiffies_to_msecs(end_jiffies - start_jiffies); 70 return jiffies_to_msecs(end_jiffies - start_jiffies);
70
71exit_do_move:
72 if (fence)
73 radeon_fence_unref(&fence);
74 return r;
75} 71}
76 72
77 73
diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c
index cd517ab93608..ec4840cb8a07 100644
--- a/drivers/gpu/drm/radeon/radeon_cs.c
+++ b/drivers/gpu/drm/radeon/radeon_cs.c
@@ -255,16 +255,12 @@ static void radeon_cs_sync_rings(struct radeon_cs_parser *p)
255 255
256 for (i = 0; i < p->nrelocs; i++) { 256 for (i = 0; i < p->nrelocs; i++) {
257 struct reservation_object *resv; 257 struct reservation_object *resv;
258 struct fence *fence;
259 258
260 if (!p->relocs[i].robj) 259 if (!p->relocs[i].robj)
261 continue; 260 continue;
262 261
263 resv = p->relocs[i].robj->tbo.resv; 262 resv = p->relocs[i].robj->tbo.resv;
264 fence = reservation_object_get_excl(resv); 263 radeon_semaphore_sync_resv(p->ib.semaphore, resv, false);
265
266 radeon_semaphore_sync_to(p->ib.semaphore,
267 (struct radeon_fence *)fence);
268 } 264 }
269} 265}
270 266
@@ -569,7 +565,7 @@ static int radeon_cs_ib_vm_chunk(struct radeon_device *rdev,
569 goto out; 565 goto out;
570 } 566 }
571 radeon_cs_sync_rings(parser); 567 radeon_cs_sync_rings(parser);
572 radeon_semaphore_sync_to(parser->ib.semaphore, vm->fence); 568 radeon_semaphore_sync_fence(parser->ib.semaphore, vm->fence);
573 569
574 if ((rdev->family >= CHIP_TAHITI) && 570 if ((rdev->family >= CHIP_TAHITI) &&
575 (parser->chunk_const_ib_idx != -1)) { 571 (parser->chunk_const_ib_idx != -1)) {
diff --git a/drivers/gpu/drm/radeon/radeon_ib.c b/drivers/gpu/drm/radeon/radeon_ib.c
index 6fc7461d70c4..3f39fcca4d07 100644
--- a/drivers/gpu/drm/radeon/radeon_ib.c
+++ b/drivers/gpu/drm/radeon/radeon_ib.c
@@ -145,7 +145,7 @@ int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib,
145 if (ib->vm) { 145 if (ib->vm) {
146 struct radeon_fence *vm_id_fence; 146 struct radeon_fence *vm_id_fence;
147 vm_id_fence = radeon_vm_grab_id(rdev, ib->vm, ib->ring); 147 vm_id_fence = radeon_vm_grab_id(rdev, ib->vm, ib->ring);
148 radeon_semaphore_sync_to(ib->semaphore, vm_id_fence); 148 radeon_semaphore_sync_fence(ib->semaphore, vm_id_fence);
149 } 149 }
150 150
151 /* sync with other rings */ 151 /* sync with other rings */
diff --git a/drivers/gpu/drm/radeon/radeon_semaphore.c b/drivers/gpu/drm/radeon/radeon_semaphore.c
index 56d9fd66d8ae..5bfbd8372a3c 100644
--- a/drivers/gpu/drm/radeon/radeon_semaphore.c
+++ b/drivers/gpu/drm/radeon/radeon_semaphore.c
@@ -96,15 +96,15 @@ bool radeon_semaphore_emit_wait(struct radeon_device *rdev, int ridx,
96} 96}
97 97
98/** 98/**
99 * radeon_semaphore_sync_to - use the semaphore to sync to a fence 99 * radeon_semaphore_sync_fence - use the semaphore to sync to a fence
100 * 100 *
101 * @semaphore: semaphore object to add fence to 101 * @semaphore: semaphore object to add fence to
102 * @fence: fence to sync to 102 * @fence: fence to sync to
103 * 103 *
104 * Sync to the fence using this semaphore object 104 * Sync to the fence using this semaphore object
105 */ 105 */
106void radeon_semaphore_sync_to(struct radeon_semaphore *semaphore, 106void radeon_semaphore_sync_fence(struct radeon_semaphore *semaphore,
107 struct radeon_fence *fence) 107 struct radeon_fence *fence)
108{ 108{
109 struct radeon_fence *other; 109 struct radeon_fence *other;
110 110
@@ -116,6 +116,38 @@ void radeon_semaphore_sync_to(struct radeon_semaphore *semaphore,
116} 116}
117 117
118/** 118/**
119 * radeon_semaphore_sync_to - use the semaphore to sync to a reservation object
120 *
121 * @sema: semaphore object to add fence from reservation object to
122 * @resv: reservation object with embedded fence
123 * @shared: true if we should onyl sync to the exclusive fence
124 *
125 * Sync to the fence using this semaphore object
126 */
127void radeon_semaphore_sync_resv(struct radeon_semaphore *sema,
128 struct reservation_object *resv,
129 bool shared)
130{
131 struct reservation_object_list *flist;
132 struct fence *f;
133 unsigned i;
134
135 /* always sync to the exclusive fence */
136 f = reservation_object_get_excl(resv);
137 radeon_semaphore_sync_fence(sema, (struct radeon_fence*)f);
138
139 flist = reservation_object_get_list(resv);
140 if (shared || !flist)
141 return;
142
143 for (i = 0; i < flist->shared_count; ++i) {
144 f = rcu_dereference_protected(flist->shared[i],
145 reservation_object_held(resv));
146 radeon_semaphore_sync_fence(sema, (struct radeon_fence*)f);
147 }
148}
149
150/**
119 * radeon_semaphore_sync_rings - sync ring to all registered fences 151 * radeon_semaphore_sync_rings - sync ring to all registered fences
120 * 152 *
121 * @rdev: radeon_device pointer 153 * @rdev: radeon_device pointer
diff --git a/drivers/gpu/drm/radeon/radeon_test.c b/drivers/gpu/drm/radeon/radeon_test.c
index 17bc3dced9f1..ce943e1a5e51 100644
--- a/drivers/gpu/drm/radeon/radeon_test.c
+++ b/drivers/gpu/drm/radeon/radeon_test.c
@@ -116,11 +116,16 @@ static void radeon_do_test_moves(struct radeon_device *rdev, int flag)
116 radeon_bo_kunmap(gtt_obj[i]); 116 radeon_bo_kunmap(gtt_obj[i]);
117 117
118 if (ring == R600_RING_TYPE_DMA_INDEX) 118 if (ring == R600_RING_TYPE_DMA_INDEX)
119 r = radeon_copy_dma(rdev, gtt_addr, vram_addr, size / RADEON_GPU_PAGE_SIZE, &fence); 119 fence = radeon_copy_dma(rdev, gtt_addr, vram_addr,
120 size / RADEON_GPU_PAGE_SIZE,
121 NULL);
120 else 122 else
121 r = radeon_copy_blit(rdev, gtt_addr, vram_addr, size / RADEON_GPU_PAGE_SIZE, &fence); 123 fence = radeon_copy_blit(rdev, gtt_addr, vram_addr,
122 if (r) { 124 size / RADEON_GPU_PAGE_SIZE,
125 NULL);
126 if (IS_ERR(fence)) {
123 DRM_ERROR("Failed GTT->VRAM copy %d\n", i); 127 DRM_ERROR("Failed GTT->VRAM copy %d\n", i);
128 r = PTR_ERR(fence);
124 goto out_lclean_unpin; 129 goto out_lclean_unpin;
125 } 130 }
126 131
@@ -162,11 +167,16 @@ static void radeon_do_test_moves(struct radeon_device *rdev, int flag)
162 radeon_bo_kunmap(vram_obj); 167 radeon_bo_kunmap(vram_obj);
163 168
164 if (ring == R600_RING_TYPE_DMA_INDEX) 169 if (ring == R600_RING_TYPE_DMA_INDEX)
165 r = radeon_copy_dma(rdev, vram_addr, gtt_addr, size / RADEON_GPU_PAGE_SIZE, &fence); 170 fence = radeon_copy_dma(rdev, vram_addr, gtt_addr,
171 size / RADEON_GPU_PAGE_SIZE,
172 NULL);
166 else 173 else
167 r = radeon_copy_blit(rdev, vram_addr, gtt_addr, size / RADEON_GPU_PAGE_SIZE, &fence); 174 fence = radeon_copy_blit(rdev, vram_addr, gtt_addr,
168 if (r) { 175 size / RADEON_GPU_PAGE_SIZE,
176 NULL);
177 if (IS_ERR(fence)) {
169 DRM_ERROR("Failed VRAM->GTT copy %d\n", i); 178 DRM_ERROR("Failed VRAM->GTT copy %d\n", i);
179 r = PTR_ERR(fence);
170 goto out_lclean_unpin; 180 goto out_lclean_unpin;
171 } 181 }
172 182
@@ -222,7 +232,7 @@ out_lclean:
222 radeon_bo_unreserve(gtt_obj[i]); 232 radeon_bo_unreserve(gtt_obj[i]);
223 radeon_bo_unref(&gtt_obj[i]); 233 radeon_bo_unref(&gtt_obj[i]);
224 } 234 }
225 if (fence) 235 if (fence && !IS_ERR(fence))
226 radeon_fence_unref(&fence); 236 radeon_fence_unref(&fence);
227 break; 237 break;
228 } 238 }
diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c
index 62d1f4d730a2..eca2ce60d440 100644
--- a/drivers/gpu/drm/radeon/radeon_ttm.c
+++ b/drivers/gpu/drm/radeon/radeon_ttm.c
@@ -233,6 +233,7 @@ static int radeon_move_blit(struct ttm_buffer_object *bo,
233 struct radeon_device *rdev; 233 struct radeon_device *rdev;
234 uint64_t old_start, new_start; 234 uint64_t old_start, new_start;
235 struct radeon_fence *fence; 235 struct radeon_fence *fence;
236 unsigned num_pages;
236 int r, ridx; 237 int r, ridx;
237 238
238 rdev = radeon_get_rdev(bo->bdev); 239 rdev = radeon_get_rdev(bo->bdev);
@@ -269,12 +270,11 @@ static int radeon_move_blit(struct ttm_buffer_object *bo,
269 270
270 BUILD_BUG_ON((PAGE_SIZE % RADEON_GPU_PAGE_SIZE) != 0); 271 BUILD_BUG_ON((PAGE_SIZE % RADEON_GPU_PAGE_SIZE) != 0);
271 272
272 /* sync other rings */ 273 num_pages = new_mem->num_pages * (PAGE_SIZE / RADEON_GPU_PAGE_SIZE);
273 fence = (struct radeon_fence *)reservation_object_get_excl(bo->resv); 274 fence = radeon_copy(rdev, old_start, new_start, num_pages, bo->resv);
274 r = radeon_copy(rdev, old_start, new_start, 275 if (IS_ERR(fence))
275 new_mem->num_pages * (PAGE_SIZE / RADEON_GPU_PAGE_SIZE), /* GPU pages */ 276 return PTR_ERR(fence);
276 &fence); 277
277 /* FIXME: handle copy error */
278 r = ttm_bo_move_accel_cleanup(bo, &fence->base, 278 r = ttm_bo_move_accel_cleanup(bo, &fence->base,
279 evict, no_wait_gpu, new_mem); 279 evict, no_wait_gpu, new_mem);
280 radeon_fence_unref(&fence); 280 radeon_fence_unref(&fence);
diff --git a/drivers/gpu/drm/radeon/radeon_vm.c b/drivers/gpu/drm/radeon/radeon_vm.c
index 1cce4468cd75..ce870959dff8 100644
--- a/drivers/gpu/drm/radeon/radeon_vm.c
+++ b/drivers/gpu/drm/radeon/radeon_vm.c
@@ -696,15 +696,10 @@ int radeon_vm_update_page_directory(struct radeon_device *rdev,
696 incr, R600_PTE_VALID); 696 incr, R600_PTE_VALID);
697 697
698 if (ib.length_dw != 0) { 698 if (ib.length_dw != 0) {
699 struct fence *fence;
700
701 radeon_asic_vm_pad_ib(rdev, &ib); 699 radeon_asic_vm_pad_ib(rdev, &ib);
702 700
703 fence = reservation_object_get_excl(pd->tbo.resv); 701 radeon_semaphore_sync_resv(ib.semaphore, pd->tbo.resv, false);
704 radeon_semaphore_sync_to(ib.semaphore, 702 radeon_semaphore_sync_fence(ib.semaphore, vm->last_id_use);
705 (struct radeon_fence *)fence);
706
707 radeon_semaphore_sync_to(ib.semaphore, vm->last_id_use);
708 WARN_ON(ib.length_dw > ndw); 703 WARN_ON(ib.length_dw > ndw);
709 r = radeon_ib_schedule(rdev, &ib, NULL, false); 704 r = radeon_ib_schedule(rdev, &ib, NULL, false);
710 if (r) { 705 if (r) {
@@ -829,11 +824,8 @@ static void radeon_vm_update_ptes(struct radeon_device *rdev,
829 struct radeon_bo *pt = vm->page_tables[pt_idx].bo; 824 struct radeon_bo *pt = vm->page_tables[pt_idx].bo;
830 unsigned nptes; 825 unsigned nptes;
831 uint64_t pte; 826 uint64_t pte;
832 struct fence *fence;
833 827
834 fence = reservation_object_get_excl(pt->tbo.resv); 828 radeon_semaphore_sync_resv(ib->semaphore, pt->tbo.resv, false);
835 radeon_semaphore_sync_to(ib->semaphore,
836 (struct radeon_fence *)fence);
837 829
838 if ((addr & ~mask) == (end & ~mask)) 830 if ((addr & ~mask) == (end & ~mask))
839 nptes = end - addr; 831 nptes = end - addr;
@@ -975,7 +967,7 @@ int radeon_vm_bo_update(struct radeon_device *rdev,
975 radeon_asic_vm_pad_ib(rdev, &ib); 967 radeon_asic_vm_pad_ib(rdev, &ib);
976 WARN_ON(ib.length_dw > ndw); 968 WARN_ON(ib.length_dw > ndw);
977 969
978 radeon_semaphore_sync_to(ib.semaphore, vm->fence); 970 radeon_semaphore_sync_fence(ib.semaphore, vm->fence);
979 r = radeon_ib_schedule(rdev, &ib, NULL, false); 971 r = radeon_ib_schedule(rdev, &ib, NULL, false);
980 if (r) { 972 if (r) {
981 radeon_ib_free(rdev, &ib); 973 radeon_ib_free(rdev, &ib);
diff --git a/drivers/gpu/drm/radeon/rv770_dma.c b/drivers/gpu/drm/radeon/rv770_dma.c
index 74426ac2bb5c..c112764adfdf 100644
--- a/drivers/gpu/drm/radeon/rv770_dma.c
+++ b/drivers/gpu/drm/radeon/rv770_dma.c
@@ -33,18 +33,19 @@
33 * @src_offset: src GPU address 33 * @src_offset: src GPU address
34 * @dst_offset: dst GPU address 34 * @dst_offset: dst GPU address
35 * @num_gpu_pages: number of GPU pages to xfer 35 * @num_gpu_pages: number of GPU pages to xfer
36 * @fence: radeon fence object 36 * @resv: reservation object to sync to
37 * 37 *
38 * Copy GPU paging using the DMA engine (r7xx). 38 * Copy GPU paging using the DMA engine (r7xx).
39 * Used by the radeon ttm implementation to move pages if 39 * Used by the radeon ttm implementation to move pages if
40 * registered as the asic copy callback. 40 * registered as the asic copy callback.
41 */ 41 */
42int rv770_copy_dma(struct radeon_device *rdev, 42struct radeon_fence *rv770_copy_dma(struct radeon_device *rdev,
43 uint64_t src_offset, uint64_t dst_offset, 43 uint64_t src_offset, uint64_t dst_offset,
44 unsigned num_gpu_pages, 44 unsigned num_gpu_pages,
45 struct radeon_fence **fence) 45 struct reservation_object *resv)
46{ 46{
47 struct radeon_semaphore *sem = NULL; 47 struct radeon_semaphore *sem = NULL;
48 struct radeon_fence *fence;
48 int ring_index = rdev->asic->copy.dma_ring_index; 49 int ring_index = rdev->asic->copy.dma_ring_index;
49 struct radeon_ring *ring = &rdev->ring[ring_index]; 50 struct radeon_ring *ring = &rdev->ring[ring_index];
50 u32 size_in_dw, cur_size_in_dw; 51 u32 size_in_dw, cur_size_in_dw;
@@ -54,7 +55,7 @@ int rv770_copy_dma(struct radeon_device *rdev,
54 r = radeon_semaphore_create(rdev, &sem); 55 r = radeon_semaphore_create(rdev, &sem);
55 if (r) { 56 if (r) {
56 DRM_ERROR("radeon: moving bo (%d).\n", r); 57 DRM_ERROR("radeon: moving bo (%d).\n", r);
57 return r; 58 return ERR_PTR(r);
58 } 59 }
59 60
60 size_in_dw = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT) / 4; 61 size_in_dw = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT) / 4;
@@ -63,10 +64,10 @@ int rv770_copy_dma(struct radeon_device *rdev,
63 if (r) { 64 if (r) {
64 DRM_ERROR("radeon: moving bo (%d).\n", r); 65 DRM_ERROR("radeon: moving bo (%d).\n", r);
65 radeon_semaphore_free(rdev, &sem, NULL); 66 radeon_semaphore_free(rdev, &sem, NULL);
66 return r; 67 return ERR_PTR(r);
67 } 68 }
68 69
69 radeon_semaphore_sync_to(sem, *fence); 70 radeon_semaphore_sync_resv(sem, resv, false);
70 radeon_semaphore_sync_rings(rdev, sem, ring->idx); 71 radeon_semaphore_sync_rings(rdev, sem, ring->idx);
71 72
72 for (i = 0; i < num_loops; i++) { 73 for (i = 0; i < num_loops; i++) {
@@ -83,15 +84,15 @@ int rv770_copy_dma(struct radeon_device *rdev,
83 dst_offset += cur_size_in_dw * 4; 84 dst_offset += cur_size_in_dw * 4;
84 } 85 }
85 86
86 r = radeon_fence_emit(rdev, fence, ring->idx); 87 r = radeon_fence_emit(rdev, &fence, ring->idx);
87 if (r) { 88 if (r) {
88 radeon_ring_unlock_undo(rdev, ring); 89 radeon_ring_unlock_undo(rdev, ring);
89 radeon_semaphore_free(rdev, &sem, NULL); 90 radeon_semaphore_free(rdev, &sem, NULL);
90 return r; 91 return ERR_PTR(r);
91 } 92 }
92 93
93 radeon_ring_unlock_commit(rdev, ring, false); 94 radeon_ring_unlock_commit(rdev, ring, false);
94 radeon_semaphore_free(rdev, &sem, *fence); 95 radeon_semaphore_free(rdev, &sem, fence);
95 96
96 return r; 97 return fence;
97} 98}
diff --git a/drivers/gpu/drm/radeon/si_dma.c b/drivers/gpu/drm/radeon/si_dma.c
index 7c22baaf94db..9b0dfbc913f3 100644
--- a/drivers/gpu/drm/radeon/si_dma.c
+++ b/drivers/gpu/drm/radeon/si_dma.c
@@ -218,18 +218,19 @@ void si_dma_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm)
218 * @src_offset: src GPU address 218 * @src_offset: src GPU address
219 * @dst_offset: dst GPU address 219 * @dst_offset: dst GPU address
220 * @num_gpu_pages: number of GPU pages to xfer 220 * @num_gpu_pages: number of GPU pages to xfer
221 * @fence: radeon fence object 221 * @resv: reservation object to sync to
222 * 222 *
223 * Copy GPU paging using the DMA engine (SI). 223 * Copy GPU paging using the DMA engine (SI).
224 * Used by the radeon ttm implementation to move pages if 224 * Used by the radeon ttm implementation to move pages if
225 * registered as the asic copy callback. 225 * registered as the asic copy callback.
226 */ 226 */
227int si_copy_dma(struct radeon_device *rdev, 227struct radeon_fence *si_copy_dma(struct radeon_device *rdev,
228 uint64_t src_offset, uint64_t dst_offset, 228 uint64_t src_offset, uint64_t dst_offset,
229 unsigned num_gpu_pages, 229 unsigned num_gpu_pages,
230 struct radeon_fence **fence) 230 struct reservation_object *resv)
231{ 231{
232 struct radeon_semaphore *sem = NULL; 232 struct radeon_semaphore *sem = NULL;
233 struct radeon_fence *fence;
233 int ring_index = rdev->asic->copy.dma_ring_index; 234 int ring_index = rdev->asic->copy.dma_ring_index;
234 struct radeon_ring *ring = &rdev->ring[ring_index]; 235 struct radeon_ring *ring = &rdev->ring[ring_index];
235 u32 size_in_bytes, cur_size_in_bytes; 236 u32 size_in_bytes, cur_size_in_bytes;
@@ -239,7 +240,7 @@ int si_copy_dma(struct radeon_device *rdev,
239 r = radeon_semaphore_create(rdev, &sem); 240 r = radeon_semaphore_create(rdev, &sem);
240 if (r) { 241 if (r) {
241 DRM_ERROR("radeon: moving bo (%d).\n", r); 242 DRM_ERROR("radeon: moving bo (%d).\n", r);
242 return r; 243 return ERR_PTR(r);
243 } 244 }
244 245
245 size_in_bytes = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT); 246 size_in_bytes = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT);
@@ -248,10 +249,10 @@ int si_copy_dma(struct radeon_device *rdev,
248 if (r) { 249 if (r) {
249 DRM_ERROR("radeon: moving bo (%d).\n", r); 250 DRM_ERROR("radeon: moving bo (%d).\n", r);
250 radeon_semaphore_free(rdev, &sem, NULL); 251 radeon_semaphore_free(rdev, &sem, NULL);
251 return r; 252 return ERR_PTR(r);
252 } 253 }
253 254
254 radeon_semaphore_sync_to(sem, *fence); 255 radeon_semaphore_sync_resv(sem, resv, false);
255 radeon_semaphore_sync_rings(rdev, sem, ring->idx); 256 radeon_semaphore_sync_rings(rdev, sem, ring->idx);
256 257
257 for (i = 0; i < num_loops; i++) { 258 for (i = 0; i < num_loops; i++) {
@@ -268,16 +269,16 @@ int si_copy_dma(struct radeon_device *rdev,
268 dst_offset += cur_size_in_bytes; 269 dst_offset += cur_size_in_bytes;
269 } 270 }
270 271
271 r = radeon_fence_emit(rdev, fence, ring->idx); 272 r = radeon_fence_emit(rdev, &fence, ring->idx);
272 if (r) { 273 if (r) {
273 radeon_ring_unlock_undo(rdev, ring); 274 radeon_ring_unlock_undo(rdev, ring);
274 radeon_semaphore_free(rdev, &sem, NULL); 275 radeon_semaphore_free(rdev, &sem, NULL);
275 return r; 276 return ERR_PTR(r);
276 } 277 }
277 278
278 radeon_ring_unlock_commit(rdev, ring, false); 279 radeon_ring_unlock_commit(rdev, ring, false);
279 radeon_semaphore_free(rdev, &sem, *fence); 280 radeon_semaphore_free(rdev, &sem, fence);
280 281
281 return r; 282 return fence;
282} 283}
283 284