Skip to content

Commit

Permalink
scsi: ufs: qcom: Add quirks for Samsung UFS devices
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Manish Pandey authored and Martin K. Petersen committed Apr 12, 2025
1 parent 7f533cc commit f8cba9a
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 0 deletions.
43 changes: 43 additions & 0 deletions drivers/ufs/host/ufs-qcom.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@
((((c) >> 16) & MCQ_QCFGPTR_MASK) * MCQ_QCFGPTR_UNIT)
#define MCQ_QCFG_SIZE 0x40

/* De-emphasis for gear-5 */
#define DEEMPHASIS_3_5_dB 0x04
#define NO_DEEMPHASIS 0x0

enum {
TSTBUS_UAWM,
TSTBUS_UARM,
Expand Down Expand Up @@ -795,6 +799,23 @@ static int ufs_qcom_icc_update_bw(struct ufs_qcom_host *host)
return ufs_qcom_icc_set_bw(host, bw_table.mem_bw, bw_table.cfg_bw);
}

static void ufs_qcom_set_tx_hs_equalizer(struct ufs_hba *hba, u32 gear, u32 tx_lanes)
{
u32 equalizer_val;
int ret, i;

/* Determine the equalizer value based on the gear */
equalizer_val = (gear == 5) ? DEEMPHASIS_3_5_dB : NO_DEEMPHASIS;

for (i = 0; i < tx_lanes; i++) {
ret = ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(TX_HS_EQUALIZER, i),
equalizer_val);
if (ret)
dev_err(hba->dev, "%s: failed equalizer lane %d\n",
__func__, i);
}
}

static int ufs_qcom_pwr_change_notify(struct ufs_hba *hba,
enum ufs_notify_change_status status,
const struct ufs_pa_layer_attr *dev_max_params,
Expand Down Expand Up @@ -846,6 +867,11 @@ static int ufs_qcom_pwr_change_notify(struct ufs_hba *hba,
dev_req_params->gear_tx,
PA_INITIAL_ADAPT);
}

if (hba->dev_quirks & UFS_DEVICE_QUIRK_PA_TX_DEEMPHASIS_TUNING)
ufs_qcom_set_tx_hs_equalizer(hba,
dev_req_params->gear_tx, dev_req_params->lane_tx);

break;
case POST_CHANGE:
if (ufs_qcom_cfg_timers(hba, false)) {
Expand Down Expand Up @@ -893,13 +919,26 @@ static int ufs_qcom_quirk_host_pa_saveconfigtime(struct ufs_hba *hba)
(pa_vs_config_reg1 | (1 << 12)));
}

static void ufs_qcom_override_pa_tx_hsg1_sync_len(struct ufs_hba *hba)
{
int err;

err = ufshcd_dme_peer_set(hba, UIC_ARG_MIB(PA_TX_HSG1_SYNC_LENGTH),
PA_TX_HSG1_SYNC_LENGTH_VAL);
if (err)
dev_err(hba->dev, "Failed (%d) set PA_TX_HSG1_SYNC_LENGTH\n", 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);

if (hba->dev_quirks & UFS_DEVICE_QUIRK_PA_TX_HSG1_SYNC_LENGTH)
ufs_qcom_override_pa_tx_hsg1_sync_len(hba);

return err;
}

Expand All @@ -914,6 +953,10 @@ static struct ufs_dev_quirk ufs_qcom_dev_fixups[] = {
{ .wmanufacturerid = UFS_VENDOR_WDC,
.model = UFS_ANY_MODEL,
.quirk = UFS_DEVICE_QUIRK_HOST_PA_TACTIVATE },
{ .wmanufacturerid = UFS_VENDOR_SAMSUNG,
.model = UFS_ANY_MODEL,
.quirk = UFS_DEVICE_QUIRK_PA_TX_HSG1_SYNC_LENGTH |
UFS_DEVICE_QUIRK_PA_TX_DEEMPHASIS_TUNING },
{}
};

Expand Down
18 changes: 18 additions & 0 deletions drivers/ufs/host/ufs-qcom.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,11 @@ enum {
TMRLUT_HW_CGC_EN | OCSC_HW_CGC_EN)

/* QUniPro Vendor specific attributes */
#define PA_TX_HSG1_SYNC_LENGTH 0x1552
#define PA_VS_CONFIG_REG1 0x9000
#define DME_VS_CORE_CLK_CTRL 0xD002
#define TX_HS_EQUALIZER 0x0037

/* bit and mask definitions for DME_VS_CORE_CLK_CTRL attribute */
#define CLK_1US_CYCLES_MASK_V4 GENMASK(27, 16)
#define CLK_1US_CYCLES_MASK GENMASK(7, 0)
Expand All @@ -141,6 +144,21 @@ enum {
#define UNIPRO_CORE_CLK_FREQ_201_5_MHZ 202
#define UNIPRO_CORE_CLK_FREQ_403_MHZ 403

/* TX_HSG1_SYNC_LENGTH attr value */
#define PA_TX_HSG1_SYNC_LENGTH_VAL 0x4A

/*
* Some ufs device vendors need a different TSync length.
* Enable this quirk to give an additional TX_HS_SYNC_LENGTH.
*/
#define UFS_DEVICE_QUIRK_PA_TX_HSG1_SYNC_LENGTH BIT(16)

/*
* Some ufs device vendors need a different Deemphasis setting.
* Enable this quirk to tune TX Deemphasis parameters.
*/
#define UFS_DEVICE_QUIRK_PA_TX_DEEMPHASIS_TUNING BIT(17)

/* ICE allocator type to share AES engines among TX stream and RX stream */
#define ICE_ALLOCATOR_TYPE 2

Expand Down

0 comments on commit f8cba9a

Please sign in to comment.