From 5eac5e9c0f515f8e452321b159b4093065dfc757 Mon Sep 17 00:00:00 2001 From: Chris Zhong Date: Fri, 16 Feb 2018 13:09:54 +0100 Subject: [PATCH] phy: rockchip-typec: force to USB2 if DP at 4 lanes mode The usb3tousb2_en BIT will be clear to 0 in probe(), it make USB controller work at USB3 mode, and if the USB phy is turned on with DP only mode(4 lanes DP), the rockchip_usb3_phy_power_on() will return directly, so usb3_host_disable and usb3_host_port these 2 BIT will keep a same value as coreboot. In coreboot, these 3 BITs are set as USB2 mode, but now one of the bits is changed to USB3, it make USB controller work at a unknown status. These 3 BITs should be changed to USB2, if the Type-C works at 4 lanes mode, and then switch it back to USB3 mode, when USB disconnect. Signed-off-by: Chris Zhong Signed-off-by: Enric Balletbo i Serra Reviewed-by: Heiko Stuebner Signed-off-by: Kishon Vijay Abraham I --- drivers/phy/rockchip/phy-rockchip-typec.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/drivers/phy/rockchip/phy-rockchip-typec.c b/drivers/phy/rockchip/phy-rockchip-typec.c index 54dc52a..9bc4d4b 100644 --- a/drivers/phy/rockchip/phy-rockchip-typec.c +++ b/drivers/phy/rockchip/phy-rockchip-typec.c @@ -853,6 +853,18 @@ static int tcphy_get_mode(struct rockchip_typec_phy *tcphy) return mode; } +static int tcphy_cfg_usb3_to_usb2_only(struct rockchip_typec_phy *tcphy, + bool value) +{ + struct rockchip_usb3phy_port_cfg *cfg = tcphy->port_cfgs; + + property_enable(tcphy, &cfg->usb3tousb2_en, value); + property_enable(tcphy, &cfg->usb3_host_disable, value); + property_enable(tcphy, &cfg->usb3_host_port, !value); + + return 0; +} + static int rockchip_usb3_phy_power_on(struct phy *phy) { struct rockchip_typec_phy *tcphy = phy_get_drvdata(phy); @@ -870,8 +882,10 @@ static int rockchip_usb3_phy_power_on(struct phy *phy) } /* DP-only mode; fall back to USB2 */ - if (!(new_mode & (MODE_DFP_USB | MODE_UFP_USB))) + if (!(new_mode & (MODE_DFP_USB | MODE_UFP_USB))) { + tcphy_cfg_usb3_to_usb2_only(tcphy, true); goto unlock_ret; + } if (tcphy->mode == new_mode) goto unlock_ret; @@ -887,9 +901,9 @@ static int rockchip_usb3_phy_power_on(struct phy *phy) regmap_read(tcphy->grf_regs, reg->offset, &val); if (!(val & BIT(reg->enable_bit))) { tcphy->mode |= new_mode & (MODE_DFP_USB | MODE_UFP_USB); + /* enable usb3 host */ - property_enable(tcphy, &cfg->usb3_host_disable, 0); - property_enable(tcphy, &cfg->usb3_host_port, 1); + tcphy_cfg_usb3_to_usb2_only(tcphy, false); goto unlock_ret; } usleep_range(10, 20); @@ -910,6 +924,7 @@ static int rockchip_usb3_phy_power_off(struct phy *phy) struct rockchip_typec_phy *tcphy = phy_get_drvdata(phy); mutex_lock(&tcphy->lock); + tcphy_cfg_usb3_to_usb2_only(tcphy, false); if (tcphy->mode == MODE_DISCONNECT) goto unlock; -- 2.7.4