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

Commit 205c579c authored by Dhaval Patel's avatar Dhaval Patel Committed by Jayaprakash Madisetty
Browse files

disp: msm: sde: avoid irq enable/disable during modeset



Avoid irq enable/disable during modeset and trigger
frame as posted start frame. This saves mode_set time
and also avoids unbalanced vblank_irq in this usecase.

Change-Id: I06958da5e52bc2aca0ddc60d2783615f80a839a4
Signed-off-by: default avatarDhaval Patel <quic_pdhaval@quicinc.com>
Signed-off-by: default avatarJayaprakash Madisetty <quic_jmadiset@quicinc.com>
parent 401ab0db
Loading
Loading
Loading
Loading
+1 −15
Original line number Diff line number Diff line
/*
 * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
 * Copyright (c) 2014-2021, The Linux Foundation. All rights reserved.
 * Copyright (C) 2013 Red Hat
 * Author: Rob Clark <robdclark@gmail.com>
@@ -1873,19 +1874,6 @@ static int _sde_encoder_rc_pre_modeset(struct drm_encoder *drm_enc,
		sde_enc->rc_state = SDE_ENC_RC_STATE_ON;
	}

	ret = sde_encoder_wait_for_event(drm_enc, MSM_ENC_TX_COMPLETE);
	if (ret && ret != -EWOULDBLOCK) {
		SDE_ERROR_ENC(sde_enc,
				"wait for commit done returned %d\n",
				ret);
		SDE_EVT32(DRMID(drm_enc), sw_event, sde_enc->rc_state,
				ret, SDE_EVTLOG_ERROR);
		ret = -EINVAL;
		goto end;
	}

	sde_encoder_irq_control(drm_enc, false);

	SDE_EVT32(DRMID(drm_enc), sw_event, sde_enc->rc_state,
		SDE_ENC_RC_STATE_MODESET, SDE_EVTLOG_FUNC_CASE5);

@@ -1920,8 +1908,6 @@ static int _sde_encoder_rc_post_modeset(struct drm_encoder *drm_enc,
		goto end;
	}

	sde_encoder_irq_control(drm_enc, true);

	_sde_encoder_update_rsc_client(drm_enc, true);

	SDE_EVT32(DRMID(drm_enc), sw_event, sde_enc->rc_state,
+1 −2
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
 * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved.
 */

@@ -275,7 +276,6 @@ 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
 * @vblank_cached_refcount:	Reference count of vblank cached 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
@@ -325,7 +325,6 @@ struct sde_encoder_phys {
	enum sde_enc_enable_state enable_state;
	struct mutex *vblank_ctl_lock;
	atomic_t vblank_refcount;
	atomic_t vblank_cached_refcount;
	atomic_t wbirq_refcount;
	atomic_t vsync_cnt;
	atomic_t underrun_cnt;
+4 −46
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
 * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved.
 */

@@ -340,8 +341,6 @@ static void _sde_encoder_phys_cmd_setup_irq_hw_idx(
{
	struct sde_encoder_irq *irq;
	struct sde_kms *sde_kms;
	int ret = 0;
	u32 vblank_refcount;

	if (!phys_enc->sde_kms || !phys_enc->hw_pp || !phys_enc->hw_ctl) {
		SDE_ERROR("invalid args %d %d %d\n", !phys_enc->sde_kms,
@@ -356,39 +355,13 @@ static void _sde_encoder_phys_cmd_setup_irq_hw_idx(

	sde_kms = phys_enc->sde_kms;

	mutex_lock(phys_enc->vblank_ctl_lock);
	vblank_refcount = atomic_read(&phys_enc->vblank_refcount);
	if (vblank_refcount) {
		ret = sde_encoder_helper_unregister_irq(phys_enc,
				INTR_IDX_RDPTR);
		if (ret)
			SDE_ERROR(
				"control vblank irq registration error %d\n",
					ret);
		if (vblank_refcount > 1)
			SDE_ERROR(
				"vblank_refcount mismatch detected, try to reset %d\n",
				atomic_read(&phys_enc->vblank_refcount));
		else
			atomic_set(&phys_enc->vblank_cached_refcount, 1);

		SDE_EVT32(DRMID(phys_enc->parent),
			phys_enc->hw_pp->idx - PINGPONG_0, vblank_refcount,
			atomic_read(&phys_enc->vblank_cached_refcount));
	}
	atomic_set(&phys_enc->vblank_refcount, 0);
	mutex_unlock(phys_enc->vblank_ctl_lock);

	irq = &phys_enc->irq[INTR_IDX_CTL_START];
	irq->hw_idx = phys_enc->hw_ctl->idx;
	irq->irq_idx = -EINVAL;

	irq = &phys_enc->irq[INTR_IDX_PINGPONG];
	irq->hw_idx = phys_enc->hw_pp->idx;
	irq->irq_idx = -EINVAL;

	irq = &phys_enc->irq[INTR_IDX_RDPTR];
	irq->irq_idx = -EINVAL;
	if (phys_enc->has_intf_te)
		irq->hw_idx = phys_enc->hw_intf->idx;
	else
@@ -396,17 +369,14 @@ static void _sde_encoder_phys_cmd_setup_irq_hw_idx(

	irq = &phys_enc->irq[INTR_IDX_UNDERRUN];
	irq->hw_idx = phys_enc->intf_idx;
	irq->irq_idx = -EINVAL;

	irq = &phys_enc->irq[INTR_IDX_AUTOREFRESH_DONE];
	irq->irq_idx = -EINVAL;
	if (phys_enc->has_intf_te)
		irq->hw_idx = phys_enc->hw_intf->idx;
	else
		irq->hw_idx = phys_enc->hw_pp->idx;

	irq = &phys_enc->irq[INTR_IDX_WRPTR];
	irq->irq_idx = -EINVAL;
	if (phys_enc->has_intf_te)
		irq->hw_idx = phys_enc->hw_intf->idx;
	else
@@ -831,7 +801,7 @@ static int sde_encoder_phys_cmd_control_vblank_irq(
	struct sde_encoder_phys_cmd *cmd_enc =
		to_sde_encoder_phys_cmd(phys_enc);
	int ret = 0;
	u32 refcount, cached_refcount;
	u32 refcount;
	struct sde_kms *sde_kms;

	if (!phys_enc || !phys_enc->hw_pp) {
@@ -846,18 +816,12 @@ static int sde_encoder_phys_cmd_control_vblank_irq(
		goto end;

	refcount = atomic_read(&phys_enc->vblank_refcount);
	cached_refcount = atomic_read(&phys_enc->vblank_cached_refcount);

	/* protect against negative */
	if (!enable && refcount == 0) {
		if (cached_refcount == 1) {
			atomic_set(&phys_enc->vblank_cached_refcount, 0);
			goto end;
		} else {
		ret = -EINVAL;
		goto end;
	}
	}

	SDE_DEBUG_CMDENC(cmd_enc, "[%pS] enable=%d/%d\n",
			__builtin_return_address(0), enable, refcount);
@@ -876,11 +840,6 @@ static int sde_encoder_phys_cmd_control_vblank_irq(
			atomic_inc_return(&phys_enc->vblank_refcount);
	}

	if (enable && cached_refcount) {
		atomic_inc(&phys_enc->vblank_refcount);
		atomic_set(&phys_enc->vblank_cached_refcount, 0);
	}

end:
	mutex_unlock(phys_enc->vblank_ctl_lock);
	if (ret) {
@@ -2129,7 +2088,6 @@ struct sde_encoder_phys *sde_encoder_phys_cmd_init(
	irq->cb.func = sde_encoder_phys_cmd_wr_ptr_irq;

	atomic_set(&phys_enc->vblank_refcount, 0);
	atomic_set(&phys_enc->vblank_cached_refcount, 0);
	atomic_set(&phys_enc->pending_kickoff_cnt, 0);
	atomic_set(&phys_enc->pending_retire_fence_cnt, 0);
	atomic_set(&cmd_enc->pending_vblank_cnt, 0);