blob: b41bd6b4b9e323ea8260052b9fbbf90efa1cf80f [file] [log] [blame]
Flemmard9fc10142013-04-10 15:59:59 +02001/* Copyright (c) 2002,2008-2012, The Linux Foundation. All rights reserved.
Nicholas Flintham1e3d3112013-04-10 10:48:38 +01002 *
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
14#include <linux/module.h>
15#include <linux/debugfs.h>
16
17#include "kgsl.h"
18#include "kgsl_device.h"
Flemmard9fc10142013-04-10 15:59:59 +020019#include "kgsl_sharedmem.h"
Nicholas Flintham1e3d3112013-04-10 10:48:38 +010020
Flemmard9fc10142013-04-10 15:59:59 +020021/*default log levels is error for everything*/
Nicholas Flintham1e3d3112013-04-10 10:48:38 +010022#define KGSL_LOG_LEVEL_DEFAULT 3
23#define KGSL_LOG_LEVEL_MAX 7
24
25struct dentry *kgsl_debugfs_dir;
Flemmard9fc10142013-04-10 15:59:59 +020026static struct dentry *pm_d_debugfs;
27struct dentry *proc_d_debugfs;
28
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
73static int pm_enabled_set(void *data, u64 val)
74{
75 struct kgsl_device *device = data;
76 device->pm_dump_enable = val;
77 return 0;
78}
79
80static int pm_enabled_get(void *data, u64 *val)
81{
82 struct kgsl_device *device = data;
83 *val = device->pm_dump_enable;
84 return 0;
85}
86
87
88DEFINE_SIMPLE_ATTRIBUTE(pm_regs_enabled_fops,
89 pm_regs_enabled_get,
90 pm_regs_enabled_set, "%llu\n");
91
92DEFINE_SIMPLE_ATTRIBUTE(pm_ib_enabled_fops,
93 pm_ib_enabled_get,
94 pm_ib_enabled_set, "%llu\n");
95
96DEFINE_SIMPLE_ATTRIBUTE(pm_enabled_fops,
97 pm_enabled_get,
98 pm_enabled_set, "%llu\n");
Nicholas Flintham1e3d3112013-04-10 10:48:38 +010099
100static inline int kgsl_log_set(unsigned int *log_val, void *data, u64 val)
101{
102 *log_val = min((unsigned int)val, (unsigned int)KGSL_LOG_LEVEL_MAX);
103 return 0;
104}
105
106#define KGSL_DEBUGFS_LOG(__log) \
107static int __log ## _set(void *data, u64 val) \
108{ \
109 struct kgsl_device *device = data; \
110 return kgsl_log_set(&device->__log, data, val); \
111} \
112static int __log ## _get(void *data, u64 *val) \
113{ \
114 struct kgsl_device *device = data; \
115 *val = device->__log; \
116 return 0; \
117} \
118DEFINE_SIMPLE_ATTRIBUTE(__log ## _fops, \
119__log ## _get, __log ## _set, "%llu\n"); \
120
121KGSL_DEBUGFS_LOG(drv_log);
122KGSL_DEBUGFS_LOG(cmd_log);
123KGSL_DEBUGFS_LOG(ctxt_log);
124KGSL_DEBUGFS_LOG(mem_log);
125KGSL_DEBUGFS_LOG(pwr_log);
Flemmard9fc10142013-04-10 15:59:59 +0200126KGSL_DEBUGFS_LOG(ft_log);
Nicholas Flintham1e3d3112013-04-10 10:48:38 +0100127
128void kgsl_device_debugfs_init(struct kgsl_device *device)
129{
130 if (kgsl_debugfs_dir && !IS_ERR(kgsl_debugfs_dir))
131 device->d_debugfs = debugfs_create_dir(device->name,
132 kgsl_debugfs_dir);
133
134 if (!device->d_debugfs || IS_ERR(device->d_debugfs))
135 return;
136
137 device->cmd_log = KGSL_LOG_LEVEL_DEFAULT;
138 device->ctxt_log = KGSL_LOG_LEVEL_DEFAULT;
139 device->drv_log = KGSL_LOG_LEVEL_DEFAULT;
140 device->mem_log = KGSL_LOG_LEVEL_DEFAULT;
141 device->pwr_log = KGSL_LOG_LEVEL_DEFAULT;
Flemmard9fc10142013-04-10 15:59:59 +0200142 device->ft_log = KGSL_LOG_LEVEL_DEFAULT;
Nicholas Flintham1e3d3112013-04-10 10:48:38 +0100143
144 debugfs_create_file("log_level_cmd", 0644, device->d_debugfs, device,
145 &cmd_log_fops);
146 debugfs_create_file("log_level_ctxt", 0644, device->d_debugfs, device,
147 &ctxt_log_fops);
148 debugfs_create_file("log_level_drv", 0644, device->d_debugfs, device,
149 &drv_log_fops);
150 debugfs_create_file("log_level_mem", 0644, device->d_debugfs, device,
151 &mem_log_fops);
152 debugfs_create_file("log_level_pwr", 0644, device->d_debugfs, device,
153 &pwr_log_fops);
Flemmard9fc10142013-04-10 15:59:59 +0200154 debugfs_create_file("log_level_ft", 0644, device->d_debugfs, device,
155 &ft_log_fops);
156
157 /* Create postmortem dump control files */
158
159 pm_d_debugfs = debugfs_create_dir("postmortem", device->d_debugfs);
160
161 if (IS_ERR(pm_d_debugfs))
162 return;
163
164 debugfs_create_file("dump", 0600, pm_d_debugfs, device,
165 &pm_dump_fops);
166 debugfs_create_file("regs_enabled", 0644, pm_d_debugfs, device,
167 &pm_regs_enabled_fops);
168 debugfs_create_file("ib_enabled", 0644, pm_d_debugfs, device,
169 &pm_ib_enabled_fops);
170 device->pm_dump_enable = 0;
171 debugfs_create_file("enable", 0644, pm_d_debugfs, device,
172 &pm_enabled_fops);
173
174}
175
176static const char * const memtype_strings[] = {
177 "gpumem",
178 "pmem",
179 "ashmem",
180 "usermap",
181 "ion",
182};
183
184static const char *memtype_str(int memtype)
185{
186 if (memtype < ARRAY_SIZE(memtype_strings))
187 return memtype_strings[memtype];
188 return "unknown";
189}
190
191static char get_alignflag(const struct kgsl_memdesc *m)
192{
193 int align = kgsl_memdesc_get_align(m);
194 if (align >= ilog2(SZ_1M))
195 return 'L';
196 else if (align >= ilog2(SZ_64K))
197 return 'l';
198 return '-';
199}
200
201static int process_mem_print(struct seq_file *s, void *unused)
202{
203 struct kgsl_mem_entry *entry;
204 struct rb_node *node;
205 struct kgsl_process_private *private = s->private;
206 char flags[4];
207 char usage[16];
208
209 spin_lock(&private->mem_lock);
210 seq_printf(s, "%8s %8s %5s %10s %16s %5s\n",
211 "gpuaddr", "size", "flags", "type", "usage", "sglen");
212 for (node = rb_first(&private->mem_rb); node; node = rb_next(node)) {
213 struct kgsl_memdesc *m;
214
215 entry = rb_entry(node, struct kgsl_mem_entry, node);
216 m = &entry->memdesc;
217
218 flags[0] = m->priv & KGSL_MEMDESC_GLOBAL ? 'g' : '-';
219 flags[1] = m->flags & KGSL_MEMFLAGS_GPUREADONLY ? 'r' : '-';
220 flags[2] = get_alignflag(m);
221 flags[3] = '\0';
222
223 kgsl_get_memory_usage(usage, sizeof(usage), m->flags);
224
225 seq_printf(s, "%08x %8d %5s %10s %16s %5d\n",
226 m->gpuaddr, m->size, flags,
227 memtype_str(entry->memtype), usage, m->sglen);
228 }
229 spin_unlock(&private->mem_lock);
230 return 0;
231}
232
233static int process_mem_open(struct inode *inode, struct file *file)
234{
235 return single_open(file, process_mem_print, inode->i_private);
236}
237
238static const struct file_operations process_mem_fops = {
239 .open = process_mem_open,
240 .read = seq_read,
241 .llseek = seq_lseek,
242 .release = single_release,
243};
244
245void
246kgsl_process_init_debugfs(struct kgsl_process_private *private)
247{
248 unsigned char name[16];
249
250 snprintf(name, sizeof(name), "%d", private->pid);
251
252 private->debug_root = debugfs_create_dir(name, proc_d_debugfs);
253 debugfs_create_file("mem", 0400, private->debug_root, private,
254 &process_mem_fops);
Nicholas Flintham1e3d3112013-04-10 10:48:38 +0100255}
256
257void kgsl_core_debugfs_init(void)
258{
259 kgsl_debugfs_dir = debugfs_create_dir("kgsl", 0);
Flemmard9fc10142013-04-10 15:59:59 +0200260 proc_d_debugfs = debugfs_create_dir("proc", kgsl_debugfs_dir);
Nicholas Flintham1e3d3112013-04-10 10:48:38 +0100261}
262
263void kgsl_core_debugfs_close(void)
264{
265 debugfs_remove_recursive(kgsl_debugfs_dir);
266}