Skip to content

Commit 112fe8e

Browse files
Dinh Nguyengregkh
authored andcommitted
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: Dinh Nguyen <[email protected]> Acked-by: Paul Zimmerman <[email protected]> Reviewed-by: Felipe Balbi <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 8b3e233 commit 112fe8e

File tree

1 file changed

+68
-0
lines changed

1 file changed

+68
-0
lines changed

drivers/usb/dwc2/core.c

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -507,6 +507,72 @@ void dwc2_disable_host_interrupts(struct dwc2_hsotg *hsotg)
507507
writel(intmsk, hsotg->regs + GINTMSK);
508508
}
509509

510+
/*
511+
* dwc2_calculate_dynamic_fifo() - Calculates the default fifo size
512+
* For system that have a total fifo depth that is smaller than the default
513+
* RX + TX fifo size.
514+
*
515+
* @hsotg: Programming view of DWC_otg controller
516+
*/
517+
static void dwc2_calculate_dynamic_fifo(struct dwc2_hsotg *hsotg)
518+
{
519+
struct dwc2_core_params *params = hsotg->core_params;
520+
struct dwc2_hw_params *hw = &hsotg->hw_params;
521+
u32 rxfsiz, nptxfsiz, ptxfsiz, total_fifo_size;
522+
523+
total_fifo_size = hw->total_fifo_size;
524+
rxfsiz = params->host_rx_fifo_size;
525+
nptxfsiz = params->host_nperio_tx_fifo_size;
526+
ptxfsiz = params->host_perio_tx_fifo_size;
527+
528+
/*
529+
* Will use Method 2 defined in the DWC2 spec: minimum FIFO depth
530+
* allocation with support for high bandwidth endpoints. Synopsys
531+
* defines MPS(Max Packet size) for a periodic EP=1024, and for
532+
* non-periodic as 512.
533+
*/
534+
if (total_fifo_size < (rxfsiz + nptxfsiz + ptxfsiz)) {
535+
/*
536+
* For Buffer DMA mode/Scatter Gather DMA mode
537+
* 2 * ((Largest Packet size / 4) + 1 + 1) + n
538+
* with n = number of host channel.
539+
* 2 * ((1024/4) + 2) = 516
540+
*/
541+
rxfsiz = 516 + hw->host_channels;
542+
543+
/*
544+
* min non-periodic tx fifo depth
545+
* 2 * (largest non-periodic USB packet used / 4)
546+
* 2 * (512/4) = 256
547+
*/
548+
nptxfsiz = 256;
549+
550+
/*
551+
* min periodic tx fifo depth
552+
* (largest packet size*MC)/4
553+
* (1024 * 3)/4 = 768
554+
*/
555+
ptxfsiz = 768;
556+
557+
params->host_rx_fifo_size = rxfsiz;
558+
params->host_nperio_tx_fifo_size = nptxfsiz;
559+
params->host_perio_tx_fifo_size = ptxfsiz;
560+
}
561+
562+
/*
563+
* If the summation of RX, NPTX and PTX fifo sizes is still
564+
* bigger than the total_fifo_size, then we have a problem.
565+
*
566+
* We won't be able to allocate as many endpoints. Right now,
567+
* we're just printing an error message, but ideally this FIFO
568+
* allocation algorithm would be improved in the future.
569+
*
570+
* FIXME improve this FIFO allocation algorithm.
571+
*/
572+
if (unlikely(total_fifo_size < (rxfsiz + nptxfsiz + ptxfsiz)))
573+
dev_err(hsotg->dev, "invalid fifo sizes\n");
574+
}
575+
510576
static void dwc2_config_fifos(struct dwc2_hsotg *hsotg)
511577
{
512578
struct dwc2_core_params *params = hsotg->core_params;
@@ -515,6 +581,8 @@ static void dwc2_config_fifos(struct dwc2_hsotg *hsotg)
515581
if (!params->enable_dynamic_fifo)
516582
return;
517583

584+
dwc2_calculate_dynamic_fifo(hsotg);
585+
518586
/* Rx FIFO */
519587
grxfsiz = readl(hsotg->regs + GRXFSIZ);
520588
dev_dbg(hsotg->dev, "initial grxfsiz=%08x\n", grxfsiz);

0 commit comments

Comments
 (0)