video: tegra: host: Move debugfs inits
[linux-3.10.git] / drivers / video / tegra / host / debug.c
1 /*
2  * drivers/video/tegra/host/debug.c
3  *
4  * Copyright (C) 2010 Google, Inc.
5  * Author: Erik Gilling <konkers@android.com>
6  *
7  * Copyright (C) 2011-2013 NVIDIA Corporation
8  *
9  * This software is licensed under the terms of the GNU General Public
10  * License version 2, as published by the Free Software Foundation, and
11  * may be copied, distributed, and modified under those terms.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  */
19
20 #include <linux/debugfs.h>
21 #include <linux/seq_file.h>
22 #include <linux/uaccess.h>
23
24 #include <linux/io.h>
25
26 #include "dev.h"
27 #include "debug.h"
28 #include "nvhost_acm.h"
29 #include "nvhost_channel.h"
30 #include "chip_support.h"
31
32 pid_t nvhost_debug_null_kickoff_pid;
33 unsigned int nvhost_debug_trace_cmdbuf;
34
35 pid_t nvhost_debug_force_timeout_pid;
36 u32 nvhost_debug_force_timeout_val;
37 u32 nvhost_debug_force_timeout_channel;
38 u32 nvhost_debug_force_timeout_dump;
39
40 void nvhost_debug_output(struct output *o, const char* fmt, ...)
41 {
42         va_list args;
43         int len;
44
45         va_start(args, fmt);
46         len = vsnprintf(o->buf, sizeof(o->buf), fmt, args);
47         va_end(args);
48         o->fn(o->ctx, o->buf, len);
49 }
50
51 static int show_channels(struct platform_device *pdev, void *data)
52 {
53         struct nvhost_channel *ch;
54         struct output *o = data;
55         struct nvhost_master *m;
56         struct nvhost_device_data *pdata;
57
58         if (pdev == NULL)
59                 return 0;
60
61         pdata = platform_get_drvdata(pdev);
62         m = nvhost_get_host(pdev);
63         ch = pdata->channel;
64         if (ch) {
65                 int locked = mutex_trylock(&ch->reflock);
66                 if (ch->refcount) {
67                         mutex_lock(&ch->cdma.lock);
68                         nvhost_get_chip_ops()->debug.show_channel_fifo(
69                                 m, ch, o, pdata->index);
70                         nvhost_get_chip_ops()->debug.show_channel_cdma(
71                                 m, ch, o, pdata->index);
72                         mutex_unlock(&ch->cdma.lock);
73                 }
74                 if (locked)
75                         mutex_unlock(&ch->reflock);
76         }
77
78         return 0;
79 }
80
81 static void show_syncpts(struct nvhost_master *m, struct output *o)
82 {
83         int i;
84         nvhost_debug_output(o, "---- syncpts ----\n");
85         for (i = 0; i < nvhost_syncpt_nb_pts(&m->syncpt); i++) {
86                 u32 max = nvhost_syncpt_read_max(&m->syncpt, i);
87                 u32 min = nvhost_syncpt_update_min(&m->syncpt, i);
88                 if (!min && !max)
89                         continue;
90                 nvhost_debug_output(o, "id %d (%s) min %d max %d\n",
91                                 i, nvhost_get_chip_ops()->syncpt.name(&m->syncpt, i),
92                                 min, max);
93         }
94
95         for (i = 0; i < nvhost_syncpt_nb_bases(&m->syncpt); i++) {
96                 u32 base_val;
97                 base_val = nvhost_syncpt_read_wait_base(&m->syncpt, i);
98                 if (base_val)
99                         nvhost_debug_output(o, "waitbase id %d val %d\n",
100                                         i, base_val);
101         }
102
103         nvhost_debug_output(o, "\n");
104 }
105
106 static void show_all(struct nvhost_master *m, struct output *o)
107 {
108         nvhost_module_busy(m->dev);
109
110         nvhost_get_chip_ops()->debug.show_mlocks(m, o);
111         show_syncpts(m, o);
112         nvhost_debug_output(o, "---- channels ----\n");
113         nvhost_device_list_for_all(o, show_channels);
114
115         nvhost_module_idle(m->dev);
116 }
117
118 #ifdef CONFIG_DEBUG_FS
119 static int show_channels_no_fifo(struct platform_device *pdev, void *data)
120 {
121         struct nvhost_channel *ch;
122         struct output *o = data;
123         struct nvhost_master *m;
124         struct nvhost_device_data *pdata;
125
126         if (pdev == NULL)
127                 return 0;
128
129         pdata = platform_get_drvdata(pdev);
130         m = nvhost_get_host(pdev);
131         ch = pdata->channel;
132         if (ch) {
133                 mutex_lock(&ch->reflock);
134                 if (ch->refcount) {
135                         mutex_lock(&ch->cdma.lock);
136                         nvhost_get_chip_ops()->debug.show_channel_cdma(m,
137                                         ch, o, pdata->index);
138                         mutex_unlock(&ch->cdma.lock);
139                 }
140                 mutex_unlock(&ch->reflock);
141         }
142
143         return 0;
144 }
145
146 static void show_all_no_fifo(struct nvhost_master *m, struct output *o)
147 {
148         nvhost_module_busy(m->dev);
149
150         nvhost_get_chip_ops()->debug.show_mlocks(m, o);
151         show_syncpts(m, o);
152         nvhost_debug_output(o, "---- channels ----\n");
153         nvhost_device_list_for_all(o, show_channels_no_fifo);
154
155         nvhost_module_idle(m->dev);
156 }
157
158 static int nvhost_debug_show_all(struct seq_file *s, void *unused)
159 {
160         struct output o = {
161                 .fn = write_to_seqfile,
162                 .ctx = s
163         };
164         show_all(s->private, &o);
165         return 0;
166 }
167
168 static int nvhost_debug_show(struct seq_file *s, void *unused)
169 {
170         struct output o = {
171                 .fn = write_to_seqfile,
172                 .ctx = s
173         };
174         show_all_no_fifo(s->private, &o);
175         return 0;
176 }
177
178 static int nvhost_debug_open_all(struct inode *inode, struct file *file)
179 {
180         return single_open(file, nvhost_debug_show_all, inode->i_private);
181 }
182
183 static const struct file_operations nvhost_debug_all_fops = {
184         .open           = nvhost_debug_open_all,
185         .read           = seq_read,
186         .llseek         = seq_lseek,
187         .release        = single_release,
188 };
189
190 static int nvhost_debug_open(struct inode *inode, struct file *file)
191 {
192         return single_open(file, nvhost_debug_show, inode->i_private);
193 }
194
195 static const struct file_operations nvhost_debug_fops = {
196         .open           = nvhost_debug_open,
197         .read           = seq_read,
198         .llseek         = seq_lseek,
199         .release        = single_release,
200 };
201
202 void nvhost_device_debug_init(struct platform_device *dev)
203 {
204         struct nvhost_device_data *pdata = platform_get_drvdata(dev);
205         pdata->debugfs = debugfs_create_dir(dev->name, pdata->debugfs);
206 }
207
208 void nvhost_debug_init(struct nvhost_master *master)
209 {
210         struct nvhost_device_data *pdata;
211         struct dentry *de = debugfs_create_dir("tegra_host", NULL);
212
213         if (!de)
214                 return;
215
216         pdata = platform_get_drvdata(master->dev);
217
218         /* Store the created entry */
219         pdata->debugfs = de;
220
221         debugfs_create_file("status", S_IRUGO, de,
222                         master, &nvhost_debug_fops);
223         debugfs_create_file("status_all", S_IRUGO, de,
224                         master, &nvhost_debug_all_fops);
225
226         debugfs_create_u32("null_kickoff_pid", S_IRUGO|S_IWUSR, de,
227                         &nvhost_debug_null_kickoff_pid);
228         debugfs_create_u32("trace_cmdbuf", S_IRUGO|S_IWUSR, de,
229                         &nvhost_debug_trace_cmdbuf);
230
231         if (nvhost_get_chip_ops()->debug.debug_init)
232                 nvhost_get_chip_ops()->debug.debug_init(de);
233
234         debugfs_create_u32("force_timeout_pid", S_IRUGO|S_IWUSR, de,
235                         &nvhost_debug_force_timeout_pid);
236         debugfs_create_u32("force_timeout_val", S_IRUGO|S_IWUSR, de,
237                         &nvhost_debug_force_timeout_val);
238         debugfs_create_u32("force_timeout_channel", S_IRUGO|S_IWUSR, de,
239                         &nvhost_debug_force_timeout_channel);
240         debugfs_create_u32("force_timeout_dump", S_IRUGO|S_IWUSR, de,
241                         &nvhost_debug_force_timeout_dump);
242         nvhost_debug_force_timeout_dump = 0;
243 }
244 #else
245 void nvhost_debug_init(struct nvhost_master *master)
246 {
247 }
248 #endif
249
250 void nvhost_debug_dump(struct nvhost_master *master)
251 {
252         struct output o = {
253                 .fn = write_to_printk
254         };
255         show_all(master, &o);
256 }