summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIngrid Gallardo <ingridg@codeaurora.org>2016-11-22 12:25:33 -0800
committerIngrid Gallardo <ingridg@codeaurora.org>2016-11-22 13:04:35 -0800
commit285158e1d8f0fd8cb4c49f20a46e6203af1652bf (patch)
tree56130dc3a604b2b78d04277a2c28cc06d21f5184
parent9febdfdde008c8d7875b5186a4a37cb515cb924d (diff)
msm: mdss: fix to handle multi-rect configuration in error cases
In case of an error when configuring a pipe during kickoff, driver unstages from HW the pipe that had the error, so it makes sure this dirty pipe is not used by HW. This is a problem if the pipe is configured in multi-rect mode and we only fail one of the two multi-rect pipes since in this case HW is expecting both multi-rect pipes that represent the two HW rectangles and we are only configuring one due the error that happened. Fix this problem by making sure that if the configuration of one multi-rect fail, we unstage both multi-rect pipes. Change-Id: I09fbda8eb92c81acf24d0ff07ca9c040141680e1 Signed-off-by: Ingrid Gallardo <ingridg@codeaurora.org>
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_overlay.c51
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_pipe.c11
2 files changed, 50 insertions, 12 deletions
diff --git a/drivers/video/fbdev/msm/mdss_mdp_overlay.c b/drivers/video/fbdev/msm/mdss_mdp_overlay.c
index 298b8743f0a6..6ba5828479f5 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_overlay.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_overlay.c
@@ -1453,6 +1453,21 @@ static void mdss_mdp_overlay_update_pm(struct mdss_overlay_private *mdp5_data)
activate_event_timer(mdp5_data->cpu_pm_hdl, wakeup_time);
}
+static void __unstage_pipe_and_clean_buf(struct msm_fb_data_type *mfd,
+ struct mdss_mdp_pipe *pipe, struct mdss_mdp_data *buf)
+{
+
+ pr_debug("unstaging pipe:%d rect:%d buf:%d\n",
+ pipe->num, pipe->multirect.num, !buf);
+ MDSS_XLOG(pipe->num, pipe->multirect.num, !buf);
+ 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);
+}
+
static int __overlay_queue_pipes(struct msm_fb_data_type *mfd)
{
struct mdss_overlay_private *mdp5_data = mfd_to_mdp5_data(mfd);
@@ -1573,14 +1588,36 @@ static int __overlay_queue_pipes(struct msm_fb_data_type *mfd)
ret = mdss_mdp_pipe_queue_data(pipe, buf);
if (IS_ERR_VALUE(ret)) {
- pr_warn("Unable to queue data for pnum=%d\n",
- pipe->num);
- mdss_mdp_mixer_pipe_unstage(pipe, pipe->mixer_left);
- mdss_mdp_mixer_pipe_unstage(pipe, pipe->mixer_right);
- pipe->dirty = true;
+ pr_warn("Unable to queue data for pnum=%d rect=%d\n",
+ pipe->num, pipe->multirect.num);
+
+ /*
+ * If we fail for a multi-rect pipe, unstage both rects
+ * so we don't leave the pipe configured in multi-rect
+ * mode with only one rectangle staged.
+ */
+ if (pipe->multirect.mode !=
+ MDSS_MDP_PIPE_MULTIRECT_NONE) {
+ struct mdss_mdp_pipe *next_pipe =
+ (struct mdss_mdp_pipe *)
+ pipe->multirect.next;
+
+ if (next_pipe) {
+ struct mdss_mdp_data *next_buf =
+ list_first_entry_or_null(
+ &next_pipe->buf_queue,
+ struct mdss_mdp_data,
+ pipe_list);
+
+ __unstage_pipe_and_clean_buf(mfd,
+ next_pipe, next_buf);
+ } else {
+ pr_warn("cannot find rect pnum=%d\n",
+ pipe->num);
+ }
+ }
- if (buf)
- __pipe_buf_mark_cleanup(mfd, buf);
+ __unstage_pipe_and_clean_buf(mfd, pipe, buf);
}
}
diff --git a/drivers/video/fbdev/msm/mdss_mdp_pipe.c b/drivers/video/fbdev/msm/mdss_mdp_pipe.c
index bcf5309993b9..d7678e4d2ae5 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_pipe.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_pipe.c
@@ -2702,8 +2702,8 @@ int mdss_mdp_pipe_queue_data(struct mdss_mdp_pipe *pipe,
if (ret) {
pr_err("pipe pp setup error for pnum=%d\n", pipe->num);
- MDSS_XLOG(pipe->num, pipe->mixer_left->num,
- pipe->play_cnt, 0xbad);
+ MDSS_XLOG(pipe->num, pipe->multirect.num,
+ pipe->mixer_left->num, pipe->play_cnt, 0xbad);
goto done;
}
@@ -2714,13 +2714,14 @@ int mdss_mdp_pipe_queue_data(struct mdss_mdp_pipe *pipe,
pipe->params_changed = 0;
mdss_mdp_pipe_solidfill_setup(pipe);
- MDSS_XLOG(pipe->num, pipe->mixer_left->num, pipe->play_cnt,
- 0x111);
+ MDSS_XLOG(pipe->num, pipe->multirect.num, pipe->mixer_left->num,
+ pipe->play_cnt, 0x111);
goto update_nobuf;
}
- MDSS_XLOG(pipe->num, pipe->mixer_left->num, pipe->play_cnt, 0x222);
+ MDSS_XLOG(pipe->num, pipe->multirect.num, pipe->mixer_left->num,
+ pipe->play_cnt, 0x222);
if (params_changed) {
pipe->params_changed = 0;