]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
scsi: ufs: qcom : Refactor phy_power_on/off calls
authorNitin Rawat <quic_nitirawa@quicinc.com>
Mon, 26 May 2025 15:38:21 +0000 (21:08 +0530)
committerVinod Koul <vkoul@kernel.org>
Sun, 15 Jun 2025 14:23:24 +0000 (19:53 +0530)
Commit 3f6d1767b1a0 ("phy: ufs-qcom: Refactor all init steps into
phy_poweron") moved the phy_power_on/off from ufs_qcom_setup_clocks
to suspend/resume func.

To have a better power saving, remove the phy_power_on/off calls from
resume/suspend path and put them back to ufs_qcom_setup_clocks, so that
PHY regulators & clks can be turned on/off along with UFS's clocks.

Since phy phy_power_on is separated out from phy calibrate, make
separate calls to phy_power_on calls from ufs qcom driver.

Co-developed-by: Can Guo <quic_cang@quicinc.com>
Signed-off-by: Can Guo <quic_cang@quicinc.com>
Signed-off-by: Nitin Rawat <quic_nitirawa@quicinc.com>
Link: https://lore.kernel.org/r/20250526153821.7918-11-quic_nitirawa@quicinc.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
drivers/ufs/host/ufs-qcom.c

index b764055c1854e97346a0b72811097805466b5c87..ba4b2880279c497cffc0bf206ac8f0c4e2e6e3c1 100644 (file)
@@ -711,26 +711,17 @@ static int ufs_qcom_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op,
        enum ufs_notify_change_status status)
 {
        struct ufs_qcom_host *host = ufshcd_get_variant(hba);
-       struct phy *phy = host->generic_phy;
 
        if (status == PRE_CHANGE)
                return 0;
 
-       if (ufs_qcom_is_link_off(hba)) {
-               /*
-                * Disable the tx/rx lane symbol clocks before PHY is
-                * powered down as the PLL source should be disabled
-                * after downstream clocks are disabled.
-                */
+       if (!ufs_qcom_is_link_active(hba))
                ufs_qcom_disable_lane_clks(host);
-               phy_power_off(phy);
 
-               /* reset the connected UFS device during power down */
-               ufs_qcom_device_reset_ctrl(hba, true);
 
-       } else if (!ufs_qcom_is_link_active(hba)) {
-               ufs_qcom_disable_lane_clks(host);
-       }
+       /* reset the connected UFS device during power down */
+       if (ufs_qcom_is_link_off(hba) && host->device_reset)
+               ufs_qcom_device_reset_ctrl(hba, true);
 
        return ufs_qcom_ice_suspend(host);
 }
@@ -738,26 +729,11 @@ static int ufs_qcom_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op,
 static int ufs_qcom_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op)
 {
        struct ufs_qcom_host *host = ufshcd_get_variant(hba);
-       struct phy *phy = host->generic_phy;
        int err;
 
-       if (ufs_qcom_is_link_off(hba)) {
-               err = phy_power_on(phy);
-               if (err) {
-                       dev_err(hba->dev, "%s: failed PHY power on: %d\n",
-                               __func__, err);
-                       return err;
-               }
-
-               err = ufs_qcom_enable_lane_clks(host);
-               if (err)
-                       return err;
-
-       } else if (!ufs_qcom_is_link_active(hba)) {
-               err = ufs_qcom_enable_lane_clks(host);
-               if (err)
-                       return err;
-       }
+       err = ufs_qcom_enable_lane_clks(host);
+       if (err)
+               return err;
 
        return ufs_qcom_ice_resume(host);
 }
@@ -1136,12 +1112,20 @@ static void ufs_qcom_set_caps(struct ufs_hba *hba)
  * @on: If true, enable clocks else disable them.
  * @status: PRE_CHANGE or POST_CHANGE notify
  *
+ * There are certain clocks which comes from the PHY so it needs
+ * to be managed together along with controller clocks which also
+ * provides a better power saving. Hence keep phy_power_off/on calls
+ * in ufs_qcom_setup_clocks, so that PHY's regulators & clks can be
+ * turned on/off along with UFS's clocks.
+ *
  * Return: 0 on success, non-zero on failure.
  */
 static int ufs_qcom_setup_clocks(struct ufs_hba *hba, bool on,
                                 enum ufs_notify_change_status status)
 {
        struct ufs_qcom_host *host = ufshcd_get_variant(hba);
+       struct phy *phy = host->generic_phy;
+       int err;
 
        /*
         * In case ufs_qcom_init() is not yet done, simply ignore.
@@ -1160,10 +1144,22 @@ static int ufs_qcom_setup_clocks(struct ufs_hba *hba, bool on,
                                /* disable device ref_clk */
                                ufs_qcom_dev_ref_clk_ctrl(host, false);
                        }
+
+                       err = phy_power_off(phy);
+                       if (err) {
+                               dev_err(hba->dev, "phy power off failed, ret=%d\n", err);
+                               return err;
+                       }
                }
                break;
        case POST_CHANGE:
                if (on) {
+                       err = phy_power_on(phy);
+                       if (err) {
+                               dev_err(hba->dev, "phy power on failed, ret = %d\n", err);
+                               return err;
+                       }
+
                        /* enable the device ref clock for HS mode*/
                        if (ufshcd_is_hs_mode(&hba->pwr_info))
                                ufs_qcom_dev_ref_clk_ctrl(host, true);