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

Commit d5ef5272 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "scsi: ufs-msm: request UFS register space access after power collapse"

parents 02fec52f 0bde8160
Loading
Loading
Loading
Loading
+73 −0
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@
#include <linux/platform_device.h>

#include <linux/msm-bus.h>
#include <soc/qcom/scm.h>

#include "ufshcd.h"
#include "unipro.h"
@@ -32,6 +33,7 @@ static int ufs_msm_get_speed_mode(struct ufs_pa_layer_attr *p, char *result);
static int ufs_msm_get_bus_vote(struct ufs_msm_host *host,
		const char *speed_mode);
static int ufs_msm_set_bus_vote(struct ufs_msm_host *host, int vote);
static int ufs_msm_update_sec_cfg(struct ufs_hba *hba, bool restore_sec_cfg);

static int ufs_msm_get_connected_tx_lanes(struct ufs_hba *hba, u32 *tx_lanes)
{
@@ -1060,6 +1062,9 @@ static int ufs_msm_init(struct ufs_hba *hba)

	hba->priv = (void *)host;

	/* restore the secure configuration */
	ufs_msm_update_sec_cfg(hba, true);

	err = ufs_msm_bus_register(host);
	if (err)
		goto out_host_free;
@@ -1115,6 +1120,73 @@ void ufs_msm_clk_scale_notify(struct ufs_hba *hba)
				dev_req_params->hs_rate);
	ufs_msm_update_bus_bw_vote(host);
}

/*
 * This function should be called to restore the security configuration of UFS
 * register space after coming out of UFS host core power collapse.
 *
 * @hba: host controller instance
 * @restore_sec_cfg: Set "true" if secure configuration needs to be restored
 * and set "false" when secure configuration is lost.
 */
static int ufs_msm_update_sec_cfg(struct ufs_hba *hba, bool restore_sec_cfg)
{
	int ret = 0, scm_ret = 0;
	struct ufs_msm_host *host = hba->priv;

	/* scm command buffer structrue */
	struct msm_scm_cmd_buf {
		unsigned int device_id;
		unsigned int spare;
	} cbuf;
	#define RESTORE_SEC_CFG_CMD	0x2
	#define UFS_TZ_DEV_ID		19

	if (!host || !hba->vreg_info.vdd_hba ||
	    !(host->sec_cfg_updated ^ restore_sec_cfg)) {
		return 0;
	} else if (!restore_sec_cfg) {
		/*
		 * Clear the flag so next time when this function is called
		 * with restore_sec_cfg set to true, we can restore the secure
		 * configuration.
		 */
		host->sec_cfg_updated = false;
		goto out;
	} else if (hba->clk_gating.state != CLKS_ON) {
		/*
		 * Clocks should be ON to restore the host controller secure
		 * configuration.
		 */
		goto out;
	}

	/*
	 * If we are here, Host controller clocks are running, Host controller
	 * power collapse feature is supported and Host controller has just came
	 * out of power collapse.
	 */
	cbuf.device_id = UFS_TZ_DEV_ID;
	ret = scm_call(SCM_SVC_MP,
		       RESTORE_SEC_CFG_CMD,
		       &cbuf, sizeof(cbuf),
		       &scm_ret, sizeof(scm_ret));

	if (ret || scm_ret) {
		dev_err(hba->dev, "%s: failed, ret %d scm_ret %d\n",
			__func__, ret, scm_ret);
		if (!ret)
			ret = scm_ret;
	} else {
		host->sec_cfg_updated = true;
	}

out:
	dev_dbg(hba->dev, "%s: ip: restore_sec_cfg %d, op: restore_sec_cfg %d, ret %d scm_ret %d\n",
		__func__, restore_sec_cfg, host->sec_cfg_updated, ret, scm_ret);
	return ret;
}

/**
 * struct ufs_hba_msm_vops - UFS MSM specific variant operations
 *
@@ -1132,5 +1204,6 @@ const struct ufs_hba_variant_ops ufs_hba_msm_vops = {
	.pwr_change_notify	= ufs_msm_pwr_change_notify,
	.suspend		= ufs_msm_suspend,
	.resume			= ufs_msm_resume,
	.update_sec_cfg		= ufs_msm_update_sec_cfg,
};
EXPORT_SYMBOL(ufs_hba_msm_vops);
+1 −0
Original line number Diff line number Diff line
@@ -134,6 +134,7 @@ struct ufs_msm_host {
	struct clk *rx_l1_sync_clk;
	struct clk *tx_l1_sync_clk;
	bool is_lane_clks_enabled;
	bool sec_cfg_updated;
};

#define ufs_msm_is_link_off(hba) ufshcd_is_link_off(hba)
+12 −4
Original line number Diff line number Diff line
@@ -5252,12 +5252,17 @@ out:

static int ufshcd_setup_hba_vreg(struct ufs_hba *hba, bool on)
{
	int ret = 0;
	struct ufs_vreg_info *info = &hba->vreg_info;

	if (info)
		return ufshcd_toggle_vreg(hba->dev, info->vdd_hba, on);
	else
		return 0;
	if (info->vdd_hba) {
		ret = ufshcd_toggle_vreg(hba->dev, info->vdd_hba, on);

		if (!ret && hba->vops->update_sec_cfg)
			hba->vops->update_sec_cfg(hba, on);
	}

	return ret;
}

static int ufshcd_get_vreg(struct device *dev, struct ufs_vreg *vreg)
@@ -5356,6 +5361,9 @@ out:
				ufschd_clk_gating_state_to_string(
					hba->clk_gating.state));
		spin_unlock_irqrestore(hba->host->host_lock, flags);
		/* restore the secure configuration as clocks are enabled */
		if (hba->vops->update_sec_cfg)
			hba->vops->update_sec_cfg(hba, true);
	}
	return ret;
}
+2 −0
Original line number Diff line number Diff line
@@ -314,6 +314,7 @@ struct ufs_pwr_mode_info {
 *			to be set.
 * @suspend: called during host controller PM callback
 * @resume: called during host controller PM callback
 * @update_sec_cfg: called to restore host controller secure configuration
 */
struct ufs_hba_variant_ops {
	const char *name;
@@ -329,6 +330,7 @@ struct ufs_hba_variant_ops {
					struct ufs_pa_layer_attr *);
	int     (*suspend)(struct ufs_hba *, enum ufs_pm_op);
	int     (*resume)(struct ufs_hba *, enum ufs_pm_op);
	int	(*update_sec_cfg)(struct ufs_hba *hba, bool restore_sec_cfg);
};

/* clock gating state  */