]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
drm/nouveau/fb/tu102-: prepare for GSP-RM
authorBen Skeggs <bskeggs@redhat.com>
Mon, 18 Sep 2023 20:21:15 +0000 (06:21 +1000)
committerDave Airlie <airlied@redhat.com>
Tue, 31 Oct 2023 05:08:11 +0000 (15:08 +1000)
- add (initial) R535 implementation of FB, need VRAM size etc for boot
- expose a way to "wrap" vram at a specific address/size as a standard
  nvkm_memory allocation, which will be used to write PTEs etc for RM-
  defined memory regions

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20230918202149.4343-11-skeggsb@gmail.com
drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h
drivers/gpu/drm/nouveau/nvkm/subdev/fb/Kbuild
drivers/gpu/drm/nouveau/nvkm/subdev/fb/ga100.c
drivers/gpu/drm/nouveau/nvkm/subdev/fb/ga102.c
drivers/gpu/drm/nouveau/nvkm/subdev/fb/priv.h
drivers/gpu/drm/nouveau/nvkm/subdev/fb/r535.c [new file with mode: 0644]
drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.c
drivers/gpu/drm/nouveau/nvkm/subdev/fb/tu102.c

index 1755b0df3cc1db62a8bb967bc88aebf52420b16c..5b798a1a313d8f80bc8d040088942e087e549695 100644 (file)
@@ -158,9 +158,9 @@ struct nvkm_ram {
        struct nvkm_ram_data target;
 };
 
-int
-nvkm_ram_get(struct nvkm_device *, u8 heap, u8 type, u8 page, u64 size,
-            bool contig, bool back, struct nvkm_memory **);
+int nvkm_ram_wrap(struct nvkm_device *, u64 addr, u64 size, struct nvkm_memory **);
+int nvkm_ram_get(struct nvkm_device *, u8 heap, u8 type, u8 page, u64 size,
+                bool contig, bool back, struct nvkm_memory **);
 
 struct nvkm_ram_func {
        u64 upper;
index 394c305e759ad8f008e2e0fa784a03f9aa9851c6..d1611ad3bf81c5155ac60046e989ade88e5f954f 100644 (file)
@@ -36,6 +36,8 @@ nvkm-y += nvkm/subdev/fb/tu102.o
 nvkm-y += nvkm/subdev/fb/ga100.o
 nvkm-y += nvkm/subdev/fb/ga102.o
 
+nvkm-y += nvkm/subdev/fb/r535.o
+
 nvkm-y += nvkm/subdev/fb/ram.o
 nvkm-y += nvkm/subdev/fb/ramnv04.o
 nvkm-y += nvkm/subdev/fb/ramnv10.o
index 12037fd4fdf27fd708c345700b7a297448fae4e9..e9e7c1d5c4c427f404037cea934904c46e19522e 100644 (file)
@@ -22,6 +22,8 @@
 #include "gf100.h"
 #include "ram.h"
 
+#include <subdev/gsp.h>
+
 static const struct nvkm_fb_func
 ga100_fb = {
        .dtor = gf100_fb_dtor,
@@ -38,5 +40,8 @@ ga100_fb = {
 int
 ga100_fb_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct nvkm_fb **pfb)
 {
+       if (nvkm_gsp_rm(device->gsp))
+               return r535_fb_new(&ga100_fb, device, type, inst, pfb);
+
        return gf100_fb_new_(&ga100_fb, device, type, inst, pfb);
 }
index 76f6877b54c6f239cca61ebaef114d1b882c7e64..25f82b372bcab23e5528b0c34330adec0baa5e45 100644 (file)
@@ -22,6 +22,7 @@
 #include "gf100.h"
 #include "ram.h"
 
+#include <subdev/gsp.h>
 #include <engine/nvdec.h>
 
 static u64
@@ -59,6 +60,9 @@ ga102_fb = {
 int
 ga102_fb_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct nvkm_fb **pfb)
 {
+       if (nvkm_gsp_rm(device->gsp))
+               return r535_fb_new(&ga102_fb, device, type, inst, pfb);
+
        return gf100_fb_new_(&ga102_fb, device, type, inst, pfb);
 }
 
index 77d6a8c108298c78f4c6082ca4c2a2c65fa247b4..35c55dfba23d94725959324d30c93b960f36909a 100644 (file)
@@ -6,6 +6,9 @@
 #include <subdev/therm.h>
 struct nvkm_bios;
 
+int r535_fb_new(const struct nvkm_fb_func *,
+               struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fb **);
+
 struct nvkm_fb_func {
        void *(*dtor)(struct nvkm_fb *);
        u32 (*tags)(struct nvkm_fb *);
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/r535.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/r535.c
new file mode 100644 (file)
index 0000000..0c30188
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2023 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include "priv.h"
+
+static void *
+r535_fb_dtor(struct nvkm_fb *fb)
+{
+       kfree(fb->func);
+       return fb;
+}
+
+int
+r535_fb_new(const struct nvkm_fb_func *hw,
+           struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct nvkm_fb **pfb)
+{
+       struct nvkm_fb_func *rm;
+       int ret;
+
+       if (!(rm = kzalloc(sizeof(*rm), GFP_KERNEL)))
+               return -ENOMEM;
+
+       rm->dtor = r535_fb_dtor;
+       rm->sysmem.flush_page_init = hw->sysmem.flush_page_init;
+       rm->vidmem.size = hw->vidmem.size;
+
+       ret = nvkm_fb_new_(rm, device, type, inst, pfb);
+       if (ret)
+               kfree(rm);
+
+       return ret;
+}
index 5c34416cb637951a4bc420d75f145813172028d6..c826980bf70ee1c67ef0e58905e3bba55860d0dc 100644 (file)
@@ -88,12 +88,20 @@ nvkm_vram_dtor(struct nvkm_memory *memory)
        struct nvkm_vram *vram = nvkm_vram(memory);
        struct nvkm_mm_node *next = vram->mn;
        struct nvkm_mm_node *node;
-       mutex_lock(&vram->ram->mutex);
-       while ((node = next)) {
-               next = node->next;
-               nvkm_mm_free(&vram->ram->vram, &node);
+
+       if (next) {
+               if (likely(next->nl_entry.next)){
+                       mutex_lock(&vram->ram->mutex);
+                       while ((node = next)) {
+                               next = node->next;
+                               nvkm_mm_free(&vram->ram->vram, &node);
+                       }
+                       mutex_unlock(&vram->ram->mutex);
+               } else {
+                       kfree(vram->mn);
+               }
        }
-       mutex_unlock(&vram->ram->mutex);
+
        return vram;
 }
 
@@ -108,6 +116,34 @@ nvkm_vram = {
        .kmap = nvkm_vram_kmap,
 };
 
+int
+nvkm_ram_wrap(struct nvkm_device *device, u64 addr, u64 size,
+             struct nvkm_memory **pmemory)
+{
+       struct nvkm_ram *ram;
+       struct nvkm_vram *vram;
+
+       if (!device->fb || !(ram = device->fb->ram))
+               return -ENODEV;
+       ram = device->fb->ram;
+
+       if (!(vram = kzalloc(sizeof(*vram), GFP_KERNEL)))
+               return -ENOMEM;
+
+       nvkm_memory_ctor(&nvkm_vram, &vram->memory);
+       vram->ram = ram;
+       vram->page = NVKM_RAM_MM_SHIFT;
+       *pmemory = &vram->memory;
+
+       vram->mn = kzalloc(sizeof(*vram->mn), GFP_KERNEL);
+       if (!vram->mn)
+               return -ENOMEM;
+
+       vram->mn->offset = addr >> NVKM_RAM_MM_SHIFT;
+       vram->mn->length = size >> NVKM_RAM_MM_SHIFT;
+       return 0;
+}
+
 int
 nvkm_ram_get(struct nvkm_device *device, u8 heap, u8 type, u8 rpage, u64 size,
             bool contig, bool back, struct nvkm_memory **pmemory)
index bcc23d4c8115d1d6b44c0dc1776ce5bdaeb3bf6f..f7d2a749ce3fe9dd6174a7b5784bab231aea3830 100644 (file)
@@ -22,6 +22,8 @@
 #include "gf100.h"
 #include "ram.h"
 
+#include <subdev/gsp.h>
+
 bool
 tu102_fb_vpr_scrub_required(struct nvkm_fb *fb)
 {
@@ -46,6 +48,9 @@ tu102_fb = {
 int
 tu102_fb_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct nvkm_fb **pfb)
 {
+       if (nvkm_gsp_rm(device->gsp))
+               return r535_fb_new(&tu102_fb, device, type, inst, pfb);
+
        return gf100_fb_new_(&tu102_fb, device, type, inst, pfb);
 }