Commit dc7c948d authored by Bao D. Nguyen's avatar Bao D. Nguyen Committed by Martin K. Petersen

scsi: ufs: ufs-qcom: Add support for UFS device version detection

Start from HW ver 5, a spare register in UFS host controller is added and
used to indicate the UFS device version. The spare register is populated by
bootloader for now, but in future it will be populated by HW automatically
during link startup with its best efforts in any boot stage prior to Linux.

During host driver init, read the spare register, if it is not populated
with a UFS device version, go ahead with the dual init mechanism. If a UFS
device version is in there, use the UFS device version together with host
controller's HW version to decide the proper PHY gear which should be used
to configure the UFS PHY without going through the second init.
Signed-off-by: default avatarBao D. Nguyen <quic_nguyenb@quicinc.com>
Signed-off-by: default avatarCan Guo <quic_cang@quicinc.com>
Link: https://lore.kernel.org/r/1701520577-31163-9-git-send-email-quic_cang@quicinc.comReviewed-by: default avatarManivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Reviewed-by: default avatarNitin Rawat <quic_nitirawa@quicinc.com>
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8550-QRD
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent a68abdad
...@@ -1065,17 +1065,38 @@ static void ufs_qcom_advertise_quirks(struct ufs_hba *hba) ...@@ -1065,17 +1065,38 @@ static void ufs_qcom_advertise_quirks(struct ufs_hba *hba)
static void ufs_qcom_set_phy_gear(struct ufs_qcom_host *host) static void ufs_qcom_set_phy_gear(struct ufs_qcom_host *host)
{ {
struct ufs_host_params *host_params = &host->host_params; struct ufs_host_params *host_params = &host->host_params;
u32 val, dev_major;
host->phy_gear = host_params->hs_tx_gear; host->phy_gear = host_params->hs_tx_gear;
/* if (host->hw_ver.major < 0x4) {
* For controllers whose major HW version is < 4, power up the PHY using /*
* minimum supported gear (UFS_HS_G2). Switching to max gear will be * For controllers whose major HW version is < 4, power up the
* performed during reinit if supported. For newer controllers, whose * PHY using minimum supported gear (UFS_HS_G2). Switching to
* major HW version is >= 4, power up the PHY using max supported gear. * max gear will be performed during reinit if supported.
*/ * For newer controllers, whose major HW version is >= 4, power
if (host->hw_ver.major < 0x4) * up the PHY using max supported gear.
*/
host->phy_gear = UFS_HS_G2; host->phy_gear = UFS_HS_G2;
} else if (host->hw_ver.major >= 0x5) {
val = ufshcd_readl(host->hba, REG_UFS_DEBUG_SPARE_CFG);
dev_major = FIELD_GET(UFS_DEV_VER_MAJOR_MASK, val);
/*
* Since the UFS device version is populated, let's remove the
* REINIT quirk as the negotiated gear won't change during boot.
* So there is no need to do reinit.
*/
if (dev_major != 0x0)
host->hba->quirks &= ~UFSHCD_QUIRK_REINIT_AFTER_MAX_GEAR_SWITCH;
/*
* For UFS 3.1 device and older, power up the PHY using HS-G4
* PHY gear to save power.
*/
if (dev_major > 0x0 && dev_major < 0x4)
host->phy_gear = UFS_HS_G4;
}
} }
static void ufs_qcom_set_host_params(struct ufs_hba *hba) static void ufs_qcom_set_host_params(struct ufs_hba *hba)
......
...@@ -23,6 +23,8 @@ ...@@ -23,6 +23,8 @@
#define UFS_HW_VER_MINOR_MASK GENMASK(27, 16) #define UFS_HW_VER_MINOR_MASK GENMASK(27, 16)
#define UFS_HW_VER_STEP_MASK GENMASK(15, 0) #define UFS_HW_VER_STEP_MASK GENMASK(15, 0)
#define UFS_DEV_VER_MAJOR_MASK GENMASK(7, 4)
/* vendor specific pre-defined parameters */ /* vendor specific pre-defined parameters */
#define SLOW 1 #define SLOW 1
#define FAST 2 #define FAST 2
...@@ -54,6 +56,8 @@ enum { ...@@ -54,6 +56,8 @@ enum {
UFS_AH8_CFG = 0xFC, UFS_AH8_CFG = 0xFC,
REG_UFS_CFG3 = 0x271C, REG_UFS_CFG3 = 0x271C,
REG_UFS_DEBUG_SPARE_CFG = 0x284C,
}; };
/* QCOM UFS host controller vendor specific debug registers */ /* QCOM UFS host controller vendor specific debug registers */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment