debugfs.c 25 KB

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