Message ID | 20200729051840.31318-2-stanley.chu@mediatek.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | scsi: ufs: Introduce and apply DELAY_AFTER_LPM device quirk | expand |
Hi Stanley, On 2020-07-29 13:18, Stanley Chu wrote: > Some UFS devices require delay after VCC power rail is turned-off. > Introduce a device quirk "DELAY_AFTER_LPM" to add 5ms delays after > VCC power-off during suspend flow. > Just curious, I can understand if you want to add some delays before turnning off VCC/VCCQ/VCCQ2, but what is the delay AFTER turnning them off for? I mean the power has been cut by host from PMIC, how can the delay benefit the UFS device? Thanks, Can Guo. > Signed-off-by: Andy Teng <andy.teng@mediatek.com> > Signed-off-by: Peter Wang <peter.wang@mediatek.com> > Signed-off-by: Stanley Chu <stanley.chu@mediatek.com> > --- > drivers/scsi/ufs/ufs_quirks.h | 7 +++++++ > drivers/scsi/ufs/ufshcd.c | 11 +++++++++++ > 2 files changed, 18 insertions(+) > > diff --git a/drivers/scsi/ufs/ufs_quirks.h > b/drivers/scsi/ufs/ufs_quirks.h > index 2a0041493e30..07f559ac5883 100644 > --- a/drivers/scsi/ufs/ufs_quirks.h > +++ b/drivers/scsi/ufs/ufs_quirks.h > @@ -109,4 +109,11 @@ struct ufs_dev_fix { > */ > #define UFS_DEVICE_QUIRK_SUPPORT_EXTENDED_FEATURES (1 << 10) > > +/* > + * Some UFS devices require delay after VCC power rail is turned-off. > + * Enable this quirk to introduce 5ms delays after VCC power-off > during > + * suspend flow. > + */ > +#define UFS_DEVICE_QUIRK_DELAY_AFTER_LPM (1 << 11) > + > #endif /* UFS_QUIRKS_H_ */ > diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c > index acba2271c5d3..63f4e2f75aa1 100644 > --- a/drivers/scsi/ufs/ufshcd.c > +++ b/drivers/scsi/ufs/ufshcd.c > @@ -8111,6 +8111,8 @@ static int ufshcd_link_state_transition(struct > ufs_hba *hba, > > static void ufshcd_vreg_set_lpm(struct ufs_hba *hba) > { > + bool vcc_off = false; > + > /* > * It seems some UFS devices may keep drawing more than sleep current > * (atleast for 500us) from UFS rails (especially from VCCQ rail). > @@ -8139,13 +8141,22 @@ static void ufshcd_vreg_set_lpm(struct ufs_hba > *hba) > if (ufshcd_is_ufs_dev_poweroff(hba) && ufshcd_is_link_off(hba) && > !hba->dev_info.is_lu_power_on_wp) { > ufshcd_setup_vreg(hba, false); > + vcc_off = true; > } else if (!ufshcd_is_ufs_dev_active(hba)) { > ufshcd_toggle_vreg(hba->dev, hba->vreg_info.vcc, false); > + vcc_off = true; > if (!ufshcd_is_link_active(hba)) { > ufshcd_config_vreg_lpm(hba, hba->vreg_info.vccq); > ufshcd_config_vreg_lpm(hba, hba->vreg_info.vccq2); > } > } > + > + /* > + * Some UFS devices require delay after VCC power rail is turned-off. > + */ > + if (vcc_off && hba->vreg_info.vcc && > + hba->dev_quirks & UFS_DEVICE_QUIRK_DELAY_AFTER_LPM) > + usleep_range(5000, 5100); > } > > static int ufshcd_vreg_set_hpm(struct ufs_hba *hba)
Hi Can, On Wed, 2020-07-29 at 13:31 +0800, Can Guo wrote: > Hi Stanley, > > On 2020-07-29 13:18, Stanley Chu wrote: > > Some UFS devices require delay after VCC power rail is turned-off. > > Introduce a device quirk "DELAY_AFTER_LPM" to add 5ms delays after > > VCC power-off during suspend flow. > > > > Just curious, I can understand if you want to add some delays before > turnning off VCC/VCCQ/VCCQ2, but what is the delay AFTER turnning > them off for? I mean the power has been cut by host from PMIC, how > can the delay benefit the UFS device? > The problem comes from both sides, 1. VCC power rail design by SoC vendors, and 2. Device strategy according to VCC changes Take Micron UFS devices on MediaTek platform as example, our VCC drop rate may be too slow and lead to incorrect resume strategy by device. Without this delay, device may not resume successfully. Thanks, Stanley Chu
On 2020-07-29 13:18, Stanley Chu wrote: > Some UFS devices require delay after VCC power rail is turned-off. > Introduce a device quirk "DELAY_AFTER_LPM" to add 5ms delays after > VCC power-off during suspend flow. > > Signed-off-by: Andy Teng <andy.teng@mediatek.com> > Signed-off-by: Peter Wang <peter.wang@mediatek.com> > Signed-off-by: Stanley Chu <stanley.chu@mediatek.com> > --- > drivers/scsi/ufs/ufs_quirks.h | 7 +++++++ > drivers/scsi/ufs/ufshcd.c | 11 +++++++++++ > 2 files changed, 18 insertions(+) > > diff --git a/drivers/scsi/ufs/ufs_quirks.h > b/drivers/scsi/ufs/ufs_quirks.h > index 2a0041493e30..07f559ac5883 100644 > --- a/drivers/scsi/ufs/ufs_quirks.h > +++ b/drivers/scsi/ufs/ufs_quirks.h > @@ -109,4 +109,11 @@ struct ufs_dev_fix { > */ > #define UFS_DEVICE_QUIRK_SUPPORT_EXTENDED_FEATURES (1 << 10) > > +/* > + * Some UFS devices require delay after VCC power rail is turned-off. > + * Enable this quirk to introduce 5ms delays after VCC power-off > during > + * suspend flow. > + */ > +#define UFS_DEVICE_QUIRK_DELAY_AFTER_LPM (1 << 11) > + > #endif /* UFS_QUIRKS_H_ */ > diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c > index acba2271c5d3..63f4e2f75aa1 100644 > --- a/drivers/scsi/ufs/ufshcd.c > +++ b/drivers/scsi/ufs/ufshcd.c > @@ -8111,6 +8111,8 @@ static int ufshcd_link_state_transition(struct > ufs_hba *hba, > > static void ufshcd_vreg_set_lpm(struct ufs_hba *hba) > { > + bool vcc_off = false; > + > /* > * It seems some UFS devices may keep drawing more than sleep current > * (atleast for 500us) from UFS rails (especially from VCCQ rail). > @@ -8139,13 +8141,22 @@ static void ufshcd_vreg_set_lpm(struct ufs_hba > *hba) > if (ufshcd_is_ufs_dev_poweroff(hba) && ufshcd_is_link_off(hba) && > !hba->dev_info.is_lu_power_on_wp) { > ufshcd_setup_vreg(hba, false); > + vcc_off = true; > } else if (!ufshcd_is_ufs_dev_active(hba)) { > ufshcd_toggle_vreg(hba->dev, hba->vreg_info.vcc, false); > + vcc_off = true; > if (!ufshcd_is_link_active(hba)) { > ufshcd_config_vreg_lpm(hba, hba->vreg_info.vccq); > ufshcd_config_vreg_lpm(hba, hba->vreg_info.vccq2); > } > } > + > + /* > + * Some UFS devices require delay after VCC power rail is turned-off. > + */ > + if (vcc_off && hba->vreg_info.vcc && > + hba->dev_quirks & UFS_DEVICE_QUIRK_DELAY_AFTER_LPM) > + usleep_range(5000, 5100); > } > > static int ufshcd_vreg_set_hpm(struct ufs_hba *hba) Reviewed-by: Can Guo <cang@codeaurora.org>
diff --git a/drivers/scsi/ufs/ufs_quirks.h b/drivers/scsi/ufs/ufs_quirks.h index 2a0041493e30..07f559ac5883 100644 --- a/drivers/scsi/ufs/ufs_quirks.h +++ b/drivers/scsi/ufs/ufs_quirks.h @@ -109,4 +109,11 @@ struct ufs_dev_fix { */ #define UFS_DEVICE_QUIRK_SUPPORT_EXTENDED_FEATURES (1 << 10) +/* + * Some UFS devices require delay after VCC power rail is turned-off. + * Enable this quirk to introduce 5ms delays after VCC power-off during + * suspend flow. + */ +#define UFS_DEVICE_QUIRK_DELAY_AFTER_LPM (1 << 11) + #endif /* UFS_QUIRKS_H_ */ diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index acba2271c5d3..63f4e2f75aa1 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -8111,6 +8111,8 @@ static int ufshcd_link_state_transition(struct ufs_hba *hba, static void ufshcd_vreg_set_lpm(struct ufs_hba *hba) { + bool vcc_off = false; + /* * It seems some UFS devices may keep drawing more than sleep current * (atleast for 500us) from UFS rails (especially from VCCQ rail). @@ -8139,13 +8141,22 @@ static void ufshcd_vreg_set_lpm(struct ufs_hba *hba) if (ufshcd_is_ufs_dev_poweroff(hba) && ufshcd_is_link_off(hba) && !hba->dev_info.is_lu_power_on_wp) { ufshcd_setup_vreg(hba, false); + vcc_off = true; } else if (!ufshcd_is_ufs_dev_active(hba)) { ufshcd_toggle_vreg(hba->dev, hba->vreg_info.vcc, false); + vcc_off = true; if (!ufshcd_is_link_active(hba)) { ufshcd_config_vreg_lpm(hba, hba->vreg_info.vccq); ufshcd_config_vreg_lpm(hba, hba->vreg_info.vccq2); } } + + /* + * Some UFS devices require delay after VCC power rail is turned-off. + */ + if (vcc_off && hba->vreg_info.vcc && + hba->dev_quirks & UFS_DEVICE_QUIRK_DELAY_AFTER_LPM) + usleep_range(5000, 5100); } static int ufshcd_vreg_set_hpm(struct ufs_hba *hba)