1 /* 2 * Copyright (C) 2013-2016 Red Hat 3 * Author: Rob Clark <robdclark@gmail.com> 4 * 5 * This program is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 as published by 7 * the Free Software Foundation. 8 * 9 * This program is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12 * more details. 13 * 14 * You should have received a copy of the GNU General Public License along with 15 * this program. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 18 #ifdef CONFIG_DEBUG_FS 19 #include "msm_drv.h" 20 #include "msm_gpu.h" 21 #include "msm_kms.h" 22 #include "msm_debugfs.h" 23 24 static int msm_gpu_show(struct drm_device *dev, struct seq_file *m) 25 { 26 struct msm_drm_private *priv = dev->dev_private; 27 struct msm_gpu *gpu = priv->gpu; 28 29 if (gpu) { 30 seq_printf(m, "%s Status:\n", gpu->name); 31 gpu->funcs->show(gpu, m); 32 } 33 34 return 0; 35 } 36 37 static int msm_gem_show(struct drm_device *dev, struct seq_file *m) 38 { 39 struct msm_drm_private *priv = dev->dev_private; 40 struct msm_gpu *gpu = priv->gpu; 41 42 if (gpu) { 43 seq_printf(m, "Active Objects (%s):\n", gpu->name); 44 msm_gem_describe_objects(&gpu->active_list, m); 45 } 46 47 seq_printf(m, "Inactive Objects:\n"); 48 msm_gem_describe_objects(&priv->inactive_list, m); 49 50 return 0; 51 } 52 53 static int msm_mm_show(struct drm_device *dev, struct seq_file *m) 54 { 55 return drm_mm_dump_table(m, &dev->vma_offset_manager->vm_addr_space_mm); 56 } 57 58 static int msm_fb_show(struct drm_device *dev, struct seq_file *m) 59 { 60 struct msm_drm_private *priv = dev->dev_private; 61 struct drm_framebuffer *fb, *fbdev_fb = NULL; 62 63 if (priv->fbdev) { 64 seq_printf(m, "fbcon "); 65 fbdev_fb = priv->fbdev->fb; 66 msm_framebuffer_describe(fbdev_fb, m); 67 } 68 69 mutex_lock(&dev->mode_config.fb_lock); 70 list_for_each_entry(fb, &dev->mode_config.fb_list, head) { 71 if (fb == fbdev_fb) 72 continue; 73 74 seq_printf(m, "user "); 75 msm_framebuffer_describe(fb, m); 76 } 77 mutex_unlock(&dev->mode_config.fb_lock); 78 79 return 0; 80 } 81 82 static int show_locked(struct seq_file *m, void *arg) 83 { 84 struct drm_info_node *node = (struct drm_info_node *) m->private; 85 struct drm_device *dev = node->minor->dev; 86 int (*show)(struct drm_device *dev, struct seq_file *m) = 87 node->info_ent->data; 88 int ret; 89 90 ret = mutex_lock_interruptible(&dev->struct_mutex); 91 if (ret) 92 return ret; 93 94 ret = show(dev, m); 95 96 mutex_unlock(&dev->struct_mutex); 97 98 return ret; 99 } 100 101 static struct drm_info_list msm_debugfs_list[] = { 102 {"gpu", show_locked, 0, msm_gpu_show}, 103 {"gem", show_locked, 0, msm_gem_show}, 104 { "mm", show_locked, 0, msm_mm_show }, 105 { "fb", show_locked, 0, msm_fb_show }, 106 }; 107 108 static int late_init_minor(struct drm_minor *minor) 109 { 110 int ret; 111 112 if (!minor) 113 return 0; 114 115 ret = msm_rd_debugfs_init(minor); 116 if (ret) { 117 dev_err(minor->dev->dev, "could not install rd debugfs\n"); 118 return ret; 119 } 120 121 ret = msm_perf_debugfs_init(minor); 122 if (ret) { 123 dev_err(minor->dev->dev, "could not install perf debugfs\n"); 124 return ret; 125 } 126 127 return 0; 128 } 129 130 int msm_debugfs_late_init(struct drm_device *dev) 131 { 132 int ret; 133 ret = late_init_minor(dev->primary); 134 if (ret) 135 return ret; 136 ret = late_init_minor(dev->render); 137 if (ret) 138 return ret; 139 ret = late_init_minor(dev->control); 140 return ret; 141 } 142 143 int msm_debugfs_init(struct drm_minor *minor) 144 { 145 struct drm_device *dev = minor->dev; 146 struct msm_drm_private *priv = dev->dev_private; 147 int ret; 148 149 ret = drm_debugfs_create_files(msm_debugfs_list, 150 ARRAY_SIZE(msm_debugfs_list), 151 minor->debugfs_root, minor); 152 153 if (ret) { 154 dev_err(dev->dev, "could not install msm_debugfs_list\n"); 155 return ret; 156 } 157 158 if (priv->kms->funcs->debugfs_init) 159 ret = priv->kms->funcs->debugfs_init(priv->kms, minor); 160 161 return ret; 162 } 163 164 void msm_debugfs_cleanup(struct drm_minor *minor) 165 { 166 struct drm_device *dev = minor->dev; 167 struct msm_drm_private *priv = dev->dev_private; 168 169 drm_debugfs_remove_files(msm_debugfs_list, 170 ARRAY_SIZE(msm_debugfs_list), minor); 171 if (!priv) 172 return; 173 174 if (priv->kms->funcs->debugfs_cleanup) 175 priv->kms->funcs->debugfs_cleanup(priv->kms, minor); 176 177 msm_rd_debugfs_cleanup(minor); 178 msm_perf_debugfs_cleanup(minor); 179 } 180 #endif 181 182