drm/exynos: add debugfs interface and gem_info node
[platform/kernel/linux-exynos.git] / drivers / gpu / drm / exynos / exynos_drm_debugfs.c
1 /*
2  * Copyright (c) 2014 Samsung Electronics Co., Ltd
3  * Author: YoungJun Cho <yj44.cho@samsung.com>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation.
8 */
9
10 #include <drm/drmP.h>
11
12 #include <linux/debugfs.h>
13
14 #include "exynos_drm_drv.h"
15 #include "exynos_drm_gem.h"
16
17 struct exynos_drm_debugfs_gem_info_data {
18         struct drm_file *filp;
19         struct seq_file *m;
20 };
21
22 static int exynos_drm_debugfs_gem_one_info(int id, void *ptr, void *data)
23 {
24         struct exynos_drm_debugfs_gem_info_data *gem_info_data =
25                                 (struct exynos_drm_debugfs_gem_info_data *)data;
26         struct drm_file *filp = gem_info_data->filp;
27         struct drm_exynos_file_private *file_priv = filp->driver_priv;
28         struct drm_gem_object *obj = (struct drm_gem_object *)ptr;
29         struct exynos_drm_gem *exynos_gem = to_exynos_gem(obj);
30
31         seq_printf(gem_info_data->m,
32                         "%5d\t%5d\t%4d\t%4d\t%4d\t0x%08lx\t0x%x\t%4d\t%4d\t"
33                         "%4d\t0x%p\n",
34                                 pid_nr(filp->pid),
35                                 file_priv->tgid,
36                                 id,
37                                 kref_read(&obj->refcount),
38                                 obj->handle_count,
39                                 exynos_gem->size,
40                                 exynos_gem->flags,
41                                 0,
42                                 obj->dma_buf ? 1 : 0,
43                                 obj->import_attach ? 1 : 0,
44                                 obj);
45
46         return 0;
47 }
48
49 static int exynos_drm_debugfs_gem_info(struct seq_file *m, void *data)
50 {
51         struct drm_info_node *node = (struct drm_info_node *)m->private;
52         struct drm_minor *minor = node->minor;
53         struct drm_device *drm_dev = minor->dev;
54         struct exynos_drm_debugfs_gem_info_data gem_info_data;
55         struct drm_file *filp;
56
57         gem_info_data.m = m;
58
59         seq_puts(m, "pid\ttgid\thandle\tref_cnt\thdl_cnt\tsize\t\tflags\t"
60                         "pfnmap\texport\timport\tobj_addr\n");
61
62         mutex_lock(&drm_dev->struct_mutex);
63         list_for_each_entry(filp, &drm_dev->filelist, lhead) {
64                 gem_info_data.filp = filp;
65
66                 spin_lock(&filp->table_lock);
67                 idr_for_each(&filp->object_idr, exynos_drm_debugfs_gem_one_info,
68                                 &gem_info_data);
69                 spin_unlock(&filp->table_lock);
70         }
71         mutex_unlock(&drm_dev->struct_mutex);
72
73         return 0;
74 }
75
76 static struct drm_info_list exynos_drm_debugfs_list[] = {
77         {"gem_info",    exynos_drm_debugfs_gem_info,    DRIVER_GEM},
78 };
79 #define EXYNOS_DRM_DEBUGFS_ENTRIES      ARRAY_SIZE(exynos_drm_debugfs_list)
80
81 int exynos_drm_debugfs_init(struct drm_minor *minor)
82 {
83         return drm_debugfs_create_files(exynos_drm_debugfs_list,
84                                         EXYNOS_DRM_DEBUGFS_ENTRIES,
85                                         minor->debugfs_root, minor);
86 }