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 struct drm_printer p = drm_seq_file_printer(m); 56 57 drm_mm_print(&dev->vma_offset_manager->vm_addr_space_mm, &p); 58 59 return 0; 60 } 61 62 static int msm_fb_show(struct drm_device *dev, struct seq_file *m) 63 { 64 struct msm_drm_private *priv = dev->dev_private; 65 struct drm_framebuffer *fb, *fbdev_fb = NULL; 66 67 if (priv->fbdev) { 68 seq_printf(m, "fbcon "); 69 fbdev_fb = priv->fbdev->fb; 70 msm_framebuffer_describe(fbdev_fb, m); 71 } 72 73 mutex_lock(&dev->mode_config.fb_lock); 74 list_for_each_entry(fb, &dev->mode_config.fb_list, head) { 75 if (fb == fbdev_fb) 76 continue; 77 78 seq_printf(m, "user "); 79 msm_framebuffer_describe(fb, m); 80 } 81 mutex_unlock(&dev->mode_config.fb_lock); 82 83 return 0; 84 } 85 86 static int show_locked(struct seq_file *m, void *arg) 87 { 88 struct drm_info_node *node = (struct drm_info_node *) m->private; 89 struct drm_device *dev = node->minor->dev; 90 int (*show)(struct drm_device *dev, struct seq_file *m) = 91 node->info_ent->data; 92 int ret; 93 94 ret = mutex_lock_interruptible(&dev->struct_mutex); 95 if (ret) 96 return ret; 97 98 ret = show(dev, m); 99 100 mutex_unlock(&dev->struct_mutex); 101 102 return ret; 103 } 104 105 static struct drm_info_list msm_debugfs_list[] = { 106 {"gpu", show_locked, 0, msm_gpu_show}, 107 {"gem", show_locked, 0, msm_gem_show}, 108 { "mm", show_locked, 0, msm_mm_show }, 109 { "fb", show_locked, 0, msm_fb_show }, 110 }; 111 112 static int late_init_minor(struct drm_minor *minor) 113 { 114 int ret; 115 116 if (!minor) 117 return 0; 118 119 ret = msm_rd_debugfs_init(minor); 120 if (ret) { 121 dev_err(minor->dev->dev, "could not install rd debugfs\n"); 122 return ret; 123 } 124 125 ret = msm_perf_debugfs_init(minor); 126 if (ret) { 127 dev_err(minor->dev->dev, "could not install perf debugfs\n"); 128 return ret; 129 } 130 131 return 0; 132 } 133 134 int msm_debugfs_late_init(struct drm_device *dev) 135 { 136 int ret; 137 ret = late_init_minor(dev->primary); 138 if (ret) 139 return ret; 140 ret = late_init_minor(dev->render); 141 if (ret) 142 return ret; 143 ret = late_init_minor(dev->control); 144 return ret; 145 } 146 147 int msm_debugfs_init(struct drm_minor *minor) 148 { 149 struct drm_device *dev = minor->dev; 150 struct msm_drm_private *priv = dev->dev_private; 151 int ret; 152 153 ret = drm_debugfs_create_files(msm_debugfs_list, 154 ARRAY_SIZE(msm_debugfs_list), 155 minor->debugfs_root, minor); 156 157 if (ret) { 158 dev_err(dev->dev, "could not install msm_debugfs_list\n"); 159 return ret; 160 } 161 162 if (priv->kms->funcs->debugfs_init) 163 ret = priv->kms->funcs->debugfs_init(priv->kms, minor); 164 165 return ret; 166 } 167 168 void msm_debugfs_cleanup(struct drm_minor *minor) 169 { 170 struct drm_device *dev = minor->dev; 171 struct msm_drm_private *priv = dev->dev_private; 172 173 drm_debugfs_remove_files(msm_debugfs_list, 174 ARRAY_SIZE(msm_debugfs_list), minor); 175 if (!priv) 176 return; 177 178 if (priv->kms->funcs->debugfs_cleanup) 179 priv->kms->funcs->debugfs_cleanup(priv->kms, minor); 180 181 msm_rd_debugfs_cleanup(minor); 182 msm_perf_debugfs_cleanup(minor); 183 } 184 #endif 185 186