From e5383fac2e11713e5546a9871674dd9f99900eab Mon Sep 17 00:00:00 2001 From: Christopher Braga Date: Wed, 29 Jan 2020 16:20:13 -0500 Subject: [PATCH] drm: msm: sde: Centralize last command logic for SB DMA The original SB DMA last command logic results in multi feature sets being applied across different frames. Update the SB DMA logic to do a single last command per CTL path to ensure all features using SB DMA can get applied in the same frame. Change-Id: Ida837765c0f018b0e03afb0a33ece625a0df81eb Signed-off-by: Christopher Braga --- msm/sde/sde_color_processing.c | 38 ++++++++++++++++++++++---- msm/sde/sde_hw_reg_dma_v1_color_proc.c | 13 ++------- 2 files changed, 36 insertions(+), 15 deletions(-) diff --git a/msm/sde/sde_color_processing.c b/msm/sde/sde_color_processing.c index afee013825f5..7f07222cd342 100644 --- a/msm/sde/sde_color_processing.c +++ b/msm/sde/sde_color_processing.c @@ -1376,11 +1376,31 @@ static const int dspp_feature_to_sub_blk_tbl[SDE_CP_CRTC_MAX_FEATURES] = { [SDE_CP_CRTC_LM_GC] = SDE_DSPP_MAX, }; +static void _flush_sb_dma_hw(int *active_ctls, struct sde_hw_ctl *ctl, + u32 list_size) +{ + //For each CTL send last CD to SB DMA only once. + u32 j; + struct sde_hw_reg_dma_ops *dma_ops = sde_reg_dma_get_ops(); + + for (j = 0; j < list_size; j++) { + if (active_ctls[j] == ctl->idx) { + break; + } else if (active_ctls[j] == 0) { + active_ctls[j] = ctl->idx; + dma_ops->last_command_sb(ctl, DMA_CTL_QUEUE1, + REG_DMA_NOWAIT); + break; + } + } +} + void sde_cp_dspp_flush_helper(struct sde_crtc *sde_crtc, u32 feature) { u32 i, sub_blk, num_mixers; struct sde_hw_dspp *dspp; struct sde_hw_ctl *ctl; + int active_ctls[CTL_MAX - CTL_0]; if (!sde_crtc || feature >= SDE_CP_CRTC_MAX_FEATURES) { SDE_ERROR("invalid args: sde_crtc %s for feature %d", @@ -1390,16 +1410,24 @@ void sde_cp_dspp_flush_helper(struct sde_crtc *sde_crtc, u32 feature) num_mixers = sde_crtc->num_mixers; sub_blk = dspp_feature_to_sub_blk_tbl[feature]; + memset(&active_ctls, 0, sizeof(active_ctls)); for (i = 0; i < num_mixers; i++) { ctl = sde_crtc->mixers[i].hw_ctl; dspp = sde_crtc->mixers[i].hw_dspp; if (ctl && ctl->ops.update_bitmask_dspp_subblk) { - if (feature == SDE_CP_CRTC_DSPP_SB && - !dspp->sb_dma_in_use) - continue; - ctl->ops.update_bitmask_dspp_subblk( - ctl, dspp->idx, sub_blk, true); + if (feature == SDE_CP_CRTC_DSPP_SB) { + if (!dspp->sb_dma_in_use) + continue; + + _flush_sb_dma_hw(active_ctls, ctl, + sizeof(active_ctls)); + ctl->ops.update_bitmask_dspp_subblk(ctl, + dspp->idx, sub_blk, true); + } else { + ctl->ops.update_bitmask_dspp_subblk(ctl, + dspp->idx, sub_blk, true); + } } } } diff --git a/msm/sde/sde_hw_reg_dma_v1_color_proc.c b/msm/sde/sde_hw_reg_dma_v1_color_proc.c index 3a0d8d8e6fb6..0cc78e1ccf39 100644 --- a/msm/sde/sde_hw_reg_dma_v1_color_proc.c +++ b/msm/sde/sde_hw_reg_dma_v1_color_proc.c @@ -3839,16 +3839,9 @@ static void _perform_sbdma_kickoff(struct sde_hw_dspp *ctx, kick_off.dma_type = REG_DMA_TYPE_SB; rc = dma_ops->kick_off(&kick_off); if (!rc) { - rc = dma_ops->last_command_sb(hw_cfg->ctl, DMA_CTL_QUEUE1, - REG_DMA_NOWAIT); - if (rc) { - DRM_ERROR("failed to call last_command_sb ret %d\n", - rc); - } else { - for (i = 0; i < hw_cfg->num_of_mixers; ++i) { - if (blk & dspp_mapping[hw_cfg->dspp[i]->idx]) - hw_cfg->dspp[i]->sb_dma_in_use = true; - } + for (i = 0; i < hw_cfg->num_of_mixers; i++) { + if (blk & dspp_mapping[hw_cfg->dspp[i]->idx]) + hw_cfg->dspp[i]->sb_dma_in_use = true; } } else if (rc == -EOPNOTSUPP) { DRM_DEBUG("Falling back to dbdma\n", rc);