Re: [PATCH 2/6] scsi: ufs: ufs-qcom: Add support for UFS device version detection

From: Can Guo
Date: Tue Oct 31 2023 - 01:06:42 EST


Hi Neil,

On 10/27/2023 8:51 PM, Neil Armstrong wrote:
On 18/10/2023 16:02, Neil Armstrong wrote:
On 11/09/2023 07:59, Can Guo wrote:
From: "Bao D. Nguyen" <quic_nguyenb@xxxxxxxxxxx>

Retrieve UFS device version from UFS host controller's spare register
which is populated by bootloader, and use the UFS device version together
with host controller's HW version to decide the proper power modes which
should be used to configure the UFS PHY.

Signed-off-by: Bao D. Nguyen <quic_nguyenb@xxxxxxxxxxx>
Signed-off-by: Can Guo <quic_cang@xxxxxxxxxxx>
---
  drivers/ufs/host/ufs-qcom.c | 30 +++++++++++++++++++++++-------
  drivers/ufs/host/ufs-qcom.h |  2 ++
  2 files changed, 25 insertions(+), 7 deletions(-)

diff --git a/drivers/ufs/host/ufs-qcom.c b/drivers/ufs/host/ufs-qcom.c
index 710f079..8a9d54f 100644
--- a/drivers/ufs/host/ufs-qcom.c
+++ b/drivers/ufs/host/ufs-qcom.c
@@ -1030,7 +1030,7 @@ static void ufs_qcom_advertise_quirks(struct ufs_hba *hba)
                  | UFSHCD_QUIRK_BROKEN_PA_RXHSUNTERMCAP);
      }
-    if (host->hw_ver.major > 0x3)
+    if (host->hw_ver.major > 0x3 && host->hw_ver.major < 0x5)
          hba->quirks |= UFSHCD_QUIRK_REINIT_AFTER_MAX_GEAR_SWITCH;
  }
@@ -1038,11 +1038,33 @@ static void ufs_qcom_set_pwr_mode_limits(struct ufs_hba *hba)
  {
      struct ufs_qcom_host *host = ufshcd_get_variant(hba);
      struct ufs_dev_params *host_pwr_cap = &host->host_pwr_cap;
+    u32 val, dev_major = 0;
      ufshcd_init_pwr_dev_param(host_pwr_cap);
      /* This driver only supports symmetic gear setting i.e., hs_tx_gear == hs_rx_gear */
      host_pwr_cap->hs_tx_gear = host_pwr_cap->hs_rx_gear = ufs_qcom_get_hs_gear(hba);
+    host->phy_gear = host_pwr_cap->hs_rx_gear;
+
+    if (host->hw_ver.major < 0x5) {

Here you set G2 for < 0x5

+        /*
+         * Power up the PHY using the minimum supported gear (UFS_HS_G2).
+         * Switching to max gear will be performed during reinit if supported.
+         */
+        host->phy_gear = UFS_HS_G2;
+    } else {

So here is for >= 0x5

+        val = ufshcd_readl(host->hba, REG_UFS_DEBUG_SPARE_CFG);
+        dev_major = FIELD_GET(GENMASK(7, 4), val);
+
+        if (host->hw_ver.major == 0x5 && (dev_major >= 0x4 ||
+                          dev_major == 0)) {
+            /* For UFS 4.0 and newer, or dev version is not populated */
+            host_pwr_cap->hs_rate = PA_HS_MODE_A;
+        } else if (dev_major < 0x4 && dev_major > 0) {
+            /* For UFS 3.1 and older, apply HS-G4 PHY settings to save power */
+            host->phy_gear = UFS_HS_G4;
+        }

But behavior of > 0x5 is not clear here, could you clarify it in v2 ?

Now SM8650 is public, could you update it for v2 ?

For HWs whose hw_ver.major is > 0x5, say SM8650, initially phy_gear == host_pwr_cap->hs_rx_gear, which is HS_G5.

If a UFS3.x or older UFS device is connected, we overwrite phy_gear as HS_G4. I don't see an impact to SM8650.

Please let me know if I misunderstand anything here.


Thanks,

Can Guo.


Thanks,
Neil


Thanks,
Neil