summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp.h3
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_layer.c35
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_overlay.c33
3 files changed, 42 insertions, 29 deletions
diff --git a/drivers/video/fbdev/msm/mdss_mdp.h b/drivers/video/fbdev/msm/mdss_mdp.h
index fbf7e5ca8eb0..16227bda89ea 100644
--- a/drivers/video/fbdev/msm/mdss_mdp.h
+++ b/drivers/video/fbdev/msm/mdss_mdp.h
@@ -662,6 +662,7 @@ struct mdss_overlay_private {
struct mutex list_lock;
struct list_head pipes_used;
struct list_head pipes_cleanup;
+ struct list_head pipes_destroy;
struct list_head rot_proc_list;
bool mixer_swap;
u32 resources_state;
@@ -1169,6 +1170,8 @@ int mdp_pipe_tune_perf(struct mdss_mdp_pipe *pipe,
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);
+struct mdss_mdp_pipe *mdss_mdp_overlay_pipe_reuse(
+ struct msm_fb_data_type *mfd, int pipe_ndx);
void mdss_mdp_pipe_position_update(struct mdss_mdp_pipe *pipe,
struct mdss_rect *src, struct mdss_rect *dst);
int mdss_mdp_video_addr_setup(struct mdss_data_type *mdata,
diff --git a/drivers/video/fbdev/msm/mdss_mdp_layer.c b/drivers/video/fbdev/msm/mdss_mdp_layer.c
index 4a22dad62608..cbd0b246de38 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_layer.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_layer.c
@@ -928,21 +928,42 @@ static struct mdss_mdp_pipe *__find_layer_in_validate_q(
return found ? pipe : NULL;
}
+static bool __find_pipe_in_list(struct list_head *head,
+ int pipe_ndx, struct mdss_mdp_pipe **out_pipe)
+{
+ struct mdss_mdp_pipe *pipe;
+
+ list_for_each_entry(pipe, head, list) {
+ if (pipe_ndx == pipe->ndx) {
+ *out_pipe = pipe;
+ return true;
+ }
+ }
+
+ return false;
+}
+
static struct mdss_mdp_pipe *__find_used_pipe(struct msm_fb_data_type *mfd,
u32 pipe_ndx)
{
struct mdss_overlay_private *mdp5_data = mfd_to_mdp5_data(mfd);
- struct mdss_mdp_pipe *pipe, *tmp, *used_pipe = NULL;
+ struct mdss_mdp_pipe *pipe = NULL;
+ bool found;
mutex_lock(&mdp5_data->list_lock);
- list_for_each_entry_safe(pipe, tmp, &mdp5_data->pipes_used, list) {
- if (pipe->ndx == pipe_ndx) {
- used_pipe = pipe;
- break;
- }
+
+ found = __find_pipe_in_list(&mdp5_data->pipes_used, pipe_ndx, &pipe);
+
+ /* check if the pipe is in the cleanup or destroy list */
+ if (!found &&
+ (__find_pipe_in_list(&mdp5_data->pipes_destroy, pipe_ndx, &pipe) ||
+ __find_pipe_in_list(&mdp5_data->pipes_cleanup, pipe_ndx, &pipe))) {
+ pr_debug("reuse pipe%d ndx:%d\n", pipe->num, pipe->ndx);
+ list_move(&pipe->list, &mdp5_data->pipes_used);
}
+
mutex_unlock(&mdp5_data->list_lock);
- return used_pipe;
+ return pipe;
}
/*
diff --git a/drivers/video/fbdev/msm/mdss_mdp_overlay.c b/drivers/video/fbdev/msm/mdss_mdp_overlay.c
index a81588eeee94..a31b06257d8d 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_overlay.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_overlay.c
@@ -1893,9 +1893,7 @@ int mdss_mdp_overlay_kickoff(struct msm_fb_data_type *mfd,
struct mdss_mdp_ctl *ctl = mfd_to_ctl(mfd);
int ret = 0;
int sd_in_pipe = 0;
- bool need_cleanup = false;
struct mdss_mdp_commit_cb commit_cb;
- LIST_HEAD(destroy_pipes);
if (!ctl)
return -ENODEV;
@@ -1970,8 +1968,7 @@ int mdss_mdp_overlay_kickoff(struct msm_fb_data_type *mfd,
mdss_mdp_mixer_pipe_unstage(pipe, pipe->mixer_left);
mdss_mdp_mixer_pipe_unstage(pipe, pipe->mixer_right);
pipe->mixer_stage = MDSS_MDP_STAGE_UNUSED;
- list_move(&pipe->list, &destroy_pipes);
- need_cleanup = true;
+ list_move(&pipe->list, &mdp5_data->pipes_destroy);
}
ATRACE_BEGIN("sspp_programming");
@@ -1983,25 +1980,16 @@ int mdss_mdp_overlay_kickoff(struct msm_fb_data_type *mfd,
if (mfd->panel.type == WRITEBACK_PANEL) {
ATRACE_BEGIN("wb_kickoff");
- if (!need_cleanup) {
- commit_cb.commit_cb_fnc = mdss_mdp_commit_cb;
- commit_cb.data = mfd;
- ret = mdss_mdp_wfd_kickoff(mdp5_data->wfd, &commit_cb);
- } else {
- ret = mdss_mdp_wfd_kickoff(mdp5_data->wfd, NULL);
- }
+ commit_cb.commit_cb_fnc = mdss_mdp_commit_cb;
+ commit_cb.data = mfd;
+ ret = mdss_mdp_wfd_kickoff(mdp5_data->wfd, &commit_cb);
ATRACE_END("wb_kickoff");
} else {
ATRACE_BEGIN("display_commit");
- if (!need_cleanup) {
- commit_cb.commit_cb_fnc = mdss_mdp_commit_cb;
- commit_cb.data = mfd;
- ret = mdss_mdp_display_commit(mdp5_data->ctl, NULL,
- &commit_cb);
- } else {
- ret = mdss_mdp_display_commit(mdp5_data->ctl, NULL,
- NULL);
- }
+ commit_cb.commit_cb_fnc = mdss_mdp_commit_cb;
+ commit_cb.data = mfd;
+ ret = mdss_mdp_display_commit(mdp5_data->ctl, NULL,
+ &commit_cb);
ATRACE_END("display_commit");
}
@@ -2012,7 +2000,7 @@ int mdss_mdp_overlay_kickoff(struct msm_fb_data_type *mfd,
*/
mfd->validate_pending = false;
- if ((!need_cleanup) && (!mdp5_data->kickoff_released))
+ if (!mdp5_data->kickoff_released)
mdss_mdp_ctl_notify(ctl, MDP_NOTIFY_FRAME_CTX_DONE);
if (IS_ERR_VALUE(ret))
@@ -2059,7 +2047,7 @@ int mdss_mdp_overlay_kickoff(struct msm_fb_data_type *mfd,
mdss_fb_update_notify_update(mfd);
commit_fail:
ATRACE_BEGIN("overlay_cleanup");
- mdss_mdp_overlay_cleanup(mfd, &destroy_pipes);
+ mdss_mdp_overlay_cleanup(mfd, &mdp5_data->pipes_destroy);
ATRACE_END("overlay_cleanup");
mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF);
mdss_mdp_ctl_notify(ctl, MDP_NOTIFY_FRAME_FLUSHED);
@@ -5131,6 +5119,7 @@ int mdss_mdp_overlay_init(struct msm_fb_data_type *mfd)
INIT_LIST_HEAD(&mdp5_data->pipes_used);
INIT_LIST_HEAD(&mdp5_data->pipes_cleanup);
+ INIT_LIST_HEAD(&mdp5_data->pipes_destroy);
INIT_LIST_HEAD(&mdp5_data->bufs_pool);
INIT_LIST_HEAD(&mdp5_data->bufs_chunks);
INIT_LIST_HEAD(&mdp5_data->bufs_used);