From d948568a1f7bfbbb482c9ee39dae2c7580e24852 Mon Sep 17 00:00:00 2001 From: Hemant Kumar Date: Thu, 29 Nov 2018 18:50:54 -0800 Subject: [PATCH] usb: phy: snps: Ensure VDDA regulator is put in HPM To properly ensure that the vdd regulator is put in the correct operating mode, it needs to have a call to regulator_set_load() prior to being enabled. This is crucial for platforms where the HS PHY is the only consumer of the regulator as it could be inadvertently left in LPM mode and cause the PHY to not function properly. Change-Id: I87815c60f044d854ecc75ac6039fd80c2d3197aa Signed-off-by: Hemant Kumar --- drivers/usb/phy/phy-msm-snps-hs.c | 47 ++++++++++++++----------------- 1 file changed, 21 insertions(+), 26 deletions(-) diff --git a/drivers/usb/phy/phy-msm-snps-hs.c b/drivers/usb/phy/phy-msm-snps-hs.c index 35a46f7360aa..342fbb2ff90c 100644 --- a/drivers/usb/phy/phy-msm-snps-hs.c +++ b/drivers/usb/phy/phy-msm-snps-hs.c @@ -81,6 +81,8 @@ #define USB_HSPHY_1P8_VOL_MAX 1800000 /* uV */ #define USB_HSPHY_1P8_HPM_LOAD 19000 /* uA */ +#define USB_HSPHY_VDD_HPM_LOAD 30000 /* uA */ + struct msm_hsphy { struct usb_phy phy; void __iomem *base; @@ -146,23 +148,6 @@ static void msm_hsphy_enable_clocks(struct msm_hsphy *phy, bool on) } } -static int msm_hsphy_config_vdd(struct msm_hsphy *phy, int high) -{ - int min, ret; - - min = high ? 1 : 0; /* low or none? */ - ret = regulator_set_voltage(phy->vdd, phy->vdd_levels[min], - phy->vdd_levels[2]); - if (ret) { - dev_err(phy->phy.dev, "unable to set voltage for hsusb vdd\n"); - return ret; - } - - dev_dbg(phy->phy.dev, "%s: min_vol:%d max_vol:%d\n", __func__, - phy->vdd_levels[min], phy->vdd_levels[2]); - - return ret; -} static int msm_hsphy_enable_power(struct msm_hsphy *phy, bool on) { @@ -179,13 +164,19 @@ static int msm_hsphy_enable_power(struct msm_hsphy *phy, bool on) if (!on) goto disable_vdda33; - ret = msm_hsphy_config_vdd(phy, true); - if (ret) { - dev_err(phy->phy.dev, "Unable to config VDD:%d\n", - ret); + ret = regulator_set_load(phy->vdd, USB_HSPHY_VDD_HPM_LOAD); + if (ret < 0) { + dev_err(phy->phy.dev, "Unable to set HPM of vdd:%d\n", ret); goto err_vdd; } + ret = regulator_set_voltage(phy->vdd, phy->vdd_levels[1], + phy->vdd_levels[2]); + if (ret) { + dev_err(phy->phy.dev, "unable to set voltage for hsusb vdd\n"); + goto put_vdd_lpm; + } + ret = regulator_enable(phy->vdd); if (ret) { dev_err(phy->phy.dev, "Unable to enable VDD\n"); @@ -272,14 +263,18 @@ put_vdda18_lpm: disable_vdd: ret = regulator_disable(phy->vdd); if (ret) - dev_err(phy->phy.dev, "Unable to disable vdd:%d\n", - ret); + dev_err(phy->phy.dev, "Unable to disable vdd:%d\n", ret); unconfig_vdd: - ret = msm_hsphy_config_vdd(phy, false); + ret = regulator_set_voltage(phy->vdd, phy->vdd_levels[0], + phy->vdd_levels[2]); if (ret) - dev_err(phy->phy.dev, "Unable unconfig VDD:%d\n", - ret); + dev_err(phy->phy.dev, "unable to set voltage for hsusb vdd\n"); + +put_vdd_lpm: + ret = regulator_set_load(phy->vdd, 0); + if (ret < 0) + dev_err(phy->phy.dev, "Unable to set LPM of vdd\n"); err_vdd: phy->power_enabled = false; dev_dbg(phy->phy.dev, "HSUSB PHY's regulators are turned OFF.\n");