Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 417dbabb authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "scsi: ufs: scale up the gear in 2 steps" into msm-4.9

parents 2f6bd4ba be096037
Loading
Loading
Loading
Loading
+15 −1
Original line number Diff line number Diff line
/*
 * Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
 * Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -30,6 +30,20 @@ static struct ufs_card_fix ufs_fixups[] = {
	UFS_FIX(UFS_VENDOR_SKHYNIX, UFS_ANY_MODEL,
		UFS_DEVICE_QUIRK_HOST_PA_SAVECONFIGTIME),
	UFS_FIX(UFS_VENDOR_SKHYNIX, UFS_ANY_MODEL, UFS_DEVICE_NO_VCCQ),
	UFS_FIX(UFS_VENDOR_SKHYNIX, "hB8aL1",
		UFS_DEVICE_QUIRK_HS_G1_TO_HS_G3_SWITCH),
	UFS_FIX(UFS_VENDOR_SKHYNIX, "hC8aL1",
		UFS_DEVICE_QUIRK_HS_G1_TO_HS_G3_SWITCH),
	UFS_FIX(UFS_VENDOR_SKHYNIX, "hD8aL1",
		UFS_DEVICE_QUIRK_HS_G1_TO_HS_G3_SWITCH),
	UFS_FIX(UFS_VENDOR_SKHYNIX, "hC8aM1",
		UFS_DEVICE_QUIRK_HS_G1_TO_HS_G3_SWITCH),
	UFS_FIX(UFS_VENDOR_SKHYNIX, "h08aM1",
		UFS_DEVICE_QUIRK_HS_G1_TO_HS_G3_SWITCH),
	UFS_FIX(UFS_VENDOR_SKHYNIX, "hC8GL1",
		UFS_DEVICE_QUIRK_HS_G1_TO_HS_G3_SWITCH),
	UFS_FIX(UFS_VENDOR_SKHYNIX, "hC8HL1",
		UFS_DEVICE_QUIRK_HS_G1_TO_HS_G3_SWITCH),

	END_FIX
};
+9 −1
Original line number Diff line number Diff line
/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved.
/* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -130,6 +130,14 @@ struct ufs_card_fix {
 */
#define UFS_DEVICE_QUIRK_HOST_PA_SAVECONFIGTIME	(1 << 7)

/*
 * Some UFS devices may stop responding after switching from HS-G1 to HS-G3.
 * Also, it is found that these devices work fine if we do 2 steps switch:
 * HS-G1 to HS-G2 followed by HS-G2 to HS-G3. Enabling this quirk for such
 * device would apply this 2 steps gear switch workaround.
 */
#define UFS_DEVICE_QUIRK_HS_G1_TO_HS_G3_SWITCH (1 << 8)

struct ufs_hba;
void ufs_advertise_fixup_device(struct ufs_hba *hba);

+30 −4
Original line number Diff line number Diff line
@@ -524,7 +524,7 @@ static int ufshcd_reset_device(struct ufs_hba *hba)
/* replace non-printable or non-ASCII characters with spaces */
static inline void ufshcd_remove_non_printable(char *val)
{
	if (!val)
	if (!val || !*val)
		return;

	if (*val < 0x20 || *val > 0x7e)
@@ -3670,7 +3670,7 @@ int ufshcd_read_string_desc(struct ufs_hba *hba, int desc_index, u8 *buf,
			goto out;
		}

		buff_ascii = kmalloc(ascii_len, GFP_KERNEL);
		buff_ascii = kzalloc(ascii_len, GFP_KERNEL);
		if (!buff_ascii) {
			dev_err(hba->dev, "%s: Failed allocating %d bytes\n",
					__func__, ascii_len);
@@ -9370,6 +9370,32 @@ static int ufshcd_scale_gear(struct ufs_hba *hba, bool scale_up)
	if (scale_up) {
		memcpy(&new_pwr_info, &hba->clk_scaling.saved_pwr_info.info,
		       sizeof(struct ufs_pa_layer_attr));
		/*
		 * Some UFS devices may stop responding after switching from
		 * HS-G1 to HS-G3. Also, it is found that these devices work
		 * fine if we do 2 steps switch: HS-G1 to HS-G2 followed by
		 * HS-G2 to HS-G3. If UFS_DEVICE_QUIRK_HS_G1_TO_HS_G3_SWITCH
		 * quirk is enabled for such devices, this 2 steps gear switch
		 * workaround will be applied.
		 */
		if ((hba->dev_info.quirks &
		     UFS_DEVICE_QUIRK_HS_G1_TO_HS_G3_SWITCH)
		    && (hba->pwr_info.gear_tx == UFS_HS_G1)
		    && (new_pwr_info.gear_tx == UFS_HS_G3)) {
			/* scale up to G2 first */
			new_pwr_info.gear_tx = UFS_HS_G2;
			new_pwr_info.gear_rx = UFS_HS_G2;
			ret = ufshcd_change_power_mode(hba, &new_pwr_info);
			if (ret)
				goto out;

			/* scale up to G3 now */
			new_pwr_info.gear_tx = UFS_HS_G3;
			new_pwr_info.gear_rx = UFS_HS_G3;
			ret = ufshcd_change_power_mode(hba, &new_pwr_info);
			if (ret)
				goto out;
		}
	} else {
		memcpy(&new_pwr_info, &hba->pwr_info,
		       sizeof(struct ufs_pa_layer_attr));
@@ -9389,10 +9415,10 @@ static int ufshcd_scale_gear(struct ufs_hba *hba, bool scale_up)
				new_pwr_info.pwr_rx = FASTAUTO_MODE;
			}
		}
	}

		ret = ufshcd_change_power_mode(hba, &new_pwr_info);
	}

out:
	if (ret)
		dev_err(hba->dev, "%s: failed err %d, old gear: (tx %d rx %d), new gear: (tx %d rx %d), scale_up = %d",
			__func__, ret,