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

Commit 7c9a3efa authored by Abhijit Kulkarni's avatar Abhijit Kulkarni
Browse files

msm: mdss: Enable secure display and camera feature for msmcobalt



Add support for secure display and camera in driver. The physical address
of the secure buffers is programmed into driver and hence there is no
need of stage 1 translation. These changes handle the detach/attach of
smmu contexts while going into and coming out of secure use case.
For secure display both the secure and unsecure contexts are detached,
while for secure camera only the secure context is detached.

CRs-Fixed: 1085143
Change-Id: Iadab43e9655a9e97cdc6661c17a73891cbc2a17f
Signed-off-by: default avatarAbhijit Kulkarni <kabhijit@codeaurora.org>
parent f7768d33
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -178,6 +178,7 @@ enum mdss_hw_capabilities {
	MDSS_CAPS_CWB_SUPPORTED,
	MDSS_CAPS_MDP_VOTE_CLK_NOT_SUPPORTED,
	MDSS_CAPS_AVR_SUPPORTED,
	MDSS_CAPS_SEC_DETACH_SMMU,
	MDSS_CAPS_MAX,
};

@@ -221,6 +222,7 @@ struct mdss_smmu_client {
	bool domain_attached;
	bool handoff_pending;
	void __iomem *mmu_base;
	int domain;
};

struct mdss_mdp_qseed3_lut_tbl {
@@ -327,6 +329,7 @@ struct mdss_data_type {
	u32 wfd_mode;
	u32 has_no_lut_read;
	atomic_t sd_client_count;
	atomic_t sc_client_count;
	u8 has_wb_ad;
	u8 has_non_scalar_rgb;
	bool has_src_split;
@@ -519,6 +522,8 @@ struct mdss_data_type {
	u32 max_dest_scaler_input_width;
	u32 max_dest_scaler_output_width;
	struct mdss_mdp_destination_scaler *ds;
	u32 sec_disp_en;
	u32 sec_cam_en;
};

extern struct mdss_data_type *mdss_res;
@@ -579,6 +584,14 @@ static inline int mdss_get_sd_client_cnt(void)
		return atomic_read(&mdss_res->sd_client_count);
}

static inline int mdss_get_sc_client_cnt(void)
{
	if (!mdss_res)
		return 0;
	else
		return atomic_read(&mdss_res->sc_client_count);
}

static inline void mdss_set_quirk(struct mdss_data_type *mdata,
	enum mdss_hw_quirk bit)
{
+107 −12
Original line number Diff line number Diff line
@@ -47,6 +47,8 @@
#include <linux/msm-bus-board.h>
#include <soc/qcom/scm.h>
#include <soc/qcom/rpm-smd.h>
#include "soc/qcom/secure_buffer.h"
#include <asm/cacheflush.h>

#include "mdss.h"
#include "mdss_fb.h"
@@ -64,6 +66,8 @@
#define RES_1080p		(1088*1920)
#define RES_UHD			(3840*2160)

#define MDP_DEVICE_ID		0x1A

struct mdss_data_type *mdss_res;
static u32 mem_protect_sd_ctrl_id;

@@ -87,6 +91,7 @@ struct msm_mdp_interface mdp5 = {

#define MEM_PROTECT_SD_CTRL 0xF
#define MEM_PROTECT_SD_CTRL_FLAT 0x14
#define MEM_PROTECT_SD_CTRL_SWITCH 0x18

static DEFINE_SPINLOCK(mdp_lock);
static DEFINE_SPINLOCK(mdss_mdp_intr_lock);
@@ -1329,7 +1334,9 @@ int mdss_iommu_ctrl(int enable)
			if (mdata->iommu_ref_cnt == 0) {
				rc = mdss_smmu_detach(mdata);
				if (mdss_has_quirk(mdata,
					MDSS_QUIRK_MIN_BUS_VOTE))
					MDSS_QUIRK_MIN_BUS_VOTE) &&
					(!mdata->sec_disp_en ||
					 !mdata->sec_cam_en))
					mdss_bus_scale_set_quota(MDSS_HW_RT,
								0, 0);
			}
@@ -1985,6 +1992,7 @@ static void mdss_mdp_hw_rev_caps_init(struct mdss_data_type *mdata)
		mdata->pixel_ram_size = 50 * 1024;
		mdata->rects_per_sspp[MDSS_MDP_PIPE_TYPE_DMA] = 2;

		mem_protect_sd_ctrl_id = MEM_PROTECT_SD_CTRL_SWITCH;
		set_bit(MDSS_QOS_PER_PIPE_IB, mdata->mdss_qos_map);
		set_bit(MDSS_QOS_REMAPPER, mdata->mdss_qos_map);
		set_bit(MDSS_QOS_TS_PREFILL, mdata->mdss_qos_map);
@@ -2015,6 +2023,7 @@ static void mdss_mdp_hw_rev_caps_init(struct mdss_data_type *mdata)
		mdata->has_wb_ubwc = true;
		set_bit(MDSS_CAPS_10_BIT_SUPPORTED, mdata->mdss_caps_map);
		set_bit(MDSS_CAPS_AVR_SUPPORTED, mdata->mdss_caps_map);
		set_bit(MDSS_CAPS_SEC_DETACH_SMMU, mdata->mdss_caps_map);
		break;
	default:
		mdata->max_target_zorder = 4; /* excluding base layer */
@@ -4939,29 +4948,115 @@ static void mdss_mdp_footswitch_ctrl(struct mdss_data_type *mdata, int on)
	}
}

int mdss_mdp_secure_display_ctrl(unsigned int enable)
int mdss_mdp_secure_session_ctrl(unsigned int enable, u64 flags)
{
	struct mdss_data_type *mdata = mdss_mdp_get_mdata();
	struct sd_ctrl_req {
		unsigned int enable;
	} __attribute__ ((__packed__)) request;
	unsigned int resp = -1;
	int ret = 0;
	uint32_t sid_info;
	struct scm_desc desc;

	if (test_bit(MDSS_CAPS_SEC_DETACH_SMMU, mdata->mdss_caps_map)) {
		/*
		 * Prepare syscall to hypervisor to switch the secure_vmid
		 * between secure and non-secure contexts
		 */
		/* MDP secure SID */
		sid_info = 0x1;
		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(&sid_info);
		desc.args[2] = sizeof(uint32_t);


		pr_debug("Enable/Disable: %d, Flags %llx\n", enable, flags);
		if (enable) {
			if (flags & MDP_SECURE_DISPLAY_OVERLAY_SESSION) {
				desc.args[3] = VMID_CP_SEC_DISPLAY;
				mdata->sec_disp_en = 1;
			} else if (flags & MDP_SECURE_CAMERA_OVERLAY_SESSION) {
				desc.args[3] = VMID_CP_CAMERA_PREVIEW;
				mdata->sec_cam_en = 1;
			} else {
				return 0;
			}

			/* detach smmu contexts */
			ret = mdss_smmu_detach(mdata);
			if (ret) {
				pr_err("Error while detaching smmu contexts ret = %d\n",
					ret);
				return -EINVAL;
			}

			/* let the driver think smmu is still attached */
			mdata->iommu_attached = true;

			dmac_flush_range(&sid_info, &sid_info + 1);
			ret = scm_call2(SCM_SIP_FNID(SCM_SVC_MP,
				mem_protect_sd_ctrl_id), &desc);
			if (ret) {
				pr_err("Error scm_call MEM_PROTECT_SD_CTRL(%u) ret=%dm resp=%x\n",
						enable, ret, resp);
				return -EINVAL;
			}
			resp = desc.ret[0];

			pr_debug("scm_call MEM_PROTECT_SD_CTRL(%u): ret=%d, resp=%x\n",
					enable, ret, resp);
		} else {
			desc.args[3] = VMID_CP_PIXEL;
			if (flags & MDP_SECURE_DISPLAY_OVERLAY_SESSION)
				mdata->sec_disp_en = 0;
			else if (flags & MDP_SECURE_CAMERA_OVERLAY_SESSION)
				mdata->sec_cam_en = 0;

			dmac_flush_range(&sid_info, &sid_info + 1);
			ret = scm_call2(SCM_SIP_FNID(SCM_SVC_MP,
				mem_protect_sd_ctrl_id), &desc);
			if (ret)
				MDSS_XLOG_TOUT_HANDLER("mdp", "dsi0_ctrl",
						"dsi0_phy", "dsi1_ctrl",
						"dsi1_phy", "vbif", "vbif_nrt",
						"dbg_bus", "vbif_dbg_bus",
						"panic");
			resp = desc.ret[0];

			pr_debug("scm_call MEM_PROTECT_SD_CTRL(%u): ret=%d, resp=%x\n",
					enable, ret, resp);

			/* re-attach smmu contexts */
			mdata->iommu_attached = false;
			ret = mdss_smmu_attach(mdata);
			if (ret) {
				pr_err("Error while attaching smmu contexts ret = %d\n",
					ret);
				return -EINVAL;
			}
		}
		MDSS_XLOG(enable);
	} else {
		desc.args[0] = request.enable = enable;
		desc.arginfo = SCM_ARGS(1);

		if (!is_scm_armv8()) {
			ret = scm_call(SCM_SVC_MP, MEM_PROTECT_SD_CTRL,
			&request, sizeof(request), &resp, sizeof(resp));
					&request,
					sizeof(request),
					&resp,
					sizeof(resp));
		} else {
			ret = scm_call2(SCM_SIP_FNID(SCM_SVC_MP,
						mem_protect_sd_ctrl_id), &desc);
			resp = desc.ret[0];
		}

	pr_debug("scm_call MEM_PROTECT_SD_CTRL(%u): ret=%d, resp=%x",
		pr_debug("scm_call MEM_PROTECT_SD_CTRL(%u): ret=%d, resp=%x\n",
				enable, ret, resp);
	}
	if (ret)
		return ret;

+22 −5
Original line number Diff line number Diff line
@@ -92,6 +92,8 @@
 */
#define ENABLE_PIXEL_EXT_ONLY 0x80000000

/* Pipe flag to indicate this pipe contains secure camera buffer */
#define MDP_SECURE_CAMERA_OVERLAY_SESSION 0x100000000
/**
 * Destination Scaler control flags setting
 *
@@ -627,7 +629,7 @@ struct mdss_mdp_img_data {
	dma_addr_t addr;
	unsigned long len;
	u32 offset;
	u32 flags;
	u64 flags;
	u32 dir;
	u32 domain;
	bool mapped;
@@ -811,7 +813,7 @@ struct mdss_mdp_pipe {
	struct file *file;
	bool is_handed_off;

	u32 flags;
	u64 flags;
	u32 bwc_mode;

	/* valid only when pipe's output is crossing both layer mixers */
@@ -916,6 +918,7 @@ struct mdss_overlay_private {
	u32 splash_mem_addr;
	u32 splash_mem_size;
	u32 sd_enabled;
	u32 sc_enabled;

	struct sw_sync_timeline *vsync_timeline;
	struct mdss_mdp_vsync_handler vsync_retire_handler;
@@ -1289,6 +1292,15 @@ static inline void mdss_update_sd_client(struct mdss_data_type *mdata,
		atomic_add_unless(&mdss_res->sd_client_count, -1, 0);
}

static inline void mdss_update_sc_client(struct mdss_data_type *mdata,
							bool status)
{
	if (status)
		atomic_inc(&mdata->sc_client_count);
	else
		atomic_add_unless(&mdss_res->sc_client_count, -1, 0);
}

static inline int mdss_mdp_get_wb_ctl_support(struct mdss_data_type *mdata,
							bool rotator_session)
{
@@ -1506,6 +1518,7 @@ static inline bool mdss_mdp_is_map_needed(struct mdss_data_type *mdata,
						struct mdss_mdp_img_data *data)
{
	u32 is_secure_ui = data->flags & MDP_SECURE_DISPLAY_OVERLAY_SESSION;
	u64 is_secure_camera = data->flags & MDP_SECURE_CAMERA_OVERLAY_SESSION;

     /*
      * For ULT Targets we need SMMU Map, to issue map call for secure Display.
@@ -1513,6 +1526,10 @@ static inline bool mdss_mdp_is_map_needed(struct mdss_data_type *mdata,
	if (is_secure_ui && !mdss_has_quirk(mdata, MDSS_QUIRK_NEED_SECURE_MAP))
		return false;

	if (is_secure_camera && test_bit(MDSS_CAPS_SEC_DETACH_SMMU,
				mdata->mdss_caps_map))
		return false;

	return true;
}

@@ -1569,7 +1586,7 @@ unsigned long mdss_mdp_get_clk_rate(u32 clk_idx, bool locked);
int mdss_mdp_vsync_clk_enable(int enable, bool locked);
void mdss_mdp_clk_ctrl(int enable);
struct mdss_data_type *mdss_mdp_get_mdata(void);
int mdss_mdp_secure_display_ctrl(unsigned int enable);
int mdss_mdp_secure_session_ctrl(unsigned int enable, u64 flags);

int mdss_mdp_overlay_init(struct msm_fb_data_type *mfd);
int mdss_mdp_dfps_update_params(struct msm_fb_data_type *mfd,
@@ -1603,7 +1620,7 @@ int mdss_mdp_overlay_start(struct msm_fb_data_type *mfd);
void mdss_mdp_overlay_set_chroma_sample(
	struct mdss_mdp_pipe *pipe);
int mdp_pipe_tune_perf(struct mdss_mdp_pipe *pipe,
	u32 flags);
	u64 flags);
int mdss_mdp_overlay_setup_scaling(struct mdss_mdp_pipe *pipe);
struct mdss_mdp_pipe *mdss_mdp_pipe_assign(struct mdss_data_type *mdata,
	struct mdss_mdp_mixer *mixer, u32 ndx,
@@ -1836,7 +1853,7 @@ struct mult_factor *mdss_mdp_get_comp_factor(u32 format,
int mdss_mdp_data_map(struct mdss_mdp_data *data, bool rotator, int dir);
void mdss_mdp_data_free(struct mdss_mdp_data *data, bool rotator, int dir);
int mdss_mdp_data_get_and_validate_size(struct mdss_mdp_data *data,
	struct msmfb_data *planes, int num_planes, u32 flags,
	struct msmfb_data *planes, int num_planes, u64 flags,
	struct device *dev, bool rotator, int dir,
	struct mdp_layer_buffer *buffer);
u32 mdss_get_panel_framerate(struct msm_fb_data_type *mfd);
+1 −1
Original line number Diff line number Diff line
@@ -1868,7 +1868,7 @@ static void __dump_pipe(struct seq_file *s, struct mdss_mdp_pipe *pipe)
	int smps[4];
	int i;

	seq_printf(s, "\nSSPP #%d type=%s ndx=%x flags=0x%08x play_cnt=%u xin_id=%d\n",
	seq_printf(s, "\nSSPP #%d type=%s ndx=%x flags=0x%16llx play_cnt=%u xin_id=%d\n",
			pipe->num, mdss_mdp_pipetype2str(pipe->type),
			pipe->ndx, pipe->flags, pipe->play_cnt, pipe->xin_id);
	seq_printf(s, "\tstage=%d alpha=0x%x transp=0x%x blend_op=%d\n",
+30 −13
Original line number Diff line number Diff line
@@ -936,7 +936,7 @@ static int __configure_pipe_params(struct msm_fb_data_type *mfd,
{
	int ret = 0;
	u32 left_lm_w = left_lm_w_from_mfd(mfd);
	u32 flags;
	u64 flags;

	struct mdss_mdp_mixer *mixer = NULL;
	struct mdss_overlay_private *mdp5_data = mfd_to_mdp5_data(mfd);
@@ -978,6 +978,8 @@ static int __configure_pipe_params(struct msm_fb_data_type *mfd,
		pipe->flags |= MDP_BWC_EN;
	if (layer->flags & MDP_LAYER_PP)
		pipe->flags |= MDP_OVERLAY_PP_CFG_EN;
	if (layer->flags & MDP_LAYER_SECURE_CAMERA_SESSION)
		pipe->flags |= MDP_SECURE_CAMERA_OVERLAY_SESSION;

	pipe->scaler.enable = (layer->flags & SCALER_ENABLED);
	pipe->is_fg = layer->flags & MDP_LAYER_FORGROUND;
@@ -1348,7 +1350,7 @@ static struct mdss_mdp_data *__map_layer_buffer(struct msm_fb_data_type *mfd,
	struct mdp_layer_buffer *buffer;
	struct msmfb_data image;
	int i, ret;
	u32 flags;
	u64 flags;
	struct mdss_mdp_validate_info_t *vitem;

	for (i = 0; i < layer_count; i++) {
@@ -1374,7 +1376,8 @@ static struct mdss_mdp_data *__map_layer_buffer(struct msm_fb_data_type *mfd,
	}

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

	if (buffer->planes[0].fd < 0) {
		pr_err("invalid file descriptor for layer buffer\n");
@@ -1585,34 +1588,48 @@ end:
}

/*
 * __validate_secure_display() - validate secure display
 * __validate_secure_session() - validate various secure sessions
 *
 * 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.
 * is with secure display, secure video and secure camera enabled flag.
 * It fails if client tries to stage unsecure content with
 * secure display session and secure camera with secure video sessions.
 *
 */
static int __validate_secure_display(struct mdss_overlay_private *mdp5_data)
static int __validate_secure_session(struct mdss_overlay_private *mdp5_data)
{
	struct mdss_mdp_pipe *pipe, *tmp;
	uint32_t sd_pipes = 0, nonsd_pipes = 0;
	uint32_t secure_vid_pipes = 0, secure_cam_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 if (pipe->flags & MDP_SECURE_OVERLAY_SESSION)
			secure_vid_pipes++;
		else if (pipe->flags & MDP_SECURE_CAMERA_OVERLAY_SESSION)
			secure_cam_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);
	pr_debug("pipe count:: secure display:%d non-secure:%d secure-vid:%d,secure-cam:%d\n",
		sd_pipes, nonsd_pipes, secure_vid_pipes, secure_cam_pipes);

	if ((sd_pipes || mdss_get_sd_client_cnt()) && nonsd_pipes) {
	if ((sd_pipes || mdss_get_sd_client_cnt()) &&
		(nonsd_pipes || secure_vid_pipes ||
		secure_cam_pipes)) {
		pr_err("non-secure layer validation request during secure display session\n");
		pr_err(" secure client cnt:%d secure pipe cnt:%d non-secure pipe cnt:%d\n",
			mdss_get_sd_client_cnt(), sd_pipes, nonsd_pipes);
		pr_err(" secure client cnt:%d secure pipe:%d non-secure pipe:%d, secure-vid:%d, secure-cam:%d\n",
			mdss_get_sd_client_cnt(), sd_pipes, nonsd_pipes,
			secure_vid_pipes, secure_cam_pipes);
		return -EINVAL;
	} else if (secure_cam_pipes && (secure_vid_pipes || sd_pipes)) {
		pr_err(" incompatible layers during secure camera session\n");
		pr_err("secure-camera cnt:%d secure video:%d secure display:%d\n",
				secure_cam_pipes, secure_vid_pipes, sd_pipes);
		return -EINVAL;
	} else {
		return 0;
@@ -2388,7 +2405,7 @@ static int __validate_layers(struct msm_fb_data_type *mfd,
validate_skip:
	__handle_free_list(mdp5_data, validate_info_list, layer_count);

	ret = __validate_secure_display(mdp5_data);
	ret = __validate_secure_session(mdp5_data);

validate_exit:
	pr_debug("err=%d total_layer:%d left:%d right:%d rec0_rel_ndx=0x%x rec1_rel_ndx=0x%x rec0_destroy_ndx=0x%x rec1_destroy_ndx=0x%x processed=%d\n",
Loading