1 // SPDX-License-Identifier: GPL-2.0 2 /** 3 * debugfs.c - DesignWare USB3 DRD Controller DebugFS file 4 * 5 * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com 6 * 7 * Authors: Felipe Balbi <balbi@ti.com>, 8 * Sebastian Andrzej Siewior <bigeasy@linutronix.de> 9 */ 10 11 #include <linux/kernel.h> 12 #include <linux/slab.h> 13 #include <linux/ptrace.h> 14 #include <linux/types.h> 15 #include <linux/spinlock.h> 16 #include <linux/debugfs.h> 17 #include <linux/seq_file.h> 18 #include <linux/delay.h> 19 #include <linux/uaccess.h> 20 21 #include <linux/usb/ch9.h> 22 23 #include "core.h" 24 #include "gadget.h" 25 #include "io.h" 26 #include "debug.h" 27 28 #define DWC3_LSP_MUX_UNSELECTED 0xfffff 29 30 #define dump_register(nm) \ 31 { \ 32 .name = __stringify(nm), \ 33 .offset = DWC3_ ##nm, \ 34 } 35 36 #define dump_ep_register_set(n) \ 37 { \ 38 .name = "DEPCMDPAR2("__stringify(n)")", \ 39 .offset = DWC3_DEP_BASE(n) + \ 40 DWC3_DEPCMDPAR2, \ 41 }, \ 42 { \ 43 .name = "DEPCMDPAR1("__stringify(n)")", \ 44 .offset = DWC3_DEP_BASE(n) + \ 45 DWC3_DEPCMDPAR1, \ 46 }, \ 47 { \ 48 .name = "DEPCMDPAR0("__stringify(n)")", \ 49 .offset = DWC3_DEP_BASE(n) + \ 50 DWC3_DEPCMDPAR0, \ 51 }, \ 52 { \ 53 .name = "DEPCMD("__stringify(n)")", \ 54 .offset = DWC3_DEP_BASE(n) + \ 55 DWC3_DEPCMD, \ 56 } 57 58 59 static const struct debugfs_reg32 dwc3_regs[] = { 60 dump_register(GSBUSCFG0), 61 dump_register(GSBUSCFG1), 62 dump_register(GTXTHRCFG), 63 dump_register(GRXTHRCFG), 64 dump_register(GCTL), 65 dump_register(GEVTEN), 66 dump_register(GSTS), 67 dump_register(GUCTL1), 68 dump_register(GSNPSID), 69 dump_register(GGPIO), 70 dump_register(GUID), 71 dump_register(GUCTL), 72 dump_register(GBUSERRADDR0), 73 dump_register(GBUSERRADDR1), 74 dump_register(GPRTBIMAP0), 75 dump_register(GPRTBIMAP1), 76 dump_register(GHWPARAMS0), 77 dump_register(GHWPARAMS1), 78 dump_register(GHWPARAMS2), 79 dump_register(GHWPARAMS3), 80 dump_register(GHWPARAMS4), 81 dump_register(GHWPARAMS5), 82 dump_register(GHWPARAMS6), 83 dump_register(GHWPARAMS7), 84 dump_register(GDBGFIFOSPACE), 85 dump_register(GDBGLTSSM), 86 dump_register(GDBGBMU), 87 dump_register(GPRTBIMAP_HS0), 88 dump_register(GPRTBIMAP_HS1), 89 dump_register(GPRTBIMAP_FS0), 90 dump_register(GPRTBIMAP_FS1), 91 92 dump_register(GUSB2PHYCFG(0)), 93 dump_register(GUSB2PHYCFG(1)), 94 dump_register(GUSB2PHYCFG(2)), 95 dump_register(GUSB2PHYCFG(3)), 96 dump_register(GUSB2PHYCFG(4)), 97 dump_register(GUSB2PHYCFG(5)), 98 dump_register(GUSB2PHYCFG(6)), 99 dump_register(GUSB2PHYCFG(7)), 100 dump_register(GUSB2PHYCFG(8)), 101 dump_register(GUSB2PHYCFG(9)), 102 dump_register(GUSB2PHYCFG(10)), 103 dump_register(GUSB2PHYCFG(11)), 104 dump_register(GUSB2PHYCFG(12)), 105 dump_register(GUSB2PHYCFG(13)), 106 dump_register(GUSB2PHYCFG(14)), 107 dump_register(GUSB2PHYCFG(15)), 108 109 dump_register(GUSB2I2CCTL(0)), 110 dump_register(GUSB2I2CCTL(1)), 111 dump_register(GUSB2I2CCTL(2)), 112 dump_register(GUSB2I2CCTL(3)), 113 dump_register(GUSB2I2CCTL(4)), 114 dump_register(GUSB2I2CCTL(5)), 115 dump_register(GUSB2I2CCTL(6)), 116 dump_register(GUSB2I2CCTL(7)), 117 dump_register(GUSB2I2CCTL(8)), 118 dump_register(GUSB2I2CCTL(9)), 119 dump_register(GUSB2I2CCTL(10)), 120 dump_register(GUSB2I2CCTL(11)), 121 dump_register(GUSB2I2CCTL(12)), 122 dump_register(GUSB2I2CCTL(13)), 123 dump_register(GUSB2I2CCTL(14)), 124 dump_register(GUSB2I2CCTL(15)), 125 126 dump_register(GUSB2PHYACC(0)), 127 dump_register(GUSB2PHYACC(1)), 128 dump_register(GUSB2PHYACC(2)), 129 dump_register(GUSB2PHYACC(3)), 130 dump_register(GUSB2PHYACC(4)), 131 dump_register(GUSB2PHYACC(5)), 132 dump_register(GUSB2PHYACC(6)), 133 dump_register(GUSB2PHYACC(7)), 134 dump_register(GUSB2PHYACC(8)), 135 dump_register(GUSB2PHYACC(9)), 136 dump_register(GUSB2PHYACC(10)), 137 dump_register(GUSB2PHYACC(11)), 138 dump_register(GUSB2PHYACC(12)), 139 dump_register(GUSB2PHYACC(13)), 140 dump_register(GUSB2PHYACC(14)), 141 dump_register(GUSB2PHYACC(15)), 142 143 dump_register(GUSB3PIPECTL(0)), 144 dump_register(GUSB3PIPECTL(1)), 145 dump_register(GUSB3PIPECTL(2)), 146 dump_register(GUSB3PIPECTL(3)), 147 dump_register(GUSB3PIPECTL(4)), 148 dump_register(GUSB3PIPECTL(5)), 149 dump_register(GUSB3PIPECTL(6)), 150 dump_register(GUSB3PIPECTL(7)), 151 dump_register(GUSB3PIPECTL(8)), 152 dump_register(GUSB3PIPECTL(9)), 153 dump_register(GUSB3PIPECTL(10)), 154 dump_register(GUSB3PIPECTL(11)), 155 dump_register(GUSB3PIPECTL(12)), 156 dump_register(GUSB3PIPECTL(13)), 157 dump_register(GUSB3PIPECTL(14)), 158 dump_register(GUSB3PIPECTL(15)), 159 160 dump_register(GTXFIFOSIZ(0)), 161 dump_register(GTXFIFOSIZ(1)), 162 dump_register(GTXFIFOSIZ(2)), 163 dump_register(GTXFIFOSIZ(3)), 164 dump_register(GTXFIFOSIZ(4)), 165 dump_register(GTXFIFOSIZ(5)), 166 dump_register(GTXFIFOSIZ(6)), 167 dump_register(GTXFIFOSIZ(7)), 168 dump_register(GTXFIFOSIZ(8)), 169 dump_register(GTXFIFOSIZ(9)), 170 dump_register(GTXFIFOSIZ(10)), 171 dump_register(GTXFIFOSIZ(11)), 172 dump_register(GTXFIFOSIZ(12)), 173 dump_register(GTXFIFOSIZ(13)), 174 dump_register(GTXFIFOSIZ(14)), 175 dump_register(GTXFIFOSIZ(15)), 176 dump_register(GTXFIFOSIZ(16)), 177 dump_register(GTXFIFOSIZ(17)), 178 dump_register(GTXFIFOSIZ(18)), 179 dump_register(GTXFIFOSIZ(19)), 180 dump_register(GTXFIFOSIZ(20)), 181 dump_register(GTXFIFOSIZ(21)), 182 dump_register(GTXFIFOSIZ(22)), 183 dump_register(GTXFIFOSIZ(23)), 184 dump_register(GTXFIFOSIZ(24)), 185 dump_register(GTXFIFOSIZ(25)), 186 dump_register(GTXFIFOSIZ(26)), 187 dump_register(GTXFIFOSIZ(27)), 188 dump_register(GTXFIFOSIZ(28)), 189 dump_register(GTXFIFOSIZ(29)), 190 dump_register(GTXFIFOSIZ(30)), 191 dump_register(GTXFIFOSIZ(31)), 192 193 dump_register(GRXFIFOSIZ(0)), 194 dump_register(GRXFIFOSIZ(1)), 195 dump_register(GRXFIFOSIZ(2)), 196 dump_register(GRXFIFOSIZ(3)), 197 dump_register(GRXFIFOSIZ(4)), 198 dump_register(GRXFIFOSIZ(5)), 199 dump_register(GRXFIFOSIZ(6)), 200 dump_register(GRXFIFOSIZ(7)), 201 dump_register(GRXFIFOSIZ(8)), 202 dump_register(GRXFIFOSIZ(9)), 203 dump_register(GRXFIFOSIZ(10)), 204 dump_register(GRXFIFOSIZ(11)), 205 dump_register(GRXFIFOSIZ(12)), 206 dump_register(GRXFIFOSIZ(13)), 207 dump_register(GRXFIFOSIZ(14)), 208 dump_register(GRXFIFOSIZ(15)), 209 dump_register(GRXFIFOSIZ(16)), 210 dump_register(GRXFIFOSIZ(17)), 211 dump_register(GRXFIFOSIZ(18)), 212 dump_register(GRXFIFOSIZ(19)), 213 dump_register(GRXFIFOSIZ(20)), 214 dump_register(GRXFIFOSIZ(21)), 215 dump_register(GRXFIFOSIZ(22)), 216 dump_register(GRXFIFOSIZ(23)), 217 dump_register(GRXFIFOSIZ(24)), 218 dump_register(GRXFIFOSIZ(25)), 219 dump_register(GRXFIFOSIZ(26)), 220 dump_register(GRXFIFOSIZ(27)), 221 dump_register(GRXFIFOSIZ(28)), 222 dump_register(GRXFIFOSIZ(29)), 223 dump_register(GRXFIFOSIZ(30)), 224 dump_register(GRXFIFOSIZ(31)), 225 226 dump_register(GEVNTADRLO(0)), 227 dump_register(GEVNTADRHI(0)), 228 dump_register(GEVNTSIZ(0)), 229 dump_register(GEVNTCOUNT(0)), 230 231 dump_register(GHWPARAMS8), 232 dump_register(DCFG), 233 dump_register(DCTL), 234 dump_register(DEVTEN), 235 dump_register(DSTS), 236 dump_register(DGCMDPAR), 237 dump_register(DGCMD), 238 dump_register(DALEPENA), 239 240 dump_ep_register_set(0), 241 dump_ep_register_set(1), 242 dump_ep_register_set(2), 243 dump_ep_register_set(3), 244 dump_ep_register_set(4), 245 dump_ep_register_set(5), 246 dump_ep_register_set(6), 247 dump_ep_register_set(7), 248 dump_ep_register_set(8), 249 dump_ep_register_set(9), 250 dump_ep_register_set(10), 251 dump_ep_register_set(11), 252 dump_ep_register_set(12), 253 dump_ep_register_set(13), 254 dump_ep_register_set(14), 255 dump_ep_register_set(15), 256 dump_ep_register_set(16), 257 dump_ep_register_set(17), 258 dump_ep_register_set(18), 259 dump_ep_register_set(19), 260 dump_ep_register_set(20), 261 dump_ep_register_set(21), 262 dump_ep_register_set(22), 263 dump_ep_register_set(23), 264 dump_ep_register_set(24), 265 dump_ep_register_set(25), 266 dump_ep_register_set(26), 267 dump_ep_register_set(27), 268 dump_ep_register_set(28), 269 dump_ep_register_set(29), 270 dump_ep_register_set(30), 271 dump_ep_register_set(31), 272 273 dump_register(OCFG), 274 dump_register(OCTL), 275 dump_register(OEVT), 276 dump_register(OEVTEN), 277 dump_register(OSTS), 278 }; 279 280 static void dwc3_host_lsp(struct seq_file *s) 281 { 282 struct dwc3 *dwc = s->private; 283 bool dbc_enabled; 284 u32 sel; 285 u32 reg; 286 u32 val; 287 288 dbc_enabled = !!(dwc->hwparams.hwparams1 & DWC3_GHWPARAMS1_ENDBC); 289 290 sel = dwc->dbg_lsp_select; 291 if (sel == DWC3_LSP_MUX_UNSELECTED) { 292 seq_puts(s, "Write LSP selection to print for host\n"); 293 return; 294 } 295 296 reg = DWC3_GDBGLSPMUX_HOSTSELECT(sel); 297 298 dwc3_writel(dwc->regs, DWC3_GDBGLSPMUX, reg); 299 val = dwc3_readl(dwc->regs, DWC3_GDBGLSP); 300 seq_printf(s, "GDBGLSP[%d] = 0x%08x\n", sel, val); 301 302 if (dbc_enabled && sel < 256) { 303 reg |= DWC3_GDBGLSPMUX_ENDBC; 304 dwc3_writel(dwc->regs, DWC3_GDBGLSPMUX, reg); 305 val = dwc3_readl(dwc->regs, DWC3_GDBGLSP); 306 seq_printf(s, "GDBGLSP_DBC[%d] = 0x%08x\n", sel, val); 307 } 308 } 309 310 static void dwc3_gadget_lsp(struct seq_file *s) 311 { 312 struct dwc3 *dwc = s->private; 313 int i; 314 u32 reg; 315 316 for (i = 0; i < 16; i++) { 317 reg = DWC3_GDBGLSPMUX_DEVSELECT(i); 318 dwc3_writel(dwc->regs, DWC3_GDBGLSPMUX, reg); 319 reg = dwc3_readl(dwc->regs, DWC3_GDBGLSP); 320 seq_printf(s, "GDBGLSP[%d] = 0x%08x\n", i, reg); 321 } 322 } 323 324 static int dwc3_lsp_show(struct seq_file *s, void *unused) 325 { 326 struct dwc3 *dwc = s->private; 327 unsigned int current_mode; 328 unsigned long flags; 329 u32 reg; 330 331 spin_lock_irqsave(&dwc->lock, flags); 332 reg = dwc3_readl(dwc->regs, DWC3_GSTS); 333 current_mode = DWC3_GSTS_CURMOD(reg); 334 335 switch (current_mode) { 336 case DWC3_GSTS_CURMOD_HOST: 337 dwc3_host_lsp(s); 338 break; 339 case DWC3_GSTS_CURMOD_DEVICE: 340 dwc3_gadget_lsp(s); 341 break; 342 default: 343 seq_puts(s, "Mode is unknown, no LSP register printed\n"); 344 break; 345 } 346 spin_unlock_irqrestore(&dwc->lock, flags); 347 348 return 0; 349 } 350 351 static int dwc3_lsp_open(struct inode *inode, struct file *file) 352 { 353 return single_open(file, dwc3_lsp_show, inode->i_private); 354 } 355 356 static ssize_t dwc3_lsp_write(struct file *file, const char __user *ubuf, 357 size_t count, loff_t *ppos) 358 { 359 struct seq_file *s = file->private_data; 360 struct dwc3 *dwc = s->private; 361 unsigned long flags; 362 char buf[32] = { 0 }; 363 u32 sel; 364 int ret; 365 366 if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) 367 return -EFAULT; 368 369 ret = kstrtouint(buf, 0, &sel); 370 if (ret) 371 return ret; 372 373 spin_lock_irqsave(&dwc->lock, flags); 374 dwc->dbg_lsp_select = sel; 375 spin_unlock_irqrestore(&dwc->lock, flags); 376 377 return count; 378 } 379 380 static const struct file_operations dwc3_lsp_fops = { 381 .open = dwc3_lsp_open, 382 .write = dwc3_lsp_write, 383 .read = seq_read, 384 .llseek = seq_lseek, 385 .release = single_release, 386 }; 387 388 static int dwc3_mode_show(struct seq_file *s, void *unused) 389 { 390 struct dwc3 *dwc = s->private; 391 unsigned long flags; 392 u32 reg; 393 394 spin_lock_irqsave(&dwc->lock, flags); 395 reg = dwc3_readl(dwc->regs, DWC3_GCTL); 396 spin_unlock_irqrestore(&dwc->lock, flags); 397 398 switch (DWC3_GCTL_PRTCAP(reg)) { 399 case DWC3_GCTL_PRTCAP_HOST: 400 seq_printf(s, "host\n"); 401 break; 402 case DWC3_GCTL_PRTCAP_DEVICE: 403 seq_printf(s, "device\n"); 404 break; 405 case DWC3_GCTL_PRTCAP_OTG: 406 seq_printf(s, "otg\n"); 407 break; 408 default: 409 seq_printf(s, "UNKNOWN %08x\n", DWC3_GCTL_PRTCAP(reg)); 410 } 411 412 return 0; 413 } 414 415 static int dwc3_mode_open(struct inode *inode, struct file *file) 416 { 417 return single_open(file, dwc3_mode_show, inode->i_private); 418 } 419 420 static ssize_t dwc3_mode_write(struct file *file, 421 const char __user *ubuf, size_t count, loff_t *ppos) 422 { 423 struct seq_file *s = file->private_data; 424 struct dwc3 *dwc = s->private; 425 u32 mode = 0; 426 char buf[32]; 427 428 if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) 429 return -EFAULT; 430 431 if (!strncmp(buf, "host", 4)) 432 mode = DWC3_GCTL_PRTCAP_HOST; 433 434 if (!strncmp(buf, "device", 6)) 435 mode = DWC3_GCTL_PRTCAP_DEVICE; 436 437 if (!strncmp(buf, "otg", 3)) 438 mode = DWC3_GCTL_PRTCAP_OTG; 439 440 dwc3_set_mode(dwc, mode); 441 442 return count; 443 } 444 445 static const struct file_operations dwc3_mode_fops = { 446 .open = dwc3_mode_open, 447 .write = dwc3_mode_write, 448 .read = seq_read, 449 .llseek = seq_lseek, 450 .release = single_release, 451 }; 452 453 static int dwc3_testmode_show(struct seq_file *s, void *unused) 454 { 455 struct dwc3 *dwc = s->private; 456 unsigned long flags; 457 u32 reg; 458 459 spin_lock_irqsave(&dwc->lock, flags); 460 reg = dwc3_readl(dwc->regs, DWC3_DCTL); 461 reg &= DWC3_DCTL_TSTCTRL_MASK; 462 reg >>= 1; 463 spin_unlock_irqrestore(&dwc->lock, flags); 464 465 switch (reg) { 466 case 0: 467 seq_printf(s, "no test\n"); 468 break; 469 case TEST_J: 470 seq_printf(s, "test_j\n"); 471 break; 472 case TEST_K: 473 seq_printf(s, "test_k\n"); 474 break; 475 case TEST_SE0_NAK: 476 seq_printf(s, "test_se0_nak\n"); 477 break; 478 case TEST_PACKET: 479 seq_printf(s, "test_packet\n"); 480 break; 481 case TEST_FORCE_EN: 482 seq_printf(s, "test_force_enable\n"); 483 break; 484 default: 485 seq_printf(s, "UNKNOWN %d\n", reg); 486 } 487 488 return 0; 489 } 490 491 static int dwc3_testmode_open(struct inode *inode, struct file *file) 492 { 493 return single_open(file, dwc3_testmode_show, inode->i_private); 494 } 495 496 static ssize_t dwc3_testmode_write(struct file *file, 497 const char __user *ubuf, size_t count, loff_t *ppos) 498 { 499 struct seq_file *s = file->private_data; 500 struct dwc3 *dwc = s->private; 501 unsigned long flags; 502 u32 testmode = 0; 503 char buf[32]; 504 505 if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) 506 return -EFAULT; 507 508 if (!strncmp(buf, "test_j", 6)) 509 testmode = TEST_J; 510 else if (!strncmp(buf, "test_k", 6)) 511 testmode = TEST_K; 512 else if (!strncmp(buf, "test_se0_nak", 12)) 513 testmode = TEST_SE0_NAK; 514 else if (!strncmp(buf, "test_packet", 11)) 515 testmode = TEST_PACKET; 516 else if (!strncmp(buf, "test_force_enable", 17)) 517 testmode = TEST_FORCE_EN; 518 else 519 testmode = 0; 520 521 spin_lock_irqsave(&dwc->lock, flags); 522 dwc3_gadget_set_test_mode(dwc, testmode); 523 spin_unlock_irqrestore(&dwc->lock, flags); 524 525 return count; 526 } 527 528 static const struct file_operations dwc3_testmode_fops = { 529 .open = dwc3_testmode_open, 530 .write = dwc3_testmode_write, 531 .read = seq_read, 532 .llseek = seq_lseek, 533 .release = single_release, 534 }; 535 536 static int dwc3_link_state_show(struct seq_file *s, void *unused) 537 { 538 struct dwc3 *dwc = s->private; 539 unsigned long flags; 540 enum dwc3_link_state state; 541 u32 reg; 542 u8 speed; 543 544 spin_lock_irqsave(&dwc->lock, flags); 545 reg = dwc3_readl(dwc->regs, DWC3_GSTS); 546 if (DWC3_GSTS_CURMOD(reg) != DWC3_GSTS_CURMOD_DEVICE) { 547 seq_puts(s, "Not available\n"); 548 spin_unlock_irqrestore(&dwc->lock, flags); 549 return 0; 550 } 551 552 reg = dwc3_readl(dwc->regs, DWC3_DSTS); 553 state = DWC3_DSTS_USBLNKST(reg); 554 speed = reg & DWC3_DSTS_CONNECTSPD; 555 556 seq_printf(s, "%s\n", (speed >= DWC3_DSTS_SUPERSPEED) ? 557 dwc3_gadget_link_string(state) : 558 dwc3_gadget_hs_link_string(state)); 559 spin_unlock_irqrestore(&dwc->lock, flags); 560 561 return 0; 562 } 563 564 static int dwc3_link_state_open(struct inode *inode, struct file *file) 565 { 566 return single_open(file, dwc3_link_state_show, inode->i_private); 567 } 568 569 static ssize_t dwc3_link_state_write(struct file *file, 570 const char __user *ubuf, size_t count, loff_t *ppos) 571 { 572 struct seq_file *s = file->private_data; 573 struct dwc3 *dwc = s->private; 574 unsigned long flags; 575 enum dwc3_link_state state = 0; 576 char buf[32]; 577 u32 reg; 578 u8 speed; 579 580 if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) 581 return -EFAULT; 582 583 if (!strncmp(buf, "SS.Disabled", 11)) 584 state = DWC3_LINK_STATE_SS_DIS; 585 else if (!strncmp(buf, "Rx.Detect", 9)) 586 state = DWC3_LINK_STATE_RX_DET; 587 else if (!strncmp(buf, "SS.Inactive", 11)) 588 state = DWC3_LINK_STATE_SS_INACT; 589 else if (!strncmp(buf, "Recovery", 8)) 590 state = DWC3_LINK_STATE_RECOV; 591 else if (!strncmp(buf, "Compliance", 10)) 592 state = DWC3_LINK_STATE_CMPLY; 593 else if (!strncmp(buf, "Loopback", 8)) 594 state = DWC3_LINK_STATE_LPBK; 595 else 596 return -EINVAL; 597 598 spin_lock_irqsave(&dwc->lock, flags); 599 reg = dwc3_readl(dwc->regs, DWC3_GSTS); 600 if (DWC3_GSTS_CURMOD(reg) != DWC3_GSTS_CURMOD_DEVICE) { 601 spin_unlock_irqrestore(&dwc->lock, flags); 602 return -EINVAL; 603 } 604 605 reg = dwc3_readl(dwc->regs, DWC3_DSTS); 606 speed = reg & DWC3_DSTS_CONNECTSPD; 607 608 if (speed < DWC3_DSTS_SUPERSPEED && 609 state != DWC3_LINK_STATE_RECOV) { 610 spin_unlock_irqrestore(&dwc->lock, flags); 611 return -EINVAL; 612 } 613 614 dwc3_gadget_set_link_state(dwc, state); 615 spin_unlock_irqrestore(&dwc->lock, flags); 616 617 return count; 618 } 619 620 static const struct file_operations dwc3_link_state_fops = { 621 .open = dwc3_link_state_open, 622 .write = dwc3_link_state_write, 623 .read = seq_read, 624 .llseek = seq_lseek, 625 .release = single_release, 626 }; 627 628 struct dwc3_ep_file_map { 629 const char name[25]; 630 const struct file_operations *const fops; 631 }; 632 633 static int dwc3_tx_fifo_size_show(struct seq_file *s, void *unused) 634 { 635 struct dwc3_ep *dep = s->private; 636 struct dwc3 *dwc = dep->dwc; 637 unsigned long flags; 638 int mdwidth; 639 u32 val; 640 641 spin_lock_irqsave(&dwc->lock, flags); 642 val = dwc3_core_fifo_space(dep, DWC3_TXFIFO); 643 644 /* Convert to bytes */ 645 mdwidth = DWC3_MDWIDTH(dwc->hwparams.hwparams0); 646 if (DWC3_IP_IS(DWC32)) 647 mdwidth += DWC3_GHWPARAMS6_MDWIDTH(dwc->hwparams.hwparams6); 648 649 val *= mdwidth; 650 val >>= 3; 651 seq_printf(s, "%u\n", val); 652 spin_unlock_irqrestore(&dwc->lock, flags); 653 654 return 0; 655 } 656 657 static int dwc3_rx_fifo_size_show(struct seq_file *s, void *unused) 658 { 659 struct dwc3_ep *dep = s->private; 660 struct dwc3 *dwc = dep->dwc; 661 unsigned long flags; 662 int mdwidth; 663 u32 val; 664 665 spin_lock_irqsave(&dwc->lock, flags); 666 val = dwc3_core_fifo_space(dep, DWC3_RXFIFO); 667 668 /* Convert to bytes */ 669 mdwidth = DWC3_MDWIDTH(dwc->hwparams.hwparams0); 670 if (DWC3_IP_IS(DWC32)) 671 mdwidth += DWC3_GHWPARAMS6_MDWIDTH(dwc->hwparams.hwparams6); 672 673 val *= mdwidth; 674 val >>= 3; 675 seq_printf(s, "%u\n", val); 676 spin_unlock_irqrestore(&dwc->lock, flags); 677 678 return 0; 679 } 680 681 static int dwc3_tx_request_queue_show(struct seq_file *s, void *unused) 682 { 683 struct dwc3_ep *dep = s->private; 684 struct dwc3 *dwc = dep->dwc; 685 unsigned long flags; 686 u32 val; 687 688 spin_lock_irqsave(&dwc->lock, flags); 689 val = dwc3_core_fifo_space(dep, DWC3_TXREQQ); 690 seq_printf(s, "%u\n", val); 691 spin_unlock_irqrestore(&dwc->lock, flags); 692 693 return 0; 694 } 695 696 static int dwc3_rx_request_queue_show(struct seq_file *s, void *unused) 697 { 698 struct dwc3_ep *dep = s->private; 699 struct dwc3 *dwc = dep->dwc; 700 unsigned long flags; 701 u32 val; 702 703 spin_lock_irqsave(&dwc->lock, flags); 704 val = dwc3_core_fifo_space(dep, DWC3_RXREQQ); 705 seq_printf(s, "%u\n", val); 706 spin_unlock_irqrestore(&dwc->lock, flags); 707 708 return 0; 709 } 710 711 static int dwc3_rx_info_queue_show(struct seq_file *s, void *unused) 712 { 713 struct dwc3_ep *dep = s->private; 714 struct dwc3 *dwc = dep->dwc; 715 unsigned long flags; 716 u32 val; 717 718 spin_lock_irqsave(&dwc->lock, flags); 719 val = dwc3_core_fifo_space(dep, DWC3_RXINFOQ); 720 seq_printf(s, "%u\n", val); 721 spin_unlock_irqrestore(&dwc->lock, flags); 722 723 return 0; 724 } 725 726 static int dwc3_descriptor_fetch_queue_show(struct seq_file *s, void *unused) 727 { 728 struct dwc3_ep *dep = s->private; 729 struct dwc3 *dwc = dep->dwc; 730 unsigned long flags; 731 u32 val; 732 733 spin_lock_irqsave(&dwc->lock, flags); 734 val = dwc3_core_fifo_space(dep, DWC3_DESCFETCHQ); 735 seq_printf(s, "%u\n", val); 736 spin_unlock_irqrestore(&dwc->lock, flags); 737 738 return 0; 739 } 740 741 static int dwc3_event_queue_show(struct seq_file *s, void *unused) 742 { 743 struct dwc3_ep *dep = s->private; 744 struct dwc3 *dwc = dep->dwc; 745 unsigned long flags; 746 u32 val; 747 748 spin_lock_irqsave(&dwc->lock, flags); 749 val = dwc3_core_fifo_space(dep, DWC3_EVENTQ); 750 seq_printf(s, "%u\n", val); 751 spin_unlock_irqrestore(&dwc->lock, flags); 752 753 return 0; 754 } 755 756 static int dwc3_transfer_type_show(struct seq_file *s, void *unused) 757 { 758 struct dwc3_ep *dep = s->private; 759 struct dwc3 *dwc = dep->dwc; 760 unsigned long flags; 761 762 spin_lock_irqsave(&dwc->lock, flags); 763 if (!(dep->flags & DWC3_EP_ENABLED) || 764 !dep->endpoint.desc) { 765 seq_printf(s, "--\n"); 766 goto out; 767 } 768 769 switch (usb_endpoint_type(dep->endpoint.desc)) { 770 case USB_ENDPOINT_XFER_CONTROL: 771 seq_printf(s, "control\n"); 772 break; 773 case USB_ENDPOINT_XFER_ISOC: 774 seq_printf(s, "isochronous\n"); 775 break; 776 case USB_ENDPOINT_XFER_BULK: 777 seq_printf(s, "bulk\n"); 778 break; 779 case USB_ENDPOINT_XFER_INT: 780 seq_printf(s, "interrupt\n"); 781 break; 782 default: 783 seq_printf(s, "--\n"); 784 } 785 786 out: 787 spin_unlock_irqrestore(&dwc->lock, flags); 788 789 return 0; 790 } 791 792 static int dwc3_trb_ring_show(struct seq_file *s, void *unused) 793 { 794 struct dwc3_ep *dep = s->private; 795 struct dwc3 *dwc = dep->dwc; 796 unsigned long flags; 797 int i; 798 799 spin_lock_irqsave(&dwc->lock, flags); 800 if (dep->number <= 1) { 801 seq_printf(s, "--\n"); 802 goto out; 803 } 804 805 seq_printf(s, "buffer_addr,size,type,ioc,isp_imi,csp,chn,lst,hwo\n"); 806 807 for (i = 0; i < DWC3_TRB_NUM; i++) { 808 struct dwc3_trb *trb = &dep->trb_pool[i]; 809 unsigned int type = DWC3_TRBCTL_TYPE(trb->ctrl); 810 811 seq_printf(s, "%08x%08x,%d,%s,%d,%d,%d,%d,%d,%d %c%c\n", 812 trb->bph, trb->bpl, trb->size, 813 dwc3_trb_type_string(type), 814 !!(trb->ctrl & DWC3_TRB_CTRL_IOC), 815 !!(trb->ctrl & DWC3_TRB_CTRL_ISP_IMI), 816 !!(trb->ctrl & DWC3_TRB_CTRL_CSP), 817 !!(trb->ctrl & DWC3_TRB_CTRL_CHN), 818 !!(trb->ctrl & DWC3_TRB_CTRL_LST), 819 !!(trb->ctrl & DWC3_TRB_CTRL_HWO), 820 dep->trb_enqueue == i ? 'E' : ' ', 821 dep->trb_dequeue == i ? 'D' : ' '); 822 } 823 824 out: 825 spin_unlock_irqrestore(&dwc->lock, flags); 826 827 return 0; 828 } 829 830 static int dwc3_ep_info_register_show(struct seq_file *s, void *unused) 831 { 832 struct dwc3_ep *dep = s->private; 833 struct dwc3 *dwc = dep->dwc; 834 unsigned long flags; 835 u64 ep_info; 836 u32 lower_32_bits; 837 u32 upper_32_bits; 838 u32 reg; 839 840 spin_lock_irqsave(&dwc->lock, flags); 841 reg = DWC3_GDBGLSPMUX_EPSELECT(dep->number); 842 dwc3_writel(dwc->regs, DWC3_GDBGLSPMUX, reg); 843 844 lower_32_bits = dwc3_readl(dwc->regs, DWC3_GDBGEPINFO0); 845 upper_32_bits = dwc3_readl(dwc->regs, DWC3_GDBGEPINFO1); 846 847 ep_info = ((u64)upper_32_bits << 32) | lower_32_bits; 848 seq_printf(s, "0x%016llx\n", ep_info); 849 spin_unlock_irqrestore(&dwc->lock, flags); 850 851 return 0; 852 } 853 854 DEFINE_SHOW_ATTRIBUTE(dwc3_tx_fifo_size); 855 DEFINE_SHOW_ATTRIBUTE(dwc3_rx_fifo_size); 856 DEFINE_SHOW_ATTRIBUTE(dwc3_tx_request_queue); 857 DEFINE_SHOW_ATTRIBUTE(dwc3_rx_request_queue); 858 DEFINE_SHOW_ATTRIBUTE(dwc3_rx_info_queue); 859 DEFINE_SHOW_ATTRIBUTE(dwc3_descriptor_fetch_queue); 860 DEFINE_SHOW_ATTRIBUTE(dwc3_event_queue); 861 DEFINE_SHOW_ATTRIBUTE(dwc3_transfer_type); 862 DEFINE_SHOW_ATTRIBUTE(dwc3_trb_ring); 863 DEFINE_SHOW_ATTRIBUTE(dwc3_ep_info_register); 864 865 static const struct dwc3_ep_file_map dwc3_ep_file_map[] = { 866 { "tx_fifo_size", &dwc3_tx_fifo_size_fops, }, 867 { "rx_fifo_size", &dwc3_rx_fifo_size_fops, }, 868 { "tx_request_queue", &dwc3_tx_request_queue_fops, }, 869 { "rx_request_queue", &dwc3_rx_request_queue_fops, }, 870 { "rx_info_queue", &dwc3_rx_info_queue_fops, }, 871 { "descriptor_fetch_queue", &dwc3_descriptor_fetch_queue_fops, }, 872 { "event_queue", &dwc3_event_queue_fops, }, 873 { "transfer_type", &dwc3_transfer_type_fops, }, 874 { "trb_ring", &dwc3_trb_ring_fops, }, 875 { "GDBGEPINFO", &dwc3_ep_info_register_fops, }, 876 }; 877 878 static void dwc3_debugfs_create_endpoint_files(struct dwc3_ep *dep, 879 struct dentry *parent) 880 { 881 int i; 882 883 for (i = 0; i < ARRAY_SIZE(dwc3_ep_file_map); i++) { 884 const struct file_operations *fops = dwc3_ep_file_map[i].fops; 885 const char *name = dwc3_ep_file_map[i].name; 886 887 debugfs_create_file(name, S_IRUGO, parent, dep, fops); 888 } 889 } 890 891 static void dwc3_debugfs_create_endpoint_dir(struct dwc3_ep *dep, 892 struct dentry *parent) 893 { 894 struct dentry *dir; 895 896 dir = debugfs_create_dir(dep->name, parent); 897 dwc3_debugfs_create_endpoint_files(dep, dir); 898 } 899 900 static void dwc3_debugfs_create_endpoint_dirs(struct dwc3 *dwc, 901 struct dentry *parent) 902 { 903 int i; 904 905 for (i = 0; i < dwc->num_eps; i++) { 906 struct dwc3_ep *dep = dwc->eps[i]; 907 908 if (!dep) 909 continue; 910 911 dwc3_debugfs_create_endpoint_dir(dep, parent); 912 } 913 } 914 915 void dwc3_debugfs_init(struct dwc3 *dwc) 916 { 917 struct dentry *root; 918 919 dwc->regset = kzalloc(sizeof(*dwc->regset), GFP_KERNEL); 920 if (!dwc->regset) 921 return; 922 923 dwc->dbg_lsp_select = DWC3_LSP_MUX_UNSELECTED; 924 925 dwc->regset->regs = dwc3_regs; 926 dwc->regset->nregs = ARRAY_SIZE(dwc3_regs); 927 dwc->regset->base = dwc->regs - DWC3_GLOBALS_REGS_START; 928 929 root = debugfs_create_dir(dev_name(dwc->dev), usb_debug_root); 930 dwc->root = root; 931 932 debugfs_create_regset32("regdump", S_IRUGO, root, dwc->regset); 933 934 debugfs_create_file("lsp_dump", S_IRUGO | S_IWUSR, root, dwc, 935 &dwc3_lsp_fops); 936 937 if (IS_ENABLED(CONFIG_USB_DWC3_DUAL_ROLE)) { 938 debugfs_create_file("mode", S_IRUGO | S_IWUSR, root, dwc, 939 &dwc3_mode_fops); 940 } 941 942 if (IS_ENABLED(CONFIG_USB_DWC3_DUAL_ROLE) || 943 IS_ENABLED(CONFIG_USB_DWC3_GADGET)) { 944 debugfs_create_file("testmode", S_IRUGO | S_IWUSR, root, dwc, 945 &dwc3_testmode_fops); 946 debugfs_create_file("link_state", S_IRUGO | S_IWUSR, root, dwc, 947 &dwc3_link_state_fops); 948 dwc3_debugfs_create_endpoint_dirs(dwc, root); 949 } 950 } 951 952 void dwc3_debugfs_exit(struct dwc3 *dwc) 953 { 954 debugfs_remove_recursive(dwc->root); 955 kfree(dwc->regset); 956 } 957