debugfs.c (23715B)
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 - https://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 59static 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 280static 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 310static 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 324static 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 351static int dwc3_lsp_open(struct inode *inode, struct file *file) 352{ 353 return single_open(file, dwc3_lsp_show, inode->i_private); 354} 355 356static 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 380static 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 388static 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_puts(s, "host\n"); 401 break; 402 case DWC3_GCTL_PRTCAP_DEVICE: 403 seq_puts(s, "device\n"); 404 break; 405 case DWC3_GCTL_PRTCAP_OTG: 406 seq_puts(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 415static int dwc3_mode_open(struct inode *inode, struct file *file) 416{ 417 return single_open(file, dwc3_mode_show, inode->i_private); 418} 419 420static 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 (dwc->dr_mode != USB_DR_MODE_OTG) 432 return count; 433 434 if (!strncmp(buf, "host", 4)) 435 mode = DWC3_GCTL_PRTCAP_HOST; 436 437 if (!strncmp(buf, "device", 6)) 438 mode = DWC3_GCTL_PRTCAP_DEVICE; 439 440 if (!strncmp(buf, "otg", 3)) 441 mode = DWC3_GCTL_PRTCAP_OTG; 442 443 dwc3_set_mode(dwc, mode); 444 445 return count; 446} 447 448static const struct file_operations dwc3_mode_fops = { 449 .open = dwc3_mode_open, 450 .write = dwc3_mode_write, 451 .read = seq_read, 452 .llseek = seq_lseek, 453 .release = single_release, 454}; 455 456static int dwc3_testmode_show(struct seq_file *s, void *unused) 457{ 458 struct dwc3 *dwc = s->private; 459 unsigned long flags; 460 u32 reg; 461 462 spin_lock_irqsave(&dwc->lock, flags); 463 reg = dwc3_readl(dwc->regs, DWC3_DCTL); 464 reg &= DWC3_DCTL_TSTCTRL_MASK; 465 reg >>= 1; 466 spin_unlock_irqrestore(&dwc->lock, flags); 467 468 switch (reg) { 469 case 0: 470 seq_puts(s, "no test\n"); 471 break; 472 case USB_TEST_J: 473 seq_puts(s, "test_j\n"); 474 break; 475 case USB_TEST_K: 476 seq_puts(s, "test_k\n"); 477 break; 478 case USB_TEST_SE0_NAK: 479 seq_puts(s, "test_se0_nak\n"); 480 break; 481 case USB_TEST_PACKET: 482 seq_puts(s, "test_packet\n"); 483 break; 484 case USB_TEST_FORCE_ENABLE: 485 seq_puts(s, "test_force_enable\n"); 486 break; 487 default: 488 seq_printf(s, "UNKNOWN %d\n", reg); 489 } 490 491 return 0; 492} 493 494static int dwc3_testmode_open(struct inode *inode, struct file *file) 495{ 496 return single_open(file, dwc3_testmode_show, inode->i_private); 497} 498 499static ssize_t dwc3_testmode_write(struct file *file, 500 const char __user *ubuf, size_t count, loff_t *ppos) 501{ 502 struct seq_file *s = file->private_data; 503 struct dwc3 *dwc = s->private; 504 unsigned long flags; 505 u32 testmode = 0; 506 char buf[32]; 507 508 if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) 509 return -EFAULT; 510 511 if (!strncmp(buf, "test_j", 6)) 512 testmode = USB_TEST_J; 513 else if (!strncmp(buf, "test_k", 6)) 514 testmode = USB_TEST_K; 515 else if (!strncmp(buf, "test_se0_nak", 12)) 516 testmode = USB_TEST_SE0_NAK; 517 else if (!strncmp(buf, "test_packet", 11)) 518 testmode = USB_TEST_PACKET; 519 else if (!strncmp(buf, "test_force_enable", 17)) 520 testmode = USB_TEST_FORCE_ENABLE; 521 else 522 testmode = 0; 523 524 spin_lock_irqsave(&dwc->lock, flags); 525 dwc3_gadget_set_test_mode(dwc, testmode); 526 spin_unlock_irqrestore(&dwc->lock, flags); 527 528 return count; 529} 530 531static const struct file_operations dwc3_testmode_fops = { 532 .open = dwc3_testmode_open, 533 .write = dwc3_testmode_write, 534 .read = seq_read, 535 .llseek = seq_lseek, 536 .release = single_release, 537}; 538 539static int dwc3_link_state_show(struct seq_file *s, void *unused) 540{ 541 struct dwc3 *dwc = s->private; 542 unsigned long flags; 543 enum dwc3_link_state state; 544 u32 reg; 545 u8 speed; 546 547 spin_lock_irqsave(&dwc->lock, flags); 548 reg = dwc3_readl(dwc->regs, DWC3_GSTS); 549 if (DWC3_GSTS_CURMOD(reg) != DWC3_GSTS_CURMOD_DEVICE) { 550 seq_puts(s, "Not available\n"); 551 spin_unlock_irqrestore(&dwc->lock, flags); 552 return 0; 553 } 554 555 reg = dwc3_readl(dwc->regs, DWC3_DSTS); 556 state = DWC3_DSTS_USBLNKST(reg); 557 speed = reg & DWC3_DSTS_CONNECTSPD; 558 559 seq_printf(s, "%s\n", (speed >= DWC3_DSTS_SUPERSPEED) ? 560 dwc3_gadget_link_string(state) : 561 dwc3_gadget_hs_link_string(state)); 562 spin_unlock_irqrestore(&dwc->lock, flags); 563 564 return 0; 565} 566 567static int dwc3_link_state_open(struct inode *inode, struct file *file) 568{ 569 return single_open(file, dwc3_link_state_show, inode->i_private); 570} 571 572static ssize_t dwc3_link_state_write(struct file *file, 573 const char __user *ubuf, size_t count, loff_t *ppos) 574{ 575 struct seq_file *s = file->private_data; 576 struct dwc3 *dwc = s->private; 577 unsigned long flags; 578 enum dwc3_link_state state = 0; 579 char buf[32]; 580 u32 reg; 581 u8 speed; 582 583 if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) 584 return -EFAULT; 585 586 if (!strncmp(buf, "SS.Disabled", 11)) 587 state = DWC3_LINK_STATE_SS_DIS; 588 else if (!strncmp(buf, "Rx.Detect", 9)) 589 state = DWC3_LINK_STATE_RX_DET; 590 else if (!strncmp(buf, "SS.Inactive", 11)) 591 state = DWC3_LINK_STATE_SS_INACT; 592 else if (!strncmp(buf, "Recovery", 8)) 593 state = DWC3_LINK_STATE_RECOV; 594 else if (!strncmp(buf, "Compliance", 10)) 595 state = DWC3_LINK_STATE_CMPLY; 596 else if (!strncmp(buf, "Loopback", 8)) 597 state = DWC3_LINK_STATE_LPBK; 598 else 599 return -EINVAL; 600 601 spin_lock_irqsave(&dwc->lock, flags); 602 reg = dwc3_readl(dwc->regs, DWC3_GSTS); 603 if (DWC3_GSTS_CURMOD(reg) != DWC3_GSTS_CURMOD_DEVICE) { 604 spin_unlock_irqrestore(&dwc->lock, flags); 605 return -EINVAL; 606 } 607 608 reg = dwc3_readl(dwc->regs, DWC3_DSTS); 609 speed = reg & DWC3_DSTS_CONNECTSPD; 610 611 if (speed < DWC3_DSTS_SUPERSPEED && 612 state != DWC3_LINK_STATE_RECOV) { 613 spin_unlock_irqrestore(&dwc->lock, flags); 614 return -EINVAL; 615 } 616 617 dwc3_gadget_set_link_state(dwc, state); 618 spin_unlock_irqrestore(&dwc->lock, flags); 619 620 return count; 621} 622 623static const struct file_operations dwc3_link_state_fops = { 624 .open = dwc3_link_state_open, 625 .write = dwc3_link_state_write, 626 .read = seq_read, 627 .llseek = seq_lseek, 628 .release = single_release, 629}; 630 631struct dwc3_ep_file_map { 632 const char name[25]; 633 const struct file_operations *const fops; 634}; 635 636static int dwc3_tx_fifo_size_show(struct seq_file *s, void *unused) 637{ 638 struct dwc3_ep *dep = s->private; 639 struct dwc3 *dwc = dep->dwc; 640 unsigned long flags; 641 u32 mdwidth; 642 u32 val; 643 644 spin_lock_irqsave(&dwc->lock, flags); 645 val = dwc3_core_fifo_space(dep, DWC3_TXFIFO); 646 647 /* Convert to bytes */ 648 mdwidth = dwc3_mdwidth(dwc); 649 650 val *= mdwidth; 651 val >>= 3; 652 seq_printf(s, "%u\n", val); 653 spin_unlock_irqrestore(&dwc->lock, flags); 654 655 return 0; 656} 657 658static int dwc3_rx_fifo_size_show(struct seq_file *s, void *unused) 659{ 660 struct dwc3_ep *dep = s->private; 661 struct dwc3 *dwc = dep->dwc; 662 unsigned long flags; 663 u32 mdwidth; 664 u32 val; 665 666 spin_lock_irqsave(&dwc->lock, flags); 667 val = dwc3_core_fifo_space(dep, DWC3_RXFIFO); 668 669 /* Convert to bytes */ 670 mdwidth = dwc3_mdwidth(dwc); 671 672 val *= mdwidth; 673 val >>= 3; 674 seq_printf(s, "%u\n", val); 675 spin_unlock_irqrestore(&dwc->lock, flags); 676 677 return 0; 678} 679 680static int dwc3_tx_request_queue_show(struct seq_file *s, void *unused) 681{ 682 struct dwc3_ep *dep = s->private; 683 struct dwc3 *dwc = dep->dwc; 684 unsigned long flags; 685 u32 val; 686 687 spin_lock_irqsave(&dwc->lock, flags); 688 val = dwc3_core_fifo_space(dep, DWC3_TXREQQ); 689 seq_printf(s, "%u\n", val); 690 spin_unlock_irqrestore(&dwc->lock, flags); 691 692 return 0; 693} 694 695static int dwc3_rx_request_queue_show(struct seq_file *s, void *unused) 696{ 697 struct dwc3_ep *dep = s->private; 698 struct dwc3 *dwc = dep->dwc; 699 unsigned long flags; 700 u32 val; 701 702 spin_lock_irqsave(&dwc->lock, flags); 703 val = dwc3_core_fifo_space(dep, DWC3_RXREQQ); 704 seq_printf(s, "%u\n", val); 705 spin_unlock_irqrestore(&dwc->lock, flags); 706 707 return 0; 708} 709 710static int dwc3_rx_info_queue_show(struct seq_file *s, void *unused) 711{ 712 struct dwc3_ep *dep = s->private; 713 struct dwc3 *dwc = dep->dwc; 714 unsigned long flags; 715 u32 val; 716 717 spin_lock_irqsave(&dwc->lock, flags); 718 val = dwc3_core_fifo_space(dep, DWC3_RXINFOQ); 719 seq_printf(s, "%u\n", val); 720 spin_unlock_irqrestore(&dwc->lock, flags); 721 722 return 0; 723} 724 725static int dwc3_descriptor_fetch_queue_show(struct seq_file *s, void *unused) 726{ 727 struct dwc3_ep *dep = s->private; 728 struct dwc3 *dwc = dep->dwc; 729 unsigned long flags; 730 u32 val; 731 732 spin_lock_irqsave(&dwc->lock, flags); 733 val = dwc3_core_fifo_space(dep, DWC3_DESCFETCHQ); 734 seq_printf(s, "%u\n", val); 735 spin_unlock_irqrestore(&dwc->lock, flags); 736 737 return 0; 738} 739 740static int dwc3_event_queue_show(struct seq_file *s, void *unused) 741{ 742 struct dwc3_ep *dep = s->private; 743 struct dwc3 *dwc = dep->dwc; 744 unsigned long flags; 745 u32 val; 746 747 spin_lock_irqsave(&dwc->lock, flags); 748 val = dwc3_core_fifo_space(dep, DWC3_EVENTQ); 749 seq_printf(s, "%u\n", val); 750 spin_unlock_irqrestore(&dwc->lock, flags); 751 752 return 0; 753} 754 755static int dwc3_transfer_type_show(struct seq_file *s, void *unused) 756{ 757 struct dwc3_ep *dep = s->private; 758 struct dwc3 *dwc = dep->dwc; 759 unsigned long flags; 760 761 spin_lock_irqsave(&dwc->lock, flags); 762 if (!(dep->flags & DWC3_EP_ENABLED) || !dep->endpoint.desc) { 763 seq_puts(s, "--\n"); 764 goto out; 765 } 766 767 switch (usb_endpoint_type(dep->endpoint.desc)) { 768 case USB_ENDPOINT_XFER_CONTROL: 769 seq_puts(s, "control\n"); 770 break; 771 case USB_ENDPOINT_XFER_ISOC: 772 seq_puts(s, "isochronous\n"); 773 break; 774 case USB_ENDPOINT_XFER_BULK: 775 seq_puts(s, "bulk\n"); 776 break; 777 case USB_ENDPOINT_XFER_INT: 778 seq_puts(s, "interrupt\n"); 779 break; 780 default: 781 seq_puts(s, "--\n"); 782 } 783 784out: 785 spin_unlock_irqrestore(&dwc->lock, flags); 786 787 return 0; 788} 789 790static int dwc3_trb_ring_show(struct seq_file *s, void *unused) 791{ 792 struct dwc3_ep *dep = s->private; 793 struct dwc3 *dwc = dep->dwc; 794 unsigned long flags; 795 int i; 796 797 spin_lock_irqsave(&dwc->lock, flags); 798 if (dep->number <= 1) { 799 seq_puts(s, "--\n"); 800 goto out; 801 } 802 803 seq_puts(s, "buffer_addr,size,type,ioc,isp_imi,csp,chn,lst,hwo\n"); 804 805 for (i = 0; i < DWC3_TRB_NUM; i++) { 806 struct dwc3_trb *trb = &dep->trb_pool[i]; 807 unsigned int type = DWC3_TRBCTL_TYPE(trb->ctrl); 808 809 seq_printf(s, "%08x%08x,%d,%s,%d,%d,%d,%d,%d,%d %c%c\n", 810 trb->bph, trb->bpl, trb->size, 811 dwc3_trb_type_string(type), 812 !!(trb->ctrl & DWC3_TRB_CTRL_IOC), 813 !!(trb->ctrl & DWC3_TRB_CTRL_ISP_IMI), 814 !!(trb->ctrl & DWC3_TRB_CTRL_CSP), 815 !!(trb->ctrl & DWC3_TRB_CTRL_CHN), 816 !!(trb->ctrl & DWC3_TRB_CTRL_LST), 817 !!(trb->ctrl & DWC3_TRB_CTRL_HWO), 818 dep->trb_enqueue == i ? 'E' : ' ', 819 dep->trb_dequeue == i ? 'D' : ' '); 820 } 821 822out: 823 spin_unlock_irqrestore(&dwc->lock, flags); 824 825 return 0; 826} 827 828static int dwc3_ep_info_register_show(struct seq_file *s, void *unused) 829{ 830 struct dwc3_ep *dep = s->private; 831 struct dwc3 *dwc = dep->dwc; 832 unsigned long flags; 833 u64 ep_info; 834 u32 lower_32_bits; 835 u32 upper_32_bits; 836 u32 reg; 837 838 spin_lock_irqsave(&dwc->lock, flags); 839 reg = DWC3_GDBGLSPMUX_EPSELECT(dep->number); 840 dwc3_writel(dwc->regs, DWC3_GDBGLSPMUX, reg); 841 842 lower_32_bits = dwc3_readl(dwc->regs, DWC3_GDBGEPINFO0); 843 upper_32_bits = dwc3_readl(dwc->regs, DWC3_GDBGEPINFO1); 844 845 ep_info = ((u64)upper_32_bits << 32) | lower_32_bits; 846 seq_printf(s, "0x%016llx\n", ep_info); 847 spin_unlock_irqrestore(&dwc->lock, flags); 848 849 return 0; 850} 851 852DEFINE_SHOW_ATTRIBUTE(dwc3_tx_fifo_size); 853DEFINE_SHOW_ATTRIBUTE(dwc3_rx_fifo_size); 854DEFINE_SHOW_ATTRIBUTE(dwc3_tx_request_queue); 855DEFINE_SHOW_ATTRIBUTE(dwc3_rx_request_queue); 856DEFINE_SHOW_ATTRIBUTE(dwc3_rx_info_queue); 857DEFINE_SHOW_ATTRIBUTE(dwc3_descriptor_fetch_queue); 858DEFINE_SHOW_ATTRIBUTE(dwc3_event_queue); 859DEFINE_SHOW_ATTRIBUTE(dwc3_transfer_type); 860DEFINE_SHOW_ATTRIBUTE(dwc3_trb_ring); 861DEFINE_SHOW_ATTRIBUTE(dwc3_ep_info_register); 862 863static const struct dwc3_ep_file_map dwc3_ep_file_map[] = { 864 { "tx_fifo_size", &dwc3_tx_fifo_size_fops, }, 865 { "rx_fifo_size", &dwc3_rx_fifo_size_fops, }, 866 { "tx_request_queue", &dwc3_tx_request_queue_fops, }, 867 { "rx_request_queue", &dwc3_rx_request_queue_fops, }, 868 { "rx_info_queue", &dwc3_rx_info_queue_fops, }, 869 { "descriptor_fetch_queue", &dwc3_descriptor_fetch_queue_fops, }, 870 { "event_queue", &dwc3_event_queue_fops, }, 871 { "transfer_type", &dwc3_transfer_type_fops, }, 872 { "trb_ring", &dwc3_trb_ring_fops, }, 873 { "GDBGEPINFO", &dwc3_ep_info_register_fops, }, 874}; 875 876static void dwc3_debugfs_create_endpoint_files(struct dwc3_ep *dep, 877 struct dentry *parent) 878{ 879 int i; 880 881 for (i = 0; i < ARRAY_SIZE(dwc3_ep_file_map); i++) { 882 const struct file_operations *fops = dwc3_ep_file_map[i].fops; 883 const char *name = dwc3_ep_file_map[i].name; 884 885 debugfs_create_file(name, 0444, parent, dep, fops); 886 } 887} 888 889void dwc3_debugfs_create_endpoint_dir(struct dwc3_ep *dep) 890{ 891 struct dentry *dir; 892 struct dentry *root; 893 894 root = debugfs_lookup(dev_name(dep->dwc->dev), usb_debug_root); 895 dir = debugfs_create_dir(dep->name, root); 896 dwc3_debugfs_create_endpoint_files(dep, dir); 897} 898 899void dwc3_debugfs_init(struct dwc3 *dwc) 900{ 901 struct dentry *root; 902 903 dwc->regset = kzalloc(sizeof(*dwc->regset), GFP_KERNEL); 904 if (!dwc->regset) 905 return; 906 907 dwc->dbg_lsp_select = DWC3_LSP_MUX_UNSELECTED; 908 909 dwc->regset->regs = dwc3_regs; 910 dwc->regset->nregs = ARRAY_SIZE(dwc3_regs); 911 dwc->regset->base = dwc->regs - DWC3_GLOBALS_REGS_START; 912 913 root = debugfs_create_dir(dev_name(dwc->dev), usb_debug_root); 914 debugfs_create_regset32("regdump", 0444, root, dwc->regset); 915 debugfs_create_file("lsp_dump", 0644, root, dwc, &dwc3_lsp_fops); 916 917 if (IS_ENABLED(CONFIG_USB_DWC3_DUAL_ROLE)) 918 debugfs_create_file("mode", 0644, root, dwc, 919 &dwc3_mode_fops); 920 921 if (IS_ENABLED(CONFIG_USB_DWC3_DUAL_ROLE) || 922 IS_ENABLED(CONFIG_USB_DWC3_GADGET)) { 923 debugfs_create_file("testmode", 0644, root, dwc, 924 &dwc3_testmode_fops); 925 debugfs_create_file("link_state", 0644, root, dwc, 926 &dwc3_link_state_fops); 927 } 928} 929 930void dwc3_debugfs_exit(struct dwc3 *dwc) 931{ 932 debugfs_remove(debugfs_lookup(dev_name(dwc->dev), usb_debug_root)); 933 kfree(dwc->regset); 934}