Просмотр исходного кода

disp: msm: sde: update sspp multi rect programming

Current SDE driver allows staging of rect1 only configuration. When a
real plane is disabled sspp multi rect configuration is not updated.
This can lead to iommu faults and ping pong timeouts as framebuffer of
disabled plane is unmapped. This change fixes it by updating multi rect
config accordingly when a plane is disabled.

Change-Id: I67ae45ad0e607184c7fc49f4b220220ba1d8a2ae
Signed-off-by: Prabhanjan Kandula <[email protected]>
Prabhanjan Kandula 5 лет назад
Родитель
Сommit
f946219084
3 измененных файлов с 26 добавлено и 12 удалено
  1. 10 4
      msm/sde/sde_hw_sspp.c
  2. 4 2
      msm/sde/sde_hw_sspp.h
  3. 12 6
      msm/sde/sde_plane.c

+ 10 - 4
msm/sde/sde_hw_sspp.c

@@ -193,7 +193,8 @@ static inline int _sspp_subblk_offset(struct sde_hw_pipe *ctx,
 	return rc;
 }
 
-static void sde_hw_sspp_setup_multirect(struct sde_hw_pipe *ctx,
+static void sde_hw_sspp_update_multirect(struct sde_hw_pipe *ctx,
+		bool enable,
 		enum sde_sspp_multirect_index index,
 		enum sde_sspp_multirect_mode mode)
 {
@@ -212,8 +213,13 @@ static void sde_hw_sspp_setup_multirect(struct sde_hw_pipe *ctx,
 		mode_mask = 0;
 	} else {
 		mode_mask = SDE_REG_READ(&ctx->hw, SSPP_MULTIRECT_OPMODE + idx);
-		mode_mask |= index;
-		if (mode == SDE_SSPP_MULTIRECT_TIME_MX)
+
+		if (enable)
+			mode_mask |= index;
+		else
+			mode_mask &= ~index;
+
+		if (enable && (mode == SDE_SSPP_MULTIRECT_TIME_MX))
 			mode_mask |= BIT(2);
 		else
 			mode_mask &= ~BIT(2);
@@ -1232,7 +1238,7 @@ static void _setup_layer_ops(struct sde_hw_pipe *c,
 	}
 
 	if (sde_hw_sspp_multirect_enabled(c->cap))
-		c->ops.setup_multirect = sde_hw_sspp_setup_multirect;
+		c->ops.update_multirect = sde_hw_sspp_update_multirect;
 
 	if (test_bit(SDE_SSPP_SCALER_QSEED3, &features) ||
 			test_bit(SDE_SSPP_SCALER_QSEED3LITE, &features)) {

+ 4 - 2
msm/sde/sde_hw_sspp.h

@@ -370,13 +370,15 @@ struct sde_hw_sspp_ops {
 			enum sde_sspp_multirect_index index);
 
 	/**
-	 * setup_multirect - setup multirect configuration
+	 * update_multirect - update multirect configuration
 	 * @ctx: Pointer to pipe context
+	 * @enable: Boolean to indicate enable or disable of given config
 	 * @index: rectangle index in multirect
 	 * @mode: parallel fetch / time multiplex multirect mode
 	 */
 
-	void (*setup_multirect)(struct sde_hw_pipe *ctx,
+	void (*update_multirect)(struct sde_hw_pipe *ctx,
+			bool enable,
 			enum sde_sspp_multirect_index index,
 			enum sde_sspp_multirect_mode mode);
 

+ 12 - 6
msm/sde/sde_plane.c

@@ -3026,9 +3026,11 @@ static void _sde_plane_update_roi_config(struct drm_plane *plane,
 				&pstate->excl_rect,
 				pstate->multirect_index);
 
-	if (psde->pipe_hw->ops.setup_multirect)
-		psde->pipe_hw->ops.setup_multirect(
+	/* enable multirect config of corresponding rect */
+	if (psde->pipe_hw->ops.update_multirect)
+		psde->pipe_hw->ops.update_multirect(
 				psde->pipe_hw,
+				true,
 				pstate->multirect_index,
 				pstate->multirect_mode);
 }
@@ -3283,6 +3285,7 @@ static void _sde_plane_atomic_disable(struct drm_plane *plane,
 	struct sde_plane *psde;
 	struct drm_plane_state *state;
 	struct sde_plane_state *pstate;
+	u32 multirect_index = SDE_SSPP_RECT_0;
 
 	if (!plane) {
 		SDE_ERROR("invalid plane\n");
@@ -3304,10 +3307,13 @@ static void _sde_plane_atomic_disable(struct drm_plane *plane,
 
 	pstate->pending = true;
 
-	if (is_sde_plane_virtual(plane) &&
-			psde->pipe_hw && psde->pipe_hw->ops.setup_multirect)
-		psde->pipe_hw->ops.setup_multirect(psde->pipe_hw,
-				SDE_SSPP_RECT_SOLO, SDE_SSPP_MULTIRECT_NONE);
+	if (is_sde_plane_virtual(plane))
+		multirect_index = SDE_SSPP_RECT_1;
+
+	/* disable multirect config of corresponding rect */
+	if (psde->pipe_hw && psde->pipe_hw->ops.update_multirect)
+		psde->pipe_hw->ops.update_multirect(psde->pipe_hw, false,
+				multirect_index, SDE_SSPP_MULTIRECT_TIME_MX);
 }
 
 static void sde_plane_atomic_update(struct drm_plane *plane,