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

Commit 785a7ae1 authored by Dhaval Patel's avatar Dhaval Patel
Browse files

msm: mdss: add secure display support



Secure display architecture requires null commit
before and after secure display session. It
also adds requirement to make the SCM call before
and after secure display session. It supports secure
display with single-stage SMMU hypervisor controlled.

Change-Id: I3f41ed318c80d6e76328de114f7dee0c9891c2f0
Signed-off-by: default avatarDhaval Patel <pdhaval@codeaurora.org>
parent 55bc7ff0
Loading
Loading
Loading
Loading
+40 −1
Original line number Diff line number Diff line
@@ -445,6 +445,8 @@ static int __configure_pipe_params(struct msm_fb_data_type *mfd,
		pipe->flags |= MDP_FLIP_UD;
	if (layer->flags & MDP_LAYER_SECURE_SESSION)
		pipe->flags |= MDP_SECURE_OVERLAY_SESSION;
	if (layer->flags & MDP_LAYER_SECURE_DISPLAY_SESSION)
		pipe->flags |= MDP_SECURE_DISPLAY_OVERLAY_SESSION;
	if (layer->flags & MDP_LAYER_SOLID_FILL)
		pipe->flags |= MDP_SOLID_FILL;
	if (layer->flags & MDP_LAYER_DEINTERLACE)
@@ -813,7 +815,8 @@ static struct mdss_mdp_data *__map_layer_buffer(struct msm_fb_data_type *mfd,
		goto end;
	}

	flags = (pipe->flags & MDP_SECURE_OVERLAY_SESSION);
	flags = (pipe->flags & (MDP_SECURE_OVERLAY_SESSION |
				MDP_SECURE_DISPLAY_OVERLAY_SESSION));

	/* current implementation only supports one plane mapping */
	if (buffer->planes[0].fd < 0) {
@@ -977,6 +980,40 @@ end:
	return pipe;
}

/*
 * __validate_secure_display() - validate secure display
 *
 * This function travers through used pipe list and checks if any pipe
 * is with secure display enabled flag. It fails if client tries to stage
 * unsecure content with secure display session.
 *
 */
static int __validate_secure_display(struct mdss_overlay_private *mdp5_data)
{
	struct mdss_mdp_pipe *pipe, *tmp;
	uint32_t sd_pipes = 0, nonsd_pipes = 0;

	mutex_lock(&mdp5_data->list_lock);
	list_for_each_entry_safe(pipe, tmp, &mdp5_data->pipes_used, list) {
		if (pipe->flags & MDP_SECURE_DISPLAY_OVERLAY_SESSION)
			sd_pipes++;
		else
			nonsd_pipes++;
	}
	mutex_unlock(&mdp5_data->list_lock);

	pr_debug("pipe count:: secure display:%d non-secure:%d\n",
		sd_pipes, nonsd_pipes);

	if (sd_pipes && nonsd_pipes) {
		pr_err("pipe count:: secure display:%d non-secure:%d\n",
			sd_pipes, nonsd_pipes);
		return -EINVAL;
	} else {
		return 0;
	}
}

/*
 * __handle_free_list() - updates free pipe list
 *
@@ -1208,6 +1245,8 @@ static int __validate_layers(struct msm_fb_data_type *mfd,

	__handle_free_list(mdp5_data, layer_list, layer_count);

	ret = __validate_secure_display(mdp5_data);

validate_exit:
	pr_debug("err=%d total_layer:%d left:%d right:%d release_ndx=0x%x processed=%d\n",
		ret, layer_count, left_lm_layers, right_lm_layers,
+21 −17
Original line number Diff line number Diff line
@@ -1851,17 +1851,17 @@ int mdss_mdp_overlay_kickoff(struct msm_fb_data_type *mfd,
					pipe->num, pipe->flags);
		}
	}

	/*
	 * If there is no secure display session and sd_enabled, disable the
	 * secure display session
	 * start secure display session if there is secure display session and
	 * sd_enabled is not true.
	 */
	if (!sd_in_pipe && mdp5_data->sd_enabled) {
		/* disable the secure display on last client */
		if (mdss_get_sd_client_cnt() == 1)
			ret = mdss_mdp_secure_display_ctrl(0);
	if (!mdp5_data->sd_enabled && sd_in_pipe) {
		if (!mdss_get_sd_client_cnt())
			ret = mdss_mdp_secure_display_ctrl(1);
		if (!ret) {
			mdss_update_sd_client(mdp5_data->mdata, false);
			mdp5_data->sd_enabled = 0;
			mdp5_data->sd_enabled = 1;
			mdss_update_sd_client(mdp5_data->mdata, true);
		}
	}

@@ -1933,14 +1933,17 @@ int mdss_mdp_overlay_kickoff(struct msm_fb_data_type *mfd,
	ATRACE_END("display_wait4comp");
	mutex_lock(&mdp5_data->ov_lock);

	if (ret == 0) {
		if (!mdp5_data->sd_enabled && sd_in_pipe) {
			if (!mdss_get_sd_client_cnt())
				ret = mdss_mdp_secure_display_ctrl(1);
	/*
	 * If there is no secure display session and sd_enabled, disable the
	 * secure display session
	 */
	if (mdp5_data->sd_enabled && !sd_in_pipe && !ret) {
		/* disable the secure display on last client */
		if (mdss_get_sd_client_cnt() == 1)
			ret = mdss_mdp_secure_display_ctrl(0);
		if (!ret) {
				mdp5_data->sd_enabled = 1;
				mdss_update_sd_client(mdp5_data->mdata, true);
			}
			mdss_update_sd_client(mdp5_data->mdata, false);
			mdp5_data->sd_enabled = 0;
		}
	}

@@ -2142,7 +2145,8 @@ static int mdss_mdp_overlay_queue(struct msm_fb_data_type *mfd,
	if (pipe->flags & MDP_SOLID_FILL)
		pr_warn("Unexpected buffer queue to a solid fill pipe\n");

	flags = (pipe->flags & MDP_SECURE_OVERLAY_SESSION);
	flags = (pipe->flags & (MDP_SECURE_OVERLAY_SESSION |
		MDP_SECURE_DISPLAY_OVERLAY_SESSION));

	mutex_lock(&mdp5_data->list_lock);
	src_data = mdss_mdp_overlay_buf_alloc(mfd, pipe);
+54 −3
Original line number Diff line number Diff line
@@ -30,6 +30,8 @@
#include "mdss_smmu.h"
#include "mdss_panel.h"

#define PHY_ADDR_4G (1ULL<<32)

enum {
	MDP_INTR_VSYNC_INTF_0,
	MDP_INTR_VSYNC_INTF_1,
@@ -965,7 +967,12 @@ static int mdss_mdp_put_img(struct mdss_mdp_img_data *data, bool rotator,
				data->srcp_dma_buf = NULL;
			}
		}

	} else if (data->flags & MDP_SECURE_DISPLAY_OVERLAY_SESSION) {
		/*
		 * skip memory unmapping - secure display uses physical
		 * address which does not require buffer unmapping
		 */
		pr_debug("skip memory unmapping for secure display content\n");
	} else {
		return -ENOMEM;
	}
@@ -1007,7 +1014,8 @@ static int mdss_mdp_get_img(struct msmfb_data *img,
			pr_err("invalid FB_MAJOR\n");
			ret = -1;
		}
	} else if (iclient) {
	} else if (iclient &&
			!(data->flags & MDP_SECURE_DISPLAY_OVERLAY_SESSION)) {
		data->srcp_dma_buf = dma_buf_get(img->memory_id);
		if (IS_ERR(data->srcp_dma_buf)) {
			pr_err("error on ion_import_fd\n");
@@ -1038,6 +1046,48 @@ static int mdss_mdp_get_img(struct msmfb_data *img,
		/* return early, mapping will be done later */

		return 0;
	} else if (iclient &&
			(data->flags & MDP_SECURE_DISPLAY_OVERLAY_SESSION)) {
		struct ion_handle *ihandle = NULL;
		struct sg_table *sg_ptr = NULL;

		do {
			ihandle = ion_import_dma_buf(iclient, img->memory_id);
			if (IS_ERR_OR_NULL(ihandle)) {
				ret = -EINVAL;
				pr_err("ion import buffer failed\n");
				break;
			}

			sg_ptr = ion_sg_table(iclient, ihandle);
			if (sg_ptr == NULL) {
				pr_err("ion sg table get failed\n");
				ret = -EINVAL;
				break;
			}

			if (sg_ptr->nents != 1) {
				pr_err("ion buffer mapping failed\n");
				ret = -EINVAL;
				break;
			}

			if (((uint64_t)sg_dma_address(sg_ptr->sgl) >=
					PHY_ADDR_4G - sg_ptr->sgl->length)) {
				pr_err("ion buffer mapped size is invalid\n");
				ret = -EINVAL;
				break;
			}

			data->addr = sg_dma_address(sg_ptr->sgl);
			data->len = sg_ptr->sgl->length;
			data->mapped = true;
			ret = 0;
		} while (0);

		if (!IS_ERR_OR_NULL(ihandle))
			ion_free(iclient, ihandle);
		return ret;
	}

	if (!*start) {
@@ -1075,7 +1125,8 @@ static int mdss_mdp_map_buffer(struct mdss_mdp_img_data *data, bool rotator,
		return 0;

	if (!IS_ERR_OR_NULL(data->srcp_dma_buf)) {
		if (mdss_res->mdss_util->iommu_attached()) {
		if (mdss_res->mdss_util->iommu_attached() &&
			!(data->flags & MDP_SECURE_DISPLAY_OVERLAY_SESSION)) {
			domain = mdss_smmu_get_domain_type(data->flags,
					rotator);
			ret = mdss_smmu_map_dma_buf(data->srcp_dma_buf,
+3 −0
Original line number Diff line number Diff line
@@ -62,6 +62,9 @@ LAYER FLAG CONFIGURATION
/* layer contains postprocessing configuration data */
#define MDP_LAYER_PP			0x200

/* Flag indicates that layer is associated with secure display session */
#define MDP_LAYER_SECURE_DISPLAY_SESSION 0x400

/**********************************************************************
VALIDATE/COMMIT FLAG CONFIGURATION
**********************************************************************/