disp: msm: sde: right only pu support
This change add right only pu support by allowing the dsc to be flushed when one of the dsc is getting disabled. Since the crtc swaps the mixers in case of right only partial update, this change fixes the active display mask passed to encoder so that always the left only dsc gets programmed. This change also fixes layer mixer configuration where only one layer mixer is driving the partial update, the other mixer's configuration is disabled. Change-Id: I2dd2e9a347797bfe07c90e0ca7f999d151fba933 Signed-off-by: Abhijit Kulkarni <kabhijit@codeaurora.org>
This commit is contained in:
@@ -369,6 +369,9 @@ struct msm_roi_caps {
|
|||||||
* @dsc_4hsmerge_en: Using DSC 4HS merge topology
|
* @dsc_4hsmerge_en: Using DSC 4HS merge topology
|
||||||
* @dsc_4hsmerge_padding 4HS merge DSC pair padding value in bytes
|
* @dsc_4hsmerge_padding 4HS merge DSC pair padding value in bytes
|
||||||
* @dsc_4hsmerge_alignment 4HS merge DSC alignment value in bytes
|
* @dsc_4hsmerge_alignment 4HS merge DSC alignment value in bytes
|
||||||
|
* @half_panel_pu True For Dual dsc encoders if partial update is
|
||||||
|
* enabled and only one encoder needs to be used,
|
||||||
|
* False in all other cases
|
||||||
*/
|
*/
|
||||||
struct msm_display_dsc_info {
|
struct msm_display_dsc_info {
|
||||||
struct drm_dsc_config config;
|
struct drm_dsc_config config;
|
||||||
@@ -390,6 +393,7 @@ struct msm_display_dsc_info {
|
|||||||
bool dsc_4hsmerge_en;
|
bool dsc_4hsmerge_en;
|
||||||
u32 dsc_4hsmerge_padding;
|
u32 dsc_4hsmerge_padding;
|
||||||
u32 dsc_4hsmerge_alignment;
|
u32 dsc_4hsmerge_alignment;
|
||||||
|
bool half_panel_pu;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@@ -896,9 +896,12 @@ static u32 _sde_crtc_get_displays_affected(struct drm_crtc *crtc,
|
|||||||
disp_bitmask = BIT(1); /* right only */
|
disp_bitmask = BIT(1); /* right only */
|
||||||
else
|
else
|
||||||
disp_bitmask = BIT(0) | BIT(1); /* left and right */
|
disp_bitmask = BIT(0) | BIT(1); /* left and right */
|
||||||
|
} else if (sde_crtc->mixers_swapped) {
|
||||||
|
disp_bitmask = BIT(0);
|
||||||
} else {
|
} else {
|
||||||
for (i = 0; i < sde_crtc->num_mixers; i++) {
|
for (i = 0; i < sde_crtc->num_mixers; i++) {
|
||||||
if (!sde_kms_rect_is_null(&crtc_state->lm_roi[i]))
|
if (!sde_kms_rect_is_null(
|
||||||
|
&crtc_state->lm_roi[i]))
|
||||||
disp_bitmask |= BIT(i);
|
disp_bitmask |= BIT(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1113,7 +1116,7 @@ static void _sde_crtc_program_lm_output_roi(struct drm_crtc *crtc)
|
|||||||
struct sde_crtc_state *crtc_state;
|
struct sde_crtc_state *crtc_state;
|
||||||
const struct sde_rect *lm_roi;
|
const struct sde_rect *lm_roi;
|
||||||
struct sde_hw_mixer *hw_lm;
|
struct sde_hw_mixer *hw_lm;
|
||||||
bool right_mixer;
|
bool right_mixer = false;
|
||||||
int lm_idx;
|
int lm_idx;
|
||||||
|
|
||||||
if (!crtc)
|
if (!crtc)
|
||||||
@@ -1127,15 +1130,13 @@ static void _sde_crtc_program_lm_output_roi(struct drm_crtc *crtc)
|
|||||||
|
|
||||||
lm_roi = &crtc_state->lm_roi[lm_idx];
|
lm_roi = &crtc_state->lm_roi[lm_idx];
|
||||||
hw_lm = sde_crtc->mixers[lm_idx].hw_lm;
|
hw_lm = sde_crtc->mixers[lm_idx].hw_lm;
|
||||||
|
if (!sde_crtc->mixers_swapped)
|
||||||
right_mixer = lm_idx % MAX_MIXERS_PER_LAYOUT;
|
right_mixer = lm_idx % MAX_MIXERS_PER_LAYOUT;
|
||||||
|
|
||||||
SDE_EVT32(DRMID(crtc_state->base.crtc), lm_idx,
|
SDE_EVT32(DRMID(crtc_state->base.crtc), lm_idx,
|
||||||
lm_roi->x, lm_roi->y, lm_roi->w, lm_roi->h,
|
lm_roi->x, lm_roi->y, lm_roi->w, lm_roi->h,
|
||||||
right_mixer);
|
right_mixer);
|
||||||
|
|
||||||
if (sde_kms_rect_is_null(lm_roi))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
hw_lm->cfg.out_width = lm_roi->w;
|
hw_lm->cfg.out_width = lm_roi->w;
|
||||||
hw_lm->cfg.out_height = lm_roi->h;
|
hw_lm->cfg.out_height = lm_roi->h;
|
||||||
hw_lm->cfg.right_mixer = right_mixer;
|
hw_lm->cfg.right_mixer = right_mixer;
|
||||||
@@ -1664,13 +1665,8 @@ static void _sde_crtc_blend_setup(struct drm_crtc *crtc,
|
|||||||
ctl = mixer[i].hw_ctl;
|
ctl = mixer[i].hw_ctl;
|
||||||
lm = mixer[i].hw_lm;
|
lm = mixer[i].hw_lm;
|
||||||
|
|
||||||
if (sde_kms_rect_is_null(lm_roi)) {
|
if (sde_kms_rect_is_null(lm_roi))
|
||||||
SDE_DEBUG(
|
sde_crtc->mixers[i].mixer_op_mode = 0;
|
||||||
"%s: lm%d leave ctl%d mask 0 since null roi\n",
|
|
||||||
sde_crtc->name, lm->idx - LM_0,
|
|
||||||
ctl->idx - CTL_0);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
lm->ops.setup_alpha_out(lm, mixer[i].mixer_op_mode);
|
lm->ops.setup_alpha_out(lm, mixer[i].mixer_op_mode);
|
||||||
|
|
||||||
@@ -1684,9 +1680,18 @@ static void _sde_crtc_blend_setup(struct drm_crtc *crtc,
|
|||||||
ctl->idx - CTL_0,
|
ctl->idx - CTL_0,
|
||||||
cfg.pending_flush_mask);
|
cfg.pending_flush_mask);
|
||||||
|
|
||||||
|
if (sde_kms_rect_is_null(lm_roi)) {
|
||||||
|
SDE_DEBUG(
|
||||||
|
"%s: lm%d leave ctl%d mask 0 since null roi\n",
|
||||||
|
sde_crtc->name, lm->idx - LM_0,
|
||||||
|
ctl->idx - CTL_0);
|
||||||
|
ctl->ops.setup_blendstage(ctl, mixer[i].hw_lm->idx,
|
||||||
|
NULL);
|
||||||
|
} else {
|
||||||
ctl->ops.setup_blendstage(ctl, mixer[i].hw_lm->idx,
|
ctl->ops.setup_blendstage(ctl, mixer[i].hw_lm->idx,
|
||||||
&sde_crtc->stage_cfg[lm_layout]);
|
&sde_crtc->stage_cfg[lm_layout]);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_sde_crtc_program_lm_output_roi(crtc);
|
_sde_crtc_program_lm_output_roi(crtc);
|
||||||
}
|
}
|
||||||
|
@@ -326,11 +326,11 @@ static int _dce_dsc_setup_single(struct sde_encoder_virt *sde_enc,
|
|||||||
hw_ctl = sde_enc->cur_master->hw_ctl;
|
hw_ctl = sde_enc->cur_master->hw_ctl;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* in 3d_merge and half_panel partial update dsc should be
|
* in 3d_merge or half_panel partial update, dsc should be
|
||||||
* bound to the pp which is driving the update, else in
|
* bound to the pp which is driving the update, else in
|
||||||
* 3d_merge dsc should be bound to left side of the pipe
|
* 3d_merge dsc should be bound to left side of the pipe
|
||||||
*/
|
*/
|
||||||
if (merge_3d && half_panel_partial_update)
|
if (merge_3d || half_panel_partial_update)
|
||||||
hw_pp = (active) ? sde_enc->hw_pp[0] : sde_enc->hw_pp[1];
|
hw_pp = (active) ? sde_enc->hw_pp[0] : sde_enc->hw_pp[1];
|
||||||
else
|
else
|
||||||
hw_pp = sde_enc->hw_pp[index];
|
hw_pp = sde_enc->hw_pp[index];
|
||||||
@@ -346,9 +346,9 @@ static int _dce_dsc_setup_single(struct sde_encoder_virt *sde_enc,
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDE_EVT32(DRMID(&sde_enc->base), roi->w, roi->h,
|
SDE_EVT32(DRMID(&sde_enc->base), roi->w, roi->h, dsc_common_mode,
|
||||||
dsc_common_mode, index, active, merge_3d,
|
index, active, merge_3d, disable_merge_3d,
|
||||||
disable_merge_3d, dsc_4hsmerge);
|
dsc_4hsmerge);
|
||||||
|
|
||||||
_dce_dsc_pipe_cfg(hw_dsc, hw_pp, dsc, dsc_common_mode, ich_res,
|
_dce_dsc_pipe_cfg(hw_dsc, hw_pp, dsc, dsc_common_mode, ich_res,
|
||||||
hw_dsc_pp, mode_3d, disable_merge_3d, active,
|
hw_dsc_pp, mode_3d, disable_merge_3d, active,
|
||||||
@@ -362,11 +362,12 @@ static int _dce_dsc_setup_single(struct sde_encoder_virt *sde_enc,
|
|||||||
|
|
||||||
if (hw_ctl->ops.update_bitmask)
|
if (hw_ctl->ops.update_bitmask)
|
||||||
hw_ctl->ops.update_bitmask(hw_ctl, SDE_HW_FLUSH_DSC,
|
hw_ctl->ops.update_bitmask(hw_ctl, SDE_HW_FLUSH_DSC,
|
||||||
hw_dsc->idx, active);
|
hw_dsc->idx, true);
|
||||||
|
|
||||||
SDE_DEBUG_DCE(sde_enc, "update_intf_cfg hw_ctl[%d], dsc:%d, %s",
|
SDE_DEBUG_DCE(sde_enc, "update_intf_cfg hw_ctl[%d], dsc:%d, %s %d\n",
|
||||||
hw_ctl->idx, cfg.dsc[0],
|
hw_ctl->idx, cfg.dsc[0],
|
||||||
active ? "enabled" : "disabled");
|
active ? "enabled" : "disabled",
|
||||||
|
half_panel_partial_update);
|
||||||
|
|
||||||
if (mode_3d) {
|
if (mode_3d) {
|
||||||
memset(&cfg, 0, sizeof(cfg));
|
memset(&cfg, 0, sizeof(cfg));
|
||||||
@@ -428,6 +429,7 @@ static int _dce_dsc_setup_helper(struct sde_encoder_virt *sde_enc,
|
|||||||
|
|
||||||
half_panel_partial_update = _dce_check_half_panel_update(num_lm,
|
half_panel_partial_update = _dce_check_half_panel_update(num_lm,
|
||||||
affected_displays);
|
affected_displays);
|
||||||
|
dsc->half_panel_pu = half_panel_partial_update;
|
||||||
dsc_merge = ((num_dsc > num_intf) && !half_panel_partial_update) ?
|
dsc_merge = ((num_dsc > num_intf) && !half_panel_partial_update) ?
|
||||||
true : false;
|
true : false;
|
||||||
disable_merge_3d = (merge_3d && half_panel_partial_update) ?
|
disable_merge_3d = (merge_3d && half_panel_partial_update) ?
|
||||||
|
@@ -115,8 +115,11 @@ static void sde_hw_dsc_disable(struct sde_hw_dsc *hw_dsc)
|
|||||||
dsc_c = &hw_dsc->hw;
|
dsc_c = &hw_dsc->hw;
|
||||||
SDE_REG_WRITE(dsc_c, DSC_CFG + idx, 0);
|
SDE_REG_WRITE(dsc_c, DSC_CFG + idx, 0);
|
||||||
|
|
||||||
/* common register */
|
if (_dsc_subblk_offset(hw_dsc, SDE_DSC_ENC, &idx))
|
||||||
SDE_REG_WRITE(dsc_c, DSC_CMN_MAIN_CNF, 0);
|
return;
|
||||||
|
|
||||||
|
SDE_REG_WRITE(dsc_c, ENC_DF_CTRL + idx, 0);
|
||||||
|
SDE_REG_WRITE(dsc_c, DSC_MAIN_CONF + idx, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sde_hw_dsc_config(struct sde_hw_dsc *hw_dsc,
|
static void sde_hw_dsc_config(struct sde_hw_dsc *hw_dsc,
|
||||||
@@ -140,15 +143,14 @@ static void sde_hw_dsc_config(struct sde_hw_dsc *hw_dsc,
|
|||||||
if (mode & DSC_MODE_SPLIT_PANEL)
|
if (mode & DSC_MODE_SPLIT_PANEL)
|
||||||
data |= BIT(0);
|
data |= BIT(0);
|
||||||
|
|
||||||
if (mode & DSC_MODE_MULTIPLEX) {
|
if (mode & DSC_MODE_MULTIPLEX)
|
||||||
|
data |= BIT(1);
|
||||||
|
|
||||||
if (dsc->dsc_4hsmerge_en)
|
if (dsc->dsc_4hsmerge_en)
|
||||||
slice_count_per_enc = dsc->config.slice_count >> 2;
|
slice_count_per_enc = dsc->config.slice_count >> 2;
|
||||||
else
|
else if ((mode & DSC_MODE_MULTIPLEX) || (dsc->half_panel_pu))
|
||||||
slice_count_per_enc = dsc->config.slice_count >> 1;
|
slice_count_per_enc = dsc->config.slice_count >> 1;
|
||||||
|
|
||||||
data |= BIT(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
data |= (slice_count_per_enc & 0x3) << 7;
|
data |= (slice_count_per_enc & 0x3) << 7;
|
||||||
SDE_REG_WRITE(dsc_c, DSC_CMN_MAIN_CNF, data);
|
SDE_REG_WRITE(dsc_c, DSC_CMN_MAIN_CNF, data);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user