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;
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 *
{
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);
}
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;
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;
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);
}
#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
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
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
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);
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));
#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)
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);
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
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));
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));