|
@@ -334,88 +334,118 @@ static int _sde_kms_scm_call(struct sde_kms *sde_kms, int vmid)
|
|
|
|
|
|
static int _sde_kms_detach_all_cb(struct sde_kms *sde_kms, u32 vmid)
|
|
|
{
|
|
|
- u32 ret = 0;
|
|
|
+ u32 ret;
|
|
|
|
|
|
if (atomic_inc_return(&sde_kms->detach_all_cb) > 1)
|
|
|
- goto end;
|
|
|
+ return 0;
|
|
|
|
|
|
/* detach_all_contexts */
|
|
|
ret = sde_kms_mmu_detach(sde_kms, false);
|
|
|
if (ret) {
|
|
|
SDE_ERROR("failed to detach all cb ret:%d\n", ret);
|
|
|
- goto end;
|
|
|
+ goto mmu_error;
|
|
|
}
|
|
|
|
|
|
ret = _sde_kms_scm_call(sde_kms, vmid);
|
|
|
- if (ret)
|
|
|
- goto end;
|
|
|
+ if (ret) {
|
|
|
+ SDE_ERROR("scm call failed for vmid:%d\n", vmid);
|
|
|
+ goto scm_error;
|
|
|
+ }
|
|
|
|
|
|
-end:
|
|
|
+ return 0;
|
|
|
+
|
|
|
+scm_error:
|
|
|
+ sde_kms_mmu_attach(sde_kms, false);
|
|
|
+mmu_error:
|
|
|
+ atomic_dec(&sde_kms->detach_all_cb);
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
-static int _sde_kms_attach_all_cb(struct sde_kms *sde_kms, int vmid)
|
|
|
+static int _sde_kms_attach_all_cb(struct sde_kms *sde_kms, u32 vmid,
|
|
|
+ u32 old_vmid)
|
|
|
{
|
|
|
- u32 ret = 0;
|
|
|
+ u32 ret;
|
|
|
|
|
|
if (atomic_dec_return(&sde_kms->detach_all_cb) != 0)
|
|
|
- goto end;
|
|
|
+ return 0;
|
|
|
|
|
|
ret = _sde_kms_scm_call(sde_kms, vmid);
|
|
|
- if (ret)
|
|
|
- goto end;
|
|
|
+ if (ret) {
|
|
|
+ SDE_ERROR("scm call failed for vmid:%d\n", vmid);
|
|
|
+ goto scm_error;
|
|
|
+ }
|
|
|
|
|
|
/* attach_all_contexts */
|
|
|
ret = sde_kms_mmu_attach(sde_kms, false);
|
|
|
if (ret) {
|
|
|
SDE_ERROR("failed to attach all cb ret:%d\n", ret);
|
|
|
- goto end;
|
|
|
+ goto mmu_error;
|
|
|
}
|
|
|
|
|
|
-end:
|
|
|
+ return 0;
|
|
|
+
|
|
|
+mmu_error:
|
|
|
+ _sde_kms_scm_call(sde_kms, old_vmid);
|
|
|
+scm_error:
|
|
|
+ atomic_inc(&sde_kms->detach_all_cb);
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
static int _sde_kms_detach_sec_cb(struct sde_kms *sde_kms, int vmid)
|
|
|
{
|
|
|
- u32 ret = 0;
|
|
|
+ u32 ret;
|
|
|
|
|
|
if (atomic_inc_return(&sde_kms->detach_sec_cb) > 1)
|
|
|
- goto end;
|
|
|
+ return 0;
|
|
|
|
|
|
/* detach secure_context */
|
|
|
ret = sde_kms_mmu_detach(sde_kms, true);
|
|
|
if (ret) {
|
|
|
SDE_ERROR("failed to detach sec cb ret:%d\n", ret);
|
|
|
- goto end;
|
|
|
+ goto mmu_error;
|
|
|
}
|
|
|
|
|
|
ret = _sde_kms_scm_call(sde_kms, vmid);
|
|
|
- if (ret)
|
|
|
- goto end;
|
|
|
+ if (ret) {
|
|
|
+ SDE_ERROR("scm call failed for vmid:%d\n", vmid);
|
|
|
+ goto scm_error;
|
|
|
+ }
|
|
|
|
|
|
-end:
|
|
|
+ return 0;
|
|
|
+
|
|
|
+scm_error:
|
|
|
+ sde_kms_mmu_attach(sde_kms, true);
|
|
|
+mmu_error:
|
|
|
+ atomic_dec(&sde_kms->detach_sec_cb);
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
-static int _sde_kms_attach_sec_cb(struct sde_kms *sde_kms, int vmid)
|
|
|
+static int _sde_kms_attach_sec_cb(struct sde_kms *sde_kms, u32 vmid,
|
|
|
+ u32 old_vmid)
|
|
|
{
|
|
|
- u32 ret = 0;
|
|
|
+ u32 ret;
|
|
|
|
|
|
if (atomic_dec_return(&sde_kms->detach_sec_cb) != 0)
|
|
|
- goto end;
|
|
|
+ return 0;
|
|
|
|
|
|
ret = _sde_kms_scm_call(sde_kms, vmid);
|
|
|
- if (ret)
|
|
|
- goto end;
|
|
|
+ if (ret) {
|
|
|
+ goto scm_error;
|
|
|
+ SDE_ERROR("scm call failed for vmid:%d\n", vmid);
|
|
|
+ }
|
|
|
|
|
|
ret = sde_kms_mmu_attach(sde_kms, true);
|
|
|
if (ret) {
|
|
|
SDE_ERROR("failed to attach sec cb ret:%d\n", ret);
|
|
|
- goto end;
|
|
|
+ goto mmu_error;
|
|
|
}
|
|
|
|
|
|
-end:
|
|
|
+ return 0;
|
|
|
+
|
|
|
+mmu_error:
|
|
|
+ _sde_kms_scm_call(sde_kms, old_vmid);
|
|
|
+scm_error:
|
|
|
+ atomic_inc(&sde_kms->detach_sec_cb);
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
@@ -435,6 +465,7 @@ static int _sde_kms_sui_misr_ctrl(struct sde_kms *sde_kms,
|
|
|
|
|
|
ret = _sde_kms_secure_ctrl_xin_clients(sde_kms, crtc, true);
|
|
|
if (ret) {
|
|
|
+ sde_crtc_misr_setup(crtc, false, 0);
|
|
|
pm_runtime_put_sync(sde_kms->dev->dev);
|
|
|
return ret;
|
|
|
}
|
|
@@ -473,8 +504,10 @@ static int _sde_kms_secure_ctrl(struct sde_kms *sde_kms, struct drm_crtc *crtc,
|
|
|
/* 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)
|
|
|
+ if (ret) {
|
|
|
+ smmu_state->sui_misr_state == NONE;
|
|
|
goto end;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
mutex_lock(&sde_kms->secure_transition_lock);
|
|
@@ -486,7 +519,8 @@ static int _sde_kms_secure_ctrl(struct sde_kms *sde_kms, struct drm_crtc *crtc,
|
|
|
break;
|
|
|
|
|
|
case ATTACH_ALL_REQ:
|
|
|
- ret = _sde_kms_attach_all_cb(sde_kms, VMID_CP_PIXEL);
|
|
|
+ ret = _sde_kms_attach_all_cb(sde_kms, VMID_CP_PIXEL,
|
|
|
+ VMID_CP_SEC_DISPLAY);
|
|
|
if (!ret) {
|
|
|
smmu_state->state = ATTACHED;
|
|
|
smmu_state->secure_level = SDE_DRM_SEC_NON_SEC;
|
|
@@ -503,7 +537,9 @@ static int _sde_kms_secure_ctrl(struct sde_kms *sde_kms, struct drm_crtc *crtc,
|
|
|
break;
|
|
|
|
|
|
case ATTACH_SEC_REQ:
|
|
|
- ret = _sde_kms_attach_sec_cb(sde_kms, VMID_CP_PIXEL);
|
|
|
+ vmid = (smmu_state->secure_level == SDE_DRM_SEC_ONLY) ?
|
|
|
+ VMID_CP_SEC_DISPLAY : VMID_CP_CAMERA_PREVIEW;
|
|
|
+ ret = _sde_kms_attach_sec_cb(sde_kms, VMID_CP_PIXEL, vmid);
|
|
|
if (!ret) {
|
|
|
smmu_state->state = ATTACHED;
|
|
|
smmu_state->secure_level = SDE_DRM_SEC_NON_SEC;
|
|
@@ -527,29 +563,34 @@ static int _sde_kms_secure_ctrl(struct sde_kms *sde_kms, struct drm_crtc *crtc,
|
|
|
}
|
|
|
|
|
|
end:
|
|
|
- smmu_state->sui_misr_state = NONE;
|
|
|
- smmu_state->transition_type = NONE;
|
|
|
smmu_state->transition_error = false;
|
|
|
|
|
|
- /*
|
|
|
- * If switch failed, toggling secure_level is enough since
|
|
|
- * there are only two secure levels - secure/non-secure
|
|
|
- */
|
|
|
if (ret) {
|
|
|
smmu_state->transition_error = true;
|
|
|
+ SDE_ERROR(
|
|
|
+ "crtc%d: req_state %d, new_state %d, sec_lvl %d, ret %d\n",
|
|
|
+ DRMID(crtc), old_smmu_state, smmu_state->state,
|
|
|
+ smmu_state->secure_level, ret);
|
|
|
+
|
|
|
smmu_state->state = smmu_state->prev_state;
|
|
|
- smmu_state->secure_level = !smmu_state->secure_level;
|
|
|
+ smmu_state->secure_level = smmu_state->prev_secure_level;
|
|
|
+
|
|
|
+ if (smmu_state->sui_misr_state == SUI_MISR_ENABLE_REQ)
|
|
|
+ _sde_kms_sui_misr_ctrl(sde_kms, crtc, false);
|
|
|
}
|
|
|
|
|
|
- SDE_DEBUG(
|
|
|
- "crtc %d: old_state %d, req_state %d, new_state %d, sec_lvl %d, ret %d\n",
|
|
|
- DRMID(crtc), smmu_state->prev_state, old_smmu_state,
|
|
|
- smmu_state->state, smmu_state->secure_level, ret);
|
|
|
- SDE_EVT32(DRMID(crtc), smmu_state->prev_state,
|
|
|
- smmu_state->state, smmu_state->transition_type,
|
|
|
- smmu_state->transition_error, smmu_state->secure_level,
|
|
|
+ SDE_DEBUG("crtc %d: req_state %d, new_state %d, sec_lvl %d, ret %d\n",
|
|
|
+ DRMID(crtc), old_smmu_state, smmu_state->state,
|
|
|
+ smmu_state->secure_level, ret);
|
|
|
+ SDE_EVT32(DRMID(crtc), smmu_state->state, smmu_state->prev_state,
|
|
|
+ smmu_state->transition_type,
|
|
|
+ smmu_state->transition_error,
|
|
|
+ smmu_state->secure_level, smmu_state->prev_secure_level,
|
|
|
smmu_state->sui_misr_state, ret, SDE_EVTLOG_FUNC_EXIT);
|
|
|
|
|
|
+ smmu_state->sui_misr_state = NONE;
|
|
|
+ smmu_state->transition_type = NONE;
|
|
|
+
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
@@ -565,6 +606,7 @@ static int sde_kms_prepare_secure_transition(struct msm_kms *kms,
|
|
|
struct drm_device *dev = sde_kms->dev;
|
|
|
int i, ops = 0, ret = 0;
|
|
|
bool old_valid_fb = false;
|
|
|
+ struct sde_kms_smmu_state_data *smmu_state = &sde_kms->smmu_state;
|
|
|
|
|
|
for_each_old_crtc_in_state(state, crtc, old_crtc_state, i) {
|
|
|
if (!crtc->state || !crtc->state->active)
|
|
@@ -601,8 +643,10 @@ static int sde_kms_prepare_secure_transition(struct msm_kms *kms,
|
|
|
return ops;
|
|
|
}
|
|
|
|
|
|
- if (!ops)
|
|
|
+ if (!ops) {
|
|
|
+ smmu_state->transition_error = false;
|
|
|
goto no_ops;
|
|
|
+ }
|
|
|
|
|
|
SDE_DEBUG("%d:secure operations(%x) started on state:%pK\n",
|
|
|
crtc->base.id, ops, crtc->state);
|