[PATCH 01/18] usb: dwc3: Reserve Higher Bandwidth for HS Periodic EPs

Akash Kumar
2025-02-06T11:16:10Z

On targets using synopsys usb dwc3 controller, it is observed while testing
multiple audio devices, a glitch is observed during testing.
As per dwc datasheet,By default, HC reserves 80% of the bandwidth
for periodic EPs which can be increased with GUCTL Bit 16.

Add quirk to set GUCTL register BIT 16 to accommodate higher
bandwidth for 2 isoc eps.

If this bit is set, the bandwidth is relaxed to 85% to
accommodate two high speed, high bandwidth ISOC EPs.
USB 2.0 required 80% bandwidth allocated for ISOC traffic. If
two High-bandwidth ISOC devices (HD Webcams) are
connected, and if each requires 1024-bytes X 3 packets per
Micro-Frame, then the bandwidth required is around 82%. If
this bit is set, then it is possible to connect two Webcams of
1024bytes X 3 paylod per Micro-Frame each. Alternatively, you
might need to lower the resolution of the webcams.
This bit is valid in Host and DRD configuration and is used in
host mode operation only.
Set this bit for host mode uvc uac usecases where two isoc eps
are used and flicker is seen.

Signed-off-by: Akash Kumar <quic_akakum@quicinc.com>
---
drivers/usb/dwc3/core.c | 11 +++++++++++
drivers/usb/dwc3/core.h | 4 ++++
2 files changed, 15 insertions(+)

diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index dfa1b5fe48dc..7e55c234e4e5 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -1461,6 +1461,14 @@ static int dwc3_core_init(struct dwc3 *dwc)
dwc3_writel(dwc->regs, DWC3_GUCTL1, reg);
}

+ if (dwc->revision >= DWC3_REVISION_250A) {
+ if (dwc->dwc3_guctl_resbwhseps_quirk) {
+ reg = dwc3_readl(dwc->regs, DWC3_GUCTL);
+ reg |= DWC3_GUCTL_RESBWHSEPS;
+ dwc3_writel(dwc->regs, DWC3_GUCTL, reg);
+ }
+ }
+
dwc3_config_threshold(dwc);

/*
@@ -1818,6 +1826,9 @@ static void dwc3_get_properties(struct dwc3 *dwc)
dwc->dis_split_quirk = device_property_read_bool(dev,
"snps,dis-split-quirk");

+ dwc->dwc3_guctl_resbwhseps_quirk = device_property_read_bool(dev,
+ "snps,dwc3_guctl_resbwhseps_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 ac7c730f81ac..00f4582edfca 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -283,6 +283,9 @@
#define DWC3_GUCTL1_PARKMODE_DISABLE_HS BIT(16)
#define DWC3_GUCTL1_RESUME_OPMODE_HS_HOST BIT(10)

+/* Global User Control Register */
+#define DWC3_GUCTL_RESBWHSEPS BIT(16)
+
/* Global Status Register */
#define DWC3_GSTS_OTG_IP BIT(10)
#define DWC3_GSTS_BC_IP BIT(9)
@@ -1393,6 +1396,7 @@ struct dwc3 {
int num_ep_resized;
struct dentry *debug_root;
u32 gsbuscfg0_reqinfo;
+ bool dwc3_guctl_resbwhseps_quirk;
};

#define INCRX_BURST_MODE 0
--
2.17.1