From 91945660ac29341710b0914db200f6eacf251513 Mon Sep 17 00:00:00 2001 From: Ram Kumar Dwivedi Date: Wed, 17 Sep 2025 19:39:30 +0530 Subject: [PATCH 1/4] scsi: ufs: dt-bindings: Document gear and rate limit properties Add optional "limit-hs-gear" and "limit-rate" properties to the UFS controller common binding. These properties allow limiting the maximum HS gear and rate. This is useful in cases where the customer board may have signal integrity, clock configuration or layout issues that prevent reliable operation at higher gears. Such limitations are especially critical in those platforms, where stability is prioritized over peak performance. Reviewed-by: Krzysztof Kozlowski Signed-off-by: Ram Kumar Dwivedi Reviewed-by: Alim Akhtar Signed-off-by: Martin K. Petersen --- .../devicetree/bindings/ufs/ufs-common.yaml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/Documentation/devicetree/bindings/ufs/ufs-common.yaml b/Documentation/devicetree/bindings/ufs/ufs-common.yaml index 31fe7f30ff5b..9f04f34d8c5a 100644 --- a/Documentation/devicetree/bindings/ufs/ufs-common.yaml +++ b/Documentation/devicetree/bindings/ufs/ufs-common.yaml @@ -89,6 +89,22 @@ properties: msi-parent: true + limit-hs-gear: + $ref: /schemas/types.yaml#/definitions/uint32 + minimum: 1 + maximum: 6 + default: 6 + description: + Restricts the maximum HS gear used in both TX and RX directions. + + limit-gear-rate: + $ref: /schemas/types.yaml#/definitions/string + enum: [rate-a, rate-b] + default: rate-b + description: + Restricts the UFS controller to rate-a or rate-b for both TX and + RX directions. + dependencies: freq-table-hz: [ clocks ] operating-points-v2: [ clocks, clock-names ] From d471a075ae019118fa2e1bd251bad7e98d97b49e Mon Sep 17 00:00:00 2001 From: Ram Kumar Dwivedi Date: Wed, 17 Sep 2025 19:39:31 +0530 Subject: [PATCH 2/4] scsi: ufs: ufs-qcom: Remove redundant re-assignment to hs_rate Remove the redundant else block that assigns PA_HS_MODE_B to hs_rate, as it is already assigned in ufshcd_init_host_params(). This avoids unnecessary reassignment and prevents overwriting hs_rate when it is explicitly set to a different value. Reviewed-by: Alim Akhtar Signed-off-by: Ram Kumar Dwivedi Signed-off-by: Martin K. Petersen --- drivers/ufs/host/ufs-qcom.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/ufs/host/ufs-qcom.c b/drivers/ufs/host/ufs-qcom.c index 76fc70503a62..4b8afaf12f2e 100644 --- a/drivers/ufs/host/ufs-qcom.c +++ b/drivers/ufs/host/ufs-qcom.c @@ -494,12 +494,8 @@ static int ufs_qcom_power_up_sequence(struct ufs_hba *hba) * If the HS-G5 PHY gear is used, update host_params->hs_rate to Rate-A, * so that the subsequent power mode change shall stick to Rate-A. */ - if (host->hw_ver.major == 0x5) { - if (host->phy_gear == UFS_HS_G5) - host_params->hs_rate = PA_HS_MODE_A; - else - host_params->hs_rate = PA_HS_MODE_B; - } + if (host->hw_ver.major == 0x5 && host->phy_gear == UFS_HS_G5) + host_params->hs_rate = PA_HS_MODE_A; mode = host_params->hs_rate == PA_HS_MODE_B ? PHY_MODE_UFS_HS_B : PHY_MODE_UFS_HS_A; From 1cc577e64d68ba0a720329e37aa955c0de297a77 Mon Sep 17 00:00:00 2001 From: Ram Kumar Dwivedi Date: Wed, 17 Sep 2025 19:39:32 +0530 Subject: [PATCH 3/4] scsi: ufs: pltfrm: Add DT support to limit HS gear and gear rate Introduce parsing of 'limit-hs-gear' and 'limit-gear-rate' device tree properties to restrict high-speed gear and rate during initialization. This is useful in cases where the customer board may have signal integrity, clock configuration or layout issues that prevent reliable operation at higher gears. Such limitations are especially critical in those platforms, where stability is prioritized over peak performance. Co-developed-by: Nitin Rawat Signed-off-by: Nitin Rawat Signed-off-by: Ram Kumar Dwivedi Reviewed-by: Alim Akhtar Signed-off-by: Martin K. Petersen --- drivers/ufs/host/ufshcd-pltfrm.c | 33 ++++++++++++++++++++++++++++++++ drivers/ufs/host/ufshcd-pltfrm.h | 1 + 2 files changed, 34 insertions(+) diff --git a/drivers/ufs/host/ufshcd-pltfrm.c b/drivers/ufs/host/ufshcd-pltfrm.c index ffe5d1d2b215..c2dafb583cf5 100644 --- a/drivers/ufs/host/ufshcd-pltfrm.c +++ b/drivers/ufs/host/ufshcd-pltfrm.c @@ -430,6 +430,39 @@ int ufshcd_negotiate_pwr_params(const struct ufs_host_params *host_params, } EXPORT_SYMBOL_GPL(ufshcd_negotiate_pwr_params); +/** + * ufshcd_parse_gear_limits - Parse DT-based gear and rate limits for UFS + * @hba: Pointer to UFS host bus adapter instance + * @host_params: Pointer to UFS host parameters structure to be updated + * + * This function reads optional device tree properties to apply + * platform-specific constraints. + * + * "limit-hs-gear": Specifies the max HS gear. + * "limit-gear-rate": Specifies the max High-Speed rate. + */ +void ufshcd_parse_gear_limits(struct ufs_hba *hba, struct ufs_host_params *host_params) +{ + struct device_node *np = hba->dev->of_node; + u32 hs_gear; + const char *hs_rate; + + if (!of_property_read_u32(np, "limit-hs-gear", &hs_gear)) { + host_params->hs_tx_gear = hs_gear; + host_params->hs_rx_gear = hs_gear; + } + + if (!of_property_read_string(np, "limit-gear-rate", &hs_rate)) { + if (!strcmp(hs_rate, "rate-a")) + host_params->hs_rate = PA_HS_MODE_A; + else if (!strcmp(hs_rate, "rate-b")) + host_params->hs_rate = PA_HS_MODE_B; + else + dev_warn(hba->dev, "Invalid rate: %s\n", hs_rate); + } +} +EXPORT_SYMBOL_GPL(ufshcd_parse_gear_limits); + void ufshcd_init_host_params(struct ufs_host_params *host_params) { *host_params = (struct ufs_host_params){ diff --git a/drivers/ufs/host/ufshcd-pltfrm.h b/drivers/ufs/host/ufshcd-pltfrm.h index 3017f8e8f93c..0a18a8aed94d 100644 --- a/drivers/ufs/host/ufshcd-pltfrm.h +++ b/drivers/ufs/host/ufshcd-pltfrm.h @@ -29,6 +29,7 @@ int ufshcd_negotiate_pwr_params(const struct ufs_host_params *host_params, const struct ufs_pa_layer_attr *dev_max, struct ufs_pa_layer_attr *agreed_pwr); void ufshcd_init_host_params(struct ufs_host_params *host_params); +void ufshcd_parse_gear_limits(struct ufs_hba *hba, struct ufs_host_params *host_params); int ufshcd_pltfrm_init(struct platform_device *pdev, const struct ufs_hba_variant_ops *vops); void ufshcd_pltfrm_remove(struct platform_device *pdev); From 88f4d3aa29c8b1944ad506ac92c948258cbc004b Mon Sep 17 00:00:00 2001 From: Ram Kumar Dwivedi Date: Wed, 17 Sep 2025 19:39:33 +0530 Subject: [PATCH 4/4] scsi: ufs: ufs-qcom: Add support for limiting HS gear and rate Add support to limit Tx/Rx gear and rate during UFS initialization based on DT property. Also update the phy_gear to ensure PHY calibrations align with the required gear and rate. Signed-off-by: Ram Kumar Dwivedi Reviewed-by: Alim Akhtar Signed-off-by: Martin K. Petersen --- drivers/ufs/host/ufs-qcom.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/drivers/ufs/host/ufs-qcom.c b/drivers/ufs/host/ufs-qcom.c index 4b8afaf12f2e..749e6912a9c1 100644 --- a/drivers/ufs/host/ufs-qcom.c +++ b/drivers/ufs/host/ufs-qcom.c @@ -1092,6 +1092,18 @@ static void ufs_qcom_set_phy_gear(struct ufs_qcom_host *host) } } +static void ufs_qcom_parse_gear_limits(struct ufs_hba *hba) +{ + struct ufs_qcom_host *host = ufshcd_get_variant(hba); + struct ufs_host_params *host_params = &host->host_params; + u32 hs_gear_old = host_params->hs_tx_gear; + + ufshcd_parse_gear_limits(hba, host_params); + if (host_params->hs_tx_gear != hs_gear_old) { + host->phy_gear = host_params->hs_tx_gear; + } +} + static void ufs_qcom_set_host_params(struct ufs_hba *hba) { struct ufs_qcom_host *host = ufshcd_get_variant(hba); @@ -1333,6 +1345,7 @@ static int ufs_qcom_init(struct ufs_hba *hba) ufs_qcom_advertise_quirks(hba); ufs_qcom_set_host_params(hba); ufs_qcom_set_phy_gear(host); + ufs_qcom_parse_gear_limits(hba); err = ufs_qcom_ice_init(host); if (err)