scsi: ufs: Add a quirk to permit overriding UniPro defaults
authorKiwoong Kim <kwmad.kim@samsung.com>
Mon, 21 Dec 2020 01:24:40 +0000 (10:24 +0900)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 11 Mar 2021 13:17:27 +0000 (14:17 +0100)
[ Upstream commit b1d0d2eb89d4e3a25b212a9d836587503537067e ]

The UniPro specification states that attribute IDs of the following
parameters are vendor-specific so some SoCs could have no regions at the
defined addresses:

 - DME_LocalFC0ProtectionTimeOutVal
 - DME_LocalTC0ReplayTimeOutVal
 - DME_LocalAFC0ReqTimeOutVal

In addition, the following parameters should be set considering the
compatibility between host and device.

 - PA_PWRMODEUSERDATA0
 - PA_PWRMODEUSERDATA1
 - PA_PWRMODEUSERDATA2
 - PA_PWRMODEUSERDATA3
 - PA_PWRMODEUSERDATA4
 - PA_PWRMODEUSERDATA5

Introduce a quirk to allow vendor drivers to override the UniPro defaults.

Link: https://lore.kernel.org/r/1fedd3dea0ccc980913a5995a10510d86a5b01b9.1608513782.git.kwmad.kim@samsung.com
Acked-by: Avri Altman <Avri.Altman@wdc.com>
Signed-off-by: Kiwoong Kim <kwmad.kim@samsung.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/scsi/ufs/ufshcd.c
drivers/scsi/ufs/ufshcd.h

index 8132893..379d44d 100644 (file)
@@ -4153,25 +4153,27 @@ static int ufshcd_change_power_mode(struct ufs_hba *hba,
                ufshcd_dme_set(hba, UIC_ARG_MIB(PA_HSSERIES),
                                                pwr_mode->hs_rate);
 
-       ufshcd_dme_set(hba, UIC_ARG_MIB(PA_PWRMODEUSERDATA0),
-                       DL_FC0ProtectionTimeOutVal_Default);
-       ufshcd_dme_set(hba, UIC_ARG_MIB(PA_PWRMODEUSERDATA1),
-                       DL_TC0ReplayTimeOutVal_Default);
-       ufshcd_dme_set(hba, UIC_ARG_MIB(PA_PWRMODEUSERDATA2),
-                       DL_AFC0ReqTimeOutVal_Default);
-       ufshcd_dme_set(hba, UIC_ARG_MIB(PA_PWRMODEUSERDATA3),
-                       DL_FC1ProtectionTimeOutVal_Default);
-       ufshcd_dme_set(hba, UIC_ARG_MIB(PA_PWRMODEUSERDATA4),
-                       DL_TC1ReplayTimeOutVal_Default);
-       ufshcd_dme_set(hba, UIC_ARG_MIB(PA_PWRMODEUSERDATA5),
-                       DL_AFC1ReqTimeOutVal_Default);
-
-       ufshcd_dme_set(hba, UIC_ARG_MIB(DME_LocalFC0ProtectionTimeOutVal),
-                       DL_FC0ProtectionTimeOutVal_Default);
-       ufshcd_dme_set(hba, UIC_ARG_MIB(DME_LocalTC0ReplayTimeOutVal),
-                       DL_TC0ReplayTimeOutVal_Default);
-       ufshcd_dme_set(hba, UIC_ARG_MIB(DME_LocalAFC0ReqTimeOutVal),
-                       DL_AFC0ReqTimeOutVal_Default);
+       if (!(hba->quirks & UFSHCD_QUIRK_SKIP_DEF_UNIPRO_TIMEOUT_SETTING)) {
+               ufshcd_dme_set(hba, UIC_ARG_MIB(PA_PWRMODEUSERDATA0),
+                               DL_FC0ProtectionTimeOutVal_Default);
+               ufshcd_dme_set(hba, UIC_ARG_MIB(PA_PWRMODEUSERDATA1),
+                               DL_TC0ReplayTimeOutVal_Default);
+               ufshcd_dme_set(hba, UIC_ARG_MIB(PA_PWRMODEUSERDATA2),
+                               DL_AFC0ReqTimeOutVal_Default);
+               ufshcd_dme_set(hba, UIC_ARG_MIB(PA_PWRMODEUSERDATA3),
+                               DL_FC1ProtectionTimeOutVal_Default);
+               ufshcd_dme_set(hba, UIC_ARG_MIB(PA_PWRMODEUSERDATA4),
+                               DL_TC1ReplayTimeOutVal_Default);
+               ufshcd_dme_set(hba, UIC_ARG_MIB(PA_PWRMODEUSERDATA5),
+                               DL_AFC1ReqTimeOutVal_Default);
+
+               ufshcd_dme_set(hba, UIC_ARG_MIB(DME_LocalFC0ProtectionTimeOutVal),
+                               DL_FC0ProtectionTimeOutVal_Default);
+               ufshcd_dme_set(hba, UIC_ARG_MIB(DME_LocalTC0ReplayTimeOutVal),
+                               DL_TC0ReplayTimeOutVal_Default);
+               ufshcd_dme_set(hba, UIC_ARG_MIB(DME_LocalAFC0ReqTimeOutVal),
+                               DL_AFC0ReqTimeOutVal_Default);
+       }
 
        ret = ufshcd_uic_change_pwr_mode(hba, pwr_mode->pwr_rx << 4
                        | pwr_mode->pwr_tx);
index 6c62a28..fcca4e1 100644 (file)
@@ -544,6 +544,12 @@ enum ufshcd_quirks {
         */
        UFSHCI_QUIRK_SKIP_MANUAL_WB_FLUSH_CTRL          = 1 << 12,
 
+       /*
+        * This quirk needs to disable unipro timeout values
+        * before power mode change
+        */
+       UFSHCD_QUIRK_SKIP_DEF_UNIPRO_TIMEOUT_SETTING = 1 << 13,
+
 };
 
 enum ufshcd_caps {