diff options
author | Gregory Herrero <gregory.herrero@intel.com> | 2015-01-09 13:38:52 +0100 |
---|---|---|
committer | Felipe Balbi <balbi@ti.com> | 2015-01-12 15:33:30 -0600 |
commit | 0a176279db6817cf865ed4c685e4a414be8226fd (patch) | |
tree | 7a7b9bc8b7ec3c8b3f5e4d28a0938d9e67af9a6d /drivers/usb/dwc2/gadget.c | |
parent | cec87f1d2686057654e4565b8eaab4f539e9afca (diff) | |
download | linux-0a176279db6817cf865ed4c685e4a414be8226fd.tar.gz |
usb: dwc2: gadget: configure fifos from device tree
As fifo size can vary between SOCs, add possibility to configure
them from device tree. Fifo sizes used by the legacy driver will
be used If they are not provided by the device tree.
Tested-by: Robert Baldyga <r.baldyga@samsung.com>
Acked-by: Paul Zimmerman <paulz@synopsys.com>
Signed-off-by: Gregory Herrero <gregory.herrero@intel.com>
Signed-off-by: Mian Yousaf Kaukab <yousaf.kaukab@intel.com>
Reviewed-by: Robert Baldyga <r.baldyga@samsung.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers/usb/dwc2/gadget.c')
-rw-r--r-- | drivers/usb/dwc2/gadget.c | 88 |
1 files changed, 60 insertions, 28 deletions
diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index b7879fd82674..c43ce7e8809a 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -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 |