瀏覽代碼

disp: msm: add support for no blend planes

Some of the features in the DPU hardware needs planes to be staged but
it should not be blended in the layer mixer. Change adds support for drm
driver client to set the blend type on the plane and updates driver code
to skip staging the plane.

Change-Id: I1e8c7f6ce5617820ea8b24419e0d4d27b481819b
Signed-off-by: Gopikrishnaiah Anandan <[email protected]>
Gopikrishnaiah Anandan 5 年之前
父節點
當前提交
078d42797b
共有 6 個文件被更改,包括 98 次插入37 次删除
  1. 76 33
      msm/sde/sde_crtc.c
  2. 2 0
      msm/sde/sde_crtc.h
  3. 1 1
      msm/sde/sde_encoder.c
  4. 14 1
      msm/sde/sde_hw_ctl.c
  5. 3 1
      msm/sde/sde_hw_ctl.h
  6. 2 1
      msm/sde/sde_plane.c

+ 76 - 33
msm/sde/sde_crtc.c

@@ -93,6 +93,8 @@ static struct sde_crtc_custom_events custom_events[] = {
 #define MAX_FRAME_COUNT			1000
 #define MILI_TO_MICRO			1000
 
+#define SKIP_STAGING_PIPE_ZPOS		255
+
 static inline struct sde_kms *_sde_crtc_get_kms(struct drm_crtc *crtc)
 {
 	struct msm_drm_private *priv;
@@ -491,6 +493,11 @@ static void _sde_crtc_setup_blend_cfg(struct sde_crtc_mixer *mixer,
 			}
 		}
 		break;
+
+	case SDE_DRM_BLEND_OP_SKIP:
+		SDE_ERROR("skip the blending for plane\n");
+		return;
+
 	default:
 		/* do nothing */
 		break;
@@ -1326,6 +1333,24 @@ static void _sde_crtc_set_src_split_order(struct drm_crtc *crtc,
 			cur_pstate->sde_pstate->pipe_order_flags);
 	}
 }
+
+static void __sde_crtc_assign_active_cfg(struct sde_crtc *sdecrtc,
+				struct drm_plane *plane)
+{
+	u8 found = 0;
+	int i;
+
+	for (i = 0; i < SDE_STAGE_MAX && !found; i++) {
+		if (sdecrtc->active_cfg.stage[i][0] == SSPP_NONE)
+			found = 1;
+	}
+	if (!found) {
+		SDE_ERROR("All active configs are allocated\n");
+		return;
+	}
+	sdecrtc->active_cfg.stage[i][0] = sde_plane_pipe(plane);
+}
+
 static void _sde_crtc_blend_setup_mixer(struct drm_crtc *crtc,
 		struct drm_crtc_state *old_state, struct sde_crtc *sde_crtc,
 		struct sde_crtc_mixer *mixer)
@@ -1345,6 +1370,7 @@ static void _sde_crtc_blend_setup_mixer(struct drm_crtc *crtc,
 	int zpos_cnt[SDE_STAGE_MAX + 1] = { 0 };
 	int i, cnt = 0;
 	bool bg_alpha_enable = false;
+	u32 blend_type;
 
 	if (!sde_crtc || !crtc->state || !mixer) {
 		SDE_ERROR("invalid sde_crtc or mixer\n");
@@ -1388,38 +1414,50 @@ static void _sde_crtc_blend_setup_mixer(struct drm_crtc *crtc,
 			goto end;
 		}
 
-		if (pstate->stage == SDE_STAGE_BASE && format->alpha_enable)
-			bg_alpha_enable = true;
-
-		SDE_EVT32(DRMID(crtc), DRMID(plane),
-				state->fb ? state->fb->base.id : -1,
-				state->src_x >> 16, state->src_y >> 16,
-				state->src_w >> 16, state->src_h >> 16,
-				state->crtc_x, state->crtc_y,
-				state->crtc_w, state->crtc_h,
-				pstate->rotation);
-
-		stage_idx = zpos_cnt[pstate->stage]++;
-		stage_cfg->stage[pstate->stage][stage_idx] =
-					sde_plane_pipe(plane);
-		stage_cfg->multirect_index[pstate->stage][stage_idx] =
-					pstate->multirect_index;
-
-		SDE_EVT32(DRMID(crtc), DRMID(plane), stage_idx,
-			sde_plane_pipe(plane) - SSPP_VIG0, pstate->stage,
-			pstate->multirect_index, pstate->multirect_mode,
-			format->base.pixel_format, fb ? fb->modifier : 0);
-
-		/* blend config update */
-		for (lm_idx = 0; lm_idx < sde_crtc->num_mixers; lm_idx++) {
-			_sde_crtc_setup_blend_cfg(mixer + lm_idx, pstate,
-								format);
+		blend_type = sde_plane_get_property(pstate,
+					PLANE_PROP_BLEND_OP);
 
-			if (bg_alpha_enable && !format->alpha_enable)
-				mixer[lm_idx].mixer_op_mode = 0;
-			else
-				mixer[lm_idx].mixer_op_mode |=
-						1 << pstate->stage;
+		if (blend_type == SDE_DRM_BLEND_OP_SKIP) {
+			__sde_crtc_assign_active_cfg(sde_crtc, plane);
+		} else {
+			if (pstate->stage == SDE_STAGE_BASE &&
+					format->alpha_enable)
+				bg_alpha_enable = true;
+
+			SDE_EVT32(DRMID(crtc), DRMID(plane),
+					state->fb ? state->fb->base.id : -1,
+					state->src_x >> 16, state->src_y >> 16,
+					state->src_w >> 16, state->src_h >> 16,
+					state->crtc_x, state->crtc_y,
+					state->crtc_w, state->crtc_h,
+					pstate->rotation);
+
+			stage_idx = zpos_cnt[pstate->stage]++;
+			stage_cfg->stage[pstate->stage][stage_idx] =
+						sde_plane_pipe(plane);
+			stage_cfg->multirect_index[pstate->stage][stage_idx] =
+						pstate->multirect_index;
+
+			SDE_EVT32(DRMID(crtc), DRMID(plane), stage_idx,
+				sde_plane_pipe(plane) - SSPP_VIG0,
+				pstate->stage,
+				pstate->multirect_index,
+				pstate->multirect_mode,
+				format->base.pixel_format,
+				fb ? fb->modifier : 0);
+
+			/* blend config update */
+			for (lm_idx = 0; lm_idx < sde_crtc->num_mixers;
+							lm_idx++) {
+				_sde_crtc_setup_blend_cfg(mixer + lm_idx,
+						pstate, format);
+
+				if (bg_alpha_enable && !format->alpha_enable)
+					mixer[lm_idx].mixer_op_mode = 0;
+				else
+					mixer[lm_idx].mixer_op_mode |=
+							1 << pstate->stage;
+			}
 		}
 
 		if (cnt >= SDE_PSTATES_MAX)
@@ -1427,7 +1465,11 @@ static void _sde_crtc_blend_setup_mixer(struct drm_crtc *crtc,
 
 		pstates[cnt].sde_pstate = pstate;
 		pstates[cnt].drm_pstate = state;
-		pstates[cnt].stage = sde_plane_get_property(
+
+		if (blend_type == SDE_DRM_BLEND_OP_SKIP)
+			pstates[cnt].stage = SKIP_STAGING_PIPE_ZPOS;
+		else
+			pstates[cnt].stage = sde_plane_get_property(
 				pstates[cnt].sde_pstate, PLANE_PROP_ZPOS);
 		pstates[cnt].pipe_id = sde_plane_pipe(plane);
 
@@ -1562,6 +1604,7 @@ static void _sde_crtc_blend_setup(struct drm_crtc *crtc,
 
 	/* initialize stage cfg */
 	memset(&sde_crtc->stage_cfg, 0, sizeof(struct sde_hw_stage_cfg));
+	memset(&sde_crtc->active_cfg, 0, sizeof(sde_crtc->active_cfg));
 
 	if (add_planes)
 		_sde_crtc_blend_setup_mixer(crtc, old_state, sde_crtc, mixer);
@@ -1593,7 +1636,7 @@ static void _sde_crtc_blend_setup(struct drm_crtc *crtc,
 			cfg.pending_flush_mask);
 
 		ctl->ops.setup_blendstage(ctl, mixer[i].hw_lm->idx,
-			&sde_crtc->stage_cfg);
+			&sde_crtc->stage_cfg, &sde_crtc->active_cfg);
 	}
 
 	_sde_crtc_program_lm_output_roi(crtc);

+ 2 - 0
msm/sde/sde_crtc.h

@@ -207,6 +207,7 @@ struct sde_crtc_misr_info {
  * @property_defaults : Array of default values for generic property support
  * @output_fence  : output release fence context
  * @stage_cfg     : H/w mixer stage configuration
+ * @active_cfg    : H/w pipes active that shouldn't be staged
  * @debugfs_root  : Parent of debugfs node
  * @priv_handle   : Pointer to external private handle, if present
  * @vblank_cb_count : count of vblank callback since last reset
@@ -275,6 +276,7 @@ struct sde_crtc {
 	struct sde_fence_context *output_fence;
 
 	struct sde_hw_stage_cfg stage_cfg;
+	struct sde_hw_stage_cfg active_cfg;
 	struct dentry *debugfs_root;
 	void *priv_handle;
 

+ 1 - 1
msm/sde/sde_encoder.c

@@ -4178,7 +4178,7 @@ int sde_encoder_helper_reset_mixers(struct sde_encoder_phys *phys_enc,
 		/* only enable border color on LM */
 		if (phys_enc->hw_ctl->ops.setup_blendstage)
 			phys_enc->hw_ctl->ops.setup_blendstage(
-					phys_enc->hw_ctl, hw_lm->idx, NULL);
+				phys_enc->hw_ctl, hw_lm->idx, NULL, NULL);
 	}
 
 	if (!lm_valid) {

+ 14 - 1
msm/sde/sde_hw_ctl.c

@@ -806,7 +806,8 @@ static void sde_hw_ctl_clear_all_blendstages(struct sde_hw_ctl *ctx)
 }
 
 static void sde_hw_ctl_setup_blendstage(struct sde_hw_ctl *ctx,
-	enum sde_lm lm, struct sde_hw_stage_cfg *stage_cfg)
+	enum sde_lm lm, struct sde_hw_stage_cfg *stage_cfg,
+	struct sde_hw_stage_cfg *active_cfg)
 {
 	struct sde_hw_blk_reg_map *c;
 	u32 mixercfg = 0, mixercfg_ext = 0, mix, ext;
@@ -939,6 +940,18 @@ static void sde_hw_ctl_setup_blendstage(struct sde_hw_ctl *ctx,
 		}
 	}
 
+	for (i = 0; i <= stages && active_cfg; i++) {
+		enum sde_sspp pipe = active_cfg->stage[i][0];
+
+		if (pipe == SSPP_NONE)
+			break;
+		if (fetch_tbl[pipe] != CTL_INVALID_BIT) {
+			active_fetch_pipes |= BIT(fetch_tbl[pipe]);
+			SDE_DEBUG("fetch pipe %d active pipes %x\n",
+				pipe, active_fetch_pipes);
+		}
+	}
+
 exit:
 	if ((!mixercfg && !mixercfg_ext && !mixercfg_ext2 && !mixercfg_ext3) ||
 			(stage_cfg && !stage_cfg->stage[0][0]))

+ 3 - 1
msm/sde/sde_hw_ctl.h

@@ -426,9 +426,11 @@ struct sde_hw_ctl_ops {
 	 * @ctx       : ctl path ctx pointer
 	 * @lm        : layer mixer enumeration
 	 * @cfg       : blend stage configuration
+	 * @active_cfg: active no blend stage configuration
 	 */
 	void (*setup_blendstage)(struct sde_hw_ctl *ctx,
-		enum sde_lm lm, struct sde_hw_stage_cfg *cfg);
+		enum sde_lm lm, struct sde_hw_stage_cfg *cfg,
+		struct sde_hw_stage_cfg *active_cfg);
 
 	/**
 	 * Get all the sspp staged on a layer mixer

+ 2 - 1
msm/sde/sde_plane.c

@@ -3421,7 +3421,8 @@ static void _sde_plane_install_properties(struct drm_plane *plane,
 		{SDE_DRM_BLEND_OP_NOT_DEFINED,    "not_defined"},
 		{SDE_DRM_BLEND_OP_OPAQUE,         "opaque"},
 		{SDE_DRM_BLEND_OP_PREMULTIPLIED,  "premultiplied"},
-		{SDE_DRM_BLEND_OP_COVERAGE,       "coverage"}
+		{SDE_DRM_BLEND_OP_COVERAGE,       "coverage"},
+		{SDE_DRM_BLEND_OP_SKIP,           "skip_blending"},
 	};
 	static const struct drm_prop_enum_list e_src_config[] = {
 		{SDE_DRM_DEINTERLACE, "deinterlace"}