usb: dwc2: Fix TxFIFOn sizes and total TxFIFO size issues
In host mode reading from DPTXSIZn returning invalid value in dwc2_check_param_tx_fifo_sizes function. In total TxFIFO size calculations unnecessarily reducing by ep_info. hw->total_fifo_size can be fully allocated for FIFO's. Added num_dev_in_eps member in dwc2_hw_params structure to save number of IN EPs. Added g_tx_fifo_size array in dwc2_hw_params structure to store power on reset values of DPTXSIZn registers in forced device mode. Updated dwc2_hsotg_tx_fifo_count() function to get TxFIFO count from num_dev_in_eps. Updated dwc2_get_dev_hwparams() function to store DPTXFSIZn in g_tx_fifo_size array. dwc2_get_host/dev_hwparams() functions call moved after num_dev_in_eps set from hwcfg4. Modified dwc2_check_param_tx_fifo_sizes() function to check TxFIFOn sizes based on g_tx_fifo_size array. Removed ep_info subtraction during calculation of tx_addr_max in dwc2_hsotg_tx_fifo_total_depth() function. Also removed dwc2_hsotg_ep_info_size() function as no more need. Acked-by: John Youn <johnyoun@synopsys.com> Signed-off-by: Gevorg Sahakyan <sahakyan@synopsys.com> Signed-off-by: Minas Harutyunyan <hminas@synopsys.com> Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
This commit is contained in:
parent
ec5bb87e4e
commit
9273083a15
|
@ -537,6 +537,7 @@ struct dwc2_core_params {
|
||||||
* 2 - Internal DMA
|
* 2 - Internal DMA
|
||||||
* @power_optimized Are power optimizations enabled?
|
* @power_optimized Are power optimizations enabled?
|
||||||
* @num_dev_ep Number of device endpoints available
|
* @num_dev_ep Number of device endpoints available
|
||||||
|
* @num_dev_in_eps Number of device IN endpoints available
|
||||||
* @num_dev_perio_in_ep Number of device periodic IN endpoints
|
* @num_dev_perio_in_ep Number of device periodic IN endpoints
|
||||||
* available
|
* available
|
||||||
* @dev_token_q_depth Device Mode IN Token Sequence Learning Queue
|
* @dev_token_q_depth Device Mode IN Token Sequence Learning Queue
|
||||||
|
@ -565,6 +566,7 @@ struct dwc2_core_params {
|
||||||
* 2 - 8 or 16 bits
|
* 2 - 8 or 16 bits
|
||||||
* @snpsid: Value from SNPSID register
|
* @snpsid: Value from SNPSID register
|
||||||
* @dev_ep_dirs: Direction of device endpoints (GHWCFG1)
|
* @dev_ep_dirs: Direction of device endpoints (GHWCFG1)
|
||||||
|
* @g_tx_fifo_size[] Power-on values of TxFIFO sizes
|
||||||
*/
|
*/
|
||||||
struct dwc2_hw_params {
|
struct dwc2_hw_params {
|
||||||
unsigned op_mode:3;
|
unsigned op_mode:3;
|
||||||
|
@ -586,12 +588,14 @@ struct dwc2_hw_params {
|
||||||
unsigned fs_phy_type:2;
|
unsigned fs_phy_type:2;
|
||||||
unsigned i2c_enable:1;
|
unsigned i2c_enable:1;
|
||||||
unsigned num_dev_ep:4;
|
unsigned num_dev_ep:4;
|
||||||
|
unsigned num_dev_in_eps : 4;
|
||||||
unsigned num_dev_perio_in_ep:4;
|
unsigned num_dev_perio_in_ep:4;
|
||||||
unsigned total_fifo_size:16;
|
unsigned total_fifo_size:16;
|
||||||
unsigned power_optimized:1;
|
unsigned power_optimized:1;
|
||||||
unsigned utmi_phy_data_width:2;
|
unsigned utmi_phy_data_width:2;
|
||||||
u32 snpsid;
|
u32 snpsid;
|
||||||
u32 dev_ep_dirs;
|
u32 dev_ep_dirs;
|
||||||
|
u32 g_tx_fifo_size[MAX_EPS_CHANNELS];
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Size of control and EP0 buffers */
|
/* Size of control and EP0 buffers */
|
||||||
|
|
|
@ -195,55 +195,18 @@ int dwc2_hsotg_tx_fifo_count(struct dwc2_hsotg *hsotg)
|
||||||
{
|
{
|
||||||
if (hsotg->hw_params.en_multiple_tx_fifo)
|
if (hsotg->hw_params.en_multiple_tx_fifo)
|
||||||
/* In dedicated FIFO mode we need count of IN EPs */
|
/* In dedicated FIFO mode we need count of IN EPs */
|
||||||
return (dwc2_readl(hsotg->regs + GHWCFG4) &
|
return hsotg->hw_params.num_dev_in_eps;
|
||||||
GHWCFG4_NUM_IN_EPS_MASK) >> GHWCFG4_NUM_IN_EPS_SHIFT;
|
|
||||||
else
|
else
|
||||||
/* In shared FIFO mode we need count of Periodic IN EPs */
|
/* In shared FIFO mode we need count of Periodic IN EPs */
|
||||||
return hsotg->hw_params.num_dev_perio_in_ep;
|
return hsotg->hw_params.num_dev_perio_in_ep;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 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
|
* dwc2_hsotg_tx_fifo_total_depth - return total FIFO depth available for
|
||||||
* device mode TX FIFOs
|
* device mode TX FIFOs
|
||||||
*/
|
*/
|
||||||
int dwc2_hsotg_tx_fifo_total_depth(struct dwc2_hsotg *hsotg)
|
int dwc2_hsotg_tx_fifo_total_depth(struct dwc2_hsotg *hsotg)
|
||||||
{
|
{
|
||||||
int ep_info_size;
|
|
||||||
int addr;
|
int addr;
|
||||||
int tx_addr_max;
|
int tx_addr_max;
|
||||||
u32 np_tx_fifo_size;
|
u32 np_tx_fifo_size;
|
||||||
|
@ -252,8 +215,7 @@ int dwc2_hsotg_tx_fifo_total_depth(struct dwc2_hsotg *hsotg)
|
||||||
hsotg->params.g_np_tx_fifo_size);
|
hsotg->params.g_np_tx_fifo_size);
|
||||||
|
|
||||||
/* Get Endpoint Info Control block size in DWORDs. */
|
/* 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;
|
||||||
tx_addr_max = hsotg->hw_params.total_fifo_size - ep_info_size;
|
|
||||||
|
|
||||||
addr = hsotg->params.g_rx_fifo_size + np_tx_fifo_size;
|
addr = hsotg->params.g_rx_fifo_size + np_tx_fifo_size;
|
||||||
if (tx_addr_max <= addr)
|
if (tx_addr_max <= addr)
|
||||||
|
|
|
@ -484,8 +484,7 @@ static void dwc2_check_param_tx_fifo_sizes(struct dwc2_hsotg *hsotg)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (fifo = 1; fifo <= fifo_count; fifo++) {
|
for (fifo = 1; fifo <= fifo_count; fifo++) {
|
||||||
dptxfszn = (dwc2_readl(hsotg->regs + DPTXFSIZN(fifo)) &
|
dptxfszn = hsotg->hw_params.g_tx_fifo_size[fifo];
|
||||||
FIFOSIZE_DEPTH_MASK) >> FIFOSIZE_DEPTH_SHIFT;
|
|
||||||
|
|
||||||
if (hsotg->params.g_tx_fifo_size[fifo] < min ||
|
if (hsotg->params.g_tx_fifo_size[fifo] < min ||
|
||||||
hsotg->params.g_tx_fifo_size[fifo] > dptxfszn) {
|
hsotg->params.g_tx_fifo_size[fifo] > dptxfszn) {
|
||||||
|
@ -609,6 +608,7 @@ static void dwc2_get_dev_hwparams(struct dwc2_hsotg *hsotg)
|
||||||
struct dwc2_hw_params *hw = &hsotg->hw_params;
|
struct dwc2_hw_params *hw = &hsotg->hw_params;
|
||||||
bool forced;
|
bool forced;
|
||||||
u32 gnptxfsiz;
|
u32 gnptxfsiz;
|
||||||
|
int fifo, fifo_count;
|
||||||
|
|
||||||
if (hsotg->dr_mode == USB_DR_MODE_HOST)
|
if (hsotg->dr_mode == USB_DR_MODE_HOST)
|
||||||
return;
|
return;
|
||||||
|
@ -617,6 +617,14 @@ static void dwc2_get_dev_hwparams(struct dwc2_hsotg *hsotg)
|
||||||
|
|
||||||
gnptxfsiz = dwc2_readl(hsotg->regs + GNPTXFSIZ);
|
gnptxfsiz = dwc2_readl(hsotg->regs + GNPTXFSIZ);
|
||||||
|
|
||||||
|
fifo_count = dwc2_hsotg_tx_fifo_count(hsotg);
|
||||||
|
|
||||||
|
for (fifo = 1; fifo <= fifo_count; fifo++) {
|
||||||
|
hw->g_tx_fifo_size[fifo] =
|
||||||
|
(dwc2_readl(hsotg->regs + DPTXFSIZN(fifo)) &
|
||||||
|
FIFOSIZE_DEPTH_MASK) >> FIFOSIZE_DEPTH_SHIFT;
|
||||||
|
}
|
||||||
|
|
||||||
if (forced)
|
if (forced)
|
||||||
dwc2_clear_force_mode(hsotg);
|
dwc2_clear_force_mode(hsotg);
|
||||||
|
|
||||||
|
@ -661,14 +669,6 @@ int dwc2_get_hwparams(struct dwc2_hsotg *hsotg)
|
||||||
hwcfg4 = dwc2_readl(hsotg->regs + GHWCFG4);
|
hwcfg4 = dwc2_readl(hsotg->regs + GHWCFG4);
|
||||||
grxfsiz = dwc2_readl(hsotg->regs + GRXFSIZ);
|
grxfsiz = dwc2_readl(hsotg->regs + GRXFSIZ);
|
||||||
|
|
||||||
/*
|
|
||||||
* Host specific hardware parameters. Reading these parameters
|
|
||||||
* requires the controller to be in host mode. The mode will
|
|
||||||
* be forced, if necessary, to read these values.
|
|
||||||
*/
|
|
||||||
dwc2_get_host_hwparams(hsotg);
|
|
||||||
dwc2_get_dev_hwparams(hsotg);
|
|
||||||
|
|
||||||
/* hwcfg1 */
|
/* hwcfg1 */
|
||||||
hw->dev_ep_dirs = hwcfg1;
|
hw->dev_ep_dirs = hwcfg1;
|
||||||
|
|
||||||
|
@ -711,6 +711,8 @@ int dwc2_get_hwparams(struct dwc2_hsotg *hsotg)
|
||||||
hw->en_multiple_tx_fifo = !!(hwcfg4 & GHWCFG4_DED_FIFO_EN);
|
hw->en_multiple_tx_fifo = !!(hwcfg4 & GHWCFG4_DED_FIFO_EN);
|
||||||
hw->num_dev_perio_in_ep = (hwcfg4 & GHWCFG4_NUM_DEV_PERIO_IN_EP_MASK) >>
|
hw->num_dev_perio_in_ep = (hwcfg4 & GHWCFG4_NUM_DEV_PERIO_IN_EP_MASK) >>
|
||||||
GHWCFG4_NUM_DEV_PERIO_IN_EP_SHIFT;
|
GHWCFG4_NUM_DEV_PERIO_IN_EP_SHIFT;
|
||||||
|
hw->num_dev_in_eps = (hwcfg4 & GHWCFG4_NUM_IN_EPS_MASK) >>
|
||||||
|
GHWCFG4_NUM_IN_EPS_SHIFT;
|
||||||
hw->dma_desc_enable = !!(hwcfg4 & GHWCFG4_DESC_DMA);
|
hw->dma_desc_enable = !!(hwcfg4 & GHWCFG4_DESC_DMA);
|
||||||
hw->power_optimized = !!(hwcfg4 & GHWCFG4_POWER_OPTIMIZ);
|
hw->power_optimized = !!(hwcfg4 & GHWCFG4_POWER_OPTIMIZ);
|
||||||
hw->utmi_phy_data_width = (hwcfg4 & GHWCFG4_UTMI_PHY_DATA_WIDTH_MASK) >>
|
hw->utmi_phy_data_width = (hwcfg4 & GHWCFG4_UTMI_PHY_DATA_WIDTH_MASK) >>
|
||||||
|
@ -719,6 +721,13 @@ int dwc2_get_hwparams(struct dwc2_hsotg *hsotg)
|
||||||
/* fifo sizes */
|
/* fifo sizes */
|
||||||
hw->rx_fifo_size = (grxfsiz & GRXFSIZ_DEPTH_MASK) >>
|
hw->rx_fifo_size = (grxfsiz & GRXFSIZ_DEPTH_MASK) >>
|
||||||
GRXFSIZ_DEPTH_SHIFT;
|
GRXFSIZ_DEPTH_SHIFT;
|
||||||
|
/*
|
||||||
|
* Host specific hardware parameters. Reading these parameters
|
||||||
|
* requires the controller to be in host mode. The mode will
|
||||||
|
* be forced, if necessary, to read these values.
|
||||||
|
*/
|
||||||
|
dwc2_get_host_hwparams(hsotg);
|
||||||
|
dwc2_get_dev_hwparams(hsotg);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue