From 063d7ebf17304fe8a7b85ecb4662f20c4839b6af Mon Sep 17 00:00:00 2001 From: Qiang Yu Date: Wed, 30 May 2018 19:18:03 +0800 Subject: [PATCH 069/146] drm/lima: vm alloc buffer with multi page table Signed-off-by: Qiang Yu --- drivers/gpu/drm/lima/lima_vm.c | 95 ++++++++++++++++++++++------------ drivers/gpu/drm/lima/lima_vm.h | 6 ++- 2 files changed, 66 insertions(+), 35 deletions(-) diff --git a/drivers/gpu/drm/lima/lima_vm.c b/drivers/gpu/drm/lima/lima_vm.c index 19a683c2921b..ab7438685234 100644 --- a/drivers/gpu/drm/lima/lima_vm.c +++ b/drivers/gpu/drm/lima/lima_vm.c @@ -28,8 +28,18 @@ struct lima_bo_va { struct lima_vm *vm; }; -#define LIMA_PDE(va) (va >> 22) -#define LIMA_PTE(va) ((va & 0x3FFFFF) >> 12) +#define LIMA_VM_PD_SHIFT 22 +#define LIMA_VM_PT_SHIFT 12 +#define LIMA_VM_PB_SHIFT (LIMA_VM_PD_SHIFT + LIMA_VM_NUM_PT_PER_BT_SHIFT) +#define LIMA_VM_BT_SHIFT LIMA_VM_PT_SHIFT + +#define LIMA_VM_PT_MASK ((1 << LIMA_VM_PD_SHIFT) - 1) +#define LIMA_VM_BT_MASK ((1 << LIMA_VM_PB_SHIFT) - 1) + +#define LIMA_PDE(va) (va >> LIMA_VM_PD_SHIFT) +#define LIMA_PTE(va) ((va & LIMA_VM_PT_MASK) >> LIMA_VM_PT_SHIFT) +#define LIMA_PBE(va) (va >> LIMA_VM_PB_SHIFT) +#define LIMA_BTE(va) ((va & LIMA_VM_BT_MASK) >> LIMA_VM_BT_SHIFT) #define START(node) ((node)->start) #define LAST(node) ((node)->last) @@ -45,12 +55,12 @@ static void lima_vm_unmap_page_table(struct lima_vm *vm, u32 start, u32 end) u32 addr; for (addr = start; addr <= end; addr += LIMA_PAGE_SIZE) { - u32 pde = LIMA_PDE(addr); - u32 pte = LIMA_PTE(addr); - u32 *pt; + u32 pbe = LIMA_PBE(addr); + u32 bte = LIMA_BTE(addr); + u32 *bt; - pt = lima_bo_kmap(vm->pt[pde]); - pt[pte] = 0; + bt = lima_bo_kmap(vm->bts[pbe]); + bt[bte] = 0; } } @@ -61,32 +71,43 @@ static int lima_vm_map_page_table(struct lima_vm *vm, dma_addr_t *dma, int err, i = 0; for (addr = start; addr <= end; addr += LIMA_PAGE_SIZE) { - u32 pde = LIMA_PDE(addr); - u32 pte = LIMA_PTE(addr); - u32 *pd, *pt; + u32 pbe = LIMA_PBE(addr); + u32 bte = LIMA_BTE(addr); + u32 *bt; - if (vm->pt[pde]) - pt = lima_bo_kmap(vm->pt[pde]); + if (vm->bts[pbe]) + bt = lima_bo_kmap(vm->bts[pbe]); else { - vm->pt[pde] = lima_bo_create( - vm->dev, LIMA_PAGE_SIZE, 0, ttm_bo_type_kernel, + struct lima_bo *bt_bo; + dma_addr_t *pts; + u32 *pd; + int j; + + bt_bo = lima_bo_create( + vm->dev, LIMA_PAGE_SIZE << LIMA_VM_NUM_PT_PER_BT_SHIFT, + 0, ttm_bo_type_kernel, NULL, vm->pd->tbo.resv); - if (IS_ERR(vm->pt[pde])) { - err = PTR_ERR(vm->pt[pde]); + if (IS_ERR(bt_bo)) { + err = PTR_ERR(bt_bo); goto err_out; } - pt = lima_bo_kmap(vm->pt[pde]); - if (IS_ERR(pt)) { - err = PTR_ERR(pt); + bt = lima_bo_kmap(bt_bo); + if (IS_ERR(bt)) { + lima_bo_unref(bt_bo); + err = PTR_ERR(bt); goto err_out; } + vm->bts[pbe] = bt_bo; pd = lima_bo_kmap(vm->pd); - pd[pde] = *lima_bo_get_pages(vm->pt[pde]) | LIMA_VM_FLAG_PRESENT; + pd += pbe << LIMA_VM_NUM_PT_PER_BT_SHIFT; + pts = lima_bo_get_pages(bt_bo); + for (j = 0; j < LIMA_VM_NUM_PT_PER_BT; j++) + *pd++ = *pts++ | LIMA_VM_FLAG_PRESENT; } - pt[pte] = dma[i++] | LIMA_VM_FLAGS_CACHE; + bt[bte] = dma[i++] | LIMA_VM_FLAGS_CACHE; } return 0; @@ -293,9 +314,9 @@ void lima_vm_release(struct kref *kref) dev_err(dev->dev, "still active bo inside vm\n"); } - for (i = 0; i < LIMA_PAGE_ENT_NUM; i++) { - if (vm->pt[i]) - lima_bo_unref(vm->pt[i]); + for (i = 0; i < LIMA_VM_NUM_BT; i++) { + if (vm->bts[i]) + lima_bo_unref(vm->bts[i]); } if (vm->pd) @@ -306,20 +327,26 @@ void lima_vm_release(struct kref *kref) void lima_vm_print(struct lima_vm *vm) { - int i, j; - u32 *pd = lima_bo_kmap(vm->pd); + int i, j, k; + u32 *pd, *pt; /* to avoid the defined by not used warning */ (void)&lima_vm_it_iter_next; - for (i = 0; i < LIMA_PAGE_ENT_NUM; i++) { - if (pd[i]) { - u32 *pt = lima_bo_kmap(vm->pt[i]); - - printk(KERN_INFO "lima vm pd %03x:%08x\n", i, pd[i]); - for (j = 0; j < LIMA_PAGE_ENT_NUM; j++) { - if (pt[j]) - printk(KERN_INFO " pt %03x:%08x\n", j, pt[j]); + pd = lima_bo_kmap(vm->pd); + for (i = 0; i < LIMA_VM_NUM_BT; i++) { + if (!vm->bts[i]) + continue; + + pt = lima_bo_kmap(vm->bts[i]); + for (j = 0; j < LIMA_VM_NUM_PT_PER_BT; j++) { + int idx = (i << LIMA_VM_NUM_PT_PER_BT_SHIFT) + j; + printk(KERN_INFO "lima vm pd %03x:%08x\n", idx, pd[idx]); + + for (k = 0; k < LIMA_PAGE_ENT_NUM; k++) { + u32 pte = *pt++; + if (pte) + printk(KERN_INFO " pt %03x:%08x\n", k, pte); } } } diff --git a/drivers/gpu/drm/lima/lima_vm.h b/drivers/gpu/drm/lima/lima_vm.h index c891a1ee95df..598708ac0d31 100644 --- a/drivers/gpu/drm/lima/lima_vm.h +++ b/drivers/gpu/drm/lima/lima_vm.h @@ -12,6 +12,10 @@ #define LIMA_PAGE_MASK (LIMA_PAGE_SIZE - 1) #define LIMA_PAGE_ENT_NUM (LIMA_PAGE_SIZE / sizeof(u32)) +#define LIMA_VM_NUM_PT_PER_BT_SHIFT 3 +#define LIMA_VM_NUM_PT_PER_BT (1 << LIMA_VM_NUM_PT_PER_BT_SHIFT) +#define LIMA_VM_NUM_BT (LIMA_PAGE_ENT_NUM >> LIMA_VM_NUM_PT_PER_BT_SHIFT) + #define LIMA_VA_RESERVE_START 0xFFF00000 #define LIMA_VA_RESERVE_DLBU LIMA_VA_RESERVE_START #define LIMA_VA_RESERVE_END 0x100000000 @@ -28,7 +32,7 @@ struct lima_vm { struct lima_device *dev; struct lima_bo *pd; - struct lima_bo *pt[LIMA_PAGE_ENT_NUM]; + struct lima_bo *bts[LIMA_VM_NUM_BT]; }; int lima_vm_bo_map(struct lima_vm *vm, struct lima_bo *bo, u32 start); -- 2.17.1