Commit 3283c83e authored by Michel Dänzer's avatar Michel Dänzer Committed by Alex Deucher
Browse files

drm/amd/display: Ensure valid event timestamp for cursor-only commits

Requires enabling the vblank machinery for them.

Bug: https://gitlab.freedesktop.org/drm/amd/-/issues/2030


Signed-off-by: default avatarMichel Dänzer <mdaenzer@redhat.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Cc: stable@vger.kernel.org
parent 47053b1e
Loading
Loading
Loading
Loading
+40 −3
Original line number Diff line number Diff line
@@ -463,6 +463,26 @@ static void dm_pflip_high_irq(void *interrupt_params)
		     vrr_active, (int) !e);
}

static void dm_crtc_handle_vblank(struct amdgpu_crtc *acrtc)
{
	struct drm_crtc *crtc = &acrtc->base;
	struct drm_device *dev = crtc->dev;
	unsigned long flags;

	drm_crtc_handle_vblank(crtc);

	spin_lock_irqsave(&dev->event_lock, flags);

	/* Send completion event for cursor-only commits */
	if (acrtc->event && acrtc->pflip_status != AMDGPU_FLIP_SUBMITTED) {
		drm_crtc_send_vblank_event(crtc, acrtc->event);
		drm_crtc_vblank_put(crtc);
		acrtc->event = NULL;
	}

	spin_unlock_irqrestore(&dev->event_lock, flags);
}

static void dm_vupdate_high_irq(void *interrupt_params)
{
	struct common_irq_params *irq_params = interrupt_params;
@@ -501,7 +521,7 @@ static void dm_vupdate_high_irq(void *interrupt_params)
		 * if a pageflip happened inside front-porch.
		 */
		if (vrr_active) {
			drm_crtc_handle_vblank(&acrtc->base);
			dm_crtc_handle_vblank(acrtc);

			/* BTR processing for pre-DCE12 ASICs */
			if (acrtc->dm_irq_params.stream &&
@@ -553,7 +573,7 @@ static void dm_crtc_high_irq(void *interrupt_params)
	 * to dm_vupdate_high_irq after end of front-porch.
	 */
	if (!vrr_active)
		drm_crtc_handle_vblank(&acrtc->base);
		dm_crtc_handle_vblank(acrtc);

	/**
	 * Following stuff must happen at start of vblank, for crc
@@ -9174,6 +9194,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
	struct amdgpu_bo *abo;
	uint32_t target_vblank, last_flip_vblank;
	bool vrr_active = amdgpu_dm_vrr_active(acrtc_state);
	bool cursor_update = false;
	bool pflip_present = false;
	struct {
		struct dc_surface_update surface_updates[MAX_SURFACES];
@@ -9209,8 +9230,13 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
		struct dm_plane_state *dm_new_plane_state = to_dm_plane_state(new_plane_state);

		/* Cursor plane is handled after stream updates */
		if (plane->type == DRM_PLANE_TYPE_CURSOR)
		if (plane->type == DRM_PLANE_TYPE_CURSOR) {
			if ((fb && crtc == pcrtc) ||
			    (old_plane_state->fb && old_plane_state->crtc == pcrtc))
				cursor_update = true;

			continue;
		}

		if (!fb || !crtc || pcrtc != crtc)
			continue;
@@ -9373,6 +9399,17 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
				bundle->stream_update.vrr_infopacket =
					&acrtc_state->stream->vrr_infopacket;
		}
	} else if (cursor_update && acrtc_state->active_planes > 0 &&
		   !acrtc_state->force_dpms_off &&
		   acrtc_attach->base.state->event) {
		drm_crtc_vblank_get(pcrtc);

		spin_lock_irqsave(&pcrtc->dev->event_lock, flags);

		acrtc_attach->event = acrtc_attach->base.state->event;
		acrtc_attach->base.state->event = NULL;

		spin_unlock_irqrestore(&pcrtc->dev->event_lock, flags);
	}

	/* Update the planes if changed or disable if we don't have any. */