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

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

Merge "msm: mdss: add secure display support"

parents 2e464690 785a7ae1
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
@@ -1854,17 +1854,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);
		}
	}

@@ -1936,14 +1936,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;
		}
	}

@@ -2145,7 +2148,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");
@@ -1039,6 +1047,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) {
@@ -1076,7 +1126,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
**********************************************************************/