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

Commit e69141d2 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "drm: msm: sde: improve display interface timeout mechanism"

parents 7ddcfc4b dd7aeab5
Loading
Loading
Loading
Loading
+8 −5
Original line number Diff line number Diff line
@@ -318,6 +318,8 @@ static void _sde_crtc_blend_setup(struct drm_crtc *crtc)
	struct sde_hw_mixer *lm;
	struct sde_splash_info *sinfo;
	struct sde_kms *sde_kms = _sde_crtc_get_kms(crtc);
	bool splash_enabled = false;
	u32 mixer_mask = 0, mixer_ext_mask = 0;

	int i;

@@ -339,6 +341,9 @@ static void _sde_crtc_blend_setup(struct drm_crtc *crtc)
		return;
	}

	sde_splash_get_mixer_mask(sinfo, &splash_enabled,
				&mixer_mask, &mixer_ext_mask);

	for (i = 0; i < sde_crtc->num_mixers; i++) {
		if (!mixer[i].hw_lm || !mixer[i].hw_ctl) {
			SDE_ERROR("invalid lm or ctl assigned to mixer\n");
@@ -348,10 +353,8 @@ static void _sde_crtc_blend_setup(struct drm_crtc *crtc)
		mixer[i].flush_mask = 0;
		if (mixer[i].hw_ctl->ops.clear_all_blendstages)
			mixer[i].hw_ctl->ops.clear_all_blendstages(
					mixer[i].hw_ctl,
					sinfo->handoff,
					sinfo->reserved_pipe_info,
					MAX_BLOCKS);
					mixer[i].hw_ctl, splash_enabled,
					mixer_mask, mixer_ext_mask);
	}

	/* initialize stage cfg */
@@ -379,7 +382,7 @@ static void _sde_crtc_blend_setup(struct drm_crtc *crtc)

		ctl->ops.setup_blendstage(ctl, mixer[i].hw_lm->idx,
			&sde_crtc->stage_cfg, i,
			sinfo->handoff, sinfo->reserved_pipe_info, MAX_BLOCKS);
			splash_enabled, mixer_mask, mixer_ext_mask);
	}
}

+2 −0
Original line number Diff line number Diff line
@@ -796,6 +796,8 @@ static inline void _sde_encoder_trigger_flush(struct drm_encoder *drm_enc,
	if (extra_flush_bits && ctl->ops.update_pending_flush)
		ctl->ops.update_pending_flush(ctl, extra_flush_bits);

	phys->splash_flush_bits = phys->sde_kms->splash_info.flush_bits;

	ctl->ops.trigger_flush(ctl);
	SDE_EVT32(DRMID(drm_enc), ctl->idx);
}
+2 −0
Original line number Diff line number Diff line
@@ -186,6 +186,7 @@ enum sde_intr_idx {
 *				between 0-2 Incremented when a new kickoff is
 *				scheduled. Decremented in irq handler
 * @pending_kickoff_wq:		Wait queue for blocking until kickoff completes
 * @splash_flush_bits:	Flush bits of splash reserved hardware pipes
 */
struct sde_encoder_phys {
	struct drm_encoder *parent;
@@ -211,6 +212,7 @@ struct sde_encoder_phys {
	atomic_t underrun_cnt;
	atomic_t pending_kickoff_cnt;
	wait_queue_head_t pending_kickoff_wq;
	uint32_t splash_flush_bits;
};

static inline int sde_encoder_phys_inc_pending(struct sde_encoder_phys *phys)
+24 −19
Original line number Diff line number Diff line
@@ -132,7 +132,14 @@ static void sde_encoder_phys_shd_vblank_irq(void *arg, int irq_idx)

	shd_ctl = container_of(hw_ctl, struct sde_shd_hw_ctl, base);

	if ((flush_register & shd_ctl->flush_mask) == 0)
	/*
	 * When bootloader's splash is presented, as bootloader is concurrently
	 * flushing hardware pipes, so when checking flush_register, we need
	 * to care if the active bit in the flush_register matches with the
	 * bootloader's splash pipe flush bits.
	 */
	if ((flush_register & shd_ctl->flush_mask &
		~phys_enc->splash_flush_bits) == 0)
		new_cnt = atomic_add_unless(&phys_enc->pending_kickoff_cnt,
				-1, 0);

@@ -198,14 +205,12 @@ static int _sde_encoder_phys_shd_unregister_irq(

static void _sde_shd_hw_ctl_clear_blendstages_in_range(
	struct sde_shd_hw_ctl *hw_ctl, enum sde_lm lm,
	bool handoff, const struct splash_reserved_pipe_info *resv_pipes,
	u32 resv_pipes_length)
	bool handoff, u32 splash_mask, u32 splash_ext_mask)
{
	struct sde_hw_blk_reg_map *c = &hw_ctl->base.hw;
	u32 mixercfg, mixercfg_ext;
	u32 mixercfg_ext2;
	u32 mask = 0, ext_mask = 0, ext2_mask = 0;
	u32 splash_mask = 0, splash_ext_mask = 0;
	u32 start = hw_ctl->range.start + SDE_STAGE_0;
	u32 end = start + hw_ctl->range.size;
	u32 i;
@@ -218,8 +223,6 @@ static void _sde_shd_hw_ctl_clear_blendstages_in_range(
		goto end;

	if (handoff) {
		sde_splash_get_mixer_mask(resv_pipes,
			resv_pipes_length, &splash_mask, &splash_ext_mask);
		mask |= splash_mask;
		ext_mask |= splash_ext_mask;
	}
@@ -321,8 +324,7 @@ end:
}

static void _sde_shd_hw_ctl_clear_all_blendstages(struct sde_hw_ctl *ctx,
	bool handoff, const struct splash_reserved_pipe_info *resv_pipes,
	u32 resv_pipes_length)
	bool handoff, u32 splash_mask, u32 splash_ext_mask)
{
	struct sde_shd_hw_ctl *hw_ctl;
	int i;
@@ -336,8 +338,7 @@ static void _sde_shd_hw_ctl_clear_all_blendstages(struct sde_hw_ctl *ctx,
		int mixer_id = ctx->mixer_hw_caps[i].id;

		_sde_shd_hw_ctl_clear_blendstages_in_range(hw_ctl, mixer_id,
							handoff, resv_pipes,
							resv_pipes_length);
				handoff, splash_mask, splash_ext_mask);
	}
}

@@ -358,12 +359,10 @@ static inline int _stage_offset(struct sde_hw_mixer *ctx, enum sde_stage stage)

static void _sde_shd_hw_ctl_setup_blendstage(struct sde_hw_ctl *ctx,
	enum sde_lm lm, struct sde_hw_stage_cfg *stage_cfg, u32 index,
	bool handoff, const struct splash_reserved_pipe_info *resv_pipes,
	u32 resv_pipes_length)
	bool handoff, u32 splash_mask, u32 splash_ext_mask)
{
	struct sde_shd_hw_ctl *hw_ctl;
	u32 mixercfg = 0, mixercfg_ext = 0, mix, ext, full, mixercfg_ext2;
	u32 splash_mask = 0, splash_ext_mask = 0;
	u32 mask = 0, ext_mask = 0, ext2_mask = 0;
	int i, j;
	int stages;
@@ -383,7 +382,7 @@ static void _sde_shd_hw_ctl_setup_blendstage(struct sde_hw_ctl *ctx,
		pipes_per_stage = 1;

	_sde_shd_hw_ctl_clear_blendstages_in_range(hw_ctl, lm, handoff,
			resv_pipes, resv_pipes_length);
			splash_mask, splash_ext_mask);

	if (!stage_cfg)
		goto exit;
@@ -396,8 +395,6 @@ static void _sde_shd_hw_ctl_setup_blendstage(struct sde_hw_ctl *ctx,
	if (handoff) {
		mixercfg = SDE_REG_READ(c, CTL_LAYER(lm));
		mixercfg_ext = SDE_REG_READ(c, CTL_LAYER_EXT(lm));
		sde_splash_get_mixer_mask(resv_pipes,
			resv_pipes_length, &splash_mask, &splash_ext_mask);

		mixercfg &= splash_mask;
		mixercfg_ext &= splash_ext_mask;
@@ -610,6 +607,7 @@ static void _sde_shd_trigger_flush(struct sde_hw_ctl *ctx)
{
	struct sde_shd_hw_ctl *hw_ctl;
	struct sde_encoder_phys_shd *shd_enc;
	struct sde_encoder_phys *phys;
	struct sde_hw_blk_reg_map *c;
	unsigned long lock_flags;
	int i;
@@ -621,6 +619,9 @@ static void _sde_shd_trigger_flush(struct sde_hw_ctl *ctx)

	spin_lock_irqsave(&hw_ctl_lock, lock_flags);

	phys = &shd_enc->base;
	phys->splash_flush_bits = phys->sde_kms->splash_info.flush_bits;

	_sde_shd_hw_ctl_trigger_flush(ctx);

	for (i = 0; i < shd_enc->num_mixers; i++)
@@ -903,6 +904,8 @@ static void sde_encoder_phys_shd_disable(struct sde_encoder_phys *phys_enc)
{
	struct sde_connector *sde_conn;
	struct shd_display *display;
	bool splash_enabled = false;
	u32 mixer_mask = 0, mixer_ext_mask = 0;

	SHD_DEBUG("%d\n", phys_enc->parent->base.id);

@@ -917,10 +920,11 @@ static void sde_encoder_phys_shd_disable(struct sde_encoder_phys *phys_enc)
		return;
	}

	sde_splash_get_mixer_mask(&phys_enc->sde_kms->splash_info,
				&splash_enabled, &mixer_mask, &mixer_ext_mask);

	_sde_shd_hw_ctl_clear_all_blendstages(phys_enc->hw_ctl,
		phys_enc->sde_kms->splash_info.handoff,
		phys_enc->sde_kms->splash_info.reserved_pipe_info,
		MAX_BLOCKS);
			splash_enabled, mixer_mask, mixer_ext_mask);

	_sde_shd_trigger_flush(phys_enc->hw_ctl);

@@ -1019,6 +1023,7 @@ struct sde_encoder_phys *sde_encoder_phys_shd_init(
		INIT_LIST_HEAD(&shd_enc->irq_cb[i].list);
	atomic_set(&phys_enc->vblank_refcount, 0);
	atomic_set(&phys_enc->pending_kickoff_cnt, 0);
	phys_enc->splash_flush_bits = 0;
	init_waitqueue_head(&phys_enc->pending_kickoff_wq);
	phys_enc->enable_state = SDE_ENC_DISABLED;

+8 −1
Original line number Diff line number Diff line
@@ -308,7 +308,13 @@ static void sde_encoder_phys_vid_vblank_irq(void *arg, int irq_idx)
	if (hw_ctl && hw_ctl->ops.get_flush_register)
		flush_register = hw_ctl->ops.get_flush_register(hw_ctl);

	if (flush_register == 0)
	/*
	 * When bootloader's splash is presented, as bootloader is concurrently
	 * flushing hardware pipes, so when checking flush_register, we need
	 * to care if the active bit in the flush_register matches with the
	 * bootloader's splash pipe flush bits.
	 */
	if ((flush_register & ~phys_enc->splash_flush_bits) == 0)
		new_cnt = atomic_add_unless(&phys_enc->pending_kickoff_cnt,
				-1, 0);
	spin_unlock_irqrestore(phys_enc->enc_spinlock, lock_flags);
@@ -983,6 +989,7 @@ struct sde_encoder_phys *sde_encoder_phys_vid_init(
		INIT_LIST_HEAD(&vid_enc->irq_cb[i].list);
	atomic_set(&phys_enc->vblank_refcount, 0);
	atomic_set(&phys_enc->pending_kickoff_cnt, 0);
	phys_enc->splash_flush_bits = 0;
	init_waitqueue_head(&phys_enc->pending_kickoff_wq);
	phys_enc->enable_state = SDE_ENC_DISABLED;

Loading