From d05664f31fe823f5ec27605f839d9dfef0b9a51f Mon Sep 17 00:00:00 2001 From: Nitin Rawat Date: Thu, 16 Jul 2020 01:44:55 +0530 Subject: [PATCH] scsi: ufs: update UFS initialization sequence During UFS host init, we calibrate the UFS host PHY with HS-Gear4 Rate-B settings by default. After UFS device is initialized but before it switched to HS mode, if it found as UFS 2.x device we re-init the UFS host PHY with its HS-Gear3 Rate-B settings, then start over the UFS device initialization again. Change-Id: I854a34b2e5d76103d447508cf2137427def93d17 Signed-off-by: Can Guo Signed-off-by: Nitin Rawat Signed-off-by: Ram Prakash Gupta --- drivers/scsi/ufs/ufs-qcom.c | 7 +++++++ drivers/scsi/ufs/ufshcd.c | 34 ++++++++++++++++++++++++++++++++++ drivers/scsi/ufs/ufshcd.h | 2 +- 3 files changed, 42 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/ufs/ufs-qcom.c b/drivers/scsi/ufs/ufs-qcom.c index 18235ddcdc40..1ee2454d03fb 100644 --- a/drivers/scsi/ufs/ufs-qcom.c +++ b/drivers/scsi/ufs/ufs-qcom.c @@ -534,6 +534,10 @@ static int ufs_qcom_power_up_sequence(struct ufs_hba *hba) if (host->hw_ver.major < 0x4) submode = UFS_QCOM_PHY_SUBMODE_NON_G4; +#if defined(CONFIG_SCSI_UFSHCD_QTI) + if (hba->limit_phy_submode == 0) + submode = UFS_QCOM_PHY_SUBMODE_NON_G4; +#endif phy_set_mode_ext(phy, mode, submode); ret = ufs_qcom_phy_power_on(hba); @@ -3373,6 +3377,9 @@ static void ufs_qcom_parse_limits(struct ufs_qcom_host *host) of_property_read_u32(np, "limit-rx-pwm-gear", &host->limit_rx_pwm_gear); of_property_read_u32(np, "limit-rate", &host->limit_rate); of_property_read_u32(np, "limit-phy-submode", &host->limit_phy_submode); +#if defined(CONFIG_SCSI_UFSHCD_QTI) + host->hba->limit_phy_submode = host->limit_phy_submode; +#endif } /* diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index d4a716f170fb..f2942cc78a7c 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -7790,9 +7790,15 @@ static int ufshcd_probe_hba(struct ufs_hba *hba, bool async) { int ret; unsigned long flags; +#if defined(CONFIG_SCSI_UFSHCD_QTI) + bool reinit_needed = true; +#endif ktime_t start = ktime_get(); dev_err(hba->dev, "*** This is %s ***\n", __FILE__); +#if defined(CONFIG_SCSI_UFSHCD_QTI) +reinit: +#endif ret = ufshcd_link_startup(hba); if (ret) goto out; @@ -7827,6 +7833,34 @@ static int ufshcd_probe_hba(struct ufs_hba *hba, bool async) goto out; } +#if defined(CONFIG_SCSI_UFSHCD_QTI) + /* + * After reading the device descriptor, it is found as UFS 2.x + * device and limit_phy_submode is set as 1 in DT file i.e + * host phy is calibrated with gear4 setting, we need to + * reinitialize UFS phy host with HS-Gear3, Rate B. + */ + if (hba->dev_info.wspecversion < 0x300 && + hba->limit_phy_submode && reinit_needed) { + unsigned long flags; + int err; + + ufshcd_vops_device_reset(hba); + + /* Reset the host controller */ + spin_lock_irqsave(hba->host->host_lock, flags); + ufshcd_hba_stop(hba, false); + spin_unlock_irqrestore(hba->host->host_lock, flags); + + hba->limit_phy_submode = 0; + err = ufshcd_hba_enable(hba); + if (err) + goto out; + reinit_needed = false; + + goto reinit; + } +#endif ufshcd_tune_unipro_params(hba); /* UFS device is also active now */ diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index 24f14350087e..91aee90ec047 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -389,7 +389,6 @@ struct ufs_hba_variant_ops { void (*config_scaling_param)(struct ufs_hba *hba, struct devfreq_dev_profile *profile, void *data); - ANDROID_KABI_RESERVE(1); ANDROID_KABI_RESERVE(2); ANDROID_KABI_RESERVE(3); @@ -996,6 +995,7 @@ struct ufs_hba { u32 limit_rx_hs_gear; u32 limit_tx_pwm_gear; u32 limit_rx_pwm_gear; + u32 limit_phy_submode; bool restore_needed; u32 scsi_cmd_timeout; bool auto_h8_err;