From beaa0c9a28b30a6ba3292184d04875b6a597e433 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 6 Aug 2007 03:40:43 +1000 Subject: nouveau: Pass channel struct around instead of channel id. --- shared-core/nouveau_fifo.c | 104 ++++++++++++++++++++++----------------------- 1 file changed, 50 insertions(+), 54 deletions(-) (limited to 'shared-core/nouveau_fifo.c') diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c index e5d3ab3c..c7ce1d8d 100644 --- a/shared-core/nouveau_fifo.c +++ b/shared-core/nouveau_fifo.c @@ -186,10 +186,10 @@ int nouveau_fifo_init(struct drm_device *dev) } static int -nouveau_fifo_cmdbuf_alloc(struct drm_device *dev, int channel) +nouveau_fifo_cmdbuf_alloc(struct nouveau_channel *chan) { + struct drm_device *dev = chan->dev; struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_fifo *chan = dev_priv->fifos[channel]; struct nouveau_config *config = &dev_priv->config; struct mem_block *cb; int cb_min_size = max(NV03_FIFO_SIZE,PAGE_SIZE); @@ -211,37 +211,34 @@ nouveau_fifo_cmdbuf_alloc(struct drm_device *dev, int channel) } if (cb->flags & NOUVEAU_MEM_AGP) { - ret = nouveau_gpuobj_gart_dma_new(dev, channel, - cb->start, cb->size, + ret = nouveau_gpuobj_gart_dma_new(chan, cb->start, cb->size, NV_DMA_ACCESS_RO, &pushbuf, &chan->pushbuf_base); } else if (cb->flags & NOUVEAU_MEM_PCI) { - ret = nouveau_gpuobj_dma_new(dev, channel, - NV_CLASS_DMA_IN_MEMORY, + ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, cb->start, cb->size, NV_DMA_ACCESS_RO, NV_DMA_TARGET_PCI_NONLINEAR, &pushbuf); chan->pushbuf_base = 0; } else if (dev_priv->card_type != NV_04) { - ret = nouveau_gpuobj_dma_new - (dev, channel, NV_CLASS_DMA_IN_MEMORY, - cb->start, - cb->size, NV_DMA_ACCESS_RO, NV_DMA_TARGET_VIDMEM, - &pushbuf); + ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, + cb->start, cb->size, + NV_DMA_ACCESS_RO, + NV_DMA_TARGET_VIDMEM, &pushbuf); chan->pushbuf_base = 0; } else { /* NV04 cmdbuf hack, from original ddx.. not sure of it's * exact reason for existing :) PCI access to cmdbuf in * VRAM. */ - 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_PCI, &pushbuf); + ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, + cb->start + + drm_get_resource_start(dev, 1), + cb->size, NV_DMA_ACCESS_RO, + NV_DMA_TARGET_PCI, &pushbuf); chan->pushbuf_base = 0; } @@ -251,7 +248,7 @@ nouveau_fifo_cmdbuf_alloc(struct drm_device *dev, int channel) return ret; } - if ((ret = nouveau_gpuobj_ref_add(dev, channel, 0, pushbuf, + if ((ret = nouveau_gpuobj_ref_add(dev, chan, 0, pushbuf, &chan->pushbuf))) { DRM_ERROR("Error referencing push buffer ctxdma: %d\n", ret); if (pushbuf != dev_priv->gart_info.sg_ctxdma) @@ -270,8 +267,8 @@ int nouveau_fifo_alloc(struct drm_device *dev, int *chan_ret, { int ret; struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_engine_func *engine = &dev_priv->Engine; - struct nouveau_fifo *chan; + struct nouveau_engine *engine = &dev_priv->Engine; + struct nouveau_channel *chan; int channel; /* @@ -293,34 +290,36 @@ int nouveau_fifo_alloc(struct drm_device *dev, int *chan_ret, return -EINVAL; (*chan_ret) = channel; - dev_priv->fifos[channel] = drm_calloc(1, sizeof(struct nouveau_fifo), + dev_priv->fifos[channel] = drm_calloc(1, sizeof(struct nouveau_channel), DRM_MEM_DRIVER); if (!dev_priv->fifos[channel]) return -ENOMEM; dev_priv->fifo_alloc_count++; chan = dev_priv->fifos[channel]; + chan->dev = dev; + chan->id = channel; chan->file_priv = file_priv; DRM_INFO("Allocating FIFO number %d\n", channel); /* Setup channel's default objects */ - ret = nouveau_gpuobj_channel_init(dev, channel, vram_handle, tt_handle); + ret = nouveau_gpuobj_channel_init(chan, vram_handle, tt_handle); if (ret) { - nouveau_fifo_free(dev, channel); + nouveau_fifo_free(chan); return ret; } /* allocate a command buffer, and create a dma object for the gpu */ - ret = nouveau_fifo_cmdbuf_alloc(dev, channel); + ret = nouveau_fifo_cmdbuf_alloc(chan); if (ret) { - nouveau_fifo_free(dev, channel); + nouveau_fifo_free(chan); return ret; } /* Allocate space for per-channel fixed notifier memory */ - ret = nouveau_notifier_init_channel(dev, channel, file_priv); + ret = nouveau_notifier_init_channel(chan); if (ret) { - nouveau_fifo_free(dev, channel); + nouveau_fifo_free(chan); return ret; } @@ -333,16 +332,16 @@ int nouveau_fifo_alloc(struct drm_device *dev, int *chan_ret, NV_WRITE(NV04_PFIFO_CACHE1_PULL0, 0x00000000); /* Create a graphics context for new channel */ - ret = engine->graph.create_context(dev, channel); + ret = engine->graph.create_context(chan); if (ret) { - nouveau_fifo_free(dev, channel); + nouveau_fifo_free(chan); return ret; } /* Construct inital RAMFC for new channel */ - ret = engine->fifo.create_context(dev, channel); + ret = engine->fifo.create_context(chan); if (ret) { - nouveau_fifo_free(dev, channel); + nouveau_fifo_free(chan); return ret; } @@ -359,15 +358,15 @@ int nouveau_fifo_alloc(struct drm_device *dev, int *chan_ret, * other case, the GPU will handle this when it switches contexts. */ if (dev_priv->fifo_alloc_count == 1) { - ret = engine->fifo.load_context(dev, channel); + ret = engine->fifo.load_context(chan); if (ret) { - nouveau_fifo_free(dev, channel); + nouveau_fifo_free(chan); return ret; } - ret = engine->graph.load_context(dev, channel); + ret = engine->graph.load_context(chan); if (ret) { - nouveau_fifo_free(dev, channel); + nouveau_fifo_free(chan); return ret; } @@ -399,28 +398,23 @@ int nouveau_fifo_alloc(struct drm_device *dev, int *chan_ret, } /* stops a fifo */ -void nouveau_fifo_free(struct drm_device *dev, int channel) +void nouveau_fifo_free(struct nouveau_channel *chan) { + struct drm_device *dev = chan->dev; struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_engine_func *engine = &dev_priv->Engine; - struct nouveau_fifo *chan = dev_priv->fifos[channel]; - - if (!chan) { - DRM_ERROR("Freeing non-existant channel %d\n", channel); - return; - } + struct nouveau_engine *engine = &dev_priv->Engine; - DRM_INFO("%s: freeing fifo %d\n", __func__, channel); + DRM_INFO("%s: freeing fifo %d\n", __func__, chan->id); /* disable the fifo caches */ NV_WRITE(NV03_PFIFO_CACHES, 0x00000000); // FIXME XXX needs more code - engine->fifo.destroy_context(dev, channel); + engine->fifo.destroy_context(chan); /* Cleanup PGRAPH state */ - engine->graph.destroy_context(dev, channel); + engine->graph.destroy_context(chan); /* reenable the fifo caches */ NV_WRITE(NV03_PFIFO_CACHES, 0x00000001); @@ -432,12 +426,12 @@ void nouveau_fifo_free(struct drm_device *dev, int channel) chan->pushbuf_mem = NULL; } - nouveau_notifier_takedown_channel(dev, channel); + nouveau_notifier_takedown_channel(chan); /* Destroy objects belonging to the channel */ - nouveau_gpuobj_channel_takedown(dev, channel); + nouveau_gpuobj_channel_takedown(chan); - dev_priv->fifos[channel] = NULL; + dev_priv->fifos[chan->id] = NULL; dev_priv->fifo_alloc_count--; drm_free(chan, sizeof(*chan), DRM_MEM_DRIVER); } @@ -445,14 +439,16 @@ void nouveau_fifo_free(struct drm_device *dev, int channel) /* cleanups all the fifos from file_priv */ void nouveau_fifo_cleanup(struct drm_device *dev, struct drm_file *file_priv) { - int i; struct drm_nouveau_private *dev_priv = dev->dev_private; + int i; DRM_DEBUG("clearing FIFO enables from file_priv\n"); - for(i=0;ififos[i] && - dev_priv->fifos[i]->file_priv==file_priv) - nouveau_fifo_free(dev,i); + for(i = 0; i < nouveau_fifo_number(dev); i++) { + struct nouveau_channel *chan = dev_priv->fifos[i]; + + if (chan && chan->file_priv == file_priv) + nouveau_fifo_free(chan); + } } int @@ -477,7 +473,7 @@ static int nouveau_ioctl_fifo_alloc(struct drm_device *dev, void *data, struct d struct drm_nouveau_private *dev_priv = dev->dev_private; struct drm_nouveau_fifo_alloc *init = data; struct drm_map_list *entry; - struct nouveau_fifo *chan; + struct nouveau_channel *chan; int res; if (init->fb_ctxdma_handle == ~0 || init->tt_ctxdma_handle == ~0) -- cgit v1.2.3 From 97770db72040dc032130413e0cdabc1777560a75 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 6 Aug 2007 21:45:18 +1000 Subject: nouveau: Various internal and external API changes 1. DRM_NOUVEAU_GPUOBJ_FREE Used to free GPU objects. The obvious usage case is for Gr objects, but notifiers can also be destroyed in the same way. GPU objects gain a destructor method and private data fields with this change, so other specialised cases (like notifiers) can be implemented on top of gpuobjs. 2. DRM_NOUVEAU_CHANNEL_FREE 3. DRM_NOUVEAU_CARD_INIT Ideally we'd do init during module load, but this isn't currently possible. Doing init during firstopen() is bad as X has a love of opening/closing the DRM many times during startup. Once the modesetting-101 branch is merged this can go away. IRQs are enabled in nouveau_card_init() now, rather than having the X server call drmCtlInstHandler(). We'll need this for when we give the kernel module its own channel. 4. DRM_NOUVEAU_GETPARAM Add CHIPSET_ID value, which will return the chipset id derived from NV_PMC_BOOT_0. 4. Use list_* in a few places, rather than home-brewed stuff. --- shared-core/nouveau_fifo.c | 47 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 33 insertions(+), 14 deletions(-) (limited to 'shared-core/nouveau_fifo.c') diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c index c7ce1d8d..152b669a 100644 --- a/shared-core/nouveau_fifo.c +++ b/shared-core/nouveau_fifo.c @@ -302,22 +302,22 @@ int nouveau_fifo_alloc(struct drm_device *dev, int *chan_ret, DRM_INFO("Allocating FIFO number %d\n", channel); - /* Setup channel's default objects */ - ret = nouveau_gpuobj_channel_init(chan, vram_handle, tt_handle); + /* Allocate space for per-channel fixed notifier memory */ + ret = nouveau_notifier_init_channel(chan); if (ret) { nouveau_fifo_free(chan); return ret; } - /* allocate a command buffer, and create a dma object for the gpu */ - ret = nouveau_fifo_cmdbuf_alloc(chan); + /* Setup channel's default objects */ + ret = nouveau_gpuobj_channel_init(chan, vram_handle, tt_handle); if (ret) { nouveau_fifo_free(chan); return ret; } - /* Allocate space for per-channel fixed notifier memory */ - ret = nouveau_notifier_init_channel(chan); + /* allocate a command buffer, and create a dma object for the gpu */ + ret = nouveau_fifo_cmdbuf_alloc(chan); if (ret) { nouveau_fifo_free(chan); return ret; @@ -426,11 +426,11 @@ void nouveau_fifo_free(struct nouveau_channel *chan) chan->pushbuf_mem = NULL; } - nouveau_notifier_takedown_channel(chan); - /* Destroy objects belonging to the channel */ nouveau_gpuobj_channel_takedown(chan); + nouveau_notifier_takedown_channel(chan); + dev_priv->fifos[chan->id] = NULL; dev_priv->fifo_alloc_count--; drm_free(chan, sizeof(*chan), DRM_MEM_DRIVER); @@ -468,14 +468,17 @@ nouveau_fifo_owner(struct drm_device *dev, struct drm_file *file_priv, * ioctls wrapping the functions ***********************************/ -static int nouveau_ioctl_fifo_alloc(struct drm_device *dev, void *data, struct drm_file *file_priv) +static int nouveau_ioctl_fifo_alloc(struct drm_device *dev, void *data, + struct drm_file *file_priv) { struct drm_nouveau_private *dev_priv = dev->dev_private; - struct drm_nouveau_fifo_alloc *init = data; + struct drm_nouveau_channel_alloc *init = data; struct drm_map_list *entry; struct nouveau_channel *chan; int res; + NOUVEAU_CHECK_INITIALISED_WITH_RETURN; + if (init->fb_ctxdma_handle == ~0 || init->tt_ctxdma_handle == ~0) return -EINVAL; @@ -519,18 +522,34 @@ static int nouveau_ioctl_fifo_alloc(struct drm_device *dev, void *data, struct d return 0; } +static int nouveau_ioctl_fifo_free(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + struct drm_nouveau_channel_free *cfree = data; + struct nouveau_channel *chan; + + NOUVEAU_CHECK_INITIALISED_WITH_RETURN; + NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(cfree->channel, file_priv, chan); + + nouveau_fifo_free(chan); + return 0; +} + /*********************************** * finally, the ioctl table ***********************************/ struct drm_ioctl_desc nouveau_ioctls[] = { - DRM_IOCTL_DEF(DRM_NOUVEAU_FIFO_ALLOC, nouveau_ioctl_fifo_alloc, DRM_AUTH), + DRM_IOCTL_DEF(DRM_NOUVEAU_CARD_INIT, nouveau_ioctl_card_init, DRM_AUTH), + DRM_IOCTL_DEF(DRM_NOUVEAU_GETPARAM, nouveau_ioctl_getparam, DRM_AUTH), + DRM_IOCTL_DEF(DRM_NOUVEAU_SETPARAM, nouveau_ioctl_setparam, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), + DRM_IOCTL_DEF(DRM_NOUVEAU_CHANNEL_ALLOC, nouveau_ioctl_fifo_alloc, DRM_AUTH), + DRM_IOCTL_DEF(DRM_NOUVEAU_CHANNEL_FREE, nouveau_ioctl_fifo_free, DRM_AUTH), DRM_IOCTL_DEF(DRM_NOUVEAU_GROBJ_ALLOC, nouveau_ioctl_grobj_alloc, DRM_AUTH), - DRM_IOCTL_DEF(DRM_NOUVEAU_NOTIFIER_ALLOC, nouveau_ioctl_notifier_alloc, DRM_AUTH), + DRM_IOCTL_DEF(DRM_NOUVEAU_NOTIFIEROBJ_ALLOC, nouveau_ioctl_notifier_alloc, DRM_AUTH), + DRM_IOCTL_DEF(DRM_NOUVEAU_GPUOBJ_FREE, nouveau_ioctl_gpuobj_free, DRM_AUTH), DRM_IOCTL_DEF(DRM_NOUVEAU_MEM_ALLOC, nouveau_ioctl_mem_alloc, DRM_AUTH), DRM_IOCTL_DEF(DRM_NOUVEAU_MEM_FREE, nouveau_ioctl_mem_free, DRM_AUTH), - DRM_IOCTL_DEF(DRM_NOUVEAU_GETPARAM, nouveau_ioctl_getparam, DRM_AUTH), - DRM_IOCTL_DEF(DRM_NOUVEAU_SETPARAM, nouveau_ioctl_setparam, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), }; int nouveau_max_ioctl = DRM_ARRAY_SIZE(nouveau_ioctls); -- cgit v1.2.3 From cf04641bc61c8bc18101713a8d95ef98e6afae7f Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 6 Aug 2007 22:05:31 +1000 Subject: nouveau: Give DRM its own gpu channel If your card doesn't have working context switching, it is now broken. --- shared-core/nouveau_fifo.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'shared-core/nouveau_fifo.c') diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c index 152b669a..823801f9 100644 --- a/shared-core/nouveau_fifo.c +++ b/shared-core/nouveau_fifo.c @@ -261,9 +261,10 @@ nouveau_fifo_cmdbuf_alloc(struct nouveau_channel *chan) } /* allocates and initializes a fifo for user space consumption */ -int nouveau_fifo_alloc(struct drm_device *dev, int *chan_ret, - struct drm_file *file_priv, - uint32_t vram_handle, uint32_t tt_handle) +int +nouveau_fifo_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret, + struct drm_file *file_priv, + uint32_t vram_handle, uint32_t tt_handle) { int ret; struct drm_nouveau_private *dev_priv = dev->dev_private; @@ -288,7 +289,6 @@ int nouveau_fifo_alloc(struct drm_device *dev, int *chan_ret, /* no more fifos. you lost. */ if (channel==nouveau_fifo_number(dev)) return -EINVAL; - (*chan_ret) = channel; dev_priv->fifos[channel] = drm_calloc(1, sizeof(struct nouveau_channel), DRM_MEM_DRIVER); @@ -394,6 +394,7 @@ int nouveau_fifo_alloc(struct drm_device *dev, int *chan_ret, NV_WRITE(NV03_PFIFO_CACHES, 1); DRM_INFO("%s: initialised FIFO %d\n", __func__, channel); + *chan_ret = chan; return 0; } @@ -482,13 +483,12 @@ static int nouveau_ioctl_fifo_alloc(struct drm_device *dev, void *data, if (init->fb_ctxdma_handle == ~0 || init->tt_ctxdma_handle == ~0) return -EINVAL; - res = nouveau_fifo_alloc(dev, &init->channel, file_priv, + res = nouveau_fifo_alloc(dev, &chan, file_priv, init->fb_ctxdma_handle, init->tt_ctxdma_handle); if (res) return res; - chan = dev_priv->fifos[init->channel]; - + init->channel = chan->id; init->put_base = chan->pushbuf_base; /* make the fifo available to user space */ -- cgit v1.2.3 From 7a0a812ea42d80eed89b7b9993eae42c7c1b1613 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 6 Aug 2007 22:06:52 +1000 Subject: nouveau: Remove PGRAPH_SURFACE hack, it wont work now anyway. Need to find another way of doing this, ideally someone'd hunt down which object/method controls it! The Xv blit adaptor is likely now broken on cards that have pNv->WaitVSyncPossible enabled. --- shared-core/nouveau_fifo.c | 13 ------------- 1 file changed, 13 deletions(-) (limited to 'shared-core/nouveau_fifo.c') diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c index 823801f9..fd21d2f3 100644 --- a/shared-core/nouveau_fifo.c +++ b/shared-core/nouveau_fifo.c @@ -369,19 +369,6 @@ nouveau_fifo_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret, nouveau_fifo_free(chan); return ret; } - - /* Temporary hack, to avoid breaking Xv on cards where the - * initial context value for 0x400710 doesn't have these bits - * set. Proper fix would be to find which object+method is - * responsible for modifying this state. - */ - if (dev_priv->chipset >= 0x10 && dev_priv->chipset < 0x50) { - uint32_t tmp; - tmp = NV_READ(NV10_PGRAPH_SURFACE) & 0x0007ff00; - NV_WRITE(NV10_PGRAPH_SURFACE, tmp); - tmp = NV_READ(NV10_PGRAPH_SURFACE) | 0x00020100; - NV_WRITE(NV10_PGRAPH_SURFACE, tmp); - } } NV_WRITE(NV04_PFIFO_CACHE1_DMA_PUSH, -- cgit v1.2.3 From 4ad487190d5b79947c65e238330506db6b77e523 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 8 Aug 2007 10:42:12 +1000 Subject: nouveau: enable/disable engine-specific interrupts in _init()/_takedown() All interrupts are still masked by PMC until init is finished. --- shared-core/nouveau_fifo.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'shared-core/nouveau_fifo.c') diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c index fd21d2f3..f9677514 100644 --- a/shared-core/nouveau_fifo.c +++ b/shared-core/nouveau_fifo.c @@ -120,6 +120,10 @@ int nouveau_fifo_init(struct drm_device *dev) NV_WRITE(NV03_PMC_ENABLE, NV_READ(NV03_PMC_ENABLE) | NV_PMC_ENABLE_PFIFO); + /* Enable PFIFO error reporting */ + NV_WRITE(NV03_PFIFO_INTR_0, 0xFFFFFFFF); + NV_WRITE(NV03_PFIFO_INTR_EN_0, 0xFFFFFFFF); + NV_WRITE(NV03_PFIFO_CACHES, 0x00000000); ret = nouveau_fifo_instmem_configure(dev); -- cgit v1.2.3 From 05633ca3708f48cfbbb77518da4e791d7e1613c2 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 8 Aug 2007 16:37:55 +1000 Subject: nouveau: Always allocate drm's push buffer in VRAM Fixes #11868 --- shared-core/nouveau_fifo.c | 78 +++++++++++++++++++++++++--------------------- 1 file changed, 42 insertions(+), 36 deletions(-) (limited to 'shared-core/nouveau_fifo.c') diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c index f9677514..22bced14 100644 --- a/shared-core/nouveau_fifo.c +++ b/shared-core/nouveau_fifo.c @@ -190,46 +190,30 @@ int nouveau_fifo_init(struct drm_device *dev) } static int -nouveau_fifo_cmdbuf_alloc(struct nouveau_channel *chan) +nouveau_fifo_pushbuf_ctxdma_init(struct nouveau_channel *chan) { struct drm_device *dev = chan->dev; struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_config *config = &dev_priv->config; - struct mem_block *cb; - int cb_min_size = max(NV03_FIFO_SIZE,PAGE_SIZE); + struct mem_block *pb = chan->pushbuf_mem; struct nouveau_gpuobj *pushbuf = NULL; int ret; - /* Defaults for unconfigured values */ - if (!config->cmdbuf.location) - config->cmdbuf.location = NOUVEAU_MEM_FB; - if (!config->cmdbuf.size || config->cmdbuf.size < cb_min_size) - config->cmdbuf.size = cb_min_size; - - cb = nouveau_mem_alloc(dev, 0, config->cmdbuf.size, - config->cmdbuf.location | NOUVEAU_MEM_MAPPED, - (struct drm_file *)-2); - if (!cb) { - DRM_ERROR("Couldn't allocate DMA command buffer.\n"); - return -ENOMEM; - } - - if (cb->flags & NOUVEAU_MEM_AGP) { - ret = nouveau_gpuobj_gart_dma_new(chan, cb->start, cb->size, + if (pb->flags & NOUVEAU_MEM_AGP) { + ret = nouveau_gpuobj_gart_dma_new(chan, pb->start, pb->size, NV_DMA_ACCESS_RO, &pushbuf, &chan->pushbuf_base); } else - if (cb->flags & NOUVEAU_MEM_PCI) { + if (pb->flags & NOUVEAU_MEM_PCI) { ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, - cb->start, cb->size, + pb->start, pb->size, NV_DMA_ACCESS_RO, NV_DMA_TARGET_PCI_NONLINEAR, &pushbuf); chan->pushbuf_base = 0; } else if (dev_priv->card_type != NV_04) { ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, - cb->start, cb->size, + pb->start, pb->size, NV_DMA_ACCESS_RO, NV_DMA_TARGET_VIDMEM, &pushbuf); chan->pushbuf_base = 0; @@ -239,19 +223,13 @@ nouveau_fifo_cmdbuf_alloc(struct nouveau_channel *chan) * VRAM. */ ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, - cb->start + + pb->start + drm_get_resource_start(dev, 1), - cb->size, NV_DMA_ACCESS_RO, + pb->size, NV_DMA_ACCESS_RO, NV_DMA_TARGET_PCI, &pushbuf); chan->pushbuf_base = 0; } - if (ret) { - nouveau_mem_free(dev, cb); - DRM_ERROR("Error creating push buffer ctxdma: %d\n", ret); - return ret; - } - if ((ret = nouveau_gpuobj_ref_add(dev, chan, 0, pushbuf, &chan->pushbuf))) { DRM_ERROR("Error referencing push buffer ctxdma: %d\n", ret); @@ -260,14 +238,36 @@ nouveau_fifo_cmdbuf_alloc(struct nouveau_channel *chan) return ret; } - chan->pushbuf_mem = cb; return 0; } +static struct mem_block * +nouveau_fifo_user_pushbuf_alloc(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_config *config = &dev_priv->config; + struct mem_block *pb; + int pb_min_size = max(NV03_FIFO_SIZE,PAGE_SIZE); + + /* Defaults for unconfigured values */ + if (!config->cmdbuf.location) + config->cmdbuf.location = NOUVEAU_MEM_FB; + if (!config->cmdbuf.size || config->cmdbuf.size < pb_min_size) + config->cmdbuf.size = pb_min_size; + + pb = nouveau_mem_alloc(dev, 0, config->cmdbuf.size, + config->cmdbuf.location | NOUVEAU_MEM_MAPPED, + (struct drm_file *)-2); + if (!pb) + DRM_ERROR("Couldn't allocate DMA push buffer.\n"); + + return pb; +} + /* allocates and initializes a fifo for user space consumption */ int nouveau_fifo_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret, - struct drm_file *file_priv, + struct drm_file *file_priv, struct mem_block *pushbuf, uint32_t vram_handle, uint32_t tt_handle) { int ret; @@ -303,6 +303,7 @@ nouveau_fifo_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret, chan->dev = dev; chan->id = channel; chan->file_priv = file_priv; + chan->pushbuf_mem = pushbuf; DRM_INFO("Allocating FIFO number %d\n", channel); @@ -320,8 +321,8 @@ nouveau_fifo_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret, return ret; } - /* allocate a command buffer, and create a dma object for the gpu */ - ret = nouveau_fifo_cmdbuf_alloc(chan); + /* Create a dma object for the push buffer */ + ret = nouveau_fifo_pushbuf_ctxdma_init(chan); if (ret) { nouveau_fifo_free(chan); return ret; @@ -467,6 +468,7 @@ static int nouveau_ioctl_fifo_alloc(struct drm_device *dev, void *data, struct drm_nouveau_channel_alloc *init = data; struct drm_map_list *entry; struct nouveau_channel *chan; + struct mem_block *pushbuf; int res; NOUVEAU_CHECK_INITIALISED_WITH_RETURN; @@ -474,7 +476,11 @@ static int nouveau_ioctl_fifo_alloc(struct drm_device *dev, void *data, if (init->fb_ctxdma_handle == ~0 || init->tt_ctxdma_handle == ~0) return -EINVAL; - res = nouveau_fifo_alloc(dev, &chan, file_priv, + pushbuf = nouveau_fifo_user_pushbuf_alloc(dev); + if (!pushbuf) + return -ENOMEM; + + res = nouveau_fifo_alloc(dev, &chan, file_priv, pushbuf, init->fb_ctxdma_handle, init->tt_ctxdma_handle); if (res) -- cgit v1.2.3 From a46104674f129e873b8dfa29cf8aac9c67bd77be Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 10 Aug 2007 13:54:26 +1000 Subject: nouveau/nv50: demagic instmem setup. --- shared-core/nouveau_fifo.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'shared-core/nouveau_fifo.c') diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c index 22bced14..f0c2a556 100644 --- a/shared-core/nouveau_fifo.c +++ b/shared-core/nouveau_fifo.c @@ -285,8 +285,6 @@ nouveau_fifo_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret, * When there are no more contexts, you lost */ for(channel=0; channelcard_type == NV_50) && (channel == 0)) - continue; if (dev_priv->fifos[channel] == NULL) break; } -- cgit v1.2.3 From 216f1b0573b2c0e39ac82c7f56235c1003e9bd4d Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 21 Aug 2007 02:18:27 +1000 Subject: nouveau: Poke 0x2230 on NV47 also. Makes 0x2220 work the same way as on NV40. --- shared-core/nouveau_fifo.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'shared-core/nouveau_fifo.c') diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c index f0c2a556..1aa724f1 100644 --- a/shared-core/nouveau_fifo.c +++ b/shared-core/nouveau_fifo.c @@ -84,9 +84,16 @@ static int nouveau_fifo_instmem_configure(struct drm_device *dev) { case NV_50: case NV_40: + switch (dev_priv->chipset) { + case 0x47: + case 0x49: + case 0x4b: + NV_WRITE(0x2230, 1); + break; + default: + break; + } NV_WRITE(NV40_PFIFO_RAMFC, 0x30002); - if((dev_priv->chipset == 0x49) || (dev_priv->chipset == 0x4b)) - NV_WRITE(0x2230,0x00000001); break; case NV_44: NV_WRITE(NV40_PFIFO_RAMFC, ((nouveau_mem_fb_amount(dev)-512*1024+dev_priv->ramfc_offset)>>16) | -- cgit v1.2.3 From 69b11f44f0a0cfe0806e18dae2f360bc1ed8e005 Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Thu, 30 Aug 2007 21:51:53 +0200 Subject: nouveau: give nv03 the last cut. --- shared-core/nouveau_fifo.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'shared-core/nouveau_fifo.c') diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c index 1aa724f1..437c84f2 100644 --- a/shared-core/nouveau_fifo.c +++ b/shared-core/nouveau_fifo.c @@ -34,8 +34,6 @@ int nouveau_fifo_number(struct drm_device *dev) struct drm_nouveau_private *dev_priv=dev->dev_private; switch(dev_priv->card_type) { - case NV_03: - return 8; case NV_04: case NV_05: return 16; @@ -109,7 +107,6 @@ static int nouveau_fifo_instmem_configure(struct drm_device *dev) case NV_11: case NV_10: case NV_04: - case NV_03: NV_WRITE(NV03_PFIFO_RAMFC, dev_priv->ramfc_offset>>8); break; } -- cgit v1.2.3