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

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

drm/msm/sde: check frame pending status before failure trigger



HW might miss to trigger the CTL_START IRQ but frame trigger
was still successful. This can be confirmed by checking the
controller state. Avoid failure trigger if frame transfer
was successful.

Change-Id: I21596029f24dc9ccf80eacb40bc4925d807c61ef
Signed-off-by: default avatarDhaval Patel <pdhaval@codeaurora.org>
parent 6628ed00
Loading
Loading
Loading
Loading
+12 −4
Original line number Diff line number Diff line
@@ -1038,6 +1038,7 @@ static int _sde_encoder_phys_cmd_wait_for_ctl_start(
			to_sde_encoder_phys_cmd(phys_enc);
	struct sde_encoder_wait_info wait_info;
	int ret;
	bool frame_pending = true;

	if (!phys_enc || !phys_enc->hw_ctl) {
		SDE_ERROR("invalid argument(s)\n");
@@ -1055,10 +1056,17 @@ static int _sde_encoder_phys_cmd_wait_for_ctl_start(
	ret = sde_encoder_helper_wait_for_irq(phys_enc, INTR_IDX_CTL_START,
			&wait_info);
	if (ret == -ETIMEDOUT) {
		SDE_ERROR_CMDENC(cmd_enc, "ctl start interrupt wait failed\n");
		ret = -EINVAL;
	} else if (!ret)
		struct sde_hw_ctl *ctl = phys_enc->hw_ctl;

		if (ctl && ctl->ops.get_start_state)
			frame_pending = ctl->ops.get_start_state(ctl);

		if (frame_pending)
			SDE_ERROR_CMDENC(cmd_enc,
					"ctl start interrupt wait failed\n");
		else
			ret = 0;
	}

	return ret;
}
+6 −0
Original line number Diff line number Diff line
@@ -124,6 +124,11 @@ static inline void sde_hw_ctl_trigger_start(struct sde_hw_ctl *ctx)
	SDE_REG_WRITE(&ctx->hw, CTL_START, 0x1);
}

static inline int sde_hw_ctl_get_start_state(struct sde_hw_ctl *ctx)
{
	return SDE_REG_READ(&ctx->hw, CTL_START);
}

static inline void sde_hw_ctl_trigger_pending(struct sde_hw_ctl *ctx)
{
	SDE_REG_WRITE(&ctx->hw, CTL_PREPARE, 0x1);
@@ -649,6 +654,7 @@ static void _setup_ctl_ops(struct sde_hw_ctl_ops *ops,
	ops->get_bitmask_cdm = sde_hw_ctl_get_bitmask_cdm;
	ops->get_bitmask_wb = sde_hw_ctl_get_bitmask_wb;
	ops->reg_dma_flush = sde_hw_reg_dma_flush;
	ops->get_start_state = sde_hw_ctl_get_start_state;

	if (cap & BIT(SDE_CTL_SBUF)) {
		ops->get_bitmask_rot = sde_hw_ctl_get_bitmask_rot;
+6 −0
Original line number Diff line number Diff line
@@ -225,6 +225,12 @@ struct sde_hw_ctl_ops {
	 */
	void (*reg_dma_flush)(struct sde_hw_ctl *ctx, bool blocking);

	/**
	 * check if ctl start trigger state to confirm the frame pending
	 * status
	 * @ctx       : ctl path ctx pointer
	 */
	int (*get_start_state)(struct sde_hw_ctl *ctx);
};

/**