From a8c976f55a027707d49753be3cdc83802f7a0a0e Mon Sep 17 00:00:00 2001 From: Hemant Kumar Date: Thu, 1 Dec 2016 19:56:10 -0800 Subject: [PATCH] usb: phy: qusb2: Add support to vote for regulator L2a L2a is required to lock the phy PLL upon bus resume when exiting from XO shutdown. This LDO powers REFGEN block which is required to be powered on so that phy PLL gets locked as part of wakeup from XO shutdown. Change-Id: Ia0e3d574de7c78534832e4f8749672eb6fcde1f0 Signed-off-by: Hemant Kumar --- Documentation/devicetree/bindings/usb/msm-phy.txt | 1 + arch/arm/boot/dts/qcom/msm8998.dtsi | 1 + drivers/usb/phy/phy-msm-qusb-v2.c | 47 ++++++++++++++++++++++- 3 files changed, 48 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/usb/msm-phy.txt b/Documentation/devicetree/bindings/usb/msm-phy.txt index b45ee910258e..032f07535415 100644 --- a/Documentation/devicetree/bindings/usb/msm-phy.txt +++ b/Documentation/devicetree/bindings/usb/msm-phy.txt @@ -178,6 +178,7 @@ Required properties: "vdd" : vdd supply for digital circuit operation "vdda18" : 1.8v high-voltage analog supply "vdda33" : 3.3v high-voltage analog supply + "vdda12" : 1.2v high-voltage analog supply - qcom,vdd-voltage-level: This property must be a list of three integer values (no, min, max) where each value represents either a voltage in microvolts or a value corresponding to voltage corner diff --git a/arch/arm/boot/dts/qcom/msm8998.dtsi b/arch/arm/boot/dts/qcom/msm8998.dtsi index 0b54647fedfb..c265eafcdd30 100644 --- a/arch/arm/boot/dts/qcom/msm8998.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998.dtsi @@ -1762,6 +1762,7 @@ reg-names = "qusb_phy_base", "tcsr_clamp_dig_n_1p8"; vdd-supply = <&pm8998_l1>; + vdda12-supply = <&pm8998_l2>; vdda18-supply = <&pm8998_l12>; vdda33-supply = <&pm8998_l24>; qcom,vdd-voltage-level = <0 880000 880000>; diff --git a/drivers/usb/phy/phy-msm-qusb-v2.c b/drivers/usb/phy/phy-msm-qusb-v2.c index 5a768ee4d061..86908d2ce9d5 100644 --- a/drivers/usb/phy/phy-msm-qusb-v2.c +++ b/drivers/usb/phy/phy-msm-qusb-v2.c @@ -51,6 +51,10 @@ #define QUSB2PHY_PORT_TUNE1 0x23c +#define QUSB2PHY_1P2_VOL_MIN 1200000 /* uV */ +#define QUSB2PHY_1P2_VOL_MAX 1200000 /* uV */ +#define QUSB2PHY_1P2_HPM_LOAD 23000 + #define QUSB2PHY_1P8_VOL_MIN 1800000 /* uV */ #define QUSB2PHY_1P8_VOL_MAX 1800000 /* uV */ #define QUSB2PHY_1P8_HPM_LOAD 30000 /* uA */ @@ -83,6 +87,7 @@ struct qusb_phy { struct regulator *vdd; struct regulator *vdda33; struct regulator *vdda18; + struct regulator *vdda12; int vdd_levels[3]; /* none, low, high */ int init_seq_len; int *qusb_phy_init_seq; @@ -184,10 +189,30 @@ static int qusb_phy_enable_power(struct qusb_phy *qphy, bool on, } } + ret = regulator_set_load(qphy->vdda12, QUSB2PHY_1P2_HPM_LOAD); + if (ret < 0) { + dev_err(qphy->phy.dev, "Unable to set HPM of vdda12:%d\n", ret); + goto disable_vdd; + } + + ret = regulator_set_voltage(qphy->vdda12, QUSB2PHY_1P2_VOL_MIN, + QUSB2PHY_1P2_VOL_MAX); + if (ret) { + dev_err(qphy->phy.dev, + "Unable to set voltage for vdda12:%d\n", ret); + goto put_vdda12_lpm; + } + + ret = regulator_enable(qphy->vdda12); + if (ret) { + dev_err(qphy->phy.dev, "Unable to enable vdda12:%d\n", ret); + goto unset_vdda12; + } + ret = regulator_set_load(qphy->vdda18, QUSB2PHY_1P8_HPM_LOAD); if (ret < 0) { dev_err(qphy->phy.dev, "Unable to set HPM of vdda18:%d\n", ret); - goto disable_vdd; + goto disable_vdda12; } ret = regulator_set_voltage(qphy->vdda18, QUSB2PHY_1P8_VOL_MIN, @@ -262,6 +287,20 @@ put_vdda18_lpm: if (ret < 0) dev_err(qphy->phy.dev, "Unable to set LPM of vdda18\n"); +disable_vdda12: + ret = regulator_disable(qphy->vdda12); + if (ret) + dev_err(qphy->phy.dev, "Unable to disable vdda12:%d\n", ret); +unset_vdda12: + ret = regulator_set_voltage(qphy->vdda12, 0, QUSB2PHY_1P2_VOL_MAX); + if (ret) + dev_err(qphy->phy.dev, + "Unable to set (0) voltage for vdda12:%d\n", ret); +put_vdda12_lpm: + ret = regulator_set_load(qphy->vdda12, 0); + if (ret < 0) + dev_err(qphy->phy.dev, "Unable to set LPM of vdda12\n"); + disable_vdd: if (toggle_vdd) { ret = regulator_disable(qphy->vdd); @@ -985,6 +1024,12 @@ static int qusb_phy_probe(struct platform_device *pdev) return PTR_ERR(qphy->vdda18); } + qphy->vdda12 = devm_regulator_get(dev, "vdda12"); + if (IS_ERR(qphy->vdda12)) { + dev_err(dev, "unable to get vdda12 supply\n"); + return PTR_ERR(qphy->vdda12); + } + platform_set_drvdata(pdev, qphy); qphy->phy.label = "msm-qusb-phy-v2"; -- 2.11.0