summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--shared-core/nouveau_drm.h1
-rw-r--r--shared-core/nouveau_drv.h29
-rw-r--r--shared-core/nouveau_fifo.c8
-rw-r--r--shared-core/nouveau_mem.c43
-rw-r--r--shared-core/nouveau_object.c67
-rw-r--r--shared-core/nouveau_state.c3
6 files changed, 81 insertions, 70 deletions
diff --git a/shared-core/nouveau_drm.h b/shared-core/nouveau_drm.h
index 2517bbc3..2874d36a 100644
--- a/shared-core/nouveau_drm.h
+++ b/shared-core/nouveau_drm.h
@@ -69,6 +69,7 @@ drm_nouveau_dma_object_init_t;
#define NOUVEAU_MEM_PINNED 0x00000010
#define NOUVEAU_MEM_USER_BACKED 0x00000020
#define NOUVEAU_MEM_MAPPED 0x00000040
+#define NOUVEAU_MEM_INSTANCE 0x00000080 /* internal */
typedef struct drm_nouveau_mem_alloc {
int flags;
diff --git a/shared-core/nouveau_drv.h b/shared-core/nouveau_drv.h
index 93887839..be8f4cf4 100644
--- a/shared-core/nouveau_drv.h
+++ b/shared-core/nouveau_drv.h
@@ -52,11 +52,12 @@ struct nouveau_object
struct nouveau_object *next;
struct nouveau_object *prev;
+ struct mem_block *instance;
+ uint32_t ht_loc;
+
uint32_t handle;
int class;
int engine;
- uint32_t instance;
- uint32_t ht_loc;
};
#define NV_DMA_TARGET_VIDMEM 0
@@ -77,14 +78,6 @@ struct nouveau_fifo
struct nouveau_object *objs;
};
-struct nouveau_object_store
-{
- uint32_t *inst_bmap;
- uint32_t first_instance;
- int num_instance;
- int free_instance;
-};
-
struct mem_block {
struct mem_block *next;
struct mem_block *prev;
@@ -119,7 +112,7 @@ typedef struct drm_nouveau_private {
int fifo_alloc_count;
struct nouveau_fifo fifos[NV_MAX_FIFO_NUMBER];
- struct nouveau_object_store objs;
+
/* RAMFC and RAMRO offsets */
uint32_t ramht_offset;
uint32_t ramht_size;
@@ -132,6 +125,7 @@ typedef struct drm_nouveau_private {
struct mem_block *agp_heap;
struct mem_block *fb_heap;
struct mem_block *fb_nomap_heap;
+ struct mem_block *ramin_heap;
struct nouveau_config config;
}
@@ -155,6 +149,12 @@ extern struct mem_block* nouveau_mem_alloc(struct drm_device *dev, int alignment
extern void nouveau_mem_free(struct drm_device* dev, struct mem_block*);
extern int nouveau_mem_init(struct drm_device *dev);
extern void nouveau_mem_close(struct drm_device *dev);
+extern int nouveau_instmem_init(struct drm_device *dev,
+ uint32_t offset, uint32_t size);
+extern struct mem_block* nouveau_instmem_alloc(struct drm_device *dev,
+ uint32_t size, uint32_t align);
+extern void nouveau_instmem_free(struct drm_device *dev,
+ struct mem_block *block);
/* nouveau_fifo.c */
extern int nouveau_fifo_init(drm_device_t *dev);
@@ -163,13 +163,12 @@ extern void nouveau_fifo_cleanup(drm_device_t *dev, DRMFILE filp);
extern int nouveau_fifo_id_get(drm_device_t *dev, DRMFILE filp);
/* nouveau_object.c */
-extern int nouveau_object_init(drm_device_t *dev);
extern void nouveau_object_cleanup(drm_device_t *dev, DRMFILE filp);
extern struct nouveau_object *nouveau_dma_object_create(drm_device_t *dev,
uint32_t offset, uint32_t size, int access, uint32_t target);
extern int nouveau_ioctl_object_init(DRM_IOCTL_ARGS);
extern int nouveau_ioctl_dma_object_init(DRM_IOCTL_ARGS);
-extern uint32_t nouveau_chip_instance_get(drm_device_t *dev, uint32_t instance);
+extern uint32_t nouveau_chip_instance_get(drm_device_t *dev, struct mem_block *mem);
/* nouveau_irq.c */
extern irqreturn_t nouveau_irq_handler(DRM_IRQ_ARGS);
@@ -188,8 +187,8 @@ extern long nouveau_compat_ioctl(struct file *filp, unsigned int cmd,
#define NV_WRITE(reg,val) DRM_WRITE32( dev_priv->mmio, (reg), (val) )
#endif
-#define INSTANCE_WR(inst,ofs,val) NV_WRITE(NV_RAMIN+(inst)+((ofs)<<2),(val))
-#define INSTANCE_RD(inst,ofs) NV_READ(NV_RAMIN+(inst)+((ofs)<<2))
+#define INSTANCE_WR(mem,ofs,val) NV_WRITE(NV_RAMIN+(uint32_t)(mem)->start+((ofs)<<2),(val))
+#define INSTANCE_RD(mem,ofs) NV_READ(NV_RAMIN+(uint32_t)(mem)->start+((ofs)<<2))
#endif /* __NOUVEAU_DRV_H__ */
diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c
index 9ff0563c..94762139 100644
--- a/shared-core/nouveau_fifo.c
+++ b/shared-core/nouveau_fifo.c
@@ -69,6 +69,7 @@ static int nouveau_fifo_ctx_size(drm_device_t* dev)
static int nouveau_fifo_instmem_configure(drm_device_t *dev)
{
drm_nouveau_private_t *dev_priv = dev->dev_private;
+ uint32_t obj_base, obj_size;
int i;
/* Clear RAMIN */
@@ -123,6 +124,13 @@ static int nouveau_fifo_instmem_configure(drm_device_t *dev)
dev_priv->ramfc_offset,
dev_priv->ramfc_size);
+ obj_base = dev_priv->ramfc_offset + dev_priv->ramfc_size;
+ obj_size = (512*1024) - obj_base; /*XXX: probably wrong on some cards*/
+ if (nouveau_instmem_init(dev, obj_base, obj_size))
+ return 1;
+ DRM_DEBUG("RAMIN object space: offset=0x%08x, size=%dKiB\n",
+ obj_base, obj_size>>10);
+
return 0;
}
diff --git a/shared-core/nouveau_mem.c b/shared-core/nouveau_mem.c
index 897badd4..93b9c869 100644
--- a/shared-core/nouveau_mem.c
+++ b/shared-core/nouveau_mem.c
@@ -443,6 +443,49 @@ void nouveau_mem_free(struct drm_device* dev, struct mem_block* block)
free_block(block);
}
+int nouveau_instmem_init(struct drm_device *dev, uint32_t offset,
+ uint32_t size)
+{
+ drm_nouveau_private_t *dev_priv = dev->dev_private;
+ int ret;
+
+ ret = init_heap(&dev_priv->ramin_heap, offset, size);
+ if (ret) {
+ dev_priv->ramin_heap = NULL;
+ DRM_ERROR("Failed to init RAMIN heap\n");
+ }
+
+ return ret;
+}
+
+struct mem_block *nouveau_instmem_alloc(struct drm_device *dev,
+ uint32_t size, uint32_t align)
+{
+ drm_nouveau_private_t *dev_priv = dev->dev_private;
+ struct mem_block *block;
+
+ if (!dev_priv->ramin_heap) {
+ DRM_ERROR("instmem alloc called without init\n");
+ return NULL;
+ }
+
+ block = alloc_block(dev_priv->ramin_heap, size, align, (DRMFILE)-2);
+ if (block) {
+ block->flags = NOUVEAU_MEM_INSTANCE;
+ DRM_DEBUG("instance(size=%d, align=%d) alloc'd at 0x%08x\n",
+ size, (1<<align), block->start);
+ }
+
+ return block;
+}
+
+void nouveau_instmem_free(struct drm_device *dev, struct mem_block *block)
+{
+ if (dev && block) {
+ free_block(block);
+ }
+}
+
/*
* Ioctls
*/
diff --git a/shared-core/nouveau_object.c b/shared-core/nouveau_object.c
index 2c899335..c11b05eb 100644
--- a/shared-core/nouveau_object.c
+++ b/shared-core/nouveau_object.c
@@ -44,9 +44,13 @@
* in the future when we can access more instance ram which isn't mapped into
* the PRAMIN aperture
*/
-uint32_t nouveau_chip_instance_get(drm_device_t *dev, uint32_t instance)
+uint32_t nouveau_chip_instance_get(drm_device_t *dev,
+ struct mem_block *mem)
{
- return (instance>>4);
+ uint32_t inst = (uint32_t)mem->start >> 4;
+ DRM_DEBUG("****** on-chip instance for 0x%016llx = 0x%08x\n",
+ mem->start, inst);
+ return inst;
}
static void nouveau_object_link(drm_device_t *dev, int fifo_num,
@@ -212,27 +216,7 @@ static void nouveau_hash_table_remove(drm_device_t* dev,
static struct nouveau_object *nouveau_instance_alloc(drm_device_t* dev)
{
drm_nouveau_private_t *dev_priv=dev->dev_private;
- struct nouveau_object_store *objs=&dev_priv->objs;
struct nouveau_object *obj;
- int instance = -1;
- int i = 0, j = 0;
-
- /* Allocate a block of instance RAM */
- if (!objs->free_instance) {
- DRM_ERROR("no free instance ram\n");
- return NULL;
- }
- for (i=0;i<(objs->num_instance>>5);i++) {
- if (objs->inst_bmap[i] == ~0) continue;
- for (j=0;j<32;j++) {
- if (!(objs->inst_bmap[i] & (1<<j))) {
- instance = (i<<5) + j;
- break;
- }
- }
- if (instance != -1) break;
- }
- DRM_DEBUG("alloced instance %d (slot %d/%d)\n", instance, i, j);
/* Create object struct */
obj = drm_calloc(1, sizeof(struct nouveau_object), DRM_MEM_DRIVER);
@@ -240,13 +224,13 @@ static struct nouveau_object *nouveau_instance_alloc(drm_device_t* dev)
DRM_ERROR("couldn't alloc memory for object\n");
return NULL;
}
- obj->instance = objs->first_instance;
- obj->instance += (instance << (dev_priv->card_type >= NV_40 ? 5 : 4));
- DRM_DEBUG("instance address is 0x%08x\n", instance);
-
- /* Mark instance slot as used */
- objs->inst_bmap[i] |= (1 << j);
- objs->free_instance--;
+ obj->instance = nouveau_instmem_alloc(dev,
+ (dev_priv->card_type >= NV_40 ? 32 : 16), 4);
+ if (!obj->instance) {
+ DRM_ERROR("couldn't alloc RAMIN for object\n");
+ drm_free(obj, sizeof(struct nouveau_object), DRM_MEM_DRIVER);
+ return NULL;
+ }
return obj;
}
@@ -255,9 +239,7 @@ static void nouveau_object_instance_free(drm_device_t *dev,
struct nouveau_object *obj)
{
drm_nouveau_private_t *dev_priv=dev->dev_private;
- struct nouveau_object_store *objs=&dev_priv->objs;
int count, i;
- uint32_t be, bb;
if (dev_priv->card_type >= NV_40)
count = 8;
@@ -274,27 +256,8 @@ static void nouveau_object_instance_free(drm_device_t *dev,
INSTANCE_WR(obj->instance, i, 0x00000000);
}
- /* Mark instance as free */
- obj->instance -= objs->first_instance;
- obj->instance >>= (dev_priv->card_type >=NV_40 ? 5 : 4);
- be = obj->instance / 32;
- bb = obj->instance % 32;
- objs->inst_bmap[be] &= ~(1<<bb);
- objs->free_instance++;
-}
-
-int nouveau_object_init(drm_device_t* dev)
-{
- drm_nouveau_private_t *dev_priv=dev->dev_private;
-
- dev_priv->objs.first_instance =
- dev_priv->ramfc_offset +dev_priv->ramfc_size;
- dev_priv->objs.free_instance = 1024; /*FIXME*/
- dev_priv->objs.num_instance = 1024; /*FIXME*/
- dev_priv->objs.inst_bmap = drm_calloc
- (1, dev_priv->objs.num_instance/32, DRM_MEM_DRIVER);
-
- return 0;
+ /* Free RAMIN */
+ nouveau_instmem_free(dev, obj->instance);
}
/*
diff --git a/shared-core/nouveau_state.c b/shared-core/nouveau_state.c
index 1128da54..b2934b43 100644
--- a/shared-core/nouveau_state.c
+++ b/shared-core/nouveau_state.c
@@ -70,9 +70,6 @@ int nouveau_firstopen(struct drm_device *dev)
*/
ret = nouveau_fifo_init(dev);
if (ret) return ret;
- /* Initialise instance memory allocation */
- ret = nouveau_object_init(dev);
- if (ret) return ret;
/* FIXME: doesn't belong here, and have no idea what it's for.. */
if (dev_priv->card_type >= NV_40) {