diff options
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu.h | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c | 77 |
2 files changed, 26 insertions, 56 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 081953e1ec6c..41c725e02f39 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h | |||
@@ -822,7 +822,7 @@ struct amdgpu_ring { | |||
822 | unsigned wptr; | 822 | unsigned wptr; |
823 | unsigned wptr_old; | 823 | unsigned wptr_old; |
824 | unsigned ring_size; | 824 | unsigned ring_size; |
825 | unsigned ring_free_dw; | 825 | unsigned max_dw; |
826 | int count_dw; | 826 | int count_dw; |
827 | uint64_t gpu_addr; | 827 | uint64_t gpu_addr; |
828 | uint32_t align_mask; | 828 | uint32_t align_mask; |
@@ -1186,8 +1186,6 @@ int amdgpu_ib_schedule(struct amdgpu_device *adev, unsigned num_ibs, | |||
1186 | int amdgpu_ib_pool_init(struct amdgpu_device *adev); | 1186 | int amdgpu_ib_pool_init(struct amdgpu_device *adev); |
1187 | void amdgpu_ib_pool_fini(struct amdgpu_device *adev); | 1187 | void amdgpu_ib_pool_fini(struct amdgpu_device *adev); |
1188 | int amdgpu_ib_ring_tests(struct amdgpu_device *adev); | 1188 | int amdgpu_ib_ring_tests(struct amdgpu_device *adev); |
1189 | /* Ring access between begin & end cannot sleep */ | ||
1190 | void amdgpu_ring_free_size(struct amdgpu_ring *ring); | ||
1191 | int amdgpu_ring_alloc(struct amdgpu_ring *ring, unsigned ndw); | 1189 | int amdgpu_ring_alloc(struct amdgpu_ring *ring, unsigned ndw); |
1192 | void amdgpu_ring_insert_nop(struct amdgpu_ring *ring, uint32_t count); | 1190 | void amdgpu_ring_insert_nop(struct amdgpu_ring *ring, uint32_t count); |
1193 | void amdgpu_ring_commit(struct amdgpu_ring *ring); | 1191 | void amdgpu_ring_commit(struct amdgpu_ring *ring); |
@@ -2163,7 +2161,6 @@ static inline void amdgpu_ring_write(struct amdgpu_ring *ring, uint32_t v) | |||
2163 | ring->ring[ring->wptr++] = v; | 2161 | ring->ring[ring->wptr++] = v; |
2164 | ring->wptr &= ring->ptr_mask; | 2162 | ring->wptr &= ring->ptr_mask; |
2165 | ring->count_dw--; | 2163 | ring->count_dw--; |
2166 | ring->ring_free_dw--; | ||
2167 | } | 2164 | } |
2168 | 2165 | ||
2169 | static inline struct amdgpu_sdma_instance * | 2166 | static inline struct amdgpu_sdma_instance * |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c index 81d06d772dde..1f0db995046d 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c | |||
@@ -49,28 +49,6 @@ | |||
49 | static int amdgpu_debugfs_ring_init(struct amdgpu_device *adev, struct amdgpu_ring *ring); | 49 | static int amdgpu_debugfs_ring_init(struct amdgpu_device *adev, struct amdgpu_ring *ring); |
50 | 50 | ||
51 | /** | 51 | /** |
52 | * amdgpu_ring_free_size - update the free size | ||
53 | * | ||
54 | * @adev: amdgpu_device pointer | ||
55 | * @ring: amdgpu_ring structure holding ring information | ||
56 | * | ||
57 | * Update the free dw slots in the ring buffer (all asics). | ||
58 | */ | ||
59 | void amdgpu_ring_free_size(struct amdgpu_ring *ring) | ||
60 | { | ||
61 | uint32_t rptr = amdgpu_ring_get_rptr(ring); | ||
62 | |||
63 | /* This works because ring_size is a power of 2 */ | ||
64 | ring->ring_free_dw = rptr + (ring->ring_size / 4); | ||
65 | ring->ring_free_dw -= ring->wptr; | ||
66 | ring->ring_free_dw &= ring->ptr_mask; | ||
67 | if (!ring->ring_free_dw) { | ||
68 | /* this is an empty ring */ | ||
69 | ring->ring_free_dw = ring->ring_size / 4; | ||
70 | } | ||
71 | } | ||
72 | |||
73 | /** | ||
74 | * amdgpu_ring_alloc - allocate space on the ring buffer | 52 | * amdgpu_ring_alloc - allocate space on the ring buffer |
75 | * | 53 | * |
76 | * @adev: amdgpu_device pointer | 54 | * @adev: amdgpu_device pointer |
@@ -82,24 +60,16 @@ void amdgpu_ring_free_size(struct amdgpu_ring *ring) | |||
82 | */ | 60 | */ |
83 | int amdgpu_ring_alloc(struct amdgpu_ring *ring, unsigned ndw) | 61 | int amdgpu_ring_alloc(struct amdgpu_ring *ring, unsigned ndw) |
84 | { | 62 | { |
85 | int r; | ||
86 | |||
87 | /* make sure we aren't trying to allocate more space than there is on the ring */ | ||
88 | if (ndw > (ring->ring_size / 4)) | ||
89 | return -ENOMEM; | ||
90 | /* Align requested size with padding so unlock_commit can | 63 | /* Align requested size with padding so unlock_commit can |
91 | * pad safely */ | 64 | * pad safely */ |
92 | amdgpu_ring_free_size(ring); | ||
93 | ndw = (ndw + ring->align_mask) & ~ring->align_mask; | 65 | ndw = (ndw + ring->align_mask) & ~ring->align_mask; |
94 | while (ndw > (ring->ring_free_dw - 1)) { | 66 | |
95 | amdgpu_ring_free_size(ring); | 67 | /* Make sure we aren't trying to allocate more space |
96 | if (ndw < ring->ring_free_dw) { | 68 | * than the maximum for one submission |
97 | break; | 69 | */ |
98 | } | 70 | if (WARN_ON_ONCE(ndw > ring->max_dw)) |
99 | r = amdgpu_fence_wait_next(ring); | 71 | return -ENOMEM; |
100 | if (r) | 72 | |
101 | return r; | ||
102 | } | ||
103 | ring->count_dw = ndw; | 73 | ring->count_dw = ndw; |
104 | ring->wptr_old = ring->wptr; | 74 | ring->wptr_old = ring->wptr; |
105 | return 0; | 75 | return 0; |
@@ -326,7 +296,8 @@ int amdgpu_ring_init(struct amdgpu_device *adev, struct amdgpu_ring *ring, | |||
326 | } | 296 | } |
327 | } | 297 | } |
328 | ring->ptr_mask = (ring->ring_size / 4) - 1; | 298 | ring->ptr_mask = (ring->ring_size / 4) - 1; |
329 | ring->ring_free_dw = ring->ring_size / 4; | 299 | ring->max_dw = DIV_ROUND_UP(ring->ring_size / 4, |
300 | amdgpu_sched_hw_submission); | ||
330 | 301 | ||
331 | if (amdgpu_debugfs_ring_init(adev, ring)) { | 302 | if (amdgpu_debugfs_ring_init(adev, ring)) { |
332 | DRM_ERROR("Failed to register debugfs file for rings !\n"); | 303 | DRM_ERROR("Failed to register debugfs file for rings !\n"); |
@@ -406,25 +377,18 @@ static int amdgpu_debugfs_ring_info(struct seq_file *m, void *data) | |||
406 | struct amdgpu_ring *ring = (void *)(((uint8_t*)adev) + roffset); | 377 | struct amdgpu_ring *ring = (void *)(((uint8_t*)adev) + roffset); |
407 | 378 | ||
408 | uint32_t rptr, wptr, rptr_next; | 379 | uint32_t rptr, wptr, rptr_next; |
409 | unsigned count, i, j; | 380 | unsigned i; |
410 | |||
411 | amdgpu_ring_free_size(ring); | ||
412 | count = (ring->ring_size / 4) - ring->ring_free_dw; | ||
413 | 381 | ||
414 | wptr = amdgpu_ring_get_wptr(ring); | 382 | wptr = amdgpu_ring_get_wptr(ring); |
415 | seq_printf(m, "wptr: 0x%08x [%5d]\n", | 383 | seq_printf(m, "wptr: 0x%08x [%5d]\n", wptr, wptr); |
416 | wptr, wptr); | ||
417 | 384 | ||
418 | rptr = amdgpu_ring_get_rptr(ring); | 385 | rptr = amdgpu_ring_get_rptr(ring); |
419 | seq_printf(m, "rptr: 0x%08x [%5d]\n", | ||
420 | rptr, rptr); | ||
421 | |||
422 | rptr_next = le32_to_cpu(*ring->next_rptr_cpu_addr); | 386 | rptr_next = le32_to_cpu(*ring->next_rptr_cpu_addr); |
423 | 387 | ||
388 | seq_printf(m, "rptr: 0x%08x [%5d]\n", rptr, rptr); | ||
389 | |||
424 | seq_printf(m, "driver's copy of the wptr: 0x%08x [%5d]\n", | 390 | seq_printf(m, "driver's copy of the wptr: 0x%08x [%5d]\n", |
425 | ring->wptr, ring->wptr); | 391 | ring->wptr, ring->wptr); |
426 | seq_printf(m, "%u free dwords in ring\n", ring->ring_free_dw); | ||
427 | seq_printf(m, "%u dwords in ring\n", count); | ||
428 | 392 | ||
429 | if (!ring->ready) | 393 | if (!ring->ready) |
430 | return 0; | 394 | return 0; |
@@ -433,11 +397,20 @@ static int amdgpu_debugfs_ring_info(struct seq_file *m, void *data) | |||
433 | * packet that is the root issue | 397 | * packet that is the root issue |
434 | */ | 398 | */ |
435 | i = (rptr + ring->ptr_mask + 1 - 32) & ring->ptr_mask; | 399 | i = (rptr + ring->ptr_mask + 1 - 32) & ring->ptr_mask; |
436 | for (j = 0; j <= (count + 32); j++) { | 400 | while (i != rptr) { |
401 | seq_printf(m, "r[%5d]=0x%08x", i, ring->ring[i]); | ||
402 | if (i == rptr) | ||
403 | seq_puts(m, " *"); | ||
404 | if (i == rptr_next) | ||
405 | seq_puts(m, " #"); | ||
406 | seq_puts(m, "\n"); | ||
407 | i = (i + 1) & ring->ptr_mask; | ||
408 | } | ||
409 | while (i != wptr) { | ||
437 | seq_printf(m, "r[%5d]=0x%08x", i, ring->ring[i]); | 410 | seq_printf(m, "r[%5d]=0x%08x", i, ring->ring[i]); |
438 | if (rptr == i) | 411 | if (i == rptr) |
439 | seq_puts(m, " *"); | 412 | seq_puts(m, " *"); |
440 | if (rptr_next == i) | 413 | if (i == rptr_next) |
441 | seq_puts(m, " #"); | 414 | seq_puts(m, " #"); |
442 | seq_puts(m, "\n"); | 415 | seq_puts(m, "\n"); |
443 | i = (i + 1) & ring->ptr_mask; | 416 | i = (i + 1) & ring->ptr_mask; |