usb: dwc3: gadget: support to resize TxFIFOs dynamically

We need to dynamically resize the TxFIFOs for some cases
where the default values don't match.

Test on RK1808-stick board, configurate the usb with four
functions "rndis, ntb, mass_storage, acm", the default
values of TxFIFOs is:

GTXFIFOSIZ(0) = 0x00000042
GTXFIFOSIZ(1) = 0x00420184
GTXFIFOSIZ(2) = 0x01c60184
GTXFIFOSIZ(3) = 0x034a0184
GTXFIFOSIZ(4) = 0x04ce0184
GTXFIFOSIZ(5) = 0x06520184
GTXFIFOSIZ(6) = 0x07d6002a

The ep6-in is used for acm ep-in which maxpacket is 1024B,
but the default fifo size of ep6-in is only 336B, less than
the length of the ep maxpacket, it cause acm works abnormally.

This patch creates a simple function to allocate enough TxFIFO
space for each of the enabled endpoints.

Change-Id: I389ffdba4f3721ed6ef192f0c85f41fdeff645ce
Signed-off-by: William Wu <william.wu@rock-chips.com>
This commit is contained in:
William Wu
2019-07-05 15:09:19 +08:00
committed by Tao Huang
parent a67a9d3744
commit 256fb7670a
3 changed files with 86 additions and 0 deletions

View File

@@ -1048,6 +1048,8 @@ static int dwc3_probe(struct platform_device *pdev)
device_property_read_u32_array(dev, "snps,grx-threshold-cfg",
dwc->grxthrcfg, 2);
dwc->needs_fifo_resize = device_property_read_bool(dev,
"snps,tx-fifo-resize");
/* default to superspeed if no maximum_speed passed */
if (dwc->maximum_speed == USB_SPEED_UNKNOWN)

View File

@@ -843,6 +843,7 @@ struct dwc3_scratchpad_array {
* 1 - -3.5dB de-emphasis
* 2 - No de-emphasis
* 3 - Reserved
* @needs_fifo_resize: set if we want to resize TXFIFO.
*/
struct dwc3 {
struct usb_ctrlrequest *ctrl_req;
@@ -995,6 +996,7 @@ struct dwc3 {
unsigned tx_de_emphasis_quirk:1;
unsigned tx_de_emphasis:2;
unsigned needs_fifo_resize:1;
};
/* -------------------------------------------------------------------------- */

View File

@@ -145,6 +145,86 @@ int dwc3_gadget_set_link_state(struct dwc3 *dwc, enum dwc3_link_state state)
return -ETIMEDOUT;
}
/**
* dwc3_gadget_resize_tx_fifos - reallocate fifo spaces for current use-case
* @dwc: pointer to our context structure
*
* 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.
*
* Keep in mind that this operation will be highly dependent
* on the configured size for RAM1 - which contains TxFifo -,
* the amount of endpoints enabled on coreConsultant tool, and
* the width of the Master Bus.
*
* In the ideal world, we would always be able to satisfy the
* following equation:
*
* ((512 + 2 * MDWIDTH-Bytes) + (Number of IN Endpoints - 1) * \
* (3 * (1024 + MDWIDTH-Bytes) + MDWIDTH-Bytes)) / MDWIDTH-Bytes
*
* Unfortunately, due to many variables that's not always the case.
*/
static int dwc3_gadget_resize_tx_fifos(struct dwc3 *dwc)
{
int last_fifo_depth = 0;
int fifo_size;
int mdwidth;
u8 num;
if (!dwc->needs_fifo_resize)
return 0;
mdwidth = DWC3_MDWIDTH(dwc->hwparams.hwparams0);
/* MDWIDTH is represented in bits, we need it in bytes */
mdwidth >>= 3;
for (num = 0; num < dwc->num_in_eps; num++) {
u8 epnum = (num << 1) | 1;
struct dwc3_ep *dep = dwc->eps[epnum];
int fifo_number = dep->number >> 1;
int mult = 1;
int tmp;
if (!(dep->flags & DWC3_EP_ENABLED))
continue;
if (usb_endpoint_xfer_bulk(dep->endpoint.desc) ||
usb_endpoint_xfer_isoc(dep->endpoint.desc))
mult = 3;
/*
* REVISIT: the following assumes we will always have enough
* space available on the FIFO RAM for all possible use cases.
* Make sure that's true somehow and change FIFO allocation
* accordingly.
*
* If we have Bulk or Isochronous endpoints, we want
* them to be able to be very, very fast. So we're giving
* those endpoints a fifo_size which is enough for 3 full
* packets
*/
tmp = mult * (dep->endpoint.maxpacket + mdwidth);
tmp += mdwidth;
fifo_size = DIV_ROUND_UP(tmp, mdwidth);
fifo_size |= (last_fifo_depth << 16);
dev_dbg(dwc->dev, "%s: FIFO Addr %04x Size %d\n",
dep->name, last_fifo_depth, fifo_size & 0xffff);
dwc3_writel(dwc->regs, DWC3_GTXFIFOSIZ(fifo_number),
fifo_size);
last_fifo_depth += (fifo_size & 0xffff);
}
return 0;
}
/**
* dwc3_ep_inc_trb() - Increment a TRB index.
* @index - Pointer to the TRB index to increment.
@@ -714,6 +794,8 @@ static int dwc3_gadget_ep_enable(struct usb_ep *ep,
ret = __dwc3_gadget_ep_enable(dep, desc, ep->comp_desc, false, false);
spin_unlock_irqrestore(&dwc->lock, flags);
dwc3_gadget_resize_tx_fifos(dwc);
return ret;
}