summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--shared-core/nouveau_drv.h5
-rw-r--r--shared-core/nouveau_mem.c9
-rw-r--r--shared-core/nouveau_notifier.c2
-rw-r--r--shared-core/nouveau_object.c133
-rw-r--r--shared-core/nv04_fifo.c10
-rw-r--r--shared-core/nv10_fifo.c16
-rw-r--r--shared-core/nv40_fifo.c16
7 files changed, 106 insertions, 85 deletions
diff --git a/shared-core/nouveau_drv.h b/shared-core/nouveau_drv.h
index b2ddf0a6..3cca07fc 100644
--- a/shared-core/nouveau_drv.h
+++ b/shared-core/nouveau_drv.h
@@ -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 *
diff --git a/shared-core/nouveau_mem.c b/shared-core/nouveau_mem.c
index 4c6d0d5c..d8ae52b7 100644
--- a/shared-core/nouveau_mem.c
+++ b/shared-core/nouveau_mem.c
@@ -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
diff --git a/shared-core/nouveau_notifier.c b/shared-core/nouveau_notifier.c
index ab6f8c2d..0cfe733e 100644
--- a/shared-core/nouveau_notifier.c
+++ b/shared-core/nouveau_notifier.c
@@ -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");
diff --git a/shared-core/nouveau_object.c b/shared-core/nouveau_object.c
index e7528e23..dac08df4 100644
--- a/shared-core/nouveau_object.c
+++ b/shared-core/nouveau_object.c
@@ -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);
}
diff --git a/shared-core/nv04_fifo.c b/shared-core/nv04_fifo.c
index 783514a7..57010182 100644
--- a/shared-core/nv04_fifo.c
+++ b/shared-core/nv04_fifo.c
@@ -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
diff --git a/shared-core/nv10_fifo.c b/shared-core/nv10_fifo.c
index 8dad45aa..710a47f7 100644
--- a/shared-core/nv10_fifo.c
+++ b/shared-core/nv10_fifo.c
@@ -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));
diff --git a/shared-core/nv40_fifo.c b/shared-core/nv40_fifo.c
index 9d7afbe5..945fe228 100644
--- a/shared-core/nv40_fifo.c
+++ b/shared-core/nv40_fifo.c
@@ -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));