aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c127
1 files changed, 62 insertions, 65 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c
index dc8a7bbedfea..5491696ac827 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c
@@ -28,6 +28,7 @@
28 */ 28 */
29#include <linux/seq_file.h> 29#include <linux/seq_file.h>
30#include <linux/slab.h> 30#include <linux/slab.h>
31#include <linux/debugfs.h>
31#include <drm/drmP.h> 32#include <drm/drmP.h>
32#include <drm/amdgpu_drm.h> 33#include <drm/amdgpu_drm.h>
33#include "amdgpu.h" 34#include "amdgpu.h"
@@ -368,57 +369,62 @@ void amdgpu_ring_fini(struct amdgpu_ring *ring)
368 */ 369 */
369#if defined(CONFIG_DEBUG_FS) 370#if defined(CONFIG_DEBUG_FS)
370 371
371static int amdgpu_debugfs_ring_info(struct seq_file *m, void *data) 372/* Layout of file is 12 bytes consisting of
373 * - rptr
374 * - wptr
375 * - driver's copy of wptr
376 *
377 * followed by n-words of ring data
378 */
379static ssize_t amdgpu_debugfs_ring_read(struct file *f, char __user *buf,
380 size_t size, loff_t *pos)
372{ 381{
373 struct drm_info_node *node = (struct drm_info_node *) m->private; 382 struct amdgpu_ring *ring = (struct amdgpu_ring*)f->f_inode->i_private;
374 struct drm_device *dev = node->minor->dev; 383 int r, i;
375 struct amdgpu_device *adev = dev->dev_private; 384 uint32_t value, result, early[3];
376 int roffset = (unsigned long)node->info_ent->data; 385
377 struct amdgpu_ring *ring = (void *)(((uint8_t*)adev) + roffset); 386 if (*pos & 3)
378 uint32_t rptr, wptr, rptr_next; 387 return -EINVAL;
379 unsigned i; 388
380 389 result = 0;
381 wptr = amdgpu_ring_get_wptr(ring); 390
382 seq_printf(m, "wptr: 0x%08x [%5d]\n", wptr, wptr); 391 if (*pos < 12) {
383 392 early[0] = amdgpu_ring_get_rptr(ring);
384 rptr = amdgpu_ring_get_rptr(ring); 393 early[1] = amdgpu_ring_get_wptr(ring);
385 rptr_next = le32_to_cpu(*ring->next_rptr_cpu_addr); 394 early[2] = ring->wptr;
386 395 for (i = *pos / 4; i < 3 && size; i++) {
387 seq_printf(m, "rptr: 0x%08x [%5d]\n", rptr, rptr); 396 r = put_user(early[i], (uint32_t *)buf);
388 397 if (r)
389 seq_printf(m, "driver's copy of the wptr: 0x%08x [%5d]\n", 398 return r;
390 ring->wptr, ring->wptr); 399 buf += 4;
391 400 result += 4;
392 if (!ring->ready) 401 size -= 4;
393 return 0; 402 *pos += 4;
394 403 }
395 /* print 8 dw before current rptr as often it's the last executed
396 * packet that is the root issue
397 */
398 i = (rptr + ring->ptr_mask + 1 - 32) & ring->ptr_mask;
399 while (i != rptr) {
400 seq_printf(m, "r[%5d]=0x%08x", i, ring->ring[i]);
401 if (i == rptr)
402 seq_puts(m, " *");
403 if (i == rptr_next)
404 seq_puts(m, " #");
405 seq_puts(m, "\n");
406 i = (i + 1) & ring->ptr_mask;
407 } 404 }
408 while (i != wptr) { 405
409 seq_printf(m, "r[%5d]=0x%08x", i, ring->ring[i]); 406 while (size) {
410 if (i == rptr) 407 if (*pos >= (ring->ring_size + 12))
411 seq_puts(m, " *"); 408 return result;
412 if (i == rptr_next) 409
413 seq_puts(m, " #"); 410 value = ring->ring[(*pos - 12)/4];
414 seq_puts(m, "\n"); 411 r = put_user(value, (uint32_t*)buf);
415 i = (i + 1) & ring->ptr_mask; 412 if (r)
413 return r;
414 buf += 4;
415 result += 4;
416 size -= 4;
417 *pos += 4;
416 } 418 }
417 return 0; 419
420 return result;
418} 421}
419 422
420static struct drm_info_list amdgpu_debugfs_ring_info_list[AMDGPU_MAX_RINGS]; 423static const struct file_operations amdgpu_debugfs_ring_fops = {
421static char amdgpu_debugfs_ring_names[AMDGPU_MAX_RINGS][32]; 424 .owner = THIS_MODULE,
425 .read = amdgpu_debugfs_ring_read,
426 .llseek = default_llseek
427};
422 428
423#endif 429#endif
424 430
@@ -426,28 +432,19 @@ static int amdgpu_debugfs_ring_init(struct amdgpu_device *adev,
426 struct amdgpu_ring *ring) 432 struct amdgpu_ring *ring)
427{ 433{
428#if defined(CONFIG_DEBUG_FS) 434#if defined(CONFIG_DEBUG_FS)
429 unsigned offset = (uint8_t*)ring - (uint8_t*)adev; 435 struct drm_minor *minor = adev->ddev->primary;
430 unsigned i; 436 struct dentry *ent, *root = minor->debugfs_root;
431 struct drm_info_list *info; 437 char name[32];
432 char *name;
433
434 for (i = 0; i < ARRAY_SIZE(amdgpu_debugfs_ring_info_list); ++i) {
435 info = &amdgpu_debugfs_ring_info_list[i];
436 if (!info->data)
437 break;
438 }
439 438
440 if (i == ARRAY_SIZE(amdgpu_debugfs_ring_info_list))
441 return -ENOSPC;
442
443 name = &amdgpu_debugfs_ring_names[i][0];
444 sprintf(name, "amdgpu_ring_%s", ring->name); 439 sprintf(name, "amdgpu_ring_%s", ring->name);
445 info->name = name;
446 info->show = amdgpu_debugfs_ring_info;
447 info->driver_features = 0;
448 info->data = (void*)(uintptr_t)offset;
449 440
450 return amdgpu_debugfs_add_files(adev, info, 1); 441 ent = debugfs_create_file(name,
442 S_IFREG | S_IRUGO, root,
443 ring, &amdgpu_debugfs_ring_fops);
444 if (IS_ERR(ent))
445 return PTR_ERR(ent);
446
447 i_size_write(ent->d_inode, ring->ring_size + 12);
451#endif 448#endif
452 return 0; 449 return 0;
453} 450}