Commit 196f7489 authored by Chunming Zhou's avatar Chunming Zhou Committed by Alex Deucher

drm/amdgpu: add enumerate for PDB/PTB v3

v2:
  remove SUBPTB member
v3:
  remove last_level, use AMDGPU_VM_PTB directly instead.
Signed-off-by: default avatarChunming Zhou <david1.zhou@amd.com>
Reviewed-by: default avatarChristian König <christian.koenig@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent a53d45d8
...@@ -148,12 +148,23 @@ struct amdgpu_prt_cb { ...@@ -148,12 +148,23 @@ struct amdgpu_prt_cb {
static unsigned amdgpu_vm_level_shift(struct amdgpu_device *adev, static unsigned amdgpu_vm_level_shift(struct amdgpu_device *adev,
unsigned level) unsigned level)
{ {
if (level != adev->vm_manager.num_level) unsigned shift = 0xff;
return 9 * (adev->vm_manager.num_level - level - 1) +
switch (level) {
case AMDGPU_VM_PDB2:
case AMDGPU_VM_PDB1:
case AMDGPU_VM_PDB0:
shift = 9 * (AMDGPU_VM_PDB0 - level) +
adev->vm_manager.block_size; adev->vm_manager.block_size;
else break;
/* For the page tables on the leaves */ case AMDGPU_VM_PTB:
return 0; shift = 0;
break;
default:
dev_err(adev->dev, "the level%d isn't supported.\n", level);
}
return shift;
} }
/** /**
...@@ -166,12 +177,13 @@ static unsigned amdgpu_vm_level_shift(struct amdgpu_device *adev, ...@@ -166,12 +177,13 @@ static unsigned amdgpu_vm_level_shift(struct amdgpu_device *adev,
static unsigned amdgpu_vm_num_entries(struct amdgpu_device *adev, static unsigned amdgpu_vm_num_entries(struct amdgpu_device *adev,
unsigned level) unsigned level)
{ {
unsigned shift = amdgpu_vm_level_shift(adev, 0); unsigned shift = amdgpu_vm_level_shift(adev,
adev->vm_manager.root_level);
if (level == 0) if (level == adev->vm_manager.root_level)
/* For the root directory */ /* For the root directory */
return round_up(adev->vm_manager.max_pfn, 1 << shift) >> shift; return round_up(adev->vm_manager.max_pfn, 1 << shift) >> shift;
else if (level != adev->vm_manager.num_level) else if (level != AMDGPU_VM_PTB)
/* Everything in between */ /* Everything in between */
return 512; return 512;
else else
...@@ -343,7 +355,7 @@ static int amdgpu_vm_alloc_levels(struct amdgpu_device *adev, ...@@ -343,7 +355,7 @@ static int amdgpu_vm_alloc_levels(struct amdgpu_device *adev,
if (vm->pte_support_ats) { if (vm->pte_support_ats) {
init_value = AMDGPU_PTE_DEFAULT_ATC; init_value = AMDGPU_PTE_DEFAULT_ATC;
if (level != adev->vm_manager.num_level) if (level != AMDGPU_VM_PTB)
init_value |= AMDGPU_PDE_PTE; init_value |= AMDGPU_PDE_PTE;
} }
...@@ -385,7 +397,7 @@ static int amdgpu_vm_alloc_levels(struct amdgpu_device *adev, ...@@ -385,7 +397,7 @@ static int amdgpu_vm_alloc_levels(struct amdgpu_device *adev,
spin_unlock(&vm->status_lock); spin_unlock(&vm->status_lock);
} }
if (level < adev->vm_manager.num_level) { if (level < AMDGPU_VM_PTB) {
uint64_t sub_saddr = (pt_idx == from) ? saddr : 0; uint64_t sub_saddr = (pt_idx == from) ? saddr : 0;
uint64_t sub_eaddr = (pt_idx == to) ? eaddr : uint64_t sub_eaddr = (pt_idx == to) ? eaddr :
((1 << shift) - 1); ((1 << shift) - 1);
...@@ -431,7 +443,8 @@ int amdgpu_vm_alloc_pts(struct amdgpu_device *adev, ...@@ -431,7 +443,8 @@ int amdgpu_vm_alloc_pts(struct amdgpu_device *adev,
saddr /= AMDGPU_GPU_PAGE_SIZE; saddr /= AMDGPU_GPU_PAGE_SIZE;
eaddr /= AMDGPU_GPU_PAGE_SIZE; eaddr /= AMDGPU_GPU_PAGE_SIZE;
return amdgpu_vm_alloc_levels(adev, vm, &vm->root, saddr, eaddr, 0); return amdgpu_vm_alloc_levels(adev, vm, &vm->root, saddr, eaddr,
adev->vm_manager.root_level);
} }
/** /**
...@@ -1091,6 +1104,7 @@ static void amdgpu_vm_update_pde(struct amdgpu_pte_update_params *params, ...@@ -1091,6 +1104,7 @@ static void amdgpu_vm_update_pde(struct amdgpu_pte_update_params *params,
for (level = 0, pbo = parent->base.bo->parent; pbo; ++level) for (level = 0, pbo = parent->base.bo->parent; pbo; ++level)
pbo = pbo->parent; pbo = pbo->parent;
level += params->adev->vm_manager.root_level;
pt = amdgpu_bo_gpu_offset(bo); pt = amdgpu_bo_gpu_offset(bo);
flags = AMDGPU_PTE_VALID; flags = AMDGPU_PTE_VALID;
amdgpu_gart_get_vm_pde(params->adev, level, &pt, &flags); amdgpu_gart_get_vm_pde(params->adev, level, &pt, &flags);
...@@ -1247,7 +1261,8 @@ int amdgpu_vm_update_directories(struct amdgpu_device *adev, ...@@ -1247,7 +1261,8 @@ int amdgpu_vm_update_directories(struct amdgpu_device *adev,
return 0; return 0;
error: error:
amdgpu_vm_invalidate_level(adev, vm, &vm->root, 0); amdgpu_vm_invalidate_level(adev, vm, &vm->root,
adev->vm_manager.root_level);
amdgpu_job_free(job); amdgpu_job_free(job);
return r; return r;
} }
...@@ -1266,7 +1281,7 @@ void amdgpu_vm_get_entry(struct amdgpu_pte_update_params *p, uint64_t addr, ...@@ -1266,7 +1281,7 @@ void amdgpu_vm_get_entry(struct amdgpu_pte_update_params *p, uint64_t addr,
struct amdgpu_vm_pt **entry, struct amdgpu_vm_pt **entry,
struct amdgpu_vm_pt **parent) struct amdgpu_vm_pt **parent)
{ {
unsigned level = 0; unsigned level = p->adev->vm_manager.root_level;
*parent = NULL; *parent = NULL;
*entry = &p->vm->root; *entry = &p->vm->root;
...@@ -1278,7 +1293,7 @@ void amdgpu_vm_get_entry(struct amdgpu_pte_update_params *p, uint64_t addr, ...@@ -1278,7 +1293,7 @@ void amdgpu_vm_get_entry(struct amdgpu_pte_update_params *p, uint64_t addr,
addr &= (1ULL << shift) - 1; addr &= (1ULL << shift) - 1;
} }
if (level != p->adev->vm_manager.num_level) if (level != AMDGPU_VM_PTB)
*entry = NULL; *entry = NULL;
} }
...@@ -1320,7 +1335,7 @@ static void amdgpu_vm_handle_huge_pages(struct amdgpu_pte_update_params *p, ...@@ -1320,7 +1335,7 @@ static void amdgpu_vm_handle_huge_pages(struct amdgpu_pte_update_params *p,
return; return;
entry->huge = !!(flags & AMDGPU_PDE_PTE); entry->huge = !!(flags & AMDGPU_PDE_PTE);
amdgpu_gart_get_vm_pde(p->adev, p->adev->vm_manager.num_level - 1, amdgpu_gart_get_vm_pde(p->adev, AMDGPU_VM_PDB0,
&dst, &flags); &dst, &flags);
if (use_cpu_update) { if (use_cpu_update) {
...@@ -1636,7 +1651,8 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev, ...@@ -1636,7 +1651,8 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev,
error_free: error_free:
amdgpu_job_free(job); amdgpu_job_free(job);
amdgpu_vm_invalidate_level(adev, vm, &vm->root, 0); amdgpu_vm_invalidate_level(adev, vm, &vm->root,
adev->vm_manager.root_level);
return r; return r;
} }
...@@ -2552,7 +2568,19 @@ void amdgpu_vm_adjust_size(struct amdgpu_device *adev, uint32_t vm_size, ...@@ -2552,7 +2568,19 @@ void amdgpu_vm_adjust_size(struct amdgpu_device *adev, uint32_t vm_size,
tmp >>= amdgpu_vm_block_size - 9; tmp >>= amdgpu_vm_block_size - 9;
tmp = DIV_ROUND_UP(fls64(tmp) - 1, 9) - 1; tmp = DIV_ROUND_UP(fls64(tmp) - 1, 9) - 1;
adev->vm_manager.num_level = min(max_level, (unsigned)tmp); adev->vm_manager.num_level = min(max_level, (unsigned)tmp);
switch (adev->vm_manager.num_level) {
case 3:
adev->vm_manager.root_level = AMDGPU_VM_PDB2;
break;
case 2:
adev->vm_manager.root_level = AMDGPU_VM_PDB1;
break;
case 1:
adev->vm_manager.root_level = AMDGPU_VM_PDB0;
break;
default:
dev_err(adev->dev, "VMPT only supports 2~4+1 levels\n");
}
/* block size depends on vm size and hw setup*/ /* block size depends on vm size and hw setup*/
if (amdgpu_vm_block_size != -1) if (amdgpu_vm_block_size != -1)
adev->vm_manager.block_size = adev->vm_manager.block_size =
...@@ -2646,7 +2674,9 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm, ...@@ -2646,7 +2674,9 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm,
flags |= (AMDGPU_GEM_CREATE_NO_CPU_ACCESS | flags |= (AMDGPU_GEM_CREATE_NO_CPU_ACCESS |
AMDGPU_GEM_CREATE_SHADOW); AMDGPU_GEM_CREATE_SHADOW);
r = amdgpu_bo_create(adev, amdgpu_vm_bo_size(adev, 0), align, true, r = amdgpu_bo_create(adev,
amdgpu_vm_bo_size(adev, adev->vm_manager.root_level),
align, true,
AMDGPU_GEM_DOMAIN_VRAM, AMDGPU_GEM_DOMAIN_VRAM,
flags, flags,
NULL, NULL, init_pde_value, &vm->root.base.bo); NULL, NULL, init_pde_value, &vm->root.base.bo);
...@@ -2782,7 +2812,8 @@ void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm) ...@@ -2782,7 +2812,8 @@ void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm)
if (r) { if (r) {
dev_err(adev->dev, "Leaking page tables because BO reservation failed\n"); dev_err(adev->dev, "Leaking page tables because BO reservation failed\n");
} else { } else {
amdgpu_vm_free_levels(adev, &vm->root, 0); amdgpu_vm_free_levels(adev, &vm->root,
adev->vm_manager.root_level);
amdgpu_bo_unreserve(root); amdgpu_bo_unreserve(root);
} }
amdgpu_bo_unref(&root); amdgpu_bo_unref(&root);
......
...@@ -120,6 +120,16 @@ struct amdgpu_bo_list_entry; ...@@ -120,6 +120,16 @@ struct amdgpu_bo_list_entry;
#define AMDGPU_VM_USE_CPU_FOR_GFX (1 << 0) #define AMDGPU_VM_USE_CPU_FOR_GFX (1 << 0)
#define AMDGPU_VM_USE_CPU_FOR_COMPUTE (1 << 1) #define AMDGPU_VM_USE_CPU_FOR_COMPUTE (1 << 1)
/* VMPT level enumerate, and the hiberachy is:
* PDB2->PDB1->PDB0->PTB
*/
enum amdgpu_vm_level {
AMDGPU_VM_PDB2,
AMDGPU_VM_PDB1,
AMDGPU_VM_PDB0,
AMDGPU_VM_PTB
};
/* base structure for tracking BO usage in a VM */ /* base structure for tracking BO usage in a VM */
struct amdgpu_vm_bo_base { struct amdgpu_vm_bo_base {
/* constant after initialization */ /* constant after initialization */
...@@ -236,6 +246,7 @@ struct amdgpu_vm_manager { ...@@ -236,6 +246,7 @@ struct amdgpu_vm_manager {
uint32_t num_level; uint32_t num_level;
uint32_t block_size; uint32_t block_size;
uint32_t fragment_size; uint32_t fragment_size;
enum amdgpu_vm_level root_level;
/* vram base address for page table entry */ /* vram base address for page table entry */
u64 vram_base_offset; u64 vram_base_offset;
/* vm pte handling */ /* vm pte handling */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment