From 5d55b0655cb480b7d6ab4cf2467dac6dc6d8df25 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 24 Jun 2007 18:58:38 +1000 Subject: nouveau: NV3X PGRAPH engtab functions --- shared-core/nv30_graph.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 65 insertions(+), 1 deletion(-) (limited to 'shared-core/nv30_graph.c') diff --git a/shared-core/nv30_graph.c b/shared-core/nv30_graph.c index f4faadd8..9f064a0a 100644 --- a/shared-core/nv30_graph.c +++ b/shared-core/nv30_graph.c @@ -100,7 +100,7 @@ static void nv30_graph_context_init(drm_device_t *dev, struct mem_block *ctx) } -int nv30_graph_context_create(drm_device_t *dev, int channel) +int nv30_graph_create_context(drm_device_t *dev, int channel) { drm_nouveau_private_t *dev_priv = (drm_nouveau_private_t *)dev->dev_private; @@ -132,6 +132,70 @@ int nv30_graph_context_create(drm_device_t *dev, int channel) return 0; } +void nv30_graph_destroy_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]; + + if (chan->ramin_grctx) { + nouveau_instmem_free(dev, chan->ramin_grctx); + chan->ramin_grctx = NULL; + } + + INSTANCE_WR(dev_priv->ctx_table, channel, 0); +} + +static int +nouveau_graph_wait_idle(drm_device_t *dev) +{ + drm_nouveau_private_t *dev_priv = dev->dev_private; + int tv = 1000; + + while (tv--) { + if (NV_READ(0x400700) == 0) + break; + } + + if (NV_READ(0x400700)) { + DRM_ERROR("timeout!\n"); + return DRM_ERR(EBUSY); + } + return 0; +} + +int nv30_graph_load_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 inst; + + if (!chan->ramin_grctx) + return DRM_ERR(EINVAL); + inst = nouveau_chip_instance_get(dev, chan->ramin_grctx); + + NV_WRITE(0x400784, inst); + NV_WRITE(0x400788, 1); + + return nouveau_graph_wait_idle(dev); +} + +int nv30_graph_save_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 inst; + + if (!chan->ramin_grctx) + return DRM_ERR(EINVAL); + inst = nouveau_chip_instance_get(dev, chan->ramin_grctx); + + NV_WRITE(0x400784, inst); + NV_WRITE(0x400788, 2); + + return nouveau_graph_wait_idle(dev); +} + int nv30_graph_init(drm_device_t *dev) { drm_nouveau_private_t *dev_priv = -- cgit v1.2.3 From 38617b6a26d893bbd7b235019159e609f6cdd84b Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 25 Jun 2007 03:52:06 +1000 Subject: nouveau: name some regs --- shared-core/nv30_graph.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'shared-core/nv30_graph.c') diff --git a/shared-core/nv30_graph.c b/shared-core/nv30_graph.c index 9f064a0a..7a87990a 100644 --- a/shared-core/nv30_graph.c +++ b/shared-core/nv30_graph.c @@ -174,8 +174,9 @@ int nv30_graph_load_context(drm_device_t *dev, int channel) return DRM_ERR(EINVAL); inst = nouveau_chip_instance_get(dev, chan->ramin_grctx); - NV_WRITE(0x400784, inst); - NV_WRITE(0x400788, 1); + NV_WRITE(NV20_PGRAPH_CHANNEL_CTX_POINTER, inst); + NV_WRITE(NV20_PGRAPH_CHANNEL_CTX_XFER, + NV20_PGRAPH_CHANNEL_CTX_XFER_LOAD); return nouveau_graph_wait_idle(dev); } @@ -190,8 +191,9 @@ int nv30_graph_save_context(drm_device_t *dev, int channel) return DRM_ERR(EINVAL); inst = nouveau_chip_instance_get(dev, chan->ramin_grctx); - NV_WRITE(0x400784, inst); - NV_WRITE(0x400788, 2); + NV_WRITE(NV20_PGRAPH_CHANNEL_CTX_POINTER, inst); + NV_WRITE(NV20_PGRAPH_CHANNEL_CTX_XFER, + NV20_PGRAPH_CHANNEL_CTX_XFER_SAVE); return nouveau_graph_wait_idle(dev); } -- cgit v1.2.3 From 163f8526123ffa38783fc911b5f7a19debce7f73 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 2 Jul 2007 19:31:18 +1000 Subject: 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. --- shared-core/nv30_graph.c | 53 +++++++++++++++++++++++------------------------- 1 file changed, 25 insertions(+), 28 deletions(-) (limited to 'shared-core/nv30_graph.c') diff --git a/shared-core/nv30_graph.c b/shared-core/nv30_graph.c index 7a87990a..65f4f868 100644 --- a/shared-core/nv30_graph.c +++ b/shared-core/nv30_graph.c @@ -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; iramin_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); - - 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)); + 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; + + 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); -- cgit v1.2.3 From c806bba4665bb369168ee0b453fa28e2e0bf2a5d Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 5 Jul 2007 00:12:33 +1000 Subject: nouveau/nv50: Initial channel/object support Should be OK on G84 for a single channel, multiple channels *almost* work. Untested on G80. --- shared-core/nv30_graph.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'shared-core/nv30_graph.c') diff --git a/shared-core/nv30_graph.c b/shared-core/nv30_graph.c index 65f4f868..a83ad714 100644 --- a/shared-core/nv30_graph.c +++ b/shared-core/nv30_graph.c @@ -104,7 +104,7 @@ 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]; + struct nouveau_fifo *chan = dev_priv->fifos[channel]; void (*ctx_init)(drm_device_t *, nouveau_gpuobj_t *); unsigned int ctx_size; int ret; @@ -135,7 +135,7 @@ void nv30_graph_destroy_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]; + struct nouveau_fifo *chan = dev_priv->fifos[channel]; if (chan->ramin_grctx) nouveau_gpuobj_ref_del(dev, &chan->ramin_grctx); @@ -164,7 +164,7 @@ nouveau_graph_wait_idle(drm_device_t *dev) int nv30_graph_load_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_fifo *chan = dev_priv->fifos[channel]; uint32_t inst; if (!chan->ramin_grctx) @@ -181,7 +181,7 @@ int nv30_graph_load_context(drm_device_t *dev, int channel) int nv30_graph_save_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_fifo *chan = dev_priv->fifos[channel]; uint32_t inst; if (!chan->ramin_grctx) -- cgit v1.2.3