diff --git a/msm/msm_drv.h b/msm/msm_drv.h index 356fb6404c..64976cf982 100644 --- a/msm/msm_drv.h +++ b/msm/msm_drv.h @@ -369,6 +369,9 @@ struct msm_roi_caps { * @dsc_4hsmerge_en: Using DSC 4HS merge topology * @dsc_4hsmerge_padding 4HS merge DSC pair padding 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 drm_dsc_config config; @@ -390,6 +393,7 @@ struct msm_display_dsc_info { bool dsc_4hsmerge_en; u32 dsc_4hsmerge_padding; u32 dsc_4hsmerge_alignment; + bool half_panel_pu; }; diff --git a/msm/sde/sde_crtc.c b/msm/sde/sde_crtc.c index 932c931d46..c2a7cd44a5 100644 --- a/msm/sde/sde_crtc.c +++ b/msm/sde/sde_crtc.c @@ -896,9 +896,12 @@ static u32 _sde_crtc_get_displays_affected(struct drm_crtc *crtc, disp_bitmask = BIT(1); /* right only */ else disp_bitmask = BIT(0) | BIT(1); /* left and right */ + } else if (sde_crtc->mixers_swapped) { + disp_bitmask = BIT(0); } else { 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); } } @@ -1113,7 +1116,7 @@ static void _sde_crtc_program_lm_output_roi(struct drm_crtc *crtc) struct sde_crtc_state *crtc_state; const struct sde_rect *lm_roi; struct sde_hw_mixer *hw_lm; - bool right_mixer; + bool right_mixer = false; int lm_idx; 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]; hw_lm = sde_crtc->mixers[lm_idx].hw_lm; - right_mixer = lm_idx % MAX_MIXERS_PER_LAYOUT; + if (!sde_crtc->mixers_swapped) + right_mixer = lm_idx % MAX_MIXERS_PER_LAYOUT; SDE_EVT32(DRMID(crtc_state->base.crtc), lm_idx, lm_roi->x, lm_roi->y, lm_roi->w, lm_roi->h, right_mixer); - if (sde_kms_rect_is_null(lm_roi)) - continue; - hw_lm->cfg.out_width = lm_roi->w; hw_lm->cfg.out_height = lm_roi->h; 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; lm = mixer[i].hw_lm; - 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); - continue; - } + if (sde_kms_rect_is_null(lm_roi)) + sde_crtc->mixers[i].mixer_op_mode = 0; lm->ops.setup_alpha_out(lm, mixer[i].mixer_op_mode); @@ -1684,8 +1680,17 @@ static void _sde_crtc_blend_setup(struct drm_crtc *crtc, ctl->idx - CTL_0, cfg.pending_flush_mask); - ctl->ops.setup_blendstage(ctl, mixer[i].hw_lm->idx, - &sde_crtc->stage_cfg[lm_layout]); + 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, + &sde_crtc->stage_cfg[lm_layout]); + } } _sde_crtc_program_lm_output_roi(crtc); diff --git a/msm/sde/sde_encoder_dce.c b/msm/sde/sde_encoder_dce.c index ab93c486f3..e8f76b4187 100644 --- a/msm/sde/sde_encoder_dce.c +++ b/msm/sde/sde_encoder_dce.c @@ -326,11 +326,11 @@ static int _dce_dsc_setup_single(struct sde_encoder_virt *sde_enc, 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 * 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]; else 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; } - SDE_EVT32(DRMID(&sde_enc->base), roi->w, roi->h, - dsc_common_mode, index, active, merge_3d, - disable_merge_3d, dsc_4hsmerge); + SDE_EVT32(DRMID(&sde_enc->base), roi->w, roi->h, dsc_common_mode, + index, active, merge_3d, disable_merge_3d, + dsc_4hsmerge); _dce_dsc_pipe_cfg(hw_dsc, hw_pp, dsc, dsc_common_mode, ich_res, 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) 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], - active ? "enabled" : "disabled"); + active ? "enabled" : "disabled", + half_panel_partial_update); if (mode_3d) { 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, affected_displays); + dsc->half_panel_pu = half_panel_partial_update; dsc_merge = ((num_dsc > num_intf) && !half_panel_partial_update) ? true : false; disable_merge_3d = (merge_3d && half_panel_partial_update) ? diff --git a/msm/sde/sde_hw_dsc_1_2.c b/msm/sde/sde_hw_dsc_1_2.c index 38a2824fc6..29c41ba42e 100644 --- a/msm/sde/sde_hw_dsc_1_2.c +++ b/msm/sde/sde_hw_dsc_1_2.c @@ -115,8 +115,11 @@ static void sde_hw_dsc_disable(struct sde_hw_dsc *hw_dsc) dsc_c = &hw_dsc->hw; SDE_REG_WRITE(dsc_c, DSC_CFG + idx, 0); - /* common register */ - SDE_REG_WRITE(dsc_c, DSC_CMN_MAIN_CNF, 0); + if (_dsc_subblk_offset(hw_dsc, SDE_DSC_ENC, &idx)) + 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, @@ -140,14 +143,13 @@ static void sde_hw_dsc_config(struct sde_hw_dsc *hw_dsc, if (mode & DSC_MODE_SPLIT_PANEL) data |= BIT(0); - if (mode & DSC_MODE_MULTIPLEX) { - if (dsc->dsc_4hsmerge_en) - slice_count_per_enc = dsc->config.slice_count >> 2; - else - slice_count_per_enc = dsc->config.slice_count >> 1; - + if (mode & DSC_MODE_MULTIPLEX) data |= BIT(1); - } + + if (dsc->dsc_4hsmerge_en) + slice_count_per_enc = dsc->config.slice_count >> 2; + else if ((mode & DSC_MODE_MULTIPLEX) || (dsc->half_panel_pu)) + slice_count_per_enc = dsc->config.slice_count >> 1; data |= (slice_count_per_enc & 0x3) << 7; SDE_REG_WRITE(dsc_c, DSC_CMN_MAIN_CNF, data);