summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/nouveau/nouveau_fence.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-08-05 16:02:01 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2010-08-05 16:02:01 -0700
commitfc1caf6eafb30ea185720e29f7f5eccca61ecd60 (patch)
tree666dabc25a9b02e5c05f9eba32fa6b0d8027341a /drivers/gpu/drm/nouveau/nouveau_fence.c
parent9779714c8af09d57527f18d9aa2207dcc27a8687 (diff)
parent96576a9e1a0cdb8a43d3af5846be0948f52b4460 (diff)
downloadlwn-fc1caf6eafb30ea185720e29f7f5eccca61ecd60.tar.gz
lwn-fc1caf6eafb30ea185720e29f7f5eccca61ecd60.zip
Merge branch 'drm-core-next' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6
* 'drm-core-next' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6: (204 commits) agp: intel-agp: do not use PCI resources before pci_enable_device() agp: efficeon-agp: do not use PCI resources before pci_enable_device() drm: kill BKL from common code drm/kms: Simplify setup of the initial I2C encoder config. drm,io-mapping: Specify slot to use for atomic mappings drm/radeon/kms: only expose underscan on avivo chips drm/radeon: add new pci ids drm: Cleanup after failing to create master->unique and dev->name drm/radeon: tone down overchatty acpi debug messages. drm/radeon/kms: enable underscan option for digital connectors drm/radeon/kms: fix calculation of h/v scaling factors drm/radeon/kms/igp: sideport is AMD only drm/radeon/kms: handle the case of no active displays properly in the bandwidth code drm: move ttm global code to core drm drm/i915: Clear the Ironlake dithering flags when the pipe doesn't want it. drm/radeon/kms: make sure HPD is set to NONE on analog-only connectors drm/radeon/kms: make sure rio_mem is valid before unmapping it drm/agp/i915: trim stolen space to 32M drm/i915: Unset cursor if out-of-bounds upon mode change (v4) drm/i915: Unreference object not handle on creation ...
Diffstat (limited to 'drivers/gpu/drm/nouveau/nouveau_fence.c')
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_fence.c35
1 files changed, 8 insertions, 27 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c
index faddf53ff9ed..6b208ffafa8d 100644
--- a/drivers/gpu/drm/nouveau/nouveau_fence.c
+++ b/drivers/gpu/drm/nouveau/nouveau_fence.c
@@ -67,12 +67,13 @@ nouveau_fence_update(struct nouveau_channel *chan)
if (USE_REFCNT)
sequence = nvchan_rd32(chan, 0x48);
else
- sequence = chan->fence.last_sequence_irq;
+ sequence = atomic_read(&chan->fence.last_sequence_irq);
if (chan->fence.sequence_ack == sequence)
return;
chan->fence.sequence_ack = sequence;
+ spin_lock(&chan->fence.lock);
list_for_each_safe(entry, tmp, &chan->fence.pending) {
fence = list_entry(entry, struct nouveau_fence, entry);
@@ -84,6 +85,7 @@ nouveau_fence_update(struct nouveau_channel *chan)
if (sequence == chan->fence.sequence_ack)
break;
}
+ spin_unlock(&chan->fence.lock);
}
int
@@ -119,7 +121,6 @@ nouveau_fence_emit(struct nouveau_fence *fence)
{
struct drm_nouveau_private *dev_priv = fence->channel->dev->dev_private;
struct nouveau_channel *chan = fence->channel;
- unsigned long flags;
int ret;
ret = RING_SPACE(chan, 2);
@@ -127,9 +128,7 @@ nouveau_fence_emit(struct nouveau_fence *fence)
return ret;
if (unlikely(chan->fence.sequence == chan->fence.sequence_ack - 1)) {
- spin_lock_irqsave(&chan->fence.lock, flags);
nouveau_fence_update(chan);
- spin_unlock_irqrestore(&chan->fence.lock, flags);
BUG_ON(chan->fence.sequence ==
chan->fence.sequence_ack - 1);
@@ -138,9 +137,9 @@ nouveau_fence_emit(struct nouveau_fence *fence)
fence->sequence = ++chan->fence.sequence;
kref_get(&fence->refcount);
- spin_lock_irqsave(&chan->fence.lock, flags);
+ spin_lock(&chan->fence.lock);
list_add_tail(&fence->entry, &chan->fence.pending);
- spin_unlock_irqrestore(&chan->fence.lock, flags);
+ spin_unlock(&chan->fence.lock);
BEGIN_RING(chan, NvSubSw, USE_REFCNT ? 0x0050 : 0x0150, 1);
OUT_RING(chan, fence->sequence);
@@ -173,14 +172,11 @@ nouveau_fence_signalled(void *sync_obj, void *sync_arg)
{
struct nouveau_fence *fence = nouveau_fence(sync_obj);
struct nouveau_channel *chan = fence->channel;
- unsigned long flags;
if (fence->signalled)
return true;
- spin_lock_irqsave(&chan->fence.lock, flags);
nouveau_fence_update(chan);
- spin_unlock_irqrestore(&chan->fence.lock, flags);
return fence->signalled;
}
@@ -190,8 +186,6 @@ nouveau_fence_wait(void *sync_obj, void *sync_arg, bool lazy, bool intr)
unsigned long timeout = jiffies + (3 * DRM_HZ);
int ret = 0;
- __set_current_state(intr ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE);
-
while (1) {
if (nouveau_fence_signalled(sync_obj, sync_arg))
break;
@@ -201,6 +195,8 @@ nouveau_fence_wait(void *sync_obj, void *sync_arg, bool lazy, bool intr)
break;
}
+ __set_current_state(intr ? TASK_INTERRUPTIBLE
+ : TASK_UNINTERRUPTIBLE);
if (lazy)
schedule_timeout(1);
@@ -221,27 +217,12 @@ nouveau_fence_flush(void *sync_obj, void *sync_arg)
return 0;
}
-void
-nouveau_fence_handler(struct drm_device *dev, int channel)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_channel *chan = NULL;
-
- if (channel >= 0 && channel < dev_priv->engine.fifo.channels)
- chan = dev_priv->fifos[channel];
-
- if (chan) {
- spin_lock_irq(&chan->fence.lock);
- nouveau_fence_update(chan);
- spin_unlock_irq(&chan->fence.lock);
- }
-}
-
int
nouveau_fence_init(struct nouveau_channel *chan)
{
INIT_LIST_HEAD(&chan->fence.pending);
spin_lock_init(&chan->fence.lock);
+ atomic_set(&chan->fence.last_sequence_irq, 0);
return 0;
}