mirror of https://gitee.com/openkylin/linux.git
usb: dwc2: gadget: Set TX FIFO depths to calculated defaults
Remove legacy DWC2_G_P_LEGACY_TX_FIFO_SIZE array for TX FIFOs. Update dwc2_set_param_tx_fifo_sizes function to calculate and assign default average FIFO depth to each member of g_tx_fifo_size array. Total FIFO size, EP Info block's size, FIFO operation mode and device operation mode are taken into consideration during the calculation. Cc: Stefan Wahren <stefan.wahren@i2se.com> Signed-off-by: Sevak Arakelyan <sevaka@synopsys.com> Signed-off-by: John Youn <johnyoun@synopsys.com> Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
This commit is contained in:
parent
e1f411d1b3
commit
c138ecfa61
|
@ -274,13 +274,6 @@ enum dwc2_lx_state {
|
|||
DWC2_L3, /* Off state */
|
||||
};
|
||||
|
||||
/*
|
||||
* Gadget periodic tx fifo sizes as used by legacy driver
|
||||
* EP0 is not included
|
||||
*/
|
||||
#define DWC2_G_P_LEGACY_TX_FIFO_SIZE {256, 256, 256, 256, 768, 768, 768, \
|
||||
768, 0, 0, 0, 0, 0, 0, 0}
|
||||
|
||||
/* Gadget ep0 states */
|
||||
enum dwc2_ep0_state {
|
||||
DWC2_EP0_SETUP,
|
||||
|
@ -1180,6 +1173,9 @@ int dwc2_hsotg_set_test_mode(struct dwc2_hsotg *hsotg, int testmode);
|
|||
#define dwc2_is_device_connected(hsotg) (hsotg->connected)
|
||||
int dwc2_backup_device_registers(struct dwc2_hsotg *hsotg);
|
||||
int dwc2_restore_device_registers(struct dwc2_hsotg *hsotg);
|
||||
int dwc2_hsotg_tx_fifo_count(struct dwc2_hsotg *hsotg);
|
||||
int dwc2_hsotg_tx_fifo_total_depth(struct dwc2_hsotg *hsotg);
|
||||
int dwc2_hsotg_tx_fifo_average_depth(struct dwc2_hsotg *hsotg);
|
||||
#else
|
||||
static inline int dwc2_hsotg_remove(struct dwc2_hsotg *dwc2)
|
||||
{ return 0; }
|
||||
|
@ -1201,6 +1197,12 @@ static inline int dwc2_backup_device_registers(struct dwc2_hsotg *hsotg)
|
|||
{ return 0; }
|
||||
static inline int dwc2_restore_device_registers(struct dwc2_hsotg *hsotg)
|
||||
{ return 0; }
|
||||
static inline int dwc2_hsotg_tx_fifo_count(struct dwc2_hsotg *hsotg)
|
||||
{ return 0; }
|
||||
static inline int dwc2_hsotg_tx_fifo_total_depth(struct dwc2_hsotg *hsotg)
|
||||
{ return 0; }
|
||||
static inline int dwc2_hsotg_tx_fifo_average_depth(struct dwc2_hsotg *hsotg)
|
||||
{ return 0; }
|
||||
#endif
|
||||
|
||||
#if IS_ENABLED(CONFIG_USB_DWC2_HOST) || IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE)
|
||||
|
|
|
@ -191,6 +191,99 @@ static void dwc2_hsotg_ctrl_epint(struct dwc2_hsotg *hsotg,
|
|||
local_irq_restore(flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* dwc2_hsotg_tx_fifo_count - return count of TX FIFOs in device mode
|
||||
*/
|
||||
int dwc2_hsotg_tx_fifo_count(struct dwc2_hsotg *hsotg)
|
||||
{
|
||||
if (hsotg->hw_params.en_multiple_tx_fifo)
|
||||
/* In dedicated FIFO mode we need count of IN EPs */
|
||||
return (dwc2_readl(hsotg->regs + GHWCFG4) &
|
||||
GHWCFG4_NUM_IN_EPS_MASK) >> GHWCFG4_NUM_IN_EPS_SHIFT;
|
||||
else
|
||||
/* In shared FIFO mode we need count of Periodic IN EPs */
|
||||
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
|
||||
* 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;
|
||||
|
||||
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;
|
||||
|
||||
addr = hsotg->params.g_rx_fifo_size + np_tx_fifo_size;
|
||||
if (tx_addr_max <= addr)
|
||||
return 0;
|
||||
|
||||
return tx_addr_max - addr;
|
||||
}
|
||||
|
||||
/**
|
||||
* dwc2_hsotg_tx_fifo_average_depth - returns average depth of device mode
|
||||
* TX FIFOs
|
||||
*/
|
||||
int dwc2_hsotg_tx_fifo_average_depth(struct dwc2_hsotg *hsotg)
|
||||
{
|
||||
int tx_fifo_count;
|
||||
int tx_fifo_depth;
|
||||
|
||||
tx_fifo_depth = dwc2_hsotg_tx_fifo_total_depth(hsotg);
|
||||
|
||||
tx_fifo_count = dwc2_hsotg_tx_fifo_count(hsotg);
|
||||
|
||||
if (!tx_fifo_count)
|
||||
return tx_fifo_depth;
|
||||
else
|
||||
return tx_fifo_depth / tx_fifo_count;
|
||||
}
|
||||
|
||||
/**
|
||||
* dwc2_hsotg_init_fifo - initialise non-periodic FIFOs
|
||||
* @hsotg: The device instance.
|
||||
|
|
|
@ -207,12 +207,16 @@ static void dwc2_set_param_phy_utmi_width(struct dwc2_hsotg *hsotg)
|
|||
static void dwc2_set_param_tx_fifo_sizes(struct dwc2_hsotg *hsotg)
|
||||
{
|
||||
struct dwc2_core_params *p = &hsotg->params;
|
||||
u32 p_tx_fifo[] = DWC2_G_P_LEGACY_TX_FIFO_SIZE;
|
||||
int depth_average;
|
||||
int fifo_count;
|
||||
int i;
|
||||
|
||||
fifo_count = dwc2_hsotg_tx_fifo_count(hsotg);
|
||||
|
||||
memset(p->g_tx_fifo_size, 0, sizeof(p->g_tx_fifo_size));
|
||||
memcpy(&p->g_tx_fifo_size[1],
|
||||
p_tx_fifo,
|
||||
sizeof(p_tx_fifo));
|
||||
depth_average = dwc2_hsotg_tx_fifo_average_depth(hsotg);
|
||||
for (i = 1; i <= fifo_count; i++)
|
||||
p->g_tx_fifo_size[i] = depth_average;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue