Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 58c0aaeb authored by Gilad Broner's avatar Gilad Broner
Browse files

ufs: qcom: add dts property to disable LPM modes



Since msmcobalt RUMI uses QRBTC-V2 UFS PHY, there are a few limitations
that must be applied in order to be able to initialize UFS:
1. UFS should remain in PWM-G1 1-Lane and never change its gear, as other
gears are not stable
2. hibern8 enter/exit should be bypassed
3. we should avoid any power change (as in runtime suspend/resume)

Add "qcom,disable-lpm" property to facilitate disabling of these.

Change-Id: I3f1801da1e2bf1ce8ce98f5ab08211683106ae8c
Signed-off-by: default avatarYaniv Gardi <ygardi@codeaurora.org>
Signed-off-by: default avatarGilad Broner <gbroner@codeaurora.org>
parent 99d7b718
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -28,6 +28,8 @@ Optional properties:
- vddp-ref-clk-supply   : phandle to UFS device ref_clk pad power supply
- vddp-ref-clk-max-microamp : specifies max. load that can be drawn from this supply
- vddp-ref-clk-always-on : specifies if this supply needs to be kept always on
- qcom,disable-lpm : disable various LPM mechanisms in UFS for platform compatibility
  (limit link to PWM Gear-1, 1-lane slow mode; disable hibernate, and avoid suspend/resume)

Example:

+9 −1
Original line number Diff line number Diff line
/*
 * Copyright (c) 2013-2015, Linux Foundation. All rights reserved.
 * Copyright (c) 2013-2016, Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -611,6 +611,14 @@ int ufs_qcom_phy_calibrate_phy(struct phy *generic_phy, bool is_rate_B)
}
EXPORT_SYMBOL(ufs_qcom_phy_calibrate_phy);

const char *ufs_qcom_phy_name(struct phy *phy)
{
	struct ufs_qcom_phy *ufs_qcom_phy = get_ufs_qcom_phy(phy);

	return ufs_qcom_phy->name;
}
EXPORT_SYMBOL(ufs_qcom_phy_name);

int ufs_qcom_phy_remove(struct phy *generic_phy,
			struct ufs_qcom_phy *ufs_qcom_phy)
{
+35 −4
Original line number Diff line number Diff line
/*
 * Copyright (c) 2013-2015, Linux Foundation. All rights reserved.
 * Copyright (c) 2013-2016, Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -1107,6 +1107,18 @@ static int ufs_qcom_pwr_change_notify(struct ufs_hba *hba,
				ufs_qcom_cap.hs_rx_gear = UFS_HS_G2;
		}

		/*
		 * Platforms using QRBTCv2 phy must limit link to PWM Gear-1
		 * and SLOW mode to successfully bring up the link.
		 */
		if (!strcmp(ufs_qcom_phy_name(phy), "ufs_phy_qrbtc_v2")) {
			ufs_qcom_cap.tx_lanes = 1;
			ufs_qcom_cap.rx_lanes = 1;
			ufs_qcom_cap.pwm_rx_gear = UFS_PWM_G1;
			ufs_qcom_cap.pwm_tx_gear = UFS_PWM_G1;
			ufs_qcom_cap.desired_working_mode = SLOW;
		}

		ret = ufs_qcom_get_pwr_dev_param(&ufs_qcom_cap,
						 dev_max_params,
						 dev_req_params);
@@ -1238,11 +1250,15 @@ static void ufs_qcom_set_caps(struct ufs_hba *hba)
{
	struct ufs_qcom_host *host = ufshcd_get_variant(hba);

	hba->caps |= UFSHCD_CAP_CLK_GATING | UFSHCD_CAP_HIBERN8_WITH_CLK_GATING;
	if (!host->disable_lpm) {
		hba->caps |= UFSHCD_CAP_CLK_GATING;
		hba->caps |= UFSHCD_CAP_HIBERN8_WITH_CLK_GATING;
		hba->caps |= UFSHCD_CAP_CLK_SCALING;
	}
	hba->caps |= UFSHCD_CAP_AUTO_BKOPS_SUSPEND;

	if (host->hw_ver.major >= 0x2) {
		if (!host->disable_lpm)
			hba->caps |= UFSHCD_CAP_POWER_COLLAPSE_DURING_HIBERN8;
		host->caps = UFS_QCOM_CAP_QUNIPRO |
			     UFS_QCOM_CAP_RETAIN_SEC_CFG_AFTER_PWR_COLLAPSE;
@@ -1720,6 +1736,18 @@ static int __init get_android_boot_dev(char *str)
__setup("androidboot.bootdevice=", get_android_boot_dev);
#endif

/*
 * ufs_qcom_parse_lpm - read from DTS whether LPM modes should be disabled.
 */
static void ufs_qcom_parse_lpm(struct ufs_qcom_host *host)
{
	struct device_node *node = host->hba->dev->of_node;

	host->disable_lpm = of_property_read_bool(node, "qcom,disable-lpm");
	if (host->disable_lpm)
		pr_info("%s: will disable all LPM modes\n", __func__);
}

/**
 * ufs_qcom_init - bind phy with controller
 * @hba: host controller instance
@@ -1851,6 +1879,9 @@ static int ufs_qcom_init(struct ufs_hba *hba)
	if (err)
		goto out_disable_phy;

	ufs_qcom_parse_lpm(host);
	if (host->disable_lpm)
		pm_runtime_forbid(host->hba->dev);
	ufs_qcom_set_caps(hba);
	ufs_qcom_advertise_quirks(hba);

+2 −1
Original line number Diff line number Diff line
/* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
/* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -323,6 +323,7 @@ struct ufs_qcom_host {
	/* PM Quality-of-Service (QoS) data */
	struct ufs_qcom_pm_qos pm_qos;

	bool disable_lpm;
	bool is_lane_clks_enabled;
	bool sec_cfg_updated;
	struct ufs_qcom_ice_data ice;
+2 −1
Original line number Diff line number Diff line
/*
 * Copyright (c) 2013-2015, Linux Foundation. All rights reserved.
 * Copyright (c) 2013-2016, Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -28,4 +28,5 @@ int ufs_qcom_phy_calibrate_phy(struct phy *phy, bool is_rate_B);
int ufs_qcom_phy_is_pcs_ready(struct phy *phy);
void ufs_qcom_phy_save_controller_version(struct phy *phy,
			u8 major, u16 minor, u16 step);
const char *ufs_qcom_phy_name(struct phy *phy);
#endif