Skip to content

Commit

Permalink
scsi: ufs: Introduce quirk to extend PA_HIBERN8TIME for UFS devices
Browse files Browse the repository at this point in the history
Samsung UFS devices require 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, a value derived from experiments, to ensure a proper hibernation
process.

Signed-off-by: Manish Pandey <quic_mapa@quicinc.com>
Link: https://lore.kernel.org/r/20250411121630.21330-3-quic_mapa@quicinc.com
Reviewed-by: Bean Huo <beanhuo@micron.com>
Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
  • Loading branch information
Manish Pandey authored and Martin K. Petersen committed Apr 12, 2025
1 parent f8cba9a commit 569330a
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 0 deletions.
29 changes: 29 additions & 0 deletions drivers/ufs/core/ufshcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -8470,6 +8471,31 @@ 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;
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);
Expand All @@ -8480,6 +8506,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)
Expand Down
6 changes: 6 additions & 0 deletions include/ufs/ufs_quirks.h
Original file line number Diff line number Diff line change
Expand Up @@ -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_ */

0 comments on commit 569330a

Please sign in to comment.