|
@@ -174,15 +174,14 @@ static void s3c_hsotg_init_fifo(struct dwc2_hsotg *hsotg)
|
|
|
{
|
|
|
unsigned int ep;
|
|
|
unsigned int addr;
|
|
|
- unsigned int size;
|
|
|
int timeout;
|
|
|
u32 val;
|
|
|
|
|
|
- /* set FIFO sizes to 2048/1024 */
|
|
|
-
|
|
|
- writel(2048, hsotg->regs + GRXFSIZ);
|
|
|
- writel((2048 << FIFOSIZE_STARTADDR_SHIFT) |
|
|
|
- (1024 << FIFOSIZE_DEPTH_SHIFT), hsotg->regs + GNPTXFSIZ);
|
|
|
+ /* set RX/NPTX FIFO sizes */
|
|
|
+ writel(hsotg->g_rx_fifo_sz, hsotg->regs + GRXFSIZ);
|
|
|
+ writel((hsotg->g_rx_fifo_sz << FIFOSIZE_STARTADDR_SHIFT) |
|
|
|
+ (hsotg->g_np_g_tx_fifo_sz << FIFOSIZE_DEPTH_SHIFT),
|
|
|
+ hsotg->regs + GNPTXFSIZ);
|
|
|
|
|
|
/*
|
|
|
* arange all the rest of the TX FIFOs, as some versions of this
|
|
@@ -192,35 +191,21 @@ static void s3c_hsotg_init_fifo(struct dwc2_hsotg *hsotg)
|
|
|
*/
|
|
|
|
|
|
/* start at the end of the GNPTXFSIZ, rounded up */
|
|
|
- addr = 2048 + 1024;
|
|
|
+ addr = hsotg->g_rx_fifo_sz + hsotg->g_np_g_tx_fifo_sz;
|
|
|
|
|
|
/*
|
|
|
- * Because we have not enough memory to have each TX FIFO of size at
|
|
|
- * least 3072 bytes (the maximum single packet size), we create four
|
|
|
- * FIFOs of lenght 1024, and four of length 3072 bytes, and assing
|
|
|
+ * Configure fifos sizes from provided configuration and assign
|
|
|
* them to endpoints dynamically according to maxpacket size value of
|
|
|
* given endpoint.
|
|
|
*/
|
|
|
-
|
|
|
- /* 256*4=1024 bytes FIFO length */
|
|
|
- size = 256;
|
|
|
- for (ep = 1; ep <= 4; ep++) {
|
|
|
- val = addr;
|
|
|
- val |= size << FIFOSIZE_DEPTH_SHIFT;
|
|
|
- WARN_ONCE(addr + size > hsotg->fifo_mem,
|
|
|
- "insufficient fifo memory");
|
|
|
- addr += size;
|
|
|
-
|
|
|
- writel(val, hsotg->regs + DPTXFSIZN(ep));
|
|
|
- }
|
|
|
- /* 768*4=3072 bytes FIFO length */
|
|
|
- size = 768;
|
|
|
- for (ep = 5; ep <= 8; ep++) {
|
|
|
+ for (ep = 1; ep < MAX_EPS_CHANNELS; ep++) {
|
|
|
+ if (!hsotg->g_tx_fifo_sz[ep])
|
|
|
+ continue;
|
|
|
val = addr;
|
|
|
- val |= size << FIFOSIZE_DEPTH_SHIFT;
|
|
|
- WARN_ONCE(addr + size > hsotg->fifo_mem,
|
|
|
+ val |= hsotg->g_tx_fifo_sz[ep] << FIFOSIZE_DEPTH_SHIFT;
|
|
|
+ WARN_ONCE(addr + hsotg->g_tx_fifo_sz[ep] > hsotg->fifo_mem,
|
|
|
"insufficient fifo memory");
|
|
|
- addr += size;
|
|
|
+ addr += hsotg->g_tx_fifo_sz[ep];
|
|
|
|
|
|
writel(val, hsotg->regs + DPTXFSIZN(ep));
|
|
|
}
|
|
@@ -3495,9 +3480,42 @@ static void s3c_hsotg_delete_debug(struct dwc2_hsotg *hsotg)
|
|
|
static void s3c_hsotg_of_probe(struct dwc2_hsotg *hsotg)
|
|
|
{
|
|
|
struct device_node *np = hsotg->dev->of_node;
|
|
|
+ u32 len = 0;
|
|
|
+ u32 i = 0;
|
|
|
|
|
|
/* Enable dma if requested in device tree */
|
|
|
hsotg->g_using_dma = of_property_read_bool(np, "g-use-dma");
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Register TX periodic fifo size per endpoint.
|
|
|
+ * EP0 is excluded since it has no fifo configuration.
|
|
|
+ */
|
|
|
+ if (!of_find_property(np, "g-tx-fifo-size", &len))
|
|
|
+ goto rx_fifo;
|
|
|
+
|
|
|
+ len /= sizeof(u32);
|
|
|
+
|
|
|
+ /* Read tx fifo sizes other than ep0 */
|
|
|
+ if (of_property_read_u32_array(np, "g-tx-fifo-size",
|
|
|
+ &hsotg->g_tx_fifo_sz[1], len))
|
|
|
+ goto rx_fifo;
|
|
|
+
|
|
|
+ /* Add ep0 */
|
|
|
+ len++;
|
|
|
+
|
|
|
+ /* Make remaining TX fifos unavailable */
|
|
|
+ if (len < MAX_EPS_CHANNELS) {
|
|
|
+ for (i = len; i < MAX_EPS_CHANNELS; i++)
|
|
|
+ hsotg->g_tx_fifo_sz[i] = 0;
|
|
|
+ }
|
|
|
+
|
|
|
+rx_fifo:
|
|
|
+ /* Register RX fifo size */
|
|
|
+ of_property_read_u32(np, "g-rx-fifo-size", &hsotg->g_rx_fifo_sz);
|
|
|
+
|
|
|
+ /* Register NPTX fifo size */
|
|
|
+ of_property_read_u32(np, "g-np-tx-fifo-size",
|
|
|
+ &hsotg->g_np_g_tx_fifo_sz);
|
|
|
}
|
|
|
#else
|
|
|
static inline void s3c_hsotg_of_probe(struct dwc2_hsotg *hsotg) { }
|
|
@@ -3515,12 +3533,26 @@ int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq)
|
|
|
int epnum;
|
|
|
int ret;
|
|
|
int i;
|
|
|
+ u32 p_tx_fifo[] = DWC2_G_P_LEGACY_TX_FIFO_SIZE;
|
|
|
|
|
|
/* Set default UTMI width */
|
|
|
hsotg->phyif = GUSBCFG_PHYIF16;
|
|
|
|
|
|
s3c_hsotg_of_probe(hsotg);
|
|
|
|
|
|
+ /* Initialize to legacy fifo configuration values */
|
|
|
+ hsotg->g_rx_fifo_sz = 2048;
|
|
|
+ hsotg->g_np_g_tx_fifo_sz = 1024;
|
|
|
+ memcpy(&hsotg->g_tx_fifo_sz[1], p_tx_fifo, sizeof(p_tx_fifo));
|
|
|
+ /* Device tree specific probe */
|
|
|
+ s3c_hsotg_of_probe(hsotg);
|
|
|
+ /* Dump fifo information */
|
|
|
+ dev_dbg(dev, "NonPeriodic TXFIFO size: %d\n",
|
|
|
+ hsotg->g_np_g_tx_fifo_sz);
|
|
|
+ dev_dbg(dev, "RXFIFO size: %d\n", hsotg->g_rx_fifo_sz);
|
|
|
+ for (i = 0; i < MAX_EPS_CHANNELS; i++)
|
|
|
+ dev_dbg(dev, "Periodic TXFIFO%2d size: %d\n", i,
|
|
|
+ hsotg->g_tx_fifo_sz[i]);
|
|
|
/*
|
|
|
* If platform probe couldn't find a generic PHY or an old style
|
|
|
* USB PHY, fall back to pdata
|