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>
This commit is contained in:
Ujwal Patel 2015-12-08 13:16:40 -08:00 committed by David Keitel
parent 8c1a218070
commit e75a440cec
2 changed files with 37 additions and 14 deletions

View file

@ -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)
{

View file

@ -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)