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

Commit 9d7e6b27 authored by Krishna Chaitanya Devarakonda's avatar Krishna Chaitanya Devarakonda
Browse files

msm: mdss: Add support for direct secure dispaly transition



In the current implementation, during secure to non secure
and non secure to secure transitions, a NULL commit will be
issued by the framework to make sure that the previous settings
are completely cleared. This is not required for command mode
panels, as we can wait for the frame transfer when the transition
happens.

Adding support to wait for the previous frame transfer completion,
during the non secure to secure and vice-versa transitions.

Change-Id: Id17b456b5b0744cff2f53688b7857569e4d257d6
Signed-off-by: default avatarKrishna Chaitanya Devarakonda <kdevarak@codeaurora.org>
parent aa982f7c
Loading
Loading
Loading
Loading
+9 −1
Original line number Diff line number Diff line
@@ -4788,7 +4788,8 @@ 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_display_ctrl(struct mdss_data_type *mdata,
	unsigned int enable)
{
	struct sd_ctrl_req {
		unsigned int enable;
@@ -4797,6 +4798,12 @@ int mdss_mdp_secure_display_ctrl(unsigned int enable)
	int ret = 0;
	struct scm_desc desc;

	if ((enable && (mdss_get_sd_client_cnt() > 0)) ||
		(!enable && (mdss_get_sd_client_cnt() > 1))) {
		mdss_update_sd_client(mdata, enable);
		return ret;
	}

	desc.args[0] = request.enable = enable;
	desc.arginfo = SCM_ARGS(1);

@@ -4814,6 +4821,7 @@ int mdss_mdp_secure_display_ctrl(unsigned int enable)
	if (ret)
		return ret;

	mdss_update_sd_client(mdata, enable);
	return resp;
}

+10 −2
Original line number Diff line number Diff line
@@ -115,6 +115,12 @@ enum mdss_mdp_mixer_mux {
	MDSS_MDP_MIXER_MUX_RIGHT,
};

enum mdss_sd_transition {
	SD_TRANSITION_NONE,
	SD_TRANSITION_SECURE_TO_NON_SECURE,
	SD_TRANSITION_NON_SECURE_TO_SECURE
};

static inline enum mdss_mdp_sspp_index get_pipe_num_from_ndx(u32 ndx)
{
	u32 id;
@@ -1008,6 +1014,7 @@ struct mdss_overlay_private {

	/* video frame info used by deterministic frame rate control */
	struct mdss_mdp_frc_fsm *frc_fsm;
	u8 sd_transition_state;
};

struct mdss_mdp_set_ot_params {
@@ -1304,7 +1311,7 @@ static inline struct clk *mdss_mdp_get_clk(u32 clk_idx)
}

static inline void mdss_update_sd_client(struct mdss_data_type *mdata,
							bool status)
							unsigned int status)
{
	if (status)
		atomic_inc(&mdata->sd_client_count);
@@ -1603,7 +1610,8 @@ 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_display_ctrl(struct mdss_data_type *mdata,
	unsigned int enable);

int mdss_mdp_overlay_init(struct msm_fb_data_type *mfd);
int mdss_mdp_dfps_update_params(struct msm_fb_data_type *mfd,
+49 −5
Original line number Diff line number Diff line
@@ -1107,6 +1107,40 @@ end:
	return pipe;
}

/*
 * __is_sd_state_valid() - validate secure display state
 *
 * This function checks if the current state of secrure display is valid,
 * based on the new settings.
 * For command mode panels, the sd state would be invalid if a non secure pipe
 * comes and one of the below condition is met:
 *	1) Secure Display is enabled for current client, and there is other
	secure client.
 *	2) Secure Display is disabled for current client, and there is other
	secure client.
 *	3) Secure pipes are already staged for the current client.
 * For other panels, the sd state would be invalid if a non secure pipe comes
 * and one of the below condition is met:
 *	1) Secure Display is enabled for current or other client.
 *	2) Secure pipes are already staged for the current client.
 *
 */
static inline bool __is_sd_state_valid(uint32_t sd_pipes, uint32_t nonsd_pipes,
	int panel_type, u32 sd_enabled)
{
	if (panel_type == MIPI_CMD_PANEL) {
		if ((((mdss_get_sd_client_cnt() > 1) && sd_enabled) ||
			(mdss_get_sd_client_cnt() && !sd_enabled) ||
			sd_pipes)
			&& nonsd_pipes)
			return false;
	} else {
		if ((sd_pipes || mdss_get_sd_client_cnt()) && nonsd_pipes)
			return false;
	}
	return true;
}

/*
 * __validate_secure_display() - validate secure display
 *
@@ -1119,6 +1153,8 @@ 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;
	int panel_type = mdp5_data->ctl->panel_data->panel_info.type;
	int ret = 0;

	mutex_lock(&mdp5_data->list_lock);
	list_for_each_entry_safe(pipe, tmp, &mdp5_data->pipes_used, list) {
@@ -1132,14 +1168,21 @@ static int __validate_secure_display(struct mdss_overlay_private *mdp5_data)
	pr_debug("pipe count:: secure display:%d non-secure:%d\n",
		sd_pipes, nonsd_pipes);

	if ((sd_pipes || mdss_get_sd_client_cnt()) && nonsd_pipes) {
	mdp5_data->sd_transition_state = SD_TRANSITION_NONE;
	if (!__is_sd_state_valid(sd_pipes, nonsd_pipes, panel_type,
		mdp5_data->sd_enabled)) {
		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);
		return -EINVAL;
	} else {
		return 0;
		ret = -EINVAL;
	} else if (!mdp5_data->sd_enabled && sd_pipes) {
			mdp5_data->sd_transition_state =
				SD_TRANSITION_NON_SECURE_TO_SECURE;
	} else if (mdp5_data->sd_enabled && !sd_pipes) {
			mdp5_data->sd_transition_state =
				SD_TRANSITION_SECURE_TO_NON_SECURE;
	}
	return ret;
}

/*
@@ -2000,7 +2043,8 @@ int mdss_mdp_layer_pre_commit(struct msm_fb_data_type *mfd,
	/* handle null commit */
	if (!layer_count) {
		__handle_free_list(mdp5_data, NULL, layer_count);
		return 0;
		/* Check for secure state transition. */
		return __validate_secure_display(mdp5_data);
	}

	validate_info_list = kcalloc(layer_count, sizeof(*validate_info_list),
+50 −34
Original line number Diff line number Diff line
@@ -2656,6 +2656,42 @@ static void __post_frc_in_disable_state(struct mdss_mdp_frc_fsm *frc_fsm,
	/* do nothing */
}

static int __config_secure_display(struct mdss_overlay_private *mdp5_data)
{
	int panel_type = mdp5_data->ctl->panel_data->panel_info.type;
	int sd_enable = -1; /* Since 0 is a valid state, initialize with -1 */
	int ret = 0;

	if (panel_type == MIPI_CMD_PANEL)
		mdss_mdp_display_wait4pingpong(mdp5_data->ctl, true);

	/*
	 * Start secure display session if we are transitioning from non secure
	 * to secure display.
	 */
	if (mdp5_data->sd_transition_state ==
			SD_TRANSITION_NON_SECURE_TO_SECURE)
		sd_enable = 1;

	/*
	 * For command mode panels, if we are trasitioning from secure to
	 * non secure session, disable the secure display, as we've already
	 * waited for the previous frame transfer.
	 */
	if ((panel_type == MIPI_CMD_PANEL) &&
			(mdp5_data->sd_transition_state ==
			 SD_TRANSITION_SECURE_TO_NON_SECURE))
		sd_enable = 0;

	if (sd_enable != -1) {
		ret = mdss_mdp_secure_display_ctrl(mdp5_data->mdata, sd_enable);
		if (!ret)
			mdp5_data->sd_enabled = sd_enable;
	}

	return ret;
}

/* predefined state table of FRC FSM */
static struct mdss_mdp_frc_fsm_state frc_fsm_states[FRC_STATE_MAX] = {
	{
@@ -2783,7 +2819,6 @@ int mdss_mdp_overlay_kickoff(struct msm_fb_data_type *mfd,
	struct mdss_mdp_pipe *pipe, *tmp;
	struct mdss_mdp_ctl *ctl = mfd_to_ctl(mfd);
	int ret = 0;
	int sd_in_pipe = 0;
	struct mdss_mdp_commit_cb commit_cb;

	if (!ctl)
@@ -2816,30 +2851,6 @@ int mdss_mdp_overlay_kickoff(struct msm_fb_data_type *mfd,
	}
	mutex_lock(&mdp5_data->list_lock);

	/*
	 * check if there is a secure display session
	 */
	list_for_each_entry(pipe, &mdp5_data->pipes_used, list) {
		if (pipe->flags & MDP_SECURE_DISPLAY_OVERLAY_SESSION) {
			sd_in_pipe = 1;
			pr_debug("Secure pipe: %u : %08X\n",
					pipe->num, pipe->flags);
		}
	}

	/*
	 * start secure display session if there is secure display session and
	 * sd_enabled is not true.
	 */
	if (!mdp5_data->sd_enabled && sd_in_pipe) {
		if (!mdss_get_sd_client_cnt())
			ret = mdss_mdp_secure_display_ctrl(1);
		if (!ret) {
			mdp5_data->sd_enabled = 1;
			mdss_update_sd_client(mdp5_data->mdata, true);
		}
	}

	if (!ctl->shared_lock)
		mdss_mdp_ctl_notify(ctl, MDP_NOTIFY_FRAME_BEGIN);

@@ -2852,6 +2863,14 @@ int mdss_mdp_overlay_kickoff(struct msm_fb_data_type *mfd,
	if (ctl->ops.wait_pingpong && mdp5_data->mdata->serialize_wait4pp)
		mdss_mdp_display_wait4pingpong(ctl, true);

	if (mdp5_data->sd_transition_state != SD_TRANSITION_NONE) {
		ret = __config_secure_display(mdp5_data);
		if (IS_ERR_VALUE(ret)) {
			pr_err("Secure session config failed\n");
			goto commit_fail;
		}
	}

	/*
	 * Setup pipe in solid fill before unstaging,
	 * to ensure no fetches are happening after dettach or reattach.
@@ -2931,18 +2950,15 @@ int mdss_mdp_overlay_kickoff(struct msm_fb_data_type *mfd,

	mutex_lock(&mdp5_data->ov_lock);
	/*
	 * If there is no secure display session and sd_enabled, disable the
	 * secure display session
	 * If we are transitioning from secure to non-secure display,
	 * disable the secure display.
	 */
	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) {
			mdss_update_sd_client(mdp5_data->mdata, false);
	if (mdp5_data->sd_enabled && (mdp5_data->sd_transition_state ==
			SD_TRANSITION_SECURE_TO_NON_SECURE)) {
		ret = mdss_mdp_secure_display_ctrl(mdp5_data->mdata, 0);
		if (!ret)
			mdp5_data->sd_enabled = 0;
	}
	}

	mdss_fb_update_notify_update(mfd);
commit_fail: