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

Commit 82933a00 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: Enable secure display and camera feature for msmcobalt"

parents a273d731 7c9a3efa
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
 *
@@ -629,7 +631,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;
@@ -813,7 +815,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 */
@@ -921,6 +923,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;
@@ -1294,6 +1297,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)
{
@@ -1511,6 +1523,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.
@@ -1518,6 +1531,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;
}

@@ -1574,7 +1591,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,
@@ -1608,7 +1625,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,
@@ -1841,7 +1858,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
@@ -986,7 +986,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);
@@ -1028,6 +1028,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;
@@ -1399,7 +1401,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++) {
@@ -1425,7 +1427,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");
@@ -1636,34 +1639,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;
@@ -2439,7 +2456,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