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

Commit 7601d069 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "disp: msm: sde: wait for ctl to be idle to ensure transfer complete"

parents 6de4953b 28b1be3b
Loading
Loading
Loading
Loading
+47 −3
Original line number Diff line number Diff line
@@ -6047,12 +6047,41 @@ int sde_encoder_update_caps_for_cont_splash(struct drm_encoder *encoder,
	return ret;
}

static void sde_encoder_wait_for_ctl_idle(struct sde_encoder_virt *sde_enc)
{
	int i = 0, rc = 0;
	struct sde_encoder_phys *phys;
	struct sde_hw_ctl *ctl;

	for (i = 0; i < sde_enc->num_phys_encs; i++) {
		phys = sde_enc->phys_encs[i];

		if (!phys || !phys->hw_ctl)
			return;

		ctl = phys->hw_ctl;
		if (ctl && ctl->ops.get_scheduler_status) {
			rc = wait_event_timeout(phys->pending_kickoff_wq,
				(ctl->ops.get_scheduler_status(ctl) & BIT(0)),
				msecs_to_jiffies(KICKOFF_TIMEOUT_MS));
			if (!rc) {
				SDE_ERROR("wait for ctl idle failed\n");
				SDE_EVT32(SDE_EVTLOG_ERROR);
				return;
			}

			SDE_EVT32(ctl->ops.get_scheduler_status(ctl));
		}
	}
}

int sde_encoder_display_failure_notification(struct drm_encoder *enc,
	bool skip_pre_kickoff)
{
	struct msm_drm_thread *event_thread = NULL;
	struct msm_drm_private *priv = NULL;
	struct sde_encoder_virt *sde_enc = NULL;
	bool posted_start_en = false;

	if (!enc || !enc->dev || !enc->dev->dev_private) {
		SDE_ERROR("invalid parameters\n");
@@ -6070,10 +6099,16 @@ int sde_encoder_display_failure_notification(struct drm_encoder *enc,
		return -EINVAL;
	}

	SDE_EVT32_VERBOSE(DRMID(enc));

	event_thread = &priv->event_thread[sde_enc->crtc->index];

	if (sde_enc->cur_master && sde_enc->cur_master->connector)
		posted_start_en = (sde_connector_get_property(
				sde_enc->cur_master->connector->state,
				CONNECTOR_PROP_CMD_FRAME_TRIGGER_MODE) ==
				FRAME_DONE_WAIT_POSTED_START) ? true : false;

	SDE_EVT32_VERBOSE(DRMID(enc), posted_start_en);

	if (!skip_pre_kickoff) {
		kthread_queue_work(&event_thread->worker,
				   &sde_enc->esd_trigger_work);
@@ -6087,7 +6122,16 @@ int sde_encoder_display_failure_notification(struct drm_encoder *enc,
	 */
	sde_encoder_helper_switch_vsync(enc, true);

	if (!skip_pre_kickoff)
	if (skip_pre_kickoff)
		return 0;
	else if (posted_start_en)
		/*
		 * Make sure that the frame transfer is completed after
		 * switching to watchdog vsync. The timeout will be
		 * handled in the commit context for posted start usecases.
		 */
		sde_encoder_wait_for_ctl_idle(sde_enc);
	else
		sde_encoder_wait_for_event(enc, MSM_ENC_TX_COMPLETE);

	return 0;