Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 572cfd20 authored by Dhaval Patel's avatar Dhaval Patel
Browse files

drm/msm/sde: stage source pipes on both layer mixer for src_split



The source split requires to stage each source pipe on both
layer mixers. The SDE hardware layer mixer hangs if left only
pipe is not staged on right layer mixer when same stage has
layer mixer crossing source split pipe. This change stages
all the pipes on both layer mixers to avoid layer mixer hang
issue.

Change-Id: Ie5c3361c8cada4e8bafd7a8842a908843d611019
Signed-off-by: default avatarDhaval Patel <pdhaval@codeaurora.org>
parent 4784ec24
Loading
Loading
Loading
Loading
+22 −38
Original line number Diff line number Diff line
@@ -1113,10 +1113,10 @@ static void _sde_crtc_blend_setup_mixer(struct drm_crtc *crtc,
	struct sde_rect plane_crtc_roi;

	u32 flush_mask, flush_sbuf, flush_tmp;
	uint32_t lm_idx = LEFT_MIXER, stage_idx;
	bool bg_alpha_enable[CRTC_DUAL_MIXERS] = {false};
	int zpos_cnt[CRTC_DUAL_MIXERS][SDE_STAGE_MAX + 1] = { {0} };
	uint32_t stage_idx, lm_idx;
	int zpos_cnt[SDE_STAGE_MAX + 1] = { 0 };
	int i;
	bool bg_alpha_enable = false;
	u32 prefill = 0;

	if (!sde_crtc || !mixer) {
@@ -1166,6 +1166,8 @@ static void _sde_crtc_blend_setup_mixer(struct drm_crtc *crtc,
				state->fb ? state->fb->base.id : -1);

		format = to_sde_format(msm_framebuffer_format(pstate->base.fb));
		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,
@@ -1175,46 +1177,28 @@ static void _sde_crtc_blend_setup_mixer(struct drm_crtc *crtc,
				state->crtc_w, state->crtc_h,
				cstate->sbuf_cfg.rot_op_mode);

		for (lm_idx = 0; lm_idx < sde_crtc->num_mixers; lm_idx++) {
			struct sde_rect intersect;

			/* skip if the roi doesn't fall within LM's bounds */
			sde_kms_rect_intersect(&plane_crtc_roi,
					&cstate->lm_bounds[lm_idx],
					&intersect);
			if (sde_kms_rect_is_null(&intersect))
				continue;

			stage_idx = zpos_cnt[lm_idx][pstate->stage]++;
			stage_cfg->stage[lm_idx][pstate->stage][stage_idx] =
		stage_idx = zpos_cnt[pstate->stage]++;
		stage_cfg->stage[pstate->stage][stage_idx] =
					sde_plane_pipe(plane);
			stage_cfg->multirect_index
					[lm_idx][pstate->stage][stage_idx] =
		stage_cfg->multirect_index[pstate->stage][stage_idx] =
					pstate->multirect_index;

			mixer[lm_idx].flush_mask |= flush_mask;


			SDE_EVT32(DRMID(plane), DRMID(crtc), lm_idx, stage_idx,
				pstate->stage, pstate->multirect_index,
				pstate->multirect_mode,
				format->base.pixel_format,
				fb ? fb->modifier[0] : 0);
		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] : 0);

		/* blend config update */
			if (pstate->stage != SDE_STAGE_BASE) {
				_sde_crtc_setup_blend_cfg(mixer + lm_idx,
						pstate, format);
		for (lm_idx = 0; lm_idx < sde_crtc->num_mixers; lm_idx++) {
			_sde_crtc_setup_blend_cfg(mixer + lm_idx, pstate,
								format);
			mixer[lm_idx].flush_mask |= flush_mask;

				if (bg_alpha_enable[lm_idx] &&
						!format->alpha_enable)
			if (bg_alpha_enable && !format->alpha_enable)
				mixer[lm_idx].mixer_op_mode = 0;
			else
				mixer[lm_idx].mixer_op_mode |=
						1 << pstate->stage;
			} else if (format->alpha_enable) {
				bg_alpha_enable[lm_idx] = true;
			}
		}
	}

@@ -1377,7 +1361,7 @@ static void _sde_crtc_blend_setup(struct drm_crtc *crtc)
			mixer[i].flush_mask);

		ctl->ops.setup_blendstage(ctl, mixer[i].hw_lm->idx,
			&sde_crtc->stage_cfg, i);
			&sde_crtc->stage_cfg);
	}

	_sde_crtc_program_lm_output_roi(crtc);
+1 −2
Original line number Diff line number Diff line
@@ -2217,8 +2217,7 @@ int sde_encoder_helper_hw_release(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, 0, 0);
					phys_enc->hw_ctl, hw_lm->idx, NULL);
	}

	if (!lm_valid) {
+3 −6
Original line number Diff line number Diff line
@@ -354,7 +354,7 @@ 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, u32 index)
	enum sde_lm lm, struct sde_hw_stage_cfg *stage_cfg)
{
	struct sde_hw_blk_reg_map *c = &ctx->hw;
	u32 mixercfg = 0, mixercfg_ext = 0, mix, ext;
@@ -363,9 +363,6 @@ static void sde_hw_ctl_setup_blendstage(struct sde_hw_ctl *ctx,
	u8 stages;
	int pipes_per_stage;

	if (index >= CRTC_DUAL_MIXERS)
		return;

	stages = _mixer_stages(ctx->mixer_hw_caps, ctx->mixer_count, lm);
	if (stages < 0)
		return;
@@ -388,9 +385,9 @@ static void sde_hw_ctl_setup_blendstage(struct sde_hw_ctl *ctx,

		for (j = 0 ; j < pipes_per_stage; j++) {
			enum sde_sspp_multirect_index rect_index =
				stage_cfg->multirect_index[index][i][j];
				stage_cfg->multirect_index[i][j];

			switch (stage_cfg->stage[index][i][j]) {
			switch (stage_cfg->stage[i][j]) {
			case SSPP_VIG0:
				if (rect_index == SDE_SSPP_RECT_1) {
					mixercfg_ext3 |= ((i + 1) & 0xF) << 0;
+3 −3
Original line number Diff line number Diff line
@@ -49,8 +49,8 @@ struct sde_hw_ctl;
 * @multirect_index: index of the rectangle of SSPP.
 */
struct sde_hw_stage_cfg {
	enum sde_sspp stage[CRTC_DUAL_MIXERS][SDE_STAGE_MAX][PIPES_PER_STAGE];
	enum sde_sspp_multirect_index multirect_index[CRTC_DUAL_MIXERS]
	enum sde_sspp stage[SDE_STAGE_MAX][PIPES_PER_STAGE];
	enum sde_sspp_multirect_index multirect_index
					[SDE_STAGE_MAX][PIPES_PER_STAGE];
};

@@ -201,7 +201,7 @@ struct sde_hw_ctl_ops {
	 * @cfg       : blend stage configuration
	 */
	void (*setup_blendstage)(struct sde_hw_ctl *ctx,
		enum sde_lm lm, struct sde_hw_stage_cfg *cfg, u32 index);
		enum sde_lm lm, struct sde_hw_stage_cfg *cfg);

	void (*setup_sbuf_cfg)(struct sde_hw_ctl *ctx,
		struct sde_ctl_sbuf_cfg *cfg);
+2 −1
Original line number Diff line number Diff line
@@ -4291,7 +4291,8 @@ struct drm_plane *sde_plane_init(struct drm_device *dev,

	mutex_init(&psde->lock);

	SDE_DEBUG("%s created for pipe %u\n", psde->pipe_name, pipe);
	SDE_DEBUG("%s created for pipe:%u id:%u virtual:%u\n", psde->pipe_name,
					pipe, plane->base.id, master_plane_id);
	return plane;

clean_sspp: