Commit b799fdf7 authored by Yaniv Gardi's avatar Yaniv Gardi Committed by Martin K. Petersen

scsi: ufs: add device quirk delay before putting UFS rails in LPM

We put the UFS device in sleep state & UFS link in hibern8 state during
runtime suspend. After this we put all the UFS rails in low power
modes immediately but it seems some devices may still draw more than
sleep current from UFS rails (especially from VCCQ rail) at-least for
500us.
To avoid this situation, this change adds 2ms delay before putting
these UFS rails in LPM mode.
Reviewed-by: default avatarGilad Broner <gbroner@codeaurora.org>
Reviewed-by: default avatarHannes Reinecke <hare@suse.de>
Signed-off-by: default avatarSubhash Jadavani <subhashj@codeaurora.org>
Signed-off-by: default avatarYaniv Gardi <ygardi@codeaurora.org>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent f3099fbd
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
/* return true if s1 is a prefix of s2 */ /* return true if s1 is a prefix of s2 */
#define STR_PRFX_EQUAL(s1, s2) !strncmp(s1, s2, strlen(s1)) #define STR_PRFX_EQUAL(s1, s2) !strncmp(s1, s2, strlen(s1))
#define UFS_ANY_VENDOR -1 #define UFS_ANY_VENDOR 0xFFFF
#define UFS_ANY_MODEL "ANY_MODEL" #define UFS_ANY_MODEL "ANY_MODEL"
#define MAX_MODEL_LEN 16 #define MAX_MODEL_LEN 16
...@@ -119,16 +119,28 @@ struct ufs_dev_fix { ...@@ -119,16 +119,28 @@ struct ufs_dev_fix {
*/ */
#define UFS_DEVICE_NO_FASTAUTO (1 << 5) #define UFS_DEVICE_NO_FASTAUTO (1 << 5)
/*
* It seems some UFS devices may keep drawing more than sleep current
* (atleast for 500us) from UFS rails (especially from VCCQ rail).
* To avoid this situation, add 2ms delay before putting these UFS
* rails in LPM mode.
*/
#define UFS_DEVICE_QUIRK_DELAY_BEFORE_LPM (1 << 6)
struct ufs_hba; struct ufs_hba;
void ufs_advertise_fixup_device(struct ufs_hba *hba); void ufs_advertise_fixup_device(struct ufs_hba *hba);
static struct ufs_dev_fix ufs_fixups[] = { static struct ufs_dev_fix ufs_fixups[] = {
/* UFS cards deviations table */ /* UFS cards deviations table */
UFS_FIX(UFS_VENDOR_SAMSUNG, UFS_ANY_MODEL,
UFS_DEVICE_QUIRK_DELAY_BEFORE_LPM),
UFS_FIX(UFS_VENDOR_SAMSUNG, UFS_ANY_MODEL, UFS_DEVICE_NO_VCCQ), UFS_FIX(UFS_VENDOR_SAMSUNG, UFS_ANY_MODEL, UFS_DEVICE_NO_VCCQ),
UFS_FIX(UFS_VENDOR_SAMSUNG, UFS_ANY_MODEL, UFS_FIX(UFS_VENDOR_SAMSUNG, UFS_ANY_MODEL,
UFS_DEVICE_QUIRK_RECOVERY_FROM_DL_NAC_ERRORS), UFS_DEVICE_QUIRK_RECOVERY_FROM_DL_NAC_ERRORS),
UFS_FIX(UFS_VENDOR_SAMSUNG, UFS_ANY_MODEL, UFS_FIX(UFS_VENDOR_SAMSUNG, UFS_ANY_MODEL,
UFS_DEVICE_NO_FASTAUTO), UFS_DEVICE_NO_FASTAUTO),
UFS_FIX(UFS_VENDOR_TOSHIBA, UFS_ANY_MODEL,
UFS_DEVICE_QUIRK_DELAY_BEFORE_LPM),
UFS_FIX(UFS_VENDOR_TOSHIBA, "THGLF2G9C8KBADG", UFS_FIX(UFS_VENDOR_TOSHIBA, "THGLF2G9C8KBADG",
UFS_DEVICE_QUIRK_PA_TACTIVATE), UFS_DEVICE_QUIRK_PA_TACTIVATE),
UFS_FIX(UFS_VENDOR_TOSHIBA, "THGLF2G9D8KBADG", UFS_FIX(UFS_VENDOR_TOSHIBA, "THGLF2G9D8KBADG",
......
...@@ -5715,6 +5715,16 @@ static int ufshcd_link_state_transition(struct ufs_hba *hba, ...@@ -5715,6 +5715,16 @@ static int ufshcd_link_state_transition(struct ufs_hba *hba,
static void ufshcd_vreg_set_lpm(struct ufs_hba *hba) static void ufshcd_vreg_set_lpm(struct ufs_hba *hba)
{ {
/*
* It seems some UFS devices may keep drawing more than sleep current
* (atleast for 500us) from UFS rails (especially from VCCQ rail).
* To avoid this situation, add 2ms delay before putting these UFS
* rails in LPM mode.
*/
if (!ufshcd_is_link_active(hba) &&
hba->dev_quirks & UFS_DEVICE_QUIRK_DELAY_BEFORE_LPM)
usleep_range(2000, 2100);
/* /*
* If UFS device is either in UFS_Sleep turn off VCC rail to save some * If UFS device is either in UFS_Sleep turn off VCC rail to save some
* power. * power.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment