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

Commit 61e4fba7 authored by Veera Sundaram Sankaran's avatar Veera Sundaram Sankaran Committed by Gerrit - the friendly Code Review server
Browse files

drm/msm/sde: enable MISR during secure-ui session



Enable MISR before transitioning into secure mode and
disable it while transitioning back to non-secure mode
based on secure-ui-misr feature flag set in the catalog.
Add a vote on the core-clks to make sure all the resources
are up and ensuring there is no power-collapse during the
session, so MISR can be read throughout the session.

Change-Id: I18f4fb6f60b3a64b3c28b05525224a59b08055a9
Signed-off-by: default avatarVeera Sundaram Sankaran <veeras@codeaurora.org>
parent 8fd692a4
Loading
Loading
Loading
Loading
+65 −14
Original line number Diff line number Diff line
@@ -1787,6 +1787,7 @@ int sde_crtc_get_secure_transition_ops(struct drm_crtc *crtc,
	struct drm_encoder *encoder;
	struct sde_crtc *sde_crtc;
	struct sde_kms *sde_kms;
	struct sde_mdss_cfg *catalog;
	struct sde_kms_smmu_state_data *smmu_state;
	uint32_t translation_mode = 0, secure_level;
	int ops  = 0;
@@ -1804,6 +1805,7 @@ int sde_crtc_get_secure_transition_ops(struct drm_crtc *crtc,
	smmu_state = &sde_kms->smmu_state;
	sde_crtc = to_sde_crtc(crtc);
	secure_level = sde_crtc_get_secure_level(crtc, crtc->state);
	catalog = sde_kms->catalog;

	SDE_DEBUG("crtc%d, secure_level%d old_valid_fb%d\n",
			crtc->base.id, secure_level, old_valid_fb);
@@ -1858,6 +1860,9 @@ int sde_crtc_get_secure_transition_ops(struct drm_crtc *crtc,
				ops |= (SDE_KMS_OPS_WAIT_FOR_TX_DONE  |
					SDE_KMS_OPS_CLEANUP_PLANE_FB);
			}
			if (catalog->sui_misr_supported)
				smmu_state->sui_misr_state =
						SUI_MISR_ENABLE_REQ;
		/* secure camera usecase */
		} else if (smmu_state->state == ATTACHED) {
			smmu_state->state = DETACH_SEC_REQ;
@@ -1885,6 +1890,9 @@ int sde_crtc_get_secure_transition_ops(struct drm_crtc *crtc,
			if (old_valid_fb)
				ops |= (SDE_KMS_OPS_WAIT_FOR_TX_DONE |
				 SDE_KMS_OPS_CLEANUP_PLANE_FB);
			if (catalog->sui_misr_supported)
				smmu_state->sui_misr_state =
						SUI_MISR_DISABLE_REQ;
		}
		break;

@@ -5295,6 +5303,46 @@ static int sde_crtc_atomic_get_property(struct drm_crtc *crtc,
	return ret;
}

void sde_crtc_misr_setup(struct drm_crtc *crtc, bool enable, u32 frame_count)
{
	struct sde_kms *sde_kms;
	struct sde_crtc *sde_crtc;
	struct sde_crtc_mixer *m;
	int i;

	if (!crtc) {
		SDE_ERROR("invalid argument\n");
		return;
	}
	sde_crtc = to_sde_crtc(crtc);

	sde_kms = _sde_crtc_get_kms(crtc);
	if (!sde_kms) {
		SDE_ERROR("invalid sde_kms\n");
		return;
	}

	mutex_lock(&sde_crtc->crtc_lock);
	if (sde_kms_is_secure_session_inprogress(sde_kms)) {
		SDE_DEBUG("crtc:%d misr enable/disable not allowed\n",
				DRMID(crtc));
		mutex_unlock(&sde_crtc->crtc_lock);
		return;
	}

	sde_crtc->misr_enable = enable;
	sde_crtc->misr_frame_count = frame_count;
	for (i = 0; i < sde_crtc->num_mixers; ++i) {
		sde_crtc->misr_data[i] = 0;
		m = &sde_crtc->mixers[i];
		if (!m->hw_lm || !m->hw_lm->ops.setup_misr)
			continue;

		m->hw_lm->ops.setup_misr(m->hw_lm, enable, frame_count);
	}
	mutex_unlock(&sde_crtc->crtc_lock);
}

#ifdef CONFIG_DEBUG_FS
static int _sde_debugfs_status_show(struct seq_file *s, void *data)
{
@@ -5442,9 +5490,9 @@ static int _sde_debugfs_status_open(struct inode *inode, struct file *file)
static ssize_t _sde_crtc_misr_setup(struct file *file,
		const char __user *user_buf, size_t count, loff_t *ppos)
{
	struct drm_crtc *crtc;
	struct sde_crtc *sde_crtc;
	struct sde_crtc_mixer *m;
	int i = 0, rc;
	int rc;
	char buf[MISR_BUFF_SIZE + 1];
	u32 frame_count, enable;
	size_t buff_copy;
@@ -5453,6 +5501,8 @@ static ssize_t _sde_crtc_misr_setup(struct file *file,
		return -EINVAL;

	sde_crtc = file->private_data;
	crtc = &sde_crtc->base;

	buff_copy = min_t(size_t, count, MISR_BUFF_SIZE);
	if (copy_from_user(buf, user_buf, buff_copy)) {
		SDE_ERROR("buffer copy failed\n");
@@ -5468,18 +5518,7 @@ static ssize_t _sde_crtc_misr_setup(struct file *file,
	if (rc)
		return rc;

	mutex_lock(&sde_crtc->crtc_lock);
	sde_crtc->misr_enable = enable;
	sde_crtc->misr_frame_count = frame_count;
	for (i = 0; i < sde_crtc->num_mixers; ++i) {
		sde_crtc->misr_data[i] = 0;
		m = &sde_crtc->mixers[i];
		if (!m->hw_lm || !m->hw_lm->ops.setup_misr)
			continue;

		m->hw_lm->ops.setup_misr(m->hw_lm, enable, frame_count);
	}
	mutex_unlock(&sde_crtc->crtc_lock);
	sde_crtc_misr_setup(crtc, enable, frame_count);
	_sde_crtc_power_enable(sde_crtc, false);

	return count;
@@ -5488,7 +5527,9 @@ static ssize_t _sde_crtc_misr_setup(struct file *file,
static ssize_t _sde_crtc_misr_read(struct file *file,
		char __user *user_buff, size_t count, loff_t *ppos)
{
	struct drm_crtc *crtc;
	struct sde_crtc *sde_crtc;
	struct sde_kms *sde_kms;
	struct sde_crtc_mixer *m;
	int i = 0, rc;
	u32 misr_status;
@@ -5502,11 +5543,21 @@ static ssize_t _sde_crtc_misr_read(struct file *file,
		return -EINVAL;

	sde_crtc = file->private_data;
	crtc = &sde_crtc->base;
	sde_kms = _sde_crtc_get_kms(crtc);
	if (!sde_kms)
		return -EINVAL;

	rc = _sde_crtc_power_enable(sde_crtc, true);
	if (rc)
		return rc;

	mutex_lock(&sde_crtc->crtc_lock);
	if (sde_kms_is_secure_session_inprogress(sde_kms)) {
		SDE_DEBUG("crtc:%d misr read not allowed\n", DRMID(crtc));
		goto end;
	}

	if (!sde_crtc->misr_enable) {
		len += snprintf(buf + len, MISR_BUFF_SIZE - len,
			"disabled\n");
+8 −0
Original line number Diff line number Diff line
@@ -741,4 +741,12 @@ void sde_crtc_update_cont_splash_mixer_settings(
 */
uint64_t sde_crtc_get_sbuf_clk(struct drm_crtc_state *state);

/**
 * sde_crtc_misr_setup - to configure and enable/disable MISR
 * @crtc: Pointer to drm crtc structure
 * @enable: boolean to indicate enable/disable misr
 * @frame_count: frame_count to be configured
 */
void sde_crtc_misr_setup(struct drm_crtc *crtc, bool enable, u32 frame_count);

#endif /* _SDE_CRTC_H_ */
+3 −0
Original line number Diff line number Diff line
@@ -932,6 +932,7 @@ struct sde_perf_cfg {
 * @wb_formats         Supported formats for wb
 * @vbif_qos_nlvl      number of vbif QoS priority level
 * @ts_prefill_rev     prefill traffic shaper feature revision
 * @sui_misr_supported  indicate if secure-ui-misr is supported
 */
struct sde_mdss_cfg {
	u32 hwversion;
@@ -962,6 +963,8 @@ struct sde_mdss_cfg {
	u32 vbif_qos_nlvl;
	u32 ts_prefill_rev;

	bool sui_misr_supported;

	bool has_hdr;
	u32 mdss_count;
	struct sde_mdss_base_cfg mdss[MAX_BLOCKS];
+43 −1
Original line number Diff line number Diff line
@@ -546,6 +546,31 @@ static int _sde_kms_attach_sec_cb(struct sde_kms *sde_kms)
	return ret;
}

static int _sde_kms_sui_misr_ctrl(struct sde_kms *sde_kms,
		struct drm_crtc *crtc, bool enable)
{
	struct drm_device *dev = sde_kms->dev;
	struct msm_drm_private *priv = dev->dev_private;
	int ret;

	if (enable) {
		ret = sde_power_resource_enable(&priv->phandle,
					sde_kms->core_client, true);
		if (ret) {
			SDE_ERROR("failed to enable resource, ret:%d\n", ret);
			return ret;
		}
		sde_crtc_misr_setup(crtc, true, 1);

	} else {
		sde_crtc_misr_setup(crtc, false, 0);
		sde_power_resource_enable(&priv->phandle,
					sde_kms->core_client, false);
	}

	return 0;
}

static int _sde_kms_secure_ctrl(struct sde_kms *sde_kms, struct drm_crtc *crtc,
		bool post_commit)
{
@@ -559,13 +584,21 @@ static int _sde_kms_secure_ctrl(struct sde_kms *sde_kms, struct drm_crtc *crtc,
	}

	SDE_EVT32(DRMID(crtc), smmu_state->state, smmu_state->transition_type,
			post_commit, SDE_EVTLOG_FUNC_ENTRY);
			post_commit, smmu_state->sui_misr_state,
			SDE_EVTLOG_FUNC_ENTRY);

	if ((!smmu_state->transition_type) ||
	    ((smmu_state->transition_type == POST_COMMIT) && !post_commit))
		/* Bail out */
		return 0;

	/* enable sui misr if requested, before the transition */
	if (smmu_state->sui_misr_state == SUI_MISR_ENABLE_REQ) {
		ret = _sde_kms_sui_misr_ctrl(sde_kms, crtc, true);
		if (ret)
			goto end;
	}

	mutex_lock(&sde_kms->secure_transition_lock);
	switch (smmu_state->state) {
	/* Secure UI use case enable */
@@ -605,6 +638,15 @@ static int _sde_kms_secure_ctrl(struct sde_kms *sde_kms, struct drm_crtc *crtc,
	}
	mutex_unlock(&sde_kms->secure_transition_lock);

	/* disable sui misr if requested, after the transition */
	if (!ret && (smmu_state->sui_misr_state == SUI_MISR_DISABLE_REQ)) {
		ret = _sde_kms_sui_misr_ctrl(sde_kms, crtc, false);
		if (ret)
			goto end;
	}

end:
	smmu_state->sui_misr_state = NONE;
	smmu_state->transition_type = NONE;
	smmu_state->transition_error = ret ? true : false;

+14 −2
Original line number Diff line number Diff line
@@ -145,6 +145,18 @@ enum sde_kms_smmu_state_transition_type {
	POST_COMMIT
};

/**
 * enum sde_kms_sui_misr_state: state request for enabling/disabling MISR
 * @NONE: no request
 * @ENABLE_SUI_MISR_REQ: request to enable sui MISR
 * @DISABLE_SUI_MISR_REQ: request to disable sui MISR
 */
enum sde_kms_sui_misr_state {
	SUI_MISR_NONE,
	SUI_MISR_ENABLE_REQ,
	SUI_MISR_DISABLE_REQ
};

/**
 * struct sde_kms_smmu_state_data: stores the smmu state and transition type
 * @state: current state of smmu context banks
@@ -155,6 +167,7 @@ struct sde_kms_smmu_state_data {
	uint32_t state;
	uint32_t transition_type;
	uint32_t transition_error;
	uint32_t sui_misr_state;
};

/*
@@ -351,8 +364,7 @@ static inline bool sde_kms_is_secure_session_inprogress(struct sde_kms *sde_kms)
		return false;

	mutex_lock(&sde_kms->secure_transition_lock);
	if ((sde_kms->smmu_state.state == DETACHED) ||
			(sde_kms->smmu_state.state == DETACH_ALL_REQ))
	if (sde_kms->smmu_state.state == DETACHED)
		ret = true;
	mutex_unlock(&sde_kms->secure_transition_lock);