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

Commit 85f4f453 authored by Clarence Ip's avatar Clarence Ip
Browse files

drm/msm/sde: propagate kickoff prepare errors to crtc



Report errors during the encoder's prepare for kickoff calls
to the CRTC, so that the CRTC can avoid blindly dispatching
the current commit even in the face of preparation errors.

Change-Id: I3ad5d89877d65ff8d61a20d10a096bc2f3f5601a
Signed-off-by: default avatarClarence Ip <cip@codeaurora.org>
parent 1cc4edf0
Loading
Loading
Loading
Loading
+17 −7
Original line number Diff line number Diff line
@@ -3044,18 +3044,18 @@ static void sde_encoder_vsync_event_work_handler(struct kthread_work *work)
			nsecs_to_jiffies(ktime_to_ns(wakeup_time)));
}

void sde_encoder_prepare_for_kickoff(struct drm_encoder *drm_enc,
int sde_encoder_prepare_for_kickoff(struct drm_encoder *drm_enc,
		struct sde_encoder_kickoff_params *params)
{
	struct sde_encoder_virt *sde_enc;
	struct sde_encoder_phys *phys;
	bool needs_hw_reset = false;
	unsigned int i;
	int rc;
	int rc, ret = 0;

	if (!drm_enc || !params) {
		SDE_ERROR("invalid args\n");
		return;
		return -EINVAL;
	}
	sde_enc = to_sde_encoder_virt(drm_enc);

@@ -3067,8 +3067,12 @@ void sde_encoder_prepare_for_kickoff(struct drm_encoder *drm_enc,
	for (i = 0; i < sde_enc->num_phys_encs; i++) {
		phys = sde_enc->phys_encs[i];
		if (phys) {
			if (phys->ops.prepare_for_kickoff)
				phys->ops.prepare_for_kickoff(phys, params);
			if (phys->ops.prepare_for_kickoff) {
				rc = phys->ops.prepare_for_kickoff(
						phys, params);
				if (rc)
					ret = rc;
			}
			if (phys->enable_state == SDE_ENC_ERR_NEEDS_HW_RESET)
				needs_hw_reset = true;
			_sde_encoder_setup_dither(phys);
@@ -3094,19 +3098,25 @@ void sde_encoder_prepare_for_kickoff(struct drm_encoder *drm_enc,

	if (sde_enc->cur_master && sde_enc->cur_master->connector) {
		rc = sde_connector_pre_kickoff(sde_enc->cur_master->connector);
		if (rc)
		if (rc) {
			SDE_ERROR_ENC(sde_enc, "kickoff conn%d failed rc %d\n",
					sde_enc->cur_master->connector->base.id,
					rc);
			ret = rc;
		}
	}

	if (sde_encoder_is_dsc_enabled(drm_enc)) {
		rc = _sde_encoder_dsc_setup(sde_enc, params);
		if (rc)
		if (rc) {
			SDE_ERROR_ENC(sde_enc, "failed to setup DSC: %d\n", rc);
			ret = rc;
		}
	}

	return ret;
}

/**
 * _sde_encoder_reset_ctl_hw - reset h/w configuration for all ctl's associated
 *	with the specified encoder, and unstage all pipes from it
+2 −1
Original line number Diff line number Diff line
@@ -115,8 +115,9 @@ struct sde_rsc_client *sde_encoder_get_rsc_client(struct drm_encoder *encoder);
 *	Delayed: Block until next trigger can be issued.
 * @encoder:	encoder pointer
 * @params:	kickoff time parameters
 * @Returns:	Zero on success, last detected error otherwise
 */
void sde_encoder_prepare_for_kickoff(struct drm_encoder *encoder,
int sde_encoder_prepare_for_kickoff(struct drm_encoder *encoder,
		struct sde_encoder_kickoff_params *params);

/**
+1 −1
Original line number Diff line number Diff line
@@ -160,7 +160,7 @@ struct sde_encoder_phys_ops {
	int (*wait_for_commit_done)(struct sde_encoder_phys *phys_enc);
	int (*wait_for_tx_complete)(struct sde_encoder_phys *phys_enc);
	int (*wait_for_vblank)(struct sde_encoder_phys *phys_enc);
	void (*prepare_for_kickoff)(struct sde_encoder_phys *phys_enc,
	int (*prepare_for_kickoff)(struct sde_encoder_phys *phys_enc,
			struct sde_encoder_kickoff_params *params);
	void (*handle_post_kickoff)(struct sde_encoder_phys *phys_enc);
	void (*trigger_flush)(struct sde_encoder_phys *phys_enc);
+3 −2
Original line number Diff line number Diff line
@@ -984,7 +984,7 @@ static void sde_encoder_phys_cmd_get_hw_resources(
	hw_res->intfs[phys_enc->intf_idx - INTF_0] = INTF_MODE_CMD;
}

static void sde_encoder_phys_cmd_prepare_for_kickoff(
static int sde_encoder_phys_cmd_prepare_for_kickoff(
		struct sde_encoder_phys *phys_enc,
		struct sde_encoder_kickoff_params *params)
{
@@ -994,7 +994,7 @@ static void sde_encoder_phys_cmd_prepare_for_kickoff(

	if (!phys_enc || !phys_enc->hw_pp) {
		SDE_ERROR("invalid encoder\n");
		return;
		return -EINVAL;
	}
	SDE_DEBUG_CMDENC(cmd_enc, "pp %d\n", phys_enc->hw_pp->idx - PINGPONG_0);

@@ -1018,6 +1018,7 @@ static void sde_encoder_phys_cmd_prepare_for_kickoff(
	SDE_DEBUG_CMDENC(cmd_enc, "pp:%d pending_cnt %d\n",
			phys_enc->hw_pp->idx - PINGPONG_0,
			atomic_read(&phys_enc->pending_kickoff_cnt));
	return ret;
}

static int _sde_encoder_phys_cmd_wait_for_ctl_start(
+7 −5
Original line number Diff line number Diff line
@@ -763,7 +763,7 @@ static int sde_encoder_phys_vid_wait_for_vblank(
	return _sde_encoder_phys_vid_wait_for_vblank(phys_enc, true);
}

static void sde_encoder_phys_vid_prepare_for_kickoff(
static int sde_encoder_phys_vid_prepare_for_kickoff(
		struct sde_encoder_phys *phys_enc,
		struct sde_encoder_kickoff_params *params)
{
@@ -771,15 +771,15 @@ static void sde_encoder_phys_vid_prepare_for_kickoff(
	struct sde_hw_ctl *ctl;
	int rc;

	if (!phys_enc || !params) {
	if (!phys_enc || !params || !phys_enc->hw_ctl) {
		SDE_ERROR("invalid encoder/parameters\n");
		return;
		return -EINVAL;
	}
	vid_enc = to_sde_encoder_phys_vid(phys_enc);

	ctl = phys_enc->hw_ctl;
	if (!ctl || !ctl->ops.wait_reset_status)
		return;
	if (!ctl->ops.wait_reset_status)
		return 0;

	/*
	 * hw supports hardware initiated ctl reset, so before we kickoff a new
@@ -794,6 +794,8 @@ static void sde_encoder_phys_vid_prepare_for_kickoff(
	}

	programmable_rot_fetch_config(phys_enc, params->inline_rotate_prefill);

	return rc;
}

static void sde_encoder_phys_vid_disable(struct sde_encoder_phys *phys_enc)
Loading