[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