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

Commit 1d9dd22e authored by Narendra Muppalla's avatar Narendra Muppalla Committed by Gerrit - the friendly Code Review server
Browse files

drm/msm/sde: reset clt path after timing engine disabled



For MDP rev 5.0, CTL path reset is required after timing engine
is disabled for video mode interface. The reset includes 3d_merge,
active_intf, layer mixer and ctl path after timing engine is
disabled. This reset call does not need to wait for vsync because
timing engine is already disabled. It may lead to continuous underrun
if reset sequence is not followed and same ctl path is used for
different resolution display.

Change-Id: I06492a0c12e860616aa09e462e34717592f2f9e3
Signed-off-by: default avatarNarendra Muppalla <NarendraM@codeaurora.org>
parent 4163908c
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -959,6 +959,20 @@ static void sde_encoder_phys_vid_disable(struct sde_encoder_phys *phys_enc)
		}
		sde_encoder_phys_vid_control_vblank_irq(phys_enc, false);
	}

	if (phys_enc->hw_intf->ops.bind_pingpong_blk)
		phys_enc->hw_intf->ops.bind_pingpong_blk(phys_enc->hw_intf,
				false, phys_enc->hw_pp->idx - PINGPONG_0);

	if (phys_enc->hw_pp && phys_enc->hw_pp->ops.reset_3d_mode)
		phys_enc->hw_pp->ops.reset_3d_mode(phys_enc->hw_pp);

	if (phys_enc->hw_pp && phys_enc->hw_pp->merge_3d &&
			phys_enc->hw_ctl->ops.reset_post_te_disable)
		phys_enc->hw_ctl->ops.reset_post_te_disable(
				phys_enc->hw_ctl, &phys_enc->intf_cfg_v1,
				phys_enc->hw_pp->merge_3d->idx);

exit:
	phys_enc->enable_state = SDE_ENC_DISABLED;
}
+43 −0
Original line number Diff line number Diff line
@@ -912,6 +912,48 @@ static int sde_hw_ctl_intf_cfg_v1(struct sde_hw_ctl *ctx,
	return 0;
}

static int sde_hw_ctl_reset_post_te_disable(struct sde_hw_ctl *ctx,
		struct sde_hw_intf_cfg_v1 *cfg, u32 merge_3d_idx)
{
	struct sde_hw_blk_reg_map *c;
	u32 intf_active = 0;
	u32 intf_flush = 0;
	u32 merge_3d_active = 0;
	u32 merge_3d_flush = 0;
	u32 i;

	if (!ctx || !cfg) {
		SDE_ERROR("invalid hw_ctl or hw_intf blk\n");
		return -EINVAL;
	}

	c = &ctx->hw;
	for (i = 0; i < cfg->intf_count; i++) {
		if (cfg->intf[i]) {
			intf_active &= ~BIT(cfg->intf[i] - INTF_0);
			intf_flush |= BIT(cfg->intf[i] - INTF_0);
		}
	}

	/* disable and flush merge3d_blk */
	merge_3d_flush = BIT(merge_3d_idx - MERGE_3D_0);
	merge_3d_active &= ~BIT(merge_3d_idx - MERGE_3D_0);

	sde_hw_ctl_clear_all_blendstages(ctx);
	SDE_REG_WRITE(c, CTL_MERGE_3D_ACTIVE, merge_3d_active);
	SDE_REG_WRITE(c, CTL_INTF_ACTIVE, intf_active);
	SDE_REG_WRITE(c, CTL_MERGE_3D_FLUSH, merge_3d_flush);
	SDE_REG_WRITE(c, CTL_INTF_FLUSH, intf_flush);

	/* flush intf, ctl, layer mixer and merge_3d in reset sequence */
	SDE_REG_WRITE(c, CTL_FLUSH, 0x809207C0);

	/* do ctl start for flushing ctl path when timing engine is disabled */
	SDE_REG_WRITE(c, CTL_START, 0x1);

	return 0;
}

static int sde_hw_ctl_dsc_cfg(struct sde_hw_ctl *ctx,
		struct sde_ctl_dsc_cfg *cfg)
{
@@ -1048,6 +1090,7 @@ static void _setup_ctl_ops(struct sde_hw_ctl_ops *ops,
			sde_hw_ctl_update_bitmask_merge3d_v1;
		ops->update_bitmask_cwb = sde_hw_ctl_update_bitmask_cwb_v1;
		ops->get_ctl_intf = sde_hw_ctl_get_intf_v1;
		ops->reset_post_te_disable = sde_hw_ctl_reset_post_te_disable;
	} else {
		ops->update_pending_flush = sde_hw_ctl_update_pending_flush;
		ops->trigger_flush = sde_hw_ctl_trigger_flush;
+10 −0
Original line number Diff line number Diff line
@@ -240,6 +240,16 @@ struct sde_hw_ctl_ops {
	int (*setup_intf_cfg)(struct sde_hw_ctl *ctx,
		struct sde_hw_intf_cfg *cfg);

	/**
	 * Reset ctl_path iterface config
	 * @ctx
	 * @cfg    : interface config structure pointer
	 * @merge_3d_idx	: index of merge3d blk
	 * @Return: error code
	 */
	int (*reset_post_te_disable)(struct sde_hw_ctl *ctx,
		struct sde_hw_intf_cfg_v1 *cfg, u32 merge_3d_idx);

	/**
	 * Setup ctl_path interface config for SDE_CTL_ACTIVE_CFG
	 * @ctx   : ctl path ctx pointer
+20 −0
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@ static u32 dither_depth_map[DITHER_DEPTH_MAP_INDEX] = {
};

#define MERGE_3D_MODE 0x004
#define MERGE_3D_MUX  0x000

static struct sde_merge_3d_cfg *_merge_3d_offset(enum sde_merge_3d idx,
		struct sde_mdss_cfg *m,
@@ -86,10 +87,23 @@ static void _sde_hw_merge_3d_setup_blend_mode(struct sde_hw_merge_3d *ctx,
	SDE_REG_WRITE(c, MERGE_3D_MODE, mode);
}

static void sde_hw_merge_3d_reset_blend_mode(struct sde_hw_merge_3d *ctx)
{
	struct sde_hw_blk_reg_map *c;

	if (!ctx)
		return;

	c = &ctx->hw;
	SDE_REG_WRITE(c, MERGE_3D_MODE, 0x0);
	SDE_REG_WRITE(c, MERGE_3D_MUX, 0x0);
}

static void _setup_merge_3d_ops(struct sde_hw_merge_3d_ops *ops,
	const struct sde_merge_3d_cfg *hw_cap)
{
	ops->setup_blend_mode = _sde_hw_merge_3d_setup_blend_mode;
	ops->reset_blend_mode = sde_hw_merge_3d_reset_blend_mode;
}

static struct sde_hw_merge_3d *_sde_pp_merge_3d_init(enum sde_merge_3d idx,
@@ -438,6 +452,11 @@ static void sde_hw_pp_setup_3d_merge_mode(struct sde_hw_pingpong *pp,
		pp->merge_3d->ops.setup_blend_mode(pp->merge_3d, cfg);
}

static void sde_hw_pp_reset_3d_merge_mode(struct sde_hw_pingpong *pp)
{
	if (pp->merge_3d && pp->merge_3d->ops.reset_blend_mode)
		pp->merge_3d->ops.reset_blend_mode(pp->merge_3d);
}
static void _setup_pingpong_ops(struct sde_hw_pingpong_ops *ops,
	const struct sde_pingpong_cfg *hw_cap)
{
@@ -470,6 +489,7 @@ static void _setup_pingpong_ops(struct sde_hw_pingpong_ops *ops,
	}
	if (test_bit(SDE_PINGPONG_MERGE_3D, &hw_cap->features))
		ops->setup_3d_mode = sde_hw_pp_setup_3d_merge_mode;
		ops->reset_3d_mode = sde_hw_pp_reset_3d_merge_mode;
};

static struct sde_hw_blk_ops sde_hw_ops = {
+10 −0
Original line number Diff line number Diff line
@@ -128,6 +128,11 @@ struct sde_hw_pingpong_ops {
	 */
	void (*setup_3d_mode)(struct sde_hw_pingpong *pp,
			enum sde_3d_blend_mode cfg);

	/**
	 * reset 3d blend configuration
	 */
	void (*reset_3d_mode)(struct sde_hw_pingpong *pp);
};

struct sde_hw_merge_3d_ops {
@@ -136,6 +141,11 @@ struct sde_hw_merge_3d_ops {
	 */
	void (*setup_blend_mode)(struct sde_hw_merge_3d *id,
			enum sde_3d_blend_mode cfg);

	/**
	 * reset 3d blend mode configuration
	 */
	void (*reset_blend_mode)(struct sde_hw_merge_3d *id);
};

struct sde_hw_merge_3d {