linux-mediatek.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/5] scsi: ufs-mediatek: Fix clk-gating and introduce low-power mode for vccq2
@ 2020-05-29  9:23 Stanley Chu
  2020-05-29  9:23 ` [PATCH v2 1/5] scsi: ufs-mediatek: Fix imprecise waiting time for ref-clk control Stanley Chu
                   ` (4 more replies)
  0 siblings, 5 replies; 8+ messages in thread
From: Stanley Chu @ 2020-05-29  9:23 UTC (permalink / raw)
  To: linux-scsi, martin.petersen, avri.altman, alim.akhtar, jejb
  Cc: pengshun.zhao, Stanley Chu, bvanassche, andy.teng, cc.chou,
	chun-hung.wu, kuohong.wang, linux-kernel, cang, linux-mediatek,
	peter.wang, matthias.bgg, beanhuo, chaotian.jing,
	linux-arm-kernel, asutoshd

Hi,
This series fixes clk-gating issues and introduces low-power mode for vccq2 in MediaTek platforms.

v1 -> v2:
  - Add patch [4] and [5]

Stanley Chu (5):
  scsi: ufs-mediatek: Fix imprecise waiting time for ref-clk control
  scsi: ufs-mediatek: Do not gate clocks if auto-hibern8 is not entered
    yet
  scsi: ufs-mediatek: Introduce low-power mode for device power supply
  scsi: ufs-mediatek: Fix unbalanced clock on/off
  scsi: ufs-mediatek: Allow unbound mphy

 drivers/scsi/ufs/ufs-mediatek.c | 112 +++++++++++++++++++++++---------
 drivers/scsi/ufs/ufs-mediatek.h |   2 +-
 2 files changed, 84 insertions(+), 30 deletions(-)

-- 
2.18.0
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH v2 1/5] scsi: ufs-mediatek: Fix imprecise waiting time for ref-clk control
  2020-05-29  9:23 [PATCH v2 0/5] scsi: ufs-mediatek: Fix clk-gating and introduce low-power mode for vccq2 Stanley Chu
@ 2020-05-29  9:23 ` Stanley Chu
  2020-05-31  7:10   ` Avri Altman
  2020-05-29  9:23 ` [PATCH v2 2/5] scsi: ufs-mediatek: Do not gate clocks if auto-hibern8 is not entered yet Stanley Chu
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 8+ messages in thread
From: Stanley Chu @ 2020-05-29  9:23 UTC (permalink / raw)
  To: linux-scsi, martin.petersen, avri.altman, alim.akhtar, jejb
  Cc: pengshun.zhao, Stanley Chu, bvanassche, andy.teng, cc.chou,
	chun-hung.wu, kuohong.wang, linux-kernel, cang, linux-mediatek,
	peter.wang, matthias.bgg, beanhuo, chaotian.jing,
	linux-arm-kernel, asutoshd

Currently ref-clk control timeout is implemented by Jiffies. However
jiffies is not accurate enough thus "false timeout" may happen.

Use more accurate delay mechanism instead, for example, ktime.

Signed-off-by: Stanley Chu <stanley.chu@mediatek.com>
Reviewed-by: Andy Teng <andy.teng@mediatek.com>
---
 drivers/scsi/ufs/ufs-mediatek.c | 7 ++++---
 drivers/scsi/ufs/ufs-mediatek.h | 2 +-
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/scsi/ufs/ufs-mediatek.c b/drivers/scsi/ufs/ufs-mediatek.c
index d56ce8d97d4e..523ee5573921 100644
--- a/drivers/scsi/ufs/ufs-mediatek.c
+++ b/drivers/scsi/ufs/ufs-mediatek.c
@@ -120,7 +120,7 @@ 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;
+	ktime_t timeout, time_checked;
 	u32 value;
 
 	if (host->ref_clk_enabled == on)
@@ -135,8 +135,9 @@ static int ufs_mtk_setup_ref_clk(struct ufs_hba *hba, bool on)
 	}
 
 	/* Wait for ack */
-	timeout = jiffies + msecs_to_jiffies(REFCLK_REQ_TIMEOUT_MS);
+	timeout = ktime_add_us(ktime_get(), REFCLK_REQ_TIMEOUT_US);
 	do {
+		time_checked = ktime_get();
 		value = ufshcd_readl(hba, REG_UFS_REFCLK_CTRL);
 
 		/* Wait until ack bit equals to req bit */
@@ -144,7 +145,7 @@ static int ufs_mtk_setup_ref_clk(struct ufs_hba *hba, bool on)
 			goto out;
 
 		usleep_range(100, 200);
-	} while (time_before(jiffies, timeout));
+	} while (ktime_before(time_checked, timeout));
 
 	dev_err(hba->dev, "missing ack of refclk req, reg: 0x%x\n", value);
 
diff --git a/drivers/scsi/ufs/ufs-mediatek.h b/drivers/scsi/ufs/ufs-mediatek.h
index 5bbd3e9cbae2..fc42dcbfd800 100644
--- a/drivers/scsi/ufs/ufs-mediatek.h
+++ b/drivers/scsi/ufs/ufs-mediatek.h
@@ -28,7 +28,7 @@
 #define REFCLK_REQUEST              BIT(0)
 #define REFCLK_ACK                  BIT(1)
 
-#define REFCLK_REQ_TIMEOUT_MS       3
+#define REFCLK_REQ_TIMEOUT_US       3000
 
 /*
  * Vendor specific pre-defined parameters
-- 
2.18.0
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v2 2/5] scsi: ufs-mediatek: Do not gate clocks if auto-hibern8 is not entered yet
  2020-05-29  9:23 [PATCH v2 0/5] scsi: ufs-mediatek: Fix clk-gating and introduce low-power mode for vccq2 Stanley Chu
  2020-05-29  9:23 ` [PATCH v2 1/5] scsi: ufs-mediatek: Fix imprecise waiting time for ref-clk control Stanley Chu
@ 2020-05-29  9:23 ` Stanley Chu
  2020-05-29  9:23 ` [PATCH v2 3/5] scsi: ufs-mediatek: Introduce low-power mode for device power supply Stanley Chu
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 8+ messages in thread
From: Stanley Chu @ 2020-05-29  9:23 UTC (permalink / raw)
  To: linux-scsi, martin.petersen, avri.altman, alim.akhtar, jejb
  Cc: pengshun.zhao, Stanley Chu, bvanassche, andy.teng, cc.chou,
	chun-hung.wu, kuohong.wang, linux-kernel, cang, linux-mediatek,
	peter.wang, matthias.bgg, beanhuo, chaotian.jing,
	linux-arm-kernel, asutoshd

There are some chances that link enters hibern8 lately by auto-hibern8
scheme during the clock-gating flow. Clocks shall not be gated if link
is still active otherwise host or device may hang.

Fix this by returning error code to the caller __ufshcd_setup_clocks()
to skip gating clocks there if link is not confirmed in hibern8
state yet.

Also allow some waiting time for the hibern8 state transition.

Signed-off-by: Stanley Chu <stanley.chu@mediatek.com>
Reviewed-by: Andy Teng <andy.teng@mediatek.com>
---
 drivers/scsi/ufs/ufs-mediatek.c | 36 ++++++++++++++++++++++++---------
 1 file changed, 27 insertions(+), 9 deletions(-)

diff --git a/drivers/scsi/ufs/ufs-mediatek.c b/drivers/scsi/ufs/ufs-mediatek.c
index 523ee5573921..3c85f5e97dea 100644
--- a/drivers/scsi/ufs/ufs-mediatek.c
+++ b/drivers/scsi/ufs/ufs-mediatek.c
@@ -178,15 +178,30 @@ static void ufs_mtk_setup_ref_clk_wait_us(struct ufs_hba *hba,
 	host->ref_clk_ungating_wait_us = ungating_us;
 }
 
-static u32 ufs_mtk_link_get_state(struct ufs_hba *hba)
+int ufs_mtk_wait_link_state(struct ufs_hba *hba, u32 state,
+			    unsigned long max_wait_ms)
 {
+	ktime_t timeout, time_checked;
 	u32 val;
 
-	ufshcd_writel(hba, 0x20, REG_UFS_DEBUG_SEL);
-	val = ufshcd_readl(hba, REG_UFS_PROBE);
-	val = val >> 28;
+	timeout = ktime_add_us(ktime_get(), ms_to_ktime(max_wait_ms));
+	do {
+		time_checked = ktime_get();
+		ufshcd_writel(hba, 0x20, REG_UFS_DEBUG_SEL);
+		val = ufshcd_readl(hba, REG_UFS_PROBE);
+		val = val >> 28;
+
+		if (val == state)
+			return 0;
 
-	return val;
+		/* Sleep for max. 200us */
+		usleep_range(100, 200);
+	} while (ktime_before(time_checked, timeout));
+
+	if (val == state)
+		return 0;
+
+	return -ETIMEDOUT;
 }
 
 /**
@@ -221,10 +236,13 @@ static int ufs_mtk_setup_clocks(struct ufs_hba *hba, bool on,
 			 * triggered by Auto-Hibern8.
 			 */
 			if (!ufshcd_can_hibern8_during_gating(hba) &&
-			    ufshcd_is_auto_hibern8_enabled(hba) &&
-			    ufs_mtk_link_get_state(hba) ==
-			    VS_LINK_HIBERN8)
-				ufs_mtk_setup_ref_clk(hba, on);
+			    ufshcd_is_auto_hibern8_enabled(hba)) {
+				ret = ufs_mtk_wait_link_state(hba,
+							      VS_LINK_HIBERN8,
+							      15);
+				if (!ret)
+					ufs_mtk_setup_ref_clk(hba, on);
+			}
 		}
 	} else if (on && status == POST_CHANGE) {
 		ret = phy_power_on(host->mphy);
-- 
2.18.0
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v2 3/5] scsi: ufs-mediatek: Introduce low-power mode for device power supply
  2020-05-29  9:23 [PATCH v2 0/5] scsi: ufs-mediatek: Fix clk-gating and introduce low-power mode for vccq2 Stanley Chu
  2020-05-29  9:23 ` [PATCH v2 1/5] scsi: ufs-mediatek: Fix imprecise waiting time for ref-clk control Stanley Chu
  2020-05-29  9:23 ` [PATCH v2 2/5] scsi: ufs-mediatek: Do not gate clocks if auto-hibern8 is not entered yet Stanley Chu
@ 2020-05-29  9:23 ` Stanley Chu
  2020-05-29  9:23 ` [PATCH v2 4/5] scsi: ufs-mediatek: Fix unbalanced clock on/off Stanley Chu
  2020-05-29  9:23 ` [PATCH v2 5/5] scsi: ufs-mediatek: Allow unbound mphy Stanley Chu
  4 siblings, 0 replies; 8+ messages in thread
From: Stanley Chu @ 2020-05-29  9:23 UTC (permalink / raw)
  To: linux-scsi, martin.petersen, avri.altman, alim.akhtar, jejb
  Cc: pengshun.zhao, Stanley Chu, bvanassche, andy.teng, cc.chou,
	chun-hung.wu, kuohong.wang, linux-kernel, cang, linux-mediatek,
	peter.wang, matthias.bgg, beanhuo, chaotian.jing,
	linux-arm-kernel, asutoshd

Allow device power supply to enter low-power mode if device will
do nothing to save more power.

Signed-off-by: Stanley Chu <stanley.chu@mediatek.com>
Reviewed-by: Pengshun Zhao <pengshun.zhao@mediatek.com>
---
 drivers/scsi/ufs/ufs-mediatek.c | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/drivers/scsi/ufs/ufs-mediatek.c b/drivers/scsi/ufs/ufs-mediatek.c
index 3c85f5e97dea..5f41b7b7db8f 100644
--- a/drivers/scsi/ufs/ufs-mediatek.c
+++ b/drivers/scsi/ufs/ufs-mediatek.c
@@ -12,6 +12,7 @@
 #include <linux/of_address.h>
 #include <linux/phy/phy.h>
 #include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
 #include <linux/soc/mediatek/mtk_sip_svc.h>
 
 #include "ufshcd.h"
@@ -521,6 +522,19 @@ static int ufs_mtk_link_set_lpm(struct ufs_hba *hba)
 	return 0;
 }
 
+static void ufs_mtk_vreg_set_lpm(struct ufs_hba *hba, bool lpm)
+{
+	if (!hba->vreg_info.vccq2)
+		return;
+
+	if (lpm & !hba->vreg_info.vcc->enabled)
+		regulator_set_mode(hba->vreg_info.vccq2->reg,
+				   REGULATOR_MODE_IDLE);
+	else if (!lpm)
+		regulator_set_mode(hba->vreg_info.vccq2->reg,
+				   REGULATOR_MODE_NORMAL);
+}
+
 static int ufs_mtk_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op)
 {
 	int err;
@@ -537,6 +551,12 @@ static int ufs_mtk_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op)
 			ufshcd_set_link_off(hba);
 			return -EAGAIN;
 		}
+		/*
+		 * 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);
 	}
 
 	if (!ufshcd_is_link_active(hba))
@@ -554,6 +574,7 @@ static int ufs_mtk_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op)
 		phy_power_on(host->mphy);
 
 	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);
-- 
2.18.0
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v2 4/5] scsi: ufs-mediatek: Fix unbalanced clock on/off
  2020-05-29  9:23 [PATCH v2 0/5] scsi: ufs-mediatek: Fix clk-gating and introduce low-power mode for vccq2 Stanley Chu
                   ` (2 preceding siblings ...)
  2020-05-29  9:23 ` [PATCH v2 3/5] scsi: ufs-mediatek: Introduce low-power mode for device power supply Stanley Chu
@ 2020-05-29  9:23 ` Stanley Chu
  2020-05-29  9:23 ` [PATCH v2 5/5] scsi: ufs-mediatek: Allow unbound mphy Stanley Chu
  4 siblings, 0 replies; 8+ messages in thread
From: Stanley Chu @ 2020-05-29  9:23 UTC (permalink / raw)
  To: linux-scsi, martin.petersen, avri.altman, alim.akhtar, jejb
  Cc: pengshun.zhao, Stanley Chu, bvanassche, andy.teng, cc.chou,
	chun-hung.wu, kuohong.wang, linux-kernel, cang, linux-mediatek,
	peter.wang, matthias.bgg, beanhuo, chaotian.jing,
	linux-arm-kernel, asutoshd

MediaTek UFS clocks are separated to two parts and controlled
by different modules: ufs-mediatek and phy-ufs-mediatek.

If both Auto-Hibern8 and clk-gating feature are enabled, mphy
power control is not balanced thus unbalanced control also
happens to the clocks probed by phy-ufs-mediatek module.

Fix this issue by

- Promise usage of phy_power_on/off balanced

- Remove phy_power_on/off control in suspend/resume vops since
  both can be handled in setup_clock vops only

Signed-off-by: Stanley Chu <stanley.chu@mediatek.com>
Reviewed-by: Peter Wang <peter.wang@mediatek.com>
---
 drivers/scsi/ufs/ufs-mediatek.c | 56 +++++++++++++++++++--------------
 1 file changed, 32 insertions(+), 24 deletions(-)

diff --git a/drivers/scsi/ufs/ufs-mediatek.c b/drivers/scsi/ufs/ufs-mediatek.c
index 5f41b7b7db8f..de9e643fb8dd 100644
--- a/drivers/scsi/ufs/ufs-mediatek.c
+++ b/drivers/scsi/ufs/ufs-mediatek.c
@@ -205,6 +205,23 @@ 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)
+{
+	struct ufs_mtk_host *host = ufshcd_get_variant(hba);
+	struct phy *mphy = host->mphy;
+
+	if (!mphy)
+		return;
+
+	if (on && !host->mphy_powered_on)
+		phy_power_on(mphy);
+	else if (!on && host->mphy_powered_on)
+		phy_power_off(mphy);
+	else
+		return;
+	host->mphy_powered_on = on;
+}
+
 /**
  * ufs_mtk_setup_clocks - enables/disable clocks
  * @hba: host controller instance
@@ -228,25 +245,24 @@ static int ufs_mtk_setup_clocks(struct ufs_hba *hba, bool on,
 		return 0;
 
 	if (!on && status == PRE_CHANGE) {
-		if (!ufshcd_is_link_active(hba)) {
-			ufs_mtk_setup_ref_clk(hba, on);
-			ret = phy_power_off(host->mphy);
-		} else {
-			/*
-			 * Gate ref-clk if link state is in Hibern8
-			 * triggered by Auto-Hibern8.
-			 */
-			if (!ufshcd_can_hibern8_during_gating(hba) &&
-			    ufshcd_is_auto_hibern8_enabled(hba)) {
-				ret = ufs_mtk_wait_link_state(hba,
-							      VS_LINK_HIBERN8,
-							      15);
-				if (!ret)
-					ufs_mtk_setup_ref_clk(hba, on);
+		/*
+		 * Gate ref-clk and poweroff mphy if link state is in OFF
+		 * or Hibern8 by either ufshcd_link_state_transition() or
+		 * Auto-Hibern8.
+		 */
+		if (!ufshcd_is_link_active(hba) ||
+			(!ufshcd_can_hibern8_during_gating(hba) &&
+			ufshcd_is_auto_hibern8_enabled(hba))) {
+			ret = ufs_mtk_wait_link_state(hba,
+						      VS_LINK_HIBERN8,
+						      15);
+			if (!ret) {
+				ufs_mtk_setup_ref_clk(hba, on);
+				ufs_mtk_mphy_power_on(hba, on);
 			}
 		}
 	} else if (on && status == POST_CHANGE) {
-		ret = phy_power_on(host->mphy);
+		ufs_mtk_mphy_power_on(hba, on);
 		ufs_mtk_setup_ref_clk(hba, on);
 	}
 
@@ -538,7 +554,6 @@ static void ufs_mtk_vreg_set_lpm(struct ufs_hba *hba, bool lpm)
 static int ufs_mtk_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op)
 {
 	int err;
-	struct ufs_mtk_host *host = ufshcd_get_variant(hba);
 
 	if (ufshcd_is_link_hibern8(hba)) {
 		err = ufs_mtk_link_set_lpm(hba);
@@ -559,20 +574,13 @@ static int ufs_mtk_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op)
 		ufs_mtk_vreg_set_lpm(hba, true);
 	}
 
-	if (!ufshcd_is_link_active(hba))
-		phy_power_off(host->mphy);
-
 	return 0;
 }
 
 static int ufs_mtk_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op)
 {
-	struct ufs_mtk_host *host = ufshcd_get_variant(hba);
 	int err;
 
-	if (!ufshcd_is_link_active(hba))
-		phy_power_on(host->mphy);
-
 	if (ufshcd_is_link_hibern8(hba)) {
 		ufs_mtk_vreg_set_lpm(hba, false);
 		err = ufs_mtk_link_set_hpm(hba);
-- 
2.18.0
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v2 5/5] scsi: ufs-mediatek: Allow unbound mphy
  2020-05-29  9:23 [PATCH v2 0/5] scsi: ufs-mediatek: Fix clk-gating and introduce low-power mode for vccq2 Stanley Chu
                   ` (3 preceding siblings ...)
  2020-05-29  9:23 ` [PATCH v2 4/5] scsi: ufs-mediatek: Fix unbalanced clock on/off Stanley Chu
@ 2020-05-29  9:23 ` Stanley Chu
  4 siblings, 0 replies; 8+ messages in thread
From: Stanley Chu @ 2020-05-29  9:23 UTC (permalink / raw)
  To: linux-scsi, martin.petersen, avri.altman, alim.akhtar, jejb
  Cc: pengshun.zhao, Stanley Chu, bvanassche, andy.teng, cc.chou,
	chun-hung.wu, kuohong.wang, linux-kernel, cang, linux-mediatek,
	peter.wang, matthias.bgg, beanhuo, chaotian.jing,
	linux-arm-kernel, asutoshd

Allow unbound MPHY module since not every MediaTek UFS platform
needs specific MPHY control.

Signed-off-by: Stanley Chu <stanley.chu@mediatek.com>
Reviewed-by: Peter Wang <peter.wang@mediatek.com>
---
 drivers/scsi/ufs/ufs-mediatek.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/scsi/ufs/ufs-mediatek.c b/drivers/scsi/ufs/ufs-mediatek.c
index de9e643fb8dd..d587b3276aa8 100644
--- a/drivers/scsi/ufs/ufs-mediatek.c
+++ b/drivers/scsi/ufs/ufs-mediatek.c
@@ -113,6 +113,12 @@ static int ufs_mtk_bind_mphy(struct ufs_hba *hba)
 
 	if (err)
 		host->mphy = NULL;
+	/*
+	 * Allow unbound mphy because not every platform needs specific
+	 * mphy control.
+	 */
+	if (err == -ENODEV)
+		err = 0;
 
 	return err;
 }
-- 
2.18.0
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* RE: [PATCH v2 1/5] scsi: ufs-mediatek: Fix imprecise waiting time for ref-clk control
  2020-05-29  9:23 ` [PATCH v2 1/5] scsi: ufs-mediatek: Fix imprecise waiting time for ref-clk control Stanley Chu
@ 2020-05-31  7:10   ` Avri Altman
  2020-05-31 13:45     ` Stanley Chu
  0 siblings, 1 reply; 8+ messages in thread
From: Avri Altman @ 2020-05-31  7:10 UTC (permalink / raw)
  To: Stanley Chu, linux-scsi, martin.petersen, alim.akhtar, jejb
  Cc: pengshun.zhao, bvanassche, andy.teng, cc.chou, chun-hung.wu,
	kuohong.wang, linux-kernel, cang, linux-mediatek, peter.wang,
	matthias.bgg, beanhuo, chaotian.jing, linux-arm-kernel, asutoshd

 
> 
> Currently ref-clk control timeout is implemented by Jiffies. However
> jiffies is not accurate enough thus "false timeout" may happen.
> 
> Use more accurate delay mechanism instead, for example, ktime.
> 
> Signed-off-by: Stanley Chu <stanley.chu@mediatek.com>
> Reviewed-by: Andy Teng <andy.teng@mediatek.com>
Reviewed-by: Avri Altman <avri.altman@wdc.com>

> ---
>  drivers/scsi/ufs/ufs-mediatek.c | 7 ++++---
>  drivers/scsi/ufs/ufs-mediatek.h | 2 +-
>  2 files changed, 5 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/scsi/ufs/ufs-mediatek.c b/drivers/scsi/ufs/ufs-mediatek.c
> index d56ce8d97d4e..523ee5573921 100644
> --- a/drivers/scsi/ufs/ufs-mediatek.c
> +++ b/drivers/scsi/ufs/ufs-mediatek.c
> @@ -120,7 +120,7 @@ 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;
> +       ktime_t timeout, time_checked;
>         u32 value;
> 
>         if (host->ref_clk_enabled == on)
> @@ -135,8 +135,9 @@ static int ufs_mtk_setup_ref_clk(struct ufs_hba *hba,
> bool on)
>         }
> 
>         /* Wait for ack */
> -       timeout = jiffies + msecs_to_jiffies(REFCLK_REQ_TIMEOUT_MS);
> +       timeout = ktime_add_us(ktime_get(), REFCLK_REQ_TIMEOUT_US);
>         do {
> +               time_checked = ktime_get();
>                 value = ufshcd_readl(hba, REG_UFS_REFCLK_CTRL);
> 
>                 /* Wait until ack bit equals to req bit */
> @@ -144,7 +145,7 @@ static int ufs_mtk_setup_ref_clk(struct ufs_hba *hba,
> bool on)
>                         goto out;
> 
>                 usleep_range(100, 200);
> -       } while (time_before(jiffies, timeout));
> +       } while (ktime_before(time_checked, timeout));
Nit: you could get rid of time_checked if you would use ktime_compare(ktime_get(), timeout) > 0

Thanks,
Avri

> 
>         dev_err(hba->dev, "missing ack of refclk req, reg: 0x%x\n", value);
> 
> diff --git a/drivers/scsi/ufs/ufs-mediatek.h b/drivers/scsi/ufs/ufs-mediatek.h
> index 5bbd3e9cbae2..fc42dcbfd800 100644
> --- a/drivers/scsi/ufs/ufs-mediatek.h
> +++ b/drivers/scsi/ufs/ufs-mediatek.h
> @@ -28,7 +28,7 @@
>  #define REFCLK_REQUEST              BIT(0)
>  #define REFCLK_ACK                  BIT(1)
> 
> -#define REFCLK_REQ_TIMEOUT_MS       3
> +#define REFCLK_REQ_TIMEOUT_US       3000
> 
>  /*
>   * Vendor specific pre-defined parameters
> --
> 2.18.0

_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply	[flat|nested] 8+ messages in thread

* RE: [PATCH v2 1/5] scsi: ufs-mediatek: Fix imprecise waiting time for ref-clk control
  2020-05-31  7:10   ` Avri Altman
@ 2020-05-31 13:45     ` Stanley Chu
  0 siblings, 0 replies; 8+ messages in thread
From: Stanley Chu @ 2020-05-31 13:45 UTC (permalink / raw)
  To: Avri Altman
  Cc: pengshun.zhao, linux-scsi, martin.petersen, andy.teng, jejb,
	chun-hung.wu, kuohong.wang, linux-kernel, cc.chou, cang,
	linux-mediatek, peter.wang, alim.akhtar, matthias.bgg, beanhuo,
	chaotian.jing, bvanassche, linux-arm-kernel, asutoshd

Hi Avri,

On Sun, 2020-05-31 at 07:10 +0000, Avri Altman wrote:
> > 
> > Currently ref-clk control timeout is implemented by Jiffies. However
> > jiffies is not accurate enough thus "false timeout" may happen.
> > 
> > Use more accurate delay mechanism instead, for example, ktime.
> > 
> > Signed-off-by: Stanley Chu <stanley.chu@mediatek.com>
> > Reviewed-by: Andy Teng <andy.teng@mediatek.com>
> Reviewed-by: Avri Altman <avri.altman@wdc.com>
> 

Thanks for your review.

> > 
> >         /* Wait for ack */
> > -       timeout = jiffies + msecs_to_jiffies(REFCLK_REQ_TIMEOUT_MS);
> > +       timeout = ktime_add_us(ktime_get(), REFCLK_REQ_TIMEOUT_US);
> >         do {
> > +               time_checked = ktime_get();
> >                 value = ufshcd_readl(hba, REG_UFS_REFCLK_CTRL);
> > 
> >                 /* Wait until ack bit equals to req bit */
> > @@ -144,7 +145,7 @@ static int ufs_mtk_setup_ref_clk(struct ufs_hba *hba,
> > bool on)
> >                         goto out;
> > 
> >                 usleep_range(100, 200);
> > -       } while (time_before(jiffies, timeout));
> > +       } while (ktime_before(time_checked, timeout));
> Nit: you could get rid of time_checked if you would use ktime_compare(ktime_get(), timeout) > 0
> 
> Thanks,
> Avri

If this context is preempted and scheduled out between ufshcd_readl()
and ktime_compare(ktime_get(), timeout), then the ktime_get() may get a
"timed-out" time even though the last ufshcd_readl() is actually
executed before the "timed-out" time. In this case, false alarm will
show up. Using "time_checked" here could solve above issue.

Thanks,
Stanley Chu


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2020-05-31 13:45 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-05-29  9:23 [PATCH v2 0/5] scsi: ufs-mediatek: Fix clk-gating and introduce low-power mode for vccq2 Stanley Chu
2020-05-29  9:23 ` [PATCH v2 1/5] scsi: ufs-mediatek: Fix imprecise waiting time for ref-clk control Stanley Chu
2020-05-31  7:10   ` Avri Altman
2020-05-31 13:45     ` Stanley Chu
2020-05-29  9:23 ` [PATCH v2 2/5] scsi: ufs-mediatek: Do not gate clocks if auto-hibern8 is not entered yet Stanley Chu
2020-05-29  9:23 ` [PATCH v2 3/5] scsi: ufs-mediatek: Introduce low-power mode for device power supply Stanley Chu
2020-05-29  9:23 ` [PATCH v2 4/5] scsi: ufs-mediatek: Fix unbalanced clock on/off Stanley Chu
2020-05-29  9:23 ` [PATCH v2 5/5] scsi: ufs-mediatek: Allow unbound mphy Stanley Chu

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).