Merge git://proxy01.pd.intel.com:9419/git/mesa/drm into crestline
commit
80d0018bc0
|
@ -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);
|
||||||
|
|
|
@ -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--;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
Loading…
Reference in New Issue