Signed-off-by: Jules Maselbas <jmaselbas@xxxxxxxxx> --- drivers/usb/dwc2/host.c | 146 ++++++++++++++++++++++++++++++++++------ drivers/usb/dwc2/regs.h | 8 --- 2 files changed, 124 insertions(+), 30 deletions(-) diff --git a/drivers/usb/dwc2/host.c b/drivers/usb/dwc2/host.c index a1f2e3ea1..84eb9b627 100644 --- a/drivers/usb/dwc2/host.c +++ b/drivers/usb/dwc2/host.c @@ -437,6 +437,129 @@ int dwc2_submit_int_msg(struct usb_device *udev, unsigned long pipe, } } +/* + * dwc2_calculate_dynamic_fifo() - Calculates the default fifo size + * For system that have a total fifo depth that is smaller than the default + * RX + TX fifo size. + * + * @dwc2: Programming view of DWC_otg controller + */ +static void dwc2_calculate_dynamic_fifo(struct dwc2 *dwc2) +{ + struct dwc2_core_params *params = &dwc2->params; + struct dwc2_hw_params *hw = &dwc2->hw_params; + u32 rxfsiz, nptxfsiz, ptxfsiz, total_fifo_size; + + total_fifo_size = hw->total_fifo_size; + rxfsiz = params->host_rx_fifo_size; + nptxfsiz = params->host_nperio_tx_fifo_size; + ptxfsiz = params->host_perio_tx_fifo_size; + + /* + * Will use Method 2 defined in the DWC2 spec: minimum FIFO depth + * allocation with support for high bandwidth endpoints. Synopsys + * defines MPS(Max Packet size) for a periodic EP=1024, and for + * non-periodic as 512. + */ + if (total_fifo_size < (rxfsiz + nptxfsiz + ptxfsiz)) { + /* + * For Buffer DMA mode/Scatter Gather DMA mode + * 2 * ((Largest Packet size / 4) + 1 + 1) + n + * with n = number of host channel. + * 2 * ((1024/4) + 2) = 516 + */ + rxfsiz = 516 + hw->host_channels; + + /* + * min non-periodic tx fifo depth + * 2 * (largest non-periodic USB packet used / 4) + * 2 * (512/4) = 256 + */ + nptxfsiz = 256; + + /* + * min periodic tx fifo depth + * (largest packet size*MC)/4 + * (1024 * 3)/4 = 768 + */ + ptxfsiz = 768; + } + + params->host_rx_fifo_size = rxfsiz; + params->host_nperio_tx_fifo_size = nptxfsiz; + params->host_perio_tx_fifo_size = ptxfsiz; + + /* + * If the summation of RX, NPTX and PTX fifo sizes is still + * bigger than the total_fifo_size, then we have a problem. + * + * We won't be able to allocate as many endpoints. Right now, + * we're just printing an error message, but ideally this FIFO + * allocation algorithm would be improved in the future. + * + * FIXME improve this FIFO allocation algorithm. + */ + if (unlikely(total_fifo_size < (rxfsiz + nptxfsiz + ptxfsiz))) + dwc2_err(dwc2, "invalid fifo sizes\n"); +} + +static void dwc2_config_fifos(struct dwc2 *dwc2) +{ + struct dwc2_core_params *params = &dwc2->params; + u32 nptxfsiz, hptxfsiz, dfifocfg, grxfsiz; + + if (!params->enable_dynamic_fifo) + return; + + dwc2_calculate_dynamic_fifo(dwc2); + + /* Rx FIFO */ + grxfsiz = dwc2_readl(dwc2, GRXFSIZ); + dwc2_dbg(dwc2, "initial grxfsiz=%08x\n", grxfsiz); + grxfsiz &= ~GRXFSIZ_DEPTH_MASK; + grxfsiz |= params->host_rx_fifo_size << + GRXFSIZ_DEPTH_SHIFT & GRXFSIZ_DEPTH_MASK; + dwc2_writel(dwc2, grxfsiz, GRXFSIZ); + dwc2_dbg(dwc2, "new grxfsiz=%08x\n", dwc2_readl(dwc2, GRXFSIZ)); + + /* Non-periodic Tx FIFO */ + dwc2_dbg(dwc2, "initial gnptxfsiz=%08x\n", dwc2_readl(dwc2, GNPTXFSIZ)); + nptxfsiz = params->host_nperio_tx_fifo_size << + FIFOSIZE_DEPTH_SHIFT & FIFOSIZE_DEPTH_MASK; + nptxfsiz |= params->host_rx_fifo_size << + FIFOSIZE_STARTADDR_SHIFT & FIFOSIZE_STARTADDR_MASK; + dwc2_writel(dwc2, nptxfsiz, GNPTXFSIZ); + dwc2_dbg(dwc2, "new gnptxfsiz=%08x\n", dwc2_readl(dwc2, GNPTXFSIZ)); + + /* Periodic Tx FIFO */ + dwc2_dbg(dwc2, "initial hptxfsiz=%08x\n", dwc2_readl(dwc2, HPTXFSIZ)); + hptxfsiz = params->host_perio_tx_fifo_size << + FIFOSIZE_DEPTH_SHIFT & FIFOSIZE_DEPTH_MASK; + hptxfsiz |= (params->host_rx_fifo_size + + params->host_nperio_tx_fifo_size) << + FIFOSIZE_STARTADDR_SHIFT & FIFOSIZE_STARTADDR_MASK; + dwc2_writel(dwc2, hptxfsiz, HPTXFSIZ); + dwc2_dbg(dwc2, "new hptxfsiz=%08x\n", dwc2_readl(dwc2, HPTXFSIZ)); + + if (dwc2->params.en_multiple_tx_fifo && + dwc2->hw_params.snpsid >= DWC2_CORE_REV_2_91a) { + /* + * This feature was implemented in 2.91a version + * Global DFIFOCFG calculation for Host mode - + * include RxFIFO, NPTXFIFO and HPTXFIFO + */ + dfifocfg = dwc2_readl(dwc2, GDFIFOCFG); + dfifocfg &= ~GDFIFOCFG_EPINFOBASE_MASK; + dfifocfg |= (params->host_rx_fifo_size + + params->host_nperio_tx_fifo_size + + params->host_perio_tx_fifo_size) << + GDFIFOCFG_EPINFOBASE_SHIFT & + GDFIFOCFG_EPINFOBASE_MASK; + dwc2_writel(dwc2, dfifocfg, GDFIFOCFG); + dwc2_dbg(dwc2, "new dfifocfg=%08x\n", dfifocfg); + } +} + /* * This function initializes the DWC2 controller registers for * host mode. @@ -452,8 +575,6 @@ int dwc2_submit_int_msg(struct usb_device *udev, unsigned long pipe, static void dwc2_core_host_init(struct device_d *dev, struct dwc2 *dwc2) { - uint32_t nptxfifosize = 0; - uint32_t ptxfifosize = 0; uint32_t hcchar, hcfg, hprt0, hotgctl, usbcfg; int i, ret, num_channels; @@ -501,26 +622,7 @@ static void dwc2_core_host_init(struct device_d *dev, } } - /* Configure data FIFO sizes */ - if (dwc2_readl(dwc2, GHWCFG2) & GHWCFG2_DYNAMIC_FIFO) { - /* Rx FIFO */ - dwc2_writel(dwc2, CONFIG_DWC2_HOST_RX_FIFO_SIZE, GRXFSIZ); - - /* Non-periodic Tx FIFO */ - nptxfifosize |= CONFIG_DWC2_HOST_NPERIO_TX_FIFO_SIZE << - FIFOSIZE_DEPTH_SHIFT; - nptxfifosize |= CONFIG_DWC2_HOST_RX_FIFO_SIZE << - FIFOSIZE_STARTADDR_SHIFT; - dwc2_writel(dwc2, nptxfifosize, GNPTXFSIZ); - - /* Periodic Tx FIFO */ - ptxfifosize |= CONFIG_DWC2_HOST_PERIO_TX_FIFO_SIZE << - FIFOSIZE_DEPTH_SHIFT; - ptxfifosize |= (CONFIG_DWC2_HOST_RX_FIFO_SIZE + - CONFIG_DWC2_HOST_NPERIO_TX_FIFO_SIZE) << - FIFOSIZE_STARTADDR_SHIFT; - dwc2_writel(dwc2, ptxfifosize, HPTXFSIZ); - } + dwc2_config_fifos(dwc2); /* Clear Host Set HNP Enable in the OTG Control Register */ hotgctl = dwc2_readl(dwc2, GOTGCTL); diff --git a/drivers/usb/dwc2/regs.h b/drivers/usb/dwc2/regs.h index b2b312e1b..0dee1813d 100644 --- a/drivers/usb/dwc2/regs.h +++ b/drivers/usb/dwc2/regs.h @@ -836,12 +836,4 @@ struct dwc2_dma_desc { #define DWC2_FS_IOT_ID 0x55310000 #define DWC2_HS_IOT_ID 0x55320000 -/* ==== u-boot ==== */ - -/* Default driver configuration */ -#define CONFIG_DWC2_MAX_CHANNELS DWC2_MAX_EPS_CHANNELS /* Max # of EPs */ -#define CONFIG_DWC2_HOST_RX_FIFO_SIZE (516 + CONFIG_DWC2_MAX_CHANNELS) -#define CONFIG_DWC2_HOST_NPERIO_TX_FIFO_SIZE 0x100 /* nPeriodic TX FIFO */ -#define CONFIG_DWC2_HOST_PERIO_TX_FIFO_SIZE 0x200 /* Periodic TX FIFO */ - #endif /* __DWC2_H__ */ -- 2.21.0.196.g041f5ea _______________________________________________ barebox mailing list barebox@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/barebox