* [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