Skip to content

Commit

Permalink
usb: dwc2: defer probe in case of core reset failure
Browse files Browse the repository at this point in the history
Normally the core reset can take several clocks, depending on the current
state of the core. After this bit is cleared, the application must wait at
least 3 PHY clocks before doing any access to the PHY domain
(synchronization delay).
But on STM32MP15, after the 10ms delay, the bit is still not cleared. The
reason is not known right now, so, the proposal is to defer probe when the
issue occurs.

Change-Id: I6bb7624f649bdf5fd5663311fd25e3f1af518946
Signed-off-by: Amelie Delaunay <[email protected]>
Reviewed-on: https://gerrit.st.com/c/mpu/oe/st/linux-stm32/+/168068
Reviewed-by: CITOOLS <[email protected]>
Reviewed-by: Fabrice GASNIER <[email protected]>
  • Loading branch information
ADESTM authored and atorgue committed Jun 1, 2020
1 parent 5742265 commit b8663f5
Showing 1 changed file with 4 additions and 1 deletion.
5 changes: 4 additions & 1 deletion drivers/usb/dwc2/platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -450,8 +450,11 @@ static int dwc2_driver_probe(struct platform_device *dev)
* reset value form registers.
*/
retval = dwc2_core_reset(hsotg, false);
if (retval)
if (retval) {
/* TEMPORARY WORKAROUND */
retval = -EPROBE_DEFER;
goto error;
}

/* Detect config values from hardware */
retval = dwc2_get_hwparams(hsotg);
Expand Down

4 comments on commit b8663f5

@eathanq
Copy link

@eathanq eathanq commented on b8663f5 Jul 20, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So now do we know how to solve "core reset failure on STM32MP15" ?? If somedody knows the answer, Please tell me. Help !

@ADESTM
Copy link
Collaborator Author

@ADESTM ADESTM commented on b8663f5 Jul 20, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi,

The OTG core reset failure on STM32MP15 is due to a bad supply management.
In the AN5031 application note (https://www.st.com/resource/en/application_note/an5031-getting-started-with-stm32mp151-stm32mp153-and-stm32mp157-line-hardware-development-stmicroelectronics.pdf), there is a "Caution" under 4.2 Power supply schemes:
"VDD3V3_USBHS must not be present unless VDDA1V8_REG is present, otherwise permanent
STM32MP15x lines damage could occur. Must be ensured by PMIC ranking order or with
external component in case of discrete component power supply implementation."

The side effect of such case (vdd3v3_usbhs ON while vdda1v8_reg OFF) is the OTG core reset failure.
To solve core reset failure, you must ensure vdd3v3_usbhs (vdd_usb on STPMIC) is OFF if vdda1v8_reg (reg18 of STM32MP15 PWR block) is OFF. And you must set vdd3v3_usbhs only when vdda1v8_reg is ON.

In OpenSTLinux, it as been solved by removing regulator-always-on property from vdd_usb regulator node in device tree files, and by disabling STPMIC LDO4 (vdd_usb) in bootloaders:
STMicroelectronics/arm-trusted-firmware@ddb0ae7
STMicroelectronics/optee_os@1f6fa28

@eathanq
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi, ADESTM. Thanks for your reply !

According to your description i can tell that the problem is supply management.
However, I found some workaround solutions such as below:

https://community.st.com/s/question/0D53W00000UA60XSAT/mainline-linux-fails-to-set-up-fs-otg

@@ -475,6 +475,18 @@ static int dwc2_driver_probe(struct platform_device *dev)
        if (retval)
                goto error;

+       /* connect phy transceiver to preventdwc2_core_reset timeout */
+       if (!hsotg->phy) {
+               u32 ggpio;
+               ggpio = dwc2_readl(hsotg, GGPIO);
+               if (!(ggpio & GGPIO_STM32_OTG_GCCFG_PWRDWN)) {
+                       ggpio |= GGPIO_STM32_OTG_GCCFG_PWRDWN;
+                       dwc2_writel(hsotg, ggpio, GGPIO);
+               }
+               ggpio = dwc2_readl(hsotg, GUSBCFG);
+               ggpio |= GUSBCFG_PHYSEL;
+               dwc2_writel(hsotg, ggpio, GUSBCFG);
+       }
        /*
         * Reset before dwc2_get_hwparams() then it could get power-on real
         * reset value form registers.
         */
         retval = dwc2_core_reset(hsotg, false);

I test it and it does work ! Do you know the theory behind it ? And can this be a normal solution ?

Thanks again !

@ADESTM
Copy link
Collaborator Author

@ADESTM ADESTM commented on b8663f5 Jul 20, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I forgot to ask your OTG configuration: OTG FS using FS phy or OTG HS using USBPHYC HS PHY (compatible "st,stm32mp1-fsotg" or "st,stm32mp1-hsotg") ?

PHY configuration is done later, when Host and/or Gadget mode are initialized (using dwc2_phy_init() function, which configures either dwc2_fs_phy_init() or dwc2_hs_phy_init()).
So default PHY before configuration is USBPHYC HS PHY.

On STM32MP15, USB FS IOs are supplied with vdd3v3_usbfs. This supply is connected to vdd3v3_usbhs. So I guess that if you have the core reset failure, it is due to the fact that vdd3v3_usbhs is ON whatever the vdda1v8 state, so, vdd3v3_usbfs is ON, and OTG FS IOs are supplied. I just hope you are really using OTG FS with FS phy on your layout because you also need to configure OTG FS pin muxing (PA11/OTG_FS_DP and PA12 OTG_FS_DM).

When you set GUSBCFG_PHYSEL, OTG relies on FS PHY signals, no more on USBPHYC HS PHY signals. I think it is why the core reset doesn't fail anymore.

It is a workaround to temporarily avoid the core reset failure, not a normal solution: supplies should be well managed.
Moveover, this workaround doesn't work if you can suspend/resume your platform.

Please sign in to comment.