
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 ---
drivers/usb/dwc3/dwc3-generic.c | 108 ++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+)
diff --git a/drivers/usb/dwc3/dwc3-generic.c b/drivers/usb/dwc3/dwc3-generic.c index cb96e1f344f..0cd03bf0787 100644 --- a/drivers/usb/dwc3/dwc3-generic.c +++ b/drivers/usb/dwc3/dwc3-generic.c @@ -14,7 +14,9 @@ #include <generic-phy.h> #include <log.h> #include <malloc.h> +#include <regmap.h> #include <reset.h> +#include <syscon.h> #include <usb.h> #include <asm/gpio.h> #include <dm/device-internal.h> @@ -511,6 +513,111 @@ struct dwc3_glue_ops rk_ops = { .glue_get_ctrl_dev = dwc3_rk_glue_get_ctrl_dev, };
+void dwc3_stih407_glue_configure(struct udevice *dev, int index, + enum usb_dr_mode mode) +{ +/* 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) + + struct dwc3_glue_data *glue = dev_get_plat(dev); + struct regmap *regmap; + ulong syscfg_base; + ulong syscfg_offset; + ulong glue_base; + u32 reg; + int ret; + + /* deassert both powerdown and softreset */ + ret = reset_deassert_bulk(&glue->resets); + if (ret) { + debug("reset_deassert_bulk error: %d\n", ret); + return; + } + + regmap = syscon_regmap_lookup_by_phandle(dev, "st,syscfg"); + + syscfg_base = regmap->ranges[0].start; + glue_base = dev_read_addr_index(dev, 0); + syscfg_offset = dev_read_addr_index(dev, 1); + + reg = readl(syscfg_base + syscfg_offset); + reg &= USB3_CONTROL_MASK; + + /* glue drd init */ + switch (mode) { + case USB_DR_MODE_PERIPHERAL: + reg &= ~(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); + + reg |= USB3_DEVICE_NOT_HOST | USB3_FORCE_VBUSVALID; + break; + + case USB_DR_MODE_HOST: + reg &= ~(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); + + reg |= USB3_DELAY_VBUSVALID; + break; + + default: + debug("Unsupported mode of operation %d\n", mode); + return; + } + writel(reg, syscfg_base + syscfg_offset); + + /* glue init */ + reg = readl(glue_base + CLKRST_CTRL); + + reg |= AUX_CLK_EN | EXT_CFG_RESET_N | XHCI_REVISION; + reg &= ~SW_PIPEW_RESET_N; + + writel(reg, glue_base + CLKRST_CTRL); + + /* configure mux for vbus, powerpresent and bvalid signals */ + reg = readl(glue_base + USB2_VBUS_MNGMNT_SEL1); + + reg |= SEL_OVERRIDE_VBUSVALID(USB2_VBUS_UTMIOTG) | + SEL_OVERRIDE_POWERPRESENT(USB2_VBUS_UTMIOTG) | + SEL_OVERRIDE_BVALID(USB2_VBUS_UTMIOTG); + + writel(reg, glue_base + USB2_VBUS_MNGMNT_SEL1); + + setbits_le32(glue_base + CLKRST_CTRL, SW_PIPEW_RESET_N); +}; + +struct dwc3_glue_ops stih407_ops = { + .glue_configure = dwc3_stih407_glue_configure, +}; + static int dwc3_glue_bind_common(struct udevice *parent, ofnode node) { const char *name = ofnode_get_name(node); @@ -714,6 +821,7 @@ static const struct udevice_id dwc3_glue_ids[] = { { .compatible = "fsl,imx8mp-dwc3", .data = (ulong)&imx8mp_ops }, { .compatible = "fsl,imx8mq-dwc3" }, { .compatible = "intel,tangier-dwc3" }, + { .compatible = "st,stih407-dwc3", .data = (ulong)&stih407_ops}, { } };