diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-18 17:35:05 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-18 17:39:31 +0000 |
commit | 85c675d0d09a45a135bddd15d7b385f8758c32fb (patch) | |
tree | 76267dbc9b9a130337be3640948fe397b04ac629 /drivers/gpu/drm/nouveau/include/nvkm | |
parent | Adding upstream version 6.6.15. (diff) | |
download | linux-85c675d0d09a45a135bddd15d7b385f8758c32fb.tar.xz linux-85c675d0d09a45a135bddd15d7b385f8758c32fb.zip |
Adding upstream version 6.7.7.upstream/6.7.7
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'drivers/gpu/drm/nouveau/include/nvkm')
19 files changed, 548 insertions, 8 deletions
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/device.h b/drivers/gpu/drm/nouveau/include/nvkm/core/device.h index f65b5009ac..f057d34822 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/core/device.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/device.h @@ -46,6 +46,7 @@ struct nvkm_device { GV100 = 0x140, TU100 = 0x160, GA100 = 0x170, + AD100 = 0x190, } card_type; u32 chipset; u8 chiprev; diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/falcon.h b/drivers/gpu/drm/nouveau/include/nvkm/core/falcon.h index b857cf142c..3d3f1063aa 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/core/falcon.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/falcon.h @@ -48,6 +48,8 @@ int nvkm_falcon_pio_rd(struct nvkm_falcon *, u8 port, enum nvkm_falcon_mem type, const u8 *img, u32 img_base, int len); int nvkm_falcon_dma_wr(struct nvkm_falcon *, const u8 *img, u64 dma_addr, u32 dma_base, enum nvkm_falcon_mem mem_type, u32 mem_base, int len, bool sec); +bool nvkm_falcon_riscv_active(struct nvkm_falcon *); +void nvkm_falcon_intr_retrigger(struct nvkm_falcon *); int gm200_flcn_reset_wait_mem_scrubbing(struct nvkm_falcon *); int gm200_flcn_disable(struct nvkm_falcon *); @@ -61,10 +63,15 @@ void gm200_flcn_tracepc(struct nvkm_falcon *); int gp102_flcn_reset_eng(struct nvkm_falcon *); extern const struct nvkm_falcon_func_pio gp102_flcn_emem_pio; +bool tu102_flcn_riscv_active(struct nvkm_falcon *); + +void ga100_flcn_intr_retrigger(struct nvkm_falcon *); + int ga102_flcn_select(struct nvkm_falcon *); int ga102_flcn_reset_prep(struct nvkm_falcon *); int ga102_flcn_reset_wait_mem_scrubbing(struct nvkm_falcon *); extern const struct nvkm_falcon_func_dma ga102_flcn_dma; +bool ga102_flcn_riscv_active(struct nvkm_falcon *); void nvkm_falcon_v1_load_imem(struct nvkm_falcon *, void *, u32, u32, u16, u8, bool); diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/firmware.h b/drivers/gpu/drm/nouveau/include/nvkm/core/firmware.h index d4e507e252..20839be726 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/core/firmware.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/firmware.h @@ -10,6 +10,7 @@ struct nvkm_firmware { enum nvkm_firmware_type { NVKM_FIRMWARE_IMG_RAM, NVKM_FIRMWARE_IMG_DMA, + NVKM_FIRMWARE_IMG_SGT, } type; } *func; const char *name; @@ -21,7 +22,10 @@ struct nvkm_firmware { struct nvkm_firmware_mem { struct nvkm_memory memory; - struct scatterlist sgl; + union { + struct scatterlist sgl; /* DMA */ + struct sg_table sgt; /* SGT */ + }; } mem; }; diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/layout.h b/drivers/gpu/drm/nouveau/include/nvkm/core/layout.h index 58108dea5a..30c17db483 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/core/layout.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/layout.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: MIT */ -NVKM_LAYOUT_ONCE(NVKM_SUBDEV_TOP , struct nvkm_top , top) NVKM_LAYOUT_ONCE(NVKM_SUBDEV_GSP , struct nvkm_gsp , gsp) +NVKM_LAYOUT_ONCE(NVKM_SUBDEV_TOP , struct nvkm_top , top) NVKM_LAYOUT_ONCE(NVKM_SUBDEV_VFN , struct nvkm_vfn , vfn) NVKM_LAYOUT_ONCE(NVKM_SUBDEV_PCI , struct nvkm_pci , pci) NVKM_LAYOUT_ONCE(NVKM_SUBDEV_VBIOS , struct nvkm_bios , bios) @@ -42,9 +42,9 @@ NVKM_LAYOUT_ONCE(NVKM_ENGINE_MSENC , struct nvkm_engine , msenc) NVKM_LAYOUT_ONCE(NVKM_ENGINE_MSPDEC , struct nvkm_engine , mspdec) NVKM_LAYOUT_ONCE(NVKM_ENGINE_MSPPP , struct nvkm_engine , msppp) NVKM_LAYOUT_ONCE(NVKM_ENGINE_MSVLD , struct nvkm_engine , msvld) -NVKM_LAYOUT_INST(NVKM_ENGINE_NVDEC , struct nvkm_nvdec , nvdec, 5) +NVKM_LAYOUT_INST(NVKM_ENGINE_NVDEC , struct nvkm_nvdec , nvdec, 8) NVKM_LAYOUT_INST(NVKM_ENGINE_NVENC , struct nvkm_nvenc , nvenc, 3) -NVKM_LAYOUT_ONCE(NVKM_ENGINE_NVJPG , struct nvkm_engine , nvjpg) +NVKM_LAYOUT_INST(NVKM_ENGINE_NVJPG , struct nvkm_engine , nvjpg, 8) NVKM_LAYOUT_ONCE(NVKM_ENGINE_OFA , struct nvkm_engine , ofa) NVKM_LAYOUT_ONCE(NVKM_ENGINE_PM , struct nvkm_pm , pm) NVKM_LAYOUT_ONCE(NVKM_ENGINE_SEC , struct nvkm_engine , sec) diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/memory.h b/drivers/gpu/drm/nouveau/include/nvkm/core/memory.h index d3b6a68ddd..fc0f389813 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/core/memory.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/memory.h @@ -12,6 +12,7 @@ struct nvkm_tags { }; enum nvkm_memory_target { + NVKM_MEM_TARGET_INST_SR_LOST, /* instance memory - not preserved across suspend */ NVKM_MEM_TARGET_INST, /* instance memory */ NVKM_MEM_TARGET_VRAM, /* video memory */ NVKM_MEM_TARGET_HOST, /* coherent system memory */ diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/disp.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/disp.h index ad9aef2df4..3e8db8280e 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/engine/disp.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/disp.h @@ -5,11 +5,29 @@ #include <core/engine.h> #include <core/object.h> #include <core/event.h> +#include <subdev/gsp.h> struct nvkm_disp { const struct nvkm_disp_func *func; struct nvkm_engine engine; + struct { + struct nvkm_gsp_client client; + struct nvkm_gsp_device device; + + struct nvkm_gsp_object objcom; + struct nvkm_gsp_object object; + +#define NVKM_DPYID_PLUG BIT(0) +#define NVKM_DPYID_UNPLUG BIT(1) +#define NVKM_DPYID_IRQ BIT(2) + struct nvkm_event event; + struct nvkm_gsp_event hpd; + struct nvkm_gsp_event irq; + + u32 assigned_sors; + } rm; + struct list_head heads; struct list_head iors; struct list_head outps; @@ -69,4 +87,5 @@ int gp102_disp_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct int gv100_disp_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_disp **); int tu102_disp_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_disp **); int ga102_disp_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_disp **); +int ad102_disp_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_disp **); #endif diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/falcon.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/falcon.h index b7bb8a29a7..341f133dc3 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/engine/falcon.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/falcon.h @@ -62,6 +62,7 @@ struct nvkm_falcon_func { int (*enable)(struct nvkm_falcon *); int (*select)(struct nvkm_falcon *); u32 addr2; + u32 riscv_irqmask; bool reset_pmc; int (*reset_eng)(struct nvkm_falcon *); int (*reset_prep)(struct nvkm_falcon *); @@ -87,6 +88,9 @@ struct nvkm_falcon_func { u32 stride; } cmdq, msgq; + bool (*riscv_active)(struct nvkm_falcon *); + void (*intr_retrigger)(struct nvkm_falcon *); + struct { u32 *data; u32 size; diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h index 221abd6c43..be508f65b2 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h @@ -4,6 +4,7 @@ #include <core/engine.h> #include <core/object.h> #include <core/event.h> +#include <subdev/gsp.h> struct nvkm_fault_data; #define NVKM_FIFO_ENGN_NR 16 @@ -35,6 +36,15 @@ struct nvkm_chan { atomic_t blocked; atomic_t errored; + struct { + struct nvkm_gsp_object object; + struct { + dma_addr_t addr; + void *ptr; + } mthdbuf; + struct nvkm_vctx *grctx; + } rm; + struct list_head cctxs; struct list_head head; }; @@ -43,6 +53,8 @@ struct nvkm_chan *nvkm_chan_get_chid(struct nvkm_engine *, int id, unsigned long struct nvkm_chan *nvkm_chan_get_inst(struct nvkm_engine *, u64 inst, unsigned long *irqflags); void nvkm_chan_put(struct nvkm_chan **, unsigned long irqflags); +struct nvkm_chan *nvkm_uchan_chan(struct nvkm_object *); + struct nvkm_fifo { const struct nvkm_fifo_func *func; struct nvkm_engine engine; @@ -66,8 +78,15 @@ struct nvkm_fifo { struct { struct nvkm_memory *mem; struct nvkm_vma *bar1; + + struct mutex mutex; + struct list_head list; } userd; + struct { + u32 mthdbuf_size; + } rm; + spinlock_t lock; struct mutex mutex; }; diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/gr.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/gr.h index a2333cfe69..8145796ffc 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/engine/gr.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/gr.h @@ -55,4 +55,5 @@ int gp10b_gr_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct n int gv100_gr_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_gr **); int tu102_gr_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_gr **); int ga102_gr_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_gr **); +int ad102_gr_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_gr **); #endif diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/nvdec.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/nvdec.h index 9baf197ac8..8d2e170883 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/engine/nvdec.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/nvdec.h @@ -12,5 +12,8 @@ struct nvkm_nvdec { }; int gm107_nvdec_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_nvdec **); +int tu102_nvdec_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_nvdec **); +int ga100_nvdec_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_nvdec **); int ga102_nvdec_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_nvdec **); +int ad102_nvdec_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_nvdec **); #endif diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/nvenc.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/nvenc.h index 1a259c5c9a..018c58fc32 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/engine/nvenc.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/nvenc.h @@ -12,4 +12,7 @@ struct nvkm_nvenc { }; int gm107_nvenc_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_nvenc **); +int tu102_nvenc_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_nvenc **); +int ga102_nvenc_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_nvenc **); +int ad102_nvenc_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_nvenc **); #endif diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/nvjpg.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/nvjpg.h new file mode 100644 index 0000000000..80b7933a78 --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/nvjpg.h @@ -0,0 +1,8 @@ +/* SPDX-License-Identifier: MIT */ +#ifndef __NVKM_NVJPG_H__ +#define __NVKM_NVJPG_H__ +#include <core/engine.h> + +int ga100_nvjpg_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_engine **); +int ad102_nvjpg_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_engine **); +#endif diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/ofa.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/ofa.h new file mode 100644 index 0000000000..e72e211533 --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/ofa.h @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: MIT */ +#ifndef __NVKM_OFA_H__ +#define __NVKM_OFA_H__ +#include <core/engine.h> + +int ga100_ofa_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_engine **); +int ga102_ofa_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_engine **); +int ad102_ofa_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_engine **); +#endif 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, |