drm/nouveau: Don't remove ramht entries from the neighboring channels.
authorFrancisco Jerez <currojerez@riseup.net>
Sun, 5 Sep 2010 04:03:07 +0000 (06:03 +0200)
committerBen Skeggs <bskeggs@redhat.com>
Fri, 24 Sep 2010 06:25:03 +0000 (16:25 +1000)
Signed-off-by: Francisco Jerez <currojerez@riseup.net>
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
drivers/gpu/drm/nouveau/nouveau_ramht.c

index f240ba2419434182884f508f2d9551764b3fd964..7f16697cc96ce6438896414735b5fa4d12a84a34 100644 (file)
@@ -63,6 +63,23 @@ nouveau_ramht_entry_valid(struct drm_device *dev, struct nouveau_gpuobj *ramht,
        return (ctx != 0);
 }
 
+static int
+nouveau_ramht_entry_same_channel(struct nouveau_channel *chan,
+                                struct nouveau_gpuobj *ramht, u32 offset)
+{
+       struct drm_nouveau_private *dev_priv = chan->dev->dev_private;
+       u32 ctx = nv_ro32(ramht, offset + 4);
+
+       if (dev_priv->card_type >= NV_50)
+               return true;
+       else if (dev_priv->card_type >= NV_40)
+               return chan->id ==
+                       ((ctx >> NV40_RAMHT_CONTEXT_CHANNEL_SHIFT) & 0x1f);
+       else
+               return chan->id ==
+                       ((ctx >> NV_RAMHT_CONTEXT_CHANNEL_SHIFT) & 0x1f);
+}
+
 int
 nouveau_ramht_insert(struct nouveau_channel *chan, u32 handle,
                     struct nouveau_gpuobj *gpuobj)
@@ -159,6 +176,7 @@ nouveau_ramht_remove_locked(struct nouveau_channel *chan, u32 handle)
        co = ho = nouveau_ramht_hash_handle(chan, handle);
        do {
                if (nouveau_ramht_entry_valid(dev, ramht, co) &&
+                   nouveau_ramht_entry_same_channel(chan, ramht, co) &&
                    (handle == nv_ro32(ramht, co))) {
                        NV_DEBUG(dev,
                                 "remove ch%d 0x%08x: h=0x%08x, c=0x%08x\n",