Hello,
I am working on Freescale Vybrid with a Chipidea based USB controller and a Sigmatel Phy or something if my memory serves me right. We are currently in the process of implementing suspend resume and fixing related issues. After resume the USB PHY does not come up and the USB subsytem prints
[129.570097] usb 1-1: USB disconnect, device number 2
which comes from the core code in hub.c.
I am using the 4.1.5 kernel with some of our own patches especially with regards to suspend resume being present only in our own tree which we plan to eventually push out to mainline.
From what I can see, the USB USBPHYx_PWDn register which has bits related to power down, all stay in their default "1" state which denotes power down, after resume. Now this is in spite of the fact that the code seems [2] to write 0 to the register on resume. However, doing a quick check with devmem2 shows the register to have the default values of "1" denoting power down. So write seems to have no effect at all.
Instead of the code at lines 392[1] and 394[2] if I do
return mxs_phy_hw_init(mxs_phy);
on resume, the USBPHYx_PWDn seems to have the correct value of all bits as zero. However of course, the USB PHY does not come up. The stmp block reset in mxs_phy_hw_init seems to make the write work.
There is an errata for Vybrid at [3] in VYBRID_2N02G going as e4535: USB: USB suspend and resume flow clarifications. Not sure if I understand the explanation, however the following workaround which the errata mentions:
To place the USB PHY in low power suspend mode, the following sequence should be performed in an atomic operation. (interrupts should be disabled during these three steps)
1. Set the PORTSC1.PHCD bit
2. Set all bits in USBPHY_PWD register
3. Set the USBPHY_CTRL.CLKGATE bit
These sequence of steps seem to be correctly followed in the suspend code [4] of Chipidea IP AFAICT.
I am not that well versed with USB subsystem code having only worked on it once before for fixing non working USB client on Vybrid [5]. Have tried messing with different register bits in the USB PHY, USBPHY_CTRL and USB miscellaneous register like UTMI_SUSPENDM, HOST_FORCE_LS_SE0 and HOST_RESUME_DEBUG but with no results. Have already made sure that all the ANADIG and CCM registers are at their correct values after resume.
From what I can see this seems to be USB PHY issue.
MXS_PHY_ABNORMAL_IN_SUSPEND and MXS_PHY_SENDING_SOF_TOO_FAST, these two flags are not implemented in mainline. However implementing them with old patches from mainline and the way it is done in Freescale's 3.14 kernel release does not help either.
Is there an errata with the USB suspend resume issue of Chipidea IP core and Sigmatel PHY on Vybrid? Can anyone from Freescale or one of the hardware IC engineers know of steps to bring up the USB PHY on resume?
Thanks & Regards,
Sanchayan.
[1]. http://lxr.free-electrons.com/source/drivers/usb/phy/phy-mxs-usb.c#L392
[2]. http://lxr.free-electrons.com/source/drivers/usb/phy/phy-mxs-usb.c#L394
[3]. http://www.freescale.com/webapp/sps/site/prod_summary.jsp?code=VF6xx&fpsp=1&tab=Documentation_Tab
[4]. http://lxr.free-electrons.com/source/drivers/usb/chipidea/core.c#L891
[5]. https://lkml.org/lkml/2014/12/19/110
已解决! 转到解答。
Hello Richard,
Thanks for the ping. sanchayanmaity - as you note at the beginning of this thread, our 3.13 kernel doesn't implement this, and you're working on a much more recent release. Given the amount of investigation already undertaken by you and Freescale engineers, perhaps we can discuss this outside the forum to determine a cooperative effort to further investigate.
In the interim, I have passed this to our Vybrid engineers for review.
Thank you,
Timesys Support
timesyssupport do you have an update?
Hello Karina,
At this time, I do not. As noted, this is not present in our 3.0, or 3.13 kernel support; as the MX6 USB team has reviewed this an not seen an issue, perhaps the Freescale Vybrid team may have some insight?
Regards,
Timesys Support
The Vybrid team just handed it off to Timesys Support because the RESET bit in the PHY was set when the system resumed from suspend.
I checked previously with the FSL MX6 Linux team and they confirmed this RESET is not being set in the i.MX6 USB driver.
So my conclusion is that the Vybrid USB driver sets the PHY reset bit when it should not be set. Possibly the addition of the suspend/resume functionality triggers this in some way.
Best regards,
Richard
Hello,
We implemented the suspend resume support on Vybrid and while we have had to fix quite a few drivers for suspend resume to work, USB was not one of them. I have been working on USB suspend resume issue for a while now but no modifications have been made to the USB code in any way for suspend resume.
Coming back to the main question, which I will raise once again
391 mxs_phy_clock_switch_delay();
392 ret = clk_prepare_enable(mxs_phy->clk);
395 writel(BM_USBPHY_CTRL_CLKGATE,
396 x->io_priv + HW_USBPHY_CTRL_CLR);
397 writel(0, x->io_priv + HW_USBPHY_PWD);
Above is the code which gets executed in suspend path of phy-mxs-usb.c which is the USB PHY driver for all iMXs and Vybrid. The clock is enabled, clock gating is removed and 0 is written to USBPHY_PWD register. However if I read the value of USBPHY_PWD after this, it has 1's in the locations that matter which indicate power down.
If I check all clocks and PLL's they seem to be fine. The SFTRST bit is only ever set and then cleared during initialisation indirectly here with a call to stmp_reset_block.
Linux/drivers/usb/phy/phy-mxs-usb.c - Linux Cross Reference - Free Electrons
Nothing else sets SFTRST which can be checked as simply as by searching for it in the driver. While it is defined, it is not referenced anywhere.
Linux/drivers/usb/phy/phy-mxs-usb.c - Linux Cross Reference - Free Electrons
While I am already looking at our suspend resume implementation and comparing it with iMX6 but the above is my primary question. Is there something which can make SFTRST held and asserted even though it is not being asserted anywhere in the driver itself? And no the suspend resume code does not set it atleast not directly. If some particular setting or sequence of operations do this indirectly, then I am not aware, USB is not touched at all in core suspend resume PM code. Why even when 0 is being written to PWD register does it have no effect at all? If this is due to SFTRST, then manually clearing it is not suppose to work?
- Sanchayan.
I am not sure this is the right forum to bring this up, or if it is even fully related but we seem to have the same issue, was wondering if there ever was a resolution to this? I don't have the same USB chip I believe, but seem to have the same symptom
I am not sure if I have picked up this problem by adding a USB interface driver too many or if it was there from the start.
But I can get the USB backup and running after resume by rebinding it
echo -n ci_hdrc.0 > unbind
echo -n ci_hdrc.0 > bind
This is what suspend looks like
[158534.857346] usb 1-1: USB disconnect, device number 2
[158536.734315] usb 2-1: USB disconnect, device number 2
[158536.891107] option1 ttyUSB0: GSM modem (1-port) converter now disconnected from ttyUSB0
[158537.079254] option1 ttyUSB1: GSM modem (1-port) converter now disconnected from ttyUSB1
[158537.252492] option1 ttyUSB2: GSM modem (1-port) converter now disconnected from ttyUSB2
[158537.446913] option1 ttyUSB3: GSM modem (1-port) converter now disconnected from ttyUSB3
And here is the rebind (you can see the disconnect for unbind)
[160674.068857] usb usb1: USB disconnect, device number 1
[160674.082197] ci_hdrc ci_hdrc.0: USB bus 1 deregistered
[160682.085904] ci_hdrc ci_hdrc.0: new USB bus registered, assigned bus number 1
[160682.111159] ci_hdrc ci_hdrc.0: USB 2.0 started, EHCI 1.00
[160682.123253] hub 1-0:1.0: USB hub found
[160682.471362] usb 1-1: new high-speed USB device number 2 using ci_hdrc
[160682.771626] usb 1-1: reset high-speed USB device number 2 using ci_hdrc
[160700.260155] usb usb2: USB disconnect, device number 1
[160700.273563] ci_hdrc ci_hdrc.1: USB bus 2 deregistered
[160703.128948] ci_hdrc ci_hdrc.1: new USB bus registered, assigned bus number 2
[160703.151672] ci_hdrc ci_hdrc.1: USB 2.0 started, EHCI 1.00
[160703.167571] hub 2-0:1.0: USB hub found
[160703.522047] usb 2-1: new high-speed USB device number 2 using ci_hdrc
[160703.780430] usb 2-1: GSM modem (1-port) converter now attached to ttyUSB0
[160703.903555] usb 2-1: GSM modem (1-port) converter now attached to ttyUSB1
[160704.092937] usb 2-1: GSM modem (1-port) converter now attached to ttyUSB2
[160704.369570] usb 2-1: GSM modem (1-port) converter now attached to ttyUSB3
Not sure if that worked in the case above as well?
Hi Niclas,
I'm not a Linux engineer, but assuming that unbind and bind are unloading and loading the device driver, then that is not suspend/resume.
With suspend/resume, the driver remains loaded and both the host and the peripheral keep their configuration during suspend. There is just no communication during suspend, and the device can go in to low-power retention mode if so desired.
Best regards,
Richard
Yes, the unbind/bind was done after the resume from sleep. To get it all working again, as the driver won't resume properly. It has now been verified that we have and see the same issue with the flags from the USB PHY.
I was merely wondering if unbind/bind after a stuck resume would bring the USB back online for Sanchayan as well. As it might suggest that the problem might be outside the driver or some other driver dipping its feet where it shouldn't.
Hello Niclas,
Thank you very much for sharing your findings here.
I can confirm that the unbinding and binding does work and can serve as a possible workaround for the moment. I must admit that I have not looked into the suspend resume issue for quite a while now but it still remains one the primary open issues with respect to suspend resume on Vybrid for us. Will start looking into it again perhaps.
- Sanchayan.
Just to make sure, in USB terms suspend means no activity on the bus and peripheral draws no more thna 5 mA on VBUS.
I sometimes see system suspend (System low power retention mode) being associated with USB suspend, but these are 2 different things. USB can be suspended with the system fully operational (ex as host, suspend bus to put a peripheral into low-power mode to reduce current draw).
In this case, the host can resume the bus when it needs the peripheral, or the peripheral can request the host to resume the bus when it needs to be serviced.
Regards,
Richard
sanchayanmaity did you get previous comment?
Hello Richard,
Yes, both the module clock bits show it is running.
Before suspend,
CCM_CCGR1 0x30c3030c
CCM_CCGR7 0x00c00300
After resume,
CCM_CCGR1 0x30c3030c
CCM_CCGR7 0x00c00300
Both occupy the 9th and 8th bit positions in the CCM_CCGRn registers and as per the above register values, they are both on after resume.
And also the clock gate is removed, because if it didn't work properly, the immediate write of "0" to PWD after removing the clock gate would fail and the SoC never resumes requiring a power reset.
- Sanchayan.
Hi,
I have looked for an example with not success. rendy I hope you are doing well and sorry to trouble you, but do you know if we have some validation code or snippet code that can be helpful for Sanchayan?
Thanks a lot,
Alejandro
Or maybe richard_stulens will have some hint
/Jiri
timesyssupport can you help to attend this case?
Hello,
I do not think the Timesys guys will be of help here. They are still with 3.13 kernel as far as I am aware and they do not have suspend resume support implemented for Vybrid.
Only some engineer from inside Freescale can probably resolve this, as to what is required specifically for the USB PHY to work out of resume.
- Sanchayan.