diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-18 17:40:19 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-18 17:40:19 +0000 |
commit | 9f0fc191371843c4fc000a226b0a26b6c059aacd (patch) | |
tree | 35f8be3ef04506ac891ad001e8c41e535ae8d01d /drivers/gpu/drm/nouveau/include/nvkm/subdev | |
parent | Releasing progress-linux version 6.6.15-2~progress7.99u1. (diff) | |
download | linux-9f0fc191371843c4fc000a226b0a26b6c059aacd.tar.xz linux-9f0fc191371843c4fc000a226b0a26b6c059aacd.zip |
Merging upstream version 6.7.7.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'drivers/gpu/drm/nouveau/include/nvkm/subdev')
6 files changed, 465 insertions, 4 deletions
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bar.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bar.h index 4f07836ab9..874a5080ba 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bar.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bar.h @@ -11,6 +11,10 @@ struct nvkm_bar { spinlock_t lock; bool bar2; + void __iomem *flushBAR2PhysMode; + struct nvkm_memory *flushFBZero; + void __iomem *flushBAR2; + /* whether the BAR supports to be ioremapped WC or should be uncached */ bool iomap_uncached; }; diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios.h index b61cfb0775..b4b7841e3b 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios.h @@ -29,6 +29,7 @@ int nvbios_memcmp(struct nvkm_bios *, u32 addr, const char *, u32 len); u8 nvbios_rd08(struct nvkm_bios *, u32 addr); u16 nvbios_rd16(struct nvkm_bios *, u32 addr); u32 nvbios_rd32(struct nvkm_bios *, u32 addr); +void *nvbios_pointer(struct nvkm_bios *, u32 addr); int nvkm_bios_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_bios **); #endif diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h index 1755b0df3c..5b798a1a31 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h @@ -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; diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h index 72619d7df7..6f5d376d8f 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h @@ -3,14 +3,452 @@ #define nvkm_gsp(p) container_of((p), struct nvkm_gsp, subdev) #include <core/subdev.h> #include <core/falcon.h> +#include <core/firmware.h> + +#define GSP_PAGE_SHIFT 12 +#define GSP_PAGE_SIZE BIT(GSP_PAGE_SHIFT) + +struct nvkm_gsp_mem { + size_t size; + void *data; + dma_addr_t addr; +}; + +struct nvkm_gsp_radix3 { + struct nvkm_gsp_mem mem[3]; +}; + +int nvkm_gsp_sg(struct nvkm_device *, u64 size, struct sg_table *); +void nvkm_gsp_sg_free(struct nvkm_device *, struct sg_table *); + +typedef int (*nvkm_gsp_msg_ntfy_func)(void *priv, u32 fn, void *repv, u32 repc); + +struct nvkm_gsp_event; +typedef void (*nvkm_gsp_event_func)(struct nvkm_gsp_event *, void *repv, u32 repc); struct nvkm_gsp { const struct nvkm_gsp_func *func; struct nvkm_subdev subdev; struct nvkm_falcon falcon; + + struct { + struct { + const struct firmware *load; + const struct firmware *unload; + } booter; + const struct firmware *bl; + const struct firmware *rm; + } fws; + + struct nvkm_firmware fw; + struct nvkm_gsp_mem sig; + struct nvkm_gsp_radix3 radix3; + + struct { + struct { + struct { + u64 addr; + u64 size; + } vga_workspace; + u64 addr; + u64 size; + } bios; + struct { + struct { + u64 addr; + u64 size; + } frts, boot, elf, heap; + u64 addr; + u64 size; + } wpr2; + struct { + u64 addr; + u64 size; + } heap; + u64 addr; + u64 size; + + struct { + u64 addr; + u64 size; + } region[16]; + int region_nr; + u32 rsvd_size; + } fb; + + struct { + struct nvkm_falcon_fw load; + struct nvkm_falcon_fw unload; + } booter; + + struct { + struct nvkm_gsp_mem fw; + u32 code_offset; + u32 data_offset; + u32 manifest_offset; + u32 app_version; + } boot; + + struct nvkm_gsp_mem libos; + struct nvkm_gsp_mem loginit; + struct nvkm_gsp_mem logintr; + struct nvkm_gsp_mem logrm; + struct nvkm_gsp_mem rmargs; + + struct nvkm_gsp_mem wpr_meta; + + struct { + struct sg_table sgt; + struct nvkm_gsp_radix3 radix3; + struct nvkm_gsp_mem meta; + } sr; + + struct { + struct nvkm_gsp_mem mem; + + struct { + int nr; + u32 size; + u64 *ptr; + } ptes; + + struct { + u32 size; + void *ptr; + } cmdq, msgq; + } shm; + + struct nvkm_gsp_cmdq { + struct mutex mutex; + u32 cnt; + u32 seq; + u32 *wptr; + u32 *rptr; + } cmdq; + + struct nvkm_gsp_msgq { + struct mutex mutex; + u32 cnt; + u32 *wptr; + u32 *rptr; + struct nvkm_gsp_msgq_ntfy { + u32 fn; + nvkm_gsp_msg_ntfy_func func; + void *priv; + } ntfy[16]; + int ntfy_nr; + struct work_struct work; + } msgq; + + bool running; + + /* Internal GSP-RM control handles. */ + struct { + struct nvkm_gsp_client { + struct nvkm_gsp_object { + struct nvkm_gsp_client *client; + struct nvkm_gsp_object *parent; + u32 handle; + } object; + + struct nvkm_gsp *gsp; + + struct list_head events; + } client; + + struct nvkm_gsp_device { + struct nvkm_gsp_object object; + struct nvkm_gsp_object subdevice; + } device; + } internal; + + struct { + enum nvkm_subdev_type type; + int inst; + u32 stall; + u32 nonstall; + } intr[32]; + int intr_nr; + + struct { + u64 rm_bar1_pdb; + u64 rm_bar2_pdb; + } bar; + + struct { + u8 gpcs; + u8 tpcs; + } gr; + + const struct nvkm_gsp_rm { + void *(*rpc_get)(struct nvkm_gsp *, u32 fn, u32 argc); + void *(*rpc_push)(struct nvkm_gsp *, void *argv, bool wait, u32 repc); + void (*rpc_done)(struct nvkm_gsp *gsp, void *repv); + + void *(*rm_ctrl_get)(struct nvkm_gsp_object *, u32 cmd, u32 argc); + int (*rm_ctrl_push)(struct nvkm_gsp_object *, void **argv, u32 repc); + void (*rm_ctrl_done)(struct nvkm_gsp_object *, void *repv); + + void *(*rm_alloc_get)(struct nvkm_gsp_object *, u32 oclass, u32 argc); + void *(*rm_alloc_push)(struct nvkm_gsp_object *, void *argv, u32 repc); + void (*rm_alloc_done)(struct nvkm_gsp_object *, void *repv); + + int (*rm_free)(struct nvkm_gsp_object *); + + int (*client_ctor)(struct nvkm_gsp *, struct nvkm_gsp_client *); + void (*client_dtor)(struct nvkm_gsp_client *); + + int (*device_ctor)(struct nvkm_gsp_client *, struct nvkm_gsp_device *); + void (*device_dtor)(struct nvkm_gsp_device *); + + int (*event_ctor)(struct nvkm_gsp_device *, u32 handle, u32 id, + nvkm_gsp_event_func, struct nvkm_gsp_event *); + void (*event_dtor)(struct nvkm_gsp_event *); + } *rm; + + struct { + struct mutex mutex;; + struct idr idr; + } client_id; +}; + +static inline bool +nvkm_gsp_rm(struct nvkm_gsp *gsp) +{ + return gsp && (gsp->fws.rm || gsp->fw.img); +} + +static inline void * +nvkm_gsp_rpc_get(struct nvkm_gsp *gsp, u32 fn, u32 argc) +{ + return gsp->rm->rpc_get(gsp, fn, argc); +} + +static inline void * +nvkm_gsp_rpc_push(struct nvkm_gsp *gsp, void *argv, bool wait, u32 repc) +{ + return gsp->rm->rpc_push(gsp, argv, wait, repc); +} + +static inline void * +nvkm_gsp_rpc_rd(struct nvkm_gsp *gsp, u32 fn, u32 argc) +{ + void *argv = nvkm_gsp_rpc_get(gsp, fn, argc); + + if (IS_ERR_OR_NULL(argv)) + return argv; + + return nvkm_gsp_rpc_push(gsp, argv, true, argc); +} + +static inline int +nvkm_gsp_rpc_wr(struct nvkm_gsp *gsp, void *argv, bool wait) +{ + void *repv = nvkm_gsp_rpc_push(gsp, argv, wait, 0); + + if (IS_ERR(repv)) + return PTR_ERR(repv); + + return 0; +} + +static inline void +nvkm_gsp_rpc_done(struct nvkm_gsp *gsp, void *repv) +{ + gsp->rm->rpc_done(gsp, repv); +} + +static inline void * +nvkm_gsp_rm_ctrl_get(struct nvkm_gsp_object *object, u32 cmd, u32 argc) +{ + return object->client->gsp->rm->rm_ctrl_get(object, cmd, argc); +} + +static inline int +nvkm_gsp_rm_ctrl_push(struct nvkm_gsp_object *object, void *argv, u32 repc) +{ + return object->client->gsp->rm->rm_ctrl_push(object, argv, repc); +} + +static inline void * +nvkm_gsp_rm_ctrl_rd(struct nvkm_gsp_object *object, u32 cmd, u32 repc) +{ + void *argv = nvkm_gsp_rm_ctrl_get(object, cmd, repc); + int ret; + + if (IS_ERR(argv)) + return argv; + + ret = nvkm_gsp_rm_ctrl_push(object, &argv, repc); + if (ret) + return ERR_PTR(ret); + return argv; +} + +static inline int +nvkm_gsp_rm_ctrl_wr(struct nvkm_gsp_object *object, void *argv) +{ + int ret = nvkm_gsp_rm_ctrl_push(object, &argv, 0); + + if (ret) + return ret; + return 0; +} + +static inline void +nvkm_gsp_rm_ctrl_done(struct nvkm_gsp_object *object, void *repv) +{ + object->client->gsp->rm->rm_ctrl_done(object, repv); +} + +static inline void * +nvkm_gsp_rm_alloc_get(struct nvkm_gsp_object *parent, u32 handle, u32 oclass, u32 argc, + struct nvkm_gsp_object *object) +{ + struct nvkm_gsp_client *client = parent->client; + struct nvkm_gsp *gsp = client->gsp; + void *argv; + + object->client = parent->client; + object->parent = parent; + object->handle = handle; + + argv = gsp->rm->rm_alloc_get(object, oclass, argc); + if (IS_ERR_OR_NULL(argv)) { + object->client = NULL; + return argv; + } + + return argv; +} + +static inline void * +nvkm_gsp_rm_alloc_push(struct nvkm_gsp_object *object, void *argv, u32 repc) +{ + void *repv = object->client->gsp->rm->rm_alloc_push(object, argv, repc); + + if (IS_ERR(repv)) + object->client = NULL; + + return repv; +} + +static inline int +nvkm_gsp_rm_alloc_wr(struct nvkm_gsp_object *object, void *argv) +{ + void *repv = nvkm_gsp_rm_alloc_push(object, argv, 0); + + if (IS_ERR(repv)) + return PTR_ERR(repv); + + return 0; +} + +static inline void +nvkm_gsp_rm_alloc_done(struct nvkm_gsp_object *object, void *repv) +{ + object->client->gsp->rm->rm_alloc_done(object, repv); +} + +static inline int +nvkm_gsp_rm_alloc(struct nvkm_gsp_object *parent, u32 handle, u32 oclass, u32 argc, + struct nvkm_gsp_object *object) +{ + void *argv = nvkm_gsp_rm_alloc_get(parent, handle, oclass, argc, object); + + if (IS_ERR_OR_NULL(argv)) + return argv ? PTR_ERR(argv) : -EIO; + + return nvkm_gsp_rm_alloc_wr(object, argv); +} + +static inline int +nvkm_gsp_rm_free(struct nvkm_gsp_object *object) +{ + if (object->client) + return object->client->gsp->rm->rm_free(object); + + return 0; +} + +static inline int +nvkm_gsp_client_ctor(struct nvkm_gsp *gsp, struct nvkm_gsp_client *client) +{ + if (WARN_ON(!gsp->rm)) + return -ENOSYS; + + return gsp->rm->client_ctor(gsp, client); +} + +static inline void +nvkm_gsp_client_dtor(struct nvkm_gsp_client *client) +{ + if (client->gsp) + client->gsp->rm->client_dtor(client); +} + +static inline int +nvkm_gsp_device_ctor(struct nvkm_gsp_client *client, struct nvkm_gsp_device *device) +{ + return client->gsp->rm->device_ctor(client, device); +} + +static inline void +nvkm_gsp_device_dtor(struct nvkm_gsp_device *device) +{ + if (device->object.client) + device->object.client->gsp->rm->device_dtor(device); +} + +static inline int +nvkm_gsp_client_device_ctor(struct nvkm_gsp *gsp, + struct nvkm_gsp_client *client, struct nvkm_gsp_device *device) +{ + int ret = nvkm_gsp_client_ctor(gsp, client); + + if (ret == 0) { + ret = nvkm_gsp_device_ctor(client, device); + if (ret) + nvkm_gsp_client_dtor(client); + } + + return ret; +} + +struct nvkm_gsp_event { + struct nvkm_gsp_device *device; + u32 id; + nvkm_gsp_event_func func; + + struct nvkm_gsp_object object; + + struct list_head head; }; +static inline int +nvkm_gsp_device_event_ctor(struct nvkm_gsp_device *device, u32 handle, u32 id, + nvkm_gsp_event_func func, struct nvkm_gsp_event *event) +{ + return device->object.client->gsp->rm->event_ctor(device, handle, id, func, event); +} + +static inline void +nvkm_gsp_event_dtor(struct nvkm_gsp_event *event) +{ + struct nvkm_gsp_device *device = event->device; + + if (device) + device->object.client->gsp->rm->event_dtor(event); +} + +int nvkm_gsp_intr_stall(struct nvkm_gsp *, enum nvkm_subdev_type, int); +int nvkm_gsp_intr_nonstall(struct nvkm_gsp *, enum nvkm_subdev_type, int); + int gv100_gsp_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_gsp **); +int tu102_gsp_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_gsp **); +int tu116_gsp_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_gsp **); +int ga100_gsp_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_gsp **); int ga102_gsp_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_gsp **); +int ad102_gsp_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_gsp **); #endif diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/instmem.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/instmem.h index fcdaefc99f..e10cbd9203 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/instmem.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/instmem.h @@ -8,6 +8,8 @@ struct nvkm_instmem { const struct nvkm_instmem_func *func; struct nvkm_subdev subdev; + bool suspend; + spinlock_t lock; struct list_head list; struct list_head boot; @@ -22,11 +24,16 @@ struct nvkm_instmem { struct nvkm_ramht *ramht; struct nvkm_memory *ramro; struct nvkm_memory *ramfc; + + struct { + struct sg_table fbsr; + bool fbsr_valid; + } rm; }; u32 nvkm_instmem_rd32(struct nvkm_instmem *, u32 addr); void nvkm_instmem_wr32(struct nvkm_instmem *, u32 addr, u32 data); -int nvkm_instobj_new(struct nvkm_instmem *, u32 size, u32 align, bool zero, +int nvkm_instobj_new(struct nvkm_instmem *, u32 size, u32 align, bool zero, bool preserve, struct nvkm_memory **); int nvkm_instobj_wrap(struct nvkm_device *, struct nvkm_memory *, struct nvkm_memory **); diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h index 2fd2f2433f..935b1cacd5 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h @@ -2,6 +2,7 @@ #ifndef __NVKM_MMU_H__ #define __NVKM_MMU_H__ #include <core/subdev.h> +#include <subdev/gsp.h> struct nvkm_vma { struct list_head head; @@ -63,6 +64,16 @@ struct nvkm_vmm { void *nullp; bool replay; + + struct { + u64 bar2_pdb; + + struct nvkm_gsp_client client; + struct nvkm_gsp_device device; + struct nvkm_gsp_object object; + + struct nvkm_vma *rsvd; + } rm; }; int nvkm_vmm_new(struct nvkm_device *, u64 addr, u64 size, void *argv, u32 argc, |