summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/radeon/radeon_fence.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-09-21 19:10:09 +0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-09-21 19:10:09 +0400
commit44040f107e64d689ccd3211ac62c6bc44f3f0775 (patch)
treef85059028aa570e758c7fb272fd8cf823ab4f119 /drivers/gpu/drm/radeon/radeon_fence.c
parent388dba30471c236a290c4082bce5f2b5cd1a7a06 (diff)
parent28d520433b6375740990ab99d69b0d0067fd656b (diff)
downloadlinux-44040f107e64d689ccd3211ac62c6bc44f3f0775.tar.xz
Merge branch 'drm-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6
* 'drm-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6: (133 commits) drm/vgaarb: add VGA arbitration support to the drm and kms. drm/radeon: some r420s have a CP race with the DMA engine. drm/radeon/r600/kms: rv670 is not DCE3 drm/radeon/kms: r420 idle after programming GA_ENHANCE drm/radeon/kms: more fixes to rv770 suspend/resume path. drm/radeon/kms: more alignment for rv770.c with r600.c drm/radeon/kms: rv770 blit init called too late. drm/radeon/kms: move around new init path code to avoid posting at init drm/radeon/r600: fix some issues with suspend/resume. drm/radeon/kms: disable VGA rendering engine before taking over VRAM drm/radeon/kms: Move radeon_get_clock_info() call out of radeon_clocks_init(). drm/radeon/kms: add initial connector properties drm/radeon/kms: Use surfaces for scanout / cursor byte swapping on big endian. drm/radeon/kms: don't fail if we fail to init GPU acceleration drm/r600/kms: fixup number of loops per blit calculation. drm/radeon/kms: reprogram format in set base. drm/radeon: avivo chips have no separate int bit for display drm/radeon/r600: don't do interrupts drm: fix _DRM_GEM addmap error message drm: update crtc x/y when only fb changes ... Fixed up trivial conflicts in firmware/Makefile due to network driver (cxgb3) and drm (mga/r128/radeon) firmware being listed next to each other.
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_fence.c')
-rw-r--r--drivers/gpu/drm/radeon/radeon_fence.c49
1 files changed, 44 insertions, 5 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/radeon/radeon_fence.c
index b4e48dd2e859..3beb26d74719 100644
--- a/drivers/gpu/drm/radeon/radeon_fence.c
+++ b/drivers/gpu/drm/radeon/radeon_fence.c
@@ -53,9 +53,9 @@ int radeon_fence_emit(struct radeon_device *rdev, struct radeon_fence *fence)
* away
*/
WREG32(rdev->fence_drv.scratch_reg, fence->seq);
- } else {
+ } else
radeon_fence_ring_emit(rdev, fence);
- }
+
fence->emited = true;
fence->timeout = jiffies + ((2000 * HZ) / 1000);
list_del(&fence->list);
@@ -168,7 +168,38 @@ bool radeon_fence_signaled(struct radeon_fence *fence)
return signaled;
}
-int radeon_fence_wait(struct radeon_fence *fence, bool interruptible)
+int r600_fence_wait(struct radeon_fence *fence, bool intr, bool lazy)
+{
+ struct radeon_device *rdev;
+ int ret = 0;
+
+ rdev = fence->rdev;
+
+ __set_current_state(intr ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE);
+
+ while (1) {
+ if (radeon_fence_signaled(fence))
+ break;
+
+ if (time_after_eq(jiffies, fence->timeout)) {
+ ret = -EBUSY;
+ break;
+ }
+
+ if (lazy)
+ schedule_timeout(1);
+
+ if (intr && signal_pending(current)) {
+ ret = -ERESTARTSYS;
+ break;
+ }
+ }
+ __set_current_state(TASK_RUNNING);
+ return ret;
+}
+
+
+int radeon_fence_wait(struct radeon_fence *fence, bool intr)
{
struct radeon_device *rdev;
unsigned long cur_jiffies;
@@ -176,7 +207,6 @@ int radeon_fence_wait(struct radeon_fence *fence, bool interruptible)
bool expired = false;
int r;
-
if (fence == NULL) {
WARN(1, "Querying an invalid fence : %p !\n", fence);
return 0;
@@ -185,13 +215,22 @@ int radeon_fence_wait(struct radeon_fence *fence, bool interruptible)
if (radeon_fence_signaled(fence)) {
return 0;
}
+
+ if (rdev->family >= CHIP_R600) {
+ r = r600_fence_wait(fence, intr, 0);
+ if (r == -ERESTARTSYS)
+ return -EBUSY;
+ return r;
+ }
+
retry:
cur_jiffies = jiffies;
timeout = HZ / 100;
if (time_after(fence->timeout, cur_jiffies)) {
timeout = fence->timeout - cur_jiffies;
}
- if (interruptible) {
+
+ if (intr) {
r = wait_event_interruptible_timeout(rdev->fence_drv.queue,
radeon_fence_signaled(fence), timeout);
if (unlikely(r == -ERESTARTSYS)) {