[PATCHv2] usb: dwc2: Add function to calculate correct FIFO sizes

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Dinh Nguyen <dinguyen@xxxxxxxxxx>

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 <dinguyen@xxxxxxxxxx>
Acked-by: Paul Zimmerman <paulz@xxxxxxxxxxxx>
---
v2: Fix coding style with braces around both if() branches
---
 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..efa7a45 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 majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux