Blob Blame History Raw
From: Andrey Grodzovsky <Andrey.Grodzovsky@amd.com>
Date: Sun, 4 Jun 2017 09:11:56 -0400
Subject: drm/amd/display: Get rid of seperate flip function.
Git-commit: 70470154104e935eed36478169550eda577dcdb3
Patch-mainline: v4.15-rc1
References: FATE#326289 FATE#326079 FATE#326049 FATE#322398 FATE#326166

This code is remanant of pre atomic age when flip was a
standalone IOCTL.

Signed-off-by: Andrey Grodzovsky <Andrey.Grodzovsky@amd.com>
Reviewed-by: Tony Cheng <Tony.Cheng@amd.com>
Reviewed-by: Harry Wentland <Harry.Wentland@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Acked-by: Petr Tesarik <ptesarik@suse.com>
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c       |   97 ----------------
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_types.c |   37 +++++-
 2 files changed, 34 insertions(+), 100 deletions(-)

--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -1328,102 +1328,6 @@ static u8 dm_get_backlight_level(struct
 	return 0;
 }
 
-/******************************************************************************
- * Page Flip functions
- ******************************************************************************/
-
-/**
- * dm_page_flip - called by amdgpu_flip_work_func(), which is triggered
- * 			via DRM IOCTL, by user mode.
- *
- * @adev: amdgpu_device pointer
- * @crtc_id: crtc to cleanup pageflip on
- * @crtc_base: new address of the crtc (GPU MC address)
- *
- * Does the actual pageflip (surface address update).
- */
-static void dm_page_flip(struct amdgpu_device *adev,
-			 int crtc_id, u64 crtc_base, bool async)
-{
-	struct amdgpu_crtc *acrtc;
-	const struct dc_stream *stream;
-	struct dc_flip_addrs addr = { {0} };
-	struct dc_surface_update surface_updates[1] = { {0} };
-
-	/*
-	 * TODO risk of concurrency issues
-	 *
-	 * This should guarded by the dal_mutex but we can't do this since the
-	 * caller uses a spin_lock on event_lock.
-	 *
-	 * If we wait on the dal_mutex a second page flip interrupt might come,
-	 * spin on the event_lock, disabling interrupts while it does so. At
-	 * this point the core can no longer be pre-empted and return to the
-	 * thread that waited on the dal_mutex and we're deadlocked.
-	 *
-	 * With multiple cores the same essentially happens but might just take
-	 * a little longer to lock up all cores.
-	 *
-	 * The reason we should lock on dal_mutex is so that we can be sure
-	 * nobody messes with acrtc->stream after we read and check its value.
-	 *
-	 * We might be able to fix our concurrency issues with a work queue
-	 * where we schedule all work items (mode_set, page_flip, etc.) and
-	 * execute them one by one. Care needs to be taken to still deal with
-	 * any potential concurrency issues arising from interrupt calls.
-	 */
-
-	acrtc = adev->mode_info.crtcs[crtc_id];
-	stream = acrtc->stream;
-
-
-	if (acrtc->pflip_status != AMDGPU_FLIP_NONE) {
-		DRM_ERROR("flip queue: acrtc %d, already busy\n", acrtc->crtc_id);
-		/* In commit tail framework this cannot happen */
-		BUG_ON(0);
-	}
-
-
-	/*
-	 * Received a page flip call after the display has been reset.
-	 * Just return in this case. Everything should be clean-up on reset.
-	 */
-
-	if (!stream) {
-		WARN_ON(1);
-		return;
-	}
-
-	addr.address.grph.addr.low_part = lower_32_bits(crtc_base);
-	addr.address.grph.addr.high_part = upper_32_bits(crtc_base);
-	addr.flip_immediate = async;
-
-
-	if (acrtc->base.state->event &&
-	    acrtc->base.state->event->event.base.type ==
-			    DRM_EVENT_FLIP_COMPLETE) {
-		acrtc->event = acrtc->base.state->event;
-
-		/* Set the flip status */
-		acrtc->pflip_status = AMDGPU_FLIP_SUBMITTED;
-
-		/* Mark this event as consumed */
-		acrtc->base.state->event = NULL;
-	}
-
-	surface_updates->surface = dc_stream_get_status(stream)->surfaces[0];
-	surface_updates->flip_addr = &addr;
-
-
-	dc_update_surfaces_for_stream(adev->dm.dc, surface_updates, 1, stream);
-
-	DRM_DEBUG_DRIVER("%s Flipping to hi: 0x%x, low: 0x%x \n",
-			 __func__,
-			 addr.address.grph.addr.high_part,
-			 addr.address.grph.addr.low_part);
-
-}
-
 static int amdgpu_notify_freesync(struct drm_device *dev, void *data,
 				struct drm_file *filp)
 {
@@ -1460,7 +1364,6 @@ static const struct amdgpu_display_funcs
 	.hpd_sense = NULL,/* called unconditionally */
 	.hpd_set_polarity = NULL, /* called unconditionally */
 	.hpd_get_gpio_reg = NULL, /* VBIOS parsing. DAL does it. */
-	.page_flip = dm_page_flip, /* called unconditionally */
 	.page_flip_get_scanoutpos =
 		dm_crtc_get_scanoutpos,/* called unconditionally */
 	.add_encoder = NULL, /* VBIOS parsing. DAL does it. */
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_types.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_types.c
@@ -2198,6 +2198,8 @@ static void amdgpu_dm_do_flip(
 	struct amdgpu_bo *abo = gem_to_amdgpu_bo(afb->obj);
 	struct amdgpu_device *adev = crtc->dev->dev_private;
 	bool async_flip = (acrtc->flip_flags & DRM_MODE_PAGE_FLIP_ASYNC) != 0;
+	struct dc_flip_addrs addr = { {0} };
+	struct dc_surface_update surface_updates[1] = { {0} };
 
 	/* Prepare wait for target vblank early - before the fence-waits */
 	target_vblank = target - drm_crtc_vblank_count(crtc) +
@@ -2211,7 +2213,7 @@ static void amdgpu_dm_do_flip(
 	r = amdgpu_bo_reserve(abo, true);
 	if (unlikely(r != 0)) {
 		DRM_ERROR("failed to reserve buffer before flip\n");
-		BUG_ON(0);
+		WARN_ON(1);
 	}
 
 	/* Wait for all fences on this FB */
@@ -2239,8 +2241,37 @@ static void amdgpu_dm_do_flip(
 	/* update crtc fb */
 	crtc->primary->fb = fb;
 
-	/* Do the flip (mmio) */
-	adev->mode_info.funcs->page_flip(adev, acrtc->crtc_id, afb->address, async_flip);
+	WARN_ON(acrtc->pflip_status != AMDGPU_FLIP_NONE);
+	WARN_ON(!acrtc->stream);
+
+	addr.address.grph.addr.low_part = lower_32_bits(afb->address);
+	addr.address.grph.addr.high_part = upper_32_bits(afb->address);
+	addr.flip_immediate = async_flip;
+
+
+	if (acrtc->base.state->event &&
+	    acrtc->base.state->event->event.base.type ==
+			    DRM_EVENT_FLIP_COMPLETE) {
+		acrtc->event = acrtc->base.state->event;
+
+		/* Set the flip status */
+		acrtc->pflip_status = AMDGPU_FLIP_SUBMITTED;
+
+		/* Mark this event as consumed */
+		acrtc->base.state->event = NULL;
+	}
+
+	surface_updates->surface = dc_stream_get_status(acrtc->stream)->surfaces[0];
+	surface_updates->flip_addr = &addr;
+
+
+	dc_update_surfaces_for_stream(adev->dm.dc, surface_updates, 1, acrtc->stream);
+
+	DRM_DEBUG_DRIVER("%s Flipping to hi: 0x%x, low: 0x%x \n",
+			 __func__,
+			 addr.address.grph.addr.high_part,
+			 addr.address.grph.addr.low_part);
+
 
 	spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
 	DRM_DEBUG_DRIVER("crtc:%d, pflip_stat:AMDGPU_FLIP_SUBMITTED\n",