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

Commit a48a8900 authored by Dhaval Patel's avatar Dhaval Patel
Browse files

drm/msm/sde: turn on timing engine for only master intf



Current SDE driver turns on timing engine for master
and slave intfs for split display. It does not cause any
issue but it is advisable to turn on timing engine only
on master intf instead of both intfs. SW should also wait
for extra vsync on master intf if timing engine status
bit is high after "disable + vsync wait". HW takes extra
vsync wait to turn off timing engine if timing engine
disable request is during prefetch area with programmable
fetch is enabled.

Change-Id: Ice4949a3ecb0e1a76555497a104d50228ef13381
Signed-off-by: default avatarDhaval Patel <pdhaval@codeaurora.org>
parent 6464c0fa
Loading
Loading
Loading
Loading
+62 −39
Original line number Original line Diff line number Diff line
@@ -1050,12 +1050,52 @@ static int sde_encoder_phys_vid_prepare_for_kickoff(
	return rc;
	return rc;
}
}


static void sde_encoder_phys_vid_single_vblank_wait(
		struct sde_encoder_phys *phys_enc)
{
	int ret;
	struct sde_encoder_phys_vid *vid_enc
					= to_sde_encoder_phys_vid(phys_enc);

	/*
	 * Wait for a vsync so we know the ENABLE=0 latched before
	 * the (connector) source of the vsync's gets disabled,
	 * otherwise we end up in a funny state if we re-enable
	 * before the disable latches, which results that some of
	 * the settings changes for the new modeset (like new
	 * scanout buffer) don't latch properly..
	 */
	ret = sde_encoder_phys_vid_control_vblank_irq(phys_enc, true);
	if (ret) {
		SDE_ERROR_VIDENC(vid_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_vid_wait_for_vblank(phys_enc, false);
		if (ret) {
			atomic_set(&phys_enc->pending_kickoff_cnt, 0);
			SDE_ERROR_VIDENC(vid_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_vid_control_vblank_irq(phys_enc, false);
	}
}

static void sde_encoder_phys_vid_disable(struct sde_encoder_phys *phys_enc)
static void sde_encoder_phys_vid_disable(struct sde_encoder_phys *phys_enc)
{
{
	struct msm_drm_private *priv;
	struct msm_drm_private *priv;
	struct sde_encoder_phys_vid *vid_enc;
	struct sde_encoder_phys_vid *vid_enc;
	unsigned long lock_flags;
	unsigned long lock_flags;
	int ret;
	struct intf_status intf_status = {0};


	if (!phys_enc || !phys_enc->parent || !phys_enc->parent->dev ||
	if (!phys_enc || !phys_enc->parent || !phys_enc->parent->dev ||
			!phys_enc->parent->dev->dev_private) {
			!phys_enc->parent->dev->dev_private) {
@@ -1075,6 +1115,8 @@ static void sde_encoder_phys_vid_disable(struct sde_encoder_phys *phys_enc)


	if (WARN_ON(!phys_enc->hw_intf->ops.enable_timing))
	if (WARN_ON(!phys_enc->hw_intf->ops.enable_timing))
		return;
		return;
	else if (!sde_encoder_phys_vid_is_master(phys_enc))
		goto exit;


	if (phys_enc->enable_state == SDE_ENC_DISABLED) {
	if (phys_enc->enable_state == SDE_ENC_DISABLED) {
		SDE_ERROR("already disabled\n");
		SDE_ERROR("already disabled\n");
@@ -1083,43 +1125,20 @@ static void sde_encoder_phys_vid_disable(struct sde_encoder_phys *phys_enc)


	spin_lock_irqsave(phys_enc->enc_spinlock, lock_flags);
	spin_lock_irqsave(phys_enc->enc_spinlock, lock_flags);
	phys_enc->hw_intf->ops.enable_timing(phys_enc->hw_intf, 0);
	phys_enc->hw_intf->ops.enable_timing(phys_enc->hw_intf, 0);
	if (sde_encoder_phys_vid_is_master(phys_enc))
	sde_encoder_phys_inc_pending(phys_enc);
	sde_encoder_phys_inc_pending(phys_enc);
	spin_unlock_irqrestore(phys_enc->enc_spinlock, lock_flags);
	spin_unlock_irqrestore(phys_enc->enc_spinlock, lock_flags);


	if (!sde_encoder_phys_vid_is_master(phys_enc))
	sde_encoder_phys_vid_single_vblank_wait(phys_enc);
		goto exit;
	if (phys_enc->hw_intf->ops.get_status)
		phys_enc->hw_intf->ops.get_status(phys_enc->hw_intf,
			&intf_status);


	/*
	if (intf_status.is_en) {
	 * Wait for a vsync so we know the ENABLE=0 latched before
		spin_lock_irqsave(phys_enc->enc_spinlock, lock_flags);
	 * the (connector) source of the vsync's gets disabled,
		sde_encoder_phys_inc_pending(phys_enc);
	 * otherwise we end up in a funny state if we re-enable
		spin_unlock_irqrestore(phys_enc->enc_spinlock, lock_flags);
	 * before the disable latches, which results that some of

	 * the settings changes for the new modeset (like new
		sde_encoder_phys_vid_single_vblank_wait(phys_enc);
	 * scanout buffer) don't latch properly..
	 */
	ret = sde_encoder_phys_vid_control_vblank_irq(phys_enc, true);
	if (ret) {
		SDE_ERROR_VIDENC(vid_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_vid_wait_for_vblank(phys_enc, false);
		if (ret) {
			atomic_set(&phys_enc->pending_kickoff_cnt, 0);
			SDE_ERROR_VIDENC(vid_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_vid_control_vblank_irq(phys_enc, false);
	}
	}


	sde_encoder_helper_phys_disable(phys_enc, NULL);
	sde_encoder_helper_phys_disable(phys_enc, NULL);
@@ -1150,11 +1169,15 @@ static void sde_encoder_phys_vid_handle_post_kickoff(
	 * Video encoders need to turn on their interfaces now
	 * Video encoders need to turn on their interfaces now
	 */
	 */
	if (phys_enc->enable_state == SDE_ENC_ENABLING) {
	if (phys_enc->enable_state == SDE_ENC_ENABLING) {
		if (sde_encoder_phys_vid_is_master(phys_enc)) {
			SDE_EVT32(DRMID(phys_enc->parent),
			SDE_EVT32(DRMID(phys_enc->parent),
				phys_enc->hw_intf->idx - INTF_0);
				phys_enc->hw_intf->idx - INTF_0);
			spin_lock_irqsave(phys_enc->enc_spinlock, lock_flags);
			spin_lock_irqsave(phys_enc->enc_spinlock, lock_flags);
		phys_enc->hw_intf->ops.enable_timing(phys_enc->hw_intf, 1);
			phys_enc->hw_intf->ops.enable_timing(phys_enc->hw_intf,
		spin_unlock_irqrestore(phys_enc->enc_spinlock, lock_flags);
				1);
			spin_unlock_irqrestore(phys_enc->enc_spinlock,
				lock_flags);
		}
		phys_enc->enable_state = SDE_ENC_ENABLED;
		phys_enc->enable_state = SDE_ENC_ENABLED;
	}
	}


+17 −0
Original line number Original line Diff line number Diff line
@@ -69,6 +69,7 @@
#define INTF_MISR_SIGNATURE		0x184
#define INTF_MISR_SIGNATURE		0x184


#define INTF_MUX                        0x25C
#define INTF_MUX                        0x25C
#define INTF_STATUS                     0x26C
#define INTF_AVR_CONTROL                0x270
#define INTF_AVR_CONTROL                0x270
#define INTF_AVR_MODE                   0x274
#define INTF_AVR_MODE                   0x274
#define INTF_AVR_TRIGGER                0x278
#define INTF_AVR_TRIGGER                0x278
@@ -387,6 +388,21 @@ static void sde_hw_intf_get_status(
	}
	}
}
}


static void sde_hw_intf_v1_get_status(
		struct sde_hw_intf *intf,
		struct intf_status *s)
{
	struct sde_hw_blk_reg_map *c = &intf->hw;

	s->is_en = SDE_REG_READ(c, INTF_STATUS) & BIT(0);
	if (s->is_en) {
		s->frame_count = SDE_REG_READ(c, INTF_FRAME_COUNT);
		s->line_count = SDE_REG_READ(c, INTF_LINE_COUNT);
	} else {
		s->line_count = 0;
		s->frame_count = 0;
	}
}
static void sde_hw_intf_setup_misr(struct sde_hw_intf *intf,
static void sde_hw_intf_setup_misr(struct sde_hw_intf *intf,
						bool enable, u32 frame_count)
						bool enable, u32 frame_count)
{
{
@@ -625,6 +641,7 @@ static void _setup_intf_ops(struct sde_hw_intf_ops *ops,
		ops->get_autorefresh = sde_hw_intf_get_autorefresh_config;
		ops->get_autorefresh = sde_hw_intf_get_autorefresh_config;
		ops->poll_timeout_wr_ptr = sde_hw_intf_poll_timeout_wr_ptr;
		ops->poll_timeout_wr_ptr = sde_hw_intf_poll_timeout_wr_ptr;
		ops->vsync_sel = sde_hw_intf_vsync_sel;
		ops->vsync_sel = sde_hw_intf_vsync_sel;
		ops->get_status = sde_hw_intf_v1_get_status;
	}
	}
}
}