diff options
Diffstat (limited to 'shared-core/nouveau_mem.c')
-rw-r--r-- | shared-core/nouveau_mem.c | 76 |
1 files changed, 44 insertions, 32 deletions
diff --git a/shared-core/nouveau_mem.c b/shared-core/nouveau_mem.c index d79c1a52..af23214e 100644 --- a/shared-core/nouveau_mem.c +++ b/shared-core/nouveau_mem.c @@ -231,34 +231,46 @@ 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 */ +/*XXX BSD needs compat functions for pci access + * #define DRM_PCI_DEV struct device + * #define drm_pci_get_bsf pci_get_bsf + * and a small inline to do *val = pci_read_config(pdev->device, where, 4); + * might work + */ +static uint32_t nforce_pci_fn_read_config_dword(int devfn, int where, uint32_t *val) +{ +#ifdef __linux__ + DRM_PCI_DEV *pdev; + + if (!(pdev = drm_pci_get_bsf(0, 0, devfn))) { + DRM_ERROR("nForce PCI device function 0x%02x not found\n", + devfn); + return -ENODEV; + } + + return drm_pci_read_config_dword(pdev, where, val); +#else + DRM_ERROR("BSD compat for checking IGP memory amount needed\n"); + return 0; +#endif +} + static uint32_t nouveau_mem_fb_amount_igp(struct drm_device *dev) { -#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; - - bridge = pci_get_bus_and_slot(0, PCI_DEVFN(0,1)); - if (!bridge) { - DRM_ERROR("no bridge device\n"); - return 0; - } + uint32_t mem = 0; - if (dev_priv->flags&NV_NFORCE) { - pci_read_config_dword(bridge, 0x7C, &mem); + if (dev_priv->flags & NV_NFORCE) { + nforce_pci_fn_read_config_dword(1, 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); + } + if (dev_priv->flags & NV_NFORCE2) { + nforce_pci_fn_read_config_dword(1, 0x84, &mem); return (uint64_t)(((mem >> 4) & 127) + 1)*1024*1024; } DRM_ERROR("impossible!\n"); -#else - DRM_ERROR("Linux kernel >= 2.6.19 required to check for igp memory amount\n"); -#endif return 0; } @@ -300,9 +312,9 @@ uint64_t nouveau_mem_fb_amount(struct drm_device *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(NV10_PFB_CSTATUS) & + NV10_PFB_CSTATUS_RAM_AMOUNT_MB_MASK) >> + NV10_PFB_CSTATUS_RAM_AMOUNT_MB_SHIFT; return mem*1024*1024; } break; @@ -485,10 +497,7 @@ int nouveau_mem_init(struct drm_device *dev) */ if (dev_priv->card_type >= NV_50 && fb_size > (512 * 1024 * 1024)) fb_size = (512 * 1024 * 1024); - /* 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_rsvd_vram; + fb_size -= dev_priv->ramin_rsvd_vram; dev_priv->fb_available_size = fb_size; DRM_DEBUG("Available VRAM: %dKiB\n", fb_size>>10); @@ -587,18 +596,21 @@ nouveau_mem_alloc(struct drm_device *dev, int alignment, uint64_t size, * Make things easier on ourselves: all allocations are page-aligned. * We need that to map allocated regions into the user space */ - if (alignment < PAGE_SHIFT) - alignment = PAGE_SHIFT; + if (alignment < PAGE_SIZE) + alignment = PAGE_SIZE; /* Align allocation sizes to 64KiB blocks on G8x. We use a 64KiB * page size in the GPU VM. */ if (flags & NOUVEAU_MEM_FB && dev_priv->card_type >= NV_50) { size = (size + 65535) & ~65535; - if (alignment < 16) - alignment = 16; + if (alignment < 65536) + alignment = 65536; } + /* Further down wants alignment in pages, not bytes */ + alignment >>= PAGE_SHIFT; + /* * Warn about 0 sized allocations, but let it go through. It'll return 1 page */ @@ -806,11 +818,11 @@ nouveau_ioctl_mem_free(struct drm_device *dev, void *data, memfree->offset -= 512*1024*1024; block=NULL; - if (memfree->flags & NOUVEAU_MEM_FB) + if (dev_priv->fb_heap && memfree->flags & NOUVEAU_MEM_FB) block = find_block(dev_priv->fb_heap, memfree->offset); - else if (memfree->flags & NOUVEAU_MEM_AGP) + else if (dev_priv->agp_heap && memfree->flags & NOUVEAU_MEM_AGP) block = find_block(dev_priv->agp_heap, memfree->offset); - else if (memfree->flags & NOUVEAU_MEM_PCI) + else if (dev_priv->pci_heap && memfree->flags & NOUVEAU_MEM_PCI) block = find_block(dev_priv->pci_heap, memfree->offset); if (!block) return -EFAULT; |