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/nv20_graph.c | 53 ++++++++++++++++++++++++------------------------ 1 file changed, 26 insertions(+), 27 deletions(-) (limited to 'shared-core/nv20_graph.c') diff --git a/shared-core/nv20_graph.c b/shared-core/nv20_graph.c index 1b8a6727..13271051 100644 --- a/shared-core/nv20_graph.c +++ b/shared-core/nv20_graph.c @@ -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; 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 */ - 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); - - 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); //XXX need to be done and save/restore for each fifo ??? nv20_graph_rdi(dev); -- cgit v1.2.3