Commit 8897a761 authored by Felipe Balbi's avatar Felipe Balbi

usb: dwc3: gadget: make use of No Response Update Transfer

No Response Update Transfer is a special type of
Update Transfer command which can be used whenever
we're not relying on XferNotReady to prepare
transfers. With this, we don't need to wait for
CMDACT to be cleared and issue further commands to
the endpoint straight away.

Let's start using this version to skip the long-ish
wait.
Signed-off-by: default avatarFelipe Balbi <felipe.balbi@linux.intel.com>
parent 5999914f
...@@ -233,6 +233,7 @@ static int __dwc3_gadget_wakeup(struct dwc3 *dwc); ...@@ -233,6 +233,7 @@ static int __dwc3_gadget_wakeup(struct dwc3 *dwc);
int dwc3_send_gadget_ep_cmd(struct dwc3_ep *dep, unsigned cmd, int dwc3_send_gadget_ep_cmd(struct dwc3_ep *dep, unsigned cmd,
struct dwc3_gadget_ep_cmd_params *params) struct dwc3_gadget_ep_cmd_params *params)
{ {
const struct usb_endpoint_descriptor *desc = dep->endpoint.desc;
struct dwc3 *dwc = dep->dwc; struct dwc3 *dwc = dep->dwc;
u32 timeout = 500; u32 timeout = 500;
u32 reg; u32 reg;
...@@ -276,7 +277,28 @@ int dwc3_send_gadget_ep_cmd(struct dwc3_ep *dep, unsigned cmd, ...@@ -276,7 +277,28 @@ int dwc3_send_gadget_ep_cmd(struct dwc3_ep *dep, unsigned cmd,
dwc3_writel(dep->regs, DWC3_DEPCMDPAR1, params->param1); dwc3_writel(dep->regs, DWC3_DEPCMDPAR1, params->param1);
dwc3_writel(dep->regs, DWC3_DEPCMDPAR2, params->param2); dwc3_writel(dep->regs, DWC3_DEPCMDPAR2, params->param2);
dwc3_writel(dep->regs, DWC3_DEPCMD, cmd | DWC3_DEPCMD_CMDACT); /*
* Synopsys Databook 2.60a states in section 6.3.2.5.6 of that if we're
* not relying on XferNotReady, we can make use of a special "No
* Response Update Transfer" command where we should clear both CmdAct
* and CmdIOC bits.
*
* With this, we don't need to wait for command completion and can
* straight away issue further commands to the endpoint.
*
* NOTICE: We're making an assumption that control endpoints will never
* make use of Update Transfer command. This is a safe assumption
* because we can never have more than one request at a time with
* Control Endpoints. If anybody changes that assumption, this chunk
* needs to be updated accordingly.
*/
if (DWC3_DEPCMD_CMD(cmd) == DWC3_DEPCMD_UPDATETRANSFER &&
!usb_endpoint_xfer_isoc(desc))
cmd &= ~(DWC3_DEPCMD_CMDIOC | DWC3_DEPCMD_CMDACT);
else
cmd |= DWC3_DEPCMD_CMDACT;
dwc3_writel(dep->regs, DWC3_DEPCMD, cmd);
do { do {
reg = dwc3_readl(dep->regs, DWC3_DEPCMD); reg = dwc3_readl(dep->regs, DWC3_DEPCMD);
if (!(reg & DWC3_DEPCMD_CMDACT)) { if (!(reg & DWC3_DEPCMD_CMDACT)) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment