From: Stanley Chu <stanley.chu@mediatek.com>
To: <linux-scsi@vger.kernel.org>, <martin.petersen@oracle.com>,
<avri.altman@wdc.com>, <alim.akhtar@samsung.com>,
<jejb@linux.ibm.com>
Cc: <matthias.bgg@gmail.com>, <linux-mediatek@lists.infradead.org>,
<linux-arm-kernel@lists.infradead.org>,
<linux-kernel@vger.kernel.org>, <kuohong.wang@mediatek.com>,
<peter.wang@mediatek.com>, <chun-hung.wu@mediatek.com>,
<andy.teng@mediatek.com>, <chaotian.jing@mediatek.com>,
<cc.chou@mediatek.com>, <jiajie.hao@mediatek.com>,
<alice.chao@mediatek.com>, Stanley Chu <stanley.chu@mediatek.com>
Subject: [PATCH v1 2/6] scsi: ufs-mediatek: Support VA09 regulator operations
Date: Thu, 29 Oct 2020 19:57:46 +0800 [thread overview]
Message-ID: <20201029115750.24391-3-stanley.chu@mediatek.com> (raw)
In-Reply-To: <20201029115750.24391-1-stanley.chu@mediatek.com>
Some MediaTek UFS platforms need to control VA09 power
specifically. Provide such control according to the device
tree binding.
Signed-off-by: Stanley Chu <stanley.chu@mediatek.com>
---
drivers/scsi/ufs/ufs-mediatek.c | 137 ++++++++++++++++++++++++--------
drivers/scsi/ufs/ufs-mediatek.h | 3 +
2 files changed, 108 insertions(+), 32 deletions(-)
diff --git a/drivers/scsi/ufs/ufs-mediatek.c b/drivers/scsi/ufs/ufs-mediatek.c
index 0196a89055b5..795fc2961f77 100644
--- a/drivers/scsi/ufs/ufs-mediatek.c
+++ b/drivers/scsi/ufs/ufs-mediatek.c
@@ -28,6 +28,9 @@
arm_smccc_smc(MTK_SIP_UFS_CONTROL, \
cmd, val, 0, 0, 0, 0, 0, &(res))
+#define ufs_mtk_va09_pwr_ctrl(res, on) \
+ ufs_mtk_smc(UFS_MTK_SIP_VA09_PWR_CTRL, on, res)
+
#define ufs_mtk_crypto_ctrl(res, enable) \
ufs_mtk_smc(UFS_MTK_SIP_CRYPTO_CTRL, enable, res)
@@ -45,6 +48,10 @@ static struct ufs_dev_fix ufs_mtk_dev_fixups[] = {
END_FIX
};
+static const struct ufs_mtk_host_cfg ufs_mtk_mt8183_cfg = {
+ .caps = UFS_MTK_CAP_VA09_PWR_CTRL,
+};
+
static const struct ufs_mtk_host_cfg ufs_mtk_mt8192_cfg = {
.caps = UFS_MTK_CAP_BOOST_CRYPT_ENGINE,
};
@@ -52,6 +59,7 @@ static const struct ufs_mtk_host_cfg ufs_mtk_mt8192_cfg = {
static const struct of_device_id ufs_mtk_of_match[] = {
{
.compatible = "mediatek,mt8183-ufshci",
+ .data = &ufs_mtk_mt8183_cfg
},
{
.compatible = "mediatek,mt8192-ufshci",
@@ -67,6 +75,13 @@ static bool ufs_mtk_is_boost_crypt_enabled(struct ufs_hba *hba)
return (host->caps & UFS_MTK_CAP_BOOST_CRYPT_ENGINE);
}
+static bool ufs_mtk_is_va09_supported(struct ufs_hba *hba)
+{
+ struct ufs_mtk_host *host = ufshcd_get_variant(hba);
+
+ return (host->caps & UFS_MTK_CAP_VA09_PWR_CTRL);
+}
+
static void ufs_mtk_cfg_unipro_cg(struct ufs_hba *hba, bool enable)
{
u32 tmp;
@@ -300,21 +315,46 @@ static int ufs_mtk_wait_link_state(struct ufs_hba *hba, u32 state,
return -ETIMEDOUT;
}
-static void ufs_mtk_mphy_power_on(struct ufs_hba *hba, bool on)
+static int ufs_mtk_mphy_power_on(struct ufs_hba *hba, bool on)
{
struct ufs_mtk_host *host = ufshcd_get_variant(hba);
struct phy *mphy = host->mphy;
+ struct arm_smccc_res res;
+ int ret = 0;
- if (!mphy)
- return;
+ if (!mphy || !(on ^ host->mphy_powered_on))
+ return 0;
- if (on && !host->mphy_powered_on)
+ if (on) {
+ if (host->reg_va09) {
+ ret = regulator_enable(host->reg_va09);
+ if (ret < 0)
+ goto out;
+ /* wait 200 us to stablize VA09 */
+ usleep_range(200, 210);
+ ufs_mtk_va09_pwr_ctrl(res, 1);
+ }
phy_power_on(mphy);
- else if (!on && host->mphy_powered_on)
+ } else {
phy_power_off(mphy);
- else
- return;
- host->mphy_powered_on = on;
+ if (host->reg_va09) {
+ ufs_mtk_va09_pwr_ctrl(res, 0);
+ ret = regulator_disable(host->reg_va09);
+ if (ret < 0)
+ goto out;
+ }
+ }
+out:
+ if (ret) {
+ dev_info(hba->dev,
+ "failed to %s va09: %d\n",
+ on ? "enable" : "disable",
+ ret);
+ } else {
+ host->mphy_powered_on = on;
+ }
+
+ return ret;
}
static int ufs_mtk_get_host_clk(struct device *dev, const char *name,
@@ -402,7 +442,7 @@ static int ufs_mtk_init_host_clk(struct ufs_hba *hba, const char *name,
return ret;
}
-static void ufs_mtk_init_host_caps(struct ufs_hba *hba)
+static void ufs_mtk_init_boost_crypt(struct ufs_hba *hba)
{
struct ufs_mtk_host *host = ufshcd_get_variant(hba);
struct ufs_mtk_crypt_cfg *cfg;
@@ -410,11 +450,6 @@ static void ufs_mtk_init_host_caps(struct ufs_hba *hba)
struct regulator *reg;
u32 volt;
- host->caps = host->cfg->caps;
-
- if (!ufs_mtk_is_boost_crypt_enabled(hba))
- return;
-
host->crypt = devm_kzalloc(dev, sizeof(*(host->crypt)),
GFP_KERNEL);
if (!host->crypt)
@@ -448,13 +483,38 @@ static void ufs_mtk_init_host_caps(struct ufs_hba *hba)
cfg->reg_vcore = reg;
cfg->vcore_volt = volt;
- dev_info(dev, "caps: boost-crypt");
return;
disable_caps:
host->caps &= ~UFS_MTK_CAP_BOOST_CRYPT_ENGINE;
}
+static void ufs_mtk_init_va09_pwr_ctrl(struct ufs_hba *hba)
+{
+ struct ufs_mtk_host *host = ufshcd_get_variant(hba);
+
+ host->reg_va09 = regulator_get(hba->dev, "va09");
+ if (!host->reg_va09) {
+ dev_info(hba->dev, "failed to get va09");
+ host->caps &= ~UFS_MTK_CAP_VA09_PWR_CTRL;
+ }
+}
+
+static void ufs_mtk_init_host_caps(struct ufs_hba *hba)
+{
+ struct ufs_mtk_host *host = ufshcd_get_variant(hba);
+
+ host->caps = host->cfg->caps;
+
+ if (ufs_mtk_is_boost_crypt_enabled(hba))
+ ufs_mtk_init_boost_crypt(hba);
+
+ if (ufs_mtk_is_va09_supported(hba))
+ ufs_mtk_init_va09_pwr_ctrl(hba);
+
+ dev_info(hba->dev, "caps: 0x%x", host->caps);
+}
+
/**
* ufs_mtk_setup_clocks - enables/disable clocks
* @hba: host controller instance
@@ -467,8 +527,8 @@ static int ufs_mtk_setup_clocks(struct ufs_hba *hba, bool on,
enum ufs_notify_change_status status)
{
struct ufs_mtk_host *host = ufshcd_get_variant(hba);
- int ret = 0;
bool clk_pwr_off = false;
+ int ret = 0;
/*
* In case ufs_mtk_init() is not yet done, simply ignore.
@@ -499,10 +559,10 @@ static int ufs_mtk_setup_clocks(struct ufs_hba *hba, bool on,
if (clk_pwr_off) {
ufs_mtk_boost_crypt(hba, on);
ufs_mtk_setup_ref_clk(hba, on);
- ufs_mtk_mphy_power_on(hba, on);
+ phy_power_off(host->mphy);
}
} else if (on && status == POST_CHANGE) {
- ufs_mtk_mphy_power_on(hba, on);
+ phy_power_on(host->mphy);
ufs_mtk_setup_ref_clk(hba, on);
ufs_mtk_boost_crypt(hba, on);
}
@@ -575,6 +635,7 @@ static int ufs_mtk_init(struct ufs_hba *hba)
*
* Enable phy clocks specifically here.
*/
+ ufs_mtk_mphy_power_on(hba, true);
ufs_mtk_setup_clocks(hba, true, POST_CHANGE);
goto out;
@@ -824,40 +885,52 @@ static int ufs_mtk_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op)
if (ufshcd_is_link_hibern8(hba)) {
err = ufs_mtk_link_set_lpm(hba);
- if (err) {
- /*
- * Set link as off state enforcedly to trigger
- * ufshcd_host_reset_and_restore() in ufshcd_suspend()
- * for completed host reset.
- */
- ufshcd_set_link_off(hba);
- return -EAGAIN;
- }
+ if (err)
+ goto fail;
+ }
+
+ if (!ufshcd_is_link_active(hba)) {
/*
* Make sure no error will be returned to prevent
* ufshcd_suspend() re-enabling regulators while vreg is still
* in low-power mode.
*/
ufs_mtk_vreg_set_lpm(hba, true);
+ err = ufs_mtk_mphy_power_on(hba, false);
+ if (err)
+ goto fail;
}
return 0;
+fail:
+ /*
+ * Set link as off state enforcedly to trigger
+ * ufshcd_host_reset_and_restore() in ufshcd_suspend()
+ * for completed host reset.
+ */
+ ufshcd_set_link_off(hba);
+ return -EAGAIN;
}
static int ufs_mtk_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op)
{
int err;
+ err = ufs_mtk_mphy_power_on(hba, true);
+ if (err)
+ goto fail;
+
+ ufs_mtk_vreg_set_lpm(hba, false);
+
if (ufshcd_is_link_hibern8(hba)) {
- ufs_mtk_vreg_set_lpm(hba, false);
err = ufs_mtk_link_set_hpm(hba);
- if (err) {
- err = ufshcd_link_recovery(hba);
- return err;
- }
+ if (err)
+ goto fail;
}
return 0;
+fail:
+ return ufshcd_link_recovery(hba);
}
static void ufs_mtk_dbg_register_dump(struct ufs_hba *hba)
diff --git a/drivers/scsi/ufs/ufs-mediatek.h b/drivers/scsi/ufs/ufs-mediatek.h
index 2b6a1312c9bc..f668241d37f8 100644
--- a/drivers/scsi/ufs/ufs-mediatek.h
+++ b/drivers/scsi/ufs/ufs-mediatek.h
@@ -69,6 +69,7 @@ enum {
* SiP commands
*/
#define MTK_SIP_UFS_CONTROL MTK_SIP_SMC_CMD(0x276)
+#define UFS_MTK_SIP_VA09_PWR_CTRL BIT(0)
#define UFS_MTK_SIP_DEVICE_RESET BIT(1)
#define UFS_MTK_SIP_CRYPTO_CTRL BIT(2)
#define UFS_MTK_SIP_REF_CLK_NOTIFICATION BIT(3)
@@ -94,6 +95,7 @@ enum {
*/
enum ufs_mtk_host_caps {
UFS_MTK_CAP_BOOST_CRYPT_ENGINE = 1 << 0,
+ UFS_MTK_CAP_VA09_PWR_CTRL = 1 << 1,
};
struct ufs_mtk_crypt_cfg {
@@ -113,6 +115,7 @@ struct ufs_mtk_host {
struct phy *mphy;
struct ufs_mtk_host_cfg *cfg;
struct ufs_mtk_crypt_cfg *crypt;
+ struct regulator *reg_va09;
enum ufs_mtk_host_caps caps;
struct reset_control *hci_reset;
struct reset_control *unipro_reset;
--
2.18.0
next prev parent reply other threads:[~2020-10-29 11:58 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-10-29 11:57 [PATCH v1 0/6] scsi: ufs: Add some proprietary features in MediaTek UFS platforms Stanley Chu
2020-10-29 11:57 ` [PATCH v1 1/6] scsi: ufs-mediatek: Assign arguments with correct type Stanley Chu
2020-11-03 7:12 ` Avri Altman
2020-11-03 7:39 ` Stanley Chu
2020-11-03 8:55 ` Avri Altman
2020-10-29 11:57 ` Stanley Chu [this message]
2020-10-29 11:57 ` [PATCH v1 3/6] scsi: ufs-mediatek: Decouple features from platform bindings Stanley Chu
2020-10-29 11:57 ` [PATCH v1 4/6] scsi: ufs-mediatek: Support option to disable auto-hibern8 Stanley Chu
2020-10-29 11:57 ` [PATCH v1 5/6] scsi: ufs: Add enums for UniPro version higher than 1.6 Stanley Chu
2020-10-29 11:57 ` [PATCH v1 6/6] scsi: ufs-mediatek: Add HS-G4 support Stanley Chu
2020-11-06 6:10 ` [PATCH v1 0/6] scsi: ufs: Add some proprietary features in MediaTek UFS platforms Stanley Chu
2020-11-11 4:04 ` Martin K. Petersen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20201029115750.24391-3-stanley.chu@mediatek.com \
--to=stanley.chu@mediatek.com \
--cc=alice.chao@mediatek.com \
--cc=alim.akhtar@samsung.com \
--cc=andy.teng@mediatek.com \
--cc=avri.altman@wdc.com \
--cc=cc.chou@mediatek.com \
--cc=chaotian.jing@mediatek.com \
--cc=chun-hung.wu@mediatek.com \
--cc=jejb@linux.ibm.com \
--cc=jiajie.hao@mediatek.com \
--cc=kuohong.wang@mediatek.com \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mediatek@lists.infradead.org \
--cc=linux-scsi@vger.kernel.org \
--cc=martin.petersen@oracle.com \
--cc=matthias.bgg@gmail.com \
--cc=peter.wang@mediatek.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox