summaryrefslogtreecommitdiffstats
path: root/drivers/usb/dwc3/gadget.c
diff options
context:
space:
mode:
authorFelipe Balbi <balbi@ti.com>2012-01-18 18:04:09 +0200
committerFelipe Balbi <balbi@ti.com>2012-02-06 11:48:34 +0200
commit457e84b6624b4d97e6ffae437887ea51a22d54a0 (patch)
treee1ca1503cdda97570fa692589e44a1ca43e72d8b /drivers/usb/dwc3/gadget.c
parentbb5cfd6811c63c47403e98028bde7e98bd7a1751 (diff)
downloadtalos-op-linux-457e84b6624b4d97e6ffae437887ea51a22d54a0.tar.gz
talos-op-linux-457e84b6624b4d97e6ffae437887ea51a22d54a0.zip
usb: dwc3: gadget: dynamically re-size TxFifos
We need to dynamically re-size TxFifos for the cases where default values will not do. While at that, we create a simple function which, for now, will just allocate one full packet fifo space for each of the enabled endpoints. This can be improved later in order to allow for better throughput by allocating more space for endpoints which could make good use of that like isochronous and bulk. Signed-off-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers/usb/dwc3/gadget.c')
-rw-r--r--drivers/usb/dwc3/gadget.c74
1 files changed, 74 insertions, 0 deletions
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index d406a75456a0..7913d1b50e38 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -125,6 +125,80 @@ 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.
+ */
+int dwc3_gadget_resize_tx_fifos(struct dwc3 *dwc)
+{
+ int last_fifo_depth = 0;
+ int ram1_depth;
+ int fifo_size;
+ int mdwidth;
+ int num;
+
+ if (!dwc->needs_fifo_resize)
+ return 0;
+
+ ram1_depth = DWC3_RAM1_DEPTH(dwc->hwparams.hwparams7);
+ mdwidth = DWC3_MDWIDTH(dwc->hwparams.hwparams0);
+
+ /* MDWIDTH is represented in bits, we need it in bytes */
+ mdwidth >>= 3;
+
+ /*
+ * FIXME For now we will only allocate 1 wMaxPacketSize space
+ * for each enabled endpoint, later patches will come to
+ * improve this algorithm so that we better use the internal
+ * FIFO space
+ */
+ for (num = 0; num < DWC3_ENDPOINTS_NUM; num++) {
+ struct dwc3_ep *dep = dwc->eps[num];
+ int fifo_number = dep->number >> 1;
+ int tmp;
+
+ if (!(dep->number & 1))
+ continue;
+
+ if (!(dep->flags & DWC3_EP_ENABLED))
+ continue;
+
+ tmp = dep->endpoint.maxpacket;
+ tmp += mdwidth;
+ tmp += mdwidth;
+
+ fifo_size = DIV_ROUND_UP(tmp, mdwidth);
+ fifo_size |= (last_fifo_depth << 16);
+
+ dev_vdbg(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;
+}
+
void dwc3_map_buffer_to_dma(struct dwc3_request *req)
{
struct dwc3 *dwc = req->dep->dwc;
OpenPOWER on IntegriCloud