[prev in list] [next in list] [prev in thread] [next in thread] 

List:       linux-usb
Subject:    =?UTF-8?q?=5BGIT=20PULL=5D=20DWC3=20patches=20for=20next?=
From:       Felipe Balbi <balbi () ti ! com>
Date:       2011-09-30 8:06:33
Message-ID: 1317369993-15724-1-git-send-email-balbi () ti ! com
[Download RAW message or body]

Hi Greg,

Here are the latest updates to DWC3 driver. With them
I have USB30CV passing all except LPM-related tests.

Driver is now a lot more stable and works fine in FS/HS/SS
modes.

Consolidated changes are appended below and patches were
sent to linux-usb a while ago for reference.

The following changes since commit 0ae52d5458ddb14d5da63054f1d8269a13fe9054:

  usb: musb: Enable DMA mode1 RX for transfers without short packets (2011-09-09 13:08:17 +0300)

are available in the git repository at:
  gitorious.org:usb/usb.git for-next

Felipe Balbi (9):
      usb: dwc3: ep0: Make USB30CV happy with SetAddress
      usb: dwc3: ep0: ignore direction on 2-stage transfer
      usb: dwc3: ep0: fix debug message
      usb: dwc3: gadget: add support for Bursts
      usb: dwc3: gadget: implement streams support
      usb: dwc3: add struct dwc3_hwparams
      usb: dwc3: core: cache GHWPARAMS* registers
      usb: dwc3: gadget: allow clock gating to work
      usb: dwc3: convert structures into bitshifts

Paul Zimmerman (4):
      usb: dwc3: gadget: fix DEPSTARTCFG for non-EP0 EPs
      usb: dwc3: gadget: driver should not wait for RxFIFO to drain
      usb: dwc3: gadget: make DWC3_EP_WEDGE do the right thing
      usb: dwc3: gadget: fix DMA offset calculation

Sebastian Andrzej Siewior (3):
      usb: dwc3: ep0: remove second giveback in error case
      usb: dwc3: ep0: fix debug output
      usb: dwc: remove "All rights reserved" statement.

 Documentation/usb/dwc3.txt   |    8 ---
 drivers/usb/dwc3/core.c      |   18 +++++-
 drivers/usb/dwc3/core.h      |   41 ++++++++++++-
 drivers/usb/dwc3/debug.h     |    1 -
 drivers/usb/dwc3/debugfs.c   |    1 -
 drivers/usb/dwc3/dwc3-omap.c |    1 -
 drivers/usb/dwc3/dwc3-pci.c  |    1 -
 drivers/usb/dwc3/ep0.c       |   58 ++++++-----------
 drivers/usb/dwc3/gadget.c    |  115 +++++++++++++++++++++-------------
 drivers/usb/dwc3/gadget.h    |  140 ++++++++----------------------------------
 drivers/usb/dwc3/io.h        |    1 -
 11 files changed, 175 insertions(+), 210 deletions(-)

diff --git a/Documentation/usb/dwc3.txt b/Documentation/usb/dwc3.txt
index 2f65853..7b590ed 100644
--- a/Documentation/usb/dwc3.txt
+++ b/Documentation/usb/dwc3.txt
@@ -3,14 +3,6 @@
 ~~~~~~
 Please pick something while reading :)
 
-- Implement streaming support for BULK endpoints
-  Tatyana's patch "usb: Add streams support to the gadget framework"
-  introduces streaming support for the gadget driver.
-  Every usb_request has new field called stream_id which holds its id.
-  Every usb_ep has a field num_supported_strms which describes the max
-  number of streams supported (for this ep).
-  UAS is AFAIK the only gadget with streaming support.
-
 - Convert interrupt handler to per-ep-thread-irq
 
   As it turns out some DWC3-commands ~1ms to complete. Currently we spin
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index 64ba097..d35f905 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -2,7 +2,6 @@
  * core.c - DesignWare USB3 DRD Controller Core file
  *
  * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com
- * All rights reserved.
  *
  * Authors: Felipe Balbi <balbi@ti.com>,
  *	    Sebastian Andrzej Siewior <bigeasy@linutronix.de>
@@ -230,6 +229,21 @@ static void dwc3_event_buffers_cleanup(struct dwc3 *dwc)
 	}
 }
 
+static void __devinit dwc3_cache_hwparams(struct dwc3 *dwc)
+{
+	struct dwc3_hwparams	*parms = &dwc->hwparams;
+
+	parms->hwparams0 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS0);
+	parms->hwparams1 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS1);
+	parms->hwparams2 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS2);
+	parms->hwparams3 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS3);
+	parms->hwparams4 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS4);
+	parms->hwparams5 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS5);
+	parms->hwparams6 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS6);
+	parms->hwparams7 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS7);
+	parms->hwparams8 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS8);
+}
+
 /**
  * dwc3_core_init - Low-level initialization of DWC3 Core
  * @dwc: Pointer to our controller context structure
@@ -284,6 +298,8 @@ static int __devinit dwc3_core_init(struct dwc3 *dwc)
 		goto err1;
 	}
 
+	dwc3_cache_hwparams(dwc);
+
 	return 0;
 
 err1:
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index 07d2018..29a8e16 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -2,7 +2,6 @@
  * core.h - DesignWare USB3 DRD Core Header
  *
  * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com
- * All rights reserved.
  *
  * Authors: Felipe Balbi <balbi@ti.com>,
  *	    Sebastian Andrzej Siewior <bigeasy@linutronix.de>
@@ -162,6 +161,7 @@
 #define DWC3_GCTL_CORESOFTRESET	(1 << 11)
 #define DWC3_GCTL_SCALEDOWN(n)	(n << 4)
 #define DWC3_GCTL_DISSCRAMBLE	(1 << 3)
+#define DWC3_GCTL_DSBLCLKGTNG	(1 << 0)
 
 /* Global USB2 PHY Configuration Register */
 #define DWC3_GUSB2PHYCFG_PHYSOFTRST (1 << 31)
@@ -171,6 +171,11 @@
 #define DWC3_GUSB3PIPECTL_PHYSOFTRST (1 << 31)
 #define DWC3_GUSB3PIPECTL_SUSPHY (1 << 17)
 
+/* Global HWPARAMS1 Register */
+#define DWC3_GHWPARAMS1_EN_PWROPT(n)	((n & (3 << 24)) >> 24)
+#define DWC3_GHWPARAMS1_EN_PWROPT_NO	0
+#define DWC3_GHWPARAMS1_EN_PWROPT_CLK	1
+
 /* Device Configuration Register */
 #define DWC3_DCFG_DEVADDR(addr)	((addr) << 3)
 #define DWC3_DCFG_DEVADDR_MASK	DWC3_DCFG_DEVADDR(0x7f)
@@ -330,6 +335,7 @@ struct dwc3_event_buffer {
  * @interval: the intervall on which the ISOC transfer is started
  * @name: a human readable name e.g. ep1out-bulk
  * @direction: true for TX, false for RX
+ * @stream_capable: true when streams are enabled
  */
 struct dwc3_ep {
 	struct usb_ep		endpoint;
@@ -363,6 +369,7 @@ struct dwc3_ep {
 	char			name[20];
 
 	unsigned		direction:1;
+	unsigned		stream_capable:1;
 };
 
 enum dwc3_phy {
@@ -506,6 +513,30 @@ static inline void dwc3_trb_to_nat(struct dwc3_trb_hw *hw, struct dwc3_trb *nat)
 }
 
 /**
+ * dwc3_hwparams - copy of HWPARAMS registers
+ * @hwparams0 - GHWPARAMS0
+ * @hwparams1 - GHWPARAMS1
+ * @hwparams2 - GHWPARAMS2
+ * @hwparams3 - GHWPARAMS3
+ * @hwparams4 - GHWPARAMS4
+ * @hwparams5 - GHWPARAMS5
+ * @hwparams6 - GHWPARAMS6
+ * @hwparams7 - GHWPARAMS7
+ * @hwparams8 - GHWPARAMS8
+ */
+struct dwc3_hwparams {
+	u32	hwparams0;
+	u32	hwparams1;
+	u32	hwparams2;
+	u32	hwparams3;
+	u32	hwparams4;
+	u32	hwparams5;
+	u32	hwparams6;
+	u32	hwparams7;
+	u32	hwparams8;
+};
+
+/**
  * struct dwc3 - representation of our controller
  * @ctrl_req: usb control request which is used for ep0
  * @ep0_trb: trb which is used for the ctrl_req
@@ -530,11 +561,13 @@ static inline void dwc3_trb_to_nat(struct dwc3_trb_hw *hw, struct dwc3_trb *nat)
  * @ep0_status_pending: ep0 status response without a req is pending
  * @ep0_bounced: true when we used bounce buffer
  * @ep0_expect_in: true when we expect a DATA IN transfer
+ * @start_config_issued: true when StartConfig command has been issued
  * @ep0_next_event: hold the next expected event
  * @ep0state: state of endpoint zero
  * @link_state: link state
  * @speed: device speed (super, high, full, low)
  * @mem: points to start of memory which is used for this struct.
+ * @hwparams: copy of hwparams registers
  * @root: debugfs root folder pointer
  */
 struct dwc3 {
@@ -577,6 +610,7 @@ struct dwc3 {
 	unsigned		ep0_status_pending:1;
 	unsigned		ep0_bounced:1;
 	unsigned		ep0_expect_in:1;
+	unsigned		start_config_issued:1;
 
 	enum dwc3_ep0_next	ep0_next_event;
 	enum dwc3_ep0_state	ep0state;
@@ -586,6 +620,7 @@ struct dwc3 {
 	u8			speed;
 	void			*mem;
 
+	struct dwc3_hwparams	hwparams;
 	struct dentry		*root;
 };
 
@@ -649,6 +684,10 @@ struct dwc3_event_depevt {
 #define DEPEVT_STATUS_IOC       (1 << 2)
 #define DEPEVT_STATUS_LST	(1 << 3)
 
+/* Stream event only */
+#define DEPEVT_STREAMEVT_FOUND		1
+#define DEPEVT_STREAMEVT_NOTFOUND	2
+
 /* Control-only Status */
 #define DEPEVT_STATUS_CONTROL_SETUP	0
 #define DEPEVT_STATUS_CONTROL_DATA	1
diff --git a/drivers/usb/dwc3/debug.h b/drivers/usb/dwc3/debug.h
index ee3ba73..5894ee8 100644
--- a/drivers/usb/dwc3/debug.h
+++ b/drivers/usb/dwc3/debug.h
@@ -2,7 +2,6 @@
  * debug.h - DesignWare USB3 DRD Controller Debug Header
  *
  * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com
- * All rights reserved.
  *
  * Authors: Felipe Balbi <balbi@ti.com>,
  *	    Sebastian Andrzej Siewior <bigeasy@linutronix.de>
diff --git a/drivers/usb/dwc3/debugfs.c b/drivers/usb/dwc3/debugfs.c
index 20d329f..da1ad77 100644
--- a/drivers/usb/dwc3/debugfs.c
+++ b/drivers/usb/dwc3/debugfs.c
@@ -2,7 +2,6 @@
  * debugfs.c - DesignWare USB3 DRD Controller DebugFS file
  *
  * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com
- * All rights reserved.
  *
  * Authors: Felipe Balbi <balbi@ti.com>,
  *	    Sebastian Andrzej Siewior <bigeasy@linutronix.de>
diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c
index 72cc92b..64ce3fc 100644
--- a/drivers/usb/dwc3/dwc3-omap.c
+++ b/drivers/usb/dwc3/dwc3-omap.c
@@ -2,7 +2,6 @@
  * dwc3-omap.c - OMAP Specific Glue layer
  *
  * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com
- * All rights reserved.
  *
  * Authors: Felipe Balbi <balbi@ti.com>,
  *	    Sebastian Andrzej Siewior <bigeasy@linutronix.de>
diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c
index e3b77d2..f77c000 100644
--- a/drivers/usb/dwc3/dwc3-pci.c
+++ b/drivers/usb/dwc3/dwc3-pci.c
@@ -2,7 +2,6 @@
  * dwc3-pci.c - PCI Specific glue layer
  *
  * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com
- * All rights reserved.
  *
  * Authors: Felipe Balbi <balbi@ti.com>,
  *	    Sebastian Andrzej Siewior <bigeasy@linutronix.de>
diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c
index b66d969..69a4e43 100644
--- a/drivers/usb/dwc3/ep0.c
+++ b/drivers/usb/dwc3/ep0.c
@@ -2,7 +2,6 @@
  * ep0.c - DesignWare USB3 DRD Controller Endpoint 0 Handling
  *
  * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com
- * All rights reserved.
  *
  * Authors: Felipe Balbi <balbi@ti.com>,
  *	    Sebastian Andrzej Siewior <bigeasy@linutronix.de>
@@ -104,10 +103,8 @@ static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum, dma_addr_t buf_dma,
 	dwc3_trb_to_hw(&trb, trb_hw);
 
 	memset(&params, 0, sizeof(params));
-	params.param0.depstrtxfer.transfer_desc_addr_high =
-		upper_32_bits(dwc->ep0_trb_addr);
-	params.param1.depstrtxfer.transfer_desc_addr_low =
-		lower_32_bits(dwc->ep0_trb_addr);
+	params.param0 = upper_32_bits(dwc->ep0_trb_addr);
+	params.param1 = lower_32_bits(dwc->ep0_trb_addr);
 
 	ret = dwc3_send_gadget_ep_cmd(dwc, dep->number,
 			DWC3_DEPCMD_STARTTRANSFER, &params);
@@ -421,7 +418,6 @@ static int dwc3_ep0_handle_feature(struct dwc3 *dwc,
 
 static int dwc3_ep0_set_address(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl)
 {
-	int ret = 0;
 	u32 addr;
 	u32 reg;
 
@@ -429,29 +425,17 @@ static int dwc3_ep0_set_address(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl)
 	if (addr > 127)
 		return -EINVAL;
 
-	switch (dwc->dev_state) {
-	case DWC3_DEFAULT_STATE:
-	case DWC3_ADDRESS_STATE:
-		/*
-		 * Not sure if we should program DevAddr now or later
-		 */
-		reg = dwc3_readl(dwc->regs, DWC3_DCFG);
-		reg &= ~(DWC3_DCFG_DEVADDR_MASK);
-		reg |= DWC3_DCFG_DEVADDR(addr);
-		dwc3_writel(dwc->regs, DWC3_DCFG, reg);
-
-		if (addr)
-			dwc->dev_state = DWC3_ADDRESS_STATE;
-		else
-			dwc->dev_state = DWC3_DEFAULT_STATE;
-		break;
+	reg = dwc3_readl(dwc->regs, DWC3_DCFG);
+	reg &= ~(DWC3_DCFG_DEVADDR_MASK);
+	reg |= DWC3_DCFG_DEVADDR(addr);
+	dwc3_writel(dwc->regs, DWC3_DCFG, reg);
 
-	case DWC3_CONFIGURED_STATE:
-		ret = -EINVAL;
-		break;
-	}
+	if (addr)
+		dwc->dev_state = DWC3_ADDRESS_STATE;
+	else
+		dwc->dev_state = DWC3_DEFAULT_STATE;
 
-	return ret;
+	return 0;
 }
 
 static int dwc3_ep0_delegate_req(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl)
@@ -469,6 +453,7 @@ static int dwc3_ep0_set_config(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl)
 	u32 cfg;
 	int ret;
 
+	dwc->start_config_issued = false;
 	cfg = le16_to_cpu(ctrl->wValue);
 
 	switch (dwc->dev_state) {
@@ -538,15 +523,15 @@ static void dwc3_ep0_inspect_setup(struct dwc3 *dwc,
 
 	len = le16_to_cpu(ctrl->wLength);
 	if (!len) {
-		dwc->three_stage_setup = 0;
+		dwc->three_stage_setup = false;
+		dwc->ep0_expect_in = false;
 		dwc->ep0_next_event = DWC3_EP0_NRDY_STATUS;
 	} else {
-		dwc->three_stage_setup = 1;
+		dwc->three_stage_setup = true;
+		dwc->ep0_expect_in = !!(ctrl->bRequestType & USB_DIR_IN);
 		dwc->ep0_next_event = DWC3_EP0_NRDY_DATA;
 	}
 
-	dwc->ep0_expect_in = !!(ctrl->bRequestType & USB_DIR_IN);
-
 	if ((ctrl->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD)
 		ret = dwc3_ep0_std_request(dwc, ctrl);
 	else
@@ -600,7 +585,6 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc,
 		/* for some reason we did not get everything out */
 
 		dwc3_ep0_stall_and_restart(dwc);
-		dwc3_gadget_giveback(dep, r, -ECONNRESET);
 	} else {
 		/*
 		 * handle the case where we have to send a zero packet. This
@@ -753,8 +737,8 @@ static void dwc3_ep0_xfernotready(struct dwc3 *dwc,
 
 		if (dwc->ep0_next_event != DWC3_EP0_NRDY_DATA) {
 			dev_vdbg(dwc->dev, "Expected %d got %d\n",
-					DEPEVT_STATUS_CONTROL_DATA,
-					event->status);
+					dwc->ep0_next_event,
+					DWC3_EP0_NRDY_DATA);
 
 			dwc3_ep0_stall_and_restart(dwc);
 			return;
@@ -782,8 +766,8 @@ static void dwc3_ep0_xfernotready(struct dwc3 *dwc,
 
 		if (dwc->ep0_next_event != DWC3_EP0_NRDY_STATUS) {
 			dev_vdbg(dwc->dev, "Expected %d got %d\n",
-					DEPEVT_STATUS_CONTROL_STATUS,
-					event->status);
+					dwc->ep0_next_event,
+					DWC3_EP0_NRDY_STATUS);
 
 			dwc3_ep0_stall_and_restart(dwc);
 			return;
@@ -799,7 +783,7 @@ void dwc3_ep0_interrupt(struct dwc3 *dwc,
 
 	dev_dbg(dwc->dev, "%s while ep%d%s in state '%s'\n",
 			dwc3_ep_event_string(event->endpoint_event),
-			epnum, (epnum & 1) ? "in" : "out",
+			epnum >> 1, (epnum & 1) ? "in" : "out",
 			dwc3_ep0_state_string(dwc->ep0state));
 
 	switch (event->endpoint_event) {
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 859257a..fa824cf 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -2,7 +2,6 @@
  * gadget.c - DesignWare USB3 DRD Controller Gadget Framework Link
  *
  * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com
- * All rights reserved.
  *
  * Authors: Felipe Balbi <balbi@ti.com>,
  *	    Sebastian Andrzej Siewior <bigeasy@linutronix.de>
@@ -159,12 +158,12 @@ int dwc3_send_gadget_ep_cmd(struct dwc3 *dwc, unsigned ep,
 
 	dev_vdbg(dwc->dev, "%s: cmd '%s' params %08x %08x %08x\n",
 			dep->name,
-			dwc3_gadget_ep_cmd_string(cmd), params->param0.raw,
-			params->param1.raw, params->param2.raw);
+			dwc3_gadget_ep_cmd_string(cmd), params->param0,
+			params->param1, params->param2);
 
-	dwc3_writel(dwc->regs, DWC3_DEPCMDPAR0(ep), params->param0.raw);
-	dwc3_writel(dwc->regs, DWC3_DEPCMDPAR1(ep), params->param1.raw);
-	dwc3_writel(dwc->regs, DWC3_DEPCMDPAR2(ep), params->param2.raw);
+	dwc3_writel(dwc->regs, DWC3_DEPCMDPAR0(ep), params->param0);
+	dwc3_writel(dwc->regs, DWC3_DEPCMDPAR1(ep), params->param1);
+	dwc3_writel(dwc->regs, DWC3_DEPCMDPAR2(ep), params->param2);
 
 	dwc3_writel(dwc->regs, DWC3_DEPCMD(ep), cmd | DWC3_DEPCMD_CMDACT);
 	do {
@@ -190,7 +189,7 @@ int dwc3_send_gadget_ep_cmd(struct dwc3 *dwc, unsigned ep,
 static dma_addr_t dwc3_trb_dma_offset(struct dwc3_ep *dep,
 		struct dwc3_trb_hw *trb)
 {
-	u32		offset = trb - dep->trb_pool;
+	u32		offset = (char *) trb - (char *) dep->trb_pool;
 
 	return dep->trb_pool_dma + offset;
 }
@@ -238,8 +237,12 @@ static int dwc3_gadget_start_config(struct dwc3 *dwc, struct dwc3_ep *dep)
 	if (dep->number != 1) {
 		cmd = DWC3_DEPCMD_DEPSTARTCFG;
 		/* XferRscIdx == 0 for ep0 and 2 for the remaining */
-		if (dep->number > 1)
+		if (dep->number > 1) {
+			if (dwc->start_config_issued)
+				return 0;
+			dwc->start_config_issued = true;
 			cmd |= DWC3_DEPCMD_PARAM(2);
+		}
 
 		return dwc3_send_gadget_ep_cmd(dwc, 0, cmd, &params);
 	}
@@ -254,14 +257,21 @@ static int dwc3_gadget_set_ep_config(struct dwc3 *dwc, struct dwc3_ep *dep,
 
 	memset(&params, 0x00, sizeof(params));
 
-	params.param0.depcfg.ep_type = usb_endpoint_type(desc);
-	params.param0.depcfg.max_packet_size = usb_endpoint_maxp(desc);
+	params.param0 = DWC3_DEPCFG_EP_TYPE(usb_endpoint_type(desc))
+		| DWC3_DEPCFG_MAX_PACKET_SIZE(usb_endpoint_maxp(desc))
+		| DWC3_DEPCFG_BURST_SIZE(dep->endpoint.maxburst);
+
+	params.param1 = DWC3_DEPCFG_XFER_COMPLETE_EN
+		| DWC3_DEPCFG_XFER_NOT_READY_EN;
 
-	params.param1.depcfg.xfer_complete_enable = true;
-	params.param1.depcfg.xfer_not_ready_enable = true;
+	if (usb_endpoint_xfer_bulk(desc) && dep->endpoint.max_streams) {
+		params.param1 |= DWC3_DEPCFG_STREAM_CAPABLE
+			| DWC3_DEPCFG_STREAM_EVENT_EN;
+		dep->stream_capable = true;
+	}
 
 	if (usb_endpoint_xfer_isoc(desc))
-		params.param1.depcfg.xfer_in_progress_enable = true;
+		params.param1 |= DWC3_DEPCFG_XFER_IN_PROGRESS_EN;
 
 	/*
 	 * We are doing 1:1 mapping for endpoints, meaning
@@ -269,17 +279,17 @@ static int dwc3_gadget_set_ep_config(struct dwc3 *dwc, struct dwc3_ep *dep,
 	 * so on. We consider the direction bit as part of the physical
 	 * endpoint number. So USB endpoint 0x81 is 0x03.
 	 */
-	params.param1.depcfg.ep_number = dep->number;
+	params.param1 |= DWC3_DEPCFG_EP_NUMBER(dep->number);
 
 	/*
 	 * We must use the lower 16 TX FIFOs even though
 	 * HW might have more
 	 */
 	if (dep->direction)
-		params.param0.depcfg.fifo_number = dep->number >> 1;
+		params.param0 |= DWC3_DEPCFG_FIFO_NUMBER(dep->number >> 1);
 
 	if (desc->bInterval) {
-		params.param1.depcfg.binterval_m1 = desc->bInterval - 1;
+		params.param1 |= DWC3_DEPCFG_BINTERVAL_M1(desc->bInterval - 1);
 		dep->interval = 1 << (desc->bInterval - 1);
 	}
 
@@ -293,7 +303,7 @@ static int dwc3_gadget_set_xfer_resource(struct dwc3 *dwc, struct dwc3_ep *dep)
 
 	memset(&params, 0x00, sizeof(params));
 
-	params.param0.depxfercfg.number_xfer_resources = 1;
+	params.param0 = DWC3_DEPXFERCFG_NUM_XFER_RES(1);
 
 	return dwc3_send_gadget_ep_cmd(dwc, dep->number,
 			DWC3_DEPCMD_SETTRANSFRESOURCE, &params);
@@ -387,15 +397,16 @@ static int __dwc3_gadget_ep_disable(struct dwc3_ep *dep)
 	struct dwc3		*dwc = dep->dwc;
 	u32			reg;
 
-	dep->flags &= ~DWC3_EP_ENABLED;
 	dwc3_remove_requests(dwc, dep);
 
 	reg = dwc3_readl(dwc->regs, DWC3_DALEPENA);
 	reg &= ~DWC3_DALEPENA_EP(dep->number);
 	dwc3_writel(dwc->regs, DWC3_DALEPENA, reg);
 
+	dep->stream_capable = false;
 	dep->desc = NULL;
 	dep->type = 0;
+	dep->flags = 0;
 
 	return 0;
 }
@@ -629,6 +640,9 @@ static struct dwc3_request *dwc3_prepare_trbs(struct dwc3_ep *dep,
 			trb.lst = last_one;
 		}
 
+		if (usb_endpoint_xfer_bulk(dep->desc) && dep->stream_capable)
+			trb.sid_sofn = req->request.stream_id;
+
 		switch (usb_endpoint_type(dep->desc)) {
 		case USB_ENDPOINT_XFER_CONTROL:
 			trb.trbctl = DWC3_TRBCTL_CONTROL_SETUP;
@@ -705,10 +719,8 @@ static int __dwc3_gadget_kick_transfer(struct dwc3_ep *dep, u16 cmd_param,
 	}
 
 	memset(&params, 0, sizeof(params));
-	params.param0.depstrtxfer.transfer_desc_addr_high =
-		upper_32_bits(req->trb_dma);
-	params.param1.depstrtxfer.transfer_desc_addr_low =
-		lower_32_bits(req->trb_dma);
+	params.param0 = upper_32_bits(req->trb_dma);
+	params.param1 = lower_32_bits(req->trb_dma);
 
 	if (start_new)
 		cmd = DWC3_DEPCMD_STARTTRANSFER;
@@ -891,6 +903,9 @@ int __dwc3_gadget_ep_set_halt(struct dwc3_ep *dep, int value)
 		else
 			dep->flags |= DWC3_EP_STALL;
 	} else {
+		if (dep->flags & DWC3_EP_WEDGE)
+			return 0;
+
 		ret = dwc3_send_gadget_ep_cmd(dwc, dep->number,
 			DWC3_DEPCMD_CLEARSTALL, &params);
 		if (ret)
@@ -900,6 +915,7 @@ int __dwc3_gadget_ep_set_halt(struct dwc3_ep *dep, int value)
 		else
 			dep->flags &= ~DWC3_EP_STALL;
 	}
+
 	return ret;
 }
 
@@ -933,7 +949,7 @@ static int dwc3_gadget_ep_set_wedge(struct usb_ep *ep)
 
 	dep->flags |= DWC3_EP_WEDGE;
 
-	return usb_ep_set_halt(ep);
+	return dwc3_gadget_ep_set_halt(ep, 1);
 }
 
 /* -------------------------------------------------------------------------- */
@@ -1146,6 +1162,14 @@ static int dwc3_gadget_start(struct usb_gadget *g,
 	reg &= ~DWC3_GCTL_DISSCRAMBLE;
 	reg |= DWC3_GCTL_PRTCAPDIR(DWC3_GCTL_PRTCAP_DEVICE);
 
+	switch (DWC3_GHWPARAMS1_EN_PWROPT(dwc->hwparams.hwparams0)) {
+	case DWC3_GHWPARAMS1_EN_PWROPT_CLK:
+		reg &= ~DWC3_GCTL_DSBLCLKGTNG;
+		break;
+	default:
+		dev_dbg(dwc->dev, "No power optimization available\n");
+	}
+
 	/*
 	 * WORKAROUND: DWC3 revisions <1.90a have a bug
 	 * when The device fails to connect at SuperSpeed
@@ -1162,6 +1186,8 @@ static int dwc3_gadget_start(struct usb_gadget *g,
 	reg |= DWC3_DCFG_SUPERSPEED;
 	dwc3_writel(dwc->regs, DWC3_DCFG, reg);
 
+	dwc->start_config_issued = false;
+
 	/* Start with SuperSpeed Default */
 	dwc3_gadget_ep0_desc.wMaxPacketSize = cpu_to_le16(512);
 
@@ -1495,12 +1521,28 @@ static void dwc3_endpoint_interrupt(struct dwc3 *dwc,
 		}
 
 		break;
+	case DWC3_DEPEVT_STREAMEVT:
+		if (!usb_endpoint_xfer_bulk(dep->desc)) {
+			dev_err(dwc->dev, "Stream event for non-Bulk %s\n",
+					dep->name);
+			return;
+		}
+
+		switch (event->status) {
+		case DEPEVT_STREAMEVT_FOUND:
+			dev_vdbg(dwc->dev, "Stream %d found and started\n",
+					event->parameters);
+
+			break;
+		case DEPEVT_STREAMEVT_NOTFOUND:
+			/* FALLTHROUGH */
+		default:
+			dev_dbg(dwc->dev, "Couldn't find suitable stream\n");
+		}
+		break;
 	case DWC3_DEPEVT_RXTXFIFOEVT:
 		dev_dbg(dwc->dev, "%s FIFO Overrun\n", dep->name);
 		break;
-	case DWC3_DEPEVT_STREAMEVT:
-		dev_dbg(dwc->dev, "%s Stream Event\n", dep->name);
-		break;
 	case DWC3_DEPEVT_EPCMDCMPLT:
 		dwc3_ep_cmd_compl(dep, event);
 		break;
@@ -1593,6 +1635,7 @@ static void dwc3_gadget_disconnect_interrupt(struct dwc3 *dwc)
 
 	dwc3_stop_active_transfers(dwc);
 	dwc3_disconnect_gadget(dwc);
+	dwc->start_config_issued = false;
 
 	dwc->gadget.speed = USB_SPEED_UNKNOWN;
 }
@@ -1644,30 +1687,12 @@ static void dwc3_gadget_reset_interrupt(struct dwc3 *dwc)
 
 	dwc3_stop_active_transfers(dwc);
 	dwc3_clear_stall_all_ep(dwc);
+	dwc->start_config_issued = false;
 
 	/* Reset device address to zero */
 	reg = dwc3_readl(dwc->regs, DWC3_DCFG);
 	reg &= ~(DWC3_DCFG_DEVADDR_MASK);
 	dwc3_writel(dwc->regs, DWC3_DCFG, reg);
-
-	/*
-	 * Wait for RxFifo to drain
-	 *
-	 * REVISIT probably shouldn't wait forever.
-	 * In case Hardware ends up in a screwed up
-	 * case, we error out, notify the user and,
-	 * maybe, WARN() or BUG() but leave the rest
-	 * of the kernel working fine.
-	 *
-	 * REVISIT the below is rather CPU intensive,
-	 * maybe we should read and if it doesn't work
-	 * sleep (not busy wait) for a few useconds.
-	 *
-	 * REVISIT why wait until the RXFIFO is empty anyway?
-	 */
-	while (!(dwc3_readl(dwc->regs, DWC3_DSTS)
-				& DWC3_DSTS_RXFIFOEMPTY))
-		cpu_relax();
 }
 
 static void dwc3_update_ram_clk_sel(struct dwc3 *dwc, u32 speed)
diff --git a/drivers/usb/dwc3/gadget.h b/drivers/usb/dwc3/gadget.h
index 4809ac8..71145a4 100644
--- a/drivers/usb/dwc3/gadget.h
+++ b/drivers/usb/dwc3/gadget.h
@@ -2,7 +2,6 @@
  * gadget.h - DesignWare USB3 DRD Gadget Header
  *
  * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com
- * All rights reserved.
  *
  * Authors: Felipe Balbi <balbi@ti.com>,
  *	    Sebastian Andrzej Siewior <bigeasy@linutronix.de>
@@ -48,120 +47,35 @@ struct dwc3;
 #define to_dwc3_ep(ep)		(container_of(ep, struct dwc3_ep, endpoint))
 #define gadget_to_dwc(g)	(container_of(g, struct dwc3, gadget))
 
-/**
- * struct dwc3_gadget_ep_depcfg_param1 - DEPCMDPAR0 for DEPCFG command
- * @interrupt_number: self-explanatory
- * @reserved7_5: set to zero
- * @xfer_complete_enable: event generated when transfer completed
- * @xfer_in_progress_enable: event generated when transfer in progress
- * @xfer_not_ready_enable: event generated when transfer not read
- * @fifo_error_enable: generates events when FIFO Underrun (IN eps)
- *	or FIFO Overrun (OUT) eps
- * @reserved_12: set to zero
- * @stream_event_enable: event generated on stream
- * @reserved14_15: set to zero
- * @binterval_m1: bInterval minus 1
- * @stream_capable: this EP is capable of handling streams
- * @ep_number: self-explanatory
- * @bulk_based: Set to ‘1' if this isochronous endpoint represents a bulk
- *	data stream that ignores the relationship of bus time to the
- *	intervals programmed in TRBs.
- * @fifo_based: Set to ‘1' if this isochronous endpoint represents a
- *	FIFO-based data stream where TRBs have fixed values and are never
- *	written back by the core.
- */
-struct dwc3_gadget_ep_depcfg_param1 {
-	u32	interrupt_number:5;
-	u32	reserved7_5:3;		/* set to zero */
-	u32	xfer_complete_enable:1;
-	u32	xfer_in_progress_enable:1;
-	u32	xfer_not_ready_enable:1;
-	u32	fifo_error_enable:1;	/* IN-underrun, OUT-overrun */
-	u32	reserved12:1;		/* set to zero */
-	u32	stream_event_enable:1;
-	u32	reserved14_15:2;
-	u32	binterval_m1:8;		/* bInterval minus 1 */
-	u32	stream_capable:1;
-	u32	ep_number:5;
-	u32	bulk_based:1;
-	u32	fifo_based:1;
-} __packed;
-
-/**
- * struct dwc3_gadget_ep_depcfg_param0 - Parameter 0 for DEPCFG
- * @reserved0: set to zero
- * @ep_type: Endpoint Type (control, bulk, iso, interrupt)
- * @max_packet_size: max packet size in bytes
- * @reserved16_14: set to zero
- * @fifo_number: self-explanatory
- * @burst_size: burst size minus 1
- * @data_sequence_number: Must be 0 when an endpoint is initially configured
- *	May be non-zero when an endpoint is configured after a power transition
- *	that requires a save/restore.
- * @ignore_sequence_number: Set to ‘1' to avoid resetting the sequence
- *	number. This setting is used by software to modify the DEPEVTEN
- *	event enable bits without modifying other endpoint settings.
- */
-struct dwc3_gadget_ep_depcfg_param0 {
-	u32	reserved0:1;
-	u32	ep_type:2;
-	u32	max_packet_size:11;
-	u32	reserved16_14:3;
-	u32	fifo_number:5;
-	u32	burst_size:4;
-	u32	data_sequence_number:5;
-	u32	ignore_sequence_number:1;
-} __packed;
-
-/**
- * struct dwc3_gadget_ep_depxfercfg_param0 - Parameter 0 of DEPXFERCFG
- * @number_xfer_resources: Defines the number of Transfer Resources allocated
- *	to this endpoint.  This field must be set to 1.
- * @reserved16_31: set to zero;
- */
-struct dwc3_gadget_ep_depxfercfg_param0 {
-	u32		number_xfer_resources:16;
-	u32		reserved16_31:16;
-} __packed;
-
-/**
- * struct dwc3_gadget_ep_depstrtxfer_param1 - Parameter 1 of DEPSTRTXFER
- * @transfer_desc_addr_low: Indicates the lower 32 bits of the external
- *	memory's start address for the transfer descriptor. Because TRBs
- *	must be aligned to a 16-byte boundary, the lower 4 bits of this
- *	address must be 0.
- */
-struct dwc3_gadget_ep_depstrtxfer_param1 {
-	u32		transfer_desc_addr_low;
-} __packed;
-
-/**
- * struct dwc3_gadget_ep_depstrtxfer_param1 - Parameter 1 of DEPSTRTXFER
- * @transfer_desc_addr_high: Indicates the higher 32 bits of the external
- *	memory's start address for the transfer descriptor.
- */
-struct dwc3_gadget_ep_depstrtxfer_param0 {
-	u32		transfer_desc_addr_high;
-} __packed;
+/* DEPCFG parameter 1 */
+#define DWC3_DEPCFG_INT_NUM(n)		((n) << 0)
+#define DWC3_DEPCFG_XFER_COMPLETE_EN	(1 << 8)
+#define DWC3_DEPCFG_XFER_IN_PROGRESS_EN	(1 << 9)
+#define DWC3_DEPCFG_XFER_NOT_READY_EN	(1 << 10)
+#define DWC3_DEPCFG_FIFO_ERROR_EN	(1 << 11)
+#define DWC3_DEPCFG_STREAM_EVENT_EN	(1 << 13)
+#define DWC3_DEPCFG_BINTERVAL_M1(n)	((n) << 16)
+#define DWC3_DEPCFG_STREAM_CAPABLE	(1 << 24)
+#define DWC3_DEPCFG_EP_NUMBER(n)	((n) << 25)
+#define DWC3_DEPCFG_BULK_BASED		(1 << 30)
+#define DWC3_DEPCFG_FIFO_BASED		(1 << 31)
+
+/* DEPCFG parameter 0 */
+#define DWC3_DEPCFG_EP_TYPE(n)		((n) << 1)
+#define DWC3_DEPCFG_MAX_PACKET_SIZE(n)	((n) << 3)
+#define DWC3_DEPCFG_FIFO_NUMBER(n)	((n) << 17)
+#define DWC3_DEPCFG_BURST_SIZE(n)	((n) << 22)
+#define DWC3_DEPCFG_DATA_SEQ_NUM(n)	((n) << 26)
+#define DWC3_DEPCFG_IGN_SEQ_NUM		(1 << 31)
+
+/* DEPXFERCFG parameter 0 */
+#define DWC3_DEPXFERCFG_NUM_XFER_RES(n)	((n) & 0xffff)
 
 struct dwc3_gadget_ep_cmd_params {
-	union {
-		u32	raw;
-	} param2;
-
-	union {
-		u32	raw;
-		struct dwc3_gadget_ep_depcfg_param1 depcfg;
-		struct dwc3_gadget_ep_depstrtxfer_param1 depstrtxfer;
-	} param1;
-
-	union {
-		u32	raw;
-		struct dwc3_gadget_ep_depcfg_param0 depcfg;
-		struct dwc3_gadget_ep_depxfercfg_param0 depxfercfg;
-		struct dwc3_gadget_ep_depstrtxfer_param0 depstrtxfer;
-	} param0;
-} __packed;
+	u32	param2;
+	u32	param1;
+	u32	param0;
+};
 
 /* -------------------------------------------------------------------------- */
 
diff --git a/drivers/usb/dwc3/io.h b/drivers/usb/dwc3/io.h
index 0c4e2a9..bc957db 100644
--- a/drivers/usb/dwc3/io.h
+++ b/drivers/usb/dwc3/io.h
@@ -2,7 +2,6 @@
  * io.h - DesignWare USB3 DRD IO Header
  *
  * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com
- * All rights reserved.
  *
  * Authors: Felipe Balbi <balbi@ti.com>,
  *	    Sebastian Andrzej Siewior <bigeasy@linutronix.de>
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic