Skip to content

Commit 3bd70ae

Browse files
Merge patch series "Add DT-based gear and rate limiting support"
Ram Kumar Dwivedi <[email protected]> says: This patch series adds support for limiting the maximum high-speed gear and rate used by the UFS controller via device tree properties. Some platforms may have signal integrity, clock configuration, or layout issues that prevent reliable operation at higher gears or rates. This is especially critical in automotive and other platforms where stability is prioritized over peak performance. The series follows this logical progression: 1. Document the new DT properties in the common UFS binding 2. Clean up existing redundant code in the qcom driver 3. Add platform-level parsing support for the new properties 4. Integrate the platform support in the qcom driver This approach makes the functionality available to other UFS host drivers and provides a cleaner, more maintainable implementation. Signed-off-by: Martin K. Petersen <[email protected]>
2 parents 79dde5f + 88f4d3a commit 3bd70ae

File tree

4 files changed

+65
-6
lines changed

4 files changed

+65
-6
lines changed

Documentation/devicetree/bindings/ufs/ufs-common.yaml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,22 @@ properties:
8989

9090
msi-parent: true
9191

92+
limit-hs-gear:
93+
$ref: /schemas/types.yaml#/definitions/uint32
94+
minimum: 1
95+
maximum: 6
96+
default: 6
97+
description:
98+
Restricts the maximum HS gear used in both TX and RX directions.
99+
100+
limit-gear-rate:
101+
$ref: /schemas/types.yaml#/definitions/string
102+
enum: [rate-a, rate-b]
103+
default: rate-b
104+
description:
105+
Restricts the UFS controller to rate-a or rate-b for both TX and
106+
RX directions.
107+
92108
dependencies:
93109
freq-table-hz: [ clocks ]
94110
operating-points-v2: [ clocks, clock-names ]

drivers/ufs/host/ufs-qcom.c

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -497,12 +497,8 @@ static int ufs_qcom_power_up_sequence(struct ufs_hba *hba)
497497
* If the HS-G5 PHY gear is used, update host_params->hs_rate to Rate-A,
498498
* so that the subsequent power mode change shall stick to Rate-A.
499499
*/
500-
if (host->hw_ver.major == 0x5) {
501-
if (host->phy_gear == UFS_HS_G5)
502-
host_params->hs_rate = PA_HS_MODE_A;
503-
else
504-
host_params->hs_rate = PA_HS_MODE_B;
505-
}
500+
if (host->hw_ver.major == 0x5 && host->phy_gear == UFS_HS_G5)
501+
host_params->hs_rate = PA_HS_MODE_A;
506502

507503
mode = host_params->hs_rate == PA_HS_MODE_B ? PHY_MODE_UFS_HS_B : PHY_MODE_UFS_HS_A;
508504

@@ -1117,6 +1113,18 @@ static void ufs_qcom_set_phy_gear(struct ufs_qcom_host *host)
11171113
}
11181114
}
11191115

1116+
static void ufs_qcom_parse_gear_limits(struct ufs_hba *hba)
1117+
{
1118+
struct ufs_qcom_host *host = ufshcd_get_variant(hba);
1119+
struct ufs_host_params *host_params = &host->host_params;
1120+
u32 hs_gear_old = host_params->hs_tx_gear;
1121+
1122+
ufshcd_parse_gear_limits(hba, host_params);
1123+
if (host_params->hs_tx_gear != hs_gear_old) {
1124+
host->phy_gear = host_params->hs_tx_gear;
1125+
}
1126+
}
1127+
11201128
static void ufs_qcom_set_host_params(struct ufs_hba *hba)
11211129
{
11221130
struct ufs_qcom_host *host = ufshcd_get_variant(hba);
@@ -1368,6 +1376,7 @@ static int ufs_qcom_init(struct ufs_hba *hba)
13681376
ufs_qcom_advertise_quirks(hba);
13691377
ufs_qcom_set_host_params(hba);
13701378
ufs_qcom_set_phy_gear(host);
1379+
ufs_qcom_parse_gear_limits(hba);
13711380

13721381
err = ufs_qcom_ice_init(host);
13731382
if (err)

drivers/ufs/host/ufshcd-pltfrm.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -430,6 +430,39 @@ int ufshcd_negotiate_pwr_params(const struct ufs_host_params *host_params,
430430
}
431431
EXPORT_SYMBOL_GPL(ufshcd_negotiate_pwr_params);
432432

433+
/**
434+
* ufshcd_parse_gear_limits - Parse DT-based gear and rate limits for UFS
435+
* @hba: Pointer to UFS host bus adapter instance
436+
* @host_params: Pointer to UFS host parameters structure to be updated
437+
*
438+
* This function reads optional device tree properties to apply
439+
* platform-specific constraints.
440+
*
441+
* "limit-hs-gear": Specifies the max HS gear.
442+
* "limit-gear-rate": Specifies the max High-Speed rate.
443+
*/
444+
void ufshcd_parse_gear_limits(struct ufs_hba *hba, struct ufs_host_params *host_params)
445+
{
446+
struct device_node *np = hba->dev->of_node;
447+
u32 hs_gear;
448+
const char *hs_rate;
449+
450+
if (!of_property_read_u32(np, "limit-hs-gear", &hs_gear)) {
451+
host_params->hs_tx_gear = hs_gear;
452+
host_params->hs_rx_gear = hs_gear;
453+
}
454+
455+
if (!of_property_read_string(np, "limit-gear-rate", &hs_rate)) {
456+
if (!strcmp(hs_rate, "rate-a"))
457+
host_params->hs_rate = PA_HS_MODE_A;
458+
else if (!strcmp(hs_rate, "rate-b"))
459+
host_params->hs_rate = PA_HS_MODE_B;
460+
else
461+
dev_warn(hba->dev, "Invalid rate: %s\n", hs_rate);
462+
}
463+
}
464+
EXPORT_SYMBOL_GPL(ufshcd_parse_gear_limits);
465+
433466
void ufshcd_init_host_params(struct ufs_host_params *host_params)
434467
{
435468
*host_params = (struct ufs_host_params){

drivers/ufs/host/ufshcd-pltfrm.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ int ufshcd_negotiate_pwr_params(const struct ufs_host_params *host_params,
2929
const struct ufs_pa_layer_attr *dev_max,
3030
struct ufs_pa_layer_attr *agreed_pwr);
3131
void ufshcd_init_host_params(struct ufs_host_params *host_params);
32+
void ufshcd_parse_gear_limits(struct ufs_hba *hba, struct ufs_host_params *host_params);
3233
int ufshcd_pltfrm_init(struct platform_device *pdev,
3334
const struct ufs_hba_variant_ops *vops);
3435
void ufshcd_pltfrm_remove(struct platform_device *pdev);

0 commit comments

Comments
 (0)