aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu.h5
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c77
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,
1186int amdgpu_ib_pool_init(struct amdgpu_device *adev); 1186int amdgpu_ib_pool_init(struct amdgpu_device *adev);
1187void amdgpu_ib_pool_fini(struct amdgpu_device *adev); 1187void amdgpu_ib_pool_fini(struct amdgpu_device *adev);
1188int amdgpu_ib_ring_tests(struct amdgpu_device *adev); 1188int amdgpu_ib_ring_tests(struct amdgpu_device *adev);
1189/* Ring access between begin & end cannot sleep */
1190void amdgpu_ring_free_size(struct amdgpu_ring *ring);
1191int amdgpu_ring_alloc(struct amdgpu_ring *ring, unsigned ndw); 1189int amdgpu_ring_alloc(struct amdgpu_ring *ring, unsigned ndw);
1192void amdgpu_ring_insert_nop(struct amdgpu_ring *ring, uint32_t count); 1190void amdgpu_ring_insert_nop(struct amdgpu_ring *ring, uint32_t count);
1193void amdgpu_ring_commit(struct amdgpu_ring *ring); 1191void 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
2169static inline struct amdgpu_sdma_instance * 2166static 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 @@
49static int amdgpu_debugfs_ring_init(struct amdgpu_device *adev, struct amdgpu_ring *ring); 49static 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 */
59void 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 */
83int amdgpu_ring_alloc(struct amdgpu_ring *ring, unsigned ndw) 61int 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;