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

Commit d3ee5030 authored by Venkat Gopalakrishnan's avatar Venkat Gopalakrishnan
Browse files

scsi: ufs: export set_bus_vote ops



The bus bandwidth vote is required to be done before the bus clocks
are enabled, hence separate the bus voting from vendor specific
setup clocks that is called after the ufs core clocks are enabled.

Change-Id: I5148ec4ce55a00f5130a60d0c088b3f0218d2261
Signed-off-by: default avatarVenkat Gopalakrishnan <venkatg@codeaurora.org>
parent c6855ffd
Loading
Loading
Loading
Loading
+33 −12
Original line number Diff line number Diff line
@@ -996,7 +996,7 @@ static void ufs_qcom_get_speed_mode(struct ufs_pa_layer_attr *p, char *result)
	}
}

static int ufs_qcom_set_bus_vote(struct ufs_qcom_host *host, int vote)
static int __ufs_qcom_set_bus_vote(struct ufs_qcom_host *host, int vote)
{
	int err = 0;

@@ -1027,7 +1027,7 @@ static int ufs_qcom_update_bus_bw_vote(struct ufs_qcom_host *host)

	vote = ufs_qcom_get_bus_vote(host, mode);
	if (vote >= 0)
		err = ufs_qcom_set_bus_vote(host, vote);
		err = __ufs_qcom_set_bus_vote(host, vote);
	else
		err = vote;

@@ -1038,6 +1038,35 @@ static int ufs_qcom_update_bus_bw_vote(struct ufs_qcom_host *host)
	return err;
}

static int ufs_qcom_set_bus_vote(struct ufs_hba *hba, bool on)
{
	struct ufs_qcom_host *host = ufshcd_get_variant(hba);
	int vote, err;

	/*
	 * In case ufs_qcom_init() is not yet done, simply ignore.
	 * This ufs_qcom_set_bus_vote() shall be called from
	 * ufs_qcom_init() after init is done.
	 */
	if (!host)
		return 0;

	if (on) {
		vote = host->bus_vote.saved_vote;
		if (vote == host->bus_vote.min_bw_vote)
			ufs_qcom_update_bus_bw_vote(host);
	} else {
		vote = host->bus_vote.min_bw_vote;
	}

	err = __ufs_qcom_set_bus_vote(host, vote);
	if (err)
		dev_err(hba->dev, "%s: set bus vote failed %d\n",
				__func__, err);

	return err;
}

static ssize_t
show_ufs_to_mem_max_bus_bw(struct device *dev, struct device_attribute *attr,
			char *buf)
@@ -1403,7 +1432,6 @@ static int ufs_qcom_setup_clocks(struct ufs_hba *hba, bool on,
{
	struct ufs_qcom_host *host = ufshcd_get_variant(hba);
	int err;
	int vote = 0;

	/*
	 * In case ufs_qcom_init() is not yet done, simply ignore.
@@ -1428,9 +1456,6 @@ static int ufs_qcom_setup_clocks(struct ufs_hba *hba, bool on,
		/* enable the device ref clock for HS mode*/
		if (ufshcd_is_hs_mode(&hba->pwr_info))
			ufs_qcom_dev_ref_clk_ctrl(host, true);
		vote = host->bus_vote.saved_vote;
		if (vote == host->bus_vote.min_bw_vote)
			ufs_qcom_update_bus_bw_vote(host);

		err = ufs_qcom_ice_resume(host);
		if (err)
@@ -1449,14 +1474,8 @@ static int ufs_qcom_setup_clocks(struct ufs_hba *hba, bool on,
			/* disable device ref_clk */
			ufs_qcom_dev_ref_clk_ctrl(host, false);
		}
		vote = host->bus_vote.min_bw_vote;
	}

	err = ufs_qcom_set_bus_vote(host, vote);
	if (err)
		dev_err(hba->dev, "%s: set bus vote failed %d\n",
				__func__, err);

out:
	return err;
}
@@ -2011,6 +2030,7 @@ static int ufs_qcom_init(struct ufs_hba *hba)
	ufs_qcom_set_caps(hba);
	ufs_qcom_advertise_quirks(hba);

	ufs_qcom_set_bus_vote(hba, true);
	ufs_qcom_setup_clocks(hba, true, false);

	if (hba->dev->id < MAX_UFS_QCOM_HOSTS)
@@ -2521,6 +2541,7 @@ static struct ufs_hba_variant_ops ufs_hba_qcom_vops = {
	.full_reset		= ufs_qcom_full_reset,
	.update_sec_cfg		= ufs_qcom_update_sec_cfg,
	.get_scale_down_gear	= ufs_qcom_get_scale_down_gear,
	.set_bus_vote		= ufs_qcom_set_bus_vote,
	.dbg_register_dump	= ufs_qcom_dump_dbg_regs,
#ifdef CONFIG_DEBUG_FS
	.add_debugfs		= ufs_qcom_dbg_add_debugfs,
+21 −1
Original line number Diff line number Diff line
@@ -7555,6 +7555,13 @@ static int ufshcd_setup_clocks(struct ufs_hba *hba, bool on,
	if (!head || list_empty(head))
		goto out;

	/* call vendor specific bus vote before enabling the clocks */
	if (on) {
		ret = ufshcd_vops_set_bus_vote(hba, on);
		if (ret)
			return ret;
	}

	/*
	 * vendor specific setup_clocks ops may depend on clocks managed by
	 * this standard driver hence call the vendor specific setup_clocks
@@ -7593,11 +7600,24 @@ static int ufshcd_setup_clocks(struct ufs_hba *hba, bool on,
	 * this standard driver hence call the vendor specific setup_clocks
	 * after enabling the clocks managed here.
	 */
	if (on)
	if (on) {
		ret = ufshcd_vops_setup_clocks(hba, on, is_gating_context);
		if (ret)
			goto out;
	}

	/*
	 * call vendor specific bus vote to remove the vote after
	 * disabling the clocks.
	 */
	if (!on)
		ret = ufshcd_vops_set_bus_vote(hba, on);

out:
	if (ret) {
		if (on)
			/* Can't do much if this fails */
			(void) ufshcd_vops_set_bus_vote(hba, false);
		list_for_each_entry(clki, head, list) {
			if (!IS_ERR_OR_NULL(clki->clk) && clki->enabled)
				clk_disable_unprepare(clki->clk);
+9 −0
Original line number Diff line number Diff line
@@ -309,6 +309,7 @@ struct ufs_pwr_mode_info {
 * @update_sec_cfg: called to restore host controller secure configuration
 * @get_scale_down_gear: called to get the minimum supported gear to
 *			 scale down
 * @set_bus_vote: called to vote for the required bus bandwidth
 * @add_debugfs: used to add debugfs entries
 * @remove_debugfs: used to remove debugfs entries
 */
@@ -335,6 +336,7 @@ struct ufs_hba_variant_ops {
	void	(*dbg_register_dump)(struct ufs_hba *hba);
	int	(*update_sec_cfg)(struct ufs_hba *hba, bool restore_sec_cfg);
	u32	(*get_scale_down_gear)(struct ufs_hba *);
	int	(*set_bus_vote)(struct ufs_hba *, bool);
#ifdef CONFIG_DEBUG_FS
	void	(*add_debugfs)(struct ufs_hba *hba, struct dentry *root);
	void	(*remove_debugfs)(struct ufs_hba *hba);
@@ -1259,6 +1261,13 @@ static inline u32 ufshcd_vops_get_scale_down_gear(struct ufs_hba *hba)
	return UFS_HS_G1;
}

static inline int ufshcd_vops_set_bus_vote(struct ufs_hba *hba, bool on)
{
	if (hba->var && hba->var->vops && hba->var->vops->set_bus_vote)
		return hba->var->vops->set_bus_vote(hba, on);
	return 0;
}

#ifdef CONFIG_DEBUG_FS
static inline void ufshcd_vops_add_debugfs(struct ufs_hba *hba,
						struct dentry *root)