Commit b99a5067 authored by Martin K. Petersen's avatar Martin K. Petersen
Browse files

Merge patch series "ufs: ufs-qcom: Align programming sequence as per HW spec"

Nitin Rawat <quic_nitirawa@quicinc.com> says:

This patch series adds programming support for Qualcomm UFS
to align with Hardware Specification.

In this patch series below changes are taken care.

1. Enable QUnipro Internal Clock Gating
2. Update esi_vec_mask for HW major version >= 6

Link: https://lore.kernel.org/r/20250714075336.2133-1-quic_nitirawa@quicinc.com


Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parents 063bec44 5a6f304f
Loading
Loading
Loading
Loading
+24 −0
Original line number Diff line number Diff line
@@ -4272,6 +4272,30 @@ int ufshcd_dme_get_attr(struct ufs_hba *hba, u32 attr_sel,
}
EXPORT_SYMBOL_GPL(ufshcd_dme_get_attr);

/**
 * ufshcd_dme_rmw - get modify set a DME attribute
 * @hba: per adapter instance
 * @mask: indicates which bits to clear from the value that has been read
 * @val: actual value to write
 * @attr: dme attribute
 */
int ufshcd_dme_rmw(struct ufs_hba *hba, u32 mask,
		   u32 val, u32 attr)
{
	u32 cfg = 0;
	int err;

	err = ufshcd_dme_get(hba, UIC_ARG_MIB(attr), &cfg);
	if (err)
		return err;

	cfg &= ~mask;
	cfg |= (val & mask);

	return ufshcd_dme_set(hba, UIC_ARG_MIB(attr), cfg);
}
EXPORT_SYMBOL_GPL(ufshcd_dme_rmw);

/**
 * ufshcd_uic_pwr_ctrl - executes UIC commands (which affects the link power
 * state) and waits for it to take effect.
+22 −2
Original line number Diff line number Diff line
@@ -552,11 +552,32 @@ static int ufs_qcom_power_up_sequence(struct ufs_hba *hba)
 */
static void ufs_qcom_enable_hw_clk_gating(struct ufs_hba *hba)
{
	int err;

	/* Enable UTP internal clock gating */
	ufshcd_rmwl(hba, REG_UFS_CFG2_CGC_EN_ALL, REG_UFS_CFG2_CGC_EN_ALL,
		    REG_UFS_CFG2);

	/* Ensure that HW clock gating is enabled before next operations */
	ufshcd_readl(hba, REG_UFS_CFG2);

	/* Enable Unipro internal clock gating */
	err = ufshcd_dme_rmw(hba, DL_VS_CLK_CFG_MASK,
			     DL_VS_CLK_CFG_MASK, DL_VS_CLK_CFG);
	if (err)
		goto out;

	err = ufshcd_dme_rmw(hba, PA_VS_CLK_CFG_REG_MASK,
			     PA_VS_CLK_CFG_REG_MASK, PA_VS_CLK_CFG_REG);
	if (err)
		goto out;

	err = ufshcd_dme_rmw(hba, DME_VS_CORE_CLK_CTRL_DME_HW_CGC_EN,
			     DME_VS_CORE_CLK_CTRL_DME_HW_CGC_EN,
			     DME_VS_CORE_CLK_CTRL);
out:
	if (err)
		dev_err(hba->dev, "hw clk gating enabled failed\n");
}

static int ufs_qcom_hce_enable_notify(struct ufs_hba *hba,
@@ -2109,8 +2130,7 @@ static int ufs_qcom_config_esi(struct ufs_hba *hba)

	retain_and_null_ptr(qi);

	if (host->hw_ver.major == 6 && host->hw_ver.minor == 0 &&
	    host->hw_ver.step == 0) {
	if (host->hw_ver.major >= 6) {
		ufshcd_rmwl(hba, ESI_VEC_MASK, FIELD_PREP(ESI_VEC_MASK, MAX_ESI_VEC - 1),
			    REG_UFS_CFG3);
	}
+9 −0
Original line number Diff line number Diff line
@@ -24,6 +24,15 @@

#define UFS_QCOM_LIMIT_HS_RATE		PA_HS_MODE_B

/* bit and mask definitions for PA_VS_CLK_CFG_REG attribute */
#define PA_VS_CLK_CFG_REG      0x9004
#define PA_VS_CLK_CFG_REG_MASK GENMASK(8, 0)

/* bit and mask definitions for DL_VS_CLK_CFG attribute */
#define DL_VS_CLK_CFG          0xA00B
#define DL_VS_CLK_CFG_MASK GENMASK(9, 0)
#define DME_VS_CORE_CLK_CTRL_DME_HW_CGC_EN             BIT(9)

/* QCOM UFS host controller vendor specific registers */
enum {
	REG_UFS_SYS1CLK_1US                 = 0xC0,
+1 −0
Original line number Diff line number Diff line
@@ -1480,6 +1480,7 @@ void ufshcd_resume_complete(struct device *dev);
bool ufshcd_is_hba_active(struct ufs_hba *hba);
void ufshcd_pm_qos_init(struct ufs_hba *hba);
void ufshcd_pm_qos_exit(struct ufs_hba *hba);
int ufshcd_dme_rmw(struct ufs_hba *hba, u32 mask, u32 val, u32 attr);

/* Wrapper functions for safely calling variant operations */
static inline int ufshcd_vops_init(struct ufs_hba *hba)