phy: rockchip: inno-usb2: fix phy power off causes usb controller abnormal

Usb controller require the clk from phy to work normally. In the
current code, if the dr_mode is set to peripheral and limit to
high speed, there are two cases that usb controller will work
abnormally due to phy power off.

1. The USB cable is not plug in when system start up, at this
time, the otg_sm_work will call rockchip_usb2phy_power_off to
suspend phy. However, if the upper layer uses configfs to operate
the controller after phy power off, controller will work abnormally.

2. Plug in the usb cable and start up the system, the controller
works in peripheral mode and PC recongnize it. IF we unplug the
usb cable, the vbus will not detected, otg_sm_work will also call
rockchip_usb2phy_power_off to suspend phy, when the upper layer
use configfs to operate the controller, phy has been suspended,
controller will work abnormally.

To fix these cases, this patch add a new property "rockchip,dis-u2-
susphy" to avoid phy power off.

Signed-off-by: Jianwei Zheng <jianwei.zheng@rock-chips.com>
Change-Id: I6c9921c8060747667d7bedb2cf76a38a896c05f5
This commit is contained in:
Jianwei Zheng
2022-11-24 10:47:27 +08:00
committed by Tao Huang
parent 0960de8b28
commit 5df41387b9
2 changed files with 12 additions and 2 deletions

View File

@@ -166,6 +166,10 @@ properties:
controller. It's used when the usb3 phy is disabled, and it needs
to combine with the usbctrl-grf.
rockchip,dis-u2-susphy:
$ref: /schemas/types.yaml#/definitions/flag
description: when set, disable the usb2 phy enter suspend automatically.
required:
- "#phy-cells"
- interrupts

View File

@@ -243,6 +243,7 @@ struct rockchip_usb2phy_cfg {
* @vbus_enabled: vbus regulator status.
* @bypass_uart_en: usb bypass uart enable, passed from DT.
* @host_disconnect: usb host disconnect status.
* @dis_u2_susphy: disable usb2 phy suspend.
* @bvalid_irq: IRQ number assigned for vbus valid rise detection.
* @ls_irq: IRQ number assigned for linestate detection.
* @id_irq: IRQ number assigned for id fall or rise detection.
@@ -275,6 +276,7 @@ struct rockchip_usb2phy_port {
bool vbus_enabled;
bool bypass_uart_en;
bool host_disconnect;
bool dis_u2_susphy;
int bvalid_irq;
int ls_irq;
int id_irq;
@@ -1184,7 +1186,8 @@ static void rockchip_usb2phy_otg_sm_work(struct work_struct *work)
rport->state = OTG_STATE_B_IDLE;
if (!rport->vbus_attached) {
mutex_unlock(&rport->mutex);
rockchip_usb2phy_power_off(rport->phy);
if (!rport->dis_u2_susphy)
rockchip_usb2phy_power_off(rport->phy);
mutex_lock(&rport->mutex);
}
fallthrough;
@@ -1245,7 +1248,8 @@ static void rockchip_usb2phy_otg_sm_work(struct work_struct *work)
rphy->chg_state = USB_CHG_STATE_UNDEFINED;
rphy->chg_type = POWER_SUPPLY_TYPE_UNKNOWN;
mutex_unlock(&rport->mutex);
rockchip_usb2phy_power_off(rport->phy);
if (!rport->dis_u2_susphy)
rockchip_usb2phy_power_off(rport->phy);
mutex_lock(&rport->mutex);
}
break;
@@ -2054,6 +2058,8 @@ static int rockchip_usb2phy_otg_port_init(struct rockchip_usb2phy *rphy,
of_property_read_bool(child_np, "rockchip,vbus-always-on");
rport->utmi_avalid =
of_property_read_bool(child_np, "rockchip,utmi-avalid");
rport->dis_u2_susphy =
of_property_read_bool(child_np, "rockchip,dis-u2-susphy");
/* enter lower power state when suspend */
rport->low_power_en =