public inbox for u-boot@lists.denx.de
 help / color / mirror / Atom feed
* [PATCH] usb: dwc3: Initialize Xilinx glue registers
@ 2026-01-06 22:17 Sean Anderson
  2026-01-16  8:19 ` Michal Simek
  0 siblings, 1 reply; 8+ messages in thread
From: Sean Anderson @ 2026-01-06 22:17 UTC (permalink / raw)
  To: Marek Vasut, u-boot; +Cc: Michal Simek, Sean Anderson

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;
 };
-- 
2.35.1.1320.gc452695387.dirty

base-commit: beab3fe49e1e9209dd32fe2791e7ac706038460f
branch: dwc3_xlnx_glue

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH] usb: dwc3: Initialize Xilinx glue registers
  2026-01-06 22:17 [PATCH] usb: dwc3: Initialize Xilinx glue registers Sean Anderson
@ 2026-01-16  8:19 ` Michal Simek
  2026-01-16 14:07   ` Marek Vasut
  0 siblings, 1 reply; 8+ messages in thread
From: Michal Simek @ 2026-01-16  8:19 UTC (permalink / raw)
  To: Sean Anderson, Marek Vasut, u-boot



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

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] usb: dwc3: Initialize Xilinx glue registers
  2026-01-16  8:19 ` Michal Simek
@ 2026-01-16 14:07   ` Marek Vasut
  2026-01-16 16:14     ` Sean Anderson
  0 siblings, 1 reply; 8+ messages in thread
From: Marek Vasut @ 2026-01-16 14:07 UTC (permalink / raw)
  To: Michal Simek, Sean Anderson, u-boot, Ilias Apalodimas

On 1/16/26 9:19 AM, Michal Simek wrote:
> 
> 
> 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.
Since this fixes a real bug and is isolated to xilinx platform, it would 
be good if xilinx at least provided feedback on this patch.

+CC Ilias

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] usb: dwc3: Initialize Xilinx glue registers
  2026-01-16 14:07   ` Marek Vasut
@ 2026-01-16 16:14     ` Sean Anderson
  2026-01-22 13:25       ` Michal Simek
  2026-01-29 10:13       ` Michal Simek
  0 siblings, 2 replies; 8+ messages in thread
From: Sean Anderson @ 2026-01-16 16:14 UTC (permalink / raw)
  To: Marek Vasut, Michal Simek, u-boot, Ilias Apalodimas

On 1/16/26 09:07, Marek Vasut wrote:
> On 1/16/26 9:19 AM, Michal Simek wrote:
>>
>>
>> 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.
> Since this fixes a real bug and is isolated to xilinx platform, it would be good if xilinx at least provided feedback on this patch.
> 
> +CC Ilias

It's not a bug fix (hence no fixes tag). See [1,2] for details.

--Sean

[1] https://lore.kernel.org/linux-usb/8f0e04a5-49df-4fe3-9c76-9a1c0bd822a0@linux.dev/
[2] https://lore.kernel.org/linux-usb/be8a566a-163f-4d20-b712-67de6f63a6b5@linux.dev/

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] usb: dwc3: Initialize Xilinx glue registers
  2026-01-16 16:14     ` Sean Anderson
@ 2026-01-22 13:25       ` Michal Simek
  2026-02-17  8:48         ` Kumar, Love
  2026-01-29 10:13       ` Michal Simek
  1 sibling, 1 reply; 8+ messages in thread
From: Michal Simek @ 2026-01-22 13:25 UTC (permalink / raw)
  To: Sean Anderson, Marek Vasut, u-boot, Ilias Apalodimas, Love Kumar

+Love

On 1/16/26 17:14, Sean Anderson wrote:
> On 1/16/26 09:07, Marek Vasut wrote:
>> On 1/16/26 9:19 AM, Michal Simek wrote:
>>>
>>>
>>> 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.
>> Since this fixes a real bug and is isolated to xilinx platform, it would be good if xilinx at least provided feedback on this patch.
>>
>> +CC Ilias
> 
> It's not a bug fix (hence no fixes tag). See [1,2] for details.
> 
> --Sean
> 
> [1] https://lore.kernel.org/linux-usb/8f0e04a5-49df-4fe3-9c76-9a1c0bd822a0@linux.dev/
> [2] https://lore.kernel.org/linux-usb/be8a566a-163f-4d20-b712-67de6f63a6b5@linux.dev/

Love: Can you please test this patch and provide your tested-by flag if it is 
working.

Thanks,
Michal


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] usb: dwc3: Initialize Xilinx glue registers
  2026-01-16 16:14     ` Sean Anderson
  2026-01-22 13:25       ` Michal Simek
@ 2026-01-29 10:13       ` Michal Simek
  2026-02-17 11:06         ` Michal Simek
  1 sibling, 1 reply; 8+ messages in thread
From: Michal Simek @ 2026-01-29 10:13 UTC (permalink / raw)
  To: Sean Anderson, Marek Vasut, u-boot, Ilias Apalodimas, Love Kumar



On 1/16/26 17:14, Sean Anderson wrote:
> On 1/16/26 09:07, Marek Vasut wrote:
>> On 1/16/26 9:19 AM, Michal Simek wrote:
>>>
>>>
>>> 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.
>> Since this fixes a real bug and is isolated to xilinx platform, it would be good if xilinx at least provided feedback on this patch.
>>
>> +CC Ilias
> 
> It's not a bug fix (hence no fixes tag). See [1,2] for details.
> 

Please hold on this patch. I got information that we see some issues on one 
board when this patch is applied.
We will get back to you.

Thanks,
Michal


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] usb: dwc3: Initialize Xilinx glue registers
  2026-01-22 13:25       ` Michal Simek
@ 2026-02-17  8:48         ` Kumar, Love
  0 siblings, 0 replies; 8+ messages in thread
From: Kumar, Love @ 2026-02-17  8:48 UTC (permalink / raw)
  To: Michal Simek, Sean Anderson, Marek Vasut, u-boot,
	Ilias Apalodimas

Hi,

On 1/22/2026 6:55 PM, Michal Simek wrote:
> +Love
> 
> On 1/16/26 17:14, Sean Anderson wrote:
>> On 1/16/26 09:07, Marek Vasut wrote:
>>> On 1/16/26 9:19 AM, Michal Simek wrote:
>>>>
>>>>
>>>> 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>

Verified it on AMD platforms and not seeing any issue.

Tested-by: Love Kumar <love.kumar@amd.com>

Regards,
Love Kumar

>>>>>
>>>>> ---
>>>>>
>>>>>    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.
>>> Since this fixes a real bug and is isolated to xilinx platform, it would be good if xilinx at least provided feedback on this patch.
>>>
>>> +CC Ilias
>>
>> It's not a bug fix (hence no fixes tag). See [1,2] for details.
>>
>> --Sean
>>
>> [1] https://lore.kernel.org/linux-usb/8f0e04a5-49df-4fe3-9c76-9a1c0bd822a0@linux.dev/
>> [2] https://lore.kernel.org/linux-usb/be8a566a-163f-4d20-b712-67de6f63a6b5@linux.dev/
> 
> Love: Can you please test this patch and provide your tested-by flag if it is working.
> 
> Thanks,
> Michal
> 


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] usb: dwc3: Initialize Xilinx glue registers
  2026-01-29 10:13       ` Michal Simek
@ 2026-02-17 11:06         ` Michal Simek
  0 siblings, 0 replies; 8+ messages in thread
From: Michal Simek @ 2026-02-17 11:06 UTC (permalink / raw)
  To: Sean Anderson, Marek Vasut, u-boot, Ilias Apalodimas, Love Kumar



On 1/29/26 11:13, Michal Simek wrote:
> 
> 
> On 1/16/26 17:14, Sean Anderson wrote:
>> On 1/16/26 09:07, Marek Vasut wrote:
>>> On 1/16/26 9:19 AM, Michal Simek wrote:
>>>>
>>>>
>>>> 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.
>>> Since this fixes a real bug and is isolated to xilinx platform, it would be 
>>> good if xilinx at least provided feedback on this patch.
>>>
>>> +CC Ilias
>>
>> It's not a bug fix (hence no fixes tag). See [1,2] for details.
>>
> 
> Please hold on this patch. I got information that we see some issues on one 
> board when this patch is applied.
> We will get back to you.

ok. No problem from our side.

M

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2026-02-17 11:07 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-01-06 22:17 [PATCH] usb: dwc3: Initialize Xilinx glue registers Sean Anderson
2026-01-16  8:19 ` Michal Simek
2026-01-16 14:07   ` Marek Vasut
2026-01-16 16:14     ` Sean Anderson
2026-01-22 13:25       ` Michal Simek
2026-02-17  8:48         ` Kumar, Love
2026-01-29 10:13       ` Michal Simek
2026-02-17 11:06         ` Michal Simek

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox