Loading drivers/scsi/ufs/ufs_quirks.h +11 −0 Original line number Diff line number Diff line Loading @@ -155,4 +155,15 @@ struct ufs_dev_fix { */ #define UFS_DEVICE_QUIRK_WAIT_AFTER_REF_CLK_UNGATE (1 << 11) /* * Few samsung UFS device models advertise PA_HIBERN8TIME as * 200us during handshaking in link establishment b/w host and device but * which may not be enough for the UFS device. * To workaround this issue, host should set its PA_HIBERN8TIME time to * 300us even if device advertises PA_HIBERN8TIME of 200us. */ #define UFS_DEVICE_QUIRK_PA_HIBER8TIME (1 << 12) #endif /* UFS_QUIRKS_H_ */ drivers/scsi/ufs/ufshcd.c +20 −4 Original line number Diff line number Diff line Loading @@ -463,7 +463,10 @@ static struct ufs_dev_fix ufs_fixups[] = { UFS_DEVICE_QUIRK_HS_G1_TO_HS_G3_SWITCH), UFS_FIX(UFS_VENDOR_SKHYNIX, "hC8HL1", UFS_DEVICE_QUIRK_HS_G1_TO_HS_G3_SWITCH), UFS_FIX(UFS_VENDOR_SAMSUNG, "KLUEG8UHDB-C2D1", UFS_DEVICE_QUIRK_PA_HIBER8TIME), UFS_FIX(UFS_VENDOR_SAMSUNG, "KLUDG4UHDB-B2D1", UFS_DEVICE_QUIRK_PA_HIBER8TIME), END_FIX }; Loading Loading @@ -8656,6 +8659,13 @@ static int ufshcd_tune_pa_hibern8time(struct ufs_hba *hba) int ret = 0; u32 local_tx_hibern8_time_cap = 0, peer_rx_hibern8_time_cap = 0; u32 max_hibern8_time, tuned_pa_hibern8time; u32 pa_hibern8time_quirk_enabled = hba->dev_info.quirks & UFS_DEVICE_QUIRK_PA_HIBER8TIME; if (!ufshcd_is_unipro_pa_params_tuning_req(hba) && !pa_hibern8time_quirk_enabled) { return 0; } ret = ufshcd_dme_get(hba, UIC_ARG_MIB_SEL(TX_HIBERN8TIME_CAPABILITY, Loading @@ -8676,6 +8686,13 @@ static int ufshcd_tune_pa_hibern8time(struct ufs_hba *hba) /* make sure proper unit conversion is applied */ tuned_pa_hibern8time = ((max_hibern8_time * HIBERN8TIME_UNIT_US) / PA_HIBERN8_TIME_UNIT_US); /* PA_HIBERN8TIME is product of tuned_pa_hibern8time * granularity, * setting tuned_pa_hibern8time as 3 and since granularity is 100us * for both host and device side, 3 *100us = 300us is set as * PA_HIBERN8TIME if UFS_DEVICE_QUIRK_PA_HIBER8TIME quirk is enabled */ if (pa_hibern8time_quirk_enabled) tuned_pa_hibern8time = 3; /* 3 *100us =300us */ ret = ufshcd_dme_set(hba, UIC_ARG_MIB(PA_HIBERN8TIME), tuned_pa_hibern8time); out: Loading Loading @@ -8754,11 +8771,10 @@ static int ufshcd_quirk_tune_host_pa_tactivate(struct ufs_hba *hba) static void ufshcd_tune_unipro_params(struct ufs_hba *hba) { if (ufshcd_is_unipro_pa_params_tuning_req(hba)) { if (ufshcd_is_unipro_pa_params_tuning_req(hba)) ufshcd_tune_pa_tactivate(hba); ufshcd_tune_pa_hibern8time(hba); } ufshcd_tune_pa_hibern8time(hba); if (hba->dev_info.quirks & UFS_DEVICE_QUIRK_PA_TACTIVATE) /* set 1ms timeout for PA_TACTIVATE */ ufshcd_dme_set(hba, UIC_ARG_MIB(PA_TACTIVATE), 10); Loading Loading
drivers/scsi/ufs/ufs_quirks.h +11 −0 Original line number Diff line number Diff line Loading @@ -155,4 +155,15 @@ struct ufs_dev_fix { */ #define UFS_DEVICE_QUIRK_WAIT_AFTER_REF_CLK_UNGATE (1 << 11) /* * Few samsung UFS device models advertise PA_HIBERN8TIME as * 200us during handshaking in link establishment b/w host and device but * which may not be enough for the UFS device. * To workaround this issue, host should set its PA_HIBERN8TIME time to * 300us even if device advertises PA_HIBERN8TIME of 200us. */ #define UFS_DEVICE_QUIRK_PA_HIBER8TIME (1 << 12) #endif /* UFS_QUIRKS_H_ */
drivers/scsi/ufs/ufshcd.c +20 −4 Original line number Diff line number Diff line Loading @@ -463,7 +463,10 @@ static struct ufs_dev_fix ufs_fixups[] = { UFS_DEVICE_QUIRK_HS_G1_TO_HS_G3_SWITCH), UFS_FIX(UFS_VENDOR_SKHYNIX, "hC8HL1", UFS_DEVICE_QUIRK_HS_G1_TO_HS_G3_SWITCH), UFS_FIX(UFS_VENDOR_SAMSUNG, "KLUEG8UHDB-C2D1", UFS_DEVICE_QUIRK_PA_HIBER8TIME), UFS_FIX(UFS_VENDOR_SAMSUNG, "KLUDG4UHDB-B2D1", UFS_DEVICE_QUIRK_PA_HIBER8TIME), END_FIX }; Loading Loading @@ -8656,6 +8659,13 @@ static int ufshcd_tune_pa_hibern8time(struct ufs_hba *hba) int ret = 0; u32 local_tx_hibern8_time_cap = 0, peer_rx_hibern8_time_cap = 0; u32 max_hibern8_time, tuned_pa_hibern8time; u32 pa_hibern8time_quirk_enabled = hba->dev_info.quirks & UFS_DEVICE_QUIRK_PA_HIBER8TIME; if (!ufshcd_is_unipro_pa_params_tuning_req(hba) && !pa_hibern8time_quirk_enabled) { return 0; } ret = ufshcd_dme_get(hba, UIC_ARG_MIB_SEL(TX_HIBERN8TIME_CAPABILITY, Loading @@ -8676,6 +8686,13 @@ static int ufshcd_tune_pa_hibern8time(struct ufs_hba *hba) /* make sure proper unit conversion is applied */ tuned_pa_hibern8time = ((max_hibern8_time * HIBERN8TIME_UNIT_US) / PA_HIBERN8_TIME_UNIT_US); /* PA_HIBERN8TIME is product of tuned_pa_hibern8time * granularity, * setting tuned_pa_hibern8time as 3 and since granularity is 100us * for both host and device side, 3 *100us = 300us is set as * PA_HIBERN8TIME if UFS_DEVICE_QUIRK_PA_HIBER8TIME quirk is enabled */ if (pa_hibern8time_quirk_enabled) tuned_pa_hibern8time = 3; /* 3 *100us =300us */ ret = ufshcd_dme_set(hba, UIC_ARG_MIB(PA_HIBERN8TIME), tuned_pa_hibern8time); out: Loading Loading @@ -8754,11 +8771,10 @@ static int ufshcd_quirk_tune_host_pa_tactivate(struct ufs_hba *hba) static void ufshcd_tune_unipro_params(struct ufs_hba *hba) { if (ufshcd_is_unipro_pa_params_tuning_req(hba)) { if (ufshcd_is_unipro_pa_params_tuning_req(hba)) ufshcd_tune_pa_tactivate(hba); ufshcd_tune_pa_hibern8time(hba); } ufshcd_tune_pa_hibern8time(hba); if (hba->dev_info.quirks & UFS_DEVICE_QUIRK_PA_TACTIVATE) /* set 1ms timeout for PA_TACTIVATE */ ufshcd_dme_set(hba, UIC_ARG_MIB(PA_TACTIVATE), 10); Loading