Linux-libre 5.3.12-gnu
[librecmc/linux-libre.git] / drivers / gpu / drm / msm / msm_debugfs.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (C) 2013-2016 Red Hat
4  * Author: Rob Clark <robdclark@gmail.com>
5  */
6
7 #ifdef CONFIG_DEBUG_FS
8 #include <linux/debugfs.h>
9 #include "msm_drv.h"
10 #include "msm_gpu.h"
11 #include "msm_kms.h"
12 #include "msm_debugfs.h"
13
14 struct msm_gpu_show_priv {
15         struct msm_gpu_state *state;
16         struct drm_device *dev;
17 };
18
19 static int msm_gpu_show(struct seq_file *m, void *arg)
20 {
21         struct drm_printer p = drm_seq_file_printer(m);
22         struct msm_gpu_show_priv *show_priv = m->private;
23         struct msm_drm_private *priv = show_priv->dev->dev_private;
24         struct msm_gpu *gpu = priv->gpu;
25         int ret;
26
27         ret = mutex_lock_interruptible(&show_priv->dev->struct_mutex);
28         if (ret)
29                 return ret;
30
31         drm_printf(&p, "%s Status:\n", gpu->name);
32         gpu->funcs->show(gpu, show_priv->state, &p);
33
34         mutex_unlock(&show_priv->dev->struct_mutex);
35
36         return 0;
37 }
38
39 static int msm_gpu_release(struct inode *inode, struct file *file)
40 {
41         struct seq_file *m = file->private_data;
42         struct msm_gpu_show_priv *show_priv = m->private;
43         struct msm_drm_private *priv = show_priv->dev->dev_private;
44         struct msm_gpu *gpu = priv->gpu;
45         int ret;
46
47         ret = mutex_lock_interruptible(&show_priv->dev->struct_mutex);
48         if (ret)
49                 return ret;
50
51         gpu->funcs->gpu_state_put(show_priv->state);
52         mutex_unlock(&show_priv->dev->struct_mutex);
53
54         kfree(show_priv);
55
56         return single_release(inode, file);
57 }
58
59 static int msm_gpu_open(struct inode *inode, struct file *file)
60 {
61         struct drm_device *dev = inode->i_private;
62         struct msm_drm_private *priv = dev->dev_private;
63         struct msm_gpu *gpu = priv->gpu;
64         struct msm_gpu_show_priv *show_priv;
65         int ret;
66
67         if (!gpu || !gpu->funcs->gpu_state_get)
68                 return -ENODEV;
69
70         show_priv = kmalloc(sizeof(*show_priv), GFP_KERNEL);
71         if (!show_priv)
72                 return -ENOMEM;
73
74         ret = mutex_lock_interruptible(&dev->struct_mutex);
75         if (ret)
76                 goto free_priv;
77
78         pm_runtime_get_sync(&gpu->pdev->dev);
79         show_priv->state = gpu->funcs->gpu_state_get(gpu);
80         pm_runtime_put_sync(&gpu->pdev->dev);
81
82         mutex_unlock(&dev->struct_mutex);
83
84         if (IS_ERR(show_priv->state)) {
85                 ret = PTR_ERR(show_priv->state);
86                 goto free_priv;
87         }
88
89         show_priv->dev = dev;
90
91         ret = single_open(file, msm_gpu_show, show_priv);
92         if (ret)
93                 goto free_priv;
94
95         return 0;
96
97 free_priv:
98         kfree(show_priv);
99         return ret;
100 }
101
102 static const struct file_operations msm_gpu_fops = {
103         .owner = THIS_MODULE,
104         .open = msm_gpu_open,
105         .read = seq_read,
106         .llseek = seq_lseek,
107         .release = msm_gpu_release,
108 };
109
110 static int msm_gem_show(struct drm_device *dev, struct seq_file *m)
111 {
112         struct msm_drm_private *priv = dev->dev_private;
113         struct msm_gpu *gpu = priv->gpu;
114
115         if (gpu) {
116                 seq_printf(m, "Active Objects (%s):\n", gpu->name);
117                 msm_gem_describe_objects(&gpu->active_list, m);
118         }
119
120         seq_printf(m, "Inactive Objects:\n");
121         msm_gem_describe_objects(&priv->inactive_list, m);
122
123         return 0;
124 }
125
126 static int msm_mm_show(struct drm_device *dev, struct seq_file *m)
127 {
128         struct drm_printer p = drm_seq_file_printer(m);
129
130         drm_mm_print(&dev->vma_offset_manager->vm_addr_space_mm, &p);
131
132         return 0;
133 }
134
135 static int msm_fb_show(struct drm_device *dev, struct seq_file *m)
136 {
137         struct msm_drm_private *priv = dev->dev_private;
138         struct drm_framebuffer *fb, *fbdev_fb = NULL;
139
140         if (priv->fbdev) {
141                 seq_printf(m, "fbcon ");
142                 fbdev_fb = priv->fbdev->fb;
143                 msm_framebuffer_describe(fbdev_fb, m);
144         }
145
146         mutex_lock(&dev->mode_config.fb_lock);
147         list_for_each_entry(fb, &dev->mode_config.fb_list, head) {
148                 if (fb == fbdev_fb)
149                         continue;
150
151                 seq_printf(m, "user ");
152                 msm_framebuffer_describe(fb, m);
153         }
154         mutex_unlock(&dev->mode_config.fb_lock);
155
156         return 0;
157 }
158
159 static int show_locked(struct seq_file *m, void *arg)
160 {
161         struct drm_info_node *node = (struct drm_info_node *) m->private;
162         struct drm_device *dev = node->minor->dev;
163         int (*show)(struct drm_device *dev, struct seq_file *m) =
164                         node->info_ent->data;
165         int ret;
166
167         ret = mutex_lock_interruptible(&dev->struct_mutex);
168         if (ret)
169                 return ret;
170
171         ret = show(dev, m);
172
173         mutex_unlock(&dev->struct_mutex);
174
175         return ret;
176 }
177
178 static struct drm_info_list msm_debugfs_list[] = {
179                 {"gem", show_locked, 0, msm_gem_show},
180                 { "mm", show_locked, 0, msm_mm_show },
181                 { "fb", show_locked, 0, msm_fb_show },
182 };
183
184 static int late_init_minor(struct drm_minor *minor)
185 {
186         int ret;
187
188         if (!minor)
189                 return 0;
190
191         ret = msm_rd_debugfs_init(minor);
192         if (ret) {
193                 DRM_DEV_ERROR(minor->dev->dev, "could not install rd debugfs\n");
194                 return ret;
195         }
196
197         ret = msm_perf_debugfs_init(minor);
198         if (ret) {
199                 DRM_DEV_ERROR(minor->dev->dev, "could not install perf debugfs\n");
200                 return ret;
201         }
202
203         return 0;
204 }
205
206 int msm_debugfs_late_init(struct drm_device *dev)
207 {
208         int ret;
209         ret = late_init_minor(dev->primary);
210         if (ret)
211                 return ret;
212         ret = late_init_minor(dev->render);
213         return ret;
214 }
215
216 int msm_debugfs_init(struct drm_minor *minor)
217 {
218         struct drm_device *dev = minor->dev;
219         struct msm_drm_private *priv = dev->dev_private;
220         int ret;
221
222         ret = drm_debugfs_create_files(msm_debugfs_list,
223                         ARRAY_SIZE(msm_debugfs_list),
224                         minor->debugfs_root, minor);
225
226         if (ret) {
227                 DRM_DEV_ERROR(dev->dev, "could not install msm_debugfs_list\n");
228                 return ret;
229         }
230
231         debugfs_create_file("gpu", S_IRUSR, minor->debugfs_root,
232                 dev, &msm_gpu_fops);
233
234         if (priv->kms && priv->kms->funcs->debugfs_init) {
235                 ret = priv->kms->funcs->debugfs_init(priv->kms, minor);
236                 if (ret)
237                         return ret;
238         }
239
240         return ret;
241 }
242 #endif
243