From 0029713451af6f5f216079775ff77cae9b423c0e Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 13 Jul 2007 15:09:31 +1000 Subject: nouveau: nuke internal typedefs, and drm_device_t use. --- shared-core/nouveau_object.c | 133 ++++++++++++++++++++++--------------------- 1 file changed, 67 insertions(+), 66 deletions(-) (limited to 'shared-core/nouveau_object.c') diff --git a/shared-core/nouveau_object.c b/shared-core/nouveau_object.c index 16b38e95..c5697d8e 100644 --- a/shared-core/nouveau_object.c +++ b/shared-core/nouveau_object.c @@ -66,9 +66,9 @@ is given as: */ static uint32_t -nouveau_ramht_hash_handle(drm_device_t *dev, int channel, uint32_t handle) +nouveau_ramht_hash_handle(struct drm_device *dev, int channel, uint32_t handle) { - drm_nouveau_private_t *dev_priv=dev->dev_private; + struct drm_nouveau_private *dev_priv=dev->dev_private; uint32_t hash = 0; int i; @@ -85,10 +85,10 @@ nouveau_ramht_hash_handle(drm_device_t *dev, int channel, uint32_t handle) } static int -nouveau_ramht_entry_valid(drm_device_t *dev, nouveau_gpuobj_t *ramht, +nouveau_ramht_entry_valid(struct drm_device *dev, struct nouveau_gpuobj *ramht, uint32_t offset) { - drm_nouveau_private_t *dev_priv=dev->dev_private; + struct drm_nouveau_private *dev_priv=dev->dev_private; uint32_t ctx = INSTANCE_RD(ramht, (offset + 4)/4); if (dev_priv->card_type < NV_40) @@ -97,12 +97,12 @@ nouveau_ramht_entry_valid(drm_device_t *dev, nouveau_gpuobj_t *ramht, } static int -nouveau_ramht_insert(drm_device_t* dev, nouveau_gpuobj_ref_t *ref) +nouveau_ramht_insert(struct drm_device *dev, struct nouveau_gpuobj_ref *ref) { - drm_nouveau_private_t *dev_priv=dev->dev_private; + struct drm_nouveau_private *dev_priv=dev->dev_private; struct nouveau_fifo *chan = dev_priv->fifos[ref->channel]; - nouveau_gpuobj_t *ramht = chan->ramht ? chan->ramht->gpuobj : NULL; - nouveau_gpuobj_t *gpuobj = ref->gpuobj; + struct nouveau_gpuobj *ramht = chan->ramht ? chan->ramht->gpuobj : NULL; + struct nouveau_gpuobj *gpuobj = ref->gpuobj; uint32_t ctx, co, ho; if (!ramht) { @@ -146,11 +146,11 @@ nouveau_ramht_insert(drm_device_t* dev, nouveau_gpuobj_ref_t *ref) } static void -nouveau_ramht_remove(drm_device_t* dev, nouveau_gpuobj_ref_t *ref) +nouveau_ramht_remove(struct drm_device *dev, struct nouveau_gpuobj_ref *ref) { - drm_nouveau_private_t *dev_priv = dev->dev_private; + struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_fifo *chan = dev_priv->fifos[ref->channel]; - nouveau_gpuobj_t *ramht = chan->ramht ? chan->ramht->gpuobj : NULL; + struct nouveau_gpuobj *ramht = chan->ramht ? chan->ramht->gpuobj : NULL; uint32_t co, ho; if (!ramht) { @@ -180,13 +180,13 @@ nouveau_ramht_remove(drm_device_t* dev, nouveau_gpuobj_ref_t *ref) } int -nouveau_gpuobj_new(drm_device_t *dev, int channel, int size, int align, - uint32_t flags, nouveau_gpuobj_t **gpuobj_ret) +nouveau_gpuobj_new(struct drm_device *dev, int channel, int size, int align, + uint32_t flags, struct nouveau_gpuobj **gpuobj_ret) { - drm_nouveau_private_t *dev_priv = dev->dev_private; - nouveau_engine_func_t *engine = &dev_priv->Engine; + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_engine_func *engine = &dev_priv->Engine; struct nouveau_fifo *chan = NULL; - nouveau_gpuobj_t *gpuobj; + struct nouveau_gpuobj *gpuobj; struct mem_block *pramin = NULL; int ret; @@ -270,10 +270,10 @@ nouveau_gpuobj_new(drm_device_t *dev, int channel, int size, int align, return 0; } -void nouveau_gpuobj_takedown(drm_device_t *dev) +void nouveau_gpuobj_takedown(struct drm_device *dev) { - drm_nouveau_private_t *dev_priv = dev->dev_private; - nouveau_gpuobj_t *gpuobj = NULL; + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_gpuobj *gpuobj = NULL; DRM_DEBUG("\n"); @@ -285,11 +285,11 @@ void nouveau_gpuobj_takedown(drm_device_t *dev) } } -int nouveau_gpuobj_del(drm_device_t *dev, nouveau_gpuobj_t **pgpuobj) +int nouveau_gpuobj_del(struct drm_device *dev, struct nouveau_gpuobj **pgpuobj) { - drm_nouveau_private_t *dev_priv = dev->dev_private; - nouveau_engine_func_t *engine = &dev_priv->Engine; - nouveau_gpuobj_t *gpuobj; + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_engine_func *engine = &dev_priv->Engine; + struct nouveau_gpuobj *gpuobj; DRM_DEBUG("gpuobj %p\n", pgpuobj ? *pgpuobj : NULL); @@ -325,11 +325,11 @@ int nouveau_gpuobj_del(drm_device_t *dev, nouveau_gpuobj_t **pgpuobj) } static int -nouveau_gpuobj_instance_get(drm_device_t *dev, int channel, - nouveau_gpuobj_t *gpuobj, uint32_t *inst) +nouveau_gpuobj_instance_get(struct drm_device *dev, int channel, + struct nouveau_gpuobj *gpuobj, uint32_t *inst) { - drm_nouveau_private_t *dev_priv = dev->dev_private; - nouveau_gpuobj_t *cpramin; + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_gpuobj *cpramin; /* card_type < NV_50) { @@ -371,12 +371,12 @@ nouveau_gpuobj_instance_get(drm_device_t *dev, int channel, } int -nouveau_gpuobj_ref_add(drm_device_t *dev, int channel, uint32_t handle, - nouveau_gpuobj_t *gpuobj, nouveau_gpuobj_ref_t **ref_ret) +nouveau_gpuobj_ref_add(struct drm_device *dev, int channel, uint32_t handle, + struct nouveau_gpuobj *gpuobj, struct nouveau_gpuobj_ref **ref_ret) { - drm_nouveau_private_t *dev_priv = dev->dev_private; + struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_fifo *chan = NULL; - nouveau_gpuobj_ref_t *ref; + struct nouveau_gpuobj_ref *ref; uint32_t instance; int ret; @@ -424,9 +424,9 @@ nouveau_gpuobj_ref_add(drm_device_t *dev, int channel, uint32_t handle, return 0; } -int nouveau_gpuobj_ref_del(drm_device_t *dev, nouveau_gpuobj_ref_t **pref) +int nouveau_gpuobj_ref_del(struct drm_device *dev, struct nouveau_gpuobj_ref **pref) { - nouveau_gpuobj_ref_t *ref; + struct nouveau_gpuobj_ref *ref; DRM_DEBUG("ref %p\n", pref ? *pref : NULL); @@ -452,11 +452,11 @@ int nouveau_gpuobj_ref_del(drm_device_t *dev, nouveau_gpuobj_ref_t **pref) } int -nouveau_gpuobj_new_ref(drm_device_t *dev, int oc, int rc, uint32_t handle, +nouveau_gpuobj_new_ref(struct drm_device *dev, int oc, int rc, uint32_t handle, int size, int align, uint32_t flags, - nouveau_gpuobj_ref_t **ref) + struct nouveau_gpuobj_ref **ref) { - nouveau_gpuobj_t *gpuobj = NULL; + struct nouveau_gpuobj *gpuobj = NULL; int ret; if ((ret = nouveau_gpuobj_new(dev, oc, size, align, flags, &gpuobj))) @@ -471,12 +471,12 @@ nouveau_gpuobj_new_ref(drm_device_t *dev, int oc, int rc, uint32_t handle, } static int -nouveau_gpuobj_ref_find(drm_device_t *dev, int channel, uint32_t handle, - nouveau_gpuobj_ref_t **ref_ret) +nouveau_gpuobj_ref_find(struct drm_device *dev, int channel, uint32_t handle, + struct nouveau_gpuobj_ref **ref_ret) { - drm_nouveau_private_t *dev_priv = dev->dev_private; + struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_fifo *chan = dev_priv->fifos[channel]; - nouveau_gpuobj_ref_t *ref = chan->ramht_refs; + struct nouveau_gpuobj_ref *ref = chan->ramht_refs; while (ref) { if (ref->handle == handle) { @@ -491,12 +491,12 @@ nouveau_gpuobj_ref_find(drm_device_t *dev, int channel, uint32_t handle, } int -nouveau_gpuobj_new_fake(drm_device_t *dev, uint32_t offset, uint32_t size, - uint32_t flags, nouveau_gpuobj_t **pgpuobj, - nouveau_gpuobj_ref_t **pref) +nouveau_gpuobj_new_fake(struct drm_device *dev, uint32_t offset, uint32_t size, + uint32_t flags, struct nouveau_gpuobj **pgpuobj, + struct nouveau_gpuobj_ref **pref) { - drm_nouveau_private_t *dev_priv = dev->dev_private; - nouveau_gpuobj_t *gpuobj = NULL; + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_gpuobj *gpuobj = NULL; int i; DRM_DEBUG("offset=0x%08x size=0x%08x flags=0x%08x\n", @@ -537,9 +537,9 @@ nouveau_gpuobj_new_fake(drm_device_t *dev, uint32_t offset, uint32_t size, static int -nouveau_gpuobj_class_instmem_size(drm_device_t *dev, int class) +nouveau_gpuobj_class_instmem_size(struct drm_device *dev, int class) { - drm_nouveau_private_t *dev_priv = dev->dev_private; + struct drm_nouveau_private *dev_priv = dev->dev_private; /*XXX: dodgy hack for now */ if (dev_priv->card_type >= NV_50) @@ -577,11 +577,11 @@ nouveau_gpuobj_class_instmem_size(drm_device_t *dev, int class) to it that can be used to set up context objects. */ int -nouveau_gpuobj_dma_new(drm_device_t *dev, int channel, int class, +nouveau_gpuobj_dma_new(struct drm_device *dev, int channel, int class, uint64_t offset, uint64_t size, int access, int target, - nouveau_gpuobj_t **gpuobj) + struct nouveau_gpuobj **gpuobj) { - drm_nouveau_private_t *dev_priv = dev->dev_private; + struct drm_nouveau_private *dev_priv = dev->dev_private; int ret; uint32_t is_scatter_gather = 0; @@ -755,10 +755,10 @@ nouveau_gpuobj_dma_new(drm_device_t *dev, int channel, int class, set to 0? */ int -nouveau_gpuobj_gr_new(drm_device_t *dev, int channel, int class, - nouveau_gpuobj_t **gpuobj) +nouveau_gpuobj_gr_new(struct drm_device *dev, int channel, int class, + struct nouveau_gpuobj **gpuobj) { - drm_nouveau_private_t *dev_priv = dev->dev_private; + struct drm_nouveau_private *dev_priv = dev->dev_private; int ret; DRM_DEBUG("ch%d class=0x%04x\n", channel, class); @@ -804,11 +804,11 @@ nouveau_gpuobj_gr_new(drm_device_t *dev, int channel, int class, } static int -nouveau_gpuobj_channel_init_pramin(drm_device_t *dev, int channel) +nouveau_gpuobj_channel_init_pramin(struct drm_device *dev, int channel) { - drm_nouveau_private_t *dev_priv = dev->dev_private; + struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_fifo *chan = dev_priv->fifos[channel]; - nouveau_gpuobj_t *pramin = NULL; + struct nouveau_gpuobj *pramin = NULL; int size, base, ret; DRM_DEBUG("ch%d\n", channel); @@ -854,12 +854,12 @@ nouveau_gpuobj_channel_init_pramin(drm_device_t *dev, int channel) } int -nouveau_gpuobj_channel_init(drm_device_t *dev, int channel, +nouveau_gpuobj_channel_init(struct drm_device *dev, int channel, uint32_t vram_h, uint32_t tt_h) { - drm_nouveau_private_t *dev_priv = dev->dev_private; + struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_fifo *chan = dev_priv->fifos[channel]; - nouveau_gpuobj_t *vram = NULL, *tt = NULL; + struct nouveau_gpuobj *vram = NULL, *tt = NULL; int ret; DRM_DEBUG("ch%d vram=0x%08x tt=0x%08x\n", channel, vram_h, tt_h); @@ -940,11 +940,11 @@ nouveau_gpuobj_channel_init(drm_device_t *dev, int channel, } void -nouveau_gpuobj_channel_takedown(drm_device_t *dev, int channel) +nouveau_gpuobj_channel_takedown(struct drm_device *dev, int channel) { - drm_nouveau_private_t *dev_priv = dev->dev_private; + struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_fifo *chan = dev_priv->fifos[channel]; - nouveau_gpuobj_ref_t *ref; + struct nouveau_gpuobj_ref *ref; DRM_DEBUG("ch%d\n", channel); @@ -964,12 +964,13 @@ nouveau_gpuobj_channel_takedown(drm_device_t *dev, int channel) int nouveau_ioctl_grobj_alloc(DRM_IOCTL_ARGS) { DRM_DEVICE; - drm_nouveau_grobj_alloc_t init; - nouveau_gpuobj_t *gr = NULL; + struct drm_nouveau_grobj_alloc init; + struct nouveau_gpuobj *gr = NULL; int ret; - DRM_COPY_FROM_USER_IOCTL(init, (drm_nouveau_grobj_alloc_t __user *) - data, sizeof(init)); + DRM_COPY_FROM_USER_IOCTL(init, + (struct drm_nouveau_grobj_alloc_t __user*)data, + sizeof(init)); if (!nouveau_fifo_owner(dev, filp, init.channel)) { DRM_ERROR("pid %d doesn't own channel %d\n", -- cgit v1.2.3 From 5ae3ad4f015aa072180a0c55255832be4e7557cf Mon Sep 17 00:00:00 2001 From: Arthur Huillet Date: Fri, 13 Jul 2007 15:57:17 +0200 Subject: now attempting to create PCI object only when there is a pci_heap --- shared-core/nouveau_object.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'shared-core/nouveau_object.c') diff --git a/shared-core/nouveau_object.c b/shared-core/nouveau_object.c index c5697d8e..aab2e3ac 100644 --- a/shared-core/nouveau_object.c +++ b/shared-core/nouveau_object.c @@ -918,7 +918,7 @@ nouveau_gpuobj_channel_init(struct drm_device *dev, int channel, return ret; } } - else { + else if ( dev_priv->pci_heap) { if (dev_priv -> card_type >= NV_50 ) return 0; /*no PCIGART for NV50*/ /*PCI*/ -- cgit v1.2.3 From aa6d9199fa7b0cbe04a936312db7be75bb53bdc8 Mon Sep 17 00:00:00 2001 From: Arthur Huillet Date: Fri, 13 Jul 2007 20:51:52 +0200 Subject: applied patch from Ian Romanick fixing PCI DMA object creation code --- shared-core/nouveau_object.c | 77 +++++++++++++++++++++----------------------- 1 file changed, 37 insertions(+), 40 deletions(-) (limited to 'shared-core/nouveau_object.c') diff --git a/shared-core/nouveau_object.c b/shared-core/nouveau_object.c index aab2e3ac..146c4f1c 100644 --- a/shared-core/nouveau_object.c +++ b/shared-core/nouveau_object.c @@ -585,6 +585,11 @@ nouveau_gpuobj_dma_new(struct drm_device *dev, int channel, int class, int ret; uint32_t is_scatter_gather = 0; + /* Total number of pages covered by the request. + */ + const unsigned int page_count = (size + PAGE_SIZE - 1) / PAGE_SIZE; + + DRM_DEBUG("ch%d class=0x%04x offset=0x%llx size=0x%llx\n", channel, class, offset, size); DRM_DEBUG("access=%d target=%d\n", access, target); @@ -604,7 +609,7 @@ nouveau_gpuobj_dma_new(struct drm_device *dev, int channel, int class, } ret = nouveau_gpuobj_new(dev, channel, - is_scatter_gather ? ((((size + PAGE_SIZE - 1) / PAGE_SIZE) << 2) + 12) : nouveau_gpuobj_class_instmem_size(dev, class), + is_scatter_gather ? ((page_count << 2) + 12) : nouveau_gpuobj_class_instmem_size(dev, class), 16, NVOBJ_FLAG_ZERO_ALLOC | NVOBJ_FLAG_ZERO_FREE, gpuobj); @@ -634,9 +639,19 @@ nouveau_gpuobj_dma_new(struct drm_device *dev, int channel, int class, } else { + /* Intial page entry in the scatter-gather area that + * corresponds to the base offset + */ + unsigned int idx = offset / PAGE_SIZE; + uint32_t instance_offset; - uint64_t bus_addr; - size = (uint32_t) size; + unsigned int i; + + if ((idx + page_count) > dev->sg->pages) { + DRM_ERROR("Requested page range exceedes " + "allocated scatter-gather range!"); + return DRM_ERR(E2BIG); + } DRM_DEBUG("Creating PCI DMA object using virtual zone starting at %#llx, size %d\n", offset, (uint32_t)size); INSTANCE_WR(*gpuobj, 0, ((1<<12) | (0<<13) | @@ -644,52 +659,34 @@ nouveau_gpuobj_dma_new(struct drm_device *dev, int channel, int class, (access << 14) | (target << 16) | class)); - INSTANCE_WR(*gpuobj, 1, size-1); + INSTANCE_WR(*gpuobj, 1, (uint32_t) size-1); - offset += dev->sg->virtual; /*write starting at the third dword*/ instance_offset = 2; /*for each PAGE, get its bus address, fill in the page table entry, and advance*/ - while ( size > 0 ) { - bus_addr = vmalloc_to_page(offset); - if ( ! bus_addr ) - { - DRM_ERROR("Couldn't map virtual address %#llx to a page number\n", offset); - nouveau_gpuobj_del(dev, gpuobj); - return DRM_ERR(ENOMEM); + for (i = 0; i < page_count; i++) { + if (dev->sg->busaddr[idx] == 0) { + dev->sg->busaddr[idx] = + pci_map_page(dev->pdev, + dev->sg->pagelist[idx], + 0, + DMA_31BIT_MASK, + DMA_BIDIRECTIONAL); + + if (dev->sg->busaddr[idx] == 0) { + return DRM_ERR(ENOMEM); } - bus_addr = (uint64_t) page_address(bus_addr); - if ( ! bus_addr ) - { - DRM_ERROR("Couldn't find page address for address %#llx\n", offset); - nouveau_gpuobj_del(dev, gpuobj); - return DRM_ERR(ENOMEM); - } - bus_addr |= (offset & ~PAGE_MASK); - bus_addr = virt_to_bus((void *)bus_addr); - if ( ! bus_addr ) - { - DRM_ERROR("Couldn't get bus address for %#llx\n", offset); - nouveau_gpuobj_del(dev, gpuobj); - return DRM_ERR(ENOMEM); - } - - /*if ( bus_addr >= 1 << 32 ) - { - DRM_ERROR("Bus address %#llx is over 32 bits, Nvidia cards cannot address it !\n", bus_addr); - nouveau_gpuobj_del(dev, gpuobj); - return DRM_ERR(EINVAL); - }*/ - - frame = (uint32_t) bus_addr & ~0x00000FFF; - INSTANCE_WR(*gpuobj, instance_offset, frame | pte_flags); - offset += PAGE_SIZE; - instance_offset ++; - size -= PAGE_SIZE; } + frame = (uint32_t) dev->sg->busaddr[idx]; + INSTANCE_WR(*gpuobj, instance_offset, + frame | pte_flags); + + idx++; + instance_offset ++; + } } } else { INSTANCE_WR(*gpuobj, 0, 0x00190000 | class); -- cgit v1.2.3 From 70a8a60a3e81c18f9c6485102cb226c340c3cd73 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Mon, 16 Jul 2007 10:56:43 -0700 Subject: Correct errors in the usage of pci_map_page. With these changes the driver no longer instantly hard-locks a 6600LE on a PowerPC G5. I haven't tested any 3D apps yet. --- shared-core/nouveau_object.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'shared-core/nouveau_object.c') diff --git a/shared-core/nouveau_object.c b/shared-core/nouveau_object.c index 146c4f1c..ea0edb08 100644 --- a/shared-core/nouveau_object.c +++ b/shared-core/nouveau_object.c @@ -672,10 +672,10 @@ nouveau_gpuobj_dma_new(struct drm_device *dev, int channel, int class, pci_map_page(dev->pdev, dev->sg->pagelist[idx], 0, - DMA_31BIT_MASK, + PAGE_SIZE, DMA_BIDIRECTIONAL); - if (dev->sg->busaddr[idx] == 0) { + if (dma_mapping_error(dev->sg->busaddr[idx])) { return DRM_ERR(ENOMEM); } } -- cgit v1.2.3 From ec67c2def9af16bf9252d6742aec815b817f135a Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 15 Jul 2007 17:18:15 +1000 Subject: nouveau: G8x PCIEGART Actually a NV04-NV50 ttm backend for both PCI and PCIEGART, but PCIGART support for G8X using the current mm has been hacked on top of it. --- shared-core/nouveau_object.c | 136 ++++++++++++++++++++++++++++++++----------- 1 file changed, 101 insertions(+), 35 deletions(-) (limited to 'shared-core/nouveau_object.c') diff --git a/shared-core/nouveau_object.c b/shared-core/nouveau_object.c index ea0edb08..f0025d7a 100644 --- a/shared-core/nouveau_object.c +++ b/shared-core/nouveau_object.c @@ -596,7 +596,7 @@ nouveau_gpuobj_dma_new(struct drm_device *dev, int channel, int class, switch (target) { case NV_DMA_TARGET_AGP: - offset += dev_priv->agp_phys; + offset += dev_priv->gart_info.aper_base; break; case NV_DMA_TARGET_PCI_NONLINEAR: /*assume the "offset" is a virtual memory address*/ @@ -689,10 +689,20 @@ nouveau_gpuobj_dma_new(struct drm_device *dev, int channel, int class, } } } else { - INSTANCE_WR(*gpuobj, 0, 0x00190000 | class); + uint32_t flags0, flags5; + + if (target == NV_DMA_TARGET_VIDMEM) { + flags0 = 0x00190000; + flags5 = 0x00010000; + } else { + flags0 = 0x7fc00000; + flags5 = 0x00080000; + } + + INSTANCE_WR(*gpuobj, 0, flags0 | class); INSTANCE_WR(*gpuobj, 1, offset + size - 1); INSTANCE_WR(*gpuobj, 2, offset); - INSTANCE_WR(*gpuobj, 5, 0x00010000); + INSTANCE_WR(*gpuobj, 5, flags5); } (*gpuobj)->engine = NVOBJ_ENGINE_SW; @@ -700,6 +710,42 @@ nouveau_gpuobj_dma_new(struct drm_device *dev, int channel, int class, return 0; } +int +nouveau_gpuobj_gart_dma_new(struct drm_device *dev, int channel, + uint64_t offset, uint64_t size, int access, + struct nouveau_gpuobj **gpuobj, + uint32_t *o_ret) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + int ret; + + if (dev_priv->gart_info.type == NOUVEAU_GART_AGP || + (dev_priv->card_type >= NV_50 && + dev_priv->gart_info.type == NOUVEAU_GART_SGDMA)) { + ret = nouveau_gpuobj_dma_new(dev, channel, + NV_CLASS_DMA_IN_MEMORY, + offset, size, access, + NV_DMA_TARGET_AGP, gpuobj); + if (o_ret) + *o_ret = 0; + } else + if (dev_priv->gart_info.type == NOUVEAU_GART_SGDMA) { + *gpuobj = dev_priv->gart_info.sg_ctxdma; + if (offset & ~0xffffffffULL) { + DRM_ERROR("obj offset exceeds 32-bits\n"); + return DRM_ERR(EINVAL); + } + if (o_ret) + *o_ret = (uint32_t)offset; + ret = (*gpuobj != NULL) ? 0 : DRM_ERR(EINVAL); + } else { + DRM_ERROR("Invalid GART type %d\n", dev_priv->gart_info.type); + return DRM_ERR(EINVAL); + } + + return ret; +} + /* Context objects in the instance RAM have the following structure. * On NV40 they are 32 byte long, on NV30 and smaller 16 bytes. @@ -857,7 +903,7 @@ nouveau_gpuobj_channel_init(struct drm_device *dev, int channel, struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_fifo *chan = dev_priv->fifos[channel]; struct nouveau_gpuobj *vram = NULL, *tt = NULL; - int ret; + int ret, i; DRM_DEBUG("ch%d vram=0x%08x tt=0x%08x\n", channel, vram_h, tt_h); @@ -870,6 +916,29 @@ nouveau_gpuobj_channel_init(struct drm_device *dev, int channel, return ret; } + /* NV50 VM, point offset 0-512MiB at shared PCIEGART table */ + if (dev_priv->card_type >= NV_50) { + uint32_t vm_offset; + + vm_offset = (dev_priv->chipset & 0xf0) == 0x50 ? 0x1400 : 0x200; + vm_offset += chan->ramin->gpuobj->im_pramin->start; + if ((ret = nouveau_gpuobj_new_fake(dev, vm_offset, 0x4000, + 0, &chan->vm_pd, NULL))) + return ret; + for (i=0; i<0x4000; i+=8) { + INSTANCE_WR(chan->vm_pd, (i+0)/4, 0x00000000); + INSTANCE_WR(chan->vm_pd, (i+4)/4, 0xdeadcafe); + } + + if ((ret = nouveau_gpuobj_ref_add(dev, -1, 0, + dev_priv->gart_info.sg_ctxdma, + &chan->vm_gart_pt))) + return ret; + INSTANCE_WR(chan->vm_pd, (0+0)/4, + chan->vm_gart_pt->instance | 0x03); + INSTANCE_WR(chan->vm_pd, (0+4)/4, 0x00000000); + } + /* RAMHT */ if (dev_priv->card_type < NV_50) { ret = nouveau_gpuobj_ref_add(dev, -1, 0, dev_priv->ramht, @@ -899,40 +968,34 @@ nouveau_gpuobj_channel_init(struct drm_device *dev, int channel, return ret; } - if (dev_priv->agp_heap) { - /* AGPGART ctxdma */ - if ((ret = nouveau_gpuobj_dma_new(dev, channel, NV_CLASS_DMA_IN_MEMORY, - 0, dev_priv->agp_available_size, - NV_DMA_ACCESS_RW, - NV_DMA_TARGET_AGP, &tt))) { - DRM_ERROR("Error creating AGP TT ctxdma: %d\n", DRM_ERR(ENOMEM)); - return DRM_ERR(ENOMEM); - } - - ret = nouveau_gpuobj_ref_add(dev, channel, tt_h, tt, NULL); - if (ret) { - DRM_ERROR("Error referencing AGP TT ctxdma: %d\n", ret); - return ret; - } + /* TT memory ctxdma */ + if (dev_priv->gart_info.type != NOUVEAU_GART_NONE) { + ret = nouveau_gpuobj_gart_dma_new(dev, channel, 0, + dev_priv->gart_info.aper_size, + NV_DMA_ACCESS_RW, &tt, NULL); + } else + if (dev_priv->pci_heap) { + ret = nouveau_gpuobj_dma_new(dev, channel, + NV_CLASS_DMA_IN_MEMORY, + 0, dev->sg->pages * PAGE_SIZE, + NV_DMA_ACCESS_RW, + NV_DMA_TARGET_PCI_NONLINEAR, &tt); + } else { + DRM_ERROR("Invalid GART type %d\n", dev_priv->gart_info.type); + ret = DRM_ERR(EINVAL); } - else if ( dev_priv->pci_heap) { - if (dev_priv -> card_type >= NV_50 ) return 0; /*no PCIGART for NV50*/ - /*PCI*/ - if((ret = nouveau_gpuobj_dma_new(dev, channel, NV_CLASS_DMA_IN_MEMORY, - 0, dev->sg->pages * PAGE_SIZE, - NV_DMA_ACCESS_RW, - NV_DMA_TARGET_PCI_NONLINEAR, &tt))) { - DRM_ERROR("Error creating PCI TT ctxdma: %d\n", DRM_ERR(ENOMEM)); - return 0; //this is noncritical - } - - ret = nouveau_gpuobj_ref_add(dev, channel, tt_h, tt, NULL); - if (ret) { - DRM_ERROR("Error referencing PCI TT ctxdma: %d\n", ret); - return ret; - } + if (ret) { + DRM_ERROR("Error creating TT ctxdma: %d\n", ret); + return ret; } + + ret = nouveau_gpuobj_ref_add(dev, channel, tt_h, tt, NULL); + if (ret) { + DRM_ERROR("Error referencing TT ctxdma: %d\n", ret); + return ret; + } + return 0; } @@ -951,6 +1014,9 @@ nouveau_gpuobj_channel_takedown(struct drm_device *dev, int channel) } nouveau_gpuobj_ref_del(dev, &chan->ramht); + nouveau_gpuobj_del(dev, &chan->vm_pd); + nouveau_gpuobj_ref_del(dev, &chan->vm_gart_pt); + if (chan->ramin_heap) nouveau_mem_takedown(&chan->ramin_heap); if (chan->ramin) -- cgit v1.2.3 From e39286eb5eab8846a228863abf8f1b8b07a9e29d Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 19 Jul 2007 17:00:17 -0700 Subject: Remove DRM_ERR OS macro. This was used to make all ioctl handlers return -errno on linux and errno on *BSD. Instead, just return -errno in shared code, and flip sign on return from shared code to *BSD code. --- shared-core/nouveau_object.c | 58 ++++++++++++++++++++++---------------------- 1 file changed, 29 insertions(+), 29 deletions(-) (limited to 'shared-core/nouveau_object.c') diff --git a/shared-core/nouveau_object.c b/shared-core/nouveau_object.c index f0025d7a..30d515f0 100644 --- a/shared-core/nouveau_object.c +++ b/shared-core/nouveau_object.c @@ -107,7 +107,7 @@ nouveau_ramht_insert(struct drm_device *dev, struct nouveau_gpuobj_ref *ref) if (!ramht) { DRM_ERROR("No hash table!\n"); - return DRM_ERR(EINVAL); + return -EINVAL; } if (dev_priv->card_type < NV_40) { @@ -142,7 +142,7 @@ nouveau_ramht_insert(struct drm_device *dev, struct nouveau_gpuobj_ref *ref) } while (co != ho); DRM_ERROR("RAMHT space exhausted. ch=%d\n", ref->channel); - return DRM_ERR(ENOMEM); + return -ENOMEM; } static void @@ -194,17 +194,17 @@ nouveau_gpuobj_new(struct drm_device *dev, int channel, int size, int align, channel, size, align, flags); if (!dev_priv || !gpuobj_ret || *gpuobj_ret != NULL) - return DRM_ERR(EINVAL); + return -EINVAL; if (channel >= 0) { if (channel > nouveau_fifo_number(dev)) - return DRM_ERR(EINVAL); + return -EINVAL; chan = dev_priv->fifos[channel]; } gpuobj = drm_calloc(1, sizeof(*gpuobj), DRM_MEM_DRIVER); if (!gpuobj) - return DRM_ERR(ENOMEM); + return -ENOMEM; DRM_DEBUG("gpuobj %p\n", gpuobj); gpuobj->flags = flags; gpuobj->im_channel = channel; @@ -230,7 +230,7 @@ nouveau_gpuobj_new(struct drm_device *dev, int channel, int size, int align, if (!pramin) { DRM_ERROR("No PRAMIN heap!\n"); - return DRM_ERR(EINVAL); + return -EINVAL; } if (!chan && (ret = engine->instmem.populate(dev, gpuobj, &size))) { @@ -244,7 +244,7 @@ nouveau_gpuobj_new(struct drm_device *dev, int channel, int size, int align, (DRMFILE)-2); if (!gpuobj->im_pramin) { nouveau_gpuobj_del(dev, &gpuobj); - return DRM_ERR(ENOMEM); + return -ENOMEM; } gpuobj->im_pramin->flags = NOUVEAU_MEM_INSTANCE; @@ -294,12 +294,12 @@ int nouveau_gpuobj_del(struct drm_device *dev, struct nouveau_gpuobj **pgpuobj) DRM_DEBUG("gpuobj %p\n", pgpuobj ? *pgpuobj : NULL); if (!dev_priv || !pgpuobj || !(*pgpuobj)) - return DRM_ERR(EINVAL); + return -EINVAL; gpuobj = *pgpuobj; if (gpuobj->refcount != 0) { DRM_ERROR("gpuobj refcount is %d\n", gpuobj->refcount); - return DRM_ERR(EINVAL); + return -EINVAL; } engine->instmem.clear(dev, gpuobj); @@ -340,7 +340,7 @@ nouveau_gpuobj_instance_get(struct drm_device *dev, int channel, if ((channel > 0) && gpuobj->im_channel != channel) { DRM_ERROR("Channel mismatch: obj %d, ref %d\n", gpuobj->im_channel, channel); - return DRM_ERR(EINVAL); + return -EINVAL; } /* NV50 channel-local instance */ @@ -355,7 +355,7 @@ nouveau_gpuobj_instance_get(struct drm_device *dev, int channel, /* ...from global heap */ if (!gpuobj->im_backing) { DRM_ERROR("AII, no VRAM backing gpuobj\n"); - return DRM_ERR(EINVAL); + return -EINVAL; } *inst = gpuobj->im_backing->start; return 0; @@ -367,7 +367,7 @@ nouveau_gpuobj_instance_get(struct drm_device *dev, int channel, return 0; } - return DRM_ERR(EINVAL); + return -EINVAL; } int @@ -383,15 +383,15 @@ nouveau_gpuobj_ref_add(struct drm_device *dev, int channel, uint32_t handle, DRM_DEBUG("ch%d h=0x%08x gpuobj=%p\n", channel, handle, gpuobj); if (!dev_priv || !gpuobj || (ref_ret && *ref_ret != NULL)) - return DRM_ERR(EINVAL); + return -EINVAL; if (channel >= 0) { if (channel > nouveau_fifo_number(dev)) - return DRM_ERR(EINVAL); + return -EINVAL; chan = dev_priv->fifos[channel]; } else if (!ref_ret) - return DRM_ERR(EINVAL); + return -EINVAL; ret = nouveau_gpuobj_instance_get(dev, channel, gpuobj, &instance); if (ret) @@ -399,7 +399,7 @@ nouveau_gpuobj_ref_add(struct drm_device *dev, int channel, uint32_t handle, ref = drm_calloc(1, sizeof(*ref), DRM_MEM_DRIVER); if (!ref) - return DRM_ERR(ENOMEM); + return -ENOMEM; ref->gpuobj = gpuobj; ref->channel = channel; ref->instance = instance; @@ -431,7 +431,7 @@ int nouveau_gpuobj_ref_del(struct drm_device *dev, struct nouveau_gpuobj_ref **p DRM_DEBUG("ref %p\n", pref ? *pref : NULL); if (!dev || !pref || *pref == NULL) - return DRM_ERR(EINVAL); + return -EINVAL; ref = *pref; if (ref->handle != ~0) @@ -487,7 +487,7 @@ nouveau_gpuobj_ref_find(struct drm_device *dev, int channel, uint32_t handle, ref = ref->next; } - return DRM_ERR(EINVAL); + return -EINVAL; } int @@ -504,7 +504,7 @@ nouveau_gpuobj_new_fake(struct drm_device *dev, uint32_t offset, uint32_t size, gpuobj = drm_calloc(1, sizeof(*gpuobj), DRM_MEM_DRIVER); if (!gpuobj) - return DRM_ERR(ENOMEM); + return -ENOMEM; DRM_DEBUG("gpuobj %p\n", gpuobj); gpuobj->im_channel = -1; gpuobj->flags = flags | NVOBJ_FLAG_FAKE; @@ -513,7 +513,7 @@ nouveau_gpuobj_new_fake(struct drm_device *dev, uint32_t offset, uint32_t size, DRM_MEM_DRIVER); if (!gpuobj->im_pramin) { nouveau_gpuobj_del(dev, &gpuobj); - return DRM_ERR(ENOMEM); + return -ENOMEM; } gpuobj->im_pramin->start = offset; gpuobj->im_pramin->size = size; @@ -650,7 +650,7 @@ nouveau_gpuobj_dma_new(struct drm_device *dev, int channel, int class, if ((idx + page_count) > dev->sg->pages) { DRM_ERROR("Requested page range exceedes " "allocated scatter-gather range!"); - return DRM_ERR(E2BIG); + return -E2BIG; } DRM_DEBUG("Creating PCI DMA object using virtual zone starting at %#llx, size %d\n", offset, (uint32_t)size); @@ -676,7 +676,7 @@ nouveau_gpuobj_dma_new(struct drm_device *dev, int channel, int class, DMA_BIDIRECTIONAL); if (dma_mapping_error(dev->sg->busaddr[idx])) { - return DRM_ERR(ENOMEM); + return -ENOMEM; } } @@ -733,14 +733,14 @@ nouveau_gpuobj_gart_dma_new(struct drm_device *dev, int channel, *gpuobj = dev_priv->gart_info.sg_ctxdma; if (offset & ~0xffffffffULL) { DRM_ERROR("obj offset exceeds 32-bits\n"); - return DRM_ERR(EINVAL); + return -EINVAL; } if (o_ret) *o_ret = (uint32_t)offset; - ret = (*gpuobj != NULL) ? 0 : DRM_ERR(EINVAL); + ret = (*gpuobj != NULL) ? 0 : -EINVAL; } else { DRM_ERROR("Invalid GART type %d\n", dev_priv->gart_info.type); - return DRM_ERR(EINVAL); + return -EINVAL; } return ret; @@ -982,7 +982,7 @@ nouveau_gpuobj_channel_init(struct drm_device *dev, int channel, NV_DMA_TARGET_PCI_NONLINEAR, &tt); } else { DRM_ERROR("Invalid GART type %d\n", dev_priv->gart_info.type); - ret = DRM_ERR(EINVAL); + ret = -EINVAL; } if (ret) { @@ -1038,15 +1038,15 @@ int nouveau_ioctl_grobj_alloc(DRM_IOCTL_ARGS) if (!nouveau_fifo_owner(dev, filp, init.channel)) { DRM_ERROR("pid %d doesn't own channel %d\n", DRM_CURRENTPID, init.channel); - return DRM_ERR(EINVAL); + return -EINVAL; } //FIXME: check args, only allow trusted objects to be created if (init.handle == ~0) - return DRM_ERR(EINVAL); + return -EINVAL; if (nouveau_gpuobj_ref_find(dev, init.channel, init.handle, NULL) == 0) - return DRM_ERR(EEXIST); + return -EEXIST; if ((ret = nouveau_gpuobj_gr_new(dev, init.channel, init.class, &gr))) { DRM_ERROR("Error creating gr object: %d (%d/0x%08x)\n", -- cgit v1.2.3 From c1119b1b092527fbb6950d0b5e51e076ddb00f29 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 20 Jul 2007 06:39:25 -0700 Subject: Replace filp in ioctl arguments with drm_file *file_priv. As a fallout, replace filp storage with file_priv storage for "unique identifier of a client" all over the DRM. There is a 1:1 mapping, so this should be a noop. This could be a minor performance improvement, as everything on Linux dereferenced filp to get file_priv anyway, while only the mmap ioctls went the other direction. --- shared-core/nouveau_object.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'shared-core/nouveau_object.c') diff --git a/shared-core/nouveau_object.c b/shared-core/nouveau_object.c index 30d515f0..f11cc115 100644 --- a/shared-core/nouveau_object.c +++ b/shared-core/nouveau_object.c @@ -241,7 +241,7 @@ nouveau_gpuobj_new(struct drm_device *dev, int channel, int size, int align, /* Allocate a chunk of the PRAMIN aperture */ gpuobj->im_pramin = nouveau_mem_alloc_block(pramin, size, drm_order(align), - (DRMFILE)-2); + (struct drm_file *)-2); if (!gpuobj->im_pramin) { nouveau_gpuobj_del(dev, &gpuobj); return -ENOMEM; @@ -1035,7 +1035,7 @@ int nouveau_ioctl_grobj_alloc(DRM_IOCTL_ARGS) (struct drm_nouveau_grobj_alloc_t __user*)data, sizeof(init)); - if (!nouveau_fifo_owner(dev, filp, init.channel)) { + if (!nouveau_fifo_owner(dev, file_priv, init.channel)) { DRM_ERROR("pid %d doesn't own channel %d\n", DRM_CURRENTPID, init.channel); return -EINVAL; -- cgit v1.2.3 From 5b38e134163cc375e91424c4688cc9328c6e9082 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 19 Jul 2007 17:11:11 -0700 Subject: Replace DRM_IOCTL_ARGS with (dev, data, file_priv) and remove DRM_DEVICE. The data is now in kernel space, copied in/out as appropriate according to the This results in DRM_COPY_{TO,FROM}_USER going away, and error paths to deal with those failures. This also means that XFree86 4.2.0 support for i810 DRM is lost. --- shared-core/nouveau_object.c | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) (limited to 'shared-core/nouveau_object.c') diff --git a/shared-core/nouveau_object.c b/shared-core/nouveau_object.c index f11cc115..e8b12bb7 100644 --- a/shared-core/nouveau_object.c +++ b/shared-core/nouveau_object.c @@ -1024,40 +1024,37 @@ nouveau_gpuobj_channel_takedown(struct drm_device *dev, int channel) } -int nouveau_ioctl_grobj_alloc(DRM_IOCTL_ARGS) +int nouveau_ioctl_grobj_alloc(struct drm_device *dev, void *data, struct drm_file *file_priv) { - DRM_DEVICE; - struct drm_nouveau_grobj_alloc init; + struct drm_nouveau_grobj_alloc *init = data; struct nouveau_gpuobj *gr = NULL; int ret; - DRM_COPY_FROM_USER_IOCTL(init, - (struct drm_nouveau_grobj_alloc_t __user*)data, - sizeof(init)); - - if (!nouveau_fifo_owner(dev, file_priv, init.channel)) { + if (!nouveau_fifo_owner(dev, file_priv, init->channel)) { DRM_ERROR("pid %d doesn't own channel %d\n", - DRM_CURRENTPID, init.channel); + DRM_CURRENTPID, init->channel); return -EINVAL; } //FIXME: check args, only allow trusted objects to be created - if (init.handle == ~0) + if (init->handle == ~0) return -EINVAL; - if (nouveau_gpuobj_ref_find(dev, init.channel, init.handle, NULL) == 0) + if (nouveau_gpuobj_ref_find(dev, init->channel, init->handle, NULL) == + 0) return -EEXIST; - if ((ret = nouveau_gpuobj_gr_new(dev, init.channel, init.class, &gr))) { + ret = nouveau_gpuobj_gr_new(dev, init->channel, init->class, &gr); + if (ret) { DRM_ERROR("Error creating gr object: %d (%d/0x%08x)\n", - ret, init.channel, init.handle); + ret, init->channel, init->handle); return ret; } - if ((ret = nouveau_gpuobj_ref_add(dev, init.channel, init.handle, + if ((ret = nouveau_gpuobj_ref_add(dev, init->channel, init->handle, gr, NULL))) { DRM_ERROR("Error referencing gr object: %d (%d/0x%08x\n)", - ret, init.channel, init.handle); + ret, init->channel, init->handle); nouveau_gpuobj_del(dev, &gr); return ret; } -- cgit v1.2.3