diff --git a/arch/arm64/boot/dts/qcom/hamoa.dtsi b/arch/arm64/boot/dts/qcom/hamoa.dtsi index 97b6514f5a614..40ed25a6d0624 100644 --- a/arch/arm64/boot/dts/qcom/hamoa.dtsi +++ b/arch/arm64/boot/dts/qcom/hamoa.dtsi @@ -3961,6 +3961,7 @@ /bits/ 64 <0>, /bits/ 64 <0>, /bits/ 64 <0>; + opp-level = <1>; /* HS-G1 */ required-opps = <&rpmhpd_opp_low_svs>; }; @@ -3973,6 +3974,7 @@ /bits/ 64 <0>, /bits/ 64 <0>, /bits/ 64 <0>; + opp-level = <3>; /* HS-G3 */ required-opps = <&rpmhpd_opp_svs>; }; @@ -3985,6 +3987,7 @@ /bits/ 64 <0>, /bits/ 64 <0>, /bits/ 64 <0>; + opp-level = <5>; /* HS-G5 */ required-opps = <&rpmhpd_opp_nom>; }; }; diff --git a/drivers/ufs/host/ufs-qcom.c b/drivers/ufs/host/ufs-qcom.c index 1e347092a7d8d..c2fe0f58ca327 100644 --- a/drivers/ufs/host/ufs-qcom.c +++ b/drivers/ufs/host/ufs-qcom.c @@ -2182,8 +2182,9 @@ static unsigned long ufs_qcom_opp_freq_to_clk_freq(struct ufs_hba *hba, bool found = false; opp = dev_pm_opp_find_freq_exact_indexed(hba->dev, freq, 0, true); - if (IS_ERR(opp)) { - dev_err(hba->dev, "Failed to find OPP for exact frequency %lu\n", freq); + if (IS_ERR_OR_NULL(opp)) { + dev_err(hba->dev, "%s: Failed to find OPP for exact frequency %lu\n", + __func__, freq); return 0; } @@ -2211,12 +2212,32 @@ static unsigned long ufs_qcom_opp_freq_to_clk_freq(struct ufs_hba *hba, static u32 ufs_qcom_freq_to_gear_speed(struct ufs_hba *hba, unsigned long freq) { - u32 gear = UFS_HS_DONT_CHANGE; + struct dev_pm_opp *opp; unsigned long unipro_freq; + u32 gear = UFS_HS_DONT_CHANGE; if (!hba->use_pm_opp) return gear; + opp = dev_pm_opp_find_freq_exact_indexed(hba->dev, freq, 0, true); + if (IS_ERR_OR_NULL(opp)) { + dev_err(hba->dev, "%s: Failed to find OPP for exact frequency %lu\n", + __func__, freq); + return gear; + } + + /* Get HS gear speed from 'opp-level' */ + gear = dev_pm_opp_get_level(opp); + dev_pm_opp_put(opp); + + /* + * Greater than max gear means that there is no specified gear configured in DT + * or the specified gear is invalid. + */ + if (gear <= hba->max_pwr_info.info.gear_rx) + return gear; + + gear = UFS_HS_DONT_CHANGE; unipro_freq = ufs_qcom_opp_freq_to_clk_freq(hba, freq, "core_clk_unipro"); switch (unipro_freq) { case 403000000: @@ -2237,7 +2258,8 @@ static u32 ufs_qcom_freq_to_gear_speed(struct ufs_hba *hba, unsigned long freq) gear = UFS_HS_G1; break; default: - dev_err(hba->dev, "%s: Unsupported clock freq : %lu\n", __func__, freq); + dev_err(hba->dev, "%s: Unsupported clock freq [sys_clk: %lu, unipro_clk: %lu]\n", + __func__, freq, unipro_freq); return UFS_HS_DONT_CHANGE; }