diff options
| author | Ingrid Gallardo <ingridg@codeaurora.org> | 2016-11-22 12:25:33 -0800 |
|---|---|---|
| committer | Ingrid Gallardo <ingridg@codeaurora.org> | 2016-11-22 13:04:35 -0800 |
| commit | 285158e1d8f0fd8cb4c49f20a46e6203af1652bf (patch) | |
| tree | 56130dc3a604b2b78d04277a2c28cc06d21f5184 | |
| parent | 9febdfdde008c8d7875b5186a4a37cb515cb924d (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.c | 51 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp_pipe.c | 11 |
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; |
