DWC2_L3, /* Off state */
};
+/*
+ * Gadget periodic tx fifo sizes as used by legacy driver
+ * EP0 is not included
+ */
+#define DWC2_G_P_LEGACY_TX_FIFO_SIZE {256, 256, 256, 256, 768, 768, 768, \
+ 768, 0, 0, 0, 0, 0, 0, 0}
+
/**
* struct dwc2_core_params - Parameters for configuring the core
*
* @last_rst: Time of last reset
* @eps: The endpoints being supplied to the gadget framework
* @g_using_dma: Indicate if dma usage is enabled
+ * @g_rx_fifo_sz: Contains rx fifo size value
+ * @g_np_g_tx_fifo_sz: Contains Non-Periodic tx fifo size value
+ * @g_tx_fifo_sz: Contains tx fifo size value per endpoints
*/
struct dwc2_hsotg {
struct device *dev;
struct s3c_hsotg_ep *eps_in[MAX_EPS_CHANNELS];
struct s3c_hsotg_ep *eps_out[MAX_EPS_CHANNELS];
u32 g_using_dma;
+ u32 g_rx_fifo_sz;
+ u32 g_np_g_tx_fifo_sz;
+ u32 g_tx_fifo_sz[MAX_EPS_CHANNELS];
#endif /* CONFIG_USB_DWC2_PERIPHERAL || CONFIG_USB_DWC2_DUAL_ROLE */
};
{
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
*/
/* 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));
}
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) { }
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