nouveau: rewrite gpu object code
Allows multiple references to a single object, needed to support PCI(E)GART scatter-gather DMA objects which would quickly fill PRAMIN if each channel had its own. Handle per-channel private instmem areas. This is needed to support NV50, but might be something we want to do on earlier chipsets at some point? Everything that touches PRAMIN is a GPU object.main
parent
d57b7f02d2
commit
163f852612
|
@ -57,18 +57,38 @@ enum nouveau_flags {
|
|||
NV_NFORCE2 =0x20000000
|
||||
};
|
||||
|
||||
struct nouveau_object
|
||||
{
|
||||
struct nouveau_object *next;
|
||||
struct nouveau_object *prev;
|
||||
#define NVOBJ_ENGINE_SW 0
|
||||
#define NVOBJ_ENGINE_GR 1
|
||||
#define NVOBJ_ENGINE_INT 0xdeadbeef
|
||||
|
||||
#define NVOBJ_FLAG_ALLOW_NO_REFS (1 << 0)
|
||||
#define NVOBJ_FLAG_ZERO_ALLOC (1 << 1)
|
||||
#define NVOBJ_FLAG_ZERO_FREE (1 << 2)
|
||||
#define NVOBJ_FLAG_FAKE (1 << 3)
|
||||
typedef struct nouveau_gpuobj {
|
||||
struct nouveau_gpuobj *next;
|
||||
struct nouveau_gpuobj *prev;
|
||||
|
||||
int im_channel;
|
||||
struct mem_block *im_pramin;
|
||||
struct mem_block *im_backing;
|
||||
|
||||
uint32_t flags;
|
||||
int refcount;
|
||||
|
||||
uint32_t engine;
|
||||
uint32_t class;
|
||||
} nouveau_gpuobj_t;
|
||||
|
||||
typedef struct nouveau_gpuobj_ref {
|
||||
struct nouveau_gpuobj_ref *next;
|
||||
|
||||
nouveau_gpuobj_t *gpuobj;
|
||||
uint32_t instance;
|
||||
|
||||
int channel;
|
||||
|
||||
struct mem_block *instance;
|
||||
|
||||
uint32_t handle;
|
||||
int class;
|
||||
int engine;
|
||||
};
|
||||
int handle;
|
||||
} nouveau_gpuobj_ref_t;
|
||||
|
||||
struct nouveau_fifo
|
||||
{
|
||||
|
@ -79,21 +99,29 @@ struct nouveau_fifo
|
|||
drm_local_map_t *map;
|
||||
/* mapping of the regs controling the fifo */
|
||||
drm_local_map_t *regs;
|
||||
/* dma object for the command buffer itself */
|
||||
struct mem_block *cmdbuf_mem;
|
||||
struct nouveau_object *cmdbuf_obj;
|
||||
uint32_t pushbuf_base;
|
||||
/* notifier memory */
|
||||
|
||||
/* DMA push buffer */
|
||||
struct mem_block *cmdbuf_mem;
|
||||
nouveau_gpuobj_ref_t *pushbuf;
|
||||
uint32_t pushbuf_base;
|
||||
|
||||
/* Notifier memory */
|
||||
struct mem_block *notifier_block;
|
||||
struct mem_block *notifier_heap;
|
||||
drm_local_map_t *notifier_map;
|
||||
/* PGRAPH context, for cards that keep it in RAMIN */
|
||||
struct mem_block *ramin_grctx;
|
||||
/* objects belonging to this fifo */
|
||||
struct nouveau_object *objs;
|
||||
|
||||
/* XXX dynamic alloc ? */
|
||||
uint32_t pgraph_ctx [340];
|
||||
/* PFIFO context */
|
||||
nouveau_gpuobj_ref_t *ramfc;
|
||||
|
||||
/* PGRAPH context */
|
||||
nouveau_gpuobj_ref_t *ramin_grctx;
|
||||
uint32_t pgraph_ctx [340]; /* XXX dynamic alloc ? */
|
||||
|
||||
/* Objects */
|
||||
nouveau_gpuobj_ref_t *ramin; /* Private instmem */
|
||||
struct mem_block *ramin_heap; /* Private PRAMIN heap */
|
||||
nouveau_gpuobj_ref_t *ramht; /* Hash table */
|
||||
nouveau_gpuobj_ref_t *ramht_refs; /* Objects referenced by RAMHT */
|
||||
};
|
||||
|
||||
struct nouveau_config {
|
||||
|
@ -157,6 +185,7 @@ typedef struct drm_nouveau_private {
|
|||
struct nouveau_engine_func Engine;
|
||||
|
||||
/* RAMIN configuration, RAMFC, RAMHT and RAMRO offsets */
|
||||
nouveau_gpuobj_t *ramht;
|
||||
uint32_t ramin_size;
|
||||
uint32_t ramht_offset;
|
||||
uint32_t ramht_size;
|
||||
|
@ -182,9 +211,11 @@ typedef struct drm_nouveau_private {
|
|||
|
||||
/* context table pointed to be NV_PGRAPH_CHANNEL_CTX_TABLE (0x400780) */
|
||||
uint32_t ctx_table_size;
|
||||
struct mem_block *ctx_table;
|
||||
nouveau_gpuobj_ref_t *ctx_table;
|
||||
|
||||
struct nouveau_config config;
|
||||
|
||||
nouveau_gpuobj_t *gpuobj_all;
|
||||
}
|
||||
drm_nouveau_private_t;
|
||||
|
||||
|
@ -205,6 +236,7 @@ extern int nouveau_mem_init_heap(struct mem_block **,
|
|||
extern struct mem_block *nouveau_mem_alloc_block(struct mem_block *,
|
||||
uint64_t size, int align2,
|
||||
DRMFILE);
|
||||
extern void nouveau_mem_takedown(struct mem_block **heap);
|
||||
extern void nouveau_mem_free_block(struct mem_block *);
|
||||
extern uint64_t nouveau_mem_fb_amount(struct drm_device *dev);
|
||||
extern void nouveau_mem_release(DRMFILE filp, struct mem_block *heap);
|
||||
|
@ -236,22 +268,28 @@ extern int nouveau_fifo_owner(drm_device_t *dev, DRMFILE filp, int channel);
|
|||
extern void nouveau_fifo_free(drm_device_t *dev, int channel);
|
||||
|
||||
/* nouveau_object.c */
|
||||
extern int nouveau_object_init_channel(drm_device_t *, int channel,
|
||||
uint32_t vram_handle,
|
||||
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_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 *
|
||||
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_grobj_alloc(DRM_IOCTL_ARGS);
|
||||
extern uint32_t nouveau_chip_instance_get(drm_device_t *dev, struct mem_block *mem);
|
||||
extern void nouveau_gpuobj_takedown(drm_device_t *dev);
|
||||
extern int nouveau_gpuobj_channel_init(drm_device_t *, int channel,
|
||||
uint32_t vram_h, uint32_t tt_h);
|
||||
extern void nouveau_gpuobj_channel_takedown(drm_device_t *, int channel);
|
||||
extern int nouveau_gpuobj_new(drm_device_t *, int channel, int size, int align,
|
||||
uint32_t flags, nouveau_gpuobj_t **);
|
||||
extern int nouveau_gpuobj_del(drm_device_t *, nouveau_gpuobj_t **);
|
||||
extern int nouveau_gpuobj_ref_add(drm_device_t *, int channel, uint32_t handle,
|
||||
nouveau_gpuobj_t *, nouveau_gpuobj_ref_t **);
|
||||
extern int nouveau_gpuobj_ref_del(drm_device_t *, nouveau_gpuobj_ref_t **);
|
||||
extern int nouveau_gpuobj_new_ref(drm_device_t *, int chan_obj, int chan_ref,
|
||||
uint32_t handle, int size, int align,
|
||||
uint32_t flags, nouveau_gpuobj_ref_t **);
|
||||
extern int nouveau_gpuobj_new_fake(drm_device_t *, uint32_t offset,
|
||||
uint32_t size, uint32_t flags,
|
||||
nouveau_gpuobj_t**, nouveau_gpuobj_ref_t**);
|
||||
extern int nouveau_gpuobj_dma_new(drm_device_t *, int channel, int class,
|
||||
uint64_t offset, uint64_t size,
|
||||
int access, int target, nouveau_gpuobj_t **);
|
||||
extern int nouveau_gpuobj_gr_new(drm_device_t *, int channel, int class,
|
||||
nouveau_gpuobj_t **);
|
||||
extern int nouveau_ioctl_grobj_alloc(DRM_IOCTL_ARGS);
|
||||
|
||||
/* nouveau_irq.c */
|
||||
extern irqreturn_t nouveau_irq_handler(DRM_IRQ_ARGS);
|
||||
|
@ -384,8 +422,8 @@ extern long nouveau_compat_ioctl(struct file *filp, unsigned int cmd,
|
|||
#define NV_WI32(o,v) DRM_WRITE32(dev_priv->ramin, (o), (v))
|
||||
#endif
|
||||
|
||||
#define INSTANCE_RD(o,i) NV_RI32((o)->start + ((i)<<2))
|
||||
#define INSTANCE_WR(o,i,v) NV_WI32((o)->start + ((i)<<2), (v))
|
||||
#define INSTANCE_RD(o,i) NV_RI32((o)->im_pramin->start + ((i)<<2))
|
||||
#define INSTANCE_WR(o,i,v) NV_WI32((o)->im_pramin->start + ((i)<<2), (v))
|
||||
|
||||
#endif /* __NOUVEAU_DRV_H__ */
|
||||
|
||||
|
|
|
@ -186,10 +186,12 @@ static int
|
|||
nouveau_fifo_cmdbuf_alloc(struct drm_device *dev, int channel)
|
||||
{
|
||||
drm_nouveau_private_t *dev_priv = dev->dev_private;
|
||||
struct nouveau_fifo *chan = &dev_priv->fifos[channel];
|
||||
struct nouveau_config *config = &dev_priv->config;
|
||||
struct mem_block *cb;
|
||||
struct nouveau_object *cb_dma = NULL;
|
||||
int cb_min_size = max(NV03_FIFO_SIZE,PAGE_SIZE);
|
||||
nouveau_gpuobj_t *pushbuf = NULL;
|
||||
int ret;
|
||||
|
||||
/* Defaults for unconfigured values */
|
||||
if (!config->cmdbuf.location)
|
||||
|
@ -206,37 +208,42 @@ nouveau_fifo_cmdbuf_alloc(struct drm_device *dev, int channel)
|
|||
}
|
||||
|
||||
if (cb->flags & NOUVEAU_MEM_AGP) {
|
||||
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);
|
||||
ret = nouveau_gpuobj_dma_new
|
||||
(dev, channel, NV_CLASS_DMA_IN_MEMORY,
|
||||
cb->start - dev_priv->agp_phys,
|
||||
cb->size, NV_DMA_ACCESS_RO, NV_DMA_TARGET_AGP,
|
||||
&pushbuf);
|
||||
} else if (dev_priv->card_type != NV_04) {
|
||||
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);
|
||||
ret = nouveau_gpuobj_dma_new
|
||||
(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,
|
||||
&pushbuf);
|
||||
} else {
|
||||
/* NV04 cmdbuf hack, from original ddx.. not sure of it's
|
||||
* exact reason for existing :) PCI access to cmdbuf in
|
||||
* VRAM.
|
||||
*/
|
||||
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);
|
||||
ret = nouveau_gpuobj_dma_new
|
||||
(dev, channel, NV_CLASS_DMA_IN_MEMORY,
|
||||
cb->start, cb->size, NV_DMA_ACCESS_RO,
|
||||
NV_DMA_TARGET_PCI, &pushbuf);
|
||||
}
|
||||
|
||||
if (!cb_dma) {
|
||||
if (ret) {
|
||||
nouveau_mem_free(dev, cb);
|
||||
DRM_ERROR("Failed to alloc DMA object for command buffer\n");
|
||||
return DRM_ERR(ENOMEM);
|
||||
DRM_ERROR("Error creating push buffer ctxdma: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if ((ret = nouveau_gpuobj_ref_add(dev, channel, 0, pushbuf,
|
||||
&chan->pushbuf))) {
|
||||
DRM_ERROR("Error referencing push buffer ctxdma: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
dev_priv->fifos[channel].pushbuf_base = 0;
|
||||
dev_priv->fifos[channel].cmdbuf_mem = cb;
|
||||
dev_priv->fifos[channel].cmdbuf_obj = cb_dma;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -266,6 +273,7 @@ int nouveau_fifo_alloc(drm_device_t* dev, int *chan_ret, DRMFILE filp,
|
|||
return DRM_ERR(EINVAL);
|
||||
(*chan_ret) = channel;
|
||||
chan = &dev_priv->fifos[channel];
|
||||
memset(chan, sizeof(*chan), 0);
|
||||
|
||||
DRM_INFO("Allocating FIFO number %d\n", channel);
|
||||
|
||||
|
@ -273,18 +281,15 @@ int nouveau_fifo_alloc(drm_device_t* dev, int *chan_ret, DRMFILE filp,
|
|||
chan->used = 1;
|
||||
chan->filp = filp;
|
||||
|
||||
/* FIFO has no objects yet */
|
||||
chan->objs = NULL;
|
||||
|
||||
/* allocate a command buffer, and create a dma object for the gpu */
|
||||
ret = nouveau_fifo_cmdbuf_alloc(dev, channel);
|
||||
/* Setup channel's default objects */
|
||||
ret = nouveau_gpuobj_channel_init(dev, channel, vram_handle, tt_handle);
|
||||
if (ret) {
|
||||
nouveau_fifo_free(dev, channel);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Setup channel's default objects */
|
||||
ret = nouveau_object_init_channel(dev, channel, vram_handle, tt_handle);
|
||||
/* allocate a command buffer, and create a dma object for the gpu */
|
||||
ret = nouveau_fifo_cmdbuf_alloc(dev, channel);
|
||||
if (ret) {
|
||||
nouveau_fifo_free(dev, channel);
|
||||
return ret;
|
||||
|
@ -395,13 +400,18 @@ void nouveau_fifo_free(drm_device_t* dev, int channel)
|
|||
NV_WRITE(NV03_PFIFO_CACHES, 0x00000001);
|
||||
|
||||
/* Deallocate command buffer */
|
||||
if (chan->cmdbuf_mem)
|
||||
if (chan->pushbuf)
|
||||
nouveau_gpuobj_ref_del(dev, &chan->pushbuf);
|
||||
|
||||
if (chan->cmdbuf_mem) {
|
||||
nouveau_mem_free(dev, chan->cmdbuf_mem);
|
||||
chan->cmdbuf_mem = NULL;
|
||||
}
|
||||
|
||||
nouveau_notifier_takedown_channel(dev, channel);
|
||||
|
||||
/* Destroy objects belonging to the channel */
|
||||
nouveau_object_cleanup(dev, channel);
|
||||
nouveau_gpuobj_channel_takedown(dev, channel);
|
||||
|
||||
dev_priv->fifo_alloc_count--;
|
||||
}
|
||||
|
|
|
@ -189,7 +189,7 @@ void nouveau_mem_release(DRMFILE filp, struct mem_block *heap)
|
|||
/*
|
||||
* Cleanup everything
|
||||
*/
|
||||
static void nouveau_mem_takedown(struct mem_block **heap)
|
||||
void nouveau_mem_takedown(struct mem_block **heap)
|
||||
{
|
||||
struct mem_block *p;
|
||||
|
||||
|
@ -554,6 +554,13 @@ int nouveau_instmem_init(struct drm_device *dev)
|
|||
nouveau_instmem_determine_amount(dev);
|
||||
nouveau_instmem_configure_fixed_tables(dev);
|
||||
|
||||
if ((ret = nouveau_gpuobj_new_fake(dev, dev_priv->ramht_offset,
|
||||
dev_priv->ramht_size,
|
||||
NVOBJ_FLAG_ZERO_ALLOC |
|
||||
NVOBJ_FLAG_ALLOW_NO_REFS,
|
||||
&dev_priv->ramht, NULL)))
|
||||
return ret;
|
||||
|
||||
/* Create a heap to manage RAMIN allocations, we don't allocate
|
||||
* the space that was reserved for RAMHT/FC/RO.
|
||||
*/
|
||||
|
|
|
@ -74,10 +74,10 @@ nouveau_notifier_alloc(drm_device_t *dev, int channel, uint32_t handle,
|
|||
{
|
||||
drm_nouveau_private_t *dev_priv = dev->dev_private;
|
||||
struct nouveau_fifo *chan = &dev_priv->fifos[channel];
|
||||
struct nouveau_object *obj;
|
||||
nouveau_gpuobj_t *nobj = NULL;
|
||||
struct mem_block *mem;
|
||||
uint32_t offset;
|
||||
int target;
|
||||
int target, ret;
|
||||
|
||||
if (!chan->notifier_heap) {
|
||||
DRM_ERROR("Channel %d doesn't have a notifier heap!\n",
|
||||
|
@ -105,21 +105,19 @@ nouveau_notifier_alloc(drm_device_t *dev, int channel, uint32_t handle,
|
|||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
|
||||
obj = nouveau_object_dma_create(dev, channel, NV_CLASS_DMA_IN_MEMORY,
|
||||
offset, mem->size, NV_DMA_ACCESS_RW,
|
||||
target);
|
||||
if (!obj) {
|
||||
if ((ret = nouveau_gpuobj_dma_new(dev, channel, NV_CLASS_DMA_IN_MEMORY,
|
||||
offset, mem->size,
|
||||
NV_DMA_ACCESS_RW, target, &nobj))) {
|
||||
nouveau_mem_free_block(mem);
|
||||
DRM_ERROR("Error creating notifier ctxdma\n");
|
||||
return DRM_ERR(ENOMEM);
|
||||
DRM_ERROR("Error creating notifier ctxdma: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
obj->handle = handle;
|
||||
if (nouveau_ramht_insert(dev, channel, handle, obj)) {
|
||||
nouveau_object_free(dev, obj);
|
||||
if ((ret = nouveau_gpuobj_ref_add(dev, channel, handle, nobj, NULL))) {
|
||||
nouveau_gpuobj_del(dev, &nobj);
|
||||
nouveau_mem_free_block(mem);
|
||||
DRM_ERROR("Error inserting notifier ctxdma into RAMHT\n");
|
||||
return DRM_ERR(ENOMEM);
|
||||
DRM_ERROR("Error referencing notifier ctxdma: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
*b_offset = mem->start;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -283,6 +283,20 @@ static int nouveau_card_init(drm_device_t *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void nouveau_card_takedown(drm_device_t *dev)
|
||||
{
|
||||
drm_nouveau_private_t *dev_priv = dev->dev_private;
|
||||
nouveau_engine_func_t *engine = &dev_priv->Engine;
|
||||
|
||||
engine->fifo.takedown(dev);
|
||||
engine->graph.takedown(dev);
|
||||
engine->fb.takedown(dev);
|
||||
engine->timer.takedown(dev);
|
||||
engine->mc.takedown(dev);
|
||||
nouveau_gpuobj_takedown(dev);
|
||||
nouveau_mem_close(dev);
|
||||
}
|
||||
|
||||
/* here a client dies, release the stuff that was allocated for its filp */
|
||||
void nouveau_preclose(drm_device_t * dev, DRMFILE filp)
|
||||
{
|
||||
|
@ -314,11 +328,10 @@ int nouveau_load(struct drm_device *dev, unsigned long flags)
|
|||
if (flags==NV_UNKNOWN)
|
||||
return DRM_ERR(EINVAL);
|
||||
|
||||
dev_priv = drm_alloc(sizeof(drm_nouveau_private_t), DRM_MEM_DRIVER);
|
||||
dev_priv = drm_calloc(1, sizeof(*dev_priv), DRM_MEM_DRIVER);
|
||||
if (!dev_priv)
|
||||
return DRM_ERR(ENOMEM);
|
||||
|
||||
memset(dev_priv, 0, sizeof(drm_nouveau_private_t));
|
||||
dev_priv->card_type=flags&NOUVEAU_FAMILY;
|
||||
dev_priv->flags=flags&NOUVEAU_FLAGS;
|
||||
|
||||
|
@ -338,6 +351,9 @@ int nouveau_load(struct drm_device *dev, unsigned long flags)
|
|||
void nouveau_lastclose(struct drm_device *dev)
|
||||
{
|
||||
drm_nouveau_private_t *dev_priv = dev->dev_private;
|
||||
|
||||
nouveau_card_takedown(dev);
|
||||
|
||||
if(dev_priv->fb_mtrr>0)
|
||||
{
|
||||
drm_mtrr_del(dev_priv->fb_mtrr, drm_get_resource_start(dev, 1),nouveau_mem_fb_amount(dev), DRM_MTRR_WC);
|
||||
|
|
|
@ -28,8 +28,10 @@
|
|||
#include "drm.h"
|
||||
#include "nouveau_drv.h"
|
||||
|
||||
#define RAMFC_WR(offset, val) NV_WI32(fifoctx + NV04_RAMFC_##offset, (val))
|
||||
#define RAMFC_RD(offset) NV_RI32(fifoctx + NV04_RAMFC_##offset)
|
||||
#define RAMFC_WR(offset,val) INSTANCE_WR(chan->ramfc->gpuobj, \
|
||||
NV04_RAMFC_##offset/4, (val))
|
||||
#define RAMFC_RD(offset) INSTANCE_RD(chan->ramfc->gpuobj, \
|
||||
NV04_RAMFC_##offset/4)
|
||||
#define NV04_RAMFC(c) (dev_priv->ramfc_offset + ((c) * NV04_RAMFC__SIZE))
|
||||
#define NV04_RAMFC__SIZE 32
|
||||
|
||||
|
@ -38,21 +40,19 @@ nv04_fifo_create_context(drm_device_t *dev, int channel)
|
|||
{
|
||||
drm_nouveau_private_t *dev_priv = dev->dev_private;
|
||||
struct nouveau_fifo *chan = &dev_priv->fifos[channel];
|
||||
struct nouveau_object *pb = chan->cmdbuf_obj;
|
||||
uint32_t fifoctx = NV04_RAMFC(channel);
|
||||
int i;
|
||||
int ret;
|
||||
|
||||
if (!pb || !pb->instance)
|
||||
return DRM_ERR(EINVAL);
|
||||
if ((ret = nouveau_gpuobj_new_fake(dev, NV04_RAMFC(channel),
|
||||
NV04_RAMFC__SIZE,
|
||||
NVOBJ_FLAG_ZERO_ALLOC |
|
||||
NVOBJ_FLAG_ZERO_FREE,
|
||||
NULL, &chan->ramfc)))
|
||||
return ret;
|
||||
|
||||
/* Clear RAMFC */
|
||||
for (i=0; i<NV04_RAMFC__SIZE; i+=4)
|
||||
NV_WI32(fifoctx + i, 0);
|
||||
|
||||
/* Setup initial state */
|
||||
RAMFC_WR(DMA_PUT, chan->pushbuf_base);
|
||||
RAMFC_WR(DMA_GET, chan->pushbuf_base);
|
||||
RAMFC_WR(DMA_INSTANCE, nouveau_chip_instance_get(dev, pb->instance));
|
||||
RAMFC_WR(DMA_INSTANCE, chan->pushbuf->instance >> 4);
|
||||
RAMFC_WR(DMA_FETCH, (NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES |
|
||||
NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES |
|
||||
NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_8 |
|
||||
|
@ -67,18 +67,17 @@ void
|
|||
nv04_fifo_destroy_context(drm_device_t *dev, int channel)
|
||||
{
|
||||
drm_nouveau_private_t *dev_priv = dev->dev_private;
|
||||
uint32_t fifoctx = NV04_RAMFC(channel);
|
||||
int i;
|
||||
struct nouveau_fifo *chan = &dev_priv->fifos[channel];
|
||||
|
||||
for (i=0; i<NV04_RAMFC__SIZE; i+=4)
|
||||
NV_WI32(fifoctx + i, 0);
|
||||
if (chan->ramfc)
|
||||
nouveau_gpuobj_ref_del(dev, &chan->ramfc);
|
||||
}
|
||||
|
||||
int
|
||||
nv04_fifo_load_context(drm_device_t *dev, int channel)
|
||||
{
|
||||
drm_nouveau_private_t *dev_priv = dev->dev_private;
|
||||
uint32_t fifoctx = NV04_RAMFC(channel);
|
||||
struct nouveau_fifo *chan = &dev_priv->fifos[channel];
|
||||
uint32_t tmp;
|
||||
|
||||
NV_WRITE(NV03_PFIFO_CACHE1_PUSH1, (1<<8) | channel);
|
||||
|
@ -106,7 +105,7 @@ int
|
|||
nv04_fifo_save_context(drm_device_t *dev, int channel)
|
||||
{
|
||||
drm_nouveau_private_t *dev_priv = dev->dev_private;
|
||||
uint32_t fifoctx = NV04_RAMFC(channel);
|
||||
struct nouveau_fifo *chan = &dev_priv->fifos[channel];
|
||||
uint32_t tmp;
|
||||
|
||||
RAMFC_WR(DMA_PUT, NV04_PFIFO_CACHE1_DMA_PUT);
|
||||
|
|
|
@ -28,8 +28,11 @@
|
|||
#include "drm.h"
|
||||
#include "nouveau_drv.h"
|
||||
|
||||
#define RAMFC_WR(offset, val) NV_WI32(fifoctx + NV10_RAMFC_##offset, (val))
|
||||
#define RAMFC_RD(offset) NV_RI32(fifoctx + NV10_RAMFC_##offset)
|
||||
|
||||
#define RAMFC_WR(offset,val) INSTANCE_WR(chan->ramfc->gpuobj, \
|
||||
NV10_RAMFC_##offset/4, (val))
|
||||
#define RAMFC_RD(offset) INSTANCE_RD(chan->ramfc->gpuobj, \
|
||||
NV10_RAMFC_##offset/4)
|
||||
#define NV10_RAMFC(c) (dev_priv->ramfc_offset + NV10_RAMFC__SIZE)
|
||||
#define NV10_RAMFC__SIZE ((dev_priv->chipset) >= 0x17 ? 64 : 32)
|
||||
|
||||
|
@ -38,20 +41,21 @@ nv10_fifo_create_context(drm_device_t *dev, int channel)
|
|||
{
|
||||
drm_nouveau_private_t *dev_priv = dev->dev_private;
|
||||
struct nouveau_fifo *chan = &dev_priv->fifos[channel];
|
||||
uint32_t fifoctx = NV10_RAMFC(channel), pushbuf;
|
||||
int i;
|
||||
int ret;
|
||||
|
||||
pushbuf = nouveau_chip_instance_get(dev, chan->cmdbuf_obj->instance);
|
||||
|
||||
for (i=0; i<NV10_RAMFC__SIZE; i+=4)
|
||||
NV_WI32(fifoctx + i, 0);
|
||||
if ((ret = nouveau_gpuobj_new_fake(dev, NV10_RAMFC(channel),
|
||||
NV10_RAMFC__SIZE,
|
||||
NVOBJ_FLAG_ZERO_ALLOC |
|
||||
NVOBJ_FLAG_ZERO_FREE,
|
||||
NULL, &chan->ramfc)))
|
||||
return ret;
|
||||
|
||||
/* Fill entries that are seen filled in dumps of nvidia driver just
|
||||
* after channel's is put into DMA mode
|
||||
*/
|
||||
RAMFC_WR(DMA_PUT , chan->pushbuf_base);
|
||||
RAMFC_WR(DMA_GET , chan->pushbuf_base);
|
||||
RAMFC_WR(DMA_INSTANCE , pushbuf);
|
||||
RAMFC_WR(DMA_INSTANCE , chan->pushbuf->instance >> 4);
|
||||
RAMFC_WR(DMA_FETCH , NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES |
|
||||
NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES |
|
||||
NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_8 |
|
||||
|
@ -67,18 +71,17 @@ void
|
|||
nv10_fifo_destroy_context(drm_device_t *dev, int channel)
|
||||
{
|
||||
drm_nouveau_private_t *dev_priv = dev->dev_private;
|
||||
uint32_t fifoctx = NV10_RAMFC(channel);
|
||||
int i;
|
||||
struct nouveau_fifo *chan = &dev_priv->fifos[channel];
|
||||
|
||||
for (i=0; i<NV10_RAMFC__SIZE; i+=4)
|
||||
NV_WI32(fifoctx + i, 0);
|
||||
if (chan->ramfc)
|
||||
nouveau_gpuobj_ref_del(dev, &chan->ramfc);
|
||||
}
|
||||
|
||||
int
|
||||
nv10_fifo_load_context(drm_device_t *dev, int channel)
|
||||
{
|
||||
drm_nouveau_private_t *dev_priv = dev->dev_private;
|
||||
uint32_t fifoctx = NV10_RAMFC(channel);
|
||||
struct nouveau_fifo *chan = &dev_priv->fifos[channel];
|
||||
uint32_t tmp;
|
||||
|
||||
NV_WRITE(NV03_PFIFO_CACHE1_PUSH1 , 0x00000100 | channel);
|
||||
|
@ -120,7 +123,7 @@ int
|
|||
nv10_fifo_save_context(drm_device_t *dev, int channel)
|
||||
{
|
||||
drm_nouveau_private_t *dev_priv = dev->dev_private;
|
||||
uint32_t fifoctx = NV10_RAMFC(channel);
|
||||
struct nouveau_fifo *chan = &dev_priv->fifos[channel];
|
||||
uint32_t tmp;
|
||||
|
||||
RAMFC_WR(DMA_PUT , NV_READ(NV04_PFIFO_CACHE1_DMA_PUT));
|
||||
|
|
|
@ -34,19 +34,18 @@ int nv20_graph_create_context(drm_device_t *dev, int channel) {
|
|||
(drm_nouveau_private_t *)dev->dev_private;
|
||||
struct nouveau_fifo *chan = &dev_priv->fifos[channel];
|
||||
unsigned int ctx_size = NV20_GRCTX_SIZE;
|
||||
int i;
|
||||
int ret;
|
||||
|
||||
/* Alloc and clear RAMIN to store the context */
|
||||
chan->ramin_grctx = nouveau_instmem_alloc(dev, ctx_size, 4);
|
||||
if (!chan->ramin_grctx)
|
||||
return DRM_ERR(ENOMEM);
|
||||
for (i=0; i<ctx_size; i+=4)
|
||||
INSTANCE_WR(chan->ramin_grctx, i/4, 0x00000000);
|
||||
if ((ret = nouveau_gpuobj_new_ref(dev, channel, -1, 0, ctx_size, 16,
|
||||
NVOBJ_FLAG_ZERO_ALLOC,
|
||||
&chan->ramin_grctx)))
|
||||
return ret;
|
||||
|
||||
/* Initialise default context values */
|
||||
INSTANCE_WR(chan->ramin_grctx, 10, channel << 24); /* CTX_USER */
|
||||
INSTANCE_WR(chan->ramin_grctx->gpuobj, 10, channel<<24); /* CTX_USER */
|
||||
|
||||
INSTANCE_WR(dev_priv->ctx_table, channel, nouveau_chip_instance_get(dev, chan->ramin_grctx));
|
||||
INSTANCE_WR(dev_priv->ctx_table->gpuobj, channel,
|
||||
chan->ramin_grctx->instance >> 4);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -54,12 +53,10 @@ void nv20_graph_destroy_context(drm_device_t *dev, int channel) {
|
|||
drm_nouveau_private_t *dev_priv = dev->dev_private;
|
||||
struct nouveau_fifo *chan = &dev_priv->fifos[channel];
|
||||
|
||||
if (chan->ramin_grctx) {
|
||||
nouveau_instmem_free(dev, chan->ramin_grctx);
|
||||
chan->ramin_grctx = NULL;
|
||||
}
|
||||
if (chan->ramin_grctx)
|
||||
nouveau_gpuobj_ref_del(dev, &chan->ramin_grctx);
|
||||
|
||||
INSTANCE_WR(dev_priv->ctx_table, channel, 0);
|
||||
INSTANCE_WR(dev_priv->ctx_table->gpuobj, channel, 0);
|
||||
}
|
||||
|
||||
static void nv20_graph_rdi(drm_device_t *dev) {
|
||||
|
@ -79,13 +76,14 @@ static void nv20_graph_rdi(drm_device_t *dev) {
|
|||
int nv20_graph_save_context(drm_device_t *dev, int channel) {
|
||||
drm_nouveau_private_t *dev_priv =
|
||||
(drm_nouveau_private_t *)dev->dev_private;
|
||||
struct nouveau_fifo *chan = &dev_priv->fifos[channel];
|
||||
uint32_t instance;
|
||||
|
||||
instance = INSTANCE_RD(dev_priv->ctx_table, channel);
|
||||
instance = INSTANCE_RD(dev_priv->ctx_table->gpuobj, channel);
|
||||
if (!instance) {
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
if (instance != nouveau_chip_instance_get(dev, dev_priv->fifos[channel].ramin_grctx))
|
||||
if (instance != (chan->ramin_grctx->instance >> 4))
|
||||
DRM_ERROR("nv20_graph_save_context : bad instance\n");
|
||||
|
||||
NV_WRITE(NV10_PGRAPH_CHANNEL_CTX_SIZE, instance);
|
||||
|
@ -99,13 +97,14 @@ int nv20_graph_save_context(drm_device_t *dev, int channel) {
|
|||
int nv20_graph_load_context(drm_device_t *dev, int channel) {
|
||||
drm_nouveau_private_t *dev_priv =
|
||||
(drm_nouveau_private_t *)dev->dev_private;
|
||||
struct nouveau_fifo *chan = &dev_priv->fifos[channel];
|
||||
uint32_t instance;
|
||||
|
||||
instance = INSTANCE_RD(dev_priv->ctx_table, channel);
|
||||
instance = INSTANCE_RD(dev_priv->ctx_table->gpuobj, channel);
|
||||
if (!instance) {
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
if (instance != nouveau_chip_instance_get(dev, dev_priv->fifos[channel].ramin_grctx))
|
||||
if (instance != (chan->ramin_grctx->instance >> 4))
|
||||
DRM_ERROR("nv20_graph_load_context_current : bad instance\n");
|
||||
|
||||
NV_WRITE(NV10_PGRAPH_CTX_USER, channel << 24);
|
||||
|
@ -148,8 +147,8 @@ void nouveau_nv20_context_switch(drm_device_t *dev)
|
|||
int nv20_graph_init(drm_device_t *dev) {
|
||||
drm_nouveau_private_t *dev_priv =
|
||||
(drm_nouveau_private_t *)dev->dev_private;
|
||||
int i;
|
||||
uint32_t tmp, vramsz;
|
||||
int ret, i;
|
||||
|
||||
NV_WRITE(NV03_PMC_ENABLE, NV_READ(NV03_PMC_ENABLE) &
|
||||
~NV_PMC_ENABLE_PGRAPH);
|
||||
|
@ -158,14 +157,14 @@ int nv20_graph_init(drm_device_t *dev) {
|
|||
|
||||
/* Create Context Pointer Table */
|
||||
dev_priv->ctx_table_size = 32 * 4;
|
||||
dev_priv->ctx_table = nouveau_instmem_alloc(dev, dev_priv->ctx_table_size, 4);
|
||||
if (!dev_priv->ctx_table)
|
||||
return DRM_ERR(ENOMEM);
|
||||
if ((ret = nouveau_gpuobj_new_ref(dev, -1, -1, 0,
|
||||
dev_priv->ctx_table_size, 16,
|
||||
NVOBJ_FLAG_ZERO_ALLOC,
|
||||
&dev_priv->ctx_table)))
|
||||
return ret;
|
||||
|
||||
for (i=0; i< dev_priv->ctx_table_size; i+=4)
|
||||
INSTANCE_WR(dev_priv->ctx_table, i/4, 0x00000000);
|
||||
|
||||
NV_WRITE(NV10_PGRAPH_CHANNEL_CTX_TABLE, nouveau_chip_instance_get(dev, dev_priv->ctx_table));
|
||||
NV_WRITE(NV10_PGRAPH_CHANNEL_CTX_TABLE,
|
||||
dev_priv->ctx_table->instance >> 4);
|
||||
|
||||
//XXX need to be done and save/restore for each fifo ???
|
||||
nv20_graph_rdi(dev);
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* contexts are taken from dumps just after the 3D object is
|
||||
* created.
|
||||
*/
|
||||
static void nv30_graph_context_init(drm_device_t *dev, struct mem_block *ctx)
|
||||
static void nv30_graph_context_init(drm_device_t *dev, nouveau_gpuobj_t *ctx)
|
||||
{
|
||||
drm_nouveau_private_t *dev_priv = dev->dev_private;
|
||||
int i;
|
||||
|
@ -105,9 +105,9 @@ int nv30_graph_create_context(drm_device_t *dev, int channel)
|
|||
drm_nouveau_private_t *dev_priv =
|
||||
(drm_nouveau_private_t *)dev->dev_private;
|
||||
struct nouveau_fifo *chan = &dev_priv->fifos[channel];
|
||||
void (*ctx_init)(drm_device_t *, struct mem_block *);
|
||||
void (*ctx_init)(drm_device_t *, nouveau_gpuobj_t *);
|
||||
unsigned int ctx_size;
|
||||
int i;
|
||||
int ret;
|
||||
|
||||
switch (dev_priv->chipset) {
|
||||
default:
|
||||
|
@ -116,18 +116,17 @@ int nv30_graph_create_context(drm_device_t *dev, int channel)
|
|||
break;
|
||||
}
|
||||
|
||||
/* Alloc and clear RAMIN to store the context */
|
||||
chan->ramin_grctx = nouveau_instmem_alloc(dev, ctx_size, 4);
|
||||
if (!chan->ramin_grctx)
|
||||
return DRM_ERR(ENOMEM);
|
||||
for (i=0; i<ctx_size; i+=4)
|
||||
INSTANCE_WR(chan->ramin_grctx, i/4, 0x00000000);
|
||||
if ((ret = nouveau_gpuobj_new_ref(dev, channel, -1, 0, ctx_size, 16,
|
||||
NVOBJ_FLAG_ZERO_ALLOC,
|
||||
&chan->ramin_grctx)))
|
||||
return ret;
|
||||
|
||||
/* Initialise default context values */
|
||||
ctx_init(dev, chan->ramin_grctx);
|
||||
ctx_init(dev, chan->ramin_grctx->gpuobj);
|
||||
|
||||
INSTANCE_WR(chan->ramin_grctx, 10, channel << 24); /* CTX_USER */
|
||||
INSTANCE_WR(dev_priv->ctx_table, channel, nouveau_chip_instance_get(dev, chan->ramin_grctx));
|
||||
INSTANCE_WR(chan->ramin_grctx->gpuobj, 10, channel<<24); /* CTX_USER */
|
||||
INSTANCE_WR(dev_priv->ctx_table->gpuobj, channel,
|
||||
chan->ramin_grctx->instance >> 4);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -138,12 +137,10 @@ void nv30_graph_destroy_context(drm_device_t *dev, int channel)
|
|||
(drm_nouveau_private_t *)dev->dev_private;
|
||||
struct nouveau_fifo *chan = &dev_priv->fifos[channel];
|
||||
|
||||
if (chan->ramin_grctx) {
|
||||
nouveau_instmem_free(dev, chan->ramin_grctx);
|
||||
chan->ramin_grctx = NULL;
|
||||
}
|
||||
if (chan->ramin_grctx)
|
||||
nouveau_gpuobj_ref_del(dev, &chan->ramin_grctx);
|
||||
|
||||
INSTANCE_WR(dev_priv->ctx_table, channel, 0);
|
||||
INSTANCE_WR(dev_priv->ctx_table->gpuobj, channel, 0);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -172,7 +169,7 @@ int nv30_graph_load_context(drm_device_t *dev, int channel)
|
|||
|
||||
if (!chan->ramin_grctx)
|
||||
return DRM_ERR(EINVAL);
|
||||
inst = nouveau_chip_instance_get(dev, chan->ramin_grctx);
|
||||
inst = chan->ramin_grctx->instance >> 4;
|
||||
|
||||
NV_WRITE(NV20_PGRAPH_CHANNEL_CTX_POINTER, inst);
|
||||
NV_WRITE(NV20_PGRAPH_CHANNEL_CTX_XFER,
|
||||
|
@ -189,7 +186,7 @@ int nv30_graph_save_context(drm_device_t *dev, int channel)
|
|||
|
||||
if (!chan->ramin_grctx)
|
||||
return DRM_ERR(EINVAL);
|
||||
inst = nouveau_chip_instance_get(dev, chan->ramin_grctx);
|
||||
inst = chan->ramin_grctx->instance >> 4;
|
||||
|
||||
NV_WRITE(NV20_PGRAPH_CHANNEL_CTX_POINTER, inst);
|
||||
NV_WRITE(NV20_PGRAPH_CHANNEL_CTX_XFER,
|
||||
|
@ -203,7 +200,7 @@ int nv30_graph_init(drm_device_t *dev)
|
|||
drm_nouveau_private_t *dev_priv =
|
||||
(drm_nouveau_private_t *)dev->dev_private;
|
||||
uint32_t vramsz, tmp;
|
||||
int i;
|
||||
int ret, i;
|
||||
|
||||
NV_WRITE(NV03_PMC_ENABLE, NV_READ(NV03_PMC_ENABLE) &
|
||||
~NV_PMC_ENABLE_PGRAPH);
|
||||
|
@ -212,14 +209,14 @@ int nv30_graph_init(drm_device_t *dev)
|
|||
|
||||
/* Create Context Pointer Table */
|
||||
dev_priv->ctx_table_size = 32 * 4;
|
||||
dev_priv->ctx_table = nouveau_instmem_alloc(dev, dev_priv->ctx_table_size, 4);
|
||||
if (!dev_priv->ctx_table)
|
||||
return DRM_ERR(ENOMEM);
|
||||
if ((ret = nouveau_gpuobj_new_ref(dev, -1, -1, 0,
|
||||
dev_priv->ctx_table_size, 16,
|
||||
NVOBJ_FLAG_ZERO_ALLOC,
|
||||
&dev_priv->ctx_table)))
|
||||
return ret;
|
||||
|
||||
for (i=0; i< dev_priv->ctx_table_size; i+=4)
|
||||
INSTANCE_WR(dev_priv->ctx_table, i/4, 0x00000000);
|
||||
|
||||
NV_WRITE(NV10_PGRAPH_CHANNEL_CTX_TABLE, nouveau_chip_instance_get(dev, dev_priv->ctx_table));
|
||||
NV_WRITE(NV10_PGRAPH_CHANNEL_CTX_TABLE,
|
||||
dev_priv->ctx_table->instance >> 4);
|
||||
|
||||
NV_WRITE(NV03_PGRAPH_INTR_EN, 0x00000000);
|
||||
NV_WRITE(NV03_PGRAPH_INTR , 0xFFFFFFFF);
|
||||
|
|
|
@ -28,8 +28,11 @@
|
|||
#include "nouveau_drv.h"
|
||||
#include "nouveau_drm.h"
|
||||
|
||||
#define RAMFC_WR(offset, val) NV_WI32(fifoctx + NV40_RAMFC_##offset, (val))
|
||||
#define RAMFC_RD(offset) NV_RI32(fifoctx + NV40_RAMFC_##offset)
|
||||
|
||||
#define RAMFC_WR(offset,val) INSTANCE_WR(chan->ramfc->gpuobj, \
|
||||
NV40_RAMFC_##offset/4, (val))
|
||||
#define RAMFC_RD(offset) INSTANCE_RD(chan->ramfc->gpuobj, \
|
||||
NV40_RAMFC_##offset/4)
|
||||
#define NV40_RAMFC(c) (dev_priv->ramfc_offset + ((c)*NV40_RAMFC__SIZE))
|
||||
#define NV40_RAMFC__SIZE 128
|
||||
|
||||
|
@ -38,21 +41,21 @@ nv40_fifo_create_context(drm_device_t *dev, int channel)
|
|||
{
|
||||
drm_nouveau_private_t *dev_priv = dev->dev_private;
|
||||
struct nouveau_fifo *chan = &dev_priv->fifos[channel];
|
||||
uint32_t fifoctx = NV40_RAMFC(channel), grctx, pushbuf;
|
||||
int i;
|
||||
int ret;
|
||||
|
||||
for (i = 0; i < NV40_RAMFC__SIZE; i+=4)
|
||||
NV_WI32(fifoctx + i, 0);
|
||||
|
||||
grctx = nouveau_chip_instance_get(dev, chan->ramin_grctx);
|
||||
pushbuf = nouveau_chip_instance_get(dev, chan->cmdbuf_obj->instance);
|
||||
if ((ret = nouveau_gpuobj_new_fake(dev, NV40_RAMFC(channel),
|
||||
NV40_RAMFC__SIZE,
|
||||
NVOBJ_FLAG_ZERO_ALLOC |
|
||||
NVOBJ_FLAG_ZERO_FREE,
|
||||
NULL, &chan->ramfc)))
|
||||
return ret;
|
||||
|
||||
/* Fill entries that are seen filled in dumps of nvidia driver just
|
||||
* after channel's is put into DMA mode
|
||||
*/
|
||||
RAMFC_WR(DMA_PUT , chan->pushbuf_base);
|
||||
RAMFC_WR(DMA_GET , chan->pushbuf_base);
|
||||
RAMFC_WR(DMA_INSTANCE , pushbuf);
|
||||
RAMFC_WR(DMA_INSTANCE , chan->pushbuf->instance >> 4);
|
||||
RAMFC_WR(DMA_FETCH , NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES |
|
||||
NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES |
|
||||
NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_8 |
|
||||
|
@ -61,7 +64,7 @@ nv40_fifo_create_context(drm_device_t *dev, int channel)
|
|||
#endif
|
||||
0x30000000 /* no idea.. */);
|
||||
RAMFC_WR(DMA_SUBROUTINE, 0);
|
||||
RAMFC_WR(GRCTX_INSTANCE, grctx);
|
||||
RAMFC_WR(GRCTX_INSTANCE, chan->ramin_grctx->instance >> 4);
|
||||
RAMFC_WR(DMA_TIMESLICE , 0x0001FFFF);
|
||||
|
||||
return 0;
|
||||
|
@ -71,18 +74,17 @@ void
|
|||
nv40_fifo_destroy_context(drm_device_t *dev, int channel)
|
||||
{
|
||||
drm_nouveau_private_t *dev_priv = dev->dev_private;
|
||||
uint32_t fifoctx = NV40_RAMFC(channel);
|
||||
int i;
|
||||
struct nouveau_fifo *chan = &dev_priv->fifos[channel];
|
||||
|
||||
for (i = 0; i < NV40_RAMFC__SIZE; i+=4)
|
||||
NV_WI32(fifoctx + i, 0);
|
||||
if (chan->ramfc)
|
||||
nouveau_gpuobj_ref_del(dev, &chan->ramfc);
|
||||
}
|
||||
|
||||
int
|
||||
nv40_fifo_load_context(drm_device_t *dev, int channel)
|
||||
{
|
||||
drm_nouveau_private_t *dev_priv = dev->dev_private;
|
||||
uint32_t fifoctx = NV40_RAMFC(channel);
|
||||
struct nouveau_fifo *chan = &dev_priv->fifos[channel];
|
||||
uint32_t tmp, tmp2;
|
||||
|
||||
NV_WRITE(NV04_PFIFO_CACHE1_DMA_GET , RAMFC_RD(DMA_GET));
|
||||
|
@ -141,7 +143,7 @@ int
|
|||
nv40_fifo_save_context(drm_device_t *dev, int channel)
|
||||
{
|
||||
drm_nouveau_private_t *dev_priv = dev->dev_private;
|
||||
uint32_t fifoctx = NV40_RAMFC(channel);
|
||||
struct nouveau_fifo *chan = &dev_priv->fifos[channel];
|
||||
uint32_t tmp;
|
||||
|
||||
RAMFC_WR(DMA_PUT , NV_READ(NV04_PFIFO_CACHE1_DMA_PUT));
|
||||
|
|
|
@ -47,13 +47,13 @@
|
|||
* created.
|
||||
*/
|
||||
static void
|
||||
nv40_graph_context_init(drm_device_t *dev, struct mem_block *ctx)
|
||||
nv40_graph_context_init(drm_device_t *dev, nouveau_gpuobj_t *ctx)
|
||||
{
|
||||
drm_nouveau_private_t *dev_priv = dev->dev_private;
|
||||
int i;
|
||||
|
||||
/* Always has the "instance address" of itself at offset 0 */
|
||||
INSTANCE_WR(ctx, 0x00000/4, nouveau_chip_instance_get(dev, ctx));
|
||||
INSTANCE_WR(ctx, 0x00000/4, ctx->im_pramin->start);
|
||||
/* unknown */
|
||||
INSTANCE_WR(ctx, 0x00024/4, 0x0000ffff);
|
||||
INSTANCE_WR(ctx, 0x00028/4, 0x0000ffff);
|
||||
|
@ -188,12 +188,12 @@ nv40_graph_context_init(drm_device_t *dev, struct mem_block *ctx)
|
|||
}
|
||||
|
||||
static void
|
||||
nv43_graph_context_init(drm_device_t *dev, struct mem_block *ctx)
|
||||
nv43_graph_context_init(drm_device_t *dev, nouveau_gpuobj_t *ctx)
|
||||
{
|
||||
drm_nouveau_private_t *dev_priv = dev->dev_private;
|
||||
int i;
|
||||
|
||||
INSTANCE_WR(ctx, 0x00000/4, nouveau_chip_instance_get(dev, ctx));
|
||||
INSTANCE_WR(ctx, 0x00000/4, ctx->im_pramin->start);
|
||||
INSTANCE_WR(ctx, 0x00024/4, 0x0000ffff);
|
||||
INSTANCE_WR(ctx, 0x00028/4, 0x0000ffff);
|
||||
INSTANCE_WR(ctx, 0x00030/4, 0x00000001);
|
||||
|
@ -304,12 +304,12 @@ nv43_graph_context_init(drm_device_t *dev, struct mem_block *ctx)
|
|||
};
|
||||
|
||||
static void
|
||||
nv46_graph_context_init(drm_device_t *dev, struct mem_block *ctx)
|
||||
nv46_graph_context_init(drm_device_t *dev, nouveau_gpuobj_t *ctx)
|
||||
{
|
||||
drm_nouveau_private_t *dev_priv = dev->dev_private;
|
||||
int i;
|
||||
|
||||
INSTANCE_WR(ctx, 0x00000/4, nouveau_chip_instance_get(dev, ctx));
|
||||
INSTANCE_WR(ctx, 0x00000/4, ctx->im_pramin->start);
|
||||
INSTANCE_WR(ctx, 0x00040/4, 0x0000ffff);
|
||||
INSTANCE_WR(ctx, 0x00044/4, 0x0000ffff);
|
||||
INSTANCE_WR(ctx, 0x0004c/4, 0x00000001);
|
||||
|
@ -455,12 +455,12 @@ nv46_graph_context_init(drm_device_t *dev, struct mem_block *ctx)
|
|||
}
|
||||
|
||||
static void
|
||||
nv49_graph_context_init(drm_device_t *dev, struct mem_block *ctx)
|
||||
nv49_graph_context_init(drm_device_t *dev, nouveau_gpuobj_t *ctx)
|
||||
{
|
||||
drm_nouveau_private_t *dev_priv = dev->dev_private;
|
||||
int i;
|
||||
|
||||
INSTANCE_WR(ctx, 0x00000/4, nouveau_chip_instance_get(dev, ctx));
|
||||
INSTANCE_WR(ctx, 0x00000/4, ctx->im_pramin->start);
|
||||
INSTANCE_WR(ctx, 0x00004/4, 0x0000c040);
|
||||
INSTANCE_WR(ctx, 0x00008/4, 0x0000c040);
|
||||
INSTANCE_WR(ctx, 0x0000c/4, 0x0000c040);
|
||||
|
@ -678,12 +678,12 @@ nv49_graph_context_init(drm_device_t *dev, struct mem_block *ctx)
|
|||
}
|
||||
|
||||
static void
|
||||
nv4a_graph_context_init(drm_device_t *dev, struct mem_block *ctx)
|
||||
nv4a_graph_context_init(drm_device_t *dev, nouveau_gpuobj_t *ctx)
|
||||
{
|
||||
drm_nouveau_private_t *dev_priv = dev->dev_private;
|
||||
int i;
|
||||
|
||||
INSTANCE_WR(ctx, 0x00000/4, nouveau_chip_instance_get(dev, ctx));
|
||||
INSTANCE_WR(ctx, 0x00000/4, ctx->im_pramin->start);
|
||||
INSTANCE_WR(ctx, 0x00024/4, 0x0000ffff);
|
||||
INSTANCE_WR(ctx, 0x00028/4, 0x0000ffff);
|
||||
INSTANCE_WR(ctx, 0x00030/4, 0x00000001);
|
||||
|
@ -795,12 +795,12 @@ nv4a_graph_context_init(drm_device_t *dev, struct mem_block *ctx)
|
|||
}
|
||||
|
||||
static void
|
||||
nv4b_graph_context_init(drm_device_t *dev, struct mem_block *ctx)
|
||||
nv4b_graph_context_init(drm_device_t *dev, nouveau_gpuobj_t *ctx)
|
||||
{
|
||||
drm_nouveau_private_t *dev_priv = dev->dev_private;
|
||||
int i;
|
||||
|
||||
INSTANCE_WR(ctx, 0x00000/4, nouveau_chip_instance_get(dev, ctx));
|
||||
INSTANCE_WR(ctx, 0x00000/4, ctx->im_pramin->start);
|
||||
INSTANCE_WR(ctx, 0x00004/4, 0x0000c040);
|
||||
INSTANCE_WR(ctx, 0x00008/4, 0x0000c040);
|
||||
INSTANCE_WR(ctx, 0x0000c/4, 0x0000c040);
|
||||
|
@ -1010,12 +1010,12 @@ nv4b_graph_context_init(drm_device_t *dev, struct mem_block *ctx)
|
|||
}
|
||||
|
||||
static void
|
||||
nv4c_graph_context_init(drm_device_t *dev, struct mem_block *ctx)
|
||||
nv4c_graph_context_init(drm_device_t *dev, nouveau_gpuobj_t *ctx)
|
||||
{
|
||||
drm_nouveau_private_t *dev_priv = dev->dev_private;
|
||||
int i;
|
||||
|
||||
INSTANCE_WR(ctx, 0x00000/4, nouveau_chip_instance_get(dev, ctx));
|
||||
INSTANCE_WR(ctx, 0x00000/4, ctx->im_pramin->start);
|
||||
INSTANCE_WR(ctx, 0x00024/4, 0x0000ffff);
|
||||
INSTANCE_WR(ctx, 0x00028/4, 0x0000ffff);
|
||||
INSTANCE_WR(ctx, 0x00030/4, 0x00000001);
|
||||
|
@ -1117,12 +1117,12 @@ nv4c_graph_context_init(drm_device_t *dev, struct mem_block *ctx)
|
|||
}
|
||||
|
||||
static void
|
||||
nv4e_graph_context_init(drm_device_t *dev, struct mem_block *ctx)
|
||||
nv4e_graph_context_init(drm_device_t *dev, nouveau_gpuobj_t *ctx)
|
||||
{
|
||||
drm_nouveau_private_t *dev_priv = dev->dev_private;
|
||||
int i;
|
||||
|
||||
INSTANCE_WR(ctx, 0x00000/4, nouveau_chip_instance_get(dev, ctx));
|
||||
INSTANCE_WR(ctx, 0x00000/4, ctx->im_pramin->start);
|
||||
INSTANCE_WR(ctx, 0x00024/4, 0x0000ffff);
|
||||
INSTANCE_WR(ctx, 0x00028/4, 0x0000ffff);
|
||||
INSTANCE_WR(ctx, 0x00030/4, 0x00000001);
|
||||
|
@ -1229,9 +1229,9 @@ nv40_graph_create_context(drm_device_t *dev, int channel)
|
|||
drm_nouveau_private_t *dev_priv =
|
||||
(drm_nouveau_private_t *)dev->dev_private;
|
||||
struct nouveau_fifo *chan = &dev_priv->fifos[channel];
|
||||
void (*ctx_init)(drm_device_t *, struct mem_block *);
|
||||
void (*ctx_init)(drm_device_t *, nouveau_gpuobj_t *);
|
||||
unsigned int ctx_size;
|
||||
int i;
|
||||
int ret;
|
||||
|
||||
switch (dev_priv->chipset) {
|
||||
case 0x40:
|
||||
|
@ -1272,15 +1272,13 @@ nv40_graph_create_context(drm_device_t *dev, int channel)
|
|||
break;
|
||||
}
|
||||
|
||||
/* Alloc and clear RAMIN to store the context */
|
||||
chan->ramin_grctx = nouveau_instmem_alloc(dev, ctx_size, 4);
|
||||
if (!chan->ramin_grctx)
|
||||
return DRM_ERR(ENOMEM);
|
||||
for (i=0; i<ctx_size; i+=4)
|
||||
INSTANCE_WR(chan->ramin_grctx, i/4, 0x00000000);
|
||||
if ((ret = nouveau_gpuobj_new_ref(dev, channel, -1, 0, ctx_size, 16,
|
||||
NVOBJ_FLAG_ZERO_ALLOC,
|
||||
&chan->ramin_grctx)))
|
||||
return ret;
|
||||
|
||||
/* Initialise default context values */
|
||||
ctx_init(dev, chan->ramin_grctx);
|
||||
ctx_init(dev, chan->ramin_grctx->gpuobj);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1291,10 +1289,8 @@ nv40_graph_destroy_context(drm_device_t *dev, int channel)
|
|||
drm_nouveau_private_t *dev_priv = dev->dev_private;
|
||||
struct nouveau_fifo *chan = &dev_priv->fifos[channel];
|
||||
|
||||
if (chan->ramin_grctx) {
|
||||
nouveau_instmem_free(dev, chan->ramin_grctx);
|
||||
chan->ramin_grctx = NULL;
|
||||
}
|
||||
if (chan->ramin_grctx)
|
||||
nouveau_gpuobj_ref_del(dev, &chan->ramin_grctx);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -1339,7 +1335,7 @@ nv40_graph_save_context(drm_device_t *dev, int channel)
|
|||
|
||||
if (!chan->ramin_grctx)
|
||||
return DRM_ERR(EINVAL);
|
||||
inst = nouveau_chip_instance_get(dev, chan->ramin_grctx);
|
||||
inst = chan->ramin_grctx->instance >> 4;
|
||||
|
||||
return nv40_graph_transfer_context(dev, inst, 1);
|
||||
}
|
||||
|
@ -1357,7 +1353,7 @@ nv40_graph_load_context(drm_device_t *dev, int channel)
|
|||
|
||||
if (!chan->ramin_grctx)
|
||||
return DRM_ERR(EINVAL);
|
||||
inst = nouveau_chip_instance_get(dev, chan->ramin_grctx);
|
||||
inst = chan->ramin_grctx->instance >> 4;
|
||||
|
||||
ret = nv40_graph_transfer_context(dev, inst, 0);
|
||||
if (ret)
|
||||
|
|
Loading…
Reference in New Issue