blob: df9564640c18e5b6c08e01af7234aa2db3dc47f3 [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
Hemant Kumar1b378d92013-04-19 11:24:05 -0700696 seq_printf(s,
697 "req:0x%p len: %d sts: %d dma:0x%pa num_sgs: %d\n",
Vijayavardhan Vennapusaffeb26b2013-02-14 16:33:30 +0530698 req, req->request.length, req->request.status,
Hemant Kumar1b378d92013-04-19 11:24:05 -0700699 &req->request.dma, req->request.num_sgs);
Vijayavardhan Vennapusaffeb26b2013-02-14 16:33:30 +0530700 }
701 spin_unlock_irqrestore(&dwc->lock, flags);
702
703 return 0;
704}
705
706static int dwc3_ep_req_list_open(struct inode *inode, struct file *file)
707{
708 return single_open(file, dwc3_ep_req_list_show, inode->i_private);
709}
710
711static const struct file_operations dwc3_ep_req_list_fops = {
712 .open = dwc3_ep_req_list_open,
713 .write = dwc3_store_ep_num,
714 .read = seq_read,
715 .llseek = seq_lseek,
716 .release = single_release,
717};
718
719static int dwc3_ep_queued_req_show(struct seq_file *s, void *unused)
720{
721 struct dwc3 *dwc = s->private;
722 struct dwc3_ep *dep;
723 struct dwc3_request *req = NULL;
724 struct list_head *ptr = NULL;
725 unsigned long flags;
726
727 spin_lock_irqsave(&dwc->lock, flags);
728 dep = dwc->eps[ep_num];
729
730 seq_printf(s, "%s queued reqs to HW: flags:0x%x\n", dep->name,
731 dep->flags);
732 list_for_each(ptr, &dep->req_queued) {
733 req = list_entry(ptr, struct dwc3_request, list);
734
Hemant Kumar1b378d92013-04-19 11:24:05 -0700735 seq_printf(s,
736 "req:0x%p len:%d sts:%d dma:%pa nsg:%d trb:0x%p\n",
Vijayavardhan Vennapusaffeb26b2013-02-14 16:33:30 +0530737 req, req->request.length, req->request.status,
Hemant Kumar1b378d92013-04-19 11:24:05 -0700738 &req->request.dma, req->request.num_sgs, req->trb);
Vijayavardhan Vennapusaffeb26b2013-02-14 16:33:30 +0530739 }
740 spin_unlock_irqrestore(&dwc->lock, flags);
741
742 return 0;
743}
744
745static int dwc3_ep_queued_req_open(struct inode *inode, struct file *file)
746{
747 return single_open(file, dwc3_ep_queued_req_show, inode->i_private);
748}
749
750const struct file_operations dwc3_ep_req_queued_fops = {
751 .open = dwc3_ep_queued_req_open,
752 .write = dwc3_store_ep_num,
753 .read = seq_read,
754 .llseek = seq_lseek,
755 .release = single_release,
756};
757
758static int dwc3_ep_trbs_show(struct seq_file *s, void *unused)
759{
760 struct dwc3 *dwc = s->private;
761 struct dwc3_ep *dep;
762 struct dwc3_trb *trb;
763 unsigned long flags;
764 int j;
765
766 if (!ep_num)
767 return 0;
768
769 spin_lock_irqsave(&dwc->lock, flags);
770 dep = dwc->eps[ep_num];
771
772 seq_printf(s, "%s trb pool: flags:0x%x freeslot:%d busyslot:%d\n",
773 dep->name, dep->flags, dep->free_slot, dep->busy_slot);
774 for (j = 0; j < DWC3_TRB_NUM; j++) {
775 trb = &dep->trb_pool[j];
776 seq_printf(s, "trb:0x%p bph:0x%x bpl:0x%x size:0x%x ctrl: %x\n",
777 trb, trb->bph, trb->bpl, trb->size, trb->ctrl);
778 }
779 spin_unlock_irqrestore(&dwc->lock, flags);
780
781 return 0;
782}
783
784static int dwc3_ep_trbs_list_open(struct inode *inode, struct file *file)
785{
786 return single_open(file, dwc3_ep_trbs_show, inode->i_private);
787}
788
789const struct file_operations dwc3_ep_trb_list_fops = {
790 .open = dwc3_ep_trbs_list_open,
791 .write = dwc3_store_ep_num,
792 .read = seq_read,
793 .llseek = seq_lseek,
794 .release = single_release,
795};
796
797static unsigned int ep_addr_rxdbg_mask;
798module_param(ep_addr_rxdbg_mask, uint, S_IRUGO | S_IWUSR);
799static unsigned int ep_addr_txdbg_mask;
800module_param(ep_addr_txdbg_mask, uint, S_IRUGO | S_IWUSR);
801
802/* Maximum debug message length */
803#define DBG_DATA_MSG 64UL
804
805/* Maximum number of messages */
806#define DBG_DATA_MAX 128UL
807
808static struct {
809 char (buf[DBG_DATA_MAX])[DBG_DATA_MSG]; /* buffer */
810 unsigned idx; /* index */
811 unsigned tty; /* print to console? */
812 rwlock_t lck; /* lock */
813} dbg_dwc3_data = {
814 .idx = 0,
815 .tty = 0,
816 .lck = __RW_LOCK_UNLOCKED(lck)
817};
818
819/**
820 * dbg_dec: decrements debug event index
821 * @idx: buffer index
822 */
823static inline void __maybe_unused dbg_dec(unsigned *idx)
824{
825 *idx = (*idx - 1) % DBG_DATA_MAX;
826}
827
828/**
829 * dbg_inc: increments debug event index
830 * @idx: buffer index
831 */
832static inline void dbg_inc(unsigned *idx)
833{
834 *idx = (*idx + 1) % DBG_DATA_MAX;
835}
836
837#define TIME_BUF_LEN 20
838/*get_timestamp - returns time of day in us */
839static char *get_timestamp(char *tbuf)
840{
841 unsigned long long t;
842 unsigned long nanosec_rem;
843
844 t = cpu_clock(smp_processor_id());
845 nanosec_rem = do_div(t, 1000000000)/1000;
846 scnprintf(tbuf, TIME_BUF_LEN, "[%5lu.%06lu] ", (unsigned long)t,
847 nanosec_rem);
848 return tbuf;
849}
850
851static int allow_dbg_print(u8 ep_num)
852{
853 int dir, num;
854
855 /* allow bus wide events */
856 if (ep_num == 0xff)
857 return 1;
858
859 dir = ep_num & 0x1;
860 num = ep_num >> 1;
861 num = 1 << num;
862
863 if (dir && (num & ep_addr_txdbg_mask))
864 return 1;
865 if (!dir && (num & ep_addr_rxdbg_mask))
866 return 1;
867
868 return 0;
869}
870
871/**
872 * dbg_print: prints the common part of the event
873 * @addr: endpoint address
874 * @name: event name
875 * @status: status
876 * @extra: extra information
877 */
878void dbg_print(u8 ep_num, const char *name, int status, const char *extra)
879{
880 unsigned long flags;
881 char tbuf[TIME_BUF_LEN];
882
883 if (!allow_dbg_print(ep_num))
884 return;
885
886 write_lock_irqsave(&dbg_dwc3_data.lck, flags);
887
888 scnprintf(dbg_dwc3_data.buf[dbg_dwc3_data.idx], DBG_DATA_MSG,
889 "%s\t? %02X %-7.7s %4i ?\t%s\n",
890 get_timestamp(tbuf), ep_num, name, status, extra);
891
892 dbg_inc(&dbg_dwc3_data.idx);
893
894 write_unlock_irqrestore(&dbg_dwc3_data.lck, flags);
895
896 if (dbg_dwc3_data.tty != 0)
897 pr_notice("%s\t? %02X %-7.7s %4i ?\t%s\n",
898 get_timestamp(tbuf), ep_num, name, status, extra);
899}
900
901/**
902 * dbg_done: prints a DONE event
903 * @addr: endpoint address
904 * @td: transfer descriptor
905 * @status: status
906 */
907void dbg_done(u8 ep_num, const u32 count, int status)
908{
909 char msg[DBG_DATA_MSG];
910
911 if (!allow_dbg_print(ep_num))
912 return;
913
914 scnprintf(msg, sizeof(msg), "%d", count);
915 dbg_print(ep_num, "DONE", status, msg);
916}
917
918/**
919 * dbg_event: prints a generic event
920 * @addr: endpoint address
921 * @name: event name
922 * @status: status
923 */
924void dbg_event(u8 ep_num, const char *name, int status)
925{
926 if (!allow_dbg_print(ep_num))
927 return;
928
929 if (name != NULL)
930 dbg_print(ep_num, name, status, "");
931}
932
933/*
934 * dbg_queue: prints a QUEUE event
935 * @addr: endpoint address
936 * @req: USB request
937 * @status: status
938 */
939void dbg_queue(u8 ep_num, const struct usb_request *req, int status)
940{
941 char msg[DBG_DATA_MSG];
942
943 if (!allow_dbg_print(ep_num))
944 return;
945
946 if (req != NULL) {
947 scnprintf(msg, sizeof(msg),
948 "%d %d", !req->no_interrupt, req->length);
949 dbg_print(ep_num, "QUEUE", status, msg);
950 }
951}
952
953/**
954 * dbg_setup: prints a SETUP event
955 * @addr: endpoint address
956 * @req: setup request
957 */
958void dbg_setup(u8 ep_num, const struct usb_ctrlrequest *req)
959{
960 char msg[DBG_DATA_MSG];
961
962 if (!allow_dbg_print(ep_num))
963 return;
964
965 if (req != NULL) {
966 scnprintf(msg, sizeof(msg),
967 "%02X %02X %04X %04X %d", req->bRequestType,
968 req->bRequest, le16_to_cpu(req->wValue),
969 le16_to_cpu(req->wIndex), le16_to_cpu(req->wLength));
970 dbg_print(ep_num, "SETUP", 0, msg);
971 }
972}
973
974/**
975 * store_events: configure if events are going to be also printed to console
976 *
977 */
978static ssize_t dwc3_store_events(struct file *file,
979 const char __user *buf, size_t count, loff_t *ppos)
980{
981 unsigned tty;
982
983 if (buf == NULL) {
984 pr_err("[%s] EINVAL\n", __func__);
985 goto done;
986 }
987
988 if (sscanf(buf, "%u", &tty) != 1 || tty > 1) {
989 pr_err("<1|0>: enable|disable console log\n");
990 goto done;
991 }
992
993 dbg_dwc3_data.tty = tty;
994 pr_info("tty = %u", dbg_dwc3_data.tty);
995
996 done:
997 return count;
998}
999
1000static int dwc3_gadget_data_events_show(struct seq_file *s, void *unused)
1001{
1002 unsigned long flags;
1003 unsigned i;
1004
1005 read_lock_irqsave(&dbg_dwc3_data.lck, flags);
1006
1007 i = dbg_dwc3_data.idx;
1008 if (strnlen(dbg_dwc3_data.buf[i], DBG_DATA_MSG))
1009 seq_printf(s, "%s\n", dbg_dwc3_data.buf[i]);
1010 for (dbg_inc(&i); i != dbg_dwc3_data.idx; dbg_inc(&i)) {
1011 if (!strnlen(dbg_dwc3_data.buf[i], DBG_DATA_MSG))
1012 continue;
1013 seq_printf(s, "%s\n", dbg_dwc3_data.buf[i]);
1014 }
1015
1016 read_unlock_irqrestore(&dbg_dwc3_data.lck, flags);
1017
1018 return 0;
1019}
1020
1021static int dwc3_gadget_data_events_open(struct inode *inode, struct file *f)
1022{
1023 return single_open(f, dwc3_gadget_data_events_show, inode->i_private);
1024}
1025
1026const struct file_operations dwc3_gadget_dbg_data_fops = {
1027 .open = dwc3_gadget_data_events_open,
1028 .read = seq_read,
1029 .write = dwc3_store_events,
1030 .llseek = seq_lseek,
1031 .release = single_release,
1032};
1033
Felipe Balbi72246da2011-08-19 18:10:58 +03001034int __devinit dwc3_debugfs_init(struct dwc3 *dwc)
1035{
1036 struct dentry *root;
1037 struct dentry *file;
1038 int ret;
1039
1040 root = debugfs_create_dir(dev_name(dwc->dev), NULL);
Felipe Balbi3d4c0d42012-01-31 13:33:32 +02001041 if (!root) {
1042 ret = -ENOMEM;
Felipe Balbi72246da2011-08-19 18:10:58 +03001043 goto err0;
1044 }
1045
1046 dwc->root = root;
1047
1048 file = debugfs_create_file("regdump", S_IRUGO, root, dwc,
1049 &dwc3_regdump_fops);
Felipe Balbi3d4c0d42012-01-31 13:33:32 +02001050 if (!file) {
1051 ret = -ENOMEM;
Felipe Balbi72246da2011-08-19 18:10:58 +03001052 goto err1;
1053 }
Felipe Balbi0b9fe322011-10-17 08:50:39 +03001054
1055 file = debugfs_create_file("mode", S_IRUGO | S_IWUSR, root,
1056 dwc, &dwc3_mode_fops);
Felipe Balbi3d4c0d42012-01-31 13:33:32 +02001057 if (!file) {
1058 ret = -ENOMEM;
Felipe Balbi0b9fe322011-10-17 08:50:39 +03001059 goto err1;
1060 }
1061
Felipe Balbi080d9212012-01-02 18:38:30 +02001062 file = debugfs_create_file("testmode", S_IRUGO | S_IWUSR, root,
1063 dwc, &dwc3_testmode_fops);
Felipe Balbi3d4c0d42012-01-31 13:33:32 +02001064 if (!file) {
1065 ret = -ENOMEM;
Felipe Balbi080d9212012-01-02 18:38:30 +02001066 goto err1;
1067 }
1068
Felipe Balbi138801a2012-01-02 19:25:16 +02001069 file = debugfs_create_file("link_state", S_IRUGO | S_IWUSR, root,
1070 dwc, &dwc3_link_state_fops);
Felipe Balbi3d4c0d42012-01-31 13:33:32 +02001071 if (!file) {
1072 ret = -ENOMEM;
Felipe Balbi138801a2012-01-02 19:25:16 +02001073 goto err1;
1074 }
1075
Vijayavardhan Vennapusaffeb26b2013-02-14 16:33:30 +05301076 file = debugfs_create_file("trbs", S_IRUGO | S_IWUSR, root,
1077 dwc, &dwc3_ep_trb_list_fops);
1078 if (!file) {
1079 ret = -ENOMEM;
1080 goto err1;
1081 }
1082
1083 file = debugfs_create_file("requests", S_IRUGO | S_IWUSR, root,
1084 dwc, &dwc3_ep_req_list_fops);
1085 if (!file) {
1086 ret = -ENOMEM;
1087 goto err1;
1088 }
1089
1090 file = debugfs_create_file("queued_reqs", S_IRUGO | S_IWUSR, root,
1091 dwc, &dwc3_ep_req_queued_fops);
1092 if (!file) {
1093 ret = -ENOMEM;
1094 goto err1;
1095 }
1096
1097 file = debugfs_create_file("events", S_IRUGO | S_IWUSR, root,
1098 dwc, &dwc3_gadget_dbg_data_fops);
1099 if (!file) {
1100 ret = -ENOMEM;
1101 goto err1;
1102 }
Felipe Balbi72246da2011-08-19 18:10:58 +03001103 return 0;
1104
1105err1:
1106 debugfs_remove_recursive(root);
1107
1108err0:
1109 return ret;
1110}
1111
1112void __devexit dwc3_debugfs_exit(struct dwc3 *dwc)
1113{
1114 debugfs_remove_recursive(dwc->root);
1115 dwc->root = NULL;
1116}