dri-devel.lists.freedesktop.org archive mirror
 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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).