diff mbox series

ARM: socfpga: gen5: release reset before using USB as device with ums

Message ID c90b9e3f-ef41-7b45-ca89-32a75cf27840@aries-embedded.de
State Deferred
Delegated to: Tom Rini
Headers show
Series ARM: socfpga: gen5: release reset before using USB as device with ums | expand

Commit Message

Wolfgang Grandegger Feb. 28, 2022, 2:13 p.m. UTC
The command "ums 0 mmc 0" does not work because the USB port is still
in reset. Releasing it in board_usb_init() fixes the problem. This issue
has been observed and fixed on the Aries MCVEVP board.

Signed-off-by: Wolfgang Grandegger <wg@aries-embedded.de>
---
 arch/arm/dts/socfpga_cyclone5_mcvevk.dts                | 1 +
 arch/arm/mach-socfpga/board.c                           | 8 ++++++++
 arch/arm/mach-socfpga/include/mach/reset_manager_gen5.h | 2 ++
 3 files changed, 11 insertions(+)

Comments

Marek Vasut Feb. 28, 2022, 2:51 p.m. UTC | #1
On 2/28/22 15:13, Wolfgang Grandegger wrote:
> The command "ums 0 mmc 0" does not work because the USB port is still
> in reset. Releasing it in board_usb_init() fixes the problem. This issue
> has been observed and fixed on the Aries MCVEVP board.
> 
> Signed-off-by: Wolfgang Grandegger <wg@aries-embedded.de>
> ---
>   arch/arm/dts/socfpga_cyclone5_mcvevk.dts                | 1 +
>   arch/arm/mach-socfpga/board.c                           | 8 ++++++++
>   arch/arm/mach-socfpga/include/mach/reset_manager_gen5.h | 2 ++
>   3 files changed, 11 insertions(+)
> 
> diff --git a/arch/arm/dts/socfpga_cyclone5_mcvevk.dts b/arch/arm/dts/socfpga_cyclone5_mcvevk.dts
> index ceaec29770..a673837f25 100644
> --- a/arch/arm/dts/socfpga_cyclone5_mcvevk.dts
> +++ b/arch/arm/dts/socfpga_cyclone5_mcvevk.dts
> @@ -12,6 +12,7 @@
>   	aliases {
>   		ethernet0 = &gmac0;
>   		stmpe-i2c0 = &stmpe1;
> +		udc0 = &usb1;
>   	};
>   
>   	chosen {
> diff --git a/arch/arm/mach-socfpga/board.c b/arch/arm/mach-socfpga/board.c
> index 7267163222..a2eed73fe9 100644
> --- a/arch/arm/mach-socfpga/board.c
> +++ b/arch/arm/mach-socfpga/board.c
> @@ -83,6 +83,14 @@ int board_usb_init(int index, enum usb_init_type init)
>   	/* Patch the address from OF into the controller pdata. */
>   	socfpga_otg_data.regs_otg = addr;
>   
> +#ifdef CONFIG_TARGET_SOCFPGA_GEN5
> +	/* First release reset of the USB port */
> +	if (addr == SOCFPGA_USB0_ADDRESS)
> +		socfpga_per_reset(SOCFPGA_RESET(USB0), 0);
> +	else if (addr == SOCFPGA_USB1_ADDRESS)
> +		socfpga_per_reset(SOCFPGA_RESET(USB1), 0);
> +#endif

Is this really needed at all ?

There is drivers/reset/reset-socfpga.c which should handle the reset of 
the DWC2 USB IP.
Wolfgang Grandegger Feb. 28, 2022, 3:18 p.m. UTC | #2
Hello Marek,

Am 28.02.22 um 15:51 schrieb Marek Vasut:
> On 2/28/22 15:13, Wolfgang Grandegger wrote:
>> The command "ums 0 mmc 0" does not work because the USB port is still
>> in reset. Releasing it in board_usb_init() fixes the problem. This issue
>> has been observed and fixed on the Aries MCVEVP board.
>>
>> Signed-off-by: Wolfgang Grandegger <wg@aries-embedded.de>
>> ---
>>   arch/arm/dts/socfpga_cyclone5_mcvevk.dts                | 1 +
>>   arch/arm/mach-socfpga/board.c                           | 8 ++++++++
>>   arch/arm/mach-socfpga/include/mach/reset_manager_gen5.h | 2 ++
>>   3 files changed, 11 insertions(+)
>>
>> diff --git a/arch/arm/dts/socfpga_cyclone5_mcvevk.dts
>> b/arch/arm/dts/socfpga_cyclone5_mcvevk.dts
>> index ceaec29770..a673837f25 100644
>> --- a/arch/arm/dts/socfpga_cyclone5_mcvevk.dts
>> +++ b/arch/arm/dts/socfpga_cyclone5_mcvevk.dts
>> @@ -12,6 +12,7 @@
>>       aliases {
>>           ethernet0 = &gmac0;
>>           stmpe-i2c0 = &stmpe1;
>> +        udc0 = &usb1;
>>       };
>>         chosen {
>> diff --git a/arch/arm/mach-socfpga/board.c
>> b/arch/arm/mach-socfpga/board.c
>> index 7267163222..a2eed73fe9 100644
>> --- a/arch/arm/mach-socfpga/board.c
>> +++ b/arch/arm/mach-socfpga/board.c
>> @@ -83,6 +83,14 @@ int board_usb_init(int index, enum usb_init_type init)
>>       /* Patch the address from OF into the controller pdata. */
>>       socfpga_otg_data.regs_otg = addr;
>>   +#ifdef CONFIG_TARGET_SOCFPGA_GEN5
>> +    /* First release reset of the USB port */
>> +    if (addr == SOCFPGA_USB0_ADDRESS)
>> +        socfpga_per_reset(SOCFPGA_RESET(USB0), 0);
>> +    else if (addr == SOCFPGA_USB1_ADDRESS)
>> +        socfpga_per_reset(SOCFPGA_RESET(USB1), 0);
>> +#endif
> 
> Is this really needed at all ?

Yes, it's needed, otherwise "ums 0 mmc 0" does not work. It was working
some time ago but commit 430b42f76a4e50ffef7cc2b3c195ff645a438433 did
remove the ad-hoc reset code. I realize the issue an on Aries MCVEVP
board, but I'm quite sure that it's present on all Cyclone5 boards.

> There is drivers/reset/reset-socfpga.c which should handle the reset of
> the DWC2 USB IP.

See above!

Wolfgang
Marek Vasut Feb. 28, 2022, 3:22 p.m. UTC | #3
On 2/28/22 16:18, Wolfgang Grandegger wrote:

Hi,

[...]

>>> diff --git a/arch/arm/mach-socfpga/board.c
>>> b/arch/arm/mach-socfpga/board.c
>>> index 7267163222..a2eed73fe9 100644
>>> --- a/arch/arm/mach-socfpga/board.c
>>> +++ b/arch/arm/mach-socfpga/board.c
>>> @@ -83,6 +83,14 @@ int board_usb_init(int index, enum usb_init_type init)
>>>        /* Patch the address from OF into the controller pdata. */
>>>        socfpga_otg_data.regs_otg = addr;
>>>    +#ifdef CONFIG_TARGET_SOCFPGA_GEN5
>>> +    /* First release reset of the USB port */
>>> +    if (addr == SOCFPGA_USB0_ADDRESS)
>>> +        socfpga_per_reset(SOCFPGA_RESET(USB0), 0);
>>> +    else if (addr == SOCFPGA_USB1_ADDRESS)
>>> +        socfpga_per_reset(SOCFPGA_RESET(USB1), 0);
>>> +#endif
>>
>> Is this really needed at all ?
> 
> Yes, it's needed, otherwise "ums 0 mmc 0" does not work. It was working
> some time ago but commit 430b42f76a4e50ffef7cc2b3c195ff645a438433 did
> remove the ad-hoc reset code. I realize the issue an on Aries MCVEVP
> board, but I'm quite sure that it's present on all Cyclone5 boards.

Can you investigate why the reset-socfpga.c does not release the USB 
from reset instead ? That would be the right approach.
Wolfgang Grandegger March 14, 2022, 10:57 a.m. UTC | #4
Hello,

Am 28.02.22 um 16:22 schrieb Marek Vasut:
> On 2/28/22 16:18, Wolfgang Grandegger wrote:
> 
> Hi,
> 
> [...]
> 
>>>> diff --git a/arch/arm/mach-socfpga/board.c
>>>> b/arch/arm/mach-socfpga/board.c
>>>> index 7267163222..a2eed73fe9 100644
>>>> --- a/arch/arm/mach-socfpga/board.c
>>>> +++ b/arch/arm/mach-socfpga/board.c
>>>> @@ -83,6 +83,14 @@ int board_usb_init(int index, enum usb_init_type
>>>> init)
>>>>        /* Patch the address from OF into the controller pdata. */
>>>>        socfpga_otg_data.regs_otg = addr;
>>>>    +#ifdef CONFIG_TARGET_SOCFPGA_GEN5
>>>> +    /* First release reset of the USB port */
>>>> +    if (addr == SOCFPGA_USB0_ADDRESS)
>>>> +        socfpga_per_reset(SOCFPGA_RESET(USB0), 0);
>>>> +    else if (addr == SOCFPGA_USB1_ADDRESS)
>>>> +        socfpga_per_reset(SOCFPGA_RESET(USB1), 0);
>>>> +#endif
>>>
>>> Is this really needed at all ?
>>
>> Yes, it's needed, otherwise "ums 0 mmc 0" does not work. It was working
>> some time ago but commit 430b42f76a4e50ffef7cc2b3c195ff645a438433 did
>> remove the ad-hoc reset code. I realize the issue an on Aries MCVEVP
>> board, but I'm quite sure that it's present on all Cyclone5 boards.
> 
> Can you investigate why the reset-socfpga.c does not release the USB
> from reset instead ? That would be the right approach.

The attached patch works. It enables CONFIG_DM_USB_GADGET and adds
"dr_mode = otg" to the USB device tree node. "ums 0 mmc 0" deasserts the
reset for USB1 and re-assert it when done. All ok with that!

But then "usb start" is broken:

  => usb start
  starting USB...
  USB: drv id 110 name usb
  USB: drv id 90 name serial
  USB: drv id 101 name sysreset
  USB: drv id 85 name reset
  USB: drv id 22 name blk
  USB: drv id 59 name mmc
  USB: drv id 99 name syscon
  USB: drv id 25 name cache
  USB: drv id 43 name i2c
  USB: drv id 40 name gpio
  USB: drv id 36 name ethernet
  USB: drv id 91 name simple_bus
  USB: drv id 0 name root
  No working controllers found


The function "uclass_find()" does no longer find the USB host device
(UCLASS_USB). The debug ouput is with:

diff --git a/drivers/core/uclass.c b/drivers/core/uclass.c
index 2578803b7a..b59a5dcdad 100644
--- a/drivers/core/uclass.c
+++ b/drivers/core/uclass.c
@@ -35,6 +35,9 @@ struct uclass *uclass_find(enum uclass_id key)
         * id to node.
         */
        list_for_each_entry(uc, gd->uclass_root, sibling_node) {
+               if (key == UCLASS_USB)
+                       printf("USB: drv id %d name %s\n", 
+                              uc->uc_drv->id, uc->uc_drv->name);
                if (uc->uc_drv->id == key)
                        return uc;
        }

Id 110 is UCLASS_USB_GADGET_GENERIC, but UCLASS_USB is gone. There is
some magic with usb device scanning. Any idea what could cause that
problem?

Wolfgang
Marek Vasut March 14, 2022, 11:32 a.m. UTC | #5
On 3/14/22 11:57, Wolfgang Grandegger wrote:
> Hello,
> 
> Am 28.02.22 um 16:22 schrieb Marek Vasut:
>> On 2/28/22 16:18, Wolfgang Grandegger wrote:
>>
>> Hi,
>>
>> [...]
>>
>>>>> diff --git a/arch/arm/mach-socfpga/board.c
>>>>> b/arch/arm/mach-socfpga/board.c
>>>>> index 7267163222..a2eed73fe9 100644
>>>>> --- a/arch/arm/mach-socfpga/board.c
>>>>> +++ b/arch/arm/mach-socfpga/board.c
>>>>> @@ -83,6 +83,14 @@ int board_usb_init(int index, enum usb_init_type
>>>>> init)
>>>>>         /* Patch the address from OF into the controller pdata. */
>>>>>         socfpga_otg_data.regs_otg = addr;
>>>>>     +#ifdef CONFIG_TARGET_SOCFPGA_GEN5
>>>>> +    /* First release reset of the USB port */
>>>>> +    if (addr == SOCFPGA_USB0_ADDRESS)
>>>>> +        socfpga_per_reset(SOCFPGA_RESET(USB0), 0);
>>>>> +    else if (addr == SOCFPGA_USB1_ADDRESS)
>>>>> +        socfpga_per_reset(SOCFPGA_RESET(USB1), 0);
>>>>> +#endif
>>>>
>>>> Is this really needed at all ?
>>>
>>> Yes, it's needed, otherwise "ums 0 mmc 0" does not work. It was working
>>> some time ago but commit 430b42f76a4e50ffef7cc2b3c195ff645a438433 did
>>> remove the ad-hoc reset code. I realize the issue an on Aries MCVEVP
>>> board, but I'm quite sure that it's present on all Cyclone5 boards.
>>
>> Can you investigate why the reset-socfpga.c does not release the USB
>> from reset instead ? That would be the right approach.
> 
> The attached patch works. It enables CONFIG_DM_USB_GADGET and adds
> "dr_mode = otg" to the USB device tree node. "ums 0 mmc 0" deasserts the
> reset for USB1 and re-assert it when done. All ok with that!
> 
> But then "usb start" is broken:
> 
>    => usb start
>    starting USB...
>    USB: drv id 110 name usb
>    USB: drv id 90 name serial
>    USB: drv id 101 name sysreset
>    USB: drv id 85 name reset
>    USB: drv id 22 name blk
>    USB: drv id 59 name mmc
>    USB: drv id 99 name syscon
>    USB: drv id 25 name cache
>    USB: drv id 43 name i2c
>    USB: drv id 40 name gpio
>    USB: drv id 36 name ethernet
>    USB: drv id 91 name simple_bus
>    USB: drv id 0 name root
>    No working controllers found
> 
> 
> The function "uclass_find()" does no longer find the USB host device
> (UCLASS_USB). The debug ouput is with:
> 
> diff --git a/drivers/core/uclass.c b/drivers/core/uclass.c
> index 2578803b7a..b59a5dcdad 100644
> --- a/drivers/core/uclass.c
> +++ b/drivers/core/uclass.c
> @@ -35,6 +35,9 @@ struct uclass *uclass_find(enum uclass_id key)
>           * id to node.
>           */
>          list_for_each_entry(uc, gd->uclass_root, sibling_node) {
> +               if (key == UCLASS_USB)
> +                       printf("USB: drv id %d name %s\n",
> +                              uc->uc_drv->id, uc->uc_drv->name);
>                  if (uc->uc_drv->id == key)
>                          return uc;
>          }
> 
> Id 110 is UCLASS_USB_GADGET_GENERIC, but UCLASS_USB is gone. There is
> some magic with usb device scanning. Any idea what could cause that
> problem?

+CC Simon
diff mbox series

Patch

diff --git a/arch/arm/dts/socfpga_cyclone5_mcvevk.dts b/arch/arm/dts/socfpga_cyclone5_mcvevk.dts
index ceaec29770..a673837f25 100644
--- a/arch/arm/dts/socfpga_cyclone5_mcvevk.dts
+++ b/arch/arm/dts/socfpga_cyclone5_mcvevk.dts
@@ -12,6 +12,7 @@ 
 	aliases {
 		ethernet0 = &gmac0;
 		stmpe-i2c0 = &stmpe1;
+		udc0 = &usb1;
 	};
 
 	chosen {
diff --git a/arch/arm/mach-socfpga/board.c b/arch/arm/mach-socfpga/board.c
index 7267163222..a2eed73fe9 100644
--- a/arch/arm/mach-socfpga/board.c
+++ b/arch/arm/mach-socfpga/board.c
@@ -83,6 +83,14 @@  int board_usb_init(int index, enum usb_init_type init)
 	/* Patch the address from OF into the controller pdata. */
 	socfpga_otg_data.regs_otg = addr;
 
+#ifdef CONFIG_TARGET_SOCFPGA_GEN5
+	/* First release reset of the USB port */
+	if (addr == SOCFPGA_USB0_ADDRESS)
+		socfpga_per_reset(SOCFPGA_RESET(USB0), 0);
+	else if (addr == SOCFPGA_USB1_ADDRESS)
+		socfpga_per_reset(SOCFPGA_RESET(USB1), 0);
+#endif
+
 	return dwc2_udc_probe(&socfpga_otg_data);
 }
 
diff --git a/arch/arm/mach-socfpga/include/mach/reset_manager_gen5.h b/arch/arm/mach-socfpga/include/mach/reset_manager_gen5.h
index d108eac1e2..611403cf00 100644
--- a/arch/arm/mach-socfpga/include/mach/reset_manager_gen5.h
+++ b/arch/arm/mach-socfpga/include/mach/reset_manager_gen5.h
@@ -31,6 +31,8 @@  void socfpga_bridges_reset(int enable);
  */
 #define RSTMGR_EMAC0		RSTMGR_DEFINE(1, 0)
 #define RSTMGR_EMAC1		RSTMGR_DEFINE(1, 1)
+#define RSTMGR_USB0		RSTMGR_DEFINE(1, 2)
+#define RSTMGR_USB1		RSTMGR_DEFINE(1, 3)
 #define RSTMGR_NAND		RSTMGR_DEFINE(1, 4)
 #define RSTMGR_QSPI		RSTMGR_DEFINE(1, 5)
 #define RSTMGR_L4WD0		RSTMGR_DEFINE(1, 6)