phy: rockchip: inno-usb2: fix otg port with vbus always on

The otg port on Rockchip platforms can be designed in
three different hardware circuits with Type-A interface.

1. RK3588 EVB2 Type-A OTG0 port with vbus is controlled
   by gpio, and vbus is always in high level.

2. RV1106 EVB1 Type-A OTG port with standard vbus designed
   that vbus isn't always on, and just depends on the OTG
   mode, that is, when the OTG port work as device mode,
   the vbus is supplied by Host, when the OTG port work
   as host mode, the vbus is always on.

3. RV1103 EVB1 Type-A OTG port has no vbus pin, and we set
   the utmi_bvalid of phy to high from GRF software control.
   In this case, the utmi_bvalid status register is in low
   level, so we can't use the utmi_bvalid status to check the
   utmi_bvalid for RV1103.

In order to support the above three application scenarios
for Type-A OTG port, especially phy runtime suspend control
for device mode, we need this patch.

With this patch, we can fix the following two issues:

1. RV1106 EVB1 Type-A OTG port can't enter phy suspend if
   no usb cable connected.

2. RV1103 failed to switch to device mode by "otg_mode"
   node, because phy enter suspend unexpectedly.

Signed-off-by: William Wu <william.wu@rock-chips.com>
Change-Id: Ia0d388345a4768a721a7e289956bca9684f69a36
This commit is contained in:
William Wu
2022-05-16 12:07:43 +08:00
committed by Tao Huang
parent c8c84e5b9c
commit 00168bb5b5

View File

@@ -954,7 +954,8 @@ static int rockchip_usb2phy_set_mode(struct phy *phy,
rockchip_set_vbus_power(rport, false);
extcon_set_state_sync(rphy->edev, EXTCON_USB_VBUS_EN, false);
/* For vbus always on, set EXTCON_USB to true. */
extcon_set_state(rphy->edev, EXTCON_USB, true);
if (rport->vbus_always_on)
extcon_set_state(rphy->edev, EXTCON_USB, true);
rport->perip_connected = true;
vbus_det_en = true;
break;
@@ -969,7 +970,8 @@ static int rockchip_usb2phy_set_mode(struct phy *phy,
extcon_set_state_sync(rphy->edev, EXTCON_USB_VBUS_EN, true);
/* For vbus always on, deinit EXTCON_USB to false. */
extcon_set_state(rphy->edev, EXTCON_USB, false);
if (rport->vbus_always_on)
extcon_set_state(rphy->edev, EXTCON_USB, false);
rport->perip_connected = false;
fallthrough;
case PHY_MODE_INVALID:
@@ -2092,10 +2094,6 @@ static int rockchip_usb2phy_otg_port_init(struct rockchip_usb2phy *rphy,
return ret;
}
if (rport->vbus_always_on || rport->mode == USB_DR_MODE_HOST ||
rport->mode == USB_DR_MODE_UNKNOWN)
goto out;
/*
* Set the utmi bvalid come from the usb phy or grf.
* For most of Rockchip SoCs, them have VBUSDET pin
@@ -2113,6 +2111,13 @@ static int rockchip_usb2phy_otg_port_init(struct rockchip_usb2phy *rphy,
property_enable(base, &rport->port_cfg->bvalid_grf_sel, false);
}
if (rport->vbus_always_on)
extcon_set_state(rphy->edev, EXTCON_USB, true);
if (rport->vbus_always_on || rport->mode == USB_DR_MODE_HOST ||
rport->mode == USB_DR_MODE_UNKNOWN)
goto out;
wake_lock_init(&rport->wakelock, WAKE_LOCK_SUSPEND, "rockchip_otg");
INIT_DELAYED_WORK(&rport->bypass_uart_work,
rockchip_usb_bypass_uart_work);