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

Commit 1e2f9b68 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "drm/msm/shd: wait for single vblank when disable shared encoder"

parents 19181fc3 ae23c848
Loading
Loading
Loading
Loading
+88 −54
Original line number Diff line number Diff line
@@ -461,6 +461,59 @@ void sde_encoder_phys_shd_trigger_flush(
			shd_enc->hw_lm, shd_enc->num_mixers);
}

static int sde_encoder_phys_shd_control_vblank_irq(
		struct sde_encoder_phys *phys_enc,
		bool enable)
{
	int ret = 0;
	struct sde_encoder_phys_shd *shd_enc;
	int refcount;

	if (!phys_enc || !phys_enc->hw_intf) {
		SDE_ERROR("invalid encoder\n");
		return -EINVAL;
	}

	refcount = atomic_read(&phys_enc->vblank_refcount);
	shd_enc = to_sde_encoder_phys_shd(phys_enc);

	/* protect against negative */
	if (!enable && refcount == 0) {
		ret = -EINVAL;
		goto end;
	}

	SDE_DEBUG("[%pS] %d enable=%d/%d\n",
			__builtin_return_address(0), DRMID(phys_enc->parent),
			enable, atomic_read(&phys_enc->vblank_refcount));

	SDE_EVT32(DRMID(phys_enc->parent), enable,
			atomic_read(&phys_enc->vblank_refcount));

	if (enable && atomic_inc_return(&phys_enc->vblank_refcount) == 1) {
		ret = _sde_encoder_phys_shd_register_irq(phys_enc,
				INTR_IDX_VSYNC, true);
		if (ret)
			atomic_dec_return(&phys_enc->vblank_refcount);
	} else if (!enable &&
			atomic_dec_return(&phys_enc->vblank_refcount) == 0) {
		ret = _sde_encoder_phys_shd_register_irq(phys_enc,
				INTR_IDX_VSYNC, false);
		if (ret)
			atomic_inc_return(&phys_enc->vblank_refcount);
	}

end:
	if (ret) {
		SDE_DEBUG("control vblank irq error %d, enable %d\n",
				ret, enable);
		SDE_EVT32(DRMID(phys_enc->parent),
				phys_enc->hw_intf->idx - INTF_0,
				enable, refcount, SDE_EVTLOG_ERROR);
	}
	return ret;
}

static void sde_encoder_phys_shd_enable(struct sde_encoder_phys *phys_enc)
{
	struct drm_connector *connector;
@@ -485,10 +538,41 @@ static void sde_encoder_phys_shd_enable(struct sde_encoder_phys *phys_enc)
		atomic_read(&phys_enc->pending_retire_fence_cnt));
}

static void sde_encoder_phys_shd_single_vblank_wait(
		struct sde_encoder_phys *phys_enc)
{
	int ret;

	ret = sde_encoder_phys_shd_control_vblank_irq(phys_enc, true);
	if (ret) {
		SDE_ERROR_PHYS(phys_enc,
				"failed to enable vblank irq: %d\n",
				ret);
		SDE_EVT32(DRMID(phys_enc->parent),
				phys_enc->hw_intf->idx - INTF_0, ret,
				SDE_EVTLOG_FUNC_CASE1,
				SDE_EVTLOG_ERROR);
	} else {
		ret = _sde_encoder_phys_shd_wait_for_vblank(phys_enc, false);
		if (ret) {
			atomic_set(&phys_enc->pending_kickoff_cnt, 0);
			SDE_ERROR_PHYS(phys_enc,
					"failure waiting for disable: %d\n",
					ret);
			SDE_EVT32(DRMID(phys_enc->parent),
					phys_enc->hw_intf->idx - INTF_0, ret,
					SDE_EVTLOG_FUNC_CASE2,
					SDE_EVTLOG_ERROR);
		}
		sde_encoder_phys_shd_control_vblank_irq(phys_enc, false);
	}
}

static void sde_encoder_phys_shd_disable(struct sde_encoder_phys *phys_enc)
{
	struct sde_connector *sde_conn;
	struct shd_display *display;
	unsigned long lock_flags;

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

@@ -511,9 +595,12 @@ static void sde_encoder_phys_shd_disable(struct sde_encoder_phys *phys_enc)

	sde_encoder_helper_reset_mixers(phys_enc, NULL);

	spin_lock_irqsave(phys_enc->enc_spinlock, lock_flags);
	sde_encoder_phys_shd_trigger_flush(phys_enc);
	sde_encoder_phys_inc_pending(phys_enc);
	spin_unlock_irqrestore(phys_enc->enc_spinlock, lock_flags);

	sde_encoder_phys_shd_wait_for_vblank_no_notify(phys_enc);
	sde_encoder_phys_shd_single_vblank_wait(phys_enc);

	phys_enc->enable_state = SDE_ENC_DISABLED;

@@ -541,59 +628,6 @@ void sde_encoder_phys_shd_destroy(struct sde_encoder_phys *phys_enc)
	kfree(shd_enc);
}

static int sde_encoder_phys_shd_control_vblank_irq(
		struct sde_encoder_phys *phys_enc,
		bool enable)
{
	int ret = 0;
	struct sde_encoder_phys_shd *shd_enc;
	int refcount;

	if (!phys_enc || !phys_enc->hw_intf) {
		SDE_ERROR("invalid encoder\n");
		return -EINVAL;
	}

	refcount = atomic_read(&phys_enc->vblank_refcount);
	shd_enc = to_sde_encoder_phys_shd(phys_enc);

	/* protect against negative */
	if (!enable && refcount == 0) {
		ret = -EINVAL;
		goto end;
	}

	SDE_DEBUG("[%pS] %d enable=%d/%d\n",
			__builtin_return_address(0), DRMID(phys_enc->parent),
			enable, atomic_read(&phys_enc->vblank_refcount));

	SDE_EVT32(DRMID(phys_enc->parent), enable,
			atomic_read(&phys_enc->vblank_refcount));

	if (enable && atomic_inc_return(&phys_enc->vblank_refcount) == 1) {
		ret = _sde_encoder_phys_shd_register_irq(phys_enc,
				INTR_IDX_VSYNC, true);
		if (ret)
			atomic_dec_return(&phys_enc->vblank_refcount);
	} else if (!enable &&
			atomic_dec_return(&phys_enc->vblank_refcount) == 0) {
		ret = _sde_encoder_phys_shd_register_irq(phys_enc,
				INTR_IDX_VSYNC, false);
		if (ret)
			atomic_inc_return(&phys_enc->vblank_refcount);
	}

end:
	if (ret) {
		SDE_DEBUG("control vblank irq error %d, enable %d\n",
				ret, enable);
		SDE_EVT32(DRMID(phys_enc->parent),
				phys_enc->hw_intf->idx - INTF_0,
				enable, refcount, SDE_EVTLOG_ERROR);
	}
	return ret;
}

static inline
void sde_encoder_phys_shd_irq_ctrl(
		struct sde_encoder_phys *phys_enc, bool enable)