[PATCH v8 phy-next 12/31] scsi: ufs: qcom: make use of QMP PHY dynamic gear switching ability

Vladimir Oltean vladimir.oltean at nxp.com
Tue May 5 03:05:04 PDT 2026


Currently, phy_set_mode_ext() on the QMP UFS PHY makes no change to the
hardware state, instead it is mandatory that phy_power_on() followed by
phy_calibrate() be run afterwards, for the new mode to be picked up.

By absorbing the phy_power_off() -> ... -> phy_power_on() ->
phy_calibrate() surrounding sequence into phy_set_mode_ext(), the UFS
HCD consumer driver can be greatly simplified, and we also have a proper
self-standing phy_set_mode_ext() implementation which does not rely on
other calls to do its job.

So simplify ufs_qcom_power_up_sequence() to only call phy_set_mode_ext()
and let PHY power management be handled just by ufs_qcom_setup_clocks().
Actually, after this change, ufs_qcom_power_up_sequence() becomes an
inadequate name, since from the consumer perspective the powering up is
invisible. So change it to ufs_qcom_phy_change_mode().

The consumer and the provider are modified at once because ufs-qcom.c
already calls phy_set_mode_ext() while the QMP PHY is powered on, so
introducing the extra logic in qmp_ufs_set_mode() would cause a
potentially breaking second QMP PHY power sequence until the consumer is
patched to remove its own calls.

Signed-off-by: Vladimir Oltean <vladimir.oltean at nxp.com>
---
Cc: Can Guo <quic_cang at quicinc.com>
Cc: "James E.J. Bottomley" <James.Bottomley at HansenPartnership.com>
Cc: "Martin K. Petersen" <martin.petersen at oracle.com>
Cc: Dmitry Baryshkov <dmitry.baryshkov at oss.qualcomm.com>
Cc: Nitin Rawat <quic_nitirawa at quicinc.com>
Cc: Manivannan Sadhasivam <mani at kernel.org>

v7->v8: patch is new
Commit was previously posted here but did not get any testing.
https://lore.kernel.org/linux-phy/20260327112858.r5lpqygtvsane2vf@skbuf/

Signed-off-by: Vladimir Oltean <vladimir.oltean at nxp.com>
---
 drivers/phy/qualcomm/phy-qcom-qmp-ufs.c |  6 ++++++
 drivers/ufs/host/ufs-qcom.c             | 25 +++++--------------------
 2 files changed, 11 insertions(+), 20 deletions(-)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
index 771bc7c2ab50..e4e7966eb39a 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
@@ -2012,6 +2012,12 @@ static int qmp_ufs_set_mode(struct phy *phy, enum phy_mode mode, int submode)
 	qmp->mode = mode;
 	qmp->submode = submode;
 
+	if (phy->power_count) {
+		qmp_ufs_power_off(phy);
+		qmp_ufs_power_on(phy);
+		return qmp_ufs_phy_calibrate(phy);
+	}
+
 	return 0;
 }
 
diff --git a/drivers/ufs/host/ufs-qcom.c b/drivers/ufs/host/ufs-qcom.c
index 9039b087bf21..e28edcfd13a1 100644
--- a/drivers/ufs/host/ufs-qcom.c
+++ b/drivers/ufs/host/ufs-qcom.c
@@ -485,7 +485,7 @@ static u32 ufs_qcom_get_hs_gear(struct ufs_hba *hba)
 	return UFS_HS_G3;
 }
 
-static int ufs_qcom_power_up_sequence(struct ufs_hba *hba)
+static int ufs_qcom_phy_change_mode(struct ufs_hba *hba)
 {
 	struct ufs_qcom_host *host = ufshcd_get_variant(hba);
 	struct ufs_host_params *host_params = &host->host_params;
@@ -508,26 +508,11 @@ static int ufs_qcom_power_up_sequence(struct ufs_hba *hba)
 	if (ret)
 		return ret;
 
-	if (phy->power_count)
-		phy_power_off(phy);
-
-
-	/* phy initialization - calibrate the phy */
 	ret = phy_set_mode_ext(phy, mode, host->phy_gear);
-	if (ret)
-		goto out_disable_phy;
-
-	/* power on phy - start serdes and phy's power and clocks */
-	ret = phy_power_on(phy);
-	if (ret) {
-		dev_err(hba->dev, "%s: phy power on failed, ret = %d\n",
-			__func__, ret);
-		return ret;
-	}
-
-	ret = phy_calibrate(phy);
 	if (ret) {
-		dev_err(hba->dev, "Failed to calibrate PHY: %d\n", ret);
+		dev_err(hba->dev,
+			"Failed to change PHY mode %d submode %d: %pe\n",
+			mode, host->phy_gear, ERR_PTR(ret));
 		return ret;
 	}
 
@@ -582,7 +567,7 @@ static int ufs_qcom_hce_enable_notify(struct ufs_hba *hba,
 
 	switch (status) {
 	case PRE_CHANGE:
-		err = ufs_qcom_power_up_sequence(hba);
+		err = ufs_qcom_phy_change_mode(hba);
 		if (err)
 			return err;
 
-- 
2.34.1




More information about the linux-arm-kernel mailing list