scsi: ufs-qcom: add device ref_clk pad regulator voting support

UFS device's phy ref_clk is sourced via MSM's ref_clk pad. This pad is
having its own power domain which is powered by 1.2v rail. This change
adds the voting support for this pad rail.

Change-Id: I179b2b9bb7ef2e7938ba0aaa87faed09cdad6139
Signed-off-by: Subhash Jadavani <subhashj@codeaurora.org>
[venkatg@codeaurora.org: dropped ufs-qcom.h and
include/linux/phy/phy-qcom-ufs.h changes]
Signed-off-by: Venkat Gopalakrishnan <venkatg@codeaurora.org>
This commit is contained in:
Subhash Jadavani 2014-10-29 19:20:13 -07:00 committed by David Keitel
parent f76e7d00c7
commit 2f94b8d7bd

View file

@ -232,12 +232,19 @@ ufs_qcom_phy_init_vregulators(struct phy *generic_phy,
err = ufs_qcom_phy_init_vreg(generic_phy, &phy_common->vdda_phy, err = ufs_qcom_phy_init_vreg(generic_phy, &phy_common->vdda_phy,
"vdda-phy"); "vdda-phy");
if (err)
goto out;
/* vddp-ref-clk-* properties are optional */
__ufs_qcom_phy_init_vreg(generic_phy, &phy_common->vddp_ref_clk,
"vddp-ref-clk", true);
out: out:
return err; return err;
} }
int ufs_qcom_phy_init_vreg(struct phy *phy, static int __ufs_qcom_phy_init_vreg(struct phy *phy,
struct ufs_qcom_phy_vreg *vreg, const char *name) struct ufs_qcom_phy_vreg *vreg, const char *name, bool optional)
{ {
int err = 0; int err = 0;
struct ufs_qcom_phy *ufs_qcom_phy = get_ufs_qcom_phy(phy); struct ufs_qcom_phy *ufs_qcom_phy = get_ufs_qcom_phy(phy);
@ -254,7 +261,9 @@ int ufs_qcom_phy_init_vreg(struct phy *phy,
vreg->reg = devm_regulator_get(dev, name); vreg->reg = devm_regulator_get(dev, name);
if (IS_ERR(vreg->reg)) { if (IS_ERR(vreg->reg)) {
err = PTR_ERR(vreg->reg); err = PTR_ERR(vreg->reg);
dev_err(dev, "failed to get %s, %d\n", name, err); vreg->reg = NULL;
if (!optional)
dev_err(dev, "failed to get %s, %d\n", name, err);
goto out; goto out;
} }
@ -274,6 +283,11 @@ int ufs_qcom_phy_init_vreg(struct phy *phy,
} }
err = 0; err = 0;
} }
snprintf(prop_name, MAX_PROP_NAME, "%s-always-on", name);
if (of_get_property(dev->of_node, prop_name, NULL))
vreg->is_always_on = true;
else
vreg->is_always_on = false;
} }
if (!strcmp(name, "vdda-pll")) { if (!strcmp(name, "vdda-pll")) {
@ -282,6 +296,9 @@ int ufs_qcom_phy_init_vreg(struct phy *phy,
} else if (!strcmp(name, "vdda-phy")) { } else if (!strcmp(name, "vdda-phy")) {
vreg->max_uV = VDDA_PHY_MAX_UV; vreg->max_uV = VDDA_PHY_MAX_UV;
vreg->min_uV = VDDA_PHY_MIN_UV; vreg->min_uV = VDDA_PHY_MIN_UV;
} else if (!strcmp(name, "vddp-ref-clk")) {
vreg->max_uV = VDDP_REF_CLK_MAX_UV;
vreg->min_uV = VDDP_REF_CLK_MIN_UV;
} }
out: out:
@ -425,7 +442,7 @@ int ufs_qcom_phy_disable_vreg(struct phy *phy,
struct device *dev = ufs_qcom_phy->dev; struct device *dev = ufs_qcom_phy->dev;
int ret = 0; int ret = 0;
if (!vreg || !vreg->enabled) if (!vreg || !vreg->enabled || vreg->is_always_on)
goto out; goto out;
ret = regulator_disable(vreg->reg); ret = regulator_disable(vreg->reg);
@ -643,9 +660,22 @@ int ufs_qcom_phy_power_on(struct phy *generic_phy)
goto out_disable_pll; goto out_disable_pll;
} }
/* enable device PHY ref_clk pad rail */
if (phy_common->vddp_ref_clk.reg) {
err = ufs_qcom_phy_enable_vreg(generic_phy,
&phy_common->vddp_ref_clk);
if (err) {
dev_err(dev, "%s enable vddp_ref_clk failed, err=%d\n",
__func__, err);
goto out_disable_ref_clk;
}
}
phy_common->is_powered_on = true; phy_common->is_powered_on = true;
goto out; goto out;
out_disable_ref_clk:
ufs_qcom_phy_disable_ref_clk(generic_phy);
out_disable_pll: out_disable_pll:
ufs_qcom_phy_disable_vreg(generic_phy, &phy_common->vdda_pll); ufs_qcom_phy_disable_vreg(generic_phy, &phy_common->vdda_pll);
out_disable_phy: out_disable_phy:
@ -660,6 +690,9 @@ int ufs_qcom_phy_power_off(struct phy *generic_phy)
phy_common->phy_spec_ops->power_control(phy_common, false); phy_common->phy_spec_ops->power_control(phy_common, false);
if (phy_common->vddp_ref_clk.reg)
ufs_qcom_phy_disable_vreg(generic_phy,
&phy_common->vddp_ref_clk);
ufs_qcom_phy_disable_ref_clk(generic_phy); ufs_qcom_phy_disable_ref_clk(generic_phy);
ufs_qcom_phy_disable_vreg(generic_phy, &phy_common->vdda_pll); ufs_qcom_phy_disable_vreg(generic_phy, &phy_common->vdda_pll);