linux/drivers/gpu/drm/msm/msm_debugfs.c
<<
>>
Prefs
   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
  14struct msm_gpu_show_priv {
  15        struct msm_gpu_state *state;
  16        struct drm_device *dev;
  17};
  18
  19static 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
  39static 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
  59static 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
  97free_priv:
  98        kfree(show_priv);
  99        return ret;
 100}
 101
 102static 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
 110static 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
 126static 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
 135static 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
 159static 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
 178static 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
 184static 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
 206int 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
 216int 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
 244