diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 5ed3fd54a05e..c1f75d097afb 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -1121,6 +1121,16 @@ int dwc3_core_init(struct dwc3 *dwc) } dwc3_notify_event(dwc, DWC3_CONTROLLER_POST_RESET_EVENT, 0); + /* + * clear Elastic buffer mode in GUSBPIPE_CTRL(0) register, otherwise + * it results in high link errors and could cause SS mode transfer + * failure. + */ + if (!dwc->nominal_elastic_buffer) { + reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0)); + reg &= ~DWC3_GUSB3PIPECTL_ELASTIC_BUF_MODE; + dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg); + } return 0; @@ -1369,6 +1379,8 @@ static void dwc3_get_properties(struct dwc3 *dwc) &tx_thr_num_pkt_prd); device_property_read_u8(dev, "snps,tx-max-burst-prd", &tx_max_burst_prd); + dwc->nominal_elastic_buffer = of_property_read_bool(dev->of_node, + "nominal-elastic-buffer"); dwc->needs_fifo_resize = device_property_read_bool(dev, "tx-fifo-resize"); diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index e160d3319ea2..35eabb803e45 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -337,6 +337,7 @@ #define DWC3_GUSB3PIPECTL_TX_DEEPH_MASK DWC3_GUSB3PIPECTL_TX_DEEPH(3) #define DWC3_GUSB3PIPECTL_TX_DEEPH(n) ((n) << 1) #define DWC3_GUSB3PIPECTL_DELAYP1TRANS BIT(18) +#define DWC3_GUSB3PIPECTL_ELASTIC_BUF_MODE (1 << 0) /* Global TX Fifo Size Register */ #define DWC31_GTXFIFOSIZ_TXFRAMNUM BIT(15) /* DWC_usb31 only */ @@ -1364,6 +1365,7 @@ struct dwc3 { struct dwc3_gadget_events dbg_gadget_events; int tx_fifo_size; int last_fifo_depth; + bool nominal_elastic_buffer; /* IRQ timing statistics */ int irq;