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

Commit c84acc8c authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "scsi: ufs-qcom: Adjust the order of bus bandwidth voting and unvoting"

parents fadb781f 55af5bb5
Loading
Loading
Loading
Loading
+69 −29
Original line number Diff line number Diff line
@@ -64,7 +64,6 @@ struct ufs_qcom_dev_params {

static struct ufs_qcom_host *ufs_qcom_hosts[MAX_UFS_QCOM_HOSTS];

static int ufs_qcom_set_bus_vote(struct ufs_qcom_host *host, int vote);
static void ufs_qcom_get_default_testbus_cfg(struct ufs_qcom_host *host);
static int ufs_qcom_set_dme_vs_core_clk_ctrl_clear_div(struct ufs_hba *hba,
						       u32 clk_1us_cycles,
@@ -1053,7 +1052,7 @@ static int ufs_qcom_get_ib_ab(struct ufs_qcom_host *host, int index,
	return 0;
}

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;
	struct qcom_bus_scale_data *d = host->qbsd;
@@ -1100,7 +1099,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;

@@ -1111,6 +1110,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)
@@ -1271,7 +1299,7 @@ static int ufs_qcom_bus_register(struct ufs_qcom_host *host)
			err);

	/* Full throttle */
	err = ufs_qcom_set_bus_vote(host, host->bus_vote.max_bw_vote);
	err = __ufs_qcom_set_bus_vote(host, host->bus_vote.max_bw_vote);
	if (err)
		dev_err(dev, "Error: (%d) Failed to set max bus vote\n", err);

@@ -1550,8 +1578,7 @@ static int ufs_qcom_setup_clocks(struct ufs_hba *hba, bool on,
				 enum ufs_notify_change_status status)
{
	struct ufs_qcom_host *host = ufshcd_get_variant(hba);
	int err;
	int vote = 0;
	int err = 0;

	/*
	 * In case ufs_qcom_init() is not yet done, simply ignore.
@@ -1561,32 +1588,28 @@ static int ufs_qcom_setup_clocks(struct ufs_hba *hba, bool on,
	if (!host)
		return 0;

	if (on && (status == POST_CHANGE)) {
	switch (status) {
	case PRE_CHANGE:
		if (on) {
			err = ufs_qcom_set_bus_vote(hba, true);
		} else {
			if (!ufs_qcom_is_link_active(hba)) {
				/* disable device ref_clk */
				ufs_qcom_dev_ref_clk_ctrl(host, false);
			}
		}
		break;
	case POST_CHANGE:
		if (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);

	} else if (!on && (status == PRE_CHANGE)) {
		if ((ufshcd_is_auto_hibern8_supported(hba) &&
			!!hba->ahit) ||
			!ufs_qcom_is_link_active(hba)) {
			/* disable device ref_clk */
			ufs_qcom_dev_ref_clk_ctrl(host, false);
			/* powering off PHY during aggressive clk gating */
		} else {
			err = ufs_qcom_set_bus_vote(hba, false);
		}


		vote = host->bus_vote.min_bw_vote;
		break;
	}

	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;
}

@@ -1979,6 +2002,21 @@ ufs_qcom_ioctl(struct scsi_device *dev, unsigned int cmd, void __user *buffer)
	return err;
}

static void ufs_qcom_parse_pm_level(struct ufs_hba *hba)
{
	struct device *dev = hba->dev;
	struct device_node *np = dev->of_node;

	if (np) {
		if (of_property_read_u32(np, "rpm-level",
					 &hba->rpm_lvl))
			hba->rpm_lvl = -1;
		if (of_property_read_u32(np, "spm-level",
					 &hba->spm_lvl))
			hba->spm_lvl = -1;
	}
}

/**
 * ufs_qcom_init - bind phy with controller
 * @hba: host controller instance
@@ -2132,6 +2170,7 @@ static int ufs_qcom_init(struct ufs_hba *hba)
	if (err)
		goto out_set_load_vccq_parent;

	ufs_qcom_parse_pm_level(hba);
	ufs_qcom_parse_limits(host);
	ufs_qcom_parse_lpm(host);
	if (host->disable_lpm)
@@ -2140,6 +2179,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, POST_CHANGE);

	if (hba->dev->id < MAX_UFS_QCOM_HOSTS)
+4 −11
Original line number Diff line number Diff line
@@ -8705,11 +8705,9 @@ static int ufshcd_setup_clocks(struct ufs_hba *hba, bool on,
	 * this standard driver hence call the vendor specific setup_clocks
	 * before disabling the clocks managed here.
	 */
	if (!on) {
	ret = ufshcd_vops_setup_clocks(hba, on, PRE_CHANGE);
	if (ret)
			goto out_unlock;
	}
		return ret;

	list_for_each_entry(clki, head, list) {
		if (!IS_ERR_OR_NULL(clki->clk)) {
@@ -8744,11 +8742,7 @@ 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) {
	ret = ufshcd_vops_setup_clocks(hba, on, POST_CHANGE);
		if (ret)
			goto out;
	}

out:
	if (ret) {
@@ -8768,7 +8762,6 @@ static int ufshcd_setup_clocks(struct ufs_hba *hba, bool on,
		trace_ufshcd_profile_clk_gating(dev_name(hba->dev),
			(on ? "on" : "off"),
			ktime_to_us(ktime_sub(ktime_get(), start)), ret);
out_unlock:
	return ret;
}