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 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_mem.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) (limited to 'shared-core/nouveau_mem.c') diff --git a/shared-core/nouveau_mem.c b/shared-core/nouveau_mem.c index 79d1bb87..2b2418fb 100644 --- a/shared-core/nouveau_mem.c +++ b/shared-core/nouveau_mem.c @@ -208,7 +208,7 @@ void nouveau_mem_takedown(struct mem_block **heap) void nouveau_mem_close(struct drm_device *dev) { - drm_nouveau_private_t *dev_priv = dev->dev_private; + struct drm_nouveau_private *dev_priv = dev->dev_private; nouveau_mem_takedown(&dev_priv->agp_heap); nouveau_mem_takedown(&dev_priv->fb_heap); if ( dev_priv->pci_heap ) @@ -220,7 +220,7 @@ void nouveau_mem_close(struct drm_device *dev) /* returns the amount of FB ram in bytes */ uint64_t nouveau_mem_fb_amount(struct drm_device *dev) { - drm_nouveau_private_t *dev_priv=dev->dev_private; + struct drm_nouveau_private *dev_priv=dev->dev_private; switch(dev_priv->card_type) { case NV_03: @@ -285,7 +285,7 @@ uint64_t nouveau_mem_fb_amount(struct drm_device *dev) int nouveau_mem_init(struct drm_device *dev) { - drm_nouveau_private_t *dev_priv = dev->dev_private; + struct drm_nouveau_private *dev_priv = dev->dev_private; uint32_t fb_size; drm_scatter_gather_t sgreq; dev_priv->agp_phys=0; @@ -405,7 +405,7 @@ struct mem_block* nouveau_mem_alloc(struct drm_device *dev, int alignment, uint6 { struct mem_block *block; int type; - drm_nouveau_private_t *dev_priv = dev->dev_private; + struct drm_nouveau_private *dev_priv = dev->dev_private; /* * Make things easier on ourselves: all allocations are page-aligned. @@ -515,8 +515,8 @@ void nouveau_mem_free(struct drm_device* dev, struct mem_block* block) int nouveau_ioctl_mem_alloc(DRM_IOCTL_ARGS) { DRM_DEVICE; - drm_nouveau_private_t *dev_priv = dev->dev_private; - drm_nouveau_mem_alloc_t alloc; + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct drm_nouveau_mem_alloc alloc; struct mem_block *block; if (!dev_priv) { @@ -524,7 +524,8 @@ int nouveau_ioctl_mem_alloc(DRM_IOCTL_ARGS) return DRM_ERR(EINVAL); } - DRM_COPY_FROM_USER_IOCTL(alloc, (drm_nouveau_mem_alloc_t __user *) data, + DRM_COPY_FROM_USER_IOCTL(alloc, + (struct drm_nouveau_mem_alloc_t __user *) data, sizeof(alloc)); block=nouveau_mem_alloc(dev, alloc.alignment, alloc.size, alloc.flags, filp); @@ -534,7 +535,8 @@ int nouveau_ioctl_mem_alloc(DRM_IOCTL_ARGS) alloc.offset=block->start; alloc.flags=block->flags; - DRM_COPY_TO_USER_IOCTL((drm_nouveau_mem_alloc_t __user *) data, alloc, sizeof(alloc)); + DRM_COPY_TO_USER_IOCTL((struct drm_nouveau_mem_alloc __user *)data, + alloc, sizeof(alloc)); return 0; } @@ -542,11 +544,12 @@ int nouveau_ioctl_mem_alloc(DRM_IOCTL_ARGS) int nouveau_ioctl_mem_free(DRM_IOCTL_ARGS) { DRM_DEVICE; - drm_nouveau_private_t *dev_priv = dev->dev_private; - drm_nouveau_mem_free_t memfree; + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct drm_nouveau_mem_free memfree; struct mem_block *block; - DRM_COPY_FROM_USER_IOCTL(memfree, (drm_nouveau_mem_free_t __user *) data, + DRM_COPY_FROM_USER_IOCTL(memfree, + (struct drm_nouveau_mem_free_t __user *)data, sizeof(memfree)); block=NULL; -- cgit v1.2.3 From bc7d6c76fab2ff4d2f11b6bd84ca8b8f124729fd Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Sat, 14 Jul 2007 18:32:11 +0200 Subject: nouveau: nv10 and nv11/15 are different --- shared-core/nouveau_mem.c | 1 + 1 file changed, 1 insertion(+) (limited to 'shared-core/nouveau_mem.c') diff --git a/shared-core/nouveau_mem.c b/shared-core/nouveau_mem.c index 2b2418fb..f09bcea7 100644 --- a/shared-core/nouveau_mem.c +++ b/shared-core/nouveau_mem.c @@ -253,6 +253,7 @@ uint64_t nouveau_mem_fb_amount(struct drm_device *dev) } break; case NV_10: + case NV_11: case NV_17: case NV_20: case NV_30: -- cgit v1.2.3 From b95ac8b7b313ad3eadc9e8bb0ead155303b7fa92 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 16 Jul 2007 11:22:15 +1000 Subject: drm: detypedef drm.h and fixup all problems --- shared-core/nouveau_mem.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'shared-core/nouveau_mem.c') diff --git a/shared-core/nouveau_mem.c b/shared-core/nouveau_mem.c index f09bcea7..ef9df359 100644 --- a/shared-core/nouveau_mem.c +++ b/shared-core/nouveau_mem.c @@ -288,7 +288,7 @@ int nouveau_mem_init(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; uint32_t fb_size; - drm_scatter_gather_t sgreq; + struct drm_scatter_gather sgreq; dev_priv->agp_phys=0; dev_priv->fb_phys=0; sgreq . size = 4 << 20; //4MB of PCI scatter-gather zone @@ -298,10 +298,10 @@ int nouveau_mem_init(struct drm_device *dev) if (drm_device_is_agp(dev)) { int err; - drm_agp_info_t info; - drm_agp_mode_t mode; - drm_agp_buffer_t agp_req; - drm_agp_binding_t bind_req; + struct drm_agp_info info; + struct drm_agp_mode mode; + struct drm_agp_buffer agp_req; + struct drm_agp_binding bind_req; err = drm_agp_acquire(dev); if (err) { -- cgit v1.2.3 From 21ee6fbfb8f2219a454458204afc9c5fcd89f9a8 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 16 Jul 2007 12:32:51 +1000 Subject: drm: remove drmP.h internal typedefs --- shared-core/nouveau_mem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'shared-core/nouveau_mem.c') diff --git a/shared-core/nouveau_mem.c b/shared-core/nouveau_mem.c index ef9df359..e5906867 100644 --- a/shared-core/nouveau_mem.c +++ b/shared-core/nouveau_mem.c @@ -469,7 +469,7 @@ alloc_ok: if (flags&NOUVEAU_MEM_MAPPED) { - drm_map_list_t *entry; + struct drm_map_list *entry; int ret = 0; block->flags|=NOUVEAU_MEM_MAPPED; -- 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_mem.c | 187 ++++++++++++++++++++++++++-------------------- 1 file changed, 107 insertions(+), 80 deletions(-) (limited to 'shared-core/nouveau_mem.c') diff --git a/shared-core/nouveau_mem.c b/shared-core/nouveau_mem.c index e5906867..7a923e17 100644 --- a/shared-core/nouveau_mem.c +++ b/shared-core/nouveau_mem.c @@ -209,12 +209,11 @@ void nouveau_mem_takedown(struct mem_block **heap) void nouveau_mem_close(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; + nouveau_mem_takedown(&dev_priv->agp_heap); nouveau_mem_takedown(&dev_priv->fb_heap); - if ( dev_priv->pci_heap ) - { + if (dev_priv->pci_heap) nouveau_mem_takedown(&dev_priv->pci_heap); - } } /* returns the amount of FB ram in bytes */ @@ -282,93 +281,68 @@ uint64_t nouveau_mem_fb_amount(struct drm_device *dev) return 0; } - - -int nouveau_mem_init(struct drm_device *dev) +static int +nouveau_mem_init_agp(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; - uint32_t fb_size; - struct drm_scatter_gather 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; - if (drm_device_is_agp(dev)) - { - int err; - struct drm_agp_info info; - struct drm_agp_mode mode; - struct drm_agp_buffer agp_req; - struct drm_agp_binding bind_req; - - err = drm_agp_acquire(dev); - if (err) { - DRM_ERROR("Unable to acquire AGP: %d\n", err); - goto no_agp; - } - - err = drm_agp_info(dev, &info); - if (err) { - DRM_ERROR("Unable to get AGP info: %d\n", err); - goto no_agp; - } - - /* see agp.h for the AGPSTAT_* modes available */ - mode.mode = info.mode; - err = drm_agp_enable(dev, mode); - if (err) { - DRM_ERROR("Unable to enable AGP: %d\n", err); - goto no_agp; - } - - agp_req.size = info.aperture_size; - agp_req.type = 0; - err = drm_agp_alloc(dev, &agp_req); - if (err) { - DRM_ERROR("Unable to alloc AGP: %d\n", err); - goto no_agp; - } + struct drm_agp_info info; + struct drm_agp_mode mode; + struct drm_agp_buffer agp_req; + struct drm_agp_binding bind_req; + int ret; + + ret = drm_agp_acquire(dev); + if (ret) { + DRM_ERROR("Unable to acquire AGP: %d\n", ret); + return ret; + } - bind_req.handle = agp_req.handle; - bind_req.offset = 0; - err = drm_agp_bind(dev, &bind_req); - if (err) { - DRM_ERROR("Unable to bind AGP: %d\n", err); - goto no_agp; - } + ret = drm_agp_info(dev, &info); + if (ret) { + DRM_ERROR("Unable to get AGP info: %d\n", ret); + return ret; + } - if (nouveau_mem_init_heap(&dev_priv->agp_heap, - 0, info.aperture_size)) - goto no_agp; + /* see agp.h for the AGPSTAT_* modes available */ + mode.mode = info.mode; + ret = drm_agp_enable(dev, mode); + if (ret) { + DRM_ERROR("Unable to enable AGP: %d\n", ret); + return ret; + } - dev_priv->agp_phys = info.aperture_base; - dev_priv->agp_available_size = info.aperture_size; - goto have_agp; + agp_req.size = info.aperture_size; + agp_req.type = 0; + ret = drm_agp_alloc(dev, &agp_req); + if (ret) { + DRM_ERROR("Unable to alloc AGP: %d\n", ret); + return ret; } -no_agp: + bind_req.handle = agp_req.handle; + bind_req.offset = 0; + ret = drm_agp_bind(dev, &bind_req); + if (ret) { + DRM_ERROR("Unable to bind AGP: %d\n", ret); + return ret; + } - if ( dev_priv->card_type >= NV_50 ) goto no_pci; + dev_priv->gart_info.type = NOUVEAU_GART_AGP; + dev_priv->gart_info.aper_base = info.aperture_base; + dev_priv->gart_info.aper_size = info.aperture_size; + return 0; +} - 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; - } +int nouveau_mem_init(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + uint32_t fb_size; + int ret = 0; - 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; - } + dev_priv->agp_heap = dev_priv->pci_heap = dev_priv->fb_heap = NULL; + dev_priv->fb_phys = 0; + dev_priv->gart_info.type = NOUVEAU_GART_NONE; -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), @@ -399,6 +373,54 @@ have_agp: dev_priv->fb_nomap_heap=NULL; } + /* Init AGP / NV50 PCIEGART */ + if (drm_device_is_agp(dev) && dev->agp) { + if ((ret = nouveau_mem_init_agp(dev))) + DRM_ERROR("Error initialising AGP: %d\n", ret); + } + + /*Note: this is *not* just NV50 code, but only used on NV50 for now */ + if (dev_priv->gart_info.type == NOUVEAU_GART_NONE && + dev_priv->card_type >= NV_50) { + ret = nouveau_sgdma_init(dev); + if (!ret) { + ret = nouveau_sgdma_nottm_hack_init(dev); + if (ret) + nouveau_sgdma_takedown(dev); + } + + if (ret) + DRM_ERROR("Error initialising SG DMA: %d\n", ret); + } + + if (dev_priv->gart_info.type != NOUVEAU_GART_NONE) { + if (nouveau_mem_init_heap(&dev_priv->agp_heap, + 0, dev_priv->gart_info.aper_size)) { + if (dev_priv->gart_info.type == NOUVEAU_GART_SGDMA) { + nouveau_sgdma_nottm_hack_takedown(dev); + nouveau_sgdma_takedown(dev); + } + } + } + + /* NV04-NV40 PCIEGART */ + if (!dev_priv->agp_heap && dev_priv->card_type < NV_50) { + struct drm_scatter_gather sgreq; + + DRM_DEBUG("Allocating sg memory for PCI DMA\n"); + sgreq.size = 4 << 20; //4MB of PCI scatter-gather zone + + if (drm_sg_alloc(dev, &sgreq)) { + DRM_ERROR("Unable to allocate 4MB of scatter-gather" + " pages for PCI DMA!"); + } else { + if (nouveau_mem_init_heap(&dev_priv->pci_heap, 0, + dev->sg->pages * PAGE_SIZE)) { + DRM_ERROR("Unable to initialize pci_heap!"); + } + } + } + return 0; } @@ -473,9 +495,14 @@ alloc_ok: int ret = 0; block->flags|=NOUVEAU_MEM_MAPPED; - if (type == NOUVEAU_MEM_AGP) + if (type == NOUVEAU_MEM_AGP) { + if (dev_priv->gart_info.type != NOUVEAU_GART_SGDMA) ret = drm_addmap(dev, block->start, block->size, _DRM_AGP, 0, &block->map); + else + ret = drm_addmap(dev, block->start, block->size, + _DRM_SCATTER_GATHER, 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 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_mem.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'shared-core/nouveau_mem.c') diff --git a/shared-core/nouveau_mem.c b/shared-core/nouveau_mem.c index 7a923e17..143378ff 100644 --- a/shared-core/nouveau_mem.c +++ b/shared-core/nouveau_mem.c @@ -138,12 +138,12 @@ int nouveau_mem_init_heap(struct mem_block **heap, uint64_t start, struct mem_block *blocks = drm_alloc(sizeof(*blocks), DRM_MEM_BUFS); if (!blocks) - return DRM_ERR(ENOMEM); + return -ENOMEM; *heap = drm_alloc(sizeof(**heap), DRM_MEM_BUFS); if (!*heap) { drm_free(blocks, sizeof(*blocks), DRM_MEM_BUFS); - return DRM_ERR(ENOMEM); + return -ENOMEM; } blocks->start = start; @@ -363,13 +363,13 @@ int nouveau_mem_init(struct drm_device *dev) * So we create a second FB heap for that type of memory */ if (nouveau_mem_init_heap(&dev_priv->fb_heap, 0, 256*1024*1024)) - return DRM_ERR(ENOMEM); + return -ENOMEM; if (nouveau_mem_init_heap(&dev_priv->fb_nomap_heap, 256*1024*1024, fb_size-256*1024*1024)) - return DRM_ERR(ENOMEM); + return -ENOMEM; } else { if (nouveau_mem_init_heap(&dev_priv->fb_heap, 0, fb_size)) - return DRM_ERR(ENOMEM); + return -ENOMEM; dev_priv->fb_nomap_heap=NULL; } @@ -549,7 +549,7 @@ int nouveau_ioctl_mem_alloc(DRM_IOCTL_ARGS) if (!dev_priv) { DRM_ERROR("%s called with no initialization\n", __FUNCTION__); - return DRM_ERR(EINVAL); + return -EINVAL; } DRM_COPY_FROM_USER_IOCTL(alloc, @@ -558,7 +558,7 @@ 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); + return -ENOMEM; alloc.map_handle=block->map_handle; alloc.offset=block->start; alloc.flags=block->flags; @@ -588,9 +588,9 @@ int nouveau_ioctl_mem_free(DRM_IOCTL_ARGS) else if (memfree.flags&NOUVEAU_MEM_PCI) block = find_block(dev_priv->pci_heap, memfree.offset); if (!block) - return DRM_ERR(EFAULT); + return -EFAULT; if (block->filp != filp) - return DRM_ERR(EPERM); + return -EPERM; nouveau_mem_free(dev, block); return 0; -- 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_mem.c | 62 ++++++++++++++++++++++++++--------------------- 1 file changed, 35 insertions(+), 27 deletions(-) (limited to 'shared-core/nouveau_mem.c') diff --git a/shared-core/nouveau_mem.c b/shared-core/nouveau_mem.c index 143378ff..6a4818c5 100644 --- a/shared-core/nouveau_mem.c +++ b/shared-core/nouveau_mem.c @@ -36,7 +36,7 @@ #include "nouveau_drv.h" static struct mem_block *split_block(struct mem_block *p, uint64_t start, uint64_t size, - DRMFILE filp) + struct drm_file *file_priv) { /* Maybe cut off the start of an existing block */ if (start > p->start) { @@ -46,7 +46,7 @@ static struct mem_block *split_block(struct mem_block *p, uint64_t start, uint64 goto out; newblock->start = start; newblock->size = p->size - (start - p->start); - newblock->filp = NULL; + newblock->file_priv = NULL; newblock->next = p->next; newblock->prev = p; p->next->prev = newblock; @@ -63,7 +63,7 @@ static struct mem_block *split_block(struct mem_block *p, uint64_t start, uint64 goto out; newblock->start = start + size; newblock->size = p->size - size; - newblock->filp = NULL; + newblock->file_priv = NULL; newblock->next = p->next; newblock->prev = p; p->next->prev = newblock; @@ -73,12 +73,14 @@ static struct mem_block *split_block(struct mem_block *p, uint64_t start, uint64 out: /* Our block is in the middle */ - p->filp = filp; + p->file_priv = file_priv; return p; } -struct mem_block *nouveau_mem_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, + struct drm_file *file_priv) { struct mem_block *p; uint64_t mask = (1 << align2) - 1; @@ -88,8 +90,8 @@ struct mem_block *nouveau_mem_alloc_block(struct mem_block *heap, uint64_t size, list_for_each(p, heap) { uint64_t start = (p->start + mask) & ~mask; - if (p->filp == 0 && start + size <= p->start + p->size) - return split_block(p, start, size, filp); + if (p->file_priv == 0 && start + size <= p->start + p->size) + return split_block(p, start, size, file_priv); } return NULL; @@ -108,12 +110,12 @@ static struct mem_block *find_block(struct mem_block *heap, uint64_t start) void nouveau_mem_free_block(struct mem_block *p) { - p->filp = NULL; + p->file_priv = NULL; - /* Assumes a single contiguous range. Needs a special filp in + /* Assumes a single contiguous range. Needs a special file_priv in * 'heap' to stop it being subsumed. */ - if (p->next->filp == 0) { + if (p->next->file_priv == 0) { struct mem_block *q = p->next; p->size += q->size; p->next = q->next; @@ -121,7 +123,7 @@ void nouveau_mem_free_block(struct mem_block *p) drm_free(q, sizeof(*q), DRM_MEM_BUFS); } - if (p->prev->filp == 0) { + if (p->prev->file_priv == 0) { struct mem_block *q = p->prev; q->size += p->size; q->next = p->next; @@ -148,19 +150,19 @@ int nouveau_mem_init_heap(struct mem_block **heap, uint64_t start, blocks->start = start; blocks->size = size; - blocks->filp = NULL; + blocks->file_priv = NULL; blocks->next = blocks->prev = *heap; memset(*heap, 0, sizeof(**heap)); - (*heap)->filp = (DRMFILE) - 1; + (*heap)->file_priv = (struct drm_file *) - 1; (*heap)->next = (*heap)->prev = blocks; return 0; } /* - * Free all blocks associated with the releasing filp + * Free all blocks associated with the releasing file_priv */ -void nouveau_mem_release(DRMFILE filp, struct mem_block *heap) +void nouveau_mem_release(struct drm_file *file_priv, struct mem_block *heap) { struct mem_block *p; @@ -168,15 +170,16 @@ void nouveau_mem_release(DRMFILE filp, struct mem_block *heap) return; list_for_each(p, heap) { - if (p->filp == filp) - p->filp = NULL; + if (p->file_priv == file_priv) + p->file_priv = NULL; } - /* Assumes a single contiguous range. Needs a special filp in + /* Assumes a single contiguous range. Needs a special file_priv in * 'heap' to stop it being subsumed. */ list_for_each(p, heap) { - while ((p->filp == 0) && (p->next->filp == 0) && (p->next!=heap)) { + while ((p->file_priv == 0) && (p->next->file_priv == 0) && + (p->next!=heap)) { struct mem_block *q = p->next; p->size += q->size; p->next = q->next; @@ -424,7 +427,9 @@ int nouveau_mem_init(struct drm_device *dev) return 0; } -struct mem_block* nouveau_mem_alloc(struct drm_device *dev, int alignment, uint64_t size, int flags, DRMFILE filp) +struct mem_block* nouveau_mem_alloc(struct drm_device *dev, int alignment, + uint64_t size, int flags, + struct drm_file *file_priv) { struct mem_block *block; int type; @@ -453,13 +458,14 @@ struct mem_block* nouveau_mem_alloc(struct drm_device *dev, int alignment, uint6 #define NOUVEAU_MEM_ALLOC_AGP {\ type=NOUVEAU_MEM_AGP;\ block = nouveau_mem_alloc_block(dev_priv->agp_heap, size,\ - alignment, filp);\ + alignment, file_priv); \ 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);\ + block = nouveau_mem_alloc_block(dev_priv->pci_heap, size, \ + alignment, file_priv); \ if ( block ) goto alloc_ok;\ } @@ -467,11 +473,12 @@ struct mem_block* nouveau_mem_alloc(struct drm_device *dev, int alignment, uint6 type=NOUVEAU_MEM_FB;\ if (!(flags&NOUVEAU_MEM_MAPPED)) {\ block = nouveau_mem_alloc_block(dev_priv->fb_nomap_heap,\ - size, alignment, filp); \ + size, alignment, \ + file_priv); \ if (block) goto alloc_ok;\ }\ block = nouveau_mem_alloc_block(dev_priv->fb_heap, size,\ - alignment, filp);\ + alignment, file_priv);\ if (block) goto alloc_ok;\ } @@ -556,7 +563,8 @@ int nouveau_ioctl_mem_alloc(DRM_IOCTL_ARGS) (struct drm_nouveau_mem_alloc_t __user *) data, sizeof(alloc)); - block=nouveau_mem_alloc(dev, alloc.alignment, alloc.size, alloc.flags, filp); + block=nouveau_mem_alloc(dev, alloc.alignment, alloc.size, alloc.flags, + file_priv); if (!block) return -ENOMEM; alloc.map_handle=block->map_handle; @@ -589,7 +597,7 @@ int nouveau_ioctl_mem_free(DRM_IOCTL_ARGS) block = find_block(dev_priv->pci_heap, memfree.offset); if (!block) return -EFAULT; - if (block->filp != filp) + if (block->file_priv != file_priv) return -EPERM; nouveau_mem_free(dev, block); -- 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_mem.c | 43 +++++++++++++++---------------------------- 1 file changed, 15 insertions(+), 28 deletions(-) (limited to 'shared-core/nouveau_mem.c') diff --git a/shared-core/nouveau_mem.c b/shared-core/nouveau_mem.c index 6a4818c5..a7044c94 100644 --- a/shared-core/nouveau_mem.c +++ b/shared-core/nouveau_mem.c @@ -547,11 +547,10 @@ void nouveau_mem_free(struct drm_device* dev, struct mem_block* block) * Ioctls */ -int nouveau_ioctl_mem_alloc(DRM_IOCTL_ARGS) +int nouveau_ioctl_mem_alloc(struct drm_device *dev, void *data, struct drm_file *file_priv) { - DRM_DEVICE; struct drm_nouveau_private *dev_priv = dev->dev_private; - struct drm_nouveau_mem_alloc alloc; + struct drm_nouveau_mem_alloc *alloc = data; struct mem_block *block; if (!dev_priv) { @@ -559,42 +558,30 @@ int nouveau_ioctl_mem_alloc(DRM_IOCTL_ARGS) return -EINVAL; } - DRM_COPY_FROM_USER_IOCTL(alloc, - (struct drm_nouveau_mem_alloc_t __user *) data, - sizeof(alloc)); - - block=nouveau_mem_alloc(dev, alloc.alignment, alloc.size, alloc.flags, - file_priv); + block=nouveau_mem_alloc(dev, alloc->alignment, alloc->size, + alloc->flags, file_priv); if (!block) return -ENOMEM; - alloc.map_handle=block->map_handle; - alloc.offset=block->start; - alloc.flags=block->flags; - - DRM_COPY_TO_USER_IOCTL((struct drm_nouveau_mem_alloc __user *)data, - alloc, sizeof(alloc)); + alloc->map_handle=block->map_handle; + alloc->offset=block->start; + alloc->flags=block->flags; return 0; } -int nouveau_ioctl_mem_free(DRM_IOCTL_ARGS) +int nouveau_ioctl_mem_free(struct drm_device *dev, void *data, struct drm_file *file_priv) { - DRM_DEVICE; struct drm_nouveau_private *dev_priv = dev->dev_private; - struct drm_nouveau_mem_free memfree; + struct drm_nouveau_mem_free *memfree = data; struct mem_block *block; - DRM_COPY_FROM_USER_IOCTL(memfree, - (struct drm_nouveau_mem_free_t __user *)data, - sizeof(memfree)); - block=NULL; - if (memfree.flags&NOUVEAU_MEM_FB) - block = find_block(dev_priv->fb_heap, memfree.offset); - else if (memfree.flags&NOUVEAU_MEM_AGP) - block = find_block(dev_priv->agp_heap, memfree.offset); - else if (memfree.flags&NOUVEAU_MEM_PCI) - block = find_block(dev_priv->pci_heap, memfree.offset); + if (memfree->flags & NOUVEAU_MEM_FB) + block = find_block(dev_priv->fb_heap, memfree->offset); + else if (memfree->flags & NOUVEAU_MEM_AGP) + block = find_block(dev_priv->agp_heap, memfree->offset); + else if (memfree->flags & NOUVEAU_MEM_PCI) + block = find_block(dev_priv->pci_heap, memfree->offset); if (!block) return -EFAULT; if (block->file_priv != file_priv) -- 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_mem.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'shared-core/nouveau_mem.c') diff --git a/shared-core/nouveau_mem.c b/shared-core/nouveau_mem.c index a7044c94..981af8a6 100644 --- a/shared-core/nouveau_mem.c +++ b/shared-core/nouveau_mem.c @@ -549,14 +549,10 @@ void nouveau_mem_free(struct drm_device* dev, struct mem_block* block) int nouveau_ioctl_mem_alloc(struct drm_device *dev, void *data, struct drm_file *file_priv) { - struct drm_nouveau_private *dev_priv = dev->dev_private; struct drm_nouveau_mem_alloc *alloc = data; struct mem_block *block; - if (!dev_priv) { - DRM_ERROR("%s called with no initialization\n", __FUNCTION__); - return -EINVAL; - } + NOUVEAU_CHECK_INITIALISED_WITH_RETURN; block=nouveau_mem_alloc(dev, alloc->alignment, alloc->size, alloc->flags, file_priv); @@ -575,6 +571,8 @@ int nouveau_ioctl_mem_free(struct drm_device *dev, void *data, struct drm_file * struct drm_nouveau_mem_free *memfree = data; struct mem_block *block; + NOUVEAU_CHECK_INITIALISED_WITH_RETURN; + block=NULL; if (memfree->flags & NOUVEAU_MEM_FB) block = find_block(dev_priv->fb_heap, memfree->offset); -- cgit v1.2.3 From ac24f328ec8954f78b1025db716abdd5b25b3dd9 Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Mon, 6 Aug 2007 17:14:26 +0200 Subject: nouveau: Bump PCI GART to 16MB --- shared-core/nouveau_mem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'shared-core/nouveau_mem.c') diff --git a/shared-core/nouveau_mem.c b/shared-core/nouveau_mem.c index 981af8a6..419522f4 100644 --- a/shared-core/nouveau_mem.c +++ b/shared-core/nouveau_mem.c @@ -411,7 +411,7 @@ int nouveau_mem_init(struct drm_device *dev) struct drm_scatter_gather sgreq; DRM_DEBUG("Allocating sg memory for PCI DMA\n"); - sgreq.size = 4 << 20; //4MB of PCI scatter-gather zone + sgreq.size = 16 << 20; //4MB of PCI scatter-gather zone if (drm_sg_alloc(dev, &sgreq)) { DRM_ERROR("Unable to allocate 4MB of scatter-gather" -- cgit v1.2.3 From a615d2fde77092062f7e2bbfa39705b5f34547e8 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 15 Aug 2007 13:53:58 +1000 Subject: nouveau: Turn some messages into DRM_DEBUGs.. --- 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 419522f4..92fa6b05 100644 --- a/shared-core/nouveau_mem.c +++ b/shared-core/nouveau_mem.c @@ -531,13 +531,13 @@ alloc_ok: block->map_handle = entry->user_token; } - DRM_INFO("allocated 0x%llx\n", block->start); + DRM_DEBUG("allocated 0x%llx type=0x%08x\n", block->start, block->flags); return block; } void nouveau_mem_free(struct drm_device* dev, struct mem_block* block) { - DRM_INFO("freeing 0x%llx\n", block->start); + DRM_DEBUG("freeing 0x%llx type=0x%08x\n", block->start, block->flags); if (block->flags&NOUVEAU_MEM_MAPPED) drm_rmmap(dev, block->map); nouveau_mem_free_block(block); -- cgit v1.2.3 From 8a4d7f34d9c0182c466518c6f413d9a039db402d Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 17 Aug 2007 01:12:46 +1000 Subject: nouveau: Detect memory on NFORCE/NFORCE2 correctly. --- shared-core/nouveau_mem.c | 43 +++++++++++++++++++++++++++++++++---------- 1 file changed, 33 insertions(+), 10 deletions(-) (limited to 'shared-core/nouveau_mem.c') diff --git a/shared-core/nouveau_mem.c b/shared-core/nouveau_mem.c index 92fa6b05..30345797 100644 --- a/shared-core/nouveau_mem.c +++ b/shared-core/nouveau_mem.c @@ -219,6 +219,33 @@ void nouveau_mem_close(struct drm_device *dev) nouveau_mem_takedown(&dev_priv->pci_heap); } +/*XXX won't work on BSD because of pci_read_config_dword */ +static uint32_t +nouveau_mem_fb_amount_igp(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct pci_dev *bridge; + uint32_t mem; + + bridge = pci_get_bus_and_slot(0, PCI_DEVFN(0,1)); + if (!bridge) { + DRM_ERROR("no bridge device\n"); + return 0; + } + + if (dev_priv->flags&NV_NFORCE) { + pci_read_config_dword(bridge, 0x7C, &mem); + return (uint64_t)(((mem >> 6) & 31) + 1)*1024*1024; + } else + if(dev_priv->flags&NV_NFORCE2) { + pci_read_config_dword(bridge, 0x84, &mem); + return (uint64_t)(((mem >> 4) & 127) + 1)*1024*1024; + } + + DRM_ERROR("impossible!\n"); + return 0; +} + /* returns the amount of FB ram in bytes */ uint64_t nouveau_mem_fb_amount(struct drm_device *dev) { @@ -263,18 +290,14 @@ uint64_t nouveau_mem_fb_amount(struct drm_device *dev) case NV_44: case NV_50: default: - // XXX won't work on BSD because of pci_read_config_dword - if (dev_priv->flags&NV_NFORCE) { - uint32_t mem; - pci_read_config_dword(dev->pdev, 0x7C, &mem); - return (uint64_t)(((mem >> 6) & 31) + 1)*1024*1024; - } else if(dev_priv->flags&NV_NFORCE2) { - uint32_t mem; - pci_read_config_dword(dev->pdev, 0x84, &mem); - return (uint64_t)(((mem >> 4) & 127) + 1)*1024*1024; + if (dev_priv->flags & (NV_NFORCE | NV_NFORCE2)) { + return nouveau_mem_fb_amount_igp(dev); } else { uint64_t mem; - mem=(NV_READ(NV04_FIFO_DATA)&NV10_FIFO_DATA_RAM_AMOUNT_MB_MASK) >> NV10_FIFO_DATA_RAM_AMOUNT_MB_SHIFT; + + mem = (NV_READ(NV04_FIFO_DATA) & + NV10_FIFO_DATA_RAM_AMOUNT_MB_MASK) >> + NV10_FIFO_DATA_RAM_AMOUNT_MB_SHIFT; return mem*1024*1024; } break; -- cgit v1.2.3 From a122e7dabfaade751e8f6bb6d1488902fd36a40e Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Sun, 19 Aug 2007 18:41:18 +0200 Subject: Function pci_get_bus_and_slot needs 2.6.19 or later --- shared-core/nouveau_mem.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'shared-core/nouveau_mem.c') diff --git a/shared-core/nouveau_mem.c b/shared-core/nouveau_mem.c index 30345797..3c294e4b 100644 --- a/shared-core/nouveau_mem.c +++ b/shared-core/nouveau_mem.c @@ -223,6 +223,7 @@ void nouveau_mem_close(struct drm_device *dev) static uint32_t nouveau_mem_fb_amount_igp(struct drm_device *dev) { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19) struct drm_nouveau_private *dev_priv = dev->dev_private; struct pci_dev *bridge; uint32_t mem; @@ -243,6 +244,10 @@ nouveau_mem_fb_amount_igp(struct drm_device *dev) } DRM_ERROR("impossible!\n"); +#else + DRM_ERROR("Linux kernel >= 2.6.19 required to check for igp memory amount\n"); +#endif + return 0; } -- cgit v1.2.3 From c8760c7999b8aeb6d51b09c062331f518953a920 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Sun, 19 Aug 2007 18:45:01 +0200 Subject: Check also for Linux, as it's not supported on different OS --- shared-core/nouveau_mem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'shared-core/nouveau_mem.c') diff --git a/shared-core/nouveau_mem.c b/shared-core/nouveau_mem.c index 3c294e4b..12d1ba75 100644 --- a/shared-core/nouveau_mem.c +++ b/shared-core/nouveau_mem.c @@ -223,7 +223,7 @@ void nouveau_mem_close(struct drm_device *dev) static uint32_t nouveau_mem_fb_amount_igp(struct drm_device *dev) { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19) +#if defined(LINUX) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)) struct drm_nouveau_private *dev_priv = dev->dev_private; struct pci_dev *bridge; uint32_t mem; -- cgit v1.2.3 From 76337bdb19fb6a098fc6d6ceaafb58a4ed15f9b0 Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Mon, 6 Aug 2007 17:42:31 +0200 Subject: nouveau: fix the comment and debug message for PCIGART size --- shared-core/nouveau_mem.c | 6 +++--- 1 file changed, 3 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 12d1ba75..2cc0ed77 100644 --- a/shared-core/nouveau_mem.c +++ b/shared-core/nouveau_mem.c @@ -439,11 +439,11 @@ int nouveau_mem_init(struct drm_device *dev) struct drm_scatter_gather sgreq; DRM_DEBUG("Allocating sg memory for PCI DMA\n"); - sgreq.size = 16 << 20; //4MB of PCI scatter-gather zone + sgreq.size = 16 << 20; //16MB of PCI scatter-gather zone if (drm_sg_alloc(dev, &sgreq)) { - DRM_ERROR("Unable to allocate 4MB of scatter-gather" - " pages for PCI DMA!"); + DRM_ERROR("Unable to allocate %dMB of scatter-gather" + " pages for PCI DMA!",sgreq.size>>20); } else { if (nouveau_mem_init_heap(&dev_priv->pci_heap, 0, dev->sg->pages * PAGE_SIZE)) { -- 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_mem.c | 12 ------------ 1 file changed, 12 deletions(-) (limited to 'shared-core/nouveau_mem.c') diff --git a/shared-core/nouveau_mem.c b/shared-core/nouveau_mem.c index 2cc0ed77..dbfba351 100644 --- a/shared-core/nouveau_mem.c +++ b/shared-core/nouveau_mem.c @@ -257,18 +257,6 @@ uint64_t nouveau_mem_fb_amount(struct drm_device *dev) struct drm_nouveau_private *dev_priv=dev->dev_private; switch(dev_priv->card_type) { - case NV_03: - switch(NV_READ(NV03_BOOT_0)&NV03_BOOT_0_RAM_AMOUNT) - { - case NV03_BOOT_0_RAM_AMOUNT_8MB: - case NV03_BOOT_0_RAM_AMOUNT_8MB_SDRAM: - return 8*1024*1024; - case NV03_BOOT_0_RAM_AMOUNT_4MB: - return 4*1024*1024; - case NV03_BOOT_0_RAM_AMOUNT_2MB: - return 2*1024*1024; - } - break; case NV_04: case NV_05: if (NV_READ(NV03_BOOT_0) & 0x00000100) { -- cgit v1.2.3 From 811e43f9e27abdf4c8a4b36c7c287e53134fc950 Mon Sep 17 00:00:00 2001 From: Jeremy Kolb Date: Sun, 14 Oct 2007 10:56:17 -0400 Subject: nouveau: fix warning. --- shared-core/nouveau_mem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'shared-core/nouveau_mem.c') diff --git a/shared-core/nouveau_mem.c b/shared-core/nouveau_mem.c index dbfba351..e2f0b38d 100644 --- a/shared-core/nouveau_mem.c +++ b/shared-core/nouveau_mem.c @@ -430,7 +430,7 @@ int nouveau_mem_init(struct drm_device *dev) sgreq.size = 16 << 20; //16MB of PCI scatter-gather zone if (drm_sg_alloc(dev, &sgreq)) { - DRM_ERROR("Unable to allocate %dMB of scatter-gather" + DRM_ERROR("Unable to allocate %ldMB of scatter-gather" " pages for PCI DMA!",sgreq.size>>20); } else { if (nouveau_mem_init_heap(&dev_priv->pci_heap, 0, -- cgit v1.2.3 From 6398325ba11da8a01c72f6203af0a2e4b43125c2 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 16 Oct 2007 13:27:27 +1100 Subject: nouveau: Handle multiple PFIFO exceptions per irq, cleanup output. --- shared-core/nouveau_mem.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'shared-core/nouveau_mem.c') diff --git a/shared-core/nouveau_mem.c b/shared-core/nouveau_mem.c index e2f0b38d..97691780 100644 --- a/shared-core/nouveau_mem.c +++ b/shared-core/nouveau_mem.c @@ -399,8 +399,7 @@ int nouveau_mem_init(struct drm_device *dev) } /*Note: this is *not* just NV50 code, but only used on NV50 for now */ - if (dev_priv->gart_info.type == NOUVEAU_GART_NONE && - dev_priv->card_type >= NV_50) { + if (dev_priv->gart_info.type == NOUVEAU_GART_NONE) { ret = nouveau_sgdma_init(dev); if (!ret) { ret = nouveau_sgdma_nottm_hack_init(dev); -- cgit v1.2.3 From 9fdab5b5c512f586012654917438327b3c67eaa4 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 16 Oct 2007 14:43:57 +1100 Subject: nouveau: revert unintended change. --- shared-core/nouveau_mem.c | 3 ++- 1 file changed, 2 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 97691780..e2f0b38d 100644 --- a/shared-core/nouveau_mem.c +++ b/shared-core/nouveau_mem.c @@ -399,7 +399,8 @@ int nouveau_mem_init(struct drm_device *dev) } /*Note: this is *not* just NV50 code, but only used on NV50 for now */ - if (dev_priv->gart_info.type == NOUVEAU_GART_NONE) { + if (dev_priv->gart_info.type == NOUVEAU_GART_NONE && + dev_priv->card_type >= NV_50) { ret = nouveau_sgdma_init(dev); if (!ret) { ret = nouveau_sgdma_nottm_hack_init(dev); -- cgit v1.2.3 From 9a115080e870f8196adef4a19598343e63e61e45 Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Tue, 23 Oct 2007 02:18:56 +0200 Subject: nouveau: fix IGP --- shared-core/nouveau_mem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'shared-core/nouveau_mem.c') diff --git a/shared-core/nouveau_mem.c b/shared-core/nouveau_mem.c index e2f0b38d..448b69d3 100644 --- a/shared-core/nouveau_mem.c +++ b/shared-core/nouveau_mem.c @@ -223,7 +223,7 @@ void nouveau_mem_close(struct drm_device *dev) static uint32_t nouveau_mem_fb_amount_igp(struct drm_device *dev) { -#if defined(LINUX) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)) +#if defined(__linux__) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)) struct drm_nouveau_private *dev_priv = dev->dev_private; struct pci_dev *bridge; uint32_t mem; -- cgit v1.2.3