[PATCH v4 4/9] usb: dwc3-generic: Add STih407 support

Patrice Chotard patrice.chotard at foss.st.com
Thu Jan 23 15:47:13 CET 2025


Add STi glue logic to manage the DWC3 HC on STiH407
SoC family. It configures the internal glue logic and
syscfg registers.

Signed-off-by: Patrice Chotard <patrice.chotard at foss.st.com>
Cc: Marek Vasut <marex at denx.de>
Reviewed-by: Mattijs Korpershoek <mkorpershoek at baylibre.com>

---

Changes in v4:
  - Update Kconfig description

Changes in v3:
  - Replace debug() by dev_err()
  - check return value of syscon_regmap_lookup_by_phandle()

Changes in v2:
  - add dwc3-sti.c DWC3 wrapper as done for dwc3-am62.c

 MAINTAINERS                         |   1 +
 drivers/usb/dwc3/Kconfig            |   8 ++
 drivers/usb/dwc3/Makefile           |   1 +
 drivers/usb/dwc3/dwc3-generic-sti.c | 132 ++++++++++++++++++++++++++++
 4 files changed, 142 insertions(+)
 create mode 100644 drivers/usb/dwc3/dwc3-generic-sti.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 8c6c0c2a4bc..5d7e251e601 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -656,6 +656,7 @@ F:	drivers/mmc/sti_sdhci.c
 F:	drivers/reset/sti-reset.c
 F:	drivers/serial/serial_sti_asc.c
 F:	drivers/sysreset/sysreset_sti.c
+F:	drivers/usb/host/dwc3-sti.c
 F:	drivers/timer/arm_global_timer.c
 F:	drivers/usb/host/dwc3-sti-glue.c
 F:	include/dwc3-sti-glue.h
diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig
index 0100723a68b..682a6910655 100644
--- a/drivers/usb/dwc3/Kconfig
+++ b/drivers/usb/dwc3/Kconfig
@@ -87,6 +87,14 @@ config USB_DWC3_LAYERSCAPE
 	  Host and Peripheral operation modes are supported. OTG is not
 	  supported.
 
+config USB_DWC3_STI
+	bool "STi USB wrapper"
+	depends on DM_USB && USB_DWC3_GENERIC && SYSCON
+	help
+	  Enables support for the on-chip xHCI controller on STMicroelectronics
+	  STiH407 family SoCs. This is a driver for the dwc3 to provide the
+	  glue logic to configure the controller.
+
 menu "PHY Subsystem"
 
 config USB_DWC3_PHY_OMAP
diff --git a/drivers/usb/dwc3/Makefile b/drivers/usb/dwc3/Makefile
index a085c9d4628..985206eafe4 100644
--- a/drivers/usb/dwc3/Makefile
+++ b/drivers/usb/dwc3/Makefile
@@ -15,3 +15,4 @@ obj-$(CONFIG_USB_DWC3_UNIPHIER)		+= dwc3-uniphier.o
 obj-$(CONFIG_USB_DWC3_LAYERSCAPE)	+= dwc3-layerscape.o
 obj-$(CONFIG_USB_DWC3_PHY_OMAP)		+= ti_usb_phy.o
 obj-$(CONFIG_USB_DWC3_PHY_SAMSUNG)	+= samsung_usb_phy.o
+obj-$(CONFIG_USB_DWC3_STI)		+= dwc3-generic-sti.o
diff --git a/drivers/usb/dwc3/dwc3-generic-sti.c b/drivers/usb/dwc3/dwc3-generic-sti.c
new file mode 100644
index 00000000000..2ff640cede4
--- /dev/null
+++ b/drivers/usb/dwc3/dwc3-generic-sti.c
@@ -0,0 +1,132 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR BSD-3-Clause
+/*
+ * STi specific glue layer for DWC3
+ *
+ * Copyright (C) 2025, STMicroelectronics - All Rights Reserved
+ */
+
+#include <reset.h>
+#include <regmap.h>
+#include <syscon.h>
+#include <asm/io.h>
+#include <dm/device.h>
+#include <dm/device_compat.h>
+#include <dm/read.h>
+#include <linux/usb/otg.h>
+#include "dwc3-generic.h"
+
+/* glue registers */
+#define CLKRST_CTRL		0x00
+#define AUX_CLK_EN		BIT(0)
+#define SW_PIPEW_RESET_N	BIT(4)
+#define EXT_CFG_RESET_N		BIT(8)
+
+#define XHCI_REVISION		BIT(12)
+
+#define USB2_VBUS_MNGMNT_SEL1	0x2C
+#define USB2_VBUS_UTMIOTG	0x1
+
+#define SEL_OVERRIDE_VBUSVALID(n)	((n) << 0)
+#define SEL_OVERRIDE_POWERPRESENT(n)	((n) << 4)
+#define SEL_OVERRIDE_BVALID(n)		((n) << 8)
+
+/* Static DRD configuration */
+#define USB3_CONTROL_MASK		0xf77
+
+#define USB3_DEVICE_NOT_HOST		BIT(0)
+#define USB3_FORCE_VBUSVALID		BIT(1)
+#define USB3_DELAY_VBUSVALID		BIT(2)
+#define USB3_SEL_FORCE_OPMODE		BIT(4)
+#define USB3_FORCE_OPMODE(n)		((n) << 5)
+#define USB3_SEL_FORCE_DPPULLDOWN2	BIT(8)
+#define USB3_FORCE_DPPULLDOWN2		BIT(9)
+#define USB3_SEL_FORCE_DMPULLDOWN2	BIT(10)
+#define USB3_FORCE_DMPULLDOWN2		BIT(11)
+
+static void dwc3_stih407_glue_configure(struct udevice *dev, int index,
+					enum usb_dr_mode mode)
+{
+	struct dwc3_glue_data *glue = dev_get_plat(dev);
+	struct regmap *regmap;
+	ulong syscfg_base;
+	ulong syscfg_offset;
+	ulong glue_base;
+	int ret;
+
+	/* deassert both powerdown and softreset */
+	ret = reset_deassert_bulk(&glue->resets);
+	if (ret) {
+		dev_err(dev, "reset_deassert_bulk error: %d\n", ret);
+		return;
+	}
+
+	regmap = syscon_regmap_lookup_by_phandle(dev, "st,syscfg");
+	if (IS_ERR(regmap)) {
+		dev_err(dev, "unable to get st,syscfg, dev %s\n", dev->name);
+		return;
+	}
+
+	syscfg_base = regmap->ranges[0].start;
+	glue_base = dev_read_addr_index(dev, 0);
+	syscfg_offset = dev_read_addr_index(dev, 1);
+
+	clrbits_le32(syscfg_base + syscfg_offset, USB3_CONTROL_MASK);
+
+	/* glue drd init */
+	switch (mode) {
+	case USB_DR_MODE_PERIPHERAL:
+		clrbits_le32(syscfg_base + syscfg_offset,
+			     USB3_DELAY_VBUSVALID | USB3_SEL_FORCE_OPMODE |
+			     USB3_FORCE_OPMODE(0x3) | USB3_SEL_FORCE_DPPULLDOWN2 |
+			     USB3_FORCE_DPPULLDOWN2 | USB3_SEL_FORCE_DMPULLDOWN2 |
+			     USB3_FORCE_DMPULLDOWN2);
+
+		setbits_le32(syscfg_base + syscfg_offset,
+			     USB3_DEVICE_NOT_HOST | USB3_FORCE_VBUSVALID);
+		break;
+
+	case USB_DR_MODE_HOST:
+		clrbits_le32(syscfg_base + syscfg_offset,
+			     USB3_DEVICE_NOT_HOST | USB3_FORCE_VBUSVALID |
+			     USB3_SEL_FORCE_OPMODE | USB3_FORCE_OPMODE(0x3) |
+			     USB3_SEL_FORCE_DPPULLDOWN2 | USB3_FORCE_DPPULLDOWN2 |
+			     USB3_SEL_FORCE_DMPULLDOWN2 | USB3_FORCE_DMPULLDOWN2);
+
+		setbits_le32(syscfg_base + syscfg_offset, USB3_DELAY_VBUSVALID);
+		break;
+
+	default:
+		dev_err(dev, "Unsupported mode of operation %d\n", mode);
+		return;
+	}
+
+	/* glue init */
+	setbits_le32(glue_base + CLKRST_CTRL, AUX_CLK_EN | EXT_CFG_RESET_N | XHCI_REVISION);
+	clrbits_le32(glue_base + CLKRST_CTRL, SW_PIPEW_RESET_N);
+
+	/* configure mux for vbus, powerpresent and bvalid signals */
+	setbits_le32(glue_base + USB2_VBUS_MNGMNT_SEL1,
+		     SEL_OVERRIDE_VBUSVALID(USB2_VBUS_UTMIOTG) |
+		     SEL_OVERRIDE_POWERPRESENT(USB2_VBUS_UTMIOTG) |
+		     SEL_OVERRIDE_BVALID(USB2_VBUS_UTMIOTG));
+	setbits_le32(glue_base + CLKRST_CTRL, SW_PIPEW_RESET_N);
+};
+
+struct dwc3_glue_ops stih407_ops = {
+	.glue_configure = dwc3_stih407_glue_configure,
+};
+
+static const struct udevice_id dwc3_sti_match[] = {
+	{ .compatible = "st,stih407-dwc3", .data = (ulong)&stih407_ops},
+	{ /* sentinel */ }
+};
+
+U_BOOT_DRIVER(dwc3_sti_wrapper) = {
+	.name = "dwc3-sti",
+	.id = UCLASS_SIMPLE_BUS,
+	.of_match = dwc3_sti_match,
+	.bind = dwc3_glue_bind,
+	.probe = dwc3_glue_probe,
+	.remove = dwc3_glue_remove,
+	.plat_auto = sizeof(struct dwc3_glue_data),
+};
-- 
2.25.1



More information about the U-Boot mailing list