Skip to contentSkip to conversation

usb: dwc3: core: add Gen2 polarity detection support

PATCH In review Michael Wu 2 participants 4 messages Sep 27, 2024

Subsystems (3)
lore
Share & tools
lore

Michael Wu

author
#0 lore raw

PATCH 1/2 usb: dwc3: core: add Gen2 polarity detection support

According to the DWC31 Enhanced SuperSpeed USB3.1 Controller Programming Guide, for Gen2 polarity detection, link uses data block (0011b) sync header for SYNC OS instead of control block (1100b).

Added 'snps,inv-sync-hdr-quirk' a DT property to set this bit 30 of LLUCTL if the third-party PHY doesn't correct the sync header of the SYNC OS in the case of inverse polarity.

---
 drivers/usb/dwc3/core.c | 24 ++++++++++++++++--------
 drivers/usb/dwc3/core.h |  6 ++++++
 2 files changed, 22 insertions(+), 8 deletions(-)
drivers/usb/dwc3/core.c +16 -8
index 734de2a8bd212..72fddfcbdd0c3 100644
@@ -1434,15 +1434,20 @@ static int dwc3_core_init(struct dwc3 *dwc)
 
 	dwc3_config_threshold(dwc);
 
-	/*
-	 * Modify this for all supported Super Speed ports when
-	 * multiport support is added.
-	 */
-	if (hw_mode != DWC3_GHWPARAMS0_MODE_GADGET &&
-	    (DWC3_IP_IS(DWC31)) &&
-	    dwc->maximum_speed == USB_SPEED_SUPER) {
+	if (DWC3_IP_IS(DWC31)) {
 		reg = dwc3_readl(dwc->regs, DWC3_LLUCTL);
-		reg |= DWC3_LLUCTL_FORCE_GEN1;
+
+		/*
+		 * Modify this for all supported Super Speed ports when
+		 * multiport support is added.
+		 */
+		if (hw_mode != DWC3_GHWPARAMS0_MODE_GADGET &&
+		    dwc->maximum_speed == USB_SPEED_SUPER)
+			reg |= DWC3_LLUCTL_FORCE_GEN1;
+
+		if (dwc->inv_sync_hdr_quirk)
+			reg |= DWC3_LLUCTL_INV_SYNC_HDR;
+
 		dwc3_writel(dwc->regs, DWC3_LLUCTL, reg);
 	}
 
@@ -1774,6 +1779,9 @@ static void dwc3_get_properties(struct dwc3 *dwc)
 	dwc->dis_split_quirk = device_property_read_bool(dev,
 				"snps,dis-split-quirk");
 
+	dwc->inv_sync_hdr_quirk = device_property_read_bool(dev,
+				"snps,inv-sync-hdr-quirk");
+
 	dwc->lpm_nyet_threshold = lpm_nyet_threshold;
 	dwc->tx_de_emphasis = tx_de_emphasis;
 
drivers/usb/dwc3/core.h +6 -0
index 1e561fd8b86e2..5e5971e50bc09 100644
@@ -673,6 +673,9 @@
 /* Force Gen1 speed on Gen2 link */
 #define DWC3_LLUCTL_FORCE_GEN1		BIT(10)
 
+/* Link uses data block sync header for Gen2 polarity detection */
+#define DWC3_LLUCTL_INV_SYNC_HDR	BIT(30)
+
 /* Structures */
 
 struct dwc3_trb;
@@ -1146,6 +1149,8 @@ struct dwc3_scratchpad_array {
  *	3	- Reserved
  * @dis_metastability_quirk: set to disable metastability quirk.
  * @dis_split_quirk: set to disable split boundary.
+ * @inv_sync_hdr_quirk: set if the third-party PHY does not correct the sync
+ *			header of the SYNC OS in case of inverse polarity.
  * @sys_wakeup: set if the device may do system wakeup.
  * @wakeup_configured: set if the device is configured for remote wakeup.
  * @suspended: set to track suspend event due to U3/L2.
@@ -1376,6 +1381,7 @@ struct dwc3 {
 	unsigned		dis_metastability_quirk:1;
 
 	unsigned		dis_split_quirk:1;
+	unsigned		inv_sync_hdr_quirk:1;
 	unsigned		async_callbacks:1;
 	unsigned		sys_wakeup:1;
 	unsigned		wakeup_configured:1;
Signature · 1 line
2.29.0
author
#1 lore raw

PATCH 2/2 dt-bindings: usb: snps,dwc3: Add 'snps,inv-sync-hdr-quirk' quirk

Added the new 'snps,inv-sync-hdr-quirk' DT property to dwc3 core for Gen2 polarity detection.

The link uses data block (0011b) sync header for SYNC OS instead of control block (1100b). Set this quirk if the third-party PHY does not correct the sync header of the SYNC OS in the case of inverse polarity.

---
 Documentation/devicetree/bindings/usb/snps,dwc3.yaml | 6 ++++++
 1 file changed, 6 insertions(+)
Documentation/devicetree/bindings/usb/snps,dwc3.yaml +6 -0
index 1cd0ca90127d9..e5ed5cca1cf25 100644
@@ -280,6 +280,12 @@ properties:
       asserts utmi_sleep_n.
     type: boolean
 
+  snps,inv-sync-hdr-quirk:
+    description:
+      Set if the third-party PHY does not correct the sync header of the
+      SYNC OS in the case of inverse polarity.
+    type: boolean
+
   snps,hird-threshold:
     description: HIRD threshold
     $ref: /schemas/types.yaml#/definitions/uint8
Signature · 1 line
2.29.0
#2 lore raw

Re: [PATCH 2/2] dt-bindings: usb: snps,dwc3: Add 'snps,inv-sync-hdr-quirk' quirk

Quoted 12 lines · Michael Wu

Added the new 'snps,inv-sync-hdr-quirk' DT property to dwc3 core for Gen2 polarity detection.

The link uses data block (0011b) sync header for SYNC OS instead of control block (1100b). Set this quirk if the third-party PHY does not correct the sync header of the SYNC OS in the case of inverse polarity.

---
 Documentation/devicetree/bindings/usb/snps,dwc3.yaml | 6 ++++++
 1 file changed, 6 insertions(+)

Why this cannot be deduced from compatible?

Best regards,
Krzysztof

#3 lore raw
In reply to Michael Wu
Quoted 48 lines · Michael Wu

According to the DWC31 Enhanced SuperSpeed USB3.1 Controller Programming Guide, for Gen2 polarity detection, link uses data block (0011b) sync header for SYNC OS instead of control block (1100b).

Added 'snps,inv-sync-hdr-quirk' a DT property to set this bit 30 of LLUCTL if the third-party PHY doesn't correct the sync header of the SYNC OS in the case of inverse polarity.

---
 drivers/usb/dwc3/core.c | 24 ++++++++++++++++--------
 drivers/usb/dwc3/core.h |  6 ++++++
 2 files changed, 22 insertions(+), 8 deletions(-)
drivers/usb/dwc3/core.c +13 -8
index 734de2a8bd212..72fddfcbdd0c3 100644
@@ -1434,15 +1434,20 @@ static int dwc3_core_init(struct dwc3 *dwc)
 
 	dwc3_config_threshold(dwc);
 
-	/*
-	 * Modify this for all supported Super Speed ports when
-	 * multiport support is added.
-	 */
-	if (hw_mode != DWC3_GHWPARAMS0_MODE_GADGET &&
-	    (DWC3_IP_IS(DWC31)) &&
-	    dwc->maximum_speed == USB_SPEED_SUPER) {
+	if (DWC3_IP_IS(DWC31)) {
 		reg = dwc3_readl(dwc->regs, DWC3_LLUCTL);
-		reg |= DWC3_LLUCTL_FORCE_GEN1;
+
+		/*
+		 * Modify this for all supported Super Speed ports when
+		 * multiport support is added.
+		 */
+		if (hw_mode != DWC3_GHWPARAMS0_MODE_GADGET &&
+		    dwc->maximum_speed == USB_SPEED_SUPER)
+			reg |= DWC3_LLUCTL_FORCE_GEN1;
+
+		if (dwc->inv_sync_hdr_quirk)
+			reg |= DWC3_LLUCTL_INV_SYNC_HDR;
+
 		dwc3_writel(dwc->regs, DWC3_LLUCTL, reg);
 	}
 

drivers/usb/dwc3/core.c static void dwc3_get_properties(struct dwc3 *dwc) · line 1783

Quoted 5 lines
drivers/usb/dwc3/core.c +2 -0
@@ -1774,6 +1779,9 @@ static void dwc3_get_properties(struct dwc3 *dwc)
 	dwc->dis_split_quirk = device_property_read_bool(dev,
 				"snps,dis-split-quirk");
 
+	dwc->inv_sync_hdr_quirk = device_property_read_bool(dev,
+				"snps,inv-sync-hdr-quirk");

Bindings are *always* before their users.

Best regards,
Krzysztof