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

Commit 6de2bbe8 authored by Subhash Jadavani's avatar Subhash Jadavani Committed by David Keitel
Browse files

scsi: ufs: add quirk to increase host PA_SaveConfigTime



The maximum value PA_SaveConfigTime is 250 (10us) but this is not enough
for some vendors. Gear switch from PWM to HS may fail even with this max.
PA_SaveConfigTime. Gear switch can be issued by host controller as an
error recovery and any software delay will not help on this case so we
need to increase PA_SaveConfigTime to >32us as per vendor recommendation.
This change adds a quirk to increase the PA_SaveConfigTime parameter.

Change-Id: I02a0394bb07f165ba8ae6c5802567cc6d8ad0d16
Signed-off-by: default avatarSubhash Jadavani <subhashj@codeaurora.org>
parent 8f47acdd
Loading
Loading
Loading
Loading
+30 −0
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@
#include "unipro.h"
#include "ufs-qcom.h"
#include "ufshci.h"
#include "ufs_quirks.h"
#include "ufs-qcom-ice.h"
#include "ufs-qcom-debugfs.h"
#include <linux/clk/msm-clk.h>
@@ -1161,6 +1162,34 @@ out:
	return ret;
}

static int ufs_qcom_quirk_host_pa_saveconfigtime(struct ufs_hba *hba)
{
	int err;
	u32 pa_vs_config_reg1;

	err = ufshcd_dme_get(hba, UIC_ARG_MIB(PA_VS_CONFIG_REG1),
			     &pa_vs_config_reg1);
	if (err)
		goto out;

	/* Allow extension of MSB bits of PA_SaveConfigTime attribute */
	err = ufshcd_dme_set(hba, UIC_ARG_MIB(PA_VS_CONFIG_REG1),
			    (pa_vs_config_reg1 | (1 << 12)));

out:
	return err;
}

static int ufs_qcom_apply_dev_quirks(struct ufs_hba *hba)
{
	int err = 0;

	if (hba->dev_quirks & UFS_DEVICE_QUIRK_HOST_PA_SAVECONFIGTIME)
		err = ufs_qcom_quirk_host_pa_saveconfigtime(hba);

	return err;
}

static u32 ufs_qcom_get_ufs_hci_version(struct ufs_hba *hba)
{
	struct ufs_qcom_host *host = ufshcd_get_variant(hba);
@@ -2258,6 +2287,7 @@ static struct ufs_hba_variant_ops ufs_hba_qcom_vops = {
	.hce_enable_notify      = ufs_qcom_hce_enable_notify,
	.link_startup_notify    = ufs_qcom_link_startup_notify,
	.pwr_change_notify	= ufs_qcom_pwr_change_notify,
	.apply_dev_quirks	= ufs_qcom_apply_dev_quirks,
	.suspend		= ufs_qcom_suspend,
	.resume			= ufs_qcom_resume,
	.full_reset		= ufs_qcom_full_reset,
+1 −0
Original line number Diff line number Diff line
@@ -147,6 +147,7 @@ enum ufs_qcom_phy_init_type {
	 UFS_QCOM_DBG_PRINT_TEST_BUS_EN)

/* QUniPro Vendor specific attributes */
#define PA_VS_CONFIG_REG1	0x9000
#define DME_VS_CORE_CLK_CTRL	0xD002
/* bit and mask definitions for DME_VS_CORE_CLK_CTRL attribute */
#define DME_VS_CORE_CLK_CTRL_CORE_CLK_DIV_EN_BIT		BIT(8)
+2 −0
Original line number Diff line number Diff line
@@ -28,6 +28,8 @@ static struct ufs_card_fix ufs_fixups[] = {
		UFS_DEVICE_QUIRK_PA_TACTIVATE),
	UFS_FIX(UFS_VENDOR_SAMSUNG, UFS_ANY_MODEL,
		UFS_DEVICE_QUIRK_HOST_PA_TACTIVATE),
	UFS_FIX(UFS_VENDOR_HYNIX, UFS_ANY_MODEL,
		UFS_DEVICE_QUIRK_HOST_PA_SAVECONFIGTIME),

	END_FIX
};
+10 −0
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@

#define UFS_VENDOR_TOSHIBA     0x198
#define UFS_VENDOR_SAMSUNG     0x1CE
#define UFS_VENDOR_HYNIX       0x1AD

/* UFS TOSHIBA MODELS */
#define UFS_MODEL_TOSHIBA_32GB "THGLF2G8D4KBADR"
@@ -128,6 +129,15 @@ struct ufs_card_fix {
 */
#define UFS_DEVICE_QUIRK_HOST_PA_TACTIVATE	(1 << 6)

/*
 * The max. value PA_SaveConfigTime is 250 (10us) but this is not enough for
 * some vendors.
 * Gear switch from PWM to HS may fail even with this max. PA_SaveConfigTime.
 * Gear switch can be issued by host controller as an error recovery and any
 * software delay will not help on this case so we need to increase
 * PA_SaveConfigTime to >32us as per vendor recommendation.
 */
#define UFS_DEVICE_QUIRK_HOST_PA_SAVECONFIGTIME	(1 << 7)

struct ufs_hba;
void ufs_advertise_fixup_device(struct ufs_hba *hba);
+2 −0
Original line number Diff line number Diff line
@@ -6617,6 +6617,8 @@ static void ufshcd_tune_unipro_params(struct ufs_hba *hba)

	if (hba->dev_quirks & UFS_DEVICE_QUIRK_HOST_PA_TACTIVATE)
		ufshcd_quirk_tune_host_pa_tactivate(hba);

	ufshcd_vops_apply_dev_quirks(hba);
}

static void ufshcd_clear_dbg_ufs_stats(struct ufs_hba *hba)
Loading