diff options
author | Chunming Zhou <david1.zhou@amd.com> | 2017-12-13 01:22:54 -0500 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2017-12-14 11:01:30 -0500 |
commit | 196f74897ba79f6d586894519f09796447d95be5 (patch) | |
tree | 2816a90fb29240a3da5789c99064a1154e22c666 /drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | |
parent | a53d45d8e40a39a5c34ce5257359614d41529048 (diff) |
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: Chunming Zhou <david1.zhou@amd.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 69 |
1 files changed, 50 insertions, 19 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index 709587d8a77f..564e1b1962f1 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | |||
@@ -148,12 +148,23 @@ struct amdgpu_prt_cb { | |||
148 | static unsigned amdgpu_vm_level_shift(struct amdgpu_device *adev, | 148 | static unsigned amdgpu_vm_level_shift(struct amdgpu_device *adev, |
149 | unsigned level) | 149 | unsigned level) |
150 | { | 150 | { |
151 | if (level != adev->vm_manager.num_level) | 151 | unsigned shift = 0xff; |
152 | return 9 * (adev->vm_manager.num_level - level - 1) + | 152 | |
153 | switch (level) { | ||
154 | case AMDGPU_VM_PDB2: | ||
155 | case AMDGPU_VM_PDB1: | ||
156 | case AMDGPU_VM_PDB0: | ||
157 | shift = 9 * (AMDGPU_VM_PDB0 - level) + | ||
153 | adev->vm_manager.block_size; | 158 | adev->vm_manager.block_size; |
154 | else | 159 | break; |
155 | /* For the page tables on the leaves */ | 160 | case AMDGPU_VM_PTB: |
156 | return 0; | 161 | shift = 0; |
162 | break; | ||
163 | default: | ||
164 | dev_err(adev->dev, "the level%d isn't supported.\n", level); | ||
165 | } | ||
166 | |||
167 | return shift; | ||
157 | } | 168 | } |
158 | 169 | ||
159 | /** | 170 | /** |
@@ -166,12 +177,13 @@ static unsigned amdgpu_vm_level_shift(struct amdgpu_device *adev, | |||
166 | static unsigned amdgpu_vm_num_entries(struct amdgpu_device *adev, | 177 | static unsigned amdgpu_vm_num_entries(struct amdgpu_device *adev, |
167 | unsigned level) | 178 | unsigned level) |
168 | { | 179 | { |
169 | unsigned shift = amdgpu_vm_level_shift(adev, 0); | 180 | unsigned shift = amdgpu_vm_level_shift(adev, |
181 | adev->vm_manager.root_level); | ||
170 | 182 | ||
171 | if (level == 0) | 183 | if (level == adev->vm_manager.root_level) |
172 | /* For the root directory */ | 184 | /* For the root directory */ |
173 | return round_up(adev->vm_manager.max_pfn, 1 << shift) >> shift; | 185 | return round_up(adev->vm_manager.max_pfn, 1 << shift) >> shift; |
174 | else if (level != adev->vm_manager.num_level) | 186 | else if (level != AMDGPU_VM_PTB) |
175 | /* Everything in between */ | 187 | /* Everything in between */ |
176 | return 512; | 188 | return 512; |
177 | else | 189 | else |
@@ -343,7 +355,7 @@ static int amdgpu_vm_alloc_levels(struct amdgpu_device *adev, | |||
343 | 355 | ||
344 | if (vm->pte_support_ats) { | 356 | if (vm->pte_support_ats) { |
345 | init_value = AMDGPU_PTE_DEFAULT_ATC; | 357 | init_value = AMDGPU_PTE_DEFAULT_ATC; |
346 | if (level != adev->vm_manager.num_level) | 358 | if (level != AMDGPU_VM_PTB) |
347 | init_value |= AMDGPU_PDE_PTE; | 359 | init_value |= AMDGPU_PDE_PTE; |
348 | 360 | ||
349 | } | 361 | } |
@@ -385,7 +397,7 @@ static int amdgpu_vm_alloc_levels(struct amdgpu_device *adev, | |||
385 | spin_unlock(&vm->status_lock); | 397 | spin_unlock(&vm->status_lock); |
386 | } | 398 | } |
387 | 399 | ||
388 | if (level < adev->vm_manager.num_level) { | 400 | if (level < AMDGPU_VM_PTB) { |
389 | uint64_t sub_saddr = (pt_idx == from) ? saddr : 0; | 401 | uint64_t sub_saddr = (pt_idx == from) ? saddr : 0; |
390 | uint64_t sub_eaddr = (pt_idx == to) ? eaddr : | 402 | uint64_t sub_eaddr = (pt_idx == to) ? eaddr : |
391 | ((1 << shift) - 1); | 403 | ((1 << shift) - 1); |
@@ -431,7 +443,8 @@ int amdgpu_vm_alloc_pts(struct amdgpu_device *adev, | |||
431 | saddr /= AMDGPU_GPU_PAGE_SIZE; | 443 | saddr /= AMDGPU_GPU_PAGE_SIZE; |
432 | eaddr /= AMDGPU_GPU_PAGE_SIZE; | 444 | eaddr /= AMDGPU_GPU_PAGE_SIZE; |
433 | 445 | ||
434 | return amdgpu_vm_alloc_levels(adev, vm, &vm->root, saddr, eaddr, 0); | 446 | return amdgpu_vm_alloc_levels(adev, vm, &vm->root, saddr, eaddr, |
447 | adev->vm_manager.root_level); | ||
435 | } | 448 | } |
436 | 449 | ||
437 | /** | 450 | /** |
@@ -1091,6 +1104,7 @@ static void amdgpu_vm_update_pde(struct amdgpu_pte_update_params *params, | |||
1091 | for (level = 0, pbo = parent->base.bo->parent; pbo; ++level) | 1104 | for (level = 0, pbo = parent->base.bo->parent; pbo; ++level) |
1092 | pbo = pbo->parent; | 1105 | pbo = pbo->parent; |
1093 | 1106 | ||
1107 | level += params->adev->vm_manager.root_level; | ||
1094 | pt = amdgpu_bo_gpu_offset(bo); | 1108 | pt = amdgpu_bo_gpu_offset(bo); |
1095 | flags = AMDGPU_PTE_VALID; | 1109 | flags = AMDGPU_PTE_VALID; |
1096 | amdgpu_gart_get_vm_pde(params->adev, level, &pt, &flags); | 1110 | amdgpu_gart_get_vm_pde(params->adev, level, &pt, &flags); |
@@ -1247,7 +1261,8 @@ restart: | |||
1247 | return 0; | 1261 | return 0; |
1248 | 1262 | ||
1249 | error: | 1263 | error: |
1250 | amdgpu_vm_invalidate_level(adev, vm, &vm->root, 0); | 1264 | amdgpu_vm_invalidate_level(adev, vm, &vm->root, |
1265 | adev->vm_manager.root_level); | ||
1251 | amdgpu_job_free(job); | 1266 | amdgpu_job_free(job); |
1252 | return r; | 1267 | return r; |
1253 | } | 1268 | } |
@@ -1266,7 +1281,7 @@ void amdgpu_vm_get_entry(struct amdgpu_pte_update_params *p, uint64_t addr, | |||
1266 | struct amdgpu_vm_pt **entry, | 1281 | struct amdgpu_vm_pt **entry, |
1267 | struct amdgpu_vm_pt **parent) | 1282 | struct amdgpu_vm_pt **parent) |
1268 | { | 1283 | { |
1269 | unsigned level = 0; | 1284 | unsigned level = p->adev->vm_manager.root_level; |
1270 | 1285 | ||
1271 | *parent = NULL; | 1286 | *parent = NULL; |
1272 | *entry = &p->vm->root; | 1287 | *entry = &p->vm->root; |
@@ -1278,7 +1293,7 @@ void amdgpu_vm_get_entry(struct amdgpu_pte_update_params *p, uint64_t addr, | |||
1278 | addr &= (1ULL << shift) - 1; | 1293 | addr &= (1ULL << shift) - 1; |
1279 | } | 1294 | } |
1280 | 1295 | ||
1281 | if (level != p->adev->vm_manager.num_level) | 1296 | if (level != AMDGPU_VM_PTB) |
1282 | *entry = NULL; | 1297 | *entry = NULL; |
1283 | } | 1298 | } |
1284 | 1299 | ||
@@ -1320,7 +1335,7 @@ static void amdgpu_vm_handle_huge_pages(struct amdgpu_pte_update_params *p, | |||
1320 | return; | 1335 | return; |
1321 | entry->huge = !!(flags & AMDGPU_PDE_PTE); | 1336 | entry->huge = !!(flags & AMDGPU_PDE_PTE); |
1322 | 1337 | ||
1323 | amdgpu_gart_get_vm_pde(p->adev, p->adev->vm_manager.num_level - 1, | 1338 | amdgpu_gart_get_vm_pde(p->adev, AMDGPU_VM_PDB0, |
1324 | &dst, &flags); | 1339 | &dst, &flags); |
1325 | 1340 | ||
1326 | if (use_cpu_update) { | 1341 | if (use_cpu_update) { |
@@ -1636,7 +1651,8 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev, | |||
1636 | 1651 | ||
1637 | error_free: | 1652 | error_free: |
1638 | amdgpu_job_free(job); | 1653 | amdgpu_job_free(job); |
1639 | amdgpu_vm_invalidate_level(adev, vm, &vm->root, 0); | 1654 | amdgpu_vm_invalidate_level(adev, vm, &vm->root, |
1655 | adev->vm_manager.root_level); | ||
1640 | return r; | 1656 | return r; |
1641 | } | 1657 | } |
1642 | 1658 | ||
@@ -2552,7 +2568,19 @@ void amdgpu_vm_adjust_size(struct amdgpu_device *adev, uint32_t vm_size, | |||
2552 | tmp >>= amdgpu_vm_block_size - 9; | 2568 | tmp >>= amdgpu_vm_block_size - 9; |
2553 | tmp = DIV_ROUND_UP(fls64(tmp) - 1, 9) - 1; | 2569 | tmp = DIV_ROUND_UP(fls64(tmp) - 1, 9) - 1; |
2554 | adev->vm_manager.num_level = min(max_level, (unsigned)tmp); | 2570 | adev->vm_manager.num_level = min(max_level, (unsigned)tmp); |
2555 | 2571 | switch (adev->vm_manager.num_level) { | |
2572 | case 3: | ||
2573 | adev->vm_manager.root_level = AMDGPU_VM_PDB2; | ||
2574 | break; | ||
2575 | case 2: | ||
2576 | adev->vm_manager.root_level = AMDGPU_VM_PDB1; | ||
2577 | break; | ||
2578 | case 1: | ||
2579 | adev->vm_manager.root_level = AMDGPU_VM_PDB0; | ||
2580 | break; | ||
2581 | default: | ||
2582 | dev_err(adev->dev, "VMPT only supports 2~4+1 levels\n"); | ||
2583 | } | ||
2556 | /* block size depends on vm size and hw setup*/ | 2584 | /* block size depends on vm size and hw setup*/ |
2557 | if (amdgpu_vm_block_size != -1) | 2585 | if (amdgpu_vm_block_size != -1) |
2558 | adev->vm_manager.block_size = | 2586 | adev->vm_manager.block_size = |
@@ -2646,7 +2674,9 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm, | |||
2646 | flags |= (AMDGPU_GEM_CREATE_NO_CPU_ACCESS | | 2674 | flags |= (AMDGPU_GEM_CREATE_NO_CPU_ACCESS | |
2647 | AMDGPU_GEM_CREATE_SHADOW); | 2675 | AMDGPU_GEM_CREATE_SHADOW); |
2648 | 2676 | ||
2649 | r = amdgpu_bo_create(adev, amdgpu_vm_bo_size(adev, 0), align, true, | 2677 | r = amdgpu_bo_create(adev, |
2678 | amdgpu_vm_bo_size(adev, adev->vm_manager.root_level), | ||
2679 | align, true, | ||
2650 | AMDGPU_GEM_DOMAIN_VRAM, | 2680 | AMDGPU_GEM_DOMAIN_VRAM, |
2651 | flags, | 2681 | flags, |
2652 | NULL, NULL, init_pde_value, &vm->root.base.bo); | 2682 | 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 | if (r) { | 2812 | if (r) { |
2783 | dev_err(adev->dev, "Leaking page tables because BO reservation failed\n"); | 2813 | dev_err(adev->dev, "Leaking page tables because BO reservation failed\n"); |
2784 | } else { | 2814 | } else { |
2785 | amdgpu_vm_free_levels(adev, &vm->root, 0); | 2815 | amdgpu_vm_free_levels(adev, &vm->root, |
2816 | adev->vm_manager.root_level); | ||
2786 | amdgpu_bo_unreserve(root); | 2817 | amdgpu_bo_unreserve(root); |
2787 | } | 2818 | } |
2788 | amdgpu_bo_unref(&root); | 2819 | amdgpu_bo_unref(&root); |