OSDN Git Service

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 693aa1b..8cbd072 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 b774d9a..57def72 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 dfc4b46..75f6429 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 0d33700..0ebb7bc 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 e000c3d..8086994 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 },