From 695599f18d907bb277805581bbe208b0e083e7d9 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 24 Jun 2007 19:03:35 +1000 Subject: nouveau: Nuke DMA_OBJECT_INIT ioctl (bumps interface to 0.0.7) For various reasons, this ioctl was a bad idea. At channel creation we now automatically create DMA objects covering available VRAM and GART memory, where the client used to do this themselves. However, there is still a need to be able to create DMA objects pointing at specific areas of memory (ie. notifiers). Each channel is now allocated a small amount of memory from which a client can suballocate things (such as notifiers), and have a DMA object created which covers the suballocated area. The NOTIFIER_ALLOC ioctl exposes this functionality. --- shared-core/nouveau_mem.c | 51 ++++++++++++++++++++++++++++++----------------- 1 file changed, 33 insertions(+), 18 deletions(-) (limited to 'shared-core/nouveau_mem.c') diff --git a/shared-core/nouveau_mem.c b/shared-core/nouveau_mem.c index a5343b99..edfc9d3f 100644 --- a/shared-core/nouveau_mem.c +++ b/shared-core/nouveau_mem.c @@ -77,8 +77,8 @@ out: return p; } -static struct mem_block *alloc_block(struct mem_block *heap, uint64_t size, - int align2, DRMFILE filp) +struct mem_block *nouveau_mem_alloc_block(struct mem_block *heap, uint64_t size, + int align2, DRMFILE filp) { struct mem_block *p; uint64_t mask = (1 << align2) - 1; @@ -106,7 +106,7 @@ static struct mem_block *find_block(struct mem_block *heap, uint64_t start) return NULL; } -static void free_block(struct mem_block *p) +void nouveau_mem_free_block(struct mem_block *p) { p->filp = NULL; @@ -132,7 +132,8 @@ static void free_block(struct mem_block *p) /* Initialize. How to check for an uninitialized heap? */ -static int init_heap(struct mem_block **heap, uint64_t start, uint64_t size) +int nouveau_mem_init_heap(struct mem_block **heap, uint64_t start, + uint64_t size) { struct mem_block *blocks = drm_alloc(sizeof(*blocks), DRM_MEM_BUFS); @@ -331,7 +332,9 @@ int nouveau_mem_init(struct drm_device *dev) goto no_agp; } - if (init_heap(&dev_priv->agp_heap, info.aperture_base, info.aperture_size)) + if (nouveau_mem_init_heap(&dev_priv->agp_heap, + info.aperture_base, + info.aperture_size)) goto no_agp; dev_priv->agp_phys = info.aperture_base; @@ -357,12 +360,19 @@ no_agp: if (fb_size>256*1024*1024) { /* On cards with > 256Mb, you can't map everything. * So we create a second FB heap for that type of memory */ - if (init_heap(&dev_priv->fb_heap, drm_get_resource_start(dev,1), 256*1024*1024)) + if (nouveau_mem_init_heap(&dev_priv->fb_heap, + drm_get_resource_start(dev,1), + 256*1024*1024)) return DRM_ERR(ENOMEM); - if (init_heap(&dev_priv->fb_nomap_heap, drm_get_resource_start(dev,1)+256*1024*1024, fb_size-256*1024*1024)) + if (nouveau_mem_init_heap(&dev_priv->fb_nomap_heap, + drm_get_resource_start(dev,1) + + 256*1024*1024, + fb_size-256*1024*1024)) return DRM_ERR(ENOMEM); } else { - if (init_heap(&dev_priv->fb_heap, drm_get_resource_start(dev,1), fb_size)) + if (nouveau_mem_init_heap(&dev_priv->fb_heap, + drm_get_resource_start(dev,1), + fb_size)) return DRM_ERR(ENOMEM); dev_priv->fb_nomap_heap=NULL; } @@ -397,21 +407,25 @@ struct mem_block* nouveau_mem_alloc(struct drm_device *dev, int alignment, uint6 if (flags&NOUVEAU_MEM_AGP) { type=NOUVEAU_MEM_AGP; - block = alloc_block(dev_priv->agp_heap, size, alignment, filp); + block = nouveau_mem_alloc_block(dev_priv->agp_heap, size, + alignment, filp); if (block) goto alloc_ok; } if (flags&(NOUVEAU_MEM_FB|NOUVEAU_MEM_FB_ACCEPTABLE)) { type=NOUVEAU_MEM_FB; if (!(flags&NOUVEAU_MEM_MAPPED)) { - block = alloc_block(dev_priv->fb_nomap_heap, size, alignment, filp); + block = nouveau_mem_alloc_block(dev_priv->fb_nomap_heap, + size, alignment, filp); if (block) goto alloc_ok; } - block = alloc_block(dev_priv->fb_heap, size, alignment, filp); + block = nouveau_mem_alloc_block(dev_priv->fb_heap, size, + alignment, filp); if (block) goto alloc_ok; } if (flags&NOUVEAU_MEM_AGP_ACCEPTABLE) { type=NOUVEAU_MEM_AGP; - block = alloc_block(dev_priv->agp_heap, size, alignment, filp); + block = nouveau_mem_alloc_block(dev_priv->agp_heap, size, + alignment, filp); if (block) goto alloc_ok; } @@ -432,7 +446,7 @@ alloc_ok: ret = drm_addmap(dev, block->start, block->size, _DRM_FRAME_BUFFER, 0, &block->map); if (ret) { - free_block(block); + nouveau_mem_free_block(block); return NULL; } } @@ -446,7 +460,7 @@ void nouveau_mem_free(struct drm_device* dev, struct mem_block* block) DRM_INFO("freeing 0x%llx\n", block->start); if (block->flags&NOUVEAU_MEM_MAPPED) drm_rmmap(dev, block->map); - free_block(block); + nouveau_mem_free_block(block); } static void @@ -549,8 +563,8 @@ int nouveau_instmem_init(struct drm_device *dev) * the space that was reserved for RAMHT/FC/RO. */ offset = dev_priv->ramfc_offset + dev_priv->ramfc_size; - ret = init_heap(&dev_priv->ramin_heap, - offset, dev_priv->ramin_size - offset); + ret = nouveau_mem_init_heap(&dev_priv->ramin_heap, + offset, dev_priv->ramin_size - offset); if (ret) { dev_priv->ramin_heap = NULL; DRM_ERROR("Failed to init RAMIN heap\n"); @@ -570,7 +584,8 @@ struct mem_block *nouveau_instmem_alloc(struct drm_device *dev, return NULL; } - block = alloc_block(dev_priv->ramin_heap, size, align, (DRMFILE)-2); + block = nouveau_mem_alloc_block(dev_priv->ramin_heap, size, align, + (DRMFILE)-2); if (block) { block->flags = NOUVEAU_MEM_INSTANCE; DRM_DEBUG("instance(size=%d, align=%d) alloc'd at 0x%08x\n", @@ -583,7 +598,7 @@ struct mem_block *nouveau_instmem_alloc(struct drm_device *dev, void nouveau_instmem_free(struct drm_device *dev, struct mem_block *block) { if (dev && block) { - free_block(block); + nouveau_mem_free_block(block); } } -- cgit v1.2.3 From 18a6d1c9c380b6b19524f654d9173a79e19aa1df Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 25 Jun 2007 15:16:19 +1000 Subject: nouveau: simplify PRAMIN access --- shared-core/nouveau_mem.c | 32 -------------------------------- 1 file changed, 32 deletions(-) (limited to 'shared-core/nouveau_mem.c') diff --git a/shared-core/nouveau_mem.c b/shared-core/nouveau_mem.c index edfc9d3f..4c6d0d5c 100644 --- a/shared-core/nouveau_mem.c +++ b/shared-core/nouveau_mem.c @@ -602,38 +602,6 @@ void nouveau_instmem_free(struct drm_device *dev, struct mem_block *block) } } -uint32_t nouveau_instmem_r32(drm_nouveau_private_t *dev_priv, - struct mem_block *mem, int index) -{ - uint32_t ofs = (uint32_t)mem->start + (index<<2); - - if (dev_priv->ramin) { -#if defined(__powerpc__) - return in_be32((void __iomem *)(dev_priv->ramin)->handle + ofs); -#else - return DRM_READ32(dev_priv->ramin, ofs); -#endif - } else { - return NV_READ(NV_RAMIN+ofs); - } -} - -void nouveau_instmem_w32(drm_nouveau_private_t *dev_priv, - struct mem_block *mem, int index, uint32_t val) -{ - uint32_t ofs = (uint32_t)mem->start + (index<<2); - - if (dev_priv->ramin) { -#if defined(__powerpc__) - out_be32((void __iomem *)(dev_priv->ramin)->handle + ofs, val); -#else - DRM_WRITE32(dev_priv->ramin, ofs, val); -#endif - } else { - NV_WRITE(NV_RAMIN+ofs, val); - } -} - /* * Ioctls */ -- cgit v1.2.3 From 68ecf61647e9ec16d59cc8f50550d11478eb3118 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 25 Jun 2007 15:42:55 +1000 Subject: nouveau: never touch PRAMIN with NV_WRITE, cleanup RAMHT code a bit --- shared-core/nouveau_mem.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'shared-core/nouveau_mem.c') diff --git a/shared-core/nouveau_mem.c b/shared-core/nouveau_mem.c index 4c6d0d5c..d8ae52b7 100644 --- a/shared-core/nouveau_mem.c +++ b/shared-core/nouveau_mem.c @@ -489,13 +489,8 @@ nouveau_instmem_determine_amount(struct drm_device *dev) DRM_DEBUG("RAMIN size: %dKiB\n", dev_priv->ramin_size>>10); /* Clear all of it, except the BIOS image that's in the first 64KiB */ - if (dev_priv->ramin) { - for (i=(64*1024); iramin_size; i+=4) - DRM_WRITE32(dev_priv->ramin, i, 0x00000000); - } else { - for (i=(64*1024); iramin_size; i+=4) - DRM_WRITE32(dev_priv->mmio, NV_RAMIN + i, 0x00000000); - } + for (i=(64*1024); iramin_size; i+=4) + NV_WI32(i, 0x00000000); } static void -- 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/nouveau_mem.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'shared-core/nouveau_mem.c') diff --git a/shared-core/nouveau_mem.c b/shared-core/nouveau_mem.c index d8ae52b7..49041862 100644 --- a/shared-core/nouveau_mem.c +++ b/shared-core/nouveau_mem.c @@ -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. */ -- 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/nouveau_mem.c | 143 +--------------------------------------------- 1 file changed, 1 insertion(+), 142 deletions(-) (limited to 'shared-core/nouveau_mem.c') diff --git a/shared-core/nouveau_mem.c b/shared-core/nouveau_mem.c index 49041862..c75a9356 100644 --- a/shared-core/nouveau_mem.c +++ b/shared-core/nouveau_mem.c @@ -353,7 +353,7 @@ no_agp: /* On at least NV40, RAMIN is actually at the end of vram. * We don't want to allocate this... */ if (dev_priv->card_type >= NV_40) - fb_size -= dev_priv->ramin_size; + fb_size -= dev_priv->ramin_rsvd_vram; dev_priv->fb_available_size = fb_size; DRM_DEBUG("Available VRAM: %dKiB\n", fb_size>>10); @@ -463,147 +463,6 @@ void nouveau_mem_free(struct drm_device* dev, struct mem_block* block) nouveau_mem_free_block(block); } -static void -nouveau_instmem_determine_amount(struct drm_device *dev) -{ - drm_nouveau_private_t *dev_priv = dev->dev_private; - int i; - - /* Figure out how much instance memory we need */ - switch (dev_priv->card_type) { - case NV_40: - /* We'll want more instance memory than this on some NV4x cards. - * There's a 16MB aperture to play with that maps onto the end - * of vram. For now, only reserve a small piece until we know - * more about what each chipset requires. - */ - dev_priv->ramin_size = (1*1024* 1024); - break; - default: - /*XXX: what *are* the limits on ramin_size = (512*1024); - break; - } - DRM_DEBUG("RAMIN size: %dKiB\n", dev_priv->ramin_size>>10); - - /* Clear all of it, except the BIOS image that's in the first 64KiB */ - for (i=(64*1024); iramin_size; i+=4) - NV_WI32(i, 0x00000000); -} - -static void -nouveau_instmem_configure_fixed_tables(struct drm_device *dev) -{ - drm_nouveau_private_t *dev_priv = dev->dev_private; - - /* FIFO hash table (RAMHT) - * use 4k hash table at RAMIN+0x10000 - * TODO: extend the hash table - */ - dev_priv->ramht_offset = 0x10000; - dev_priv->ramht_bits = 9; - dev_priv->ramht_size = (1 << dev_priv->ramht_bits); - DRM_DEBUG("RAMHT offset=0x%x, size=%d\n", dev_priv->ramht_offset, - dev_priv->ramht_size); - - /* FIFO runout table (RAMRO) - 512k at 0x11200 */ - dev_priv->ramro_offset = 0x11200; - dev_priv->ramro_size = 512; - DRM_DEBUG("RAMRO offset=0x%x, size=%d\n", dev_priv->ramro_offset, - dev_priv->ramro_size); - - /* FIFO context table (RAMFC) - * NV40 : Not sure exactly how to position RAMFC on some cards, - * 0x30002 seems to position it at RAMIN+0x20000 on these - * cards. RAMFC is 4kb (32 fifos, 128byte entries). - * Others: Position RAMFC at RAMIN+0x11400 - */ - switch(dev_priv->card_type) - { - case NV_50: - case NV_40: - case NV_44: - dev_priv->ramfc_offset = 0x20000; - dev_priv->ramfc_size = nouveau_fifo_number(dev) * - nouveau_fifo_ctx_size(dev); - break; - case NV_30: - case NV_20: - case NV_17: - case NV_10: - case NV_04: - case NV_03: - default: - dev_priv->ramfc_offset = 0x11400; - dev_priv->ramfc_size = nouveau_fifo_number(dev) * - nouveau_fifo_ctx_size(dev); - break; - } - DRM_DEBUG("RAMFC offset=0x%x, size=%d\n", dev_priv->ramfc_offset, - dev_priv->ramfc_size); -} - -int nouveau_instmem_init(struct drm_device *dev) -{ - drm_nouveau_private_t *dev_priv = dev->dev_private; - uint32_t offset; - int ret = 0; - - 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. - */ - offset = dev_priv->ramfc_offset + dev_priv->ramfc_size; - ret = nouveau_mem_init_heap(&dev_priv->ramin_heap, - offset, dev_priv->ramin_size - offset); - if (ret) { - dev_priv->ramin_heap = NULL; - DRM_ERROR("Failed to init RAMIN heap\n"); - } - - return ret; -} - -struct mem_block *nouveau_instmem_alloc(struct drm_device *dev, - uint32_t size, uint32_t align) -{ - drm_nouveau_private_t *dev_priv = dev->dev_private; - struct mem_block *block; - - if (!dev_priv->ramin_heap) { - DRM_ERROR("instmem alloc called without init\n"); - return NULL; - } - - block = nouveau_mem_alloc_block(dev_priv->ramin_heap, size, align, - (DRMFILE)-2); - if (block) { - block->flags = NOUVEAU_MEM_INSTANCE; - DRM_DEBUG("instance(size=%d, align=%d) alloc'd at 0x%08x\n", - size, (1<start); - } - - return block; -} - -void nouveau_instmem_free(struct drm_device *dev, struct mem_block *block) -{ - if (dev && block) { - nouveau_mem_free_block(block); - } -} - /* * Ioctls */ -- cgit v1.2.3 From 694e1c5c3f768436651ddf95e11ab5a89ccc8ffa Mon Sep 17 00:00:00 2001 From: Arthur Huillet Date: Wed, 11 Jul 2007 02:35:10 +0200 Subject: Added support for PCIGART for PCI(E) cards. Bumped DRM interface patchlevel. --- shared-core/nouveau_mem.c | 89 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 64 insertions(+), 25 deletions(-) (limited to 'shared-core/nouveau_mem.c') diff --git a/shared-core/nouveau_mem.c b/shared-core/nouveau_mem.c index c75a9356..79f94fd4 100644 --- a/shared-core/nouveau_mem.c +++ b/shared-core/nouveau_mem.c @@ -211,6 +211,10 @@ void nouveau_mem_close(struct drm_device *dev) drm_nouveau_private_t *dev_priv = dev->dev_private; nouveau_mem_takedown(&dev_priv->agp_heap); nouveau_mem_takedown(&dev_priv->fb_heap); + if ( dev_priv->pci_heap ) + { + nouveau_mem_takedown(&dev_priv->pci_heap); + } } /* returns the amount of FB ram in bytes */ @@ -283,8 +287,10 @@ int nouveau_mem_init(struct drm_device *dev) { drm_nouveau_private_t *dev_priv = dev->dev_private; uint32_t fb_size; + drm_scatter_gather_t sgreq; dev_priv->agp_phys=0; dev_priv->fb_phys=0; + sgreq . size = 4 << 20; //4MB of PCI scatter-gather zone /* init AGP */ dev_priv->agp_heap=NULL; @@ -340,8 +346,26 @@ int nouveau_mem_init(struct drm_device *dev) dev_priv->agp_phys = info.aperture_base; dev_priv->agp_available_size = info.aperture_size; } + +goto have_agp; no_agp: + dev_priv->pci_heap = NULL; + DRM_DEBUG("Allocating sg memory for PCI DMA\n"); + if ( drm_sg_alloc(dev, &sgreq) ) + { + DRM_ERROR("Unable to allocate 4MB of scatter-gather pages for PCI DMA!"); + goto no_pci; + } + DRM_DEBUG("Got %d KiB\n", (dev->sg->pages * PAGE_SIZE) >> 10); + if ( nouveau_mem_init_heap(&dev_priv->pci_heap, dev->sg->virtual, dev->sg->pages * PAGE_SIZE)) + { + DRM_ERROR("Unable to initialize pci_heap!"); + goto no_pci; + } + +no_pci: +have_agp: /* setup a mtrr over the FB */ dev_priv->fb_mtrr = drm_mtrr_add(drm_get_resource_start(dev, 1), nouveau_mem_fb_amount(dev), @@ -405,29 +429,40 @@ struct mem_block* nouveau_mem_alloc(struct drm_device *dev, int alignment, uint6 if (size & (~PAGE_MASK)) size = ((size/PAGE_SIZE) + 1) * PAGE_SIZE; - if (flags&NOUVEAU_MEM_AGP) { - type=NOUVEAU_MEM_AGP; - block = nouveau_mem_alloc_block(dev_priv->agp_heap, size, - alignment, filp); - if (block) goto alloc_ok; - } - if (flags&(NOUVEAU_MEM_FB|NOUVEAU_MEM_FB_ACCEPTABLE)) { - type=NOUVEAU_MEM_FB; - if (!(flags&NOUVEAU_MEM_MAPPED)) { - block = nouveau_mem_alloc_block(dev_priv->fb_nomap_heap, - size, alignment, filp); - if (block) goto alloc_ok; - } - block = nouveau_mem_alloc_block(dev_priv->fb_heap, size, - alignment, filp); - if (block) goto alloc_ok; - } - if (flags&NOUVEAU_MEM_AGP_ACCEPTABLE) { - type=NOUVEAU_MEM_AGP; - block = nouveau_mem_alloc_block(dev_priv->agp_heap, size, - alignment, filp); - if (block) goto alloc_ok; - } + +#define NOUVEAU_MEM_ALLOC_AGP {\ + type=NOUVEAU_MEM_AGP;\ + block = nouveau_mem_alloc_block(dev_priv->agp_heap, size,\ + alignment, filp);\ + if (block) goto alloc_ok;\ + } + +#define NOUVEAU_MEM_ALLOC_PCI {\ + type = NOUVEAU_MEM_PCI;\ + block = nouveau_mem_alloc_block(dev_priv->pci_heap, size, alignment, filp);\ + if ( block ) goto alloc_ok;\ + } + +#define NOUVEAU_MEM_ALLOC_FB {\ + type=NOUVEAU_MEM_FB;\ + if (!(flags&NOUVEAU_MEM_MAPPED)) {\ + block = nouveau_mem_alloc_block(dev_priv->fb_nomap_heap,\ + size, alignment, filp); \ + if (block) goto alloc_ok;\ + }\ + block = nouveau_mem_alloc_block(dev_priv->fb_heap, size,\ + alignment, filp);\ + if (block) goto alloc_ok;\ + } + + + if (flags&NOUVEAU_MEM_FB) NOUVEAU_MEM_ALLOC_FB + if (flags&NOUVEAU_MEM_AGP) NOUVEAU_MEM_ALLOC_AGP + if (flags&NOUVEAU_MEM_PCI) NOUVEAU_MEM_ALLOC_PCI + if (flags&NOUVEAU_MEM_FB_ACCEPTABLE) NOUVEAU_MEM_ALLOC_FB + if (flags&NOUVEAU_MEM_AGP_ACCEPTABLE) NOUVEAU_MEM_ALLOC_AGP + if (flags&NOUVEAU_MEM_PCI_ACCEPTABLE) NOUVEAU_MEM_ALLOC_PCI + return NULL; @@ -436,15 +471,19 @@ alloc_ok: if (flags&NOUVEAU_MEM_MAPPED) { - int ret; + int ret = 0; block->flags|=NOUVEAU_MEM_MAPPED; if (type == NOUVEAU_MEM_AGP) ret = drm_addmap(dev, block->start - dev->agp->base, block->size, _DRM_AGP, 0, &block->map); - else + else if (type == NOUVEAU_MEM_FB) ret = drm_addmap(dev, block->start, block->size, _DRM_FRAME_BUFFER, 0, &block->map); + else if (type == NOUVEAU_MEM_PCI) + ret = drm_addmap(dev, block->start - (unsigned long int)dev->sg->virtual, block->size, + _DRM_SCATTER_GATHER, 0, &block->map); + if (ret) { nouveau_mem_free_block(block); return NULL; -- cgit v1.2.3 From d26ae22c2b17e0f193334cefec7d141befcfa1ee Mon Sep 17 00:00:00 2001 From: Arthur Huillet Date: Wed, 11 Jul 2007 14:56:27 +0200 Subject: fixed bug that prevented PCIE cards from actually using PCIGART - NV50 will probably still have a problem --- shared-core/nouveau_mem.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'shared-core/nouveau_mem.c') diff --git a/shared-core/nouveau_mem.c b/shared-core/nouveau_mem.c index 79f94fd4..c545acf2 100644 --- a/shared-core/nouveau_mem.c +++ b/shared-core/nouveau_mem.c @@ -345,9 +345,9 @@ int nouveau_mem_init(struct drm_device *dev) dev_priv->agp_phys = info.aperture_base; dev_priv->agp_available_size = info.aperture_size; + goto have_agp; } -goto have_agp; no_agp: dev_priv->pci_heap = NULL; DRM_DEBUG("Allocating sg memory for PCI DMA\n"); @@ -357,8 +357,7 @@ no_agp: goto no_pci; } - DRM_DEBUG("Got %d KiB\n", (dev->sg->pages * PAGE_SIZE) >> 10); - if ( nouveau_mem_init_heap(&dev_priv->pci_heap, dev->sg->virtual, dev->sg->pages * PAGE_SIZE)) + if ( nouveau_mem_init_heap(&dev_priv->pci_heap, (uint64_t) dev->sg->virtual, dev->sg->pages * PAGE_SIZE)) { DRM_ERROR("Unable to initialize pci_heap!"); goto no_pci; -- cgit v1.2.3 From b301a9051b3fd9ad3dce6bcf32b06da7953a8b91 Mon Sep 17 00:00:00 2001 From: Arthur Huillet Date: Wed, 11 Jul 2007 15:01:37 +0200 Subject: NV50 will not attempt to use PCIGART now --- shared-core/nouveau_mem.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'shared-core/nouveau_mem.c') diff --git a/shared-core/nouveau_mem.c b/shared-core/nouveau_mem.c index c545acf2..a428b813 100644 --- a/shared-core/nouveau_mem.c +++ b/shared-core/nouveau_mem.c @@ -349,6 +349,9 @@ int nouveau_mem_init(struct drm_device *dev) } no_agp: + + if ( dev_priv->card_type >= NV_50 ) goto no_pci; + dev_priv->pci_heap = NULL; DRM_DEBUG("Allocating sg memory for PCI DMA\n"); if ( drm_sg_alloc(dev, &sgreq) ) -- cgit v1.2.3 From 5fbdf9da8bda996c0a474d13fe69d260f12ffce7 Mon Sep 17 00:00:00 2001 From: Arthur Huillet Date: Thu, 12 Jul 2007 02:35:39 +0200 Subject: fixed object creation code to not Oops on 64bits, worked around memalloc not working on 64bit for PCIGART --- shared-core/nouveau_mem.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'shared-core/nouveau_mem.c') diff --git a/shared-core/nouveau_mem.c b/shared-core/nouveau_mem.c index a428b813..790f6b5b 100644 --- a/shared-core/nouveau_mem.c +++ b/shared-core/nouveau_mem.c @@ -549,6 +549,8 @@ int nouveau_ioctl_mem_free(DRM_IOCTL_ARGS) block = find_block(dev_priv->fb_heap, memfree.region_offset); else if (memfree.flags&NOUVEAU_MEM_AGP) block = find_block(dev_priv->agp_heap, memfree.region_offset); + else if (memfree.flags&NOUVEAU_MEM_PCI) + block = find_block(dev_priv->pci_heap, memfree.region_offset); if (!block) return DRM_ERR(EFAULT); if (block->filp != filp) -- cgit v1.2.3 From 750371cb6ea9a64c9d4d4d3b9716c3c68d810d48 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 12 Jul 2007 10:15:16 +1000 Subject: nouveau: separate region_offset into map_handle and offset. --- shared-core/nouveau_mem.c | 48 ++++++++++++++++++++++++++--------------------- 1 file changed, 27 insertions(+), 21 deletions(-) (limited to 'shared-core/nouveau_mem.c') diff --git a/shared-core/nouveau_mem.c b/shared-core/nouveau_mem.c index 790f6b5b..d4b2bc04 100644 --- a/shared-core/nouveau_mem.c +++ b/shared-core/nouveau_mem.c @@ -339,8 +339,7 @@ int nouveau_mem_init(struct drm_device *dev) } if (nouveau_mem_init_heap(&dev_priv->agp_heap, - info.aperture_base, - info.aperture_size)) + 0, info.aperture_size)) goto no_agp; dev_priv->agp_phys = info.aperture_base; @@ -360,7 +359,8 @@ no_agp: goto no_pci; } - if ( nouveau_mem_init_heap(&dev_priv->pci_heap, (uint64_t) dev->sg->virtual, dev->sg->pages * PAGE_SIZE)) + if ( nouveau_mem_init_heap(&dev_priv->pci_heap, 0, + dev->sg->pages * PAGE_SIZE)) { DRM_ERROR("Unable to initialize pci_heap!"); goto no_pci; @@ -387,18 +387,13 @@ have_agp: /* On cards with > 256Mb, you can't map everything. * So we create a second FB heap for that type of memory */ if (nouveau_mem_init_heap(&dev_priv->fb_heap, - drm_get_resource_start(dev,1), - 256*1024*1024)) + 0, 256*1024*1024)) return DRM_ERR(ENOMEM); if (nouveau_mem_init_heap(&dev_priv->fb_nomap_heap, - drm_get_resource_start(dev,1) + - 256*1024*1024, - fb_size-256*1024*1024)) + 256*1024*1024, fb_size-256*1024*1024)) return DRM_ERR(ENOMEM); } else { - if (nouveau_mem_init_heap(&dev_priv->fb_heap, - drm_get_resource_start(dev,1), - fb_size)) + if (nouveau_mem_init_heap(&dev_priv->fb_heap, 0, fb_size)) return DRM_ERR(ENOMEM); dev_priv->fb_nomap_heap=NULL; } @@ -473,23 +468,33 @@ alloc_ok: if (flags&NOUVEAU_MEM_MAPPED) { + drm_map_list_t *entry; int ret = 0; block->flags|=NOUVEAU_MEM_MAPPED; if (type == NOUVEAU_MEM_AGP) - ret = drm_addmap(dev, block->start - dev->agp->base, block->size, - _DRM_AGP, 0, &block->map); + ret = drm_addmap(dev, block->start + dev->agp->base, + block->size, _DRM_AGP, 0, &block->map); else if (type == NOUVEAU_MEM_FB) - ret = drm_addmap(dev, block->start, block->size, - _DRM_FRAME_BUFFER, 0, &block->map); + ret = drm_addmap(dev, block->start + dev_priv->fb_phys, + block->size, _DRM_FRAME_BUFFER, + 0, &block->map); else if (type == NOUVEAU_MEM_PCI) - ret = drm_addmap(dev, block->start - (unsigned long int)dev->sg->virtual, block->size, - _DRM_SCATTER_GATHER, 0, &block->map); + ret = drm_addmap(dev, block->start, block->size, + _DRM_SCATTER_GATHER, 0, &block->map); if (ret) { nouveau_mem_free_block(block); return NULL; } + + entry = drm_find_matching_map(dev, block->map); + if (!entry) { + nouveau_mem_free_block(block); + return NULL; + } + DRM_ERROR("user_token=0x%08x\n", entry->user_token); + block->map_handle = entry->user_token; } DRM_INFO("allocated 0x%llx\n", block->start); @@ -526,7 +531,8 @@ int nouveau_ioctl_mem_alloc(DRM_IOCTL_ARGS) block=nouveau_mem_alloc(dev, alloc.alignment, alloc.size, alloc.flags, filp); if (!block) return DRM_ERR(ENOMEM); - alloc.region_offset=block->start; + alloc.map_handle=block->map_handle; + alloc.offset=block->start; alloc.flags=block->flags; DRM_COPY_TO_USER_IOCTL((drm_nouveau_mem_alloc_t __user *) data, alloc, sizeof(alloc)); @@ -546,11 +552,11 @@ int nouveau_ioctl_mem_free(DRM_IOCTL_ARGS) block=NULL; if (memfree.flags&NOUVEAU_MEM_FB) - block = find_block(dev_priv->fb_heap, memfree.region_offset); + block = find_block(dev_priv->fb_heap, memfree.offset); else if (memfree.flags&NOUVEAU_MEM_AGP) - block = find_block(dev_priv->agp_heap, memfree.region_offset); + block = find_block(dev_priv->agp_heap, memfree.offset); else if (memfree.flags&NOUVEAU_MEM_PCI) - block = find_block(dev_priv->pci_heap, memfree.region_offset); + block = find_block(dev_priv->pci_heap, memfree.offset); if (!block) return DRM_ERR(EFAULT); if (block->filp != filp) -- cgit v1.2.3 From 522a0c868c79b48c5434f39faab1a02ca4425a90 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 12 Jul 2007 11:39:45 +1000 Subject: nouveau: nuke left over debug message --- shared-core/nouveau_mem.c | 1 - 1 file changed, 1 deletion(-) (limited to 'shared-core/nouveau_mem.c') diff --git a/shared-core/nouveau_mem.c b/shared-core/nouveau_mem.c index d4b2bc04..9bfa8365 100644 --- a/shared-core/nouveau_mem.c +++ b/shared-core/nouveau_mem.c @@ -493,7 +493,6 @@ alloc_ok: nouveau_mem_free_block(block); return NULL; } - DRM_ERROR("user_token=0x%08x\n", entry->user_token); block->map_handle = entry->user_token; } -- cgit v1.2.3 From 851c950d988e5a47fa6add71427e5ef8d4dcf231 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 13 Jul 2007 02:18:59 +1000 Subject: nouveau: unbreak AGP --- shared-core/nouveau_mem.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'shared-core/nouveau_mem.c') diff --git a/shared-core/nouveau_mem.c b/shared-core/nouveau_mem.c index 9bfa8365..79d1bb87 100644 --- a/shared-core/nouveau_mem.c +++ b/shared-core/nouveau_mem.c @@ -473,8 +473,8 @@ alloc_ok: block->flags|=NOUVEAU_MEM_MAPPED; if (type == NOUVEAU_MEM_AGP) - ret = drm_addmap(dev, block->start + dev->agp->base, - block->size, _DRM_AGP, 0, &block->map); + ret = drm_addmap(dev, block->start, block->size, + _DRM_AGP, 0, &block->map); else if (type == NOUVEAU_MEM_FB) ret = drm_addmap(dev, block->start + dev_priv->fb_phys, block->size, _DRM_FRAME_BUFFER, -- cgit v1.2.3