On 11/20/2017 4:48 PM, Stefan Wahren wrote: > Hi Minas, > > Am 20.11.2017 um 12:59 schrieb Minas Harutyunyan: >> Hi Stefan, >> Looks like I know cause of issue... but I'm overloaded today and will able to check it tomorrow. Sorry for delay. > > thanks for your reply. There is no need to hurry, because the merge > window isn't open yet, but i like to get this fixed for the next kernel > release. > > I have the suspicion this is related to the fact that u-boot already > initialize the USB IP, before dwc2 driver is loaded. > > Regards > Stefan > >> >> Thanks, >> Minas >> > > Hi Stefan, We have prepared patch for this issue in July-August'17. Find attached 2 patch files. Please apply patches and test. If issue gone, we will send these patches to LKML by regular flow. Thanks, Minas
From 8eff278552aaf248161df9af04f8b93f03526bcd Mon Sep 17 00:00:00 2001 From: Gevorg Sahakyan <sahakyan@xxxxxxxxxxxx> Date: Mon, 31 Jul 2017 17:19:51 +0400 Subject: [PATCH] usb: dwc2: Fix TxFIFO setup issue In host mode reading from DPTXSIZn returning invalid value(0) in dwc2_check_param_tx_fifo_sizes function. Added g_tx_fifo_size array in dwc2_hw_params structure in which stored power on reset valus of DPTXSIZn registers in device mode (forced to device). Updated dwc2_get_hwparams function to write DPTXFSIZn to array. Modyfied dwc2_check_param_tx_fifo_sizes function accordingly. Change-Id: I61d3db753b1bc06f0f2caf40df350a09655f18fd Signed-off-by: Gevorg Sahakyan <sahakyan@xxxxxxxxxxxx> --- diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index 5029dde..3b71b49 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -533,6 +533,7 @@ unsigned utmi_phy_data_width:2; u32 snpsid; u32 dev_ep_dirs; + u32 g_tx_fifo_size[MAX_EPS_CHANNELS]; }; /* Size of control and EP0 buffers */ diff --git a/drivers/usb/dwc2/params.c b/drivers/usb/dwc2/params.c index 701516e..79080a9 100644 --- a/drivers/usb/dwc2/params.c +++ b/drivers/usb/dwc2/params.c @@ -452,7 +452,6 @@ int fifo; int min; u32 total = 0; - u32 dptxfszn; fifo_count = dwc2_hsotg_tx_fifo_count(hsotg); min = hsotg->hw_params.en_multiple_tx_fifo ? 16 : 4; @@ -467,15 +466,15 @@ } for (fifo = 1; fifo <= fifo_count; fifo++) { - dptxfszn = (dwc2_readl(hsotg, DPTXFSIZN(fifo)) & - FIFOSIZE_DEPTH_MASK) >> FIFOSIZE_DEPTH_SHIFT; if (hsotg->params.g_tx_fifo_size[fifo] < min || - hsotg->params.g_tx_fifo_size[fifo] > dptxfszn) { + hsotg->params.g_tx_fifo_size[fifo] > + hsotg->hw_params.g_tx_fifo_size[fifo]) { dev_warn(hsotg->dev, "%s: Invalid parameter g_tx_fifo_size[%d]=%d\n", __func__, fifo, hsotg->params.g_tx_fifo_size[fifo]); - hsotg->params.g_tx_fifo_size[fifo] = dptxfszn; + hsotg->params.g_tx_fifo_size[fifo] = + hsotg->hw_params.g_tx_fifo_size[fifo]; } } } @@ -607,6 +606,7 @@ { struct dwc2_hw_params *hw = &hsotg->hw_params; unsigned int width; + int fifo, fifo_count; u32 hwcfg1, hwcfg2, hwcfg3, hwcfg4; u32 grxfsiz; @@ -675,6 +675,12 @@ hw->rx_fifo_size = (grxfsiz & GRXFSIZ_DEPTH_MASK) >> GRXFSIZ_DEPTH_SHIFT; + fifo_count = dwc2_hsotg_tx_fifo_count(hsotg); + + for (fifo = 1; fifo <= fifo_count; fifo++) { + hw->g_tx_fifo_size[fifo] = (dwc2_readl(hsotg, DPTXFSIZN(fifo)) & + FIFOSIZE_DEPTH_MASK) >> FIFOSIZE_DEPTH_SHIFT; + } return 0; }
From c6f7e1c790c4ef30ba818b119a177fdcd9ca7b34 Mon Sep 17 00:00:00 2001 From: Gevorg Sahakyan <sahakyan@xxxxxxxxxxxx> Date: Tue, 08 Aug 2017 15:45:32 +0400 Subject: [PATCH] usb: dwc2: Fix tx_fifo_total_depth calculation Removed ep_info subtraction during calculation tx_addr_max in dwc2_hsotg_tx_fifo_total_depth function, because its already done in hardware. Also removed dwc2_hsotg_ep_info_size function as no more need. Change-Id: If9a9f8ab115a6e998736ab991056f374eab9f747 Signed-off-by: Gevorg Sahakyan <sahakyan@xxxxxxxxxxxx> --- diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 98a4a79..3c52f46 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -206,47 +206,11 @@ } /** - * dwc2_hsotg_ep_info_size - return Endpoint Info Control block size in DWORDs - */ -static int dwc2_hsotg_ep_info_size(struct dwc2_hsotg *hsotg) -{ - int val = 0; - int i; - u32 ep_dirs; - - /* - * Don't need additional space for ep info control registers in - * slave mode. - */ - if (!using_dma(hsotg)) { - dev_dbg(hsotg->dev, "Buffer DMA ep info size 0\n"); - return 0; - } - - /* - * Buffer DMA mode - 1 location per endpoit - * Descriptor DMA mode - 4 locations per endpoint - */ - ep_dirs = hsotg->hw_params.dev_ep_dirs; - - for (i = 0; i <= hsotg->hw_params.num_dev_ep; i++) { - val += ep_dirs & 3 ? 1 : 2; - ep_dirs >>= 2; - } - - if (using_desc_dma(hsotg)) - val = val * 4; - - return val; -} - -/** * dwc2_hsotg_tx_fifo_total_depth - return total FIFO depth available for * device mode TX FIFOs */ int dwc2_hsotg_tx_fifo_total_depth(struct dwc2_hsotg *hsotg) { - int ep_info_size; int addr; int tx_addr_max; u32 np_tx_fifo_size; @@ -254,9 +218,7 @@ np_tx_fifo_size = min_t(u32, hsotg->hw_params.dev_nperio_tx_fifo_size, hsotg->params.g_np_tx_fifo_size); - /* Get Endpoint Info Control block size in DWORDs. */ - ep_info_size = dwc2_hsotg_ep_info_size(hsotg); - tx_addr_max = hsotg->hw_params.total_fifo_size - ep_info_size; + tx_addr_max = hsotg->hw_params.total_fifo_size; addr = hsotg->params.g_rx_fifo_size + np_tx_fifo_size; if (tx_addr_max <= addr)