mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-09 04:10:18 +09:00
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:
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user