From: Federico Amedeo Izzo <[email protected]> The qcom UFS driver works without touching the regulators on most platforms as ABL leaves them already configured and enabled. On some SC7280 phones with UFS 3.1 like nothing-spacewar, vcc regulator is not enabled by ABL, so we need to configure and enable it to use the UFS storage.
Tested on nothing-spacewar and motorola-dubai using Tauchgang U-Boot. Signed-off-by: Federico Amedeo Izzo <[email protected]> --- drivers/ufs/ufs-qcom.c | 33 +++++++++++++++++++++++++++++++++ drivers/ufs/ufs-qcom.h | 4 ++++ 2 files changed, 37 insertions(+) diff --git a/drivers/ufs/ufs-qcom.c b/drivers/ufs/ufs-qcom.c index dc40ee62daf..376be2eeaaf 100644 --- a/drivers/ufs/ufs-qcom.c +++ b/drivers/ufs/ufs-qcom.c @@ -16,6 +16,7 @@ #include <generic-phy.h> #include <asm/gpio.h> #include <interconnect.h> +#include <power/regulator.h> #include <linux/bitops.h> #include <linux/delay.h> @@ -557,10 +558,31 @@ static void ufs_qcom_dev_ref_clk_ctrl(struct ufs_hba *hba, bool enable) static int ufs_qcom_init(struct ufs_hba *hba) { struct ufs_qcom_priv *priv = dev_get_priv(hba->dev); + int mode; int err; priv->hba = hba; + /* Apply regulator initial-mode from dts */ + err = dev_read_u32(priv->vcc, "regulator-initial-mode", &mode); + if (!err) { + err = regulator_set_mode(priv->vcc, mode); + if (err && err != -ENOSYS) + dev_warn(hba->dev, "failed to set vcc-supply mode:%d\n", err); + } + + err = regulator_set_enable(priv->vcc, true); + if (err && err != -ENOSYS) + dev_warn(hba->dev, "failed to enable regulator vcc-supply:%d\n", err); + + err = regulator_set_enable(priv->vccq, true); + if (err && err != -ENOSYS) + dev_warn(hba->dev, "failed to enable regulator vccq-supply:%d\n", err); + + err = regulator_set_enable(priv->vccq2, true); + if (err && err != -ENOSYS) + dev_warn(hba->dev, "failed to enable regulator vccq2-supply:%d\n", err); + /* setup clocks */ ufs_qcom_setup_clocks(hba, true, PRE_CHANGE); @@ -651,6 +673,17 @@ static int ufs_qcom_probe(struct udevice *dev) dev_err(dev, "Warning: cannot get reset GPIO\n"); } + ret = device_get_supply_regulator(dev, "vcc-supply", &priv->vcc); + if (ret) + dev_warn(dev, "failed to get regulator vcc-supply:%d\n", ret); + + ret = device_get_supply_regulator(dev, "vccq-supply", &priv->vccq); + if (ret) + dev_warn(dev, "failed to get regulator vccq-supply:%d\n", ret); + + /* vccq2 is optional on UFS2 and missing on UFS3 and later */ + device_get_supply_regulator(dev, "vccq2-supply", &priv->vccq2); + ret = ufshcd_probe(dev, &ufs_qcom_hba_ops); if (ret) { dev_err(dev, "ufshcd_probe() failed, ret:%d\n", ret); diff --git a/drivers/ufs/ufs-qcom.h b/drivers/ufs/ufs-qcom.h index de957ae60f3..115565db7e9 100644 --- a/drivers/ufs/ufs-qcom.h +++ b/drivers/ufs/ufs-qcom.h @@ -134,6 +134,10 @@ struct ufs_qcom_priv { struct clk_bulk clks; bool is_clks_enabled; + struct udevice *vcc; + struct udevice *vccq; + struct udevice *vccq2; + struct ufs_hw_version hw_ver; /* Reset control of HCI */ -- 2.54.0

