mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 11:26:02 +09:00
usb: dwc3: gadget: get the txfifos depth properly
The DWC3 controller may have different RAM configurations. For 2-RAM configuration and 3-RAM configuration, the RAM1 depth is used for the TxFIFOs. And for 1-RAM configuration (e.g. RV1109/RV1106), RAM0 depth contains the descriptor cache depth, RxFIFOs depth, and TxFIFOs depth. This patch checks the number of RAM configuration from the hwparams1 and get the TxFIFOs depth correctly. Signed-off-by: William Wu <william.wu@rock-chips.com> Change-Id: Iff0c4d0540d920ca9277496e27d2b9f90e956341
This commit is contained in:
@@ -324,6 +324,7 @@
|
||||
/* Global RX Fifo Size Register */
|
||||
#define DWC31_GRXFIFOSIZ_RXFDEP(n) ((n) & 0x7fff) /* DWC_usb31 only */
|
||||
#define DWC3_GRXFIFOSIZ_RXFDEP(n) ((n) & 0xffff)
|
||||
#define DWC3_GRXFIFOSIZ_RXFSTADDR(n) ((n) & 0xffff0000)
|
||||
|
||||
/* Global Event Size Registers */
|
||||
#define DWC3_GEVNTSIZ_INTMASK BIT(31)
|
||||
@@ -374,6 +375,7 @@
|
||||
#define DWC3_GHWPARAMS6_HNPSUPPORT BIT(11)
|
||||
#define DWC3_GHWPARAMS6_SRPSUPPORT BIT(10)
|
||||
#define DWC3_GHWPARAMS6_EN_FPGA BIT(7)
|
||||
#define DWC3_GHWPARAMS6_RAM0_DEPTH(n) (((n) >> 16) & 0xffff)
|
||||
|
||||
/* DWC_usb32 only */
|
||||
#define DWC3_GHWPARAMS6_MDWIDTH(n) ((n) & (0x3 << 8))
|
||||
@@ -884,6 +886,7 @@ struct dwc3_hwparams {
|
||||
|
||||
/* HWPARAMS1 */
|
||||
#define DWC3_NUM_INT(n) (((n) & (0x3f << 15)) >> 15)
|
||||
#define DWC3_NUM_RAMS(n) (((n) & (0x3 << 21)) >> 21)
|
||||
|
||||
/* HWPARAMS3 */
|
||||
#define DWC3_NUM_IN_EPS_MASK (0x1f << 18)
|
||||
|
||||
@@ -629,6 +629,49 @@ static int dwc3_gadget_set_ep_config(struct dwc3_ep *dep, unsigned int action)
|
||||
return dwc3_send_gadget_ep_cmd(dep, DWC3_DEPCMD_SETEPCONFIG, ¶ms);
|
||||
}
|
||||
|
||||
/**
|
||||
* dwc3_gadget_get_tx_fifos_size - Get the txfifos total size
|
||||
* @dwc: pointer to the DWC3 context
|
||||
*
|
||||
* 3-RAM configuration:
|
||||
* RAM0 depth = Descriptor Cache depth
|
||||
* RAM1 depth = TxFIFOs depth
|
||||
* RAM2 depth = RxFIFOs depth
|
||||
*
|
||||
* 2-RAM configuration:
|
||||
* RAM0 depth = Descriptor Cache depth + RxFIFOs depth
|
||||
* RAM1 depth = TxFIFOs depth
|
||||
*
|
||||
* 1-RAM configuration:
|
||||
* RAM0 depth = Descriptor Cache depth + RxFIFOs depth + TxFIFOs depth
|
||||
*/
|
||||
static int dwc3_gadget_get_tx_fifos_size(struct dwc3 *dwc)
|
||||
{
|
||||
int txfifo_depth = 0;
|
||||
int ram0_depth, rxfifo_size;
|
||||
|
||||
/* Get the depth of the TxFIFOs */
|
||||
if (DWC3_NUM_RAMS(dwc->hwparams.hwparams1) > 1) {
|
||||
/* For 2 or 3-RAM, RAM1 contains TxFIFOs */
|
||||
txfifo_depth = DWC3_RAM1_DEPTH(dwc->hwparams.hwparams7);
|
||||
} else {
|
||||
/* For 1-RAM, RAM0 contains Descriptor Cache, RxFIFOs, and TxFIFOs */
|
||||
ram0_depth = DWC3_GHWPARAMS6_RAM0_DEPTH(dwc->hwparams.hwparams6);
|
||||
|
||||
/* All OUT endpoints share a single RxFIFO space */
|
||||
rxfifo_size = dwc3_readl(dwc->regs, DWC3_GRXFIFOSIZ(0));
|
||||
if (DWC3_IP_IS(DWC3))
|
||||
txfifo_depth = ram0_depth - DWC3_GRXFIFOSIZ_RXFDEP(rxfifo_size);
|
||||
else
|
||||
txfifo_depth = ram0_depth - DWC31_GRXFIFOSIZ_RXFDEP(rxfifo_size);
|
||||
|
||||
/* The value of GRxFIFOSIZ0[31:16] is the depth of Descriptor Cache */
|
||||
txfifo_depth -= DWC3_GRXFIFOSIZ_RXFSTADDR(rxfifo_size) >> 16;
|
||||
}
|
||||
|
||||
return txfifo_depth;
|
||||
}
|
||||
|
||||
/**
|
||||
* dwc3_gadget_calc_tx_fifo_size - calculates the txfifo size value
|
||||
* @dwc: pointer to the DWC3 context
|
||||
@@ -750,7 +793,7 @@ static int dwc3_gadget_resize_tx_fifos(struct dwc3_ep *dep)
|
||||
if (dep->flags & DWC3_EP_TXFIFO_RESIZED)
|
||||
return 0;
|
||||
|
||||
ram1_depth = DWC3_RAM1_DEPTH(dwc->hwparams.hwparams7);
|
||||
ram1_depth = dwc3_gadget_get_tx_fifos_size(dwc);
|
||||
|
||||
if ((dep->endpoint.maxburst > 1 &&
|
||||
usb_endpoint_xfer_bulk(dep->endpoint.desc)) ||
|
||||
@@ -2848,7 +2891,7 @@ static int dwc3_gadget_check_config(struct usb_gadget *g)
|
||||
fifo_size += dwc->max_cfg_eps;
|
||||
|
||||
/* Check if we can fit a single fifo per endpoint */
|
||||
ram1_depth = DWC3_RAM1_DEPTH(dwc->hwparams.hwparams7);
|
||||
ram1_depth = dwc3_gadget_get_tx_fifos_size(dwc);
|
||||
if (fifo_size > ram1_depth)
|
||||
return -ENOMEM;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user