summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexandre Courbot <acourbot@nvidia.com>2014-07-16 17:42:06 +0900
committerAlexandre Courbot <acourbot@nvidia.com>2014-08-27 16:42:29 -0700
commit62d1f5d2f5b3e5122eeac0f763dcdd1d04bf5c45 (patch)
tree726606bfbfb12a4fb0a20d7409bfd63964e50c66
parent46725edf1c286abfe063dfacdeccbf498d0be60f (diff)
downloadnouveau-62d1f5d2f5b3e5122eeac0f763dcdd1d04bf5c45.tar.gz
Experiments with large pagesbaserock/jetson/3.17-rc5
-rw-r--r--drm/nouveau_sgdma.c1
-rw-r--r--drm/nouveau_ttm.c3
-rw-r--r--nvkm/subdev/fb/ramgk20a.c22
-rw-r--r--nvkm/subdev/vm/base.c16
4 files changed, 33 insertions, 9 deletions
diff --git a/drm/nouveau_sgdma.c b/drm/nouveau_sgdma.c
index 01707e7de..3274eda02 100644
--- a/drm/nouveau_sgdma.c
+++ b/drm/nouveau_sgdma.c
@@ -38,6 +38,7 @@ nv04_sgdma_bind(struct ttm_tt *ttm, struct ttm_mem_reg *mem)
node->pages = nvbe->ttm.dma_address;
}
node->size = (mem->num_pages << PAGE_SHIFT) >> 12;
+ node->page_shift = PAGE_SHIFT;
nouveau_vm_map(&node->vma[0], node);
nvbe->node = node;
diff --git a/drm/nouveau_ttm.c b/drm/nouveau_ttm.c
index 53874b76b..2298c7b08 100644
--- a/drm/nouveau_ttm.c
+++ b/drm/nouveau_ttm.c
@@ -93,7 +93,8 @@ nouveau_vram_manager_new(struct ttm_mem_type_manager *man,
return (ret == -ENOSPC) ? 0 : ret;
}
- node->page_shift = nvbo->page_shift;
+ if (!node->page_shift)
+ node->page_shift = nvbo->page_shift;
mem->mm_node = node;
mem->start = node->offset >> PAGE_SHIFT;
diff --git a/nvkm/subdev/fb/ramgk20a.c b/nvkm/subdev/fb/ramgk20a.c
index 06dfdeced..873b1ebfd 100644
--- a/nvkm/subdev/fb/ramgk20a.c
+++ b/nvkm/subdev/fb/ramgk20a.c
@@ -53,8 +53,8 @@ gk20a_ram_get(struct nouveau_fb *pfb, u64 size, u32 align, u32 ncmin,
u32 npages, order;
int i;
- nv_debug(pfb, "%s: size: %llx align: %x, ncmin: %x\n", __func__, size,
- align, ncmin);
+ nv_debug(pfb, "%s: size: 0x%llx align: 0x%x, ncmin: 0x%x\n", __func__,
+ size, align, ncmin);
npages = size >> PAGE_SHIFT;
if (npages == 0)
@@ -73,14 +73,26 @@ gk20a_ram_get(struct nouveau_fb *pfb, u64 size, u32 align, u32 ncmin,
/* ensure returned address is correctly aligned */
npages = max(align, npages);
+ /* use big pages if we can, since our memory is always contiguous */
+ if (ncmin == 0 && npages % 0x20 == 0)
+ ncmin = 0x20000;
+ else if (ncmin == 0)
+ ncmin = 0x1000;
+ ncmin >>= PAGE_SHIFT;
+
+ /* ensure size is a multiple of ncmin */
+ npages = roundup(npages, ncmin);
+
mem = kzalloc(sizeof(*mem), GFP_KERNEL);
if (!mem)
return -ENOMEM;
mem->base.size = npages;
mem->base.memtype = type;
+ mem->base.page_shift = fls(ncmin << PAGE_SHIFT) - 1;
- mem->base.pages = kzalloc(sizeof(dma_addr_t) * npages, GFP_KERNEL);
+ mem->base.pages = kzalloc(sizeof(dma_addr_t) * npages / ncmin,
+ GFP_KERNEL);
if (!mem->base.pages) {
kfree(mem);
return -ENOMEM;
@@ -106,8 +118,8 @@ gk20a_ram_get(struct nouveau_fb *pfb, u64 size, u32 align, u32 ncmin,
nv_debug(pfb, "alloc size: 0x%x, align: 0x%x, paddr: %pad, vaddr: %p\n",
npages << PAGE_SHIFT, align, &mem->handle, mem->cpuaddr);
- for (i = 0; i < npages; i++)
- mem->base.pages[i] = mem->handle + (PAGE_SIZE * i);
+ for (i = 0; i < npages / ncmin; i++)
+ mem->base.pages[i] = mem->handle + (PAGE_SIZE * i * ncmin);
mem->base.offset = (u64)mem->base.pages[0];
diff --git a/nvkm/subdev/vm/base.c b/nvkm/subdev/vm/base.c
index f75a683bd..d4a758013 100644
--- a/nvkm/subdev/vm/base.c
+++ b/nvkm/subdev/vm/base.c
@@ -136,16 +136,26 @@ nouveau_vm_map_sg(struct nouveau_vma *vma, u64 delta, u64 length,
{
struct nouveau_vm *vm = vma->vm;
struct nouveau_vmmgr *vmm = vm->vmm;
+ /* these pages are always PAGE_SIZE (should be mem->page_shift) sized */
dma_addr_t *list = mem->pages;
- int big = vma->node->type != vmm->spg_shift;
+ /* whether the VMA type matches the small page type or not */
+ /* if not, it should always match the big page type */
+ int big = mem->page_shift != vmm->spg_shift;
+ /* first VMA page to map */
u32 offset = vma->node->offset + (delta >> 12);
- u32 bits = vma->node->type - 12;
- u32 num = length >> vma->node->type;
+ /* difference between size of node pages and small pages of VMM */
+ u32 bits = mem->page_shift - vmm->spg_shift;
+ /* number of VMA pages to map */
+ u32 num = length >> mem->page_shift;
+ /* first pde */
u32 pde = (offset >> vmm->pgt_bits) - vm->fpde;
+ /* first pte */
u32 pte = (offset & ((1 << vmm->pgt_bits) - 1)) >> bits;
+ /* last pte before switching to the next pde */
u32 max = 1 << (vmm->pgt_bits - bits);
u32 end, len;
+ //printk("%s %d %d %d\n", __func__, big, vma->node->type, mem->page_shift);
while (num) {
struct nouveau_gpuobj *pgt = vm->pgt[pde].obj[big];