usb: dwc3: support global Tx/Rx threshold control

According to "TX/RX Data FIFO Sizes and TX/RX Threshold Control
Register Settings" section in the DWC SuperSpeed USB 3.0 Controller
User Guide, for large latency systems, it may cause unnecessary
performance reduction, and having large TX/RX FIFOs alone is not
sufficient, to solve this issue, the controller provides a packet
threshold feature in the host mode.

For example, on rk3399 platforms, if we set aclk_perilp to 100 MHz,
the system usb bus latency is larger than 2.2 microseconds to access
a 1024-byte packet, to avoid underrun and overrun during the burst,
threshold and burst size control must be set through GTXTHRCFG and
GRXTHRCFG registers.

On rk3399 platforms, only a 4-packet TX FIFO and 3-packet RX FIFO
is implemented due to area constraints, so we can program the USB
Maximum TX Burst Size to 13 and the USB Transmit Packet Count to
4 to avoid TX FIFO underrun during an OUT burst. Similarly, set the
USB Maximum TX Burst Size to 10 and the USB Transmit Packet Count
to 2 to avoid RX FIFO overrrun. To enable the threshold control,
add "snps,gtx-threshold-cfg = <4>, <13>" in dts dwc3 node for Tx,
add "snps,grx-threshold-cfg = <2>, <10>" in dts dwc3 node for Rx.

Change-Id: I7535fe72e6527544a20c5921440b4888e1bada22
Signed-off-by: William Wu <william.wu@rock-chips.com>
This commit is contained in:
William Wu
2018-08-27 11:43:54 +08:00
committed by Tao Huang
parent db1b25037e
commit d6dc21d7de
2 changed files with 30 additions and 0 deletions

View File

@@ -729,6 +729,22 @@ static int dwc3_core_init(struct dwc3 *dwc)
dwc3_writel(dwc->regs, DWC3_GUCTL1, reg);
if (dwc->grxthrcfg[0] > 0) {
reg = dwc3_readl(dwc->regs, DWC3_GRXTHRCFG);
reg |= DWC3_GRXTHRCFG_PKTCNTSEL |
DWC3_GRXTHRCFG_RXPKTCNT(dwc->grxthrcfg[0]) |
DWC3_GRXTHRCFG_MAXRXBURSTSIZE(dwc->grxthrcfg[1]);
dwc3_writel(dwc->regs, DWC3_GRXTHRCFG, reg);
}
if (dwc->gtxthrcfg[0] > 0) {
reg = dwc3_readl(dwc->regs, DWC3_GTXTHRCFG);
reg |= DWC3_GTXTHRCFG_PKTCNTSEL |
DWC3_GTXTHRCFG_TXPKTCNT(dwc->gtxthrcfg[0]) |
DWC3_GTXTHRCFG_MAXRXBURSTSIZE(dwc->gtxthrcfg[1]);
dwc3_writel(dwc->regs, DWC3_GTXTHRCFG, reg);
}
return 0;
err4:
@@ -1023,6 +1039,11 @@ static int dwc3_probe(struct platform_device *pdev)
&dwc->hsphy_interface);
device_property_read_u32(dev, "snps,quirk-frame-length-adjustment",
&dwc->fladj);
device_property_read_u32_array(dev, "snps,gtx-threshold-cfg",
dwc->gtxthrcfg, 2);
device_property_read_u32_array(dev, "snps,grx-threshold-cfg",
dwc->grxthrcfg, 2);
/* default to superspeed if no maximum_speed passed */
if (dwc->maximum_speed == USB_SPEED_UNKNOWN)

View File

@@ -166,6 +166,11 @@
#define DWC3_DESCFETCHQ 13
#define DWC3_EVENTQ 15
/* Global TX Threshold Configuration Register */
#define DWC3_GTXTHRCFG_MAXRXBURSTSIZE(n) (((n) & 0xff) << 16)
#define DWC3_GTXTHRCFG_TXPKTCNT(n) (((n) & 0xf) << 24)
#define DWC3_GTXTHRCFG_PKTCNTSEL BIT(29)
/* Global RX Threshold Configuration Register */
#define DWC3_GRXTHRCFG_MAXRXBURSTSIZE(n) (((n) & 0x1f) << 19)
#define DWC3_GRXTHRCFG_RXPKTCNT(n) (((n) & 0xf) << 24)
@@ -785,6 +790,8 @@ struct dwc3_scratchpad_array {
* @test_mode_nr: test feature selector
* @lpm_nyet_threshold: LPM NYET response threshold
* @hird_threshold: HIRD threshold
* @grxthrcfg: global Tx threshold config
* @gtxthrcfg: global Rx threshold config
* @hsphy_interface: "utmi" or "ulpi"
* @connected: true when we're connected to a host, false otherwise
* @delayed_status: true when gadget driver asks for delayed status
@@ -943,6 +950,8 @@ struct dwc3 {
u8 test_mode_nr;
u8 lpm_nyet_threshold;
u8 hird_threshold;
u32 grxthrcfg[2];
u32 gtxthrcfg[2];
const char *hsphy_interface;