mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Sebastian Reichel <sebastian.reichel@collabora.com>
To: Manivannan Sadhasivam <mani@kernel.org>
Cc: Vinod Koul <vkoul@kernel.org>,
	 Neil Armstrong <neil.armstrong@linaro.org>,
	Heiko Stuebner <heiko@sntech.de>,
	 Maxime Chevallier <maxime.chevallier@bootlin.com>,
	linux-phy@lists.infradead.org,
	 linux-arm-kernel@lists.infradead.org,
	linux-rockchip@lists.infradead.org, linux-kernel@vger.kernel.org,
	 Igor Paunovic <royalnet026@gmail.com>,
	kernel@collabora.com
Subject: Re: [PATCH] phy: rockchip: inno-usb2: ensure PHY is running when clock is requested
Date: Tue, 29 Sep 2026 16:44:15 +0200	[thread overview]
Message-ID: <aru3ZSWtaHTdufXM@venus> (raw)
In-Reply-To: <arqnn8s5yFmZzQvG@venus>

[-- Attachment #1: Type: text/plain, Size: 5254 bytes --]

Hello Mani,

On Mon, Sep 28, 2026 at 08:00:24PM +0200, Sebastian Reichel wrote:
> On Sat, Sep 26, 2026 at 04:50:07AM +0200, Manivannan Sadhasivam wrote:
> > On Tue, Sep 08, 2026 at 06:07:42PM +0200, Sebastian Reichel wrote:
> > > On RK3588 the OHCI controller registers can only be accessed when the
> > > PHY's 480MHz clock is running. After system suspend the controller is
> > > resumed before the PHY.
> > 
> > This statement is slightly confusing. There is no PM ops in this
> > PHY driver.
> 
> I will take a closer look how it is powered off during suspend.
> Generally I expect it to loose state in any case as the related
> power domain should be disabled.

The PHY is disabled/enabled via generic hcd_bus_suspend and
hcd_bus_resume, which is called by usb_dev_suspend/usb_dev_resume
(i.e. the child USB bus PM handles the PHY power), which is a child
of the OHCI platform device.

The OHCI platform device itself just handles resets and clocks.

It works in the normal driver probe case, since there are no
controller registers accessed before the USB bus itself is started.

> > > The controller requests the clock, which opens
> > > the gate in the PHY's clock prepare function. But with the PHY suspended
> > > this just results in a dead clock being routed. The OHCI driver will
> > > then continue to access its registers resulting in a board hang.
> > > 
> > > Fix this by resuming the suspended PHY in the clock's prepare function,
> > > so that the clock is really prepared once the function returns.
> > > 
> > > Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
> > > ---
> > > This was noticed on RK3588 EVB1 when resuming from system suspend. This
> > > is technically a fix, but its unclear when the bug was introduced and
> > > system suspend is broken on RK3588 for quite a while and not just due
> > > to this problem. So I think this fix can be merged the normal way via
> > > linux-next.
> > > ---
> > >  drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 37 +++++++++++++++++++++++++++
> > >  1 file changed, 37 insertions(+)
> > > 
> > > diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
> > > index 7d8a533f24ae..07d400967def 100644
> > > --- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
> > > +++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
> > > @@ -332,6 +332,39 @@ rockchip_usb2phy_clk480m_clkout_ctl(struct clk_hw *hw, struct regmap **base,
> > >  	}
> > >  }
> > >  
> > > +static int rockchip_usb2phy_clk480m_leave_suspend(struct clk_hw *hw)
> > > +{
> > > +	struct rockchip_usb2phy *rphy = container_of(hw, struct rockchip_usb2phy, clk480m_hw);
> > > +	bool relock = false;
> > > +	int ret, i;
> > > +
> > > +	/* Limit to single port; it's unclear how multi-port should be handled */
> > > +	if (rphy->phy_cfg->num_ports > 1)
> > > +		return 0;
> > > +
> > > +	for (i = 0; i < rphy->phy_cfg->num_ports; i++) {
> > > +		struct rockchip_usb2phy_port *rport = &rphy->ports[i];
> > > +		const struct rockchip_usb2phy_port_cfg *port_cfg = rport->port_cfg;
> > > +
> > > +		if (!rport->phy || !port_cfg || !port_cfg->phy_sus.enable)
> > > +			continue;
> > > +		if (property_enabled(rphy->grf, &port_cfg->phy_sus)) {
> > > +			property_enable(rphy->grf, &port_cfg->phy_sus,
> > > +					false);
> > > +			relock = true;
> > > +		}
> > > +	}
> > > +
> > > +	if (relock) {
> > > +		ret = rockchip_usb2phy_reset(rphy);
> > > +		if (ret)
> > > +			return ret;
> > > +		usleep_range(1500, 2000);
> > > +	}
> > > +
> > 
> > This looks like a duplication of rockchip_usb2phy_power_on(). So I'm assuming
> > that phy_power_on() is not called by the OHCI driver before accessing the
> > registers. So why don't you fix that instead?
> 
> I can look into it. My way of thinking was, that the clock should be
> running independently of that when the clock has been requested via
> common clock framework.

The exact call trace is:

ohci_platform_resume
    -> ohci_platform_resume_common
        -> deassert resets
        -> ohci_platform_power_on -> enable clocks required by controller
        -> ohci_resume
            -> ohci_readl(ohci, &ohci->regs->control); // boom
            -> ...
        -> ...
    -> root hub being resumed will resume the PHY

The ohci_readl results in the mentioned crash, since the clock is
not enabled. The read is used to figure out if the controller is
already running. There is no bus operation, so the PHY is
technically not needed. Of course the controller's clocks have to
be enabled, though. It's just on RK3588 that this means the PHY
must be enabled.

I also checked Rockchip's vendor kernel for their solution: It
solved the problem by using device_link_add() from EHCI to OHCI
based on the RK3588 compatible, so that OHCI is always resumed after
EHCI. This fixes the problem, since both share the same PHY.

I think handling this in rockchip_usb2phy_clk480m_prepare() is the
cleanest option as the disabled clock is the real issue as far as
I can tell. I will look into improving the patch to re-use
rockchip_usb2phy_power_on and improve the commit message.

Greetings,

-- Sebastian

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

      reply	other threads:[~2026-09-29 14:44 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-08 16:07 Sebastian Reichel
2026-09-08 16:29 ` Igor Paunovic
2026-09-26  2:50 ` Manivannan Sadhasivam
2026-09-28 18:00   ` Sebastian Reichel
2026-09-29 14:44     ` Sebastian Reichel [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=aru3ZSWtaHTdufXM@venus \
    --to=sebastian.reichel@collabora.com \
    --cc=heiko@sntech.de \
    --cc=kernel@collabora.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-phy@lists.infradead.org \
    --cc=linux-rockchip@lists.infradead.org \
    --cc=mani@kernel.org \
    --cc=maxime.chevallier@bootlin.com \
    --cc=neil.armstrong@linaro.org \
    --cc=royalnet026@gmail.com \
    --cc=vkoul@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®