[PATCH v4 3/5] arm: mach-snapdragon: Skip USB fixup for qcom,sc7280-dwc3

Balaji Selvanathan balaji.selvanathan at oss.qualcomm.com
Sat Apr 18 08:35:21 CEST 2026


Currently we unconditionally limit USB to high-speed on all Qualcomm
platforms since most lack super-speed PHY drivers. The sc7280
platform has a working super-speed PHY driver in U-Boot and should
not have this restriction applied.

Add a static check for the "qcom,sc7280-dwc3" compatible string at
the start of fixup_qcom_dwc3() to skip the USB high-speed fixup for
sc7280. Add a log_warning() when the fixup is applied so developers
on other platforms with working super-speed USB know to add their
compatible to the skip list.

Signed-off-by: Balaji Selvanathan <balaji.selvanathan at oss.qualcomm.com>
---
Changes in v4:
- Instead of automatically detect if SSPHY driver is
  available at runtime (which adds computational overhead), instead
  just skip HS fixup based on usb node compatible string.
---
 arch/arm/mach-snapdragon/of_fixup.c | 54 +++++++++++++++++++++++++------------
 1 file changed, 37 insertions(+), 17 deletions(-)

diff --git a/arch/arm/mach-snapdragon/of_fixup.c b/arch/arm/mach-snapdragon/of_fixup.c
index 5b6076ea8e5..6ce6f1061e9 100644
--- a/arch/arm/mach-snapdragon/of_fixup.c
+++ b/arch/arm/mach-snapdragon/of_fixup.c
@@ -27,11 +27,6 @@
 #include <stdlib.h>
 #include <time.h>
 
-/* U-Boot only supports USB high-speed mode on Qualcomm platforms with DWC3
- * USB controllers. Rather than requiring source level DT changes, we fix up
- * DT here. This improves compatibility with upstream DT and simplifies the
- * porting process for new devices.
- */
 static int fixup_qcom_dwc3(struct device_node *root, struct device_node *glue_np, bool flat)
 {
 	struct device_node *dwc3;
@@ -39,7 +34,7 @@ static int fixup_qcom_dwc3(struct device_node *root, struct device_node *glue_np
 	const __be32 *phandles;
 	const char *second_phy_name;
 
-	debug("Fixing up %s\n", glue_np->name);
+	debug("Checking USB configuration for %s\n", glue_np->name);
 
 	/* New DT flattens the glue and controller into a single node. */
 	if (flat) {
@@ -54,30 +49,56 @@ static int fixup_qcom_dwc3(struct device_node *root, struct device_node *glue_np
 		}
 	}
 
-	/* Tell the glue driver to configure the wrapper for high-speed only operation */
-	ret = of_write_prop(glue_np, "qcom,select-utmi-as-pipe-clk", 0, NULL);
-	if (ret) {
-		log_err("Failed to add property 'qcom,select-utmi-as-pipe-clk': %d\n", ret);
-		return ret;
-	}
-
 	phandles = of_get_property(dwc3, "phys", &len);
 	len /= sizeof(*phandles);
 	if (len == 1) {
 		log_debug("Only one phy, not a superspeed controller\n");
-		return 0;
+		goto apply_fixup;
 	}
 
-	/* Figure out if the superspeed phy is present and if so then which phy is it? */
+	/* Figure out if the superspeed phy is present */
 	ret = of_property_read_string_index(dwc3, "phy-names", 1, &second_phy_name);
 	if (ret == -ENODATA) {
 		log_debug("Only one phy, not a super-speed controller\n");
-		return 0;
+		goto apply_fixup;
 	} else if (ret) {
 		log_err("Failed to read second phy name: %d\n", ret);
 		return ret;
 	}
 
+	/*
+	 * Skip the fixup for platforms with proper super-speed USB support
+	 * in U-Boot. Add the DWC3 glue compatible string to this list when
+	 * super-speed USB works on a new platform.
+	 */
+	static const char * const ss_capable[] = {
+		"qcom,sc7280-dwc3",
+		NULL
+	};
+	for (int i = 0; ss_capable[i]; i++) {
+		if (of_device_is_compatible(glue_np, ss_capable[i], NULL, NULL)) {
+			debug("Skipping USB fixup for %s\n", glue_np->name);
+			return 0;
+		}
+	}
+
+apply_fixup:
+	log_warning("Applying USB high-speed fixup to %s. If super-speed USB works on this platform, add the compatible to the skip list in %s\n",
+		    glue_np->name, __FILE__);
+
+	/* Tell the glue driver to configure the wrapper for high-speed only operation */
+	ret = of_write_prop(glue_np, "qcom,select-utmi-as-pipe-clk", 0, NULL);
+	if (ret) {
+		log_err("Failed to add property 'qcom,select-utmi-as-pipe-clk': %d\n", ret);
+		return ret;
+	}
+
+	/*
+	 * Single-PHY controllers only need qcom,select-utmi-as-pipe-clk.
+	 */
+	if (len == 1)
+		return 0;
+
 	/*
 	 * Determine which phy is the superspeed phy by checking the name of the second phy
 	 * since it is typically the superspeed one.
@@ -104,7 +125,6 @@ static int fixup_qcom_dwc3(struct device_node *root, struct device_node *glue_np
 		log_err("Failed to set 'maximum-speed' property: %d\n", ret);
 		return ret;
 	}
-
 	return 0;
 }
 

-- 
2.34.1



More information about the U-Boot mailing list