mirror of
https://github.com/torvalds/linux.git
synced 2026-06-08 06:25:52 +02:00
usb: xhci: add support for xhci trb ent quirk
On some xHCI controllers (e.g. Rockchip RK3399/RK3328/RK1808), they need to enable the ENT flag in the TRB data structure to force xHC to pre-fetch the next TRB of a TD. This patch add a new quirk to enable the ENT flag. And this patch also avoids to enable the ENT flag in the following two cases: 1. The transfer length of the first TRB isn't an integer multiple of the EP maxpacket. 2. The EP support bulk streaming protocol. Change-Id: Ib7cc095a848f0846ad995529ad703ae4e4ee4d44 Signed-off-by: William Wu <william.wu@rock-chips.com>
This commit is contained in:
parent
da1f09f2a2
commit
0f580acb01
|
|
@ -291,6 +291,9 @@ static int xhci_plat_probe(struct platform_device *pdev)
|
|||
if (device_property_read_bool(tmpdev, "xhci-slow-suspend"))
|
||||
xhci->quirks |= XHCI_SLOW_SUSPEND;
|
||||
|
||||
if (device_property_read_bool(tmpdev, "xhci-trb-ent-quirk"))
|
||||
xhci->quirks |= XHCI_TRB_ENT_QUIRK;
|
||||
|
||||
device_property_read_u32(tmpdev, "imod-interval-ns",
|
||||
&xhci->imod_interval);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3166,6 +3166,7 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
|
|||
bool more_trbs_coming = true;
|
||||
bool need_zero_pkt = false;
|
||||
bool first_trb = true;
|
||||
bool en_trb_ent = true;
|
||||
unsigned int num_trbs;
|
||||
unsigned int start_cycle, num_sgs = 0;
|
||||
unsigned int enqd_len, block_len, trb_buff_len, full_len;
|
||||
|
|
@ -3202,6 +3203,13 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
|
|||
if (urb->transfer_flags & URB_ZERO_PACKET && urb_priv->num_tds > 1)
|
||||
need_zero_pkt = true;
|
||||
|
||||
/*
|
||||
* Don't enable the ENT flag in the TRB if
|
||||
* the EP support bulk streaming protocol.
|
||||
*/
|
||||
if (urb->stream_id)
|
||||
en_trb_ent = false;
|
||||
|
||||
td = &urb_priv->td[0];
|
||||
|
||||
/*
|
||||
|
|
@ -3230,6 +3238,13 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
|
|||
first_trb = false;
|
||||
if (start_cycle == 0)
|
||||
field |= TRB_CYCLE;
|
||||
/*
|
||||
* Don't enable the ENT flag in the TRB if the
|
||||
* transfer length of the first TRB isn't an
|
||||
* integer multiple of the EP maxpacket.
|
||||
*/
|
||||
if (trb_buff_len % usb_endpoint_maxp(&urb->ep->desc))
|
||||
en_trb_ent = false;
|
||||
} else
|
||||
field |= ring->cycle_state;
|
||||
|
||||
|
|
@ -3238,6 +3253,8 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
|
|||
*/
|
||||
if (enqd_len + trb_buff_len < full_len) {
|
||||
field |= TRB_CHAIN;
|
||||
if (xhci->quirks & XHCI_TRB_ENT_QUIRK && en_trb_ent)
|
||||
field |= TRB_ENT;
|
||||
if (trb_is_link(ring->enqueue + 1)) {
|
||||
if (xhci_align_td(xhci, urb, enqd_len,
|
||||
&trb_buff_len,
|
||||
|
|
|
|||
|
|
@ -1852,6 +1852,7 @@ struct xhci_hcd {
|
|||
#define XHCI_ZERO_64B_REGS BIT_ULL(32)
|
||||
#define XHCI_RESET_PLL_ON_DISCONNECT BIT_ULL(34)
|
||||
#define XHCI_SNPS_BROKEN_SUSPEND BIT_ULL(35)
|
||||
#define XHCI_TRB_ENT_QUIRK BIT_ULL(36)
|
||||
|
||||
unsigned int num_active_eps;
|
||||
unsigned int limit_active_eps;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user