lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <1694411968-14413-3-git-send-email-quic_cang@quicinc.com>
Date:   Sun, 10 Sep 2023 22:59:23 -0700
From:   Can Guo <quic_cang@...cinc.com>
To:     quic_cang@...cinc.com, mani@...nel.org, quic_nguyenb@...cinc.com,
        quic_nitirawa@...cinc.com, martin.petersen@...cle.com
Cc:     linux-scsi@...r.kernel.org, Andy Gross <agross@...nel.org>,
        Bjorn Andersson <andersson@...nel.org>,
        Konrad Dybcio <konrad.dybcio@...aro.org>,
        "James E.J. Bottomley" <jejb@...ux.ibm.com>,
        linux-arm-msm@...r.kernel.org (open list:UNIVERSAL FLASH STORAGE HOST
        CONTROLLER DRIVER...), linux-kernel@...r.kernel.org (open list)
Subject: [PATCH 2/6] scsi: ufs: ufs-qcom: Add support for UFS device version detection

From: "Bao D. Nguyen" <quic_nguyenb@...cinc.com>

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@...cinc.com>
Signed-off-by: Can Guo <quic_cang@...cinc.com>
---
 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) {
+		/*
+		 * 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 {
+		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;
+		}
+	}
 }
 
 static void ufs_qcom_set_caps(struct ufs_hba *hba)
@@ -1287,12 +1309,6 @@ static int ufs_qcom_init(struct ufs_hba *hba)
 		dev_warn(dev, "%s: failed to configure the testbus %d\n",
 				__func__, err);
 
-	/*
-	 * 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;
-
 	return 0;
 
 out_variant_clear:
diff --git a/drivers/ufs/host/ufs-qcom.h b/drivers/ufs/host/ufs-qcom.h
index 4db64d9..e10889f 100644
--- a/drivers/ufs/host/ufs-qcom.h
+++ b/drivers/ufs/host/ufs-qcom.h
@@ -56,6 +56,8 @@ enum {
 	UFS_AH8_CFG				= 0xFC,
 
 	REG_UFS_CFG3				= 0x271C,
+
+	REG_UFS_DEBUG_SPARE_CFG			= 0x284C,
 };
 
 /* QCOM UFS host controller vendor specific debug registers */
-- 
2.7.4

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ