diff options
| -rw-r--r-- | drivers/ufs/host/ufs-qcom.c | 26 | ||||
| -rw-r--r-- | drivers/ufs/host/ufs-qcom.h | 2 | 
2 files changed, 24 insertions, 4 deletions
| diff --git a/drivers/ufs/host/ufs-qcom.c b/drivers/ufs/host/ufs-qcom.c index e6a1384eb535..3370fa4364f0 100644 --- a/drivers/ufs/host/ufs-qcom.c +++ b/drivers/ufs/host/ufs-qcom.c @@ -293,7 +293,6 @@ static int ufs_qcom_power_up_sequence(struct ufs_hba *hba)  	struct ufs_qcom_host *host = ufshcd_get_variant(hba);  	struct phy *phy = host->generic_phy;  	int ret; -	bool is_rate_B = UFS_QCOM_LIMIT_HS_RATE == PA_HS_MODE_B;  	/* Reset UFS Host Controller and PHY */  	ret = ufs_qcom_host_reset(hba); @@ -301,9 +300,6 @@ static int ufs_qcom_power_up_sequence(struct ufs_hba *hba)  		dev_warn(hba->dev, "%s: host reset returned %d\n",  				  __func__, ret); -	if (is_rate_B) -		phy_set_mode(phy, PHY_MODE_UFS_HS_B); -  	/* phy initialization - calibrate the phy */  	ret = phy_init(phy);  	if (ret) { @@ -312,6 +308,8 @@ static int ufs_qcom_power_up_sequence(struct ufs_hba *hba)  		return ret;  	} +	phy_set_mode_ext(phy, PHY_MODE_UFS_HS_B, host->hs_gear); +  	/* power on phy - start serdes and phy's power and clocks */  	ret = phy_power_on(phy);  	if (ret) { @@ -714,6 +712,9 @@ static int ufs_qcom_pwr_change_notify(struct ufs_hba *hba,  			return ret;  		} +		/* Use the agreed gear */ +		host->hs_gear = dev_req_params->gear_tx; +  		/* enable the device ref clock before changing to HS mode */  		if (!ufshcd_is_hs_mode(&hba->pwr_info) &&  			ufshcd_is_hs_mode(dev_req_params)) @@ -827,6 +828,9 @@ static void ufs_qcom_advertise_quirks(struct ufs_hba *hba)  				| UFSHCD_QUIRK_DME_PEER_ACCESS_AUTO_MODE  				| UFSHCD_QUIRK_BROKEN_PA_RXHSUNTERMCAP);  	} + +	if (host->hw_ver.major > 0x3) +		hba->quirks |= UFSHCD_QUIRK_REINIT_AFTER_MAX_GEAR_SWITCH;  }  static void ufs_qcom_set_caps(struct ufs_hba *hba) @@ -1034,6 +1038,12 @@ static int ufs_qcom_init(struct ufs_hba *hba)  		dev_warn(dev, "%s: failed to configure the testbus %d\n",  				__func__, err); +	/* +	 * Power up the PHY using the minimum supported gear (UFS_HS_G2). +	 * Switching to max gear will be performed during reinit if supported. +	 */ +	host->hs_gear = UFS_HS_G2; +  	return 0;  out_variant_clear: @@ -1377,6 +1387,13 @@ static void ufs_qcom_config_scaling_param(struct ufs_hba *hba,  }  #endif +static void ufs_qcom_reinit_notify(struct ufs_hba *hba) +{ +	struct ufs_qcom_host *host = ufshcd_get_variant(hba); + +	phy_power_off(host->generic_phy); +} +  /*   * struct ufs_hba_qcom_vops - UFS QCOM specific variant operations   * @@ -1400,6 +1417,7 @@ static const struct ufs_hba_variant_ops ufs_hba_qcom_vops = {  	.device_reset		= ufs_qcom_device_reset,  	.config_scaling_param = ufs_qcom_config_scaling_param,  	.program_key		= ufs_qcom_ice_program_key, +	.reinit_notify		= ufs_qcom_reinit_notify,  };  /** diff --git a/drivers/ufs/host/ufs-qcom.h b/drivers/ufs/host/ufs-qcom.h index 1d9bad596a87..6cb970530060 100644 --- a/drivers/ufs/host/ufs-qcom.h +++ b/drivers/ufs/host/ufs-qcom.h @@ -206,6 +206,8 @@ struct ufs_qcom_host {  	struct reset_controller_dev rcdev;  	struct gpio_desc *device_reset; + +	u32 hs_gear;  };  static inline u32 | 
