--- zzzz-none-000/linux-3.10.107/drivers/gpu/drm/nouveau/nouveau_ttm.c 2017-06-27 09:49:32.000000000 +0000 +++ scorpion-7490-727/linux-3.10.107/drivers/gpu/drm/nouveau/nouveau_ttm.c 2021-02-04 17:41:59.000000000 +0000 @@ -24,20 +24,20 @@ * USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#include -#include -#include - #include "nouveau_drm.h" #include "nouveau_ttm.h" #include "nouveau_gem.h" +#include "drm_legacy.h" + +#include + static int nouveau_vram_manager_init(struct ttm_mem_type_manager *man, unsigned long psize) { struct nouveau_drm *drm = nouveau_bdev(man->bdev); - struct nouveau_fb *pfb = nouveau_fb(drm->device); - man->priv = pfb; + struct nvkm_fb *fb = nvxx_fb(&drm->device); + man->priv = fb; return 0; } @@ -49,16 +49,16 @@ } static inline void -nouveau_mem_node_cleanup(struct nouveau_mem *node) +nvkm_mem_node_cleanup(struct nvkm_mem *node) { if (node->vma[0].node) { - nouveau_vm_unmap(&node->vma[0]); - nouveau_vm_put(&node->vma[0]); + nvkm_vm_unmap(&node->vma[0]); + nvkm_vm_put(&node->vma[0]); } if (node->vma[1].node) { - nouveau_vm_unmap(&node->vma[1]); - nouveau_vm_put(&node->vma[1]); + nvkm_vm_unmap(&node->vma[1]); + nvkm_vm_put(&node->vma[1]); } } @@ -67,30 +67,33 @@ struct ttm_mem_reg *mem) { struct nouveau_drm *drm = nouveau_bdev(man->bdev); - struct nouveau_fb *pfb = nouveau_fb(drm->device); - nouveau_mem_node_cleanup(mem->mm_node); - pfb->ram.put(pfb, (struct nouveau_mem **)&mem->mm_node); + struct nvkm_ram *ram = nvxx_fb(&drm->device)->ram; + nvkm_mem_node_cleanup(mem->mm_node); + ram->func->put(ram, (struct nvkm_mem **)&mem->mm_node); } static int nouveau_vram_manager_new(struct ttm_mem_type_manager *man, struct ttm_buffer_object *bo, - struct ttm_placement *placement, + const struct ttm_place *place, struct ttm_mem_reg *mem) { struct nouveau_drm *drm = nouveau_bdev(man->bdev); - struct nouveau_fb *pfb = nouveau_fb(drm->device); + struct nvkm_ram *ram = nvxx_fb(&drm->device)->ram; struct nouveau_bo *nvbo = nouveau_bo(bo); - struct nouveau_mem *node; + struct nvkm_mem *node; u32 size_nc = 0; int ret; + if (drm->device.info.ram_size == 0) + return -ENOMEM; + if (nvbo->tile_flags & NOUVEAU_GEM_TILE_NONCONTIG) size_nc = 1 << nvbo->page_shift; - ret = pfb->ram.get(pfb, mem->num_pages << PAGE_SHIFT, - mem->page_alignment << PAGE_SHIFT, size_nc, - (nvbo->tile_flags >> 8) & 0x3ff, &node); + ret = ram->func->get(ram, mem->num_pages << PAGE_SHIFT, + mem->page_alignment << PAGE_SHIFT, size_nc, + (nvbo->tile_flags >> 8) & 0x3ff, &node); if (ret) { mem->mm_node = NULL; return (ret == -ENOSPC) ? 0 : ret; @@ -103,38 +106,11 @@ return 0; } -static void -nouveau_vram_manager_debug(struct ttm_mem_type_manager *man, const char *prefix) -{ - struct nouveau_fb *pfb = man->priv; - struct nouveau_mm *mm = &pfb->vram; - struct nouveau_mm_node *r; - u32 total = 0, free = 0; - - mutex_lock(&mm->mutex); - list_for_each_entry(r, &mm->nodes, nl_entry) { - printk(KERN_DEBUG "%s %d: 0x%010llx 0x%010llx\n", - prefix, r->type, ((u64)r->offset << 12), - (((u64)r->offset + r->length) << 12)); - - total += r->length; - if (!r->type) - free += r->length; - } - mutex_unlock(&mm->mutex); - - printk(KERN_DEBUG "%s total: 0x%010llx free: 0x%010llx\n", - prefix, (u64)total << 12, (u64)free << 12); - printk(KERN_DEBUG "%s block: 0x%08x\n", - prefix, mm->block_size << 12); -} - const struct ttm_mem_type_manager_func nouveau_vram_manager = { nouveau_vram_manager_init, nouveau_vram_manager_fini, nouveau_vram_manager_new, nouveau_vram_manager_del, - nouveau_vram_manager_debug }; static int @@ -153,7 +129,7 @@ nouveau_gart_manager_del(struct ttm_mem_type_manager *man, struct ttm_mem_reg *mem) { - nouveau_mem_node_cleanup(mem->mm_node); + nvkm_mem_node_cleanup(mem->mm_node); kfree(mem->mm_node); mem->mm_node = NULL; } @@ -161,32 +137,38 @@ static int nouveau_gart_manager_new(struct ttm_mem_type_manager *man, struct ttm_buffer_object *bo, - struct ttm_placement *placement, + const struct ttm_place *place, struct ttm_mem_reg *mem) { struct nouveau_drm *drm = nouveau_bdev(bo->bdev); struct nouveau_bo *nvbo = nouveau_bo(bo); - struct nouveau_mem *node; - - if (unlikely((mem->num_pages << PAGE_SHIFT) >= 512 * 1024 * 1024)) - return -ENOMEM; + struct nvkm_mem *node; node = kzalloc(sizeof(*node), GFP_KERNEL); if (!node) return -ENOMEM; + node->page_shift = 12; - switch (nv_device(drm->device)->card_type) { - case NV_50: - if (nv_device(drm->device)->chipset != 0x50) + switch (drm->device.info.family) { + case NV_DEVICE_INFO_V0_TNT: + case NV_DEVICE_INFO_V0_CELSIUS: + case NV_DEVICE_INFO_V0_KELVIN: + case NV_DEVICE_INFO_V0_RANKINE: + case NV_DEVICE_INFO_V0_CURIE: + break; + case NV_DEVICE_INFO_V0_TESLA: + if (drm->device.info.chipset != 0x50) node->memtype = (nvbo->tile_flags & 0x7f00) >> 8; break; - case NV_C0: - case NV_D0: - case NV_E0: + case NV_DEVICE_INFO_V0_FERMI: + case NV_DEVICE_INFO_V0_KEPLER: + case NV_DEVICE_INFO_V0_MAXWELL: node->memtype = (nvbo->tile_flags & 0xff00) >> 8; break; default: + NV_WARN(drm, "%s: unhandled family type %x\n", __func__, + drm->device.info.family); break; } @@ -208,15 +190,16 @@ nouveau_gart_manager_debug }; -#include +/*XXX*/ +#include static int nv04_gart_manager_init(struct ttm_mem_type_manager *man, unsigned long psize) { struct nouveau_drm *drm = nouveau_bdev(man->bdev); - struct nouveau_vmmgr *vmm = nouveau_vmmgr(drm->device); - struct nv04_vmmgr_priv *priv = (void *)vmm; - struct nouveau_vm *vm = NULL; - nouveau_vm_ref(priv->vm, &vm, NULL); + struct nvkm_mmu *mmu = nvxx_mmu(&drm->device); + struct nv04_mmu *priv = (void *)mmu; + struct nvkm_vm *vm = NULL; + nvkm_vm_ref(priv->vm, &vm, NULL); man->priv = vm; return 0; } @@ -224,8 +207,8 @@ static int nv04_gart_manager_fini(struct ttm_mem_type_manager *man) { - struct nouveau_vm *vm = man->priv; - nouveau_vm_ref(NULL, &vm, NULL); + struct nvkm_vm *vm = man->priv; + nvkm_vm_ref(NULL, &vm, NULL); man->priv = NULL; return 0; } @@ -233,9 +216,9 @@ static void nv04_gart_manager_del(struct ttm_mem_type_manager *man, struct ttm_mem_reg *mem) { - struct nouveau_mem *node = mem->mm_node; + struct nvkm_mem *node = mem->mm_node; if (node->vma[0].node) - nouveau_vm_put(&node->vma[0]); + nvkm_vm_put(&node->vma[0]); kfree(mem->mm_node); mem->mm_node = NULL; } @@ -243,10 +226,10 @@ static int nv04_gart_manager_new(struct ttm_mem_type_manager *man, struct ttm_buffer_object *bo, - struct ttm_placement *placement, + const struct ttm_place *place, struct ttm_mem_reg *mem) { - struct nouveau_mem *node; + struct nvkm_mem *node; int ret; node = kzalloc(sizeof(*node), GFP_KERNEL); @@ -255,8 +238,8 @@ node->page_shift = 12; - ret = nouveau_vm_get(man->priv, mem->num_pages << 12, node->page_shift, - NV_MEM_ACCESS_RW, &node->vma[0]); + ret = nvkm_vm_get(man->priv, mem->num_pages << 12, node->page_shift, + NV_MEM_ACCESS_RW, &node->vma[0]); if (ret) { kfree(node); return ret; @@ -287,7 +270,7 @@ struct nouveau_drm *drm = nouveau_drm(file_priv->minor->dev); if (unlikely(vma->vm_pgoff < DRM_FILE_PAGE_OFFSET)) - return drm_mmap(filp, vma); + return drm_legacy_mmap(filp, vma); return ttm_bo_mmap(filp, vma, &drm->ttm.bdev); } @@ -355,22 +338,46 @@ int nouveau_ttm_init(struct nouveau_drm *drm) { + struct nvkm_device *device = nvxx_device(&drm->device); + struct nvkm_pci *pci = device->pci; struct drm_device *dev = drm->dev; - u32 bits; + u8 bits; int ret; - bits = nouveau_vmmgr(drm->device)->dma_bits; - if ( drm->agp.stat == ENABLED || - !pci_dma_supported(dev->pdev, DMA_BIT_MASK(bits))) - bits = 32; + if (pci && pci->agp.bridge) { + drm->agp.bridge = pci->agp.bridge; + drm->agp.base = pci->agp.base; + drm->agp.size = pci->agp.size; + drm->agp.cma = pci->agp.cma; + } + + bits = nvxx_mmu(&drm->device)->dma_bits; + if (nvxx_device(&drm->device)->func->pci) { + if (drm->agp.bridge) + bits = 32; + } else if (device->func->tegra) { + struct nvkm_device_tegra *tegra = device->func->tegra(device); + + /* + * If the platform can use a IOMMU, then the addressable DMA + * space is constrained by the IOMMU bit + */ + if (tegra->func->iommu_bit) + bits = min(bits, tegra->func->iommu_bit); - ret = pci_set_dma_mask(dev->pdev, DMA_BIT_MASK(bits)); + } + + ret = dma_set_mask(dev->dev, DMA_BIT_MASK(bits)); + if (ret && bits != 32) { + bits = 32; + ret = dma_set_mask(dev->dev, DMA_BIT_MASK(bits)); + } if (ret) return ret; - ret = pci_set_consistent_dma_mask(dev->pdev, DMA_BIT_MASK(bits)); + ret = dma_set_coherent_mask(dev->dev, DMA_BIT_MASK(bits)); if (ret) - pci_set_consistent_dma_mask(dev->pdev, DMA_BIT_MASK(32)); + dma_set_coherent_mask(dev->dev, DMA_BIT_MASK(32)); ret = nouveau_ttm_global_init(drm); if (ret) @@ -378,7 +385,9 @@ ret = ttm_bo_device_init(&drm->ttm.bdev, drm->ttm.bo_global_ref.ref.object, - &nouveau_bo_driver, DRM_FILE_PAGE_OFFSET, + &nouveau_bo_driver, + dev->anon_inode->i_mapping, + DRM_FILE_PAGE_OFFSET, bits <= 32 ? true : false); if (ret) { NV_ERROR(drm, "error initialising bo driver, %d\n", ret); @@ -386,8 +395,7 @@ } /* VRAM init */ - drm->gem.vram_available = nouveau_fb(drm->device)->ram.size; - drm->gem.vram_available -= nouveau_instmem(drm->device)->reserved; + drm->gem.vram_available = drm->device.info.ram_user; ret = ttm_bo_init_mm(&drm->ttm.bdev, TTM_PL_VRAM, drm->gem.vram_available >> PAGE_SHIFT); @@ -396,15 +404,12 @@ return ret; } - drm->ttm.mtrr = drm_mtrr_add(pci_resource_start(dev->pdev, 1), - pci_resource_len(dev->pdev, 1), - DRM_MTRR_WC); + drm->ttm.mtrr = arch_phys_wc_add(device->func->resource_addr(device, 1), + device->func->resource_size(device, 1)); /* GART init */ - if (drm->agp.stat != ENABLED) { - drm->gem.gart_available = nouveau_vmmgr(drm->device)->limit; - if (drm->gem.gart_available > 512 * 1024 * 1024) - drm->gem.gart_available = 512 * 1024 * 1024; + if (!drm->agp.bridge) { + drm->gem.gart_available = nvxx_mmu(&drm->device)->limit; } else { drm->gem.gart_available = drm->agp.size; } @@ -424,19 +429,13 @@ void nouveau_ttm_fini(struct nouveau_drm *drm) { - mutex_lock(&drm->dev->struct_mutex); ttm_bo_clean_mm(&drm->ttm.bdev, TTM_PL_VRAM); ttm_bo_clean_mm(&drm->ttm.bdev, TTM_PL_TT); - mutex_unlock(&drm->dev->struct_mutex); ttm_bo_device_release(&drm->ttm.bdev); nouveau_ttm_global_release(drm); - if (drm->ttm.mtrr >= 0) { - drm_mtrr_del(drm->ttm.mtrr, - pci_resource_start(drm->dev->pdev, 1), - pci_resource_len(drm->dev->pdev, 1), DRM_MTRR_WC); - drm->ttm.mtrr = -1; - } + arch_phys_wc_del(drm->ttm.mtrr); + drm->ttm.mtrr = 0; }