Selaa lähdekoodia

Merge "disp: msm: sde: handle all error cases during sui transitions"

qctecmdr 5 vuotta sitten
vanhempi
sitoutus
fba0fc0b11
3 muutettua tiedostoa jossa 91 lisäystä ja 44 poistoa
  1. 1 0
      msm/sde/sde_crtc.c
  2. 88 44
      msm/sde/sde_kms.c
  3. 2 0
      msm/sde/sde_kms.h

+ 1 - 0
msm/sde/sde_crtc.c

@@ -1783,6 +1783,7 @@ int sde_crtc_get_secure_transition_ops(struct drm_crtc *crtc,
 
 	smmu_state = &sde_kms->smmu_state;
 	smmu_state->prev_state = smmu_state->state;
+	smmu_state->prev_secure_level = smmu_state->secure_level;
 
 	sde_crtc = to_sde_crtc(crtc);
 	secure_level = sde_crtc_get_secure_level(crtc, crtc->state);

+ 88 - 44
msm/sde/sde_kms.c

@@ -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);

+ 2 - 0
msm/sde/sde_kms.h

@@ -189,6 +189,7 @@ enum frame_trigger_mode_type {
  * @state: current state of smmu context banks
  * @prev_state: previous state of smmu context banks
  * @secure_level: secure level cached from crtc
+ * @prev_secure_level: previous secure level
  * @transition_type: transition request type
  * @transition_error: whether there is error while transitioning the state
  */
@@ -196,6 +197,7 @@ struct sde_kms_smmu_state_data {
 	uint32_t state;
 	uint32_t prev_state;
 	uint32_t secure_level;
+	uint32_t prev_secure_level;
 	uint32_t transition_type;
 	uint32_t transition_error;
 	uint32_t sui_misr_state;