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

Commit 23008f1f authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

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

parents 28eca5aa 61210ea2
Loading
Loading
Loading
Loading
+24 −2
Original line number Diff line number Diff line
@@ -2625,6 +2625,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);

@@ -2652,8 +2675,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);

		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
@@ -132,6 +132,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 {
@@ -176,6 +178,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;
@@ -945,6 +976,7 @@ static void sde_encoder_phys_vid_init_ops(struct sde_encoder_phys_ops *ops)
	ops->trigger_flush = sde_encoder_helper_trigger_flush;
	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 −2
Original line number Diff line number Diff line
@@ -565,12 +565,13 @@ static void sde_hw_ctl_setup_sbuf_cfg(struct sde_hw_ctl *ctx,
	SDE_REG_WRITE(c, CTL_ROT_TOP, val);
}

static void sde_hw_reg_dma_flush(struct sde_hw_ctl *ctx)
static void sde_hw_reg_dma_flush(struct sde_hw_ctl *ctx, bool blocking)
{
	struct sde_hw_reg_dma_ops *ops = sde_reg_dma_get_ops();

	if (ops && ops->last_command)
		ops->last_command(ctx, DMA_CTL_QUEUE0);
		ops->last_command(ctx, DMA_CTL_QUEUE0,
		    (blocking ? REG_DMA_WAIT4_COMP : REG_DMA_NOWAIT));
}

static void _setup_ctl_ops(struct sde_hw_ctl_ops *ops,
+2 −1
Original line number Diff line number Diff line
@@ -214,8 +214,9 @@ struct sde_hw_ctl_ops {
	/**
	 * Flush the reg dma by sending last command.
	 * @ctx       : ctl path ctx pointer
	 * @blocking  : if set to true api will block until flush is done
	 */
	void (*reg_dma_flush)(struct sde_hw_ctl *ctx);
	void (*reg_dma_flush)(struct sde_hw_ctl *ctx, bool blocking);

};

Loading