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

Commit 4e341a11 authored by Ray Zhang's avatar Ray Zhang Committed by Gerrit - the friendly Code Review server
Browse files

Revert "drm/msm/sde: use atomic counter for pending frame done"



This reverts commit 3a50ed28.

Change-Id: I7b24aa318f9cb1b26d47ca84facf78a6b95f8022
Signed-off-by: default avatarRay Zhang <rayz@codeaurora.org>
parent 2c3a2b7b
Loading
Loading
Loading
Loading
+46 −44
Original line number Diff line number Diff line
@@ -197,8 +197,9 @@ enum sde_enc_rc_states {
 * @debugfs_root:		Debug file system root file node
 * @enc_lock:			Lock around physical encoder create/destroy and
				access.
 * @frame_done_cnt:		Atomic counter for tracking which phy_enc is
 *						done with frame processing.
 * @frame_busy_mask:		Bitmask tracking which phys_enc we are still
 *				busy processing current command.
 *				Bit0 = phys_encs[0] etc.
 * @crtc_frame_event_cb:	callback handler for frame event
 * @crtc_frame_event_cb_data:	callback handler private data
 * @vsync_event_timer:		vsync timer
@@ -259,7 +260,7 @@ struct sde_encoder_virt {

	struct dentry *debugfs_root;
	struct mutex enc_lock;
	atomic_t frame_done_cnt[MAX_PHYS_ENCODERS_PER_VIRTUAL];
	DECLARE_BITMAP(frame_busy_mask, MAX_PHYS_ENCODERS_PER_VIRTUAL);
	void (*crtc_frame_event_cb)(void *, u32 event);
	struct sde_crtc_frame_event_cb_data crtc_frame_event_cb_data;

@@ -2447,16 +2448,6 @@ static int sde_encoder_resource_control(struct drm_encoder *drm_enc,
			return -EINVAL;
		}

		/*
		 * schedule off work item only when there are no
		 * frames pending
		 */
		if (sde_crtc_frame_pending(sde_enc->crtc) > 1) {
			SDE_DEBUG_ENC(sde_enc, "skip schedule work");
			SDE_EVT32(DRMID(drm_enc), sw_event, sde_enc->rc_state,
				SDE_EVTLOG_FUNC_CASE2);
			return 0;
		}
		if (sde_enc->crtc->index >= ARRAY_SIZE(priv->disp_thread)) {
			SDE_ERROR("invalid crtc index :%u\n",
					sde_enc->crtc->index);
@@ -2478,6 +2469,17 @@ static int sde_encoder_resource_control(struct drm_encoder *drm_enc,
			return -EINVAL;
		}

		/*
		 * schedule off work item only when there are no
		 * frames pending
		 */
		if (sde_crtc_frame_pending(sde_enc->crtc) > 1) {
			SDE_DEBUG_ENC(sde_enc, "skip schedule work");
			SDE_EVT32(DRMID(drm_enc), sw_event, sde_enc->rc_state,
				SDE_EVTLOG_FUNC_CASE2);
			return 0;
		}

		/* schedule delayed off work if autorefresh is disabled */
		if (sde_enc->cur_master &&
			sde_enc->cur_master->ops.is_autorefresh_enabled)
@@ -2690,10 +2692,17 @@ static int sde_encoder_resource_control(struct drm_encoder *drm_enc,
					SDE_EVTLOG_ERROR);
			mutex_unlock(&sde_enc->rc_lock);
			return 0;
		} else if (sde_crtc_frame_pending(sde_enc->crtc) > 1) {
			SDE_DEBUG_ENC(sde_enc, "skip idle entry");
		}

		/*
		 * if we are in ON but a frame was just kicked off,
		 * ignore the IDLE event, it's probably a stale timer event
		 */
		if (sde_enc->frame_busy_mask[0]) {
			SDE_ERROR_ENC(sde_enc,
					"sw_event:%d, rc:%d frame pending\n",
					sw_event, sde_enc->rc_state);
			SDE_EVT32(DRMID(drm_enc), sw_event, sde_enc->rc_state,
					sde_crtc_frame_pending(sde_enc->crtc),
					SDE_EVTLOG_ERROR);
			mutex_unlock(&sde_enc->rc_lock);
			return 0;
@@ -3654,8 +3663,6 @@ static void sde_encoder_frame_done_callback(
{
	struct sde_encoder_virt *sde_enc = to_sde_encoder_virt(drm_enc);
	unsigned int i;
	bool trigger = true;
	enum sde_rm_topology_name topology = SDE_RM_TOPOLOGY_NONE;

	if (!drm_enc || !sde_enc->cur_master) {
		SDE_ERROR("invalid param: drm_enc %lx, cur_master %lx\n",
@@ -3670,35 +3677,26 @@ static void sde_encoder_frame_done_callback(
	if (event & (SDE_ENCODER_FRAME_EVENT_DONE
			| SDE_ENCODER_FRAME_EVENT_ERROR
			| SDE_ENCODER_FRAME_EVENT_PANEL_DEAD)) {
		if (ready_phys->connector)
			topology = sde_connector_get_topology_name(
							ready_phys->connector);

		if (!sde_enc->frame_busy_mask[0]) {
			/**
			 * suppress frame_done without waiter,
			 * likely autorefresh
			 */
			SDE_EVT32(DRMID(drm_enc), event, ready_phys->intf_idx);
			return;
		}

		/* One of the physical encoders has become idle */
		for (i = 0; i < sde_enc->num_phys_encs; i++) {
			if ((sde_enc->phys_encs[i] == ready_phys) ||
				(event & SDE_ENCODER_FRAME_EVENT_ERROR)) {
			if (sde_enc->phys_encs[i] == ready_phys) {
				clear_bit(i, sde_enc->frame_busy_mask);
				SDE_EVT32_VERBOSE(DRMID(drm_enc), i,
					atomic_read(
						&sde_enc->frame_done_cnt[i]));
				if (!atomic_add_unless(
					&sde_enc->frame_done_cnt[i], 1, 1)) {
					SDE_EVT32(DRMID(drm_enc), event,
						ready_phys->intf_idx,
						SDE_EVTLOG_ERROR);
					SDE_ERROR_ENC(sde_enc,
						"intf idx:%d, event:%d\n",
						ready_phys->intf_idx, event);
					return;
					sde_enc->frame_busy_mask[0]);
			}
		}

			if (topology != SDE_RM_TOPOLOGY_PPSPLIT &&
				atomic_read(&sde_enc->frame_done_cnt[i]) != 1)
				trigger = false;
		}

		if (trigger) {
		if (!sde_enc->frame_busy_mask[0]) {
			sde_encoder_resource_control(drm_enc,
					SDE_ENC_RC_EVENT_FRAME_DONE);

@@ -3706,8 +3704,6 @@ static void sde_encoder_frame_done_callback(
				sde_enc->crtc_frame_event_cb(
					&sde_enc->crtc_frame_event_cb_data,
					event);
			for (i = 0; i < sde_enc->num_phys_encs; i++)
				atomic_set(&sde_enc->frame_done_cnt[i], 0);
		}
	} else {
		if (sde_enc->crtc_frame_event_cb)
@@ -4019,6 +4015,14 @@ static void _sde_encoder_kickoff_phys(struct sde_encoder_virt *sde_enc)
		if (phys->connector)
			topology = sde_connector_get_topology_name(
					phys->connector);
		/*
		 * don't wait on ppsplit slaves or skipped encoders because
		 * they dont receive irqs
		 */
		if (!(topology == SDE_RM_TOPOLOGY_PPSPLIT &&
				phys->split_role == ENC_ROLE_SLAVE) &&
				phys->split_role != ENC_ROLE_SKIP)
			set_bit(i, sde_enc->frame_busy_mask);

		if (!phys->ops.needs_single_flush ||
				!phys->ops.needs_single_flush(phys)) {
@@ -5483,8 +5487,6 @@ struct drm_encoder *sde_encoder_init_with_ops(
	sde_enc->cur_master = NULL;
	spin_lock_init(&sde_enc->enc_spinlock);
	mutex_init(&sde_enc->vblank_ctl_lock);
	for (i = 0; i < MAX_PHYS_ENCODERS_PER_VIRTUAL; i++)
		atomic_set(&sde_enc->frame_done_cnt[i], 0);
	drm_enc = &sde_enc->base;
	drm_encoder_init(dev, drm_enc, &sde_encoder_funcs, drm_enc_mode, NULL);
	drm_encoder_helper_add(drm_enc, &sde_encoder_helper_funcs);