143 lines
5.0 KiB
Diff
143 lines
5.0 KiB
Diff
--- a/arch/arm64/boot/dts/rockchip/rk356x.dtsi
|
|
+++ b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
|
|
@@ -292,6 +292,7 @@
|
|
power-domains = <&power RK3568_PD_PIPE>;
|
|
resets = <&cru SRST_USB3OTG0>;
|
|
snps,dis_u2_susphy_quirk;
|
|
+ snps,xhci-trb-ent-quirk;
|
|
status = "disabled";
|
|
};
|
|
|
|
@@ -310,6 +311,7 @@
|
|
power-domains = <&power RK3568_PD_PIPE>;
|
|
resets = <&cru SRST_USB3OTG1>;
|
|
snps,dis_u2_susphy_quirk;
|
|
+ snps,xhci-trb-ent-quirk;
|
|
status = "disabled";
|
|
};
|
|
|
|
--- a/drivers/usb/dwc3/core.c
|
|
+++ b/drivers/usb/dwc3/core.c
|
|
@@ -1578,6 +1578,8 @@ static void dwc3_get_properties(struct d
|
|
"snps,dis-del-phy-power-chg-quirk");
|
|
dwc->dis_tx_ipgap_linecheck_quirk = device_property_read_bool(dev,
|
|
"snps,dis-tx-ipgap-linecheck-quirk");
|
|
+ dwc->xhci_trb_ent_quirk = device_property_read_bool(dev,
|
|
+ "snps,xhci-trb-ent-quirk");
|
|
dwc->resume_hs_terminations = device_property_read_bool(dev,
|
|
"snps,resume-hs-terminations");
|
|
dwc->ulpi_ext_vbus_drv = device_property_read_bool(dev,
|
|
--- a/drivers/usb/dwc3/core.h
|
|
+++ b/drivers/usb/dwc3/core.h
|
|
@@ -1107,6 +1107,9 @@ struct dwc3_scratchpad_array {
|
|
* change quirk.
|
|
* @dis_tx_ipgap_linecheck_quirk: set if we disable u2mac linestate
|
|
* check during HS transmit.
|
|
+ * @xhci_trb_ent_quirk: set if need to enable the Evaluate Next TRB(ENT)
|
|
+ * flag in the TRB data structure to force xHC to
|
|
+ * pre-fetch the next TRB of a TD.
|
|
* @resume_hs_terminations: Set if we enable quirk for fixing improper crc
|
|
* generation after resume from suspend.
|
|
* @ulpi_ext_vbus_drv: Set to confiure the upli chip to drives CPEN pin
|
|
@@ -1333,6 +1336,7 @@ struct dwc3 {
|
|
unsigned dis_u2_freeclk_exists_quirk:1;
|
|
unsigned dis_del_phy_power_chg_quirk:1;
|
|
unsigned dis_tx_ipgap_linecheck_quirk:1;
|
|
+ unsigned xhci_trb_ent_quirk:1;
|
|
unsigned resume_hs_terminations:1;
|
|
unsigned ulpi_ext_vbus_drv:1;
|
|
unsigned parkmode_disable_ss_quirk:1;
|
|
--- a/drivers/usb/dwc3/host.c
|
|
+++ b/drivers/usb/dwc3/host.c
|
|
@@ -115,6 +115,9 @@ int dwc3_host_init(struct dwc3 *dwc)
|
|
if (dwc->usb3_lpm_capable)
|
|
props[prop_idx++] = PROPERTY_ENTRY_BOOL("usb3-lpm-capable");
|
|
|
|
+ if (dwc->xhci_trb_ent_quirk)
|
|
+ props[prop_idx++] = PROPERTY_ENTRY_BOOL("xhci-trb-ent-quirk");
|
|
+
|
|
if (dwc->usb2_lpm_disable)
|
|
props[prop_idx++] = PROPERTY_ENTRY_BOOL("usb2-lpm-disable");
|
|
|
|
--- a/drivers/usb/host/xhci-plat.c
|
|
+++ b/drivers/usb/host/xhci-plat.c
|
|
@@ -253,6 +253,9 @@ int xhci_plat_probe(struct platform_devi
|
|
if (device_property_read_bool(tmpdev, "xhci-sg-trb-cache-size-quirk"))
|
|
xhci->quirks |= XHCI_SG_TRB_CACHE_SIZE_QUIRK;
|
|
|
|
+ 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);
|
|
}
|
|
--- a/drivers/usb/host/xhci-ring.c
|
|
+++ b/drivers/usb/host/xhci-ring.c
|
|
@@ -3637,6 +3637,7 @@ int xhci_queue_bulk_tx(struct xhci_hcd *
|
|
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;
|
|
@@ -3673,6 +3674,13 @@ int xhci_queue_bulk_tx(struct xhci_hcd *
|
|
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];
|
|
|
|
/*
|
|
@@ -3701,6 +3709,13 @@ int xhci_queue_bulk_tx(struct xhci_hcd *
|
|
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;
|
|
|
|
@@ -3709,6 +3724,8 @@ int xhci_queue_bulk_tx(struct xhci_hcd *
|
|
*/
|
|
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,
|
|
--- a/drivers/usb/host/xhci.h
|
|
+++ b/drivers/usb/host/xhci.h
|
|
@@ -1530,7 +1530,11 @@ static inline const char *xhci_trb_type_
|
|
#define TRB_SEGMENT_SIZE (TRBS_PER_SEGMENT*16)
|
|
#define TRB_SEGMENT_SHIFT (ilog2(TRB_SEGMENT_SIZE))
|
|
/* TRB buffer pointers can't cross 64KB boundaries */
|
|
+#ifdef CONFIG_ARCH_ROCKCHIP
|
|
+#define TRB_MAX_BUFF_SHIFT 12
|
|
+#else
|
|
#define TRB_MAX_BUFF_SHIFT 16
|
|
+#endif
|
|
#define TRB_MAX_BUFF_SIZE (1 << TRB_MAX_BUFF_SHIFT)
|
|
/* How much data is left before the 64KB boundary? */
|
|
#define TRB_BUFF_LEN_UP_TO_BOUNDARY(addr) (TRB_MAX_BUFF_SIZE - \
|
|
@@ -1855,6 +1859,7 @@ struct xhci_hcd {
|
|
#define XHCI_STATE_HALTED (1 << 1)
|
|
#define XHCI_STATE_REMOVING (1 << 2)
|
|
unsigned long long quirks;
|
|
+#define XHCI_TRB_ENT_QUIRK BIT_ULL(63)
|
|
#define XHCI_LINK_TRB_QUIRK BIT_ULL(0)
|
|
#define XHCI_RESET_EP_QUIRK BIT_ULL(1) /* Deprecated */
|
|
#define XHCI_NEC_HOST BIT_ULL(2)
|