Re: USB runtime PM issues on i.MX6ULL

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, Jan 03, 2023 at 03:45:42AM +0000, Jun Li wrote:
> > -----Original Message-----
> > From: Francesco Dolcini <francesco@xxxxxxxxxx>
> > Sent: Monday, December 26, 2022 11:45 PM
> > To: Jun Li <jun.li@xxxxxxx>
> > Cc: Francesco Dolcini <francesco@xxxxxxxxxx>; Jun Li (OSS)
> > <jun.li@xxxxxxxxxxx>; Peter Chen <peter.chen@xxxxxxxxxx>;
> > linux-usb@xxxxxxxxxxxxxxx; Greg Kroah-Hartman
> > <gregkh@xxxxxxxxxxxxxxxxxxx>; Shawn Guo <shawnguo@xxxxxxxxxx>; Sascha
> > Hauer <s.hauer@xxxxxxxxxxxxxx>; Pengutronix Kernel Team
> > <kernel@xxxxxxxxxxxxxx>; Fabio Estevam <festevam@xxxxxxxxx>; dl-linux-imx
> > <linux-imx@xxxxxxx>; Felipe Balbi <balbi@xxxxxxxxxx>;
> > philippe.schenker@xxxxxxxxxxx; Francesco Dolcini
> > <francesco.dolcini@xxxxxxxxxxx>; Xu Yang <xu.yang_2@xxxxxxx>
> > Subject: Re: USB runtime PM issues on i.MX6ULL
> > 
> > On Mon, Dec 26, 2022 at 03:17:12AM +0000, Jun Li wrote:
> > > > From: Jun Li
> > > > Sent: Thursday, November 3, 2022 7:53 PM
> > > > > From: Francesco Dolcini <francesco@xxxxxxxxxx>
> > > > > Sent: Thursday, November 3, 2022 1:59 AM On Wed, Nov 02, 2022 at
> > > > > 10:12:42AM +0000, Jun Li wrote:
> > > > > > > > On Tue, Nov 01, 2022 at 03:10:46AM +0000, Jun Li wrote:
> > > > > > > > > > On Mon, Oct 31, 2022 at 01:40:39PM +0000, Jun Li (OSS) wrote:
> > > > > > > > > > > > I am debugging some unexpected USB behavior on a
> > > > > > > > > > > > i.MX6ULL SOC, chipidea controller ("fsl,imx6ul-usb")
> > > > > > > > > > > > and a fsl mxs usbphy ("fsl,imx6ul-usbphy").
> > > > > > > > > > > >
> > > > > > > > > > > > The HW design has 2 USB interface, the first one is
> > > > > > > > > > > > dual-role, while the second one is a host port with
> > > > > > > > > > > > NO way to re-read
> > > > > the
> > > > > > > > > > > > VBUS (USB_OTG2_VBUS is not really connected, there
> > > > > > > > > > > > is just
> > > > > a
> > > > > > > > > > > > capacitor to GND).
> > > > > > > > > > >
> > > > > > > > > > > How is your USB_OTG1_VBUS status? Can you try to make
> > > > > > > > > > > your USB_OTG1_VBUS pad has a valid VBUS voltage, then
> > > > > > > > > > > run your Host only port test with runtime PM enabled?
> > > > > > > > > >
> > > > > > > > > > USB_OTG1_VBUS is tied to GND the same way as
> > > > > > > > > > USB_OTG2_VBUS, not really straightforward to do such a test.
> > > > > > > > >
> > > > > > > > > iMX6ULL need at least one valid VBUS(either from OTG1 or
> > > > > > > > > OTG2) as input to power the internal USB LDO if I understand
> > correctly.
> > > > > > > > This surprise me a little bit, since
> > > > > > > >  - the i.MX6ULL datasheet prescribe to keep the VBUS
> > > > > > > > disconnected
> > > > if
> > > > > > > >    unused
> > > > > > >
> > > > > > > I think "unused" here means you do not need/enable the port at
> > all.
> > > > > > >
> > > > > > > >  - downstream NXP kernel seems to work fine ("seems" since
> > > > > > > > we do
> > > > have
> > > > > > > >    some patches there, so I could be wrong)
> > > > > > >
> > > > > > > What do you mean by " downstream NXP kernel seems to work fine"?
> > > > > > > The downstream kernel can work on your HW? But upstream kernel
> > > > > > > driver does not?
> > > > >
> > > > > Correct, NXP downstream kernel is working fine, upstream kernel
> > > > > requires runtime PM disabled to work correctly.
> > > > >
> > > > > > > >  - disabling runtime pm on upstream Linux kernel make it works
> > > > > > > >    perfectly, so there is a way in SW to have this HW configuration
> > > > > > > >    working.
> > > > > > >
> > > > > > > Again I want to make sure the both VBUS pads(OTG1 and OTG2)
> > > > > > > voltage are always at 0v on your HW, can you double check and confirm?
> > > > > > > I ask this again because such situation should cause the USB
> > > > > > > port Cannot work at any cases, but your current status is:
> > > > > > > only low power wakeup cannot work.
> > > > > >
> > > > > > Could you please check the voltage of pad of VDD_USB_CAP on your
> > HW?
> > > > >
> > > > > I was about to clarify you this point, it's important and I forgot
> > > > > about it, sorry about that!
> > > > >
> > > > > VDD_USB_CAP in our design is connected to a 3.0V external LDO,
> > > > > voltage on both VBUS pads is 0V (FYI: this specific hardware
> > > > > design was validated by NXP hardware engineers).
> > > >
> > > > Then the HW design should be fine.
> > > > I need find time to try the upstream kernel on my iMX6ULL board to
> > > > check this.
> > >
> > > My iMX6ULL EVK board cannot reproduce this issue with upstream kernel.
> > >
> > > Could you try to set the bits [7,3] of 0x020c8200(for 2nd USB
> > > controller OTG2) to be value like 0x1000FC? This may be done at your
> > > bootloader(uboot), so make sure those targets bits are set before
> > > doing your test, or doing this with below change(not compiled or tested):
> > >
> > > diff --git a/drivers/usb/phy/phy-mxs-usb.c
> > > b/drivers/usb/phy/phy-mxs-usb.c index d2836ef5d15c..e390ef534a7c
> > > 100644
> > > --- a/drivers/usb/phy/phy-mxs-usb.c
> > > +++ b/drivers/usb/phy/phy-mxs-usb.c
> > > @@ -89,6 +89,9 @@
> > >  #define ANADIG_USB1_CHRG_DET_STAT_CHRG_DETECTED        BIT(1)
> > >  #define ANADIG_USB1_CHRG_DET_STAT_PLUG_CONTACT BIT(0)
> > >
> > > +#define ANADIG_USB2_VBUS_DET_SET               0x204
> > > +#define ANADIG_USB2_VBUS_DET_VBUS_OVERRIDE     GENMASK(7, 3)
> > > +
> > >  #define ANADIG_USB2_VBUS_DET_STAT              0x220
> > >
> > >  #define ANADIG_USB1_LOOPBACK_SET               0x1e4
> > > @@ -288,6 +291,11 @@ static int mxs_phy_hw_init(struct mxs_phy *mxs_phy)
> > >         if (ret)
> > >                 goto disable_pll;
> > >
> > > +       if (mxs_phy->regmap_anatop && (mxs_phy->port_id == 1))
> > > +               regmap_write(mxs_phy->regmap_anatop,
> > > +                            ANADIG_USB2_VBUS_DET_SET,
> > > +                            ANADIG_USB2_VBUS_DET_VBUS_OVERRIDE);
> > > +
> > >         /* Power up the PHY */
> > >         writel(0, base + HW_USBPHY_PWD);
> > 
> > Hello,
> > I tested your patch and it does not work. I therefore tested a slightly
> > improved version that really ensure the right register value is written.
> > 
> > [    8.408564] port=0 reg=0x200 val=0x1000fc
> > [    8.440235] port=1 reg=0x204 val=0x1000fc
> > 
> > but it does not work never the less. Unfortunately bits 7-3 are not documented,
> > so I was not able to do much more.
> > 
> > 
> > diff --git a/drivers/usb/phy/phy-mxs-usb.c
> > b/drivers/usb/phy/phy-mxs-usb.c index d2836ef5d15c..3ff5489d679e 100644
> > --- a/drivers/usb/phy/phy-mxs-usb.c
> > +++ b/drivers/usb/phy/phy-mxs-usb.c
> > @@ -89,6 +89,10 @@
> >  #define ANADIG_USB1_CHRG_DET_STAT_CHRG_DETECTED        BIT(1)
> >  #define ANADIG_USB1_CHRG_DET_STAT_PLUG_CONTACT BIT(0)
> > 
> > +#define ANADIG_USB1_VBUS_DET_SET               0x200
> > +#define ANADIG_USB2_VBUS_DET_SET               0x204
> > +#define ANADIG_USB1_VBUS_DET_VBUS_OVERRIDE     GENMASK(7, 3)
> > +
> >  #define ANADIG_USB2_VBUS_DET_STAT              0x220
> > 
> >  #define ANADIG_USB1_LOOPBACK_SET               0x1e4
> > @@ -309,6 +313,7 @@ static int mxs_phy_hw_init(struct mxs_phy *mxs_phy)
> >                 writel(BM_USBPHY_IP_FIX, base + HW_USBPHY_IP_SET);
> > 
> >         if (mxs_phy->regmap_anatop) {
> > +               unsigned int val;
> >                 unsigned int reg = mxs_phy->port_id ?
> >                         ANADIG_USB1_CHRG_DETECT_SET :
> >                         ANADIG_USB2_CHRG_DETECT_SET; @@ -319,6 +324,15 @@
> > static int mxs_phy_hw_init(struct mxs_phy *mxs_phy)
> >                 regmap_write(mxs_phy->regmap_anatop, reg,
> >                              ANADIG_USB1_CHRG_DETECT_EN_B |
> >                              ANADIG_USB1_CHRG_DETECT_CHK_CHRG_B);
> > +
> > +               reg = mxs_phy->port_id ?
> > +                       ANADIG_USB2_VBUS_DET_SET :
> > +                       ANADIG_USB1_VBUS_DET_SET;
> > +
> > +               regmap_set_bits(mxs_phy->regmap_anatop, reg,
> > +                            ANADIG_USB1_VBUS_DET_VBUS_OVERRIDE);
> > +               regmap_read(mxs_phy->regmap_anatop, reg, &val);
> > +               printk("port=%d reg=0x%x val=0x%x\n", mxs_phy->port_id,
> > + reg, val);
> >         }
> > 
> >         mxs_phy_tx_init(mxs_phy);
> > 
> 
> Thanks for try those, those bits are for vbus valid override,
> You can verify if the override real works by checking the OTGSC
> Registers(a few bits to show the BSV/ASV/AVV) via the debugfs
> /sys/kernel/debug/usb/ci_hdrc.1/registers.
> 
> echo on > /sys/bus/platform/devices/ci_hdrc.1/power/control
> cat /sys/kernel/debug/usb/ci_hdrc.1/registers
> 
> if the BSV/ASV/AVV are all set to be 1, means it works.
> 
> Enable runtime PM back:
> echo auto > /sys/bus/platform/devices/ci_hdrc.1/power/control
> then do your issue test.

== Running Linux 6.0.16, WITH the patch shared on this email thread.

[    8.318987] port=0 reg=0x200 val=0x1000fc
[    8.350386] port=1 reg=0x204 val=0x1000fc

# echo on > /sys/bus/platform/devices/ci_hdrc.1/power/control

# cat /sys/kernel/debug/usb/ci_hdrc.1/registers
USBINTR reg: 00000037
USBSTS reg: 000c0088
USBMODE reg: 00005003
USBCMD reg: 00010005
PORTSC reg: 18601a85
OTGSC reg: 00201720

And these the various valid bits - correct me if I'm wrong.
 - AVV is set
 - ASV is set
 - BSP is NOT set

[  268.421848] usb 1-1: reset high-speed USB device number 2 using ci_hdrc
[  270.931732] usb 1-1: reset high-speed USB device number 2 using ci_hdrc
...

and it's not working as already stated.



== WITHOUT any patch, plain v6.0.16 kernel:

root@colibri-imx6ull-emmc-06906487:~# echo on > /sys/bus/platform/devices/ci_hdrc.1/power/control
root@colibri-imx6ull-emmc-06906487:~# cat /sys/kernel/debug/usb/ci_hdrc.1/registers
USBINTR reg: 00000037
USBSTS reg: 00040088
USBMODE reg: 00005003
USBCMD reg: 00010005
PORTSC reg: 18601a85
OTGSC reg: 00200520

And these the various valid bits - correct me if I'm wrong.
 - AVV is NOT set
 - ASV is set
 - BSP is NOT set


> BTW, how is __mxs_phy_disconnect_line() impacting this issue
> result on your HW? If not called, then the direct plug usb device
> to the OTG2 port can work, but adding an external hub between still
> cannot work?

== Running Linux 6.0.16, WITH the patch shared on this email thread.

With NO external HUB:
 - it does not work and it does not recover in any way

With external HUB:
 - `reset high-speed USB` every 2 seconds, it stops as soon as I connect something to the USB HUB.



== Running Linux 6.0.16, WITH the patch shared on this email thread

with the following patch in addition

diff --git a/drivers/usb/phy/phy-mxs-usb.c b/drivers/usb/phy/phy-mxs-usb.c
index 3e190638bcae..1a4ec039005b 100644
--- a/drivers/usb/phy/phy-mxs-usb.c
+++ b/drivers/usb/phy/phy-mxs-usb.c
@@ -424,7 +424,7 @@ static void mxs_phy_disconnect_line(struct mxs_phy *mxs_phy, bool on)
        if (!mxs_phy->regmap_anatop)
                return;

-       vbus_is_on = mxs_phy_get_vbus_status(mxs_phy);
+       vbus_is_on = true; // mxs_phy_get_vbus_status(mxs_phy);

        if (on && !vbus_is_on && !mxs_phy_is_otg_host(mxs_phy))
                __mxs_phy_disconnect_line(mxs_phy, true);


the behavior is greatly improved. It just works fine 95% of the time,
but sometime, after doing multiple plug in/out it fails to recognize
the device and it does not really recover. I never saw this behavior
just disabling runtimepm that is our current workaround.

Francesco




[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux