1039 lines · 24.8 KB · C
RawDownload
// SPDX-License-Identifier: GPL-2.0/* * debugfs.c - DesignWare USB3 DRD Controller DebugFS file * * Copyright (C) 2010-2011 Texas Instruments Incorporated - https://www.ti.com * * Authors: Felipe Balbi <balbi@ti.com>, *	    Sebastian Andrzej Siewior <bigeasy@linutronix.de> */ #include <linux/kernel.h>#include <linux/slab.h>#include <linux/ptrace.h>#include <linux/types.h>#include <linux/spinlock.h>#include <linux/debugfs.h>#include <linux/seq_file.h>#include <linux/delay.h>#include <linux/uaccess.h> #include <linux/usb/ch9.h> #include "core.h"#include "gadget.h"#include "io.h"#include "debug.h" #define DWC3_LSP_MUX_UNSELECTED 0xfffff #define dump_register(nm)				\{							\	.name	= __stringify(nm),			\	.offset	= DWC3_ ##nm,				\} #define dump_ep_register_set(n)			\	{					\		.name = "DEPCMDPAR2("__stringify(n)")",	\		.offset = DWC3_DEPCMDPAR2(n),	\	},					\	{					\		.name = "DEPCMDPAR1("__stringify(n)")",	\		.offset = DWC3_DEPCMDPAR1(n),	\	},					\	{					\		.name = "DEPCMDPAR0("__stringify(n)")",	\		.offset = DWC3_DEPCMDPAR0(n),	\	},					\	{					\		.name = "DEPCMD("__stringify(n)")",	\		.offset = DWC3_DEPCMD(n),		\	}  static const struct debugfs_reg32 dwc3_regs[] = {	dump_register(GSBUSCFG0),	dump_register(GSBUSCFG1),	dump_register(GTXTHRCFG),	dump_register(GRXTHRCFG),	dump_register(GCTL),	dump_register(GEVTEN),	dump_register(GSTS),	dump_register(GUCTL1),	dump_register(GSNPSID),	dump_register(GGPIO),	dump_register(GUID),	dump_register(GUCTL),	dump_register(GBUSERRADDR0),	dump_register(GBUSERRADDR1),	dump_register(GPRTBIMAP0),	dump_register(GPRTBIMAP1),	dump_register(GHWPARAMS0),	dump_register(GHWPARAMS1),	dump_register(GHWPARAMS2),	dump_register(GHWPARAMS3),	dump_register(GHWPARAMS4),	dump_register(GHWPARAMS5),	dump_register(GHWPARAMS6),	dump_register(GHWPARAMS7),	dump_register(GDBGFIFOSPACE),	dump_register(GDBGLTSSM),	dump_register(GDBGBMU),	dump_register(GPRTBIMAP_HS0),	dump_register(GPRTBIMAP_HS1),	dump_register(GPRTBIMAP_FS0),	dump_register(GPRTBIMAP_FS1),	dump_register(GUCTL2),	dump_register(VER_NUMBER),	dump_register(VER_TYPE), 	dump_register(GUSB2PHYCFG(0)),	dump_register(GUSB2PHYCFG(1)),	dump_register(GUSB2PHYCFG(2)),	dump_register(GUSB2PHYCFG(3)),	dump_register(GUSB2PHYCFG(4)),	dump_register(GUSB2PHYCFG(5)),	dump_register(GUSB2PHYCFG(6)),	dump_register(GUSB2PHYCFG(7)),	dump_register(GUSB2PHYCFG(8)),	dump_register(GUSB2PHYCFG(9)),	dump_register(GUSB2PHYCFG(10)),	dump_register(GUSB2PHYCFG(11)),	dump_register(GUSB2PHYCFG(12)),	dump_register(GUSB2PHYCFG(13)),	dump_register(GUSB2PHYCFG(14)),	dump_register(GUSB2PHYCFG(15)), 	dump_register(GUSB2I2CCTL(0)),	dump_register(GUSB2I2CCTL(1)),	dump_register(GUSB2I2CCTL(2)),	dump_register(GUSB2I2CCTL(3)),	dump_register(GUSB2I2CCTL(4)),	dump_register(GUSB2I2CCTL(5)),	dump_register(GUSB2I2CCTL(6)),	dump_register(GUSB2I2CCTL(7)),	dump_register(GUSB2I2CCTL(8)),	dump_register(GUSB2I2CCTL(9)),	dump_register(GUSB2I2CCTL(10)),	dump_register(GUSB2I2CCTL(11)),	dump_register(GUSB2I2CCTL(12)),	dump_register(GUSB2I2CCTL(13)),	dump_register(GUSB2I2CCTL(14)),	dump_register(GUSB2I2CCTL(15)), 	dump_register(GUSB2PHYACC(0)),	dump_register(GUSB2PHYACC(1)),	dump_register(GUSB2PHYACC(2)),	dump_register(GUSB2PHYACC(3)),	dump_register(GUSB2PHYACC(4)),	dump_register(GUSB2PHYACC(5)),	dump_register(GUSB2PHYACC(6)),	dump_register(GUSB2PHYACC(7)),	dump_register(GUSB2PHYACC(8)),	dump_register(GUSB2PHYACC(9)),	dump_register(GUSB2PHYACC(10)),	dump_register(GUSB2PHYACC(11)),	dump_register(GUSB2PHYACC(12)),	dump_register(GUSB2PHYACC(13)),	dump_register(GUSB2PHYACC(14)),	dump_register(GUSB2PHYACC(15)), 	dump_register(GUSB3PIPECTL(0)),	dump_register(GUSB3PIPECTL(1)),	dump_register(GUSB3PIPECTL(2)),	dump_register(GUSB3PIPECTL(3)),	dump_register(GUSB3PIPECTL(4)),	dump_register(GUSB3PIPECTL(5)),	dump_register(GUSB3PIPECTL(6)),	dump_register(GUSB3PIPECTL(7)),	dump_register(GUSB3PIPECTL(8)),	dump_register(GUSB3PIPECTL(9)),	dump_register(GUSB3PIPECTL(10)),	dump_register(GUSB3PIPECTL(11)),	dump_register(GUSB3PIPECTL(12)),	dump_register(GUSB3PIPECTL(13)),	dump_register(GUSB3PIPECTL(14)),	dump_register(GUSB3PIPECTL(15)), 	dump_register(GTXFIFOSIZ(0)),	dump_register(GTXFIFOSIZ(1)),	dump_register(GTXFIFOSIZ(2)),	dump_register(GTXFIFOSIZ(3)),	dump_register(GTXFIFOSIZ(4)),	dump_register(GTXFIFOSIZ(5)),	dump_register(GTXFIFOSIZ(6)),	dump_register(GTXFIFOSIZ(7)),	dump_register(GTXFIFOSIZ(8)),	dump_register(GTXFIFOSIZ(9)),	dump_register(GTXFIFOSIZ(10)),	dump_register(GTXFIFOSIZ(11)),	dump_register(GTXFIFOSIZ(12)),	dump_register(GTXFIFOSIZ(13)),	dump_register(GTXFIFOSIZ(14)),	dump_register(GTXFIFOSIZ(15)),	dump_register(GTXFIFOSIZ(16)),	dump_register(GTXFIFOSIZ(17)),	dump_register(GTXFIFOSIZ(18)),	dump_register(GTXFIFOSIZ(19)),	dump_register(GTXFIFOSIZ(20)),	dump_register(GTXFIFOSIZ(21)),	dump_register(GTXFIFOSIZ(22)),	dump_register(GTXFIFOSIZ(23)),	dump_register(GTXFIFOSIZ(24)),	dump_register(GTXFIFOSIZ(25)),	dump_register(GTXFIFOSIZ(26)),	dump_register(GTXFIFOSIZ(27)),	dump_register(GTXFIFOSIZ(28)),	dump_register(GTXFIFOSIZ(29)),	dump_register(GTXFIFOSIZ(30)),	dump_register(GTXFIFOSIZ(31)), 	dump_register(GRXFIFOSIZ(0)),	dump_register(GRXFIFOSIZ(1)),	dump_register(GRXFIFOSIZ(2)),	dump_register(GRXFIFOSIZ(3)),	dump_register(GRXFIFOSIZ(4)),	dump_register(GRXFIFOSIZ(5)),	dump_register(GRXFIFOSIZ(6)),	dump_register(GRXFIFOSIZ(7)),	dump_register(GRXFIFOSIZ(8)),	dump_register(GRXFIFOSIZ(9)),	dump_register(GRXFIFOSIZ(10)),	dump_register(GRXFIFOSIZ(11)),	dump_register(GRXFIFOSIZ(12)),	dump_register(GRXFIFOSIZ(13)),	dump_register(GRXFIFOSIZ(14)),	dump_register(GRXFIFOSIZ(15)),	dump_register(GRXFIFOSIZ(16)),	dump_register(GRXFIFOSIZ(17)),	dump_register(GRXFIFOSIZ(18)),	dump_register(GRXFIFOSIZ(19)),	dump_register(GRXFIFOSIZ(20)),	dump_register(GRXFIFOSIZ(21)),	dump_register(GRXFIFOSIZ(22)),	dump_register(GRXFIFOSIZ(23)),	dump_register(GRXFIFOSIZ(24)),	dump_register(GRXFIFOSIZ(25)),	dump_register(GRXFIFOSIZ(26)),	dump_register(GRXFIFOSIZ(27)),	dump_register(GRXFIFOSIZ(28)),	dump_register(GRXFIFOSIZ(29)),	dump_register(GRXFIFOSIZ(30)),	dump_register(GRXFIFOSIZ(31)), 	dump_register(GEVNTADRLO(0)),	dump_register(GEVNTADRHI(0)),	dump_register(GEVNTSIZ(0)),	dump_register(GEVNTCOUNT(0)), 	dump_register(GHWPARAMS8),	dump_register(GUCTL3),	dump_register(GFLADJ),	dump_register(DCFG),	dump_register(DCTL),	dump_register(DEVTEN),	dump_register(DSTS),	dump_register(DGCMDPAR),	dump_register(DGCMD),	dump_register(DALEPENA), 	dump_ep_register_set(0),	dump_ep_register_set(1),	dump_ep_register_set(2),	dump_ep_register_set(3),	dump_ep_register_set(4),	dump_ep_register_set(5),	dump_ep_register_set(6),	dump_ep_register_set(7),	dump_ep_register_set(8),	dump_ep_register_set(9),	dump_ep_register_set(10),	dump_ep_register_set(11),	dump_ep_register_set(12),	dump_ep_register_set(13),	dump_ep_register_set(14),	dump_ep_register_set(15),	dump_ep_register_set(16),	dump_ep_register_set(17),	dump_ep_register_set(18),	dump_ep_register_set(19),	dump_ep_register_set(20),	dump_ep_register_set(21),	dump_ep_register_set(22),	dump_ep_register_set(23),	dump_ep_register_set(24),	dump_ep_register_set(25),	dump_ep_register_set(26),	dump_ep_register_set(27),	dump_ep_register_set(28),	dump_ep_register_set(29),	dump_ep_register_set(30),	dump_ep_register_set(31), 	dump_register(OCFG),	dump_register(OCTL),	dump_register(OEVT),	dump_register(OEVTEN),	dump_register(OSTS),}; static void dwc3_host_lsp(struct seq_file *s){	struct dwc3		*dwc = s->private;	bool			dbc_enabled;	u32			sel;	u32			reg;	u32			val; 	dbc_enabled = !!(dwc->hwparams.hwparams1 & DWC3_GHWPARAMS1_ENDBC); 	sel = dwc->dbg_lsp_select;	if (sel == DWC3_LSP_MUX_UNSELECTED) {		seq_puts(s, "Write LSP selection to print for host\n");		return;	} 	reg = DWC3_GDBGLSPMUX_HOSTSELECT(sel); 	dwc3_writel(dwc, DWC3_GDBGLSPMUX, reg);	val = dwc3_readl(dwc, DWC3_GDBGLSP);	seq_printf(s, "GDBGLSP[%d] = 0x%08x\n", sel, val); 	if (dbc_enabled && sel < 256) {		reg |= DWC3_GDBGLSPMUX_ENDBC;		dwc3_writel(dwc, DWC3_GDBGLSPMUX, reg);		val = dwc3_readl(dwc, DWC3_GDBGLSP);		seq_printf(s, "GDBGLSP_DBC[%d] = 0x%08x\n", sel, val);	}} static void dwc3_gadget_lsp(struct seq_file *s){	struct dwc3		*dwc = s->private;	int			i;	u32			reg; 	for (i = 0; i < 16; i++) {		reg = DWC3_GDBGLSPMUX_DEVSELECT(i);		dwc3_writel(dwc, DWC3_GDBGLSPMUX, reg);		reg = dwc3_readl(dwc, DWC3_GDBGLSP);		seq_printf(s, "GDBGLSP[%d] = 0x%08x\n", i, reg);	}} static int dwc3_lsp_show(struct seq_file *s, void *unused){	struct dwc3		*dwc = s->private;	unsigned int		current_mode;	unsigned long		flags;	u32			reg;	int			ret; 	ret = pm_runtime_resume_and_get(dwc->dev);	if (ret < 0)		return ret; 	spin_lock_irqsave(&dwc->lock, flags);	reg = dwc3_readl(dwc, DWC3_GSTS);	current_mode = DWC3_GSTS_CURMOD(reg); 	switch (current_mode) {	case DWC3_GSTS_CURMOD_HOST:		dwc3_host_lsp(s);		break;	case DWC3_GSTS_CURMOD_DEVICE:		dwc3_gadget_lsp(s);		break;	default:		seq_puts(s, "Mode is unknown, no LSP register printed\n");		break;	}	spin_unlock_irqrestore(&dwc->lock, flags); 	pm_runtime_put_sync(dwc->dev); 	return 0;} static int dwc3_lsp_open(struct inode *inode, struct file *file){	return single_open(file, dwc3_lsp_show, inode->i_private);} static ssize_t dwc3_lsp_write(struct file *file, const char __user *ubuf,			      size_t count, loff_t *ppos){	struct seq_file		*s = file->private_data;	struct dwc3		*dwc = s->private;	unsigned long		flags;	char			buf[32] = { 0 };	u32			sel;	int			ret; 	if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))		return -EFAULT; 	ret = kstrtouint(buf, 0, &sel);	if (ret)		return ret; 	spin_lock_irqsave(&dwc->lock, flags);	dwc->dbg_lsp_select = sel;	spin_unlock_irqrestore(&dwc->lock, flags); 	return count;} static const struct file_operations dwc3_lsp_fops = {	.open			= dwc3_lsp_open,	.write			= dwc3_lsp_write,	.read			= seq_read,	.llseek			= seq_lseek,	.release		= single_release,}; static int dwc3_mode_show(struct seq_file *s, void *unused){	struct dwc3		*dwc = s->private;	unsigned long		flags;	u32			reg;	u32			mode;	int			ret; 	ret = pm_runtime_resume_and_get(dwc->dev);	if (ret < 0)		return ret; 	spin_lock_irqsave(&dwc->lock, flags);	reg = dwc3_readl(dwc, DWC3_GCTL);	spin_unlock_irqrestore(&dwc->lock, flags); 	mode = DWC3_GCTL_PRTCAP(reg);	switch (mode) {	case DWC3_GCTL_PRTCAP_HOST:	case DWC3_GCTL_PRTCAP_DEVICE:	case DWC3_GCTL_PRTCAP_OTG:		seq_printf(s, "%s\n", dwc3_mode_string(mode));		break;	default:		seq_printf(s, "UNKNOWN %08x\n", mode);	} 	pm_runtime_put_sync(dwc->dev); 	return 0;} static int dwc3_mode_open(struct inode *inode, struct file *file){	return single_open(file, dwc3_mode_show, inode->i_private);} static ssize_t dwc3_mode_write(struct file *file,		const char __user *ubuf, size_t count, loff_t *ppos){	struct seq_file		*s = file->private_data;	struct dwc3		*dwc = s->private;	u32			mode = 0;	char			buf[32]; 	if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))		return -EFAULT; 	if (dwc->dr_mode != USB_DR_MODE_OTG)		return count; 	if (!strncmp(buf, "host", 4))		mode = DWC3_GCTL_PRTCAP_HOST; 	if (!strncmp(buf, "device", 6))		mode = DWC3_GCTL_PRTCAP_DEVICE; 	if (!strncmp(buf, "otg", 3))		mode = DWC3_GCTL_PRTCAP_OTG; 	dwc3_set_mode(dwc, mode); 	return count;} static const struct file_operations dwc3_mode_fops = {	.open			= dwc3_mode_open,	.write			= dwc3_mode_write,	.read			= seq_read,	.llseek			= seq_lseek,	.release		= single_release,}; static int dwc3_testmode_show(struct seq_file *s, void *unused){	struct dwc3		*dwc = s->private;	unsigned long		flags;	u32			reg;	int			ret; 	ret = pm_runtime_resume_and_get(dwc->dev);	if (ret < 0)		return ret; 	spin_lock_irqsave(&dwc->lock, flags);	reg = dwc3_readl(dwc, DWC3_DCTL);	reg &= DWC3_DCTL_TSTCTRL_MASK;	reg >>= 1;	spin_unlock_irqrestore(&dwc->lock, flags); 	switch (reg) {	case 0:		seq_puts(s, "no test\n");		break;	case USB_TEST_J:		seq_puts(s, "test_j\n");		break;	case USB_TEST_K:		seq_puts(s, "test_k\n");		break;	case USB_TEST_SE0_NAK:		seq_puts(s, "test_se0_nak\n");		break;	case USB_TEST_PACKET:		seq_puts(s, "test_packet\n");

Lines 1–500 of 1039.