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

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

Merge "drm/msm/sde: use secure-direct translation for secure display"

parents ecfe8f4e c5507b7e
Loading
Loading
Loading
Loading
+33 −47
Original line number Diff line number Diff line
@@ -1524,7 +1524,6 @@ static void _sde_crtc_blend_setup(struct drm_crtc *crtc)
static int _sde_crtc_find_plane_fb_modes(struct drm_crtc_state *state,
		uint32_t *fb_ns,
		uint32_t *fb_sec,
		uint32_t *fb_ns_dir,
		uint32_t *fb_sec_dir)
{
	struct drm_plane *plane;
@@ -1540,7 +1539,6 @@ static int _sde_crtc_find_plane_fb_modes(struct drm_crtc_state *state,

	*fb_ns = 0;
	*fb_sec = 0;
	*fb_ns_dir = 0;
	*fb_sec_dir = 0;
	drm_atomic_crtc_state_for_each_plane_state(plane, pstate, state) {
		if (IS_ERR_OR_NULL(pstate)) {
@@ -1560,16 +1558,12 @@ static int _sde_crtc_find_plane_fb_modes(struct drm_crtc_state *state,
		case SDE_DRM_FB_SEC:
			(*fb_sec)++;
			break;
		case SDE_DRM_FB_NON_SEC_DIR_TRANS:
			(*fb_ns_dir)++;
			break;
		case SDE_DRM_FB_SEC_DIR_TRANS:
			(*fb_sec_dir)++;
			break;
		default:
			SDE_ERROR("Error: Plane[%d], fb_trans_mode:%d",
					plane->base.id,
					mode);
					plane->base.id, mode);
			return -EINVAL;
		}
	}
@@ -1593,7 +1587,7 @@ int sde_crtc_get_secure_transition_ops(struct drm_crtc *crtc,
	struct sde_crtc *sde_crtc;
	struct sde_crtc_state *cstate;
	struct sde_crtc_smmu_state_data *smmu_state;
	uint32_t translation_mode = 0;
	uint32_t translation_mode = 0, secure_level;
	int ops  = 0;
	bool post_commit = false;

@@ -1605,10 +1599,10 @@ int sde_crtc_get_secure_transition_ops(struct drm_crtc *crtc,
	sde_crtc = to_sde_crtc(crtc);
	cstate = to_sde_crtc_state(crtc->state);
	smmu_state = &sde_crtc->smmu_state;
	secure_level = sde_crtc_get_secure_level(crtc, crtc->state);

	SDE_DEBUG("crtc%d, secure_level%d\n",
			crtc->base.id,
			sde_crtc_get_secure_level(crtc, crtc->state));
	SDE_DEBUG("crtc%d, secure_level%d old_valid_fb%d\n",
			crtc->base.id, secure_level, old_valid_fb);

	/**
	 * SMMU operations need to be delayed in case of
@@ -1632,8 +1626,7 @@ int sde_crtc_get_secure_transition_ops(struct drm_crtc *crtc,
				PLANE_PROP_FB_TRANSLATION_MODE);
		if (translation_mode > SDE_DRM_FB_SEC_DIR_TRANS) {
			SDE_ERROR("crtc%d, invalid translation_mode%d\n",
					crtc->base.id,
					translation_mode);
					crtc->base.id, translation_mode);
			return -EINVAL;
		}

@@ -1641,14 +1634,15 @@ int sde_crtc_get_secure_transition_ops(struct drm_crtc *crtc,
		 * we can break if we find sec_fir or non_sec_dir
		 * plane
		 */
		if ((translation_mode == SDE_DRM_FB_NON_SEC_DIR_TRANS) ||
			(translation_mode == SDE_DRM_FB_SEC_DIR_TRANS))
		if (translation_mode == SDE_DRM_FB_SEC_DIR_TRANS)
			break;
	}

	switch (translation_mode) {
	case SDE_DRM_FB_NON_SEC_DIR_TRANS:
		if (smmu_state->state == ATTACHED) {
	case SDE_DRM_FB_SEC_DIR_TRANS:
		/* secure display usecase */
		if ((smmu_state->state == ATTACHED) &&
				(secure_level == SDE_DRM_SEC_ONLY)) {
			smmu_state->state = DETACH_ALL_REQ;
			smmu_state->transition_type = PRE_COMMIT;
			ops |= SDE_KMS_OPS_CRTC_SECURE_STATE_CHANGE;
@@ -1656,10 +1650,8 @@ 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);
			}
		}
		break;
	case SDE_DRM_FB_SEC_DIR_TRANS:
		if (smmu_state->state == ATTACHED) {
		/* secure camera usecase */
		} else if (smmu_state->state == ATTACHED) {
			smmu_state->state = DETACH_SEC_REQ;
			smmu_state->transition_type = PRE_COMMIT;
			ops |= SDE_KMS_OPS_CRTC_SECURE_STATE_CHANGE;
@@ -1667,14 +1659,18 @@ int sde_crtc_get_secure_transition_ops(struct drm_crtc *crtc,
		break;
	case SDE_DRM_FB_SEC:
	case SDE_DRM_FB_NON_SEC:
		if (smmu_state->state == DETACHED_SEC) {
		if ((smmu_state->state == DETACHED_SEC) ||
			(smmu_state->state == DETACH_SEC_REQ)) {
			smmu_state->state = ATTACH_SEC_REQ;
			smmu_state->transition_type = post_commit ?
				POST_COMMIT : PRE_COMMIT;
			ops |= SDE_KMS_OPS_CRTC_SECURE_STATE_CHANGE;
			if (translation_mode == SDE_DRM_FB_SEC)
				ops |= SDE_KMS_OPS_PREPARE_PLANE_FB;
		} else if (smmu_state->state == DETACHED) {
			if (old_valid_fb)
				ops |= SDE_KMS_OPS_WAIT_FOR_TX_DONE;
		} else if ((smmu_state->state == DETACHED) ||
				(smmu_state->state == DETACH_ALL_REQ)) {
			smmu_state->state = ATTACH_ALL_REQ;
			smmu_state->transition_type = post_commit ?
				POST_COMMIT : PRE_COMMIT;
@@ -1686,15 +1682,13 @@ int sde_crtc_get_secure_transition_ops(struct drm_crtc *crtc,
		}
		break;
	default:
		SDE_ERROR("invalid plane fb_mode:%d\n",
				translation_mode);
		SDE_ERROR("invalid plane fb_mode:%d\n", translation_mode);
		ops = 0;
		return -EINVAL;
	}

	SDE_DEBUG("SMMU State:%d, type:%d ops:%x\n", smmu_state->state,
			smmu_state->transition_type,
			ops);
			smmu_state->transition_type, ops);
	return ops;
}

@@ -1722,13 +1716,13 @@ static int _sde_crtc_scm_call(int vmid)
	 */
	sec_sid[0] = SEC_SID_MASK_0;
	sec_sid[1] = SEC_SID_MASK_1;
	dmac_flush_range(&sec_sid, &sec_sid + num_sids);
	dmac_flush_range(sec_sid, sec_sid + num_sids);

	SDE_DEBUG("calling scm_call for vmid %d", vmid);

	desc.arginfo = SCM_ARGS(4, SCM_VAL, SCM_RW, SCM_VAL, SCM_VAL);
	desc.args[0] = MDP_DEVICE_ID;
	desc.args[1] = SCM_BUFFER_PHYS(&sec_sid);
	desc.args[1] = SCM_BUFFER_PHYS(sec_sid);
	desc.args[2] = sizeof(uint32_t) * num_sids;
	desc.args[3] =  vmid;

@@ -1736,8 +1730,7 @@ static int _sde_crtc_scm_call(int vmid)
				mem_protect_sd_ctrl_id), &desc);
	if (ret) {
		SDE_ERROR("Error:scm_call2, vmid (%lld): ret%d\n",
				desc.args[3],
				ret);
				desc.args[3], ret);
	}

	kfree(sec_sid);
@@ -1780,7 +1773,6 @@ int sde_crtc_secure_ctrl(struct drm_crtc *crtc, bool post_commit)
		/* Bail out */
		return 0;


	/* Secure UI use case enable */
	switch (smmu_state->state) {
	case DETACH_ALL_REQ:
@@ -1856,11 +1848,10 @@ int sde_crtc_secure_ctrl(struct drm_crtc *crtc, bool post_commit)
	SDE_DEBUG("crtc: %d, old_state %d new_state %d\n", crtc->base.id,
			old_smmu_state,
			smmu_state->state);
	smmu_state->transition_error = false;
	smmu_state->transition_type = NONE;

error:
	smmu_state->transition_error = true;
	smmu_state->transition_error = ret ? true : false;
	return ret;
}

@@ -2573,7 +2564,7 @@ static void sde_crtc_atomic_begin(struct drm_crtc *crtc,
	 * apply color processing properties only if
	 * smmu state is attached,
	 */
	if ((smmu_state->state != DETACHED) ||
	if ((smmu_state->state != DETACHED) &&
			(smmu_state->state != DETACH_ALL_REQ))
		sde_cp_crtc_apply_properties(crtc);

@@ -3416,7 +3407,7 @@ static int _sde_crtc_check_secure_state(struct drm_crtc *crtc,
	struct drm_encoder *encoder;
	struct sde_crtc_state *cstate;
	uint32_t secure;
	uint32_t fb_ns = 0, fb_sec = 0, fb_ns_dir = 0, fb_sec_dir = 0;
	uint32_t fb_ns = 0, fb_sec = 0, fb_sec_dir = 0;
	int encoder_cnt = 0;
	int rc;

@@ -3433,26 +3424,21 @@ static int _sde_crtc_check_secure_state(struct drm_crtc *crtc,
	rc = _sde_crtc_find_plane_fb_modes(state,
			&fb_ns,
			&fb_sec,
			&fb_ns_dir,
			&fb_sec_dir);
	if (rc)
		return rc;

	/**
	 * validate planes
	 * fb_ns_dir is for  secure display use case,
	 * fb_sec_dir is for secure camera preview use case,
	 * fb_sec_dir is for secure camera preview and secure display  use case,
	 * fb_sec is for secure video playback,
	 * fb_ns is for normal non secure use cases.
	 */
	if (((secure == SDE_DRM_SEC_ONLY) &&
				(fb_ns || fb_sec || fb_sec_dir)) ||
			(fb_sec && fb_sec_dir)) {
	if ((secure == SDE_DRM_SEC_ONLY) &&
			(fb_ns || fb_sec || (fb_sec && fb_sec_dir))) {
		SDE_ERROR(
			"crtc%d: invalid planes fb_modes Sec:%d, NS:%d, Sec_Dir:%d, NS_Dir%d\n",
				crtc->base.id,
				fb_sec, fb_ns, fb_sec_dir,
				fb_ns_dir);
		"crtc%d: invalid planes fb_modes Sec:%d, NS:%d, Sec_Dir:%d\n",
				crtc->base.id, fb_sec, fb_ns, fb_sec_dir);
		return -EINVAL;
	}

@@ -3460,7 +3446,7 @@ static int _sde_crtc_check_secure_state(struct drm_crtc *crtc,
	 * secure_crtc is not allowed in a shared toppolgy
	 * across different encoders.
	 */
	if (fb_ns_dir || fb_sec_dir) {
	if (fb_sec_dir) {
		drm_for_each_encoder(encoder, crtc->dev)
			if (encoder->crtc ==  crtc)
				encoder_cnt++;
+10 −10
Original line number Diff line number Diff line
@@ -422,19 +422,19 @@ static void sde_hw_sspp_setup_secure(struct sde_hw_pipe *ctx,
	if (_sspp_subblk_offset(ctx, SDE_SSPP_SRC, &idx))
		return;

	if (rect_mode == SDE_SSPP_RECT_SOLO || rect_mode == SDE_SSPP_RECT_0)
		secure_bit_mask = (rect_mode == SDE_SSPP_RECT_SOLO) ? 0xF :
			0x5;
	c = &ctx->hw;

	if (enable) {
		if ((rect_mode == SDE_SSPP_RECT_SOLO)
				|| (rect_mode == SDE_SSPP_RECT_0))
			secure_bit_mask =
				(rect_mode == SDE_SSPP_RECT_SOLO) ? 0xF : 0x5;
		else
			secure_bit_mask = 0xA;

	c = &ctx->hw;

		secure = SDE_REG_READ(c, SSPP_SRC_ADDR_SW_STATUS + idx);
	if (enable)
		secure |= secure_bit_mask;
	else
		secure &= ~secure_bit_mask;
	}

	SDE_REG_WRITE(c, SSPP_SRC_ADDR_SW_STATUS + idx, secure);
}
+12 −1
Original line number Diff line number Diff line
@@ -878,7 +878,6 @@ static int _sde_plane_get_aspace(
			return -EINVAL;
		break;
	case SDE_DRM_FB_SEC_DIR_TRANS:
	case SDE_DRM_FB_NON_SEC_DIR_TRANS:
		*aspace = NULL;
		break;
	default:
@@ -2791,6 +2790,18 @@ static int sde_plane_prepare_fb(struct drm_plane *plane,
	new_rstate = &to_sde_plane_state(new_state)->rot;

	if (pstate->aspace) {
		/*
		 * when transitioning from secure to non-secure,
		 * plane->prepare_fb happens before the commit. In such case,
		 * return early, as prepare_fb would be handled as part
		 * of the transition after attaching the domains,
		 * during the commit
		 */
		if (!pstate->aspace->domain_attached) {
			SDE_DEBUG_PLANE(psde,
			    "domain not attached, prepare_fb handled later\n");
			return 0;
		}
		ret = msm_framebuffer_prepare(new_rstate->out_fb,
				pstate->aspace);
		if (ret) {
+1 −0
Original line number Diff line number Diff line
@@ -157,6 +157,7 @@ struct sde_smmu_client {
	struct reg_bus_client *reg_bus_clt;
	bool domain_attached;
	int domain;
	u32 sid;
};

/*
+14 −13
Original line number Diff line number Diff line
@@ -45,18 +45,12 @@
/* Rotator device id to be used in SCM call */
#define SDE_ROTATOR_DEVICE	21

#ifndef VMID_CP_CAMERA_PREVIEW
#define VMID_CP_CAMERA_PREVIEW	VMID_INVAL
#endif

/* SCM call function id to be used for switching between secure and non
/*
 * SCM call function id to be used for switching between secure and non
 * secure context
 */
#define MEM_PROTECT_SD_CTRL_SWITCH 0x18

/* Rotator secure SID */
#define SDE_ROTATOR_SECURE_SID  0xe01

/* waiting for hw time out, 3 vsync for 30fps*/
#define ROT_HW_ACQUIRE_TIMEOUT_IN_MS 100

@@ -601,7 +595,7 @@ static int sde_rotator_secure_session_ctrl(bool enable)

	if (test_bit(SDE_CAPS_SEC_ATTACH_DETACH_SMMU,
		mdata->sde_caps_map)) {
		sid_info = SDE_ROTATOR_SECURE_SID;
		sid_info = mdata->sde_smmu[SDE_IOMMU_DOMAIN_ROT_SECURE].sid;
		desc.arginfo = SCM_ARGS(4, SCM_VAL, SCM_RW, SCM_VAL, SCM_VAL);
		desc.args[0] = SDE_ROTATOR_DEVICE;
		desc.args[1] = SCM_BUFFER_PHYS(&sid_info);
@@ -631,9 +625,12 @@ static int sde_rotator_secure_session_ctrl(bool enable)
				return -EINVAL;
			}

			SDEROT_DBG("scm_call(1) ret=%d, resp=%x",
			SDEROT_DBG(
			  "scm(1) sid0x%x dev0x%llx vmid0x%llx ret%d resp%x\n",
				sid_info, desc.args[0], desc.args[3],
				ret, resp);
			SDEROT_EVTLOG(1, sid_info, desc.args[0], desc.args[3],
					ret, resp);
			SDEROT_EVTLOG(1);
		} else if (mdata->sec_cam_en && !enable) {
			/*
			 * Disable secure camera operation
@@ -648,12 +645,16 @@ static int sde_rotator_secure_session_ctrl(bool enable)
				MEM_PROTECT_SD_CTRL_SWITCH), &desc);
			resp = desc.ret[0];

			SDEROT_DBG("scm_call(0): ret=%d, resp=%x",
			SDEROT_DBG(
			  "scm(0) sid0x%x dev0x%llx vmid0x%llx ret%d resp%d\n",
				sid_info, desc.args[0], desc.args[3],
				ret, resp);

			/* force smmu to reattach */
			sde_smmu_secure_ctrl(1);
			SDEROT_EVTLOG(0);

			SDEROT_EVTLOG(0, sid_info, desc.args[0], desc.args[3],
					ret, resp);
		}
	} else {
		return 0;
Loading