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: Veera Sundaram Sankaran <veeras@codeaurora.org>
diff --git a/drivers/gpu/drm/msm/sde/sde_crtc.c b/drivers/gpu/drm/msm/sde/sde_crtc.c
index 1a1ebac..3a23fd9 100644
--- a/drivers/gpu/drm/msm/sde/sde_crtc.c
+++ b/drivers/gpu/drm/msm/sde/sde_crtc.c
@@ -1787,6 +1787,7 @@
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 @@
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 @@
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 @@
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 @@
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 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 @@
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 @@
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_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 @@
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");
diff --git a/drivers/gpu/drm/msm/sde/sde_crtc.h b/drivers/gpu/drm/msm/sde/sde_crtc.h
index d66812b..bc1614c 100644
--- a/drivers/gpu/drm/msm/sde/sde_crtc.h
+++ b/drivers/gpu/drm/msm/sde/sde_crtc.h
@@ -741,4 +741,12 @@
*/
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_ */
diff --git a/drivers/gpu/drm/msm/sde/sde_hw_catalog.h b/drivers/gpu/drm/msm/sde/sde_hw_catalog.h
index 0bb61b3..0cb14d1 100644
--- a/drivers/gpu/drm/msm/sde/sde_hw_catalog.h
+++ b/drivers/gpu/drm/msm/sde/sde_hw_catalog.h
@@ -932,6 +932,7 @@
* @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 @@
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];
diff --git a/drivers/gpu/drm/msm/sde/sde_kms.c b/drivers/gpu/drm/msm/sde/sde_kms.c
index 2bdded6..652be26 100644
--- a/drivers/gpu/drm/msm/sde/sde_kms.c
+++ b/drivers/gpu/drm/msm/sde/sde_kms.c
@@ -546,6 +546,31 @@
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 @@
}
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 @@
}
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;
diff --git a/drivers/gpu/drm/msm/sde/sde_kms.h b/drivers/gpu/drm/msm/sde/sde_kms.h
index e4353e7..fa0d7f4 100644
--- a/drivers/gpu/drm/msm/sde/sde_kms.h
+++ b/drivers/gpu/drm/msm/sde/sde_kms.h
@@ -146,6 +146,18 @@
};
/**
+ * 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
* @transition_type: transition request type
@@ -155,6 +167,7 @@
uint32_t state;
uint32_t transition_type;
uint32_t transition_error;
+ uint32_t sui_misr_state;
};
/*
@@ -351,8 +364,7 @@
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);