From 5667396e05723afc5a626e1ba0384e29a240dea3 Mon Sep 17 00:00:00 2001 From: Oliver McFadden Date: Tue, 13 Mar 2007 00:50:05 +0000 Subject: Guess another unknown register used for R300 pacification. --- shared-core/r300_cmdbuf.c | 4 ++-- shared-core/r300_reg.h | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/shared-core/r300_cmdbuf.c b/shared-core/r300_cmdbuf.c index 0c04b5f8..aa8b80e5 100644 --- a/shared-core/r300_cmdbuf.c +++ b/shared-core/r300_cmdbuf.c @@ -224,7 +224,7 @@ void r300_init_reg_flags(void) ADD_RANGE(R300_TX_BORDER_COLOR_0, 16); /* Sporadic registers used as primitives are emitted */ - ADD_RANGE(0x4f18, 1); + ADD_RANGE(R300_RB3D_ZCACHE_CTLSTAT, 1); ADD_RANGE(R300_RB3D_DSTCACHE_CTLSTAT, 1); ADD_RANGE(R300_VAP_INPUT_ROUTE_0_0, 8); ADD_RANGE(R300_VAP_INPUT_ROUTE_1_0, 8); @@ -693,7 +693,7 @@ static __inline__ void r300_pacify(drm_radeon_private_t *dev_priv) BEGIN_RING(6); OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0)); OUT_RING(0xa); - OUT_RING(CP_PACKET0(0x4f18, 0)); + OUT_RING(CP_PACKET0(R300_RB3D_ZCACHE_CTLSTAT, 0)); OUT_RING(0x3); OUT_RING(CP_PACKET3(RADEON_CP_NOP, 0)); OUT_RING(0x0); diff --git a/shared-core/r300_reg.h b/shared-core/r300_reg.h index 69bc994c..667fe05a 100644 --- a/shared-core/r300_reg.h +++ b/shared-core/r300_reg.h @@ -1394,6 +1394,10 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* gap */ +#define R300_RB3D_ZCACHE_CTLSTAT 0x4F18 /* GUESS */ + +/* gap */ + #define R300_RB3D_DEPTHOFFSET 0x4F20 #define R300_RB3D_DEPTHPITCH 0x4F24 # define R300_DEPTHPITCH_MASK 0x00001FF8 /* GUESS */ -- cgit v1.2.3 From 462a6ea4caadae0c68f6fe3e0343950ced2095cb Mon Sep 17 00:00:00 2001 From: Oliver McFadden Date: Tue, 13 Mar 2007 01:19:56 +0000 Subject: Corrected values written to R300_RB3D_DSTCACHE_CTLSTAT to either R300_RB3D_DSTCACHE_02 or R300_RB3D_DSTCACHE_0A, rather than hexadecimal values. --- shared-core/r300_cmdbuf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared-core/r300_cmdbuf.c b/shared-core/r300_cmdbuf.c index aa8b80e5..e62cbda5 100644 --- a/shared-core/r300_cmdbuf.c +++ b/shared-core/r300_cmdbuf.c @@ -692,7 +692,7 @@ static __inline__ void r300_pacify(drm_radeon_private_t *dev_priv) BEGIN_RING(6); OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0)); - OUT_RING(0xa); + OUT_RING(R300_RB3D_DSTCACHE_0A); OUT_RING(CP_PACKET0(R300_RB3D_ZCACHE_CTLSTAT, 0)); OUT_RING(0x3); OUT_RING(CP_PACKET3(RADEON_CP_NOP, 0)); -- cgit v1.2.3 From 7e2bbe295424adfcd455a4c4b42dd0342087615e Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 13 Mar 2007 13:43:14 +1100 Subject: nouveau: s/fifo/channel/ --- shared-core/nouveau_object.c | 101 ++++++++++++++++++++++--------------------- 1 file changed, 52 insertions(+), 49 deletions(-) diff --git a/shared-core/nouveau_object.c b/shared-core/nouveau_object.c index b3c4b0e0..ed214c69 100644 --- a/shared-core/nouveau_object.c +++ b/shared-core/nouveau_object.c @@ -44,8 +44,8 @@ * 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, - struct mem_block *mem) +uint32_t +nouveau_chip_instance_get(drm_device_t *dev, struct mem_block *mem) { uint32_t inst = (uint32_t)mem->start >> 4; DRM_DEBUG("****** on-chip instance for 0x%016llx = 0x%08x\n", @@ -53,34 +53,35 @@ uint32_t nouveau_chip_instance_get(drm_device_t *dev, return inst; } -static void nouveau_object_link(drm_device_t *dev, int fifo_num, - struct nouveau_object *obj) +static void +nouveau_object_link(drm_device_t *dev, int channel, struct nouveau_object *obj) { drm_nouveau_private_t *dev_priv=dev->dev_private; - struct nouveau_fifo *fifo = &dev_priv->fifos[fifo_num]; + struct nouveau_fifo *chan = &dev_priv->fifos[channel]; - if (!fifo->objs) { - fifo->objs = obj; + if (!chan->objs) { + chan->objs = obj; return; } obj->prev = NULL; - obj->next = fifo->objs; + obj->next = chan->objs; - fifo->objs->prev = obj; - fifo->objs = obj; + chan->objs->prev = obj; + chan->objs = obj; } -static void nouveau_object_unlink(drm_device_t *dev, int fifo_num, - struct nouveau_object *obj) +static void +nouveau_object_unlink(drm_device_t *dev, int channel, + struct nouveau_object *obj) { drm_nouveau_private_t *dev_priv=dev->dev_private; - struct nouveau_fifo *fifo = &dev_priv->fifos[fifo_num]; + struct nouveau_fifo *chan = &dev_priv->fifos[channel]; if (obj->prev == NULL) { if (obj->next) obj->next->prev = NULL; - fifo->objs = obj->next; + chan->objs = obj->next; } else if (obj->next == NULL) { if (obj->prev) obj->prev->next = NULL; @@ -91,11 +92,11 @@ static void nouveau_object_unlink(drm_device_t *dev, int fifo_num, } static struct nouveau_object * -nouveau_object_handle_find(drm_device_t *dev, int fifo_num, uint32_t handle) +nouveau_object_handle_find(drm_device_t *dev, int channel, uint32_t handle) { drm_nouveau_private_t *dev_priv=dev->dev_private; - struct nouveau_fifo *fifo = &dev_priv->fifos[fifo_num]; - struct nouveau_object *obj = fifo->objs; + struct nouveau_fifo *chan = &dev_priv->fifos[channel]; + struct nouveau_object *obj = chan->objs; DRM_DEBUG("Looking for handle 0x%08x\n", handle); while (obj) { @@ -138,8 +139,8 @@ nouveau_object_handle_find(drm_device_t *dev, int fifo_num, uint32_t handle) The key into the hash table depends on the object handle and channel id and is given as: */ -static uint32_t nouveau_handle_hash(drm_device_t* dev, uint32_t handle, - int fifo) +static uint32_t +nouveau_ht_handle_hash(drm_device_t *dev, int channel, uint32_t handle) { drm_nouveau_private_t *dev_priv=dev->dev_private; uint32_t hash = 0; @@ -149,19 +150,20 @@ static uint32_t nouveau_handle_hash(drm_device_t* dev, uint32_t handle, hash ^= (handle & ((1 << dev_priv->ramht_bits) - 1)); handle >>= dev_priv->ramht_bits; } - hash ^= fifo << (dev_priv->ramht_bits - 4); + hash ^= channel << (dev_priv->ramht_bits - 4); return hash << 3; } -static int nouveau_hash_table_insert(drm_device_t* dev, int fifo, - struct nouveau_object *obj) +static int +nouveau_ht_object_insert(drm_device_t* dev, int channel, + 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; - o_ofs = ofs = nouveau_handle_hash(dev, obj->handle, fifo); + 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; @@ -174,19 +176,19 @@ static int nouveau_hash_table_insert(drm_device_t* dev, int fifo, ofs += ht_base; DRM_DEBUG("Channel %d - Handle 0x%08x at 0x%08x\n", - fifo, obj->handle, ofs); + 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, - (fifo << NV40_RAMHT_CONTEXT_CHANNEL_SHIFT) | + (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 | - (fifo << NV_RAMHT_CONTEXT_CHANNEL_SHIFT) | + (channel << NV_RAMHT_CONTEXT_CHANNEL_SHIFT) | (obj->engine << NV_RAMHT_CONTEXT_ENGINE_SHIFT) | nouveau_chip_instance_get(dev, obj->instance) ); @@ -445,9 +447,9 @@ nouveau_context_object_create(drm_device_t* dev, int class) } static void -nouveau_object_free(drm_device_t *dev, int fifo_num, struct nouveau_object *obj) +nouveau_object_free(drm_device_t *dev, int channel, struct nouveau_object *obj) { - nouveau_object_unlink(dev, fifo_num, obj); + nouveau_object_unlink(dev, channel, obj); nouveau_object_instance_free(dev, obj); nouveau_hash_table_remove(dev, obj); @@ -459,14 +461,15 @@ nouveau_object_free(drm_device_t *dev, int fifo_num, struct nouveau_object *obj) void nouveau_object_cleanup(drm_device_t *dev, DRMFILE filp) { drm_nouveau_private_t *dev_priv=dev->dev_private; - int fifo; + int channel; - fifo = nouveau_fifo_id_get(dev, filp); - if (fifo == -1) + channel = nouveau_fifo_id_get(dev, filp); + if (channel == -1) return; - while (dev_priv->fifos[fifo].objs) - nouveau_object_free(dev, fifo, dev_priv->fifos[fifo].objs); + while (dev_priv->fifos[channel].objs) + nouveau_object_free(dev, channel, + dev_priv->fifos[channel].objs); } int nouveau_ioctl_object_init(DRM_IOCTL_ARGS) @@ -474,10 +477,10 @@ int nouveau_ioctl_object_init(DRM_IOCTL_ARGS) DRM_DEVICE; drm_nouveau_object_init_t init; struct nouveau_object *obj; - int fifo; + int channel; - fifo = nouveau_fifo_id_get(dev, filp); - if (fifo == -1) + channel = nouveau_fifo_id_get(dev, filp); + if (channel == -1) return DRM_ERR(EINVAL); DRM_COPY_FROM_USER_IOCTL(init, (drm_nouveau_object_init_t __user *) @@ -485,9 +488,9 @@ int nouveau_ioctl_object_init(DRM_IOCTL_ARGS) //FIXME: check args, only allow trusted objects to be created - if (nouveau_object_handle_find(dev, fifo, init.handle)) { + if (nouveau_object_handle_find(dev, channel, init.handle)) { DRM_ERROR("Channel %d: handle 0x%08x already exists\n", - fifo, init.handle); + channel, init.handle); return DRM_ERR(EINVAL); } @@ -496,12 +499,12 @@ int nouveau_ioctl_object_init(DRM_IOCTL_ARGS) return DRM_ERR(ENOMEM); obj->handle = init.handle; - if (nouveau_hash_table_insert(dev, fifo, obj)) { - nouveau_object_free(dev, fifo, obj); + if (nouveau_ht_object_insert(dev, channel, obj)) { + nouveau_object_free(dev, channel, obj); return DRM_ERR(ENOMEM); } - nouveau_object_link(dev, fifo, obj); + nouveau_object_link(dev, channel, obj); return 0; } @@ -569,10 +572,10 @@ int nouveau_ioctl_dma_object_init(DRM_IOCTL_ARGS) DRM_DEVICE; drm_nouveau_dma_object_init_t init; struct nouveau_object *obj; - int fifo; + int channel; - fifo = nouveau_fifo_id_get(dev, filp); - if (fifo == -1) + channel = nouveau_fifo_id_get(dev, filp); + if (channel == -1) return DRM_ERR(EINVAL); DRM_COPY_FROM_USER_IOCTL(init, (drm_nouveau_dma_object_init_t __user *) @@ -581,9 +584,9 @@ int nouveau_ioctl_dma_object_init(DRM_IOCTL_ARGS) if (nouveau_dma_object_check_access(dev, &init)) return DRM_ERR(EPERM); - if (nouveau_object_handle_find(dev, fifo, init.handle)) { + if (nouveau_object_handle_find(dev, channel, init.handle)) { DRM_ERROR("Channel %d: handle 0x%08x already exists\n", - fifo, init.handle); + channel, init.handle); return DRM_ERR(EINVAL); } @@ -594,12 +597,12 @@ int nouveau_ioctl_dma_object_init(DRM_IOCTL_ARGS) return DRM_ERR(ENOMEM); obj->handle = init.handle; - if (nouveau_hash_table_insert(dev, fifo, obj)) { - nouveau_object_free(dev, fifo, obj); + if (nouveau_ht_object_insert(dev, channel, obj)) { + nouveau_object_free(dev, channel, obj); return DRM_ERR(ENOMEM); } - nouveau_object_link(dev, fifo, obj); + nouveau_object_link(dev, channel, obj); return 0; } -- cgit v1.2.3 From 1775202cf96c51018bf369b1b4d08023d622513c Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 13 Mar 2007 14:18:03 +1100 Subject: nouveau: associate all created objects with a channel + cleanups --- shared-core/nouveau_drv.h | 6 +++- shared-core/nouveau_fifo.c | 9 ++++-- shared-core/nouveau_object.c | 77 +++++++++++++++++++++----------------------- shared-core/nv40_graph.c | 1 - 4 files changed, 48 insertions(+), 45 deletions(-) diff --git a/shared-core/nouveau_drv.h b/shared-core/nouveau_drv.h index c3d19bb0..a4b05895 100644 --- a/shared-core/nouveau_drv.h +++ b/shared-core/nouveau_drv.h @@ -61,6 +61,7 @@ struct nouveau_object { struct nouveau_object *next; struct nouveau_object *prev; + int channel; struct mem_block *instance; uint32_t ht_loc; @@ -192,9 +193,12 @@ extern void nouveau_fifo_free(drm_device_t *dev, int channel); /* nouveau_object.c */ extern void nouveau_object_cleanup(drm_device_t *dev, DRMFILE filp); extern struct nouveau_object * -nouveau_dma_object_create(drm_device_t *dev, int class, +nouveau_object_gr_create(drm_device_t *dev, int channel, int class); +extern struct nouveau_object * +nouveau_object_dma_create(drm_device_t *dev, int channel, int class, uint32_t offset, uint32_t size, int access, int target); +extern void nouveau_object_free(drm_device_t *dev, struct nouveau_object *obj); 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, struct mem_block *mem); diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c index ebdf7fb6..8c4e8309 100644 --- a/shared-core/nouveau_fifo.c +++ b/shared-core/nouveau_fifo.c @@ -239,12 +239,14 @@ nouveau_fifo_cmdbuf_alloc(struct drm_device *dev, int channel) } if (cb->flags & NOUVEAU_MEM_AGP) { - cb_dma = nouveau_dma_object_create(dev, NV_CLASS_DMA_IN_MEMORY, + cb_dma = nouveau_object_dma_create(dev, channel, + NV_CLASS_DMA_IN_MEMORY, cb->start - dev_priv->agp_phys, cb->size, NV_DMA_ACCESS_RO, NV_DMA_TARGET_AGP); } else if (dev_priv->card_type != NV_04) { - cb_dma = nouveau_dma_object_create(dev, NV_CLASS_DMA_IN_MEMORY, + cb_dma = nouveau_object_dma_create(dev, channel, + NV_CLASS_DMA_IN_MEMORY, cb->start - drm_get_resource_start(dev, 1), cb->size, NV_DMA_ACCESS_RO, NV_DMA_TARGET_VIDMEM); @@ -253,7 +255,8 @@ nouveau_fifo_cmdbuf_alloc(struct drm_device *dev, int channel) * exact reason for existing :) PCI access to cmdbuf in * VRAM. */ - cb_dma = nouveau_dma_object_create(dev, NV_CLASS_DMA_IN_MEMORY, + cb_dma = nouveau_object_dma_create(dev, channel, + NV_CLASS_DMA_IN_MEMORY, cb->start, cb->size, NV_DMA_ACCESS_RO, NV_DMA_TARGET_PCI); } diff --git a/shared-core/nouveau_object.c b/shared-core/nouveau_object.c index ed214c69..c5cf8496 100644 --- a/shared-core/nouveau_object.c +++ b/shared-core/nouveau_object.c @@ -54,10 +54,10 @@ nouveau_chip_instance_get(drm_device_t *dev, struct mem_block *mem) } static void -nouveau_object_link(drm_device_t *dev, int channel, struct nouveau_object *obj) +nouveau_object_link(drm_device_t *dev, struct nouveau_object *obj) { drm_nouveau_private_t *dev_priv=dev->dev_private; - struct nouveau_fifo *chan = &dev_priv->fifos[channel]; + struct nouveau_fifo *chan = &dev_priv->fifos[obj->channel]; if (!chan->objs) { chan->objs = obj; @@ -72,11 +72,10 @@ nouveau_object_link(drm_device_t *dev, int channel, struct nouveau_object *obj) } static void -nouveau_object_unlink(drm_device_t *dev, int channel, - struct nouveau_object *obj) +nouveau_object_unlink(drm_device_t *dev, struct nouveau_object *obj) { drm_nouveau_private_t *dev_priv=dev->dev_private; - struct nouveau_fifo *chan = &dev_priv->fifos[channel]; + struct nouveau_fifo *chan = &dev_priv->fifos[obj->channel]; if (obj->prev == NULL) { if (obj->next) @@ -155,7 +154,7 @@ nouveau_ht_handle_hash(drm_device_t *dev, int channel, uint32_t handle) } static int -nouveau_ht_object_insert(drm_device_t* dev, int channel, +nouveau_ht_object_insert(drm_device_t* dev, int channel, uint32_t handle, struct nouveau_object *obj) { drm_nouveau_private_t *dev_priv=dev->dev_private; @@ -163,6 +162,7 @@ nouveau_ht_object_insert(drm_device_t* dev, int channel, 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)) { @@ -212,7 +212,8 @@ static void nouveau_hash_table_remove(drm_device_t* dev, } } -static struct nouveau_object *nouveau_instance_alloc(drm_device_t* dev) +static struct nouveau_object * +nouveau_object_instance_alloc(drm_device_t* dev, int channel) { drm_nouveau_private_t *dev_priv=dev->dev_private; struct nouveau_object *obj; @@ -223,6 +224,8 @@ static struct nouveau_object *nouveau_instance_alloc(drm_device_t* dev) DRM_ERROR("couldn't alloc memory for object\n"); return NULL; } + + /* Allocate instance memory */ obj->instance = nouveau_instmem_alloc(dev, (dev_priv->card_type >= NV_40 ? 32 : 16), 4); if (!obj->instance) { @@ -231,25 +234,28 @@ static struct nouveau_object *nouveau_instance_alloc(drm_device_t* dev) return NULL; } + /* Bind object to channel */ + obj->channel = channel; + obj->handle = ~0; + nouveau_object_link(dev, obj); + return obj; } -static void nouveau_object_instance_free(drm_device_t *dev, - struct nouveau_object *obj) +static void +nouveau_object_instance_free(drm_device_t *dev, struct nouveau_object *obj) { drm_nouveau_private_t *dev_priv=dev->dev_private; - int count, i; + int i; - if (dev_priv->card_type >= NV_40) - count = 8; - else - count = 4; + /* Unbind object from channel */ + nouveau_object_unlink(dev, obj); /* Clean RAMIN entry */ DRM_DEBUG("Instance entry for 0x%08x" "(engine %d, class 0x%x) before destroy:\n", obj->handle, obj->engine, obj->class); - for (i=0;iinstance->size/4); i++) { DRM_DEBUG(" +0x%02x: 0x%08x\n", (i*4), INSTANCE_RD(obj->instance, i)); INSTANCE_WR(obj->instance, i, 0x00000000); @@ -285,7 +291,7 @@ static void nouveau_object_instance_free(drm_device_t *dev, */ struct nouveau_object * -nouveau_dma_object_create(drm_device_t* dev, int class, +nouveau_object_dma_create(drm_device_t* dev, int channel, int class, uint32_t offset, uint32_t size, int access, int target) { @@ -320,7 +326,7 @@ nouveau_dma_object_create(drm_device_t* dev, int class, frame = offset & ~0x00000FFF; adjust = offset & 0x00000FFF; - obj = nouveau_instance_alloc(dev); + obj = nouveau_object_instance_alloc(dev, channel); if (!obj) { DRM_ERROR("couldn't allocate DMA object\n"); return obj; @@ -393,15 +399,15 @@ nouveau_dma_object_create(drm_device_t* dev, int class, entry[5]: set to 0? */ -static struct nouveau_object * -nouveau_context_object_create(drm_device_t* dev, int class) +struct nouveau_object * +nouveau_object_gr_create(drm_device_t* dev, int channel, int class) { drm_nouveau_private_t *dev_priv=dev->dev_private; struct nouveau_object *obj; DRM_DEBUG("class=%x\n", class); - obj = nouveau_instance_alloc(dev); + obj = nouveau_object_instance_alloc(dev, channel); if (!obj) { DRM_ERROR("couldn't allocate context object\n"); return obj; @@ -446,16 +452,13 @@ nouveau_context_object_create(drm_device_t* dev, int class) return obj; } -static void -nouveau_object_free(drm_device_t *dev, int channel, struct nouveau_object *obj) +void +nouveau_object_free(drm_device_t *dev, struct nouveau_object *obj) { - nouveau_object_unlink(dev, channel, obj); - nouveau_object_instance_free(dev, obj); - nouveau_hash_table_remove(dev, obj); - + if (obj->handle != ~0) + nouveau_hash_table_remove(dev, obj); drm_free(obj, sizeof(struct nouveau_object), DRM_MEM_DRIVER); - return; } void nouveau_object_cleanup(drm_device_t *dev, DRMFILE filp) @@ -468,8 +471,7 @@ void nouveau_object_cleanup(drm_device_t *dev, DRMFILE filp) return; while (dev_priv->fifos[channel].objs) - nouveau_object_free(dev, channel, - dev_priv->fifos[channel].objs); + nouveau_object_free(dev, dev_priv->fifos[channel].objs); } int nouveau_ioctl_object_init(DRM_IOCTL_ARGS) @@ -494,18 +496,15 @@ int nouveau_ioctl_object_init(DRM_IOCTL_ARGS) return DRM_ERR(EINVAL); } - obj = nouveau_context_object_create(dev, init.class); + obj = nouveau_object_gr_create(dev, channel, init.class); if (!obj) return DRM_ERR(ENOMEM); - obj->handle = init.handle; - if (nouveau_ht_object_insert(dev, channel, obj)) { - nouveau_object_free(dev, channel, obj); + if (nouveau_ht_object_insert(dev, channel, init.handle, obj)) { + nouveau_object_free(dev, obj); return DRM_ERR(ENOMEM); } - nouveau_object_link(dev, channel, obj); - return 0; } @@ -590,20 +589,18 @@ int nouveau_ioctl_dma_object_init(DRM_IOCTL_ARGS) return DRM_ERR(EINVAL); } - obj = nouveau_dma_object_create(dev, init.class, + obj = nouveau_object_dma_create(dev, channel, init.class, init.offset, init.size, init.access, init.target); if (!obj) return DRM_ERR(ENOMEM); obj->handle = init.handle; - if (nouveau_ht_object_insert(dev, channel, obj)) { - nouveau_object_free(dev, channel, obj); + if (nouveau_ht_object_insert(dev, channel, init.handle, obj)) { + nouveau_object_free(dev, obj); return DRM_ERR(ENOMEM); } - nouveau_object_link(dev, channel, obj); - return 0; } diff --git a/shared-core/nv40_graph.c b/shared-core/nv40_graph.c index 5e0d8d77..f2650ca1 100644 --- a/shared-core/nv40_graph.c +++ b/shared-core/nv40_graph.c @@ -894,7 +894,6 @@ nv40_graph_init(drm_device_t *dev) drm_nouveau_private_t *dev_priv = (drm_nouveau_private_t *)dev->dev_private; uint32_t *ctx_voodoo; - uint32_t pg0220_inst; int i; switch (dev_priv->chipset) { -- cgit v1.2.3 From 90f8c691a57a79a6a9652b7d2a01c59acc127b3f Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 13 Mar 2007 14:51:55 +1100 Subject: nouveau: make sure cmdbuf object gets destroyed --- shared-core/nouveau_drv.h | 2 +- shared-core/nouveau_fifo.c | 47 +++++++++++++++++++++++++++----------------- shared-core/nouveau_object.c | 10 +++------- shared-core/nouveau_state.c | 1 - 4 files changed, 33 insertions(+), 27 deletions(-) diff --git a/shared-core/nouveau_drv.h b/shared-core/nouveau_drv.h index a4b05895..c27c93ea 100644 --- a/shared-core/nouveau_drv.h +++ b/shared-core/nouveau_drv.h @@ -191,7 +191,7 @@ extern int nouveau_fifo_id_get(drm_device_t *dev, DRMFILE filp); extern void nouveau_fifo_free(drm_device_t *dev, int channel); /* nouveau_object.c */ -extern void nouveau_object_cleanup(drm_device_t *dev, DRMFILE filp); +extern void nouveau_object_cleanup(drm_device_t *dev, int channel); 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_fifo.c b/shared-core/nouveau_fifo.c index 8c4e8309..3ffb0516 100644 --- a/shared-core/nouveau_fifo.c +++ b/shared-core/nouveau_fifo.c @@ -527,15 +527,20 @@ static int nouveau_fifo_alloc(drm_device_t* dev,drm_nouveau_fifo_alloc_t* init, if (i==nouveau_fifo_number(dev)) return DRM_ERR(EINVAL); + /* that fifo is used */ + dev_priv->fifos[i].used = 1; + dev_priv->fifos[i].filp = filp; + /* FIFO has no objects yet */ + dev_priv->fifos[i].objs = NULL; + /* allocate a command buffer, and create a dma object for the gpu */ ret = nouveau_fifo_cmdbuf_alloc(dev, i); - if (ret) return ret; + if (ret) { + nouveau_fifo_free(dev, i); + return ret; + } cb_obj = dev_priv->fifos[i].cmdbuf_obj; - /* that fifo is used */ - dev_priv->fifos[i].used=1; - dev_priv->fifos[i].filp=filp; - init->channel = i; init->put_base = 0; dev_priv->cur_fifo = init->channel; @@ -638,8 +643,6 @@ static int nouveau_fifo_alloc(drm_device_t* dev,drm_nouveau_fifo_alloc_t* init, init->cmdbuf = dev_priv->fifos[init->channel].cmdbuf_mem->start; init->cmdbuf_size = dev_priv->fifos[init->channel].cmdbuf_mem->size; - /* FIFO has no objects yet */ - dev_priv->fifos[init->channel].objs = NULL; dev_priv->fifo_alloc_count++; DRM_INFO("%s: initialised FIFO %d\n", __func__, init->channel); @@ -647,43 +650,51 @@ static int nouveau_fifo_alloc(drm_device_t* dev,drm_nouveau_fifo_alloc_t* init, } /* stops a fifo */ -void nouveau_fifo_free(drm_device_t* dev,int n) +void nouveau_fifo_free(drm_device_t* dev, int channel) { drm_nouveau_private_t *dev_priv = dev->dev_private; + struct nouveau_fifo *chan = &dev_priv->fifos[channel]; int i; int ctx_size = nouveau_fifo_ctx_size(dev); - dev_priv->fifos[n].used=0; - DRM_INFO("%s: freeing fifo %d\n", __func__, n); + chan->used = 0; + DRM_INFO("%s: freeing fifo %d\n", __func__, channel); /* disable the fifo caches */ NV_WRITE(NV03_PFIFO_CACHES, 0x00000000); - NV_WRITE(NV04_PFIFO_MODE,NV_READ(NV04_PFIFO_MODE)&~(1<ramfc_offset + n*ctx_size + i)); - NV_WRITE(NV_RAMIN + dev_priv->ramfc_offset + n*ctx_size + i, 0); + dev_priv->ramfc_offset + + channel*ctx_size + i)); + NV_WRITE(NV_RAMIN + dev_priv->ramfc_offset + + channel*ctx_size + i, 0); } + /* Cleanup PGRAPH state */ if (dev_priv->card_type >= NV_40) - nouveau_instmem_free(dev, dev_priv->fifos[n].ramin_grctx); + nouveau_instmem_free(dev, chan->ramin_grctx); else if (dev_priv->card_type >= NV_30) { } else if (dev_priv->card_type >= NV_20) { /* clear ctx table */ - INSTANCE_WR(dev_priv->ctx_table, n, 0); - nouveau_instmem_free(dev, dev_priv->fifos[n].ramin_grctx); + INSTANCE_WR(dev_priv->ctx_table, channel, 0); + nouveau_instmem_free(dev, chan->ramin_grctx); } /* reenable the fifo caches */ NV_WRITE(NV03_PFIFO_CACHES, 0x00000001); - /* Deallocate command buffer, and dma object */ - nouveau_mem_free(dev, dev_priv->fifos[n].cmdbuf_mem); + /* Deallocate command buffer */ + if (chan->cmdbuf_mem) + nouveau_mem_free(dev, chan->cmdbuf_mem); + + /* Destroy objects belonging to the channel */ + nouveau_object_cleanup(dev, channel); dev_priv->fifo_alloc_count--; } diff --git a/shared-core/nouveau_object.c b/shared-core/nouveau_object.c index c5cf8496..83f039db 100644 --- a/shared-core/nouveau_object.c +++ b/shared-core/nouveau_object.c @@ -461,17 +461,13 @@ nouveau_object_free(drm_device_t *dev, struct nouveau_object *obj) drm_free(obj, sizeof(struct nouveau_object), DRM_MEM_DRIVER); } -void nouveau_object_cleanup(drm_device_t *dev, DRMFILE filp) +void nouveau_object_cleanup(drm_device_t *dev, int channel) { drm_nouveau_private_t *dev_priv=dev->dev_private; - int channel; - - channel = nouveau_fifo_id_get(dev, filp); - if (channel == -1) - return; - while (dev_priv->fifos[channel].objs) + while (dev_priv->fifos[channel].objs) { nouveau_object_free(dev, dev_priv->fifos[channel].objs); + } } int nouveau_ioctl_object_init(DRM_IOCTL_ARGS) diff --git a/shared-core/nouveau_state.c b/shared-core/nouveau_state.c index e1fc6330..ed45c166 100644 --- a/shared-core/nouveau_state.c +++ b/shared-core/nouveau_state.c @@ -34,7 +34,6 @@ void nouveau_preclose(drm_device_t * dev, DRMFILE filp) nouveau_mem_release(filp,dev_priv->fb_heap); nouveau_mem_release(filp,dev_priv->agp_heap); - nouveau_object_cleanup(dev, filp); nouveau_fifo_cleanup(dev, filp); } -- cgit v1.2.3 From a90c2854a7a71953e03d36b1ff7db3e9c2babb99 Mon Sep 17 00:00:00 2001 From: Oliver McFadden Date: Tue, 13 Mar 2007 06:25:04 +0000 Subject: Add defines for the values written to R300_RB3D_ZCACHE_CTLSTAT. Note that just like the values written to R300_RB3D_DSTCACHE_CTLSTAT these values are really unknown; ideally more reverse engineering should be done to determine what these values mean and when they should be set. --- shared-core/r300_cmdbuf.c | 2 +- shared-core/r300_reg.h | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/shared-core/r300_cmdbuf.c b/shared-core/r300_cmdbuf.c index e62cbda5..815b9f86 100644 --- a/shared-core/r300_cmdbuf.c +++ b/shared-core/r300_cmdbuf.c @@ -694,7 +694,7 @@ static __inline__ void r300_pacify(drm_radeon_private_t *dev_priv) OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0)); OUT_RING(R300_RB3D_DSTCACHE_0A); OUT_RING(CP_PACKET0(R300_RB3D_ZCACHE_CTLSTAT, 0)); - OUT_RING(0x3); + OUT_RING(R300_RB3D_ZCACHE_CTLSTAT_03); OUT_RING(CP_PACKET3(RADEON_CP_NOP, 0)); OUT_RING(0x0); ADVANCE_RING(); diff --git a/shared-core/r300_reg.h b/shared-core/r300_reg.h index 667fe05a..5115b086 100644 --- a/shared-core/r300_reg.h +++ b/shared-core/r300_reg.h @@ -1395,6 +1395,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* gap */ #define R300_RB3D_ZCACHE_CTLSTAT 0x4F18 /* GUESS */ +# define R300_RB3D_ZCACHE_CTLSTAT_01 0x1 +# define R300_RB3D_ZCACHE_CTLSTAT_03 0x3 /* gap */ -- cgit v1.2.3