nouveau: never touch PRAMIN with NV_WRITE, cleanup RAMHT code a bit
authorBen Skeggs <skeggsb@gmail.com>
Mon, 25 Jun 2007 05:42:55 +0000 (15:42 +1000)
committerBen Skeggs <skeggsb@gmail.com>
Wed, 27 Jun 2007 17:26:44 +0000 (03:26 +1000)
shared-core/nouveau_drv.h
shared-core/nouveau_mem.c
shared-core/nouveau_notifier.c
shared-core/nouveau_object.c
shared-core/nv04_fifo.c
shared-core/nv10_fifo.c
shared-core/nv40_fifo.c

index b2ddf0a..3cca07f 100644 (file)
@@ -64,7 +64,6 @@ struct nouveau_object
        int channel;
 
        struct mem_block *instance;
-       uint32_t          ht_loc;
 
        uint32_t handle;
        int      class;
@@ -242,8 +241,8 @@ extern int  nouveau_object_init_channel(drm_device_t *, int channel,
                                        uint32_t tt_handle);
 extern void nouveau_object_takedown_channel(drm_device_t *dev, int channel);
 extern void nouveau_object_cleanup(drm_device_t *dev, int channel);
-extern int  nouveau_ht_object_insert(drm_device_t *, int channel,
-                                    uint32_t handle, struct nouveau_object *);
+extern int  nouveau_ramht_insert(drm_device_t *, int channel,
+                                uint32_t handle, struct nouveau_object *);
 extern struct nouveau_object *
 nouveau_object_gr_create(drm_device_t *dev, int channel, int class);
 extern struct nouveau_object *
index 4c6d0d5..d8ae52b 100644 (file)
@@ -489,13 +489,8 @@ nouveau_instmem_determine_amount(struct drm_device *dev)
        DRM_DEBUG("RAMIN size: %dKiB\n", dev_priv->ramin_size>>10);
 
        /* Clear all of it, except the BIOS image that's in the first 64KiB */
-       if (dev_priv->ramin) {
-               for (i=(64*1024); i<dev_priv->ramin_size; i+=4)
-                       DRM_WRITE32(dev_priv->ramin, i, 0x00000000);
-       } else {
-               for (i=(64*1024); i<dev_priv->ramin_size; i+=4)
-                       DRM_WRITE32(dev_priv->mmio, NV_RAMIN + i, 0x00000000);
-       }
+       for (i=(64*1024); i<dev_priv->ramin_size; i+=4)
+               NV_WI32(i, 0x00000000);
 }
 
 static void
index ab6f8c2..0cfe733 100644 (file)
@@ -115,7 +115,7 @@ nouveau_notifier_alloc(drm_device_t *dev, int channel, uint32_t handle,
        }
 
        obj->handle = handle;
-       if (nouveau_ht_object_insert(dev, channel, handle, obj)) {
+       if (nouveau_ramht_insert(dev, channel, handle, obj)) {
                nouveau_object_free(dev, obj);
                nouveau_mem_free_block(mem);
                DRM_ERROR("Error inserting notifier ctxdma into RAMHT\n");
index e7528e2..dac08df 100644 (file)
@@ -139,7 +139,7 @@ nouveau_object_handle_find(drm_device_t *dev, int channel, uint32_t handle)
    is given as:
 */
 static uint32_t
-nouveau_ht_handle_hash(drm_device_t *dev, int channel, uint32_t handle)
+nouveau_ramht_hash_handle(drm_device_t *dev, int channel, uint32_t handle)
 {
        drm_nouveau_private_t *dev_priv=dev->dev_private;
        uint32_t hash = 0;
@@ -153,63 +153,90 @@ nouveau_ht_handle_hash(drm_device_t *dev, int channel, uint32_t handle)
        return hash << 3;
 }
 
+static int
+nouveau_ramht_entry_valid(drm_device_t *dev, uint32_t ramht, uint32_t offset)
+{
+       drm_nouveau_private_t *dev_priv=dev->dev_private;
+       uint32_t ctx = NV_RI32(ramht + offset + 4);
+
+       if (dev_priv->card_type < NV_40)
+               return ((ctx & NV_RAMHT_CONTEXT_VALID) != 0);
+       return (ctx != 0);
+}
+
 int
-nouveau_ht_object_insert(drm_device_t* dev, int channel, uint32_t handle,
-                        struct nouveau_object *obj)
+nouveau_ramht_insert(drm_device_t* dev, int channel, uint32_t handle,
+                    struct nouveau_object *obj)
 {
        drm_nouveau_private_t *dev_priv=dev->dev_private;
-       int ht_base = NV_RAMIN + dev_priv->ramht_offset;
-/*     int ht_end  = ht_base + dev_priv->ramht_size; */
-       int o_ofs, ofs;
-
-       obj->handle = handle;
-       o_ofs = ofs = nouveau_ht_handle_hash(dev, channel, obj->handle);
-
-       while (NV_READ(ht_base + ofs) || NV_READ(ht_base + ofs + 4)) {
-               ofs += 8;
-               if (ofs == dev_priv->ramht_size) ofs = 0;
-               if (ofs == o_ofs) {
-                       DRM_ERROR("no free hash table entries\n");
-                       return 1;
-               }
+       uint32_t ramht = dev_priv->ramht_offset;
+       uint32_t ctx, co, ho;
+       uint32_t inst;
+
+       inst = nouveau_chip_instance_get(dev, obj->instance);
+       if (dev_priv->card_type < NV_40) {
+               ctx = NV_RAMHT_CONTEXT_VALID | inst |
+                     (channel     << NV_RAMHT_CONTEXT_CHANNEL_SHIFT) |
+                     (obj->engine << NV_RAMHT_CONTEXT_ENGINE_SHIFT);
+       } else
+       if (dev_priv->card_type < NV_50) {
+               ctx = inst |
+                     (channel     << NV40_RAMHT_CONTEXT_CHANNEL_SHIFT) |
+                     (obj->engine << NV40_RAMHT_CONTEXT_ENGINE_SHIFT);
+       } else {
+               ctx = inst |
+                     (obj->engine << NV40_RAMHT_CONTEXT_ENGINE_SHIFT);
        }
-       ofs += ht_base;
-
-       DRM_DEBUG("Channel %d - Handle 0x%08x at 0x%08x\n",
-               channel, obj->handle, ofs);
-
-       NV_WRITE(NV_RAMHT_HANDLE_OFFSET + ofs, obj->handle);
-       if (dev_priv->card_type >= NV_40)
-               NV_WRITE(NV_RAMHT_CONTEXT_OFFSET + ofs,
-                       (channel     << NV40_RAMHT_CONTEXT_CHANNEL_SHIFT) |
-                       (obj->engine << NV40_RAMHT_CONTEXT_ENGINE_SHIFT) |
-                       nouveau_chip_instance_get(dev, obj->instance)
-                       );          
-       else
-               NV_WRITE(NV_RAMHT_CONTEXT_OFFSET + ofs,
-                       NV_RAMHT_CONTEXT_VALID |
-                       (channel     << NV_RAMHT_CONTEXT_CHANNEL_SHIFT) |
-                       (obj->engine << NV_RAMHT_CONTEXT_ENGINE_SHIFT) |
-                       nouveau_chip_instance_get(dev, obj->instance)
-                       );
-
-       obj->ht_loc = ofs;
-       return 0;
+
+       co = ho = nouveau_ramht_hash_handle(dev, channel, handle);
+       do {
+               if (!nouveau_ramht_entry_valid(dev, ramht, co)) {
+                       DRM_DEBUG("insert ch%d 0x%08x: h=0x%08x, c=0x%08x\n",
+                                 channel, co, handle, ctx);
+                       NV_WI32(ramht + co + 0, handle);
+                       NV_WI32(ramht + co + 4, ctx);
+                       obj->handle = handle;
+                       return 0;
+               }
+               DRM_DEBUG("collision ch%d 0x%08x: h=0x%08x\n",
+                         channel, co, NV_RI32(ramht + co));
+
+               co += 8;
+               if (co == dev_priv->ramht_size)
+                       co = 0;
+       } while (co != ho);
+
+       DRM_ERROR("RAMHT space exhausted. ch=%d\n", channel);
+       return DRM_ERR(ENOMEM);
 }
 
-static void nouveau_hash_table_remove(drm_device_t* dev,
-                                     struct nouveau_object *obj)
+static void
+nouveau_ramht_remove(drm_device_t* dev, struct nouveau_object *obj)
 {
        drm_nouveau_private_t *dev_priv = dev->dev_private;
+       uint32_t ramht = dev_priv->ramht_offset;
+       uint32_t co, ho;
+
+       co = ho = nouveau_ramht_hash_handle(dev, obj->channel, obj->handle);
+       do {
+               if (nouveau_ramht_entry_valid(dev, ramht, co) &&
+                   (obj->handle == NV_RI32(ramht + co))) {
+                       DRM_DEBUG("remove ch%d 0x%08x: h=0x%08x, c=0x%08x\n",
+                                 obj->channel, co, obj->handle,
+                                 NV_RI32(ramht + co + 4));
+                       NV_WI32(ramht + co + 0, 0x00000000);
+                       NV_WI32(ramht + co + 4, 0x00000000);
+                       obj->handle = ~0;
+                       return;
+               }
 
-       DRM_DEBUG("Remove handle 0x%08x at 0x%08x from HT\n",
-                       obj->handle, obj->ht_loc);
-       if (obj->ht_loc) {
-               DRM_DEBUG("... HT entry was: 0x%08x/0x%08x\n",
-                               NV_READ(obj->ht_loc), NV_READ(obj->ht_loc+4));
-               NV_WRITE(obj->ht_loc  , 0x00000000);
-               NV_WRITE(obj->ht_loc+4, 0x00000000);
-       }
+               co += 8;
+               if (co == dev_priv->ramht_size)
+                       co = 0;
+       } while (co != ho);
+
+       DRM_ERROR("RAMHT entry not found. ch=%d, handle=0x%08x\n",
+                 obj->channel, obj->handle);
 }
 
 static struct nouveau_object *
@@ -457,7 +484,7 @@ nouveau_object_free(drm_device_t *dev, struct nouveau_object *obj)
 {
        nouveau_object_instance_free(dev, obj);
        if (obj->handle != ~0)
-               nouveau_hash_table_remove(dev, obj);
+               nouveau_ramht_remove(dev, obj);
        drm_free(obj, sizeof(struct nouveau_object), DRM_MEM_DRIVER);
 }
 
@@ -480,7 +507,7 @@ nouveau_object_init_channel(drm_device_t *dev, int channel,
                return DRM_ERR(ENOMEM);
        }
 
-       ret = nouveau_ht_object_insert(dev, channel, vram_handle, gpuobj);
+       ret = nouveau_ramht_insert(dev, channel, vram_handle, gpuobj);
        if (ret) {
                DRM_ERROR("Error referencing VRAM ctxdma: %d\n", ret);
                return ret;
@@ -500,7 +527,7 @@ nouveau_object_init_channel(drm_device_t *dev, int channel,
                return DRM_ERR(ENOMEM);
        }
 
-       ret = nouveau_ht_object_insert(dev, channel, tt_handle, gpuobj);
+       ret = nouveau_ramht_insert(dev, channel, tt_handle, gpuobj);
        if (ret) {
                DRM_ERROR("Error referencing TT ctxdma: %d\n", ret);
                return ret;
@@ -545,7 +572,7 @@ int nouveau_ioctl_grobj_alloc(DRM_IOCTL_ARGS)
        if (!obj)
                return DRM_ERR(ENOMEM);
 
-       if (nouveau_ht_object_insert(dev, init.channel, init.handle, obj)) {
+       if (nouveau_ramht_insert(dev, init.channel, init.handle, obj)) {
                nouveau_object_free(dev, obj);
                return DRM_ERR(ENOMEM);
        }
index 783514a..5701018 100644 (file)
@@ -28,9 +28,9 @@
 #include "drm.h"
 #include "nouveau_drv.h"
 
-#define NV04_RAMFC (NV_RAMIN + dev_priv->ramfc_offset)
-#define RAMFC_WR(offset, val) NV_WRITE(fifoctx + NV04_RAMFC_##offset, (val))
-#define RAMFC_RD(offset)      NV_READ(fifoctx + NV04_RAMFC_##offset)
+#define NV04_RAMFC dev_priv->ramfc_offset
+#define RAMFC_WR(offset, val) NV_WI32(fifoctx + NV04_RAMFC_##offset, (val))
+#define RAMFC_RD(offset)      NV_RI32(fifoctx + NV04_RAMFC_##offset)
 #define NV04_FIFO_CONTEXT_SIZE 32
 
 int
@@ -47,7 +47,7 @@ nv04_fifo_create_context(drm_device_t *dev, int channel)
 
        /* Clear RAMFC */
        for (i=0; i<NV04_FIFO_CONTEXT_SIZE; i+=4)
-               NV_WRITE(fifoctx + i, 0);
+               NV_WI32(fifoctx + i, 0);
        
        /* Setup initial state */
        RAMFC_WR(DMA_PUT, chan->pushbuf_base);
@@ -72,7 +72,7 @@ nv04_fifo_destroy_context(drm_device_t *dev, int channel)
 
        fifoctx = NV04_RAMFC + (channel * NV04_FIFO_CONTEXT_SIZE);
        for (i=0; i<NV04_FIFO_CONTEXT_SIZE; i+=4)
-               NV_WRITE(fifoctx + i, 0);
+               NV_WI32(fifoctx + i, 0);
 }
 
 int
index 8dad45a..710a47f 100644 (file)
@@ -28,8 +28,8 @@
 #include "drm.h"
 #include "nouveau_drv.h"
 
-#define RAMFC_WR(offset, val)  NV_WRITE(fifoctx + NV10_RAMFC_##offset, (val))
-#define RAMFC_RD(offset)       NV_READ (fifoctx + NV10_RAMFC_##offset)
+#define RAMFC_WR(offset, val)  NV_WI32(fifoctx + NV10_RAMFC_##offset, (val))
+#define RAMFC_RD(offset)       NV_RI32(fifoctx + NV10_RAMFC_##offset)
 #define NV10_FIFO_CONTEXT_SIZE 64
 
 int
@@ -42,9 +42,9 @@ nv10_fifo_create_context(drm_device_t *dev, int channel)
 
        pushbuf = nouveau_chip_instance_get(dev, chan->cmdbuf_obj->instance);
 
-       fifoctx = NV_RAMIN + dev_priv->ramfc_offset + channel*64;
+       fifoctx = dev_priv->ramfc_offset + channel*64;
        for (i=0; i<NV10_FIFO_CONTEXT_SIZE;i+=4)
-               NV_WRITE(fifoctx + i, 0);
+               NV_WI32(fifoctx + i, 0);
 
        /* Fill entries that are seen filled in dumps of nvidia driver just
         * after channel's is put into DMA mode
@@ -70,9 +70,9 @@ nv10_fifo_destroy_context(drm_device_t *dev, int channel)
        uint32_t fifoctx;
        int i;
 
-       fifoctx = NV_RAMIN + dev_priv->ramfc_offset + channel*64;
+       fifoctx = dev_priv->ramfc_offset + channel*64;
        for (i=0; i<NV10_FIFO_CONTEXT_SIZE;i+=4)
-               NV_WRITE(fifoctx + i, 0);
+               NV_WI32(fifoctx + i, 0);
 }
 
 int
@@ -82,7 +82,7 @@ nv10_fifo_load_context(drm_device_t *dev, int channel)
        uint32_t fifoctx;
        uint32_t tmp;
 
-       fifoctx = NV_RAMIN + dev_priv->ramfc_offset + channel*64;
+       fifoctx = dev_priv->ramfc_offset + channel*64;
 
        NV_WRITE(NV03_PFIFO_CACHE1_PUSH1            , 0x00000100 | channel);
 
@@ -118,7 +118,7 @@ nv10_fifo_save_context(drm_device_t *dev, int channel)
        uint32_t fifoctx;
        uint32_t tmp;
 
-       fifoctx = NV_RAMIN + dev_priv->ramfc_offset + channel*64;
+       fifoctx = dev_priv->ramfc_offset + channel*64;
 
        RAMFC_WR(DMA_PUT          , NV_READ(NV04_PFIFO_CACHE1_DMA_PUT));
        RAMFC_WR(DMA_GET          , NV_READ(NV04_PFIFO_CACHE1_DMA_GET));
index 9d7afbe..945fe22 100644 (file)
@@ -28,8 +28,8 @@
 #include "nouveau_drv.h"
 #include "nouveau_drm.h"
 
-#define RAMFC_WR(offset, val)  NV_WRITE(fifoctx + NV40_RAMFC_##offset, (val))
-#define RAMFC_RD(offset)       NV_READ (fifoctx + NV40_RAMFC_##offset)
+#define RAMFC_WR(offset, val)  NV_WI32(fifoctx + NV40_RAMFC_##offset, (val))
+#define RAMFC_RD(offset)       NV_RI32(fifoctx + NV40_RAMFC_##offset)
 
 int
 nv40_fifo_create_context(drm_device_t *dev, int channel)
@@ -39,9 +39,9 @@ nv40_fifo_create_context(drm_device_t *dev, int channel)
        uint32_t fifoctx, grctx, pushbuf;
        int i;
 
-       fifoctx = NV_RAMIN + dev_priv->ramfc_offset + channel*128;
+       fifoctx = dev_priv->ramfc_offset + channel*128;
        for (i=0;i<128;i+=4)
-               NV_WRITE(fifoctx + i, 0);
+               NV_WI32(fifoctx + i, 0);
 
        grctx   = nouveau_chip_instance_get(dev, chan->ramin_grctx);
        pushbuf = nouveau_chip_instance_get(dev, chan->cmdbuf_obj->instance);
@@ -73,9 +73,9 @@ nv40_fifo_destroy_context(drm_device_t *dev, int channel)
        uint32_t fifoctx;
        int i;
 
-       fifoctx = NV_RAMIN + dev_priv->ramfc_offset + channel*128;
+       fifoctx = dev_priv->ramfc_offset + channel*128;
        for (i=0;i<128;i+=4)
-               NV_WRITE(fifoctx + i, 0);
+               NV_WI32(fifoctx + i, 0);
 }
 
 int
@@ -85,7 +85,7 @@ nv40_fifo_load_context(drm_device_t *dev, int channel)
        uint32_t fifoctx;
        uint32_t tmp, tmp2;
 
-       fifoctx = NV_RAMIN + dev_priv->ramfc_offset + channel*128;
+       fifoctx = dev_priv->ramfc_offset + channel*128;
 
        NV_WRITE(NV04_PFIFO_CACHE1_DMA_GET          , RAMFC_RD(DMA_GET));
        NV_WRITE(NV04_PFIFO_CACHE1_DMA_PUT          , RAMFC_RD(DMA_PUT));
@@ -146,7 +146,7 @@ nv40_fifo_save_context(drm_device_t *dev, int channel)
        uint32_t fifoctx;
        uint32_t tmp;
 
-       fifoctx = NV_RAMIN + dev_priv->ramfc_offset + channel*128;
+       fifoctx = dev_priv->ramfc_offset + channel*128;
 
        RAMFC_WR(DMA_PUT          , NV_READ(NV04_PFIFO_CACHE1_DMA_PUT));
        RAMFC_WR(DMA_GET          , NV_READ(NV04_PFIFO_CACHE1_DMA_GET));