drm/nouveau/mmu/gk104,gk20a: implement new vmm backend
authorBen Skeggs <bskeggs@redhat.com>
Tue, 31 Oct 2017 17:56:19 +0000 (03:56 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Thu, 2 Nov 2017 03:32:29 +0000 (13:32 +1000)
Adds support for:
- 64KiB big page size.
- System-memory PTs.
- LPTE "invalid" state.
- (Tegra) Use of video memory aperture.

Adds support for marking LPTEs invalid, resulting in the corresponding
SPTEs being ignored, which is supposed to speed up TLB invalidates.

On The Tegra side, this will switch to using the video memory aperture
for all mappings.  The HW will still target non-coherent system memory,
but this aperture needs to be selected in order to support compression.

Tegra's instmem backend somewhat cheated to get this effect previously.

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk104.c
drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk20a.c
drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h
drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgk104.c
drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgk20a.c

index 693aa1b875f2881a58b3bce50390efc9e15782cb..8cbd0723c25b6797b6b8e1039cec2485607ef578 100644 (file)
@@ -30,12 +30,8 @@ gk104_mmu = {
        .pgt_bits  = 27 - 12,
        .spg_shift = 12,
        .lpg_shift = 17,
-       .map_pgt = gf100_vm_map_pgt,
-       .map = gf100_vm_map,
-       .map_sg = gf100_vm_map_sg,
-       .unmap = gf100_vm_unmap,
-       .flush = gf100_vm_flush,
        .vmm = {{ -1, -1, NVIF_CLASS_VMM_GF100}, gk104_vmm_new },
+       .kind = gf100_mmu_kind,
 };
 
 int
index b774d9a25c3e87630eddb302052014932b103205..57def7244d38513adddde8b7119a1078e5092cd1 100644 (file)
@@ -30,12 +30,8 @@ gk20a_mmu = {
        .pgt_bits  = 27 - 12,
        .spg_shift = 12,
        .lpg_shift = 17,
-       .map_pgt = gf100_vm_map_pgt,
-       .map = gf100_vm_map,
-       .map_sg = gf100_vm_map_sg,
-       .unmap = gf100_vm_unmap,
-       .flush = gf100_vm_flush,
        .vmm = {{ -1, -1, NVIF_CLASS_VMM_GF100}, gk20a_vmm_new },
+       .kind = gf100_mmu_kind,
 };
 
 int
index dfc4b46129bdc564e04ece424878ab1854aadd6b..75f6429001405340b70df9dd00c311d2027c742f 100644 (file)
@@ -80,6 +80,8 @@ void gf100_vmm_pgt_dma(struct nvkm_vmm *, struct nvkm_mmu_pt *, u32, u32,
 void gf100_vmm_pgt_sgl(struct nvkm_vmm *, struct nvkm_mmu_pt *, u32, u32,
                       struct nvkm_vmm_map *);
 
+void gk104_vmm_lpt_invalid(struct nvkm_vmm *, struct nvkm_mmu_pt *, u32, u32);
+
 struct nvkm_vmm_desc {
        enum {
                PGD,
@@ -178,6 +180,8 @@ int gf100_vmm_valid(struct nvkm_vmm *, void *, u32, struct nvkm_vmm_map *);
 void gf100_vmm_flush_(struct nvkm_vmm *, int);
 void gf100_vmm_flush(struct nvkm_vmm *, int);
 
+int gk20a_vmm_aper(enum nvkm_memory_target);
+
 int gm200_vmm_new_(const struct nvkm_vmm_func *, const struct nvkm_vmm_func *,
                   struct nvkm_mmu *, u64, u64, void *, u32,
                   struct lock_class_key *, const char *, struct nvkm_vmm **);
index 0d33700e3d88ef8b5bc3f870fc46189fd6f65f16..0ebb7bccfcd22c386118df7e45edd4571044c1d4 100644 (file)
  */
 #include "vmm.h"
 
+void
+gk104_vmm_lpt_invalid(struct nvkm_vmm *vmm,
+                     struct nvkm_mmu_pt *pt, u32 ptei, u32 ptes)
+{
+       /* VALID_FALSE + PRIV tells the MMU to ignore corresponding SPTEs. */
+       VMM_FO064(pt, vmm, ptei * 8, BIT_ULL(1) /* PRIV. */, ptes);
+}
+
 static const struct nvkm_vmm_desc_func
 gk104_vmm_lpt = {
+       .invalid = gk104_vmm_lpt_invalid,
+       .unmap = gf100_vmm_pgt_unmap,
+       .mem = gf100_vmm_pgt_mem,
 };
 
 const struct nvkm_vmm_desc
@@ -57,6 +68,9 @@ static const struct nvkm_vmm_func
 gk104_vmm_17 = {
        .join = gf100_vmm_join,
        .part = gf100_vmm_part,
+       .aper = gf100_vmm_aper,
+       .valid = gf100_vmm_valid,
+       .flush = gf100_vmm_flush,
        .page = {
                { 17, &gk104_vmm_desc_17_17[0], NVKM_VMM_PAGE_xVxC },
                { 12, &gk104_vmm_desc_17_12[0], NVKM_VMM_PAGE_xVHx },
@@ -68,6 +82,9 @@ static const struct nvkm_vmm_func
 gk104_vmm_16 = {
        .join = gf100_vmm_join,
        .part = gf100_vmm_part,
+       .aper = gf100_vmm_aper,
+       .valid = gf100_vmm_valid,
+       .flush = gf100_vmm_flush,
        .page = {
                { 16, &gk104_vmm_desc_16_16[0], NVKM_VMM_PAGE_xVxC },
                { 12, &gk104_vmm_desc_16_12[0], NVKM_VMM_PAGE_xVHx },
index e000c3d1554aeaec481595a5671d9c58e40a1c17..8086994a0446164c38feb56a20c57708f4866c3b 100644 (file)
  */
 #include "vmm.h"
 
+#include <core/memory.h>
+
+int
+gk20a_vmm_aper(enum nvkm_memory_target target)
+{
+       switch (target) {
+       case NVKM_MEM_TARGET_NCOH: return 0;
+       default:
+               return -EINVAL;
+       }
+}
+
 static const struct nvkm_vmm_func
 gk20a_vmm_17 = {
        .join = gf100_vmm_join,
        .part = gf100_vmm_part,
+       .aper = gf100_vmm_aper,
+       .valid = gf100_vmm_valid,
+       .flush = gf100_vmm_flush,
        .page = {
                { 17, &gk104_vmm_desc_17_17[0], NVKM_VMM_PAGE_xxHC },
                { 12, &gk104_vmm_desc_17_12[0], NVKM_VMM_PAGE_xxHx },
@@ -36,6 +51,9 @@ static const struct nvkm_vmm_func
 gk20a_vmm_16 = {
        .join = gf100_vmm_join,
        .part = gf100_vmm_part,
+       .aper = gf100_vmm_aper,
+       .valid = gf100_vmm_valid,
+       .flush = gf100_vmm_flush,
        .page = {
                { 16, &gk104_vmm_desc_16_16[0], NVKM_VMM_PAGE_xxHC },
                { 12, &gk104_vmm_desc_16_12[0], NVKM_VMM_PAGE_xxHx },