blob: 93504eb7eaecc30b039f16f0a371e2f0bee94e71 [file] [log] [blame]
Felipe Balbi72246da2011-08-19 18:10:58 +03001/**
2 * debugfs.c - DesignWare USB3 DRD Controller DebugFS file
3 *
4 * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com
Felipe Balbi72246da2011-08-19 18:10:58 +03005 *
6 * Authors: Felipe Balbi <balbi@ti.com>,
7 * Sebastian Andrzej Siewior <bigeasy@linutronix.de>
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions, and the following disclaimer,
14 * without modification.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. The names of the above-listed copyright holders may not be used
19 * to endorse or promote products derived from this software without
20 * specific prior written permission.
21 *
22 * ALTERNATIVELY, this software may be distributed under the terms of the
23 * GNU General Public License ("GPL") version 2, as published by the Free
24 * Software Foundation.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
27 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
28 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
30 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 */
38
Vijayavardhan Vennapusaffeb26b2013-02-14 16:33:30 +053039#include <linux/module.h>
Felipe Balbi72246da2011-08-19 18:10:58 +030040#include <linux/kernel.h>
41#include <linux/slab.h>
42#include <linux/ptrace.h>
43#include <linux/types.h>
44#include <linux/spinlock.h>
45#include <linux/debugfs.h>
46#include <linux/seq_file.h>
47#include <linux/delay.h>
Felipe Balbi25b8ff62011-11-04 12:32:47 +020048#include <linux/uaccess.h>
Felipe Balbi72246da2011-08-19 18:10:58 +030049
Felipe Balbi080d9212012-01-02 18:38:30 +020050#include <linux/usb/ch9.h>
51
Felipe Balbi72246da2011-08-19 18:10:58 +030052#include "core.h"
53#include "gadget.h"
54#include "io.h"
Felipe Balbi8becf272011-11-04 12:40:05 +020055#include "debug.h"
Felipe Balbi72246da2011-08-19 18:10:58 +030056
Felipe Balbi72246da2011-08-19 18:10:58 +030057#define dump_register(nm) \
58{ \
59 .name = __stringify(nm), \
Jack Pham7bcc6b12012-12-01 20:19:48 -080060 .offset = DWC3_ ##nm - DWC3_GLOBALS_REGS_START, \
Felipe Balbi72246da2011-08-19 18:10:58 +030061}
62
Alessandro Rubinic8d2a6f2011-11-18 14:51:43 +010063static const struct debugfs_reg32 dwc3_regs[] = {
Felipe Balbi72246da2011-08-19 18:10:58 +030064 dump_register(GSBUSCFG0),
65 dump_register(GSBUSCFG1),
66 dump_register(GTXTHRCFG),
67 dump_register(GRXTHRCFG),
68 dump_register(GCTL),
69 dump_register(GEVTEN),
70 dump_register(GSTS),
71 dump_register(GSNPSID),
72 dump_register(GGPIO),
73 dump_register(GUID),
74 dump_register(GUCTL),
75 dump_register(GBUSERRADDR0),
76 dump_register(GBUSERRADDR1),
77 dump_register(GPRTBIMAP0),
78 dump_register(GPRTBIMAP1),
79 dump_register(GHWPARAMS0),
80 dump_register(GHWPARAMS1),
81 dump_register(GHWPARAMS2),
82 dump_register(GHWPARAMS3),
83 dump_register(GHWPARAMS4),
84 dump_register(GHWPARAMS5),
85 dump_register(GHWPARAMS6),
86 dump_register(GHWPARAMS7),
87 dump_register(GDBGFIFOSPACE),
88 dump_register(GDBGLTSSM),
89 dump_register(GPRTBIMAP_HS0),
90 dump_register(GPRTBIMAP_HS1),
91 dump_register(GPRTBIMAP_FS0),
92 dump_register(GPRTBIMAP_FS1),
93
94 dump_register(GUSB2PHYCFG(0)),
95 dump_register(GUSB2PHYCFG(1)),
96 dump_register(GUSB2PHYCFG(2)),
97 dump_register(GUSB2PHYCFG(3)),
98 dump_register(GUSB2PHYCFG(4)),
99 dump_register(GUSB2PHYCFG(5)),
100 dump_register(GUSB2PHYCFG(6)),
101 dump_register(GUSB2PHYCFG(7)),
102 dump_register(GUSB2PHYCFG(8)),
103 dump_register(GUSB2PHYCFG(9)),
104 dump_register(GUSB2PHYCFG(10)),
105 dump_register(GUSB2PHYCFG(11)),
106 dump_register(GUSB2PHYCFG(12)),
107 dump_register(GUSB2PHYCFG(13)),
108 dump_register(GUSB2PHYCFG(14)),
109 dump_register(GUSB2PHYCFG(15)),
110
111 dump_register(GUSB2I2CCTL(0)),
112 dump_register(GUSB2I2CCTL(1)),
113 dump_register(GUSB2I2CCTL(2)),
114 dump_register(GUSB2I2CCTL(3)),
115 dump_register(GUSB2I2CCTL(4)),
116 dump_register(GUSB2I2CCTL(5)),
117 dump_register(GUSB2I2CCTL(6)),
118 dump_register(GUSB2I2CCTL(7)),
119 dump_register(GUSB2I2CCTL(8)),
120 dump_register(GUSB2I2CCTL(9)),
121 dump_register(GUSB2I2CCTL(10)),
122 dump_register(GUSB2I2CCTL(11)),
123 dump_register(GUSB2I2CCTL(12)),
124 dump_register(GUSB2I2CCTL(13)),
125 dump_register(GUSB2I2CCTL(14)),
126 dump_register(GUSB2I2CCTL(15)),
127
128 dump_register(GUSB2PHYACC(0)),
129 dump_register(GUSB2PHYACC(1)),
130 dump_register(GUSB2PHYACC(2)),
131 dump_register(GUSB2PHYACC(3)),
132 dump_register(GUSB2PHYACC(4)),
133 dump_register(GUSB2PHYACC(5)),
134 dump_register(GUSB2PHYACC(6)),
135 dump_register(GUSB2PHYACC(7)),
136 dump_register(GUSB2PHYACC(8)),
137 dump_register(GUSB2PHYACC(9)),
138 dump_register(GUSB2PHYACC(10)),
139 dump_register(GUSB2PHYACC(11)),
140 dump_register(GUSB2PHYACC(12)),
141 dump_register(GUSB2PHYACC(13)),
142 dump_register(GUSB2PHYACC(14)),
143 dump_register(GUSB2PHYACC(15)),
144
145 dump_register(GUSB3PIPECTL(0)),
146 dump_register(GUSB3PIPECTL(1)),
147 dump_register(GUSB3PIPECTL(2)),
148 dump_register(GUSB3PIPECTL(3)),
149 dump_register(GUSB3PIPECTL(4)),
150 dump_register(GUSB3PIPECTL(5)),
151 dump_register(GUSB3PIPECTL(6)),
152 dump_register(GUSB3PIPECTL(7)),
153 dump_register(GUSB3PIPECTL(8)),
154 dump_register(GUSB3PIPECTL(9)),
155 dump_register(GUSB3PIPECTL(10)),
156 dump_register(GUSB3PIPECTL(11)),
157 dump_register(GUSB3PIPECTL(12)),
158 dump_register(GUSB3PIPECTL(13)),
159 dump_register(GUSB3PIPECTL(14)),
160 dump_register(GUSB3PIPECTL(15)),
161
162 dump_register(GTXFIFOSIZ(0)),
163 dump_register(GTXFIFOSIZ(1)),
164 dump_register(GTXFIFOSIZ(2)),
165 dump_register(GTXFIFOSIZ(3)),
166 dump_register(GTXFIFOSIZ(4)),
167 dump_register(GTXFIFOSIZ(5)),
168 dump_register(GTXFIFOSIZ(6)),
169 dump_register(GTXFIFOSIZ(7)),
170 dump_register(GTXFIFOSIZ(8)),
171 dump_register(GTXFIFOSIZ(9)),
172 dump_register(GTXFIFOSIZ(10)),
173 dump_register(GTXFIFOSIZ(11)),
174 dump_register(GTXFIFOSIZ(12)),
175 dump_register(GTXFIFOSIZ(13)),
176 dump_register(GTXFIFOSIZ(14)),
177 dump_register(GTXFIFOSIZ(15)),
178 dump_register(GTXFIFOSIZ(16)),
179 dump_register(GTXFIFOSIZ(17)),
180 dump_register(GTXFIFOSIZ(18)),
181 dump_register(GTXFIFOSIZ(19)),
182 dump_register(GTXFIFOSIZ(20)),
183 dump_register(GTXFIFOSIZ(21)),
184 dump_register(GTXFIFOSIZ(22)),
185 dump_register(GTXFIFOSIZ(23)),
186 dump_register(GTXFIFOSIZ(24)),
187 dump_register(GTXFIFOSIZ(25)),
188 dump_register(GTXFIFOSIZ(26)),
189 dump_register(GTXFIFOSIZ(27)),
190 dump_register(GTXFIFOSIZ(28)),
191 dump_register(GTXFIFOSIZ(29)),
192 dump_register(GTXFIFOSIZ(30)),
193 dump_register(GTXFIFOSIZ(31)),
194
195 dump_register(GRXFIFOSIZ(0)),
196 dump_register(GRXFIFOSIZ(1)),
197 dump_register(GRXFIFOSIZ(2)),
198 dump_register(GRXFIFOSIZ(3)),
199 dump_register(GRXFIFOSIZ(4)),
200 dump_register(GRXFIFOSIZ(5)),
201 dump_register(GRXFIFOSIZ(6)),
202 dump_register(GRXFIFOSIZ(7)),
203 dump_register(GRXFIFOSIZ(8)),
204 dump_register(GRXFIFOSIZ(9)),
205 dump_register(GRXFIFOSIZ(10)),
206 dump_register(GRXFIFOSIZ(11)),
207 dump_register(GRXFIFOSIZ(12)),
208 dump_register(GRXFIFOSIZ(13)),
209 dump_register(GRXFIFOSIZ(14)),
210 dump_register(GRXFIFOSIZ(15)),
211 dump_register(GRXFIFOSIZ(16)),
212 dump_register(GRXFIFOSIZ(17)),
213 dump_register(GRXFIFOSIZ(18)),
214 dump_register(GRXFIFOSIZ(19)),
215 dump_register(GRXFIFOSIZ(20)),
216 dump_register(GRXFIFOSIZ(21)),
217 dump_register(GRXFIFOSIZ(22)),
218 dump_register(GRXFIFOSIZ(23)),
219 dump_register(GRXFIFOSIZ(24)),
220 dump_register(GRXFIFOSIZ(25)),
221 dump_register(GRXFIFOSIZ(26)),
222 dump_register(GRXFIFOSIZ(27)),
223 dump_register(GRXFIFOSIZ(28)),
224 dump_register(GRXFIFOSIZ(29)),
225 dump_register(GRXFIFOSIZ(30)),
226 dump_register(GRXFIFOSIZ(31)),
227
228 dump_register(GEVNTADRLO(0)),
229 dump_register(GEVNTADRHI(0)),
230 dump_register(GEVNTSIZ(0)),
231 dump_register(GEVNTCOUNT(0)),
232
233 dump_register(GHWPARAMS8),
234 dump_register(DCFG),
235 dump_register(DCTL),
236 dump_register(DEVTEN),
237 dump_register(DSTS),
238 dump_register(DGCMDPAR),
239 dump_register(DGCMD),
240 dump_register(DALEPENA),
241
242 dump_register(DEPCMDPAR2(0)),
243 dump_register(DEPCMDPAR2(1)),
244 dump_register(DEPCMDPAR2(2)),
245 dump_register(DEPCMDPAR2(3)),
246 dump_register(DEPCMDPAR2(4)),
247 dump_register(DEPCMDPAR2(5)),
248 dump_register(DEPCMDPAR2(6)),
249 dump_register(DEPCMDPAR2(7)),
250 dump_register(DEPCMDPAR2(8)),
251 dump_register(DEPCMDPAR2(9)),
252 dump_register(DEPCMDPAR2(10)),
253 dump_register(DEPCMDPAR2(11)),
254 dump_register(DEPCMDPAR2(12)),
255 dump_register(DEPCMDPAR2(13)),
256 dump_register(DEPCMDPAR2(14)),
257 dump_register(DEPCMDPAR2(15)),
258 dump_register(DEPCMDPAR2(16)),
259 dump_register(DEPCMDPAR2(17)),
260 dump_register(DEPCMDPAR2(18)),
261 dump_register(DEPCMDPAR2(19)),
262 dump_register(DEPCMDPAR2(20)),
263 dump_register(DEPCMDPAR2(21)),
264 dump_register(DEPCMDPAR2(22)),
265 dump_register(DEPCMDPAR2(23)),
266 dump_register(DEPCMDPAR2(24)),
267 dump_register(DEPCMDPAR2(25)),
268 dump_register(DEPCMDPAR2(26)),
269 dump_register(DEPCMDPAR2(27)),
270 dump_register(DEPCMDPAR2(28)),
271 dump_register(DEPCMDPAR2(29)),
272 dump_register(DEPCMDPAR2(30)),
273 dump_register(DEPCMDPAR2(31)),
274
275 dump_register(DEPCMDPAR1(0)),
276 dump_register(DEPCMDPAR1(1)),
277 dump_register(DEPCMDPAR1(2)),
278 dump_register(DEPCMDPAR1(3)),
279 dump_register(DEPCMDPAR1(4)),
280 dump_register(DEPCMDPAR1(5)),
281 dump_register(DEPCMDPAR1(6)),
282 dump_register(DEPCMDPAR1(7)),
283 dump_register(DEPCMDPAR1(8)),
284 dump_register(DEPCMDPAR1(9)),
285 dump_register(DEPCMDPAR1(10)),
286 dump_register(DEPCMDPAR1(11)),
287 dump_register(DEPCMDPAR1(12)),
288 dump_register(DEPCMDPAR1(13)),
289 dump_register(DEPCMDPAR1(14)),
290 dump_register(DEPCMDPAR1(15)),
291 dump_register(DEPCMDPAR1(16)),
292 dump_register(DEPCMDPAR1(17)),
293 dump_register(DEPCMDPAR1(18)),
294 dump_register(DEPCMDPAR1(19)),
295 dump_register(DEPCMDPAR1(20)),
296 dump_register(DEPCMDPAR1(21)),
297 dump_register(DEPCMDPAR1(22)),
298 dump_register(DEPCMDPAR1(23)),
299 dump_register(DEPCMDPAR1(24)),
300 dump_register(DEPCMDPAR1(25)),
301 dump_register(DEPCMDPAR1(26)),
302 dump_register(DEPCMDPAR1(27)),
303 dump_register(DEPCMDPAR1(28)),
304 dump_register(DEPCMDPAR1(29)),
305 dump_register(DEPCMDPAR1(30)),
306 dump_register(DEPCMDPAR1(31)),
307
308 dump_register(DEPCMDPAR0(0)),
309 dump_register(DEPCMDPAR0(1)),
310 dump_register(DEPCMDPAR0(2)),
311 dump_register(DEPCMDPAR0(3)),
312 dump_register(DEPCMDPAR0(4)),
313 dump_register(DEPCMDPAR0(5)),
314 dump_register(DEPCMDPAR0(6)),
315 dump_register(DEPCMDPAR0(7)),
316 dump_register(DEPCMDPAR0(8)),
317 dump_register(DEPCMDPAR0(9)),
318 dump_register(DEPCMDPAR0(10)),
319 dump_register(DEPCMDPAR0(11)),
320 dump_register(DEPCMDPAR0(12)),
321 dump_register(DEPCMDPAR0(13)),
322 dump_register(DEPCMDPAR0(14)),
323 dump_register(DEPCMDPAR0(15)),
324 dump_register(DEPCMDPAR0(16)),
325 dump_register(DEPCMDPAR0(17)),
326 dump_register(DEPCMDPAR0(18)),
327 dump_register(DEPCMDPAR0(19)),
328 dump_register(DEPCMDPAR0(20)),
329 dump_register(DEPCMDPAR0(21)),
330 dump_register(DEPCMDPAR0(22)),
331 dump_register(DEPCMDPAR0(23)),
332 dump_register(DEPCMDPAR0(24)),
333 dump_register(DEPCMDPAR0(25)),
334 dump_register(DEPCMDPAR0(26)),
335 dump_register(DEPCMDPAR0(27)),
336 dump_register(DEPCMDPAR0(28)),
337 dump_register(DEPCMDPAR0(29)),
338 dump_register(DEPCMDPAR0(30)),
339 dump_register(DEPCMDPAR0(31)),
340
341 dump_register(DEPCMD(0)),
342 dump_register(DEPCMD(1)),
343 dump_register(DEPCMD(2)),
344 dump_register(DEPCMD(3)),
345 dump_register(DEPCMD(4)),
346 dump_register(DEPCMD(5)),
347 dump_register(DEPCMD(6)),
348 dump_register(DEPCMD(7)),
349 dump_register(DEPCMD(8)),
350 dump_register(DEPCMD(9)),
351 dump_register(DEPCMD(10)),
352 dump_register(DEPCMD(11)),
353 dump_register(DEPCMD(12)),
354 dump_register(DEPCMD(13)),
355 dump_register(DEPCMD(14)),
356 dump_register(DEPCMD(15)),
357 dump_register(DEPCMD(16)),
358 dump_register(DEPCMD(17)),
359 dump_register(DEPCMD(18)),
360 dump_register(DEPCMD(19)),
361 dump_register(DEPCMD(20)),
362 dump_register(DEPCMD(21)),
363 dump_register(DEPCMD(22)),
364 dump_register(DEPCMD(23)),
365 dump_register(DEPCMD(24)),
366 dump_register(DEPCMD(25)),
367 dump_register(DEPCMD(26)),
368 dump_register(DEPCMD(27)),
369 dump_register(DEPCMD(28)),
370 dump_register(DEPCMD(29)),
371 dump_register(DEPCMD(30)),
372 dump_register(DEPCMD(31)),
373
374 dump_register(OCFG),
375 dump_register(OCTL),
376 dump_register(OEVTEN),
377 dump_register(OSTS),
378};
379
380static int dwc3_regdump_show(struct seq_file *s, void *unused)
381{
382 struct dwc3 *dwc = s->private;
Felipe Balbi72246da2011-08-19 18:10:58 +0300383
384 seq_printf(s, "DesignWare USB3 Core Register Dump\n");
Alessandro Rubinic8d2a6f2011-11-18 14:51:43 +0100385 debugfs_print_regs32(s, dwc3_regs, ARRAY_SIZE(dwc3_regs),
386 dwc->regs, "");
Felipe Balbi72246da2011-08-19 18:10:58 +0300387 return 0;
388}
389
390static int dwc3_regdump_open(struct inode *inode, struct file *file)
391{
392 return single_open(file, dwc3_regdump_show, inode->i_private);
393}
394
395static const struct file_operations dwc3_regdump_fops = {
396 .open = dwc3_regdump_open,
397 .read = seq_read,
398 .release = single_release,
399};
400
Felipe Balbi0b9fe322011-10-17 08:50:39 +0300401static int dwc3_mode_show(struct seq_file *s, void *unused)
402{
403 struct dwc3 *dwc = s->private;
404 unsigned long flags;
405 u32 reg;
406
407 spin_lock_irqsave(&dwc->lock, flags);
408 reg = dwc3_readl(dwc->regs, DWC3_GCTL);
409 spin_unlock_irqrestore(&dwc->lock, flags);
410
411 switch (DWC3_GCTL_PRTCAP(reg)) {
412 case DWC3_GCTL_PRTCAP_HOST:
413 seq_printf(s, "host\n");
414 break;
415 case DWC3_GCTL_PRTCAP_DEVICE:
416 seq_printf(s, "device\n");
417 break;
418 case DWC3_GCTL_PRTCAP_OTG:
419 seq_printf(s, "OTG\n");
420 break;
421 default:
422 seq_printf(s, "UNKNOWN %08x\n", DWC3_GCTL_PRTCAP(reg));
423 }
424
425 return 0;
426}
427
428static int dwc3_mode_open(struct inode *inode, struct file *file)
429{
430 return single_open(file, dwc3_mode_show, inode->i_private);
431}
432
433static ssize_t dwc3_mode_write(struct file *file,
434 const char __user *ubuf, size_t count, loff_t *ppos)
435{
436 struct seq_file *s = file->private_data;
437 struct dwc3 *dwc = s->private;
438 unsigned long flags;
Sebastian Andrzej Siewior3140e8c2011-10-31 22:25:40 +0100439 u32 mode = 0;
Felipe Balbi0b9fe322011-10-17 08:50:39 +0300440 char buf[32];
441
442 if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
443 return -EFAULT;
444
Felipe Balbi0b9fe322011-10-17 08:50:39 +0300445 if (!strncmp(buf, "host", 4))
Sebastian Andrzej Siewior3140e8c2011-10-31 22:25:40 +0100446 mode |= DWC3_GCTL_PRTCAP_HOST;
Felipe Balbi0b9fe322011-10-17 08:50:39 +0300447
448 if (!strncmp(buf, "device", 6))
Sebastian Andrzej Siewior3140e8c2011-10-31 22:25:40 +0100449 mode |= DWC3_GCTL_PRTCAP_DEVICE;
Felipe Balbi0b9fe322011-10-17 08:50:39 +0300450
451 if (!strncmp(buf, "otg", 3))
Sebastian Andrzej Siewior3140e8c2011-10-31 22:25:40 +0100452 mode |= DWC3_GCTL_PRTCAP_OTG;
Felipe Balbi0b9fe322011-10-17 08:50:39 +0300453
Sebastian Andrzej Siewior3140e8c2011-10-31 22:25:40 +0100454 if (mode) {
455 spin_lock_irqsave(&dwc->lock, flags);
456 dwc3_set_mode(dwc, mode);
457 spin_unlock_irqrestore(&dwc->lock, flags);
458 }
Felipe Balbi0b9fe322011-10-17 08:50:39 +0300459 return count;
460}
461
462static const struct file_operations dwc3_mode_fops = {
463 .open = dwc3_mode_open,
464 .write = dwc3_mode_write,
465 .read = seq_read,
466 .llseek = seq_lseek,
467 .release = single_release,
468};
469
Felipe Balbi080d9212012-01-02 18:38:30 +0200470static int dwc3_testmode_show(struct seq_file *s, void *unused)
471{
472 struct dwc3 *dwc = s->private;
473 unsigned long flags;
474 u32 reg;
475
476 spin_lock_irqsave(&dwc->lock, flags);
477 reg = dwc3_readl(dwc->regs, DWC3_DCTL);
478 reg &= DWC3_DCTL_TSTCTRL_MASK;
479 reg >>= 1;
480 spin_unlock_irqrestore(&dwc->lock, flags);
481
482 switch (reg) {
483 case 0:
484 seq_printf(s, "no test\n");
485 break;
486 case TEST_J:
487 seq_printf(s, "test_j\n");
488 break;
489 case TEST_K:
490 seq_printf(s, "test_k\n");
491 break;
492 case TEST_SE0_NAK:
493 seq_printf(s, "test_se0_nak\n");
494 break;
495 case TEST_PACKET:
496 seq_printf(s, "test_packet\n");
497 break;
498 case TEST_FORCE_EN:
499 seq_printf(s, "test_force_enable\n");
500 break;
501 default:
502 seq_printf(s, "UNKNOWN %d\n", reg);
503 }
504
505 return 0;
506}
507
508static int dwc3_testmode_open(struct inode *inode, struct file *file)
509{
510 return single_open(file, dwc3_testmode_show, inode->i_private);
511}
512
513static ssize_t dwc3_testmode_write(struct file *file,
514 const char __user *ubuf, size_t count, loff_t *ppos)
515{
516 struct seq_file *s = file->private_data;
517 struct dwc3 *dwc = s->private;
518 unsigned long flags;
519 u32 testmode = 0;
520 char buf[32];
521
522 if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
523 return -EFAULT;
524
525 if (!strncmp(buf, "test_j", 6))
526 testmode = TEST_J;
527 else if (!strncmp(buf, "test_k", 6))
528 testmode = TEST_K;
Gerard Cauvy09072542012-02-10 12:14:53 +0200529 else if (!strncmp(buf, "test_se0_nak", 12))
Felipe Balbi080d9212012-01-02 18:38:30 +0200530 testmode = TEST_SE0_NAK;
Gerard Cauvy09072542012-02-10 12:14:53 +0200531 else if (!strncmp(buf, "test_packet", 11))
Felipe Balbi080d9212012-01-02 18:38:30 +0200532 testmode = TEST_PACKET;
Gerard Cauvy09072542012-02-10 12:14:53 +0200533 else if (!strncmp(buf, "test_force_enable", 17))
Felipe Balbi080d9212012-01-02 18:38:30 +0200534 testmode = TEST_FORCE_EN;
535 else
536 testmode = 0;
537
538 spin_lock_irqsave(&dwc->lock, flags);
539 dwc3_gadget_set_test_mode(dwc, testmode);
540 spin_unlock_irqrestore(&dwc->lock, flags);
541
542 return count;
543}
544
545static const struct file_operations dwc3_testmode_fops = {
546 .open = dwc3_testmode_open,
547 .write = dwc3_testmode_write,
548 .read = seq_read,
549 .llseek = seq_lseek,
550 .release = single_release,
551};
552
Felipe Balbi138801a2012-01-02 19:25:16 +0200553static int dwc3_link_state_show(struct seq_file *s, void *unused)
554{
555 struct dwc3 *dwc = s->private;
556 unsigned long flags;
557 enum dwc3_link_state state;
558 u32 reg;
559
560 spin_lock_irqsave(&dwc->lock, flags);
561 reg = dwc3_readl(dwc->regs, DWC3_DSTS);
562 state = DWC3_DSTS_USBLNKST(reg);
563 spin_unlock_irqrestore(&dwc->lock, flags);
564
565 switch (state) {
566 case DWC3_LINK_STATE_U0:
567 seq_printf(s, "U0\n");
568 break;
569 case DWC3_LINK_STATE_U1:
570 seq_printf(s, "U1\n");
571 break;
572 case DWC3_LINK_STATE_U2:
573 seq_printf(s, "U2\n");
574 break;
575 case DWC3_LINK_STATE_U3:
576 seq_printf(s, "U3\n");
577 break;
578 case DWC3_LINK_STATE_SS_DIS:
579 seq_printf(s, "SS.Disabled\n");
580 break;
581 case DWC3_LINK_STATE_RX_DET:
582 seq_printf(s, "Rx.Detect\n");
583 break;
584 case DWC3_LINK_STATE_SS_INACT:
585 seq_printf(s, "SS.Inactive\n");
586 break;
587 case DWC3_LINK_STATE_POLL:
588 seq_printf(s, "Poll\n");
589 break;
590 case DWC3_LINK_STATE_RECOV:
591 seq_printf(s, "Recovery\n");
592 break;
593 case DWC3_LINK_STATE_HRESET:
594 seq_printf(s, "HRESET\n");
595 break;
596 case DWC3_LINK_STATE_CMPLY:
597 seq_printf(s, "Compliance\n");
598 break;
599 case DWC3_LINK_STATE_LPBK:
600 seq_printf(s, "Loopback\n");
601 break;
602 default:
603 seq_printf(s, "UNKNOWN %d\n", reg);
604 }
605
606 return 0;
607}
608
609static int dwc3_link_state_open(struct inode *inode, struct file *file)
610{
611 return single_open(file, dwc3_link_state_show, inode->i_private);
612}
613
614static ssize_t dwc3_link_state_write(struct file *file,
615 const char __user *ubuf, size_t count, loff_t *ppos)
616{
617 struct seq_file *s = file->private_data;
618 struct dwc3 *dwc = s->private;
619 unsigned long flags;
620 enum dwc3_link_state state = 0;
621 char buf[32];
622
623 if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
624 return -EFAULT;
625
626 if (!strncmp(buf, "SS.Disabled", 11))
627 state = DWC3_LINK_STATE_SS_DIS;
628 else if (!strncmp(buf, "Rx.Detect", 9))
629 state = DWC3_LINK_STATE_RX_DET;
630 else if (!strncmp(buf, "SS.Inactive", 11))
631 state = DWC3_LINK_STATE_SS_INACT;
632 else if (!strncmp(buf, "Recovery", 8))
633 state = DWC3_LINK_STATE_RECOV;
634 else if (!strncmp(buf, "Compliance", 10))
635 state = DWC3_LINK_STATE_CMPLY;
636 else if (!strncmp(buf, "Loopback", 8))
637 state = DWC3_LINK_STATE_LPBK;
638 else
639 return -EINVAL;
640
641 spin_lock_irqsave(&dwc->lock, flags);
642 dwc3_gadget_set_link_state(dwc, state);
643 spin_unlock_irqrestore(&dwc->lock, flags);
644
645 return count;
646}
647
648static const struct file_operations dwc3_link_state_fops = {
649 .open = dwc3_link_state_open,
650 .write = dwc3_link_state_write,
651 .read = seq_read,
652 .llseek = seq_lseek,
653 .release = single_release,
654};
655
Vijayavardhan Vennapusaffeb26b2013-02-14 16:33:30 +0530656static int ep_num;
657static ssize_t dwc3_store_ep_num(struct file *file, const char __user *ubuf,
658 size_t count, loff_t *ppos)
659{
660 struct seq_file *s = file->private_data;
661 struct dwc3 *dwc = s->private;
662 char kbuf[10];
663 unsigned int num, dir;
664 unsigned long flags;
665
666 memset(kbuf, 0, 10);
667
668 if (copy_from_user(kbuf, ubuf, count > 10 ? 10 : count))
669 return -EFAULT;
670
671 if (sscanf(kbuf, "%u %u", &num, &dir) != 2)
672 return -EINVAL;
673
674 spin_lock_irqsave(&dwc->lock, flags);
675 ep_num = (num << 1) + dir;
676 spin_unlock_irqrestore(&dwc->lock, flags);
677
678 return count;
679}
680
681static int dwc3_ep_req_list_show(struct seq_file *s, void *unused)
682{
683 struct dwc3 *dwc = s->private;
684 struct dwc3_ep *dep;
685 struct dwc3_request *req = NULL;
686 struct list_head *ptr = NULL;
687 unsigned long flags;
688
689 spin_lock_irqsave(&dwc->lock, flags);
690 dep = dwc->eps[ep_num];
691
692 seq_printf(s, "%s request list: flags: 0x%x\n", dep->name, dep->flags);
693 list_for_each(ptr, &dep->request_list) {
694 req = list_entry(ptr, struct dwc3_request, list);
695
696 seq_printf(s, "req:0x%p len: %d sts: %d dma:0x%x num_sgs: %d\n",
697 req, req->request.length, req->request.status,
698 req->request.dma, req->request.num_sgs);
699 }
700 spin_unlock_irqrestore(&dwc->lock, flags);
701
702 return 0;
703}
704
705static int dwc3_ep_req_list_open(struct inode *inode, struct file *file)
706{
707 return single_open(file, dwc3_ep_req_list_show, inode->i_private);
708}
709
710static const struct file_operations dwc3_ep_req_list_fops = {
711 .open = dwc3_ep_req_list_open,
712 .write = dwc3_store_ep_num,
713 .read = seq_read,
714 .llseek = seq_lseek,
715 .release = single_release,
716};
717
718static int dwc3_ep_queued_req_show(struct seq_file *s, void *unused)
719{
720 struct dwc3 *dwc = s->private;
721 struct dwc3_ep *dep;
722 struct dwc3_request *req = NULL;
723 struct list_head *ptr = NULL;
724 unsigned long flags;
725
726 spin_lock_irqsave(&dwc->lock, flags);
727 dep = dwc->eps[ep_num];
728
729 seq_printf(s, "%s queued reqs to HW: flags:0x%x\n", dep->name,
730 dep->flags);
731 list_for_each(ptr, &dep->req_queued) {
732 req = list_entry(ptr, struct dwc3_request, list);
733
734 seq_printf(s, "req:0x%p len:%d sts:%d dma:%x nsg:%d trb:0x%p\n",
735 req, req->request.length, req->request.status,
736 req->request.dma, req->request.num_sgs, req->trb);
737 }
738 spin_unlock_irqrestore(&dwc->lock, flags);
739
740 return 0;
741}
742
743static int dwc3_ep_queued_req_open(struct inode *inode, struct file *file)
744{
745 return single_open(file, dwc3_ep_queued_req_show, inode->i_private);
746}
747
748const struct file_operations dwc3_ep_req_queued_fops = {
749 .open = dwc3_ep_queued_req_open,
750 .write = dwc3_store_ep_num,
751 .read = seq_read,
752 .llseek = seq_lseek,
753 .release = single_release,
754};
755
756static int dwc3_ep_trbs_show(struct seq_file *s, void *unused)
757{
758 struct dwc3 *dwc = s->private;
759 struct dwc3_ep *dep;
760 struct dwc3_trb *trb;
761 unsigned long flags;
762 int j;
763
764 if (!ep_num)
765 return 0;
766
767 spin_lock_irqsave(&dwc->lock, flags);
768 dep = dwc->eps[ep_num];
769
770 seq_printf(s, "%s trb pool: flags:0x%x freeslot:%d busyslot:%d\n",
771 dep->name, dep->flags, dep->free_slot, dep->busy_slot);
772 for (j = 0; j < DWC3_TRB_NUM; j++) {
773 trb = &dep->trb_pool[j];
774 seq_printf(s, "trb:0x%p bph:0x%x bpl:0x%x size:0x%x ctrl: %x\n",
775 trb, trb->bph, trb->bpl, trb->size, trb->ctrl);
776 }
777 spin_unlock_irqrestore(&dwc->lock, flags);
778
779 return 0;
780}
781
782static int dwc3_ep_trbs_list_open(struct inode *inode, struct file *file)
783{
784 return single_open(file, dwc3_ep_trbs_show, inode->i_private);
785}
786
787const struct file_operations dwc3_ep_trb_list_fops = {
788 .open = dwc3_ep_trbs_list_open,
789 .write = dwc3_store_ep_num,
790 .read = seq_read,
791 .llseek = seq_lseek,
792 .release = single_release,
793};
794
795static unsigned int ep_addr_rxdbg_mask;
796module_param(ep_addr_rxdbg_mask, uint, S_IRUGO | S_IWUSR);
797static unsigned int ep_addr_txdbg_mask;
798module_param(ep_addr_txdbg_mask, uint, S_IRUGO | S_IWUSR);
799
800/* Maximum debug message length */
801#define DBG_DATA_MSG 64UL
802
803/* Maximum number of messages */
804#define DBG_DATA_MAX 128UL
805
806static struct {
807 char (buf[DBG_DATA_MAX])[DBG_DATA_MSG]; /* buffer */
808 unsigned idx; /* index */
809 unsigned tty; /* print to console? */
810 rwlock_t lck; /* lock */
811} dbg_dwc3_data = {
812 .idx = 0,
813 .tty = 0,
814 .lck = __RW_LOCK_UNLOCKED(lck)
815};
816
817/**
818 * dbg_dec: decrements debug event index
819 * @idx: buffer index
820 */
821static inline void __maybe_unused dbg_dec(unsigned *idx)
822{
823 *idx = (*idx - 1) % DBG_DATA_MAX;
824}
825
826/**
827 * dbg_inc: increments debug event index
828 * @idx: buffer index
829 */
830static inline void dbg_inc(unsigned *idx)
831{
832 *idx = (*idx + 1) % DBG_DATA_MAX;
833}
834
835#define TIME_BUF_LEN 20
836/*get_timestamp - returns time of day in us */
837static char *get_timestamp(char *tbuf)
838{
839 unsigned long long t;
840 unsigned long nanosec_rem;
841
842 t = cpu_clock(smp_processor_id());
843 nanosec_rem = do_div(t, 1000000000)/1000;
844 scnprintf(tbuf, TIME_BUF_LEN, "[%5lu.%06lu] ", (unsigned long)t,
845 nanosec_rem);
846 return tbuf;
847}
848
849static int allow_dbg_print(u8 ep_num)
850{
851 int dir, num;
852
853 /* allow bus wide events */
854 if (ep_num == 0xff)
855 return 1;
856
857 dir = ep_num & 0x1;
858 num = ep_num >> 1;
859 num = 1 << num;
860
861 if (dir && (num & ep_addr_txdbg_mask))
862 return 1;
863 if (!dir && (num & ep_addr_rxdbg_mask))
864 return 1;
865
866 return 0;
867}
868
869/**
870 * dbg_print: prints the common part of the event
871 * @addr: endpoint address
872 * @name: event name
873 * @status: status
874 * @extra: extra information
875 */
876void dbg_print(u8 ep_num, const char *name, int status, const char *extra)
877{
878 unsigned long flags;
879 char tbuf[TIME_BUF_LEN];
880
881 if (!allow_dbg_print(ep_num))
882 return;
883
884 write_lock_irqsave(&dbg_dwc3_data.lck, flags);
885
886 scnprintf(dbg_dwc3_data.buf[dbg_dwc3_data.idx], DBG_DATA_MSG,
887 "%s\t? %02X %-7.7s %4i ?\t%s\n",
888 get_timestamp(tbuf), ep_num, name, status, extra);
889
890 dbg_inc(&dbg_dwc3_data.idx);
891
892 write_unlock_irqrestore(&dbg_dwc3_data.lck, flags);
893
894 if (dbg_dwc3_data.tty != 0)
895 pr_notice("%s\t? %02X %-7.7s %4i ?\t%s\n",
896 get_timestamp(tbuf), ep_num, name, status, extra);
897}
898
899/**
900 * dbg_done: prints a DONE event
901 * @addr: endpoint address
902 * @td: transfer descriptor
903 * @status: status
904 */
905void dbg_done(u8 ep_num, const u32 count, int status)
906{
907 char msg[DBG_DATA_MSG];
908
909 if (!allow_dbg_print(ep_num))
910 return;
911
912 scnprintf(msg, sizeof(msg), "%d", count);
913 dbg_print(ep_num, "DONE", status, msg);
914}
915
916/**
917 * dbg_event: prints a generic event
918 * @addr: endpoint address
919 * @name: event name
920 * @status: status
921 */
922void dbg_event(u8 ep_num, const char *name, int status)
923{
924 if (!allow_dbg_print(ep_num))
925 return;
926
927 if (name != NULL)
928 dbg_print(ep_num, name, status, "");
929}
930
931/*
932 * dbg_queue: prints a QUEUE event
933 * @addr: endpoint address
934 * @req: USB request
935 * @status: status
936 */
937void dbg_queue(u8 ep_num, const struct usb_request *req, int status)
938{
939 char msg[DBG_DATA_MSG];
940
941 if (!allow_dbg_print(ep_num))
942 return;
943
944 if (req != NULL) {
945 scnprintf(msg, sizeof(msg),
946 "%d %d", !req->no_interrupt, req->length);
947 dbg_print(ep_num, "QUEUE", status, msg);
948 }
949}
950
951/**
952 * dbg_setup: prints a SETUP event
953 * @addr: endpoint address
954 * @req: setup request
955 */
956void dbg_setup(u8 ep_num, const struct usb_ctrlrequest *req)
957{
958 char msg[DBG_DATA_MSG];
959
960 if (!allow_dbg_print(ep_num))
961 return;
962
963 if (req != NULL) {
964 scnprintf(msg, sizeof(msg),
965 "%02X %02X %04X %04X %d", req->bRequestType,
966 req->bRequest, le16_to_cpu(req->wValue),
967 le16_to_cpu(req->wIndex), le16_to_cpu(req->wLength));
968 dbg_print(ep_num, "SETUP", 0, msg);
969 }
970}
971
972/**
973 * store_events: configure if events are going to be also printed to console
974 *
975 */
976static ssize_t dwc3_store_events(struct file *file,
977 const char __user *buf, size_t count, loff_t *ppos)
978{
979 unsigned tty;
980
981 if (buf == NULL) {
982 pr_err("[%s] EINVAL\n", __func__);
983 goto done;
984 }
985
986 if (sscanf(buf, "%u", &tty) != 1 || tty > 1) {
987 pr_err("<1|0>: enable|disable console log\n");
988 goto done;
989 }
990
991 dbg_dwc3_data.tty = tty;
992 pr_info("tty = %u", dbg_dwc3_data.tty);
993
994 done:
995 return count;
996}
997
998static int dwc3_gadget_data_events_show(struct seq_file *s, void *unused)
999{
1000 unsigned long flags;
1001 unsigned i;
1002
1003 read_lock_irqsave(&dbg_dwc3_data.lck, flags);
1004
1005 i = dbg_dwc3_data.idx;
1006 if (strnlen(dbg_dwc3_data.buf[i], DBG_DATA_MSG))
1007 seq_printf(s, "%s\n", dbg_dwc3_data.buf[i]);
1008 for (dbg_inc(&i); i != dbg_dwc3_data.idx; dbg_inc(&i)) {
1009 if (!strnlen(dbg_dwc3_data.buf[i], DBG_DATA_MSG))
1010 continue;
1011 seq_printf(s, "%s\n", dbg_dwc3_data.buf[i]);
1012 }
1013
1014 read_unlock_irqrestore(&dbg_dwc3_data.lck, flags);
1015
1016 return 0;
1017}
1018
1019static int dwc3_gadget_data_events_open(struct inode *inode, struct file *f)
1020{
1021 return single_open(f, dwc3_gadget_data_events_show, inode->i_private);
1022}
1023
1024const struct file_operations dwc3_gadget_dbg_data_fops = {
1025 .open = dwc3_gadget_data_events_open,
1026 .read = seq_read,
1027 .write = dwc3_store_events,
1028 .llseek = seq_lseek,
1029 .release = single_release,
1030};
1031
Felipe Balbi72246da2011-08-19 18:10:58 +03001032int __devinit dwc3_debugfs_init(struct dwc3 *dwc)
1033{
1034 struct dentry *root;
1035 struct dentry *file;
1036 int ret;
1037
1038 root = debugfs_create_dir(dev_name(dwc->dev), NULL);
Felipe Balbi3d4c0d42012-01-31 13:33:32 +02001039 if (!root) {
1040 ret = -ENOMEM;
Felipe Balbi72246da2011-08-19 18:10:58 +03001041 goto err0;
1042 }
1043
1044 dwc->root = root;
1045
1046 file = debugfs_create_file("regdump", S_IRUGO, root, dwc,
1047 &dwc3_regdump_fops);
Felipe Balbi3d4c0d42012-01-31 13:33:32 +02001048 if (!file) {
1049 ret = -ENOMEM;
Felipe Balbi72246da2011-08-19 18:10:58 +03001050 goto err1;
1051 }
Felipe Balbi0b9fe322011-10-17 08:50:39 +03001052
1053 file = debugfs_create_file("mode", S_IRUGO | S_IWUSR, root,
1054 dwc, &dwc3_mode_fops);
Felipe Balbi3d4c0d42012-01-31 13:33:32 +02001055 if (!file) {
1056 ret = -ENOMEM;
Felipe Balbi0b9fe322011-10-17 08:50:39 +03001057 goto err1;
1058 }
1059
Felipe Balbi080d9212012-01-02 18:38:30 +02001060 file = debugfs_create_file("testmode", S_IRUGO | S_IWUSR, root,
1061 dwc, &dwc3_testmode_fops);
Felipe Balbi3d4c0d42012-01-31 13:33:32 +02001062 if (!file) {
1063 ret = -ENOMEM;
Felipe Balbi080d9212012-01-02 18:38:30 +02001064 goto err1;
1065 }
1066
Felipe Balbi138801a2012-01-02 19:25:16 +02001067 file = debugfs_create_file("link_state", S_IRUGO | S_IWUSR, root,
1068 dwc, &dwc3_link_state_fops);
Felipe Balbi3d4c0d42012-01-31 13:33:32 +02001069 if (!file) {
1070 ret = -ENOMEM;
Felipe Balbi138801a2012-01-02 19:25:16 +02001071 goto err1;
1072 }
1073
Vijayavardhan Vennapusaffeb26b2013-02-14 16:33:30 +05301074 file = debugfs_create_file("trbs", S_IRUGO | S_IWUSR, root,
1075 dwc, &dwc3_ep_trb_list_fops);
1076 if (!file) {
1077 ret = -ENOMEM;
1078 goto err1;
1079 }
1080
1081 file = debugfs_create_file("requests", S_IRUGO | S_IWUSR, root,
1082 dwc, &dwc3_ep_req_list_fops);
1083 if (!file) {
1084 ret = -ENOMEM;
1085 goto err1;
1086 }
1087
1088 file = debugfs_create_file("queued_reqs", S_IRUGO | S_IWUSR, root,
1089 dwc, &dwc3_ep_req_queued_fops);
1090 if (!file) {
1091 ret = -ENOMEM;
1092 goto err1;
1093 }
1094
1095 file = debugfs_create_file("events", S_IRUGO | S_IWUSR, root,
1096 dwc, &dwc3_gadget_dbg_data_fops);
1097 if (!file) {
1098 ret = -ENOMEM;
1099 goto err1;
1100 }
Felipe Balbi72246da2011-08-19 18:10:58 +03001101 return 0;
1102
1103err1:
1104 debugfs_remove_recursive(root);
1105
1106err0:
1107 return ret;
1108}
1109
1110void __devexit dwc3_debugfs_exit(struct dwc3 *dwc)
1111{
1112 debugfs_remove_recursive(dwc->root);
1113 dwc->root = NULL;
1114}