[Nouveau] [PATCH] drm/nouveau: Add correct turing page kinds

Ben Skeggs skeggsb at gmail.com
Mon Jan 6 01:16:59 UTC 2020


On Tue, 17 Dec 2019 at 10:57, James Jones <jajones at nvidia.com> wrote:
>
> Turing introduced a new simplified page kind
> scheme, reducing the number of possible page
> kinds from 256 to 16.  It also is the first
> NVIDIA GPU in which the highest possible page
> kind value is not reserved as an "invalid" page
> kind.
>
> To address this, the invalid page kind is made
> an explicit property of the MMU HAL, and a new
> table of page kinds is added to the tu102 MMU
> HAL.
>
> One hardware change not addressed here is that
> 0x00 is technically no longer a supported page
> kind, and pitch surfaces are instead intended to
> share the block-linear generic page kind 0x06.
> However, because that will be a rather invasive
> change to nouveau and 0x00 still works fine in
> practice on Turing hardware, addressing this new
> behavior is deferred.
Thanks James, I've merged this and the BO move fix into my tree.

>
> Signed-off-by: James Jones <jajones at nvidia.com>
> ---
>  drivers/gpu/drm/nouveau/include/nvif/if0008.h    |  2 +-
>  drivers/gpu/drm/nouveau/include/nvif/mmu.h       |  4 ++--
>  drivers/gpu/drm/nouveau/nvif/mmu.c               |  1 +
>  drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gf100.c  |  3 ++-
>  drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm200.c  |  3 ++-
>  drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv50.c   |  3 ++-
>  drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h   |  8 ++++----
>  drivers/gpu/drm/nouveau/nvkm/subdev/mmu/tu102.c  | 16 +++++++++++++++-
>  drivers/gpu/drm/nouveau/nvkm/subdev/mmu/ummu.c   |  7 +++++--
>  .../gpu/drm/nouveau/nvkm/subdev/mmu/vmmgf100.c   |  6 +++---
>  .../gpu/drm/nouveau/nvkm/subdev/mmu/vmmgp100.c   |  6 +++---
>  .../gpu/drm/nouveau/nvkm/subdev/mmu/vmmnv50.c    |  6 +++---
>  12 files changed, 43 insertions(+), 22 deletions(-)
>
> diff --git a/drivers/gpu/drm/nouveau/include/nvif/if0008.h b/drivers/gpu/drm/nouveau/include/nvif/if0008.h
> index 8450127420f5..c21d09f04f1d 100644
> --- a/drivers/gpu/drm/nouveau/include/nvif/if0008.h
> +++ b/drivers/gpu/drm/nouveau/include/nvif/if0008.h
> @@ -35,7 +35,7 @@ struct nvif_mmu_type_v0 {
>
>  struct nvif_mmu_kind_v0 {
>         __u8  version;
> -       __u8  pad01[1];
> +       __u8  kind_inv;
>         __u16 count;
>         __u8  data[];
>  };
> diff --git a/drivers/gpu/drm/nouveau/include/nvif/mmu.h b/drivers/gpu/drm/nouveau/include/nvif/mmu.h
> index 747ecf67e403..cec1e88a0a05 100644
> --- a/drivers/gpu/drm/nouveau/include/nvif/mmu.h
> +++ b/drivers/gpu/drm/nouveau/include/nvif/mmu.h
> @@ -7,6 +7,7 @@ struct nvif_mmu {
>         u8  dmabits;
>         u8  heap_nr;
>         u8  type_nr;
> +       u8  kind_inv;
>         u16 kind_nr;
>         s32 mem;
>
> @@ -36,9 +37,8 @@ void nvif_mmu_fini(struct nvif_mmu *);
>  static inline bool
>  nvif_mmu_kind_valid(struct nvif_mmu *mmu, u8 kind)
>  {
> -       const u8 invalid = mmu->kind_nr - 1;
>         if (kind) {
> -               if (kind >= mmu->kind_nr || mmu->kind[kind] == invalid)
> +               if (kind >= mmu->kind_nr || mmu->kind[kind] == mmu->kind_inv)
>                         return false;
>         }
>         return true;
> diff --git a/drivers/gpu/drm/nouveau/nvif/mmu.c b/drivers/gpu/drm/nouveau/nvif/mmu.c
> index 5641bda2046d..47efc408efa6 100644
> --- a/drivers/gpu/drm/nouveau/nvif/mmu.c
> +++ b/drivers/gpu/drm/nouveau/nvif/mmu.c
> @@ -121,6 +121,7 @@ nvif_mmu_init(struct nvif_object *parent, s32 oclass, struct nvif_mmu *mmu)
>                                        kind, argc);
>                 if (ret == 0)
>                         memcpy(mmu->kind, kind->data, kind->count);
> +               mmu->kind_inv = kind->kind_inv;
>                 kfree(kind);
>         }
>
> diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gf100.c
> index 2d075246dc46..2cd5ec81c0d0 100644
> --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gf100.c
> +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gf100.c
> @@ -30,7 +30,7 @@
>   * The value 0xff represents an invalid storage type.
>   */
>  const u8 *
> -gf100_mmu_kind(struct nvkm_mmu *mmu, int *count)
> +gf100_mmu_kind(struct nvkm_mmu *mmu, int *count, u8 *invalid)
>  {
>         static const u8
>         kind[256] = {
> @@ -69,6 +69,7 @@ gf100_mmu_kind(struct nvkm_mmu *mmu, int *count)
>         };
>
>         *count = ARRAY_SIZE(kind);
> +       *invalid = 0xff;
>         return kind;
>  }
>
> diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm200.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm200.c
> index dbf644ebac97..83990c83f9f8 100644
> --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm200.c
> +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm200.c
> @@ -27,7 +27,7 @@
>  #include <nvif/class.h>
>
>  const u8 *
> -gm200_mmu_kind(struct nvkm_mmu *mmu, int *count)
> +gm200_mmu_kind(struct nvkm_mmu *mmu, int *count, u8 *invalid)
>  {
>         static const u8
>         kind[256] = {
> @@ -65,6 +65,7 @@ gm200_mmu_kind(struct nvkm_mmu *mmu, int *count)
>                 0xfe, 0xfe, 0xfe, 0xfe, 0xff, 0xfd, 0xfe, 0xff
>         };
>         *count = ARRAY_SIZE(kind);
> +       *invalid = 0xff;
>         return kind;
>  }
>
> diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv50.c
> index db3dfbbb2aa0..c0083ddda65a 100644
> --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv50.c
> +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv50.c
> @@ -27,7 +27,7 @@
>  #include <nvif/class.h>
>
>  const u8 *
> -nv50_mmu_kind(struct nvkm_mmu *base, int *count)
> +nv50_mmu_kind(struct nvkm_mmu *base, int *count, u8 *invalid)
>  {
>         /* 0x01: no bank swizzle
>          * 0x02: bank swizzled
> @@ -57,6 +57,7 @@ nv50_mmu_kind(struct nvkm_mmu *base, int *count)
>                 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x7f, 0x7f
>         };
>         *count = ARRAY_SIZE(kind);
> +       *invalid = 0x7f;
>         return kind;
>  }
>
> diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h
> index 07f2fcd18f3d..479b02344271 100644
> --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h
> +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h
> @@ -35,17 +35,17 @@ struct nvkm_mmu_func {
>                 u32 pd_offset;
>         } vmm;
>
> -       const u8 *(*kind)(struct nvkm_mmu *, int *count);
> +       const u8 *(*kind)(struct nvkm_mmu *, int *count, u8 *invalid);
>         bool kind_sys;
>  };
>
>  extern const struct nvkm_mmu_func nv04_mmu;
>
> -const u8 *nv50_mmu_kind(struct nvkm_mmu *, int *count);
> +const u8 *nv50_mmu_kind(struct nvkm_mmu *, int *count, u8 *invalid);
>
> -const u8 *gf100_mmu_kind(struct nvkm_mmu *, int *count);
> +const u8 *gf100_mmu_kind(struct nvkm_mmu *, int *count, u8 *invalid);
>
> -const u8 *gm200_mmu_kind(struct nvkm_mmu *, int *);
> +const u8 *gm200_mmu_kind(struct nvkm_mmu *, int *, u8 *);
>
>  struct nvkm_mmu_pt {
>         union {
> diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/tu102.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/tu102.c
> index c0db0ce10cba..b21e82eb0916 100644
> --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/tu102.c
> +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/tu102.c
> @@ -1,5 +1,6 @@
>  /*
>   * Copyright 2018 Red Hat Inc.
> + * Copyright 2019 NVIDIA Corporation.
>   *
>   * Permission is hereby granted, free of charge, to any person obtaining a
>   * copy of this software and associated documentation files (the "Software"),
> @@ -26,13 +27,26 @@
>
>  #include <nvif/class.h>
>
> +const u8 *
> +tu102_mmu_kind(struct nvkm_mmu *mmu, int *count, u8 *invalid)
> +{
> +       static const u8
> +       kind[16] = {
> +               0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00 */
> +               0x06, 0x06, 0x02, 0x01, 0x03, 0x04, 0x05, 0x07,
> +       };
> +       *count = ARRAY_SIZE(kind);
> +       *invalid = 0x07;
> +       return kind;
> +}
> +
>  static const struct nvkm_mmu_func
>  tu102_mmu = {
>         .dma_bits = 47,
>         .mmu = {{ -1, -1, NVIF_CLASS_MMU_GF100}},
>         .mem = {{ -1,  0, NVIF_CLASS_MEM_GF100}, gf100_mem_new, gf100_mem_map },
>         .vmm = {{ -1,  0, NVIF_CLASS_VMM_GP100}, tu102_vmm_new },
> -       .kind = gm200_mmu_kind,
> +       .kind = tu102_mmu_kind,
>         .kind_sys = true,
>  };
>
> diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/ummu.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/ummu.c
> index 353f10f92b77..0e4b8941da37 100644
> --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/ummu.c
> +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/ummu.c
> @@ -111,15 +111,17 @@ nvkm_ummu_kind(struct nvkm_ummu *ummu, void *argv, u32 argc)
>         } *args = argv;
>         const u8 *kind = NULL;
>         int ret = -ENOSYS, count = 0;
> +       u8 kind_inv = 0;
>
>         if (mmu->func->kind)
> -               kind = mmu->func->kind(mmu, &count);
> +               kind = mmu->func->kind(mmu, &count, &kind_inv);
>
>         if (!(ret = nvif_unpack(ret, &argv, &argc, args->v0, 0, 0, true))) {
>                 if (argc != args->v0.count * sizeof(*args->v0.data))
>                         return -EINVAL;
>                 if (args->v0.count > count)
>                         return -EINVAL;
> +               args->v0.kind_inv = kind_inv;
>                 memcpy(args->v0.data, kind, args->v0.count);
>         } else
>                 return ret;
> @@ -157,9 +159,10 @@ nvkm_ummu_new(struct nvkm_device *device, const struct nvkm_oclass *oclass,
>         struct nvkm_mmu *mmu = device->mmu;
>         struct nvkm_ummu *ummu;
>         int ret = -ENOSYS, kinds = 0;
> +       u8 unused = 0;
>
>         if (mmu->func->kind)
> -               mmu->func->kind(mmu, &kinds);
> +               mmu->func->kind(mmu, &kinds, &unused);
>
>         if (!(ret = nvif_unpack(ret, &argv, &argc, args->v0, 0, 0, false))) {
>                 args->v0.dmabits = mmu->dma_bits;
> diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgf100.c
> index ab6424faf84c..6a2d9eb8e1ea 100644
> --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgf100.c
> +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgf100.c
> @@ -247,7 +247,7 @@ gf100_vmm_valid(struct nvkm_vmm *vmm, void *argv, u32 argc,
>         } *args = argv;
>         struct nvkm_device *device = vmm->mmu->subdev.device;
>         struct nvkm_memory *memory = map->memory;
> -       u8  kind, priv, ro, vol;
> +       u8  kind, kind_inv, priv, ro, vol;
>         int kindn, aper, ret = -ENOSYS;
>         const u8 *kindm;
>
> @@ -274,8 +274,8 @@ gf100_vmm_valid(struct nvkm_vmm *vmm, void *argv, u32 argc,
>         if (WARN_ON(aper < 0))
>                 return aper;
>
> -       kindm = vmm->mmu->func->kind(vmm->mmu, &kindn);
> -       if (kind >= kindn || kindm[kind] == 0xff) {
> +       kindm = vmm->mmu->func->kind(vmm->mmu, &kindn, &kind_inv);
> +       if (kind >= kindn || kindm[kind] == kind_inv) {
>                 VMM_DEBUG(vmm, "kind %02x", kind);
>                 return -EINVAL;
>         }
> diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgp100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgp100.c
> index b4f519768d5e..d86287565542 100644
> --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgp100.c
> +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgp100.c
> @@ -320,7 +320,7 @@ gp100_vmm_valid(struct nvkm_vmm *vmm, void *argv, u32 argc,
>         } *args = argv;
>         struct nvkm_device *device = vmm->mmu->subdev.device;
>         struct nvkm_memory *memory = map->memory;
> -       u8  kind, priv, ro, vol;
> +       u8  kind, kind_inv, priv, ro, vol;
>         int kindn, aper, ret = -ENOSYS;
>         const u8 *kindm;
>
> @@ -347,8 +347,8 @@ gp100_vmm_valid(struct nvkm_vmm *vmm, void *argv, u32 argc,
>         if (WARN_ON(aper < 0))
>                 return aper;
>
> -       kindm = vmm->mmu->func->kind(vmm->mmu, &kindn);
> -       if (kind >= kindn || kindm[kind] == 0xff) {
> +       kindm = vmm->mmu->func->kind(vmm->mmu, &kindn, &kind_inv);
> +       if (kind >= kindn || kindm[kind] == kind_inv) {
>                 VMM_DEBUG(vmm, "kind %02x", kind);
>                 return -EINVAL;
>         }
> diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmnv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmnv50.c
> index c98afe3134ee..2d89e27e8e9e 100644
> --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmnv50.c
> +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmnv50.c
> @@ -235,7 +235,7 @@ nv50_vmm_valid(struct nvkm_vmm *vmm, void *argv, u32 argc,
>         struct nvkm_device *device = vmm->mmu->subdev.device;
>         struct nvkm_ram *ram = device->fb->ram;
>         struct nvkm_memory *memory = map->memory;
> -       u8  aper, kind, comp, priv, ro;
> +       u8  aper, kind, kind_inv, comp, priv, ro;
>         int kindn, ret = -ENOSYS;
>         const u8 *kindm;
>
> @@ -278,8 +278,8 @@ nv50_vmm_valid(struct nvkm_vmm *vmm, void *argv, u32 argc,
>                 return -EINVAL;
>         }
>
> -       kindm = vmm->mmu->func->kind(vmm->mmu, &kindn);
> -       if (kind >= kindn || kindm[kind] == 0x7f) {
> +       kindm = vmm->mmu->func->kind(vmm->mmu, &kindn, &kind_inv);
> +       if (kind >= kindn || kindm[kind] == kind_inv) {
>                 VMM_DEBUG(vmm, "kind %02x", kind);
>                 return -EINVAL;
>         }
> --
> 2.17.1
>
> _______________________________________________
> Nouveau mailing list
> Nouveau at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/nouveau


More information about the dri-devel mailing list