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)
committerMartin K. Petersen <martin.petersen@oracle.com>
Wed, 6 Jan 2021 04:02:09 +0000 (23:02 -0500)
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>
drivers/scsi/ufs/ufshcd.c
drivers/scsi/ufs/ufshcd.h

index 82ad317..ab65783 100644 (file)
@@ -4215,25 +4215,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 aa9ea35..85f9d0f 100644 (file)
@@ -551,6 +551,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 {