From: Dinh Nguyen <dingu...@altera.com>

The dwc2 IP on the SOCFPGA cannot use the default HW configured
FIFO sizes. The total FIFO depth as read from GHWCFG3 reports 0x1f80 or 8064
32-bit words. But the GRXFSIZ, GNPTXFSIZ, and HPTXFSIZ register defaults
to 0x2000 or 8192 32-bit words. So the driver cannot just use the fifo sizes
as read from those registers.

For platforms that face the same issue, this commits sets the RX, periodic TX,
and non-periodic TX fifo size to those that are recommended v2.93a spec for
the DWC2 IP.

Signed-off-by: Dinh Nguyen <dingu...@altera.com>
Cc: Paul Zimmerman <pa...@synopsys.com>
Cc: Greg Kroah-Hartman <gre...@linuxfoundation.org>
---
 drivers/usb/dwc2/core.c |   41 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 41 insertions(+)

diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c
index 1d12988..e8e394c 100644
--- a/drivers/usb/dwc2/core.c
+++ b/drivers/usb/dwc2/core.c
@@ -507,6 +507,44 @@ void dwc2_disable_host_interrupts(struct dwc2_hsotg *hsotg)
        writel(intmsk, hsotg->regs + GINTMSK);
 }
 
+/*
+ * 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.
+ *
+ * @hsotg: Programming view of DWC_otg controller
+ */
+static void dwc2_calculate_dynamic_fifo(struct dwc2_hsotg *hsotg)
+{
+       struct dwc2_core_params *params = hsotg->core_params;
+       struct dwc2_hw_params *hw = &hsotg->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;
+
+       if (total_fifo_size >= (rxfsiz + nptxfsiz + ptxfsiz))
+               /* Params are valid, nothing to do */
+               return;
+       else {
+               /* min rx fifo size = ((largest packet/4)*2)+2 */
+               rxfsiz = (512/4) * 2 + 2;
+               /* min non-periodic tx fifo depth */
+               nptxfsiz = 2 * (512/4);
+               /* min periodic tx fifo depth */
+               ptxfsiz = (512 * 3)/4;
+       }
+
+       if (total_fifo_size < (rxfsiz + nptxfsiz + ptxfsiz))
+               dev_err(hsotg->dev, "invalid fifo sizes\n");
+
+       params->host_rx_fifo_size = rxfsiz;
+       params->host_nperio_tx_fifo_size = nptxfsiz;
+       params->host_perio_tx_fifo_size = ptxfsiz;
+}
+
 static void dwc2_config_fifos(struct dwc2_hsotg *hsotg)
 {
        struct dwc2_core_params *params = hsotg->core_params;
@@ -515,6 +553,9 @@ static void dwc2_config_fifos(struct dwc2_hsotg *hsotg)
        if (!params->enable_dynamic_fifo)
                return;
 
+       /* Calculate the correct FIFO sizes */
+       dwc2_calculate_dynamic_fifo(hsotg);
+
        /* Rx FIFO */
        grxfsiz = readl(hsotg->regs + GRXFSIZ);
        dev_dbg(hsotg->dev, "initial grxfsiz=%08x\n", grxfsiz);
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to