build/patch/kernel/sunxi-next/0069-drm-lima-vm-alloc-buffer-with-multi-page-table.patch

189 lines
5.4 KiB
Diff

From 063d7ebf17304fe8a7b85ecb4662f20c4839b6af Mon Sep 17 00:00:00 2001
From: Qiang Yu <yuq825@gmail.com>
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 <yuq825@gmail.com>
---
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