aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/dwc2/gadget.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/dwc2/gadget.c')
-rw-r--r--drivers/usb/dwc2/gadget.c53
1 files changed, 42 insertions, 11 deletions
diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c
index 4cd6403a7566..24fbebc9b409 100644
--- a/drivers/usb/dwc2/gadget.c
+++ b/drivers/usb/dwc2/gadget.c
@@ -186,10 +186,9 @@ static void dwc2_hsotg_ctrl_epint(struct dwc2_hsotg *hsotg,
186 */ 186 */
187static void dwc2_hsotg_init_fifo(struct dwc2_hsotg *hsotg) 187static void dwc2_hsotg_init_fifo(struct dwc2_hsotg *hsotg)
188{ 188{
189 unsigned int fifo; 189 unsigned int ep;
190 unsigned int addr; 190 unsigned int addr;
191 int timeout; 191 int timeout;
192 u32 dptxfsizn;
193 u32 val; 192 u32 val;
194 193
195 /* Reset fifo map if not correctly cleared during previous session */ 194 /* Reset fifo map if not correctly cleared during previous session */
@@ -217,16 +216,16 @@ static void dwc2_hsotg_init_fifo(struct dwc2_hsotg *hsotg)
217 * them to endpoints dynamically according to maxpacket size value of 216 * them to endpoints dynamically according to maxpacket size value of
218 * given endpoint. 217 * given endpoint.
219 */ 218 */
220 for (fifo = 1; fifo < MAX_EPS_CHANNELS; fifo++) { 219 for (ep = 1; ep < MAX_EPS_CHANNELS; ep++) {
221 dptxfsizn = dwc2_readl(hsotg->regs + DPTXFSIZN(fifo)); 220 if (!hsotg->g_tx_fifo_sz[ep])
222 221 continue;
223 val = (dptxfsizn & FIFOSIZE_DEPTH_MASK) | addr; 222 val = addr;
224 addr += dptxfsizn >> FIFOSIZE_DEPTH_SHIFT; 223 val |= hsotg->g_tx_fifo_sz[ep] << FIFOSIZE_DEPTH_SHIFT;
225 224 WARN_ONCE(addr + hsotg->g_tx_fifo_sz[ep] > hsotg->fifo_mem,
226 if (addr > hsotg->fifo_mem) 225 "insufficient fifo memory");
227 break; 226 addr += hsotg->g_tx_fifo_sz[ep];
228 227
229 dwc2_writel(val, hsotg->regs + DPTXFSIZN(fifo)); 228 dwc2_writel(val, hsotg->regs + DPTXFSIZN(ep));
230 } 229 }
231 230
232 /* 231 /*
@@ -3807,10 +3806,36 @@ static void dwc2_hsotg_dump(struct dwc2_hsotg *hsotg)
3807static void dwc2_hsotg_of_probe(struct dwc2_hsotg *hsotg) 3806static void dwc2_hsotg_of_probe(struct dwc2_hsotg *hsotg)
3808{ 3807{
3809 struct device_node *np = hsotg->dev->of_node; 3808 struct device_node *np = hsotg->dev->of_node;
3809 u32 len = 0;
3810 u32 i = 0;
3810 3811
3811 /* Enable dma if requested in device tree */ 3812 /* Enable dma if requested in device tree */
3812 hsotg->g_using_dma = of_property_read_bool(np, "g-use-dma"); 3813 hsotg->g_using_dma = of_property_read_bool(np, "g-use-dma");
3813 3814
3815 /*
3816 * Register TX periodic fifo size per endpoint.
3817 * EP0 is excluded since it has no fifo configuration.
3818 */
3819 if (!of_find_property(np, "g-tx-fifo-size", &len))
3820 goto rx_fifo;
3821
3822 len /= sizeof(u32);
3823
3824 /* Read tx fifo sizes other than ep0 */
3825 if (of_property_read_u32_array(np, "g-tx-fifo-size",
3826 &hsotg->g_tx_fifo_sz[1], len))
3827 goto rx_fifo;
3828
3829 /* Add ep0 */
3830 len++;
3831
3832 /* Make remaining TX fifos unavailable */
3833 if (len < MAX_EPS_CHANNELS) {
3834 for (i = len; i < MAX_EPS_CHANNELS; i++)
3835 hsotg->g_tx_fifo_sz[i] = 0;
3836 }
3837
3838rx_fifo:
3814 /* Register RX fifo size */ 3839 /* Register RX fifo size */
3815 of_property_read_u32(np, "g-rx-fifo-size", &hsotg->g_rx_fifo_sz); 3840 of_property_read_u32(np, "g-rx-fifo-size", &hsotg->g_rx_fifo_sz);
3816 3841
@@ -3832,10 +3857,13 @@ int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq)
3832 struct device *dev = hsotg->dev; 3857 struct device *dev = hsotg->dev;
3833 int epnum; 3858 int epnum;
3834 int ret; 3859 int ret;
3860 int i;
3861 u32 p_tx_fifo[] = DWC2_G_P_LEGACY_TX_FIFO_SIZE;
3835 3862
3836 /* Initialize to legacy fifo configuration values */ 3863 /* Initialize to legacy fifo configuration values */
3837 hsotg->g_rx_fifo_sz = 2048; 3864 hsotg->g_rx_fifo_sz = 2048;
3838 hsotg->g_np_g_tx_fifo_sz = 1024; 3865 hsotg->g_np_g_tx_fifo_sz = 1024;
3866 memcpy(&hsotg->g_tx_fifo_sz[1], p_tx_fifo, sizeof(p_tx_fifo));
3839 /* Device tree specific probe */ 3867 /* Device tree specific probe */
3840 dwc2_hsotg_of_probe(hsotg); 3868 dwc2_hsotg_of_probe(hsotg);
3841 3869
@@ -3853,6 +3881,9 @@ int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq)
3853 dev_dbg(dev, "NonPeriodic TXFIFO size: %d\n", 3881 dev_dbg(dev, "NonPeriodic TXFIFO size: %d\n",
3854 hsotg->g_np_g_tx_fifo_sz); 3882 hsotg->g_np_g_tx_fifo_sz);
3855 dev_dbg(dev, "RXFIFO size: %d\n", hsotg->g_rx_fifo_sz); 3883 dev_dbg(dev, "RXFIFO size: %d\n", hsotg->g_rx_fifo_sz);
3884 for (i = 0; i < MAX_EPS_CHANNELS; i++)
3885 dev_dbg(dev, "Periodic TXFIFO%2d size: %d\n", i,
3886 hsotg->g_tx_fifo_sz[i]);
3856 3887
3857 hsotg->gadget.max_speed = USB_SPEED_HIGH; 3888 hsotg->gadget.max_speed = USB_SPEED_HIGH;
3858 hsotg->gadget.ops = &dwc2_hsotg_gadget_ops; 3889 hsotg->gadget.ops = &dwc2_hsotg_gadget_ops;