소스 검색

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 <[email protected]>
Christopher Braga 5 년 전
부모
커밋
e5383fac2e
2개의 변경된 파일36개의 추가작업 그리고 15개의 파일을 삭제
  1. 33 5
      msm/sde/sde_color_processing.c
  2. 3 10
      msm/sde/sde_hw_reg_dma_v1_color_proc.c

+ 33 - 5
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);
+			}
 		}
 	}
 }

+ 3 - 10
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);