Re: [PATCH v5 6/8] scsi: ufs: Add dev ref clock gating wait time support

From: Can Guo
Date: Tue Feb 04 2020 - 23:52:25 EST


On 2020-02-05 10:50, Stanley Chu wrote:
Hi Can,

On Mon, 2020-02-03 at 01:17 -0800, Can Guo wrote:
In UFS version 3.0, a newly added attribute bRefClkGatingWaitTime defines
the minimum time for which the reference clock is required by device during
transition to LS-MODE or HIBERN8 state. Make this change to reflect the new
requirement by adding delays before turning off the clock.

Signed-off-by: Can Guo <cang@xxxxxxxxxxxxxx>
Reviewed-by: Asutosh Das <asutoshd@xxxxxxxxxxxxxx>
---
drivers/scsi/ufs/ufs.h | 3 +++
drivers/scsi/ufs/ufshcd.c | 40 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 43 insertions(+)

diff --git a/drivers/scsi/ufs/ufs.h b/drivers/scsi/ufs/ufs.h
index cfe3803..304076e 100644
--- a/drivers/scsi/ufs/ufs.h
+++ b/drivers/scsi/ufs/ufs.h
@@ -167,6 +167,7 @@ enum attr_idn {
QUERY_ATTR_IDN_FFU_STATUS = 0x14,
QUERY_ATTR_IDN_PSA_STATE = 0x15,
QUERY_ATTR_IDN_PSA_DATA_SIZE = 0x16,
+ QUERY_ATTR_IDN_REF_CLK_GATING_WAIT_TIME = 0x17,
};

/* Descriptor idn for Query requests */
@@ -534,6 +535,8 @@ struct ufs_dev_info {
u16 wmanufacturerid;
/*UFS device Product Name */
u8 *model;
+ u16 spec_version;
+ u32 clk_gating_wait_us;
};

/**
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index e8f7f9d..d5c547b 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -91,6 +91,9 @@
/* default delay of autosuspend: 2000 ms */
#define RPM_AUTOSUSPEND_DELAY_MS 2000

+/* Default value of wait time before gating device ref clock */
+#define UFSHCD_REF_CLK_GATING_WAIT_US 0xFF /* microsecs */
+
#define ufshcd_toggle_vreg(_dev, _vreg, _on) \
({ \
int _ret; \
@@ -3281,6 +3284,37 @@ static inline int ufshcd_read_unit_desc_param(struct ufs_hba *hba,
param_offset, param_read_buf, param_size);
}

+static int ufshcd_get_ref_clk_gating_wait(struct ufs_hba *hba)
+{
+ int err = 0;
+ u32 gating_wait = UFSHCD_REF_CLK_GATING_WAIT_US;
+
+ if (hba->dev_info.spec_version >= 0x300) {
+ err = ufshcd_query_attr_retry(hba, UPIU_QUERY_OPCODE_READ_ATTR,
+ QUERY_ATTR_IDN_REF_CLK_GATING_WAIT_TIME, 0, 0,
+ &gating_wait);
+ if (err)
+ dev_err(hba->dev, "Failed reading bRefClkGatingWait. err = %d, use default %uus\n",
+ err, gating_wait);
+
+ if (gating_wait == 0) {
+ gating_wait = UFSHCD_REF_CLK_GATING_WAIT_US;
+ dev_err(hba->dev, "Undefined ref clk gating wait time, use default %uus\n",
+ gating_wait);
+ }
+
+ /*
+ * bRefClkGatingWaitTime defines the minimum time for which the
+ * reference clock is required by device during transition from
+ * HS-MODE to LS-MODE or HIBERN8 state. Give it more time to be
+ * on the safe side.
+ */
+ hba->dev_info.clk_gating_wait_us = gating_wait + 50;


Not sure if the additional 50us wait time here is too large.

Is there any special reason to fix it as "50"?


Thanks,
Stanley


Hi Stanley,

We used to ask vendors about it, 50 is somehow agreed by them. Do you have a
better value in mind?

For me, I just wanted to give it 10, so that we can directly use usleep_range
with it, no need to decide whether to use udelay or usleep_range.

Thanks,
Can Guo.

&dev_info->model, SD_ASCII_STD);
@@ -7003,6 +7041,8 @@ static int ufshcd_device_params_init(struct ufs_hba *hba)
goto out;
}

+ ufshcd_get_ref_clk_gating_wait(hba);
+
ufs_fixup_device_setup(hba);

if (!ufshcd_query_flag_retry(hba, UPIU_QUERY_OPCODE_READ_FLAG,