From: Anders Roxell <anders.roxell@linaro.org>
To: u-boot@lists.denx.de, marex@denx.de
Cc: mkorpershoek@kernel.org, ilias.apalodimas@linaro.org,
trini@konsulko.com, michal.simek@amd.com, alchark@flipper.net,
jerome.forissier@arm.com,
Anders Roxell <anders.roxell@linaro.org>,
Jerome Forissier <jerome.forissier@linaro.org>,
Jens Wiklander <jens.wiklander@linaro.org>
Subject: [PATCH v5 67/75] usb: dwc3: make the core driver build in u-boot
Date: Thu, 16 Jul 2026 15:42:37 +0200 [thread overview]
Message-ID: <20260716134305.614278-68-anders.roxell@linaro.org> (raw)
In-Reply-To: <20260716134305.614278-1-anders.roxell@linaro.org>
Adapt the DWC3 core files to u-boot: core, io, Makefile and the omap and
ti phy glue.
Co-developed-by: Jerome Forissier <jerome.forissier@linaro.org>
Signed-off-by: Jerome Forissier <jerome.forissier@linaro.org>
Co-developed-by: Jens Wiklander <jens.wiklander@linaro.org>
Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
Signed-off-by: Anders Roxell <anders.roxell@linaro.org>
---
drivers/usb/dwc3/Makefile | 57 +-
drivers/usb/dwc3/core.c | 1761 ++++++++-------------------------
drivers/usb/dwc3/core.h | 39 +-
drivers/usb/dwc3/dwc3-omap.c | 2 -
drivers/usb/dwc3/io.h | 28 +-
drivers/usb/dwc3/ti_usb_phy.c | 2 -
6 files changed, 464 insertions(+), 1425 deletions(-)
diff --git a/drivers/usb/dwc3/Makefile b/drivers/usb/dwc3/Makefile
index a619cd374fb4..6700ea93eae0 100644
--- a/drivers/usb/dwc3/Makefile
+++ b/drivers/usb/dwc3/Makefile
@@ -1,18 +1,59 @@
-# SPDX-License-Identifier: GPL-2.0+
-
+# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_USB_DWC3) += dwc3.o
dwc3-y := core.o
-obj-$(CONFIG_USB_DWC3_GADGET) += gadget.o ep0.o
+ifneq ($(filter y,$(CONFIG_USB_DWC3_HOST) $(CONFIG_USB_DWC3_DUAL_ROLE)),)
+ dwc3-y += host.o
+endif
+
+ifneq ($(filter y,$(CONFIG_USB_DWC3_GADGET) $(CONFIG_USB_DWC3_DUAL_ROLE)),)
+ dwc3-y += gadget.o ep0.o
+endif
+
+ifneq ($(CONFIG_USB_DWC3_DUAL_ROLE),)
+ dwc3-y += drd.o
+endif
+
+ifneq ($(CONFIG_USB_DWC3_ULPI),)
+ dwc3-y += ulpi.o
+endif
+
+ifneq ($(CONFIG_DEBUG_FS),)
+ dwc3-y += debugfs.o
+endif
+
+##
+# Platform-specific glue layers go here
+#
+# NOTICE: Make sure your glue layer doesn't depend on anything
+# which is arch-specific and that it compiles on all situations.
+#
+# We want to keep this requirement in order to be able to compile
+# the entire driver (with all its glue layers) on several architectures
+# and make sure it compiles fine. This will also help with allmodconfig
+# and allyesconfig builds.
+##
-obj-$(CONFIG_$(PHASE_)USB_DWC3_AM62) += dwc3-am62.o
+obj-$(CONFIG_$(PHASE_)USB_DWC3_AM62) += dwc3-am62.o
obj-$(CONFIG_USB_DWC3_OMAP) += dwc3-omap.o
+obj-$(CONFIG_USB_DWC3_EXYNOS) += dwc3-exynos.o
+obj-$(CONFIG_$(PHASE_)USB_DWC3_GENERIC) += dwc3-generic.o
+obj-$(CONFIG_USB_DWC3_STI) += dwc3-generic-sti.o
+obj-$(CONFIG_USB_DWC3_PCI) += dwc3-pci.o
+obj-$(CONFIG_USB_DWC3_HAPS) += dwc3-haps.o
+obj-$(CONFIG_USB_DWC3_IMX8MP) += dwc3-imx8mp.o
+obj-$(CONFIG_USB_DWC3_KEYSTONE) += dwc3-keystone.o
+obj-$(CONFIG_USB_DWC3_LAYERSCAPE) += dwc3-layerscape.o
obj-$(CONFIG_USB_DWC3_MESON_G12A) += dwc3-meson-g12a.o
obj-$(CONFIG_USB_DWC3_MESON_GXL) += dwc3-meson-gxl.o
-obj-$(CONFIG_$(PHASE_)USB_DWC3_GENERIC) += dwc3-generic.o
+obj-$(CONFIG_USB_DWC3_OCTEON) += dwc3-octeon.o
+obj-$(CONFIG_USB_DWC3_OF_SIMPLE) += dwc3-of-simple.o
+obj-$(CONFIG_USB_DWC3_QCOM) += dwc3-qcom.o
+obj-$(CONFIG_USB_DWC3_QCOM) += dwc3-qcom-legacy.o
+obj-$(CONFIG_USB_DWC3_RTK) += dwc3-rtk.o
+obj-$(CONFIG_USB_DWC3_ST) += dwc3-st.o
obj-$(CONFIG_USB_DWC3_UNIPHIER) += dwc3-uniphier.o
-obj-$(CONFIG_USB_DWC3_LAYERSCAPE) += dwc3-layerscape.o
+obj-$(CONFIG_USB_DWC3_XILINX) += dwc3-xilinx.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
+obj-$(CONFIG_$(PHASE_)USB_DWC3_GENERIC) += dwc3-generic.o
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index 8002c23a5a02..5b6004a54d9b 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -8,104 +8,40 @@
* Sebastian Andrzej Siewior <bigeasy@linutronix.de>
*/
-#include <linux/clk.h>
-#include <linux/version.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/platform_device.h>
-#include <linux/pm_runtime.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/io.h>
-#include <linux/list.h>
+#include <clk.h>
+#include <cpu_func.h>
+#include <malloc.h>
+#include <dwc3-uboot.h>
+#include <dm/device_compat.h>
+#include <dm/devres.h>
+#include <linux/bug.h>
#include <linux/delay.h>
#include <linux/dma-mapping.h>
-#include <linux/of.h>
-#include <linux/of_graph.h>
-#include <linux/acpi.h>
-#include <linux/pinctrl/consumer.h>
-#include <linux/pinctrl/devinfo.h>
-#include <linux/reset.h>
-#include <linux/bitfield.h>
-
+#include <linux/err.h>
+#include <linux/iopoll.h>
+#include <linux/ioport.h>
+#include <dm.h>
+#include <generic-phy.h>
#include <linux/usb/ch9.h>
#include <linux/usb/gadget.h>
-#include <linux/usb/of.h>
-#include <linux/usb/otg.h>
+#include <linux/bitfield.h>
+#include <linux/math64.h>
+#include <linux/time.h>
+
+#include <version.h>
#include "core.h"
#include "gadget.h"
#include "glue.h"
#include "io.h"
-#include "debug.h"
#include "../host/xhci-ext-caps.h"
-#define DWC3_DEFAULT_AUTOSUSPEND_DELAY 5000 /* ms */
-
-/**
- * dwc3_get_dr_mode - Validates and sets dr_mode
- * @dwc: pointer to our context structure
- */
-static int dwc3_get_dr_mode(struct dwc3 *dwc)
-{
- enum usb_dr_mode mode;
- struct device *dev = dwc->dev;
- unsigned int hw_mode;
-
- if (dwc->dr_mode == USB_DR_MODE_UNKNOWN)
- dwc->dr_mode = USB_DR_MODE_OTG;
-
- mode = dwc->dr_mode;
- hw_mode = DWC3_GHWPARAMS0_MODE(dwc->hwparams.hwparams0);
-
- switch (hw_mode) {
- case DWC3_GHWPARAMS0_MODE_GADGET:
- if (IS_ENABLED(CONFIG_USB_DWC3_HOST)) {
- dev_err(dev,
- "Controller does not support host mode.\n");
- return -EINVAL;
- }
- mode = USB_DR_MODE_PERIPHERAL;
- break;
- case DWC3_GHWPARAMS0_MODE_HOST:
- if (IS_ENABLED(CONFIG_USB_DWC3_GADGET)) {
- dev_err(dev,
- "Controller does not support device mode.\n");
- return -EINVAL;
- }
- mode = USB_DR_MODE_HOST;
- break;
- default:
- if (IS_ENABLED(CONFIG_USB_DWC3_HOST))
- mode = USB_DR_MODE_HOST;
- else if (IS_ENABLED(CONFIG_USB_DWC3_GADGET))
- mode = USB_DR_MODE_PERIPHERAL;
-
- /*
- * DWC_usb31 and DWC_usb3 v3.30a and higher do not support OTG
- * mode. If the controller supports DRD but the dr_mode is not
- * specified or set to OTG, then set the mode to peripheral.
- */
- if (mode == USB_DR_MODE_OTG && !dwc->edev &&
- (!IS_ENABLED(CONFIG_USB_ROLE_SWITCH) ||
- !device_property_read_bool(dwc->dev, "usb-role-switch")) &&
- !DWC3_VER_IS_PRIOR(DWC3, 330A))
- mode = USB_DR_MODE_PERIPHERAL;
- }
-
- if (mode != dwc->dr_mode) {
- dev_warn(dev,
- "Configuration mismatch. dr_mode forced to %s\n",
- mode == USB_DR_MODE_HOST ? "host" : "gadget");
+#define msleep(a) udelay(a * 1000)
- dwc->dr_mode = mode;
- }
+#define DWC3_DEFAULT_AUTOSUSPEND_DELAY 5000 /* ms */
- return 0;
-}
+static LIST_HEAD(dwc3_list);
void dwc3_enable_susphy(struct dwc3 *dwc, bool enable)
{
@@ -158,146 +94,6 @@ void dwc3_set_prtcap(struct dwc3 *dwc, u32 mode, bool ignore_susphy)
dwc->current_dr_role = mode;
}
-static void __dwc3_set_mode(struct work_struct *work)
-{
- struct dwc3 *dwc = work_to_dwc(work);
- unsigned long flags;
- int ret;
- u32 reg;
- u32 desired_dr_role;
- int i;
-
- mutex_lock(&dwc->mutex);
- spin_lock_irqsave(&dwc->lock, flags);
- desired_dr_role = dwc->desired_dr_role;
- spin_unlock_irqrestore(&dwc->lock, flags);
-
- pm_runtime_get_sync(dwc->dev);
-
- if (dwc->current_dr_role == DWC3_GCTL_PRTCAP_OTG)
- dwc3_otg_update(dwc, 0);
-
- if (!desired_dr_role)
- goto out;
-
- if (desired_dr_role == dwc->current_dr_role)
- goto out;
-
- if (desired_dr_role == DWC3_GCTL_PRTCAP_OTG && dwc->edev)
- goto out;
-
- switch (dwc->current_dr_role) {
- case DWC3_GCTL_PRTCAP_HOST:
- dwc3_host_exit(dwc);
- break;
- case DWC3_GCTL_PRTCAP_DEVICE:
- dwc3_gadget_exit(dwc);
- dwc3_event_buffers_cleanup(dwc);
- break;
- case DWC3_GCTL_PRTCAP_OTG:
- dwc3_otg_exit(dwc);
- spin_lock_irqsave(&dwc->lock, flags);
- dwc->desired_otg_role = DWC3_OTG_ROLE_IDLE;
- spin_unlock_irqrestore(&dwc->lock, flags);
- dwc3_otg_update(dwc, 1);
- break;
- default:
- break;
- }
-
- /*
- * When current_dr_role is not set, there's no role switching.
- * Only perform GCTL.CoreSoftReset when there's DRD role switching.
- */
- if (dwc->current_dr_role && ((DWC3_IP_IS(DWC3) ||
- DWC3_VER_IS_PRIOR(DWC31, 190A)) &&
- desired_dr_role != DWC3_GCTL_PRTCAP_OTG)) {
- reg = dwc3_readl(dwc->regs, DWC3_GCTL);
- reg |= DWC3_GCTL_CORESOFTRESET;
- dwc3_writel(dwc->regs, DWC3_GCTL, reg);
-
- /*
- * Wait for internal clocks to synchronized. DWC_usb31 and
- * DWC_usb32 may need at least 50ms (less for DWC_usb3). To
- * keep it consistent across different IPs, let's wait up to
- * 100ms before clearing GCTL.CORESOFTRESET.
- */
- msleep(100);
-
- reg = dwc3_readl(dwc->regs, DWC3_GCTL);
- reg &= ~DWC3_GCTL_CORESOFTRESET;
- dwc3_writel(dwc->regs, DWC3_GCTL, reg);
- }
-
- spin_lock_irqsave(&dwc->lock, flags);
-
- dwc3_set_prtcap(dwc, desired_dr_role, false);
-
- spin_unlock_irqrestore(&dwc->lock, flags);
-
- switch (desired_dr_role) {
- case DWC3_GCTL_PRTCAP_HOST:
- ret = dwc3_host_init(dwc);
- if (ret) {
- dev_err(dwc->dev, "failed to initialize host\n");
- } else {
- if (dwc->usb2_phy)
- otg_set_vbus(dwc->usb2_phy->otg, true);
-
- for (i = 0; i < dwc->num_usb2_ports; i++)
- phy_set_mode(dwc->usb2_generic_phy[i], PHY_MODE_USB_HOST);
- for (i = 0; i < dwc->num_usb3_ports; i++)
- phy_set_mode(dwc->usb3_generic_phy[i], PHY_MODE_USB_HOST);
-
- if (dwc->dis_split_quirk) {
- reg = dwc3_readl(dwc->regs, DWC3_GUCTL3);
- reg |= DWC3_GUCTL3_SPLITDISABLE;
- dwc3_writel(dwc->regs, DWC3_GUCTL3, reg);
- }
- }
- break;
- case DWC3_GCTL_PRTCAP_DEVICE:
- dwc3_core_soft_reset(dwc);
-
- dwc3_event_buffers_setup(dwc);
-
- if (dwc->usb2_phy)
- otg_set_vbus(dwc->usb2_phy->otg, false);
- phy_set_mode(dwc->usb2_generic_phy[0], PHY_MODE_USB_DEVICE);
- phy_set_mode(dwc->usb3_generic_phy[0], PHY_MODE_USB_DEVICE);
-
- ret = dwc3_gadget_init(dwc);
- if (ret)
- dev_err(dwc->dev, "failed to initialize peripheral\n");
- break;
- case DWC3_GCTL_PRTCAP_OTG:
- dwc3_otg_init(dwc);
- dwc3_otg_update(dwc, 0);
- break;
- default:
- break;
- }
-
-out:
- pm_runtime_mark_last_busy(dwc->dev);
- pm_runtime_put_autosuspend(dwc->dev);
- mutex_unlock(&dwc->mutex);
-}
-
-void dwc3_set_mode(struct dwc3 *dwc, u32 mode)
-{
- unsigned long flags;
-
- if (dwc->dr_mode != USB_DR_MODE_OTG)
- return;
-
- spin_lock_irqsave(&dwc->lock, flags);
- dwc->desired_dr_role = mode;
- spin_unlock_irqrestore(&dwc->lock, flags);
-
- queue_work(system_freezable_wq, &dwc->drd_work);
-}
-
u32 dwc3_core_fifo_space(struct dwc3_ep *dep, u8 type)
{
struct dwc3 *dwc = dep->dwc;
@@ -474,7 +270,7 @@ static void dwc3_ref_clk_period(struct dwc3 *dwc)
static void dwc3_free_one_event_buffer(struct dwc3 *dwc,
struct dwc3_event_buffer *evt)
{
- dma_free_coherent(dwc->sysdev, evt->length, evt->buf, evt->dma);
+ dma_free_coherent(evt->buf);
}
/**
@@ -490,18 +286,19 @@ static struct dwc3_event_buffer *dwc3_alloc_one_event_buffer(struct dwc3 *dwc,
{
struct dwc3_event_buffer *evt;
- evt = devm_kzalloc(dwc->dev, sizeof(*evt), GFP_KERNEL);
+ evt = devm_kzalloc((struct udevice*)dwc->dev, sizeof(*evt), GFP_KERNEL);
if (!evt)
return ERR_PTR(-ENOMEM);
evt->dwc = dwc;
evt->length = length;
- evt->cache = devm_kzalloc(dwc->dev, length, GFP_KERNEL);
+ evt->cache = devm_kzalloc((struct udevice *)dwc->dev, length,
+ GFP_KERNEL);
if (!evt->cache)
return ERR_PTR(-ENOMEM);
- evt->buf = dma_alloc_coherent(dwc->sysdev, length,
- &evt->dma, GFP_KERNEL);
+ evt->buf = dma_alloc_coherent(length,
+ (unsigned long *)&evt->dma);
if (!evt->buf)
return ERR_PTR(-ENOMEM);
@@ -817,13 +614,13 @@ static int dwc3_phy_init(struct dwc3 *dwc)
usb_phy_init(dwc->usb3_phy);
for (i = 0; i < dwc->num_usb2_ports; i++) {
- ret = phy_init(dwc->usb2_generic_phy[i]);
+ ret = generic_phy_init(dwc->usb2_generic_phy[i]);
if (ret < 0)
goto err_exit_usb2_phy;
}
for (j = 0; j < dwc->num_usb3_ports; j++) {
- ret = phy_init(dwc->usb3_generic_phy[j]);
+ ret = generic_phy_init(dwc->usb3_generic_phy[j]);
if (ret < 0)
goto err_exit_usb3_phy;
}
@@ -851,11 +648,11 @@ static int dwc3_phy_init(struct dwc3 *dwc)
err_exit_usb3_phy:
while (--j >= 0)
- phy_exit(dwc->usb3_generic_phy[j]);
+ generic_phy_exit(dwc->usb3_generic_phy[j]);
err_exit_usb2_phy:
while (--i >= 0)
- phy_exit(dwc->usb2_generic_phy[i]);
+ generic_phy_exit(dwc->usb2_generic_phy[i]);
usb_phy_shutdown(dwc->usb3_phy);
usb_phy_shutdown(dwc->usb2_phy);
@@ -868,10 +665,10 @@ static void dwc3_phy_exit(struct dwc3 *dwc)
int i;
for (i = 0; i < dwc->num_usb3_ports; i++)
- phy_exit(dwc->usb3_generic_phy[i]);
+ generic_phy_exit(dwc->usb3_generic_phy[i]);
for (i = 0; i < dwc->num_usb2_ports; i++)
- phy_exit(dwc->usb2_generic_phy[i]);
+ generic_phy_exit(dwc->usb2_generic_phy[i]);
usb_phy_shutdown(dwc->usb3_phy);
usb_phy_shutdown(dwc->usb2_phy);
@@ -887,13 +684,13 @@ static int dwc3_phy_power_on(struct dwc3 *dwc)
usb_phy_set_suspend(dwc->usb3_phy, 0);
for (i = 0; i < dwc->num_usb2_ports; i++) {
- ret = phy_power_on(dwc->usb2_generic_phy[i]);
+ ret = generic_phy_power_on(dwc->usb2_generic_phy[i]);
if (ret < 0)
goto err_power_off_usb2_phy;
}
for (j = 0; j < dwc->num_usb3_ports; j++) {
- ret = phy_power_on(dwc->usb3_generic_phy[j]);
+ ret = generic_phy_power_on(dwc->usb3_generic_phy[j]);
if (ret < 0)
goto err_power_off_usb3_phy;
}
@@ -902,11 +699,11 @@ static int dwc3_phy_power_on(struct dwc3 *dwc)
err_power_off_usb3_phy:
while (--j >= 0)
- phy_power_off(dwc->usb3_generic_phy[j]);
+ generic_phy_power_off(dwc->usb3_generic_phy[j]);
err_power_off_usb2_phy:
while (--i >= 0)
- phy_power_off(dwc->usb2_generic_phy[i]);
+ generic_phy_power_off(dwc->usb2_generic_phy[i]);
usb_phy_set_suspend(dwc->usb3_phy, 1);
usb_phy_set_suspend(dwc->usb2_phy, 1);
@@ -919,52 +716,15 @@ static void dwc3_phy_power_off(struct dwc3 *dwc)
int i;
for (i = 0; i < dwc->num_usb3_ports; i++)
- phy_power_off(dwc->usb3_generic_phy[i]);
+ generic_phy_power_off(dwc->usb3_generic_phy[i]);
for (i = 0; i < dwc->num_usb2_ports; i++)
- phy_power_off(dwc->usb2_generic_phy[i]);
+ generic_phy_power_off(dwc->usb2_generic_phy[i]);
usb_phy_set_suspend(dwc->usb3_phy, 1);
usb_phy_set_suspend(dwc->usb2_phy, 1);
}
-static int dwc3_clk_enable(struct dwc3 *dwc)
-{
- int ret;
-
- ret = clk_prepare_enable(dwc->bus_clk);
- if (ret)
- return ret;
-
- ret = clk_prepare_enable(dwc->ref_clk);
- if (ret)
- goto disable_bus_clk;
-
- ret = clk_prepare_enable(dwc->susp_clk);
- if (ret)
- goto disable_ref_clk;
-
- ret = clk_prepare_enable(dwc->utmi_clk);
- if (ret)
- goto disable_susp_clk;
-
- ret = clk_prepare_enable(dwc->pipe_clk);
- if (ret)
- goto disable_utmi_clk;
-
- return 0;
-
-disable_utmi_clk:
- clk_disable_unprepare(dwc->utmi_clk);
-disable_susp_clk:
- clk_disable_unprepare(dwc->susp_clk);
-disable_ref_clk:
- clk_disable_unprepare(dwc->ref_clk);
-disable_bus_clk:
- clk_disable_unprepare(dwc->bus_clk);
- return ret;
-}
-
static void dwc3_clk_disable(struct dwc3 *dwc)
{
clk_disable_unprepare(dwc->pipe_clk);
@@ -983,26 +743,6 @@ static void dwc3_core_exit(struct dwc3 *dwc)
reset_control_assert(dwc->reset);
}
-static bool dwc3_core_is_valid(struct dwc3 *dwc)
-{
- u32 reg;
-
- reg = dwc3_readl(dwc->regs, DWC3_GSNPSID);
- dwc->ip = DWC3_GSNPS_ID(reg);
-
- /* This should read as U3 followed by revision number */
- if (DWC3_IP_IS(DWC3)) {
- dwc->revision = reg;
- } else if (DWC3_IP_IS(DWC31) || DWC3_IP_IS(DWC32)) {
- dwc->revision = dwc3_readl(dwc->regs, DWC3_VER_NUMBER);
- dwc->version_type = dwc3_readl(dwc->regs, DWC3_VER_TYPE);
- } else {
- return false;
- }
-
- return true;
-}
-
static void dwc3_core_setup_global_control(struct dwc3 *dwc)
{
unsigned int power_opt;
@@ -1090,13 +830,12 @@ static void dwc3_core_setup_global_control(struct dwc3 *dwc)
dwc3_writel(dwc->regs, DWC3_GCTL, reg);
}
-static int dwc3_core_get_phy(struct dwc3 *dwc);
static int dwc3_core_ulpi_init(struct dwc3 *dwc);
/* set global incr burst type configuration registers */
static void dwc3_set_incr_burst_type(struct dwc3 *dwc)
{
- struct device *dev = dwc->dev;
+ struct udevice *dev = dwc->dev;
/* incrx_mode : for INCR burst type. */
bool incrx_mode;
/* incrx_size : for size of INCRX burst. */
@@ -1337,9 +1076,9 @@ static int dwc3_core_init(struct dwc3 *dwc)
/*
* Write Linux Version Code to our GUID register so it's easy to figure
- * out which kernel version a bug was found.
+ * out which U-Boot version a bug was found.
*/
- dwc3_writel(dwc->regs, DWC3_GUID, LINUX_VERSION_CODE);
+ dwc3_writel(dwc->regs, DWC3_GUID, U_BOOT_VERSION_NUM);
ret = dwc3_phy_setup(dwc);
if (ret)
@@ -1357,13 +1096,6 @@ static int dwc3_core_init(struct dwc3 *dwc)
dwc->ulpi_ready = true;
}
- if (!dwc->phys_ready) {
- ret = dwc3_core_get_phy(dwc);
- if (ret)
- goto err_exit_ulpi;
- dwc->phys_ready = true;
- }
-
ret = dwc3_phy_init(dwc);
if (ret)
goto err_exit_ulpi;
@@ -1528,78 +1260,17 @@ err_exit_ulpi:
return ret;
}
-static int dwc3_core_get_phy(struct dwc3 *dwc)
+int phy_set_mode_ext(struct phy *phy, enum phy_mode mode, int submode)
{
- struct device *dev = dwc->dev;
- struct device_node *node = dev->of_node;
- char phy_name[9];
- int ret;
- u8 i;
-
- if (node) {
- dwc->usb2_phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 0);
- dwc->usb3_phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 1);
- } else {
- dwc->usb2_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2);
- dwc->usb3_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB3);
- }
-
- if (IS_ERR(dwc->usb2_phy)) {
- ret = PTR_ERR(dwc->usb2_phy);
- if (ret == -ENXIO || ret == -ENODEV)
- dwc->usb2_phy = NULL;
- else
- return dev_err_probe(dev, ret, "no usb2 phy configured\n");
- }
-
- if (IS_ERR(dwc->usb3_phy)) {
- ret = PTR_ERR(dwc->usb3_phy);
- if (ret == -ENXIO || ret == -ENODEV)
- dwc->usb3_phy = NULL;
- else
- return dev_err_probe(dev, ret, "no usb3 phy configured\n");
- }
-
- for (i = 0; i < dwc->num_usb2_ports; i++) {
- if (dwc->num_usb2_ports == 1)
- snprintf(phy_name, sizeof(phy_name), "usb2-phy");
- else
- snprintf(phy_name, sizeof(phy_name), "usb2-%u", i);
-
- dwc->usb2_generic_phy[i] = devm_phy_get(dev, phy_name);
- if (IS_ERR(dwc->usb2_generic_phy[i])) {
- ret = PTR_ERR(dwc->usb2_generic_phy[i]);
- if (ret == -ENOSYS || ret == -ENODEV)
- dwc->usb2_generic_phy[i] = NULL;
- else
- return dev_err_probe(dev, ret, "failed to lookup phy %s\n",
- phy_name);
- }
- }
-
- for (i = 0; i < dwc->num_usb3_ports; i++) {
- if (dwc->num_usb3_ports == 1)
- snprintf(phy_name, sizeof(phy_name), "usb3-phy");
- else
- snprintf(phy_name, sizeof(phy_name), "usb3-%u", i);
-
- dwc->usb3_generic_phy[i] = devm_phy_get(dev, phy_name);
- if (IS_ERR(dwc->usb3_generic_phy[i])) {
- ret = PTR_ERR(dwc->usb3_generic_phy[i]);
- if (ret == -ENOSYS || ret == -ENODEV)
- dwc->usb3_generic_phy[i] = NULL;
- else
- return dev_err_probe(dev, ret, "failed to lookup phy %s\n",
- phy_name);
- }
- }
-
- return 0;
+ /* TODO */
+ return -ENOSYS;
}
+#define phy_set_mode(phy, mode) \
+ phy_set_mode_ext(phy, mode, 0)
static int dwc3_core_init_mode(struct dwc3 *dwc)
{
- struct device *dev = dwc->dev;
+ struct udevice *dev = dwc->dev;
int ret;
int i;
@@ -1607,8 +1278,6 @@ static int dwc3_core_init_mode(struct dwc3 *dwc)
case USB_DR_MODE_PERIPHERAL:
dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_DEVICE, false);
- if (dwc->usb2_phy)
- otg_set_vbus(dwc->usb2_phy->otg, false);
phy_set_mode(dwc->usb2_generic_phy[0], PHY_MODE_USB_DEVICE);
phy_set_mode(dwc->usb3_generic_phy[0], PHY_MODE_USB_DEVICE);
@@ -1619,8 +1288,6 @@ static int dwc3_core_init_mode(struct dwc3 *dwc)
case USB_DR_MODE_HOST:
dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_HOST, false);
- if (dwc->usb2_phy)
- otg_set_vbus(dwc->usb2_phy->otg, true);
for (i = 0; i < dwc->num_usb2_ports; i++)
phy_set_mode(dwc->usb2_generic_phy[i], PHY_MODE_USB_HOST);
for (i = 0; i < dwc->num_usb3_ports; i++)
@@ -1644,6 +1311,14 @@ static int dwc3_core_init_mode(struct dwc3 *dwc)
return 0;
}
+static void dwc3_core_stop(struct dwc3 *dwc)
+{
+ u32 reg;
+
+ reg = dwc3_readl(dwc->regs, DWC3_DCTL);
+ dwc3_writel(dwc->regs, DWC3_DCTL, reg & ~(DWC3_DCTL_RUN_STOP));
+}
+
static void dwc3_core_exit_mode(struct dwc3 *dwc)
{
switch (dwc->dr_mode) {
@@ -1665,46 +1340,109 @@ static void dwc3_core_exit_mode(struct dwc3 *dwc)
dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_DEVICE, true);
}
-static void dwc3_get_software_properties(struct dwc3 *dwc)
+#define DWC3_ALIGN_MASK (16 - 1)
+
+
+/* check whether the core supports IMOD */
+bool dwc3_has_imod(struct dwc3 *dwc)
{
- struct device *tmpdev;
- u16 gsbuscfg0_reqinfo;
- int ret;
+ return DWC3_VER_IS_WITHIN(DWC3, 300A, ANY) ||
+ DWC3_VER_IS_WITHIN(DWC31, 120A, ANY) ||
+ DWC3_IP_IS(DWC32);
+}
- dwc->gsbuscfg0_reqinfo = DWC3_GSBUSCFG0_REQINFO_UNSPECIFIED;
+static int dwc3_get_num_ports(struct dwc3 *dwc)
+{
+ void __iomem *base;
+ u8 major_revision;
+ u32 offset;
+ u32 val;
/*
- * Iterate over all parent nodes for finding swnode properties
- * and non-DT (non-ABI) properties.
+ * Remap xHCI address space to access XHCI ext cap regs since it is
+ * needed to get information on number of ports present.
*/
- for (tmpdev = dwc->dev; tmpdev; tmpdev = tmpdev->parent) {
- ret = device_property_read_u16(tmpdev,
- "snps,gsbuscfg0-reqinfo",
- &gsbuscfg0_reqinfo);
- if (!ret)
- dwc->gsbuscfg0_reqinfo = gsbuscfg0_reqinfo;
- }
+ base = ioremap(dwc->xhci_resources[0].start,
+ resource_size(&dwc->xhci_resources[0]));
+ if (!base)
+ return -ENOMEM;
+
+ offset = 0;
+ do {
+ offset = xhci_find_next_ext_cap(base, offset,
+ XHCI_EXT_CAPS_PROTOCOL);
+ if (!offset)
+ break;
+
+ val = readl(base + offset);
+ major_revision = XHCI_EXT_PORT_MAJOR(val);
+
+ val = readl(base + offset + 0x08);
+ if (major_revision == 0x03) {
+ dwc->num_usb3_ports += XHCI_EXT_PORT_COUNT(val);
+ } else if (major_revision <= 0x02) {
+ dwc->num_usb2_ports += XHCI_EXT_PORT_COUNT(val);
+ } else {
+ dev_warn(dwc->dev, "unrecognized port major revision %d\n",
+ major_revision);
+ }
+ } while (1);
+
+ dev_dbg(dwc->dev, "hs-ports: %u ss-ports: %u\n",
+ dwc->num_usb2_ports, dwc->num_usb3_ports);
+
+ iounmap(base);
+
+ if (dwc->num_usb2_ports > DWC3_USB2_MAX_PORTS ||
+ dwc->num_usb3_ports > DWC3_USB3_MAX_PORTS)
+ return -EINVAL;
+
+ return 0;
}
-static void dwc3_get_properties(struct dwc3 *dwc)
+#if CONFIG_IS_ENABLED(PHY) && CONFIG_IS_ENABLED(DM_USB)
+int dwc3_setup_phy(struct udevice *dev, struct phy_bulk *phys)
{
- struct device *dev = dwc->dev;
- u8 lpm_nyet_threshold;
- u8 tx_de_emphasis;
- u8 hird_threshold;
- u8 rx_thr_num_pkt = 0;
- u8 rx_max_burst = 0;
- u8 tx_thr_num_pkt = 0;
- u8 tx_max_burst = 0;
- u8 rx_thr_num_pkt_prd = 0;
- u8 rx_max_burst_prd = 0;
- u8 tx_thr_num_pkt_prd = 0;
- u8 tx_max_burst_prd = 0;
- u8 tx_fifo_resize_max_num;
- u16 num_hc_interrupters;
+ int ret;
+
+ ret = generic_phy_get_bulk(dev, phys);
+ if (ret)
+ return ret;
+
+ ret = generic_phy_init_bulk(phys);
+ if (ret)
+ return ret;
+
+ ret = generic_phy_power_on_bulk(phys);
+ if (ret)
+ generic_phy_exit_bulk(phys);
+
+ return ret;
+}
+
+int dwc3_shutdown_phy(struct udevice *dev, struct phy_bulk *phys)
+{
+ int ret;
+
+ ret = generic_phy_power_off_bulk(phys);
+ ret |= generic_phy_exit_bulk(phys);
+ return ret;
+}
+#endif
+
+#if CONFIG_IS_ENABLED(DM_USB)
+void dwc3_of_parse(struct dwc3 *dwc)
+{
+ const u8 *tmp;
+ struct udevice *dev = dwc->dev;
+ u8 lpm_nyet_threshold;
+ u8 tx_de_emphasis;
+ u8 hird_threshold;
+ u32 val;
+ int i;
/* default to highest possible threshold */
- lpm_nyet_threshold = 0xf;
+ lpm_nyet_threshold = 0xff;
/* default to -3.5dB de-emphasis */
tx_de_emphasis = 1;
@@ -1715,538 +1453,89 @@ static void dwc3_get_properties(struct dwc3 *dwc)
*/
hird_threshold = 12;
- /*
- * default to a TXFIFO size large enough to fit 6 max packets. This
- * allows for systems with larger bus latencies to have some headroom
- * for endpoints that have a large bMaxBurst value.
- */
- tx_fifo_resize_max_num = 6;
-
- /* default to a single XHCI interrupter */
- num_hc_interrupters = 1;
-
- dwc->maximum_speed = usb_get_maximum_speed(dev);
- dwc->max_ssp_rate = usb_get_maximum_ssp_rate(dev);
- dwc->dr_mode = usb_get_dr_mode(dev);
- dwc->hsphy_mode = of_usb_get_phy_mode(dev->of_node);
-
- dwc->sysdev_is_parent = device_property_read_bool(dev,
- "linux,sysdev_is_parent");
- if (dwc->sysdev_is_parent)
- dwc->sysdev = dwc->dev->parent;
- else
- dwc->sysdev = dwc->dev;
-
- dwc->sys_wakeup = device_may_wakeup(dwc->sysdev);
+ dwc->hsphy_mode = usb_get_phy_mode(dev_ofnode(dev));
- dwc->has_lpm_erratum = device_property_read_bool(dev,
+ dwc->has_lpm_erratum = dev_read_bool(dev,
"snps,has-lpm-erratum");
- device_property_read_u8(dev, "snps,lpm-nyet-threshold",
- &lpm_nyet_threshold);
- dwc->is_utmi_l1_suspend = device_property_read_bool(dev,
+ tmp = dev_read_u8_array_ptr(dev, "snps,lpm-nyet-threshold", 1);
+ if (tmp)
+ lpm_nyet_threshold = *tmp;
+
+ dwc->is_utmi_l1_suspend = dev_read_bool(dev,
"snps,is-utmi-l1-suspend");
- device_property_read_u8(dev, "snps,hird-threshold",
- &hird_threshold);
- dwc->dis_start_transfer_quirk = device_property_read_bool(dev,
- "snps,dis-start-transfer-quirk");
- dwc->usb3_lpm_capable = device_property_read_bool(dev,
- "snps,usb3_lpm_capable");
- dwc->usb2_lpm_disable = device_property_read_bool(dev,
- "snps,usb2-lpm-disable");
- dwc->usb2_gadget_lpm_disable = device_property_read_bool(dev,
- "snps,usb2-gadget-lpm-disable");
- device_property_read_u8(dev, "snps,rx-thr-num-pkt",
- &rx_thr_num_pkt);
- device_property_read_u8(dev, "snps,rx-max-burst",
- &rx_max_burst);
- device_property_read_u8(dev, "snps,tx-thr-num-pkt",
- &tx_thr_num_pkt);
- device_property_read_u8(dev, "snps,tx-max-burst",
- &tx_max_burst);
- device_property_read_u8(dev, "snps,rx-thr-num-pkt-prd",
- &rx_thr_num_pkt_prd);
- device_property_read_u8(dev, "snps,rx-max-burst-prd",
- &rx_max_burst_prd);
- device_property_read_u8(dev, "snps,tx-thr-num-pkt-prd",
- &tx_thr_num_pkt_prd);
- device_property_read_u8(dev, "snps,tx-max-burst-prd",
- &tx_max_burst_prd);
- device_property_read_u16(dev, "num-hc-interrupters",
- &num_hc_interrupters);
- /* DWC3 core allowed to have a max of 8 interrupters */
- if (num_hc_interrupters > 8)
- num_hc_interrupters = 8;
-
- dwc->do_fifo_resize = device_property_read_bool(dev,
- "tx-fifo-resize");
- if (dwc->do_fifo_resize)
- device_property_read_u8(dev, "tx-fifo-max-num",
- &tx_fifo_resize_max_num);
-
- dwc->disable_scramble_quirk = device_property_read_bool(dev,
+ tmp = dev_read_u8_array_ptr(dev, "snps,hird-threshold", 1);
+ if (tmp)
+ hird_threshold = *tmp;
+
+ dwc->disable_scramble_quirk = dev_read_bool(dev,
"snps,disable_scramble_quirk");
- dwc->u2exit_lfps_quirk = device_property_read_bool(dev,
+ dwc->u2exit_lfps_quirk = dev_read_bool(dev,
"snps,u2exit_lfps_quirk");
- dwc->u2ss_inp3_quirk = device_property_read_bool(dev,
+ dwc->u2ss_inp3_quirk = dev_read_bool(dev,
"snps,u2ss_inp3_quirk");
- dwc->req_p1p2p3_quirk = device_property_read_bool(dev,
+ dwc->req_p1p2p3_quirk = dev_read_bool(dev,
"snps,req_p1p2p3_quirk");
- dwc->del_p1p2p3_quirk = device_property_read_bool(dev,
+ dwc->del_p1p2p3_quirk = dev_read_bool(dev,
"snps,del_p1p2p3_quirk");
- dwc->del_phy_power_chg_quirk = device_property_read_bool(dev,
+ dwc->del_phy_power_chg_quirk = dev_read_bool(dev,
"snps,del_phy_power_chg_quirk");
- dwc->lfps_filter_quirk = device_property_read_bool(dev,
+ dwc->lfps_filter_quirk = dev_read_bool(dev,
"snps,lfps_filter_quirk");
- dwc->rx_detect_poll_quirk = device_property_read_bool(dev,
+ dwc->rx_detect_poll_quirk = dev_read_bool(dev,
"snps,rx_detect_poll_quirk");
- dwc->dis_u3_susphy_quirk = device_property_read_bool(dev,
+ dwc->dis_u3_susphy_quirk = dev_read_bool(dev,
"snps,dis_u3_susphy_quirk");
- dwc->dis_u2_susphy_quirk = device_property_read_bool(dev,
+ dwc->dis_u2_susphy_quirk = dev_read_bool(dev,
"snps,dis_u2_susphy_quirk");
- dwc->dis_enblslpm_quirk = device_property_read_bool(dev,
- "snps,dis_enblslpm_quirk");
- dwc->dis_u1_entry_quirk = device_property_read_bool(dev,
- "snps,dis-u1-entry-quirk");
- dwc->dis_u2_entry_quirk = device_property_read_bool(dev,
- "snps,dis-u2-entry-quirk");
- dwc->dis_rxdet_inp3_quirk = device_property_read_bool(dev,
- "snps,dis_rxdet_inp3_quirk");
- dwc->dis_u2_freeclk_exists_quirk = device_property_read_bool(dev,
- "snps,dis-u2-freeclk-exists-quirk");
- dwc->dis_del_phy_power_chg_quirk = device_property_read_bool(dev,
+ dwc->dis_del_phy_power_chg_quirk = dev_read_bool(dev,
"snps,dis-del-phy-power-chg-quirk");
- dwc->dis_tx_ipgap_linecheck_quirk = device_property_read_bool(dev,
+ dwc->dis_tx_ipgap_linecheck_quirk = dev_read_bool(dev,
"snps,dis-tx-ipgap-linecheck-quirk");
- dwc->resume_hs_terminations = device_property_read_bool(dev,
- "snps,resume-hs-terminations");
- dwc->ulpi_ext_vbus_drv = device_property_read_bool(dev,
- "snps,ulpi-ext-vbus-drv");
- dwc->parkmode_disable_ss_quirk = device_property_read_bool(dev,
- "snps,parkmode-disable-ss-quirk");
- dwc->parkmode_disable_hs_quirk = device_property_read_bool(dev,
- "snps,parkmode-disable-hs-quirk");
- dwc->gfladj_refclk_lpm_sel = device_property_read_bool(dev,
- "snps,gfladj-refclk-lpm-sel-quirk");
-
- dwc->tx_de_emphasis_quirk = device_property_read_bool(dev,
+ dwc->dis_enblslpm_quirk = dev_read_bool(dev,
+ "snps,dis_enblslpm_quirk");
+ dwc->dis_u2_freeclk_exists_quirk = dev_read_bool(dev,
+ "snps,dis-u2-freeclk-exists-quirk");
+ dwc->tx_de_emphasis_quirk = dev_read_bool(dev,
"snps,tx_de_emphasis_quirk");
- device_property_read_u8(dev, "snps,tx_de_emphasis",
- &tx_de_emphasis);
- device_property_read_string(dev, "snps,hsphy_interface",
- &dwc->hsphy_interface);
- device_property_read_u32(dev, "snps,quirk-frame-length-adjustment",
- &dwc->fladj);
- device_property_read_u32(dev, "snps,ref-clock-period-ns",
- &dwc->ref_clk_per);
-
- dwc->dis_metastability_quirk = device_property_read_bool(dev,
- "snps,dis_metastability_quirk");
-
- dwc->dis_split_quirk = device_property_read_bool(dev,
- "snps,dis-split-quirk");
+ tmp = dev_read_u8_array_ptr(dev, "snps,tx_de_emphasis", 1);
+ if (tmp)
+ tx_de_emphasis = *tmp;
dwc->lpm_nyet_threshold = lpm_nyet_threshold;
dwc->tx_de_emphasis = tx_de_emphasis;
- dwc->hird_threshold = hird_threshold;
-
- dwc->rx_thr_num_pkt = rx_thr_num_pkt;
- dwc->rx_max_burst = rx_max_burst;
-
- dwc->tx_thr_num_pkt = tx_thr_num_pkt;
- dwc->tx_max_burst = tx_max_burst;
-
- dwc->rx_thr_num_pkt_prd = rx_thr_num_pkt_prd;
- dwc->rx_max_burst_prd = rx_max_burst_prd;
-
- dwc->tx_thr_num_pkt_prd = tx_thr_num_pkt_prd;
- dwc->tx_max_burst_prd = tx_max_burst_prd;
-
- dwc->tx_fifo_resize_max_num = tx_fifo_resize_max_num;
-
- dwc->num_hc_interrupters = num_hc_interrupters;
-}
-
-/* check whether the core supports IMOD */
-bool dwc3_has_imod(struct dwc3 *dwc)
-{
- return DWC3_VER_IS_WITHIN(DWC3, 300A, ANY) ||
- DWC3_VER_IS_WITHIN(DWC31, 120A, ANY) ||
- DWC3_IP_IS(DWC32);
-}
+ dwc->hird_threshold = hird_threshold
+ | (dwc->is_utmi_l1_suspend << 4);
-static void dwc3_check_params(struct dwc3 *dwc)
-{
- struct device *dev = dwc->dev;
- unsigned int hwparam_gen =
- DWC3_GHWPARAMS3_SSPHY_IFC(dwc->hwparams.hwparams3);
+ dev_read_u32(dev, "snps,quirk-frame-length-adjustment", &dwc->fladj);
/*
- * Enable IMOD for all supporting controllers.
- *
- * Particularly, DWC_usb3 v3.00a must enable this feature for
- * the following reason:
- *
- * Workaround for STAR 9000961433 which affects only version
- * 3.00a of the DWC_usb3 core. This prevents the controller
- * interrupt from being masked while handling events. IMOD
- * allows us to work around this issue. Enable it for the
- * affected version.
+ * Handle property "snps,incr-burst-type-adjustment".
+ * Get the number of value from this property:
+ * result <= 0, means this property is not supported.
+ * result = 1, means INCRx burst mode supported.
+ * result > 1, means undefined length burst mode supported.
*/
- if (dwc3_has_imod((dwc)))
- dwc->imod_interval = 1;
-
- /* Check the maximum_speed parameter */
- switch (dwc->maximum_speed) {
- case USB_SPEED_FULL:
- case USB_SPEED_HIGH:
- break;
- case USB_SPEED_SUPER:
- if (hwparam_gen == DWC3_GHWPARAMS3_SSPHY_IFC_DIS)
- dev_warn(dev, "UDC doesn't support Gen 1\n");
- break;
- case USB_SPEED_SUPER_PLUS:
- if ((DWC3_IP_IS(DWC32) &&
- hwparam_gen == DWC3_GHWPARAMS3_SSPHY_IFC_DIS) ||
- (!DWC3_IP_IS(DWC32) &&
- hwparam_gen != DWC3_GHWPARAMS3_SSPHY_IFC_GEN2))
- dev_warn(dev, "UDC doesn't support SSP\n");
- break;
- default:
- dev_err(dev, "invalid maximum_speed parameter %d\n",
- dwc->maximum_speed);
- fallthrough;
- case USB_SPEED_UNKNOWN:
- switch (hwparam_gen) {
- case DWC3_GHWPARAMS3_SSPHY_IFC_GEN2:
- dwc->maximum_speed = USB_SPEED_SUPER_PLUS;
- break;
- case DWC3_GHWPARAMS3_SSPHY_IFC_GEN1:
- if (DWC3_IP_IS(DWC32))
- dwc->maximum_speed = USB_SPEED_SUPER_PLUS;
- else
- dwc->maximum_speed = USB_SPEED_SUPER;
- break;
- case DWC3_GHWPARAMS3_SSPHY_IFC_DIS:
- dwc->maximum_speed = USB_SPEED_HIGH;
- break;
- default:
- dwc->maximum_speed = USB_SPEED_SUPER;
+ dwc->incrx_mode = INCRX_BURST_MODE;
+ dwc->incrx_size = 0;
+ for (i = 0; i < 8; i++) {
+ if (dev_read_u32_index(dev, "snps,incr-burst-type-adjustment",
+ i, &val))
break;
- }
- break;
- }
- /*
- * Currently the controller does not have visibility into the HW
- * parameter to determine the maximum number of lanes the HW supports.
- * If the number of lanes is not specified in the device property, then
- * set the default to support dual-lane for DWC_usb32 and single-lane
- * for DWC_usb31 for super-speed-plus.
- */
- if (dwc->maximum_speed == USB_SPEED_SUPER_PLUS) {
- switch (dwc->max_ssp_rate) {
- case USB_SSP_GEN_2x1:
- if (hwparam_gen == DWC3_GHWPARAMS3_SSPHY_IFC_GEN1)
- dev_warn(dev, "UDC only supports Gen 1\n");
- break;
- case USB_SSP_GEN_1x2:
- case USB_SSP_GEN_2x2:
- if (DWC3_IP_IS(DWC31))
- dev_warn(dev, "UDC only supports single lane\n");
- break;
- case USB_SSP_GEN_UNKNOWN:
- default:
- switch (hwparam_gen) {
- case DWC3_GHWPARAMS3_SSPHY_IFC_GEN2:
- if (DWC3_IP_IS(DWC32))
- dwc->max_ssp_rate = USB_SSP_GEN_2x2;
- else
- dwc->max_ssp_rate = USB_SSP_GEN_2x1;
- break;
- case DWC3_GHWPARAMS3_SSPHY_IFC_GEN1:
- if (DWC3_IP_IS(DWC32))
- dwc->max_ssp_rate = USB_SSP_GEN_1x2;
- break;
- }
- break;
- }
+ dwc->incrx_mode = INCRX_UNDEF_LENGTH_BURST_MODE;
+ dwc->incrx_size = max(dwc->incrx_size, val);
}
}
-static struct extcon_dev *dwc3_get_extcon(struct dwc3 *dwc)
-{
- struct device *dev = dwc->dev;
- struct device_node *np_phy;
- struct extcon_dev *edev = NULL;
- const char *name;
-
- if (device_property_present(dev, "extcon"))
- return extcon_get_edev_by_phandle(dev, 0);
-
- /*
- * Device tree platforms should get extcon via phandle.
- * On ACPI platforms, we get the name from a device property.
- * This device property is for kernel internal use only and
- * is expected to be set by the glue code.
- */
- if (device_property_read_string(dev, "linux,extcon-name", &name) == 0)
- return extcon_get_extcon_dev(name);
-
- /*
- * Check explicitly if "usb-role-switch" is used since
- * extcon_find_edev_by_node() can not be used to check the absence of
- * an extcon device. In the absence of an device it will always return
- * EPROBE_DEFER.
- */
- if (IS_ENABLED(CONFIG_USB_ROLE_SWITCH) &&
- device_property_read_bool(dev, "usb-role-switch"))
- return NULL;
-
- /*
- * Try to get an extcon device from the USB PHY controller's "port"
- * node. Check if it has the "port" node first, to avoid printing the
- * error message from underlying code, as it's a valid case: extcon
- * device (and "port" node) may be missing in case of "usb-role-switch"
- * or OTG mode.
- */
- np_phy = of_parse_phandle(dev->of_node, "phys", 0);
- if (of_graph_is_present(np_phy)) {
- struct device_node *np_conn;
-
- np_conn = of_graph_get_remote_node(np_phy, -1, -1);
- if (np_conn)
- edev = extcon_find_edev_by_node(np_conn);
- of_node_put(np_conn);
- }
- of_node_put(np_phy);
-
- return edev;
-}
-
-static int dwc3_get_clocks(struct dwc3 *dwc)
-{
- struct device *dev = dwc->dev;
-
- if (!dev->of_node)
- return 0;
-
- /*
- * Clocks are optional, but new DT platforms should support all clocks
- * as required by the DT-binding.
- * Some devices have different clock names in legacy device trees,
- * check for them to retain backwards compatibility.
- */
- dwc->bus_clk = devm_clk_get_optional(dev, "bus_early");
- if (IS_ERR(dwc->bus_clk)) {
- return dev_err_probe(dev, PTR_ERR(dwc->bus_clk),
- "could not get bus clock\n");
- }
-
- if (dwc->bus_clk == NULL) {
- dwc->bus_clk = devm_clk_get_optional(dev, "bus_clk");
- if (IS_ERR(dwc->bus_clk)) {
- return dev_err_probe(dev, PTR_ERR(dwc->bus_clk),
- "could not get bus clock\n");
- }
- }
-
- dwc->ref_clk = devm_clk_get_optional(dev, "ref");
- if (IS_ERR(dwc->ref_clk)) {
- return dev_err_probe(dev, PTR_ERR(dwc->ref_clk),
- "could not get ref clock\n");
- }
-
- if (dwc->ref_clk == NULL) {
- dwc->ref_clk = devm_clk_get_optional(dev, "ref_clk");
- if (IS_ERR(dwc->ref_clk)) {
- return dev_err_probe(dev, PTR_ERR(dwc->ref_clk),
- "could not get ref clock\n");
- }
- }
-
- dwc->susp_clk = devm_clk_get_optional(dev, "suspend");
- if (IS_ERR(dwc->susp_clk)) {
- return dev_err_probe(dev, PTR_ERR(dwc->susp_clk),
- "could not get suspend clock\n");
- }
-
- if (dwc->susp_clk == NULL) {
- dwc->susp_clk = devm_clk_get_optional(dev, "suspend_clk");
- if (IS_ERR(dwc->susp_clk)) {
- return dev_err_probe(dev, PTR_ERR(dwc->susp_clk),
- "could not get suspend clock\n");
- }
- }
-
- /* specific to Rockchip RK3588 */
- dwc->utmi_clk = devm_clk_get_optional(dev, "utmi");
- if (IS_ERR(dwc->utmi_clk)) {
- return dev_err_probe(dev, PTR_ERR(dwc->utmi_clk),
- "could not get utmi clock\n");
- }
-
- /* specific to Rockchip RK3588 */
- dwc->pipe_clk = devm_clk_get_optional(dev, "pipe");
- if (IS_ERR(dwc->pipe_clk)) {
- return dev_err_probe(dev, PTR_ERR(dwc->pipe_clk),
- "could not get pipe clock\n");
- }
-
- return 0;
-}
-
-static int dwc3_get_num_ports(struct dwc3 *dwc)
-{
- void __iomem *base;
- u8 major_revision;
- u32 offset;
- u32 val;
-
- /*
- * Remap xHCI address space to access XHCI ext cap regs since it is
- * needed to get information on number of ports present.
- */
- base = ioremap(dwc->xhci_resources[0].start,
- resource_size(&dwc->xhci_resources[0]));
- if (!base)
- return -ENOMEM;
-
- offset = 0;
- do {
- offset = xhci_find_next_ext_cap(base, offset,
- XHCI_EXT_CAPS_PROTOCOL);
- if (!offset)
- break;
-
- val = readl(base + offset);
- major_revision = XHCI_EXT_PORT_MAJOR(val);
-
- val = readl(base + offset + 0x08);
- if (major_revision == 0x03) {
- dwc->num_usb3_ports += XHCI_EXT_PORT_COUNT(val);
- } else if (major_revision <= 0x02) {
- dwc->num_usb2_ports += XHCI_EXT_PORT_COUNT(val);
- } else {
- dev_warn(dwc->dev, "unrecognized port major revision %d\n",
- major_revision);
- }
- } while (1);
-
- dev_dbg(dwc->dev, "hs-ports: %u ss-ports: %u\n",
- dwc->num_usb2_ports, dwc->num_usb3_ports);
-
- iounmap(base);
-
- if (dwc->num_usb2_ports > DWC3_USB2_MAX_PORTS ||
- dwc->num_usb3_ports > DWC3_USB3_MAX_PORTS)
- return -EINVAL;
-
- return 0;
-}
-
-static struct power_supply *dwc3_get_usb_power_supply(struct dwc3 *dwc)
+int dwc3_init(struct dwc3 *dwc)
{
- struct power_supply *usb_psy;
- const char *usb_psy_name;
+ unsigned int hw_mode;
int ret;
+ u32 reg;
- ret = device_property_read_string(dwc->dev, "usb-psy-name", &usb_psy_name);
- if (ret < 0)
- return NULL;
-
- usb_psy = power_supply_get_by_name(usb_psy_name);
- if (!usb_psy)
- return ERR_PTR(-EPROBE_DEFER);
-
- return usb_psy;
-}
-
-int dwc3_core_probe(const struct dwc3_probe_data *data)
-{
- struct dwc3 *dwc = data->dwc;
- struct device *dev = dwc->dev;
- struct resource dwc_res;
- unsigned int hw_mode;
- void __iomem *regs;
- struct resource *res = data->res;
- int ret;
-
- dwc->xhci_resources[0].start = res->start;
- dwc->xhci_resources[0].end = dwc->xhci_resources[0].start +
- DWC3_XHCI_REGS_END;
- dwc->xhci_resources[0].flags = res->flags;
- dwc->xhci_resources[0].name = res->name;
-
- /*
- * Request memory region but exclude xHCI regs,
- * since it will be requested by the xhci-plat driver.
- */
- dwc_res = *res;
- dwc_res.start += DWC3_GLOBALS_REGS_START;
-
- if (dev->of_node) {
- struct device_node *parent = of_get_parent(dev->of_node);
-
- if (of_device_is_compatible(parent, "realtek,rtd-dwc3")) {
- dwc_res.start -= DWC3_GLOBALS_REGS_START;
- dwc_res.start += DWC3_RTK_RTD_GLOBALS_REGS_START;
- }
-
- of_node_put(parent);
- }
-
- regs = devm_ioremap_resource(dev, &dwc_res);
- if (IS_ERR(regs))
- return PTR_ERR(regs);
-
- dwc->regs = regs;
- dwc->regs_size = resource_size(&dwc_res);
-
- dwc3_get_properties(dwc);
-
- dwc3_get_software_properties(dwc);
-
- dwc->usb_psy = dwc3_get_usb_power_supply(dwc);
- if (IS_ERR(dwc->usb_psy))
- return dev_err_probe(dev, PTR_ERR(dwc->usb_psy), "couldn't get usb power supply\n");
-
- if (!data->ignore_clocks_and_resets) {
- dwc->reset = devm_reset_control_array_get_optional_shared(dev);
- if (IS_ERR(dwc->reset)) {
- ret = PTR_ERR(dwc->reset);
- goto err_put_psy;
- }
-
- ret = dwc3_get_clocks(dwc);
- if (ret)
- goto err_put_psy;
- }
-
- ret = reset_control_deassert(dwc->reset);
- if (ret)
- goto err_put_psy;
-
- ret = dwc3_clk_enable(dwc);
- if (ret)
- goto err_assert_reset;
-
- if (!dwc3_core_is_valid(dwc)) {
- dev_err(dwc->dev, "this is not a DesignWare USB3 DRD Core\n");
- ret = -ENODEV;
- goto err_disable_clks;
- }
-
- dev_set_drvdata(dev, dwc);
dwc3_cache_hwparams(dwc);
- if (!dwc->sysdev_is_parent &&
- DWC3_GHWPARAMS0_AWIDTH(dwc->hwparams.hwparams0) == 64) {
- ret = dma_set_mask_and_coherent(dwc->sysdev, DMA_BIT_MASK(64));
- if (ret)
- goto err_disable_clks;
- }
-
/*
* Currently only DWC3 controllers that are host-only capable
* can have more than one port.
@@ -2255,7 +1544,7 @@ int dwc3_core_probe(const struct dwc3_probe_data *data)
if (hw_mode == DWC3_GHWPARAMS0_MODE_HOST) {
ret = dwc3_get_num_ports(dwc);
if (ret)
- goto err_disable_clks;
+ return ret;
} else {
dwc->num_usb2_ports = 1;
dwc->num_usb3_ports = 1;
@@ -2264,551 +1553,275 @@ int dwc3_core_probe(const struct dwc3_probe_data *data)
spin_lock_init(&dwc->lock);
mutex_init(&dwc->mutex);
- pm_runtime_get_noresume(dev);
- pm_runtime_set_active(dev);
- pm_runtime_use_autosuspend(dev);
- pm_runtime_set_autosuspend_delay(dev, DWC3_DEFAULT_AUTOSUSPEND_DELAY);
- pm_runtime_enable(dev);
-
- pm_runtime_forbid(dev);
-
ret = dwc3_alloc_event_buffers(dwc, DWC3_EVENT_BUFFERS_SIZE);
if (ret) {
dev_err(dwc->dev, "failed to allocate event buffers\n");
- ret = -ENOMEM;
- goto err_allow_rpm;
- }
-
- dwc->edev = dwc3_get_extcon(dwc);
- if (IS_ERR(dwc->edev)) {
- ret = dev_err_probe(dwc->dev, PTR_ERR(dwc->edev), "failed to get extcon\n");
- goto err_free_event_buffers;
+ return -ENOMEM;
}
- ret = dwc3_get_dr_mode(dwc);
- if (ret)
- goto err_free_event_buffers;
-
ret = dwc3_core_init(dwc);
if (ret) {
- dev_err_probe(dev, ret, "failed to initialize core\n");
- goto err_free_event_buffers;
+ dev_err(dwc->dev, "failed to initialize core\n");
+ goto core_fail;
}
- dwc3_check_params(dwc);
- dwc3_debugfs_init(dwc);
-
- ret = dwc3_core_init_mode(dwc);
- if (ret)
- goto err_exit_debugfs;
-
- pm_runtime_put(dev);
-
- dma_set_max_seg_size(dev, UINT_MAX);
-
- return 0;
+ ret = dwc3_event_buffers_setup(dwc);
+ if (ret) {
+ dev_err(dwc->dev, "failed to setup event buffers\n");
+ goto event_fail;
+ }
-err_exit_debugfs:
- dwc3_debugfs_exit(dwc);
- dwc3_event_buffers_cleanup(dwc);
- dwc3_phy_power_off(dwc);
- dwc3_phy_exit(dwc);
- dwc3_ulpi_exit(dwc);
-err_free_event_buffers:
- dwc3_free_event_buffers(dwc);
-err_allow_rpm:
- pm_runtime_allow(dev);
- pm_runtime_disable(dev);
- pm_runtime_dont_use_autosuspend(dev);
- pm_runtime_set_suspended(dev);
- pm_runtime_put_noidle(dev);
-err_disable_clks:
- dwc3_clk_disable(dwc);
-err_assert_reset:
- reset_control_assert(dwc->reset);
-err_put_psy:
- if (dwc->usb_psy)
- power_supply_put(dwc->usb_psy);
+ if (dwc->revision >= DWC3_REVISION_250A) {
+ reg = dwc3_readl(dwc->regs, DWC3_GUCTL1);
- return ret;
-}
-EXPORT_SYMBOL_GPL(dwc3_core_probe);
+ /*
+ * Enable hardware control of sending remote wakeup
+ * in HS when the device is in the L1 state.
+ */
+ if (dwc->revision >= DWC3_REVISION_290A)
+ reg |= DWC3_GUCTL1_DEV_L1_EXIT_BY_HW;
-static int dwc3_probe(struct platform_device *pdev)
-{
- struct dwc3_probe_data probe_data = {};
- struct resource *res;
- struct dwc3 *dwc;
+ if (dwc->dis_tx_ipgap_linecheck_quirk)
+ reg |= DWC3_GUCTL1_TX_IPGAP_LINECHECK_DIS;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res) {
- dev_err(&pdev->dev, "missing memory resource\n");
- return -ENODEV;
+ dwc3_writel(dwc->regs, DWC3_GUCTL1, reg);
}
- dwc = devm_kzalloc(&pdev->dev, sizeof(*dwc), GFP_KERNEL);
- if (!dwc)
- return -ENOMEM;
+ if (dwc->dr_mode == USB_DR_MODE_HOST ||
+ dwc->dr_mode == USB_DR_MODE_OTG) {
+ reg = dwc3_readl(dwc->regs, DWC3_GUCTL);
- dwc->dev = &pdev->dev;
+ reg |= DWC3_GUCTL_HSTINAUTORETRY;
- probe_data.dwc = dwc;
- probe_data.res = res;
+ dwc3_writel(dwc->regs, DWC3_GUCTL, reg);
+ }
- return dwc3_core_probe(&probe_data);
-}
+ ret = dwc3_core_init_mode(dwc);
+ if (ret)
+ goto mode_fail;
-void dwc3_core_remove(struct dwc3 *dwc)
-{
- pm_runtime_get_sync(dwc->dev);
+ return 0;
- dwc3_core_exit_mode(dwc);
- dwc3_debugfs_exit(dwc);
+mode_fail:
+ dwc3_event_buffers_cleanup(dwc);
+event_fail:
dwc3_core_exit(dwc);
- dwc3_ulpi_exit(dwc);
-
- pm_runtime_allow(dwc->dev);
- pm_runtime_disable(dwc->dev);
- pm_runtime_dont_use_autosuspend(dwc->dev);
- pm_runtime_put_noidle(dwc->dev);
- /*
- * HACK: Clear the driver data, which is currently accessed by parent
- * glue drivers, before allowing the parent to suspend.
- */
- dev_set_drvdata(dwc->dev, NULL);
- pm_runtime_set_suspended(dwc->dev);
+core_fail:
dwc3_free_event_buffers(dwc);
- if (dwc->usb_psy)
- power_supply_put(dwc->usb_psy);
+ return ret;
}
-EXPORT_SYMBOL_GPL(dwc3_core_remove);
-static void dwc3_remove(struct platform_device *pdev)
+void dwc3_remove(struct dwc3 *dwc)
{
- dwc3_core_remove(platform_get_drvdata(pdev));
+ dwc3_core_exit_mode(dwc);
+ dwc3_event_buffers_cleanup(dwc);
+ dwc3_free_event_buffers(dwc);
+ dwc3_core_stop(dwc);
+ dwc3_core_exit(dwc);
}
+#endif
-#ifdef CONFIG_PM
-static int dwc3_core_init_for_resume(struct dwc3 *dwc)
+/**
+ * dwc3_uboot_init - dwc3 core uboot initialization code
+ * @dwc3_dev: struct dwc3_device containing initialization data
+ *
+ * Entry point for dwc3 driver (equivalent to dwc3_probe in linux
+ * kernel driver). Pointer to dwc3_device should be passed containing
+ * base address and other initialization data. Returns '0' on success and
+ * a negative value on failure.
+ *
+ * Generally called from board_usb_init() implemented in board file.
+ */
+int dwc3_uboot_init(struct dwc3_device *dwc3_dev)
{
- int ret;
-
- ret = reset_control_deassert(dwc->reset);
- if (ret)
- return ret;
-
- ret = dwc3_clk_enable(dwc);
- if (ret)
- goto assert_reset;
-
- ret = dwc3_core_init(dwc);
- if (ret)
- goto disable_clks;
-
- return 0;
-
-disable_clks:
- dwc3_clk_disable(dwc);
-assert_reset:
- reset_control_assert(dwc->reset);
-
- return ret;
-}
+ struct dwc3 *dwc;
+ struct device *dev = NULL;
+ u8 lpm_nyet_threshold;
+ u8 tx_de_emphasis;
+ u8 hird_threshold;
-static int dwc3_suspend_common(struct dwc3 *dwc, pm_message_t msg)
-{
- u32 reg;
- int i;
- int ret;
+ int ret;
- if (!pm_runtime_suspended(dwc->dev) && !PMSG_IS_AUTO(msg)) {
- dwc->susphy_state = (dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)) &
- DWC3_GUSB2PHYCFG_SUSPHY) ||
- (dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0)) &
- DWC3_GUSB3PIPECTL_SUSPHY);
- /*
- * TI AM62 platform requires SUSPHY to be
- * enabled for system suspend to work.
- */
- if (!dwc->susphy_state)
- dwc3_enable_susphy(dwc, true);
- }
+ void *mem;
- switch (dwc->current_dr_role) {
- case DWC3_GCTL_PRTCAP_DEVICE:
- if (pm_runtime_suspended(dwc->dev))
- break;
- ret = dwc3_gadget_suspend(dwc);
- if (ret)
- return ret;
- synchronize_irq(dwc->irq_gadget);
- dwc3_core_exit(dwc);
- break;
- case DWC3_GCTL_PRTCAP_HOST:
- if (!PMSG_IS_AUTO(msg) && !device_may_wakeup(dwc->dev)) {
- dwc3_core_exit(dwc);
- break;
- }
+ mem = devm_kzalloc((struct udevice *)dev,
+ sizeof(*dwc) + DWC3_ALIGN_MASK, GFP_KERNEL);
+ if (!mem)
+ return -ENOMEM;
- /* Let controller to suspend HSPHY before PHY driver suspends */
- if (dwc->dis_u2_susphy_quirk ||
- dwc->dis_enblslpm_quirk) {
- for (i = 0; i < dwc->num_usb2_ports; i++) {
- reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(i));
- reg |= DWC3_GUSB2PHYCFG_ENBLSLPM |
- DWC3_GUSB2PHYCFG_SUSPHY;
- dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(i), reg);
- }
+ dwc = PTR_ALIGN(mem, DWC3_ALIGN_MASK + 1);
+ dwc->mem = mem;
- /* Give some time for USB2 PHY to suspend */
- usleep_range(5000, 6000);
- }
-
- for (i = 0; i < dwc->num_usb2_ports; i++)
- phy_pm_runtime_put_sync(dwc->usb2_generic_phy[i]);
- for (i = 0; i < dwc->num_usb3_ports; i++)
- phy_pm_runtime_put_sync(dwc->usb3_generic_phy[i]);
- break;
- case DWC3_GCTL_PRTCAP_OTG:
- /* do nothing during runtime_suspend */
- if (PMSG_IS_AUTO(msg))
- break;
+ dwc->regs = (void *)(uintptr_t)(dwc3_dev->base +
+ DWC3_GLOBALS_REGS_START);
- if (dwc->current_otg_role == DWC3_OTG_ROLE_DEVICE) {
- ret = dwc3_gadget_suspend(dwc);
- if (ret)
- return ret;
- synchronize_irq(dwc->irq_gadget);
- }
+ /* default to highest possible threshold */
+ lpm_nyet_threshold = 0xff;
- dwc3_otg_exit(dwc);
- dwc3_core_exit(dwc);
- break;
- default:
- /* do nothing */
- break;
- }
+ /* default to -3.5dB de-emphasis */
+ tx_de_emphasis = 1;
- return 0;
-}
+ /*
+ * default to assert utmi_sleep_n and use maximum allowed HIRD
+ * threshold value of 0b1100
+ */
+ hird_threshold = 12;
-static int dwc3_resume_common(struct dwc3 *dwc, pm_message_t msg)
-{
- int ret;
- u32 reg;
- int i;
+ dwc->maximum_speed = dwc3_dev->maximum_speed;
+ dwc->has_lpm_erratum = dwc3_dev->has_lpm_erratum;
+ if (dwc3_dev->lpm_nyet_threshold)
+ lpm_nyet_threshold = dwc3_dev->lpm_nyet_threshold;
+ dwc->is_utmi_l1_suspend = dwc3_dev->is_utmi_l1_suspend;
+ if (dwc3_dev->hird_threshold)
+ hird_threshold = dwc3_dev->hird_threshold;
+
+ dwc->do_fifo_resize = dwc3_dev->tx_fifo_resize;
+ dwc->dr_mode = dwc3_dev->dr_mode;
+
+ dwc->disable_scramble_quirk = dwc3_dev->disable_scramble_quirk;
+ dwc->u2exit_lfps_quirk = dwc3_dev->u2exit_lfps_quirk;
+ dwc->u2ss_inp3_quirk = dwc3_dev->u2ss_inp3_quirk;
+ dwc->req_p1p2p3_quirk = dwc3_dev->req_p1p2p3_quirk;
+ dwc->del_p1p2p3_quirk = dwc3_dev->del_p1p2p3_quirk;
+ dwc->del_phy_power_chg_quirk = dwc3_dev->del_phy_power_chg_quirk;
+ dwc->lfps_filter_quirk = dwc3_dev->lfps_filter_quirk;
+ dwc->rx_detect_poll_quirk = dwc3_dev->rx_detect_poll_quirk;
+ dwc->dis_u3_susphy_quirk = dwc3_dev->dis_u3_susphy_quirk;
+ dwc->dis_u2_susphy_quirk = dwc3_dev->dis_u2_susphy_quirk;
+ dwc->dis_del_phy_power_chg_quirk = dwc3_dev->dis_del_phy_power_chg_quirk;
+ dwc->dis_tx_ipgap_linecheck_quirk = dwc3_dev->dis_tx_ipgap_linecheck_quirk;
+ dwc->dis_enblslpm_quirk = dwc3_dev->dis_enblslpm_quirk;
+ dwc->dis_u2_freeclk_exists_quirk = dwc3_dev->dis_u2_freeclk_exists_quirk;
+
+ dwc->tx_de_emphasis_quirk = dwc3_dev->tx_de_emphasis_quirk;
+ if (dwc3_dev->tx_de_emphasis)
+ tx_de_emphasis = dwc3_dev->tx_de_emphasis;
+
+ /* default to superspeed if no maximum_speed passed */
+ if (dwc->maximum_speed == USB_SPEED_UNKNOWN)
+ dwc->maximum_speed = USB_SPEED_SUPER;
- switch (dwc->current_dr_role) {
- case DWC3_GCTL_PRTCAP_DEVICE:
- ret = dwc3_core_init_for_resume(dwc);
- if (ret)
- return ret;
+ dwc->lpm_nyet_threshold = lpm_nyet_threshold;
+ dwc->tx_de_emphasis = tx_de_emphasis;
- dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_DEVICE, true);
- dwc3_gadget_resume(dwc);
- break;
- case DWC3_GCTL_PRTCAP_HOST:
- if (!PMSG_IS_AUTO(msg) && !device_may_wakeup(dwc->dev)) {
- ret = dwc3_core_init_for_resume(dwc);
- if (ret)
- return ret;
- dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_HOST, true);
- break;
- }
- /* Restore GUSB2PHYCFG bits that were modified in suspend */
- for (i = 0; i < dwc->num_usb2_ports; i++) {
- reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(i));
- if (dwc->dis_u2_susphy_quirk)
- reg &= ~DWC3_GUSB2PHYCFG_SUSPHY;
+ dwc->hird_threshold = hird_threshold
+ | (dwc->is_utmi_l1_suspend << 4);
- if (dwc->dis_enblslpm_quirk)
- reg &= ~DWC3_GUSB2PHYCFG_ENBLSLPM;
+ dwc->hsphy_mode = dwc3_dev->hsphy_mode;
- dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(i), reg);
- }
+ dwc->index = dwc3_dev->index;
- for (i = 0; i < dwc->num_usb2_ports; i++)
- phy_pm_runtime_get_sync(dwc->usb2_generic_phy[i]);
- for (i = 0; i < dwc->num_usb3_ports; i++)
- phy_pm_runtime_get_sync(dwc->usb3_generic_phy[i]);
- break;
- case DWC3_GCTL_PRTCAP_OTG:
- /* nothing to do on runtime_resume */
- if (PMSG_IS_AUTO(msg))
- break;
+ dwc3_cache_hwparams(dwc);
- ret = dwc3_core_init_for_resume(dwc);
- if (ret)
- return ret;
+ ret = dwc3_alloc_event_buffers(dwc, DWC3_EVENT_BUFFERS_SIZE);
+ if (ret) {
+ dev_err(dwc->dev, "failed to allocate event buffers\n");
+ return -ENOMEM;
+ }
- dwc3_set_prtcap(dwc, dwc->current_dr_role, true);
+ if (!IS_ENABLED(CONFIG_USB_DWC3_GADGET))
+ dwc->dr_mode = USB_DR_MODE_HOST;
+ else if (!IS_ENABLED(CONFIG_USB_HOST))
+ dwc->dr_mode = USB_DR_MODE_PERIPHERAL;
- dwc3_otg_init(dwc);
- if (dwc->current_otg_role == DWC3_OTG_ROLE_HOST) {
- dwc3_otg_host_init(dwc);
- } else if (dwc->current_otg_role == DWC3_OTG_ROLE_DEVICE) {
- dwc3_gadget_resume(dwc);
- }
+ if (dwc->dr_mode == USB_DR_MODE_UNKNOWN)
+ dwc->dr_mode = USB_DR_MODE_OTG;
- break;
- default:
- /* do nothing */
- break;
+ ret = dwc3_core_init(dwc);
+ if (ret) {
+ dev_err(dwc->dev, "failed to initialize core\n");
+ goto err0;
}
- if (!PMSG_IS_AUTO(msg)) {
- /* restore SUSPHY state to that before system suspend. */
- dwc3_enable_susphy(dwc, dwc->susphy_state);
+ ret = dwc3_event_buffers_setup(dwc);
+ if (ret) {
+ dev_err(dwc->dev, "failed to setup event buffers\n");
+ goto err1;
}
- return 0;
-}
+ ret = dwc3_core_init_mode(dwc);
+ if (ret)
+ goto err2;
-static int dwc3_runtime_checks(struct dwc3 *dwc)
-{
- switch (dwc->current_dr_role) {
- case DWC3_GCTL_PRTCAP_DEVICE:
- if (dwc->connected)
- return -EBUSY;
- break;
- case DWC3_GCTL_PRTCAP_HOST:
- default:
- /* do nothing */
- break;
- }
+ list_add_tail(&dwc->list, &dwc3_list);
return 0;
-}
-int dwc3_runtime_suspend(struct dwc3 *dwc)
-{
- int ret;
+err2:
+ dwc3_event_buffers_cleanup(dwc);
- if (dwc3_runtime_checks(dwc))
- return -EBUSY;
+err1:
+ dwc3_core_exit(dwc);
- ret = dwc3_suspend_common(dwc, PMSG_AUTO_SUSPEND);
- if (ret)
- return ret;
+err0:
+ dwc3_free_event_buffers(dwc);
- return 0;
+ return ret;
}
-EXPORT_SYMBOL_GPL(dwc3_runtime_suspend);
-int dwc3_runtime_resume(struct dwc3 *dwc)
+/**
+ * dwc3_uboot_exit - dwc3 core uboot cleanup code
+ * @index: index of this controller
+ *
+ * Performs cleanup of memory allocated in dwc3_uboot_init and other misc
+ * cleanups (equivalent to dwc3_remove in linux). index of _this_ controller
+ * should be passed and should match with the index passed in
+ * dwc3_device during init.
+ *
+ * Generally called from board file.
+ */
+void dwc3_uboot_exit(int index)
{
- struct device *dev = dwc->dev;
- int ret;
-
- ret = dwc3_resume_common(dwc, PMSG_AUTO_RESUME);
- if (ret)
- return ret;
-
- switch (dwc->current_dr_role) {
- case DWC3_GCTL_PRTCAP_DEVICE:
- if (dwc->pending_events) {
- pm_runtime_put(dev);
- dwc->pending_events = false;
- enable_irq(dwc->irq_gadget);
- }
- break;
- case DWC3_GCTL_PRTCAP_HOST:
- default:
- /* do nothing */
- break;
- }
-
- pm_runtime_mark_last_busy(dev);
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(dwc3_runtime_resume);
+ struct dwc3 *dwc;
-int dwc3_runtime_idle(struct dwc3 *dwc)
-{
- struct device *dev = dwc->dev;
+ list_for_each_entry(dwc, &dwc3_list, list) {
+ if (dwc->index != index)
+ continue;
- switch (dwc->current_dr_role) {
- case DWC3_GCTL_PRTCAP_DEVICE:
- if (dwc3_runtime_checks(dwc))
- return -EBUSY;
- break;
- case DWC3_GCTL_PRTCAP_HOST:
- default:
- /* do nothing */
+ dwc3_core_exit_mode(dwc);
+ dwc3_event_buffers_cleanup(dwc);
+ dwc3_free_event_buffers(dwc);
+ dwc3_core_exit(dwc);
+ list_del(&dwc->list);
+ kfree(dwc->mem);
break;
}
-
- pm_runtime_mark_last_busy(dev);
- pm_runtime_autosuspend(dev);
-
- return 0;
}
-EXPORT_SYMBOL_GPL(dwc3_runtime_idle);
-static int dwc3_plat_runtime_suspend(struct device *dev)
-{
- return dwc3_runtime_suspend(dev_get_drvdata(dev));
-}
-static int dwc3_plat_runtime_resume(struct device *dev)
+#if !CONFIG_IS_ENABLED(DM_USB_GADGET)
+__weak int dwc3_uboot_interrupt_status(struct udevice *dev)
{
- return dwc3_runtime_resume(dev_get_drvdata(dev));
+ return 1;
}
-static int dwc3_plat_runtime_idle(struct device *dev)
-{
- return dwc3_runtime_idle(dev_get_drvdata(dev));
-}
-#endif /* CONFIG_PM */
-
-#ifdef CONFIG_PM_SLEEP
-int dwc3_pm_suspend(struct dwc3 *dwc)
-{
- struct device *dev = dwc->dev;
- int ret;
-
- ret = dwc3_suspend_common(dwc, PMSG_SUSPEND);
- if (ret)
- return ret;
-
- pinctrl_pm_select_sleep_state(dev);
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(dwc3_pm_suspend);
-
-int dwc3_pm_resume(struct dwc3 *dwc)
+/**
+ * dm_usb_gadget_handle_interrupts - handle dwc3 core interrupt
+ * @dev: device of this controller
+ *
+ * Invokes dwc3 gadget interrupts.
+ *
+ * Generally called from board file.
+ */
+int dm_usb_gadget_handle_interrupts(struct udevice *dev)
{
- struct device *dev = dwc->dev;
- int ret = 0;
-
- pinctrl_pm_select_default_state(dev);
-
- pm_runtime_disable(dev);
- ret = pm_runtime_set_active(dev);
- if (ret)
- goto out;
-
- ret = dwc3_resume_common(dwc, PMSG_RESUME);
- if (ret)
- pm_runtime_set_suspended(dev);
+ struct dwc3 *dwc = NULL;
-out:
- pm_runtime_enable(dev);
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(dwc3_pm_resume);
+ if (!dwc3_uboot_interrupt_status(dev))
+ return 0;
-void dwc3_pm_complete(struct dwc3 *dwc)
-{
- u32 reg;
+ list_for_each_entry(dwc, &dwc3_list, list) {
+ if (dwc->dev != dev)
+ continue;
- if (dwc->current_dr_role == DWC3_GCTL_PRTCAP_HOST &&
- dwc->dis_split_quirk) {
- reg = dwc3_readl(dwc->regs, DWC3_GUCTL3);
- reg |= DWC3_GUCTL3_SPLITDISABLE;
- dwc3_writel(dwc->regs, DWC3_GUCTL3, reg);
+ dwc3_gadget_uboot_handle_interrupt(dwc);
+ break;
}
-}
-EXPORT_SYMBOL_GPL(dwc3_pm_complete);
-
-int dwc3_pm_prepare(struct dwc3 *dwc)
-{
- struct device *dev = dwc->dev;
-
- /*
- * Indicate to the PM core that it may safely leave the device in
- * runtime suspend if runtime-suspended already in device mode.
- */
- if (dwc->current_dr_role == DWC3_GCTL_PRTCAP_DEVICE &&
- pm_runtime_suspended(dev) &&
- !dev_pinctrl(dev))
- return 1;
return 0;
}
-EXPORT_SYMBOL_GPL(dwc3_pm_prepare);
-
-static int dwc3_plat_suspend(struct device *dev)
-{
- return dwc3_pm_suspend(dev_get_drvdata(dev));
-}
-
-static int dwc3_plat_resume(struct device *dev)
-{
- return dwc3_pm_resume(dev_get_drvdata(dev));
-}
-
-static void dwc3_plat_complete(struct device *dev)
-{
- dwc3_pm_complete(dev_get_drvdata(dev));
-}
-
-static int dwc3_plat_prepare(struct device *dev)
-{
- return dwc3_pm_prepare(dev_get_drvdata(dev));
-}
-#else
-#define dwc3_plat_complete NULL
-#define dwc3_plat_prepare NULL
-#endif /* CONFIG_PM_SLEEP */
-
-static const struct dev_pm_ops dwc3_dev_pm_ops = {
- SET_SYSTEM_SLEEP_PM_OPS(dwc3_plat_suspend, dwc3_plat_resume)
- .complete = dwc3_plat_complete,
- .prepare = dwc3_plat_prepare,
- /*
- * Runtime suspend halts the controller on disconnection. It relies on
- * platforms with custom connection notification to start the controller
- * again.
- */
- SET_RUNTIME_PM_OPS(dwc3_plat_runtime_suspend, dwc3_plat_runtime_resume,
- dwc3_plat_runtime_idle)
-};
-
-#ifdef CONFIG_OF
-static const struct of_device_id of_dwc3_match[] = {
- {
- .compatible = "snps,dwc3"
- },
- {
- .compatible = "synopsys,dwc3"
- },
- { },
-};
-MODULE_DEVICE_TABLE(of, of_dwc3_match);
-#endif
-
-#ifdef CONFIG_ACPI
-
-#define ACPI_ID_INTEL_BSW "808622B7"
-
-static const struct acpi_device_id dwc3_acpi_match[] = {
- { ACPI_ID_INTEL_BSW, 0 },
- { },
-};
-MODULE_DEVICE_TABLE(acpi, dwc3_acpi_match);
#endif
-static struct platform_driver dwc3_driver = {
- .probe = dwc3_probe,
- .remove = dwc3_remove,
- .driver = {
- .name = "dwc3",
- .of_match_table = of_match_ptr(of_dwc3_match),
- .acpi_match_table = ACPI_PTR(dwc3_acpi_match),
- .pm = &dwc3_dev_pm_ops,
- },
-};
-
-module_platform_driver(dwc3_driver);
-
-MODULE_ALIAS("platform:dwc3");
-MODULE_AUTHOR("Felipe Balbi <balbi@ti.com>");
-MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("DesignWare USB3 DRD Controller Driver");
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index d5b985fa12f4..1b9fca02b4cf 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -11,27 +11,13 @@
#ifndef __DRIVERS_USB_DWC3_CORE_H
#define __DRIVERS_USB_DWC3_CORE_H
-#include <linux/device.h>
-#include <linux/spinlock.h>
-#include <linux/mutex.h>
#include <linux/ioport.h>
-#include <linux/list.h>
#include <linux/bitops.h>
-#include <linux/dma-mapping.h>
-#include <linux/mm.h>
-#include <linux/debugfs.h>
-#include <linux/wait.h>
-#include <linux/workqueue.h>
#include <linux/usb/ch9.h>
#include <linux/usb/gadget.h>
#include <linux/usb/otg.h>
-#include <linux/usb/role.h>
-#include <linux/ulpi/interface.h>
-
-#include <linux/phy/phy.h>
-
-#include <linux/power_supply.h>
+#include <linux/usb/phy.h>
/*
* DWC3 Multiport controllers support up to 15 High-Speed PHYs
@@ -418,6 +404,7 @@
/* Global User Control Register*/
#define DWC3_GUCTL_REFCLKPER_MASK 0xffc00000
#define DWC3_GUCTL_REFCLKPER_SEL 22
+#define DWC3_GUCTL_HSTINAUTORETRY BIT(14)
/* Global User Control Register 2 */
#define DWC3_GUCTL2_RST_ACTBITLATER BIT(14)
@@ -744,7 +731,6 @@ struct dwc3_event_buffer {
*/
struct dwc3_ep {
struct usb_ep endpoint;
- struct delayed_work nostream_work;
struct list_head cancelled_list;
struct list_head pending_list;
struct list_head started_list;
@@ -1177,7 +1163,6 @@ struct dwc3 {
dma_addr_t ep0_trb_addr;
dma_addr_t bounce_addr;
struct dwc3_request ep0_usb_req;
- struct completion ep0_in_setup;
/* device lock */
spinlock_t lock;
@@ -1185,8 +1170,11 @@ struct dwc3 {
/* mode switching lock */
struct mutex mutex;
+#if defined(__UBOOT__) && CONFIG_IS_ENABLED(DM_USB)
+ struct udevice *dev;
+#else
struct device *dev;
- struct device *sysdev;
+#endif
struct platform_device *xhci;
struct resource xhci_resources[DWC3_XHCI_RESOURCES_NUM];
@@ -1194,7 +1182,7 @@ struct dwc3 {
struct dwc3_event_buffer *ev_buf;
struct dwc3_ep *eps[DWC3_ENDPOINTS_NUM];
- struct usb_gadget *gadget;
+ struct usb_gadget gadget;
struct usb_gadget_driver *gadget_driver;
struct clk *bus_clk;
@@ -1231,9 +1219,9 @@ struct dwc3 {
struct usb_role_switch *role_sw;
enum usb_dr_mode role_switch_default_mode;
- struct power_supply *usb_psy;
-
u32 fladj;
+ u8 incrx_mode;
+ u32 incrx_size;
u32 ref_clk_per;
u32 irq_gadget;
u32 otg_irq;
@@ -1315,6 +1303,8 @@ struct dwc3 {
u8 num_eps;
+ void *mem;
+
struct dwc3_hwparams hwparams;
struct debugfs_regset32 *regset;
@@ -1400,6 +1390,9 @@ struct dwc3 {
struct dentry *debug_root;
u32 gsbuscfg0_reqinfo;
u32 wakeup_pending_funcs;
+
+ int index;
+ struct list_head list;
};
#define INCRX_BURST_MODE 0
@@ -1565,8 +1558,10 @@ struct dwc3_gadget_ep_cmd_params {
/* prototypes */
void dwc3_set_prtcap(struct dwc3 *dwc, u32 mode, bool ignore_susphy);
-void dwc3_set_mode(struct dwc3 *dwc, u32 mode);
u32 dwc3_core_fifo_space(struct dwc3_ep *dep, u8 type);
+void dwc3_of_parse(struct dwc3 *dwc);
+int dwc3_init(struct dwc3 *dwc);
+void dwc3_remove(struct dwc3 *dwc);
#define DWC3_IP_IS(_ip) \
(dwc->ip == _ip##_IP)
diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c
index 4b219c35eb35..9de8ecff3adc 100644
--- a/drivers/usb/dwc3/dwc3-omap.c
+++ b/drivers/usb/dwc3/dwc3-omap.c
@@ -25,8 +25,6 @@
#include <linux/usb/otg.h>
#include <linux/compat.h>
-#include "linux-compat.h"
-
/*
* All these registers belong to OMAP's Wrapper around the
* DesignWare USB3 Core.
diff --git a/drivers/usb/dwc3/io.h b/drivers/usb/dwc3/io.h
index 1e96ea339d48..8bb0d891226c 100644
--- a/drivers/usb/dwc3/io.h
+++ b/drivers/usb/dwc3/io.h
@@ -11,10 +11,10 @@
#ifndef __DRIVERS_USB_DWC3_IO_H
#define __DRIVERS_USB_DWC3_IO_H
-#include <linux/io.h>
-#include "trace.h"
-#include "debug.h"
-#include "core.h"
+#include <asm/io.h>
+#include <cpu_func.h>
+
+#define CACHELINE_SIZE CONFIG_SYS_CACHELINE_SIZE
static inline u32 dwc3_readl(void __iomem *base, u32 offset)
{
@@ -27,13 +27,6 @@ static inline u32 dwc3_readl(void __iomem *base, u32 offset)
*/
value = readl(base + offset - DWC3_GLOBALS_REGS_START);
- /*
- * When tracing we want to make it easy to find the correct address on
- * documentation, so we revert it back to the proper addresses, the
- * same way they are described on SNPS documentation
- */
- trace_dwc3_readl(base - DWC3_GLOBALS_REGS_START, offset, value);
-
return value;
}
@@ -45,13 +38,14 @@ static inline void dwc3_writel(void __iomem *base, u32 offset, u32 value)
* However, the offsets are given starting from xHCI address space.
*/
writel(value, base + offset - DWC3_GLOBALS_REGS_START);
+}
- /*
- * When tracing we want to make it easy to find the correct address on
- * documentation, so we revert it back to the proper addresses, the
- * same way they are described on SNPS documentation
- */
- trace_dwc3_writel(base - DWC3_GLOBALS_REGS_START, offset, value);
+static inline void dwc3_flush_cache(uintptr_t addr, int length)
+{
+ uintptr_t start_addr = (uintptr_t)addr & ~(CACHELINE_SIZE - 1);
+ uintptr_t end_addr = ALIGN((uintptr_t)addr + length, CACHELINE_SIZE);
+
+ flush_dcache_range((unsigned long)start_addr, (unsigned long)end_addr);
}
#endif /* __DRIVERS_USB_DWC3_IO_H */
diff --git a/drivers/usb/dwc3/ti_usb_phy.c b/drivers/usb/dwc3/ti_usb_phy.c
index f0ecdea958ae..f1ddc0086945 100644
--- a/drivers/usb/dwc3/ti_usb_phy.c
+++ b/drivers/usb/dwc3/ti_usb_phy.c
@@ -27,8 +27,6 @@
#include <asm/arch/sys_proto.h>
#include <dm.h>
-#include "linux-compat.h"
-
#define PLL_STATUS 0x00000004
#define PLL_GO 0x00000008
#define PLL_CONFIGURATION1 0x0000000C
--
2.53.0
next prev parent reply other threads:[~2026-07-16 16:20 UTC|newest]
Thread overview: 77+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-16 13:41 [PATCH v5 00/75] usb: dwc3: sync code with Linux v6.16 Anders Roxell
2026-07-16 13:41 ` [PATCH v5 01/75] usb: dwc3: restore to original v3.19-rc1 kernel import Anders Roxell
2026-07-16 13:41 ` [PATCH v5 02/75] usb: dwc3: import from kernel v3.19 Anders Roxell
2026-07-16 13:41 ` [PATCH v5 03/75] usb: dwc3: import from kernel v4.0 Anders Roxell
2026-07-16 13:41 ` [PATCH v5 04/75] usb: dwc3: import from kernel v4.1 Anders Roxell
2026-07-16 13:41 ` [PATCH v5 05/75] usb: dwc3: import from kernel v4.2 Anders Roxell
2026-07-16 13:41 ` [PATCH v5 06/75] usb: dwc3: import from kernel v4.3 Anders Roxell
2026-07-16 13:41 ` [PATCH v5 07/75] usb: dwc3: import from kernel v4.4 Anders Roxell
2026-07-16 13:41 ` [PATCH v5 08/75] usb: dwc3: import from kernel v4.5 Anders Roxell
2026-07-16 13:41 ` [PATCH v5 09/75] usb: dwc3: import from kernel v4.6 Anders Roxell
2026-07-16 13:41 ` [PATCH v5 10/75] usb: dwc3: import from kernel v4.7 Anders Roxell
2026-07-16 13:41 ` [PATCH v5 11/75] usb: dwc3: import from kernel v4.8 Anders Roxell
2026-07-16 13:41 ` [PATCH v5 12/75] usb: dwc3: import from kernel v4.9 Anders Roxell
2026-07-16 13:41 ` [PATCH v5 13/75] usb: dwc3: import from kernel v4.10 Anders Roxell
2026-07-16 13:41 ` [PATCH v5 14/75] usb: dwc3: import from kernel v4.11 Anders Roxell
2026-07-16 13:41 ` [PATCH v5 15/75] usb: dwc3: import from kernel v4.12 Anders Roxell
2026-07-16 13:41 ` [PATCH v5 16/75] usb: dwc3: import from kernel v4.13 Anders Roxell
2026-07-16 13:41 ` [PATCH v5 17/75] usb: dwc3: import from kernel v4.14 Anders Roxell
2026-07-16 13:41 ` [PATCH v5 18/75] usb: dwc3: import from kernel v4.15 Anders Roxell
2026-07-16 13:41 ` [PATCH v5 19/75] usb: dwc3: import from kernel v4.16 Anders Roxell
2026-07-16 13:41 ` [PATCH v5 20/75] usb: dwc3: import from kernel v4.17 Anders Roxell
2026-07-16 13:41 ` [PATCH v5 21/75] usb: dwc3: import from kernel v4.18 Anders Roxell
2026-07-16 13:41 ` [PATCH v5 22/75] usb: dwc3: import from kernel v4.19 Anders Roxell
2026-07-16 13:41 ` [PATCH v5 23/75] usb: dwc3: import from kernel v4.20 Anders Roxell
2026-07-16 13:41 ` [PATCH v5 24/75] usb: dwc3: import from kernel v5.0 Anders Roxell
2026-07-16 13:41 ` [PATCH v5 25/75] usb: dwc3: import from kernel v5.1 Anders Roxell
2026-07-16 13:41 ` [PATCH v5 26/75] usb: dwc3: import from kernel v5.2 Anders Roxell
2026-07-16 13:41 ` [PATCH v5 27/75] usb: dwc3: import from kernel v5.3 Anders Roxell
2026-07-16 13:41 ` [PATCH v5 28/75] usb: dwc3: import from kernel v5.4 Anders Roxell
2026-07-16 13:41 ` [PATCH v5 29/75] usb: dwc3: import from kernel v5.5 Anders Roxell
2026-07-16 13:42 ` [PATCH v5 30/75] usb: dwc3: import from kernel v5.6 Anders Roxell
2026-07-16 13:42 ` [PATCH v5 31/75] usb: dwc3: import from kernel v5.7 Anders Roxell
2026-07-16 13:42 ` [PATCH v5 32/75] usb: dwc3: import from kernel v5.8 Anders Roxell
2026-07-16 13:42 ` [PATCH v5 33/75] usb: dwc3: import from kernel v5.9 Anders Roxell
2026-07-16 13:42 ` [PATCH v5 34/75] usb: dwc3: import from kernel v5.10 Anders Roxell
2026-07-16 13:42 ` [PATCH v5 35/75] usb: dwc3: import from kernel v5.11 Anders Roxell
2026-07-16 13:42 ` [PATCH v5 36/75] usb: dwc3: import from kernel v5.12 Anders Roxell
2026-07-16 13:42 ` [PATCH v5 37/75] usb: dwc3: import from kernel v5.13 Anders Roxell
2026-07-16 13:42 ` [PATCH v5 38/75] usb: dwc3: import from kernel v5.14 Anders Roxell
2026-07-16 13:42 ` [PATCH v5 39/75] usb: dwc3: import from kernel v5.15 Anders Roxell
2026-07-16 13:42 ` [PATCH v5 40/75] usb: dwc3: import from kernel v5.16 Anders Roxell
2026-07-16 13:42 ` [PATCH v5 41/75] usb: dwc3: import from kernel v5.17 Anders Roxell
2026-07-16 13:42 ` [PATCH v5 42/75] usb: dwc3: import from kernel v5.18 Anders Roxell
2026-07-16 13:42 ` [PATCH v5 43/75] usb: dwc3: import from kernel v5.19 Anders Roxell
2026-07-16 13:42 ` [PATCH v5 44/75] usb: dwc3: import from kernel v6.0 Anders Roxell
2026-07-16 13:42 ` [PATCH v5 45/75] usb: dwc3: import from kernel v6.1 Anders Roxell
2026-07-16 13:42 ` [PATCH v5 46/75] usb: dwc3: import from kernel v6.2 Anders Roxell
2026-07-16 13:42 ` [PATCH v5 47/75] usb: dwc3: import from kernel v6.3 Anders Roxell
2026-07-16 13:42 ` [PATCH v5 48/75] usb: dwc3: import from kernel v6.4 Anders Roxell
2026-07-16 13:42 ` [PATCH v5 49/75] usb: dwc3: import from kernel v6.5 Anders Roxell
2026-07-16 13:42 ` [PATCH v5 50/75] usb: dwc3: import from kernel v6.6 Anders Roxell
2026-07-16 13:42 ` [PATCH v5 51/75] usb: dwc3: import from kernel v6.7 Anders Roxell
2026-07-16 13:42 ` [PATCH v5 52/75] usb: dwc3: import from kernel v6.8 Anders Roxell
2026-07-16 13:42 ` [PATCH v5 53/75] usb: dwc3: import from kernel v6.9 Anders Roxell
2026-07-16 13:42 ` [PATCH v5 54/75] usb: dwc3: import from kernel v6.10 Anders Roxell
2026-07-16 13:42 ` [PATCH v5 55/75] usb: dwc3: import from kernel v6.11 Anders Roxell
2026-07-16 13:42 ` [PATCH v5 56/75] usb: dwc3: import from kernel v6.12 Anders Roxell
2026-07-16 13:42 ` [PATCH v5 57/75] usb: dwc3: import from kernel v6.13 Anders Roxell
2026-07-16 13:42 ` [PATCH v5 58/75] usb: dwc3: import from kernel v6.14 Anders Roxell
2026-07-16 13:42 ` [PATCH v5 59/75] usb: dwc3: import from kernel v6.15 Anders Roxell
2026-07-16 13:42 ` [PATCH v5 60/75] usb: dwc3: import from kernel v6.16 Anders Roxell
2026-07-16 13:42 ` [PATCH v5 61/75] usb: host: re-import xhci-ext-caps.h " Anders Roxell
2026-07-16 13:42 ` [PATCH v5 62/75] usb: gadget: re-import epautoconf.c " Anders Roxell
2026-07-16 13:42 ` [PATCH v5 63/75] usb: udc: re-import udc-core.c " Anders Roxell
2026-07-16 13:42 ` [PATCH v5 64/75] usb: add helpers needed by the resynced DWC3 code Anders Roxell
2026-07-16 13:42 ` [PATCH v5 65/75] usb: gadget: trim the gadget API after the resync Anders Roxell
2026-07-16 13:42 ` [PATCH v5 66/75] usb: gadget: udc: make udc-core build in u-boot Anders Roxell
2026-07-16 13:42 ` Anders Roxell [this message]
2026-07-16 13:42 ` [PATCH v5 68/75] usb: dwc3: make gadget and ep0 " Anders Roxell
2026-07-16 13:42 ` [PATCH v5 69/75] usb: dwc3: make the am62 glue " Anders Roxell
2026-07-16 13:42 ` [PATCH v5 70/75] usb: gadget: ci_udc: drop code we do not use Anders Roxell
2026-07-16 13:42 ` [PATCH v5 71/75] usb: gadget: dwc2_udc_otg: fix up after the resync Anders Roxell
2026-07-16 13:42 ` [PATCH v5 72/75] usb: gadget: fix up the function drivers " Anders Roxell
2026-07-16 13:42 ` [PATCH v5 73/75] usb: gadget: fix up the last UDC " Anders Roxell
2026-07-16 13:42 ` [PATCH v5 74/75] usb: fix up musb-new and mtu3 " Anders Roxell
2026-07-16 13:42 ` [PATCH v5 75/75] usb: host: fix up xhci and cdns3 " Anders Roxell
2026-07-16 19:22 ` [PATCH v5 00/75] usb: dwc3: sync code with Linux v6.16 Marek Vasut
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260716134305.614278-68-anders.roxell@linaro.org \
--to=anders.roxell@linaro.org \
--cc=alchark@flipper.net \
--cc=ilias.apalodimas@linaro.org \
--cc=jens.wiklander@linaro.org \
--cc=jerome.forissier@arm.com \
--cc=jerome.forissier@linaro.org \
--cc=marex@denx.de \
--cc=michal.simek@amd.com \
--cc=mkorpershoek@kernel.org \
--cc=trini@konsulko.com \
--cc=u-boot@lists.denx.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.