From 7f07fcf3891a3da354a48385ec853225275c53f1 Mon Sep 17 00:00:00 2001 From: Krishna Chaitanya Devarakonda Date: Tue, 28 Feb 2017 19:35:27 +0530 Subject: [PATCH] msm: mdss: Disable secure session after Flush for video mode panels For video mode panels, the secure session (display/camera) should be disabled after the Flush. This is to make sure that the secure buffer is no longer being fetched, before disabling the secure session. Change-Id: I9cef6a00fa16f4e23cb5d860548a3502951a7281 Signed-off-by: Krishna Chaitanya Devarakonda --- drivers/video/fbdev/msm/mdss_mdp.h | 10 +++ drivers/video/fbdev/msm/mdss_mdp_overlay.c | 93 ++++++++++++++++------ 2 files changed, 79 insertions(+), 24 deletions(-) diff --git a/drivers/video/fbdev/msm/mdss_mdp.h b/drivers/video/fbdev/msm/mdss_mdp.h index 5e98de043e55..a167187b60aa 100644 --- a/drivers/video/fbdev/msm/mdss_mdp.h +++ b/drivers/video/fbdev/msm/mdss_mdp.h @@ -164,6 +164,14 @@ enum mdss_mdp_mixer_mux { MDSS_MDP_MIXER_MUX_RIGHT, }; +enum mdss_secure_transition { + SECURE_TRANSITION_NONE, + SD_NON_SECURE_TO_SECURE, + SD_SECURE_TO_NON_SECURE, + SC_NON_SECURE_TO_SECURE, + SC_SECURE_TO_NON_SECURE, +}; + static inline enum mdss_mdp_sspp_index get_pipe_num_from_ndx(u32 ndx) { u32 id; @@ -953,6 +961,8 @@ struct mdss_overlay_private { struct kthread_worker worker; struct kthread_work vsync_work; struct task_struct *thread; + + u8 secure_transition_state; }; struct mdss_mdp_set_ot_params { diff --git a/drivers/video/fbdev/msm/mdss_mdp_overlay.c b/drivers/video/fbdev/msm/mdss_mdp_overlay.c index da08917d334b..5f8107535ab9 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_overlay.c +++ b/drivers/video/fbdev/msm/mdss_mdp_overlay.c @@ -2211,14 +2211,12 @@ set_roi: } /* - * Enables/disable secure (display or camera) sessions + * Check if there is any change in secure state and store it. */ -static int __overlay_secure_ctrl(struct msm_fb_data_type *mfd) +static void __overlay_set_secure_transition_state(struct msm_fb_data_type *mfd) { struct mdss_overlay_private *mdp5_data = mfd_to_mdp5_data(mfd); - struct mdss_mdp_ctl *ctl = mfd_to_ctl(mfd); struct mdss_mdp_pipe *pipe; - int ret = 0; int sd_in_pipe = 0; int sc_in_pipe = 0; u64 pipes_flags = 0; @@ -2239,25 +2237,53 @@ static int __overlay_secure_ctrl(struct msm_fb_data_type *mfd) MDSS_XLOG(sd_in_pipe, sc_in_pipe, pipes_flags, mdp5_data->sc_enabled, mdp5_data->sd_enabled); pr_debug("sd:%d sd_in_pipe:%d sc:%d sc_in_pipe:%d flags:0x%llx\n", - mdp5_data->sd_enabled, sd_in_pipe, - mdp5_data->sc_enabled, sc_in_pipe, pipes_flags); + mdp5_data->sd_enabled, sd_in_pipe, + mdp5_data->sc_enabled, sc_in_pipe, pipes_flags); + + /* Reset the secure transition state */ + mdp5_data->secure_transition_state = SECURE_TRANSITION_NONE; /* - * Return early in only two conditions: - * 1. All the features are already disabled and state remains - * disabled for the pipes. - * 2. One of the features is already enabled and state remains - * enabled for the pipes. - */ + * Secure transition would be NONE in two conditions: + * 1. All the features are already disabled and state remains + * disabled for the pipes. + * 2. One of the features is already enabled and state remains + * enabled for the pipes. + */ if (!sd_in_pipe && !mdp5_data->sd_enabled && !sc_in_pipe && !mdp5_data->sc_enabled) - return ret; + return; else if ((sd_in_pipe && mdp5_data->sd_enabled) || (sc_in_pipe && mdp5_data->sc_enabled)) + return; + + /* Secure Display */ + if (!mdp5_data->sd_enabled && sd_in_pipe) + mdp5_data->secure_transition_state |= SD_NON_SECURE_TO_SECURE; + else if (mdp5_data->sd_enabled && !sd_in_pipe) + mdp5_data->secure_transition_state |= SD_SECURE_TO_NON_SECURE; + + /* Secure Camera */ + if (!mdp5_data->sc_enabled && sc_in_pipe) + mdp5_data->secure_transition_state |= SC_NON_SECURE_TO_SECURE; + else if (mdp5_data->sc_enabled && !sc_in_pipe) + mdp5_data->secure_transition_state |= SC_SECURE_TO_NON_SECURE; +} + +/* + * Enable/disable secure (display or camera) sessions + */ +static int __overlay_secure_ctrl(struct msm_fb_data_type *mfd) +{ + struct mdss_overlay_private *mdp5_data = mfd_to_mdp5_data(mfd); + struct mdss_mdp_ctl *ctl = mfd_to_ctl(mfd); + int ret = 0; + + if (mdp5_data->secure_transition_state == SECURE_TRANSITION_NONE) return ret; /* Secure Display */ - if (!mdp5_data->sd_enabled && sd_in_pipe) { + if (mdp5_data->secure_transition_state == SD_NON_SECURE_TO_SECURE) { if (!mdss_get_sd_client_cnt()) { MDSS_XLOG(0x11); /*wait for ping pong done */ @@ -2279,7 +2305,8 @@ static int __overlay_secure_ctrl(struct msm_fb_data_type *mfd) } mdp5_data->sd_enabled = 1; mdss_update_sd_client(mdp5_data->mdata, true); - } else if (mdp5_data->sd_enabled && !sd_in_pipe) { + } else if (mdp5_data->secure_transition_state == + SD_SECURE_TO_NON_SECURE) { /* disable the secure display on last client */ if (mdss_get_sd_client_cnt() == 1) { MDSS_XLOG(0x22); @@ -2297,11 +2324,9 @@ static int __overlay_secure_ctrl(struct msm_fb_data_type *mfd) } /* Secure Camera */ - if (!mdp5_data->sc_enabled && sc_in_pipe) { + if (mdp5_data->secure_transition_state == SC_NON_SECURE_TO_SECURE) { if (!mdss_get_sc_client_cnt()) { MDSS_XLOG(0x33); - if (ctl->ops.wait_pingpong) - mdss_mdp_display_wait4pingpong(ctl, true); ret = mdss_mdp_secure_session_ctrl(1, MDP_SECURE_CAMERA_OVERLAY_SESSION); if (ret) { @@ -2311,7 +2336,8 @@ static int __overlay_secure_ctrl(struct msm_fb_data_type *mfd) } mdp5_data->sc_enabled = 1; mdss_update_sc_client(mdp5_data->mdata, true); - } else if (mdp5_data->sc_enabled && !sc_in_pipe) { + } else if (mdp5_data->secure_transition_state == + SC_SECURE_TO_NON_SECURE) { /* disable the secure camera on last client */ if (mdss_get_sc_client_cnt() == 1) { MDSS_XLOG(0x44); @@ -2390,15 +2416,23 @@ int mdss_mdp_overlay_kickoff(struct msm_fb_data_type *mfd, list_move(&pipe->list, &mdp5_data->pipes_destroy); } + __overlay_set_secure_transition_state(mfd); /* * go to secure state if required, this should be done * after moving the buffers from the previous commit to - * destroy list + * destroy list. + * For video mode panels, secure display/camera should be disabled + * after flushing the new buffer. Skip secure disable here for those + * cases. */ - ret = __overlay_secure_ctrl(mfd); - if (IS_ERR_VALUE(ret)) { - pr_err("secure operation failed %d\n", ret); - goto commit_fail; + if (!((mfd->panel_info->type == MIPI_VIDEO_PANEL) && + ((mdp5_data->secure_transition_state == SD_SECURE_TO_NON_SECURE) || + (mdp5_data->secure_transition_state == SC_SECURE_TO_NON_SECURE)))) { + ret = __overlay_secure_ctrl(mfd); + if (IS_ERR_VALUE(ret)) { + pr_err("secure operation failed %d\n", ret); + goto commit_fail; + } } /* call this function before any registers programming */ @@ -2470,6 +2504,17 @@ int mdss_mdp_overlay_kickoff(struct msm_fb_data_type *mfd, mutex_lock(&mdp5_data->ov_lock); + /* Disable secure display/camera for video mode panels */ + if ((mfd->panel_info->type == MIPI_VIDEO_PANEL) && + ((mdp5_data->secure_transition_state == SD_SECURE_TO_NON_SECURE) || + (mdp5_data->secure_transition_state == SC_SECURE_TO_NON_SECURE))) { + ret = __overlay_secure_ctrl(mfd); + if (IS_ERR_VALUE(ret)) { + pr_err("secure operation failed %d\n", ret); + goto commit_fail; + } + } + mdss_fb_update_notify_update(mfd); commit_fail: ATRACE_BEGIN("overlay_cleanup");