msm: mdss: clean any dirty pipes after a successful prepare

After prepare call is made it should be assumed that all pipes that are
needed for this round should already be set. If there are any pipes that
are still dirty after a successful prepare call, it means that they are
not properly referenced in user land. Thus mark them for cleanup.

Change-Id: I6fea19482129223484b8061eb2917aa8987253e5
Signed-off-by: Adrian Salido-Moreno <adrianm@codeaurora.org>
(cherry picked from commit f0fb17bd97c9eb15376c589a65ea0f33174c3856)
[veeras@codeaurora.org: Resolve merge conflict in mdss_fb.h]
Signed-off-by: Veera Sundaram Sankaran <veeras@codeaurora.org>
This commit is contained in:
Adrian Salido-Moreno 2015-02-05 14:50:42 -08:00 committed by David Keitel
parent 6bbba6f01f
commit 84019e7e6c
3 changed files with 69 additions and 0 deletions

View file

@ -2727,6 +2727,15 @@ static int mdss_fb_pan_display_ex(struct fb_info *info,
return ret;
}
if (mfd->mdp.pre_commit_fnc) {
ret = mfd->mdp.pre_commit_fnc(mfd);
if (ret) {
pr_err("fb%d: pre commit failed %d\n",
mfd->index, ret);
return ret;
}
}
mutex_lock(&mfd->mdp_sync_pt_data.sync_mutex);
if (info->fix.xpanstep)
info->var.xoffset =

View file

@ -199,6 +199,7 @@ struct msm_mdp_interface {
struct mdp_layer_commit_v1 *commit);
int (*pre_commit)(struct msm_fb_data_type *mfd,
struct mdp_layer_commit_v1 *commit);
int (*pre_commit_fnc)(struct msm_fb_data_type *mfd);
int (*ioctl_handler)(struct msm_fb_data_type *mfd, u32 cmd, void *arg);
void (*dma_fnc)(struct msm_fb_data_type *mfd);
int (*cursor_update)(struct msm_fb_data_type *mfd,

View file

@ -1370,6 +1370,13 @@ static int __overlay_queue_pipes(struct msm_fb_data_type *mfd)
list_for_each_entry(pipe, &mdp5_data->pipes_used, list) {
struct mdss_mdp_data *buf;
if (pipe->dirty) {
pr_err("fb%d: pipe %d dirty! skipping configuration\n",
mfd->index, pipe->num);
continue;
}
/*
* When secure display is enabled, if there is a non secure
* display pipe, skip that
@ -1472,6 +1479,7 @@ static int __overlay_queue_pipes(struct msm_fb_data_type *mfd)
pipe->num);
mdss_mdp_mixer_pipe_unstage(pipe, pipe->mixer_left);
mdss_mdp_mixer_pipe_unstage(pipe, pipe->mixer_right);
pipe->dirty = true;
if (buf)
__pipe_buf_mark_cleanup(mfd, buf);
@ -3627,6 +3635,56 @@ static int mdss_fb_get_metadata(struct msm_fb_data_type *mfd,
return ret;
}
static int __mdss_mdp_clean_dirty_pipes(struct msm_fb_data_type *mfd)
{
struct mdss_overlay_private *mdp5_data = mfd_to_mdp5_data(mfd);
struct mdss_mdp_pipe *pipe;
int unset_ndx = 0;
mutex_lock(&mdp5_data->list_lock);
list_for_each_entry(pipe, &mdp5_data->pipes_used, list) {
if (pipe->dirty)
unset_ndx |= pipe->ndx;
}
mutex_unlock(&mdp5_data->list_lock);
if (unset_ndx)
mdss_mdp_overlay_release(mfd, unset_ndx);
return unset_ndx;
}
static int mdss_mdp_overlay_precommit(struct msm_fb_data_type *mfd)
{
struct mdss_overlay_private *mdp5_data;
int ret;
if (!mfd)
return -ENODEV;
mdp5_data = mfd_to_mdp5_data(mfd);
if (!mdp5_data)
return -ENODEV;
ret = mutex_lock_interruptible(&mdp5_data->ov_lock);
if (ret)
return ret;
/*
* we can assume that any pipes that are still dirty at this point are
* not properly tracked by user land. This could be for any reason,
* mark them for cleanup at this point.
*/
ret = __mdss_mdp_clean_dirty_pipes(mfd);
if (ret) {
pr_warn("fb%d: dirty pipes remaining %x\n",
mfd->index, ret);
ret = -EPIPE;
}
mutex_unlock(&mdp5_data->ov_lock);
return ret;
}
/*
* This routine serves two purposes.
* 1. Propagate overlay_id returned from sorted list to original list
@ -4649,6 +4707,7 @@ int mdss_mdp_overlay_init(struct msm_fb_data_type *mfd)
mdp5_interface->mode_switch = mdss_mode_switch;
mdp5_interface->pend_mode_switch = mdss_pend_mode_switch;
mdp5_interface->mode_switch_post = mdss_mode_switch_post;
mdp5_interface->pre_commit_fnc = mdss_mdp_overlay_precommit;
mdp5_interface->get_sync_fnc = mdss_mdp_rotator_sync_pt_get;
mdp5_interface->splash_init_fnc = mdss_mdp_splash_init;
mdp5_interface->configure_panel = mdss_mdp_update_panel_info;