summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAlex Waterman <alexw@nvidia.com>2016-10-31 16:17:44 -0400
committermobile promotions <svcmobile_promotions@nvidia.com>2017-01-31 19:23:07 -0500
commit95a3eb454ca2f1b1b1a5677fe024eacae79bc0ed (patch)
tree6b3daeb6e2f8ac5828faf1ddc448f61de8954b70 /drivers
parentb9b94c073ce551935be1c00cb8e756ad5ce5c631 (diff)
gpu: nvgpu: Conditional address space unification
Allow platforms to choose whether or not to have unified GPU VA spaces. This is useful for the dGPU where having a unified address space has no problems. On iGPUs testing issues is getting in the way of enabling this feature. Bug 1396644 Bug 1729947 Change-Id: I65985f1f9a818f4b06219715cc09619911e4824b Signed-off-by: Alex Waterman <alexw@nvidia.com> Reviewed-on: http://git-master/r/1265303 GVS: Gerrit_Virtual_Submit Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/nvgpu/gk20a/mm_gk20a.c223
-rw-r--r--drivers/gpu/nvgpu/gk20a/mm_gk20a.h45
-rw-r--r--drivers/gpu/nvgpu/gk20a/platform_gk20a.h3
3 files changed, 167 insertions, 104 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/mm_gk20a.c b/drivers/gpu/nvgpu/gk20a/mm_gk20a.c
index b04a7e87..e589e312 100644
--- a/drivers/gpu/nvgpu/gk20a/mm_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/mm_gk20a.c
@@ -1788,12 +1788,6 @@ struct buffer_attrs {
1788 bool ctag_user_mappable; 1788 bool ctag_user_mappable;
1789}; 1789};
1790 1790
1791static void gmmu_select_page_size(struct vm_gk20a *vm,
1792 struct buffer_attrs *bfr)
1793{
1794 bfr->pgsz_idx = __get_pte_size(vm, 0, bfr->size);
1795}
1796
1797static int setup_buffer_kind_and_compression(struct vm_gk20a *vm, 1791static int setup_buffer_kind_and_compression(struct vm_gk20a *vm,
1798 u32 flags, 1792 u32 flags,
1799 struct buffer_attrs *bfr, 1793 struct buffer_attrs *bfr,
@@ -2411,7 +2405,6 @@ u64 gk20a_vm_map(struct vm_gk20a *vm,
2411 struct device *d = dev_from_vm(vm); 2405 struct device *d = dev_from_vm(vm);
2412 struct mapped_buffer_node *mapped_buffer = NULL; 2406 struct mapped_buffer_node *mapped_buffer = NULL;
2413 bool inserted = false, va_allocated = false; 2407 bool inserted = false, va_allocated = false;
2414 u32 gmmu_page_size = 0;
2415 u64 map_offset = 0; 2408 u64 map_offset = 0;
2416 int err = 0; 2409 int err = 0;
2417 struct buffer_attrs bfr = {NULL}; 2410 struct buffer_attrs bfr = {NULL};
@@ -2482,42 +2475,7 @@ u64 gk20a_vm_map(struct vm_gk20a *vm,
2482 min_t(u64, bfr.size, bfr.align)); 2475 min_t(u64, bfr.size, bfr.align));
2483 mapping_size = mapping_size ? mapping_size : bfr.size; 2476 mapping_size = mapping_size ? mapping_size : bfr.size;
2484 2477
2485 if (vm->big_pages)
2486 gmmu_select_page_size(vm, &bfr);
2487 else
2488 bfr.pgsz_idx = gmmu_page_size_small;
2489
2490 /* If FIX_OFFSET is set, pgsz is determined at address allocation
2491 * time. The alignment at address alloc time must be the same as
2492 * the alignment determined by gmmu_select_page_size().
2493 */
2494 if (flags & NVGPU_AS_MAP_BUFFER_FLAGS_FIXED_OFFSET) {
2495 int pgsz_idx = __get_pte_size(vm, offset_align, mapping_size);
2496 if (pgsz_idx > bfr.pgsz_idx) {
2497 gk20a_err(d, "%llx buffer pgsz %d, VA pgsz %d",
2498 offset_align, bfr.pgsz_idx, pgsz_idx);
2499 err = -EINVAL;
2500 goto clean_up;
2501 }
2502 bfr.pgsz_idx = min(bfr.pgsz_idx, pgsz_idx);
2503 }
2504
2505 /* validate/adjust bfr attributes */
2506 if (unlikely(bfr.pgsz_idx == -1)) {
2507 gk20a_err(d, "unsupported page size detected");
2508 goto clean_up;
2509 }
2510
2511 if (unlikely(bfr.pgsz_idx < gmmu_page_size_small ||
2512 bfr.pgsz_idx > gmmu_page_size_big)) {
2513 BUG_ON(1);
2514 err = -EINVAL;
2515 goto clean_up;
2516 }
2517 gmmu_page_size = vm->gmmu_page_sizes[bfr.pgsz_idx];
2518
2519 /* Check if we should use a fixed offset for mapping this buffer */ 2478 /* Check if we should use a fixed offset for mapping this buffer */
2520
2521 if (flags & NVGPU_AS_MAP_BUFFER_FLAGS_FIXED_OFFSET) { 2479 if (flags & NVGPU_AS_MAP_BUFFER_FLAGS_FIXED_OFFSET) {
2522 err = validate_fixed_buffer(vm, &bfr, 2480 err = validate_fixed_buffer(vm, &bfr,
2523 offset_align, mapping_size, 2481 offset_align, mapping_size,
@@ -4289,7 +4247,7 @@ int gk20a_big_pages_possible(struct vm_gk20a *vm, u64 base, u64 size)
4289 4247
4290/* 4248/*
4291 * Attempt to find a reserved memory area to determine PTE size for the passed 4249 * Attempt to find a reserved memory area to determine PTE size for the passed
4292 * mapping. If no reserved area can be found use small pages but drop a warning. 4250 * mapping. If no reserved area can be found use small pages.
4293 */ 4251 */
4294enum gmmu_pgsz_gk20a __get_pte_size_fixed_map(struct vm_gk20a *vm, 4252enum gmmu_pgsz_gk20a __get_pte_size_fixed_map(struct vm_gk20a *vm,
4295 u64 base, u64 size) 4253 u64 base, u64 size)
@@ -4303,6 +4261,60 @@ enum gmmu_pgsz_gk20a __get_pte_size_fixed_map(struct vm_gk20a *vm,
4303 return node->pgsz_idx; 4261 return node->pgsz_idx;
4304} 4262}
4305 4263
4264/*
4265 * This is for when the address space does not support unified address spaces.
4266 */
4267enum gmmu_pgsz_gk20a __get_pte_size_split_addr(struct vm_gk20a *vm,
4268 u64 base, u64 size)
4269{
4270 if (!base) {
4271 if (size >= vm->gmmu_page_sizes[gmmu_page_size_big])
4272 return gmmu_page_size_big;
4273 return gmmu_page_size_small;
4274 } else {
4275 if (base < __nv_gmmu_va_small_page_limit())
4276 return gmmu_page_size_small;
4277 else
4278 return gmmu_page_size_big;
4279 }
4280}
4281
4282/*
4283 * This determines the PTE size for a given alloc. Used by both the GVA space
4284 * allocator and the mm core code so that agreement can be reached on how to
4285 * map allocations.
4286 *
4287 * The page size of a buffer is this:
4288 *
4289 * o If the VM doesn't support large pages then obviously small pages
4290 * must be used.
4291 * o If the base address is non-zero (fixed address map):
4292 * - Attempt to find a reserved memory area and use the page size
4293 * based on that.
4294 * - If no reserved page size is available, default to small pages.
4295 * o If the base is zero:
4296 * - If the size is larger than or equal to the big page size, use big
4297 * pages.
4298 * - Otherwise use small pages.
4299 */
4300enum gmmu_pgsz_gk20a __get_pte_size(struct vm_gk20a *vm, u64 base, u64 size)
4301{
4302 struct gk20a_platform *p = gk20a_get_platform(vm->mm->g->dev);
4303
4304 if (!vm->big_pages)
4305 return gmmu_page_size_small;
4306
4307 if (!p->unify_address_spaces)
4308 return __get_pte_size_split_addr(vm, base, size);
4309
4310 if (base)
4311 return __get_pte_size_fixed_map(vm, base, size);
4312
4313 if (size >= vm->gmmu_page_sizes[gmmu_page_size_big])
4314 return gmmu_page_size_big;
4315 return gmmu_page_size_small;
4316}
4317
4306static int init_vm_page_tables(struct vm_gk20a *vm) 4318static int init_vm_page_tables(struct vm_gk20a *vm)
4307{ 4319{
4308 u32 pde_lo, pde_hi; 4320 u32 pde_lo, pde_hi;
@@ -4376,15 +4388,20 @@ int gk20a_init_vm(struct mm_gk20a *mm,
4376{ 4388{
4377 int err; 4389 int err;
4378 char alloc_name[32]; 4390 char alloc_name[32];
4391 u64 kernel_vma_flags;
4379 u64 user_vma_start, user_vma_limit; 4392 u64 user_vma_start, user_vma_limit;
4393 u64 user_lp_vma_start, user_lp_vma_limit;
4380 u64 kernel_vma_start, kernel_vma_limit; 4394 u64 kernel_vma_start, kernel_vma_limit;
4381 struct gk20a *g = mm->g; 4395 struct gk20a *g = mm->g;
4396 struct gk20a_platform *p = gk20a_get_platform(g->dev);
4382 4397
4383 if (WARN_ON(kernel_reserved + low_hole > aperture_size)) 4398 if (WARN_ON(kernel_reserved + low_hole > aperture_size))
4384 return -ENOMEM; 4399 return -ENOMEM;
4385 4400
4386 gk20a_dbg_info("Init space for %s: va_limit=0x%llx", 4401 gk20a_dbg_info("Init space for %s: va_limit=0x%llx, "
4387 name, vm->va_limit); 4402 "big_page_size=0x%x low_hole=0x%llx",
4403 name, aperture_size,
4404 (unsigned int)big_page_size, low_hole);
4388 4405
4389 vm->mm = mm; 4406 vm->mm = mm;
4390 4407
@@ -4393,9 +4410,11 @@ int gk20a_init_vm(struct mm_gk20a *mm,
4393 vm->gmmu_page_sizes[gmmu_page_size_kernel] = SZ_4K; 4410 vm->gmmu_page_sizes[gmmu_page_size_kernel] = SZ_4K;
4394 4411
4395 /* Set up vma pointers. */ 4412 /* Set up vma pointers. */
4396 vm->vma[0] = &vm->user; 4413 vm->vma[gmmu_page_size_small] = &vm->user;
4397 vm->vma[1] = &vm->user; 4414 vm->vma[gmmu_page_size_big] = &vm->user;
4398 vm->vma[2] = &vm->kernel; 4415 vm->vma[gmmu_page_size_kernel] = &vm->kernel;
4416 if (!p->unify_address_spaces)
4417 vm->vma[gmmu_page_size_big] = &vm->user_lp;
4399 4418
4400 vm->va_start = low_hole; 4419 vm->va_start = low_hole;
4401 vm->va_limit = aperture_size; 4420 vm->va_limit = aperture_size;
@@ -4403,27 +4422,51 @@ int gk20a_init_vm(struct mm_gk20a *mm,
4403 4422
4404 vm->big_page_size = vm->gmmu_page_sizes[gmmu_page_size_big]; 4423 vm->big_page_size = vm->gmmu_page_sizes[gmmu_page_size_big];
4405 vm->userspace_managed = userspace_managed; 4424 vm->userspace_managed = userspace_managed;
4406 vm->mmu_levels = g->ops.mm.get_mmu_levels(g, big_page_size); 4425 vm->mmu_levels = g->ops.mm.get_mmu_levels(g, vm->big_page_size);
4407 4426
4408 /* Initialize the page table data structures. */ 4427 /* Initialize the page table data structures. */
4409 err = init_vm_page_tables(vm); 4428 err = init_vm_page_tables(vm);
4410 if (err) 4429 if (err)
4411 return err; 4430 return err;
4412 4431
4413 /* setup vma limits */ 4432 /* Setup vma limits. */
4414 user_vma_start = low_hole; 4433 if (kernel_reserved + low_hole < aperture_size) {
4415 user_vma_limit = vm->va_limit - kernel_reserved; 4434 if (p->unify_address_spaces) {
4416 4435 user_vma_start = low_hole;
4436 user_vma_limit = vm->va_limit - kernel_reserved;
4437 user_lp_vma_start = user_vma_limit;
4438 user_lp_vma_limit = user_vma_limit;
4439 } else {
4440 user_vma_start = low_hole;
4441 user_vma_limit = __nv_gmmu_va_small_page_limit();
4442 user_lp_vma_start = __nv_gmmu_va_small_page_limit();
4443 user_lp_vma_limit = vm->va_limit - kernel_reserved;
4444 }
4445 } else {
4446 user_vma_start = 0;
4447 user_vma_limit = 0;
4448 user_lp_vma_start = 0;
4449 user_lp_vma_limit = 0;
4450 }
4417 kernel_vma_start = vm->va_limit - kernel_reserved; 4451 kernel_vma_start = vm->va_limit - kernel_reserved;
4418 kernel_vma_limit = vm->va_limit; 4452 kernel_vma_limit = vm->va_limit;
4419 4453
4420 gk20a_dbg_info( 4454 gk20a_dbg_info("user_vma [0x%llx,0x%llx)",
4421 "user_vma=[0x%llx,0x%llx) kernel_vma=[0x%llx,0x%llx)\n", 4455 user_vma_start, user_vma_limit);
4422 user_vma_start, user_vma_limit, 4456 gk20a_dbg_info("user_lp_vma [0x%llx,0x%llx)",
4423 kernel_vma_start, kernel_vma_limit); 4457 user_lp_vma_start, user_lp_vma_limit);
4458 gk20a_dbg_info("kernel_vma [0x%llx,0x%llx)",
4459 kernel_vma_start, kernel_vma_limit);
4460
4461 if (WARN_ON(user_vma_start > user_vma_limit) ||
4462 WARN_ON(user_lp_vma_start > user_lp_vma_limit) ||
4463 WARN_ON(kernel_vma_start >= kernel_vma_limit)) {
4464 err = -EINVAL;
4465 goto clean_up_page_tables;
4466 }
4424 4467
4425 WARN_ON(user_vma_start > user_vma_limit); 4468 kernel_vma_flags = (kernel_reserved + low_hole) == aperture_size ?
4426 WARN_ON(kernel_vma_start >= kernel_vma_limit); 4469 0 : GPU_ALLOC_GVA_SPACE;
4427 4470
4428 /* 4471 /*
4429 * A "user" area only makes sense for the GVA spaces. For VMs where 4472 * A "user" area only makes sense for the GVA spaces. For VMs where
@@ -4437,12 +4480,22 @@ int gk20a_init_vm(struct mm_gk20a *mm,
4437 goto clean_up_page_tables; 4480 goto clean_up_page_tables;
4438 } 4481 }
4439 4482
4483 /*
4484 * Determine if big pages are possible in this VM. If a split address
4485 * space is used then check the user_lp vma instead of the user vma.
4486 */
4487 if (p->unify_address_spaces)
4488 vm->big_pages = gk20a_big_pages_possible(vm, user_vma_start,
4489 user_vma_limit - user_vma_start);
4490 else
4491 vm->big_pages = gk20a_big_pages_possible(vm, user_lp_vma_start,
4492 user_lp_vma_limit - user_lp_vma_start);
4493
4494 /*
4495 * User VMA.
4496 */
4440 if (user_vma_start < user_vma_limit) { 4497 if (user_vma_start < user_vma_limit) {
4441 snprintf(alloc_name, sizeof(alloc_name), "gk20a_%s", name); 4498 snprintf(alloc_name, sizeof(alloc_name), "gk20a_%s", name);
4442 if (!gk20a_big_pages_possible(vm, user_vma_start,
4443 user_vma_limit - user_vma_start))
4444 vm->big_pages = false;
4445
4446 err = __nvgpu_buddy_allocator_init(g, &vm->user, 4499 err = __nvgpu_buddy_allocator_init(g, &vm->user,
4447 vm, alloc_name, 4500 vm, alloc_name,
4448 user_vma_start, 4501 user_vma_start,
@@ -4463,20 +4516,36 @@ int gk20a_init_vm(struct mm_gk20a *mm,
4463 vm->vma[1] = &vm->kernel; 4516 vm->vma[1] = &vm->kernel;
4464 } 4517 }
4465 4518
4466 snprintf(alloc_name, sizeof(alloc_name), "gk20a_%s-sys", name); 4519 /*
4467 if (!gk20a_big_pages_possible(vm, kernel_vma_start, 4520 * User VMA for large pages when a split address range is used.
4468 kernel_vma_limit - kernel_vma_start)) 4521 */
4469 vm->big_pages = false; 4522 if (user_lp_vma_start < user_lp_vma_limit) {
4523 snprintf(alloc_name, sizeof(alloc_name), "gk20a_%s_lp", name);
4524 err = __nvgpu_buddy_allocator_init(g, &vm->user_lp,
4525 vm, alloc_name,
4526 user_lp_vma_start,
4527 user_lp_vma_limit -
4528 user_lp_vma_start,
4529 vm->big_page_size,
4530 GPU_BALLOC_MAX_ORDER,
4531 GPU_ALLOC_GVA_SPACE);
4532 if (err)
4533 goto clean_up_allocators;
4534 }
4470 4535
4536 /*
4537 * Kernel VMA. Must always exist for an address space.
4538 */
4539 snprintf(alloc_name, sizeof(alloc_name), "gk20a_%s-sys", name);
4471 err = __nvgpu_buddy_allocator_init(g, &vm->kernel, 4540 err = __nvgpu_buddy_allocator_init(g, &vm->kernel,
4472 vm, alloc_name, 4541 vm, alloc_name,
4473 kernel_vma_start, 4542 kernel_vma_start,
4474 kernel_vma_limit - kernel_vma_start, 4543 kernel_vma_limit - kernel_vma_start,
4475 SZ_4K, 4544 SZ_4K,
4476 GPU_BALLOC_MAX_ORDER, 4545 GPU_BALLOC_MAX_ORDER,
4477 GPU_ALLOC_GVA_SPACE); 4546 kernel_vma_flags);
4478 if (err) 4547 if (err)
4479 goto clean_up_user_allocator; 4548 goto clean_up_allocators;
4480 4549
4481 vm->mapped_buffers = RB_ROOT; 4550 vm->mapped_buffers = RB_ROOT;
4482 4551
@@ -4492,14 +4561,18 @@ int gk20a_init_vm(struct mm_gk20a *mm,
4492 if (vm->va_limit > SZ_4G) { 4561 if (vm->va_limit > SZ_4G) {
4493 err = gk20a_init_sema_pool(vm); 4562 err = gk20a_init_sema_pool(vm);
4494 if (err) 4563 if (err)
4495 goto clean_up_user_allocator; 4564 goto clean_up_allocators;
4496 } 4565 }
4497 4566
4498 return 0; 4567 return 0;
4499 4568
4500clean_up_user_allocator: 4569clean_up_allocators:
4501 if (user_vma_start < user_vma_limit) 4570 if (nvgpu_alloc_initialized(&vm->kernel))
4571 nvgpu_alloc_destroy(&vm->kernel);
4572 if (nvgpu_alloc_initialized(&vm->user))
4502 nvgpu_alloc_destroy(&vm->user); 4573 nvgpu_alloc_destroy(&vm->user);
4574 if (nvgpu_alloc_initialized(&vm->user_lp))
4575 nvgpu_alloc_destroy(&vm->user_lp);
4503clean_up_page_tables: 4576clean_up_page_tables:
4504 /* Cleans up init_vm_page_tables() */ 4577 /* Cleans up init_vm_page_tables() */
4505 vfree(vm->pdb.entries); 4578 vfree(vm->pdb.entries);
@@ -4871,6 +4944,8 @@ void gk20a_deinit_vm(struct vm_gk20a *vm)
4871 nvgpu_alloc_destroy(&vm->kernel); 4944 nvgpu_alloc_destroy(&vm->kernel);
4872 if (nvgpu_alloc_initialized(&vm->user)) 4945 if (nvgpu_alloc_initialized(&vm->user))
4873 nvgpu_alloc_destroy(&vm->user); 4946 nvgpu_alloc_destroy(&vm->user);
4947 if (nvgpu_alloc_initialized(&vm->user_lp))
4948 nvgpu_alloc_destroy(&vm->user_lp);
4874 4949
4875 gk20a_vm_free_entries(vm, &vm->pdb, 0); 4950 gk20a_vm_free_entries(vm, &vm->pdb, 0);
4876} 4951}
@@ -5000,7 +5075,7 @@ static int gk20a_init_cde_vm(struct mm_gk20a *mm)
5000 u32 big_page_size = gk20a_get_platform(g->dev)->default_big_page_size; 5075 u32 big_page_size = gk20a_get_platform(g->dev)->default_big_page_size;
5001 5076
5002 return gk20a_init_vm(mm, vm, big_page_size, 5077 return gk20a_init_vm(mm, vm, big_page_size,
5003 SZ_4K * 16, 5078 big_page_size << 10,
5004 NV_MM_DEFAULT_KERNEL_SIZE, 5079 NV_MM_DEFAULT_KERNEL_SIZE,
5005 NV_MM_DEFAULT_KERNEL_SIZE + NV_MM_DEFAULT_USER_SIZE, 5080 NV_MM_DEFAULT_KERNEL_SIZE + NV_MM_DEFAULT_USER_SIZE,
5006 false, false, "cde"); 5081 false, false, "cde");
@@ -5013,7 +5088,7 @@ static int gk20a_init_ce_vm(struct mm_gk20a *mm)
5013 u32 big_page_size = gk20a_get_platform(g->dev)->default_big_page_size; 5088 u32 big_page_size = gk20a_get_platform(g->dev)->default_big_page_size;
5014 5089
5015 return gk20a_init_vm(mm, vm, big_page_size, 5090 return gk20a_init_vm(mm, vm, big_page_size,
5016 SZ_4K * 16, 5091 big_page_size << 10,
5017 NV_MM_DEFAULT_KERNEL_SIZE, 5092 NV_MM_DEFAULT_KERNEL_SIZE,
5018 NV_MM_DEFAULT_KERNEL_SIZE + NV_MM_DEFAULT_USER_SIZE, 5093 NV_MM_DEFAULT_KERNEL_SIZE + NV_MM_DEFAULT_USER_SIZE,
5019 false, false, "ce"); 5094 false, false, "ce");
diff --git a/drivers/gpu/nvgpu/gk20a/mm_gk20a.h b/drivers/gpu/nvgpu/gk20a/mm_gk20a.h
index f362e27c..665aea42 100644
--- a/drivers/gpu/nvgpu/gk20a/mm_gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/mm_gk20a.h
@@ -270,9 +270,16 @@ struct vm_gk20a {
270 270
271 struct gk20a_mm_entry pdb; 271 struct gk20a_mm_entry pdb;
272 272
273 /*
274 * These structs define the address spaces. In some cases it's possible
275 * to merge address spaces (user and user_lp) and in other cases it's
276 * not. vma[] allows the code to be agnostic to this by always using
277 * address spaces through this pointer array.
278 */
273 struct nvgpu_allocator *vma[gmmu_nr_page_sizes]; 279 struct nvgpu_allocator *vma[gmmu_nr_page_sizes];
274 struct nvgpu_allocator kernel; 280 struct nvgpu_allocator kernel;
275 struct nvgpu_allocator user; 281 struct nvgpu_allocator user;
282 struct nvgpu_allocator user_lp;
276 283
277 struct rb_root mapped_buffers; 284 struct rb_root mapped_buffers;
278 285
@@ -433,41 +440,19 @@ static inline int bar1_aperture_size_mb_gk20a(void)
433/* The default kernel-reserved GPU VA size */ 440/* The default kernel-reserved GPU VA size */
434#define NV_MM_DEFAULT_KERNEL_SIZE (1ULL << 32) 441#define NV_MM_DEFAULT_KERNEL_SIZE (1ULL << 32)
435 442
436enum gmmu_pgsz_gk20a __get_pte_size_fixed_map(struct vm_gk20a *vm,
437 u64 base, u64 size);
438
439/* 443/*
440 * This determines the PTE size for a given alloc. Used by both the GVA space 444 * When not using unified address spaces the bottom 16GB of the space are used
441 * allocator and the mm core code so that agreement can be reached on how to 445 * for small pages and the remaining high memory is used for large pages.
442 * map allocations.
443 *
444 * The page size of a buffer is this:
445 *
446 * o If the VM doesn't support large pages then obviously small pages
447 * must be used.
448 * o If the base address is non-zero (fixed address map):
449 * - Attempt to find a reserved memory area and use the page size
450 * based on that.
451 * - If no reserved page size is available, default to small pages.
452 * o If the base is zero:
453 * - If the size is greater than or equal to the big page size, use big
454 * pages.
455 * - Otherwise use small pages.
456 */ 446 */
457static inline enum gmmu_pgsz_gk20a __get_pte_size(struct vm_gk20a *vm, 447static inline u64 __nv_gmmu_va_small_page_limit(void)
458 u64 base, u64 size)
459{ 448{
460 if (!vm->big_pages) 449 return ((u64)SZ_1G * 16);
461 return gmmu_page_size_small;
462
463 if (base)
464 return __get_pte_size_fixed_map(vm, base, size);
465
466 if (size >= vm->gmmu_page_sizes[gmmu_page_size_big])
467 return gmmu_page_size_big;
468 return gmmu_page_size_small;
469} 450}
470 451
452enum gmmu_pgsz_gk20a __get_pte_size_fixed_map(struct vm_gk20a *vm,
453 u64 base, u64 size);
454enum gmmu_pgsz_gk20a __get_pte_size(struct vm_gk20a *vm, u64 base, u64 size);
455
471/* 456/*
472 * Buffer accessors - wrap between begin() and end() if there is no permanent 457 * Buffer accessors - wrap between begin() and end() if there is no permanent
473 * kernel mapping for this buffer. 458 * kernel mapping for this buffer.
diff --git a/drivers/gpu/nvgpu/gk20a/platform_gk20a.h b/drivers/gpu/nvgpu/gk20a/platform_gk20a.h
index e71dbf32..3c2db924 100644
--- a/drivers/gpu/nvgpu/gk20a/platform_gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/platform_gk20a.h
@@ -71,6 +71,9 @@ struct gk20a_platform {
71 /* set if ASPM should be disabled on boot; only makes sense for PCI */ 71 /* set if ASPM should be disabled on boot; only makes sense for PCI */
72 bool disable_aspm; 72 bool disable_aspm;
73 73
74 /* Set if the platform can unify the small/large address spaces. */
75 bool unify_address_spaces;
76
74 /* Should be populated by probe. */ 77 /* Should be populated by probe. */
75 struct dentry *debugfs; 78 struct dentry *debugfs;
76 struct dentry *debugfs_alias; 79 struct dentry *debugfs_alias;