|
@@ -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;
|