]> Git Repo - linux.git/blob - drivers/gpu/drm/msm/msm_debugfs.c
Merge tag 'drm-misc-fixes-2022-08-16' of git://anongit.freedesktop.org/drm/drm-misc...
[linux.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 <[email protected]>
5  */
6
7 #ifdef CONFIG_DEBUG_FS
8
9 #include <linux/debugfs.h>
10
11 #include <drm/drm_debugfs.h>
12 #include <drm/drm_file.h>
13 #include <drm/drm_framebuffer.h>
14
15 #include "msm_drv.h"
16 #include "msm_gpu.h"
17 #include "msm_kms.h"
18 #include "msm_debugfs.h"
19 #include "disp/msm_disp_snapshot.h"
20
21 /*
22  * GPU Snapshot:
23  */
24
25 struct msm_gpu_show_priv {
26         struct msm_gpu_state *state;
27         struct drm_device *dev;
28 };
29
30 static int msm_gpu_show(struct seq_file *m, void *arg)
31 {
32         struct drm_printer p = drm_seq_file_printer(m);
33         struct msm_gpu_show_priv *show_priv = m->private;
34         struct msm_drm_private *priv = show_priv->dev->dev_private;
35         struct msm_gpu *gpu = priv->gpu;
36         int ret;
37
38         ret = mutex_lock_interruptible(&gpu->lock);
39         if (ret)
40                 return ret;
41
42         drm_printf(&p, "%s Status:\n", gpu->name);
43         gpu->funcs->show(gpu, show_priv->state, &p);
44
45         mutex_unlock(&gpu->lock);
46
47         return 0;
48 }
49
50 static int msm_gpu_release(struct inode *inode, struct file *file)
51 {
52         struct seq_file *m = file->private_data;
53         struct msm_gpu_show_priv *show_priv = m->private;
54         struct msm_drm_private *priv = show_priv->dev->dev_private;
55         struct msm_gpu *gpu = priv->gpu;
56
57         mutex_lock(&gpu->lock);
58         gpu->funcs->gpu_state_put(show_priv->state);
59         mutex_unlock(&gpu->lock);
60
61         kfree(show_priv);
62
63         return single_release(inode, file);
64 }
65
66 static int msm_gpu_open(struct inode *inode, struct file *file)
67 {
68         struct drm_device *dev = inode->i_private;
69         struct msm_drm_private *priv = dev->dev_private;
70         struct msm_gpu *gpu = priv->gpu;
71         struct msm_gpu_show_priv *show_priv;
72         int ret;
73
74         if (!gpu || !gpu->funcs->gpu_state_get)
75                 return -ENODEV;
76
77         show_priv = kmalloc(sizeof(*show_priv), GFP_KERNEL);
78         if (!show_priv)
79                 return -ENOMEM;
80
81         ret = mutex_lock_interruptible(&gpu->lock);
82         if (ret)
83                 goto free_priv;
84
85         pm_runtime_get_sync(&gpu->pdev->dev);
86         msm_gpu_hw_init(gpu);
87         show_priv->state = gpu->funcs->gpu_state_get(gpu);
88         pm_runtime_put_sync(&gpu->pdev->dev);
89
90         mutex_unlock(&gpu->lock);
91
92         if (IS_ERR(show_priv->state)) {
93                 ret = PTR_ERR(show_priv->state);
94                 goto free_priv;
95         }
96
97         show_priv->dev = dev;
98
99         ret = single_open(file, msm_gpu_show, show_priv);
100         if (ret)
101                 goto free_priv;
102
103         return 0;
104
105 free_priv:
106         kfree(show_priv);
107         return ret;
108 }
109
110 static const struct file_operations msm_gpu_fops = {
111         .owner = THIS_MODULE,
112         .open = msm_gpu_open,
113         .read = seq_read,
114         .llseek = seq_lseek,
115         .release = msm_gpu_release,
116 };
117
118 /*
119  * Display Snapshot:
120  */
121
122 static int msm_kms_show(struct seq_file *m, void *arg)
123 {
124         struct drm_printer p = drm_seq_file_printer(m);
125         struct msm_disp_state *state = m->private;
126
127         msm_disp_state_print(state, &p);
128
129         return 0;
130 }
131
132 static int msm_kms_release(struct inode *inode, struct file *file)
133 {
134         struct seq_file *m = file->private_data;
135         struct msm_disp_state *state = m->private;
136
137         msm_disp_state_free(state);
138
139         return single_release(inode, file);
140 }
141
142 static int msm_kms_open(struct inode *inode, struct file *file)
143 {
144         struct drm_device *dev = inode->i_private;
145         struct msm_drm_private *priv = dev->dev_private;
146         struct msm_disp_state *state;
147         int ret;
148
149         if (!priv->kms)
150                 return -ENODEV;
151
152         ret = mutex_lock_interruptible(&priv->kms->dump_mutex);
153         if (ret)
154                 return ret;
155
156         state = msm_disp_snapshot_state_sync(priv->kms);
157
158         mutex_unlock(&priv->kms->dump_mutex);
159
160         if (IS_ERR(state)) {
161                 return PTR_ERR(state);
162         }
163
164         ret = single_open(file, msm_kms_show, state);
165         if (ret) {
166                 msm_disp_state_free(state);
167                 return ret;
168         }
169
170         return 0;
171 }
172
173 static const struct file_operations msm_kms_fops = {
174         .owner = THIS_MODULE,
175         .open = msm_kms_open,
176         .read = seq_read,
177         .llseek = seq_lseek,
178         .release = msm_kms_release,
179 };
180
181 /*
182  * Other debugfs:
183  */
184
185 static unsigned long last_shrink_freed;
186
187 static int
188 shrink_get(void *data, u64 *val)
189 {
190         *val = last_shrink_freed;
191
192         return 0;
193 }
194
195 static int
196 shrink_set(void *data, u64 val)
197 {
198         struct drm_device *dev = data;
199
200         last_shrink_freed = msm_gem_shrinker_shrink(dev, val);
201
202         return 0;
203 }
204
205 DEFINE_DEBUGFS_ATTRIBUTE(shrink_fops,
206                          shrink_get, shrink_set,
207                          "0x%08llx\n");
208
209
210 static int msm_gem_show(struct seq_file *m, void *arg)
211 {
212         struct drm_info_node *node = (struct drm_info_node *) m->private;
213         struct drm_device *dev = node->minor->dev;
214         struct msm_drm_private *priv = dev->dev_private;
215         int ret;
216
217         ret = mutex_lock_interruptible(&priv->obj_lock);
218         if (ret)
219                 return ret;
220
221         msm_gem_describe_objects(&priv->objects, m);
222
223         mutex_unlock(&priv->obj_lock);
224
225         return 0;
226 }
227
228 static int msm_mm_show(struct seq_file *m, void *arg)
229 {
230         struct drm_info_node *node = (struct drm_info_node *) m->private;
231         struct drm_device *dev = node->minor->dev;
232         struct drm_printer p = drm_seq_file_printer(m);
233
234         drm_mm_print(&dev->vma_offset_manager->vm_addr_space_mm, &p);
235
236         return 0;
237 }
238
239 static int msm_fb_show(struct seq_file *m, void *arg)
240 {
241         struct drm_info_node *node = (struct drm_info_node *) m->private;
242         struct drm_device *dev = node->minor->dev;
243         struct msm_drm_private *priv = dev->dev_private;
244         struct drm_framebuffer *fb, *fbdev_fb = NULL;
245
246         if (priv->fbdev) {
247                 seq_printf(m, "fbcon ");
248                 fbdev_fb = priv->fbdev->fb;
249                 msm_framebuffer_describe(fbdev_fb, m);
250         }
251
252         mutex_lock(&dev->mode_config.fb_lock);
253         list_for_each_entry(fb, &dev->mode_config.fb_list, head) {
254                 if (fb == fbdev_fb)
255                         continue;
256
257                 seq_printf(m, "user ");
258                 msm_framebuffer_describe(fb, m);
259         }
260         mutex_unlock(&dev->mode_config.fb_lock);
261
262         return 0;
263 }
264
265 static struct drm_info_list msm_debugfs_list[] = {
266                 {"gem", msm_gem_show},
267                 { "mm", msm_mm_show },
268                 { "fb", msm_fb_show },
269 };
270
271 static int late_init_minor(struct drm_minor *minor)
272 {
273         int ret;
274
275         if (!minor)
276                 return 0;
277
278         ret = msm_rd_debugfs_init(minor);
279         if (ret) {
280                 DRM_DEV_ERROR(minor->dev->dev, "could not install rd debugfs\n");
281                 return ret;
282         }
283
284         ret = msm_perf_debugfs_init(minor);
285         if (ret) {
286                 DRM_DEV_ERROR(minor->dev->dev, "could not install perf debugfs\n");
287                 return ret;
288         }
289
290         return 0;
291 }
292
293 int msm_debugfs_late_init(struct drm_device *dev)
294 {
295         int ret;
296         ret = late_init_minor(dev->primary);
297         if (ret)
298                 return ret;
299         ret = late_init_minor(dev->render);
300         return ret;
301 }
302
303 void msm_debugfs_init(struct drm_minor *minor)
304 {
305         struct drm_device *dev = minor->dev;
306         struct msm_drm_private *priv = dev->dev_private;
307
308         drm_debugfs_create_files(msm_debugfs_list,
309                                  ARRAY_SIZE(msm_debugfs_list),
310                                  minor->debugfs_root, minor);
311
312         debugfs_create_file("gpu", S_IRUSR, minor->debugfs_root,
313                 dev, &msm_gpu_fops);
314
315         debugfs_create_file("kms", S_IRUSR, minor->debugfs_root,
316                 dev, &msm_kms_fops);
317
318         debugfs_create_u32("hangcheck_period_ms", 0600, minor->debugfs_root,
319                 &priv->hangcheck_period);
320
321         debugfs_create_bool("disable_err_irq", 0600, minor->debugfs_root,
322                 &priv->disable_err_irq);
323
324         debugfs_create_file("shrink", S_IRWXU, minor->debugfs_root,
325                 dev, &shrink_fops);
326
327         if (priv->kms && priv->kms->funcs->debugfs_init)
328                 priv->kms->funcs->debugfs_init(priv->kms, minor);
329 }
330 #endif
331
This page took 0.049288 seconds and 4 git commands to generate.