diff options
| author | Naseer Ahmed <naseer@codeaurora.org> | 2016-10-20 15:53:54 -0400 |
|---|---|---|
| committer | Naseer Ahmed <naseer@codeaurora.org> | 2016-10-27 15:35:48 -0400 |
| commit | 1880e6184ab9f0acc8a5077ebc8ef4be4fc9c269 (patch) | |
| tree | 97f9d2b4a337f8bbb979a365b7049c8aa7ee434c /drivers/video/fbdev | |
| parent | bcd8ec9210c9048c14d934e16267ba79a894db09 (diff) | |
msm: mdss: Dynamic resolution switch with DSC on/off
When dynamically switching resolutions from one with DSC and the
other without, DSC should be turned off in MDP and also
topology should be switched to enable 3D mux if DSC merge was
being used.
Change-Id: I381003f4542d1483004df4b24e2ffe6bd1571592
Signed-off-by: Naseer Ahmed <naseer@codeaurora.org>
Diffstat (limited to 'drivers/video/fbdev')
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp.h | 2 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp_ctl.c | 52 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c | 18 |
3 files changed, 63 insertions, 9 deletions
diff --git a/drivers/video/fbdev/msm/mdss_mdp.h b/drivers/video/fbdev/msm/mdss_mdp.h index 8ac63aaaefce..481a6e679837 100644 --- a/drivers/video/fbdev/msm/mdss_mdp.h +++ b/drivers/video/fbdev/msm/mdss_mdp.h @@ -551,6 +551,8 @@ struct mdss_mdp_mixer { bool valid_roi; bool roi_changed; struct mdss_rect roi; + bool dsc_enabled; + bool dsc_merge_enabled; u8 cursor_enabled; u16 cursor_hotx; diff --git a/drivers/video/fbdev/msm/mdss_mdp_ctl.c b/drivers/video/fbdev/msm/mdss_mdp_ctl.c index eb1e0b5c47a6..f8e5ed07b24e 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_ctl.c +++ b/drivers/video/fbdev/msm/mdss_mdp_ctl.c @@ -2743,6 +2743,7 @@ static inline void __dsc_enable(struct mdss_mdp_mixer *mixer) { mdss_mdp_pingpong_write(mixer->pingpong_base, MDSS_MDP_REG_PP_DSC_MODE, 1); + mixer->dsc_enabled = true; } static inline void __dsc_disable(struct mdss_mdp_mixer *mixer) @@ -2762,6 +2763,13 @@ static inline void __dsc_disable(struct mdss_mdp_mixer *mixer) return; } writel_relaxed(0, offset + MDSS_MDP_REG_DSC_COMMON_MODE); + mixer->dsc_enabled = false; + mixer->dsc_merge_enabled = false; +} + +static bool __is_dsc_merge_enabled(u32 common_mode) +{ + return common_mode & BIT(1); } static void __dsc_config(struct mdss_mdp_mixer *mixer, @@ -2774,6 +2782,7 @@ static void __dsc_config(struct mdss_mdp_mixer *mixer, u32 initial_lines = dsc->initial_lines; bool is_cmd_mode = !(mode & BIT(2)); + mixer->dsc_merge_enabled = __is_dsc_merge_enabled(mode); data = mdss_mdp_pingpong_read(mixer->pingpong_base, MDSS_MDP_REG_PP_DCE_DATA_OUT_SWAP); data |= BIT(18); /* endian flip */ @@ -2928,11 +2937,6 @@ static void __dsc_config_thresh(struct mdss_mdp_mixer *mixer, } } -static bool __is_dsc_merge_enabled(u32 common_mode) -{ - return common_mode & BIT(1); -} - static bool __dsc_is_3d_mux_enabled(struct mdss_mdp_ctl *ctl, struct mdss_panel_info *pinfo) { @@ -3291,8 +3295,19 @@ void mdss_mdp_ctl_dsc_setup(struct mdss_mdp_ctl *ctl, struct mdss_mdp_ctl *sctl; struct mdss_panel_info *spinfo; - if (!is_dsc_compression(pinfo)) + /* + * Check for dynamic resolution switch from DSC On to DSC Off + * and disable DSC + */ + if ((ctl->pending_mode_switch == SWITCH_RESOLUTION) && + ctl->is_master && + (!is_dsc_compression(pinfo))) { + if (ctl->mixer_left && ctl->mixer_left->dsc_enabled) + __dsc_disable(ctl->mixer_left); + if (ctl->mixer_right && ctl->mixer_right->dsc_enabled) + __dsc_disable(ctl->mixer_right); return; + } if (!ctl->is_master) { pr_debug("skip slave ctl because master will program for both\n"); @@ -3693,6 +3708,30 @@ skip_intf_reconfig: ctl->mixer_right->width = ctl->width / 2; ctl->mixer_right->height = ctl->height; } + + /* + * If we are transitioning from DSC On + DSC Merge to DSC Off + * the 3D mux needs to be enabled + */ + if (!is_dsc_compression(&pdata->panel_info) && + ctl->mixer_left && + ctl->mixer_left->dsc_enabled && + ctl->mixer_left->dsc_merge_enabled) { + ctl->opmode |= MDSS_MDP_CTL_OP_PACK_3D_ENABLE | + MDSS_MDP_CTL_OP_PACK_3D_H_ROW_INT; + } + + /* + * If we are transitioning from DSC Off to DSC On + DSC Merge + * the 3D mux needs to be disabled + */ + if (is_dsc_compression(&pdata->panel_info) && + ctl->mixer_left && + !ctl->mixer_left->dsc_enabled && + pdata->panel_info.dsc_enc_total != 1) { + ctl->opmode &= ~(MDSS_MDP_CTL_OP_PACK_3D_ENABLE | + MDSS_MDP_CTL_OP_PACK_3D_H_ROW_INT); + } } else { /* * Handles MDP_SPLIT_MODE_NONE, MDP_DUAL_LM_DUAL_DISPLAY and @@ -3707,7 +3746,6 @@ skip_intf_reconfig: ctl->border_x_off = pdata->panel_info.lcdc.border_left; ctl->border_y_off = pdata->panel_info.lcdc.border_top; - return ret; } diff --git a/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c b/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c index 4eb121f01aca..f08af5d6edd3 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c +++ b/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c @@ -2029,8 +2029,22 @@ static void mdss_mdp_cmd_dsc_reconfig(struct mdss_mdp_ctl *ctl) return; pinfo = &ctl->panel_data->panel_info; - if (pinfo->compression_mode != COMPRESSION_DSC) - return; + if (pinfo->compression_mode != COMPRESSION_DSC) { + /* + * Check for a dynamic resolution switch from DSC On to + * DSC Off and call mdss_mdp_ctl_dsc_setup to disable DSC + */ + if (ctl->pending_mode_switch == SWITCH_RESOLUTION) { + if (ctl->mixer_left && ctl->mixer_left->dsc_enabled) + changed = true; + if (is_split_lm(ctl->mfd) && + ctl->mixer_right && + ctl->mixer_right->dsc_enabled) + changed = true; + } else { + return; + } + } changed = ctl->mixer_left->roi_changed; if (is_split_lm(ctl->mfd)) |
