All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/5] drm/radeon: remove (pre|post)_page_flip callbacks
@ 2014-05-27 14:49 Christian König
  2014-05-27 14:49 ` [PATCH 2/5] drm/radeon: remove drm_vblank_get|put from pflip handling Christian König
                   ` (4 more replies)
  0 siblings, 5 replies; 13+ messages in thread
From: Christian König @ 2014-05-27 14:49 UTC (permalink / raw)
  To: dri-devel

From: Christian König <christian.koenig@amd.com>

They are doing the same on all generations anyway.

Signed-off-by: Christian König <christian.koenig@amd.com>
---
 drivers/gpu/drm/radeon/evergreen.c      | 30 ----------------------
 drivers/gpu/drm/radeon/r100.c           | 30 ----------------------
 drivers/gpu/drm/radeon/radeon.h         |  4 ---
 drivers/gpu/drm/radeon/radeon_asic.c    | 44 ---------------------------------
 drivers/gpu/drm/radeon/radeon_asic.h    |  6 -----
 drivers/gpu/drm/radeon/radeon_display.c |  4 +--
 drivers/gpu/drm/radeon/rs600.c          | 12 ---------
 7 files changed, 2 insertions(+), 128 deletions(-)

diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c
index b406546..ec31a82 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -1301,36 +1301,6 @@ void dce4_wait_for_vblank(struct radeon_device *rdev, int crtc)
 }
 
 /**
- * radeon_irq_kms_pflip_irq_get - pre-pageflip callback.
- *
- * @rdev: radeon_device pointer
- * @crtc: crtc to prepare for pageflip on
- *
- * Pre-pageflip callback (evergreen+).
- * Enables the pageflip irq (vblank irq).
- */
-void evergreen_pre_page_flip(struct radeon_device *rdev, int crtc)
-{
-	/* enable the pflip int */
-	radeon_irq_kms_pflip_irq_get(rdev, crtc);
-}
-
-/**
- * evergreen_post_page_flip - pos-pageflip callback.
- *
- * @rdev: radeon_device pointer
- * @crtc: crtc to cleanup pageflip on
- *
- * Post-pageflip callback (evergreen+).
- * Disables the pageflip irq (vblank irq).
- */
-void evergreen_post_page_flip(struct radeon_device *rdev, int crtc)
-{
-	/* disable the pflip int */
-	radeon_irq_kms_pflip_irq_put(rdev, crtc);
-}
-
-/**
  * evergreen_page_flip - pageflip callback.
  *
  * @rdev: radeon_device pointer
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
index b6c3264..840651f 100644
--- a/drivers/gpu/drm/radeon/r100.c
+++ b/drivers/gpu/drm/radeon/r100.c
@@ -142,36 +142,6 @@ void r100_wait_for_vblank(struct radeon_device *rdev, int crtc)
 }
 
 /**
- * r100_pre_page_flip - pre-pageflip callback.
- *
- * @rdev: radeon_device pointer
- * @crtc: crtc to prepare for pageflip on
- *
- * Pre-pageflip callback (r1xx-r4xx).
- * Enables the pageflip irq (vblank irq).
- */
-void r100_pre_page_flip(struct radeon_device *rdev, int crtc)
-{
-	/* enable the pflip int */
-	radeon_irq_kms_pflip_irq_get(rdev, crtc);
-}
-
-/**
- * r100_post_page_flip - pos-pageflip callback.
- *
- * @rdev: radeon_device pointer
- * @crtc: crtc to cleanup pageflip on
- *
- * Post-pageflip callback (r1xx-r4xx).
- * Disables the pageflip irq (vblank irq).
- */
-void r100_post_page_flip(struct radeon_device *rdev, int crtc)
-{
-	/* disable the pflip int */
-	radeon_irq_kms_pflip_irq_put(rdev, crtc);
-}
-
-/**
  * r100_page_flip - pageflip callback.
  *
  * @rdev: radeon_device pointer
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 325f3a5..2b919af 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -1881,9 +1881,7 @@ struct radeon_asic {
 	} dpm;
 	/* pageflipping */
 	struct {
-		void (*pre_page_flip)(struct radeon_device *rdev, int crtc);
 		u32 (*page_flip)(struct radeon_device *rdev, int crtc, u64 crtc_base);
-		void (*post_page_flip)(struct radeon_device *rdev, int crtc);
 	} pflip;
 };
 
@@ -2742,9 +2740,7 @@ void radeon_ring_write(struct radeon_ring *ring, uint32_t v);
 #define radeon_pm_finish(rdev) (rdev)->asic->pm.finish((rdev))
 #define radeon_pm_init_profile(rdev) (rdev)->asic->pm.init_profile((rdev))
 #define radeon_pm_get_dynpm_state(rdev) (rdev)->asic->pm.get_dynpm_state((rdev))
-#define radeon_pre_page_flip(rdev, crtc) (rdev)->asic->pflip.pre_page_flip((rdev), (crtc))
 #define radeon_page_flip(rdev, crtc, base) (rdev)->asic->pflip.page_flip((rdev), (crtc), (base))
-#define radeon_post_page_flip(rdev, crtc) (rdev)->asic->pflip.post_page_flip((rdev), (crtc))
 #define radeon_wait_for_vblank(rdev, crtc) (rdev)->asic->display.wait_for_vblank((rdev), (crtc))
 #define radeon_mc_wait_for_idle(rdev) (rdev)->asic->mc_wait_for_idle((rdev))
 #define radeon_get_xclk(rdev) (rdev)->asic->get_xclk((rdev))
diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c
index ddcd0a2..cb7a0ea 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.c
+++ b/drivers/gpu/drm/radeon/radeon_asic.c
@@ -248,9 +248,7 @@ static struct radeon_asic r100_asic = {
 		.set_clock_gating = &radeon_legacy_set_clock_gating,
 	},
 	.pflip = {
-		.pre_page_flip = &r100_pre_page_flip,
 		.page_flip = &r100_page_flip,
-		.post_page_flip = &r100_post_page_flip,
 	},
 };
 
@@ -315,9 +313,7 @@ static struct radeon_asic r200_asic = {
 		.set_clock_gating = &radeon_legacy_set_clock_gating,
 	},
 	.pflip = {
-		.pre_page_flip = &r100_pre_page_flip,
 		.page_flip = &r100_page_flip,
-		.post_page_flip = &r100_post_page_flip,
 	},
 };
 
@@ -396,9 +392,7 @@ static struct radeon_asic r300_asic = {
 		.set_clock_gating = &radeon_legacy_set_clock_gating,
 	},
 	.pflip = {
-		.pre_page_flip = &r100_pre_page_flip,
 		.page_flip = &r100_page_flip,
-		.post_page_flip = &r100_post_page_flip,
 	},
 };
 
@@ -463,9 +457,7 @@ static struct radeon_asic r300_asic_pcie = {
 		.set_clock_gating = &radeon_legacy_set_clock_gating,
 	},
 	.pflip = {
-		.pre_page_flip = &r100_pre_page_flip,
 		.page_flip = &r100_page_flip,
-		.post_page_flip = &r100_post_page_flip,
 	},
 };
 
@@ -530,9 +522,7 @@ static struct radeon_asic r420_asic = {
 		.set_clock_gating = &radeon_atom_set_clock_gating,
 	},
 	.pflip = {
-		.pre_page_flip = &r100_pre_page_flip,
 		.page_flip = &r100_page_flip,
-		.post_page_flip = &r100_post_page_flip,
 	},
 };
 
@@ -597,9 +587,7 @@ static struct radeon_asic rs400_asic = {
 		.set_clock_gating = &radeon_legacy_set_clock_gating,
 	},
 	.pflip = {
-		.pre_page_flip = &r100_pre_page_flip,
 		.page_flip = &r100_page_flip,
-		.post_page_flip = &r100_post_page_flip,
 	},
 };
 
@@ -666,9 +654,7 @@ static struct radeon_asic rs600_asic = {
 		.set_clock_gating = &radeon_atom_set_clock_gating,
 	},
 	.pflip = {
-		.pre_page_flip = &rs600_pre_page_flip,
 		.page_flip = &rs600_page_flip,
-		.post_page_flip = &rs600_post_page_flip,
 	},
 };
 
@@ -735,9 +721,7 @@ static struct radeon_asic rs690_asic = {
 		.set_clock_gating = &radeon_atom_set_clock_gating,
 	},
 	.pflip = {
-		.pre_page_flip = &rs600_pre_page_flip,
 		.page_flip = &rs600_page_flip,
-		.post_page_flip = &rs600_post_page_flip,
 	},
 };
 
@@ -802,9 +786,7 @@ static struct radeon_asic rv515_asic = {
 		.set_clock_gating = &radeon_atom_set_clock_gating,
 	},
 	.pflip = {
-		.pre_page_flip = &rs600_pre_page_flip,
 		.page_flip = &rs600_page_flip,
-		.post_page_flip = &rs600_post_page_flip,
 	},
 };
 
@@ -869,9 +851,7 @@ static struct radeon_asic r520_asic = {
 		.set_clock_gating = &radeon_atom_set_clock_gating,
 	},
 	.pflip = {
-		.pre_page_flip = &rs600_pre_page_flip,
 		.page_flip = &rs600_page_flip,
-		.post_page_flip = &rs600_post_page_flip,
 	},
 };
 
@@ -968,9 +948,7 @@ static struct radeon_asic r600_asic = {
 		.get_temperature = &rv6xx_get_temp,
 	},
 	.pflip = {
-		.pre_page_flip = &rs600_pre_page_flip,
 		.page_flip = &rs600_page_flip,
-		.post_page_flip = &rs600_post_page_flip,
 	},
 };
 
@@ -1059,9 +1037,7 @@ static struct radeon_asic rv6xx_asic = {
 		.force_performance_level = &rv6xx_dpm_force_performance_level,
 	},
 	.pflip = {
-		.pre_page_flip = &rs600_pre_page_flip,
 		.page_flip = &rs600_page_flip,
-		.post_page_flip = &rs600_post_page_flip,
 	},
 };
 
@@ -1150,9 +1126,7 @@ static struct radeon_asic rs780_asic = {
 		.force_performance_level = &rs780_dpm_force_performance_level,
 	},
 	.pflip = {
-		.pre_page_flip = &rs600_pre_page_flip,
 		.page_flip = &rs600_page_flip,
-		.post_page_flip = &rs600_post_page_flip,
 	},
 };
 
@@ -1256,9 +1230,7 @@ static struct radeon_asic rv770_asic = {
 		.vblank_too_short = &rv770_dpm_vblank_too_short,
 	},
 	.pflip = {
-		.pre_page_flip = &rs600_pre_page_flip,
 		.page_flip = &rv770_page_flip,
-		.post_page_flip = &rs600_post_page_flip,
 	},
 };
 
@@ -1375,9 +1347,7 @@ static struct radeon_asic evergreen_asic = {
 		.vblank_too_short = &cypress_dpm_vblank_too_short,
 	},
 	.pflip = {
-		.pre_page_flip = &evergreen_pre_page_flip,
 		.page_flip = &evergreen_page_flip,
-		.post_page_flip = &evergreen_post_page_flip,
 	},
 };
 
@@ -1467,9 +1437,7 @@ static struct radeon_asic sumo_asic = {
 		.force_performance_level = &sumo_dpm_force_performance_level,
 	},
 	.pflip = {
-		.pre_page_flip = &evergreen_pre_page_flip,
 		.page_flip = &evergreen_page_flip,
-		.post_page_flip = &evergreen_post_page_flip,
 	},
 };
 
@@ -1560,9 +1528,7 @@ static struct radeon_asic btc_asic = {
 		.vblank_too_short = &btc_dpm_vblank_too_short,
 	},
 	.pflip = {
-		.pre_page_flip = &evergreen_pre_page_flip,
 		.page_flip = &evergreen_page_flip,
-		.post_page_flip = &evergreen_post_page_flip,
 	},
 };
 
@@ -1704,9 +1670,7 @@ static struct radeon_asic cayman_asic = {
 		.vblank_too_short = &ni_dpm_vblank_too_short,
 	},
 	.pflip = {
-		.pre_page_flip = &evergreen_pre_page_flip,
 		.page_flip = &evergreen_page_flip,
-		.post_page_flip = &evergreen_post_page_flip,
 	},
 };
 
@@ -1805,9 +1769,7 @@ static struct radeon_asic trinity_asic = {
 		.enable_bapm = &trinity_dpm_enable_bapm,
 	},
 	.pflip = {
-		.pre_page_flip = &evergreen_pre_page_flip,
 		.page_flip = &evergreen_page_flip,
-		.post_page_flip = &evergreen_post_page_flip,
 	},
 };
 
@@ -1936,9 +1898,7 @@ static struct radeon_asic si_asic = {
 		.vblank_too_short = &ni_dpm_vblank_too_short,
 	},
 	.pflip = {
-		.pre_page_flip = &evergreen_pre_page_flip,
 		.page_flip = &evergreen_page_flip,
-		.post_page_flip = &evergreen_post_page_flip,
 	},
 };
 
@@ -2099,9 +2059,7 @@ static struct radeon_asic ci_asic = {
 		.powergate_uvd = &ci_dpm_powergate_uvd,
 	},
 	.pflip = {
-		.pre_page_flip = &evergreen_pre_page_flip,
 		.page_flip = &evergreen_page_flip,
-		.post_page_flip = &evergreen_post_page_flip,
 	},
 };
 
@@ -2204,9 +2162,7 @@ static struct radeon_asic kv_asic = {
 		.enable_bapm = &kv_dpm_enable_bapm,
 	},
 	.pflip = {
-		.pre_page_flip = &evergreen_pre_page_flip,
 		.page_flip = &evergreen_page_flip,
-		.post_page_flip = &evergreen_post_page_flip,
 	},
 };
 
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h
index e6455b9..953607d 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.h
+++ b/drivers/gpu/drm/radeon/radeon_asic.h
@@ -135,9 +135,7 @@ extern void r100_pm_prepare(struct radeon_device *rdev);
 extern void r100_pm_finish(struct radeon_device *rdev);
 extern void r100_pm_init_profile(struct radeon_device *rdev);
 extern void r100_pm_get_dynpm_state(struct radeon_device *rdev);
-extern void r100_pre_page_flip(struct radeon_device *rdev, int crtc);
 extern u32 r100_page_flip(struct radeon_device *rdev, int crtc, u64 crtc_base);
-extern void r100_post_page_flip(struct radeon_device *rdev, int crtc);
 extern void r100_wait_for_vblank(struct radeon_device *rdev, int crtc);
 extern int r100_mc_wait_for_idle(struct radeon_device *rdev);
 
@@ -241,9 +239,7 @@ void rs600_hpd_set_polarity(struct radeon_device *rdev,
 extern void rs600_pm_misc(struct radeon_device *rdev);
 extern void rs600_pm_prepare(struct radeon_device *rdev);
 extern void rs600_pm_finish(struct radeon_device *rdev);
-extern void rs600_pre_page_flip(struct radeon_device *rdev, int crtc);
 extern u32 rs600_page_flip(struct radeon_device *rdev, int crtc, u64 crtc_base);
-extern void rs600_post_page_flip(struct radeon_device *rdev, int crtc);
 void rs600_set_safe_registers(struct radeon_device *rdev);
 extern void avivo_wait_for_vblank(struct radeon_device *rdev, int crtc);
 extern int rs600_mc_wait_for_idle(struct radeon_device *rdev);
@@ -520,9 +516,7 @@ extern void sumo_pm_init_profile(struct radeon_device *rdev);
 extern void btc_pm_init_profile(struct radeon_device *rdev);
 int sumo_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk);
 int evergreen_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk);
-extern void evergreen_pre_page_flip(struct radeon_device *rdev, int crtc);
 extern u32 evergreen_page_flip(struct radeon_device *rdev, int crtc, u64 crtc_base);
-extern void evergreen_post_page_flip(struct radeon_device *rdev, int crtc);
 extern void dce4_wait_for_vblank(struct radeon_device *rdev, int crtc);
 void evergreen_disable_interrupt_state(struct radeon_device *rdev);
 int evergreen_mc_wait_for_idle(struct radeon_device *rdev);
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c
index 8d99d5e..beccc4a 100644
--- a/drivers/gpu/drm/radeon/radeon_display.c
+++ b/drivers/gpu/drm/radeon/radeon_display.c
@@ -342,7 +342,7 @@ void radeon_crtc_handle_flip(struct radeon_device *rdev, int crtc_id)
 
 	drm_vblank_put(rdev->ddev, radeon_crtc->crtc_id);
 	radeon_fence_unref(&work->fence);
-	radeon_post_page_flip(work->rdev, work->crtc_id);
+	radeon_irq_kms_pflip_irq_get(rdev, work->crtc_id);
 	schedule_work(&work->work);
 }
 
@@ -471,7 +471,7 @@ static int radeon_crtc_page_flip(struct drm_crtc *crtc,
 	}
 
 	/* set the proper interrupt */
-	radeon_pre_page_flip(rdev, radeon_crtc->crtc_id);
+	radeon_irq_kms_pflip_irq_get(rdev, radeon_crtc->crtc_id);
 
 	return 0;
 
diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c
index 72d3616..e005bd7 100644
--- a/drivers/gpu/drm/radeon/rs600.c
+++ b/drivers/gpu/drm/radeon/rs600.c
@@ -109,18 +109,6 @@ void avivo_wait_for_vblank(struct radeon_device *rdev, int crtc)
 	}
 }
 
-void rs600_pre_page_flip(struct radeon_device *rdev, int crtc)
-{
-	/* enable the pflip int */
-	radeon_irq_kms_pflip_irq_get(rdev, crtc);
-}
-
-void rs600_post_page_flip(struct radeon_device *rdev, int crtc)
-{
-	/* disable the pflip int */
-	radeon_irq_kms_pflip_irq_put(rdev, crtc);
-}
-
 u32 rs600_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base)
 {
 	struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id];
-- 
1.9.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 2/5] drm/radeon: remove drm_vblank_get|put from pflip handling
  2014-05-27 14:49 [PATCH 1/5] drm/radeon: remove (pre|post)_page_flip callbacks Christian König
@ 2014-05-27 14:49 ` Christian König
  2014-05-27 15:56   ` Alex Deucher
  2014-05-27 14:49 ` [PATCH 3/5] drm/radeon: split page flip and pending callback Christian König
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 13+ messages in thread
From: Christian König @ 2014-05-27 14:49 UTC (permalink / raw)
  To: dri-devel

From: Christian König <christian.koenig@amd.com>

We activate the VBLANK irq manually anyway, so this is unnecessary.

Signed-off-by: Christian König <christian.koenig@amd.com>
---
 drivers/gpu/drm/radeon/radeon_display.c | 17 -----------------
 1 file changed, 17 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c
index beccc4a..d597d08 100644
--- a/drivers/gpu/drm/radeon/radeon_display.c
+++ b/drivers/gpu/drm/radeon/radeon_display.c
@@ -340,7 +340,6 @@ void radeon_crtc_handle_flip(struct radeon_device *rdev, int crtc_id)
 
 	spin_unlock_irqrestore(&rdev->ddev->event_lock, flags);
 
-	drm_vblank_put(rdev->ddev, radeon_crtc->crtc_id);
 	radeon_fence_unref(&work->fence);
 	radeon_irq_kms_pflip_irq_get(rdev, work->crtc_id);
 	schedule_work(&work->work);
@@ -464,27 +463,11 @@ static int radeon_crtc_page_flip(struct drm_crtc *crtc,
 	/* update crtc fb */
 	crtc->primary->fb = fb;
 
-	r = drm_vblank_get(dev, radeon_crtc->crtc_id);
-	if (r) {
-		DRM_ERROR("failed to get vblank before flip\n");
-		goto pflip_cleanup1;
-	}
-
 	/* set the proper interrupt */
 	radeon_irq_kms_pflip_irq_get(rdev, radeon_crtc->crtc_id);
 
 	return 0;
 
-pflip_cleanup1:
-	if (unlikely(radeon_bo_reserve(rbo, false) != 0)) {
-		DRM_ERROR("failed to reserve new rbo in error path\n");
-		goto pflip_cleanup;
-	}
-	if (unlikely(radeon_bo_unpin(rbo) != 0)) {
-		DRM_ERROR("failed to unpin new rbo in error path\n");
-	}
-	radeon_bo_unreserve(rbo);
-
 pflip_cleanup:
 	spin_lock_irqsave(&dev->event_lock, flags);
 	radeon_crtc->unpin_work = NULL;
-- 
1.9.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 3/5] drm/radeon: split page flip and pending callback
  2014-05-27 14:49 [PATCH 1/5] drm/radeon: remove (pre|post)_page_flip callbacks Christian König
  2014-05-27 14:49 ` [PATCH 2/5] drm/radeon: remove drm_vblank_get|put from pflip handling Christian König
@ 2014-05-27 14:49 ` Christian König
  2014-05-27 15:57   ` Alex Deucher
  2014-05-27 14:49 ` [PATCH 4/5] drm/radeon: separate vblank and pflip crtc handling Christian König
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 13+ messages in thread
From: Christian König @ 2014-05-27 14:49 UTC (permalink / raw)
  To: dri-devel

From: Christian König <christian.koenig@amd.com>

Signed-off-by: Christian König <christian.koenig@amd.com>
---
 drivers/gpu/drm/radeon/evergreen.c      | 18 ++++++++++++++++--
 drivers/gpu/drm/radeon/r100.c           | 21 ++++++++++++++++++---
 drivers/gpu/drm/radeon/radeon.h         |  4 +++-
 drivers/gpu/drm/radeon/radeon_asic.c    | 22 ++++++++++++++++++++++
 drivers/gpu/drm/radeon/radeon_asic.h    | 15 +++++++++++----
 drivers/gpu/drm/radeon/radeon_display.c |  3 ++-
 drivers/gpu/drm/radeon/rs600.c          | 10 ++++++++--
 drivers/gpu/drm/radeon/rv770.c          | 10 ++++++++--
 8 files changed, 88 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c
index ec31a82..336f0a5 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -1313,7 +1313,7 @@ void dce4_wait_for_vblank(struct radeon_device *rdev, int crtc)
  * double buffered update to take place.
  * Returns the current update pending status.
  */
-u32 evergreen_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base)
+void evergreen_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base)
 {
 	struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id];
 	u32 tmp = RREG32(EVERGREEN_GRPH_UPDATE + radeon_crtc->crtc_offset);
@@ -1345,9 +1345,23 @@ u32 evergreen_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base)
 	/* Unlock the lock, so double-buffering can take place inside vblank */
 	tmp &= ~EVERGREEN_GRPH_UPDATE_LOCK;
 	WREG32(EVERGREEN_GRPH_UPDATE + radeon_crtc->crtc_offset, tmp);
+}
+
+/**
+ * evergreen_page_flip_pending - check if page flip is still pending
+ *
+ * @rdev: radeon_device pointer
+ * @crtc_id: crtc to check
+ *
+ * Returns the current update pending status.
+ */
+bool evergreen_page_flip_pending(struct radeon_device *rdev, int crtc_id)
+{
+	struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id];
 
 	/* Return current update_pending status: */
-	return RREG32(EVERGREEN_GRPH_UPDATE + radeon_crtc->crtc_offset) & EVERGREEN_GRPH_SURFACE_UPDATE_PENDING;
+	return !!(RREG32(EVERGREEN_GRPH_UPDATE + radeon_crtc->crtc_offset) &
+		EVERGREEN_GRPH_SURFACE_UPDATE_PENDING);
 }
 
 /* get temperature in millidegrees */
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
index 840651f..52548f7 100644
--- a/drivers/gpu/drm/radeon/r100.c
+++ b/drivers/gpu/drm/radeon/r100.c
@@ -152,9 +152,8 @@ void r100_wait_for_vblank(struct radeon_device *rdev, int crtc)
  * During vblank we take the crtc lock and wait for the update_pending
  * bit to go high, when it does, we release the lock, and allow the
  * double buffered update to take place.
- * Returns the current update pending status.
  */
-u32 r100_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base)
+void r100_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base)
 {
 	struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id];
 	u32 tmp = ((u32)crtc_base) | RADEON_CRTC_OFFSET__OFFSET_LOCK;
@@ -176,8 +175,24 @@ u32 r100_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base)
 	tmp &= ~RADEON_CRTC_OFFSET__OFFSET_LOCK;
 	WREG32(RADEON_CRTC_OFFSET + radeon_crtc->crtc_offset, tmp);
 
+}
+
+/**
+ * r100_page_flip_pending - check if page flip is still pending
+ *
+ * @rdev: radeon_device pointer
+ * @crtc_id: crtc to check
+ *
+ * Check if the last pagefilp is still pending (r1xx-r4xx).
+ * Returns the current update pending status.
+ */
+bool r100_page_flip_pending(struct radeon_device *rdev, int crtc_id)
+{
+	struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id];
+
 	/* Return current update_pending status: */
-	return RREG32(RADEON_CRTC_OFFSET + radeon_crtc->crtc_offset) & RADEON_CRTC_OFFSET__GUI_TRIG_OFFSET;
+	return !!(RREG32(RADEON_CRTC_OFFSET + radeon_crtc->crtc_offset) &
+		RADEON_CRTC_OFFSET__GUI_TRIG_OFFSET);
 }
 
 /**
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 2b919af..4ae304d 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -1881,7 +1881,8 @@ struct radeon_asic {
 	} dpm;
 	/* pageflipping */
 	struct {
-		u32 (*page_flip)(struct radeon_device *rdev, int crtc, u64 crtc_base);
+		void (*page_flip)(struct radeon_device *rdev, int crtc, u64 crtc_base);
+		bool (*page_flip_pending)(struct radeon_device *rdev, int crtc);
 	} pflip;
 };
 
@@ -2741,6 +2742,7 @@ void radeon_ring_write(struct radeon_ring *ring, uint32_t v);
 #define radeon_pm_init_profile(rdev) (rdev)->asic->pm.init_profile((rdev))
 #define radeon_pm_get_dynpm_state(rdev) (rdev)->asic->pm.get_dynpm_state((rdev))
 #define radeon_page_flip(rdev, crtc, base) (rdev)->asic->pflip.page_flip((rdev), (crtc), (base))
+#define radeon_page_flip_pending(rdev, crtc) (rdev)->asic->pflip.page_flip_pending((rdev), (crtc))
 #define radeon_wait_for_vblank(rdev, crtc) (rdev)->asic->display.wait_for_vblank((rdev), (crtc))
 #define radeon_mc_wait_for_idle(rdev) (rdev)->asic->mc_wait_for_idle((rdev))
 #define radeon_get_xclk(rdev) (rdev)->asic->get_xclk((rdev))
diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c
index cb7a0ea..d8e1587 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.c
+++ b/drivers/gpu/drm/radeon/radeon_asic.c
@@ -249,6 +249,7 @@ static struct radeon_asic r100_asic = {
 	},
 	.pflip = {
 		.page_flip = &r100_page_flip,
+		.page_flip_pending = &r100_page_flip_pending,
 	},
 };
 
@@ -314,6 +315,7 @@ static struct radeon_asic r200_asic = {
 	},
 	.pflip = {
 		.page_flip = &r100_page_flip,
+		.page_flip_pending = &r100_page_flip_pending,
 	},
 };
 
@@ -393,6 +395,7 @@ static struct radeon_asic r300_asic = {
 	},
 	.pflip = {
 		.page_flip = &r100_page_flip,
+		.page_flip_pending = &r100_page_flip_pending,
 	},
 };
 
@@ -458,6 +461,7 @@ static struct radeon_asic r300_asic_pcie = {
 	},
 	.pflip = {
 		.page_flip = &r100_page_flip,
+		.page_flip_pending = &r100_page_flip_pending,
 	},
 };
 
@@ -523,6 +527,7 @@ static struct radeon_asic r420_asic = {
 	},
 	.pflip = {
 		.page_flip = &r100_page_flip,
+		.page_flip_pending = &r100_page_flip_pending,
 	},
 };
 
@@ -588,6 +593,7 @@ static struct radeon_asic rs400_asic = {
 	},
 	.pflip = {
 		.page_flip = &r100_page_flip,
+		.page_flip_pending = &r100_page_flip_pending,
 	},
 };
 
@@ -655,6 +661,7 @@ static struct radeon_asic rs600_asic = {
 	},
 	.pflip = {
 		.page_flip = &rs600_page_flip,
+		.page_flip_pending = &rs600_page_flip_pending,
 	},
 };
 
@@ -722,6 +729,7 @@ static struct radeon_asic rs690_asic = {
 	},
 	.pflip = {
 		.page_flip = &rs600_page_flip,
+		.page_flip_pending = &rs600_page_flip_pending,
 	},
 };
 
@@ -787,6 +795,7 @@ static struct radeon_asic rv515_asic = {
 	},
 	.pflip = {
 		.page_flip = &rs600_page_flip,
+		.page_flip_pending = &rs600_page_flip_pending,
 	},
 };
 
@@ -852,6 +861,7 @@ static struct radeon_asic r520_asic = {
 	},
 	.pflip = {
 		.page_flip = &rs600_page_flip,
+		.page_flip_pending = &rs600_page_flip_pending,
 	},
 };
 
@@ -949,6 +959,7 @@ static struct radeon_asic r600_asic = {
 	},
 	.pflip = {
 		.page_flip = &rs600_page_flip,
+		.page_flip_pending = &rs600_page_flip_pending,
 	},
 };
 
@@ -1038,6 +1049,7 @@ static struct radeon_asic rv6xx_asic = {
 	},
 	.pflip = {
 		.page_flip = &rs600_page_flip,
+		.page_flip_pending = &rs600_page_flip_pending,
 	},
 };
 
@@ -1127,6 +1139,7 @@ static struct radeon_asic rs780_asic = {
 	},
 	.pflip = {
 		.page_flip = &rs600_page_flip,
+		.page_flip_pending = &rs600_page_flip_pending,
 	},
 };
 
@@ -1231,6 +1244,7 @@ static struct radeon_asic rv770_asic = {
 	},
 	.pflip = {
 		.page_flip = &rv770_page_flip,
+		.page_flip_pending = &rv770_page_flip_pending,
 	},
 };
 
@@ -1348,6 +1362,7 @@ static struct radeon_asic evergreen_asic = {
 	},
 	.pflip = {
 		.page_flip = &evergreen_page_flip,
+		.page_flip_pending = &evergreen_page_flip_pending,
 	},
 };
 
@@ -1438,6 +1453,7 @@ static struct radeon_asic sumo_asic = {
 	},
 	.pflip = {
 		.page_flip = &evergreen_page_flip,
+		.page_flip_pending = &evergreen_page_flip_pending,
 	},
 };
 
@@ -1529,6 +1545,7 @@ static struct radeon_asic btc_asic = {
 	},
 	.pflip = {
 		.page_flip = &evergreen_page_flip,
+		.page_flip_pending = &evergreen_page_flip_pending,
 	},
 };
 
@@ -1671,6 +1688,7 @@ static struct radeon_asic cayman_asic = {
 	},
 	.pflip = {
 		.page_flip = &evergreen_page_flip,
+		.page_flip_pending = &evergreen_page_flip_pending,
 	},
 };
 
@@ -1770,6 +1788,7 @@ static struct radeon_asic trinity_asic = {
 	},
 	.pflip = {
 		.page_flip = &evergreen_page_flip,
+		.page_flip_pending = &evergreen_page_flip_pending,
 	},
 };
 
@@ -1899,6 +1918,7 @@ static struct radeon_asic si_asic = {
 	},
 	.pflip = {
 		.page_flip = &evergreen_page_flip,
+		.page_flip_pending = &evergreen_page_flip_pending,
 	},
 };
 
@@ -2060,6 +2080,7 @@ static struct radeon_asic ci_asic = {
 	},
 	.pflip = {
 		.page_flip = &evergreen_page_flip,
+		.page_flip_pending = &evergreen_page_flip_pending,
 	},
 };
 
@@ -2163,6 +2184,7 @@ static struct radeon_asic kv_asic = {
 	},
 	.pflip = {
 		.page_flip = &evergreen_page_flip,
+		.page_flip_pending = &evergreen_page_flip_pending,
 	},
 };
 
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h
index 953607d..0eab015 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.h
+++ b/drivers/gpu/drm/radeon/radeon_asic.h
@@ -135,7 +135,9 @@ extern void r100_pm_prepare(struct radeon_device *rdev);
 extern void r100_pm_finish(struct radeon_device *rdev);
 extern void r100_pm_init_profile(struct radeon_device *rdev);
 extern void r100_pm_get_dynpm_state(struct radeon_device *rdev);
-extern u32 r100_page_flip(struct radeon_device *rdev, int crtc, u64 crtc_base);
+extern void r100_page_flip(struct radeon_device *rdev, int crtc,
+			   u64 crtc_base);
+extern bool r100_page_flip_pending(struct radeon_device *rdev, int crtc);
 extern void r100_wait_for_vblank(struct radeon_device *rdev, int crtc);
 extern int r100_mc_wait_for_idle(struct radeon_device *rdev);
 
@@ -239,7 +241,9 @@ void rs600_hpd_set_polarity(struct radeon_device *rdev,
 extern void rs600_pm_misc(struct radeon_device *rdev);
 extern void rs600_pm_prepare(struct radeon_device *rdev);
 extern void rs600_pm_finish(struct radeon_device *rdev);
-extern u32 rs600_page_flip(struct radeon_device *rdev, int crtc, u64 crtc_base);
+extern void rs600_page_flip(struct radeon_device *rdev, int crtc,
+			    u64 crtc_base);
+extern bool rs600_page_flip_pending(struct radeon_device *rdev, int crtc);
 void rs600_set_safe_registers(struct radeon_device *rdev);
 extern void avivo_wait_for_vblank(struct radeon_device *rdev, int crtc);
 extern int rs600_mc_wait_for_idle(struct radeon_device *rdev);
@@ -448,7 +452,8 @@ void rv770_fini(struct radeon_device *rdev);
 int rv770_suspend(struct radeon_device *rdev);
 int rv770_resume(struct radeon_device *rdev);
 void rv770_pm_misc(struct radeon_device *rdev);
-u32 rv770_page_flip(struct radeon_device *rdev, int crtc, u64 crtc_base);
+void rv770_page_flip(struct radeon_device *rdev, int crtc, u64 crtc_base);
+bool rv770_page_flip_pending(struct radeon_device *rdev, int crtc);
 void r700_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc);
 void r700_cp_stop(struct radeon_device *rdev);
 void r700_cp_fini(struct radeon_device *rdev);
@@ -516,7 +521,9 @@ extern void sumo_pm_init_profile(struct radeon_device *rdev);
 extern void btc_pm_init_profile(struct radeon_device *rdev);
 int sumo_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk);
 int evergreen_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk);
-extern u32 evergreen_page_flip(struct radeon_device *rdev, int crtc, u64 crtc_base);
+extern void evergreen_page_flip(struct radeon_device *rdev, int crtc,
+				u64 crtc_base);
+extern bool evergreen_page_flip_pending(struct radeon_device *rdev, int crtc);
 extern void dce4_wait_for_vblank(struct radeon_device *rdev, int crtc);
 void evergreen_disable_interrupt_state(struct radeon_device *rdev);
 int evergreen_mc_wait_for_idle(struct radeon_device *rdev);
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c
index d597d08..c52c182 100644
--- a/drivers/gpu/drm/radeon/radeon_display.c
+++ b/drivers/gpu/drm/radeon/radeon_display.c
@@ -294,7 +294,8 @@ void radeon_crtc_handle_flip(struct radeon_device *rdev, int crtc_id)
 	/* New pageflip, or just completion of a previous one? */
 	if (!radeon_crtc->deferred_flip_completion) {
 		/* do the flip (mmio) */
-		update_pending = radeon_page_flip(rdev, crtc_id, work->new_crtc_base);
+		radeon_page_flip(rdev, crtc_id, work->new_crtc_base);
+		update_pending = radeon_page_flip_pending(rdev, crtc_id);
 	} else {
 		/* This is just a completion of a flip queued in crtc
 		 * at last invocation. Make sure we go directly to
diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c
index e005bd7..9922ee5 100644
--- a/drivers/gpu/drm/radeon/rs600.c
+++ b/drivers/gpu/drm/radeon/rs600.c
@@ -109,7 +109,7 @@ void avivo_wait_for_vblank(struct radeon_device *rdev, int crtc)
 	}
 }
 
-u32 rs600_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base)
+void rs600_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base)
 {
 	struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id];
 	u32 tmp = RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset);
@@ -136,9 +136,15 @@ u32 rs600_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base)
 	/* Unlock the lock, so double-buffering can take place inside vblank */
 	tmp &= ~AVIVO_D1GRPH_UPDATE_LOCK;
 	WREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset, tmp);
+}
+
+bool rs600_page_flip_pending(struct radeon_device *rdev, int crtc_id)
+{
+	struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id];
 
 	/* Return current update_pending status: */
-	return RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset) & AVIVO_D1GRPH_SURFACE_UPDATE_PENDING;
+	return !!(RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset) &
+		AVIVO_D1GRPH_SURFACE_UPDATE_PENDING);
 }
 
 void avivo_program_fmt(struct drm_encoder *encoder)
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c
index fef3107..97b7766 100644
--- a/drivers/gpu/drm/radeon/rv770.c
+++ b/drivers/gpu/drm/radeon/rv770.c
@@ -801,7 +801,7 @@ u32 rv770_get_xclk(struct radeon_device *rdev)
 	return reference_clock;
 }
 
-u32 rv770_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base)
+void rv770_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base)
 {
 	struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id];
 	u32 tmp = RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset);
@@ -835,9 +835,15 @@ u32 rv770_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base)
 	/* Unlock the lock, so double-buffering can take place inside vblank */
 	tmp &= ~AVIVO_D1GRPH_UPDATE_LOCK;
 	WREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset, tmp);
+}
+
+bool rv770_page_flip_pending(struct radeon_device *rdev, int crtc_id)
+{
+	struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id];
 
 	/* Return current update_pending status: */
-	return RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset) & AVIVO_D1GRPH_SURFACE_UPDATE_PENDING;
+	return !!(RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset) &
+		AVIVO_D1GRPH_SURFACE_UPDATE_PENDING);
 }
 
 /* get temperature in millidegrees */
-- 
1.9.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 4/5] drm/radeon: separate vblank and pflip crtc handling
  2014-05-27 14:49 [PATCH 1/5] drm/radeon: remove (pre|post)_page_flip callbacks Christian König
  2014-05-27 14:49 ` [PATCH 2/5] drm/radeon: remove drm_vblank_get|put from pflip handling Christian König
  2014-05-27 14:49 ` [PATCH 3/5] drm/radeon: split page flip and pending callback Christian König
@ 2014-05-27 14:49 ` Christian König
  2014-05-27 16:49   ` Alex Deucher
  2014-05-27 14:49 ` [PATCH 5/5] drm/radeon: rework page flip handling v3 Christian König
  2014-05-27 15:56 ` [PATCH 1/5] drm/radeon: remove (pre|post)_page_flip callbacks Alex Deucher
  4 siblings, 1 reply; 13+ messages in thread
From: Christian König @ 2014-05-27 14:49 UTC (permalink / raw)
  To: dri-devel

From: Christian König <christian.koenig@amd.com>

Signed-off-by: Christian König <christian.koenig@amd.com>
---
 drivers/gpu/drm/radeon/cik.c            | 12 ++++++------
 drivers/gpu/drm/radeon/evergreen.c      | 12 ++++++------
 drivers/gpu/drm/radeon/r100.c           |  4 ++--
 drivers/gpu/drm/radeon/r600.c           |  4 ++--
 drivers/gpu/drm/radeon/radeon_display.c | 33 +++++++++++++++++++++++++++++++--
 drivers/gpu/drm/radeon/radeon_mode.h    |  1 +
 drivers/gpu/drm/radeon/rs600.c          |  4 ++--
 drivers/gpu/drm/radeon/si.c             | 12 ++++++------
 8 files changed, 56 insertions(+), 26 deletions(-)

diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c
index 8d0f177..a518140 100644
--- a/drivers/gpu/drm/radeon/cik.c
+++ b/drivers/gpu/drm/radeon/cik.c
@@ -7314,7 +7314,7 @@ restart_ih:
 						wake_up(&rdev->irq.vblank_queue);
 					}
 					if (atomic_read(&rdev->irq.pflip[0]))
-						radeon_crtc_handle_flip(rdev, 0);
+						radeon_crtc_handle_vblank(rdev, 0);
 					rdev->irq.stat_regs.cik.disp_int &= ~LB_D1_VBLANK_INTERRUPT;
 					DRM_DEBUG("IH: D1 vblank\n");
 				}
@@ -7340,7 +7340,7 @@ restart_ih:
 						wake_up(&rdev->irq.vblank_queue);
 					}
 					if (atomic_read(&rdev->irq.pflip[1]))
-						radeon_crtc_handle_flip(rdev, 1);
+						radeon_crtc_handle_vblank(rdev, 1);
 					rdev->irq.stat_regs.cik.disp_int_cont &= ~LB_D2_VBLANK_INTERRUPT;
 					DRM_DEBUG("IH: D2 vblank\n");
 				}
@@ -7366,7 +7366,7 @@ restart_ih:
 						wake_up(&rdev->irq.vblank_queue);
 					}
 					if (atomic_read(&rdev->irq.pflip[2]))
-						radeon_crtc_handle_flip(rdev, 2);
+						radeon_crtc_handle_vblank(rdev, 2);
 					rdev->irq.stat_regs.cik.disp_int_cont2 &= ~LB_D3_VBLANK_INTERRUPT;
 					DRM_DEBUG("IH: D3 vblank\n");
 				}
@@ -7392,7 +7392,7 @@ restart_ih:
 						wake_up(&rdev->irq.vblank_queue);
 					}
 					if (atomic_read(&rdev->irq.pflip[3]))
-						radeon_crtc_handle_flip(rdev, 3);
+						radeon_crtc_handle_vblank(rdev, 3);
 					rdev->irq.stat_regs.cik.disp_int_cont3 &= ~LB_D4_VBLANK_INTERRUPT;
 					DRM_DEBUG("IH: D4 vblank\n");
 				}
@@ -7418,7 +7418,7 @@ restart_ih:
 						wake_up(&rdev->irq.vblank_queue);
 					}
 					if (atomic_read(&rdev->irq.pflip[4]))
-						radeon_crtc_handle_flip(rdev, 4);
+						radeon_crtc_handle_vblank(rdev, 4);
 					rdev->irq.stat_regs.cik.disp_int_cont4 &= ~LB_D5_VBLANK_INTERRUPT;
 					DRM_DEBUG("IH: D5 vblank\n");
 				}
@@ -7444,7 +7444,7 @@ restart_ih:
 						wake_up(&rdev->irq.vblank_queue);
 					}
 					if (atomic_read(&rdev->irq.pflip[5]))
-						radeon_crtc_handle_flip(rdev, 5);
+						radeon_crtc_handle_vblank(rdev, 5);
 					rdev->irq.stat_regs.cik.disp_int_cont5 &= ~LB_D6_VBLANK_INTERRUPT;
 					DRM_DEBUG("IH: D6 vblank\n");
 				}
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c
index 336f0a5..0318230 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -4789,7 +4789,7 @@ restart_ih:
 						wake_up(&rdev->irq.vblank_queue);
 					}
 					if (atomic_read(&rdev->irq.pflip[0]))
-						radeon_crtc_handle_flip(rdev, 0);
+						radeon_crtc_handle_vblank(rdev, 0);
 					rdev->irq.stat_regs.evergreen.disp_int &= ~LB_D1_VBLANK_INTERRUPT;
 					DRM_DEBUG("IH: D1 vblank\n");
 				}
@@ -4815,7 +4815,7 @@ restart_ih:
 						wake_up(&rdev->irq.vblank_queue);
 					}
 					if (atomic_read(&rdev->irq.pflip[1]))
-						radeon_crtc_handle_flip(rdev, 1);
+						radeon_crtc_handle_vblank(rdev, 1);
 					rdev->irq.stat_regs.evergreen.disp_int_cont &= ~LB_D2_VBLANK_INTERRUPT;
 					DRM_DEBUG("IH: D2 vblank\n");
 				}
@@ -4841,7 +4841,7 @@ restart_ih:
 						wake_up(&rdev->irq.vblank_queue);
 					}
 					if (atomic_read(&rdev->irq.pflip[2]))
-						radeon_crtc_handle_flip(rdev, 2);
+						radeon_crtc_handle_vblank(rdev, 2);
 					rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~LB_D3_VBLANK_INTERRUPT;
 					DRM_DEBUG("IH: D3 vblank\n");
 				}
@@ -4867,7 +4867,7 @@ restart_ih:
 						wake_up(&rdev->irq.vblank_queue);
 					}
 					if (atomic_read(&rdev->irq.pflip[3]))
-						radeon_crtc_handle_flip(rdev, 3);
+						radeon_crtc_handle_vblank(rdev, 3);
 					rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~LB_D4_VBLANK_INTERRUPT;
 					DRM_DEBUG("IH: D4 vblank\n");
 				}
@@ -4893,7 +4893,7 @@ restart_ih:
 						wake_up(&rdev->irq.vblank_queue);
 					}
 					if (atomic_read(&rdev->irq.pflip[4]))
-						radeon_crtc_handle_flip(rdev, 4);
+						radeon_crtc_handle_vblank(rdev, 4);
 					rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~LB_D5_VBLANK_INTERRUPT;
 					DRM_DEBUG("IH: D5 vblank\n");
 				}
@@ -4919,7 +4919,7 @@ restart_ih:
 						wake_up(&rdev->irq.vblank_queue);
 					}
 					if (atomic_read(&rdev->irq.pflip[5]))
-						radeon_crtc_handle_flip(rdev, 5);
+						radeon_crtc_handle_vblank(rdev, 5);
 					rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~LB_D6_VBLANK_INTERRUPT;
 					DRM_DEBUG("IH: D6 vblank\n");
 				}
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
index 52548f7..ad99813 100644
--- a/drivers/gpu/drm/radeon/r100.c
+++ b/drivers/gpu/drm/radeon/r100.c
@@ -779,7 +779,7 @@ int r100_irq_process(struct radeon_device *rdev)
 				wake_up(&rdev->irq.vblank_queue);
 			}
 			if (atomic_read(&rdev->irq.pflip[0]))
-				radeon_crtc_handle_flip(rdev, 0);
+				radeon_crtc_handle_vblank(rdev, 0);
 		}
 		if (status & RADEON_CRTC2_VBLANK_STAT) {
 			if (rdev->irq.crtc_vblank_int[1]) {
@@ -788,7 +788,7 @@ int r100_irq_process(struct radeon_device *rdev)
 				wake_up(&rdev->irq.vblank_queue);
 			}
 			if (atomic_read(&rdev->irq.pflip[1]))
-				radeon_crtc_handle_flip(rdev, 1);
+				radeon_crtc_handle_vblank(rdev, 1);
 		}
 		if (status & RADEON_FP_DETECT_STAT) {
 			queue_hotplug = true;
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index 6e887d0..436e550 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -3876,7 +3876,7 @@ restart_ih:
 						wake_up(&rdev->irq.vblank_queue);
 					}
 					if (atomic_read(&rdev->irq.pflip[0]))
-						radeon_crtc_handle_flip(rdev, 0);
+						radeon_crtc_handle_vblank(rdev, 0);
 					rdev->irq.stat_regs.r600.disp_int &= ~LB_D1_VBLANK_INTERRUPT;
 					DRM_DEBUG("IH: D1 vblank\n");
 				}
@@ -3902,7 +3902,7 @@ restart_ih:
 						wake_up(&rdev->irq.vblank_queue);
 					}
 					if (atomic_read(&rdev->irq.pflip[1]))
-						radeon_crtc_handle_flip(rdev, 1);
+						radeon_crtc_handle_vblank(rdev, 1);
 					rdev->irq.stat_regs.r600.disp_int &= ~LB_D2_VBLANK_INTERRUPT;
 					DRM_DEBUG("IH: D2 vblank\n");
 				}
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c
index c52c182..88e3cbe 100644
--- a/drivers/gpu/drm/radeon/radeon_display.c
+++ b/drivers/gpu/drm/radeon/radeon_display.c
@@ -276,7 +276,7 @@ static void radeon_unpin_work_func(struct work_struct *__work)
 	kfree(work);
 }
 
-void radeon_crtc_handle_flip(struct radeon_device *rdev, int crtc_id)
+void radeon_crtc_handle_vblank(struct radeon_device *rdev, int crtc_id)
 {
 	struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id];
 	struct radeon_unpin_work *work;
@@ -302,7 +302,6 @@ void radeon_crtc_handle_flip(struct radeon_device *rdev, int crtc_id)
 		 * completion routine.
 		 */
 		update_pending = 0;
-		radeon_crtc->deferred_flip_completion = 0;
 	}
 
 	/* Has the pageflip already completed in crtc, or is it certain
@@ -330,10 +329,40 @@ void radeon_crtc_handle_flip(struct radeon_device *rdev, int crtc_id)
 		radeon_crtc->deferred_flip_completion = 1;
 		spin_unlock_irqrestore(&rdev->ddev->event_lock, flags);
 		return;
+	} else {
+		spin_unlock_irqrestore(&rdev->ddev->event_lock, flags);
+		radeon_crtc_handle_flip(rdev, crtc_id);
+	}
+}
+
+/**
+ * radeon_crtc_handle_flip - page flip completed
+ *
+ * @rdev: radeon device pointer
+ * @crtc_id: crtc number this event is for
+ *
+ * Called when we are sure that a page flip for this crtc is completed.
+ */
+void radeon_crtc_handle_flip(struct radeon_device *rdev, int crtc_id)
+{
+	struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id];
+	struct radeon_unpin_work *work;
+	unsigned long flags;
+
+	/* this can happen at init */
+	if (radeon_crtc == NULL)
+		return;
+
+	spin_lock_irqsave(&rdev->ddev->event_lock, flags);
+	work = radeon_crtc->unpin_work;
+	if (work == NULL) {
+		spin_unlock_irqrestore(&rdev->ddev->event_lock, flags);
+		return;
 	}
 
 	/* Pageflip (will be) certainly completed in this vblank. Clean up. */
 	radeon_crtc->unpin_work = NULL;
+	radeon_crtc->deferred_flip_completion = 0;
 
 	/* wakeup userspace */
 	if (work->event)
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h
index b265a8b..718be1a 100644
--- a/drivers/gpu/drm/radeon/radeon_mode.h
+++ b/drivers/gpu/drm/radeon/radeon_mode.h
@@ -907,6 +907,7 @@ bool radeon_fbdev_robj_is_fb(struct radeon_device *rdev, struct radeon_bo *robj)
 
 void radeon_fb_output_poll_changed(struct radeon_device *rdev);
 
+void radeon_crtc_handle_vblank(struct radeon_device *rdev, int crtc_id);
 void radeon_crtc_handle_flip(struct radeon_device *rdev, int crtc_id);
 
 int radeon_align_pitch(struct radeon_device *rdev, int width, int bpp, bool tiled);
diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c
index 9922ee5..dd12dc2 100644
--- a/drivers/gpu/drm/radeon/rs600.c
+++ b/drivers/gpu/drm/radeon/rs600.c
@@ -781,7 +781,7 @@ int rs600_irq_process(struct radeon_device *rdev)
 				wake_up(&rdev->irq.vblank_queue);
 			}
 			if (atomic_read(&rdev->irq.pflip[0]))
-				radeon_crtc_handle_flip(rdev, 0);
+				radeon_crtc_handle_vblank(rdev, 0);
 		}
 		if (G_007EDC_LB_D2_VBLANK_INTERRUPT(rdev->irq.stat_regs.r500.disp_int)) {
 			if (rdev->irq.crtc_vblank_int[1]) {
@@ -790,7 +790,7 @@ int rs600_irq_process(struct radeon_device *rdev)
 				wake_up(&rdev->irq.vblank_queue);
 			}
 			if (atomic_read(&rdev->irq.pflip[1]))
-				radeon_crtc_handle_flip(rdev, 1);
+				radeon_crtc_handle_vblank(rdev, 1);
 		}
 		if (G_007EDC_DC_HOT_PLUG_DETECT1_INTERRUPT(rdev->irq.stat_regs.r500.disp_int)) {
 			queue_hotplug = true;
diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c
index 9739d71..5c1c0c7 100644
--- a/drivers/gpu/drm/radeon/si.c
+++ b/drivers/gpu/drm/radeon/si.c
@@ -6150,7 +6150,7 @@ restart_ih:
 						wake_up(&rdev->irq.vblank_queue);
 					}
 					if (atomic_read(&rdev->irq.pflip[0]))
-						radeon_crtc_handle_flip(rdev, 0);
+						radeon_crtc_handle_vblank(rdev, 0);
 					rdev->irq.stat_regs.evergreen.disp_int &= ~LB_D1_VBLANK_INTERRUPT;
 					DRM_DEBUG("IH: D1 vblank\n");
 				}
@@ -6176,7 +6176,7 @@ restart_ih:
 						wake_up(&rdev->irq.vblank_queue);
 					}
 					if (atomic_read(&rdev->irq.pflip[1]))
-						radeon_crtc_handle_flip(rdev, 1);
+						radeon_crtc_handle_vblank(rdev, 1);
 					rdev->irq.stat_regs.evergreen.disp_int_cont &= ~LB_D2_VBLANK_INTERRUPT;
 					DRM_DEBUG("IH: D2 vblank\n");
 				}
@@ -6202,7 +6202,7 @@ restart_ih:
 						wake_up(&rdev->irq.vblank_queue);
 					}
 					if (atomic_read(&rdev->irq.pflip[2]))
-						radeon_crtc_handle_flip(rdev, 2);
+						radeon_crtc_handle_vblank(rdev, 2);
 					rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~LB_D3_VBLANK_INTERRUPT;
 					DRM_DEBUG("IH: D3 vblank\n");
 				}
@@ -6228,7 +6228,7 @@ restart_ih:
 						wake_up(&rdev->irq.vblank_queue);
 					}
 					if (atomic_read(&rdev->irq.pflip[3]))
-						radeon_crtc_handle_flip(rdev, 3);
+						radeon_crtc_handle_vblank(rdev, 3);
 					rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~LB_D4_VBLANK_INTERRUPT;
 					DRM_DEBUG("IH: D4 vblank\n");
 				}
@@ -6254,7 +6254,7 @@ restart_ih:
 						wake_up(&rdev->irq.vblank_queue);
 					}
 					if (atomic_read(&rdev->irq.pflip[4]))
-						radeon_crtc_handle_flip(rdev, 4);
+						radeon_crtc_handle_vblank(rdev, 4);
 					rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~LB_D5_VBLANK_INTERRUPT;
 					DRM_DEBUG("IH: D5 vblank\n");
 				}
@@ -6280,7 +6280,7 @@ restart_ih:
 						wake_up(&rdev->irq.vblank_queue);
 					}
 					if (atomic_read(&rdev->irq.pflip[5]))
-						radeon_crtc_handle_flip(rdev, 5);
+						radeon_crtc_handle_vblank(rdev, 5);
 					rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~LB_D6_VBLANK_INTERRUPT;
 					DRM_DEBUG("IH: D6 vblank\n");
 				}
-- 
1.9.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 5/5] drm/radeon: rework page flip handling v3
  2014-05-27 14:49 [PATCH 1/5] drm/radeon: remove (pre|post)_page_flip callbacks Christian König
                   ` (2 preceding siblings ...)
  2014-05-27 14:49 ` [PATCH 4/5] drm/radeon: separate vblank and pflip crtc handling Christian König
@ 2014-05-27 14:49 ` Christian König
  2014-05-27 17:03   ` Alex Deucher
  2014-05-28  6:56   ` Michel Dänzer
  2014-05-27 15:56 ` [PATCH 1/5] drm/radeon: remove (pre|post)_page_flip callbacks Alex Deucher
  4 siblings, 2 replies; 13+ messages in thread
From: Christian König @ 2014-05-27 14:49 UTC (permalink / raw)
  To: dri-devel

From: Christian König <christian.koenig@amd.com>

Instead of trying to flip inside the vblank period when
the buffer is idle, offload blocking for idle to a kernel
thread and program the flip directly into the hardware.

v2: add error handling, fix EBUSY handling
v3: add proper exclusive_lock handling

Signed-off-by: Christian König <christian.koenig@amd.com>
---
 drivers/gpu/drm/radeon/radeon.h         |  16 ++-
 drivers/gpu/drm/radeon/radeon_display.c | 245 ++++++++++++++++++--------------
 drivers/gpu/drm/radeon/radeon_mode.h    |   4 +-
 3 files changed, 150 insertions(+), 115 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 4ae304d..736bfa2 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -676,14 +676,16 @@ void radeon_doorbell_free(struct radeon_device *rdev, u32 doorbell);
  * IRQS.
  */
 
-struct radeon_unpin_work {
-	struct work_struct work;
-	struct radeon_device *rdev;
-	int crtc_id;
-	struct radeon_fence *fence;
+struct radeon_flip_work {
+	struct work_struct		flip_work;
+	struct work_struct		unpin_work;
+	struct radeon_device		*rdev;
+	int				crtc_id;
+	struct drm_framebuffer		*fb;
 	struct drm_pending_vblank_event *event;
-	struct radeon_bo *old_rbo;
-	u64 new_crtc_base;
+	struct radeon_bo		*old_rbo;
+	struct radeon_bo		*new_rbo;
+	struct radeon_fence		*fence;
 };
 
 struct r500_irq_stat_regs {
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c
index 88e3cbe..6b3de5c 100644
--- a/drivers/gpu/drm/radeon/radeon_display.c
+++ b/drivers/gpu/drm/radeon/radeon_display.c
@@ -249,16 +249,21 @@ static void radeon_crtc_destroy(struct drm_crtc *crtc)
 	struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
 
 	drm_crtc_cleanup(crtc);
+	destroy_workqueue(radeon_crtc->flip_queue);
 	kfree(radeon_crtc);
 }
 
-/*
- * Handle unpin events outside the interrupt handler proper.
+/**
+ * radeon_unpin_work_func - unpin old buffer object
+ *
+ * @__work - kernel work item
+ *
+ * Unpin the old frame buffer object outside of the interrupt handler
  */
 static void radeon_unpin_work_func(struct work_struct *__work)
 {
-	struct radeon_unpin_work *work =
-		container_of(__work, struct radeon_unpin_work, work);
+	struct radeon_flip_work *work =
+		container_of(__work, struct radeon_flip_work, unpin_work);
 	int r;
 
 	/* unpin of the old buffer */
@@ -279,30 +284,19 @@ static void radeon_unpin_work_func(struct work_struct *__work)
 void radeon_crtc_handle_vblank(struct radeon_device *rdev, int crtc_id)
 {
 	struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id];
-	struct radeon_unpin_work *work;
+	struct radeon_flip_work *work;
 	unsigned long flags;
 	u32 update_pending;
 	int vpos, hpos;
 
 	spin_lock_irqsave(&rdev->ddev->event_lock, flags);
-	work = radeon_crtc->unpin_work;
-	if (work == NULL ||
-	    (work->fence && !radeon_fence_signaled(work->fence))) {
+	work = radeon_crtc->flip_work;
+	if (work == NULL) {
 		spin_unlock_irqrestore(&rdev->ddev->event_lock, flags);
 		return;
 	}
-	/* New pageflip, or just completion of a previous one? */
-	if (!radeon_crtc->deferred_flip_completion) {
-		/* do the flip (mmio) */
-		radeon_page_flip(rdev, crtc_id, work->new_crtc_base);
-		update_pending = radeon_page_flip_pending(rdev, crtc_id);
-	} else {
-		/* This is just a completion of a flip queued in crtc
-		 * at last invocation. Make sure we go directly to
-		 * completion routine.
-		 */
-		update_pending = 0;
-	}
+
+	update_pending = radeon_page_flip_pending(rdev, crtc_id);
 
 	/* Has the pageflip already completed in crtc, or is it certain
 	 * to complete in this vblank?
@@ -320,19 +314,9 @@ void radeon_crtc_handle_vblank(struct radeon_device *rdev, int crtc_id)
 		 */
 		update_pending = 0;
 	}
-	if (update_pending) {
-		/* crtc didn't flip in this target vblank interval,
-		 * but flip is pending in crtc. It will complete it
-		 * in next vblank interval, so complete the flip at
-		 * next vblank irq.
-		 */
-		radeon_crtc->deferred_flip_completion = 1;
-		spin_unlock_irqrestore(&rdev->ddev->event_lock, flags);
-		return;
-	} else {
-		spin_unlock_irqrestore(&rdev->ddev->event_lock, flags);
+	spin_unlock_irqrestore(&rdev->ddev->event_lock, flags);
+	if (!update_pending)
 		radeon_crtc_handle_flip(rdev, crtc_id);
-	}
 }
 
 /**
@@ -346,7 +330,7 @@ void radeon_crtc_handle_vblank(struct radeon_device *rdev, int crtc_id)
 void radeon_crtc_handle_flip(struct radeon_device *rdev, int crtc_id)
 {
 	struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id];
-	struct radeon_unpin_work *work;
+	struct radeon_flip_work *work;
 	unsigned long flags;
 
 	/* this can happen at init */
@@ -354,15 +338,14 @@ void radeon_crtc_handle_flip(struct radeon_device *rdev, int crtc_id)
 		return;
 
 	spin_lock_irqsave(&rdev->ddev->event_lock, flags);
-	work = radeon_crtc->unpin_work;
+	work = radeon_crtc->flip_work;
 	if (work == NULL) {
 		spin_unlock_irqrestore(&rdev->ddev->event_lock, flags);
 		return;
 	}
 
-	/* Pageflip (will be) certainly completed in this vblank. Clean up. */
-	radeon_crtc->unpin_work = NULL;
-	radeon_crtc->deferred_flip_completion = 0;
+	/* Pageflip completed. Clean up. */
+	radeon_crtc->flip_work = NULL;
 
 	/* wakeup userspace */
 	if (work->event)
@@ -372,83 +355,69 @@ void radeon_crtc_handle_flip(struct radeon_device *rdev, int crtc_id)
 
 	radeon_fence_unref(&work->fence);
 	radeon_irq_kms_pflip_irq_get(rdev, work->crtc_id);
-	schedule_work(&work->work);
+	queue_work(radeon_crtc->flip_queue, &work->unpin_work);
 }
 
-static int radeon_crtc_page_flip(struct drm_crtc *crtc,
-				 struct drm_framebuffer *fb,
-				 struct drm_pending_vblank_event *event,
-				 uint32_t page_flip_flags)
+/**
+ * radeon_flip_work_func - page flip framebuffer
+ *
+ * @work - kernel work item
+ *
+ * Wait for the buffer object to become idle and do the actual page flip
+ */
+static void radeon_flip_work_func(struct work_struct *__work)
 {
-	struct drm_device *dev = crtc->dev;
-	struct radeon_device *rdev = dev->dev_private;
-	struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
-	struct radeon_framebuffer *old_radeon_fb;
-	struct radeon_framebuffer *new_radeon_fb;
-	struct drm_gem_object *obj;
-	struct radeon_bo *rbo;
-	struct radeon_unpin_work *work;
-	unsigned long flags;
-	u32 tiling_flags, pitch_pixels;
-	u64 base;
-	int r;
+	struct radeon_flip_work *work =
+		container_of(__work, struct radeon_flip_work, flip_work);
+	struct radeon_device *rdev = work->rdev;
+	struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[work->crtc_id];
 
-	work = kzalloc(sizeof *work, GFP_KERNEL);
-	if (work == NULL)
-		return -ENOMEM;
+	struct drm_crtc *crtc = &radeon_crtc->base;
+	struct drm_framebuffer *fb = work->fb;
 
-	work->event = event;
-	work->rdev = rdev;
-	work->crtc_id = radeon_crtc->crtc_id;
-	old_radeon_fb = to_radeon_framebuffer(crtc->primary->fb);
-	new_radeon_fb = to_radeon_framebuffer(fb);
-	/* schedule unpin of the old buffer */
-	obj = old_radeon_fb->obj;
-	/* take a reference to the old object */
-	drm_gem_object_reference(obj);
-	rbo = gem_to_radeon_bo(obj);
-	work->old_rbo = rbo;
-	obj = new_radeon_fb->obj;
-	rbo = gem_to_radeon_bo(obj);
+	uint32_t tiling_flags, pitch_pixels;
+	uint64_t base;
 
-	spin_lock(&rbo->tbo.bdev->fence_lock);
-	if (rbo->tbo.sync_obj)
-		work->fence = radeon_fence_ref(rbo->tbo.sync_obj);
-	spin_unlock(&rbo->tbo.bdev->fence_lock);
+	unsigned long flags;
+	int r;
 
-	INIT_WORK(&work->work, radeon_unpin_work_func);
+        down_read(&rdev->exclusive_lock);
+	while (work->fence) {
+		r = radeon_fence_wait(work->fence, false);
+		if (r == -EDEADLK) {
+			up_read(&rdev->exclusive_lock);
+			r = radeon_gpu_reset(rdev);
+			down_read(&rdev->exclusive_lock);
+		}
 
-	/* We borrow the event spin lock for protecting unpin_work */
-	spin_lock_irqsave(&dev->event_lock, flags);
-	if (radeon_crtc->unpin_work) {
-		DRM_DEBUG_DRIVER("flip queue: crtc already busy\n");
-		r = -EBUSY;
-		goto unlock_free;
+		if (r) {
+			DRM_ERROR("failed to wait on page flip fence (%d)!\n",
+				  r);
+			goto cleanup;
+		} else
+			radeon_fence_unref(&work->fence);
 	}
-	radeon_crtc->unpin_work = work;
-	radeon_crtc->deferred_flip_completion = 0;
-	spin_unlock_irqrestore(&dev->event_lock, flags);
 
 	/* pin the new buffer */
 	DRM_DEBUG_DRIVER("flip-ioctl() cur_fbo = %p, cur_bbo = %p\n",
-			 work->old_rbo, rbo);
+			 work->old_rbo, work->new_rbo);
 
-	r = radeon_bo_reserve(rbo, false);
+	r = radeon_bo_reserve(work->new_rbo, false);
 	if (unlikely(r != 0)) {
 		DRM_ERROR("failed to reserve new rbo buffer before flip\n");
-		goto pflip_cleanup;
+		goto cleanup;
 	}
 	/* Only 27 bit offset for legacy CRTC */
-	r = radeon_bo_pin_restricted(rbo, RADEON_GEM_DOMAIN_VRAM,
+	r = radeon_bo_pin_restricted(work->new_rbo, RADEON_GEM_DOMAIN_VRAM,
 				     ASIC_IS_AVIVO(rdev) ? 0 : 1 << 27, &base);
 	if (unlikely(r != 0)) {
-		radeon_bo_unreserve(rbo);
+		radeon_bo_unreserve(work->new_rbo);
 		r = -EINVAL;
 		DRM_ERROR("failed to pin new rbo buffer before flip\n");
-		goto pflip_cleanup;
+		goto cleanup;
 	}
-	radeon_bo_get_tiling_flags(rbo, &tiling_flags, NULL);
-	radeon_bo_unreserve(rbo);
+	radeon_bo_get_tiling_flags(work->new_rbo, &tiling_flags, NULL);
+	radeon_bo_unreserve(work->new_rbo);
 
 	if (!ASIC_IS_AVIVO(rdev)) {
 		/* crtc offset is from display base addr not FB location */
@@ -486,28 +455,91 @@ static int radeon_crtc_page_flip(struct drm_crtc *crtc,
 		base &= ~7;
 	}
 
-	spin_lock_irqsave(&dev->event_lock, flags);
-	work->new_crtc_base = base;
-	spin_unlock_irqrestore(&dev->event_lock, flags);
-
-	/* update crtc fb */
-	crtc->primary->fb = fb;
+	/* We borrow the event spin lock for protecting flip_work */
+	spin_lock_irqsave(&crtc->dev->event_lock, flags);
 
 	/* set the proper interrupt */
 	radeon_irq_kms_pflip_irq_get(rdev, radeon_crtc->crtc_id);
 
-	return 0;
+	/* do the flip (mmio) */
+	radeon_page_flip(rdev, radeon_crtc->crtc_id, base);
 
-pflip_cleanup:
-	spin_lock_irqsave(&dev->event_lock, flags);
-	radeon_crtc->unpin_work = NULL;
-unlock_free:
-	spin_unlock_irqrestore(&dev->event_lock, flags);
-	drm_gem_object_unreference_unlocked(old_radeon_fb->obj);
+	spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
+	up_read(&rdev->exclusive_lock);
+
+	return;
+
+cleanup:
+	drm_gem_object_unreference_unlocked(&work->old_rbo->gem_base);
 	radeon_fence_unref(&work->fence);
 	kfree(work);
+	up_read(&rdev->exclusive_lock);
+}
+
+static int radeon_crtc_page_flip(struct drm_crtc *crtc,
+				 struct drm_framebuffer *fb,
+				 struct drm_pending_vblank_event *event,
+				 uint32_t page_flip_flags)
+{
+	struct drm_device *dev = crtc->dev;
+	struct radeon_device *rdev = dev->dev_private;
+	struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
+	struct radeon_framebuffer *old_radeon_fb;
+	struct radeon_framebuffer *new_radeon_fb;
+	struct drm_gem_object *obj;
+	struct radeon_flip_work *work;
+	unsigned long flags;
+
+	work = kzalloc(sizeof *work, GFP_KERNEL);
+	if (work == NULL)
+		return -ENOMEM;
+
+	INIT_WORK(&work->flip_work, radeon_flip_work_func);
+	INIT_WORK(&work->unpin_work, radeon_unpin_work_func);
 
-	return r;
+	work->rdev = rdev;
+	work->crtc_id = radeon_crtc->crtc_id;
+	work->fb = fb;
+	work->event = event;
+
+	/* schedule unpin of the old buffer */
+	old_radeon_fb = to_radeon_framebuffer(crtc->primary->fb);
+	obj = old_radeon_fb->obj;
+
+	/* take a reference to the old object */
+	drm_gem_object_reference(obj);
+	work->old_rbo = gem_to_radeon_bo(obj);
+
+	new_radeon_fb = to_radeon_framebuffer(fb);
+	obj = new_radeon_fb->obj;
+	work->new_rbo = gem_to_radeon_bo(obj);
+
+	spin_lock(&work->new_rbo->tbo.bdev->fence_lock);
+	if (work->new_rbo->tbo.sync_obj)
+		work->fence = radeon_fence_ref(work->new_rbo->tbo.sync_obj);
+	spin_unlock(&work->new_rbo->tbo.bdev->fence_lock);
+
+	/* update crtc fb */
+	crtc->primary->fb = fb;
+
+	/* We borrow the event spin lock for protecting flip_work */
+	spin_lock_irqsave(&crtc->dev->event_lock, flags);
+
+	if (radeon_crtc->flip_work) {
+		DRM_DEBUG_DRIVER("flip queue: crtc already busy\n");
+		spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
+		drm_gem_object_unreference_unlocked(&work->old_rbo->gem_base);
+		radeon_fence_unref(&work->fence);
+		kfree(work);
+		return -EBUSY;
+	}
+	radeon_crtc->flip_work = work;
+
+	spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
+
+	queue_work(radeon_crtc->flip_queue, &work->flip_work);
+
+	return 0;
 }
 
 static int
@@ -577,6 +609,7 @@ static void radeon_crtc_init(struct drm_device *dev, int index)
 
 	drm_mode_crtc_set_gamma_size(&radeon_crtc->base, 256);
 	radeon_crtc->crtc_id = index;
+	radeon_crtc->flip_queue = create_singlethread_workqueue("radeon-crtc");
 	rdev->mode_info.crtcs[index] = radeon_crtc;
 
 	if (rdev->family >= CHIP_BONAIRE) {
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h
index 718be1a..ea72ad8 100644
--- a/drivers/gpu/drm/radeon/radeon_mode.h
+++ b/drivers/gpu/drm/radeon/radeon_mode.h
@@ -325,8 +325,8 @@ struct radeon_crtc {
 	struct drm_display_mode native_mode;
 	int pll_id;
 	/* page flipping */
-	struct radeon_unpin_work *unpin_work;
-	int deferred_flip_completion;
+	struct workqueue_struct *flip_queue;
+	struct radeon_flip_work *flip_work;
 	/* pll sharing */
 	struct radeon_atom_ss ss;
 	bool ss_enabled;
-- 
1.9.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [PATCH 1/5] drm/radeon: remove (pre|post)_page_flip callbacks
  2014-05-27 14:49 [PATCH 1/5] drm/radeon: remove (pre|post)_page_flip callbacks Christian König
                   ` (3 preceding siblings ...)
  2014-05-27 14:49 ` [PATCH 5/5] drm/radeon: rework page flip handling v3 Christian König
@ 2014-05-27 15:56 ` Alex Deucher
  4 siblings, 0 replies; 13+ messages in thread
From: Alex Deucher @ 2014-05-27 15:56 UTC (permalink / raw)
  To: Christian König; +Cc: Maling list - DRI developers

On Tue, May 27, 2014 at 10:49 AM, Christian König
<deathsimple@vodafone.de> wrote:
> From: Christian König <christian.koenig@amd.com>
>
> They are doing the same on all generations anyway.
>
> Signed-off-by: Christian König <christian.koenig@amd.com>

Reviewed-by: Alex Deucher <alexander.deucher@amd.com>

> ---
>  drivers/gpu/drm/radeon/evergreen.c      | 30 ----------------------
>  drivers/gpu/drm/radeon/r100.c           | 30 ----------------------
>  drivers/gpu/drm/radeon/radeon.h         |  4 ---
>  drivers/gpu/drm/radeon/radeon_asic.c    | 44 ---------------------------------
>  drivers/gpu/drm/radeon/radeon_asic.h    |  6 -----
>  drivers/gpu/drm/radeon/radeon_display.c |  4 +--
>  drivers/gpu/drm/radeon/rs600.c          | 12 ---------
>  7 files changed, 2 insertions(+), 128 deletions(-)
>
> diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c
> index b406546..ec31a82 100644
> --- a/drivers/gpu/drm/radeon/evergreen.c
> +++ b/drivers/gpu/drm/radeon/evergreen.c
> @@ -1301,36 +1301,6 @@ void dce4_wait_for_vblank(struct radeon_device *rdev, int crtc)
>  }
>
>  /**
> - * radeon_irq_kms_pflip_irq_get - pre-pageflip callback.
> - *
> - * @rdev: radeon_device pointer
> - * @crtc: crtc to prepare for pageflip on
> - *
> - * Pre-pageflip callback (evergreen+).
> - * Enables the pageflip irq (vblank irq).
> - */
> -void evergreen_pre_page_flip(struct radeon_device *rdev, int crtc)
> -{
> -       /* enable the pflip int */
> -       radeon_irq_kms_pflip_irq_get(rdev, crtc);
> -}
> -
> -/**
> - * evergreen_post_page_flip - pos-pageflip callback.
> - *
> - * @rdev: radeon_device pointer
> - * @crtc: crtc to cleanup pageflip on
> - *
> - * Post-pageflip callback (evergreen+).
> - * Disables the pageflip irq (vblank irq).
> - */
> -void evergreen_post_page_flip(struct radeon_device *rdev, int crtc)
> -{
> -       /* disable the pflip int */
> -       radeon_irq_kms_pflip_irq_put(rdev, crtc);
> -}
> -
> -/**
>   * evergreen_page_flip - pageflip callback.
>   *
>   * @rdev: radeon_device pointer
> diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
> index b6c3264..840651f 100644
> --- a/drivers/gpu/drm/radeon/r100.c
> +++ b/drivers/gpu/drm/radeon/r100.c
> @@ -142,36 +142,6 @@ void r100_wait_for_vblank(struct radeon_device *rdev, int crtc)
>  }
>
>  /**
> - * r100_pre_page_flip - pre-pageflip callback.
> - *
> - * @rdev: radeon_device pointer
> - * @crtc: crtc to prepare for pageflip on
> - *
> - * Pre-pageflip callback (r1xx-r4xx).
> - * Enables the pageflip irq (vblank irq).
> - */
> -void r100_pre_page_flip(struct radeon_device *rdev, int crtc)
> -{
> -       /* enable the pflip int */
> -       radeon_irq_kms_pflip_irq_get(rdev, crtc);
> -}
> -
> -/**
> - * r100_post_page_flip - pos-pageflip callback.
> - *
> - * @rdev: radeon_device pointer
> - * @crtc: crtc to cleanup pageflip on
> - *
> - * Post-pageflip callback (r1xx-r4xx).
> - * Disables the pageflip irq (vblank irq).
> - */
> -void r100_post_page_flip(struct radeon_device *rdev, int crtc)
> -{
> -       /* disable the pflip int */
> -       radeon_irq_kms_pflip_irq_put(rdev, crtc);
> -}
> -
> -/**
>   * r100_page_flip - pageflip callback.
>   *
>   * @rdev: radeon_device pointer
> diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
> index 325f3a5..2b919af 100644
> --- a/drivers/gpu/drm/radeon/radeon.h
> +++ b/drivers/gpu/drm/radeon/radeon.h
> @@ -1881,9 +1881,7 @@ struct radeon_asic {
>         } dpm;
>         /* pageflipping */
>         struct {
> -               void (*pre_page_flip)(struct radeon_device *rdev, int crtc);
>                 u32 (*page_flip)(struct radeon_device *rdev, int crtc, u64 crtc_base);
> -               void (*post_page_flip)(struct radeon_device *rdev, int crtc);
>         } pflip;
>  };
>
> @@ -2742,9 +2740,7 @@ void radeon_ring_write(struct radeon_ring *ring, uint32_t v);
>  #define radeon_pm_finish(rdev) (rdev)->asic->pm.finish((rdev))
>  #define radeon_pm_init_profile(rdev) (rdev)->asic->pm.init_profile((rdev))
>  #define radeon_pm_get_dynpm_state(rdev) (rdev)->asic->pm.get_dynpm_state((rdev))
> -#define radeon_pre_page_flip(rdev, crtc) (rdev)->asic->pflip.pre_page_flip((rdev), (crtc))
>  #define radeon_page_flip(rdev, crtc, base) (rdev)->asic->pflip.page_flip((rdev), (crtc), (base))
> -#define radeon_post_page_flip(rdev, crtc) (rdev)->asic->pflip.post_page_flip((rdev), (crtc))
>  #define radeon_wait_for_vblank(rdev, crtc) (rdev)->asic->display.wait_for_vblank((rdev), (crtc))
>  #define radeon_mc_wait_for_idle(rdev) (rdev)->asic->mc_wait_for_idle((rdev))
>  #define radeon_get_xclk(rdev) (rdev)->asic->get_xclk((rdev))
> diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c
> index ddcd0a2..cb7a0ea 100644
> --- a/drivers/gpu/drm/radeon/radeon_asic.c
> +++ b/drivers/gpu/drm/radeon/radeon_asic.c
> @@ -248,9 +248,7 @@ static struct radeon_asic r100_asic = {
>                 .set_clock_gating = &radeon_legacy_set_clock_gating,
>         },
>         .pflip = {
> -               .pre_page_flip = &r100_pre_page_flip,
>                 .page_flip = &r100_page_flip,
> -               .post_page_flip = &r100_post_page_flip,
>         },
>  };
>
> @@ -315,9 +313,7 @@ static struct radeon_asic r200_asic = {
>                 .set_clock_gating = &radeon_legacy_set_clock_gating,
>         },
>         .pflip = {
> -               .pre_page_flip = &r100_pre_page_flip,
>                 .page_flip = &r100_page_flip,
> -               .post_page_flip = &r100_post_page_flip,
>         },
>  };
>
> @@ -396,9 +392,7 @@ static struct radeon_asic r300_asic = {
>                 .set_clock_gating = &radeon_legacy_set_clock_gating,
>         },
>         .pflip = {
> -               .pre_page_flip = &r100_pre_page_flip,
>                 .page_flip = &r100_page_flip,
> -               .post_page_flip = &r100_post_page_flip,
>         },
>  };
>
> @@ -463,9 +457,7 @@ static struct radeon_asic r300_asic_pcie = {
>                 .set_clock_gating = &radeon_legacy_set_clock_gating,
>         },
>         .pflip = {
> -               .pre_page_flip = &r100_pre_page_flip,
>                 .page_flip = &r100_page_flip,
> -               .post_page_flip = &r100_post_page_flip,
>         },
>  };
>
> @@ -530,9 +522,7 @@ static struct radeon_asic r420_asic = {
>                 .set_clock_gating = &radeon_atom_set_clock_gating,
>         },
>         .pflip = {
> -               .pre_page_flip = &r100_pre_page_flip,
>                 .page_flip = &r100_page_flip,
> -               .post_page_flip = &r100_post_page_flip,
>         },
>  };
>
> @@ -597,9 +587,7 @@ static struct radeon_asic rs400_asic = {
>                 .set_clock_gating = &radeon_legacy_set_clock_gating,
>         },
>         .pflip = {
> -               .pre_page_flip = &r100_pre_page_flip,
>                 .page_flip = &r100_page_flip,
> -               .post_page_flip = &r100_post_page_flip,
>         },
>  };
>
> @@ -666,9 +654,7 @@ static struct radeon_asic rs600_asic = {
>                 .set_clock_gating = &radeon_atom_set_clock_gating,
>         },
>         .pflip = {
> -               .pre_page_flip = &rs600_pre_page_flip,
>                 .page_flip = &rs600_page_flip,
> -               .post_page_flip = &rs600_post_page_flip,
>         },
>  };
>
> @@ -735,9 +721,7 @@ static struct radeon_asic rs690_asic = {
>                 .set_clock_gating = &radeon_atom_set_clock_gating,
>         },
>         .pflip = {
> -               .pre_page_flip = &rs600_pre_page_flip,
>                 .page_flip = &rs600_page_flip,
> -               .post_page_flip = &rs600_post_page_flip,
>         },
>  };
>
> @@ -802,9 +786,7 @@ static struct radeon_asic rv515_asic = {
>                 .set_clock_gating = &radeon_atom_set_clock_gating,
>         },
>         .pflip = {
> -               .pre_page_flip = &rs600_pre_page_flip,
>                 .page_flip = &rs600_page_flip,
> -               .post_page_flip = &rs600_post_page_flip,
>         },
>  };
>
> @@ -869,9 +851,7 @@ static struct radeon_asic r520_asic = {
>                 .set_clock_gating = &radeon_atom_set_clock_gating,
>         },
>         .pflip = {
> -               .pre_page_flip = &rs600_pre_page_flip,
>                 .page_flip = &rs600_page_flip,
> -               .post_page_flip = &rs600_post_page_flip,
>         },
>  };
>
> @@ -968,9 +948,7 @@ static struct radeon_asic r600_asic = {
>                 .get_temperature = &rv6xx_get_temp,
>         },
>         .pflip = {
> -               .pre_page_flip = &rs600_pre_page_flip,
>                 .page_flip = &rs600_page_flip,
> -               .post_page_flip = &rs600_post_page_flip,
>         },
>  };
>
> @@ -1059,9 +1037,7 @@ static struct radeon_asic rv6xx_asic = {
>                 .force_performance_level = &rv6xx_dpm_force_performance_level,
>         },
>         .pflip = {
> -               .pre_page_flip = &rs600_pre_page_flip,
>                 .page_flip = &rs600_page_flip,
> -               .post_page_flip = &rs600_post_page_flip,
>         },
>  };
>
> @@ -1150,9 +1126,7 @@ static struct radeon_asic rs780_asic = {
>                 .force_performance_level = &rs780_dpm_force_performance_level,
>         },
>         .pflip = {
> -               .pre_page_flip = &rs600_pre_page_flip,
>                 .page_flip = &rs600_page_flip,
> -               .post_page_flip = &rs600_post_page_flip,
>         },
>  };
>
> @@ -1256,9 +1230,7 @@ static struct radeon_asic rv770_asic = {
>                 .vblank_too_short = &rv770_dpm_vblank_too_short,
>         },
>         .pflip = {
> -               .pre_page_flip = &rs600_pre_page_flip,
>                 .page_flip = &rv770_page_flip,
> -               .post_page_flip = &rs600_post_page_flip,
>         },
>  };
>
> @@ -1375,9 +1347,7 @@ static struct radeon_asic evergreen_asic = {
>                 .vblank_too_short = &cypress_dpm_vblank_too_short,
>         },
>         .pflip = {
> -               .pre_page_flip = &evergreen_pre_page_flip,
>                 .page_flip = &evergreen_page_flip,
> -               .post_page_flip = &evergreen_post_page_flip,
>         },
>  };
>
> @@ -1467,9 +1437,7 @@ static struct radeon_asic sumo_asic = {
>                 .force_performance_level = &sumo_dpm_force_performance_level,
>         },
>         .pflip = {
> -               .pre_page_flip = &evergreen_pre_page_flip,
>                 .page_flip = &evergreen_page_flip,
> -               .post_page_flip = &evergreen_post_page_flip,
>         },
>  };
>
> @@ -1560,9 +1528,7 @@ static struct radeon_asic btc_asic = {
>                 .vblank_too_short = &btc_dpm_vblank_too_short,
>         },
>         .pflip = {
> -               .pre_page_flip = &evergreen_pre_page_flip,
>                 .page_flip = &evergreen_page_flip,
> -               .post_page_flip = &evergreen_post_page_flip,
>         },
>  };
>
> @@ -1704,9 +1670,7 @@ static struct radeon_asic cayman_asic = {
>                 .vblank_too_short = &ni_dpm_vblank_too_short,
>         },
>         .pflip = {
> -               .pre_page_flip = &evergreen_pre_page_flip,
>                 .page_flip = &evergreen_page_flip,
> -               .post_page_flip = &evergreen_post_page_flip,
>         },
>  };
>
> @@ -1805,9 +1769,7 @@ static struct radeon_asic trinity_asic = {
>                 .enable_bapm = &trinity_dpm_enable_bapm,
>         },
>         .pflip = {
> -               .pre_page_flip = &evergreen_pre_page_flip,
>                 .page_flip = &evergreen_page_flip,
> -               .post_page_flip = &evergreen_post_page_flip,
>         },
>  };
>
> @@ -1936,9 +1898,7 @@ static struct radeon_asic si_asic = {
>                 .vblank_too_short = &ni_dpm_vblank_too_short,
>         },
>         .pflip = {
> -               .pre_page_flip = &evergreen_pre_page_flip,
>                 .page_flip = &evergreen_page_flip,
> -               .post_page_flip = &evergreen_post_page_flip,
>         },
>  };
>
> @@ -2099,9 +2059,7 @@ static struct radeon_asic ci_asic = {
>                 .powergate_uvd = &ci_dpm_powergate_uvd,
>         },
>         .pflip = {
> -               .pre_page_flip = &evergreen_pre_page_flip,
>                 .page_flip = &evergreen_page_flip,
> -               .post_page_flip = &evergreen_post_page_flip,
>         },
>  };
>
> @@ -2204,9 +2162,7 @@ static struct radeon_asic kv_asic = {
>                 .enable_bapm = &kv_dpm_enable_bapm,
>         },
>         .pflip = {
> -               .pre_page_flip = &evergreen_pre_page_flip,
>                 .page_flip = &evergreen_page_flip,
> -               .post_page_flip = &evergreen_post_page_flip,
>         },
>  };
>
> diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h
> index e6455b9..953607d 100644
> --- a/drivers/gpu/drm/radeon/radeon_asic.h
> +++ b/drivers/gpu/drm/radeon/radeon_asic.h
> @@ -135,9 +135,7 @@ extern void r100_pm_prepare(struct radeon_device *rdev);
>  extern void r100_pm_finish(struct radeon_device *rdev);
>  extern void r100_pm_init_profile(struct radeon_device *rdev);
>  extern void r100_pm_get_dynpm_state(struct radeon_device *rdev);
> -extern void r100_pre_page_flip(struct radeon_device *rdev, int crtc);
>  extern u32 r100_page_flip(struct radeon_device *rdev, int crtc, u64 crtc_base);
> -extern void r100_post_page_flip(struct radeon_device *rdev, int crtc);
>  extern void r100_wait_for_vblank(struct radeon_device *rdev, int crtc);
>  extern int r100_mc_wait_for_idle(struct radeon_device *rdev);
>
> @@ -241,9 +239,7 @@ void rs600_hpd_set_polarity(struct radeon_device *rdev,
>  extern void rs600_pm_misc(struct radeon_device *rdev);
>  extern void rs600_pm_prepare(struct radeon_device *rdev);
>  extern void rs600_pm_finish(struct radeon_device *rdev);
> -extern void rs600_pre_page_flip(struct radeon_device *rdev, int crtc);
>  extern u32 rs600_page_flip(struct radeon_device *rdev, int crtc, u64 crtc_base);
> -extern void rs600_post_page_flip(struct radeon_device *rdev, int crtc);
>  void rs600_set_safe_registers(struct radeon_device *rdev);
>  extern void avivo_wait_for_vblank(struct radeon_device *rdev, int crtc);
>  extern int rs600_mc_wait_for_idle(struct radeon_device *rdev);
> @@ -520,9 +516,7 @@ extern void sumo_pm_init_profile(struct radeon_device *rdev);
>  extern void btc_pm_init_profile(struct radeon_device *rdev);
>  int sumo_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk);
>  int evergreen_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk);
> -extern void evergreen_pre_page_flip(struct radeon_device *rdev, int crtc);
>  extern u32 evergreen_page_flip(struct radeon_device *rdev, int crtc, u64 crtc_base);
> -extern void evergreen_post_page_flip(struct radeon_device *rdev, int crtc);
>  extern void dce4_wait_for_vblank(struct radeon_device *rdev, int crtc);
>  void evergreen_disable_interrupt_state(struct radeon_device *rdev);
>  int evergreen_mc_wait_for_idle(struct radeon_device *rdev);
> diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c
> index 8d99d5e..beccc4a 100644
> --- a/drivers/gpu/drm/radeon/radeon_display.c
> +++ b/drivers/gpu/drm/radeon/radeon_display.c
> @@ -342,7 +342,7 @@ void radeon_crtc_handle_flip(struct radeon_device *rdev, int crtc_id)
>
>         drm_vblank_put(rdev->ddev, radeon_crtc->crtc_id);
>         radeon_fence_unref(&work->fence);
> -       radeon_post_page_flip(work->rdev, work->crtc_id);
> +       radeon_irq_kms_pflip_irq_get(rdev, work->crtc_id);
>         schedule_work(&work->work);
>  }
>
> @@ -471,7 +471,7 @@ static int radeon_crtc_page_flip(struct drm_crtc *crtc,
>         }
>
>         /* set the proper interrupt */
> -       radeon_pre_page_flip(rdev, radeon_crtc->crtc_id);
> +       radeon_irq_kms_pflip_irq_get(rdev, radeon_crtc->crtc_id);
>
>         return 0;
>
> diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c
> index 72d3616..e005bd7 100644
> --- a/drivers/gpu/drm/radeon/rs600.c
> +++ b/drivers/gpu/drm/radeon/rs600.c
> @@ -109,18 +109,6 @@ void avivo_wait_for_vblank(struct radeon_device *rdev, int crtc)
>         }
>  }
>
> -void rs600_pre_page_flip(struct radeon_device *rdev, int crtc)
> -{
> -       /* enable the pflip int */
> -       radeon_irq_kms_pflip_irq_get(rdev, crtc);
> -}
> -
> -void rs600_post_page_flip(struct radeon_device *rdev, int crtc)
> -{
> -       /* disable the pflip int */
> -       radeon_irq_kms_pflip_irq_put(rdev, crtc);
> -}
> -
>  u32 rs600_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base)
>  {
>         struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id];
> --
> 1.9.1
>
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 2/5] drm/radeon: remove drm_vblank_get|put from pflip handling
  2014-05-27 14:49 ` [PATCH 2/5] drm/radeon: remove drm_vblank_get|put from pflip handling Christian König
@ 2014-05-27 15:56   ` Alex Deucher
  0 siblings, 0 replies; 13+ messages in thread
From: Alex Deucher @ 2014-05-27 15:56 UTC (permalink / raw)
  To: Christian König; +Cc: Maling list - DRI developers

On Tue, May 27, 2014 at 10:49 AM, Christian König
<deathsimple@vodafone.de> wrote:
> From: Christian König <christian.koenig@amd.com>
>
> We activate the VBLANK irq manually anyway, so this is unnecessary.
>
> Signed-off-by: Christian König <christian.koenig@amd.com>

Reviewed-by: Alex Deucher <alexander.deucher@amd.com>

> ---
>  drivers/gpu/drm/radeon/radeon_display.c | 17 -----------------
>  1 file changed, 17 deletions(-)
>
> diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c
> index beccc4a..d597d08 100644
> --- a/drivers/gpu/drm/radeon/radeon_display.c
> +++ b/drivers/gpu/drm/radeon/radeon_display.c
> @@ -340,7 +340,6 @@ void radeon_crtc_handle_flip(struct radeon_device *rdev, int crtc_id)
>
>         spin_unlock_irqrestore(&rdev->ddev->event_lock, flags);
>
> -       drm_vblank_put(rdev->ddev, radeon_crtc->crtc_id);
>         radeon_fence_unref(&work->fence);
>         radeon_irq_kms_pflip_irq_get(rdev, work->crtc_id);
>         schedule_work(&work->work);
> @@ -464,27 +463,11 @@ static int radeon_crtc_page_flip(struct drm_crtc *crtc,
>         /* update crtc fb */
>         crtc->primary->fb = fb;
>
> -       r = drm_vblank_get(dev, radeon_crtc->crtc_id);
> -       if (r) {
> -               DRM_ERROR("failed to get vblank before flip\n");
> -               goto pflip_cleanup1;
> -       }
> -
>         /* set the proper interrupt */
>         radeon_irq_kms_pflip_irq_get(rdev, radeon_crtc->crtc_id);
>
>         return 0;
>
> -pflip_cleanup1:
> -       if (unlikely(radeon_bo_reserve(rbo, false) != 0)) {
> -               DRM_ERROR("failed to reserve new rbo in error path\n");
> -               goto pflip_cleanup;
> -       }
> -       if (unlikely(radeon_bo_unpin(rbo) != 0)) {
> -               DRM_ERROR("failed to unpin new rbo in error path\n");
> -       }
> -       radeon_bo_unreserve(rbo);
> -
>  pflip_cleanup:
>         spin_lock_irqsave(&dev->event_lock, flags);
>         radeon_crtc->unpin_work = NULL;
> --
> 1.9.1
>
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 3/5] drm/radeon: split page flip and pending callback
  2014-05-27 14:49 ` [PATCH 3/5] drm/radeon: split page flip and pending callback Christian König
@ 2014-05-27 15:57   ` Alex Deucher
  0 siblings, 0 replies; 13+ messages in thread
From: Alex Deucher @ 2014-05-27 15:57 UTC (permalink / raw)
  To: Christian König; +Cc: Maling list - DRI developers

On Tue, May 27, 2014 at 10:49 AM, Christian König
<deathsimple@vodafone.de> wrote:
> From: Christian König <christian.koenig@amd.com>
>
> Signed-off-by: Christian König <christian.koenig@amd.com>

Reviewed-by: Alex Deucher <alexander.deucher@amd.com>

> ---
>  drivers/gpu/drm/radeon/evergreen.c      | 18 ++++++++++++++++--
>  drivers/gpu/drm/radeon/r100.c           | 21 ++++++++++++++++++---
>  drivers/gpu/drm/radeon/radeon.h         |  4 +++-
>  drivers/gpu/drm/radeon/radeon_asic.c    | 22 ++++++++++++++++++++++
>  drivers/gpu/drm/radeon/radeon_asic.h    | 15 +++++++++++----
>  drivers/gpu/drm/radeon/radeon_display.c |  3 ++-
>  drivers/gpu/drm/radeon/rs600.c          | 10 ++++++++--
>  drivers/gpu/drm/radeon/rv770.c          | 10 ++++++++--
>  8 files changed, 88 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c
> index ec31a82..336f0a5 100644
> --- a/drivers/gpu/drm/radeon/evergreen.c
> +++ b/drivers/gpu/drm/radeon/evergreen.c
> @@ -1313,7 +1313,7 @@ void dce4_wait_for_vblank(struct radeon_device *rdev, int crtc)
>   * double buffered update to take place.
>   * Returns the current update pending status.
>   */
> -u32 evergreen_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base)
> +void evergreen_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base)
>  {
>         struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id];
>         u32 tmp = RREG32(EVERGREEN_GRPH_UPDATE + radeon_crtc->crtc_offset);
> @@ -1345,9 +1345,23 @@ u32 evergreen_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base)
>         /* Unlock the lock, so double-buffering can take place inside vblank */
>         tmp &= ~EVERGREEN_GRPH_UPDATE_LOCK;
>         WREG32(EVERGREEN_GRPH_UPDATE + radeon_crtc->crtc_offset, tmp);
> +}
> +
> +/**
> + * evergreen_page_flip_pending - check if page flip is still pending
> + *
> + * @rdev: radeon_device pointer
> + * @crtc_id: crtc to check
> + *
> + * Returns the current update pending status.
> + */
> +bool evergreen_page_flip_pending(struct radeon_device *rdev, int crtc_id)
> +{
> +       struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id];
>
>         /* Return current update_pending status: */
> -       return RREG32(EVERGREEN_GRPH_UPDATE + radeon_crtc->crtc_offset) & EVERGREEN_GRPH_SURFACE_UPDATE_PENDING;
> +       return !!(RREG32(EVERGREEN_GRPH_UPDATE + radeon_crtc->crtc_offset) &
> +               EVERGREEN_GRPH_SURFACE_UPDATE_PENDING);
>  }
>
>  /* get temperature in millidegrees */
> diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
> index 840651f..52548f7 100644
> --- a/drivers/gpu/drm/radeon/r100.c
> +++ b/drivers/gpu/drm/radeon/r100.c
> @@ -152,9 +152,8 @@ void r100_wait_for_vblank(struct radeon_device *rdev, int crtc)
>   * During vblank we take the crtc lock and wait for the update_pending
>   * bit to go high, when it does, we release the lock, and allow the
>   * double buffered update to take place.
> - * Returns the current update pending status.
>   */
> -u32 r100_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base)
> +void r100_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base)
>  {
>         struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id];
>         u32 tmp = ((u32)crtc_base) | RADEON_CRTC_OFFSET__OFFSET_LOCK;
> @@ -176,8 +175,24 @@ u32 r100_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base)
>         tmp &= ~RADEON_CRTC_OFFSET__OFFSET_LOCK;
>         WREG32(RADEON_CRTC_OFFSET + radeon_crtc->crtc_offset, tmp);
>
> +}
> +
> +/**
> + * r100_page_flip_pending - check if page flip is still pending
> + *
> + * @rdev: radeon_device pointer
> + * @crtc_id: crtc to check
> + *
> + * Check if the last pagefilp is still pending (r1xx-r4xx).
> + * Returns the current update pending status.
> + */
> +bool r100_page_flip_pending(struct radeon_device *rdev, int crtc_id)
> +{
> +       struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id];
> +
>         /* Return current update_pending status: */
> -       return RREG32(RADEON_CRTC_OFFSET + radeon_crtc->crtc_offset) & RADEON_CRTC_OFFSET__GUI_TRIG_OFFSET;
> +       return !!(RREG32(RADEON_CRTC_OFFSET + radeon_crtc->crtc_offset) &
> +               RADEON_CRTC_OFFSET__GUI_TRIG_OFFSET);
>  }
>
>  /**
> diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
> index 2b919af..4ae304d 100644
> --- a/drivers/gpu/drm/radeon/radeon.h
> +++ b/drivers/gpu/drm/radeon/radeon.h
> @@ -1881,7 +1881,8 @@ struct radeon_asic {
>         } dpm;
>         /* pageflipping */
>         struct {
> -               u32 (*page_flip)(struct radeon_device *rdev, int crtc, u64 crtc_base);
> +               void (*page_flip)(struct radeon_device *rdev, int crtc, u64 crtc_base);
> +               bool (*page_flip_pending)(struct radeon_device *rdev, int crtc);
>         } pflip;
>  };
>
> @@ -2741,6 +2742,7 @@ void radeon_ring_write(struct radeon_ring *ring, uint32_t v);
>  #define radeon_pm_init_profile(rdev) (rdev)->asic->pm.init_profile((rdev))
>  #define radeon_pm_get_dynpm_state(rdev) (rdev)->asic->pm.get_dynpm_state((rdev))
>  #define radeon_page_flip(rdev, crtc, base) (rdev)->asic->pflip.page_flip((rdev), (crtc), (base))
> +#define radeon_page_flip_pending(rdev, crtc) (rdev)->asic->pflip.page_flip_pending((rdev), (crtc))
>  #define radeon_wait_for_vblank(rdev, crtc) (rdev)->asic->display.wait_for_vblank((rdev), (crtc))
>  #define radeon_mc_wait_for_idle(rdev) (rdev)->asic->mc_wait_for_idle((rdev))
>  #define radeon_get_xclk(rdev) (rdev)->asic->get_xclk((rdev))
> diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c
> index cb7a0ea..d8e1587 100644
> --- a/drivers/gpu/drm/radeon/radeon_asic.c
> +++ b/drivers/gpu/drm/radeon/radeon_asic.c
> @@ -249,6 +249,7 @@ static struct radeon_asic r100_asic = {
>         },
>         .pflip = {
>                 .page_flip = &r100_page_flip,
> +               .page_flip_pending = &r100_page_flip_pending,
>         },
>  };
>
> @@ -314,6 +315,7 @@ static struct radeon_asic r200_asic = {
>         },
>         .pflip = {
>                 .page_flip = &r100_page_flip,
> +               .page_flip_pending = &r100_page_flip_pending,
>         },
>  };
>
> @@ -393,6 +395,7 @@ static struct radeon_asic r300_asic = {
>         },
>         .pflip = {
>                 .page_flip = &r100_page_flip,
> +               .page_flip_pending = &r100_page_flip_pending,
>         },
>  };
>
> @@ -458,6 +461,7 @@ static struct radeon_asic r300_asic_pcie = {
>         },
>         .pflip = {
>                 .page_flip = &r100_page_flip,
> +               .page_flip_pending = &r100_page_flip_pending,
>         },
>  };
>
> @@ -523,6 +527,7 @@ static struct radeon_asic r420_asic = {
>         },
>         .pflip = {
>                 .page_flip = &r100_page_flip,
> +               .page_flip_pending = &r100_page_flip_pending,
>         },
>  };
>
> @@ -588,6 +593,7 @@ static struct radeon_asic rs400_asic = {
>         },
>         .pflip = {
>                 .page_flip = &r100_page_flip,
> +               .page_flip_pending = &r100_page_flip_pending,
>         },
>  };
>
> @@ -655,6 +661,7 @@ static struct radeon_asic rs600_asic = {
>         },
>         .pflip = {
>                 .page_flip = &rs600_page_flip,
> +               .page_flip_pending = &rs600_page_flip_pending,
>         },
>  };
>
> @@ -722,6 +729,7 @@ static struct radeon_asic rs690_asic = {
>         },
>         .pflip = {
>                 .page_flip = &rs600_page_flip,
> +               .page_flip_pending = &rs600_page_flip_pending,
>         },
>  };
>
> @@ -787,6 +795,7 @@ static struct radeon_asic rv515_asic = {
>         },
>         .pflip = {
>                 .page_flip = &rs600_page_flip,
> +               .page_flip_pending = &rs600_page_flip_pending,
>         },
>  };
>
> @@ -852,6 +861,7 @@ static struct radeon_asic r520_asic = {
>         },
>         .pflip = {
>                 .page_flip = &rs600_page_flip,
> +               .page_flip_pending = &rs600_page_flip_pending,
>         },
>  };
>
> @@ -949,6 +959,7 @@ static struct radeon_asic r600_asic = {
>         },
>         .pflip = {
>                 .page_flip = &rs600_page_flip,
> +               .page_flip_pending = &rs600_page_flip_pending,
>         },
>  };
>
> @@ -1038,6 +1049,7 @@ static struct radeon_asic rv6xx_asic = {
>         },
>         .pflip = {
>                 .page_flip = &rs600_page_flip,
> +               .page_flip_pending = &rs600_page_flip_pending,
>         },
>  };
>
> @@ -1127,6 +1139,7 @@ static struct radeon_asic rs780_asic = {
>         },
>         .pflip = {
>                 .page_flip = &rs600_page_flip,
> +               .page_flip_pending = &rs600_page_flip_pending,
>         },
>  };
>
> @@ -1231,6 +1244,7 @@ static struct radeon_asic rv770_asic = {
>         },
>         .pflip = {
>                 .page_flip = &rv770_page_flip,
> +               .page_flip_pending = &rv770_page_flip_pending,
>         },
>  };
>
> @@ -1348,6 +1362,7 @@ static struct radeon_asic evergreen_asic = {
>         },
>         .pflip = {
>                 .page_flip = &evergreen_page_flip,
> +               .page_flip_pending = &evergreen_page_flip_pending,
>         },
>  };
>
> @@ -1438,6 +1453,7 @@ static struct radeon_asic sumo_asic = {
>         },
>         .pflip = {
>                 .page_flip = &evergreen_page_flip,
> +               .page_flip_pending = &evergreen_page_flip_pending,
>         },
>  };
>
> @@ -1529,6 +1545,7 @@ static struct radeon_asic btc_asic = {
>         },
>         .pflip = {
>                 .page_flip = &evergreen_page_flip,
> +               .page_flip_pending = &evergreen_page_flip_pending,
>         },
>  };
>
> @@ -1671,6 +1688,7 @@ static struct radeon_asic cayman_asic = {
>         },
>         .pflip = {
>                 .page_flip = &evergreen_page_flip,
> +               .page_flip_pending = &evergreen_page_flip_pending,
>         },
>  };
>
> @@ -1770,6 +1788,7 @@ static struct radeon_asic trinity_asic = {
>         },
>         .pflip = {
>                 .page_flip = &evergreen_page_flip,
> +               .page_flip_pending = &evergreen_page_flip_pending,
>         },
>  };
>
> @@ -1899,6 +1918,7 @@ static struct radeon_asic si_asic = {
>         },
>         .pflip = {
>                 .page_flip = &evergreen_page_flip,
> +               .page_flip_pending = &evergreen_page_flip_pending,
>         },
>  };
>
> @@ -2060,6 +2080,7 @@ static struct radeon_asic ci_asic = {
>         },
>         .pflip = {
>                 .page_flip = &evergreen_page_flip,
> +               .page_flip_pending = &evergreen_page_flip_pending,
>         },
>  };
>
> @@ -2163,6 +2184,7 @@ static struct radeon_asic kv_asic = {
>         },
>         .pflip = {
>                 .page_flip = &evergreen_page_flip,
> +               .page_flip_pending = &evergreen_page_flip_pending,
>         },
>  };
>
> diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h
> index 953607d..0eab015 100644
> --- a/drivers/gpu/drm/radeon/radeon_asic.h
> +++ b/drivers/gpu/drm/radeon/radeon_asic.h
> @@ -135,7 +135,9 @@ extern void r100_pm_prepare(struct radeon_device *rdev);
>  extern void r100_pm_finish(struct radeon_device *rdev);
>  extern void r100_pm_init_profile(struct radeon_device *rdev);
>  extern void r100_pm_get_dynpm_state(struct radeon_device *rdev);
> -extern u32 r100_page_flip(struct radeon_device *rdev, int crtc, u64 crtc_base);
> +extern void r100_page_flip(struct radeon_device *rdev, int crtc,
> +                          u64 crtc_base);
> +extern bool r100_page_flip_pending(struct radeon_device *rdev, int crtc);
>  extern void r100_wait_for_vblank(struct radeon_device *rdev, int crtc);
>  extern int r100_mc_wait_for_idle(struct radeon_device *rdev);
>
> @@ -239,7 +241,9 @@ void rs600_hpd_set_polarity(struct radeon_device *rdev,
>  extern void rs600_pm_misc(struct radeon_device *rdev);
>  extern void rs600_pm_prepare(struct radeon_device *rdev);
>  extern void rs600_pm_finish(struct radeon_device *rdev);
> -extern u32 rs600_page_flip(struct radeon_device *rdev, int crtc, u64 crtc_base);
> +extern void rs600_page_flip(struct radeon_device *rdev, int crtc,
> +                           u64 crtc_base);
> +extern bool rs600_page_flip_pending(struct radeon_device *rdev, int crtc);
>  void rs600_set_safe_registers(struct radeon_device *rdev);
>  extern void avivo_wait_for_vblank(struct radeon_device *rdev, int crtc);
>  extern int rs600_mc_wait_for_idle(struct radeon_device *rdev);
> @@ -448,7 +452,8 @@ void rv770_fini(struct radeon_device *rdev);
>  int rv770_suspend(struct radeon_device *rdev);
>  int rv770_resume(struct radeon_device *rdev);
>  void rv770_pm_misc(struct radeon_device *rdev);
> -u32 rv770_page_flip(struct radeon_device *rdev, int crtc, u64 crtc_base);
> +void rv770_page_flip(struct radeon_device *rdev, int crtc, u64 crtc_base);
> +bool rv770_page_flip_pending(struct radeon_device *rdev, int crtc);
>  void r700_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc);
>  void r700_cp_stop(struct radeon_device *rdev);
>  void r700_cp_fini(struct radeon_device *rdev);
> @@ -516,7 +521,9 @@ extern void sumo_pm_init_profile(struct radeon_device *rdev);
>  extern void btc_pm_init_profile(struct radeon_device *rdev);
>  int sumo_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk);
>  int evergreen_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk);
> -extern u32 evergreen_page_flip(struct radeon_device *rdev, int crtc, u64 crtc_base);
> +extern void evergreen_page_flip(struct radeon_device *rdev, int crtc,
> +                               u64 crtc_base);
> +extern bool evergreen_page_flip_pending(struct radeon_device *rdev, int crtc);
>  extern void dce4_wait_for_vblank(struct radeon_device *rdev, int crtc);
>  void evergreen_disable_interrupt_state(struct radeon_device *rdev);
>  int evergreen_mc_wait_for_idle(struct radeon_device *rdev);
> diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c
> index d597d08..c52c182 100644
> --- a/drivers/gpu/drm/radeon/radeon_display.c
> +++ b/drivers/gpu/drm/radeon/radeon_display.c
> @@ -294,7 +294,8 @@ void radeon_crtc_handle_flip(struct radeon_device *rdev, int crtc_id)
>         /* New pageflip, or just completion of a previous one? */
>         if (!radeon_crtc->deferred_flip_completion) {
>                 /* do the flip (mmio) */
> -               update_pending = radeon_page_flip(rdev, crtc_id, work->new_crtc_base);
> +               radeon_page_flip(rdev, crtc_id, work->new_crtc_base);
> +               update_pending = radeon_page_flip_pending(rdev, crtc_id);
>         } else {
>                 /* This is just a completion of a flip queued in crtc
>                  * at last invocation. Make sure we go directly to
> diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c
> index e005bd7..9922ee5 100644
> --- a/drivers/gpu/drm/radeon/rs600.c
> +++ b/drivers/gpu/drm/radeon/rs600.c
> @@ -109,7 +109,7 @@ void avivo_wait_for_vblank(struct radeon_device *rdev, int crtc)
>         }
>  }
>
> -u32 rs600_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base)
> +void rs600_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base)
>  {
>         struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id];
>         u32 tmp = RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset);
> @@ -136,9 +136,15 @@ u32 rs600_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base)
>         /* Unlock the lock, so double-buffering can take place inside vblank */
>         tmp &= ~AVIVO_D1GRPH_UPDATE_LOCK;
>         WREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset, tmp);
> +}
> +
> +bool rs600_page_flip_pending(struct radeon_device *rdev, int crtc_id)
> +{
> +       struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id];
>
>         /* Return current update_pending status: */
> -       return RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset) & AVIVO_D1GRPH_SURFACE_UPDATE_PENDING;
> +       return !!(RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset) &
> +               AVIVO_D1GRPH_SURFACE_UPDATE_PENDING);
>  }
>
>  void avivo_program_fmt(struct drm_encoder *encoder)
> diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c
> index fef3107..97b7766 100644
> --- a/drivers/gpu/drm/radeon/rv770.c
> +++ b/drivers/gpu/drm/radeon/rv770.c
> @@ -801,7 +801,7 @@ u32 rv770_get_xclk(struct radeon_device *rdev)
>         return reference_clock;
>  }
>
> -u32 rv770_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base)
> +void rv770_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base)
>  {
>         struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id];
>         u32 tmp = RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset);
> @@ -835,9 +835,15 @@ u32 rv770_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base)
>         /* Unlock the lock, so double-buffering can take place inside vblank */
>         tmp &= ~AVIVO_D1GRPH_UPDATE_LOCK;
>         WREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset, tmp);
> +}
> +
> +bool rv770_page_flip_pending(struct radeon_device *rdev, int crtc_id)
> +{
> +       struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id];
>
>         /* Return current update_pending status: */
> -       return RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset) & AVIVO_D1GRPH_SURFACE_UPDATE_PENDING;
> +       return !!(RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset) &
> +               AVIVO_D1GRPH_SURFACE_UPDATE_PENDING);
>  }
>
>  /* get temperature in millidegrees */
> --
> 1.9.1
>
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 4/5] drm/radeon: separate vblank and pflip crtc handling
  2014-05-27 14:49 ` [PATCH 4/5] drm/radeon: separate vblank and pflip crtc handling Christian König
@ 2014-05-27 16:49   ` Alex Deucher
  0 siblings, 0 replies; 13+ messages in thread
From: Alex Deucher @ 2014-05-27 16:49 UTC (permalink / raw)
  To: Christian König; +Cc: Maling list - DRI developers

On Tue, May 27, 2014 at 10:49 AM, Christian König
<deathsimple@vodafone.de> wrote:
> From: Christian König <christian.koenig@amd.com>
>
> Signed-off-by: Christian König <christian.koenig@amd.com>

Reviewed-by: Alex Deucher <alexander.deucher@amd.com>

> ---
>  drivers/gpu/drm/radeon/cik.c            | 12 ++++++------
>  drivers/gpu/drm/radeon/evergreen.c      | 12 ++++++------
>  drivers/gpu/drm/radeon/r100.c           |  4 ++--
>  drivers/gpu/drm/radeon/r600.c           |  4 ++--
>  drivers/gpu/drm/radeon/radeon_display.c | 33 +++++++++++++++++++++++++++++++--
>  drivers/gpu/drm/radeon/radeon_mode.h    |  1 +
>  drivers/gpu/drm/radeon/rs600.c          |  4 ++--
>  drivers/gpu/drm/radeon/si.c             | 12 ++++++------
>  8 files changed, 56 insertions(+), 26 deletions(-)
>
> diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c
> index 8d0f177..a518140 100644
> --- a/drivers/gpu/drm/radeon/cik.c
> +++ b/drivers/gpu/drm/radeon/cik.c
> @@ -7314,7 +7314,7 @@ restart_ih:
>                                                 wake_up(&rdev->irq.vblank_queue);
>                                         }
>                                         if (atomic_read(&rdev->irq.pflip[0]))
> -                                               radeon_crtc_handle_flip(rdev, 0);
> +                                               radeon_crtc_handle_vblank(rdev, 0);
>                                         rdev->irq.stat_regs.cik.disp_int &= ~LB_D1_VBLANK_INTERRUPT;
>                                         DRM_DEBUG("IH: D1 vblank\n");
>                                 }
> @@ -7340,7 +7340,7 @@ restart_ih:
>                                                 wake_up(&rdev->irq.vblank_queue);
>                                         }
>                                         if (atomic_read(&rdev->irq.pflip[1]))
> -                                               radeon_crtc_handle_flip(rdev, 1);
> +                                               radeon_crtc_handle_vblank(rdev, 1);
>                                         rdev->irq.stat_regs.cik.disp_int_cont &= ~LB_D2_VBLANK_INTERRUPT;
>                                         DRM_DEBUG("IH: D2 vblank\n");
>                                 }
> @@ -7366,7 +7366,7 @@ restart_ih:
>                                                 wake_up(&rdev->irq.vblank_queue);
>                                         }
>                                         if (atomic_read(&rdev->irq.pflip[2]))
> -                                               radeon_crtc_handle_flip(rdev, 2);
> +                                               radeon_crtc_handle_vblank(rdev, 2);
>                                         rdev->irq.stat_regs.cik.disp_int_cont2 &= ~LB_D3_VBLANK_INTERRUPT;
>                                         DRM_DEBUG("IH: D3 vblank\n");
>                                 }
> @@ -7392,7 +7392,7 @@ restart_ih:
>                                                 wake_up(&rdev->irq.vblank_queue);
>                                         }
>                                         if (atomic_read(&rdev->irq.pflip[3]))
> -                                               radeon_crtc_handle_flip(rdev, 3);
> +                                               radeon_crtc_handle_vblank(rdev, 3);
>                                         rdev->irq.stat_regs.cik.disp_int_cont3 &= ~LB_D4_VBLANK_INTERRUPT;
>                                         DRM_DEBUG("IH: D4 vblank\n");
>                                 }
> @@ -7418,7 +7418,7 @@ restart_ih:
>                                                 wake_up(&rdev->irq.vblank_queue);
>                                         }
>                                         if (atomic_read(&rdev->irq.pflip[4]))
> -                                               radeon_crtc_handle_flip(rdev, 4);
> +                                               radeon_crtc_handle_vblank(rdev, 4);
>                                         rdev->irq.stat_regs.cik.disp_int_cont4 &= ~LB_D5_VBLANK_INTERRUPT;
>                                         DRM_DEBUG("IH: D5 vblank\n");
>                                 }
> @@ -7444,7 +7444,7 @@ restart_ih:
>                                                 wake_up(&rdev->irq.vblank_queue);
>                                         }
>                                         if (atomic_read(&rdev->irq.pflip[5]))
> -                                               radeon_crtc_handle_flip(rdev, 5);
> +                                               radeon_crtc_handle_vblank(rdev, 5);
>                                         rdev->irq.stat_regs.cik.disp_int_cont5 &= ~LB_D6_VBLANK_INTERRUPT;
>                                         DRM_DEBUG("IH: D6 vblank\n");
>                                 }
> diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c
> index 336f0a5..0318230 100644
> --- a/drivers/gpu/drm/radeon/evergreen.c
> +++ b/drivers/gpu/drm/radeon/evergreen.c
> @@ -4789,7 +4789,7 @@ restart_ih:
>                                                 wake_up(&rdev->irq.vblank_queue);
>                                         }
>                                         if (atomic_read(&rdev->irq.pflip[0]))
> -                                               radeon_crtc_handle_flip(rdev, 0);
> +                                               radeon_crtc_handle_vblank(rdev, 0);
>                                         rdev->irq.stat_regs.evergreen.disp_int &= ~LB_D1_VBLANK_INTERRUPT;
>                                         DRM_DEBUG("IH: D1 vblank\n");
>                                 }
> @@ -4815,7 +4815,7 @@ restart_ih:
>                                                 wake_up(&rdev->irq.vblank_queue);
>                                         }
>                                         if (atomic_read(&rdev->irq.pflip[1]))
> -                                               radeon_crtc_handle_flip(rdev, 1);
> +                                               radeon_crtc_handle_vblank(rdev, 1);
>                                         rdev->irq.stat_regs.evergreen.disp_int_cont &= ~LB_D2_VBLANK_INTERRUPT;
>                                         DRM_DEBUG("IH: D2 vblank\n");
>                                 }
> @@ -4841,7 +4841,7 @@ restart_ih:
>                                                 wake_up(&rdev->irq.vblank_queue);
>                                         }
>                                         if (atomic_read(&rdev->irq.pflip[2]))
> -                                               radeon_crtc_handle_flip(rdev, 2);
> +                                               radeon_crtc_handle_vblank(rdev, 2);
>                                         rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~LB_D3_VBLANK_INTERRUPT;
>                                         DRM_DEBUG("IH: D3 vblank\n");
>                                 }
> @@ -4867,7 +4867,7 @@ restart_ih:
>                                                 wake_up(&rdev->irq.vblank_queue);
>                                         }
>                                         if (atomic_read(&rdev->irq.pflip[3]))
> -                                               radeon_crtc_handle_flip(rdev, 3);
> +                                               radeon_crtc_handle_vblank(rdev, 3);
>                                         rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~LB_D4_VBLANK_INTERRUPT;
>                                         DRM_DEBUG("IH: D4 vblank\n");
>                                 }
> @@ -4893,7 +4893,7 @@ restart_ih:
>                                                 wake_up(&rdev->irq.vblank_queue);
>                                         }
>                                         if (atomic_read(&rdev->irq.pflip[4]))
> -                                               radeon_crtc_handle_flip(rdev, 4);
> +                                               radeon_crtc_handle_vblank(rdev, 4);
>                                         rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~LB_D5_VBLANK_INTERRUPT;
>                                         DRM_DEBUG("IH: D5 vblank\n");
>                                 }
> @@ -4919,7 +4919,7 @@ restart_ih:
>                                                 wake_up(&rdev->irq.vblank_queue);
>                                         }
>                                         if (atomic_read(&rdev->irq.pflip[5]))
> -                                               radeon_crtc_handle_flip(rdev, 5);
> +                                               radeon_crtc_handle_vblank(rdev, 5);
>                                         rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~LB_D6_VBLANK_INTERRUPT;
>                                         DRM_DEBUG("IH: D6 vblank\n");
>                                 }
> diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
> index 52548f7..ad99813 100644
> --- a/drivers/gpu/drm/radeon/r100.c
> +++ b/drivers/gpu/drm/radeon/r100.c
> @@ -779,7 +779,7 @@ int r100_irq_process(struct radeon_device *rdev)
>                                 wake_up(&rdev->irq.vblank_queue);
>                         }
>                         if (atomic_read(&rdev->irq.pflip[0]))
> -                               radeon_crtc_handle_flip(rdev, 0);
> +                               radeon_crtc_handle_vblank(rdev, 0);
>                 }
>                 if (status & RADEON_CRTC2_VBLANK_STAT) {
>                         if (rdev->irq.crtc_vblank_int[1]) {
> @@ -788,7 +788,7 @@ int r100_irq_process(struct radeon_device *rdev)
>                                 wake_up(&rdev->irq.vblank_queue);
>                         }
>                         if (atomic_read(&rdev->irq.pflip[1]))
> -                               radeon_crtc_handle_flip(rdev, 1);
> +                               radeon_crtc_handle_vblank(rdev, 1);
>                 }
>                 if (status & RADEON_FP_DETECT_STAT) {
>                         queue_hotplug = true;
> diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
> index 6e887d0..436e550 100644
> --- a/drivers/gpu/drm/radeon/r600.c
> +++ b/drivers/gpu/drm/radeon/r600.c
> @@ -3876,7 +3876,7 @@ restart_ih:
>                                                 wake_up(&rdev->irq.vblank_queue);
>                                         }
>                                         if (atomic_read(&rdev->irq.pflip[0]))
> -                                               radeon_crtc_handle_flip(rdev, 0);
> +                                               radeon_crtc_handle_vblank(rdev, 0);
>                                         rdev->irq.stat_regs.r600.disp_int &= ~LB_D1_VBLANK_INTERRUPT;
>                                         DRM_DEBUG("IH: D1 vblank\n");
>                                 }
> @@ -3902,7 +3902,7 @@ restart_ih:
>                                                 wake_up(&rdev->irq.vblank_queue);
>                                         }
>                                         if (atomic_read(&rdev->irq.pflip[1]))
> -                                               radeon_crtc_handle_flip(rdev, 1);
> +                                               radeon_crtc_handle_vblank(rdev, 1);
>                                         rdev->irq.stat_regs.r600.disp_int &= ~LB_D2_VBLANK_INTERRUPT;
>                                         DRM_DEBUG("IH: D2 vblank\n");
>                                 }
> diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c
> index c52c182..88e3cbe 100644
> --- a/drivers/gpu/drm/radeon/radeon_display.c
> +++ b/drivers/gpu/drm/radeon/radeon_display.c
> @@ -276,7 +276,7 @@ static void radeon_unpin_work_func(struct work_struct *__work)
>         kfree(work);
>  }
>
> -void radeon_crtc_handle_flip(struct radeon_device *rdev, int crtc_id)
> +void radeon_crtc_handle_vblank(struct radeon_device *rdev, int crtc_id)
>  {
>         struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id];
>         struct radeon_unpin_work *work;
> @@ -302,7 +302,6 @@ void radeon_crtc_handle_flip(struct radeon_device *rdev, int crtc_id)
>                  * completion routine.
>                  */
>                 update_pending = 0;
> -               radeon_crtc->deferred_flip_completion = 0;
>         }
>
>         /* Has the pageflip already completed in crtc, or is it certain
> @@ -330,10 +329,40 @@ void radeon_crtc_handle_flip(struct radeon_device *rdev, int crtc_id)
>                 radeon_crtc->deferred_flip_completion = 1;
>                 spin_unlock_irqrestore(&rdev->ddev->event_lock, flags);
>                 return;
> +       } else {
> +               spin_unlock_irqrestore(&rdev->ddev->event_lock, flags);
> +               radeon_crtc_handle_flip(rdev, crtc_id);
> +       }
> +}
> +
> +/**
> + * radeon_crtc_handle_flip - page flip completed
> + *
> + * @rdev: radeon device pointer
> + * @crtc_id: crtc number this event is for
> + *
> + * Called when we are sure that a page flip for this crtc is completed.
> + */
> +void radeon_crtc_handle_flip(struct radeon_device *rdev, int crtc_id)
> +{
> +       struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id];
> +       struct radeon_unpin_work *work;
> +       unsigned long flags;
> +
> +       /* this can happen at init */
> +       if (radeon_crtc == NULL)
> +               return;
> +
> +       spin_lock_irqsave(&rdev->ddev->event_lock, flags);
> +       work = radeon_crtc->unpin_work;
> +       if (work == NULL) {
> +               spin_unlock_irqrestore(&rdev->ddev->event_lock, flags);
> +               return;
>         }
>
>         /* Pageflip (will be) certainly completed in this vblank. Clean up. */
>         radeon_crtc->unpin_work = NULL;
> +       radeon_crtc->deferred_flip_completion = 0;
>
>         /* wakeup userspace */
>         if (work->event)
> diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h
> index b265a8b..718be1a 100644
> --- a/drivers/gpu/drm/radeon/radeon_mode.h
> +++ b/drivers/gpu/drm/radeon/radeon_mode.h
> @@ -907,6 +907,7 @@ bool radeon_fbdev_robj_is_fb(struct radeon_device *rdev, struct radeon_bo *robj)
>
>  void radeon_fb_output_poll_changed(struct radeon_device *rdev);
>
> +void radeon_crtc_handle_vblank(struct radeon_device *rdev, int crtc_id);
>  void radeon_crtc_handle_flip(struct radeon_device *rdev, int crtc_id);
>
>  int radeon_align_pitch(struct radeon_device *rdev, int width, int bpp, bool tiled);
> diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c
> index 9922ee5..dd12dc2 100644
> --- a/drivers/gpu/drm/radeon/rs600.c
> +++ b/drivers/gpu/drm/radeon/rs600.c
> @@ -781,7 +781,7 @@ int rs600_irq_process(struct radeon_device *rdev)
>                                 wake_up(&rdev->irq.vblank_queue);
>                         }
>                         if (atomic_read(&rdev->irq.pflip[0]))
> -                               radeon_crtc_handle_flip(rdev, 0);
> +                               radeon_crtc_handle_vblank(rdev, 0);
>                 }
>                 if (G_007EDC_LB_D2_VBLANK_INTERRUPT(rdev->irq.stat_regs.r500.disp_int)) {
>                         if (rdev->irq.crtc_vblank_int[1]) {
> @@ -790,7 +790,7 @@ int rs600_irq_process(struct radeon_device *rdev)
>                                 wake_up(&rdev->irq.vblank_queue);
>                         }
>                         if (atomic_read(&rdev->irq.pflip[1]))
> -                               radeon_crtc_handle_flip(rdev, 1);
> +                               radeon_crtc_handle_vblank(rdev, 1);
>                 }
>                 if (G_007EDC_DC_HOT_PLUG_DETECT1_INTERRUPT(rdev->irq.stat_regs.r500.disp_int)) {
>                         queue_hotplug = true;
> diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c
> index 9739d71..5c1c0c7 100644
> --- a/drivers/gpu/drm/radeon/si.c
> +++ b/drivers/gpu/drm/radeon/si.c
> @@ -6150,7 +6150,7 @@ restart_ih:
>                                                 wake_up(&rdev->irq.vblank_queue);
>                                         }
>                                         if (atomic_read(&rdev->irq.pflip[0]))
> -                                               radeon_crtc_handle_flip(rdev, 0);
> +                                               radeon_crtc_handle_vblank(rdev, 0);
>                                         rdev->irq.stat_regs.evergreen.disp_int &= ~LB_D1_VBLANK_INTERRUPT;
>                                         DRM_DEBUG("IH: D1 vblank\n");
>                                 }
> @@ -6176,7 +6176,7 @@ restart_ih:
>                                                 wake_up(&rdev->irq.vblank_queue);
>                                         }
>                                         if (atomic_read(&rdev->irq.pflip[1]))
> -                                               radeon_crtc_handle_flip(rdev, 1);
> +                                               radeon_crtc_handle_vblank(rdev, 1);
>                                         rdev->irq.stat_regs.evergreen.disp_int_cont &= ~LB_D2_VBLANK_INTERRUPT;
>                                         DRM_DEBUG("IH: D2 vblank\n");
>                                 }
> @@ -6202,7 +6202,7 @@ restart_ih:
>                                                 wake_up(&rdev->irq.vblank_queue);
>                                         }
>                                         if (atomic_read(&rdev->irq.pflip[2]))
> -                                               radeon_crtc_handle_flip(rdev, 2);
> +                                               radeon_crtc_handle_vblank(rdev, 2);
>                                         rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~LB_D3_VBLANK_INTERRUPT;
>                                         DRM_DEBUG("IH: D3 vblank\n");
>                                 }
> @@ -6228,7 +6228,7 @@ restart_ih:
>                                                 wake_up(&rdev->irq.vblank_queue);
>                                         }
>                                         if (atomic_read(&rdev->irq.pflip[3]))
> -                                               radeon_crtc_handle_flip(rdev, 3);
> +                                               radeon_crtc_handle_vblank(rdev, 3);
>                                         rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~LB_D4_VBLANK_INTERRUPT;
>                                         DRM_DEBUG("IH: D4 vblank\n");
>                                 }
> @@ -6254,7 +6254,7 @@ restart_ih:
>                                                 wake_up(&rdev->irq.vblank_queue);
>                                         }
>                                         if (atomic_read(&rdev->irq.pflip[4]))
> -                                               radeon_crtc_handle_flip(rdev, 4);
> +                                               radeon_crtc_handle_vblank(rdev, 4);
>                                         rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~LB_D5_VBLANK_INTERRUPT;
>                                         DRM_DEBUG("IH: D5 vblank\n");
>                                 }
> @@ -6280,7 +6280,7 @@ restart_ih:
>                                                 wake_up(&rdev->irq.vblank_queue);
>                                         }
>                                         if (atomic_read(&rdev->irq.pflip[5]))
> -                                               radeon_crtc_handle_flip(rdev, 5);
> +                                               radeon_crtc_handle_vblank(rdev, 5);
>                                         rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~LB_D6_VBLANK_INTERRUPT;
>                                         DRM_DEBUG("IH: D6 vblank\n");
>                                 }
> --
> 1.9.1
>
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 5/5] drm/radeon: rework page flip handling v3
  2014-05-27 14:49 ` [PATCH 5/5] drm/radeon: rework page flip handling v3 Christian König
@ 2014-05-27 17:03   ` Alex Deucher
  2014-05-28  6:56   ` Michel Dänzer
  1 sibling, 0 replies; 13+ messages in thread
From: Alex Deucher @ 2014-05-27 17:03 UTC (permalink / raw)
  To: Christian König; +Cc: Maling list - DRI developers

On Tue, May 27, 2014 at 10:49 AM, Christian König
<deathsimple@vodafone.de> wrote:
> From: Christian König <christian.koenig@amd.com>
>
> Instead of trying to flip inside the vblank period when
> the buffer is idle, offload blocking for idle to a kernel
> thread and program the flip directly into the hardware.
>
> v2: add error handling, fix EBUSY handling
> v3: add proper exclusive_lock handling
>
> Signed-off-by: Christian König <christian.koenig@amd.com>

Reviewed-by: Alex Deucher <alexander.deucher@amd.com>


> ---
>  drivers/gpu/drm/radeon/radeon.h         |  16 ++-
>  drivers/gpu/drm/radeon/radeon_display.c | 245 ++++++++++++++++++--------------
>  drivers/gpu/drm/radeon/radeon_mode.h    |   4 +-
>  3 files changed, 150 insertions(+), 115 deletions(-)
>
> diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
> index 4ae304d..736bfa2 100644
> --- a/drivers/gpu/drm/radeon/radeon.h
> +++ b/drivers/gpu/drm/radeon/radeon.h
> @@ -676,14 +676,16 @@ void radeon_doorbell_free(struct radeon_device *rdev, u32 doorbell);
>   * IRQS.
>   */
>
> -struct radeon_unpin_work {
> -       struct work_struct work;
> -       struct radeon_device *rdev;
> -       int crtc_id;
> -       struct radeon_fence *fence;
> +struct radeon_flip_work {
> +       struct work_struct              flip_work;
> +       struct work_struct              unpin_work;
> +       struct radeon_device            *rdev;
> +       int                             crtc_id;
> +       struct drm_framebuffer          *fb;
>         struct drm_pending_vblank_event *event;
> -       struct radeon_bo *old_rbo;
> -       u64 new_crtc_base;
> +       struct radeon_bo                *old_rbo;
> +       struct radeon_bo                *new_rbo;
> +       struct radeon_fence             *fence;
>  };
>
>  struct r500_irq_stat_regs {
> diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c
> index 88e3cbe..6b3de5c 100644
> --- a/drivers/gpu/drm/radeon/radeon_display.c
> +++ b/drivers/gpu/drm/radeon/radeon_display.c
> @@ -249,16 +249,21 @@ static void radeon_crtc_destroy(struct drm_crtc *crtc)
>         struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
>
>         drm_crtc_cleanup(crtc);
> +       destroy_workqueue(radeon_crtc->flip_queue);
>         kfree(radeon_crtc);
>  }
>
> -/*
> - * Handle unpin events outside the interrupt handler proper.
> +/**
> + * radeon_unpin_work_func - unpin old buffer object
> + *
> + * @__work - kernel work item
> + *
> + * Unpin the old frame buffer object outside of the interrupt handler
>   */
>  static void radeon_unpin_work_func(struct work_struct *__work)
>  {
> -       struct radeon_unpin_work *work =
> -               container_of(__work, struct radeon_unpin_work, work);
> +       struct radeon_flip_work *work =
> +               container_of(__work, struct radeon_flip_work, unpin_work);
>         int r;
>
>         /* unpin of the old buffer */
> @@ -279,30 +284,19 @@ static void radeon_unpin_work_func(struct work_struct *__work)
>  void radeon_crtc_handle_vblank(struct radeon_device *rdev, int crtc_id)
>  {
>         struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id];
> -       struct radeon_unpin_work *work;
> +       struct radeon_flip_work *work;
>         unsigned long flags;
>         u32 update_pending;
>         int vpos, hpos;
>
>         spin_lock_irqsave(&rdev->ddev->event_lock, flags);
> -       work = radeon_crtc->unpin_work;
> -       if (work == NULL ||
> -           (work->fence && !radeon_fence_signaled(work->fence))) {
> +       work = radeon_crtc->flip_work;
> +       if (work == NULL) {
>                 spin_unlock_irqrestore(&rdev->ddev->event_lock, flags);
>                 return;
>         }
> -       /* New pageflip, or just completion of a previous one? */
> -       if (!radeon_crtc->deferred_flip_completion) {
> -               /* do the flip (mmio) */
> -               radeon_page_flip(rdev, crtc_id, work->new_crtc_base);
> -               update_pending = radeon_page_flip_pending(rdev, crtc_id);
> -       } else {
> -               /* This is just a completion of a flip queued in crtc
> -                * at last invocation. Make sure we go directly to
> -                * completion routine.
> -                */
> -               update_pending = 0;
> -       }
> +
> +       update_pending = radeon_page_flip_pending(rdev, crtc_id);
>
>         /* Has the pageflip already completed in crtc, or is it certain
>          * to complete in this vblank?
> @@ -320,19 +314,9 @@ void radeon_crtc_handle_vblank(struct radeon_device *rdev, int crtc_id)
>                  */
>                 update_pending = 0;
>         }
> -       if (update_pending) {
> -               /* crtc didn't flip in this target vblank interval,
> -                * but flip is pending in crtc. It will complete it
> -                * in next vblank interval, so complete the flip at
> -                * next vblank irq.
> -                */
> -               radeon_crtc->deferred_flip_completion = 1;
> -               spin_unlock_irqrestore(&rdev->ddev->event_lock, flags);
> -               return;
> -       } else {
> -               spin_unlock_irqrestore(&rdev->ddev->event_lock, flags);
> +       spin_unlock_irqrestore(&rdev->ddev->event_lock, flags);
> +       if (!update_pending)
>                 radeon_crtc_handle_flip(rdev, crtc_id);
> -       }
>  }
>
>  /**
> @@ -346,7 +330,7 @@ void radeon_crtc_handle_vblank(struct radeon_device *rdev, int crtc_id)
>  void radeon_crtc_handle_flip(struct radeon_device *rdev, int crtc_id)
>  {
>         struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id];
> -       struct radeon_unpin_work *work;
> +       struct radeon_flip_work *work;
>         unsigned long flags;
>
>         /* this can happen at init */
> @@ -354,15 +338,14 @@ void radeon_crtc_handle_flip(struct radeon_device *rdev, int crtc_id)
>                 return;
>
>         spin_lock_irqsave(&rdev->ddev->event_lock, flags);
> -       work = radeon_crtc->unpin_work;
> +       work = radeon_crtc->flip_work;
>         if (work == NULL) {
>                 spin_unlock_irqrestore(&rdev->ddev->event_lock, flags);
>                 return;
>         }
>
> -       /* Pageflip (will be) certainly completed in this vblank. Clean up. */
> -       radeon_crtc->unpin_work = NULL;
> -       radeon_crtc->deferred_flip_completion = 0;
> +       /* Pageflip completed. Clean up. */
> +       radeon_crtc->flip_work = NULL;
>
>         /* wakeup userspace */
>         if (work->event)
> @@ -372,83 +355,69 @@ void radeon_crtc_handle_flip(struct radeon_device *rdev, int crtc_id)
>
>         radeon_fence_unref(&work->fence);
>         radeon_irq_kms_pflip_irq_get(rdev, work->crtc_id);
> -       schedule_work(&work->work);
> +       queue_work(radeon_crtc->flip_queue, &work->unpin_work);
>  }
>
> -static int radeon_crtc_page_flip(struct drm_crtc *crtc,
> -                                struct drm_framebuffer *fb,
> -                                struct drm_pending_vblank_event *event,
> -                                uint32_t page_flip_flags)
> +/**
> + * radeon_flip_work_func - page flip framebuffer
> + *
> + * @work - kernel work item
> + *
> + * Wait for the buffer object to become idle and do the actual page flip
> + */
> +static void radeon_flip_work_func(struct work_struct *__work)
>  {
> -       struct drm_device *dev = crtc->dev;
> -       struct radeon_device *rdev = dev->dev_private;
> -       struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
> -       struct radeon_framebuffer *old_radeon_fb;
> -       struct radeon_framebuffer *new_radeon_fb;
> -       struct drm_gem_object *obj;
> -       struct radeon_bo *rbo;
> -       struct radeon_unpin_work *work;
> -       unsigned long flags;
> -       u32 tiling_flags, pitch_pixels;
> -       u64 base;
> -       int r;
> +       struct radeon_flip_work *work =
> +               container_of(__work, struct radeon_flip_work, flip_work);
> +       struct radeon_device *rdev = work->rdev;
> +       struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[work->crtc_id];
>
> -       work = kzalloc(sizeof *work, GFP_KERNEL);
> -       if (work == NULL)
> -               return -ENOMEM;
> +       struct drm_crtc *crtc = &radeon_crtc->base;
> +       struct drm_framebuffer *fb = work->fb;
>
> -       work->event = event;
> -       work->rdev = rdev;
> -       work->crtc_id = radeon_crtc->crtc_id;
> -       old_radeon_fb = to_radeon_framebuffer(crtc->primary->fb);
> -       new_radeon_fb = to_radeon_framebuffer(fb);
> -       /* schedule unpin of the old buffer */
> -       obj = old_radeon_fb->obj;
> -       /* take a reference to the old object */
> -       drm_gem_object_reference(obj);
> -       rbo = gem_to_radeon_bo(obj);
> -       work->old_rbo = rbo;
> -       obj = new_radeon_fb->obj;
> -       rbo = gem_to_radeon_bo(obj);
> +       uint32_t tiling_flags, pitch_pixels;
> +       uint64_t base;
>
> -       spin_lock(&rbo->tbo.bdev->fence_lock);
> -       if (rbo->tbo.sync_obj)
> -               work->fence = radeon_fence_ref(rbo->tbo.sync_obj);
> -       spin_unlock(&rbo->tbo.bdev->fence_lock);
> +       unsigned long flags;
> +       int r;
>
> -       INIT_WORK(&work->work, radeon_unpin_work_func);
> +        down_read(&rdev->exclusive_lock);
> +       while (work->fence) {
> +               r = radeon_fence_wait(work->fence, false);
> +               if (r == -EDEADLK) {
> +                       up_read(&rdev->exclusive_lock);
> +                       r = radeon_gpu_reset(rdev);
> +                       down_read(&rdev->exclusive_lock);
> +               }
>
> -       /* We borrow the event spin lock for protecting unpin_work */
> -       spin_lock_irqsave(&dev->event_lock, flags);
> -       if (radeon_crtc->unpin_work) {
> -               DRM_DEBUG_DRIVER("flip queue: crtc already busy\n");
> -               r = -EBUSY;
> -               goto unlock_free;
> +               if (r) {
> +                       DRM_ERROR("failed to wait on page flip fence (%d)!\n",
> +                                 r);
> +                       goto cleanup;
> +               } else
> +                       radeon_fence_unref(&work->fence);
>         }
> -       radeon_crtc->unpin_work = work;
> -       radeon_crtc->deferred_flip_completion = 0;
> -       spin_unlock_irqrestore(&dev->event_lock, flags);
>
>         /* pin the new buffer */
>         DRM_DEBUG_DRIVER("flip-ioctl() cur_fbo = %p, cur_bbo = %p\n",
> -                        work->old_rbo, rbo);
> +                        work->old_rbo, work->new_rbo);
>
> -       r = radeon_bo_reserve(rbo, false);
> +       r = radeon_bo_reserve(work->new_rbo, false);
>         if (unlikely(r != 0)) {
>                 DRM_ERROR("failed to reserve new rbo buffer before flip\n");
> -               goto pflip_cleanup;
> +               goto cleanup;
>         }
>         /* Only 27 bit offset for legacy CRTC */
> -       r = radeon_bo_pin_restricted(rbo, RADEON_GEM_DOMAIN_VRAM,
> +       r = radeon_bo_pin_restricted(work->new_rbo, RADEON_GEM_DOMAIN_VRAM,
>                                      ASIC_IS_AVIVO(rdev) ? 0 : 1 << 27, &base);
>         if (unlikely(r != 0)) {
> -               radeon_bo_unreserve(rbo);
> +               radeon_bo_unreserve(work->new_rbo);
>                 r = -EINVAL;
>                 DRM_ERROR("failed to pin new rbo buffer before flip\n");
> -               goto pflip_cleanup;
> +               goto cleanup;
>         }
> -       radeon_bo_get_tiling_flags(rbo, &tiling_flags, NULL);
> -       radeon_bo_unreserve(rbo);
> +       radeon_bo_get_tiling_flags(work->new_rbo, &tiling_flags, NULL);
> +       radeon_bo_unreserve(work->new_rbo);
>
>         if (!ASIC_IS_AVIVO(rdev)) {
>                 /* crtc offset is from display base addr not FB location */
> @@ -486,28 +455,91 @@ static int radeon_crtc_page_flip(struct drm_crtc *crtc,
>                 base &= ~7;
>         }
>
> -       spin_lock_irqsave(&dev->event_lock, flags);
> -       work->new_crtc_base = base;
> -       spin_unlock_irqrestore(&dev->event_lock, flags);
> -
> -       /* update crtc fb */
> -       crtc->primary->fb = fb;
> +       /* We borrow the event spin lock for protecting flip_work */
> +       spin_lock_irqsave(&crtc->dev->event_lock, flags);
>
>         /* set the proper interrupt */
>         radeon_irq_kms_pflip_irq_get(rdev, radeon_crtc->crtc_id);
>
> -       return 0;
> +       /* do the flip (mmio) */
> +       radeon_page_flip(rdev, radeon_crtc->crtc_id, base);
>
> -pflip_cleanup:
> -       spin_lock_irqsave(&dev->event_lock, flags);
> -       radeon_crtc->unpin_work = NULL;
> -unlock_free:
> -       spin_unlock_irqrestore(&dev->event_lock, flags);
> -       drm_gem_object_unreference_unlocked(old_radeon_fb->obj);
> +       spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
> +       up_read(&rdev->exclusive_lock);
> +
> +       return;
> +
> +cleanup:
> +       drm_gem_object_unreference_unlocked(&work->old_rbo->gem_base);
>         radeon_fence_unref(&work->fence);
>         kfree(work);
> +       up_read(&rdev->exclusive_lock);
> +}
> +
> +static int radeon_crtc_page_flip(struct drm_crtc *crtc,
> +                                struct drm_framebuffer *fb,
> +                                struct drm_pending_vblank_event *event,
> +                                uint32_t page_flip_flags)
> +{
> +       struct drm_device *dev = crtc->dev;
> +       struct radeon_device *rdev = dev->dev_private;
> +       struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
> +       struct radeon_framebuffer *old_radeon_fb;
> +       struct radeon_framebuffer *new_radeon_fb;
> +       struct drm_gem_object *obj;
> +       struct radeon_flip_work *work;
> +       unsigned long flags;
> +
> +       work = kzalloc(sizeof *work, GFP_KERNEL);
> +       if (work == NULL)
> +               return -ENOMEM;
> +
> +       INIT_WORK(&work->flip_work, radeon_flip_work_func);
> +       INIT_WORK(&work->unpin_work, radeon_unpin_work_func);
>
> -       return r;
> +       work->rdev = rdev;
> +       work->crtc_id = radeon_crtc->crtc_id;
> +       work->fb = fb;
> +       work->event = event;
> +
> +       /* schedule unpin of the old buffer */
> +       old_radeon_fb = to_radeon_framebuffer(crtc->primary->fb);
> +       obj = old_radeon_fb->obj;
> +
> +       /* take a reference to the old object */
> +       drm_gem_object_reference(obj);
> +       work->old_rbo = gem_to_radeon_bo(obj);
> +
> +       new_radeon_fb = to_radeon_framebuffer(fb);
> +       obj = new_radeon_fb->obj;
> +       work->new_rbo = gem_to_radeon_bo(obj);
> +
> +       spin_lock(&work->new_rbo->tbo.bdev->fence_lock);
> +       if (work->new_rbo->tbo.sync_obj)
> +               work->fence = radeon_fence_ref(work->new_rbo->tbo.sync_obj);
> +       spin_unlock(&work->new_rbo->tbo.bdev->fence_lock);
> +
> +       /* update crtc fb */
> +       crtc->primary->fb = fb;
> +
> +       /* We borrow the event spin lock for protecting flip_work */
> +       spin_lock_irqsave(&crtc->dev->event_lock, flags);
> +
> +       if (radeon_crtc->flip_work) {
> +               DRM_DEBUG_DRIVER("flip queue: crtc already busy\n");
> +               spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
> +               drm_gem_object_unreference_unlocked(&work->old_rbo->gem_base);
> +               radeon_fence_unref(&work->fence);
> +               kfree(work);
> +               return -EBUSY;
> +       }
> +       radeon_crtc->flip_work = work;
> +
> +       spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
> +
> +       queue_work(radeon_crtc->flip_queue, &work->flip_work);
> +
> +       return 0;
>  }
>
>  static int
> @@ -577,6 +609,7 @@ static void radeon_crtc_init(struct drm_device *dev, int index)
>
>         drm_mode_crtc_set_gamma_size(&radeon_crtc->base, 256);
>         radeon_crtc->crtc_id = index;
> +       radeon_crtc->flip_queue = create_singlethread_workqueue("radeon-crtc");
>         rdev->mode_info.crtcs[index] = radeon_crtc;
>
>         if (rdev->family >= CHIP_BONAIRE) {
> diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h
> index 718be1a..ea72ad8 100644
> --- a/drivers/gpu/drm/radeon/radeon_mode.h
> +++ b/drivers/gpu/drm/radeon/radeon_mode.h
> @@ -325,8 +325,8 @@ struct radeon_crtc {
>         struct drm_display_mode native_mode;
>         int pll_id;
>         /* page flipping */
> -       struct radeon_unpin_work *unpin_work;
> -       int deferred_flip_completion;
> +       struct workqueue_struct *flip_queue;
> +       struct radeon_flip_work *flip_work;
>         /* pll sharing */
>         struct radeon_atom_ss ss;
>         bool ss_enabled;
> --
> 1.9.1
>
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 5/5] drm/radeon: rework page flip handling v3
  2014-05-27 14:49 ` [PATCH 5/5] drm/radeon: rework page flip handling v3 Christian König
  2014-05-27 17:03   ` Alex Deucher
@ 2014-05-28  6:56   ` Michel Dänzer
  2014-06-03 13:31     ` Alex Deucher
  1 sibling, 1 reply; 13+ messages in thread
From: Michel Dänzer @ 2014-05-28  6:56 UTC (permalink / raw)
  To: Christian König; +Cc: dri-devel

On 27.05.2014 23:49, Christian König wrote:
> From: Christian König <christian.koenig@amd.com>
> 
> Instead of trying to flip inside the vblank period when
> the buffer is idle, offload blocking for idle to a kernel
> thread and program the flip directly into the hardware.
> 
> v2: add error handling, fix EBUSY handling
> v3: add proper exclusive_lock handling

[...]

> +	/* update crtc fb */
> +	crtc->primary->fb = fb;
> +
> +	/* We borrow the event spin lock for protecting flip_work */
> +	spin_lock_irqsave(&crtc->dev->event_lock, flags);
> +
> +	if (radeon_crtc->flip_work) {
> +		DRM_DEBUG_DRIVER("flip queue: crtc already busy\n");
> +		spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
> +		drm_gem_object_unreference_unlocked(&work->old_rbo->gem_base);
> +		radeon_fence_unref(&work->fence);
> +		kfree(work);
> +		return -EBUSY;
> +	}

If we return -EBUSY, we shouldn't change crtc->primary->fb, should we? I
wonder if crtc->primary->fb shouldn't be changed in
radeon_flip_work_func(), when we're sure we can actually flip.


-- 
Earthling Michel Dänzer            |                  http://www.amd.com
Libre software enthusiast          |                Mesa and X developer
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 5/5] drm/radeon: rework page flip handling v3
  2014-05-28  6:56   ` Michel Dänzer
@ 2014-06-03 13:31     ` Alex Deucher
  2014-06-03 13:45       ` Christian König
  0 siblings, 1 reply; 13+ messages in thread
From: Alex Deucher @ 2014-06-03 13:31 UTC (permalink / raw)
  To: Michel Dänzer; +Cc: Maling list - DRI developers

[-- Attachment #1: Type: text/plain, Size: 1302 bytes --]

On Wed, May 28, 2014 at 2:56 AM, Michel Dänzer <michel@daenzer.net> wrote:
> On 27.05.2014 23:49, Christian König wrote:
>> From: Christian König <christian.koenig@amd.com>
>>
>> Instead of trying to flip inside the vblank period when
>> the buffer is idle, offload blocking for idle to a kernel
>> thread and program the flip directly into the hardware.
>>
>> v2: add error handling, fix EBUSY handling
>> v3: add proper exclusive_lock handling
>
> [...]
>
>> +     /* update crtc fb */
>> +     crtc->primary->fb = fb;
>> +
>> +     /* We borrow the event spin lock for protecting flip_work */
>> +     spin_lock_irqsave(&crtc->dev->event_lock, flags);
>> +
>> +     if (radeon_crtc->flip_work) {
>> +             DRM_DEBUG_DRIVER("flip queue: crtc already busy\n");
>> +             spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
>> +             drm_gem_object_unreference_unlocked(&work->old_rbo->gem_base);
>> +             radeon_fence_unref(&work->fence);
>> +             kfree(work);
>> +             return -EBUSY;
>> +     }
>
> If we return -EBUSY, we shouldn't change crtc->primary->fb, should we? I
> wonder if crtc->primary->fb shouldn't be changed in
> radeon_flip_work_func(), when we're sure we can actually flip.

How about this?

Alex

[-- Attachment #2: 0001-drm-radeon-update-crtc-primary-fb-in-radeon_flip_wor.patch --]
[-- Type: text/x-diff, Size: 1392 bytes --]

From 2556af5d1bb1d1ffe8dfddc2e9f138546432560d Mon Sep 17 00:00:00 2001
From: Alex Deucher <alexander.deucher@amd.com>
Date: Tue, 3 Jun 2014 09:29:02 -0400
Subject: [PATCH] drm/radeon: update crtc->primary->fb in radeon_flip_work_func

To make sure we've actually flipped before updating it.

Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
---
 drivers/gpu/drm/radeon/radeon_display.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c
index 6b3de5c..d96d1ca 100644
--- a/drivers/gpu/drm/radeon/radeon_display.c
+++ b/drivers/gpu/drm/radeon/radeon_display.c
@@ -458,6 +458,9 @@ static void radeon_flip_work_func(struct work_struct *__work)
 	/* We borrow the event spin lock for protecting flip_work */
 	spin_lock_irqsave(&crtc->dev->event_lock, flags);
 
+	/* update crtc fb */
+	crtc->primary->fb = fb;
+
 	/* set the proper interrupt */
 	radeon_irq_kms_pflip_irq_get(rdev, radeon_crtc->crtc_id);
 
@@ -519,9 +522,6 @@ static int radeon_crtc_page_flip(struct drm_crtc *crtc,
 		work->fence = radeon_fence_ref(work->new_rbo->tbo.sync_obj);
 	spin_unlock(&work->new_rbo->tbo.bdev->fence_lock);
 
-	/* update crtc fb */
-	crtc->primary->fb = fb;
-
 	/* We borrow the event spin lock for protecting flip_work */
 	spin_lock_irqsave(&crtc->dev->event_lock, flags);
 
-- 
1.8.3.1


[-- Attachment #3: Type: text/plain, Size: 159 bytes --]

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [PATCH 5/5] drm/radeon: rework page flip handling v3
  2014-06-03 13:31     ` Alex Deucher
@ 2014-06-03 13:45       ` Christian König
  0 siblings, 0 replies; 13+ messages in thread
From: Christian König @ 2014-06-03 13:45 UTC (permalink / raw)
  To: Alex Deucher, Michel Dänzer; +Cc: Maling list - DRI developers

Am 03.06.2014 15:31, schrieb Alex Deucher:
> On Wed, May 28, 2014 at 2:56 AM, Michel Dänzer <michel@daenzer.net> wrote:
>> On 27.05.2014 23:49, Christian König wrote:
>>> From: Christian König <christian.koenig@amd.com>
>>>
>>> Instead of trying to flip inside the vblank period when
>>> the buffer is idle, offload blocking for idle to a kernel
>>> thread and program the flip directly into the hardware.
>>>
>>> v2: add error handling, fix EBUSY handling
>>> v3: add proper exclusive_lock handling
>> [...]
>>
>>> +     /* update crtc fb */
>>> +     crtc->primary->fb = fb;
>>> +
>>> +     /* We borrow the event spin lock for protecting flip_work */
>>> +     spin_lock_irqsave(&crtc->dev->event_lock, flags);
>>> +
>>> +     if (radeon_crtc->flip_work) {
>>> +             DRM_DEBUG_DRIVER("flip queue: crtc already busy\n");
>>> +             spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
>>> +             drm_gem_object_unreference_unlocked(&work->old_rbo->gem_base);
>>> +             radeon_fence_unref(&work->fence);
>>> +             kfree(work);
>>> +             return -EBUSY;
>>> +     }
>> If we return -EBUSY, we shouldn't change crtc->primary->fb, should we? I
>> wonder if crtc->primary->fb shouldn't be changed in
>> radeon_flip_work_func(), when we're sure we can actually flip.
> How about this?

Looks good to me. Reviewed-by: Christian König <christian.koenig@amd.com>

>
> Alex

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2014-06-03 13:45 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-05-27 14:49 [PATCH 1/5] drm/radeon: remove (pre|post)_page_flip callbacks Christian König
2014-05-27 14:49 ` [PATCH 2/5] drm/radeon: remove drm_vblank_get|put from pflip handling Christian König
2014-05-27 15:56   ` Alex Deucher
2014-05-27 14:49 ` [PATCH 3/5] drm/radeon: split page flip and pending callback Christian König
2014-05-27 15:57   ` Alex Deucher
2014-05-27 14:49 ` [PATCH 4/5] drm/radeon: separate vblank and pflip crtc handling Christian König
2014-05-27 16:49   ` Alex Deucher
2014-05-27 14:49 ` [PATCH 5/5] drm/radeon: rework page flip handling v3 Christian König
2014-05-27 17:03   ` Alex Deucher
2014-05-28  6:56   ` Michel Dänzer
2014-06-03 13:31     ` Alex Deucher
2014-06-03 13:45       ` Christian König
2014-05-27 15:56 ` [PATCH 1/5] drm/radeon: remove (pre|post)_page_flip callbacks Alex Deucher

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.