On Sun, Oct 30, 2022 at 12:48:21AM +0300, Dmitry Baryshkov wrote:
On 29/10/2022 17:16, Manivannan Sadhasivam wrote:
Starting from UFS controller v4, Qcom supports dual gear mode (i.e., the
controller/PHY can be configured to run in two gear speeds). But that
requires an agreement between the UFS controller and the UFS device.
This commit finds the max gear supported by both controller and device
then decides which one to use.
UFS controller's max gear can be read from the REG_UFS_PARAM0 register and
UFS device's max gear can be read from the "max-gear" devicetree property.
The UFS PHY also needs to be configured with the decided gear using the
phy_set_mode_ext() API.
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@xxxxxxxxxx>
---
drivers/ufs/host/ufs-qcom.c | 35 ++++++++++++++++++++++++++++++++---
drivers/ufs/host/ufs-qcom.h | 4 ++++
2 files changed, 36 insertions(+), 3 deletions(-)
diff --git a/drivers/ufs/host/ufs-qcom.c b/drivers/ufs/host/ufs-qcom.c
index f952cc76919f..268463e92d67 100644
--- a/drivers/ufs/host/ufs-qcom.c
+++ b/drivers/ufs/host/ufs-qcom.c
@@ -281,6 +281,9 @@ static int ufs_qcom_host_reset(struct ufs_hba *hba)
static u32 ufs_qcom_get_hs_gear(struct ufs_hba *hba, u32 hs_gear)
{
struct ufs_qcom_host *host = ufshcd_get_variant(hba);
+ struct device *dev = hba->dev;
+ u32 max_gear, hcd_max_gear, reg;
+ int ret;
if (host->hw_ver.major == 0x1) {
/*
@@ -292,8 +295,33 @@ static u32 ufs_qcom_get_hs_gear(struct ufs_hba *hba, u32 hs_gear)
*/
if (hs_gear > UFS_HS_G2)
return UFS_HS_G2;
+ } else if (host->hw_ver.major > 0x3) {
+ /*
+ * Starting from UFS controller v4, Qcom supports dual gear mode (i.e., the
+ * controller/PHY can be configured to run in two gear speeds). But that
+ * requires an agreement between the UFS controller and the device. Below
+ * code tries to find the max gear of both and decides which gear to use.
+ *
+ * First get the max gear supported by the UFS device if available.
+ * If the property is not defined in devicetree, then use the default gear.
+ */
+ ret = of_property_read_u32(dev->of_node, "max-gear", &max_gear);
+ if (ret)
+ goto err_out;
Can we detect the UFS device's max gear somehow? If not, the 'max-gear'
property name doesn't sound good. Maybe calling it 'device-gear' would be
better.
UFS device probing depends on PHY init sequence. So technically we cannot know
the max gear of the device without using an init sequence, but this information
is static and should be known to a board manufacturer. That's why I decided to
use this property. Another option is to use a fixed init sequence for probing
the device and do a re-init after knowing it's max gear but that is not
recommended.
We need "max" keyword because this property specifies the maximum gear at which
the device could operate and not necessarily the gear at which it operates.
Maybe, "max-device-gear" would make it clear.