diff --git a/drivers/gpu/drm/nouveau/core/subdev/device/nv40.c b/drivers/gpu/drm/nouveau/core/subdev/device/nv40.c index 320ccc4ae05c3501b2b15c5f98563a22a8b7c76a..18de4c5b202f5880553096f39f0acdce0296e121 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/device/nv40.c +++ b/drivers/gpu/drm/nouveau/core/subdev/device/nv40.c @@ -218,7 +218,7 @@ nv40_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; device->oclass[NVDEV_SUBDEV_FB ] = &nv40_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv40_instmem_oclass; - device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass; + device->oclass[NVDEV_SUBDEV_VM ] = &nv44_vmmgr_oclass; device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass; device->oclass[NVDEV_ENGINE_FIFO ] = &nv40_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass; @@ -238,7 +238,7 @@ nv40_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; device->oclass[NVDEV_SUBDEV_FB ] = &nv40_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv40_instmem_oclass; - device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass; + device->oclass[NVDEV_SUBDEV_VM ] = &nv44_vmmgr_oclass; device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass; device->oclass[NVDEV_ENGINE_FIFO ] = &nv40_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass; @@ -258,7 +258,7 @@ nv40_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; device->oclass[NVDEV_SUBDEV_FB ] = &nv40_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv40_instmem_oclass; - device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass; + device->oclass[NVDEV_SUBDEV_VM ] = &nv44_vmmgr_oclass; device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass; device->oclass[NVDEV_ENGINE_FIFO ] = &nv40_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass; @@ -278,7 +278,7 @@ nv40_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; device->oclass[NVDEV_SUBDEV_FB ] = &nv40_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv40_instmem_oclass; - device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass; + device->oclass[NVDEV_SUBDEV_VM ] = &nv44_vmmgr_oclass; device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass; device->oclass[NVDEV_ENGINE_FIFO ] = &nv40_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass; @@ -298,7 +298,7 @@ nv40_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; device->oclass[NVDEV_SUBDEV_FB ] = &nv40_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv40_instmem_oclass; - device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass; + device->oclass[NVDEV_SUBDEV_VM ] = &nv44_vmmgr_oclass; device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass; device->oclass[NVDEV_ENGINE_FIFO ] = &nv40_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass; @@ -318,7 +318,7 @@ nv40_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; device->oclass[NVDEV_SUBDEV_FB ] = &nv40_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv40_instmem_oclass; - device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass; + device->oclass[NVDEV_SUBDEV_VM ] = &nv44_vmmgr_oclass; device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass; device->oclass[NVDEV_ENGINE_FIFO ] = &nv40_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass; @@ -338,7 +338,7 @@ nv40_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; device->oclass[NVDEV_SUBDEV_FB ] = &nv40_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv40_instmem_oclass; - device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass; + device->oclass[NVDEV_SUBDEV_VM ] = &nv44_vmmgr_oclass; device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass; device->oclass[NVDEV_ENGINE_FIFO ] = &nv40_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass; @@ -358,7 +358,7 @@ nv40_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; device->oclass[NVDEV_SUBDEV_FB ] = &nv40_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv40_instmem_oclass; - device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass; + device->oclass[NVDEV_SUBDEV_VM ] = &nv44_vmmgr_oclass; device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass; device->oclass[NVDEV_ENGINE_FIFO ] = &nv40_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass; diff --git a/drivers/gpu/drm/nouveau/core/subdev/vm/nv04.c b/drivers/gpu/drm/nouveau/core/subdev/vm/nv04.c index ad6ad5de51b8fa6ac7c621f38199fa18cb46cd03..6adbbc9cc361ac96a4938918c13f07baea32f877 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/vm/nv04.c +++ b/drivers/gpu/drm/nouveau/core/subdev/vm/nv04.c @@ -132,10 +132,9 @@ nv04_vmmgr_dtor(struct nouveau_object *object) nouveau_gpuobj_ref(NULL, &priv->vm->pgt[0].obj[0]); nouveau_vm_ref(NULL, &priv->vm, NULL); } - if (priv->page) { - pci_unmap_page(nv_device(priv)->pdev, priv->null, - PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); - __free_page(priv->page); + if (priv->nullp) { + pci_free_consistent(nv_device(priv)->pdev, 16 * 1024, + priv->nullp, priv->null); } nouveau_vmmgr_destroy(&priv->base); } diff --git a/drivers/gpu/drm/nouveau/core/subdev/vm/nv04.h b/drivers/gpu/drm/nouveau/core/subdev/vm/nv04.h index e21369cd09c029e3dc96e6b5f0fdd93e46faa3da..ec42d4bc86a69b0331374d501d7b54453a8dcc75 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/vm/nv04.h +++ b/drivers/gpu/drm/nouveau/core/subdev/vm/nv04.h @@ -6,8 +6,8 @@ struct nv04_vmmgr_priv { struct nouveau_vmmgr base; struct nouveau_vm *vm; - struct page *page; dma_addr_t null; + void *nullp; }; static inline struct nv04_vmmgr_priv * diff --git a/drivers/gpu/drm/nouveau/core/subdev/vm/nv44.c b/drivers/gpu/drm/nouveau/core/subdev/vm/nv44.c index 8c9cece25e6328404a7d2696dd1bfc0c077c0f7a..0ac18d05a146389b6d87e8c7898188fda5b5c5e3 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/vm/nv44.c +++ b/drivers/gpu/drm/nouveau/core/subdev/vm/nv44.c @@ -23,6 +23,7 @@ */ #include +#include #include #include @@ -36,16 +37,6 @@ * VM map/unmap callbacks ******************************************************************************/ -static void -nv44_vm_flush_priv(struct nv04_vmmgr_priv *priv, u32 base, u32 size) -{ - nv_wr32(priv, 0x100814, (size - 1) << 12); - nv_wr32(priv, 0x100808, base | 0x20); - if (!nv_wait(priv, 0x100808, 0x00000001, 0x00000001)) - nv_error(priv, "timeout: 0x%08x\n", nv_rd32(priv, 0x100808)); - nv_wr32(priv, 0x100808, 0x00000000); -} - static void nv44_vm_fill(struct nouveau_gpuobj *pgt, dma_addr_t null, dma_addr_t *list, u32 pte, u32 cnt) @@ -57,6 +48,7 @@ nv44_vm_fill(struct nouveau_gpuobj *pgt, dma_addr_t null, tmp[1] = nv_ro32(pgt, base + 0x4); tmp[2] = nv_ro32(pgt, base + 0x8); tmp[3] = nv_ro32(pgt, base + 0xc); + while (cnt--) { u32 addr = list ? (*list++ >> 12) : (null >> 12); switch (pte++ & 0x3) { @@ -96,8 +88,6 @@ nv44_vm_map_sg(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt, struct nouveau_mem *mem, u32 pte, u32 cnt, dma_addr_t *list) { struct nv04_vmmgr_priv *priv = (void *)vma->vm->vmm; - u32 base = pte << 12; - u32 size = cnt; u32 tmp[4]; int i; @@ -122,15 +112,12 @@ nv44_vm_map_sg(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt, if (cnt) nv44_vm_fill(pgt, priv->null, list, pte, cnt); - nv44_vm_flush_priv(priv, base, size); } static void nv44_vm_unmap(struct nouveau_gpuobj *pgt, u32 pte, u32 cnt) { struct nv04_vmmgr_priv *priv = (void *)nouveau_vmmgr(pgt); - u32 base = pte << 12; - u32 size = cnt; if (pte & 3) { u32 max = 4 - (pte & 3); @@ -150,12 +137,17 @@ nv44_vm_unmap(struct nouveau_gpuobj *pgt, u32 pte, u32 cnt) if (cnt) nv44_vm_fill(pgt, priv->null, NULL, pte, cnt); - nv44_vm_flush_priv(priv, base, size); } static void nv44_vm_flush(struct nouveau_vm *vm) { + struct nv04_vmmgr_priv *priv = (void *)vm->vmm; + nv_wr32(priv, 0x100814, priv->base.limit - NV44_GART_PAGE); + nv_wr32(priv, 0x100808, 0x00000020); + if (!nv_wait(priv, 0x100808, 0x00000001, 0x00000001)) + nv_error(priv, "timeout: 0x%08x\n", nv_rd32(priv, 0x100808)); + nv_wr32(priv, 0x100808, 0x00000000); } /******************************************************************************* @@ -171,6 +163,11 @@ nv44_vmmgr_ctor(struct nouveau_object *parent, struct nouveau_object *engine, struct nv04_vmmgr_priv *priv; int ret; + if (!nouveau_boolopt(device->cfgopt, "NvPCIE", true)) { + return nouveau_object_ctor(parent, engine, &nv04_vmmgr_oclass, + data, size, pobject); + } + ret = nouveau_vmmgr_create(parent, engine, oclass, "PCIEGART", "pciegart", &priv); *pobject = nv_object(priv); @@ -187,20 +184,12 @@ nv44_vmmgr_ctor(struct nouveau_object *parent, struct nouveau_object *engine, priv->base.unmap = nv44_vm_unmap; priv->base.flush = nv44_vm_flush; - priv->page = alloc_page(GFP_DMA32 | GFP_KERNEL); - if (priv->page) { - priv->null = pci_map_page(device->pdev, priv->page, 0, - PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); - if (pci_dma_mapping_error(device->pdev, priv->null)) { - __free_page(priv->page); - priv->page = NULL; - priv->null = 0; - } + priv->nullp = pci_alloc_consistent(device->pdev, 16 * 1024, &priv->null); + if (!priv->nullp) { + nv_error(priv, "unable to allocate dummy pages\n"); + return -ENOMEM; } - if (!priv->page) - nv_warn(priv, "unable to allocate dummy page\n"); - ret = nouveau_vm_create(&priv->base, 0, NV44_GART_SIZE, 0, 4096, &priv->vm); if (ret)