[PATCH] usb: dwc3: add sprs_ctrl_trans_quirk

From: Yaqin Pan
Date: Thu Dec 09 2021 - 08:53:30 EST


Add a quirk to set GUCTL.SPRSCTRLTRANSEN bit.

Some special peripherals can't handle the control transfer well.
For example, TF card reader (aaaa:8816):
usb 1-1: new high-speed USB device number 2 using xhci-hcd
usb 1-1: device descriptor read/all, error -110
>From the usb analyzer, always return NAK in the data phase.

Signed-off-by: Yaqin Pan <akingchen@xxxxxxxx>
---
drivers/usb/dwc3/core.c | 4 ++++
drivers/usb/dwc3/core.h | 3 +++
2 files changed, 7 insertions(+)

diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index ba74ad7f6995..93ac2c79a2c0 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -1071,6 +1071,8 @@ static int dwc3_core_init(struct dwc3 *dwc)
* packet with Retry=1 & Nump != 0)
*/
reg |= DWC3_GUCTL_HSTINAUTORETRY;
+ if (dwc->sprs_ctrl_trans_quirk)
+ reg |= DWC3_GUCTL_SPRSCTRLTRANSEN;

dwc3_writel(dwc->regs, DWC3_GUCTL, reg);
}
@@ -1377,6 +1379,8 @@ static void dwc3_get_properties(struct dwc3 *dwc)

dwc->dis_split_quirk = device_property_read_bool(dev,
"snps,dis-split-quirk");
+ dwc->sprs_ctrl_trans_quirk = device_property_read_bool(dev,
+ "snps,sprs-ctrl-trans-quirk");

dwc->lpm_nyet_threshold = lpm_nyet_threshold;
dwc->tx_de_emphasis = tx_de_emphasis;
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index 5991766239ba..6048087df1d1 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -254,6 +254,7 @@

/* Global User Control Register */
#define DWC3_GUCTL_HSTINAUTORETRY BIT(14)
+#define DWC3_GUCTL_SPRSCTRLTRANSEN BIT(17)

/* Global User Control 1 Register */
#define DWC3_GUCTL1_PARKMODE_DISABLE_SS BIT(17)
@@ -1077,6 +1078,7 @@ struct dwc3_scratchpad_array {
* 3 - Reserved
* @dis_metastability_quirk: set to disable metastability quirk.
* @dis_split_quirk: set to disable split boundary.
+ * @sprs_ctrl_trans_quirk: set to enable sparse control transaction quirk.
* @imod_interval: set the interrupt moderation interval in 250ns
* increments or 0 to disable.
*/
@@ -1279,6 +1281,7 @@ struct dwc3 {
unsigned dis_metastability_quirk:1;

unsigned dis_split_quirk:1;
+ unsigned sprs_ctrl_trans_quirk:1;
unsigned async_callbacks:1;

u16 imod_interval;
--
2.17.1