phy: rockchip: inno-usb2: fix phy reset during power on for rk3588

The RK3588 USB2 PHY provides CLK12MOHCI and CLK48MOHCI to
OHCI controllers, and the two clocks are turned off upon
PHY reset, therefore it shouldn't access OHCI Controller
if USB2 PHY in reset. However, during the system PM resume,
the current USB2 PHY power on sequence with PHY reset
operation has potential risk that reset PHY accidentally
when OHCI platform resume access OHCI Controller, and
cause system hung.

The reason is EHCI/OHCI controllers resume ordering on
RK3588. In outline form, the hcd_bus_resume() of EHCI
and the ohci_resume() of OHCI operating concurrently on
different CPUs perform the following actions:

CPU 0                                   CPU 1
----------------------------            ---------------------------------
async_resume()
  usb_resume()
    hcd_bus_resume() -- EHCI
      usb_phy_roothub_resume()
        phy_power_on()
          rockchip_usb2phy_power_on()   ohci_platform_resume()
            rockchip_usb2phy_reset()      ohci_resume()
              assert phy reset              ...
                udelay(10);                 ohci_readl or ohci_writel

This patch fixes USB2 PHY reset during power on for RK3588,
only do USB2 PHY reset for RK3588 USB OTG0 and OTG1, because
their 'common_on_n' bit can be set to 1'b1 (aka REFCLK_LOGIC,
Bias, and PLL blocks are powered down) in PM runtime process.
And keep the 'common_on_n' to 1'b0 for RK3588 USB2 HOST0 and
HOST1, thus we don't need to do PHY reset during power on for
them.

This patch doesn't increase the USB2 PHY power consumption,
because the USB2 HOST0 and HOST1 don't support PM runtime
management, so actually the PHY PLL blocks of USB2 HOST0 and
HOST1 are always powered on.

Signed-off-by: William Wu <william.wu@rock-chips.com>
Change-Id: Ia0121a7c49bef4f0f3a1fb11a810e4ef95b29982
This commit is contained in:
William Wu
2022-10-10 11:27:24 +08:00
committed by Tao Huang
parent 9af1805a1b
commit d8db0c1fa4

View File

@@ -853,9 +853,12 @@ static int rockchip_usb2phy_power_on(struct phy *phy)
* please keep the common_on_n 1'b0 to set these blocks
* remain powered.
*/
ret = rockchip_usb2phy_reset(rphy);
if (ret)
goto unlock;
if (rport->port_id == USB2PHY_PORT_OTG &&
of_device_is_compatible(rphy->dev->of_node, "rockchip,rk3588-usb2phy")) {
ret = rockchip_usb2phy_reset(rphy);
if (ret)
goto unlock;
}
/* waiting for the utmi_clk to become stable */
usleep_range(1500, 2000);
@@ -3665,7 +3668,7 @@ static const struct rockchip_usb2phy_cfg rk3588_phy_cfgs[] = {
.reg = 0x8000,
.num_ports = 1,
.phy_tuning = rk3588_usb2phy_tuning,
.clkout_ctl = { 0x0000, 0, 0, 1, 0 },
.clkout_ctl = { 0x0000, 0, 0, 0, 0 },
.ls_filter_con = { 0x0040, 19, 0, 0x30100, 0x00020 },
.port_cfgs = {
[USB2PHY_PORT_HOST] = {
@@ -3687,7 +3690,7 @@ static const struct rockchip_usb2phy_cfg rk3588_phy_cfgs[] = {
.reg = 0xc000,
.num_ports = 1,
.phy_tuning = rk3588_usb2phy_tuning,
.clkout_ctl = { 0x0000, 0, 0, 1, 0 },
.clkout_ctl = { 0x0000, 0, 0, 0, 0 },
.ls_filter_con = { 0x0040, 19, 0, 0x30100, 0x00020 },
.port_cfgs = {
[USB2PHY_PORT_HOST] = {