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

Commit 5c9e202e authored by Shubhashree Dhar's avatar Shubhashree Dhar
Browse files

drm/msm/sde: Add refcount support for wb irq ctrl



Writeback timeout is seen during writeback disable. This is
because IRQ registration is now moved out of prepare kickoff
and is only enabled by resource control during kickoff. So,
refcount is added for wb irq registration balancing. Also,
add wb ctrl for null commit during writeback disable.

Change-Id: I5b1b2abbf275824158a9732b89c1f35deaf347b7
Signed-off-by: default avatarShubhashree Dhar <dhar@codeaurora.org>
parent b25832a0
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -255,6 +255,7 @@ struct sde_encoder_irq {
 * @enc_spinlock:	Virtual-Encoder-Wide Spin Lock for IRQ purposes
 * @enable_state:	Enable state tracking
 * @vblank_refcount:	Reference count of vblank request
 * @wbirq_refcount:	Reference count of wb irq request
 * @vsync_cnt:		Vsync count for the physical encoder
 * @underrun_cnt:	Underrun count for the physical encoder
 * @pending_kickoff_cnt:	Atomic counter tracking the number of kickoffs
@@ -293,6 +294,7 @@ struct sde_encoder_phys {
	enum sde_enc_enable_state enable_state;
	struct mutex *vblank_ctl_lock;
	atomic_t vblank_refcount;
	atomic_t wbirq_refcount;
	atomic_t vsync_cnt;
	atomic_t underrun_cnt;
	atomic_t pending_ctlstart_cnt;
+28 −8
Original line number Diff line number Diff line
@@ -904,7 +904,8 @@ static void sde_encoder_phys_wb_irq_ctrl(
{

	struct sde_encoder_phys_wb *wb_enc = to_sde_encoder_phys_wb(phys);
	int index = 0;
	int index = 0, refcount;
	int ret = 0;

	if (!wb_enc)
		return;
@@ -912,17 +913,33 @@ static void sde_encoder_phys_wb_irq_ctrl(
	if (wb_enc->bypass_irqreg)
		return;

	if (enable) {
		sde_encoder_helper_register_irq(phys, INTR_IDX_WB_DONE);
	refcount = atomic_read(&phys->wbirq_refcount);

	if (!enable && !refcount)
		return;

	SDE_EVT32(DRMID(phys->parent), enable,
			atomic_read(&phys->wbirq_refcount));

	if (enable && atomic_inc_return(&phys->wbirq_refcount) == 1) {
		ret = sde_encoder_helper_register_irq(phys, INTR_IDX_WB_DONE);
		if (ret)
			atomic_dec_return(&phys->wbirq_refcount);

	} else if (!enable &&
			atomic_dec_return(&phys->wbirq_refcount) == 0) {
		ret = sde_encoder_helper_unregister_irq(phys, INTR_IDX_WB_DONE);
		if (ret)
			atomic_inc_return(&phys->wbirq_refcount);
	}

	if (phys->in_clone_mode) {
		if (enable) {
			for (index = 0; index < CRTC_DUAL_MIXERS; index++)
				sde_encoder_helper_register_irq(phys,
						index ? INTR_IDX_PP3_OVFL
						: INTR_IDX_PP2_OVFL);
		}
		} else {
		sde_encoder_helper_unregister_irq(phys, INTR_IDX_WB_DONE);
		if (phys->in_clone_mode) {
			for (index = 0; index < CRTC_DUAL_MIXERS; index++)
				sde_encoder_helper_unregister_irq(phys,
						index ? INTR_IDX_PP3_OVFL
@@ -1354,10 +1371,12 @@ static void sde_encoder_phys_wb_disable(struct sde_encoder_phys *phys_enc)

	phys_enc->enable_state = SDE_ENC_DISABLING;
	sde_encoder_phys_wb_prepare_for_kickoff(phys_enc, NULL);
	sde_encoder_phys_wb_irq_ctrl(phys_enc, true);
	if (phys_enc->hw_ctl->ops.trigger_flush)
		phys_enc->hw_ctl->ops.trigger_flush(phys_enc->hw_ctl);
	sde_encoder_helper_trigger_start(phys_enc);
	sde_encoder_phys_wb_wait_for_commit_done(phys_enc);
	sde_encoder_phys_wb_irq_ctrl(phys_enc, false);
exit:
	phys_enc->enable_state = SDE_ENC_DISABLED;
	wb_enc->crtc = NULL;
@@ -1576,6 +1595,7 @@ struct sde_encoder_phys *sde_encoder_phys_wb_init(
	phys_enc->enc_spinlock = p->enc_spinlock;
	phys_enc->vblank_ctl_lock = p->vblank_ctl_lock;
	atomic_set(&phys_enc->pending_retire_fence_cnt, 0);
	atomic_set(&phys_enc->wbirq_refcount, 0);

	irq = &phys_enc->irq[INTR_IDX_WB_DONE];
	INIT_LIST_HEAD(&irq->cb.list);