diff options
| author | Ujwal Patel <ujwalp@codeaurora.org> | 2015-12-08 13:16:40 -0800 |
|---|---|---|
| committer | David Keitel <dkeitel@codeaurora.org> | 2016-03-23 21:14:13 -0700 |
| commit | e75a440cec43d11ae58cc1c35ba75172eb356054 (patch) | |
| tree | 3809e9cef47d339c7e5794c9d7cd76686fa38ead | |
| parent | 8c1a2180705a857b9a21c6a80ac5af87469967ce (diff) | |
msm: mdss: force HW reprogram when ROI changes mixer layout
Current driver has various optimizations to skip pipe reprogramming if
certain layer parameters are not changed. However if mixer layout changes
then we need to reprogram all the staged pipes on that mixer. This
scenario can happen when partial update is enabled on a topology with
split layer mixers. Add a logic to find if the mixer layout is changing
between two consecutive updates and if it does, force reprogramming of
all the staged pipes.
CRs-fixed: 946164
Change-Id: I16caa4bb8b9587b804d6543d0bd340df970784ba
Signed-off-by: Ujwal Patel <ujwalp@codeaurora.org>
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp.h | 28 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp_ctl.c | 23 |
2 files changed, 37 insertions, 14 deletions
diff --git a/drivers/video/fbdev/msm/mdss_mdp.h b/drivers/video/fbdev/msm/mdss_mdp.h index 684f29a83547..6690765b7250 100644 --- a/drivers/video/fbdev/msm/mdss_mdp.h +++ b/drivers/video/fbdev/msm/mdss_mdp.h @@ -790,6 +790,34 @@ static inline bool mdss_mdp_is_both_lm_valid(struct mdss_mdp_ctl *main_ctl) main_ctl->mixer_right && main_ctl->mixer_right->valid_roi); } +enum mdss_mdp_pu_type { + MDSS_MDP_INVALID_UPDATE = -1, + MDSS_MDP_DEFAULT_UPDATE, + MDSS_MDP_LEFT_ONLY_UPDATE, /* only valid for split_lm */ + MDSS_MDP_RIGHT_ONLY_UPDATE, /* only valid for split_lm */ +}; + +/* only call from master ctl */ +static inline enum mdss_mdp_pu_type mdss_mdp_get_pu_type( + struct mdss_mdp_ctl *mctl) +{ + enum mdss_mdp_pu_type pu_type = MDSS_MDP_INVALID_UPDATE; + + if (!mctl || !mctl->is_master) + return pu_type; + + if (!is_split_lm(mctl->mfd) || mdss_mdp_is_both_lm_valid(mctl)) + pu_type = MDSS_MDP_DEFAULT_UPDATE; + else if (mctl->mixer_left->valid_roi) + pu_type = MDSS_MDP_LEFT_ONLY_UPDATE; + else if (mctl->mixer_right->valid_roi) + pu_type = MDSS_MDP_RIGHT_ONLY_UPDATE; + else + pr_err("%s: invalid pu_type\n", __func__); + + return pu_type; +} + static inline struct mdss_mdp_ctl *mdss_mdp_get_split_ctl( struct mdss_mdp_ctl *ctl) { diff --git a/drivers/video/fbdev/msm/mdss_mdp_ctl.c b/drivers/video/fbdev/msm/mdss_mdp_ctl.c index 61d8f1999eef..9f2e1fec5cfa 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_ctl.c +++ b/drivers/video/fbdev/msm/mdss_mdp_ctl.c @@ -3970,6 +3970,7 @@ void mdss_mdp_set_roi(struct mdss_mdp_ctl *ctl, struct mdss_rect *l_roi, struct mdss_rect *r_roi) { struct mdss_data_type *mdata = mdss_mdp_get_mdata(); + enum mdss_mdp_pu_type previous_frame_pu_type, current_frame_pu_type; /* Reset ROI when we have (1) invalid ROI (2) feature disabled */ if ((!l_roi->w && l_roi->h) || (l_roi->w && !l_roi->h) || @@ -3988,6 +3989,7 @@ void mdss_mdp_set_roi(struct mdss_mdp_ctl *ctl, } } + previous_frame_pu_type = mdss_mdp_get_pu_type(ctl); mdss_mdp_set_mixer_roi(ctl->mixer_left, l_roi); ctl->roi = ctl->mixer_left->roi; @@ -4011,24 +4013,17 @@ void mdss_mdp_set_roi(struct mdss_mdp_ctl *ctl, } } + current_frame_pu_type = mdss_mdp_get_pu_type(ctl); + /* - * When source split is enabled, dst_x of all pipes staged on right - * layer-mixer (LM) has to be greater than left LM's width. - * Now when partial update is enabled, let's say frame N is updating - * full panel width so both LMs are valid thus source split is enabled - * and dst_x of all pipes is as per above requirement. Now when frame - * N+1 is right-only update without any geomatry changes, pipe's params - * are not changed and right LM's roi is also not changed. So if - * params are not changed then pipe's register programming is skipped. - * So for that right-only update, pipe's dst_x remains same - * as frame N, which not correct and can lead to unknown behaviour. - * Fix this by identifying this condition and forcing roi changed for - * right LM. + * Force HW programming whenever partial update type changes + * between two consecutive frames to avoid incorrect HW programming. */ if (is_split_lm(ctl->mfd) && mdata->has_src_split && - (!ctl->mixer_left->valid_roi && ctl->mixer_left->roi_changed) && - (ctl->mixer_right->valid_roi && !ctl->mixer_right->roi_changed)) + (previous_frame_pu_type != current_frame_pu_type)) { + ctl->mixer_left->roi_changed = true; ctl->mixer_right->roi_changed = true; + } } u32 mdss_mdp_get_mixer_mask(u32 pipe_num, u32 stage) |
