Skip to content

Commit f8cba9a

Browse files
quic-mapamartinkpetersen
authored andcommitted
scsi: ufs: qcom: Add quirks for Samsung UFS devices
Introduce quirks for Samsung UFS devices to adjust PA TX HSG1 sync length and TX_HS_EQUALIZER settings on the Qualcomm UFS Host controller. This ensures proper functionality of Samsung UFS devices with the Qualcomm UFS Host controller. Signed-off-by: Manish Pandey <quic_mapa@quicinc.com> Link: https://lore.kernel.org/r/20250411121630.21330-2-quic_mapa@quicinc.com Reviewed-by: Bean Huo <beanhuo@micron.com> Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
1 parent 7f533cc commit f8cba9a

File tree

2 files changed

+61
-0
lines changed

2 files changed

+61
-0
lines changed

drivers/ufs/host/ufs-qcom.c

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@
3333
((((c) >> 16) & MCQ_QCFGPTR_MASK) * MCQ_QCFGPTR_UNIT)
3434
#define MCQ_QCFG_SIZE 0x40
3535

36+
/* De-emphasis for gear-5 */
37+
#define DEEMPHASIS_3_5_dB 0x04
38+
#define NO_DEEMPHASIS 0x0
39+
3640
enum {
3741
TSTBUS_UAWM,
3842
TSTBUS_UARM,
@@ -795,6 +799,23 @@ static int ufs_qcom_icc_update_bw(struct ufs_qcom_host *host)
795799
return ufs_qcom_icc_set_bw(host, bw_table.mem_bw, bw_table.cfg_bw);
796800
}
797801

802+
static void ufs_qcom_set_tx_hs_equalizer(struct ufs_hba *hba, u32 gear, u32 tx_lanes)
803+
{
804+
u32 equalizer_val;
805+
int ret, i;
806+
807+
/* Determine the equalizer value based on the gear */
808+
equalizer_val = (gear == 5) ? DEEMPHASIS_3_5_dB : NO_DEEMPHASIS;
809+
810+
for (i = 0; i < tx_lanes; i++) {
811+
ret = ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(TX_HS_EQUALIZER, i),
812+
equalizer_val);
813+
if (ret)
814+
dev_err(hba->dev, "%s: failed equalizer lane %d\n",
815+
__func__, i);
816+
}
817+
}
818+
798819
static int ufs_qcom_pwr_change_notify(struct ufs_hba *hba,
799820
enum ufs_notify_change_status status,
800821
const struct ufs_pa_layer_attr *dev_max_params,
@@ -846,6 +867,11 @@ static int ufs_qcom_pwr_change_notify(struct ufs_hba *hba,
846867
dev_req_params->gear_tx,
847868
PA_INITIAL_ADAPT);
848869
}
870+
871+
if (hba->dev_quirks & UFS_DEVICE_QUIRK_PA_TX_DEEMPHASIS_TUNING)
872+
ufs_qcom_set_tx_hs_equalizer(hba,
873+
dev_req_params->gear_tx, dev_req_params->lane_tx);
874+
849875
break;
850876
case POST_CHANGE:
851877
if (ufs_qcom_cfg_timers(hba, false)) {
@@ -893,13 +919,26 @@ static int ufs_qcom_quirk_host_pa_saveconfigtime(struct ufs_hba *hba)
893919
(pa_vs_config_reg1 | (1 << 12)));
894920
}
895921

922+
static void ufs_qcom_override_pa_tx_hsg1_sync_len(struct ufs_hba *hba)
923+
{
924+
int err;
925+
926+
err = ufshcd_dme_peer_set(hba, UIC_ARG_MIB(PA_TX_HSG1_SYNC_LENGTH),
927+
PA_TX_HSG1_SYNC_LENGTH_VAL);
928+
if (err)
929+
dev_err(hba->dev, "Failed (%d) set PA_TX_HSG1_SYNC_LENGTH\n", err);
930+
}
931+
896932
static int ufs_qcom_apply_dev_quirks(struct ufs_hba *hba)
897933
{
898934
int err = 0;
899935

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

939+
if (hba->dev_quirks & UFS_DEVICE_QUIRK_PA_TX_HSG1_SYNC_LENGTH)
940+
ufs_qcom_override_pa_tx_hsg1_sync_len(hba);
941+
903942
return err;
904943
}
905944

@@ -914,6 +953,10 @@ static struct ufs_dev_quirk ufs_qcom_dev_fixups[] = {
914953
{ .wmanufacturerid = UFS_VENDOR_WDC,
915954
.model = UFS_ANY_MODEL,
916955
.quirk = UFS_DEVICE_QUIRK_HOST_PA_TACTIVATE },
956+
{ .wmanufacturerid = UFS_VENDOR_SAMSUNG,
957+
.model = UFS_ANY_MODEL,
958+
.quirk = UFS_DEVICE_QUIRK_PA_TX_HSG1_SYNC_LENGTH |
959+
UFS_DEVICE_QUIRK_PA_TX_DEEMPHASIS_TUNING },
917960
{}
918961
};
919962

drivers/ufs/host/ufs-qcom.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,8 +122,11 @@ enum {
122122
TMRLUT_HW_CGC_EN | OCSC_HW_CGC_EN)
123123

124124
/* QUniPro Vendor specific attributes */
125+
#define PA_TX_HSG1_SYNC_LENGTH 0x1552
125126
#define PA_VS_CONFIG_REG1 0x9000
126127
#define DME_VS_CORE_CLK_CTRL 0xD002
128+
#define TX_HS_EQUALIZER 0x0037
129+
127130
/* bit and mask definitions for DME_VS_CORE_CLK_CTRL attribute */
128131
#define CLK_1US_CYCLES_MASK_V4 GENMASK(27, 16)
129132
#define CLK_1US_CYCLES_MASK GENMASK(7, 0)
@@ -141,6 +144,21 @@ enum {
141144
#define UNIPRO_CORE_CLK_FREQ_201_5_MHZ 202
142145
#define UNIPRO_CORE_CLK_FREQ_403_MHZ 403
143146

147+
/* TX_HSG1_SYNC_LENGTH attr value */
148+
#define PA_TX_HSG1_SYNC_LENGTH_VAL 0x4A
149+
150+
/*
151+
* Some ufs device vendors need a different TSync length.
152+
* Enable this quirk to give an additional TX_HS_SYNC_LENGTH.
153+
*/
154+
#define UFS_DEVICE_QUIRK_PA_TX_HSG1_SYNC_LENGTH BIT(16)
155+
156+
/*
157+
* Some ufs device vendors need a different Deemphasis setting.
158+
* Enable this quirk to tune TX Deemphasis parameters.
159+
*/
160+
#define UFS_DEVICE_QUIRK_PA_TX_DEEMPHASIS_TUNING BIT(17)
161+
144162
/* ICE allocator type to share AES engines among TX stream and RX stream */
145163
#define ICE_ALLOCATOR_TYPE 2
146164

0 commit comments

Comments
 (0)