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

Commit 61210ea2 authored by Ingrid Gallardo's avatar Ingrid Gallardo Committed by Gerrit - the friendly Code Review server
Browse files

drm: msm: sde: add api to get if dma wait is needed



In the physical encoder, when the timing engine
is flushed, driver needs to wait for the dma
flush to be done. This change adds support to
get the status from the physical encoder if wait
is needed.

Change-Id: I52442713231fc7e054bbd3c4f472d6fce2e6d73c
Signed-off-by: default avatarIngrid Gallardo <ingridg@codeaurora.org>
parent d9e78265
Loading
Loading
Loading
Loading
+24 −2
Original line number Diff line number Diff line
@@ -2610,6 +2610,29 @@ static void _sde_encoder_kickoff_phys(struct sde_encoder_virt *sde_enc)

	pending_flush = 0x0;

	/*
	 * Trigger LUT DMA flush, this might need a wait, so we need
	 * to do this outside of the atomic context
	 */
	for (i = 0; i < sde_enc->num_phys_encs; i++) {
		struct sde_encoder_phys *phys = sde_enc->phys_encs[i];
		bool wait_for_dma = false;

		if (!phys || phys->enable_state == SDE_ENC_DISABLED)
			continue;

		ctl = phys->hw_ctl;
		if (!ctl)
			continue;

		if (phys->ops.wait_dma_trigger)
			wait_for_dma = phys->ops.wait_dma_trigger(phys);

		if (phys->hw_ctl->ops.reg_dma_flush)
			phys->hw_ctl->ops.reg_dma_flush(phys->hw_ctl,
					wait_for_dma);
	}

	/* update pending counts and trigger kickoff ctl flush atomically */
	spin_lock_irqsave(&sde_enc->enc_spinlock, lock_flags);

@@ -2637,8 +2660,7 @@ static void _sde_encoder_kickoff_phys(struct sde_encoder_virt *sde_enc)
				phys->split_role == ENC_ROLE_SLAVE) &&
				phys->split_role != ENC_ROLE_SKIP)
			set_bit(i, sde_enc->frame_busy_mask);
		if (phys->hw_ctl->ops.reg_dma_flush)
			phys->hw_ctl->ops.reg_dma_flush(phys->hw_ctl, false);

		if (!phys->ops.needs_single_flush ||
				!phys->ops.needs_single_flush(phys))
			_sde_encoder_trigger_flush(&sde_enc->base, phys, 0x0);
+3 −0
Original line number Diff line number Diff line
@@ -131,6 +131,8 @@ struct sde_encoder_virt_ops {
 * @is_autorefresh_enabled:	provides the autorefresh current
 *                              enable/disable state.
 * @get_line_count:		Obtain current vertical line count
 * @wait_dma_trigger:		Returns true if lut dma has to trigger and wait
 *                              unitl transaction is complete.
 */

struct sde_encoder_phys_ops {
@@ -174,6 +176,7 @@ struct sde_encoder_phys_ops {
	void (*restore)(struct sde_encoder_phys *phys);
	bool (*is_autorefresh_enabled)(struct sde_encoder_phys *phys);
	int (*get_line_count)(struct sde_encoder_phys *phys);
	bool (*wait_dma_trigger)(struct sde_encoder_phys *phys);
};

/**
+32 −0
Original line number Diff line number Diff line
@@ -591,6 +591,37 @@ static int sde_encoder_phys_vid_control_vblank_irq(
	return ret;
}

static bool sde_encoder_phys_vid_wait_dma_trigger(
		struct sde_encoder_phys *phys_enc)
{
	struct sde_encoder_phys_vid *vid_enc;
	struct sde_hw_intf *intf;
	struct sde_hw_ctl *ctl;
	struct intf_status status;

	if (!phys_enc) {
		SDE_ERROR("invalid encoder\n");
		return false;
	}

	vid_enc = to_sde_encoder_phys_vid(phys_enc);
	intf = vid_enc->hw_intf;
	ctl = phys_enc->hw_ctl;
	if (!vid_enc->hw_intf || !phys_enc->hw_ctl) {
		SDE_ERROR("invalid hw_intf %d hw_ctl %d\n",
			vid_enc->hw_intf != NULL, phys_enc->hw_ctl != NULL);
		return false;
	}

	if (!intf->ops.get_status)
		return false;

	intf->ops.get_status(intf, &status);

	/* if interface is not enabled, return true to wait for dma trigger */
	return status.is_en ? false : true;
}

static void sde_encoder_phys_vid_enable(struct sde_encoder_phys *phys_enc)
{
	struct msm_drm_private *priv;
@@ -944,6 +975,7 @@ static void sde_encoder_phys_vid_init_ops(struct sde_encoder_phys_ops *ops)
	ops->collect_misr = sde_encoder_phys_vid_collect_misr;
	ops->hw_reset = sde_encoder_helper_hw_reset;
	ops->get_line_count = sde_encoder_phys_vid_get_line_count;
	ops->wait_dma_trigger = sde_encoder_phys_vid_wait_dma_trigger;
}

struct sde_encoder_phys *sde_encoder_phys_vid_init(
+3 −0
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@
#include "sde_hw_reg_dma_v1.h"
#include "msm_drv.h"
#include "msm_mmu.h"
#include "sde_dbg.h"

#define GUARD_BYTES (BIT(8) - 1)
#define ALIGNED_OFFSET (U32_MAX & ~(GUARD_BYTES))
@@ -848,6 +849,7 @@ static int last_cmd_v1(struct sde_hw_ctl *ctl, enum sde_reg_dma_queue q,
	memset(&hw, 0, sizeof(hw));
	SET_UP_REG_DMA_REG(hw, reg_dma);

	SDE_EVT32(SDE_EVTLOG_FUNC_ENTRY, mode);
	if (mode == REG_DMA_WAIT4_COMP) {
		rc = readl_poll_timeout(hw.base_off + hw.blk_off +
			reg_dma_int_status_off, val,
@@ -856,6 +858,7 @@ static int last_cmd_v1(struct sde_hw_ctl *ctl, enum sde_reg_dma_queue q,
		if (rc)
			DRM_ERROR("poll wait failed %d val %x mask %x\n",
			    rc, val, ctl_trigger_done_mask[ctl->idx][q]);
		SDE_EVT32(SDE_EVTLOG_FUNC_EXIT, mode);
	}

	return 0;