Re: [PATCH] usb: dwc3: Initialize Xilinx glue registers

Michal Simek
2026-01-16T08:19:17Z

On 1/6/26 23:17, Sean Anderson wrote:
> These registers may have been initialized by SPL/FSBL, but program them
> in case they have not. If they are left at their default values, the
> controller will never exit reset.
>
> Signed-off-by: Sean Anderson <sean.anderson@linux.dev>
>
> ---
>
> drivers/usb/dwc3/dwc3-generic.c | 32 ++++++++++++++++++++++++++------
> drivers/usb/dwc3/dwc3-generic.h | 2 ++
> 2 files changed, 28 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/usb/dwc3/dwc3-generic.c b/drivers/usb/dwc3/dwc3-generic.c
> index c09014aec60..ce896db9532 100644
> --- a/drivers/usb/dwc3/dwc3-generic.c
> +++ b/drivers/usb/dwc3/dwc3-generic.c
> @@ -501,6 +501,27 @@ struct dwc3_glue_ops rk_ops = {
> .glue_get_ctrl_dev = dwc3_rk_glue_get_ctrl_dev,
> };
>
> +void dwc3_xlnx_glue_configure(struct udevice *dev, int index,
> + enum usb_dr_mode mode)
> +{
> +/* USB glue registers */
> +#define USB3_FPD_PIPE_CLK 0x7c
> +#define USB3_FPD_POWER_PRSNT 0x80
> + struct dwc3_glue_data *glue = dev_get_plat(dev);
> + void *base = map_physmem(glue->regs, 0x10000, MAP_NOCACHE);
> +
> + if (generic_phy_valid(&glue->phy)) {
> + writel(0, base + USB3_FPD_PIPE_CLK);
> + writel(1, base + USB3_FPD_POWER_PRSNT);
> + } else {
> + writel(1, base + USB3_FPD_PIPE_CLK);
> + }
> +}
> +
> +struct dwc3_glue_ops xlnx_ops = {
> + .glue_configure = dwc3_xlnx_glue_configure,
> +};
> +
> static int dwc3_glue_bind_common(struct udevice *parent, ofnode node)
> {
> const char *name = ofnode_get_name(node);
> @@ -621,11 +642,10 @@ int dwc3_glue_probe(struct udevice *dev)
> struct udevice *child = NULL;
> int index = 0;
> int ret;
> - struct phy phy;
>
> - ret = generic_phy_get_by_name(dev, "usb3-phy", &phy);
> + ret = generic_phy_get_by_name(dev, "usb3-phy", &glue->phy);
> if (!ret) {
> - ret = generic_phy_init(&phy);
> + ret = generic_phy_init(&glue->phy);
> if (ret)
> return ret;
> } else if (ret != -ENOENT && ret != -ENODATA) {
> @@ -643,8 +663,8 @@ int dwc3_glue_probe(struct udevice *dev)
> if (ret)
> return ret;
>
> - if (generic_phy_valid(&phy)) {
> - ret = generic_phy_power_on(&phy);
> + if (generic_phy_valid(&glue->phy)) {
> + ret = generic_phy_power_on(&glue->phy);
> if (ret)
> return ret;
> }
> @@ -690,7 +710,7 @@ int dwc3_glue_remove(struct udevice *dev)
> }
>
> static const struct udevice_id dwc3_glue_ids[] = {
> - { .compatible = "xlnx,zynqmp-dwc3" },
> + { .compatible = "xlnx,zynqmp-dwc3", .data = (ulong)&xlnx_ops },
> { .compatible = "xlnx,versal-dwc3" },
> { .compatible = "ti,keystone-dwc3"},
> { .compatible = "ti,dwc3", .data = (ulong)&ti_ops },
> diff --git a/drivers/usb/dwc3/dwc3-generic.h b/drivers/usb/dwc3/dwc3-generic.h
> index 40902c8923f..13f6391cae8 100644
> --- a/drivers/usb/dwc3/dwc3-generic.h
> +++ b/drivers/usb/dwc3/dwc3-generic.h
> @@ -10,12 +10,14 @@
> #define __DRIVERS_USB_DWC3_GENERIC_H
>
> #include <clk.h>
> +#include <generic-phy.h>
> #include <reset.h>
> #include <dwc3-uboot.h>
>
> struct dwc3_glue_data {
> struct clk_bulk clks;
> struct reset_ctl_bulk resets;
> + struct phy phy;
> fdt_addr_t regs;
> fdt_size_t size;
> };

I will let Marek to handle this. From my perspective we should take Jerome's
patchset to update usb stack and then add this on the top.

Thanks,
Michal