diff --git a/drivers/gpu/nvgpu/common/mm/mm.c b/drivers/gpu/nvgpu/common/mm/mm.c index 0608d66ab..2e46e211c 100644 --- a/drivers/gpu/nvgpu/common/mm/mm.c +++ b/drivers/gpu/nvgpu/common/mm/mm.c @@ -202,13 +202,21 @@ static int nvgpu_init_system_vm(struct mm_gk20a *mm) struct gk20a *g = gk20a_from_mm(mm); struct nvgpu_mem *inst_block = &mm->pmu.inst_block; u32 big_page_size = g->ops.mm.get_default_big_page_size(); - u32 low_hole, aperture_size; + u64 low_hole, aperture_size; + + /* + * For some reason the maxwell PMU code is dependent on the large page + * size. No reason AFAICT for this. Probably a bug somewhere. + */ + if (nvgpu_is_enabled(g, NVGPU_MM_FORCE_128K_PMU_VM)) { + big_page_size = SZ_128K; + } /* * No user region - so we will pass that as zero sized. */ - low_hole = SZ_4K * 16; - aperture_size = GK20A_PMU_VA_SIZE * 2; + low_hole = SZ_4K * 16UL; + aperture_size = GK20A_PMU_VA_SIZE; mm->pmu.aperture_size = GK20A_PMU_VA_SIZE; nvgpu_log_info(g, "pmu vm size = 0x%x", mm->pmu.aperture_size); diff --git a/drivers/gpu/nvgpu/include/nvgpu/enabled.h b/drivers/gpu/nvgpu/include/nvgpu/enabled.h index c0fb9218d..a0b738e0b 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/enabled.h +++ b/drivers/gpu/nvgpu/include/nvgpu/enabled.h @@ -81,6 +81,8 @@ struct gk20a; #define NVGPU_USE_COHERENT_SYSMEM 26 /* Use physical scatter tables instead of IOMMU */ #define NVGPU_MM_USE_PHYSICAL_SG 27 +/* WAR for gm20b chips. */ +#define NVGPU_MM_FORCE_128K_PMU_VM 28 /* * Host flags diff --git a/drivers/gpu/nvgpu/os/linux/driver_common.c b/drivers/gpu/nvgpu/os/linux/driver_common.c index c651e3949..f1eccd06a 100644 --- a/drivers/gpu/nvgpu/os/linux/driver_common.c +++ b/drivers/gpu/nvgpu/os/linux/driver_common.c @@ -215,6 +215,8 @@ static void nvgpu_init_mm_vars(struct gk20a *g) platform->unified_memory); __nvgpu_set_enabled(g, NVGPU_MM_UNIFY_ADDRESS_SPACES, platform->unify_address_spaces); + __nvgpu_set_enabled(g, NVGPU_MM_FORCE_128K_PMU_VM, + platform->force_128K_pmu_vm); nvgpu_mutex_init(&g->mm.tlb_lock); nvgpu_mutex_init(&g->mm.priv_lock); diff --git a/drivers/gpu/nvgpu/os/linux/platform_gk20a.h b/drivers/gpu/nvgpu/os/linux/platform_gk20a.h index a4c3eca3a..f3e80b8c4 100644 --- a/drivers/gpu/nvgpu/os/linux/platform_gk20a.h +++ b/drivers/gpu/nvgpu/os/linux/platform_gk20a.h @@ -244,6 +244,8 @@ struct gk20a_platform { bool honors_aperture; /* unified or split memory with separate vidmem? */ bool unified_memory; + /* WAR for gm20b chips. */ + bool force_128K_pmu_vm; /* * DMA mask for Linux (both coh and non-coh). If not set defaults to diff --git a/drivers/gpu/nvgpu/os/linux/platform_gk20a_tegra.c b/drivers/gpu/nvgpu/os/linux/platform_gk20a_tegra.c index 432af1084..033563dc5 100644 --- a/drivers/gpu/nvgpu/os/linux/platform_gk20a_tegra.c +++ b/drivers/gpu/nvgpu/os/linux/platform_gk20a_tegra.c @@ -952,6 +952,7 @@ struct gk20a_platform gm20b_tegra_platform = { .unified_memory = true, .dma_mask = DMA_BIT_MASK(34), + .force_128K_pmu_vm = true, .secure_buffer_size = 335872, };