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>,
<pedrom.sousa@synopsys.com>, <jejb@linux.ibm.com>,
<matthias.bgg@gmail.com>, <bvanassche@acm.org>,
<f.fainelli@gmail.com>
Cc: leon.chen@mediatek.com, andy.teng@mediatek.com,
chun-hung.wu@mediatek.com, kuohong.wang@mediatek.com,
linux-kernel@vger.kernel.org, cang@codeaurora.org,
linux-mediatek@lists.infradead.org, peter.wang@mediatek.com,
Stanley Chu <stanley.chu@mediatek.com>,
linux-arm-kernel@lists.infradead.org, beanhuo@micron.com
Subject: [PATCH v2 3/6] scsi: ufs-mediatek: introduce reference clock control
Date: Mon, 30 Dec 2019 13:32:27 +0800 [thread overview]
Message-ID: <1577683950-1702-4-git-send-email-stanley.chu@mediatek.com> (raw)
In-Reply-To: <1577683950-1702-1-git-send-email-stanley.chu@mediatek.com>
Introduce reference clock control in MediaTek Chipset in order
to disable it if it is not necessary by UFS device to save system power.
Currently reference clock can be disabled during system suspend, runtime
suspend and clock-gating after link enters hibernate state.
Cc: Alim Akhtar <alim.akhtar@samsung.com>
Cc: Avri Altman <avri.altman@wdc.com>
Cc: Bart Van Assche <bvanassche@acm.org>
Cc: Bean Huo <beanhuo@micron.com>
Cc: Can Guo <cang@codeaurora.org>
Cc: Florian Fainelli <f.fainelli@gmail.com>
Cc: Matthias Brugger <matthias.bgg@gmail.com>
Signed-off-by: Stanley Chu <stanley.chu@mediatek.com>
Reviewed-by: Alim Akhtar <alim.akhtar@samsung.com>
---
drivers/scsi/ufs/ufs-mediatek.c | 62 ++++++++++++++++++++++++++++++---
drivers/scsi/ufs/ufs-mediatek.h | 22 ++++++++++--
2 files changed, 78 insertions(+), 6 deletions(-)
diff --git a/drivers/scsi/ufs/ufs-mediatek.c b/drivers/scsi/ufs/ufs-mediatek.c
index 37e2c91fc452..fc5ba21ec02a 100644
--- a/drivers/scsi/ufs/ufs-mediatek.c
+++ b/drivers/scsi/ufs/ufs-mediatek.c
@@ -22,6 +22,9 @@
arm_smccc_smc(MTK_SIP_UFS_CONTROL, \
cmd, val, 0, 0, 0, 0, 0, &(res))
+#define ufs_mtk_ref_clk_notify(on, res) \
+ ufs_mtk_smc(UFS_MTK_SIP_REF_CLK_NOTIFICATION, on, res)
+
#define ufs_mtk_device_reset_ctrl(high, res) \
ufs_mtk_smc(UFS_MTK_SIP_DEVICE_RESET, high, res)
@@ -90,6 +93,49 @@ static int ufs_mtk_bind_mphy(struct ufs_hba *hba)
return err;
}
+static int ufs_mtk_setup_ref_clk(struct ufs_hba *hba, bool on)
+{
+ struct ufs_mtk_host *host = ufshcd_get_variant(hba);
+ struct arm_smccc_res res;
+ unsigned long timeout;
+ u32 value;
+
+ if (host->ref_clk_enabled == on)
+ return 0;
+
+ if (on) {
+ ufs_mtk_ref_clk_notify(on, res);
+ ufshcd_writel(hba, REFCLK_REQUEST, REG_UFS_REFCLK_CTRL);
+ } else {
+ ufshcd_writel(hba, REFCLK_RELEASE, REG_UFS_REFCLK_CTRL);
+ }
+
+ /* Wait for ack */
+ timeout = jiffies + msecs_to_jiffies(REFCLK_REQ_TIMEOUT_MS);
+ do {
+ value = ufshcd_readl(hba, REG_UFS_REFCLK_CTRL);
+
+ /* Wait until ack bit equals to req bit */
+ if (((value & REFCLK_ACK) >> 1) == (value & REFCLK_REQUEST))
+ goto out;
+
+ usleep_range(100, 200);
+ } while (time_before(jiffies, timeout));
+
+ dev_err(hba->dev, "missing ack of refclk req, reg: 0x%x\n", value);
+
+ ufs_mtk_ref_clk_notify(host->ref_clk_enabled, res);
+
+ return -ETIMEDOUT;
+
+out:
+ host->ref_clk_enabled = on;
+ if (!on)
+ ufs_mtk_ref_clk_notify(on, res);
+
+ return 0;
+}
+
/**
* ufs_mtk_setup_clocks - enables/disable clocks
* @hba: host controller instance
@@ -114,12 +160,16 @@ static int ufs_mtk_setup_clocks(struct ufs_hba *hba, bool on,
switch (status) {
case PRE_CHANGE:
- if (!on)
+ if (!on) {
+ ufs_mtk_setup_ref_clk(hba, on);
ret = phy_power_off(host->mphy);
+ }
break;
case POST_CHANGE:
- if (on)
+ if (on) {
ret = phy_power_on(host->mphy);
+ ufs_mtk_setup_ref_clk(hba, on);
+ }
break;
}
@@ -305,8 +355,10 @@ static int ufs_mtk_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op)
{
struct ufs_mtk_host *host = ufshcd_get_variant(hba);
- if (ufshcd_is_link_hibern8(hba))
+ if (ufshcd_is_link_hibern8(hba)) {
phy_power_off(host->mphy);
+ ufs_mtk_setup_ref_clk(hba, false);
+ }
return 0;
}
@@ -315,8 +367,10 @@ static int ufs_mtk_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op)
{
struct ufs_mtk_host *host = ufshcd_get_variant(hba);
- if (ufshcd_is_link_hibern8(hba))
+ if (ufshcd_is_link_hibern8(hba)) {
+ ufs_mtk_setup_ref_clk(hba, true);
phy_power_on(host->mphy);
+ }
return 0;
}
diff --git a/drivers/scsi/ufs/ufs-mediatek.h b/drivers/scsi/ufs/ufs-mediatek.h
index ce68ce25fdd7..31b7fead19eb 100644
--- a/drivers/scsi/ufs/ufs-mediatek.h
+++ b/drivers/scsi/ufs/ufs-mediatek.h
@@ -9,6 +9,22 @@
#include <linux/bitops.h>
#include <linux/soc/mediatek/mtk_sip_svc.h>
+/*
+ * Vendor specific UFSHCI Registers
+ */
+#define REG_UFS_REFCLK_CTRL 0x144
+
+/*
+ * Ref-clk control
+ *
+ * Values for register REG_UFS_REFCLK_CTRL
+ */
+#define REFCLK_RELEASE 0x0
+#define REFCLK_REQUEST BIT(0)
+#define REFCLK_ACK BIT(1)
+
+#define REFCLK_REQ_TIMEOUT_MS 3
+
/*
* Vendor specific pre-defined parameters
*/
@@ -35,8 +51,9 @@
/*
* SiP commands
*/
-#define MTK_SIP_UFS_CONTROL MTK_SIP_SMC_CMD(0x276)
-#define UFS_MTK_SIP_DEVICE_RESET BIT(1)
+#define MTK_SIP_UFS_CONTROL MTK_SIP_SMC_CMD(0x276)
+#define UFS_MTK_SIP_DEVICE_RESET BIT(1)
+#define UFS_MTK_SIP_REF_CLK_NOTIFICATION BIT(3)
/*
* VS_DEBUGCLOCKENABLE
@@ -57,6 +74,7 @@ enum {
struct ufs_mtk_host {
struct ufs_hba *hba;
struct phy *mphy;
+ bool ref_clk_enabled;
};
#endif /* !_UFS_MEDIATEK_H */
--
2.18.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
next prev parent reply other threads:[~2019-12-30 5:34 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-12-30 5:32 [PATCH v2 0/6] scsi: ufs: add MediaTek vendor implementations Stanley Chu
2019-12-30 5:32 ` [PATCH v2 1/6] soc: mediatek: add header for SiP service interface Stanley Chu
2019-12-30 5:32 ` [PATCH v2 2/6] scsi: ufs-mediatek: add device reset implementation Stanley Chu
2019-12-30 5:32 ` Stanley Chu [this message]
2019-12-30 5:32 ` [PATCH v2 4/6] scsi: ufs: export ufshcd_auto_hibern8_update for vendor usage Stanley Chu
2019-12-30 5:32 ` [PATCH v2 5/6] scsi: ufs-mediatek: configure customized auto-hibern8 timer Stanley Chu
2019-12-30 5:32 ` [PATCH v2 6/6] scsi: ufs-mediatek: configure and enable clk-gating Stanley Chu
2020-01-03 2:59 ` [PATCH v2 0/6] scsi: ufs: add MediaTek vendor implementations 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=1577683950-1702-4-git-send-email-stanley.chu@mediatek.com \
--to=stanley.chu@mediatek.com \
--cc=alim.akhtar@samsung.com \
--cc=andy.teng@mediatek.com \
--cc=avri.altman@wdc.com \
--cc=beanhuo@micron.com \
--cc=bvanassche@acm.org \
--cc=cang@codeaurora.org \
--cc=chun-hung.wu@mediatek.com \
--cc=f.fainelli@gmail.com \
--cc=jejb@linux.ibm.com \
--cc=kuohong.wang@mediatek.com \
--cc=leon.chen@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=pedrom.sousa@synopsys.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;
as well as URLs for NNTP newsgroup(s).