diff mbox series

[V2,2/2] scsi: ufs: introduce quirk to extend PA_HIBERN8TIME for UFS devices

Message ID 20250404174539.28707-3-quic_mapa@quicinc.com (mailing list archive)
State New
Headers show
Series scsi: ufs: Implement Quirks for Samsung UFS Devices | expand

Commit Message

Manish Pandey April 4, 2025, 5:45 p.m. UTC
Some UFS devices need additional time in hibern8 mode before exiting,
beyond the negotiated handshaking phase between the host and device.
Introduce a quirk to increase the PA_HIBERN8TIME parameter by 100 µs
to ensure proper hibernation process.

Signed-off-by: Manish Pandey <quic_mapa@quicinc.com>
---
 drivers/ufs/core/ufshcd.c | 31 +++++++++++++++++++++++++++++++
 include/ufs/ufs_quirks.h  |  6 ++++++
 2 files changed, 37 insertions(+)

Comments

Manivannan Sadhasivam April 6, 2025, 6:35 p.m. UTC | #1
On Fri, Apr 04, 2025 at 11:15:39PM +0530, Manish Pandey wrote:
> Some UFS devices need additional time in hibern8 mode before exiting,
> beyond the negotiated handshaking phase between the host and device.
> Introduce a quirk to increase the PA_HIBERN8TIME parameter by 100 µs
> to ensure proper hibernation process.
> 

This commit message didn't mention the UFS device for which this quirk is being
applied.

> Signed-off-by: Manish Pandey <quic_mapa@quicinc.com>
> ---
>  drivers/ufs/core/ufshcd.c | 31 +++++++++++++++++++++++++++++++
>  include/ufs/ufs_quirks.h  |  6 ++++++
>  2 files changed, 37 insertions(+)
> 
> diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c
> index 464f13da259a..2b8203fe7b8c 100644
> --- a/drivers/ufs/core/ufshcd.c
> +++ b/drivers/ufs/core/ufshcd.c
> @@ -278,6 +278,7 @@ static const struct ufs_dev_quirk ufs_fixups[] = {
>  	  .model = UFS_ANY_MODEL,
>  	  .quirk = UFS_DEVICE_QUIRK_DELAY_BEFORE_LPM |
>  		   UFS_DEVICE_QUIRK_HOST_PA_TACTIVATE |
> +		   UFS_DEVICE_QUIRK_PA_HIBER8TIME |
>  		   UFS_DEVICE_QUIRK_RECOVERY_FROM_DL_NAC_ERRORS },
>  	{ .wmanufacturerid = UFS_VENDOR_SKHYNIX,
>  	  .model = UFS_ANY_MODEL,
> @@ -8384,6 +8385,33 @@ static int ufshcd_quirk_tune_host_pa_tactivate(struct ufs_hba *hba)
>  	return ret;
>  }
>  
> +/**
> + * ufshcd_quirk_override_pa_h8time - Ensures proper adjustment of PA_HIBERN8TIME.
> + * @hba: per-adapter instance
> + *
> + * Some UFS devices require specific adjustments to the PA_HIBERN8TIME parameter
> + * to ensure proper hibernation timing. This function retrieves the current
> + * PA_HIBERN8TIME value and increments it by 100us.
> + */
> +static void ufshcd_quirk_override_pa_h8time(struct ufs_hba *hba)
> +{
> +	u32 pa_h8time = 0;

Why do you need to initialize it?

> +	int ret;
> +
> +	ret = ufshcd_dme_get(hba, UIC_ARG_MIB(PA_HIBERN8TIME),
> +			&pa_h8time);
> +	if (ret) {
> +		dev_err(hba->dev, "Failed to get PA_HIBERN8TIME: %d\n", ret);
> +		return;
> +	}
> +
> +	/* Increment by 1 to increase hibernation time by 100 µs */

From where the value of 100us adjustment is coming from?

- Mani
diff mbox series

Patch

diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c
index 464f13da259a..2b8203fe7b8c 100644
--- a/drivers/ufs/core/ufshcd.c
+++ b/drivers/ufs/core/ufshcd.c
@@ -278,6 +278,7 @@  static const struct ufs_dev_quirk ufs_fixups[] = {
 	  .model = UFS_ANY_MODEL,
 	  .quirk = UFS_DEVICE_QUIRK_DELAY_BEFORE_LPM |
 		   UFS_DEVICE_QUIRK_HOST_PA_TACTIVATE |
+		   UFS_DEVICE_QUIRK_PA_HIBER8TIME |
 		   UFS_DEVICE_QUIRK_RECOVERY_FROM_DL_NAC_ERRORS },
 	{ .wmanufacturerid = UFS_VENDOR_SKHYNIX,
 	  .model = UFS_ANY_MODEL,
@@ -8384,6 +8385,33 @@  static int ufshcd_quirk_tune_host_pa_tactivate(struct ufs_hba *hba)
 	return ret;
 }
 
+/**
+ * ufshcd_quirk_override_pa_h8time - Ensures proper adjustment of PA_HIBERN8TIME.
+ * @hba: per-adapter instance
+ *
+ * Some UFS devices require specific adjustments to the PA_HIBERN8TIME parameter
+ * to ensure proper hibernation timing. This function retrieves the current
+ * PA_HIBERN8TIME value and increments it by 100us.
+ */
+static void ufshcd_quirk_override_pa_h8time(struct ufs_hba *hba)
+{
+	u32 pa_h8time = 0;
+	int ret;
+
+	ret = ufshcd_dme_get(hba, UIC_ARG_MIB(PA_HIBERN8TIME),
+			&pa_h8time);
+	if (ret) {
+		dev_err(hba->dev, "Failed to get PA_HIBERN8TIME: %d\n", ret);
+		return;
+	}
+
+	/* Increment by 1 to increase hibernation time by 100 µs */
+	ret = ufshcd_dme_set(hba, UIC_ARG_MIB(PA_HIBERN8TIME),
+			pa_h8time + 1);
+	if (ret)
+		dev_err(hba->dev, "Failed updating PA_HIBERN8TIME: %d\n", ret);
+}
+
 static void ufshcd_tune_unipro_params(struct ufs_hba *hba)
 {
 	ufshcd_vops_apply_dev_quirks(hba);
@@ -8394,6 +8422,9 @@  static void ufshcd_tune_unipro_params(struct ufs_hba *hba)
 
 	if (hba->dev_quirks & UFS_DEVICE_QUIRK_HOST_PA_TACTIVATE)
 		ufshcd_quirk_tune_host_pa_tactivate(hba);
+
+	if (hba->dev_quirks & UFS_DEVICE_QUIRK_PA_HIBER8TIME)
+		ufshcd_quirk_override_pa_h8time(hba);
 }
 
 static void ufshcd_clear_dbg_ufs_stats(struct ufs_hba *hba)
diff --git a/include/ufs/ufs_quirks.h b/include/ufs/ufs_quirks.h
index 41ff44dfa1db..f52de5ed1b3b 100644
--- a/include/ufs/ufs_quirks.h
+++ b/include/ufs/ufs_quirks.h
@@ -107,4 +107,10 @@  struct ufs_dev_quirk {
  */
 #define UFS_DEVICE_QUIRK_DELAY_AFTER_LPM        (1 << 11)
 
+/*
+ * Some ufs devices may need more time to be in hibern8 before exiting.
+ * Enable this quirk to give it an additional 100us.
+ */
+#define UFS_DEVICE_QUIRK_PA_HIBER8TIME          (1 << 12)
+
 #endif /* UFS_QUIRKS_H_ */