"Das U-Boot" Source Tree

usb: dwc3-generic: Add STih407 support

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@foss.st.com>
Cc: Marek Vasut <marex@denx.de>
Reviewed-by: Mattijs Korpershoek <mkorpershoek@baylibre.com>
Link: https://lore.kernel.org/r/20250130163547.512990-6-patrice.chotard@foss.st.com
Signed-off-by: Mattijs Korpershoek <mkorpershoek@baylibre.com>

authored by

Patrice Chotard and committed by
Mattijs Korpershoek
23542078 9de4b7e0

+144
+1
MAINTAINERS
··· 671 671 F: drivers/serial/serial_sti_asc.c 672 672 F: drivers/sysreset/sysreset_sti.c 673 673 F: drivers/timer/arm_global_timer.c 674 + F: drivers/usb/host/dwc3-sti.c 674 675 F: include/dt-bindings/clock/stih407-clks.h 675 676 F: include/dt-bindings/clock/stih410-clks.h 676 677 F: include/dt-bindings/reset/stih407-resets.h
+8
drivers/usb/dwc3/Kconfig
··· 87 87 Host and Peripheral operation modes are supported. OTG is not 88 88 supported. 89 89 90 + config USB_DWC3_STI 91 + bool "STi USB wrapper" 92 + depends on DM_USB && USB_DWC3_GENERIC && SYSCON 93 + help 94 + Enables support for the on-chip xHCI controller on STMicroelectronics 95 + STiH407 family SoCs. This is a driver for the dwc3 to provide the 96 + glue logic to configure the controller. 97 + 90 98 menu "PHY Subsystem" 91 99 92 100 config USB_DWC3_PHY_OMAP
+1
drivers/usb/dwc3/Makefile
··· 15 15 obj-$(CONFIG_USB_DWC3_LAYERSCAPE) += dwc3-layerscape.o 16 16 obj-$(CONFIG_USB_DWC3_PHY_OMAP) += ti_usb_phy.o 17 17 obj-$(CONFIG_USB_DWC3_PHY_SAMSUNG) += samsung_usb_phy.o 18 + obj-$(CONFIG_USB_DWC3_STI) += dwc3-generic-sti.o
+134
drivers/usb/dwc3/dwc3-generic-sti.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-or-later OR BSD-3-Clause 2 + /* 3 + * STi specific glue layer for DWC3 4 + * 5 + * Copyright (C) 2025, STMicroelectronics - All Rights Reserved 6 + */ 7 + 8 + #define LOG_CATEGORY UCLASS_NOP 9 + 10 + #include <reset.h> 11 + #include <regmap.h> 12 + #include <syscon.h> 13 + #include <asm/io.h> 14 + #include <dm/device.h> 15 + #include <dm/device_compat.h> 16 + #include <dm/read.h> 17 + #include <linux/usb/otg.h> 18 + #include "dwc3-generic.h" 19 + 20 + /* glue registers */ 21 + #define CLKRST_CTRL 0x00 22 + #define AUX_CLK_EN BIT(0) 23 + #define SW_PIPEW_RESET_N BIT(4) 24 + #define EXT_CFG_RESET_N BIT(8) 25 + 26 + #define XHCI_REVISION BIT(12) 27 + 28 + #define USB2_VBUS_MNGMNT_SEL1 0x2C 29 + #define USB2_VBUS_UTMIOTG 0x1 30 + 31 + #define SEL_OVERRIDE_VBUSVALID(n) ((n) << 0) 32 + #define SEL_OVERRIDE_POWERPRESENT(n) ((n) << 4) 33 + #define SEL_OVERRIDE_BVALID(n) ((n) << 8) 34 + 35 + /* Static DRD configuration */ 36 + #define USB3_CONTROL_MASK 0xf77 37 + 38 + #define USB3_DEVICE_NOT_HOST BIT(0) 39 + #define USB3_FORCE_VBUSVALID BIT(1) 40 + #define USB3_DELAY_VBUSVALID BIT(2) 41 + #define USB3_SEL_FORCE_OPMODE BIT(4) 42 + #define USB3_FORCE_OPMODE(n) ((n) << 5) 43 + #define USB3_SEL_FORCE_DPPULLDOWN2 BIT(8) 44 + #define USB3_FORCE_DPPULLDOWN2 BIT(9) 45 + #define USB3_SEL_FORCE_DMPULLDOWN2 BIT(10) 46 + #define USB3_FORCE_DMPULLDOWN2 BIT(11) 47 + 48 + static void dwc3_stih407_glue_configure(struct udevice *dev, int index, 49 + enum usb_dr_mode mode) 50 + { 51 + struct dwc3_glue_data *glue = dev_get_plat(dev); 52 + struct regmap *regmap; 53 + ulong syscfg_base; 54 + ulong syscfg_offset; 55 + ulong glue_base; 56 + int ret; 57 + 58 + /* deassert both powerdown and softreset */ 59 + ret = reset_deassert_bulk(&glue->resets); 60 + if (ret) { 61 + dev_err(dev, "reset_deassert_bulk error: %d\n", ret); 62 + return; 63 + } 64 + 65 + regmap = syscon_regmap_lookup_by_phandle(dev, "st,syscfg"); 66 + if (IS_ERR(regmap)) { 67 + dev_err(dev, "unable to get st,syscfg, dev %s\n", dev->name); 68 + return; 69 + } 70 + 71 + syscfg_base = regmap->ranges[0].start; 72 + glue_base = dev_read_addr_index(dev, 0); 73 + syscfg_offset = dev_read_addr_index(dev, 1); 74 + 75 + clrbits_le32(syscfg_base + syscfg_offset, USB3_CONTROL_MASK); 76 + 77 + /* glue drd init */ 78 + switch (mode) { 79 + case USB_DR_MODE_PERIPHERAL: 80 + clrbits_le32(syscfg_base + syscfg_offset, 81 + USB3_DELAY_VBUSVALID | USB3_SEL_FORCE_OPMODE | 82 + USB3_FORCE_OPMODE(0x3) | USB3_SEL_FORCE_DPPULLDOWN2 | 83 + USB3_FORCE_DPPULLDOWN2 | USB3_SEL_FORCE_DMPULLDOWN2 | 84 + USB3_FORCE_DMPULLDOWN2); 85 + 86 + setbits_le32(syscfg_base + syscfg_offset, 87 + USB3_DEVICE_NOT_HOST | USB3_FORCE_VBUSVALID); 88 + break; 89 + 90 + case USB_DR_MODE_HOST: 91 + clrbits_le32(syscfg_base + syscfg_offset, 92 + USB3_DEVICE_NOT_HOST | USB3_FORCE_VBUSVALID | 93 + USB3_SEL_FORCE_OPMODE | USB3_FORCE_OPMODE(0x3) | 94 + USB3_SEL_FORCE_DPPULLDOWN2 | USB3_FORCE_DPPULLDOWN2 | 95 + USB3_SEL_FORCE_DMPULLDOWN2 | USB3_FORCE_DMPULLDOWN2); 96 + 97 + setbits_le32(syscfg_base + syscfg_offset, USB3_DELAY_VBUSVALID); 98 + break; 99 + 100 + default: 101 + dev_err(dev, "Unsupported mode of operation %d\n", mode); 102 + return; 103 + } 104 + 105 + /* glue init */ 106 + setbits_le32(glue_base + CLKRST_CTRL, AUX_CLK_EN | EXT_CFG_RESET_N | XHCI_REVISION); 107 + clrbits_le32(glue_base + CLKRST_CTRL, SW_PIPEW_RESET_N); 108 + 109 + /* configure mux for vbus, powerpresent and bvalid signals */ 110 + setbits_le32(glue_base + USB2_VBUS_MNGMNT_SEL1, 111 + SEL_OVERRIDE_VBUSVALID(USB2_VBUS_UTMIOTG) | 112 + SEL_OVERRIDE_POWERPRESENT(USB2_VBUS_UTMIOTG) | 113 + SEL_OVERRIDE_BVALID(USB2_VBUS_UTMIOTG)); 114 + setbits_le32(glue_base + CLKRST_CTRL, SW_PIPEW_RESET_N); 115 + }; 116 + 117 + struct dwc3_glue_ops stih407_ops = { 118 + .glue_configure = dwc3_stih407_glue_configure, 119 + }; 120 + 121 + static const struct udevice_id dwc3_sti_match[] = { 122 + { .compatible = "st,stih407-dwc3", .data = (ulong)&stih407_ops}, 123 + { /* sentinel */ } 124 + }; 125 + 126 + U_BOOT_DRIVER(dwc3_sti_wrapper) = { 127 + .name = "dwc3-sti", 128 + .id = UCLASS_NOP, 129 + .of_match = dwc3_sti_match, 130 + .bind = dwc3_glue_bind, 131 + .probe = dwc3_glue_probe, 132 + .remove = dwc3_glue_remove, 133 + .plat_auto = sizeof(struct dwc3_glue_data), 134 + };