blob: 991570bbe644c952064b3b19ac9f7af47977be4b [file] [log] [blame]
Duy Truonge833aca2013-02-12 13:35:08 -08001/* Copyright (c) 2002,2008-2012, The Linux Foundation. All rights reserved.
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 */
13
Steve Mucklef132c6c2012-06-06 18:30:57 -070014#include <linux/module.h>
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070015#include <linux/debugfs.h>
16
17#include "kgsl.h"
18#include "kgsl_device.h"
Jeremy Gebbenddf93012012-09-25 10:57:38 -060019#include "kgsl_sharedmem.h"
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070020
21/*default log levels is error for everything*/
22#define KGSL_LOG_LEVEL_DEFAULT 3
23#define KGSL_LOG_LEVEL_MAX 7
24
25struct dentry *kgsl_debugfs_dir;
Harsh Vardhan Dwivedi715fb832012-05-18 00:24:18 -060026static struct dentry *pm_d_debugfs;
Jeremy Gebbenddf93012012-09-25 10:57:38 -060027struct dentry *proc_d_debugfs;
Harsh Vardhan Dwivedi715fb832012-05-18 00:24:18 -060028
29static int pm_dump_set(void *data, u64 val)
30{
31 struct kgsl_device *device = data;
32
33 if (val) {
34 mutex_lock(&device->mutex);
35 kgsl_postmortem_dump(device, 1);
36 mutex_unlock(&device->mutex);
37 }
38
39 return 0;
40}
41DEFINE_SIMPLE_ATTRIBUTE(pm_dump_fops,
42 NULL,
43 pm_dump_set, "%llu\n");
44
45static int pm_regs_enabled_set(void *data, u64 val)
46{
47 struct kgsl_device *device = data;
48 device->pm_regs_enabled = val ? 1 : 0;
49 return 0;
50}
51
52static int pm_regs_enabled_get(void *data, u64 *val)
53{
54 struct kgsl_device *device = data;
55 *val = device->pm_regs_enabled;
56 return 0;
57}
58
59static int pm_ib_enabled_set(void *data, u64 val)
60{
61 struct kgsl_device *device = data;
62 device->pm_ib_enabled = val ? 1 : 0;
63 return 0;
64}
65
66static int pm_ib_enabled_get(void *data, u64 *val)
67{
68 struct kgsl_device *device = data;
69 *val = device->pm_ib_enabled;
70 return 0;
71}
72
73
74DEFINE_SIMPLE_ATTRIBUTE(pm_regs_enabled_fops,
75 pm_regs_enabled_get,
76 pm_regs_enabled_set, "%llu\n");
77
78DEFINE_SIMPLE_ATTRIBUTE(pm_ib_enabled_fops,
79 pm_ib_enabled_get,
80 pm_ib_enabled_set, "%llu\n");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070081
82static inline int kgsl_log_set(unsigned int *log_val, void *data, u64 val)
83{
84 *log_val = min((unsigned int)val, (unsigned int)KGSL_LOG_LEVEL_MAX);
85 return 0;
86}
87
88#define KGSL_DEBUGFS_LOG(__log) \
89static int __log ## _set(void *data, u64 val) \
90{ \
91 struct kgsl_device *device = data; \
92 return kgsl_log_set(&device->__log, data, val); \
93} \
94static int __log ## _get(void *data, u64 *val) \
95{ \
96 struct kgsl_device *device = data; \
97 *val = device->__log; \
98 return 0; \
99} \
100DEFINE_SIMPLE_ATTRIBUTE(__log ## _fops, \
101__log ## _get, __log ## _set, "%llu\n"); \
102
103KGSL_DEBUGFS_LOG(drv_log);
104KGSL_DEBUGFS_LOG(cmd_log);
105KGSL_DEBUGFS_LOG(ctxt_log);
106KGSL_DEBUGFS_LOG(mem_log);
107KGSL_DEBUGFS_LOG(pwr_log);
Tarun Karrad20d71a2013-01-25 15:38:57 -0800108KGSL_DEBUGFS_LOG(ft_log);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700109
110void kgsl_device_debugfs_init(struct kgsl_device *device)
111{
112 if (kgsl_debugfs_dir && !IS_ERR(kgsl_debugfs_dir))
113 device->d_debugfs = debugfs_create_dir(device->name,
114 kgsl_debugfs_dir);
115
116 if (!device->d_debugfs || IS_ERR(device->d_debugfs))
117 return;
118
119 device->cmd_log = KGSL_LOG_LEVEL_DEFAULT;
120 device->ctxt_log = KGSL_LOG_LEVEL_DEFAULT;
121 device->drv_log = KGSL_LOG_LEVEL_DEFAULT;
122 device->mem_log = KGSL_LOG_LEVEL_DEFAULT;
123 device->pwr_log = KGSL_LOG_LEVEL_DEFAULT;
Tarun Karrad20d71a2013-01-25 15:38:57 -0800124 device->ft_log = KGSL_LOG_LEVEL_DEFAULT;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700125
126 debugfs_create_file("log_level_cmd", 0644, device->d_debugfs, device,
127 &cmd_log_fops);
128 debugfs_create_file("log_level_ctxt", 0644, device->d_debugfs, device,
129 &ctxt_log_fops);
130 debugfs_create_file("log_level_drv", 0644, device->d_debugfs, device,
131 &drv_log_fops);
132 debugfs_create_file("log_level_mem", 0644, device->d_debugfs, device,
133 &mem_log_fops);
134 debugfs_create_file("log_level_pwr", 0644, device->d_debugfs, device,
135 &pwr_log_fops);
Tarun Karrad20d71a2013-01-25 15:38:57 -0800136 debugfs_create_file("log_level_ft", 0644, device->d_debugfs, device,
137 &ft_log_fops);
Harsh Vardhan Dwivedi715fb832012-05-18 00:24:18 -0600138
139 /* Create postmortem dump control files */
140
141 pm_d_debugfs = debugfs_create_dir("postmortem", device->d_debugfs);
142
143 if (IS_ERR(pm_d_debugfs))
144 return;
145
146 debugfs_create_file("dump", 0600, pm_d_debugfs, device,
147 &pm_dump_fops);
148 debugfs_create_file("regs_enabled", 0644, pm_d_debugfs, device,
149 &pm_regs_enabled_fops);
150 debugfs_create_file("ib_enabled", 0644, pm_d_debugfs, device,
151 &pm_ib_enabled_fops);
152
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700153}
154
Jeremy Gebbenddf93012012-09-25 10:57:38 -0600155static const char * const memtype_strings[] = {
156 "gpumem",
157 "pmem",
158 "ashmem",
159 "usermap",
160 "ion",
161};
162
163static const char *memtype_str(int memtype)
164{
165 if (memtype < ARRAY_SIZE(memtype_strings))
166 return memtype_strings[memtype];
167 return "unknown";
168}
169
Jordan Crousedc67dfb2012-10-25 09:41:46 -0600170static char get_alignflag(const struct kgsl_memdesc *m)
171{
172 int align = kgsl_memdesc_get_align(m);
173 if (align >= ilog2(SZ_1M))
174 return 'L';
175 else if (align >= ilog2(SZ_64K))
176 return 'l';
177 return '-';
178}
179
Jeremy Gebbenddf93012012-09-25 10:57:38 -0600180static int process_mem_print(struct seq_file *s, void *unused)
181{
182 struct kgsl_mem_entry *entry;
183 struct rb_node *node;
184 struct kgsl_process_private *private = s->private;
Rajeev Kulkarni8dfdc3362012-11-22 00:22:32 -0800185 char flags[4];
Jeremy Gebbenddf93012012-09-25 10:57:38 -0600186 char usage[16];
187
188 spin_lock(&private->mem_lock);
189 seq_printf(s, "%8s %8s %5s %10s %16s %5s\n",
190 "gpuaddr", "size", "flags", "type", "usage", "sglen");
191 for (node = rb_first(&private->mem_rb); node; node = rb_next(node)) {
192 struct kgsl_memdesc *m;
193
194 entry = rb_entry(node, struct kgsl_mem_entry, node);
195 m = &entry->memdesc;
196
Jordan Crousedc67dfb2012-10-25 09:41:46 -0600197 flags[0] = m->priv & KGSL_MEMDESC_GLOBAL ? 'g' : '-';
198 flags[1] = m->flags & KGSL_MEMFLAGS_GPUREADONLY ? 'r' : '-';
199 flags[2] = get_alignflag(m);
Rajeev Kulkarni8dfdc3362012-11-22 00:22:32 -0800200 flags[3] = '\0';
Jeremy Gebbenddf93012012-09-25 10:57:38 -0600201
Jordan Crousedc67dfb2012-10-25 09:41:46 -0600202 kgsl_get_memory_usage(usage, sizeof(usage), m->flags);
Jeremy Gebbenddf93012012-09-25 10:57:38 -0600203
204 seq_printf(s, "%08x %8d %5s %10s %16s %5d\n",
205 m->gpuaddr, m->size, flags,
206 memtype_str(entry->memtype), usage, m->sglen);
207 }
208 spin_unlock(&private->mem_lock);
209 return 0;
210}
211
212static int process_mem_open(struct inode *inode, struct file *file)
213{
214 return single_open(file, process_mem_print, inode->i_private);
215}
216
217static const struct file_operations process_mem_fops = {
218 .open = process_mem_open,
219 .read = seq_read,
220 .llseek = seq_lseek,
221 .release = single_release,
222};
223
224void
225kgsl_process_init_debugfs(struct kgsl_process_private *private)
226{
227 unsigned char name[16];
228
229 snprintf(name, sizeof(name), "%d", private->pid);
230
231 private->debug_root = debugfs_create_dir(name, proc_d_debugfs);
232 debugfs_create_file("mem", 0400, private->debug_root, private,
233 &process_mem_fops);
234}
235
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700236void kgsl_core_debugfs_init(void)
237{
238 kgsl_debugfs_dir = debugfs_create_dir("kgsl", 0);
Jeremy Gebbenddf93012012-09-25 10:57:38 -0600239 proc_d_debugfs = debugfs_create_dir("proc", kgsl_debugfs_dir);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700240}
Jordan Croused8f1c6b2011-10-04 09:31:29 -0600241
242void kgsl_core_debugfs_close(void)
243{
244 debugfs_remove_recursive(kgsl_debugfs_dir);
245}