[PATCH 1/3] phy: qcom-qmp-ufs: support dynamic gear changing
From: Vladimir Oltean
Date: Fri Mar 27 2026 - 06:41:00 EST
Currently, phy_set_mode_ext() on the QMP UFS PHY expects the PHY to be
powered down, and it makes no change to the hardware state, instead
phy_power_on() followed by phy_calibrate() must be run afterwards.
"Order of API calls" from Documentation/driver-api/phy/phy.rst has a
roundabout and not really clear way of saying that both calling
sequences should be supported. This was further discussed here,
documentation is pending an update:
https://lore.kernel.org/linux-phy/E1vo0mF-00000007kbg-1OeA@xxxxxxxxxxxxxxxxxxxxxx/
By absorbing the phy_power_off() -> ... -> phy_power_on() ->
phy_configure() surrounding sequence into phy_set_mode_ext(), consumer
drivers 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.
Signed-off-by: Vladimir Oltean <vladimir.oltean@xxxxxxx>
---
drivers/phy/qualcomm/phy-qcom-qmp-ufs.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
index df138a5442eb..e75b059bf246 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
@@ -2004,15 +2004,24 @@ static int qmp_ufs_set_mode(struct phy *phy, enum phy_mode mode, int submode)
{
struct qmp_ufs *qmp = phy_get_drvdata(phy);
const struct qmp_phy_cfg *cfg = qmp->cfg;
+ bool powered_on = phy->power_count;
if (submode > cfg->max_supported_gear || submode == 0) {
dev_err(qmp->dev, "Invalid PHY submode %d\n", submode);
return -EINVAL;
}
+ if (powered_on)
+ qmp_ufs_power_off(phy);
+
qmp->mode = mode;
qmp->submode = submode;
+ if (powered_on) {
+ qmp_ufs_power_on(phy);
+ return qmp_ufs_phy_calibrate(phy);
+ }
+
return 0;
}
--
2.34.1
--5nqk7qqoimem4szp
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
filename="0002-scsi-ufs-qcom-call-phy_init-before-phy_power_on.patch"