Merge git://proxy01.pd.intel.com:9419/git/mesa/drm into crestline

main
Nian Wu 2007-03-13 17:00:31 +08:00
commit 80d0018bc0
7 changed files with 123 additions and 105 deletions

View File

@ -61,6 +61,7 @@ struct nouveau_object
{ {
struct nouveau_object *next; struct nouveau_object *next;
struct nouveau_object *prev; struct nouveau_object *prev;
int channel;
struct mem_block *instance; struct mem_block *instance;
uint32_t ht_loc; uint32_t ht_loc;
@ -190,11 +191,14 @@ extern int nouveau_fifo_id_get(drm_device_t *dev, DRMFILE filp);
extern void nouveau_fifo_free(drm_device_t *dev, int channel); extern void nouveau_fifo_free(drm_device_t *dev, int channel);
/* nouveau_object.c */ /* 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 * 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, uint32_t offset, uint32_t size,
int access, int target); 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_object_init(DRM_IOCTL_ARGS);
extern int nouveau_ioctl_dma_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); extern uint32_t nouveau_chip_instance_get(drm_device_t *dev, struct mem_block *mem);

View File

@ -239,12 +239,14 @@ nouveau_fifo_cmdbuf_alloc(struct drm_device *dev, int channel)
} }
if (cb->flags & NOUVEAU_MEM_AGP) { 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->start - dev_priv->agp_phys,
cb->size, cb->size,
NV_DMA_ACCESS_RO, NV_DMA_TARGET_AGP); NV_DMA_ACCESS_RO, NV_DMA_TARGET_AGP);
} else if (dev_priv->card_type != NV_04) { } 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->start - drm_get_resource_start(dev, 1),
cb->size, cb->size,
NV_DMA_ACCESS_RO, NV_DMA_TARGET_VIDMEM); 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 * exact reason for existing :) PCI access to cmdbuf in
* VRAM. * 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, cb->start, cb->size,
NV_DMA_ACCESS_RO, NV_DMA_TARGET_PCI); NV_DMA_ACCESS_RO, NV_DMA_TARGET_PCI);
} }
@ -524,15 +527,20 @@ static int nouveau_fifo_alloc(drm_device_t* dev,drm_nouveau_fifo_alloc_t* init,
if (i==nouveau_fifo_number(dev)) if (i==nouveau_fifo_number(dev))
return DRM_ERR(EINVAL); 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 */ /* allocate a command buffer, and create a dma object for the gpu */
ret = nouveau_fifo_cmdbuf_alloc(dev, i); 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; 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->channel = i;
init->put_base = 0; init->put_base = 0;
dev_priv->cur_fifo = init->channel; dev_priv->cur_fifo = init->channel;
@ -635,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 = dev_priv->fifos[init->channel].cmdbuf_mem->start;
init->cmdbuf_size = dev_priv->fifos[init->channel].cmdbuf_mem->size; 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++; dev_priv->fifo_alloc_count++;
DRM_INFO("%s: initialised FIFO %d\n", __func__, init->channel); DRM_INFO("%s: initialised FIFO %d\n", __func__, init->channel);
@ -644,43 +650,51 @@ static int nouveau_fifo_alloc(drm_device_t* dev,drm_nouveau_fifo_alloc_t* init,
} }
/* stops a fifo */ /* 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; drm_nouveau_private_t *dev_priv = dev->dev_private;
struct nouveau_fifo *chan = &dev_priv->fifos[channel];
int i; int i;
int ctx_size = nouveau_fifo_ctx_size(dev); int ctx_size = nouveau_fifo_ctx_size(dev);
dev_priv->fifos[n].used=0; chan->used = 0;
DRM_INFO("%s: freeing fifo %d\n", __func__, n); DRM_INFO("%s: freeing fifo %d\n", __func__, channel);
/* disable the fifo caches */ /* disable the fifo caches */
NV_WRITE(NV03_PFIFO_CACHES, 0x00000000); NV_WRITE(NV03_PFIFO_CACHES, 0x00000000);
NV_WRITE(NV04_PFIFO_MODE,NV_READ(NV04_PFIFO_MODE)&~(1<<n)); NV_WRITE(NV04_PFIFO_MODE, NV_READ(NV04_PFIFO_MODE)&~(1<<channel));
// FIXME XXX needs more code // FIXME XXX needs more code
/* Clean RAMFC */ /* Clean RAMFC */
for (i=0;i<ctx_size;i+=4) { for (i=0;i<ctx_size;i+=4) {
DRM_DEBUG("RAMFC +%02x: 0x%08x\n", i, NV_READ(NV_RAMIN + DRM_DEBUG("RAMFC +%02x: 0x%08x\n", i, NV_READ(NV_RAMIN +
dev_priv->ramfc_offset + n*ctx_size + i)); dev_priv->ramfc_offset +
NV_WRITE(NV_RAMIN + dev_priv->ramfc_offset + n*ctx_size + i, 0); 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) 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_30) {
} }
else if (dev_priv->card_type >= NV_20) { else if (dev_priv->card_type >= NV_20) {
/* clear ctx table */ /* clear ctx table */
INSTANCE_WR(dev_priv->ctx_table, n, 0); INSTANCE_WR(dev_priv->ctx_table, channel, 0);
nouveau_instmem_free(dev, dev_priv->fifos[n].ramin_grctx); nouveau_instmem_free(dev, chan->ramin_grctx);
} }
/* reenable the fifo caches */ /* reenable the fifo caches */
NV_WRITE(NV03_PFIFO_CACHES, 0x00000001); NV_WRITE(NV03_PFIFO_CACHES, 0x00000001);
/* Deallocate command buffer, and dma object */ /* Deallocate command buffer */
nouveau_mem_free(dev, dev_priv->fifos[n].cmdbuf_mem); 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--; dev_priv->fifo_alloc_count--;
} }

View File

@ -44,8 +44,8 @@
* in the future when we can access more instance ram which isn't mapped into * in the future when we can access more instance ram which isn't mapped into
* the PRAMIN aperture * the PRAMIN aperture
*/ */
uint32_t nouveau_chip_instance_get(drm_device_t *dev, uint32_t
struct mem_block *mem) nouveau_chip_instance_get(drm_device_t *dev, struct mem_block *mem)
{ {
uint32_t inst = (uint32_t)mem->start >> 4; uint32_t inst = (uint32_t)mem->start >> 4;
DRM_DEBUG("****** on-chip instance for 0x%016llx = 0x%08x\n", DRM_DEBUG("****** on-chip instance for 0x%016llx = 0x%08x\n",
@ -53,34 +53,34 @@ uint32_t nouveau_chip_instance_get(drm_device_t *dev,
return inst; return inst;
} }
static void nouveau_object_link(drm_device_t *dev, int fifo_num, static void
struct nouveau_object *obj) nouveau_object_link(drm_device_t *dev, struct nouveau_object *obj)
{ {
drm_nouveau_private_t *dev_priv=dev->dev_private; 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[obj->channel];
if (!fifo->objs) { if (!chan->objs) {
fifo->objs = obj; chan->objs = obj;
return; return;
} }
obj->prev = NULL; obj->prev = NULL;
obj->next = fifo->objs; obj->next = chan->objs;
fifo->objs->prev = obj; chan->objs->prev = obj;
fifo->objs = obj; chan->objs = obj;
} }
static void nouveau_object_unlink(drm_device_t *dev, int fifo_num, static void
struct nouveau_object *obj) nouveau_object_unlink(drm_device_t *dev, struct nouveau_object *obj)
{ {
drm_nouveau_private_t *dev_priv=dev->dev_private; 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[obj->channel];
if (obj->prev == NULL) { if (obj->prev == NULL) {
if (obj->next) if (obj->next)
obj->next->prev = NULL; obj->next->prev = NULL;
fifo->objs = obj->next; chan->objs = obj->next;
} else if (obj->next == NULL) { } else if (obj->next == NULL) {
if (obj->prev) if (obj->prev)
obj->prev->next = NULL; obj->prev->next = NULL;
@ -91,11 +91,11 @@ static void nouveau_object_unlink(drm_device_t *dev, int fifo_num,
} }
static struct nouveau_object * 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; 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];
struct nouveau_object *obj = fifo->objs; struct nouveau_object *obj = chan->objs;
DRM_DEBUG("Looking for handle 0x%08x\n", handle); DRM_DEBUG("Looking for handle 0x%08x\n", handle);
while (obj) { while (obj) {
@ -138,8 +138,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 The key into the hash table depends on the object handle and channel id and
is given as: is given as:
*/ */
static uint32_t nouveau_handle_hash(drm_device_t* dev, uint32_t handle, static uint32_t
int fifo) nouveau_ht_handle_hash(drm_device_t *dev, int channel, uint32_t handle)
{ {
drm_nouveau_private_t *dev_priv=dev->dev_private; drm_nouveau_private_t *dev_priv=dev->dev_private;
uint32_t hash = 0; uint32_t hash = 0;
@ -149,19 +149,21 @@ static uint32_t nouveau_handle_hash(drm_device_t* dev, uint32_t handle,
hash ^= (handle & ((1 << dev_priv->ramht_bits) - 1)); hash ^= (handle & ((1 << dev_priv->ramht_bits) - 1));
handle >>= dev_priv->ramht_bits; handle >>= dev_priv->ramht_bits;
} }
hash ^= fifo << (dev_priv->ramht_bits - 4); hash ^= channel << (dev_priv->ramht_bits - 4);
return hash << 3; return hash << 3;
} }
static int nouveau_hash_table_insert(drm_device_t* dev, int fifo, static int
struct nouveau_object *obj) 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; drm_nouveau_private_t *dev_priv=dev->dev_private;
int ht_base = NV_RAMIN + dev_priv->ramht_offset; int ht_base = NV_RAMIN + dev_priv->ramht_offset;
int ht_end = ht_base + dev_priv->ramht_size; int ht_end = ht_base + dev_priv->ramht_size;
int o_ofs, ofs; int o_ofs, ofs;
o_ofs = ofs = nouveau_handle_hash(dev, obj->handle, fifo); 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)) { while (NV_READ(ht_base + ofs) || NV_READ(ht_base + ofs + 4)) {
ofs += 8; ofs += 8;
@ -174,19 +176,19 @@ static int nouveau_hash_table_insert(drm_device_t* dev, int fifo,
ofs += ht_base; ofs += ht_base;
DRM_DEBUG("Channel %d - Handle 0x%08x at 0x%08x\n", 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); NV_WRITE(NV_RAMHT_HANDLE_OFFSET + ofs, obj->handle);
if (dev_priv->card_type >= NV_40) if (dev_priv->card_type >= NV_40)
NV_WRITE(NV_RAMHT_CONTEXT_OFFSET + ofs, 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) | (obj->engine << NV40_RAMHT_CONTEXT_ENGINE_SHIFT) |
nouveau_chip_instance_get(dev, obj->instance) nouveau_chip_instance_get(dev, obj->instance)
); );
else else
NV_WRITE(NV_RAMHT_CONTEXT_OFFSET + ofs, NV_WRITE(NV_RAMHT_CONTEXT_OFFSET + ofs,
NV_RAMHT_CONTEXT_VALID | NV_RAMHT_CONTEXT_VALID |
(fifo << NV_RAMHT_CONTEXT_CHANNEL_SHIFT) | (channel << NV_RAMHT_CONTEXT_CHANNEL_SHIFT) |
(obj->engine << NV_RAMHT_CONTEXT_ENGINE_SHIFT) | (obj->engine << NV_RAMHT_CONTEXT_ENGINE_SHIFT) |
nouveau_chip_instance_get(dev, obj->instance) nouveau_chip_instance_get(dev, obj->instance)
); );
@ -210,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; drm_nouveau_private_t *dev_priv=dev->dev_private;
struct nouveau_object *obj; struct nouveau_object *obj;
@ -221,6 +224,8 @@ static struct nouveau_object *nouveau_instance_alloc(drm_device_t* dev)
DRM_ERROR("couldn't alloc memory for object\n"); DRM_ERROR("couldn't alloc memory for object\n");
return NULL; return NULL;
} }
/* Allocate instance memory */
obj->instance = nouveau_instmem_alloc(dev, obj->instance = nouveau_instmem_alloc(dev,
(dev_priv->card_type >= NV_40 ? 32 : 16), 4); (dev_priv->card_type >= NV_40 ? 32 : 16), 4);
if (!obj->instance) { if (!obj->instance) {
@ -229,25 +234,28 @@ static struct nouveau_object *nouveau_instance_alloc(drm_device_t* dev)
return NULL; return NULL;
} }
/* Bind object to channel */
obj->channel = channel;
obj->handle = ~0;
nouveau_object_link(dev, obj);
return obj; return obj;
} }
static void nouveau_object_instance_free(drm_device_t *dev, static void
struct nouveau_object *obj) nouveau_object_instance_free(drm_device_t *dev, struct nouveau_object *obj)
{ {
drm_nouveau_private_t *dev_priv=dev->dev_private; drm_nouveau_private_t *dev_priv=dev->dev_private;
int count, i; int i;
if (dev_priv->card_type >= NV_40) /* Unbind object from channel */
count = 8; nouveau_object_unlink(dev, obj);
else
count = 4;
/* Clean RAMIN entry */ /* Clean RAMIN entry */
DRM_DEBUG("Instance entry for 0x%08x" DRM_DEBUG("Instance entry for 0x%08x"
"(engine %d, class 0x%x) before destroy:\n", "(engine %d, class 0x%x) before destroy:\n",
obj->handle, obj->engine, obj->class); obj->handle, obj->engine, obj->class);
for (i=0;i<count;i++) { for (i=0; i<(obj->instance->size/4); i++) {
DRM_DEBUG(" +0x%02x: 0x%08x\n", (i*4), DRM_DEBUG(" +0x%02x: 0x%08x\n", (i*4),
INSTANCE_RD(obj->instance, i)); INSTANCE_RD(obj->instance, i));
INSTANCE_WR(obj->instance, i, 0x00000000); INSTANCE_WR(obj->instance, i, 0x00000000);
@ -283,7 +291,7 @@ static void nouveau_object_instance_free(drm_device_t *dev,
*/ */
struct nouveau_object * 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, uint32_t offset, uint32_t size,
int access, int target) int access, int target)
{ {
@ -318,7 +326,7 @@ nouveau_dma_object_create(drm_device_t* dev, int class,
frame = offset & ~0x00000FFF; frame = offset & ~0x00000FFF;
adjust = offset & 0x00000FFF; adjust = offset & 0x00000FFF;
obj = nouveau_instance_alloc(dev); obj = nouveau_object_instance_alloc(dev, channel);
if (!obj) { if (!obj) {
DRM_ERROR("couldn't allocate DMA object\n"); DRM_ERROR("couldn't allocate DMA object\n");
return obj; return obj;
@ -391,15 +399,15 @@ nouveau_dma_object_create(drm_device_t* dev, int class,
entry[5]: entry[5]:
set to 0? set to 0?
*/ */
static struct nouveau_object * struct nouveau_object *
nouveau_context_object_create(drm_device_t* dev, int class) nouveau_object_gr_create(drm_device_t* dev, int channel, int class)
{ {
drm_nouveau_private_t *dev_priv=dev->dev_private; drm_nouveau_private_t *dev_priv=dev->dev_private;
struct nouveau_object *obj; struct nouveau_object *obj;
DRM_DEBUG("class=%x\n", class); DRM_DEBUG("class=%x\n", class);
obj = nouveau_instance_alloc(dev); obj = nouveau_object_instance_alloc(dev, channel);
if (!obj) { if (!obj) {
DRM_ERROR("couldn't allocate context object\n"); DRM_ERROR("couldn't allocate context object\n");
return obj; return obj;
@ -444,29 +452,22 @@ nouveau_context_object_create(drm_device_t* dev, int class)
return obj; return obj;
} }
static void void
nouveau_object_free(drm_device_t *dev, int fifo_num, struct nouveau_object *obj) nouveau_object_free(drm_device_t *dev, struct nouveau_object *obj)
{ {
nouveau_object_unlink(dev, fifo_num, obj);
nouveau_object_instance_free(dev, 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); drm_free(obj, sizeof(struct nouveau_object), DRM_MEM_DRIVER);
return;
} }
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; drm_nouveau_private_t *dev_priv=dev->dev_private;
int fifo;
fifo = nouveau_fifo_id_get(dev, filp); while (dev_priv->fifos[channel].objs) {
if (fifo == -1) nouveau_object_free(dev, dev_priv->fifos[channel].objs);
return; }
while (dev_priv->fifos[fifo].objs)
nouveau_object_free(dev, fifo, dev_priv->fifos[fifo].objs);
} }
int nouveau_ioctl_object_init(DRM_IOCTL_ARGS) int nouveau_ioctl_object_init(DRM_IOCTL_ARGS)
@ -474,10 +475,10 @@ int nouveau_ioctl_object_init(DRM_IOCTL_ARGS)
DRM_DEVICE; DRM_DEVICE;
drm_nouveau_object_init_t init; drm_nouveau_object_init_t init;
struct nouveau_object *obj; struct nouveau_object *obj;
int fifo; int channel;
fifo = nouveau_fifo_id_get(dev, filp); channel = nouveau_fifo_id_get(dev, filp);
if (fifo == -1) if (channel == -1)
return DRM_ERR(EINVAL); return DRM_ERR(EINVAL);
DRM_COPY_FROM_USER_IOCTL(init, (drm_nouveau_object_init_t __user *) DRM_COPY_FROM_USER_IOCTL(init, (drm_nouveau_object_init_t __user *)
@ -485,24 +486,21 @@ int nouveau_ioctl_object_init(DRM_IOCTL_ARGS)
//FIXME: check args, only allow trusted objects to be created //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", DRM_ERROR("Channel %d: handle 0x%08x already exists\n",
fifo, init.handle); channel, init.handle);
return DRM_ERR(EINVAL); return DRM_ERR(EINVAL);
} }
obj = nouveau_context_object_create(dev, init.class); obj = nouveau_object_gr_create(dev, channel, init.class);
if (!obj) if (!obj)
return DRM_ERR(ENOMEM); return DRM_ERR(ENOMEM);
obj->handle = init.handle; if (nouveau_ht_object_insert(dev, channel, init.handle, obj)) {
if (nouveau_hash_table_insert(dev, fifo, obj)) { nouveau_object_free(dev, obj);
nouveau_object_free(dev, fifo, obj);
return DRM_ERR(ENOMEM); return DRM_ERR(ENOMEM);
} }
nouveau_object_link(dev, fifo, obj);
return 0; return 0;
} }
@ -569,10 +567,10 @@ int nouveau_ioctl_dma_object_init(DRM_IOCTL_ARGS)
DRM_DEVICE; DRM_DEVICE;
drm_nouveau_dma_object_init_t init; drm_nouveau_dma_object_init_t init;
struct nouveau_object *obj; struct nouveau_object *obj;
int fifo; int channel;
fifo = nouveau_fifo_id_get(dev, filp); channel = nouveau_fifo_id_get(dev, filp);
if (fifo == -1) if (channel == -1)
return DRM_ERR(EINVAL); return DRM_ERR(EINVAL);
DRM_COPY_FROM_USER_IOCTL(init, (drm_nouveau_dma_object_init_t __user *) DRM_COPY_FROM_USER_IOCTL(init, (drm_nouveau_dma_object_init_t __user *)
@ -581,26 +579,24 @@ int nouveau_ioctl_dma_object_init(DRM_IOCTL_ARGS)
if (nouveau_dma_object_check_access(dev, &init)) if (nouveau_dma_object_check_access(dev, &init))
return DRM_ERR(EPERM); 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", DRM_ERROR("Channel %d: handle 0x%08x already exists\n",
fifo, init.handle); channel, init.handle);
return DRM_ERR(EINVAL); 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.offset, init.size,
init.access, init.target); init.access, init.target);
if (!obj) if (!obj)
return DRM_ERR(ENOMEM); return DRM_ERR(ENOMEM);
obj->handle = init.handle; obj->handle = init.handle;
if (nouveau_hash_table_insert(dev, fifo, obj)) { if (nouveau_ht_object_insert(dev, channel, init.handle, obj)) {
nouveau_object_free(dev, fifo, obj); nouveau_object_free(dev, obj);
return DRM_ERR(ENOMEM); return DRM_ERR(ENOMEM);
} }
nouveau_object_link(dev, fifo, obj);
return 0; return 0;
} }

View File

@ -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->fb_heap);
nouveau_mem_release(filp,dev_priv->agp_heap); nouveau_mem_release(filp,dev_priv->agp_heap);
nouveau_object_cleanup(dev, filp);
nouveau_fifo_cleanup(dev, filp); nouveau_fifo_cleanup(dev, filp);
} }

View File

@ -894,7 +894,6 @@ nv40_graph_init(drm_device_t *dev)
drm_nouveau_private_t *dev_priv = drm_nouveau_private_t *dev_priv =
(drm_nouveau_private_t *)dev->dev_private; (drm_nouveau_private_t *)dev->dev_private;
uint32_t *ctx_voodoo; uint32_t *ctx_voodoo;
uint32_t pg0220_inst;
int i; int i;
switch (dev_priv->chipset) { switch (dev_priv->chipset) {

View File

@ -224,7 +224,7 @@ void r300_init_reg_flags(void)
ADD_RANGE(R300_TX_BORDER_COLOR_0, 16); ADD_RANGE(R300_TX_BORDER_COLOR_0, 16);
/* Sporadic registers used as primitives are emitted */ /* 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_RB3D_DSTCACHE_CTLSTAT, 1);
ADD_RANGE(R300_VAP_INPUT_ROUTE_0_0, 8); ADD_RANGE(R300_VAP_INPUT_ROUTE_0_0, 8);
ADD_RANGE(R300_VAP_INPUT_ROUTE_1_0, 8); ADD_RANGE(R300_VAP_INPUT_ROUTE_1_0, 8);
@ -692,9 +692,9 @@ static __inline__ void r300_pacify(drm_radeon_private_t *dev_priv)
BEGIN_RING(6); BEGIN_RING(6);
OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0)); OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0));
OUT_RING(0xa); OUT_RING(R300_RB3D_DSTCACHE_0A);
OUT_RING(CP_PACKET0(0x4f18, 0)); 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(CP_PACKET3(RADEON_CP_NOP, 0));
OUT_RING(0x0); OUT_RING(0x0);
ADVANCE_RING(); ADVANCE_RING();

View File

@ -1394,6 +1394,12 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
/* gap */ /* gap */
#define R300_RB3D_ZCACHE_CTLSTAT 0x4F18 /* GUESS */
# define R300_RB3D_ZCACHE_CTLSTAT_01 0x1
# define R300_RB3D_ZCACHE_CTLSTAT_03 0x3
/* gap */
#define R300_RB3D_DEPTHOFFSET 0x4F20 #define R300_RB3D_DEPTHOFFSET 0x4F20
#define R300_RB3D_DEPTHPITCH 0x4F24 #define R300_RB3D_DEPTHPITCH 0x4F24
# define R300_DEPTHPITCH_MASK 0x00001FF8 /* GUESS */ # define R300_DEPTHPITCH_MASK 0x00001FF8 /* GUESS */