diff options
Diffstat (limited to 'drivers/usb/dwc2/gadget.c')
-rw-r--r-- | drivers/usb/dwc2/gadget.c | 53 |
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 | */ |
187 | static void dwc2_hsotg_init_fifo(struct dwc2_hsotg *hsotg) | 187 | static 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) | |||
3807 | static void dwc2_hsotg_of_probe(struct dwc2_hsotg *hsotg) | 3806 | static 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 | |||
3838 | rx_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; |