usb: dwc3: resize tx fifos for rockchip platform

Due to TX FIFO size limits on Rockchip platform, we need to
resize TX FIFOs more precisely based on USB transfer type
and Speed, so implement the private method hooked to the
original function.

If you want to enable the Tx fifos resize on rockchip platform,
add the property "tx-fifo-resize" in DTS usbdrd_dwc3 node.

By default, we recommend not to enable the Tx fifo resize,
because the default TxFIFO depth configuration in the
GTXFIFOSIZ(#n) is enough for most of USB composite device.

And for mult UVC function (e.g 2 * UVC + 1 * UAC + ADB),
it needs to enable the Tx fifo resize for UVC streaming
endpoints with 1024 maxpacket.

Note that, the Tx fifos resize code only assign 64 bytes
TxFIFO depth for interrupt endpoint which usually used for
MTP and HID function. If you want to support HID EP-IN
to transfer maxpacket more than 64 bytes, you need to
change the maxpacket of usb_endpoint_xfer_int(dep->endpoint.desc)
in the __dwc3_gadget_resize_tx_fifos().

Signed-off-by: Frank Wang <frank.wang@rock-chips.com>
Signed-off-by: William Wu <william.wu@rock-chips.com>
Change-Id: I8ff1ed206ac423e9076c8054eb07138658720f25
This commit is contained in:
Frank Wang
2022-06-08 15:43:49 +08:00
committed by Tao Huang
parent 0de7d2764b
commit d6b0925fc8

View File

@@ -748,6 +748,101 @@ void dwc3_gadget_clear_tx_fifos(struct dwc3 *dwc)
dwc->num_ep_resized = 0;
}
/**
* __dwc3_gadget_resize_tx_fifos - reallocate fifo spaces for Rockchip platform
*
* @dep: pointer to dwc3_ep structure
*
* According to the different USB transfer type and Speed,
* this function will a best effort FIFO allocation in order
* to improve FIFO usage and throughput, while still allowing
* us to enable as many endpoints as possible.
*/
static int __dwc3_gadget_resize_tx_fifos(struct dwc3_ep *dep)
{
struct dwc3 *dwc = dep->dwc;
u32 fifo_0_start, last_fifo_depth, ram1_depth;
u32 fifo_size, maxpacket, mdwidth, mult;
u32 tmp;
if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) {
/*
* Set enough tx fifos for Isochronous endpoints to get better
* performance and more compliance with bus latency.
*/
maxpacket = dep->endpoint.maxpacket;
if (gadget_is_superspeed(dwc->gadget))
mult = dep->endpoint.mult * dep->endpoint.maxburst;
else
mult = dep->endpoint.mult;
mult = mult > 0 ? mult * 2 : 3;
if (mult > 6)
mult = 6;
} else if (usb_endpoint_xfer_bulk(dep->endpoint.desc)) {
/*
* Set enough tx fifos for Bulk endpoints to get
* better transmission performance.
*/
mult = 3;
if (gadget_is_superspeed(dwc->gadget)) {
if (dep->endpoint.maxburst > mult) {
mult = dep->endpoint.maxburst;
if (mult > 6)
mult = 6;
}
maxpacket = 1024;
} else {
maxpacket = 512;
}
} else if (usb_endpoint_xfer_int(dep->endpoint.desc)) {
/*
* REVIST: we assume that the maxpacket of interrupt
* endpoint is 64 Bytes for MTP and the other functions.
*/
mult = 1;
maxpacket = 64;
} else {
goto out;
}
mdwidth = dwc3_mdwidth(dwc);
mdwidth >>= 3; /* bits convert to bytes */
ram1_depth = dwc3_gadget_get_tx_fifos_size(dwc);
last_fifo_depth = dwc->last_fifo_depth;
/* Calculate the fifo size for this EP */
tmp = mult * (maxpacket + mdwidth);
tmp += mdwidth;
fifo_size = DIV_ROUND_UP(tmp, mdwidth);
/* Check if TXFIFOs start at non-zero addr */
tmp = dwc3_readl(dwc->regs, DWC3_GTXFIFOSIZ(0));
fifo_0_start = DWC3_GTXFIFOSIZ_TXFSTADDR(tmp);
fifo_size |= (fifo_0_start + (last_fifo_depth << 16));
if (DWC3_IP_IS(DWC3))
last_fifo_depth += DWC3_GTXFIFOSIZ_TXFDEP(fifo_size);
else
last_fifo_depth += DWC31_GTXFIFOSIZ_TXFDEP(fifo_size);
/* Check fifo size allocation doesn't exceed available RAM size. */
if (last_fifo_depth >= ram1_depth) {
dev_err(dwc->dev, "Fifosize(0x%x) > RAM size(0x%x) %s depth(0x%x)\n",
last_fifo_depth, ram1_depth,
dep->endpoint.name, fifo_size & 0xfff);
return -ENOMEM;
}
dwc3_writel(dwc->regs, DWC3_GTXFIFOSIZ(dep->number >> 1), fifo_size);
dep->flags |= DWC3_EP_TXFIFO_RESIZED;
dwc->last_fifo_depth = last_fifo_depth;
dwc->num_ep_resized++;
out:
return 0;
}
/*
* dwc3_gadget_resize_tx_fifos - reallocate fifo spaces for current use-case
* @dwc: pointer to our context structure
@@ -793,6 +888,9 @@ static int dwc3_gadget_resize_tx_fifos(struct dwc3_ep *dep)
if (dep->flags & DWC3_EP_TXFIFO_RESIZED)
return 0;
if (IS_REACHABLE(CONFIG_ARCH_ROCKCHIP))
return __dwc3_gadget_resize_tx_fifos(dep);
ram1_depth = dwc3_gadget_get_tx_fifos_size(dwc);
if ((dep->endpoint.maxburst > 1 &&