Commit 112fe8e2 authored by Dinh Nguyen's avatar Dinh Nguyen Committed by Greg Kroah-Hartman

usb: dwc2: Add function to calculate correct FIFO sizes

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. Implements Method #2 from the Synopsys v2.93a spec for the DWC2.
Signed-off-by: default avatarDinh Nguyen <dinguyen@altera.com>
Acked-by: default avatarPaul Zimmerman <paulz@synopsys.com>
Reviewed-by: default avatarFelipe Balbi <balbi@ti.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 8b3e233e
...@@ -507,6 +507,72 @@ void dwc2_disable_host_interrupts(struct dwc2_hsotg *hsotg) ...@@ -507,6 +507,72 @@ void dwc2_disable_host_interrupts(struct dwc2_hsotg *hsotg)
writel(intmsk, hsotg->regs + GINTMSK); 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;
/*
* 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)))
dev_err(hsotg->dev, "invalid fifo sizes\n");
}
static void dwc2_config_fifos(struct dwc2_hsotg *hsotg) static void dwc2_config_fifos(struct dwc2_hsotg *hsotg)
{ {
struct dwc2_core_params *params = hsotg->core_params; struct dwc2_core_params *params = hsotg->core_params;
...@@ -515,6 +581,8 @@ static void dwc2_config_fifos(struct dwc2_hsotg *hsotg) ...@@ -515,6 +581,8 @@ static void dwc2_config_fifos(struct dwc2_hsotg *hsotg)
if (!params->enable_dynamic_fifo) if (!params->enable_dynamic_fifo)
return; return;
dwc2_calculate_dynamic_fifo(hsotg);
/* Rx FIFO */ /* Rx FIFO */
grxfsiz = readl(hsotg->regs + GRXFSIZ); grxfsiz = readl(hsotg->regs + GRXFSIZ);
dev_dbg(hsotg->dev, "initial grxfsiz=%08x\n", grxfsiz); dev_dbg(hsotg->dev, "initial grxfsiz=%08x\n", grxfsiz);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment