Ben Skeggs
2025-May-17 00:08 UTC
[PATCH v3 00/62] add support for Hopper and Blackwell GPUs
This series implements support for booting GSP-RM firmware version 570.144, and adds support for GH100, GB10x, and GB20x GPUs. A tree containing this series is available here[1], and a temporary linux-firmware tree here[2]. Timur will send an official patch to the linux-firmware tree once this series is closer to being merged. The series is broken down as follows: Patches 1-2 are simple fixes for both the RM shutdown wait condition, and chid allocation. Neither are known to fix any pressing issues, but kept separate in case they need to be backported. Patches 3-5 bump up the maximum instance counts of various engines to support those available on r570 / newer HW. Patches 6-14 split up the GSP-RM code into modules (roughly) around RM API boundaries, and move all the r535-specific code and headers under nvkm/subdev/gsp/rm/r535 to make it easier to contain version-specific code. Patches 15-20 reduce the amount of boilerplate needed to implement engines and engine objects when running on GSP-RM by adding a common implementation which can be used for all engine types. Patches 21-45 add a bunch of simple HALs around the RMAPI calls that change between r535 and r570, and, finally, adds support for 570.144. Patches 46-54 add support for GH100 Hopper GPUs Patches 55-58 add support for GB10x Blackwell GPUs Patches 59-62 add support for GB20x Blackwell GPUs More details on the various changes are in the specific commit messages. v2: - switch to shorter spdx headers on source files - minor adjustments to some comments - fix tu10x regression with r570 v3: - fixes for a couple of gsp-rm heap leaks Signed-off-by: Ben Skeggs <bskeggs at nvidia.com> Reviewed-by: Dave Airlie <airlied at redhat.com> Reviewed-by: Timur Tabi <ttabi at nvidia.com> Tested-by: Timur Tabi <ttabi at nvidia.com> Ben Skeggs (61): drm/nouveau/gsp: fix rm shutdown wait condition drm/nouveau/gsp: remove gsp-specific chid allocation path drm/nouveau/ce: bump max instances to 20 drm/nouveau/nvenc: bump max instances to 4 drm/nouveau/ofa: bump max instances to 2 drm/nouveau/gsp: split rpc handling out on its own drm/nouveau/gsp: split rm ctrl handling out on its own drm/nouveau/gsp: split rm alloc handling out on its own drm/nouveau/gsp: split client handling out on its own drm/nouveau/gsp: split device handling out on its own drm/nouveau/gsp: move firmware loading to GPU-specific code drm/nouveau/gsp: move booter handling to GPU-specific code drm/nouveau/gsp: move subdev/engine impls to subdev/gsp/rm/r535/ drm/nouveau/gsp: switch to a simpler GSP-RM header layout drm/nouveau/gsp: add gpu hal stubs drm/nouveau/gsp: add display class ids to gpu hal drm/nouveau/gsp: add usermode class id to gpu hal drm/nouveau/gsp: add channel class id to gpu hal drm/nouveau/gsp: add common code for engines/engine objects drm/nouveau/gsp: add defines for rmapi object handles drm/nouveau/gsp: add hal for wpr config info + meta init drm/nouveau/gsp: add hal for gsp.set_system_info() drm/nouveau/gsp: add hal for gsp.get_static_info() drm/nouveau/gsp: add hal for gsp.xlat_mc_engine_idx() drm/nouveau/gsp: add hal for gsp.drop_send_user_shared_data() drm/nouveau/gsp: add hal for disp.bl_ctrl() drm/nouveau/gsp: add hal for disp.dp.set_indexed_link_rates() drm/nouveau/gsp: add hal for disp.get_static_info() drm/nouveau/gsp: add hal for disp.chan.set_pushbuf() drm/nouveau/gsp: add hal for fifo.xlat_rm_engine_type() drm/nouveau/gsp: add hal for fifo.ectx_size() drm/nouveau/gsp: add hal for gr.get_ctxbufs_info() drm/nouveau/gsp: add hal for gsp.set_rmargs() drm/nouveau/gsp: add hals for fbsr.suspend/resume() drm/nouveau/gsp: add hal for disp.get_supported() drm/nouveau/gsp: add hal for disp.get_connect_state() drm/nouveau/gsp: add hal for disp.get_active() drm/nouveau/gsp: add hal for disp.dp.get_caps() drm/nouveau/gsp: add hal for fifo.chan.alloc drm/nouveau/gsp: add hal for fifo.rsvd_chids drm/nouveau/gsp: add hal for fifo.rc_triggered() drm/nouveau/gsp: add hal for disp.chan.dmac_alloc() drm/nouveau/gsp: add hal for gsp.sr_data_size() drm/nouveau/gsp: add common client alloc code drm/nouveau/gsp: add support for 570.144 drm/nouveau/pci: add PRI address of config space mirror to nvkm_pci_func drm/nouveau/instmem: add hal for set_bar0_window_addr() drm/nouveau/mmu: bump up the maximum page table depth drm/nouveau/gsp: fetch level shift and PDE from BAR2 VMM drm/nouveau/gsp: init client VMMs with NV0080_CTRL_DMA_SET_PAGE_DIRECTORY drm/nouveau/gsp: support deeper page tables in COPY_SERVER_RESERVED_PDES drm/nouveau/gv100-: switch to volta semaphore methods drm/nouveau: improve handling of 64-bit BARs drm/nouveau: add support for GH100 drm/nouveau: add helper functions for allocating pinned/cpu-mapped bos drm/nouveau/nv50-: separate CHANNEL_GPFIFO handling out from CHANNEL_DMA drm/nouveau/gf100-: track chan progress with non-WFI semaphore release drm/nouveau: add support for GB10x drm/nouveau/gsp: add hal for fifo.chan.doorbell_handle drm/nouveau: add support for GB20x drm/nouveau/kms: add support for GB20x Dave Airlie (1): drm/dp: add option to disable zero sized address only transactions. drivers/gpu/drm/display/drm_dp_helper.c | 39 +- drivers/gpu/drm/nouveau/Kbuild | 2 + drivers/gpu/drm/nouveau/dispnv04/crtc.c | 22 +- drivers/gpu/drm/nouveau/dispnv50/Kbuild | 4 + drivers/gpu/drm/nouveau/dispnv50/core.c | 1 + drivers/gpu/drm/nouveau/dispnv50/core.h | 6 + drivers/gpu/drm/nouveau/dispnv50/core507d.c | 1 + drivers/gpu/drm/nouveau/dispnv50/corec37d.c | 3 +- drivers/gpu/drm/nouveau/dispnv50/corec57d.c | 2 + drivers/gpu/drm/nouveau/dispnv50/coreca7d.c | 122 ++ drivers/gpu/drm/nouveau/dispnv50/crc.c | 4 + drivers/gpu/drm/nouveau/dispnv50/crc.h | 1 + drivers/gpu/drm/nouveau/dispnv50/crcca7d.c | 98 + drivers/gpu/drm/nouveau/dispnv50/curs.c | 1 + drivers/gpu/drm/nouveau/dispnv50/disp.c | 30 +- drivers/gpu/drm/nouveau/dispnv50/head.c | 1 + drivers/gpu/drm/nouveau/dispnv50/head.h | 5 + drivers/gpu/drm/nouveau/dispnv50/headc57d.c | 2 +- drivers/gpu/drm/nouveau/dispnv50/headca7d.c | 297 ++++ drivers/gpu/drm/nouveau/dispnv50/wimm.c | 1 + drivers/gpu/drm/nouveau/dispnv50/wndw.c | 25 +- drivers/gpu/drm/nouveau/dispnv50/wndw.h | 3 + drivers/gpu/drm/nouveau/dispnv50/wndwc37e.c | 1 + drivers/gpu/drm/nouveau/dispnv50/wndwca7e.c | 209 +++ drivers/gpu/drm/nouveau/gv100_fence.c | 93 + .../drm/nouveau/include/nvhw/class/clc36f.h | 52 + .../drm/nouveau/include/nvhw/class/clc97b.h | 22 + .../drm/nouveau/include/nvhw/class/clca7d.h | 868 +++++++++ .../drm/nouveau/include/nvhw/class/clca7e.h | 137 ++ .../include/nvhw/ref/gb100/dev_hshub_base.h | 28 + .../include/nvhw/ref/gb10b/dev_fbhub.h | 18 + .../nouveau/include/nvhw/ref/gb202/dev_ce.h | 12 + .../include/nvhw/ref/gb202/dev_therm.h | 17 + .../include/nvhw/ref/gh100/dev_falcon_v4.h | 20 + .../nouveau/include/nvhw/ref/gh100/dev_fb.h | 15 + .../include/nvhw/ref/gh100/dev_fsp_pri.h | 28 + .../nouveau/include/nvhw/ref/gh100/dev_mmu.h | 173 ++ .../include/nvhw/ref/gh100/dev_riscv_pri.h | 14 + .../include/nvhw/ref/gh100/dev_therm.h | 17 + .../include/nvhw/ref/gh100/dev_xtl_ep_pri.h | 10 + .../include/nvhw/ref/gh100/pri_nv_xal_ep.h | 13 + drivers/gpu/drm/nouveau/include/nvif/chan.h | 76 + drivers/gpu/drm/nouveau/include/nvif/cl0080.h | 2 + drivers/gpu/drm/nouveau/include/nvif/class.h | 35 + drivers/gpu/drm/nouveau/include/nvif/object.h | 2 +- drivers/gpu/drm/nouveau/include/nvif/push.h | 14 +- .../gpu/drm/nouveau/include/nvif/push906f.h | 1 + .../gpu/drm/nouveau/include/nvif/pushc97b.h | 18 + .../drm/nouveau/include/nvkm/core/device.h | 17 +- .../drm/nouveau/include/nvkm/core/layout.h | 7 +- .../drm/nouveau/include/nvkm/engine/disp.h | 1 - .../drm/nouveau/include/nvkm/engine/fifo.h | 3 - .../gpu/drm/nouveau/include/nvkm/engine/gr.h | 1 - .../drm/nouveau/include/nvkm/engine/nvdec.h | 2 - .../drm/nouveau/include/nvkm/engine/nvenc.h | 2 - .../drm/nouveau/include/nvkm/engine/nvjpg.h | 8 - .../gpu/drm/nouveau/include/nvkm/engine/ofa.h | 9 - .../gpu/drm/nouveau/include/nvkm/subdev/fb.h | 3 + .../gpu/drm/nouveau/include/nvkm/subdev/fsp.h | 24 + .../gpu/drm/nouveau/include/nvkm/subdev/gsp.h | 100 +- .../drm/nouveau/include/nvkm/subdev/instmem.h | 6 +- .../gpu/drm/nouveau/include/nvkm/subdev/mmu.h | 4 +- .../gpu/drm/nouveau/include/nvkm/subdev/pci.h | 1 + .../common/sdk/nvidia/inc/class/cl0000.h | 38 - .../common/sdk/nvidia/inc/class/cl0005.h | 38 - .../common/sdk/nvidia/inc/class/cl0080.h | 43 - .../common/sdk/nvidia/inc/class/cl2080.h | 35 - .../nvidia/inc/class/cl2080_notification.h | 62 - .../common/sdk/nvidia/inc/class/cl84a0.h | 33 - .../common/sdk/nvidia/inc/class/cl90f1.h | 31 - .../common/sdk/nvidia/inc/class/clc0b5sw.h | 34 - .../nvidia/inc/ctrl/ctrl0073/ctrl0073common.h | 39 - .../nvidia/inc/ctrl/ctrl0073/ctrl0073dfp.h | 166 -- .../sdk/nvidia/inc/ctrl/ctrl0073/ctrl0073dp.h | 335 ---- .../inc/ctrl/ctrl0073/ctrl0073specific.h | 216 --- .../nvidia/inc/ctrl/ctrl0073/ctrl0073system.h | 65 - .../nvidia/inc/ctrl/ctrl0080/ctrl0080gpu.h | 48 - .../sdk/nvidia/inc/ctrl/ctrl0080/ctrl0080gr.h | 31 - .../nvidia/inc/ctrl/ctrl2080/ctrl2080bios.h | 40 - .../sdk/nvidia/inc/ctrl/ctrl2080/ctrl2080ce.h | 35 - .../nvidia/inc/ctrl/ctrl2080/ctrl2080event.h | 41 - .../sdk/nvidia/inc/ctrl/ctrl2080/ctrl2080fb.h | 51 - .../nvidia/inc/ctrl/ctrl2080/ctrl2080fifo.h | 52 - .../nvidia/inc/ctrl/ctrl2080/ctrl2080gpu.h | 100 -- .../sdk/nvidia/inc/ctrl/ctrl2080/ctrl2080gr.h | 41 - .../inc/ctrl/ctrl2080/ctrl2080internal.h | 162 -- .../common/sdk/nvidia/inc/ctrl/ctrl90f1.h | 95 - .../nvidia/inc/ctrl/ctrla06f/ctrla06fgpfifo.h | 42 - .../common/sdk/nvidia/inc/nvlimits.h | 33 - .../535.113.01/common/sdk/nvidia/inc/nvos.h | 148 -- .../common/shared/msgq/inc/msgq/msgq_priv.h | 97 - .../uproc/os/common/include/libos_init_args.h | 52 - .../nvalloc/common/inc/gsp/gsp_fw_sr_meta.h | 79 - .../nvalloc/common/inc/gsp/gsp_fw_wpr_meta.h | 170 -- .../arch/nvalloc/common/inc/rmRiscvUcode.h | 82 - .../nvidia/arch/nvalloc/common/inc/rmgspseq.h | 100 -- .../nvidia/generated/g_allclasses.h | 33 - .../nvidia/generated/g_chipset_nvoc.h | 38 - .../535.113.01/nvidia/generated/g_fbsr_nvoc.h | 31 - .../535.113.01/nvidia/generated/g_gpu_nvoc.h | 35 - .../nvidia/generated/g_kernel_channel_nvoc.h | 62 - .../nvidia/generated/g_kernel_fifo_nvoc.h | 119 -- .../nvidia/generated/g_mem_desc_nvoc.h | 32 - .../535.113.01/nvidia/generated/g_os_nvoc.h | 44 - .../nvidia/generated/g_rpc-structures.h | 124 -- .../nvidia/generated/g_sdk-structures.h | 45 - .../nvidia/inc/kernel/gpu/gpu_acpi_data.h | 74 - .../nvidia/inc/kernel/gpu/gpu_engine_type.h | 86 - .../nvidia/inc/kernel/gpu/gsp/gsp_fw_heap.h | 33 - .../nvidia/inc/kernel/gpu/gsp/gsp_init_args.h | 57 - .../inc/kernel/gpu/gsp/gsp_static_config.h | 174 -- .../nvidia/inc/kernel/gpu/intr/engine_idx.h | 57 - .../nvidia/inc/kernel/gpu/nvbitmask.h | 33 - .../nvidia/inc/kernel/os/nv_memory_type.h | 31 - .../nvidia/kernel/inc/vgpu/rpc_headers.h | 51 - .../nvidia/kernel/inc/vgpu/sdk-structures.h | 40 - .../gpu/drm/nouveau/include/nvrm/nvtypes.h | 2 + drivers/gpu/drm/nouveau/nouveau_abi16.c | 4 +- drivers/gpu/drm/nouveau/nouveau_bo.c | 84 +- drivers/gpu/drm/nouveau/nouveau_bo.h | 7 + drivers/gpu/drm/nouveau/nouveau_chan.c | 99 +- drivers/gpu/drm/nouveau/nouveau_chan.h | 16 +- drivers/gpu/drm/nouveau/nouveau_connector.c | 2 + drivers/gpu/drm/nouveau/nouveau_dma.c | 103 +- drivers/gpu/drm/nouveau/nouveau_dma.h | 13 +- drivers/gpu/drm/nouveau/nouveau_dmem.c | 18 +- drivers/gpu/drm/nouveau/nouveau_drm.c | 7 +- drivers/gpu/drm/nouveau/nouveau_exec.c | 12 +- drivers/gpu/drm/nouveau/nouveau_fence.h | 1 + drivers/gpu/drm/nouveau/nouveau_gem.c | 10 +- drivers/gpu/drm/nouveau/nouveau_ttm.c | 12 +- drivers/gpu/drm/nouveau/nv10_fence.c | 6 +- drivers/gpu/drm/nouveau/nv17_fence.c | 15 +- drivers/gpu/drm/nouveau/nv50_fence.c | 15 +- drivers/gpu/drm/nouveau/nv84_fence.c | 19 +- drivers/gpu/drm/nouveau/nvif/Kbuild | 6 + drivers/gpu/drm/nouveau/nvif/chan.c | 156 ++ drivers/gpu/drm/nouveau/nvif/chan506f.c | 72 + drivers/gpu/drm/nouveau/nvif/chan906f.c | 93 + drivers/gpu/drm/nouveau/nvif/chanc36f.c | 77 + drivers/gpu/drm/nouveau/nvif/disp.c | 1 + drivers/gpu/drm/nouveau/nvif/user.c | 8 +- drivers/gpu/drm/nouveau/nvkm/engine/Kbuild | 2 - drivers/gpu/drm/nouveau/nvkm/engine/ce/Kbuild | 3 +- .../gpu/drm/nouveau/nvkm/engine/ce/ga100.c | 2 +- .../gpu/drm/nouveau/nvkm/engine/ce/ga102.c | 2 +- .../gpu/drm/nouveau/nvkm/engine/ce/gb202.c | 16 + drivers/gpu/drm/nouveau/nvkm/engine/ce/priv.h | 2 + drivers/gpu/drm/nouveau/nvkm/engine/ce/r535.c | 108 -- .../gpu/drm/nouveau/nvkm/engine/ce/tu102.c | 2 +- .../gpu/drm/nouveau/nvkm/engine/device/base.c | 189 +- .../gpu/drm/nouveau/nvkm/engine/device/pci.c | 32 +- .../gpu/drm/nouveau/nvkm/engine/device/priv.h | 3 +- .../drm/nouveau/nvkm/engine/device/tegra.c | 18 +- .../gpu/drm/nouveau/nvkm/engine/device/user.c | 7 +- .../gpu/drm/nouveau/nvkm/engine/disp/Kbuild | 3 - .../gpu/drm/nouveau/nvkm/engine/disp/ad102.c | 52 - .../gpu/drm/nouveau/nvkm/engine/disp/chan.c | 2 +- .../gpu/drm/nouveau/nvkm/engine/disp/gv100.c | 2 +- .../gpu/drm/nouveau/nvkm/engine/fifo/Kbuild | 3 +- .../gpu/drm/nouveau/nvkm/engine/fifo/base.c | 7 +- .../gpu/drm/nouveau/nvkm/engine/fifo/chan.c | 50 +- .../gpu/drm/nouveau/nvkm/engine/fifo/chan.h | 5 +- .../gpu/drm/nouveau/nvkm/engine/fifo/gb202.c | 14 + .../gpu/drm/nouveau/nvkm/engine/fifo/gf100.c | 2 +- .../gpu/drm/nouveau/nvkm/engine/fifo/gk104.c | 4 +- .../gpu/drm/nouveau/nvkm/engine/fifo/gv100.c | 1 - .../gpu/drm/nouveau/nvkm/engine/fifo/nv04.c | 2 +- .../gpu/drm/nouveau/nvkm/engine/fifo/nv40.c | 2 +- .../gpu/drm/nouveau/nvkm/engine/fifo/nv50.c | 2 +- .../gpu/drm/nouveau/nvkm/engine/fifo/priv.h | 4 + .../gpu/drm/nouveau/nvkm/engine/fifo/tu102.c | 2 +- .../gpu/drm/nouveau/nvkm/engine/fifo/uchan.c | 2 +- drivers/gpu/drm/nouveau/nvkm/engine/gr/Kbuild | 3 - .../gpu/drm/nouveau/nvkm/engine/gr/ga102.c | 2 +- .../gpu/drm/nouveau/nvkm/engine/gr/gf100.h | 2 - drivers/gpu/drm/nouveau/nvkm/engine/gr/nv20.c | 2 +- drivers/gpu/drm/nouveau/nvkm/engine/gr/nv40.c | 2 +- drivers/gpu/drm/nouveau/nvkm/engine/gr/r535.c | 508 ------ .../gpu/drm/nouveau/nvkm/engine/gr/tu102.c | 2 +- .../gpu/drm/nouveau/nvkm/engine/nvdec/Kbuild | 4 - .../gpu/drm/nouveau/nvkm/engine/nvdec/ga102.c | 12 +- .../gpu/drm/nouveau/nvkm/engine/nvdec/priv.h | 3 - .../gpu/drm/nouveau/nvkm/engine/nvdec/r535.c | 110 -- .../gpu/drm/nouveau/nvkm/engine/nvdec/tu102.c | 12 +- .../gpu/drm/nouveau/nvkm/engine/nvenc/Kbuild | 4 - .../gpu/drm/nouveau/nvkm/engine/nvenc/ga102.c | 44 - .../gpu/drm/nouveau/nvkm/engine/nvenc/priv.h | 3 - .../gpu/drm/nouveau/nvkm/engine/nvenc/r535.c | 110 -- .../gpu/drm/nouveau/nvkm/engine/nvenc/tu102.c | 12 +- .../gpu/drm/nouveau/nvkm/engine/nvjpg/Kbuild | 5 - .../gpu/drm/nouveau/nvkm/engine/nvjpg/ad102.c | 44 - .../gpu/drm/nouveau/nvkm/engine/nvjpg/ga100.c | 44 - .../gpu/drm/nouveau/nvkm/engine/nvjpg/priv.h | 8 - .../gpu/drm/nouveau/nvkm/engine/nvjpg/r535.c | 107 -- .../gpu/drm/nouveau/nvkm/engine/ofa/Kbuild | 6 - .../gpu/drm/nouveau/nvkm/engine/ofa/ad102.c | 44 - .../gpu/drm/nouveau/nvkm/engine/ofa/ga100.c | 44 - .../gpu/drm/nouveau/nvkm/engine/ofa/ga102.c | 44 - .../gpu/drm/nouveau/nvkm/engine/ofa/priv.h | 8 - .../gpu/drm/nouveau/nvkm/engine/ofa/r535.c | 107 -- drivers/gpu/drm/nouveau/nvkm/subdev/Kbuild | 1 + .../gpu/drm/nouveau/nvkm/subdev/bar/Kbuild | 2 - .../gpu/drm/nouveau/nvkm/subdev/bar/gf100.c | 14 +- .../gpu/drm/nouveau/nvkm/subdev/bar/nv50.c | 4 +- .../drm/nouveau/nvkm/subdev/devinit/fbmem.h | 4 +- .../gpu/drm/nouveau/nvkm/subdev/fault/user.c | 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/fb/Kbuild | 3 + .../gpu/drm/nouveau/nvkm/subdev/fb/ga102.c | 2 +- .../gpu/drm/nouveau/nvkm/subdev/fb/gb100.c | 34 + .../gpu/drm/nouveau/nvkm/subdev/fb/gb202.c | 30 + .../gpu/drm/nouveau/nvkm/subdev/fb/gh100.c | 30 + drivers/gpu/drm/nouveau/nvkm/subdev/fb/priv.h | 2 + .../gpu/drm/nouveau/nvkm/subdev/fsp/Kbuild | 8 + .../gpu/drm/nouveau/nvkm/subdev/fsp/base.c | 66 + .../gpu/drm/nouveau/nvkm/subdev/fsp/gb100.c | 24 + .../gpu/drm/nouveau/nvkm/subdev/fsp/gb202.c | 45 + .../gpu/drm/nouveau/nvkm/subdev/fsp/gh100.c | 275 +++ .../gpu/drm/nouveau/nvkm/subdev/fsp/priv.h | 29 + .../gpu/drm/nouveau/nvkm/subdev/gsp/Kbuild | 5 +- .../gpu/drm/nouveau/nvkm/subdev/gsp/ad102.c | 27 +- .../gpu/drm/nouveau/nvkm/subdev/gsp/base.c | 42 +- .../gpu/drm/nouveau/nvkm/subdev/gsp/ga100.c | 17 +- .../gpu/drm/nouveau/nvkm/subdev/gsp/ga102.c | 27 +- .../gpu/drm/nouveau/nvkm/subdev/gsp/gb100.c | 35 + .../gpu/drm/nouveau/nvkm/subdev/gsp/gb202.c | 38 + .../gpu/drm/nouveau/nvkm/subdev/gsp/gh100.c | 358 ++++ .../gpu/drm/nouveau/nvkm/subdev/gsp/priv.h | 41 +- .../gpu/drm/nouveau/nvkm/subdev/gsp/rm/Kbuild | 19 + .../drm/nouveau/nvkm/subdev/gsp/rm/ad10x.c | 39 + .../drm/nouveau/nvkm/subdev/gsp/rm/client.c | 49 + .../drm/nouveau/nvkm/subdev/gsp/rm/engine.c | 189 ++ .../drm/nouveau/nvkm/subdev/gsp/rm/engine.h | 20 + .../drm/nouveau/nvkm/subdev/gsp/rm/ga100.c | 28 + .../drm/nouveau/nvkm/subdev/gsp/rm/ga1xx.c | 39 + .../drm/nouveau/nvkm/subdev/gsp/rm/gb10x.c | 30 + .../drm/nouveau/nvkm/subdev/gsp/rm/gb20x.c | 44 + .../drm/nouveau/nvkm/subdev/gsp/rm/gh100.c | 30 + .../gpu/drm/nouveau/nvkm/subdev/gsp/rm/gpu.h | 70 + .../gpu/drm/nouveau/nvkm/subdev/gsp/rm/gr.c | 87 + .../gpu/drm/nouveau/nvkm/subdev/gsp/rm/gr.h | 55 + .../drm/nouveau/nvkm/subdev/gsp/rm/handles.h | 18 + .../drm/nouveau/nvkm/subdev/gsp/rm/nvdec.c | 33 + .../drm/nouveau/nvkm/subdev/gsp/rm/nvenc.c | 33 + .../nouveau/nvkm/subdev/gsp/rm/r535/Kbuild | 25 + .../nouveau/nvkm/subdev/gsp/rm/r535/alloc.c | 112 ++ .../subdev/{bar/r535.c => gsp/rm/r535/bar.c} | 41 +- .../drm/nouveau/nvkm/subdev/gsp/rm/r535/ce.c | 46 + .../ga100.c => subdev/gsp/rm/r535/client.c} | 35 +- .../nouveau/nvkm/subdev/gsp/rm/r535/ctrl.c | 93 + .../nouveau/nvkm/subdev/gsp/rm/r535/device.c | 148 ++ .../disp/r535.c => subdev/gsp/rm/r535/disp.c} | 394 ++-- .../{instmem/r535.c => gsp/rm/r535/fbsr.c} | 58 +- .../fifo/r535.c => subdev/gsp/rm/r535/fifo.c} | 417 ++--- .../drm/nouveau/nvkm/subdev/gsp/rm/r535/gr.c | 356 ++++ .../nvkm/subdev/gsp/{r535.c => rm/r535/gsp.c} | 1581 ++--------------- .../ad102.c => subdev/gsp/rm/r535/nvdec.c} | 35 +- .../gr/ad102.c => subdev/gsp/rm/r535/nvenc.c} | 37 +- .../nouveau/nvkm/subdev/gsp/rm/r535/nvjpg.c | 45 + .../nvkm/subdev/gsp/rm/r535/nvrm/alloc.h | 36 + .../nvkm/subdev/gsp/rm/r535/nvrm/bar.h | 29 + .../nouveau/nvkm/subdev/gsp/rm/r535/nvrm/ce.h | 15 + .../nvkm/subdev/gsp/rm/r535/nvrm/client.h | 20 + .../nvkm/subdev/gsp/rm/r535/nvrm/ctrl.h | 21 + .../nvkm/subdev/gsp/rm/r535/nvrm/device.h | 30 + .../nvkm/subdev/gsp/rm/r535/nvrm/disp.h | 741 ++++++++ .../nvkm/subdev/gsp/rm/r535/nvrm/engine.h | 260 +++ .../nvkm/subdev/gsp/rm/r535/nvrm/event.h | 47 + .../nvkm/subdev/gsp/rm/r535/nvrm/fbsr.h | 106 ++ .../nvkm/subdev/gsp/rm/r535/nvrm/fifo.h | 350 ++++ .../subdev/gsp/rm/r535/nvrm/gr.h} | 64 +- .../nvkm/subdev/gsp/rm/r535/nvrm/gsp.h | 825 +++++++++ .../nvkm/subdev/gsp/rm/r535/nvrm/msgfn.h | 53 + .../nvkm/subdev/gsp/rm/r535/nvrm/nvdec.h | 17 + .../nvkm/subdev/gsp/rm/r535/nvrm/nvenc.h | 17 + .../nvkm/subdev/gsp/rm/r535/nvrm/nvjpg.h | 17 + .../nvkm/subdev/gsp/rm/r535/nvrm/ofa.h | 16 + .../subdev/gsp/rm/r535/nvrm/rpcfn.h} | 55 +- .../nvkm/subdev/gsp/rm/r535/nvrm/vmm.h | 132 ++ .../ad102.c => subdev/gsp/rm/r535/ofa.c} | 34 +- .../drm/nouveau/nvkm/subdev/gsp/rm/r535/rm.c | 52 + .../drm/nouveau/nvkm/subdev/gsp/rm/r535/rpc.c | 691 +++++++ .../subdev/{mmu/r535.c => gsp/rm/r535/vmm.c} | 118 +- .../nouveau/nvkm/subdev/gsp/rm/r570/Kbuild | 9 + .../nouveau/nvkm/subdev/gsp/rm/r570/client.c | 28 + .../nouveau/nvkm/subdev/gsp/rm/r570/disp.c | 263 +++ .../nouveau/nvkm/subdev/gsp/rm/r570/fbsr.c | 149 ++ .../nouveau/nvkm/subdev/gsp/rm/r570/fifo.c | 217 +++ .../drm/nouveau/nvkm/subdev/gsp/rm/r570/gr.c | 191 ++ .../drm/nouveau/nvkm/subdev/gsp/rm/r570/gsp.c | 216 +++ .../nvkm/subdev/gsp/rm/r570/nvrm/client.h | 21 + .../nvkm/subdev/gsp/rm/r570/nvrm/disp.h | 355 ++++ .../nvkm/subdev/gsp/rm/r570/nvrm/engine.h | 318 ++++ .../nvkm/subdev/gsp/rm/r570/nvrm/fbsr.h | 19 + .../subdev/gsp/rm/r570/nvrm/fifo.h} | 241 +-- .../nouveau/nvkm/subdev/gsp/rm/r570/nvrm/gr.h | 79 + .../nvkm/subdev/gsp/rm/r570/nvrm/gsp.h | 634 +++++++ .../nvkm/subdev/gsp/rm/r570/nvrm/msgfn.h | 57 + .../nvkm/subdev/gsp/rm/r570/nvrm/ofa.h | 17 + .../nvkm/subdev/gsp/rm/r570/nvrm/rpcfn.h | 249 +++ .../drm/nouveau/nvkm/subdev/gsp/rm/r570/ofa.c | 28 + .../drm/nouveau/nvkm/subdev/gsp/rm/r570/rm.c | 99 ++ .../gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h | 191 ++ .../gpu/drm/nouveau/nvkm/subdev/gsp/rm/rpc.h | 18 + .../drm/nouveau/nvkm/subdev/gsp/rm/tu1xx.c | 38 + .../gpu/drm/nouveau/nvkm/subdev/gsp/tu102.c | 271 ++- .../gpu/drm/nouveau/nvkm/subdev/gsp/tu116.c | 20 +- .../drm/nouveau/nvkm/subdev/instmem/Kbuild | 3 +- .../drm/nouveau/nvkm/subdev/instmem/base.c | 8 +- .../drm/nouveau/nvkm/subdev/instmem/gh100.c | 28 + .../drm/nouveau/nvkm/subdev/instmem/nv40.c | 10 +- .../drm/nouveau/nvkm/subdev/instmem/nv50.c | 17 +- .../drm/nouveau/nvkm/subdev/instmem/priv.h | 6 + .../gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild | 4 +- .../gpu/drm/nouveau/nvkm/subdev/mmu/gh100.c | 25 + .../drm/nouveau/nvkm/subdev/mmu/memgf100.c | 2 +- .../gpu/drm/nouveau/nvkm/subdev/mmu/memnv04.c | 2 +- .../gpu/drm/nouveau/nvkm/subdev/mmu/memnv50.c | 2 +- .../gpu/drm/nouveau/nvkm/subdev/mmu/priv.h | 2 + .../gpu/drm/nouveau/nvkm/subdev/mmu/tu102.c | 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c | 10 +- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h | 7 + .../drm/nouveau/nvkm/subdev/mmu/vmmgh100.c | 306 ++++ .../drm/nouveau/nvkm/subdev/mmu/vmmgp100.c | 3 + .../drm/nouveau/nvkm/subdev/mmu/vmmtu102.c | 2 +- .../gpu/drm/nouveau/nvkm/subdev/pci/Kbuild | 1 + .../gpu/drm/nouveau/nvkm/subdev/pci/base.c | 10 +- drivers/gpu/drm/nouveau/nvkm/subdev/pci/g84.c | 5 +- drivers/gpu/drm/nouveau/nvkm/subdev/pci/g92.c | 5 +- drivers/gpu/drm/nouveau/nvkm/subdev/pci/g94.c | 5 +- .../gpu/drm/nouveau/nvkm/subdev/pci/gf100.c | 5 +- .../gpu/drm/nouveau/nvkm/subdev/pci/gf106.c | 5 +- .../gpu/drm/nouveau/nvkm/subdev/pci/gh100.c | 30 + .../gpu/drm/nouveau/nvkm/subdev/pci/gk104.c | 5 +- .../gpu/drm/nouveau/nvkm/subdev/pci/gp100.c | 4 +- .../gpu/drm/nouveau/nvkm/subdev/pci/nv04.c | 25 +- .../gpu/drm/nouveau/nvkm/subdev/pci/nv40.c | 25 +- .../gpu/drm/nouveau/nvkm/subdev/pci/nv46.c | 4 +- .../gpu/drm/nouveau/nvkm/subdev/pci/nv4c.c | 4 +- .../gpu/drm/nouveau/nvkm/subdev/pci/priv.h | 11 +- .../gpu/drm/nouveau/nvkm/subdev/vfn/r535.c | 11 +- .../gpu/drm/nouveau/nvkm/subdev/vfn/uvfn.c | 2 +- include/drm/display/drm_dp_helper.h | 5 + 343 files changed, 14630 insertions(+), 8101 deletions(-) create mode 100644 drivers/gpu/drm/nouveau/dispnv50/coreca7d.c create mode 100644 drivers/gpu/drm/nouveau/dispnv50/crcca7d.c create mode 100644 drivers/gpu/drm/nouveau/dispnv50/headca7d.c create mode 100644 drivers/gpu/drm/nouveau/dispnv50/wndwca7e.c create mode 100644 drivers/gpu/drm/nouveau/gv100_fence.c create mode 100644 drivers/gpu/drm/nouveau/include/nvhw/class/clc36f.h create mode 100644 drivers/gpu/drm/nouveau/include/nvhw/class/clc97b.h create mode 100644 drivers/gpu/drm/nouveau/include/nvhw/class/clca7d.h create mode 100644 drivers/gpu/drm/nouveau/include/nvhw/class/clca7e.h create mode 100644 drivers/gpu/drm/nouveau/include/nvhw/ref/gb100/dev_hshub_base.h create mode 100644 drivers/gpu/drm/nouveau/include/nvhw/ref/gb10b/dev_fbhub.h create mode 100644 drivers/gpu/drm/nouveau/include/nvhw/ref/gb202/dev_ce.h create mode 100644 drivers/gpu/drm/nouveau/include/nvhw/ref/gb202/dev_therm.h create mode 100644 drivers/gpu/drm/nouveau/include/nvhw/ref/gh100/dev_falcon_v4.h create mode 100644 drivers/gpu/drm/nouveau/include/nvhw/ref/gh100/dev_fb.h create mode 100644 drivers/gpu/drm/nouveau/include/nvhw/ref/gh100/dev_fsp_pri.h create mode 100644 drivers/gpu/drm/nouveau/include/nvhw/ref/gh100/dev_mmu.h create mode 100644 drivers/gpu/drm/nouveau/include/nvhw/ref/gh100/dev_riscv_pri.h create mode 100644 drivers/gpu/drm/nouveau/include/nvhw/ref/gh100/dev_therm.h create mode 100644 drivers/gpu/drm/nouveau/include/nvhw/ref/gh100/dev_xtl_ep_pri.h create mode 100644 drivers/gpu/drm/nouveau/include/nvhw/ref/gh100/pri_nv_xal_ep.h create mode 100644 drivers/gpu/drm/nouveau/include/nvif/chan.h create mode 100644 drivers/gpu/drm/nouveau/include/nvif/pushc97b.h delete mode 100644 drivers/gpu/drm/nouveau/include/nvkm/engine/nvjpg.h delete mode 100644 drivers/gpu/drm/nouveau/include/nvkm/engine/ofa.h create mode 100644 drivers/gpu/drm/nouveau/include/nvkm/subdev/fsp.h delete mode 100644 drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/class/cl0000.h delete mode 100644 drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/class/cl0005.h delete mode 100644 drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/class/cl0080.h delete mode 100644 drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/class/cl2080.h delete mode 100644 drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/class/cl2080_notification.h delete mode 100644 drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/class/cl84a0.h delete mode 100644 drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/class/cl90f1.h delete mode 100644 drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/class/clc0b5sw.h delete mode 100644 drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl0073/ctrl0073common.h delete mode 100644 drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl0073/ctrl0073dfp.h delete mode 100644 drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl0073/ctrl0073dp.h delete mode 100644 drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl0073/ctrl0073specific.h delete mode 100644 drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl0073/ctrl0073system.h delete mode 100644 drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl0080/ctrl0080gpu.h delete mode 100644 drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl0080/ctrl0080gr.h delete mode 100644 drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl2080/ctrl2080bios.h delete mode 100644 drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl2080/ctrl2080ce.h delete mode 100644 drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl2080/ctrl2080event.h delete mode 100644 drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl2080/ctrl2080fb.h delete mode 100644 drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl2080/ctrl2080fifo.h delete mode 100644 drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl2080/ctrl2080gpu.h delete mode 100644 drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl2080/ctrl2080gr.h delete mode 100644 drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl2080/ctrl2080internal.h delete mode 100644 drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl90f1.h delete mode 100644 drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrla06f/ctrla06fgpfifo.h delete mode 100644 drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/nvlimits.h delete mode 100644 drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/nvos.h delete mode 100644 drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/shared/msgq/inc/msgq/msgq_priv.h delete mode 100644 drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/uproc/os/common/include/libos_init_args.h delete mode 100644 drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/arch/nvalloc/common/inc/gsp/gsp_fw_sr_meta.h delete mode 100644 drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/arch/nvalloc/common/inc/gsp/gsp_fw_wpr_meta.h delete mode 100644 drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/arch/nvalloc/common/inc/rmRiscvUcode.h delete mode 100644 drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/arch/nvalloc/common/inc/rmgspseq.h delete mode 100644 drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/generated/g_allclasses.h delete mode 100644 drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/generated/g_chipset_nvoc.h delete mode 100644 drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/generated/g_fbsr_nvoc.h delete mode 100644 drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/generated/g_gpu_nvoc.h delete mode 100644 drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/generated/g_kernel_channel_nvoc.h delete mode 100644 drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/generated/g_kernel_fifo_nvoc.h delete mode 100644 drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/generated/g_mem_desc_nvoc.h delete mode 100644 drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/generated/g_os_nvoc.h delete mode 100644 drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/generated/g_rpc-structures.h delete mode 100644 drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/generated/g_sdk-structures.h delete mode 100644 drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/inc/kernel/gpu/gpu_acpi_data.h delete mode 100644 drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/inc/kernel/gpu/gpu_engine_type.h delete mode 100644 drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/inc/kernel/gpu/gsp/gsp_fw_heap.h delete mode 100644 drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/inc/kernel/gpu/gsp/gsp_init_args.h delete mode 100644 drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/inc/kernel/gpu/gsp/gsp_static_config.h delete mode 100644 drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/inc/kernel/gpu/intr/engine_idx.h delete mode 100644 drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/inc/kernel/gpu/nvbitmask.h delete mode 100644 drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/inc/kernel/os/nv_memory_type.h delete mode 100644 drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/kernel/inc/vgpu/rpc_headers.h delete mode 100644 drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/kernel/inc/vgpu/sdk-structures.h create mode 100644 drivers/gpu/drm/nouveau/nvif/chan.c create mode 100644 drivers/gpu/drm/nouveau/nvif/chan506f.c create mode 100644 drivers/gpu/drm/nouveau/nvif/chan906f.c create mode 100644 drivers/gpu/drm/nouveau/nvif/chanc36f.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/ce/gb202.c delete mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/ce/r535.c delete mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/disp/ad102.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/fifo/gb202.c delete mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/gr/r535.c delete mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/nvdec/r535.c delete mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/nvenc/ga102.c delete mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/nvenc/r535.c delete mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/nvjpg/Kbuild delete mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/nvjpg/ad102.c delete mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/nvjpg/ga100.c delete mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/nvjpg/priv.h delete mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/nvjpg/r535.c delete mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/ofa/Kbuild delete mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/ofa/ad102.c delete mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/ofa/ga100.c delete mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/ofa/ga102.c delete mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/ofa/priv.h delete mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/ofa/r535.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/fb/gb100.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/fb/gb202.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/fb/gh100.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/fsp/Kbuild create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/fsp/base.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/fsp/gb100.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/fsp/gb202.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/fsp/gh100.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/fsp/priv.h create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/gb100.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/gb202.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/gh100.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/Kbuild create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ad10x.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/client.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/engine.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/engine.h create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ga100.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ga1xx.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gb10x.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gb20x.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gh100.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gpu.h create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gr.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gr.h create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/handles.h create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/nvdec.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/nvenc.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/Kbuild create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/alloc.c rename drivers/gpu/drm/nouveau/nvkm/subdev/{bar/r535.c => gsp/rm/r535/bar.c} (82%) create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/ce.c rename drivers/gpu/drm/nouveau/nvkm/{engine/nvdec/ga100.c => subdev/gsp/rm/r535/client.c} (69%) create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/ctrl.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/device.c rename drivers/gpu/drm/nouveau/nvkm/{engine/disp/r535.c => subdev/gsp/rm/r535/disp.c} (86%) rename drivers/gpu/drm/nouveau/nvkm/subdev/{instmem/r535.c => gsp/rm/r535/fbsr.c} (84%) rename drivers/gpu/drm/nouveau/nvkm/{engine/fifo/r535.c => subdev/gsp/rm/r535/fifo.c} (65%) create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gr.c rename drivers/gpu/drm/nouveau/nvkm/subdev/gsp/{r535.c => rm/r535/gsp.c} (61%) rename drivers/gpu/drm/nouveau/nvkm/{engine/nvenc/ad102.c => subdev/gsp/rm/r535/nvdec.c} (68%) rename drivers/gpu/drm/nouveau/nvkm/{engine/gr/ad102.c => subdev/gsp/rm/r535/nvenc.c} (68%) create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvjpg.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvrm/alloc.h create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvrm/bar.h create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvrm/ce.h create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvrm/client.h create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvrm/ctrl.h create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvrm/device.h create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvrm/disp.h create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvrm/engine.h create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvrm/event.h create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvrm/fbsr.h create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvrm/fifo.h rename drivers/gpu/drm/nouveau/{include/nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl0080/ctrl0080fifo.h => nvkm/subdev/gsp/rm/r535/nvrm/gr.h} (56%) create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvrm/gsp.h create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvrm/msgfn.h create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvrm/nvdec.h create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvrm/nvenc.h create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvrm/nvjpg.h create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvrm/ofa.h rename drivers/gpu/drm/nouveau/{include/nvrm/535.113.01/nvidia/kernel/inc/vgpu/rpc_global_enums.h => nvkm/subdev/gsp/rm/r535/nvrm/rpcfn.h} (83%) create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvrm/vmm.h rename drivers/gpu/drm/nouveau/nvkm/{engine/nvdec/ad102.c => subdev/gsp/rm/r535/ofa.c} (70%) create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rm.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rpc.c rename drivers/gpu/drm/nouveau/nvkm/subdev/{mmu/r535.c => gsp/rm/r535/vmm.c} (50%) create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/Kbuild create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/client.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/disp.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/fbsr.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/fifo.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/gr.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/gsp.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/nvrm/client.h create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/nvrm/disp.h create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/nvrm/engine.h create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/nvrm/fbsr.h rename drivers/gpu/drm/nouveau/{include/nvrm/535.113.01/common/sdk/nvidia/inc/alloc/alloc_channel.h => nvkm/subdev/gsp/rm/r570/nvrm/fifo.h} (62%) create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/nvrm/gr.h create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/nvrm/gsp.h create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/nvrm/msgfn.h create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/nvrm/ofa.h create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/nvrm/rpcfn.h create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/ofa.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/rm.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rpc.h create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/tu1xx.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gh100.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gh100.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgh100.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/pci/gh100.c -- 2.49.0
Ben Skeggs
2025-May-17 00:08 UTC
[PATCH v3 01/62] drm/nouveau/gsp: fix rm shutdown wait condition
Though the initial upstreamed GSP-RM version in nouveau was 535.113.01, the code was developed against earlier versions. 535.42.02 modified the mailbox value used by GSP-RM to signal shutdown has completed, which was missed at the time. I'm not aware of any issues caused by this, but noticed the bug while working on GB20x support. Signed-off-by: Ben Skeggs <bskeggs at nvidia.com> Reviewed-by: Dave Airlie <airlied at redhat.com> Reviewed-by: Timur Tabi <ttabi at nvidia.com> Tested-by: Timur Tabi <ttabi at nvidia.com> --- drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c index 969f6b921fdb..64b58efd3132 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c @@ -2844,7 +2844,7 @@ r535_gsp_fini(struct nvkm_gsp *gsp, bool suspend) return ret; nvkm_msec(gsp->subdev.device, 2000, - if (nvkm_falcon_rd32(&gsp->falcon, 0x040) & 0x80000000) + if (nvkm_falcon_rd32(&gsp->falcon, 0x040) == 0x80000000) break; ); -- 2.49.0
Ben Skeggs
2025-May-17 00:08 UTC
[PATCH v3 02/62] drm/nouveau/gsp: remove gsp-specific chid allocation path
In order to specify a channel ID to RM during channel allocation, the channel ID is broken down into a "userd page" index and an index into that page. It was assumed that RM would enforce that the same physical block of memory be used for all CHIDs within a "userd page", and the GSP paths override NVKM's normal CHID allocation to handle this. However, none of that turns out to be necessary. Remove the GSP-specific code and use the regular CHID allocation path. Signed-off-by: Ben Skeggs <bskeggs at nvidia.com> --- .../drm/nouveau/include/nvkm/engine/fifo.h | 3 - .../gpu/drm/nouveau/nvkm/engine/fifo/base.c | 5 - .../gpu/drm/nouveau/nvkm/engine/fifo/chan.c | 46 +++---- .../gpu/drm/nouveau/nvkm/engine/fifo/chan.h | 3 - .../gpu/drm/nouveau/nvkm/engine/fifo/r535.c | 115 ------------------ .../gpu/drm/nouveau/nvkm/subdev/gsp/r535.c | 2 +- 6 files changed, 20 insertions(+), 154 deletions(-) diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h index be508f65b280..96c16cfccf16 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h @@ -78,9 +78,6 @@ struct nvkm_fifo { struct { struct nvkm_memory *mem; struct nvkm_vma *bar1; - - struct mutex mutex; - struct list_head list; } userd; struct { diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/base.c index 22443fe4a39f..3c2ca711dc5c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/base.c @@ -349,8 +349,6 @@ nvkm_fifo_dtor(struct nvkm_engine *engine) nvkm_chid_unref(&fifo->cgid); nvkm_chid_unref(&fifo->chid); - mutex_destroy(&fifo->userd.mutex); - nvkm_event_fini(&fifo->nonstall.event); mutex_destroy(&fifo->mutex); @@ -391,8 +389,5 @@ nvkm_fifo_new_(const struct nvkm_fifo_func *func, struct nvkm_device *device, spin_lock_init(&fifo->lock); mutex_init(&fifo->mutex); - INIT_LIST_HEAD(&fifo->userd.list); - mutex_init(&fifo->userd.mutex); - return nvkm_engine_ctor(&nvkm_fifo, device, type, inst, true, &fifo->engine); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.c index 7d4716dcd512..78be7abc90d1 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.c @@ -275,11 +275,7 @@ nvkm_chan_del(struct nvkm_chan **pchan) nvkm_gpuobj_del(&chan->ramfc); if (chan->cgrp) { - if (!chan->func->id_put) - nvkm_chid_put(chan->cgrp->runl->chid, chan->id, &chan->cgrp->lock); - else - chan->func->id_put(chan); - + nvkm_chid_put(chan->cgrp->runl->chid, chan->id, &chan->cgrp->lock); nvkm_cgrp_unref(&chan->cgrp); } @@ -441,30 +437,26 @@ nvkm_chan_new_(const struct nvkm_chan_func *func, struct nvkm_runl *runl, int ru } /* Allocate channel ID. */ - if (!chan->func->id_get) { - chan->id = nvkm_chid_get(runl->chid, chan); - if (chan->id >= 0) { - if (func->userd->bar < 0) { - if (ouserd + chan->func->userd->size >- nvkm_memory_size(userd)) { - RUNL_DEBUG(runl, "ouserd %llx", ouserd); - return -EINVAL; - } - - ret = nvkm_memory_kmap(userd, &chan->userd.mem); - if (ret) { - RUNL_DEBUG(runl, "userd %d", ret); - return ret; - } - - chan->userd.base = ouserd; - } else { - chan->userd.mem = nvkm_memory_ref(fifo->userd.mem); - chan->userd.base = chan->id * chan->func->userd->size; + chan->id = nvkm_chid_get(runl->chid, chan); + if (chan->id >= 0) { + if (func->userd->bar < 0) { + if (ouserd + chan->func->userd->size >+ nvkm_memory_size(userd)) { + RUNL_DEBUG(runl, "ouserd %llx", ouserd); + return -EINVAL; + } + + ret = nvkm_memory_kmap(userd, &chan->userd.mem); + if (ret) { + RUNL_DEBUG(runl, "userd %d", ret); + return ret; } + + chan->userd.base = ouserd; + } else { + chan->userd.mem = nvkm_memory_ref(fifo->userd.mem); + chan->userd.base = chan->id * chan->func->userd->size; } - } else { - chan->id = chan->func->id_get(chan, userd, ouserd); } if (chan->id < 0) { diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.h b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.h index 013682a709d5..85b94f699128 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.h @@ -17,9 +17,6 @@ struct nvkm_cctx { }; struct nvkm_chan_func { - int (*id_get)(struct nvkm_chan *, struct nvkm_memory *userd, u64 ouserd); - void (*id_put)(struct nvkm_chan *); - const struct nvkm_chan_func_inst { u32 size; bool zero; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/r535.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/r535.c index 3454c7d29502..129f274c9bfd 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/r535.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/r535.c @@ -215,123 +215,8 @@ r535_chan_ramfc = { .priv = true, }; -struct r535_chan_userd { - struct nvkm_memory *mem; - struct nvkm_memory *map; - int chid; - u32 used; - - struct list_head head; -} *userd; - -static void -r535_chan_id_put(struct nvkm_chan *chan) -{ - struct nvkm_runl *runl = chan->cgrp->runl; - struct nvkm_fifo *fifo = runl->fifo; - struct r535_chan_userd *userd; - - mutex_lock(&fifo->userd.mutex); - list_for_each_entry(userd, &fifo->userd.list, head) { - if (userd->map == chan->userd.mem) { - u32 chid = chan->userd.base / chan->func->userd->size; - - userd->used &= ~BIT(chid); - if (!userd->used) { - nvkm_memory_unref(&userd->map); - nvkm_memory_unref(&userd->mem); - nvkm_chid_put(runl->chid, userd->chid, &chan->cgrp->lock); - list_del(&userd->head); - kfree(userd); - } - - break; - } - } - mutex_unlock(&fifo->userd.mutex); - -} - -static int -r535_chan_id_get_locked(struct nvkm_chan *chan, struct nvkm_memory *muserd, u64 ouserd) -{ - const u32 userd_size = CHID_PER_USERD * chan->func->userd->size; - struct nvkm_runl *runl = chan->cgrp->runl; - struct nvkm_fifo *fifo = runl->fifo; - struct r535_chan_userd *userd; - u32 chid; - int ret; - - if (ouserd + chan->func->userd->size >= userd_size || - (ouserd & (chan->func->userd->size - 1))) { - RUNL_DEBUG(runl, "ouserd %llx", ouserd); - return -EINVAL; - } - - chid = div_u64(ouserd, chan->func->userd->size); - - list_for_each_entry(userd, &fifo->userd.list, head) { - if (userd->mem == muserd) { - if (userd->used & BIT(chid)) - return -EBUSY; - break; - } - } - - if (&userd->head == &fifo->userd.list) { - if (nvkm_memory_size(muserd) < userd_size) { - RUNL_DEBUG(runl, "userd too small"); - return -EINVAL; - } - - userd = kzalloc(sizeof(*userd), GFP_KERNEL); - if (!userd) - return -ENOMEM; - - userd->chid = nvkm_chid_get(runl->chid, chan); - if (userd->chid < 0) { - ret = userd->chid; - kfree(userd); - return ret; - } - - userd->mem = nvkm_memory_ref(muserd); - - ret = nvkm_memory_kmap(userd->mem, &userd->map); - if (ret) { - nvkm_chid_put(runl->chid, userd->chid, &chan->cgrp->lock); - kfree(userd); - return ret; - } - - - list_add(&userd->head, &fifo->userd.list); - } - - userd->used |= BIT(chid); - - chan->userd.mem = nvkm_memory_ref(userd->map); - chan->userd.base = ouserd; - - return (userd->chid * CHID_PER_USERD) + chid; -} - -static int -r535_chan_id_get(struct nvkm_chan *chan, struct nvkm_memory *muserd, u64 ouserd) -{ - struct nvkm_fifo *fifo = chan->cgrp->runl->fifo; - int ret; - - mutex_lock(&fifo->userd.mutex); - ret = r535_chan_id_get_locked(chan, muserd, ouserd); - mutex_unlock(&fifo->userd.mutex); - return ret; -} - static const struct nvkm_chan_func r535_chan = { - .id_get = r535_chan_id_get, - .id_put = r535_chan_id_put, .inst = &gf100_chan_inst, .userd = &gv100_chan_userd, .ramfc = &r535_chan_ramfc, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c index 64b58efd3132..2bb726c0c49f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c @@ -1932,7 +1932,7 @@ r535_gsp_msg_rc_triggered(void *priv, u32 fn, void *repv, u32 repc) msg->nv2080EngineType, msg->chid, msg->exceptType, msg->scope, msg->partitionAttributionId); - chan = nvkm_chan_get_chid(&subdev->device->fifo->engine, msg->chid / 8, &flags); + chan = nvkm_chan_get_chid(&subdev->device->fifo->engine, msg->chid, &flags); if (!chan) { nvkm_error(subdev, "rc chid:%d not found!\n", msg->chid); return 0; -- 2.49.0
Ben Skeggs
2025-May-17 00:08 UTC
[PATCH v3 03/62] drm/nouveau/ce: bump max instances to 20
560.28.03 supports more copy engine instances. Signed-off-by: Ben Skeggs <bskeggs at nvidia.com> Reviewed-by: Dave Airlie <airlied at redhat.com> Reviewed-by: Timur Tabi <ttabi at nvidia.com> Tested-by: Timur Tabi <ttabi at nvidia.com> --- drivers/gpu/drm/nouveau/include/nvkm/core/layout.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/layout.h b/drivers/gpu/drm/nouveau/include/nvkm/core/layout.h index 9d2a1abf64f9..4e027c5b00c3 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/core/layout.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/layout.h @@ -29,7 +29,7 @@ NVKM_LAYOUT_INST(NVKM_SUBDEV_IOCTRL , struct nvkm_subdev , ioctrl, 3) NVKM_LAYOUT_ONCE(NVKM_SUBDEV_FLA , struct nvkm_subdev , fla) NVKM_LAYOUT_ONCE(NVKM_ENGINE_BSP , struct nvkm_engine , bsp) -NVKM_LAYOUT_INST(NVKM_ENGINE_CE , struct nvkm_engine , ce, 10) +NVKM_LAYOUT_INST(NVKM_ENGINE_CE , struct nvkm_engine , ce, 20) NVKM_LAYOUT_ONCE(NVKM_ENGINE_CIPHER , struct nvkm_engine , cipher) NVKM_LAYOUT_ONCE(NVKM_ENGINE_DISP , struct nvkm_disp , disp) NVKM_LAYOUT_ONCE(NVKM_ENGINE_DMAOBJ , struct nvkm_dma , dma) -- 2.49.0
Ben Skeggs
2025-May-17 00:08 UTC
[PATCH v3 04/62] drm/nouveau/nvenc: bump max instances to 4
570.86.16 supports more NVENC instances. Signed-off-by: Ben Skeggs <bskeggs at nvidia.com> Reviewed-by: Dave Airlie <airlied at redhat.com> Reviewed-by: Timur Tabi <ttabi at nvidia.com> Tested-by: Timur Tabi <ttabi at nvidia.com> --- drivers/gpu/drm/nouveau/include/nvkm/core/layout.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/layout.h b/drivers/gpu/drm/nouveau/include/nvkm/core/layout.h index 4e027c5b00c3..33e3bc519b9b 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/core/layout.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/layout.h @@ -43,7 +43,7 @@ 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, 8) -NVKM_LAYOUT_INST(NVKM_ENGINE_NVENC , struct nvkm_nvenc , nvenc, 3) +NVKM_LAYOUT_INST(NVKM_ENGINE_NVENC , struct nvkm_nvenc , nvenc, 4) 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_SEC , struct nvkm_engine , sec) -- 2.49.0
Ben Skeggs
2025-May-17 00:08 UTC
[PATCH v3 05/62] drm/nouveau/ofa: bump max instances to 2
560.28.03 supports more NVENC instances. Signed-off-by: Ben Skeggs <bskeggs at nvidia.com> Reviewed-by: Dave Airlie <airlied at redhat.com> Reviewed-by: Timur Tabi <ttabi at nvidia.com> Tested-by: Timur Tabi <ttabi at nvidia.com> --- drivers/gpu/drm/nouveau/include/nvkm/core/layout.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/layout.h b/drivers/gpu/drm/nouveau/include/nvkm/core/layout.h index 33e3bc519b9b..2debef27bd95 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/core/layout.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/layout.h @@ -45,7 +45,7 @@ NVKM_LAYOUT_ONCE(NVKM_ENGINE_MSVLD , struct nvkm_engine , msvld) NVKM_LAYOUT_INST(NVKM_ENGINE_NVDEC , struct nvkm_nvdec , nvdec, 8) NVKM_LAYOUT_INST(NVKM_ENGINE_NVENC , struct nvkm_nvenc , nvenc, 4) NVKM_LAYOUT_INST(NVKM_ENGINE_NVJPG , struct nvkm_engine , nvjpg, 8) -NVKM_LAYOUT_ONCE(NVKM_ENGINE_OFA , struct nvkm_engine , ofa) +NVKM_LAYOUT_INST(NVKM_ENGINE_OFA , struct nvkm_engine , ofa, 2) NVKM_LAYOUT_ONCE(NVKM_ENGINE_SEC , struct nvkm_engine , sec) NVKM_LAYOUT_ONCE(NVKM_ENGINE_SEC2 , struct nvkm_sec2 , sec2) NVKM_LAYOUT_ONCE(NVKM_ENGINE_SW , struct nvkm_sw , sw) -- 2.49.0
Ben Skeggs
2025-May-17 00:08 UTC
[PATCH v3 06/62] drm/nouveau/gsp: split rpc handling out on its own
Later patches in the series add HALs around various RM APIs in order to support a newer version of GSP-RM firmware. In order to do this, begin by splitting the code up into "modules" that roughly represent RM's API boundaries so they can be more easily managed. Aside from moving the RPC function pointers, no code change is indended. Signed-off-by: Ben Skeggs <bskeggs at nvidia.com> Reviewed-by: Dave Airlie <airlied at redhat.com> Reviewed-by: Timur Tabi <ttabi at nvidia.com> Tested-by: Timur Tabi <ttabi at nvidia.com> --- drivers/gpu/drm/nouveau/Kbuild | 1 + .../gpu/drm/nouveau/include/nvkm/subdev/gsp.h | 13 +- .../gpu/drm/nouveau/nvkm/subdev/gsp/Kbuild | 2 + .../gpu/drm/nouveau/nvkm/subdev/gsp/r535.c | 665 +---------------- .../gpu/drm/nouveau/nvkm/subdev/gsp/rm/Kbuild | 5 + .../nouveau/nvkm/subdev/gsp/rm/r535/Kbuild | 6 + .../drm/nouveau/nvkm/subdev/gsp/rm/r535/rm.c | 10 + .../drm/nouveau/nvkm/subdev/gsp/rm/r535/rpc.c | 692 ++++++++++++++++++ .../gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h | 20 + .../gpu/drm/nouveau/nvkm/subdev/gsp/rm/rpc.h | 18 + 10 files changed, 762 insertions(+), 670 deletions(-) create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/Kbuild create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/Kbuild create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rm.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rpc.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rpc.h diff --git a/drivers/gpu/drm/nouveau/Kbuild b/drivers/gpu/drm/nouveau/Kbuild index 7b863355c5c6..0759ba15954b 100644 --- a/drivers/gpu/drm/nouveau/Kbuild +++ b/drivers/gpu/drm/nouveau/Kbuild @@ -2,6 +2,7 @@ ccflags-y += -I $(src)/include ccflags-y += -I $(src)/include/nvkm ccflags-y += -I $(src)/nvkm +ccflags-y += -I $(src)/nvkm/subdev/gsp ccflags-y += -I $(src) # NVKM - HW resource manager diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h index 1c12854a8550..b543c31d3d32 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h @@ -210,10 +210,7 @@ struct nvkm_gsp { } gr; const struct nvkm_gsp_rm { - void *(*rpc_get)(struct nvkm_gsp *, u32 fn, u32 argc); - void *(*rpc_push)(struct nvkm_gsp *gsp, void *argv, - enum nvkm_gsp_rpc_reply_policy policy, u32 repc); - void (*rpc_done)(struct nvkm_gsp *gsp, void *repv); + const struct nvkm_rm_api *api; void *(*rm_ctrl_get)(struct nvkm_gsp_object *, u32 cmd, u32 argc); int (*rm_ctrl_push)(struct nvkm_gsp_object *, void **argv, u32 repc); @@ -272,17 +269,19 @@ nvkm_gsp_rm(struct nvkm_gsp *gsp) return gsp && (gsp->fws.rm || gsp->fw.img); } +#include <rm/rm.h> + static inline void * nvkm_gsp_rpc_get(struct nvkm_gsp *gsp, u32 fn, u32 argc) { - return gsp->rm->rpc_get(gsp, fn, argc); + return gsp->rm->api->rpc->get(gsp, fn, argc); } static inline void * nvkm_gsp_rpc_push(struct nvkm_gsp *gsp, void *argv, enum nvkm_gsp_rpc_reply_policy policy, u32 repc) { - return gsp->rm->rpc_push(gsp, argv, policy, repc); + return gsp->rm->api->rpc->push(gsp, argv, policy, repc); } static inline void * @@ -311,7 +310,7 @@ nvkm_gsp_rpc_wr(struct nvkm_gsp *gsp, void *argv, static inline void nvkm_gsp_rpc_done(struct nvkm_gsp *gsp, void *repv) { - gsp->rm->rpc_done(gsp, repv); + gsp->rm->api->rpc->done(gsp, repv); } static inline void * diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/Kbuild index 16bf2f1bb780..af6e55603763 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/Kbuild @@ -10,3 +10,5 @@ nvkm-y += nvkm/subdev/gsp/ga102.o nvkm-y += nvkm/subdev/gsp/ad102.o nvkm-y += nvkm/subdev/gsp/r535.o + +include $(src)/nvkm/subdev/gsp/rm/Kbuild diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c index 2bb726c0c49f..745d43586bad 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c @@ -19,6 +19,7 @@ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ +#include <rm/rpc.h> #include "priv.h" #include <core/pci.h> @@ -60,578 +61,6 @@ extern struct dentry *nouveau_debugfs_root; -#define GSP_MSG_MIN_SIZE GSP_PAGE_SIZE -#define GSP_MSG_MAX_SIZE (GSP_MSG_MIN_SIZE * 16) - -/** - * DOC: GSP message queue element - * - * https://github.com/NVIDIA/open-gpu-kernel-modules/blob/535/src/nvidia/inc/kernel/gpu/gsp/message_queue_priv.h - * - * The GSP command queue and status queue are message queues for the - * communication between software and GSP. The software submits the GSP - * RPC via the GSP command queue, GSP writes the status of the submitted - * RPC in the status queue. - * - * A GSP message queue element consists of three parts: - * - * - message element header (struct r535_gsp_msg), which mostly maintains - * the metadata for queuing the element. - * - * - RPC message header (struct nvfw_gsp_rpc), which maintains the info - * of the RPC. E.g., the RPC function number. - * - * - The payload, where the RPC message stays. E.g. the params of a - * specific RPC function. Some RPC functions also have their headers - * in the payload. E.g. rm_alloc, rm_control. - * - * The memory layout of a GSP message element can be illustrated below:: - * - * +------------------------+ - * | Message Element Header | - * | (r535_gsp_msg) | - * | | - * | (r535_gsp_msg.data) | - * | | | - * |----------V-------------| - * | GSP RPC Header | - * | (nvfw_gsp_rpc) | - * | | - * | (nvfw_gsp_rpc.data) | - * | | | - * |----------V-------------| - * | Payload | - * | | - * | header(optional) | - * | params | - * +------------------------+ - * - * The max size of a message queue element is 16 pages (including the - * headers). When a GSP message to be sent is larger than 16 pages, the - * message should be split into multiple elements and sent accordingly. - * - * In the bunch of the split elements, the first element has the expected - * function number, while the rest of the elements are sent with the - * function number NV_VGPU_MSG_FUNCTION_CONTINUATION_RECORD. - * - * GSP consumes the elements from the cmdq and always writes the result - * back to the msgq. The result is also formed as split elements. - * - * Terminology: - * - * - gsp_msg(msg): GSP message element (element header + GSP RPC header + - * payload) - * - gsp_rpc(rpc): GSP RPC (RPC header + payload) - * - gsp_rpc_buf: buffer for (GSP RPC header + payload) - * - gsp_rpc_len: size of (GSP RPC header + payload) - * - params_size: size of params in the payload - * - payload_size: size of (header if exists + params) in the payload - */ - -struct r535_gsp_msg { - u8 auth_tag_buffer[16]; - u8 aad_buffer[16]; - u32 checksum; - u32 sequence; - u32 elem_count; - u32 pad; - u8 data[]; -}; - -struct nvfw_gsp_rpc { - u32 header_version; - u32 signature; - u32 length; - u32 function; - u32 rpc_result; - u32 rpc_result_private; - u32 sequence; - union { - u32 spare; - u32 cpuRmGfid; - }; - u8 data[]; -}; - -#define GSP_MSG_HDR_SIZE offsetof(struct r535_gsp_msg, data) - -#define to_gsp_hdr(p, header) \ - container_of((void *)p, typeof(*header), data) - -#define to_payload_hdr(p, header) \ - container_of((void *)p, typeof(*header), params) - -static int -r535_rpc_status_to_errno(uint32_t rpc_status) -{ - switch (rpc_status) { - case 0x55: /* NV_ERR_NOT_READY */ - case 0x66: /* NV_ERR_TIMEOUT_RETRY */ - return -EBUSY; - case 0x51: /* NV_ERR_NO_MEMORY */ - return -ENOMEM; - default: - return -EINVAL; - } -} - -static int -r535_gsp_msgq_wait(struct nvkm_gsp *gsp, u32 gsp_rpc_len, int *ptime) -{ - u32 size, rptr = *gsp->msgq.rptr; - int used; - - size = DIV_ROUND_UP(GSP_MSG_HDR_SIZE + gsp_rpc_len, - GSP_PAGE_SIZE); - if (WARN_ON(!size || size >= gsp->msgq.cnt)) - return -EINVAL; - - do { - u32 wptr = *gsp->msgq.wptr; - - used = wptr + gsp->msgq.cnt - rptr; - if (used >= gsp->msgq.cnt) - used -= gsp->msgq.cnt; - if (used >= size) - break; - - usleep_range(1, 2); - } while (--(*ptime)); - - if (WARN_ON(!*ptime)) - return -ETIMEDOUT; - - return used; -} - -static struct r535_gsp_msg * -r535_gsp_msgq_get_entry(struct nvkm_gsp *gsp) -{ - u32 rptr = *gsp->msgq.rptr; - - /* Skip the first page, which is the message queue info */ - return (void *)((u8 *)gsp->shm.msgq.ptr + GSP_PAGE_SIZE + - rptr * GSP_PAGE_SIZE); -} - -/** - * DOC: Receive a GSP message queue element - * - * Receiving a GSP message queue element from the message queue consists of - * the following steps: - * - * - Peek the element from the queue: r535_gsp_msgq_peek(). - * Peek the first page of the element to determine the total size of the - * message before allocating the proper memory. - * - * - Allocate memory for the message. - * Once the total size of the message is determined from the GSP message - * queue element, the caller of r535_gsp_msgq_recv() allocates the - * required memory. - * - * - Receive the message: r535_gsp_msgq_recv(). - * Copy the message into the allocated memory. Advance the read pointer. - * If the message is a large GSP message, r535_gsp_msgq_recv() calls - * r535_gsp_msgq_recv_one_elem() repeatedly to receive continuation parts - * until the complete message is received. - * r535_gsp_msgq_recv() assembles the payloads of cotinuation parts into - * the return of the large GSP message. - * - * - Free the allocated memory: r535_gsp_msg_done(). - * The user is responsible for freeing the memory allocated for the GSP - * message pages after they have been processed. - */ -static void * -r535_gsp_msgq_peek(struct nvkm_gsp *gsp, u32 gsp_rpc_len, int *retries) -{ - struct r535_gsp_msg *mqe; - int ret; - - ret = r535_gsp_msgq_wait(gsp, gsp_rpc_len, retries); - if (ret < 0) - return ERR_PTR(ret); - - mqe = r535_gsp_msgq_get_entry(gsp); - - return mqe->data; -} - -struct r535_gsp_msg_info { - int *retries; - u32 gsp_rpc_len; - void *gsp_rpc_buf; - bool continuation; -}; - -static void -r535_gsp_msg_dump(struct nvkm_gsp *gsp, struct nvfw_gsp_rpc *msg, int lvl); - -static void * -r535_gsp_msgq_recv_one_elem(struct nvkm_gsp *gsp, - struct r535_gsp_msg_info *info) -{ - u8 *buf = info->gsp_rpc_buf; - u32 rptr = *gsp->msgq.rptr; - struct r535_gsp_msg *mqe; - u32 size, expected, len; - int ret; - - expected = info->gsp_rpc_len; - - ret = r535_gsp_msgq_wait(gsp, expected, info->retries); - if (ret < 0) - return ERR_PTR(ret); - - mqe = r535_gsp_msgq_get_entry(gsp); - - if (info->continuation) { - struct nvfw_gsp_rpc *rpc = (struct nvfw_gsp_rpc *)mqe->data; - - if (rpc->function != NV_VGPU_MSG_FUNCTION_CONTINUATION_RECORD) { - nvkm_error(&gsp->subdev, - "Not a continuation of a large RPC\n"); - r535_gsp_msg_dump(gsp, rpc, NV_DBG_ERROR); - return ERR_PTR(-EIO); - } - } - - size = ALIGN(expected + GSP_MSG_HDR_SIZE, GSP_PAGE_SIZE); - - len = ((gsp->msgq.cnt - rptr) * GSP_PAGE_SIZE) - sizeof(*mqe); - len = min_t(u32, expected, len); - - if (info->continuation) - memcpy(buf, mqe->data + sizeof(struct nvfw_gsp_rpc), - len - sizeof(struct nvfw_gsp_rpc)); - else - memcpy(buf, mqe->data, len); - - expected -= len; - - if (expected) { - mqe = (void *)((u8 *)gsp->shm.msgq.ptr + 0x1000 + 0 * 0x1000); - memcpy(buf + len, mqe, expected); - } - - rptr = (rptr + DIV_ROUND_UP(size, GSP_PAGE_SIZE)) % gsp->msgq.cnt; - - mb(); - (*gsp->msgq.rptr) = rptr; - return buf; -} - -static void * -r535_gsp_msgq_recv(struct nvkm_gsp *gsp, u32 gsp_rpc_len, int *retries) -{ - struct r535_gsp_msg *mqe; - const u32 max_rpc_size = GSP_MSG_MAX_SIZE - sizeof(*mqe); - struct nvfw_gsp_rpc *rpc; - struct r535_gsp_msg_info info = {0}; - u32 expected = gsp_rpc_len; - void *buf; - - mqe = r535_gsp_msgq_get_entry(gsp); - rpc = (struct nvfw_gsp_rpc *)mqe->data; - - if (WARN_ON(rpc->length > max_rpc_size)) - return NULL; - - buf = kvmalloc(max_t(u32, rpc->length, expected), GFP_KERNEL); - if (!buf) - return ERR_PTR(-ENOMEM); - - info.gsp_rpc_buf = buf; - info.retries = retries; - info.gsp_rpc_len = rpc->length; - - buf = r535_gsp_msgq_recv_one_elem(gsp, &info); - if (IS_ERR(buf)) { - kvfree(info.gsp_rpc_buf); - info.gsp_rpc_buf = NULL; - return buf; - } - - if (expected <= max_rpc_size) - return buf; - - info.gsp_rpc_buf += info.gsp_rpc_len; - expected -= info.gsp_rpc_len; - - while (expected) { - u32 size; - - rpc = r535_gsp_msgq_peek(gsp, sizeof(*rpc), info.retries); - if (IS_ERR_OR_NULL(rpc)) { - kfree(buf); - return rpc; - } - - info.gsp_rpc_len = rpc->length; - info.continuation = true; - - rpc = r535_gsp_msgq_recv_one_elem(gsp, &info); - if (IS_ERR_OR_NULL(rpc)) { - kfree(buf); - return rpc; - } - - size = info.gsp_rpc_len - sizeof(*rpc); - expected -= size; - info.gsp_rpc_buf += size; - } - - rpc = buf; - rpc->length = gsp_rpc_len; - return buf; -} - -static int -r535_gsp_cmdq_push(struct nvkm_gsp *gsp, void *rpc) -{ - struct r535_gsp_msg *msg = to_gsp_hdr(rpc, msg); - struct r535_gsp_msg *cqe; - u32 gsp_rpc_len = msg->checksum; - u64 *ptr = (void *)msg; - u64 *end; - u64 csum = 0; - int free, time = 1000000; - u32 wptr, size, step, len; - u32 off = 0; - - len = ALIGN(GSP_MSG_HDR_SIZE + gsp_rpc_len, GSP_PAGE_SIZE); - - end = (u64 *)((char *)ptr + len); - msg->pad = 0; - msg->checksum = 0; - msg->sequence = gsp->cmdq.seq++; - msg->elem_count = DIV_ROUND_UP(len, 0x1000); - - while (ptr < end) - csum ^= *ptr++; - - msg->checksum = upper_32_bits(csum) ^ lower_32_bits(csum); - - wptr = *gsp->cmdq.wptr; - do { - do { - free = *gsp->cmdq.rptr + gsp->cmdq.cnt - wptr - 1; - if (free >= gsp->cmdq.cnt) - free -= gsp->cmdq.cnt; - if (free >= 1) - break; - - usleep_range(1, 2); - } while(--time); - - if (WARN_ON(!time)) { - kvfree(msg); - return -ETIMEDOUT; - } - - cqe = (void *)((u8 *)gsp->shm.cmdq.ptr + 0x1000 + wptr * 0x1000); - step = min_t(u32, free, (gsp->cmdq.cnt - wptr)); - size = min_t(u32, len, step * GSP_PAGE_SIZE); - - memcpy(cqe, (u8 *)msg + off, size); - - wptr += DIV_ROUND_UP(size, 0x1000); - if (wptr == gsp->cmdq.cnt) - wptr = 0; - - off += size; - len -= size; - } while (len); - - nvkm_trace(&gsp->subdev, "cmdq: wptr %d\n", wptr); - wmb(); - (*gsp->cmdq.wptr) = wptr; - mb(); - - nvkm_falcon_wr32(&gsp->falcon, 0xc00, 0x00000000); - - kvfree(msg); - return 0; -} - -static void * -r535_gsp_cmdq_get(struct nvkm_gsp *gsp, u32 gsp_rpc_len) -{ - struct r535_gsp_msg *msg; - u32 size = GSP_MSG_HDR_SIZE + gsp_rpc_len; - - size = ALIGN(size, GSP_MSG_MIN_SIZE); - msg = kvzalloc(size, GFP_KERNEL); - if (!msg) - return ERR_PTR(-ENOMEM); - - msg->checksum = gsp_rpc_len; - return msg->data; -} - -static void -r535_gsp_msg_done(struct nvkm_gsp *gsp, struct nvfw_gsp_rpc *msg) -{ - kvfree(msg); -} - -static void -r535_gsp_msg_dump(struct nvkm_gsp *gsp, struct nvfw_gsp_rpc *msg, int lvl) -{ - if (gsp->subdev.debug >= lvl) { - nvkm_printk__(&gsp->subdev, lvl, info, - "msg fn:%d len:0x%x/0x%zx res:0x%x resp:0x%x\n", - msg->function, msg->length, msg->length - sizeof(*msg), - msg->rpc_result, msg->rpc_result_private); - print_hex_dump(KERN_INFO, "msg: ", DUMP_PREFIX_OFFSET, 16, 1, - msg->data, msg->length - sizeof(*msg), true); - } -} - -static struct nvfw_gsp_rpc * -r535_gsp_msg_recv(struct nvkm_gsp *gsp, int fn, u32 gsp_rpc_len) -{ - struct nvkm_subdev *subdev = &gsp->subdev; - struct nvfw_gsp_rpc *rpc; - int retries = 4000000, i; - -retry: - rpc = r535_gsp_msgq_peek(gsp, sizeof(*rpc), &retries); - if (IS_ERR_OR_NULL(rpc)) - return rpc; - - rpc = r535_gsp_msgq_recv(gsp, gsp_rpc_len, &retries); - if (IS_ERR_OR_NULL(rpc)) - return rpc; - - if (rpc->rpc_result) { - r535_gsp_msg_dump(gsp, rpc, NV_DBG_ERROR); - r535_gsp_msg_done(gsp, rpc); - return ERR_PTR(-EINVAL); - } - - r535_gsp_msg_dump(gsp, rpc, NV_DBG_TRACE); - - if (fn && rpc->function == fn) { - if (gsp_rpc_len) { - if (rpc->length < gsp_rpc_len) { - nvkm_error(subdev, "rpc len %d < %d\n", - rpc->length, gsp_rpc_len); - r535_gsp_msg_dump(gsp, rpc, NV_DBG_ERROR); - r535_gsp_msg_done(gsp, rpc); - return ERR_PTR(-EIO); - } - - return rpc; - } - - r535_gsp_msg_done(gsp, rpc); - return NULL; - } - - for (i = 0; i < gsp->msgq.ntfy_nr; i++) { - struct nvkm_gsp_msgq_ntfy *ntfy = &gsp->msgq.ntfy[i]; - - if (ntfy->fn == rpc->function) { - if (ntfy->func) - ntfy->func(ntfy->priv, ntfy->fn, rpc->data, - rpc->length - sizeof(*rpc)); - break; - } - } - - if (i == gsp->msgq.ntfy_nr) - r535_gsp_msg_dump(gsp, rpc, NV_DBG_WARN); - - r535_gsp_msg_done(gsp, rpc); - if (fn) - goto retry; - - if (*gsp->msgq.rptr != *gsp->msgq.wptr) - goto retry; - - return NULL; -} - -static int -r535_gsp_msg_ntfy_add(struct nvkm_gsp *gsp, u32 fn, nvkm_gsp_msg_ntfy_func func, void *priv) -{ - int ret = 0; - - mutex_lock(&gsp->msgq.mutex); - if (WARN_ON(gsp->msgq.ntfy_nr >= ARRAY_SIZE(gsp->msgq.ntfy))) { - ret = -ENOSPC; - } else { - gsp->msgq.ntfy[gsp->msgq.ntfy_nr].fn = fn; - gsp->msgq.ntfy[gsp->msgq.ntfy_nr].func = func; - gsp->msgq.ntfy[gsp->msgq.ntfy_nr].priv = priv; - gsp->msgq.ntfy_nr++; - } - mutex_unlock(&gsp->msgq.mutex); - return ret; -} - -static int -r535_gsp_rpc_poll(struct nvkm_gsp *gsp, u32 fn) -{ - void *repv; - - mutex_lock(&gsp->cmdq.mutex); - repv = r535_gsp_msg_recv(gsp, fn, 0); - mutex_unlock(&gsp->cmdq.mutex); - if (IS_ERR(repv)) - return PTR_ERR(repv); - - return 0; -} - -static void * -r535_gsp_rpc_handle_reply(struct nvkm_gsp *gsp, u32 fn, - enum nvkm_gsp_rpc_reply_policy policy, - u32 gsp_rpc_len) -{ - struct nvfw_gsp_rpc *reply; - void *repv = NULL; - - switch (policy) { - case NVKM_GSP_RPC_REPLY_NOWAIT: - break; - case NVKM_GSP_RPC_REPLY_RECV: - reply = r535_gsp_msg_recv(gsp, fn, gsp_rpc_len); - if (!IS_ERR_OR_NULL(reply)) - repv = reply->data; - else - repv = reply; - break; - case NVKM_GSP_RPC_REPLY_POLL: - repv = r535_gsp_msg_recv(gsp, fn, 0); - break; - } - - return repv; -} - -static void * -r535_gsp_rpc_send(struct nvkm_gsp *gsp, void *payload, - enum nvkm_gsp_rpc_reply_policy policy, u32 gsp_rpc_len) -{ - struct nvfw_gsp_rpc *rpc = to_gsp_hdr(payload, rpc); - u32 fn = rpc->function; - int ret; - - if (gsp->subdev.debug >= NV_DBG_TRACE) { - nvkm_trace(&gsp->subdev, "rpc fn:%d len:0x%x/0x%zx\n", rpc->function, - rpc->length, rpc->length - sizeof(*rpc)); - print_hex_dump(KERN_INFO, "rpc: ", DUMP_PREFIX_OFFSET, 16, 1, - rpc->data, rpc->length - sizeof(*rpc), true); - } - - ret = r535_gsp_cmdq_push(gsp, rpc); - if (ret) - return ERR_PTR(ret); - - return r535_gsp_rpc_handle_reply(gsp, fn, policy, gsp_rpc_len); -} - static void r535_gsp_event_dtor(struct nvkm_gsp_event *event) { @@ -936,99 +365,9 @@ r535_gsp_rpc_rm_ctrl_get(struct nvkm_gsp_object *object, u32 cmd, u32 params_siz return rpc->params; } -static void -r535_gsp_rpc_done(struct nvkm_gsp *gsp, void *repv) -{ - struct nvfw_gsp_rpc *rpc = container_of(repv, typeof(*rpc), data); - - r535_gsp_msg_done(gsp, rpc); -} - -static void * -r535_gsp_rpc_get(struct nvkm_gsp *gsp, u32 fn, u32 payload_size) -{ - struct nvfw_gsp_rpc *rpc; - - rpc = r535_gsp_cmdq_get(gsp, ALIGN(sizeof(*rpc) + payload_size, - sizeof(u64))); - if (IS_ERR(rpc)) - return ERR_CAST(rpc); - - rpc->header_version = 0x03000000; - rpc->signature = ('C' << 24) | ('P' << 16) | ('R' << 8) | 'V'; - rpc->function = fn; - rpc->rpc_result = 0xffffffff; - rpc->rpc_result_private = 0xffffffff; - rpc->length = sizeof(*rpc) + payload_size; - return rpc->data; -} - -static void * -r535_gsp_rpc_push(struct nvkm_gsp *gsp, void *payload, - enum nvkm_gsp_rpc_reply_policy policy, u32 gsp_rpc_len) -{ - struct nvfw_gsp_rpc *rpc = to_gsp_hdr(payload, rpc); - struct r535_gsp_msg *msg = to_gsp_hdr(rpc, msg); - const u32 max_rpc_size = GSP_MSG_MAX_SIZE - sizeof(*msg); - const u32 max_payload_size = max_rpc_size - sizeof(*rpc); - u32 payload_size = rpc->length - sizeof(*rpc); - void *repv; - - mutex_lock(&gsp->cmdq.mutex); - if (payload_size > max_payload_size) { - const u32 fn = rpc->function; - u32 remain_payload_size = payload_size; - - /* Adjust length, and send initial RPC. */ - rpc->length = sizeof(*rpc) + max_payload_size; - msg->checksum = rpc->length; - - repv = r535_gsp_rpc_send(gsp, payload, NVKM_GSP_RPC_REPLY_NOWAIT, 0); - if (IS_ERR(repv)) - goto done; - - payload += max_payload_size; - remain_payload_size -= max_payload_size; - - /* Remaining chunks sent as CONTINUATION_RECORD RPCs. */ - while (remain_payload_size) { - u32 size = min(remain_payload_size, - max_payload_size); - void *next; - - next = r535_gsp_rpc_get(gsp, NV_VGPU_MSG_FUNCTION_CONTINUATION_RECORD, size); - if (IS_ERR(next)) { - repv = next; - goto done; - } - - memcpy(next, payload, size); - - repv = r535_gsp_rpc_send(gsp, next, NVKM_GSP_RPC_REPLY_NOWAIT, 0); - if (IS_ERR(repv)) - goto done; - - payload += size; - remain_payload_size -= size; - } - - /* Wait for reply. */ - repv = r535_gsp_rpc_handle_reply(gsp, fn, policy, payload_size + - sizeof(*rpc)); - } else { - repv = r535_gsp_rpc_send(gsp, payload, policy, gsp_rpc_len); - } - -done: - mutex_unlock(&gsp->cmdq.mutex); - return repv; -} - const struct nvkm_gsp_rm r535_gsp_rm = { - .rpc_get = r535_gsp_rpc_get, - .rpc_push = r535_gsp_rpc_push, - .rpc_done = r535_gsp_rpc_done, + .api = &r535_rm, .rm_ctrl_get = r535_gsp_rpc_rm_ctrl_get, .rm_ctrl_push = r535_gsp_rpc_rm_ctrl_push, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/Kbuild new file mode 100644 index 000000000000..1c07740215ec --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/Kbuild @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: MIT +# +# Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + +include $(src)/nvkm/subdev/gsp/rm/r535/Kbuild diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/Kbuild new file mode 100644 index 000000000000..21c818ec0701 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/Kbuild @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: MIT +# +# Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + +nvkm-y += nvkm/subdev/gsp/rm/r535/rm.o +nvkm-y += nvkm/subdev/gsp/rm/r535/rpc.o diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rm.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rm.c new file mode 100644 index 000000000000..f28b781abc5c --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rm.c @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#include <rm/rm.h> + +const struct nvkm_rm_api +r535_rm = { + .rpc = &r535_rpc, +}; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rpc.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rpc.c new file mode 100644 index 000000000000..ffb4104a7d8c --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rpc.c @@ -0,0 +1,692 @@ +/* + * 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 <rm/rpc.h> + +#include <nvrm/nvtypes.h> +#include <nvrm/535.113.01/nvidia/kernel/inc/vgpu/rpc_global_enums.h> + +#define GSP_MSG_MIN_SIZE GSP_PAGE_SIZE +#define GSP_MSG_MAX_SIZE (GSP_MSG_MIN_SIZE * 16) + +/** + * DOC: GSP message queue element + * + * https://github.com/NVIDIA/open-gpu-kernel-modules/blob/535/src/nvidia/inc/kernel/gpu/gsp/message_queue_priv.h + * + * The GSP command queue and status queue are message queues for the + * communication between software and GSP. The software submits the GSP + * RPC via the GSP command queue, GSP writes the status of the submitted + * RPC in the status queue. + * + * A GSP message queue element consists of three parts: + * + * - message element header (struct r535_gsp_msg), which mostly maintains + * the metadata for queuing the element. + * + * - RPC message header (struct nvfw_gsp_rpc), which maintains the info + * of the RPC. E.g., the RPC function number. + * + * - The payload, where the RPC message stays. E.g. the params of a + * specific RPC function. Some RPC functions also have their headers + * in the payload. E.g. rm_alloc, rm_control. + * + * The memory layout of a GSP message element can be illustrated below:: + * + * +------------------------+ + * | Message Element Header | + * | (r535_gsp_msg) | + * | | + * | (r535_gsp_msg.data) | + * | | | + * |----------V-------------| + * | GSP RPC Header | + * | (nvfw_gsp_rpc) | + * | | + * | (nvfw_gsp_rpc.data) | + * | | | + * |----------V-------------| + * | Payload | + * | | + * | header(optional) | + * | params | + * +------------------------+ + * + * The max size of a message queue element is 16 pages (including the + * headers). When a GSP message to be sent is larger than 16 pages, the + * message should be split into multiple elements and sent accordingly. + * + * In the bunch of the split elements, the first element has the expected + * function number, while the rest of the elements are sent with the + * function number NV_VGPU_MSG_FUNCTION_CONTINUATION_RECORD. + * + * GSP consumes the elements from the cmdq and always writes the result + * back to the msgq. The result is also formed as split elements. + * + * Terminology: + * + * - gsp_msg(msg): GSP message element (element header + GSP RPC header + + * payload) + * - gsp_rpc(rpc): GSP RPC (RPC header + payload) + * - gsp_rpc_buf: buffer for (GSP RPC header + payload) + * - gsp_rpc_len: size of (GSP RPC header + payload) + * - params_size: size of params in the payload + * - payload_size: size of (header if exists + params) in the payload + */ + +struct r535_gsp_msg { + u8 auth_tag_buffer[16]; + u8 aad_buffer[16]; + u32 checksum; + u32 sequence; + u32 elem_count; + u32 pad; + u8 data[]; +}; + +struct nvfw_gsp_rpc { + u32 header_version; + u32 signature; + u32 length; + u32 function; + u32 rpc_result; + u32 rpc_result_private; + u32 sequence; + union { + u32 spare; + u32 cpuRmGfid; + }; + u8 data[]; +}; + +#define GSP_MSG_HDR_SIZE offsetof(struct r535_gsp_msg, data) + +#define to_gsp_hdr(p, header) \ + container_of((void *)p, typeof(*header), data) + +#define to_payload_hdr(p, header) \ + container_of((void *)p, typeof(*header), params) + +int +r535_rpc_status_to_errno(uint32_t rpc_status) +{ + switch (rpc_status) { + case 0x55: /* NV_ERR_NOT_READY */ + case 0x66: /* NV_ERR_TIMEOUT_RETRY */ + return -EBUSY; + case 0x51: /* NV_ERR_NO_MEMORY */ + return -ENOMEM; + default: + return -EINVAL; + } +} + +static int +r535_gsp_msgq_wait(struct nvkm_gsp *gsp, u32 gsp_rpc_len, int *ptime) +{ + u32 size, rptr = *gsp->msgq.rptr; + int used; + + size = DIV_ROUND_UP(GSP_MSG_HDR_SIZE + gsp_rpc_len, + GSP_PAGE_SIZE); + if (WARN_ON(!size || size >= gsp->msgq.cnt)) + return -EINVAL; + + do { + u32 wptr = *gsp->msgq.wptr; + + used = wptr + gsp->msgq.cnt - rptr; + if (used >= gsp->msgq.cnt) + used -= gsp->msgq.cnt; + if (used >= size) + break; + + usleep_range(1, 2); + } while (--(*ptime)); + + if (WARN_ON(!*ptime)) + return -ETIMEDOUT; + + return used; +} + +static struct r535_gsp_msg * +r535_gsp_msgq_get_entry(struct nvkm_gsp *gsp) +{ + u32 rptr = *gsp->msgq.rptr; + + /* Skip the first page, which is the message queue info */ + return (void *)((u8 *)gsp->shm.msgq.ptr + GSP_PAGE_SIZE + + rptr * GSP_PAGE_SIZE); +} + +/** + * DOC: Receive a GSP message queue element + * + * Receiving a GSP message queue element from the message queue consists of + * the following steps: + * + * - Peek the element from the queue: r535_gsp_msgq_peek(). + * Peek the first page of the element to determine the total size of the + * message before allocating the proper memory. + * + * - Allocate memory for the message. + * Once the total size of the message is determined from the GSP message + * queue element, the caller of r535_gsp_msgq_recv() allocates the + * required memory. + * + * - Receive the message: r535_gsp_msgq_recv(). + * Copy the message into the allocated memory. Advance the read pointer. + * If the message is a large GSP message, r535_gsp_msgq_recv() calls + * r535_gsp_msgq_recv_one_elem() repeatedly to receive continuation parts + * until the complete message is received. + * r535_gsp_msgq_recv() assembles the payloads of cotinuation parts into + * the return of the large GSP message. + * + * - Free the allocated memory: r535_gsp_msg_done(). + * The user is responsible for freeing the memory allocated for the GSP + * message pages after they have been processed. + */ +static void * +r535_gsp_msgq_peek(struct nvkm_gsp *gsp, u32 gsp_rpc_len, int *retries) +{ + struct r535_gsp_msg *mqe; + int ret; + + ret = r535_gsp_msgq_wait(gsp, gsp_rpc_len, retries); + if (ret < 0) + return ERR_PTR(ret); + + mqe = r535_gsp_msgq_get_entry(gsp); + + return mqe->data; +} + +struct r535_gsp_msg_info { + int *retries; + u32 gsp_rpc_len; + void *gsp_rpc_buf; + bool continuation; +}; + +static void +r535_gsp_msg_dump(struct nvkm_gsp *gsp, struct nvfw_gsp_rpc *msg, int lvl); + +static void * +r535_gsp_msgq_recv_one_elem(struct nvkm_gsp *gsp, + struct r535_gsp_msg_info *info) +{ + u8 *buf = info->gsp_rpc_buf; + u32 rptr = *gsp->msgq.rptr; + struct r535_gsp_msg *mqe; + u32 size, expected, len; + int ret; + + expected = info->gsp_rpc_len; + + ret = r535_gsp_msgq_wait(gsp, expected, info->retries); + if (ret < 0) + return ERR_PTR(ret); + + mqe = r535_gsp_msgq_get_entry(gsp); + + if (info->continuation) { + struct nvfw_gsp_rpc *rpc = (struct nvfw_gsp_rpc *)mqe->data; + + if (rpc->function != NV_VGPU_MSG_FUNCTION_CONTINUATION_RECORD) { + nvkm_error(&gsp->subdev, + "Not a continuation of a large RPC\n"); + r535_gsp_msg_dump(gsp, rpc, NV_DBG_ERROR); + return ERR_PTR(-EIO); + } + } + + size = ALIGN(expected + GSP_MSG_HDR_SIZE, GSP_PAGE_SIZE); + + len = ((gsp->msgq.cnt - rptr) * GSP_PAGE_SIZE) - sizeof(*mqe); + len = min_t(u32, expected, len); + + if (info->continuation) + memcpy(buf, mqe->data + sizeof(struct nvfw_gsp_rpc), + len - sizeof(struct nvfw_gsp_rpc)); + else + memcpy(buf, mqe->data, len); + + expected -= len; + + if (expected) { + mqe = (void *)((u8 *)gsp->shm.msgq.ptr + 0x1000 + 0 * 0x1000); + memcpy(buf + len, mqe, expected); + } + + rptr = (rptr + DIV_ROUND_UP(size, GSP_PAGE_SIZE)) % gsp->msgq.cnt; + + mb(); + (*gsp->msgq.rptr) = rptr; + return buf; +} + +static void * +r535_gsp_msgq_recv(struct nvkm_gsp *gsp, u32 gsp_rpc_len, int *retries) +{ + struct r535_gsp_msg *mqe; + const u32 max_rpc_size = GSP_MSG_MAX_SIZE - sizeof(*mqe); + struct nvfw_gsp_rpc *rpc; + struct r535_gsp_msg_info info = {0}; + u32 expected = gsp_rpc_len; + void *buf; + + mqe = r535_gsp_msgq_get_entry(gsp); + rpc = (struct nvfw_gsp_rpc *)mqe->data; + + if (WARN_ON(rpc->length > max_rpc_size)) + return NULL; + + buf = kvmalloc(max_t(u32, rpc->length, expected), GFP_KERNEL); + if (!buf) + return ERR_PTR(-ENOMEM); + + info.gsp_rpc_buf = buf; + info.retries = retries; + info.gsp_rpc_len = rpc->length; + + buf = r535_gsp_msgq_recv_one_elem(gsp, &info); + if (IS_ERR(buf)) { + kvfree(info.gsp_rpc_buf); + info.gsp_rpc_buf = NULL; + return buf; + } + + if (expected <= max_rpc_size) + return buf; + + info.gsp_rpc_buf += info.gsp_rpc_len; + expected -= info.gsp_rpc_len; + + while (expected) { + u32 size; + + rpc = r535_gsp_msgq_peek(gsp, sizeof(*rpc), info.retries); + if (IS_ERR_OR_NULL(rpc)) { + kfree(buf); + return rpc; + } + + info.gsp_rpc_len = rpc->length; + info.continuation = true; + + rpc = r535_gsp_msgq_recv_one_elem(gsp, &info); + if (IS_ERR_OR_NULL(rpc)) { + kfree(buf); + return rpc; + } + + size = info.gsp_rpc_len - sizeof(*rpc); + expected -= size; + info.gsp_rpc_buf += size; + } + + rpc = buf; + rpc->length = gsp_rpc_len; + return buf; +} + +static int +r535_gsp_cmdq_push(struct nvkm_gsp *gsp, void *rpc) +{ + struct r535_gsp_msg *msg = to_gsp_hdr(rpc, msg); + struct r535_gsp_msg *cqe; + u32 gsp_rpc_len = msg->checksum; + u64 *ptr = (void *)msg; + u64 *end; + u64 csum = 0; + int free, time = 1000000; + u32 wptr, size, step, len; + u32 off = 0; + + len = ALIGN(GSP_MSG_HDR_SIZE + gsp_rpc_len, GSP_PAGE_SIZE); + + end = (u64 *)((char *)ptr + len); + msg->pad = 0; + msg->checksum = 0; + msg->sequence = gsp->cmdq.seq++; + msg->elem_count = DIV_ROUND_UP(len, 0x1000); + + while (ptr < end) + csum ^= *ptr++; + + msg->checksum = upper_32_bits(csum) ^ lower_32_bits(csum); + + wptr = *gsp->cmdq.wptr; + do { + do { + free = *gsp->cmdq.rptr + gsp->cmdq.cnt - wptr - 1; + if (free >= gsp->cmdq.cnt) + free -= gsp->cmdq.cnt; + if (free >= 1) + break; + + usleep_range(1, 2); + } while(--time); + + if (WARN_ON(!time)) { + kvfree(msg); + return -ETIMEDOUT; + } + + cqe = (void *)((u8 *)gsp->shm.cmdq.ptr + 0x1000 + wptr * 0x1000); + step = min_t(u32, free, (gsp->cmdq.cnt - wptr)); + size = min_t(u32, len, step * GSP_PAGE_SIZE); + + memcpy(cqe, (u8 *)msg + off, size); + + wptr += DIV_ROUND_UP(size, 0x1000); + if (wptr == gsp->cmdq.cnt) + wptr = 0; + + off += size; + len -= size; + } while (len); + + nvkm_trace(&gsp->subdev, "cmdq: wptr %d\n", wptr); + wmb(); + (*gsp->cmdq.wptr) = wptr; + mb(); + + nvkm_falcon_wr32(&gsp->falcon, 0xc00, 0x00000000); + + kvfree(msg); + return 0; +} + +static void * +r535_gsp_cmdq_get(struct nvkm_gsp *gsp, u32 gsp_rpc_len) +{ + struct r535_gsp_msg *msg; + u32 size = GSP_MSG_HDR_SIZE + gsp_rpc_len; + + size = ALIGN(size, GSP_MSG_MIN_SIZE); + msg = kvzalloc(size, GFP_KERNEL); + if (!msg) + return ERR_PTR(-ENOMEM); + + msg->checksum = gsp_rpc_len; + return msg->data; +} + +static void +r535_gsp_msg_done(struct nvkm_gsp *gsp, struct nvfw_gsp_rpc *msg) +{ + kvfree(msg); +} + +static void +r535_gsp_msg_dump(struct nvkm_gsp *gsp, struct nvfw_gsp_rpc *msg, int lvl) +{ + if (gsp->subdev.debug >= lvl) { + nvkm_printk__(&gsp->subdev, lvl, info, + "msg fn:%d len:0x%x/0x%zx res:0x%x resp:0x%x\n", + msg->function, msg->length, msg->length - sizeof(*msg), + msg->rpc_result, msg->rpc_result_private); + print_hex_dump(KERN_INFO, "msg: ", DUMP_PREFIX_OFFSET, 16, 1, + msg->data, msg->length - sizeof(*msg), true); + } +} + +struct nvfw_gsp_rpc * +r535_gsp_msg_recv(struct nvkm_gsp *gsp, int fn, u32 gsp_rpc_len) +{ + struct nvkm_subdev *subdev = &gsp->subdev; + struct nvfw_gsp_rpc *rpc; + int retries = 4000000, i; + +retry: + rpc = r535_gsp_msgq_peek(gsp, sizeof(*rpc), &retries); + if (IS_ERR_OR_NULL(rpc)) + return rpc; + + rpc = r535_gsp_msgq_recv(gsp, gsp_rpc_len, &retries); + if (IS_ERR_OR_NULL(rpc)) + return rpc; + + if (rpc->rpc_result) { + r535_gsp_msg_dump(gsp, rpc, NV_DBG_ERROR); + r535_gsp_msg_done(gsp, rpc); + return ERR_PTR(-EINVAL); + } + + r535_gsp_msg_dump(gsp, rpc, NV_DBG_TRACE); + + if (fn && rpc->function == fn) { + if (gsp_rpc_len) { + if (rpc->length < gsp_rpc_len) { + nvkm_error(subdev, "rpc len %d < %d\n", + rpc->length, gsp_rpc_len); + r535_gsp_msg_dump(gsp, rpc, NV_DBG_ERROR); + r535_gsp_msg_done(gsp, rpc); + return ERR_PTR(-EIO); + } + + return rpc; + } + + r535_gsp_msg_done(gsp, rpc); + return NULL; + } + + for (i = 0; i < gsp->msgq.ntfy_nr; i++) { + struct nvkm_gsp_msgq_ntfy *ntfy = &gsp->msgq.ntfy[i]; + + if (ntfy->fn == rpc->function) { + if (ntfy->func) + ntfy->func(ntfy->priv, ntfy->fn, rpc->data, + rpc->length - sizeof(*rpc)); + break; + } + } + + if (i == gsp->msgq.ntfy_nr) + r535_gsp_msg_dump(gsp, rpc, NV_DBG_WARN); + + r535_gsp_msg_done(gsp, rpc); + if (fn) + goto retry; + + if (*gsp->msgq.rptr != *gsp->msgq.wptr) + goto retry; + + return NULL; +} + +int +r535_gsp_msg_ntfy_add(struct nvkm_gsp *gsp, u32 fn, nvkm_gsp_msg_ntfy_func func, void *priv) +{ + int ret = 0; + + mutex_lock(&gsp->msgq.mutex); + if (WARN_ON(gsp->msgq.ntfy_nr >= ARRAY_SIZE(gsp->msgq.ntfy))) { + ret = -ENOSPC; + } else { + gsp->msgq.ntfy[gsp->msgq.ntfy_nr].fn = fn; + gsp->msgq.ntfy[gsp->msgq.ntfy_nr].func = func; + gsp->msgq.ntfy[gsp->msgq.ntfy_nr].priv = priv; + gsp->msgq.ntfy_nr++; + } + mutex_unlock(&gsp->msgq.mutex); + return ret; +} + +int +r535_gsp_rpc_poll(struct nvkm_gsp *gsp, u32 fn) +{ + void *repv; + + mutex_lock(&gsp->cmdq.mutex); + repv = r535_gsp_msg_recv(gsp, fn, 0); + mutex_unlock(&gsp->cmdq.mutex); + if (IS_ERR(repv)) + return PTR_ERR(repv); + + return 0; +} + +static void * +r535_gsp_rpc_handle_reply(struct nvkm_gsp *gsp, u32 fn, + enum nvkm_gsp_rpc_reply_policy policy, + u32 gsp_rpc_len) +{ + struct nvfw_gsp_rpc *reply; + void *repv = NULL; + + switch (policy) { + case NVKM_GSP_RPC_REPLY_NOWAIT: + break; + case NVKM_GSP_RPC_REPLY_RECV: + reply = r535_gsp_msg_recv(gsp, fn, gsp_rpc_len); + if (!IS_ERR_OR_NULL(reply)) + repv = reply->data; + else + repv = reply; + break; + case NVKM_GSP_RPC_REPLY_POLL: + repv = r535_gsp_msg_recv(gsp, fn, 0); + break; + } + + return repv; +} + +static void * +r535_gsp_rpc_send(struct nvkm_gsp *gsp, void *payload, + enum nvkm_gsp_rpc_reply_policy policy, u32 gsp_rpc_len) +{ + struct nvfw_gsp_rpc *rpc = to_gsp_hdr(payload, rpc); + u32 fn = rpc->function; + int ret; + + if (gsp->subdev.debug >= NV_DBG_TRACE) { + nvkm_trace(&gsp->subdev, "rpc fn:%d len:0x%x/0x%zx\n", rpc->function, + rpc->length, rpc->length - sizeof(*rpc)); + print_hex_dump(KERN_INFO, "rpc: ", DUMP_PREFIX_OFFSET, 16, 1, + rpc->data, rpc->length - sizeof(*rpc), true); + } + + ret = r535_gsp_cmdq_push(gsp, rpc); + if (ret) + return ERR_PTR(ret); + + return r535_gsp_rpc_handle_reply(gsp, fn, policy, gsp_rpc_len); +} + +static void +r535_gsp_rpc_done(struct nvkm_gsp *gsp, void *repv) +{ + struct nvfw_gsp_rpc *rpc = container_of(repv, typeof(*rpc), data); + + r535_gsp_msg_done(gsp, rpc); +} + +static void * +r535_gsp_rpc_get(struct nvkm_gsp *gsp, u32 fn, u32 payload_size) +{ + struct nvfw_gsp_rpc *rpc; + + rpc = r535_gsp_cmdq_get(gsp, ALIGN(sizeof(*rpc) + payload_size, + sizeof(u64))); + if (IS_ERR(rpc)) + return ERR_CAST(rpc); + + rpc->header_version = 0x03000000; + rpc->signature = ('C' << 24) | ('P' << 16) | ('R' << 8) | 'V'; + rpc->function = fn; + rpc->rpc_result = 0xffffffff; + rpc->rpc_result_private = 0xffffffff; + rpc->length = sizeof(*rpc) + payload_size; + return rpc->data; +} + +static void * +r535_gsp_rpc_push(struct nvkm_gsp *gsp, void *payload, + enum nvkm_gsp_rpc_reply_policy policy, u32 gsp_rpc_len) +{ + struct nvfw_gsp_rpc *rpc = to_gsp_hdr(payload, rpc); + struct r535_gsp_msg *msg = to_gsp_hdr(rpc, msg); + const u32 max_rpc_size = GSP_MSG_MAX_SIZE - sizeof(*msg); + const u32 max_payload_size = max_rpc_size - sizeof(*rpc); + u32 payload_size = rpc->length - sizeof(*rpc); + void *repv; + + mutex_lock(&gsp->cmdq.mutex); + if (payload_size > max_payload_size) { + const u32 fn = rpc->function; + u32 remain_payload_size = payload_size; + + /* Adjust length, and send initial RPC. */ + rpc->length = sizeof(*rpc) + max_payload_size; + msg->checksum = rpc->length; + + repv = r535_gsp_rpc_send(gsp, payload, NVKM_GSP_RPC_REPLY_NOWAIT, 0); + if (IS_ERR(repv)) + goto done; + + payload += max_payload_size; + remain_payload_size -= max_payload_size; + + /* Remaining chunks sent as CONTINUATION_RECORD RPCs. */ + while (remain_payload_size) { + u32 size = min(remain_payload_size, + max_payload_size); + void *next; + + next = r535_gsp_rpc_get(gsp, NV_VGPU_MSG_FUNCTION_CONTINUATION_RECORD, size); + if (IS_ERR(next)) { + repv = next; + goto done; + } + + memcpy(next, payload, size); + + repv = r535_gsp_rpc_send(gsp, next, NVKM_GSP_RPC_REPLY_NOWAIT, 0); + if (IS_ERR(repv)) + goto done; + + payload += size; + remain_payload_size -= size; + } + + /* Wait for reply. */ + repv = r535_gsp_rpc_handle_reply(gsp, fn, policy, payload_size + + sizeof(*rpc)); + } else { + repv = r535_gsp_rpc_send(gsp, payload, policy, gsp_rpc_len); + } + +done: + mutex_unlock(&gsp->cmdq.mutex); + return repv; +} + +const struct nvkm_rm_api_rpc +r535_rpc = { + .get = r535_gsp_rpc_get, + .push = r535_gsp_rpc_push, + .done = r535_gsp_rpc_done, +}; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h new file mode 100644 index 000000000000..7a0ece979167 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#include <subdev/gsp.h> +#ifndef __NVKM_RM_H__ +#define __NVKM_RM_H__ + +struct nvkm_rm_api { + const struct nvkm_rm_api_rpc { + void *(*get)(struct nvkm_gsp *, u32 fn, u32 argc); + void *(*push)(struct nvkm_gsp *gsp, void *argv, + enum nvkm_gsp_rpc_reply_policy policy, u32 repc); + void (*done)(struct nvkm_gsp *gsp, void *repv); + } *rpc; +}; + +extern const struct nvkm_rm_api r535_rm; +extern const struct nvkm_rm_api_rpc r535_rpc; +#endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rpc.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rpc.h new file mode 100644 index 000000000000..4431e33b3304 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rpc.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#ifndef __NVKM_RM_RPC_H__ +#define __NVKM_RM_RPC_H__ +#include "rm.h" + +#define to_payload_hdr(p, header) \ + container_of((void *)p, typeof(*header), params) + +int r535_gsp_rpc_poll(struct nvkm_gsp *, u32 fn); + +struct nvfw_gsp_rpc *r535_gsp_msg_recv(struct nvkm_gsp *, int fn, u32 gsp_rpc_len); +int r535_gsp_msg_ntfy_add(struct nvkm_gsp *, u32 fn, nvkm_gsp_msg_ntfy_func, void *priv); + +int r535_rpc_status_to_errno(uint32_t rpc_status); +#endif -- 2.49.0
Ben Skeggs
2025-May-17 00:08 UTC
[PATCH v3 07/62] drm/nouveau/gsp: split rm ctrl handling out on its own
Split base RM_CONTROL handling out into its own module. Aside from moving the function pointers, no code change is intended. Signed-off-by: Ben Skeggs <bskeggs at nvidia.com> Reviewed-by: Dave Airlie <airlied at redhat.com> Reviewed-by: Timur Tabi <ttabi at nvidia.com> Tested-by: Timur Tabi <ttabi at nvidia.com> --- .../gpu/drm/nouveau/include/nvkm/subdev/gsp.h | 10 +- .../gpu/drm/nouveau/nvkm/subdev/gsp/r535.c | 66 +------------ .../nouveau/nvkm/subdev/gsp/rm/r535/Kbuild | 1 + .../nouveau/nvkm/subdev/gsp/rm/r535/ctrl.c | 94 +++++++++++++++++++ .../drm/nouveau/nvkm/subdev/gsp/rm/r535/rm.c | 1 + .../gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h | 7 ++ 6 files changed, 107 insertions(+), 72 deletions(-) create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/ctrl.c diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h index b543c31d3d32..bc2cf837aa9f 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h @@ -212,10 +212,6 @@ struct nvkm_gsp { const struct nvkm_gsp_rm { const struct nvkm_rm_api *api; - 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); void (*rm_alloc_done)(struct nvkm_gsp_object *, void *repv); @@ -316,13 +312,13 @@ nvkm_gsp_rpc_done(struct nvkm_gsp *gsp, void *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); + return object->client->gsp->rm->api->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); + return object->client->gsp->rm->api->ctrl->push(object, argv, repc); } static inline void * @@ -353,7 +349,7 @@ nvkm_gsp_rm_ctrl_wr(struct nvkm_gsp_object *object, void *argv) static inline void nvkm_gsp_rm_ctrl_done(struct nvkm_gsp_object *object, void *repv) { - object->client->gsp->rm->rm_ctrl_done(object, repv); + object->client->gsp->rm->api->ctrl->done(object, repv); } static inline void * diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c index 745d43586bad..4797a92708e9 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c @@ -20,6 +20,7 @@ * OTHER DEALINGS IN THE SOFTWARE. */ #include <rm/rpc.h> + #include "priv.h" #include <core/pci.h> @@ -304,75 +305,10 @@ r535_gsp_rpc_rm_alloc_get(struct nvkm_gsp_object *object, u32 oclass, return rpc->params; } -static void -r535_gsp_rpc_rm_ctrl_done(struct nvkm_gsp_object *object, void *params) -{ - rpc_gsp_rm_control_v03_00 *rpc = to_payload_hdr(params, rpc); - - if (!params) - return; - nvkm_gsp_rpc_done(object->client->gsp, rpc); -} - -static int -r535_gsp_rpc_rm_ctrl_push(struct nvkm_gsp_object *object, void **params, u32 repc) -{ - rpc_gsp_rm_control_v03_00 *rpc = to_payload_hdr((*params), rpc); - struct nvkm_gsp *gsp = object->client->gsp; - int ret = 0; - - rpc = nvkm_gsp_rpc_push(gsp, rpc, NVKM_GSP_RPC_REPLY_RECV, repc); - if (IS_ERR_OR_NULL(rpc)) { - *params = NULL; - return PTR_ERR(rpc); - } - - if (rpc->status) { - ret = r535_rpc_status_to_errno(rpc->status); - if (ret != -EAGAIN && ret != -EBUSY) - nvkm_error(&gsp->subdev, "cli:0x%08x obj:0x%08x ctrl cmd:0x%08x failed: 0x%08x\n", - object->client->object.handle, object->handle, rpc->cmd, rpc->status); - } - - if (repc) - *params = rpc->params; - else - nvkm_gsp_rpc_done(gsp, rpc); - - return ret; -} - -static void * -r535_gsp_rpc_rm_ctrl_get(struct nvkm_gsp_object *object, u32 cmd, u32 params_size) -{ - struct nvkm_gsp_client *client = object->client; - struct nvkm_gsp *gsp = client->gsp; - rpc_gsp_rm_control_v03_00 *rpc; - - nvkm_debug(&gsp->subdev, "cli:0x%08x obj:0x%08x ctrl cmd:0x%08x params_size:%d\n", - client->object.handle, object->handle, cmd, params_size); - - rpc = nvkm_gsp_rpc_get(gsp, NV_VGPU_MSG_FUNCTION_GSP_RM_CONTROL, - sizeof(*rpc) + params_size); - if (IS_ERR(rpc)) - return rpc; - - rpc->hClient = client->object.handle; - rpc->hObject = object->handle; - rpc->cmd = cmd; - rpc->status = 0; - rpc->paramsSize = params_size; - return rpc->params; -} - const struct nvkm_gsp_rm r535_gsp_rm = { .api = &r535_rm, - .rm_ctrl_get = r535_gsp_rpc_rm_ctrl_get, - .rm_ctrl_push = r535_gsp_rpc_rm_ctrl_push, - .rm_ctrl_done = r535_gsp_rpc_rm_ctrl_done, - .rm_alloc_get = r535_gsp_rpc_rm_alloc_get, .rm_alloc_push = r535_gsp_rpc_rm_alloc_push, .rm_alloc_done = r535_gsp_rpc_rm_alloc_done, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/Kbuild index 21c818ec0701..c8d7419b754f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/Kbuild @@ -4,3 +4,4 @@ nvkm-y += nvkm/subdev/gsp/rm/r535/rm.o nvkm-y += nvkm/subdev/gsp/rm/r535/rpc.o +nvkm-y += nvkm/subdev/gsp/rm/r535/ctrl.o diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/ctrl.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/ctrl.c new file mode 100644 index 000000000000..f3f0fcd22cac --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/ctrl.c @@ -0,0 +1,94 @@ +/* + * 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 <rm/rpc.h> + +#include <nvrm/nvtypes.h> +#include <nvrm/535.113.01/nvidia/generated/g_rpc-structures.h> +#include <nvrm/535.113.01/nvidia/kernel/inc/vgpu/rpc_global_enums.h> + +static void +r535_gsp_rpc_rm_ctrl_done(struct nvkm_gsp_object *object, void *params) +{ + rpc_gsp_rm_control_v03_00 *rpc = to_payload_hdr(params, rpc); + + if (!params) + return; + nvkm_gsp_rpc_done(object->client->gsp, rpc); +} + +static int +r535_gsp_rpc_rm_ctrl_push(struct nvkm_gsp_object *object, void **params, u32 repc) +{ + rpc_gsp_rm_control_v03_00 *rpc = to_payload_hdr((*params), rpc); + struct nvkm_gsp *gsp = object->client->gsp; + int ret = 0; + + rpc = nvkm_gsp_rpc_push(gsp, rpc, NVKM_GSP_RPC_REPLY_RECV, repc); + if (IS_ERR_OR_NULL(rpc)) { + *params = NULL; + return PTR_ERR(rpc); + } + + if (rpc->status) { + ret = r535_rpc_status_to_errno(rpc->status); + if (ret != -EAGAIN && ret != -EBUSY) + nvkm_error(&gsp->subdev, "cli:0x%08x obj:0x%08x ctrl cmd:0x%08x failed: 0x%08x\n", + object->client->object.handle, object->handle, rpc->cmd, rpc->status); + } + + if (repc) + *params = rpc->params; + else + nvkm_gsp_rpc_done(gsp, rpc); + + return ret; +} + +static void * +r535_gsp_rpc_rm_ctrl_get(struct nvkm_gsp_object *object, u32 cmd, u32 params_size) +{ + struct nvkm_gsp_client *client = object->client; + struct nvkm_gsp *gsp = client->gsp; + rpc_gsp_rm_control_v03_00 *rpc; + + nvkm_debug(&gsp->subdev, "cli:0x%08x obj:0x%08x ctrl cmd:0x%08x params_size:%d\n", + client->object.handle, object->handle, cmd, params_size); + + rpc = nvkm_gsp_rpc_get(gsp, NV_VGPU_MSG_FUNCTION_GSP_RM_CONTROL, + sizeof(*rpc) + params_size); + if (IS_ERR(rpc)) + return rpc; + + rpc->hClient = client->object.handle; + rpc->hObject = object->handle; + rpc->cmd = cmd; + rpc->status = 0; + rpc->paramsSize = params_size; + return rpc->params; +} + +const struct nvkm_rm_api_ctrl +r535_ctrl = { + .get = r535_gsp_rpc_rm_ctrl_get, + .push = r535_gsp_rpc_rm_ctrl_push, + .done = r535_gsp_rpc_rm_ctrl_done, +}; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rm.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rm.c index f28b781abc5c..a3ee277a999d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rm.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rm.c @@ -7,4 +7,5 @@ const struct nvkm_rm_api r535_rm = { .rpc = &r535_rpc, + .ctrl = &r535_ctrl, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h index 7a0ece979167..9558fbb59ae4 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h @@ -13,8 +13,15 @@ struct nvkm_rm_api { enum nvkm_gsp_rpc_reply_policy policy, u32 repc); void (*done)(struct nvkm_gsp *gsp, void *repv); } *rpc; + + const struct nvkm_rm_api_ctrl { + void *(*get)(struct nvkm_gsp_object *, u32 cmd, u32 params_size); + int (*push)(struct nvkm_gsp_object *, void **params, u32 repc); + void (*done)(struct nvkm_gsp_object *, void *params); + } *ctrl; }; extern const struct nvkm_rm_api r535_rm; extern const struct nvkm_rm_api_rpc r535_rpc; +extern const struct nvkm_rm_api_ctrl r535_ctrl; #endif -- 2.49.0
Ben Skeggs
2025-May-17 00:09 UTC
[PATCH v3 08/62] drm/nouveau/gsp: split rm alloc handling out on its own
Split base RM_ALLOC handling out into its own module. Aside from moving the function pointers, no code change is intended. Signed-off-by: Ben Skeggs <bskeggs at nvidia.com> Reviewed-by: Dave Airlie <airlied at redhat.com> Reviewed-by: Timur Tabi <ttabi at nvidia.com> Tested-by: Timur Tabi <ttabi at nvidia.com> --- .../gpu/drm/nouveau/include/nvkm/subdev/gsp.h | 19 ++- .../gpu/drm/nouveau/nvkm/subdev/gsp/r535.c | 85 ------------- .../nouveau/nvkm/subdev/gsp/rm/r535/Kbuild | 1 + .../nouveau/nvkm/subdev/gsp/rm/r535/alloc.c | 113 ++++++++++++++++++ .../drm/nouveau/nvkm/subdev/gsp/rm/r535/rm.c | 1 + .../gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h | 9 ++ 6 files changed, 132 insertions(+), 96 deletions(-) create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/alloc.c diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h index bc2cf837aa9f..66e3873155f0 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h @@ -212,12 +212,6 @@ struct nvkm_gsp { const struct nvkm_gsp_rm { const struct nvkm_rm_api *api; - void *(*rm_alloc_get)(struct nvkm_gsp_object *, u32 oclass, u32 argc); - void *(*rm_alloc_push)(struct nvkm_gsp_object *, void *argv); - 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 *); @@ -364,7 +358,7 @@ nvkm_gsp_rm_alloc_get(struct nvkm_gsp_object *parent, u32 handle, u32 oclass, u3 object->parent = parent; object->handle = handle; - argv = gsp->rm->rm_alloc_get(object, oclass, argc); + argv = gsp->rm->api->alloc->get(object, oclass, argc); if (IS_ERR_OR_NULL(argv)) { object->client = NULL; return argv; @@ -376,7 +370,7 @@ nvkm_gsp_rm_alloc_get(struct nvkm_gsp_object *parent, u32 handle, u32 oclass, u3 static inline void * nvkm_gsp_rm_alloc_push(struct nvkm_gsp_object *object, void *argv) { - void *repv = object->client->gsp->rm->rm_alloc_push(object, argv); + void *repv = object->client->gsp->rm->api->alloc->push(object, argv); if (IS_ERR(repv)) object->client = NULL; @@ -398,7 +392,7 @@ nvkm_gsp_rm_alloc_wr(struct nvkm_gsp_object *object, void *argv) static inline void nvkm_gsp_rm_alloc_done(struct nvkm_gsp_object *object, void *repv) { - object->client->gsp->rm->rm_alloc_done(object, repv); + object->client->gsp->rm->api->alloc->done(object, repv); } static inline int @@ -416,8 +410,11 @@ nvkm_gsp_rm_alloc(struct nvkm_gsp_object *parent, u32 handle, u32 oclass, u32 ar static inline int nvkm_gsp_rm_free(struct nvkm_gsp_object *object) { - if (object->client) - return object->client->gsp->rm->rm_free(object); + if (object->client) { + int ret = object->client->gsp->rm->api->alloc->free(object); + object->client = NULL; + return ret; + } return 0; } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c index 4797a92708e9..e9be8c2ef07e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c @@ -226,95 +226,10 @@ r535_gsp_client_ctor(struct nvkm_gsp *gsp, struct nvkm_gsp_client *client) return 0; } -static int -r535_gsp_rpc_rm_free(struct nvkm_gsp_object *object) -{ - struct nvkm_gsp_client *client = object->client; - struct nvkm_gsp *gsp = client->gsp; - rpc_free_v03_00 *rpc; - - nvkm_debug(&gsp->subdev, "cli:0x%08x obj:0x%08x free\n", - client->object.handle, object->handle); - - rpc = nvkm_gsp_rpc_get(gsp, NV_VGPU_MSG_FUNCTION_FREE, sizeof(*rpc)); - if (WARN_ON(IS_ERR_OR_NULL(rpc))) - return -EIO; - - rpc->params.hRoot = client->object.handle; - rpc->params.hObjectParent = 0; - rpc->params.hObjectOld = object->handle; - return nvkm_gsp_rpc_wr(gsp, rpc, NVKM_GSP_RPC_REPLY_RECV); -} - -static void -r535_gsp_rpc_rm_alloc_done(struct nvkm_gsp_object *object, void *params) -{ - rpc_gsp_rm_alloc_v03_00 *rpc = to_payload_hdr(params, rpc); - - nvkm_gsp_rpc_done(object->client->gsp, rpc); -} - -static void * -r535_gsp_rpc_rm_alloc_push(struct nvkm_gsp_object *object, void *params) -{ - rpc_gsp_rm_alloc_v03_00 *rpc = to_payload_hdr(params, rpc); - struct nvkm_gsp *gsp = object->client->gsp; - void *ret = NULL; - - rpc = nvkm_gsp_rpc_push(gsp, rpc, NVKM_GSP_RPC_REPLY_RECV, sizeof(*rpc)); - if (IS_ERR_OR_NULL(rpc)) - return rpc; - - if (rpc->status) { - ret = ERR_PTR(r535_rpc_status_to_errno(rpc->status)); - if (PTR_ERR(ret) != -EAGAIN && PTR_ERR(ret) != -EBUSY) - nvkm_error(&gsp->subdev, "RM_ALLOC: 0x%x\n", rpc->status); - } - - nvkm_gsp_rpc_done(gsp, rpc); - - return ret; -} - -static void * -r535_gsp_rpc_rm_alloc_get(struct nvkm_gsp_object *object, u32 oclass, - u32 params_size) -{ - struct nvkm_gsp_client *client = object->client; - struct nvkm_gsp *gsp = client->gsp; - rpc_gsp_rm_alloc_v03_00 *rpc; - - nvkm_debug(&gsp->subdev, "cli:0x%08x obj:0x%08x new obj:0x%08x\n", - client->object.handle, object->parent->handle, - object->handle); - - nvkm_debug(&gsp->subdev, "cls:0x%08x params_size:%d\n", oclass, - params_size); - - rpc = nvkm_gsp_rpc_get(gsp, NV_VGPU_MSG_FUNCTION_GSP_RM_ALLOC, - sizeof(*rpc) + params_size); - if (IS_ERR(rpc)) - return rpc; - - rpc->hClient = client->object.handle; - rpc->hParent = object->parent->handle; - rpc->hObject = object->handle; - rpc->hClass = oclass; - rpc->status = 0; - rpc->paramsSize = params_size; - return rpc->params; -} - const struct nvkm_gsp_rm r535_gsp_rm = { .api = &r535_rm, - .rm_alloc_get = r535_gsp_rpc_rm_alloc_get, - .rm_alloc_push = r535_gsp_rpc_rm_alloc_push, - .rm_alloc_done = r535_gsp_rpc_rm_alloc_done, - - .rm_free = r535_gsp_rpc_rm_free, - .client_ctor = r535_gsp_client_ctor, .client_dtor = r535_gsp_client_dtor, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/Kbuild index c8d7419b754f..48b432c9005d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/Kbuild @@ -5,3 +5,4 @@ nvkm-y += nvkm/subdev/gsp/rm/r535/rm.o nvkm-y += nvkm/subdev/gsp/rm/r535/rpc.o nvkm-y += nvkm/subdev/gsp/rm/r535/ctrl.o +nvkm-y += nvkm/subdev/gsp/rm/r535/alloc.o diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/alloc.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/alloc.c new file mode 100644 index 000000000000..968fb7e01b46 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/alloc.c @@ -0,0 +1,113 @@ +/* + * 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 <rm/rpc.h> + +#include <nvrm/nvtypes.h> +#include <nvrm/535.113.01/nvidia/generated/g_rpc-structures.h> +#include <nvrm/535.113.01/nvidia/kernel/inc/vgpu/rpc_global_enums.h> + +static int +r535_gsp_rpc_rm_free(struct nvkm_gsp_object *object) +{ + struct nvkm_gsp_client *client = object->client; + struct nvkm_gsp *gsp = client->gsp; + rpc_free_v03_00 *rpc; + + nvkm_debug(&gsp->subdev, "cli:0x%08x obj:0x%08x free\n", + client->object.handle, object->handle); + + rpc = nvkm_gsp_rpc_get(gsp, NV_VGPU_MSG_FUNCTION_FREE, sizeof(*rpc)); + if (WARN_ON(IS_ERR_OR_NULL(rpc))) + return -EIO; + + rpc->params.hRoot = client->object.handle; + rpc->params.hObjectParent = 0; + rpc->params.hObjectOld = object->handle; + return nvkm_gsp_rpc_wr(gsp, rpc, NVKM_GSP_RPC_REPLY_RECV); +} + +static void +r535_gsp_rpc_rm_alloc_done(struct nvkm_gsp_object *object, void *params) +{ + rpc_gsp_rm_alloc_v03_00 *rpc = to_payload_hdr(params, rpc); + + nvkm_gsp_rpc_done(object->client->gsp, rpc); +} + +static void * +r535_gsp_rpc_rm_alloc_push(struct nvkm_gsp_object *object, void *params) +{ + rpc_gsp_rm_alloc_v03_00 *rpc = to_payload_hdr(params, rpc); + struct nvkm_gsp *gsp = object->client->gsp; + void *ret = NULL; + + rpc = nvkm_gsp_rpc_push(gsp, rpc, NVKM_GSP_RPC_REPLY_RECV, sizeof(*rpc)); + if (IS_ERR_OR_NULL(rpc)) + return rpc; + + if (rpc->status) { + ret = ERR_PTR(r535_rpc_status_to_errno(rpc->status)); + if (PTR_ERR(ret) != -EAGAIN && PTR_ERR(ret) != -EBUSY) + nvkm_error(&gsp->subdev, "RM_ALLOC: 0x%x\n", rpc->status); + } + + nvkm_gsp_rpc_done(gsp, rpc); + + return ret; +} + +static void * +r535_gsp_rpc_rm_alloc_get(struct nvkm_gsp_object *object, u32 oclass, + u32 params_size) +{ + struct nvkm_gsp_client *client = object->client; + struct nvkm_gsp *gsp = client->gsp; + rpc_gsp_rm_alloc_v03_00 *rpc; + + nvkm_debug(&gsp->subdev, "cli:0x%08x obj:0x%08x new obj:0x%08x\n", + client->object.handle, object->parent->handle, + object->handle); + + nvkm_debug(&gsp->subdev, "cls:0x%08x params_size:%d\n", oclass, + params_size); + + rpc = nvkm_gsp_rpc_get(gsp, NV_VGPU_MSG_FUNCTION_GSP_RM_ALLOC, + sizeof(*rpc) + params_size); + if (IS_ERR(rpc)) + return rpc; + + rpc->hClient = client->object.handle; + rpc->hParent = object->parent->handle; + rpc->hObject = object->handle; + rpc->hClass = oclass; + rpc->status = 0; + rpc->paramsSize = params_size; + return rpc->params; +} + +const struct nvkm_rm_api_alloc +r535_alloc = { + .get = r535_gsp_rpc_rm_alloc_get, + .push = r535_gsp_rpc_rm_alloc_push, + .done = r535_gsp_rpc_rm_alloc_done, + .free = r535_gsp_rpc_rm_free, +}; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rm.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rm.c index a3ee277a999d..f6fcd89ec502 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rm.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rm.c @@ -8,4 +8,5 @@ const struct nvkm_rm_api r535_rm = { .rpc = &r535_rpc, .ctrl = &r535_ctrl, + .alloc = &r535_alloc, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h index 9558fbb59ae4..6d0eb8e202ca 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h @@ -19,9 +19,18 @@ struct nvkm_rm_api { int (*push)(struct nvkm_gsp_object *, void **params, u32 repc); void (*done)(struct nvkm_gsp_object *, void *params); } *ctrl; + + const struct nvkm_rm_api_alloc { + void *(*get)(struct nvkm_gsp_object *, u32 oclass, u32 params_size); + void *(*push)(struct nvkm_gsp_object *, void *params); + void (*done)(struct nvkm_gsp_object *, void *params); + + int (*free)(struct nvkm_gsp_object *); + } *alloc; }; extern const struct nvkm_rm_api r535_rm; extern const struct nvkm_rm_api_rpc r535_rpc; extern const struct nvkm_rm_api_ctrl r535_ctrl; +extern const struct nvkm_rm_api_alloc r535_alloc; #endif -- 2.49.0
Ben Skeggs
2025-May-17 00:09 UTC
[PATCH v3 09/62] drm/nouveau/gsp: split client handling out on its own
Split NV01_ROOT handling out into its own module. Aside from moving the function pointers, no code change is intended. Signed-off-by: Ben Skeggs <bskeggs at nvidia.com> Reviewed-by: Dave Airlie <airlied at redhat.com> Reviewed-by: Timur Tabi <ttabi at nvidia.com> Tested-by: Timur Tabi <ttabi at nvidia.com> --- .../gpu/drm/nouveau/include/nvkm/subdev/gsp.h | 7 +- .../gpu/drm/nouveau/nvkm/subdev/gsp/r535.c | 53 ------------ .../nouveau/nvkm/subdev/gsp/rm/r535/Kbuild | 1 + .../nouveau/nvkm/subdev/gsp/rm/r535/client.c | 80 +++++++++++++++++++ .../drm/nouveau/nvkm/subdev/gsp/rm/r535/rm.c | 1 + .../gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h | 6 ++ 6 files changed, 90 insertions(+), 58 deletions(-) create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/client.c diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h index 66e3873155f0..2c3d8fd04516 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h @@ -212,9 +212,6 @@ struct nvkm_gsp { const struct nvkm_gsp_rm { const struct nvkm_rm_api *api; - 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 *); @@ -425,14 +422,14 @@ 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); + return gsp->rm->api->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); + client->gsp->rm->api->client->dtor(client); } static inline int diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c index e9be8c2ef07e..c6fce9541c0e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c @@ -33,7 +33,6 @@ #include <nvfw/fw.h> #include <nvrm/nvtypes.h> -#include <nvrm/535.113.01/common/sdk/nvidia/inc/class/cl0000.h> #include <nvrm/535.113.01/common/sdk/nvidia/inc/class/cl0005.h> #include <nvrm/535.113.01/common/sdk/nvidia/inc/class/cl0080.h> #include <nvrm/535.113.01/common/sdk/nvidia/inc/class/cl2080.h> @@ -177,62 +176,10 @@ r535_gsp_device_ctor(struct nvkm_gsp_client *client, struct nvkm_gsp_device *dev return ret; } -static void -r535_gsp_client_dtor(struct nvkm_gsp_client *client) -{ - struct nvkm_gsp *gsp = client->gsp; - - nvkm_gsp_rm_free(&client->object); - - mutex_lock(&gsp->client_id.mutex); - idr_remove(&gsp->client_id.idr, client->object.handle & 0xffff); - mutex_unlock(&gsp->client_id.mutex); - - client->gsp = NULL; -} - -static int -r535_gsp_client_ctor(struct nvkm_gsp *gsp, struct nvkm_gsp_client *client) -{ - NV0000_ALLOC_PARAMETERS *args; - int ret; - - mutex_lock(&gsp->client_id.mutex); - ret = idr_alloc(&gsp->client_id.idr, client, 0, 0xffff + 1, GFP_KERNEL); - mutex_unlock(&gsp->client_id.mutex); - if (ret < 0) - return ret; - - client->gsp = gsp; - client->object.client = client; - INIT_LIST_HEAD(&client->events); - - args = nvkm_gsp_rm_alloc_get(&client->object, 0xc1d00000 | ret, NV01_ROOT, sizeof(*args), - &client->object); - if (IS_ERR(args)) { - r535_gsp_client_dtor(client); - return ret; - } - - args->hClient = client->object.handle; - args->processID = ~0; - - ret = nvkm_gsp_rm_alloc_wr(&client->object, args); - if (ret) { - r535_gsp_client_dtor(client); - return ret; - } - - return 0; -} - const struct nvkm_gsp_rm r535_gsp_rm = { .api = &r535_rm, - .client_ctor = r535_gsp_client_ctor, - .client_dtor = r535_gsp_client_dtor, - .device_ctor = r535_gsp_device_ctor, .device_dtor = r535_gsp_device_dtor, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/Kbuild index 48b432c9005d..f25b438fa3d9 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/Kbuild @@ -6,3 +6,4 @@ nvkm-y += nvkm/subdev/gsp/rm/r535/rm.o nvkm-y += nvkm/subdev/gsp/rm/r535/rpc.o nvkm-y += nvkm/subdev/gsp/rm/r535/ctrl.o nvkm-y += nvkm/subdev/gsp/rm/r535/alloc.o +nvkm-y += nvkm/subdev/gsp/rm/r535/client.o diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/client.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/client.c new file mode 100644 index 000000000000..7a2da37af283 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/client.c @@ -0,0 +1,80 @@ +/* + * 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 <rm/rm.h> + +#include <nvrm/nvtypes.h> +#include <nvrm/535.113.01/common/sdk/nvidia/inc/class/cl0000.h> + +static void +r535_gsp_client_dtor(struct nvkm_gsp_client *client) +{ + struct nvkm_gsp *gsp = client->gsp; + + nvkm_gsp_rm_free(&client->object); + + mutex_lock(&gsp->client_id.mutex); + idr_remove(&gsp->client_id.idr, client->object.handle & 0xffff); + mutex_unlock(&gsp->client_id.mutex); + + client->gsp = NULL; +} + +static int +r535_gsp_client_ctor(struct nvkm_gsp *gsp, struct nvkm_gsp_client *client) +{ + NV0000_ALLOC_PARAMETERS *args; + int ret; + + mutex_lock(&gsp->client_id.mutex); + ret = idr_alloc(&gsp->client_id.idr, client, 0, 0xffff + 1, GFP_KERNEL); + mutex_unlock(&gsp->client_id.mutex); + if (ret < 0) + return ret; + + client->gsp = gsp; + client->object.client = client; + INIT_LIST_HEAD(&client->events); + + args = nvkm_gsp_rm_alloc_get(&client->object, 0xc1d00000 | ret, NV01_ROOT, sizeof(*args), + &client->object); + if (IS_ERR(args)) { + r535_gsp_client_dtor(client); + return ret; + } + + args->hClient = client->object.handle; + args->processID = ~0; + + ret = nvkm_gsp_rm_alloc_wr(&client->object, args); + if (ret) { + r535_gsp_client_dtor(client); + return ret; + } + + return 0; +} + +const struct nvkm_rm_api_client +r535_client = { + .ctor = r535_gsp_client_ctor, + .dtor = r535_gsp_client_dtor, +}; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rm.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rm.c index f6fcd89ec502..dba1d2058b37 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rm.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rm.c @@ -9,4 +9,5 @@ r535_rm = { .rpc = &r535_rpc, .ctrl = &r535_ctrl, .alloc = &r535_alloc, + .client = &r535_client, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h index 6d0eb8e202ca..c3341631fbd5 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h @@ -27,10 +27,16 @@ struct nvkm_rm_api { int (*free)(struct nvkm_gsp_object *); } *alloc; + + const struct nvkm_rm_api_client { + int (*ctor)(struct nvkm_gsp *, struct nvkm_gsp_client *); + void (*dtor)(struct nvkm_gsp_client *); + } *client; }; extern const struct nvkm_rm_api r535_rm; extern const struct nvkm_rm_api_rpc r535_rpc; extern const struct nvkm_rm_api_ctrl r535_ctrl; extern const struct nvkm_rm_api_alloc r535_alloc; +extern const struct nvkm_rm_api_client r535_client; #endif -- 2.49.0
Ben Skeggs
2025-May-17 00:09 UTC
[PATCH v3 10/62] drm/nouveau/gsp: split device handling out on its own
Split handling of NV01_DEVICE (and other related objects) out into its own module. Aside from moving the function pointers, no code change is intended. Signed-off-by: Ben Skeggs <bskeggs at nvidia.com> Reviewed-by: Dave Airlie <airlied at redhat.com> Reviewed-by: Timur Tabi <ttabi at nvidia.com> Tested-by: Timur Tabi <ttabi at nvidia.com> --- .../gpu/drm/nouveau/include/nvkm/subdev/gsp.h | 17 +- .../gpu/drm/nouveau/nvkm/subdev/gsp/r535.c | 127 --------------- .../nouveau/nvkm/subdev/gsp/rm/r535/Kbuild | 1 + .../nouveau/nvkm/subdev/gsp/rm/r535/device.c | 153 ++++++++++++++++++ .../drm/nouveau/nvkm/subdev/gsp/rm/r535/rm.c | 1 + .../gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h | 12 ++ 6 files changed, 173 insertions(+), 138 deletions(-) create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/device.c diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h index 2c3d8fd04516..3fd279be8340 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h @@ -211,13 +211,6 @@ struct nvkm_gsp { const struct nvkm_gsp_rm { const struct nvkm_rm_api *api; - - 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 { @@ -435,14 +428,14 @@ nvkm_gsp_client_dtor(struct nvkm_gsp_client *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); + return client->gsp->rm->api->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); + device->object.client->gsp->rm->api->device->dtor(device); } static inline int @@ -474,7 +467,9 @@ 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); + const struct nvkm_gsp_rm *rm = device->object.client->gsp->rm; + + return rm->api->device->event.ctor(device, handle, id, func, event); } static inline void @@ -483,7 +478,7 @@ 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); + device->object.client->gsp->rm->api->device->event.dtor(event); } int nvkm_gsp_intr_stall(struct nvkm_gsp *, enum nvkm_subdev_type, int); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c index c6fce9541c0e..c292f5a4e1ec 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c @@ -33,20 +33,14 @@ #include <nvfw/fw.h> #include <nvrm/nvtypes.h> -#include <nvrm/535.113.01/common/sdk/nvidia/inc/class/cl0005.h> -#include <nvrm/535.113.01/common/sdk/nvidia/inc/class/cl0080.h> -#include <nvrm/535.113.01/common/sdk/nvidia/inc/class/cl2080.h> -#include <nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl2080/ctrl2080event.h> #include <nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl2080/ctrl2080gpu.h> #include <nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl2080/ctrl2080internal.h> -#include <nvrm/535.113.01/common/sdk/nvidia/inc/nvos.h> #include <nvrm/535.113.01/common/shared/msgq/inc/msgq/msgq_priv.h> #include <nvrm/535.113.01/common/uproc/os/common/include/libos_init_args.h> #include <nvrm/535.113.01/nvidia/arch/nvalloc/common/inc/gsp/gsp_fw_sr_meta.h> #include <nvrm/535.113.01/nvidia/arch/nvalloc/common/inc/gsp/gsp_fw_wpr_meta.h> #include <nvrm/535.113.01/nvidia/arch/nvalloc/common/inc/rmRiscvUcode.h> #include <nvrm/535.113.01/nvidia/arch/nvalloc/common/inc/rmgspseq.h> -#include <nvrm/535.113.01/nvidia/generated/g_allclasses.h> #include <nvrm/535.113.01/nvidia/generated/g_os_nvoc.h> #include <nvrm/535.113.01/nvidia/generated/g_rpc-structures.h> #include <nvrm/535.113.01/nvidia/inc/kernel/gpu/gsp/gsp_fw_heap.h> @@ -61,130 +55,9 @@ extern struct dentry *nouveau_debugfs_root; -static void -r535_gsp_event_dtor(struct nvkm_gsp_event *event) -{ - struct nvkm_gsp_device *device = event->device; - struct nvkm_gsp_client *client = device->object.client; - struct nvkm_gsp *gsp = client->gsp; - - mutex_lock(&gsp->client_id.mutex); - if (event->func) { - list_del(&event->head); - event->func = NULL; - } - mutex_unlock(&gsp->client_id.mutex); - - nvkm_gsp_rm_free(&event->object); - event->device = NULL; -} - -static int -r535_gsp_device_event_get(struct nvkm_gsp_event *event) -{ - struct nvkm_gsp_device *device = event->device; - NV2080_CTRL_EVENT_SET_NOTIFICATION_PARAMS *ctrl; - - ctrl = nvkm_gsp_rm_ctrl_get(&device->subdevice, - NV2080_CTRL_CMD_EVENT_SET_NOTIFICATION, sizeof(*ctrl)); - if (IS_ERR(ctrl)) - return PTR_ERR(ctrl); - - ctrl->event = event->id; - ctrl->action = NV2080_CTRL_EVENT_SET_NOTIFICATION_ACTION_REPEAT; - return nvkm_gsp_rm_ctrl_wr(&device->subdevice, ctrl); -} - -static int -r535_gsp_device_event_ctor(struct nvkm_gsp_device *device, u32 handle, u32 id, - nvkm_gsp_event_func func, struct nvkm_gsp_event *event) -{ - struct nvkm_gsp_client *client = device->object.client; - struct nvkm_gsp *gsp = client->gsp; - NV0005_ALLOC_PARAMETERS *args; - int ret; - - args = nvkm_gsp_rm_alloc_get(&device->subdevice, handle, - NV01_EVENT_KERNEL_CALLBACK_EX, sizeof(*args), - &event->object); - if (IS_ERR(args)) - return PTR_ERR(args); - - args->hParentClient = client->object.handle; - args->hSrcResource = 0; - args->hClass = NV01_EVENT_KERNEL_CALLBACK_EX; - args->notifyIndex = NV01_EVENT_CLIENT_RM | id; - args->data = NULL; - - ret = nvkm_gsp_rm_alloc_wr(&event->object, args); - if (ret) - return ret; - - event->device = device; - event->id = id; - - ret = r535_gsp_device_event_get(event); - if (ret) { - nvkm_gsp_event_dtor(event); - return ret; - } - - mutex_lock(&gsp->client_id.mutex); - event->func = func; - list_add(&event->head, &client->events); - mutex_unlock(&gsp->client_id.mutex); - return 0; -} - -static void -r535_gsp_device_dtor(struct nvkm_gsp_device *device) -{ - nvkm_gsp_rm_free(&device->subdevice); - nvkm_gsp_rm_free(&device->object); -} - -static int -r535_gsp_subdevice_ctor(struct nvkm_gsp_device *device) -{ - NV2080_ALLOC_PARAMETERS *args; - - return nvkm_gsp_rm_alloc(&device->object, 0x5d1d0000, NV20_SUBDEVICE_0, sizeof(*args), - &device->subdevice); -} - -static int -r535_gsp_device_ctor(struct nvkm_gsp_client *client, struct nvkm_gsp_device *device) -{ - NV0080_ALLOC_PARAMETERS *args; - int ret; - - args = nvkm_gsp_rm_alloc_get(&client->object, 0xde1d0000, NV01_DEVICE_0, sizeof(*args), - &device->object); - if (IS_ERR(args)) - return PTR_ERR(args); - - args->hClientShare = client->object.handle; - - ret = nvkm_gsp_rm_alloc_wr(&device->object, args); - if (ret) - return ret; - - ret = r535_gsp_subdevice_ctor(device); - if (ret) - nvkm_gsp_rm_free(&device->object); - - return ret; -} - const struct nvkm_gsp_rm r535_gsp_rm = { .api = &r535_rm, - - .device_ctor = r535_gsp_device_ctor, - .device_dtor = r535_gsp_device_dtor, - - .event_ctor = r535_gsp_device_event_ctor, - .event_dtor = r535_gsp_event_dtor, }; static void diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/Kbuild index f25b438fa3d9..d50f2c351d93 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/Kbuild @@ -7,3 +7,4 @@ nvkm-y += nvkm/subdev/gsp/rm/r535/rpc.o nvkm-y += nvkm/subdev/gsp/rm/r535/ctrl.o nvkm-y += nvkm/subdev/gsp/rm/r535/alloc.o nvkm-y += nvkm/subdev/gsp/rm/r535/client.o +nvkm-y += nvkm/subdev/gsp/rm/r535/device.o diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/device.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/device.c new file mode 100644 index 000000000000..09173ca1c050 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/device.c @@ -0,0 +1,153 @@ +/* + * 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 <rm/rm.h> + +#include <nvrm/nvtypes.h> +#include <nvrm/535.113.01/common/sdk/nvidia/inc/class/cl0005.h> +#include <nvrm/535.113.01/common/sdk/nvidia/inc/class/cl0080.h> +#include <nvrm/535.113.01/common/sdk/nvidia/inc/class/cl2080.h> +#include <nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl2080/ctrl2080event.h> +#include <nvrm/535.113.01/common/sdk/nvidia/inc/nvos.h> +#include <nvrm/535.113.01/nvidia/generated/g_allclasses.h> + +static void +r535_gsp_event_dtor(struct nvkm_gsp_event *event) +{ + struct nvkm_gsp_device *device = event->device; + struct nvkm_gsp_client *client = device->object.client; + struct nvkm_gsp *gsp = client->gsp; + + mutex_lock(&gsp->client_id.mutex); + if (event->func) { + list_del(&event->head); + event->func = NULL; + } + mutex_unlock(&gsp->client_id.mutex); + + nvkm_gsp_rm_free(&event->object); + event->device = NULL; +} + +static int +r535_gsp_device_event_get(struct nvkm_gsp_event *event) +{ + struct nvkm_gsp_device *device = event->device; + NV2080_CTRL_EVENT_SET_NOTIFICATION_PARAMS *ctrl; + + ctrl = nvkm_gsp_rm_ctrl_get(&device->subdevice, + NV2080_CTRL_CMD_EVENT_SET_NOTIFICATION, sizeof(*ctrl)); + if (IS_ERR(ctrl)) + return PTR_ERR(ctrl); + + ctrl->event = event->id; + ctrl->action = NV2080_CTRL_EVENT_SET_NOTIFICATION_ACTION_REPEAT; + return nvkm_gsp_rm_ctrl_wr(&device->subdevice, ctrl); +} + +static int +r535_gsp_device_event_ctor(struct nvkm_gsp_device *device, u32 handle, u32 id, + nvkm_gsp_event_func func, struct nvkm_gsp_event *event) +{ + struct nvkm_gsp_client *client = device->object.client; + struct nvkm_gsp *gsp = client->gsp; + NV0005_ALLOC_PARAMETERS *args; + int ret; + + args = nvkm_gsp_rm_alloc_get(&device->subdevice, handle, + NV01_EVENT_KERNEL_CALLBACK_EX, sizeof(*args), + &event->object); + if (IS_ERR(args)) + return PTR_ERR(args); + + args->hParentClient = client->object.handle; + args->hSrcResource = 0; + args->hClass = NV01_EVENT_KERNEL_CALLBACK_EX; + args->notifyIndex = NV01_EVENT_CLIENT_RM | id; + args->data = NULL; + + ret = nvkm_gsp_rm_alloc_wr(&event->object, args); + if (ret) + return ret; + + event->device = device; + event->id = id; + + ret = r535_gsp_device_event_get(event); + if (ret) { + nvkm_gsp_event_dtor(event); + return ret; + } + + mutex_lock(&gsp->client_id.mutex); + event->func = func; + list_add(&event->head, &client->events); + mutex_unlock(&gsp->client_id.mutex); + return 0; +} + +static void +r535_gsp_device_dtor(struct nvkm_gsp_device *device) +{ + nvkm_gsp_rm_free(&device->subdevice); + nvkm_gsp_rm_free(&device->object); +} + +static int +r535_gsp_subdevice_ctor(struct nvkm_gsp_device *device) +{ + NV2080_ALLOC_PARAMETERS *args; + + return nvkm_gsp_rm_alloc(&device->object, 0x5d1d0000, NV20_SUBDEVICE_0, sizeof(*args), + &device->subdevice); +} + +static int +r535_gsp_device_ctor(struct nvkm_gsp_client *client, struct nvkm_gsp_device *device) +{ + NV0080_ALLOC_PARAMETERS *args; + int ret; + + args = nvkm_gsp_rm_alloc_get(&client->object, 0xde1d0000, NV01_DEVICE_0, sizeof(*args), + &device->object); + if (IS_ERR(args)) + return PTR_ERR(args); + + args->hClientShare = client->object.handle; + + ret = nvkm_gsp_rm_alloc_wr(&device->object, args); + if (ret) + return ret; + + ret = r535_gsp_subdevice_ctor(device); + if (ret) + nvkm_gsp_rm_free(&device->object); + + return ret; +} + +const struct nvkm_rm_api_device +r535_device = { + .ctor = r535_gsp_device_ctor, + .dtor = r535_gsp_device_dtor, + .event.ctor = r535_gsp_device_event_ctor, + .event.dtor = r535_gsp_event_dtor, +}; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rm.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rm.c index dba1d2058b37..39cc3d0c740c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rm.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rm.c @@ -10,4 +10,5 @@ r535_rm = { .ctrl = &r535_ctrl, .alloc = &r535_alloc, .client = &r535_client, + .device = &r535_device, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h index c3341631fbd5..20841305fa55 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h @@ -32,6 +32,17 @@ struct nvkm_rm_api { int (*ctor)(struct nvkm_gsp *, struct nvkm_gsp_client *); void (*dtor)(struct nvkm_gsp_client *); } *client; + + const struct nvkm_rm_api_device { + int (*ctor)(struct nvkm_gsp_client *, struct nvkm_gsp_device *); + void (*dtor)(struct nvkm_gsp_device *); + + struct { + int (*ctor)(struct nvkm_gsp_device *, u32 handle, u32 id, + nvkm_gsp_event_func, struct nvkm_gsp_event *); + void (*dtor)(struct nvkm_gsp_event *); + } event; + } *device; }; extern const struct nvkm_rm_api r535_rm; @@ -39,4 +50,5 @@ extern const struct nvkm_rm_api_rpc r535_rpc; extern const struct nvkm_rm_api_ctrl r535_ctrl; extern const struct nvkm_rm_api_alloc r535_alloc; extern const struct nvkm_rm_api_client r535_client; +extern const struct nvkm_rm_api_device r535_device; #endif -- 2.49.0
Ben Skeggs
2025-May-17 00:09 UTC
[PATCH v3 11/62] drm/nouveau/gsp: move firmware loading to GPU-specific code
GH100/GBxxx use a slightly different set of firmwares to boot GSP-RM. Signed-off-by: Ben Skeggs <bskeggs at nvidia.com> Reviewed-by: Dave Airlie <airlied at redhat.com> Reviewed-by: Timur Tabi <ttabi at nvidia.com> Tested-by: Timur Tabi <ttabi at nvidia.com> --- .../gpu/drm/nouveau/nvkm/subdev/gsp/ad102.c | 8 +- .../gpu/drm/nouveau/nvkm/subdev/gsp/base.c | 23 ++++++ .../gpu/drm/nouveau/nvkm/subdev/gsp/ga100.c | 4 +- .../gpu/drm/nouveau/nvkm/subdev/gsp/ga102.c | 8 +- .../gpu/drm/nouveau/nvkm/subdev/gsp/priv.h | 12 ++- .../gpu/drm/nouveau/nvkm/subdev/gsp/r535.c | 78 +------------------ .../gpu/drm/nouveau/nvkm/subdev/gsp/tu102.c | 52 ++++++++++++- .../gpu/drm/nouveau/nvkm/subdev/gsp/tu116.c | 5 +- 8 files changed, 108 insertions(+), 82 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ad102.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ad102.c index c849c6299c52..221ea0fd8a51 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ad102.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ad102.c @@ -45,7 +45,7 @@ ad102_gsp_r535_113_01 = { static struct nvkm_gsp_fwif ad102_gsps[] = { - { 0, r535_gsp_load, &ad102_gsp_r535_113_01, "535.113.01", true }, + { 0, tu102_gsp_load, &ad102_gsp_r535_113_01, "535.113.01", true }, {} }; @@ -55,3 +55,9 @@ ad102_gsp_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, { return nvkm_gsp_new_(ad102_gsps, device, type, inst, pgsp); } + +NVKM_GSP_FIRMWARE_BOOTER(ad102, 535.113.01); +NVKM_GSP_FIRMWARE_BOOTER(ad103, 535.113.01); +NVKM_GSP_FIRMWARE_BOOTER(ad104, 535.113.01); +NVKM_GSP_FIRMWARE_BOOTER(ad106, 535.113.01); +NVKM_GSP_FIRMWARE_BOOTER(ad107, 535.113.01); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/base.c index da1bebb896f7..fe1cef1b6324 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/base.c @@ -80,6 +80,19 @@ nvkm_gsp_oneinit(struct nvkm_subdev *subdev) return gsp->func->oneinit(gsp); } +void +nvkm_gsp_dtor_fws(struct nvkm_gsp *gsp) +{ + nvkm_firmware_put(gsp->fws.bl); + gsp->fws.bl = NULL; + nvkm_firmware_put(gsp->fws.booter.unload); + gsp->fws.booter.unload = NULL; + nvkm_firmware_put(gsp->fws.booter.load); + gsp->fws.booter.load = NULL; + nvkm_firmware_put(gsp->fws.rm); + gsp->fws.rm = NULL; +} + static void * nvkm_gsp_dtor(struct nvkm_subdev *subdev) { @@ -100,6 +113,16 @@ nvkm_gsp = { .fini = nvkm_gsp_fini, }; +int +nvkm_gsp_load_fw(struct nvkm_gsp *gsp, const char *name, const char *ver, + const struct firmware **pfw) +{ + char fwname[64]; + + snprintf(fwname, sizeof(fwname), "gsp/%s-%s", name, ver); + return nvkm_firmware_get(&gsp->subdev, fwname, 0, pfw); +} + int nvkm_gsp_new_(const struct nvkm_gsp_fwif *fwif, struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct nvkm_gsp **pgsp) diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ga100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ga100.c index 223f68b532ef..c3be72d3390a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ga100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ga100.c @@ -61,7 +61,7 @@ ga100_gsp_r535_113_01 = { static struct nvkm_gsp_fwif ga100_gsps[] = { - { 0, r535_gsp_load, &ga100_gsp_r535_113_01, "535.113.01" }, + { 0, tu102_gsp_load, &ga100_gsp_r535_113_01, "535.113.01" }, { -1, gv100_gsp_nofw, &gv100_gsp }, {} }; @@ -72,3 +72,5 @@ ga100_gsp_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, { return nvkm_gsp_new_(ga100_gsps, device, type, inst, pgsp); } + +NVKM_GSP_FIRMWARE_BOOTER(ga100, 535.113.01); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ga102.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ga102.c index 4c4b4168a266..d7385d3989f1 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ga102.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ga102.c @@ -178,7 +178,7 @@ ga102_gsp = { static struct nvkm_gsp_fwif ga102_gsps[] = { - { 0, r535_gsp_load, &ga102_gsp_r535_113_01, "535.113.01" }, + { 0, tu102_gsp_load, &ga102_gsp_r535_113_01, "535.113.01" }, { -1, gv100_gsp_nofw, &ga102_gsp }, {} }; @@ -189,3 +189,9 @@ ga102_gsp_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, { return nvkm_gsp_new_(ga102_gsps, device, type, inst, pgsp); } + +NVKM_GSP_FIRMWARE_BOOTER(ga102, 535.113.01); +NVKM_GSP_FIRMWARE_BOOTER(ga103, 535.113.01); +NVKM_GSP_FIRMWARE_BOOTER(ga104, 535.113.01); +NVKM_GSP_FIRMWARE_BOOTER(ga106, 535.113.01); +NVKM_GSP_FIRMWARE_BOOTER(ga107, 535.113.01); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/priv.h index 9f4a62375a27..601dd5d503bb 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/priv.h @@ -15,8 +15,18 @@ struct nvkm_gsp_fwif { bool enable; }; +int nvkm_gsp_load_fw(struct nvkm_gsp *, const char *name, const char *ver, + const struct firmware **); +void nvkm_gsp_dtor_fws(struct nvkm_gsp *); + int gv100_gsp_nofw(struct nvkm_gsp *, int, const struct nvkm_gsp_fwif *); -int r535_gsp_load(struct nvkm_gsp *, int, const struct nvkm_gsp_fwif *); +int tu102_gsp_load(struct nvkm_gsp *, int, const struct nvkm_gsp_fwif *); + +#define NVKM_GSP_FIRMWARE_BOOTER(chip,vers) \ +MODULE_FIRMWARE("nvidia/"#chip"/gsp/booter_load-"#vers".bin"); \ +MODULE_FIRMWARE("nvidia/"#chip"/gsp/booter_unload-"#vers".bin"); \ +MODULE_FIRMWARE("nvidia/"#chip"/gsp/bootloader-"#vers".bin"); \ +MODULE_FIRMWARE("nvidia/"#chip"/gsp/gsp-"#vers".bin") struct nvkm_gsp_func { const struct nvkm_falcon_func *flcn; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c index c292f5a4e1ec..9d5b77b3cb2f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c @@ -1960,19 +1960,6 @@ r535_gsp_elf_section(struct nvkm_gsp *gsp, const char *name, const u8 **pdata, u return -ENOENT; } -static void -r535_gsp_dtor_fws(struct nvkm_gsp *gsp) -{ - nvkm_firmware_put(gsp->fws.bl); - gsp->fws.bl = NULL; - nvkm_firmware_put(gsp->fws.booter.unload); - gsp->fws.booter.unload = NULL; - nvkm_firmware_put(gsp->fws.booter.load); - gsp->fws.booter.load = NULL; - nvkm_firmware_put(gsp->fws.rm); - gsp->fws.rm = NULL; -} - #ifdef CONFIG_DEBUG_FS struct r535_gsp_log { @@ -2209,7 +2196,7 @@ r535_gsp_dtor(struct nvkm_gsp *gsp) mutex_destroy(&gsp->msgq.mutex); mutex_destroy(&gsp->cmdq.mutex); - r535_gsp_dtor_fws(gsp); + nvkm_gsp_dtor_fws(gsp); nvkm_gsp_mem_dtor(&gsp->rmargs); nvkm_gsp_mem_dtor(&gsp->wpr_meta); @@ -2284,7 +2271,7 @@ r535_gsp_oneinit(struct nvkm_gsp *gsp) return ret; /* Release FW images - we've copied them to DMA buffers now. */ - r535_gsp_dtor_fws(gsp); + nvkm_gsp_dtor_fws(gsp); /* Calculate FB layout. */ gsp->fb.wpr2.frts.size = 0x100000; @@ -2349,64 +2336,3 @@ r535_gsp_oneinit(struct nvkm_gsp *gsp) idr_init(&gsp->client_id.idr); return 0; } - -static int -r535_gsp_load_fw(struct nvkm_gsp *gsp, const char *name, const char *ver, - const struct firmware **pfw) -{ - char fwname[64]; - - snprintf(fwname, sizeof(fwname), "gsp/%s-%s", name, ver); - return nvkm_firmware_get(&gsp->subdev, fwname, 0, pfw); -} - -int -r535_gsp_load(struct nvkm_gsp *gsp, int ver, const struct nvkm_gsp_fwif *fwif) -{ - struct nvkm_subdev *subdev = &gsp->subdev; - int ret; - bool enable_gsp = fwif->enable; - -#if IS_ENABLED(CONFIG_DRM_NOUVEAU_GSP_DEFAULT) - enable_gsp = true; -#endif - if (!nvkm_boolopt(subdev->device->cfgopt, "NvGspRm", enable_gsp)) - return -EINVAL; - - if ((ret = r535_gsp_load_fw(gsp, "gsp", fwif->ver, &gsp->fws.rm)) || - (ret = r535_gsp_load_fw(gsp, "booter_load", fwif->ver, &gsp->fws.booter.load)) || - (ret = r535_gsp_load_fw(gsp, "booter_unload", fwif->ver, &gsp->fws.booter.unload)) || - (ret = r535_gsp_load_fw(gsp, "bootloader", fwif->ver, &gsp->fws.bl))) { - r535_gsp_dtor_fws(gsp); - return ret; - } - - return 0; -} - -#define NVKM_GSP_FIRMWARE(chip) \ -MODULE_FIRMWARE("nvidia/"#chip"/gsp/booter_load-535.113.01.bin"); \ -MODULE_FIRMWARE("nvidia/"#chip"/gsp/booter_unload-535.113.01.bin"); \ -MODULE_FIRMWARE("nvidia/"#chip"/gsp/bootloader-535.113.01.bin"); \ -MODULE_FIRMWARE("nvidia/"#chip"/gsp/gsp-535.113.01.bin") - -NVKM_GSP_FIRMWARE(tu102); -NVKM_GSP_FIRMWARE(tu104); -NVKM_GSP_FIRMWARE(tu106); - -NVKM_GSP_FIRMWARE(tu116); -NVKM_GSP_FIRMWARE(tu117); - -NVKM_GSP_FIRMWARE(ga100); - -NVKM_GSP_FIRMWARE(ga102); -NVKM_GSP_FIRMWARE(ga103); -NVKM_GSP_FIRMWARE(ga104); -NVKM_GSP_FIRMWARE(ga106); -NVKM_GSP_FIRMWARE(ga107); - -NVKM_GSP_FIRMWARE(ad102); -NVKM_GSP_FIRMWARE(ad103); -NVKM_GSP_FIRMWARE(ad104); -NVKM_GSP_FIRMWARE(ad106); -NVKM_GSP_FIRMWARE(ad107); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/tu102.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/tu102.c index 59c5f2b9172a..e7396344cfdf 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/tu102.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/tu102.c @@ -183,9 +183,55 @@ tu102_gsp_r535_113_01 = { .rm = &r535_gsp_rm, }; +static int +tu102_gsp_load_rm(struct nvkm_gsp *gsp, const struct nvkm_gsp_fwif *fwif) +{ + struct nvkm_subdev *subdev = &gsp->subdev; + bool enable_gsp = fwif->enable; + int ret; + +#if IS_ENABLED(CONFIG_DRM_NOUVEAU_GSP_DEFAULT) + enable_gsp = true; +#endif + if (!nvkm_boolopt(subdev->device->cfgopt, "NvGspRm", enable_gsp)) + return -EINVAL; + + ret = nvkm_gsp_load_fw(gsp, "gsp", fwif->ver, &gsp->fws.rm); + if (ret) + return ret; + + ret = nvkm_gsp_load_fw(gsp, "bootloader", fwif->ver, &gsp->fws.bl); + if (ret) + return ret; + + return 0; +} + +int +tu102_gsp_load(struct nvkm_gsp *gsp, int ver, const struct nvkm_gsp_fwif *fwif) +{ + int ret; + + ret = tu102_gsp_load_rm(gsp, fwif); + if (ret) + goto done; + + ret = nvkm_gsp_load_fw(gsp, "booter_load", fwif->ver, &gsp->fws.booter.load); + if (ret) + goto done; + + ret = nvkm_gsp_load_fw(gsp, "booter_unload", fwif->ver, &gsp->fws.booter.unload); + +done: + if (ret) + nvkm_gsp_dtor_fws(gsp); + + return ret; +} + static struct nvkm_gsp_fwif tu102_gsps[] = { - { 0, r535_gsp_load, &tu102_gsp_r535_113_01, "535.113.01" }, + { 0, tu102_gsp_load, &tu102_gsp_r535_113_01, "535.113.01" }, { -1, gv100_gsp_nofw, &gv100_gsp }, {} }; @@ -196,3 +242,7 @@ tu102_gsp_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, { return nvkm_gsp_new_(tu102_gsps, device, type, inst, pgsp); } + +NVKM_GSP_FIRMWARE_BOOTER(tu102, 535.113.01); +NVKM_GSP_FIRMWARE_BOOTER(tu104, 535.113.01); +NVKM_GSP_FIRMWARE_BOOTER(tu106, 535.113.01); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/tu116.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/tu116.c index 04fbd9ed28b1..a8c9480b8024 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/tu116.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/tu116.c @@ -44,7 +44,7 @@ tu116_gsp_r535_113_01 = { static struct nvkm_gsp_fwif tu116_gsps[] = { - { 0, r535_gsp_load, &tu116_gsp_r535_113_01, "535.113.01" }, + { 0, tu102_gsp_load, &tu116_gsp_r535_113_01, "535.113.01" }, { -1, gv100_gsp_nofw, &gv100_gsp }, {} }; @@ -55,3 +55,6 @@ tu116_gsp_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, { return nvkm_gsp_new_(tu116_gsps, device, type, inst, pgsp); } + +NVKM_GSP_FIRMWARE_BOOTER(tu116, 535.113.01); +NVKM_GSP_FIRMWARE_BOOTER(tu117, 535.113.01); -- 2.49.0
Ben Skeggs
2025-May-17 00:09 UTC
[PATCH v3 12/62] drm/nouveau/gsp: move booter handling to GPU-specific code
GH100/GBxxx have significant changes to the GSP-RM boot process. Signed-off-by: Ben Skeggs <bskeggs at nvidia.com> Reviewed-by: Dave Airlie <airlied at redhat.com> Reviewed-by: Timur Tabi <ttabi at nvidia.com> Tested-by: Timur Tabi <ttabi at nvidia.com> --- .../gpu/drm/nouveau/nvkm/subdev/gsp/ad102.c | 4 +- .../gpu/drm/nouveau/nvkm/subdev/gsp/base.c | 2 +- .../gpu/drm/nouveau/nvkm/subdev/gsp/ga100.c | 4 +- .../gpu/drm/nouveau/nvkm/subdev/gsp/ga102.c | 4 +- .../gpu/drm/nouveau/nvkm/subdev/gsp/priv.h | 3 + .../gpu/drm/nouveau/nvkm/subdev/gsp/r535.c | 94 +-------------- .../gpu/drm/nouveau/nvkm/subdev/gsp/tu102.c | 113 +++++++++++++++++- .../gpu/drm/nouveau/nvkm/subdev/gsp/tu116.c | 4 +- 8 files changed, 125 insertions(+), 103 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ad102.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ad102.c index 221ea0fd8a51..ea2821e7a54e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ad102.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ad102.c @@ -36,8 +36,8 @@ ad102_gsp_r535_113_01 = { .dtor = r535_gsp_dtor, .oneinit = tu102_gsp_oneinit, - .init = r535_gsp_init, - .fini = r535_gsp_fini, + .init = tu102_gsp_init, + .fini = tu102_gsp_fini, .reset = ga102_gsp_reset, .rm = &r535_gsp_rm, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/base.c index fe1cef1b6324..78f2a15f0d42 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/base.c @@ -52,7 +52,7 @@ nvkm_gsp_fini(struct nvkm_subdev *subdev, bool suspend) { struct nvkm_gsp *gsp = nvkm_gsp(subdev); - if (!gsp->func->fini) + if (!gsp->func->fini || !gsp->running) return 0; return gsp->func->fini(gsp, suspend); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ga100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ga100.c index c3be72d3390a..d9cdec4810b4 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ga100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ga100.c @@ -52,8 +52,8 @@ ga100_gsp_r535_113_01 = { .dtor = r535_gsp_dtor, .oneinit = tu102_gsp_oneinit, - .init = r535_gsp_init, - .fini = r535_gsp_fini, + .init = tu102_gsp_init, + .fini = tu102_gsp_fini, .reset = tu102_gsp_reset, .rm = &r535_gsp_rm, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ga102.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ga102.c index d7385d3989f1..7b8db70f3cb3 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ga102.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ga102.c @@ -164,8 +164,8 @@ ga102_gsp_r535_113_01 = { .dtor = r535_gsp_dtor, .oneinit = tu102_gsp_oneinit, - .init = r535_gsp_init, - .fini = r535_gsp_fini, + .init = tu102_gsp_init, + .fini = tu102_gsp_fini, .reset = ga102_gsp_reset, .rm = &r535_gsp_rm, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/priv.h index 601dd5d503bb..e6f0e865848a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/priv.h @@ -59,6 +59,8 @@ extern const struct nvkm_falcon_fw_func tu102_gsp_fwsec; int tu102_gsp_booter_ctor(struct nvkm_gsp *, const char *, const struct firmware *, struct nvkm_falcon *, struct nvkm_falcon_fw *); int tu102_gsp_oneinit(struct nvkm_gsp *); +int tu102_gsp_init(struct nvkm_gsp *); +int tu102_gsp_fini(struct nvkm_gsp *, bool suspend); int tu102_gsp_reset(struct nvkm_gsp *); extern const struct nvkm_falcon_func ga102_gsp_flcn; @@ -72,6 +74,7 @@ int r535_gsp_oneinit(struct nvkm_gsp *); int r535_gsp_init(struct nvkm_gsp *); int r535_gsp_fini(struct nvkm_gsp *, bool suspend); extern const struct nvkm_gsp_rm r535_gsp_rm; +int r535_gsp_rmargs_init(struct nvkm_gsp *gsp, bool resume); int nvkm_gsp_new_(const struct nvkm_gsp_fwif *, struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_gsp **); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c index 9d5b77b3cb2f..f42879b2ea7e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c @@ -1145,48 +1145,6 @@ r535_gsp_msg_run_cpu_sequencer(void *priv, u32 fn, void *repv, u32 repc) return 0; } -static int -r535_gsp_booter_unload(struct nvkm_gsp *gsp, u32 mbox0, u32 mbox1) -{ - struct nvkm_subdev *subdev = &gsp->subdev; - struct nvkm_device *device = subdev->device; - u32 wpr2_hi; - int ret; - - wpr2_hi = nvkm_rd32(device, 0x1fa828); - if (!wpr2_hi) { - nvkm_debug(subdev, "WPR2 not set - skipping booter unload\n"); - return 0; - } - - ret = nvkm_falcon_fw_boot(&gsp->booter.unload, &gsp->subdev, true, &mbox0, &mbox1, 0, 0); - if (WARN_ON(ret)) - return ret; - - wpr2_hi = nvkm_rd32(device, 0x1fa828); - if (WARN_ON(wpr2_hi)) - return -EIO; - - return 0; -} - -static int -r535_gsp_booter_load(struct nvkm_gsp *gsp, u32 mbox0, u32 mbox1) -{ - int ret; - - ret = nvkm_falcon_fw_boot(&gsp->booter.load, &gsp->subdev, true, &mbox0, &mbox1, 0, 0); - if (ret) - return ret; - - nvkm_falcon_wr32(&gsp->falcon, 0x080, gsp->boot.app_version); - - if (WARN_ON(!nvkm_falcon_riscv_active(&gsp->falcon))) - return -EIO; - - return 0; -} - static int r535_gsp_wpr_meta_init(struct nvkm_gsp *gsp) { @@ -1287,7 +1245,7 @@ r535_gsp_shared_init(struct nvkm_gsp *gsp) return 0; } -static int +int r535_gsp_rmargs_init(struct nvkm_gsp *gsp, bool resume) { GSP_ARGUMENTS_CACHED *args; @@ -1816,12 +1774,8 @@ nvkm_gsp_radix3_sg(struct nvkm_gsp *gsp, struct sg_table *sgt, u64 size, int r535_gsp_fini(struct nvkm_gsp *gsp, bool suspend) { - u32 mbox0 = 0xff, mbox1 = 0xff; int ret; - if (!gsp->running) - return 0; - if (suspend) { GspFwWprMeta *meta = gsp->wpr_meta.data; u64 len = meta->gspFwWprEnd - meta->gspFwWprStart; @@ -1844,9 +1798,6 @@ r535_gsp_fini(struct nvkm_gsp *gsp, bool suspend) sr->revision = GSP_FW_SR_META_REVISION; sr->sysmemAddrOfSuspendResumeData = gsp->sr.radix3.lvl0.addr; sr->sizeOfSuspendResumeData = len; - - mbox0 = lower_32_bits(gsp->sr.meta.addr); - mbox1 = upper_32_bits(gsp->sr.meta.addr); } ret = r535_gsp_rpc_unloading_guest_driver(gsp, suspend); @@ -1858,14 +1809,6 @@ r535_gsp_fini(struct nvkm_gsp *gsp, bool suspend) break; ); - nvkm_falcon_reset(&gsp->falcon); - - ret = nvkm_gsp_fwsec_sb(gsp); - WARN_ON(ret); - - ret = r535_gsp_booter_unload(gsp, mbox0, mbox1); - WARN_ON(ret); - gsp->running = false; return 0; } @@ -1873,23 +1816,12 @@ r535_gsp_fini(struct nvkm_gsp *gsp, bool suspend) int r535_gsp_init(struct nvkm_gsp *gsp) { - u32 mbox0, mbox1; int ret; - if (!gsp->sr.meta.data) { - mbox0 = lower_32_bits(gsp->wpr_meta.addr); - mbox1 = upper_32_bits(gsp->wpr_meta.addr); - } else { - r535_gsp_rmargs_init(gsp, true); - - mbox0 = lower_32_bits(gsp->sr.meta.addr); - mbox1 = upper_32_bits(gsp->sr.meta.addr); - } + nvkm_falcon_wr32(&gsp->falcon, 0x080, gsp->boot.app_version); - /* Execute booter to handle (eventually...) booting GSP-RM. */ - ret = r535_gsp_booter_load(gsp, mbox0, mbox1); - if (WARN_ON(ret)) - goto done; + if (WARN_ON(!nvkm_falcon_riscv_active(&gsp->falcon))) + return -EIO; ret = r535_gsp_rpc_poll(gsp, NV_VGPU_MSG_EVENT_GSP_INIT_DONE); if (ret) @@ -2220,16 +2152,6 @@ r535_gsp_oneinit(struct nvkm_gsp *gsp) mutex_init(&gsp->cmdq.mutex); mutex_init(&gsp->msgq.mutex); - ret = gsp->func->booter.ctor(gsp, "booter-load", gsp->fws.booter.load, - &device->sec2->falcon, &gsp->booter.load); - if (ret) - return ret; - - ret = gsp->func->booter.ctor(gsp, "booter-unload", gsp->fws.booter.unload, - &device->sec2->falcon, &gsp->booter.unload); - if (ret) - return ret; - /* Load GSP firmware from ELF image into DMA-accessible memory. */ ret = r535_gsp_elf_section(gsp, ".fwimage", &data, &size); if (ret) @@ -2324,14 +2246,6 @@ r535_gsp_oneinit(struct nvkm_gsp *gsp) if (WARN_ON(ret)) return ret; - /* Reset GSP into RISC-V mode. */ - ret = gsp->func->reset(gsp); - if (WARN_ON(ret)) - return ret; - - nvkm_falcon_wr32(&gsp->falcon, 0x040, lower_32_bits(gsp->libos.addr)); - nvkm_falcon_wr32(&gsp->falcon, 0x044, upper_32_bits(gsp->libos.addr)); - mutex_init(&gsp->client_id.mutex); idr_init(&gsp->client_id.idr); return 0; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/tu102.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/tu102.c index e7396344cfdf..451d3e588d26 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/tu102.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/tu102.c @@ -22,11 +22,43 @@ #include "priv.h" #include <subdev/fb.h> +#include <engine/sec2.h> #include <nvfw/flcn.h> #include <nvfw/fw.h> #include <nvfw/hs.h> +static int +tu102_gsp_booter_unload(struct nvkm_gsp *gsp, u32 mbox0, u32 mbox1) +{ + struct nvkm_subdev *subdev = &gsp->subdev; + struct nvkm_device *device = subdev->device; + u32 wpr2_hi; + int ret; + + wpr2_hi = nvkm_rd32(device, 0x1fa828); + if (!wpr2_hi) { + nvkm_debug(subdev, "WPR2 not set - skipping booter unload\n"); + return 0; + } + + ret = nvkm_falcon_fw_boot(&gsp->booter.unload, &gsp->subdev, true, &mbox0, &mbox1, 0, 0); + if (WARN_ON(ret)) + return ret; + + wpr2_hi = nvkm_rd32(device, 0x1fa828); + if (WARN_ON(wpr2_hi)) + return -EIO; + + return 0; +} + +static int +tu102_gsp_booter_load(struct nvkm_gsp *gsp, u32 mbox0, u32 mbox1) +{ + return nvkm_falcon_fw_boot(&gsp->booter.load, &gsp->subdev, true, &mbox0, &mbox1, 0, 0); +} + int tu102_gsp_booter_ctor(struct nvkm_gsp *gsp, const char *name, const struct firmware *blob, struct nvkm_falcon *falcon, struct nvkm_falcon_fw *fw) @@ -114,6 +146,55 @@ tu102_gsp_reset(struct nvkm_gsp *gsp) return gsp->falcon.func->reset_eng(&gsp->falcon); } +int +tu102_gsp_fini(struct nvkm_gsp *gsp, bool suspend) +{ + u32 mbox0 = 0xff, mbox1 = 0xff; + int ret; + + ret = r535_gsp_fini(gsp, suspend); + if (ret && suspend) + return ret; + + nvkm_falcon_reset(&gsp->falcon); + + ret = nvkm_gsp_fwsec_sb(gsp); + WARN_ON(ret); + + if (suspend) { + mbox0 = lower_32_bits(gsp->sr.meta.addr); + mbox1 = upper_32_bits(gsp->sr.meta.addr); + } + + ret = tu102_gsp_booter_unload(gsp, mbox0, mbox1); + WARN_ON(ret); + return 0; +} + +int +tu102_gsp_init(struct nvkm_gsp *gsp) +{ + u32 mbox0, mbox1; + int ret; + + if (!gsp->sr.meta.data) { + mbox0 = lower_32_bits(gsp->wpr_meta.addr); + mbox1 = upper_32_bits(gsp->wpr_meta.addr); + } else { + r535_gsp_rmargs_init(gsp, true); + + mbox0 = lower_32_bits(gsp->sr.meta.addr); + mbox1 = upper_32_bits(gsp->sr.meta.addr); + } + + /* Execute booter to handle (eventually...) booting GSP-RM. */ + ret = tu102_gsp_booter_load(gsp, mbox0, mbox1); + if (WARN_ON(ret)) + return ret; + + return r535_gsp_init(gsp); +} + static u64 tu102_gsp_vga_workspace_addr(struct nvkm_gsp *gsp, u64 fb_size) { @@ -136,14 +217,38 @@ tu102_gsp_vga_workspace_addr(struct nvkm_gsp *gsp, u64 fb_size) int tu102_gsp_oneinit(struct nvkm_gsp *gsp) { - gsp->fb.size = nvkm_fb_vidmem_size(gsp->subdev.device); + struct nvkm_device *device = gsp->subdev.device; + int ret; + + gsp->fb.size = nvkm_fb_vidmem_size(device); gsp->fb.bios.vga_workspace.addr = tu102_gsp_vga_workspace_addr(gsp, gsp->fb.size); gsp->fb.bios.vga_workspace.size = gsp->fb.size - gsp->fb.bios.vga_workspace.addr; gsp->fb.bios.addr = gsp->fb.bios.vga_workspace.addr; gsp->fb.bios.size = gsp->fb.bios.vga_workspace.size; - return r535_gsp_oneinit(gsp); + ret = gsp->func->booter.ctor(gsp, "booter-load", gsp->fws.booter.load, + &device->sec2->falcon, &gsp->booter.load); + if (ret) + return ret; + + ret = gsp->func->booter.ctor(gsp, "booter-unload", gsp->fws.booter.unload, + &device->sec2->falcon, &gsp->booter.unload); + if (ret) + return ret; + + ret = r535_gsp_oneinit(gsp); + if (ret) + return ret; + + /* Reset GSP into RISC-V mode. */ + ret = gsp->func->reset(gsp); + if (ret) + return ret; + + nvkm_falcon_wr32(&gsp->falcon, 0x040, lower_32_bits(gsp->libos.addr)); + nvkm_falcon_wr32(&gsp->falcon, 0x044, upper_32_bits(gsp->libos.addr)); + return 0; } const struct nvkm_falcon_func @@ -176,8 +281,8 @@ tu102_gsp_r535_113_01 = { .dtor = r535_gsp_dtor, .oneinit = tu102_gsp_oneinit, - .init = r535_gsp_init, - .fini = r535_gsp_fini, + .init = tu102_gsp_init, + .fini = tu102_gsp_fini, .reset = tu102_gsp_reset, .rm = &r535_gsp_rm, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/tu116.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/tu116.c index a8c9480b8024..1bc806a18010 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/tu116.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/tu116.c @@ -35,8 +35,8 @@ tu116_gsp_r535_113_01 = { .dtor = r535_gsp_dtor, .oneinit = tu102_gsp_oneinit, - .init = r535_gsp_init, - .fini = r535_gsp_fini, + .init = tu102_gsp_init, + .fini = tu102_gsp_fini, .reset = tu102_gsp_reset, .rm = &r535_gsp_rm, -- 2.49.0
Ben Skeggs
2025-May-17 00:09 UTC
[PATCH v3 13/62] drm/nouveau/gsp: move subdev/engine impls to subdev/gsp/rm/r535/
Move all the remaining GSP-RM code together underneath a versioned path, to make the code easier to work with when adding support for a newer RM version. Aside from adjusting include paths, no code change is intended. Signed-off-by: Ben Skeggs <bskeggs at nvidia.com> Reviewed-by: Dave Airlie <airlied at redhat.com> Reviewed-by: Timur Tabi <ttabi at nvidia.com> Tested-by: Timur Tabi <ttabi at nvidia.com> --- drivers/gpu/drm/nouveau/nvkm/engine/ce/Kbuild | 2 -- drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild | 2 -- drivers/gpu/drm/nouveau/nvkm/engine/fifo/Kbuild | 2 -- drivers/gpu/drm/nouveau/nvkm/engine/gr/Kbuild | 2 -- drivers/gpu/drm/nouveau/nvkm/engine/nvdec/Kbuild | 2 -- drivers/gpu/drm/nouveau/nvkm/engine/nvenc/Kbuild | 2 -- drivers/gpu/drm/nouveau/nvkm/engine/nvjpg/Kbuild | 2 -- drivers/gpu/drm/nouveau/nvkm/engine/ofa/Kbuild | 2 -- drivers/gpu/drm/nouveau/nvkm/subdev/bar/Kbuild | 2 -- drivers/gpu/drm/nouveau/nvkm/subdev/gsp/Kbuild | 2 -- .../drm/nouveau/nvkm/subdev/gsp/rm/r535/Kbuild | 15 +++++++++++++++ .../nvkm/subdev/{bar/r535.c => gsp/rm/r535/bar.c} | 2 +- .../{engine/ce/r535.c => subdev/gsp/rm/r535/ce.c} | 2 +- .../disp/r535.c => subdev/gsp/rm/r535/disp.c} | 14 +++++++------- .../subdev/{instmem/r535.c => gsp/rm/r535/fbsr.c} | 2 +- .../fifo/r535.c => subdev/gsp/rm/r535/fifo.c} | 10 +++++----- .../{engine/gr/r535.c => subdev/gsp/rm/r535/gr.c} | 2 +- .../nvkm/subdev/gsp/{r535.c => rm/r535/gsp.c} | 0 .../nvdec/r535.c => subdev/gsp/rm/r535/nvdec.c} | 2 +- .../nvenc/r535.c => subdev/gsp/rm/r535/nvenc.c} | 2 +- .../nvjpg/r535.c => subdev/gsp/rm/r535/nvjpg.c} | 2 +- .../ofa/r535.c => subdev/gsp/rm/r535/ofa.c} | 2 +- .../nvkm/subdev/{mmu/r535.c => gsp/rm/r535/vmm.c} | 2 +- .../gpu/drm/nouveau/nvkm/subdev/instmem/Kbuild | 2 -- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild | 2 -- 25 files changed, 36 insertions(+), 45 deletions(-) rename drivers/gpu/drm/nouveau/nvkm/subdev/{bar/r535.c => gsp/rm/r535/bar.c} (99%) rename drivers/gpu/drm/nouveau/nvkm/{engine/ce/r535.c => subdev/gsp/rm/r535/ce.c} (99%) rename drivers/gpu/drm/nouveau/nvkm/{engine/disp/r535.c => subdev/gsp/rm/r535/disp.c} (99%) rename drivers/gpu/drm/nouveau/nvkm/subdev/{instmem/r535.c => gsp/rm/r535/fbsr.c} (99%) rename drivers/gpu/drm/nouveau/nvkm/{engine/fifo/r535.c => subdev/gsp/rm/r535/fifo.c} (99%) rename drivers/gpu/drm/nouveau/nvkm/{engine/gr/r535.c => subdev/gsp/rm/r535/gr.c} (99%) rename drivers/gpu/drm/nouveau/nvkm/subdev/gsp/{r535.c => rm/r535/gsp.c} (100%) rename drivers/gpu/drm/nouveau/nvkm/{engine/nvdec/r535.c => subdev/gsp/rm/r535/nvdec.c} (99%) rename drivers/gpu/drm/nouveau/nvkm/{engine/nvenc/r535.c => subdev/gsp/rm/r535/nvenc.c} (99%) rename drivers/gpu/drm/nouveau/nvkm/{engine/nvjpg/r535.c => subdev/gsp/rm/r535/nvjpg.c} (99%) rename drivers/gpu/drm/nouveau/nvkm/{engine/ofa/r535.c => subdev/gsp/rm/r535/ofa.c} (99%) rename drivers/gpu/drm/nouveau/nvkm/subdev/{mmu/r535.c => gsp/rm/r535/vmm.c} (99%) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/ce/Kbuild b/drivers/gpu/drm/nouveau/nvkm/engine/ce/Kbuild index 165d61fc5d6c..8bf1635ffabc 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/ce/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/engine/ce/Kbuild @@ -10,5 +10,3 @@ nvkm-y += nvkm/engine/ce/gv100.o nvkm-y += nvkm/engine/ce/tu102.o nvkm-y += nvkm/engine/ce/ga100.o nvkm-y += nvkm/engine/ce/ga102.o - -nvkm-y += nvkm/engine/ce/r535.o diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild b/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild index e346e924fee8..23a10e081081 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild @@ -29,8 +29,6 @@ nvkm-y += nvkm/engine/disp/tu102.o nvkm-y += nvkm/engine/disp/ga102.o nvkm-y += nvkm/engine/disp/ad102.o -nvkm-y += nvkm/engine/disp/r535.o - nvkm-y += nvkm/engine/disp/udisp.o nvkm-y += nvkm/engine/disp/uconn.o nvkm-y += nvkm/engine/disp/uoutp.o diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/Kbuild b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/Kbuild index aff92848abfe..5a074b9970ab 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/Kbuild @@ -26,7 +26,5 @@ nvkm-y += nvkm/engine/fifo/tu102.o nvkm-y += nvkm/engine/fifo/ga100.o nvkm-y += nvkm/engine/fifo/ga102.o -nvkm-y += nvkm/engine/fifo/r535.o - nvkm-y += nvkm/engine/fifo/ucgrp.o nvkm-y += nvkm/engine/fifo/uchan.o diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/Kbuild b/drivers/gpu/drm/nouveau/nvkm/engine/gr/Kbuild index 1555f8c40b4f..487fcc14b9a9 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/Kbuild @@ -43,8 +43,6 @@ nvkm-y += nvkm/engine/gr/tu102.o nvkm-y += nvkm/engine/gr/ga102.o nvkm-y += nvkm/engine/gr/ad102.o -nvkm-y += nvkm/engine/gr/r535.o - nvkm-y += nvkm/engine/gr/ctxnv40.o nvkm-y += nvkm/engine/gr/ctxnv50.o nvkm-y += nvkm/engine/gr/ctxgf100.o diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/nvdec/Kbuild b/drivers/gpu/drm/nouveau/nvkm/engine/nvdec/Kbuild index 2b0e923cb755..5cc317abc42c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/nvdec/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/engine/nvdec/Kbuild @@ -5,5 +5,3 @@ nvkm-y += nvkm/engine/nvdec/tu102.o nvkm-y += nvkm/engine/nvdec/ga100.o nvkm-y += nvkm/engine/nvdec/ga102.o nvkm-y += nvkm/engine/nvdec/ad102.o - -nvkm-y += nvkm/engine/nvdec/r535.o diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/nvenc/Kbuild b/drivers/gpu/drm/nouveau/nvkm/engine/nvenc/Kbuild index 2c1495b730f3..3d71f2973dab 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/nvenc/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/engine/nvenc/Kbuild @@ -4,5 +4,3 @@ nvkm-y += nvkm/engine/nvenc/gm107.o nvkm-y += nvkm/engine/nvenc/tu102.o nvkm-y += nvkm/engine/nvenc/ga102.o nvkm-y += nvkm/engine/nvenc/ad102.o - -nvkm-y += nvkm/engine/nvenc/r535.o diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/nvjpg/Kbuild b/drivers/gpu/drm/nouveau/nvkm/engine/nvjpg/Kbuild index 1408f664add6..1d9bddd68605 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/nvjpg/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/engine/nvjpg/Kbuild @@ -1,5 +1,3 @@ # SPDX-License-Identifier: MIT nvkm-y += nvkm/engine/nvjpg/ga100.o nvkm-y += nvkm/engine/nvjpg/ad102.o - -nvkm-y += nvkm/engine/nvjpg/r535.o diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/ofa/Kbuild b/drivers/gpu/drm/nouveau/nvkm/engine/ofa/Kbuild index 99f1713d7e51..3faf73b35f5a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/ofa/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/engine/ofa/Kbuild @@ -2,5 +2,3 @@ nvkm-y += nvkm/engine/ofa/ga100.o nvkm-y += nvkm/engine/ofa/ga102.o nvkm-y += nvkm/engine/ofa/ad102.o - -nvkm-y += nvkm/engine/ofa/r535.o diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/Kbuild index 9754c6872543..8faee3317a74 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/Kbuild @@ -7,5 +7,3 @@ nvkm-y += nvkm/subdev/bar/gk20a.o nvkm-y += nvkm/subdev/bar/gm107.o nvkm-y += nvkm/subdev/bar/gm20b.o nvkm-y += nvkm/subdev/bar/tu102.o - -nvkm-y += nvkm/subdev/bar/r535.o diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/Kbuild index af6e55603763..ba892c111c26 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/Kbuild @@ -9,6 +9,4 @@ nvkm-y += nvkm/subdev/gsp/ga100.o nvkm-y += nvkm/subdev/gsp/ga102.o nvkm-y += nvkm/subdev/gsp/ad102.o -nvkm-y += nvkm/subdev/gsp/r535.o - include $(src)/nvkm/subdev/gsp/rm/Kbuild diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/Kbuild index d50f2c351d93..a5f6b2abfd33 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/Kbuild @@ -3,8 +3,23 @@ # Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. nvkm-y += nvkm/subdev/gsp/rm/r535/rm.o +nvkm-y += nvkm/subdev/gsp/rm/r535/gsp.o nvkm-y += nvkm/subdev/gsp/rm/r535/rpc.o nvkm-y += nvkm/subdev/gsp/rm/r535/ctrl.o nvkm-y += nvkm/subdev/gsp/rm/r535/alloc.o nvkm-y += nvkm/subdev/gsp/rm/r535/client.o nvkm-y += nvkm/subdev/gsp/rm/r535/device.o + +nvkm-y += nvkm/subdev/gsp/rm/r535/bar.o +nvkm-y += nvkm/subdev/gsp/rm/r535/fbsr.o +nvkm-y += nvkm/subdev/gsp/rm/r535/vmm.o + +nvkm-y += nvkm/subdev/gsp/rm/r535/disp.o + +nvkm-y += nvkm/subdev/gsp/rm/r535/fifo.o +nvkm-y += nvkm/subdev/gsp/rm/r535/ce.o +nvkm-y += nvkm/subdev/gsp/rm/r535/gr.o +nvkm-y += nvkm/subdev/gsp/rm/r535/nvdec.o +nvkm-y += nvkm/subdev/gsp/rm/r535/nvenc.o +nvkm-y += nvkm/subdev/gsp/rm/r535/nvjpg.o +nvkm-y += nvkm/subdev/gsp/rm/r535/ofa.o diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/r535.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/bar.c similarity index 99% rename from drivers/gpu/drm/nouveau/nvkm/subdev/bar/r535.c rename to drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/bar.c index 90186f98065c..ce2c86c159b5 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/r535.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/bar.c @@ -19,7 +19,7 @@ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ -#include "gf100.h" +#include <subdev/bar/gf100.h> #include <core/mm.h> #include <subdev/fb.h> diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/ce/r535.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/ce.c similarity index 99% rename from drivers/gpu/drm/nouveau/nvkm/engine/ce/r535.c rename to drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/ce.c index bd0d435dbbd3..0d73906f4a5a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/ce/r535.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/ce.c @@ -19,7 +19,7 @@ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ -#include "priv.h" +#include <engine/ce/priv.h> #include <core/object.h> #include <subdev/gsp.h> diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/r535.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c similarity index 99% rename from drivers/gpu/drm/nouveau/nvkm/engine/disp/r535.c rename to drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c index 99110ab2f44d..1aae15167249 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/r535.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c @@ -19,13 +19,13 @@ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ -#include "priv.h" -#include "chan.h" -#include "conn.h" -#include "dp.h" -#include "head.h" -#include "ior.h" -#include "outp.h" +#include <engine/disp/priv.h> +#include <engine/disp/chan.h> +#include <engine/disp/conn.h> +#include <engine/disp/dp.h> +#include <engine/disp/head.h> +#include <engine/disp/ior.h> +#include <engine/disp/outp.h> #include <core/ramht.h> #include <subdev/bios.h> diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/r535.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/fbsr.c similarity index 99% rename from drivers/gpu/drm/nouveau/nvkm/subdev/instmem/r535.c rename to drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/fbsr.c index 35ba1798ee6e..6305f3a93810 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/r535.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/fbsr.c @@ -19,7 +19,7 @@ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ -#include "priv.h" +#include <subdev/instmem/priv.h> #include <subdev/gsp.h> diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/r535.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/fifo.c similarity index 99% rename from drivers/gpu/drm/nouveau/nvkm/engine/fifo/r535.c rename to drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/fifo.c index 129f274c9bfd..621e5dfe898a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/r535.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/fifo.c @@ -19,11 +19,11 @@ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ -#include "priv.h" -#include "cgrp.h" -#include "chan.h" -#include "chid.h" -#include "runl.h" +#include <engine/fifo/priv.h> +#include <engine/fifo/cgrp.h> +#include <engine/fifo/chan.h> +#include <engine/fifo/chid.h> +#include <engine/fifo/runl.h> #include <core/gpuobj.h> #include <subdev/gsp.h> diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/r535.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gr.c similarity index 99% rename from drivers/gpu/drm/nouveau/nvkm/engine/gr/r535.c rename to drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gr.c index f4bed3eb1ec2..37bde547ae65 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/r535.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gr.c @@ -19,7 +19,7 @@ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ -#include "gf100.h" +#include <engine/gr/gf100.h> #include <core/memory.h> #include <subdev/gsp.h> diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c similarity index 100% rename from drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c rename to drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/nvdec/r535.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvdec.c similarity index 99% rename from drivers/gpu/drm/nouveau/nvkm/engine/nvdec/r535.c rename to drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvdec.c index 75a24f3e6617..16c1928f6d68 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/nvdec/r535.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvdec.c @@ -19,7 +19,7 @@ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ -#include "priv.h" +#include <engine/nvdec/priv.h> #include <core/object.h> #include <subdev/gsp.h> diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/nvenc/r535.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvenc.c similarity index 99% rename from drivers/gpu/drm/nouveau/nvkm/engine/nvenc/r535.c rename to drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvenc.c index c8a2a9196ce5..b6808a50c4a8 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/nvenc/r535.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvenc.c @@ -19,7 +19,7 @@ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ -#include "priv.h" +#include <engine/nvenc/priv.h> #include <core/object.h> #include <subdev/gsp.h> diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/nvjpg/r535.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvjpg.c similarity index 99% rename from drivers/gpu/drm/nouveau/nvkm/engine/nvjpg/r535.c rename to drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvjpg.c index 1babddc4eb80..994232b3d030 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/nvjpg/r535.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvjpg.c @@ -19,7 +19,7 @@ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ -#include "priv.h" +#include <engine/nvjpg/priv.h> #include <core/object.h> #include <subdev/gsp.h> diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/ofa/r535.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/ofa.c similarity index 99% rename from drivers/gpu/drm/nouveau/nvkm/engine/ofa/r535.c rename to drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/ofa.c index 438dc692eefe..200201c35f0b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/ofa/r535.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/ofa.c @@ -19,7 +19,7 @@ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ -#include "priv.h" +#include <engine/ofa/priv.h> #include <core/object.h> #include <subdev/gsp.h> diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/r535.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/vmm.c similarity index 99% rename from drivers/gpu/drm/nouveau/nvkm/subdev/mmu/r535.c rename to drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/vmm.c index d3e95453f25d..94cad290e17e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/r535.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/vmm.c @@ -19,7 +19,7 @@ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ -#include "vmm.h" +#include <subdev/mmu/vmm.h> #include <nvrm/nvtypes.h> #include <nvrm/535.113.01/common/sdk/nvidia/inc/class/cl90f1.h> diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/Kbuild index 553d540f2736..06cbe19ce376 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/Kbuild @@ -4,5 +4,3 @@ nvkm-y += nvkm/subdev/instmem/nv04.o nvkm-y += nvkm/subdev/instmem/nv40.o nvkm-y += nvkm/subdev/instmem/nv50.o nvkm-y += nvkm/subdev/instmem/gk20a.o - -nvkm-y += nvkm/subdev/instmem/r535.o diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild index 7ba35ea59c06..a602b0cb5b31 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild @@ -16,8 +16,6 @@ nvkm-y += nvkm/subdev/mmu/gp10b.o nvkm-y += nvkm/subdev/mmu/gv100.o nvkm-y += nvkm/subdev/mmu/tu102.o -nvkm-y += nvkm/subdev/mmu/r535.o - nvkm-y += nvkm/subdev/mmu/mem.o nvkm-y += nvkm/subdev/mmu/memnv04.o nvkm-y += nvkm/subdev/mmu/memnv50.o -- 2.49.0
With GSP-RM handling the majority of the HW programming, NVKM's usual HALs are more elaborate than necessary, resulting in a fair amount of duplicated boilerplate. Adds 'nvkm_rm_gpu' which serves to provide GPU-specific constants and functions in a more streamlined manner. This is initially used in subsequent commits to store engine class IDs, and replace the per-engine/engobj boilerplate with common code for all GSP-RM supported engines - and is further extended when adding GH100, GB10x and GB20x support. Signed-off-by: Ben Skeggs <bskeggs at nvidia.com> Reviewed-by: Dave Airlie <airlied at redhat.com> Reviewed-by: Timur Tabi <ttabi at nvidia.com> Tested-by: Timur Tabi <ttabi at nvidia.com> --- .../gpu/drm/nouveau/include/nvkm/subdev/gsp.h | 6 ++---- drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ad102.c | 6 +++--- drivers/gpu/drm/nouveau/nvkm/subdev/gsp/base.c | 12 +++++++++++- drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ga100.c | 6 +++--- drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ga102.c | 6 +++--- drivers/gpu/drm/nouveau/nvkm/subdev/gsp/priv.h | 7 +++++-- .../gpu/drm/nouveau/nvkm/subdev/gsp/rm/Kbuild | 5 +++++ .../gpu/drm/nouveau/nvkm/subdev/gsp/rm/ad10x.c | 9 +++++++++ .../gpu/drm/nouveau/nvkm/subdev/gsp/rm/ga100.c | 9 +++++++++ .../gpu/drm/nouveau/nvkm/subdev/gsp/rm/ga1xx.c | 9 +++++++++ drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gpu.h | 16 ++++++++++++++++ .../drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c | 5 ----- .../gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rm.c | 14 ++++++++++++-- drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h | 13 ++++++++++++- .../gpu/drm/nouveau/nvkm/subdev/gsp/rm/tu1xx.c | 9 +++++++++ drivers/gpu/drm/nouveau/nvkm/subdev/gsp/tu102.c | 6 +++--- drivers/gpu/drm/nouveau/nvkm/subdev/gsp/tu116.c | 6 +++--- 17 files changed, 114 insertions(+), 30 deletions(-) create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ad10x.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ga100.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ga1xx.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gpu.h create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/tu1xx.c diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h index 3fd279be8340..eeaf72f6add3 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h @@ -209,9 +209,7 @@ struct nvkm_gsp { u8 tpcs; } gr; - const struct nvkm_gsp_rm { - const struct nvkm_rm_api *api; - } *rm; + struct nvkm_rm *rm; struct { struct mutex mutex; @@ -467,7 +465,7 @@ 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) { - const struct nvkm_gsp_rm *rm = device->object.client->gsp->rm; + struct nvkm_rm *rm = device->object.client->gsp->rm; return rm->api->device->event.ctor(device, handle, id, func, event); } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ad102.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ad102.c index ea2821e7a54e..d7933bfc59fd 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ad102.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ad102.c @@ -22,7 +22,7 @@ #include "priv.h" static const struct nvkm_gsp_func -ad102_gsp_r535_113_01 = { +ad102_gsp = { .flcn = &ga102_gsp_flcn, .fwsec = &ga102_gsp_fwsec, @@ -40,12 +40,12 @@ ad102_gsp_r535_113_01 = { .fini = tu102_gsp_fini, .reset = ga102_gsp_reset, - .rm = &r535_gsp_rm, + .rm.gpu = &ad10x_gpu, }; static struct nvkm_gsp_fwif ad102_gsps[] = { - { 0, tu102_gsp_load, &ad102_gsp_r535_113_01, "535.113.01", true }, + { 0, tu102_gsp_load, &ad102_gsp, &r535_rm_ga102, "535.113.01", true }, {} }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/base.c index 78f2a15f0d42..0f8526aa969f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/base.c @@ -102,6 +102,7 @@ nvkm_gsp_dtor(struct nvkm_subdev *subdev) gsp->func->dtor(gsp); nvkm_falcon_dtor(&gsp->falcon); + kfree(gsp->rm); return gsp; } @@ -139,7 +140,16 @@ nvkm_gsp_new_(const struct nvkm_gsp_fwif *fwif, struct nvkm_device *device, return PTR_ERR(fwif); gsp->func = fwif->func; - gsp->rm = gsp->func->rm; + + if (fwif->rm) { + gsp->rm = kzalloc(sizeof(*gsp->rm), GFP_KERNEL); + if (!gsp->rm) + return -ENOMEM; + + gsp->rm->device = device; + gsp->rm->gpu = fwif->func->rm.gpu; + gsp->rm->api = fwif->rm->api; + } return nvkm_falcon_ctor(gsp->func->flcn, &gsp->subdev, gsp->subdev.name, 0x110000, &gsp->falcon); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ga100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ga100.c index d9cdec4810b4..77e3501296c9 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ga100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ga100.c @@ -39,7 +39,7 @@ ga100_gsp_flcn = { }; static const struct nvkm_gsp_func -ga100_gsp_r535_113_01 = { +ga100_gsp = { .flcn = &ga100_gsp_flcn, .fwsec = &tu102_gsp_fwsec, @@ -56,12 +56,12 @@ ga100_gsp_r535_113_01 = { .fini = tu102_gsp_fini, .reset = tu102_gsp_reset, - .rm = &r535_gsp_rm, + .rm.gpu = &ga100_gpu, }; static struct nvkm_gsp_fwif ga100_gsps[] = { - { 0, tu102_gsp_load, &ga100_gsp_r535_113_01, "535.113.01" }, + { 0, tu102_gsp_load, &ga100_gsp, &r535_rm_tu102, "535.113.01" }, { -1, gv100_gsp_nofw, &gv100_gsp }, {} }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ga102.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ga102.c index 7b8db70f3cb3..709a046d86bf 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ga102.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ga102.c @@ -150,7 +150,7 @@ ga102_gsp_flcn = { }; static const struct nvkm_gsp_func -ga102_gsp_r535_113_01 = { +ga102_gsp_r535 = { .flcn = &ga102_gsp_flcn, .fwsec = &ga102_gsp_fwsec, @@ -168,7 +168,7 @@ ga102_gsp_r535_113_01 = { .fini = tu102_gsp_fini, .reset = ga102_gsp_reset, - .rm = &r535_gsp_rm, + .rm.gpu = &ga1xx_gpu, }; static const struct nvkm_gsp_func @@ -178,7 +178,7 @@ ga102_gsp = { static struct nvkm_gsp_fwif ga102_gsps[] = { - { 0, tu102_gsp_load, &ga102_gsp_r535_113_01, "535.113.01" }, + { 0, tu102_gsp_load, &ga102_gsp_r535, &r535_rm_ga102, "535.113.01" }, { -1, gv100_gsp_nofw, &ga102_gsp }, {} }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/priv.h index e6f0e865848a..de274f6426c1 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/priv.h @@ -2,6 +2,7 @@ #ifndef __NVKM_GSP_PRIV_H__ #define __NVKM_GSP_PRIV_H__ #include <subdev/gsp.h> +#include <rm/gpu.h> enum nvkm_acr_lsf_id; int nvkm_gsp_fwsec_frts(struct nvkm_gsp *); @@ -11,6 +12,7 @@ struct nvkm_gsp_fwif { int version; int (*load)(struct nvkm_gsp *, int ver, const struct nvkm_gsp_fwif *); const struct nvkm_gsp_func *func; + const struct nvkm_rm_impl *rm; const char *ver; bool enable; }; @@ -51,7 +53,9 @@ struct nvkm_gsp_func { int (*fini)(struct nvkm_gsp *, bool suspend); int (*reset)(struct nvkm_gsp *); - const struct nvkm_gsp_rm *rm; + struct { + const struct nvkm_rm_gpu *gpu; + } rm; }; extern const struct nvkm_falcon_func tu102_gsp_flcn; @@ -73,7 +77,6 @@ void r535_gsp_dtor(struct nvkm_gsp *); int r535_gsp_oneinit(struct nvkm_gsp *); int r535_gsp_init(struct nvkm_gsp *); int r535_gsp_fini(struct nvkm_gsp *, bool suspend); -extern const struct nvkm_gsp_rm r535_gsp_rm; int r535_gsp_rmargs_init(struct nvkm_gsp *gsp, bool resume); int nvkm_gsp_new_(const struct nvkm_gsp_fwif *, struct nvkm_device *, enum nvkm_subdev_type, int, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/Kbuild index 1c07740215ec..841b690c0c0a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/Kbuild @@ -2,4 +2,9 @@ # # Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. +nvkm-y += nvkm/subdev/gsp/rm/tu1xx.o +nvkm-y += nvkm/subdev/gsp/rm/ga100.o +nvkm-y += nvkm/subdev/gsp/rm/ga1xx.o +nvkm-y += nvkm/subdev/gsp/rm/ad10x.o + include $(src)/nvkm/subdev/gsp/rm/r535/Kbuild diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ad10x.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ad10x.c new file mode 100644 index 000000000000..1e519bf166dd --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ad10x.c @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#include "gpu.h" + +const struct nvkm_rm_gpu +ad10x_gpu = { +}; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ga100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ga100.c new file mode 100644 index 000000000000..b10e6ff9e9b6 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ga100.c @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#include "gpu.h" + +const struct nvkm_rm_gpu +ga100_gpu = { +}; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ga1xx.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ga1xx.c new file mode 100644 index 000000000000..725ccb2c27dc --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ga1xx.c @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#include "gpu.h" + +const struct nvkm_rm_gpu +ga1xx_gpu = { +}; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gpu.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gpu.h new file mode 100644 index 000000000000..32d87ce2b77d --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gpu.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#ifndef __NVKM_RM_GPU_H__ +#define __NVKM_RM_GPU_H__ +#include "rm.h" + +struct nvkm_rm_gpu { +}; + +extern const struct nvkm_rm_gpu tu1xx_gpu; +extern const struct nvkm_rm_gpu ga100_gpu; +extern const struct nvkm_rm_gpu ga1xx_gpu; +extern const struct nvkm_rm_gpu ad10x_gpu; +#endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c index 48af5d8d22e8..8ca0f99ccbac 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c @@ -44,11 +44,6 @@ extern struct dentry *nouveau_debugfs_root; -const struct nvkm_gsp_rm -r535_gsp_rm = { - .api = &r535_rm, -}; - static void r535_gsp_msgq_work(struct work_struct *work) { diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rm.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rm.c index 39cc3d0c740c..3c17b75b5e37 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rm.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rm.c @@ -4,11 +4,21 @@ */ #include <rm/rm.h> -const struct nvkm_rm_api -r535_rm = { +static const struct nvkm_rm_api +r535_api = { .rpc = &r535_rpc, .ctrl = &r535_ctrl, .alloc = &r535_alloc, .client = &r535_client, .device = &r535_device, }; + +const struct nvkm_rm_impl +r535_rm_tu102 = { + .api = &r535_api, +}; + +const struct nvkm_rm_impl +r535_rm_ga102 = { + .api = &r535_api, +}; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h index 20841305fa55..41d4ed70fc10 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h @@ -6,6 +6,16 @@ #ifndef __NVKM_RM_H__ #define __NVKM_RM_H__ +struct nvkm_rm_impl { + const struct nvkm_rm_api *api; +}; + +struct nvkm_rm { + struct nvkm_device *device; + const struct nvkm_rm_gpu *gpu; + const struct nvkm_rm_api *api; +}; + struct nvkm_rm_api { const struct nvkm_rm_api_rpc { void *(*get)(struct nvkm_gsp *, u32 fn, u32 argc); @@ -45,7 +55,8 @@ struct nvkm_rm_api { } *device; }; -extern const struct nvkm_rm_api r535_rm; +extern const struct nvkm_rm_impl r535_rm_tu102; +extern const struct nvkm_rm_impl r535_rm_ga102; extern const struct nvkm_rm_api_rpc r535_rpc; extern const struct nvkm_rm_api_ctrl r535_ctrl; extern const struct nvkm_rm_api_alloc r535_alloc; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/tu1xx.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/tu1xx.c new file mode 100644 index 000000000000..d455a4f19854 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/tu1xx.c @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#include "gpu.h" + +const struct nvkm_rm_gpu +tu1xx_gpu = { +}; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/tu102.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/tu102.c index 451d3e588d26..fef9c4444017 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/tu102.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/tu102.c @@ -268,7 +268,7 @@ tu102_gsp_flcn = { }; static const struct nvkm_gsp_func -tu102_gsp_r535_113_01 = { +tu102_gsp = { .flcn = &tu102_gsp_flcn, .fwsec = &tu102_gsp_fwsec, @@ -285,7 +285,7 @@ tu102_gsp_r535_113_01 = { .fini = tu102_gsp_fini, .reset = tu102_gsp_reset, - .rm = &r535_gsp_rm, + .rm.gpu = &tu1xx_gpu, }; static int @@ -336,7 +336,7 @@ tu102_gsp_load(struct nvkm_gsp *gsp, int ver, const struct nvkm_gsp_fwif *fwif) static struct nvkm_gsp_fwif tu102_gsps[] = { - { 0, tu102_gsp_load, &tu102_gsp_r535_113_01, "535.113.01" }, + { 0, tu102_gsp_load, &tu102_gsp, &r535_rm_tu102, "535.113.01" }, { -1, gv100_gsp_nofw, &gv100_gsp }, {} }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/tu116.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/tu116.c index 1bc806a18010..5f279813626f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/tu116.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/tu116.c @@ -22,7 +22,7 @@ #include "priv.h" static const struct nvkm_gsp_func -tu116_gsp_r535_113_01 = { +tu116_gsp = { .flcn = &tu102_gsp_flcn, .fwsec = &tu102_gsp_fwsec, @@ -39,12 +39,12 @@ tu116_gsp_r535_113_01 = { .fini = tu102_gsp_fini, .reset = tu102_gsp_reset, - .rm = &r535_gsp_rm, + .rm.gpu = &tu1xx_gpu, }; static struct nvkm_gsp_fwif tu116_gsps[] = { - { 0, tu102_gsp_load, &tu116_gsp_r535_113_01, "535.113.01" }, + { 0, tu102_gsp_load, &tu116_gsp, &r535_rm_tu102, "535.113.01" }, { -1, gv100_gsp_nofw, &gv100_gsp }, {} }; -- 2.49.0
Ben Skeggs
2025-May-17 00:09 UTC
[PATCH v3 16/62] drm/nouveau/gsp: add display class ids to gpu hal
Use display class IDs from nvkm_rm_gpu, instead of copying them from the non-GSP HALs. Removes the AD102 display HAL, which is no longer required as there's no support for it without GSP-RM. Signed-off-by: Ben Skeggs <bskeggs at nvidia.com> Reviewed-by: Dave Airlie <airlied at redhat.com> Reviewed-by: Timur Tabi <ttabi at nvidia.com> Tested-by: Timur Tabi <ttabi at nvidia.com> --- .../drm/nouveau/include/nvkm/engine/disp.h | 1 - .../gpu/drm/nouveau/nvkm/engine/device/base.c | 10 ++-- .../gpu/drm/nouveau/nvkm/engine/disp/Kbuild | 1 - .../gpu/drm/nouveau/nvkm/engine/disp/ad102.c | 52 ------------------- .../drm/nouveau/nvkm/subdev/gsp/rm/ad10x.c | 10 ++++ .../drm/nouveau/nvkm/subdev/gsp/rm/ga1xx.c | 10 ++++ .../gpu/drm/nouveau/nvkm/subdev/gsp/rm/gpu.h | 10 ++++ .../nouveau/nvkm/subdev/gsp/rm/r535/disp.c | 35 ++++++++----- .../drm/nouveau/nvkm/subdev/gsp/rm/tu1xx.c | 10 ++++ 9 files changed, 67 insertions(+), 72 deletions(-) delete mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/disp/ad102.c diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/disp.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/disp.h index 3e8db8280e2a..7903d7470d19 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/engine/disp.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/disp.h @@ -87,5 +87,4 @@ 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/nvkm/engine/device/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c index 9093d89b16f3..aa929d3b2941 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c @@ -2709,7 +2709,7 @@ nv192_chipset = { .timer = { 0x00000001, gk20a_timer_new }, .vfn = { 0x00000001, ga100_vfn_new }, .ce = { 0x0000001f, ga102_ce_new }, - .disp = { 0x00000001, ad102_disp_new }, + .disp = { 0x00000001, ga102_disp_new }, .dma = { 0x00000001, gv100_dma_new }, .fifo = { 0x00000001, ga102_fifo_new }, .gr = { 0x00000001, ad102_gr_new }, @@ -2735,7 +2735,7 @@ nv193_chipset = { .timer = { 0x00000001, gk20a_timer_new }, .vfn = { 0x00000001, ga100_vfn_new }, .ce = { 0x0000001f, ga102_ce_new }, - .disp = { 0x00000001, ad102_disp_new }, + .disp = { 0x00000001, ga102_disp_new }, .dma = { 0x00000001, gv100_dma_new }, .fifo = { 0x00000001, ga102_fifo_new }, .gr = { 0x00000001, ad102_gr_new }, @@ -2761,7 +2761,7 @@ nv194_chipset = { .timer = { 0x00000001, gk20a_timer_new }, .vfn = { 0x00000001, ga100_vfn_new }, .ce = { 0x0000001f, ga102_ce_new }, - .disp = { 0x00000001, ad102_disp_new }, + .disp = { 0x00000001, ga102_disp_new }, .dma = { 0x00000001, gv100_dma_new }, .fifo = { 0x00000001, ga102_fifo_new }, .gr = { 0x00000001, ad102_gr_new }, @@ -2787,7 +2787,7 @@ nv196_chipset = { .timer = { 0x00000001, gk20a_timer_new }, .vfn = { 0x00000001, ga100_vfn_new }, .ce = { 0x0000001f, ga102_ce_new }, - .disp = { 0x00000001, ad102_disp_new }, + .disp = { 0x00000001, ga102_disp_new }, .dma = { 0x00000001, gv100_dma_new }, .fifo = { 0x00000001, ga102_fifo_new }, .gr = { 0x00000001, ad102_gr_new }, @@ -2813,7 +2813,7 @@ nv197_chipset = { .timer = { 0x00000001, gk20a_timer_new }, .vfn = { 0x00000001, ga100_vfn_new }, .ce = { 0x0000001f, ga102_ce_new }, - .disp = { 0x00000001, ad102_disp_new }, + .disp = { 0x00000001, ga102_disp_new }, .dma = { 0x00000001, gv100_dma_new }, .fifo = { 0x00000001, ga102_fifo_new }, .gr = { 0x00000001, ad102_gr_new }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild b/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild index 23a10e081081..e1aecd3fe96c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild @@ -27,7 +27,6 @@ nvkm-y += nvkm/engine/disp/gp102.o nvkm-y += nvkm/engine/disp/gv100.o nvkm-y += nvkm/engine/disp/tu102.o nvkm-y += nvkm/engine/disp/ga102.o -nvkm-y += nvkm/engine/disp/ad102.o nvkm-y += nvkm/engine/disp/udisp.o nvkm-y += nvkm/engine/disp/uconn.o diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/ad102.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/ad102.c deleted file mode 100644 index 7f300a79aa29..000000000000 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/ad102.c +++ /dev/null @@ -1,52 +0,0 @@ -/* - * 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" -#include "chan.h" - -#include <subdev/gsp.h> - -#include <nvif/class.h> - -static const struct nvkm_disp_func -ad102_disp = { - .uevent = &gv100_disp_chan_uevent, - .ramht_size = 0x2000, - .root = { 0, 0,AD102_DISP }, - .user = { - {{-1,-1,GV100_DISP_CAPS }, gv100_disp_caps_new }, - {{ 0, 0,GA102_DISP_CURSOR }, nvkm_disp_chan_new, &gv100_disp_curs }, - {{ 0, 0,GA102_DISP_WINDOW_IMM_CHANNEL_DMA}, nvkm_disp_wndw_new, &gv100_disp_wimm }, - {{ 0, 0,AD102_DISP_CORE_CHANNEL_DMA }, nvkm_disp_core_new, &gv100_disp_core }, - {{ 0, 0,GA102_DISP_WINDOW_CHANNEL_DMA }, nvkm_disp_wndw_new, &gv100_disp_wndw }, - {} - }, -}; - -int -ad102_disp_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, - struct nvkm_disp **pdisp) -{ - if (nvkm_gsp_rm(device->gsp)) - return r535_disp_new(&ad102_disp, device, type, inst, pdisp); - - return -ENODEV; -} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ad10x.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ad10x.c index 1e519bf166dd..bdeaffbb1077 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ad10x.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ad10x.c @@ -4,6 +4,16 @@ */ #include "gpu.h" +#include <nvif/class.h> + const struct nvkm_rm_gpu ad10x_gpu = { + .disp.class = { + .root = AD102_DISP, + .caps = GV100_DISP_CAPS, + .core = AD102_DISP_CORE_CHANNEL_DMA, + .wndw = GA102_DISP_WINDOW_CHANNEL_DMA, + .wimm = GA102_DISP_WINDOW_IMM_CHANNEL_DMA, + .curs = GA102_DISP_CURSOR, + }, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ga1xx.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ga1xx.c index 725ccb2c27dc..d4b67ccac608 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ga1xx.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ga1xx.c @@ -4,6 +4,16 @@ */ #include "gpu.h" +#include <nvif/class.h> + const struct nvkm_rm_gpu ga1xx_gpu = { + .disp.class = { + .root = GA102_DISP, + .caps = GV100_DISP_CAPS, + .core = GA102_DISP_CORE_CHANNEL_DMA, + .wndw = GA102_DISP_WINDOW_CHANNEL_DMA, + .wimm = GA102_DISP_WINDOW_IMM_CHANNEL_DMA, + .curs = GA102_DISP_CURSOR, + }, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gpu.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gpu.h index 32d87ce2b77d..7f3b5f3fd32b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gpu.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gpu.h @@ -7,6 +7,16 @@ #include "rm.h" struct nvkm_rm_gpu { + struct { + struct { + u32 root; + u32 caps; + u32 core; + u32 wndw; + u32 wimm; + u32 curs; + } class; + } disp; }; extern const struct nvkm_rm_gpu tu1xx_gpu; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c index 475faa35361a..e65f9074e94f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c @@ -34,6 +34,8 @@ #include <subdev/mmu.h> #include <subdev/vfn.h> +#include <rm/gpu.h> + #include <nvhw/drf.h> #include "nvrm/disp.h" @@ -1676,6 +1678,7 @@ int r535_disp_new(const struct nvkm_disp_func *hw, struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct nvkm_disp **pdisp) { + const struct nvkm_rm_gpu *gpu = device->gsp->rm->gpu; struct nvkm_disp_func *rm; int ret; @@ -1691,20 +1694,26 @@ r535_disp_new(const struct nvkm_disp_func *hw, struct nvkm_device *device, rm->sor.new = r535_sor_new; rm->ramht_size = hw->ramht_size; - rm->root = hw->root; + rm->root.oclass = gpu->disp.class.root; - for (int i = 0; hw->user[i].ctor; i++) { - switch (hw->user[i].base.oclass & 0xff) { - case 0x73: rm->user[i] = hw->user[i]; break; - case 0x7d: rm->user[i] = hw->user[i]; rm->user[i].chan = &r535_core; break; - case 0x7e: rm->user[i] = hw->user[i]; rm->user[i].chan = &r535_wndw; break; - case 0x7b: rm->user[i] = hw->user[i]; rm->user[i].chan = &r535_wimm; break; - case 0x7a: rm->user[i] = hw->user[i]; rm->user[i].chan = &r535_curs; break; - default: - WARN_ON(1); - continue; - } - } + rm->user[0].base.oclass = gpu->disp.class.caps; + rm->user[0].ctor = gv100_disp_caps_new; + + rm->user[1].base.oclass = gpu->disp.class.core; + rm->user[1].ctor = nvkm_disp_core_new; + rm->user[1].chan = &r535_core; + + rm->user[2].base.oclass = gpu->disp.class.wndw; + rm->user[2].ctor = nvkm_disp_wndw_new; + rm->user[2].chan = &r535_wndw; + + rm->user[3].base.oclass = gpu->disp.class.wimm; + rm->user[3].ctor = nvkm_disp_wndw_new; + rm->user[3].chan = &r535_wimm; + + rm->user[4].base.oclass = gpu->disp.class.curs; + rm->user[4].ctor = nvkm_disp_chan_new; + rm->user[4].chan = &r535_curs; ret = nvkm_disp_new_(rm, device, type, inst, pdisp); if (ret) diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/tu1xx.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/tu1xx.c index d455a4f19854..add98b2f3b6d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/tu1xx.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/tu1xx.c @@ -4,6 +4,16 @@ */ #include "gpu.h" +#include <nvif/class.h> + const struct nvkm_rm_gpu tu1xx_gpu = { + .disp.class = { + .root = TU102_DISP, + .caps = GV100_DISP_CAPS, + .core = TU102_DISP_CORE_CHANNEL_DMA, + .wndw = TU102_DISP_WINDOW_CHANNEL_DMA, + .wimm = TU102_DISP_WINDOW_IMM_CHANNEL_DMA, + .curs = TU102_DISP_CURSOR, + }, }; -- 2.49.0
Ben Skeggs
2025-May-17 00:09 UTC
[PATCH v3 17/62] drm/nouveau/gsp: add usermode class id to gpu hal
Use usermode class ID from nvkm_rm_gpu, instead of copying it from the non-GSP HALs. Signed-off-by: Ben Skeggs <bskeggs at nvidia.com> Reviewed-by: Dave Airlie <airlied at redhat.com> Reviewed-by: Timur Tabi <ttabi at nvidia.com> Tested-by: Timur Tabi <ttabi at nvidia.com> --- drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ad10x.c | 2 ++ drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ga100.c | 3 +++ drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ga1xx.c | 2 ++ drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gpu.h | 4 ++++ drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/tu1xx.c | 2 ++ drivers/gpu/drm/nouveau/nvkm/subdev/vfn/r535.c | 11 +++++++++-- 6 files changed, 22 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ad10x.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ad10x.c index bdeaffbb1077..170264d2a61b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ad10x.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ad10x.c @@ -16,4 +16,6 @@ ad10x_gpu = { .wimm = GA102_DISP_WINDOW_IMM_CHANNEL_DMA, .curs = GA102_DISP_CURSOR, }, + + .usermode.class = AMPERE_USERMODE_A, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ga100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ga100.c index b10e6ff9e9b6..164f46e0a93b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ga100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ga100.c @@ -4,6 +4,9 @@ */ #include "gpu.h" +#include <nvif/class.h> + const struct nvkm_rm_gpu ga100_gpu = { + .usermode.class = AMPERE_USERMODE_A, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ga1xx.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ga1xx.c index d4b67ccac608..f1d4778c4bc3 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ga1xx.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ga1xx.c @@ -16,4 +16,6 @@ ga1xx_gpu = { .wimm = GA102_DISP_WINDOW_IMM_CHANNEL_DMA, .curs = GA102_DISP_CURSOR, }, + + .usermode.class = AMPERE_USERMODE_A, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gpu.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gpu.h index 7f3b5f3fd32b..7d005f73326e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gpu.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gpu.h @@ -17,6 +17,10 @@ struct nvkm_rm_gpu { u32 curs; } class; } disp; + + struct { + u32 class; + } usermode; }; extern const struct nvkm_rm_gpu tu1xx_gpu; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/tu1xx.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/tu1xx.c index add98b2f3b6d..7aea54dd89ae 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/tu1xx.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/tu1xx.c @@ -16,4 +16,6 @@ tu1xx_gpu = { .wimm = TU102_DISP_WINDOW_IMM_CHANNEL_DMA, .curs = TU102_DISP_CURSOR, }, + + .usermode.class = TURING_USERMODE_A, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/vfn/r535.c b/drivers/gpu/drm/nouveau/nvkm/subdev/vfn/r535.c index dce337306cab..9446049642e1 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/vfn/r535.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/vfn/r535.c @@ -21,6 +21,8 @@ */ #include "priv.h" +#include <rm/gpu.h> + static void r535_vfn_dtor(struct nvkm_vfn *vfn) { @@ -32,6 +34,7 @@ r535_vfn_new(const struct nvkm_vfn_func *hw, struct nvkm_device *device, enum nvkm_subdev_type type, int inst, u32 addr, struct nvkm_vfn **pvfn) { + const struct nvkm_rm_gpu *gpu = device->gsp->rm->gpu; struct nvkm_vfn_func *rm; int ret; @@ -39,8 +42,12 @@ r535_vfn_new(const struct nvkm_vfn_func *hw, return -ENOMEM; rm->dtor = r535_vfn_dtor; - rm->intr = hw->intr; - rm->user = hw->user; + rm->intr = &tu102_vfn_intr, + rm->user.addr = 0x030000; + rm->user.size = 0x010000; + rm->user.base.minver = -1; + rm->user.base.maxver = -1; + rm->user.base.oclass = gpu->usermode.class; ret = nvkm_vfn_new_(rm, device, type, inst, addr, pvfn); if (ret) -- 2.49.0
Ben Skeggs
2025-May-17 00:09 UTC
[PATCH v3 18/62] drm/nouveau/gsp: add channel class id to gpu hal
Use channel class ID from nvkm_rm_gpu, instead of copying it from the non-GSP HALs. Signed-off-by: Ben Skeggs <bskeggs at nvidia.com> Reviewed-by: Dave Airlie <airlied at redhat.com> Reviewed-by: Timur Tabi <ttabi at nvidia.com> Tested-by: Timur Tabi <ttabi at nvidia.com> --- drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ad10x.c | 4 ++++ drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ga100.c | 4 ++++ drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ga1xx.c | 4 ++++ drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gpu.h | 6 ++++++ .../gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/fifo.c | 11 ++++------- drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/tu1xx.c | 4 ++++ 6 files changed, 26 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ad10x.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ad10x.c index 170264d2a61b..d5b64da712bc 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ad10x.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ad10x.c @@ -18,4 +18,8 @@ ad10x_gpu = { }, .usermode.class = AMPERE_USERMODE_A, + + .fifo.chan = { + .class = AMPERE_CHANNEL_GPFIFO_A, + }, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ga100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ga100.c index 164f46e0a93b..9bf80e196149 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ga100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ga100.c @@ -9,4 +9,8 @@ const struct nvkm_rm_gpu ga100_gpu = { .usermode.class = AMPERE_USERMODE_A, + + .fifo.chan = { + .class = AMPERE_CHANNEL_GPFIFO_A, + }, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ga1xx.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ga1xx.c index f1d4778c4bc3..55c90148a0d1 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ga1xx.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ga1xx.c @@ -18,4 +18,8 @@ ga1xx_gpu = { }, .usermode.class = AMPERE_USERMODE_A, + + .fifo.chan = { + .class = AMPERE_CHANNEL_GPFIFO_A, + }, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gpu.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gpu.h index 7d005f73326e..4aeeb4b32dc8 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gpu.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gpu.h @@ -21,6 +21,12 @@ struct nvkm_rm_gpu { struct { u32 class; } usermode; + + struct { + struct { + u32 class; + } chan; + } fifo; }; extern const struct nvkm_rm_gpu tu1xx_gpu; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/fifo.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/fifo.c index 594a6bbb1db2..28ac97415e8f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/fifo.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/fifo.c @@ -31,6 +31,8 @@ #include <subdev/vfn.h> #include <engine/gr.h> +#include <rm/gpu.h> + #include <nvhw/drf.h> #include "nvrm/fifo.h" @@ -216,10 +218,6 @@ r535_chan = { .doorbell_handle = r535_chan_doorbell_handle, }; -static const struct nvkm_cgrp_func -r535_cgrp = { -}; - static int r535_engn_nonstall(struct nvkm_engn *engn) { @@ -522,6 +520,7 @@ int r535_fifo_new(const struct nvkm_fifo_func *hw, struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct nvkm_fifo **pfifo) { + const struct nvkm_rm_gpu *gpu = device->gsp->rm->gpu; struct nvkm_fifo_func *rm; if (!(rm = kzalloc(sizeof(*rm), GFP_KERNEL))) @@ -530,9 +529,7 @@ r535_fifo_new(const struct nvkm_fifo_func *hw, struct nvkm_device *device, rm->dtor = r535_fifo_dtor; rm->runl_ctor = r535_fifo_runl_ctor; rm->runl = &r535_runl; - rm->cgrp = hw->cgrp; - rm->cgrp.func = &r535_cgrp; - rm->chan = hw->chan; + rm->chan.user.oclass = gpu->fifo.chan.class; rm->chan.func = &r535_chan; rm->nonstall = &ga100_fifo_nonstall; rm->nonstall_ctor = ga100_fifo_nonstall_ctor; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/tu1xx.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/tu1xx.c index 7aea54dd89ae..bb674b9cef69 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/tu1xx.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/tu1xx.c @@ -18,4 +18,8 @@ tu1xx_gpu = { }, .usermode.class = TURING_USERMODE_A, + + .fifo.chan = { + .class = TURING_CHANNEL_GPFIFO_A, + }, }; -- 2.49.0
Ben Skeggs
2025-May-17 00:09 UTC
[PATCH v3 19/62] drm/nouveau/gsp: add common code for engines/engine objects
With minimal to no direct HW programming required, most nvkm_engine implementations are nearly identical when running on top of GSP-RM. Add a common implementation of the boilerplate, and use nvkm_rm_gpu to expose the correct class IDs. As they're now handled by common code, and there's no support for them prior to GSP-RM support - this deletes the GA100 NVDEC/NVJPG/OFA HALs, the GA102 NVENC/OFA HALs, and the AD102 GR/NVDEC/NVENC/NVJPG/OFA HALs. Signed-off-by: Ben Skeggs <bskeggs at nvidia.com> Reviewed-by: Dave Airlie <airlied at redhat.com> Reviewed-by: Timur Tabi <ttabi at nvidia.com> Tested-by: Timur Tabi <ttabi at nvidia.com> --- drivers/gpu/drm/nouveau/include/nvif/class.h | 2 + .../gpu/drm/nouveau/include/nvkm/engine/gr.h | 1 - .../drm/nouveau/include/nvkm/engine/nvdec.h | 2 - .../drm/nouveau/include/nvkm/engine/nvenc.h | 2 - .../drm/nouveau/include/nvkm/engine/nvjpg.h | 8 - .../gpu/drm/nouveau/include/nvkm/engine/ofa.h | 9 - drivers/gpu/drm/nouveau/nvkm/engine/Kbuild | 2 - .../gpu/drm/nouveau/nvkm/engine/ce/ga100.c | 2 +- .../gpu/drm/nouveau/nvkm/engine/ce/ga102.c | 2 +- .../gpu/drm/nouveau/nvkm/engine/ce/tu102.c | 2 +- .../gpu/drm/nouveau/nvkm/engine/device/base.c | 38 ---- .../gpu/drm/nouveau/nvkm/engine/device/priv.h | 2 - drivers/gpu/drm/nouveau/nvkm/engine/gr/Kbuild | 1 - .../gpu/drm/nouveau/nvkm/engine/gr/ad102.c | 46 ----- .../gpu/drm/nouveau/nvkm/engine/gr/ga102.c | 2 +- .../gpu/drm/nouveau/nvkm/engine/gr/gf100.h | 2 - .../gpu/drm/nouveau/nvkm/engine/gr/tu102.c | 2 +- .../gpu/drm/nouveau/nvkm/engine/nvdec/Kbuild | 2 - .../gpu/drm/nouveau/nvkm/engine/nvdec/ad102.c | 44 ---- .../gpu/drm/nouveau/nvkm/engine/nvdec/ga100.c | 44 ---- .../gpu/drm/nouveau/nvkm/engine/nvdec/ga102.c | 12 +- .../gpu/drm/nouveau/nvkm/engine/nvdec/priv.h | 3 - .../gpu/drm/nouveau/nvkm/engine/nvdec/tu102.c | 12 +- .../gpu/drm/nouveau/nvkm/engine/nvenc/Kbuild | 2 - .../gpu/drm/nouveau/nvkm/engine/nvenc/ad102.c | 44 ---- .../gpu/drm/nouveau/nvkm/engine/nvenc/ga102.c | 44 ---- .../gpu/drm/nouveau/nvkm/engine/nvenc/priv.h | 3 - .../gpu/drm/nouveau/nvkm/engine/nvenc/tu102.c | 12 +- .../gpu/drm/nouveau/nvkm/engine/nvjpg/Kbuild | 3 - .../gpu/drm/nouveau/nvkm/engine/nvjpg/ad102.c | 44 ---- .../gpu/drm/nouveau/nvkm/engine/nvjpg/ga100.c | 44 ---- .../gpu/drm/nouveau/nvkm/engine/nvjpg/priv.h | 8 - .../gpu/drm/nouveau/nvkm/engine/ofa/Kbuild | 4 - .../gpu/drm/nouveau/nvkm/engine/ofa/ad102.c | 44 ---- .../gpu/drm/nouveau/nvkm/engine/ofa/ga100.c | 44 ---- .../gpu/drm/nouveau/nvkm/engine/ofa/ga102.c | 44 ---- .../gpu/drm/nouveau/nvkm/engine/ofa/priv.h | 8 - .../gpu/drm/nouveau/nvkm/subdev/gsp/rm/Kbuild | 4 + .../drm/nouveau/nvkm/subdev/gsp/rm/ad10x.c | 11 + .../drm/nouveau/nvkm/subdev/gsp/rm/engine.c | 189 ++++++++++++++++++ .../drm/nouveau/nvkm/subdev/gsp/rm/engine.h | 20 ++ .../drm/nouveau/nvkm/subdev/gsp/rm/ga100.c | 9 + .../drm/nouveau/nvkm/subdev/gsp/rm/ga1xx.c | 11 + .../gpu/drm/nouveau/nvkm/subdev/gsp/rm/gpu.h | 29 +++ .../gpu/drm/nouveau/nvkm/subdev/gsp/rm/gr.c | 56 ++++++ .../gpu/drm/nouveau/nvkm/subdev/gsp/rm/gr.h | 38 ++++ .../drm/nouveau/nvkm/subdev/gsp/rm/nvdec.c | 33 +++ .../drm/nouveau/nvkm/subdev/gsp/rm/nvenc.c | 33 +++ .../drm/nouveau/nvkm/subdev/gsp/rm/r535/ce.c | 81 +------- .../nouveau/nvkm/subdev/gsp/rm/r535/fifo.c | 14 +- .../drm/nouveau/nvkm/subdev/gsp/rm/r535/gr.c | 142 ++----------- .../nouveau/nvkm/subdev/gsp/rm/r535/nvdec.c | 84 +------- .../nouveau/nvkm/subdev/gsp/rm/r535/nvenc.c | 84 +------- .../nouveau/nvkm/subdev/gsp/rm/r535/nvjpg.c | 81 +------- .../drm/nouveau/nvkm/subdev/gsp/rm/r535/ofa.c | 80 +------- .../drm/nouveau/nvkm/subdev/gsp/rm/r535/rm.c | 5 + .../gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h | 15 ++ .../drm/nouveau/nvkm/subdev/gsp/rm/tu1xx.c | 10 + 58 files changed, 546 insertions(+), 1073 deletions(-) delete mode 100644 drivers/gpu/drm/nouveau/include/nvkm/engine/nvjpg.h delete mode 100644 drivers/gpu/drm/nouveau/include/nvkm/engine/ofa.h delete mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/gr/ad102.c delete mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/nvdec/ad102.c delete mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/nvdec/ga100.c delete mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/nvenc/ad102.c delete mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/nvenc/ga102.c delete mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/nvjpg/Kbuild delete mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/nvjpg/ad102.c delete mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/nvjpg/ga100.c delete mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/nvjpg/priv.h delete mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/ofa/Kbuild delete mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/ofa/ad102.c delete mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/ofa/ga100.c delete mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/ofa/ga102.c delete mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/ofa/priv.h create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/engine.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/engine.h create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gr.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gr.h create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/nvdec.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/nvenc.c diff --git a/drivers/gpu/drm/nouveau/include/nvif/class.h b/drivers/gpu/drm/nouveau/include/nvif/class.h index 824e052dcc25..71a2a53bff7f 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/class.h +++ b/drivers/gpu/drm/nouveau/include/nvif/class.h @@ -189,6 +189,7 @@ #define TURING_A /* cl9097.h */ 0x0000c597 +#define AMPERE_A 0x0000c697 #define AMPERE_B /* cl9097.h */ 0x0000c797 #define ADA_A /* cl9097.h */ 0x0000c997 @@ -246,6 +247,7 @@ #define PASCAL_COMPUTE_B 0x0000c1c0 #define VOLTA_COMPUTE_A 0x0000c3c0 #define TURING_COMPUTE_A 0x0000c5c0 +#define AMPERE_COMPUTE_A 0x0000c6c0 #define AMPERE_COMPUTE_B 0x0000c7c0 #define ADA_COMPUTE_A 0x0000c9c0 diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/gr.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/gr.h index 8145796ffc61..a2333cfe6955 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/engine/gr.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/gr.h @@ -55,5 +55,4 @@ 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 8d2e170883e1..ca83caa55157 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/engine/nvdec.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/nvdec.h @@ -13,7 +13,5 @@ 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 018c58fc32ba..1f6eef13f872 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/engine/nvenc.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/nvenc.h @@ -13,6 +13,4 @@ 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 deleted file mode 100644 index 80b7933a789e..000000000000 --- a/drivers/gpu/drm/nouveau/include/nvkm/engine/nvjpg.h +++ /dev/null @@ -1,8 +0,0 @@ -/* 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 deleted file mode 100644 index e72e2115333b..000000000000 --- a/drivers/gpu/drm/nouveau/include/nvkm/engine/ofa.h +++ /dev/null @@ -1,9 +0,0 @@ -/* 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/nvkm/engine/Kbuild b/drivers/gpu/drm/nouveau/nvkm/engine/Kbuild index 2e48b0816670..ddcf8782d6b6 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/engine/Kbuild @@ -17,8 +17,6 @@ include $(src)/nvkm/engine/msppp/Kbuild include $(src)/nvkm/engine/msvld/Kbuild include $(src)/nvkm/engine/nvenc/Kbuild include $(src)/nvkm/engine/nvdec/Kbuild -include $(src)/nvkm/engine/nvjpg/Kbuild -include $(src)/nvkm/engine/ofa/Kbuild include $(src)/nvkm/engine/sec/Kbuild include $(src)/nvkm/engine/sec2/Kbuild include $(src)/nvkm/engine/sw/Kbuild diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/ce/ga100.c b/drivers/gpu/drm/nouveau/nvkm/engine/ce/ga100.c index 9427a592bd16..1c0c60138706 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/ce/ga100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/ce/ga100.c @@ -90,7 +90,7 @@ ga100_ce_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct nvkm_engine **pengine) { if (nvkm_gsp_rm(device->gsp)) - return r535_ce_new(&ga100_ce, device, type, inst, pengine); + return -ENODEV; return nvkm_engine_new_(&ga100_ce, device, type, inst, true, pengine); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/ce/ga102.c b/drivers/gpu/drm/nouveau/nvkm/engine/ce/ga102.c index ce56ede7c2e9..9359c5e7aa3a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/ce/ga102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/ce/ga102.c @@ -44,7 +44,7 @@ ga102_ce_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct nvkm_engine **pengine) { if (nvkm_gsp_rm(device->gsp)) - return r535_ce_new(&ga102_ce, device, type, inst, pengine); + return -ENODEV; return nvkm_engine_new_(&ga102_ce, device, type, inst, true, pengine); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/ce/tu102.c b/drivers/gpu/drm/nouveau/nvkm/engine/ce/tu102.c index 7c8647dcb349..67d0545cf902 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/ce/tu102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/ce/tu102.c @@ -40,7 +40,7 @@ tu102_ce_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct nvkm_engine **pengine) { if (nvkm_gsp_rm(device->gsp)) - return r535_ce_new(&tu102_ce, device, type, inst, pengine); + return -ENODEV; return nvkm_engine_new_(&tu102_ce, device, type, inst, true, pengine); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c index aa929d3b2941..0cd20d0f8782 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c @@ -2529,9 +2529,6 @@ nv170_chipset = { .vfn = { 0x00000001, ga100_vfn_new }, .ce = { 0x000003ff, ga100_ce_new }, .fifo = { 0x00000001, ga100_fifo_new }, - .nvdec = { 0x0000001f, ga100_nvdec_new }, - .nvjpg = { 0x00000001, ga100_nvjpg_new }, - .ofa = { 0x00000001, ga100_ofa_new }, }; static const struct nvkm_device_chip @@ -2561,8 +2558,6 @@ nv172_chipset = { .fifo = { 0x00000001, ga102_fifo_new }, .gr = { 0x00000001, ga102_gr_new }, .nvdec = { 0x00000003, ga102_nvdec_new }, - .nvenc = { 0x00000001, ga102_nvenc_new }, - .ofa = { 0x00000001, ga102_ofa_new }, .sec2 = { 0x00000001, ga102_sec2_new }, }; @@ -2593,8 +2588,6 @@ nv173_chipset = { .fifo = { 0x00000001, ga102_fifo_new }, .gr = { 0x00000001, ga102_gr_new }, .nvdec = { 0x00000003, ga102_nvdec_new }, - .nvenc = { 0x00000001, ga102_nvenc_new }, - .ofa = { 0x00000001, ga102_ofa_new }, .sec2 = { 0x00000001, ga102_sec2_new }, }; @@ -2625,8 +2618,6 @@ nv174_chipset = { .fifo = { 0x00000001, ga102_fifo_new }, .gr = { 0x00000001, ga102_gr_new }, .nvdec = { 0x00000003, ga102_nvdec_new }, - .nvenc = { 0x00000001, ga102_nvenc_new }, - .ofa = { 0x00000001, ga102_ofa_new }, .sec2 = { 0x00000001, ga102_sec2_new }, }; @@ -2657,8 +2648,6 @@ nv176_chipset = { .fifo = { 0x00000001, ga102_fifo_new }, .gr = { 0x00000001, ga102_gr_new }, .nvdec = { 0x00000003, ga102_nvdec_new }, - .nvenc = { 0x00000001, ga102_nvenc_new }, - .ofa = { 0x00000001, ga102_ofa_new }, .sec2 = { 0x00000001, ga102_sec2_new }, }; @@ -2689,8 +2678,6 @@ nv177_chipset = { .fifo = { 0x00000001, ga102_fifo_new }, .gr = { 0x00000001, ga102_gr_new }, .nvdec = { 0x00000003, ga102_nvdec_new }, - .nvenc = { 0x00000001, ga102_nvenc_new }, - .ofa = { 0x00000001, ga102_ofa_new }, .sec2 = { 0x00000001, ga102_sec2_new }, }; @@ -2712,11 +2699,6 @@ nv192_chipset = { .disp = { 0x00000001, ga102_disp_new }, .dma = { 0x00000001, gv100_dma_new }, .fifo = { 0x00000001, ga102_fifo_new }, - .gr = { 0x00000001, ad102_gr_new }, - .nvdec = { 0x0000000f, ad102_nvdec_new }, - .nvenc = { 0x00000007, ad102_nvenc_new }, - .nvjpg = { 0x0000000f, ad102_nvjpg_new }, - .ofa = { 0x00000001, ad102_ofa_new }, .sec2 = { 0x00000001, ga102_sec2_new }, }; @@ -2738,11 +2720,6 @@ nv193_chipset = { .disp = { 0x00000001, ga102_disp_new }, .dma = { 0x00000001, gv100_dma_new }, .fifo = { 0x00000001, ga102_fifo_new }, - .gr = { 0x00000001, ad102_gr_new }, - .nvdec = { 0x0000000f, ad102_nvdec_new }, - .nvenc = { 0x00000007, ad102_nvenc_new }, - .nvjpg = { 0x0000000f, ad102_nvjpg_new }, - .ofa = { 0x00000001, ad102_ofa_new }, .sec2 = { 0x00000001, ga102_sec2_new }, }; @@ -2764,11 +2741,6 @@ nv194_chipset = { .disp = { 0x00000001, ga102_disp_new }, .dma = { 0x00000001, gv100_dma_new }, .fifo = { 0x00000001, ga102_fifo_new }, - .gr = { 0x00000001, ad102_gr_new }, - .nvdec = { 0x0000000f, ad102_nvdec_new }, - .nvenc = { 0x00000007, ad102_nvenc_new }, - .nvjpg = { 0x0000000f, ad102_nvjpg_new }, - .ofa = { 0x00000001, ad102_ofa_new }, .sec2 = { 0x00000001, ga102_sec2_new }, }; @@ -2790,11 +2762,6 @@ nv196_chipset = { .disp = { 0x00000001, ga102_disp_new }, .dma = { 0x00000001, gv100_dma_new }, .fifo = { 0x00000001, ga102_fifo_new }, - .gr = { 0x00000001, ad102_gr_new }, - .nvdec = { 0x0000000f, ad102_nvdec_new }, - .nvenc = { 0x00000007, ad102_nvenc_new }, - .nvjpg = { 0x0000000f, ad102_nvjpg_new }, - .ofa = { 0x00000001, ad102_ofa_new }, .sec2 = { 0x00000001, ga102_sec2_new }, }; @@ -2816,11 +2783,6 @@ nv197_chipset = { .disp = { 0x00000001, ga102_disp_new }, .dma = { 0x00000001, gv100_dma_new }, .fifo = { 0x00000001, ga102_fifo_new }, - .gr = { 0x00000001, ad102_gr_new }, - .nvdec = { 0x0000000f, ad102_nvdec_new }, - .nvenc = { 0x00000007, ad102_nvenc_new }, - .nvjpg = { 0x0000000f, ad102_nvjpg_new }, - .ofa = { 0x00000001, ad102_ofa_new }, .sec2 = { 0x00000001, ga102_sec2_new }, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/priv.h b/drivers/gpu/drm/nouveau/nvkm/engine/device/priv.h index e42b18820a95..8da5e896dd74 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/priv.h @@ -43,8 +43,6 @@ #include <engine/msvld.h> #include <engine/nvenc.h> #include <engine/nvdec.h> -#include <engine/nvjpg.h> -#include <engine/ofa.h> #include <engine/sec.h> #include <engine/sec2.h> #include <engine/sw.h> diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/Kbuild b/drivers/gpu/drm/nouveau/nvkm/engine/gr/Kbuild index 487fcc14b9a9..b5418f05ccd8 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/Kbuild @@ -41,7 +41,6 @@ nvkm-y += nvkm/engine/gr/gp10b.o nvkm-y += nvkm/engine/gr/gv100.o nvkm-y += nvkm/engine/gr/tu102.o nvkm-y += nvkm/engine/gr/ga102.o -nvkm-y += nvkm/engine/gr/ad102.o nvkm-y += nvkm/engine/gr/ctxnv40.o nvkm-y += nvkm/engine/gr/ctxnv50.o diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ad102.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ad102.c deleted file mode 100644 index 7bfa6240d283..000000000000 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ad102.c +++ /dev/null @@ -1,46 +0,0 @@ -/* - * 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 "gf100.h" - -#include <subdev/gsp.h> - -#include <nvif/class.h> - -static const struct gf100_gr_func -ad102_gr = { - .sclass = { - { -1, -1, FERMI_TWOD_A }, - { -1, -1, KEPLER_INLINE_TO_MEMORY_B }, - { -1, -1, ADA_A }, - { -1, -1, ADA_COMPUTE_A }, - {} - } -}; - -int -ad102_gr_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct nvkm_gr **pgr) -{ - if (nvkm_gsp_rm(device->gsp)) - return r535_gr_new(&ad102_gr, device, type, inst, pgr); - - return -ENODEV; -} diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ga102.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ga102.c index d285c597aff9..2b51f1d0c281 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ga102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ga102.c @@ -352,7 +352,7 @@ int ga102_gr_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct nvkm_gr **pgr) { if (nvkm_gsp_rm(device->gsp)) - return r535_gr_new(&ga102_gr, device, type, inst, pgr); + return -ENODEV; return gf100_gr_new_(ga102_gr_fwif, device, type, inst, pgr); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h index b0e0c9305034..54f686ba39ac 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h @@ -445,6 +445,4 @@ void gp108_gr_acr_bld_patch(struct nvkm_acr *, u32, s64); int gf100_gr_new_(const struct gf100_gr_fwif *, struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_gr **); -int r535_gr_new(const struct gf100_gr_func *, struct nvkm_device *, enum nvkm_subdev_type, int, - struct nvkm_gr **); #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/tu102.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/tu102.c index b7a458e9040a..bda8054c6b59 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/tu102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/tu102.c @@ -219,7 +219,7 @@ int tu102_gr_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct nvkm_gr **pgr) { if (nvkm_gsp_rm(device->gsp)) - return r535_gr_new(&tu102_gr, device, type, inst, pgr); + return -ENODEV; return gf100_gr_new_(tu102_gr_fwif, device, type, inst, pgr); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/nvdec/Kbuild b/drivers/gpu/drm/nouveau/nvkm/engine/nvdec/Kbuild index 5cc317abc42c..37b0cdc760c7 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/nvdec/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/engine/nvdec/Kbuild @@ -2,6 +2,4 @@ nvkm-y += nvkm/engine/nvdec/base.o nvkm-y += nvkm/engine/nvdec/gm107.o nvkm-y += nvkm/engine/nvdec/tu102.o -nvkm-y += nvkm/engine/nvdec/ga100.o nvkm-y += nvkm/engine/nvdec/ga102.o -nvkm-y += nvkm/engine/nvdec/ad102.o diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/nvdec/ad102.c b/drivers/gpu/drm/nouveau/nvkm/engine/nvdec/ad102.c deleted file mode 100644 index d72b3aae9a2b..000000000000 --- a/drivers/gpu/drm/nouveau/nvkm/engine/nvdec/ad102.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - * 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" - -#include <subdev/gsp.h> - -#include <nvif/class.h> - -static const struct nvkm_engine_func -ad102_nvdec = { - .sclass = { - { -1, -1, NVC9B0_VIDEO_DECODER }, - {} - } -}; - -int -ad102_nvdec_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, - struct nvkm_nvdec **pnvdec) -{ - if (nvkm_gsp_rm(device->gsp)) - return r535_nvdec_new(&ad102_nvdec, device, type, inst, pnvdec); - - return -ENODEV; -} diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/nvdec/ga100.c b/drivers/gpu/drm/nouveau/nvkm/engine/nvdec/ga100.c deleted file mode 100644 index 932934227b9c..000000000000 --- a/drivers/gpu/drm/nouveau/nvkm/engine/nvdec/ga100.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - * 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" - -#include <subdev/gsp.h> - -#include <nvif/class.h> - -static const struct nvkm_engine_func -ga100_nvdec = { - .sclass = { - { -1, -1, NVC6B0_VIDEO_DECODER }, - {} - } -}; - -int -ga100_nvdec_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, - struct nvkm_nvdec **pnvdec) -{ - if (nvkm_gsp_rm(device->gsp)) - return r535_nvdec_new(&ga100_nvdec, device, type, inst, pnvdec); - - return -ENODEV; -} diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/nvdec/ga102.c b/drivers/gpu/drm/nouveau/nvkm/engine/nvdec/ga102.c index 022a9c824304..eea6368adae2 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/nvdec/ga102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/nvdec/ga102.c @@ -23,16 +23,6 @@ #include <subdev/gsp.h> -#include <nvif/class.h> - -static const struct nvkm_engine_func -ga102_nvdec_gsp = { - .sclass = { - { -1, -1, NVC7B0_VIDEO_DECODER }, - {} - } -}; - static const struct nvkm_falcon_func ga102_nvdec_flcn = { .disable = gm200_flcn_disable, @@ -67,7 +57,7 @@ ga102_nvdec_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst struct nvkm_nvdec **pnvdec) { if (nvkm_gsp_rm(device->gsp)) - return r535_nvdec_new(&ga102_nvdec_gsp, device, type, inst, pnvdec); + return -ENODEV; return nvkm_nvdec_new_(ga102_nvdec_fwif, device, type, inst, 0x848000, pnvdec); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/nvdec/priv.h b/drivers/gpu/drm/nouveau/nvkm/engine/nvdec/priv.h index f506ae83bfd7..f8d43e913093 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/nvdec/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/nvdec/priv.h @@ -20,7 +20,4 @@ extern const struct nvkm_nvdec_fwif gm107_nvdec_fwif[]; int nvkm_nvdec_new_(const struct nvkm_nvdec_fwif *fwif, struct nvkm_device *, enum nvkm_subdev_type, int, u32 addr, struct nvkm_nvdec **); - -int r535_nvdec_new(const struct nvkm_engine_func *, struct nvkm_device *, - enum nvkm_subdev_type, int, struct nvkm_nvdec **); #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/nvdec/tu102.c b/drivers/gpu/drm/nouveau/nvkm/engine/nvdec/tu102.c index 808c8e010b9e..fe95b6e22f21 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/nvdec/tu102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/nvdec/tu102.c @@ -23,22 +23,12 @@ #include <subdev/gsp.h> -#include <nvif/class.h> - -static const struct nvkm_engine_func -tu102_nvdec = { - .sclass = { - { -1, -1, NVC4B0_VIDEO_DECODER }, - {} - } -}; - int tu102_nvdec_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct nvkm_nvdec **pnvdec) { if (nvkm_gsp_rm(device->gsp)) - return r535_nvdec_new(&tu102_nvdec, device, type, inst, pnvdec); + return -ENODEV; return nvkm_nvdec_new_(gm107_nvdec_fwif, device, type, inst, 0, pnvdec); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/nvenc/Kbuild b/drivers/gpu/drm/nouveau/nvkm/engine/nvenc/Kbuild index 3d71f2973dab..6dcb20d1d156 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/nvenc/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/engine/nvenc/Kbuild @@ -2,5 +2,3 @@ nvkm-y += nvkm/engine/nvenc/base.o nvkm-y += nvkm/engine/nvenc/gm107.o nvkm-y += nvkm/engine/nvenc/tu102.o -nvkm-y += nvkm/engine/nvenc/ga102.o -nvkm-y += nvkm/engine/nvenc/ad102.o diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/nvenc/ad102.c b/drivers/gpu/drm/nouveau/nvkm/engine/nvenc/ad102.c deleted file mode 100644 index 1b4619ff9e8e..000000000000 --- a/drivers/gpu/drm/nouveau/nvkm/engine/nvenc/ad102.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - * 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" - -#include <subdev/gsp.h> - -#include <nvif/class.h> - -static const struct nvkm_engine_func -ad102_nvenc = { - .sclass = { - { -1, -1, NVC9B7_VIDEO_ENCODER }, - {} - } -}; - -int -ad102_nvenc_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, - struct nvkm_nvenc **pnvenc) -{ - if (nvkm_gsp_rm(device->gsp)) - return r535_nvenc_new(&ad102_nvenc, device, type, inst, pnvenc); - - return -ENODEV; -} diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/nvenc/ga102.c b/drivers/gpu/drm/nouveau/nvkm/engine/nvenc/ga102.c deleted file mode 100644 index 6463ab8e5871..000000000000 --- a/drivers/gpu/drm/nouveau/nvkm/engine/nvenc/ga102.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - * 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" - -#include <subdev/gsp.h> - -#include <nvif/class.h> - -static const struct nvkm_engine_func -ga102_nvenc = { - .sclass = { - { -1, -1, NVC7B7_VIDEO_ENCODER }, - {} - } -}; - -int -ga102_nvenc_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, - struct nvkm_nvenc **pnvenc) -{ - if (nvkm_gsp_rm(device->gsp)) - return r535_nvenc_new(&ga102_nvenc, device, type, inst, pnvenc); - - return -ENODEV; -} diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/nvenc/priv.h b/drivers/gpu/drm/nouveau/nvkm/engine/nvenc/priv.h index 7917affc6505..b097e3f2867b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/nvenc/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/nvenc/priv.h @@ -18,7 +18,4 @@ extern const struct nvkm_nvenc_fwif gm107_nvenc_fwif[]; int nvkm_nvenc_new_(const struct nvkm_nvenc_fwif *, struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_nvenc **pnvenc); - -int r535_nvenc_new(const struct nvkm_engine_func *, struct nvkm_device *, - enum nvkm_subdev_type, int, struct nvkm_nvenc **); #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/nvenc/tu102.c b/drivers/gpu/drm/nouveau/nvkm/engine/nvenc/tu102.c index 933864423bb3..8a436b398749 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/nvenc/tu102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/nvenc/tu102.c @@ -23,22 +23,12 @@ #include <subdev/gsp.h> -#include <nvif/class.h> - -static const struct nvkm_engine_func -tu102_nvenc = { - .sclass = { - { -1, -1, NVC4B7_VIDEO_ENCODER }, - {} - } -}; - int tu102_nvenc_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct nvkm_nvenc **pnvenc) { if (nvkm_gsp_rm(device->gsp)) - return r535_nvenc_new(&tu102_nvenc, device, type, inst, pnvenc); + return -ENODEV; return nvkm_nvenc_new_(gm107_nvenc_fwif, device, type, inst, pnvenc); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/nvjpg/Kbuild b/drivers/gpu/drm/nouveau/nvkm/engine/nvjpg/Kbuild deleted file mode 100644 index 1d9bddd68605..000000000000 --- a/drivers/gpu/drm/nouveau/nvkm/engine/nvjpg/Kbuild +++ /dev/null @@ -1,3 +0,0 @@ -# SPDX-License-Identifier: MIT -nvkm-y += nvkm/engine/nvjpg/ga100.o -nvkm-y += nvkm/engine/nvjpg/ad102.o diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/nvjpg/ad102.c b/drivers/gpu/drm/nouveau/nvkm/engine/nvjpg/ad102.c deleted file mode 100644 index 62705dc6494c..000000000000 --- a/drivers/gpu/drm/nouveau/nvkm/engine/nvjpg/ad102.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - * 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" - -#include <subdev/gsp.h> - -#include <nvif/class.h> - -static const struct nvkm_engine_func -ad102_nvjpg = { - .sclass = { - { -1, -1, NVC9D1_VIDEO_NVJPG }, - {} - } -}; - -int -ad102_nvjpg_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, - struct nvkm_engine **pengine) -{ - if (nvkm_gsp_rm(device->gsp)) - return r535_nvjpg_new(&ad102_nvjpg, device, type, inst, pengine); - - return -ENODEV; -} diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/nvjpg/ga100.c b/drivers/gpu/drm/nouveau/nvkm/engine/nvjpg/ga100.c deleted file mode 100644 index f550eb07da5a..000000000000 --- a/drivers/gpu/drm/nouveau/nvkm/engine/nvjpg/ga100.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - * 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" - -#include <subdev/gsp.h> - -#include <nvif/class.h> - -static const struct nvkm_engine_func -ga100_nvjpg = { - .sclass = { - { -1, -1, NVC4D1_VIDEO_NVJPG }, - {} - } -}; - -int -ga100_nvjpg_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, - struct nvkm_engine **pengine) -{ - if (nvkm_gsp_rm(device->gsp)) - return r535_nvjpg_new(&ga100_nvjpg, device, type, inst, pengine); - - return -ENODEV; -} diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/nvjpg/priv.h b/drivers/gpu/drm/nouveau/nvkm/engine/nvjpg/priv.h deleted file mode 100644 index 1e80cf70033a..000000000000 --- a/drivers/gpu/drm/nouveau/nvkm/engine/nvjpg/priv.h +++ /dev/null @@ -1,8 +0,0 @@ -/* SPDX-License-Identifier: MIT */ -#ifndef __NVKM_NVJPG_PRIV_H__ -#define __NVKM_NVJPG_PRIV_H__ -#include <engine/nvjpg.h> - -int r535_nvjpg_new(const struct nvkm_engine_func *, struct nvkm_device *, - enum nvkm_subdev_type, int, struct nvkm_engine **); -#endif diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/ofa/Kbuild b/drivers/gpu/drm/nouveau/nvkm/engine/ofa/Kbuild deleted file mode 100644 index 3faf73b35f5a..000000000000 --- a/drivers/gpu/drm/nouveau/nvkm/engine/ofa/Kbuild +++ /dev/null @@ -1,4 +0,0 @@ -# SPDX-License-Identifier: MIT -nvkm-y += nvkm/engine/ofa/ga100.o -nvkm-y += nvkm/engine/ofa/ga102.o -nvkm-y += nvkm/engine/ofa/ad102.o diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/ofa/ad102.c b/drivers/gpu/drm/nouveau/nvkm/engine/ofa/ad102.c deleted file mode 100644 index 7ac87ef26aec..000000000000 --- a/drivers/gpu/drm/nouveau/nvkm/engine/ofa/ad102.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - * 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" - -#include <subdev/gsp.h> - -#include <nvif/class.h> - -static const struct nvkm_engine_func -ad102_ofa = { - .sclass = { - { -1, -1, NVC9FA_VIDEO_OFA }, - {} - } -}; - -int -ad102_ofa_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, - struct nvkm_engine **pengine) -{ - if (nvkm_gsp_rm(device->gsp)) - return r535_ofa_new(&ad102_ofa, device, type, inst, pengine); - - return -ENODEV; -} diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/ofa/ga100.c b/drivers/gpu/drm/nouveau/nvkm/engine/ofa/ga100.c deleted file mode 100644 index ef474f61a1b5..000000000000 --- a/drivers/gpu/drm/nouveau/nvkm/engine/ofa/ga100.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - * 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" - -#include <subdev/gsp.h> - -#include <nvif/class.h> - -static const struct nvkm_engine_func -ga100_ofa = { - .sclass = { - { -1, -1, NVC6FA_VIDEO_OFA }, - {} - } -}; - -int -ga100_ofa_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, - struct nvkm_engine **pengine) -{ - if (nvkm_gsp_rm(device->gsp)) - return r535_ofa_new(&ga100_ofa, device, type, inst, pengine); - - return -ENODEV; -} diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/ofa/ga102.c b/drivers/gpu/drm/nouveau/nvkm/engine/ofa/ga102.c deleted file mode 100644 index bea255529993..000000000000 --- a/drivers/gpu/drm/nouveau/nvkm/engine/ofa/ga102.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - * 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" - -#include <subdev/gsp.h> - -#include <nvif/class.h> - -static const struct nvkm_engine_func -ga102_ofa = { - .sclass = { - { -1, -1, NVC7FA_VIDEO_OFA }, - {} - } -}; - -int -ga102_ofa_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, - struct nvkm_engine **pengine) -{ - if (nvkm_gsp_rm(device->gsp)) - return r535_ofa_new(&ga102_ofa, device, type, inst, pengine); - - return -ENODEV; -} diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/ofa/priv.h b/drivers/gpu/drm/nouveau/nvkm/engine/ofa/priv.h deleted file mode 100644 index caf29e6bddb4..000000000000 --- a/drivers/gpu/drm/nouveau/nvkm/engine/ofa/priv.h +++ /dev/null @@ -1,8 +0,0 @@ -/* SPDX-License-Identifier: MIT */ -#ifndef __NVKM_OFA_PRIV_H__ -#define __NVKM_OFA_PRIV_H__ -#include <engine/ofa.h> - -int r535_ofa_new(const struct nvkm_engine_func *, struct nvkm_device *, - enum nvkm_subdev_type, int, struct nvkm_engine **); -#endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/Kbuild index 841b690c0c0a..e5d5f8880d31 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/Kbuild @@ -1,6 +1,10 @@ # SPDX-License-Identifier: MIT # # Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. +nvkm-y += nvkm/subdev/gsp/rm/engine.o +nvkm-y += nvkm/subdev/gsp/rm/gr.o +nvkm-y += nvkm/subdev/gsp/rm/nvdec.o +nvkm-y += nvkm/subdev/gsp/rm/nvenc.o nvkm-y += nvkm/subdev/gsp/rm/tu1xx.o nvkm-y += nvkm/subdev/gsp/rm/ga100.o diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ad10x.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ad10x.c index d5b64da712bc..d699c386adec 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ad10x.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ad10x.c @@ -22,4 +22,15 @@ ad10x_gpu = { .fifo.chan = { .class = AMPERE_CHANNEL_GPFIFO_A, }, + + .ce.class = AMPERE_DMA_COPY_B, + .gr.class = { + .i2m = KEPLER_INLINE_TO_MEMORY_B, + .twod = FERMI_TWOD_A, + .threed = ADA_A, + .compute = ADA_COMPUTE_A, + }, + .nvdec.class = NVC9B0_VIDEO_DECODER, + .nvenc.class = NVC9B7_VIDEO_ENCODER, + .ofa.class = NVC9FA_VIDEO_OFA, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/engine.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/engine.c new file mode 100644 index 000000000000..3b0e83b2f57f --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/engine.c @@ -0,0 +1,189 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#include "engine.h" +#include "gpu.h" + +#include <core/object.h> +#include <engine/fifo/chan.h> + +struct nvkm_rm_engine { + struct nvkm_engine engine; + + struct nvkm_engine_func func; +}; + +struct nvkm_rm_engine_obj { + struct nvkm_object object; + struct nvkm_gsp_object rm; +}; + +static void* +nvkm_rm_engine_obj_dtor(struct nvkm_object *object) +{ + struct nvkm_rm_engine_obj *obj = container_of(object, typeof(*obj), object); + + nvkm_gsp_rm_free(&obj->rm); + return obj; +} + +static const struct nvkm_object_func +nvkm_rm_engine_obj = { + .dtor = nvkm_rm_engine_obj_dtor, +}; + +int +nvkm_rm_engine_obj_new(struct nvkm_gsp_object *chan, int chid, const struct nvkm_oclass *oclass, + struct nvkm_object **pobject) +{ + struct nvkm_rm *rm = chan->client->gsp->rm; + const int inst = oclass->engine->subdev.inst; + const u32 class = oclass->base.oclass; + const u32 handle = oclass->handle; + struct nvkm_rm_engine_obj *obj; + int ret; + + obj = kzalloc(sizeof(*obj), GFP_KERNEL); + if (!obj) + return -ENOMEM; + + switch (oclass->engine->subdev.type) { + case NVKM_ENGINE_CE: + ret = rm->api->ce->alloc(chan, handle, class, inst, &obj->rm); + break; + case NVKM_ENGINE_GR: + ret = nvkm_gsp_rm_alloc(chan, handle, class, 0, &obj->rm); + break; + case NVKM_ENGINE_NVDEC: + ret = rm->api->nvdec->alloc(chan, handle, class, inst, &obj->rm); + break; + case NVKM_ENGINE_NVENC: + ret = rm->api->nvenc->alloc(chan, handle, class, inst, &obj->rm); + break; + case NVKM_ENGINE_NVJPG: + ret = rm->api->nvjpg->alloc(chan, handle, class, inst, &obj->rm); + break; + case NVKM_ENGINE_OFA: + ret = rm->api->ofa->alloc(chan, handle, class, inst, &obj->rm); + break; + default: + ret = -EINVAL; + WARN_ON(1); + break; + } + + if (ret) { + kfree(obj); + return ret; + } + + nvkm_object_ctor(&nvkm_rm_engine_obj, oclass, &obj->object); + *pobject = &obj->object; + return 0; +} + +static int +nvkm_rm_engine_obj_ctor(const struct nvkm_oclass *oclass, void *argv, u32 argc, + struct nvkm_object **pobject) +{ + struct nvkm_chan *chan = nvkm_uchan_chan(oclass->parent); + + return nvkm_rm_engine_obj_new(&chan->rm.object, chan->id, oclass, pobject); +} + +static void * +nvkm_rm_engine_dtor(struct nvkm_engine *engine) +{ + kfree(engine->func); + return engine; +} + +int +nvkm_rm_engine_ctor(void *(*dtor)(struct nvkm_engine *), struct nvkm_rm *rm, + enum nvkm_subdev_type type, int inst, + const u32 *class, int nclass, struct nvkm_engine *engine) +{ + struct nvkm_engine_func *func; + + func = kzalloc(struct_size(func, sclass, nclass + 1), GFP_KERNEL); + if (!func) + return -ENOMEM; + + func->dtor = dtor; + + for (int i = 0; i < nclass; i++) { + func->sclass[i].oclass = class[i]; + func->sclass[i].minver = -1; + func->sclass[i].maxver = 0; + func->sclass[i].ctor = nvkm_rm_engine_obj_ctor; + } + + nvkm_engine_ctor(func, rm->device, type, inst, true, engine); + return 0; +} + +static int +nvkm_rm_engine_new_(struct nvkm_rm *rm, enum nvkm_subdev_type type, int inst, u32 class, + struct nvkm_engine **pengine) +{ + struct nvkm_engine *engine; + int ret; + + engine = kzalloc(sizeof(*engine), GFP_KERNEL); + if (!engine) + return -ENOMEM; + + ret = nvkm_rm_engine_ctor(nvkm_rm_engine_dtor, rm, type, inst, &class, 1, engine); + if (ret) { + kfree(engine); + return ret; + } + + *pengine = engine; + return 0; +} + +int +nvkm_rm_engine_new(struct nvkm_rm *rm, enum nvkm_subdev_type type, int inst) +{ + const struct nvkm_rm_gpu *gpu = rm->gpu; + struct nvkm_device *device = rm->device; + + switch (type) { + case NVKM_ENGINE_CE: + if (WARN_ON(inst >= ARRAY_SIZE(device->ce))) + return -EINVAL; + + return nvkm_rm_engine_new_(rm, type, inst, gpu->ce.class, &device->ce[inst]); + case NVKM_ENGINE_GR: + if (inst != 0) + return -ENODEV; /* MiG not supported, just ignore. */ + + return nvkm_rm_gr_new(rm); + case NVKM_ENGINE_NVDEC: + if (WARN_ON(inst >= ARRAY_SIZE(device->nvdec))) + return -EINVAL; + + return nvkm_rm_nvdec_new(rm, inst); + case NVKM_ENGINE_NVENC: + if (WARN_ON(inst >= ARRAY_SIZE(device->nvenc))) + return -EINVAL; + + return nvkm_rm_nvenc_new(rm, inst); + case NVKM_ENGINE_NVJPG: + if (WARN_ON(inst >= ARRAY_SIZE(device->nvjpg))) + return -EINVAL; + + return nvkm_rm_engine_new_(rm, type, inst, gpu->nvjpg.class, &device->nvjpg[inst]); + case NVKM_ENGINE_OFA: + if (WARN_ON(inst >= ARRAY_SIZE(device->ofa))) + return -EINVAL; + + return nvkm_rm_engine_new_(rm, type, inst, gpu->ofa.class, &device->ofa[inst]); + default: + break; + } + + return -ENODEV; +} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/engine.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/engine.h new file mode 100644 index 000000000000..5b8c9c3901d4 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/engine.h @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#ifndef __NVKM_RM_ENGINE_H__ +#define __NVKM_RM_ENGINE_H__ +#include "gpu.h" + +int nvkm_rm_engine_ctor(void *(*dtor)(struct nvkm_engine *), struct nvkm_rm *, + enum nvkm_subdev_type type, int inst, + const u32 *class, int nclass, struct nvkm_engine *); +int nvkm_rm_engine_new(struct nvkm_rm *, enum nvkm_subdev_type, int inst); + +int nvkm_rm_engine_obj_new(struct nvkm_gsp_object *chan, int chid, const struct nvkm_oclass *, + struct nvkm_object **); + +int nvkm_rm_gr_new(struct nvkm_rm *); +int nvkm_rm_nvdec_new(struct nvkm_rm *, int inst); +int nvkm_rm_nvenc_new(struct nvkm_rm *, int inst); +#endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ga100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ga100.c index 9bf80e196149..5e7f18dbf18b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ga100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ga100.c @@ -13,4 +13,13 @@ ga100_gpu = { .fifo.chan = { .class = AMPERE_CHANNEL_GPFIFO_A, }, + + .ce.class = AMPERE_DMA_COPY_A, + .gr.class = { + .i2m = KEPLER_INLINE_TO_MEMORY_B, + .twod = FERMI_TWOD_A, + .threed = AMPERE_A, + .compute = AMPERE_COMPUTE_A, + }, + .nvdec.class = NVC6B0_VIDEO_DECODER, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ga1xx.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ga1xx.c index 55c90148a0d1..61525d23aaa0 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ga1xx.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ga1xx.c @@ -22,4 +22,15 @@ ga1xx_gpu = { .fifo.chan = { .class = AMPERE_CHANNEL_GPFIFO_A, }, + + .ce.class = AMPERE_DMA_COPY_B, + .gr.class = { + .i2m = KEPLER_INLINE_TO_MEMORY_B, + .twod = FERMI_TWOD_A, + .threed = AMPERE_B, + .compute = AMPERE_COMPUTE_B, + }, + .nvdec.class = NVC7B0_VIDEO_DECODER, + .nvenc.class = NVC7B7_VIDEO_ENCODER, + .ofa.class = NVC7FA_VIDEO_OFA, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gpu.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gpu.h index 4aeeb4b32dc8..a256be42ab6e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gpu.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gpu.h @@ -27,6 +27,35 @@ struct nvkm_rm_gpu { u32 class; } chan; } fifo; + + struct { + u32 class; + } ce; + + struct { + struct { + u32 i2m; + u32 twod; + u32 threed; + u32 compute; + } class; + } gr; + + struct { + u32 class; + } nvdec; + + struct { + u32 class; + } nvenc; + + struct { + u32 class; + } nvjpg; + + struct { + u32 class; + } ofa; }; extern const struct nvkm_rm_gpu tu1xx_gpu; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gr.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gr.c new file mode 100644 index 000000000000..22aa894da79d --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gr.c @@ -0,0 +1,56 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#include "gr.h" + +#include <engine/fifo.h> +#include <engine/gr/priv.h> + +static int +nvkm_rm_gr_obj_ctor(const struct nvkm_oclass *oclass, void *argv, u32 argc, + struct nvkm_object **pobject) +{ + struct r535_gr_chan *chan = container_of(oclass->parent, typeof(*chan), object); + + return nvkm_rm_engine_obj_new(&chan->chan->rm.object, chan->chan->id, oclass, pobject); +} + +int +nvkm_rm_gr_new(struct nvkm_rm *rm) +{ + const u32 classes[] = { + rm->gpu->gr.class.i2m, + rm->gpu->gr.class.twod, + rm->gpu->gr.class.threed, + rm->gpu->gr.class.compute, + }; + struct nvkm_gr_func *func; + struct r535_gr *gr; + + func = kzalloc(struct_size(func, sclass, ARRAY_SIZE(classes) + 1), GFP_KERNEL); + if (!func) + return -ENOMEM; + + func->dtor = r535_gr_dtor; + func->oneinit = r535_gr_oneinit; + func->units = r535_gr_units; + func->chan_new = r535_gr_chan_new; + + for (int i = 0; i < ARRAY_SIZE(classes); i++) { + func->sclass[i].oclass = classes[i]; + func->sclass[i].minver = -1; + func->sclass[i].maxver = 0; + func->sclass[i].ctor = nvkm_rm_gr_obj_ctor; + } + + gr = kzalloc(sizeof(*gr), GFP_KERNEL); + if (!gr) { + kfree(func); + return -ENOMEM; + } + + nvkm_gr_ctor(func, rm->device, NVKM_ENGINE_GR, 0, true, &gr->base); + rm->device->gr = &gr->base; + return 0; +} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gr.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gr.h new file mode 100644 index 000000000000..9f2b31651019 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gr.h @@ -0,0 +1,38 @@ +/* SPDX-License-Identifier: MIT */ +#ifndef __NVKM_RM_GR_H__ +#define __NVKM_RM_GR_H__ +#include "engine.h" + +#include <core/object.h> +#include <engine/gr.h> + +#define R515_GR_MAX_CTXBUFS 9 + +struct r535_gr_chan { + struct nvkm_object object; + struct r535_gr *gr; + + struct nvkm_vmm *vmm; + struct nvkm_chan *chan; + + struct nvkm_memory *mem[R515_GR_MAX_CTXBUFS]; + struct nvkm_vma *vma[R515_GR_MAX_CTXBUFS]; +}; + +struct r535_gr { + struct nvkm_gr base; + + struct { + u16 bufferId; + u32 size; + u8 page; + u8 align; + bool global; + bool init; + bool ro; + } ctxbuf[R515_GR_MAX_CTXBUFS]; + int ctxbuf_nr; + + struct nvkm_memory *ctxbuf_mem[R515_GR_MAX_CTXBUFS]; +}; +#endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/nvdec.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/nvdec.c new file mode 100644 index 000000000000..d9fbfc377864 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/nvdec.c @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#include "engine.h" +#include <engine/nvdec.h> + +static void * +nvkm_rm_nvdec_dtor(struct nvkm_engine *engine) +{ + return container_of(engine, struct nvkm_nvdec, engine); +} + +int +nvkm_rm_nvdec_new(struct nvkm_rm *rm, int inst) +{ + struct nvkm_nvdec *nvdec; + int ret; + + nvdec = kzalloc(sizeof(*nvdec), GFP_KERNEL); + if (!nvdec) + return -ENOMEM; + + ret = nvkm_rm_engine_ctor(nvkm_rm_nvdec_dtor, rm, NVKM_ENGINE_NVDEC, inst, + &rm->gpu->nvdec.class, 1, &nvdec->engine); + if (ret) { + kfree(nvdec); + return ret; + } + + rm->device->nvdec[inst] = nvdec; + return 0; +} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/nvenc.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/nvenc.c new file mode 100644 index 000000000000..6dfa7b789e07 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/nvenc.c @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#include "engine.h" +#include <engine/nvenc.h> + +static void * +nvkm_rm_nvenc_dtor(struct nvkm_engine *engine) +{ + return container_of(engine, struct nvkm_nvenc, engine); +} + +int +nvkm_rm_nvenc_new(struct nvkm_rm *rm, int inst) +{ + struct nvkm_nvenc *nvenc; + int ret; + + nvenc = kzalloc(sizeof(*nvenc), GFP_KERNEL); + if (!nvenc) + return -ENOMEM; + + ret = nvkm_rm_engine_ctor(nvkm_rm_nvenc_dtor, rm, NVKM_ENGINE_NVENC, inst, + &rm->gpu->nvenc.class, 1, &nvenc->engine); + if (ret) { + kfree(nvenc); + return ret; + } + + rm->device->nvenc[inst] = nvenc; + return 0; +} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/ce.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/ce.c index d60003231e6d..2d1ce9db2dcf 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/ce.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/ce.c @@ -19,89 +19,28 @@ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ -#include <engine/ce/priv.h> - -#include <core/object.h> -#include <subdev/gsp.h> -#include <engine/fifo.h> +#include <rm/engine.h> #include "nvrm/ce.h" #include "nvrm/engine.h" -struct r535_ce_obj { - struct nvkm_object object; - struct nvkm_gsp_object rm; -}; - -static void * -r535_ce_obj_dtor(struct nvkm_object *object) -{ - struct r535_ce_obj *obj = container_of(object, typeof(*obj), object); - - nvkm_gsp_rm_free(&obj->rm); - return obj; -} - -static const struct nvkm_object_func -r535_ce_obj = { - .dtor = r535_ce_obj_dtor, -}; - static int -r535_ce_obj_ctor(const struct nvkm_oclass *oclass, void *argv, u32 argc, - struct nvkm_object **pobject) +r535_ce_alloc(struct nvkm_gsp_object *chan, u32 handle, u32 class, int inst, + struct nvkm_gsp_object *ce) { - struct nvkm_chan *chan = nvkm_uchan_chan(oclass->parent); - struct r535_ce_obj *obj; NVC0B5_ALLOCATION_PARAMETERS *args; - if (!(obj = kzalloc(sizeof(*obj), GFP_KERNEL))) - return -ENOMEM; - - nvkm_object_ctor(&r535_ce_obj, oclass, &obj->object); - *pobject = &obj->object; - - args = nvkm_gsp_rm_alloc_get(&chan->rm.object, oclass->handle, oclass->base.oclass, - sizeof(*args), &obj->rm); + args = nvkm_gsp_rm_alloc_get(chan, handle, class, sizeof(*args), ce); if (WARN_ON(IS_ERR(args))) return PTR_ERR(args); args->version = 1; - args->engineType = NV2080_ENGINE_TYPE_COPY0 + oclass->engine->subdev.inst; + args->engineType = NV2080_ENGINE_TYPE_COPY0 + inst; - return nvkm_gsp_rm_alloc_wr(&obj->rm, args); + return nvkm_gsp_rm_alloc_wr(ce, args); } -static void * -r535_ce_dtor(struct nvkm_engine *engine) -{ - kfree(engine->func); - return engine; -} - -int -r535_ce_new(const struct nvkm_engine_func *hw, struct nvkm_device *device, - enum nvkm_subdev_type type, int inst, struct nvkm_engine **pengine) -{ - struct nvkm_engine_func *rm; - int nclass, ret; - - for (nclass = 0; hw->sclass[nclass].oclass; nclass++); - - if (!(rm = kzalloc(sizeof(*rm) + (nclass + 1) * sizeof(rm->sclass[0]), GFP_KERNEL))) - return -ENOMEM; - - rm->dtor = r535_ce_dtor; - for (int i = 0; i < nclass; i++) { - rm->sclass[i].minver = hw->sclass[i].minver; - rm->sclass[i].maxver = hw->sclass[i].maxver; - rm->sclass[i].oclass = hw->sclass[i].oclass; - rm->sclass[i].ctor = r535_ce_obj_ctor; - } - - ret = nvkm_engine_new_(rm, device, type, inst, true, pengine); - if (ret) - kfree(rm); - - return ret; -} +const struct nvkm_rm_api_engine +r535_ce = { + .alloc = r535_ce_alloc, +}; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/fifo.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/fifo.c index 28ac97415e8f..98aa272be642 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/fifo.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/fifo.c @@ -31,7 +31,7 @@ #include <subdev/vfn.h> #include <engine/gr.h> -#include <rm/gpu.h> +#include <rm/engine.h> #include <nvhw/drf.h> @@ -230,7 +230,7 @@ r535_engn_nonstall(struct nvkm_engn *engn) } static const struct nvkm_engn_func -r535_ce = { +r535_engn_ce = { .nonstall = r535_engn_nonstall, }; @@ -463,9 +463,17 @@ r535_fifo_runl_ctor(struct nvkm_fifo *fifo) continue; } + ret = nvkm_rm_engine_new(gsp->rm, type, inst); + if (ret) { + nvkm_runl_del(runl); + continue; + } + + engn = NULL; + switch (type) { case NVKM_ENGINE_CE: - engn = nvkm_runl_add(runl, nv2080, &r535_ce, type, inst); + engn = nvkm_runl_add(runl, nv2080, &r535_engn_ce, type, inst); break; case NVKM_ENGINE_GR: engn = nvkm_runl_add(runl, nv2080, &r535_gr, type, inst); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gr.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gr.c index ab941d808e24..3618fa36040c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gr.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gr.c @@ -19,12 +19,13 @@ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ -#include <engine/gr/gf100.h> +#include <rm/gr.h> #include <core/memory.h> #include <subdev/gsp.h> #include <subdev/mmu/vmm.h> #include <engine/fifo/priv.h> +#include <engine/gr/priv.h> #include <nvif/if900d.h> @@ -34,72 +35,6 @@ #define r535_gr(p) container_of((p), struct r535_gr, base) -#define R515_GR_MAX_CTXBUFS 9 - -struct r535_gr { - struct nvkm_gr base; - - struct { - u16 bufferId; - u32 size; - u8 page; - u8 align; - bool global; - bool init; - bool ro; - } ctxbuf[R515_GR_MAX_CTXBUFS]; - int ctxbuf_nr; - - struct nvkm_memory *ctxbuf_mem[R515_GR_MAX_CTXBUFS]; -}; - -struct r535_gr_chan { - struct nvkm_object object; - struct r535_gr *gr; - - struct nvkm_vmm *vmm; - struct nvkm_chan *chan; - - struct nvkm_memory *mem[R515_GR_MAX_CTXBUFS]; - struct nvkm_vma *vma[R515_GR_MAX_CTXBUFS]; -}; - -struct r535_gr_obj { - struct nvkm_object object; - struct nvkm_gsp_object rm; -}; - -static void * -r535_gr_obj_dtor(struct nvkm_object *object) -{ - struct r535_gr_obj *obj = container_of(object, typeof(*obj), object); - - nvkm_gsp_rm_free(&obj->rm); - return obj; -} - -static const struct nvkm_object_func -r535_gr_obj = { - .dtor = r535_gr_obj_dtor, -}; - -static int -r535_gr_obj_ctor(const struct nvkm_oclass *oclass, void *argv, u32 argc, - struct nvkm_object **pobject) -{ - struct r535_gr_chan *chan = container_of(oclass->parent, typeof(*chan), object); - struct r535_gr_obj *obj; - - if (!(obj = kzalloc(sizeof(*obj), GFP_KERNEL))) - return -ENOMEM; - - nvkm_object_ctor(&r535_gr_obj, oclass, &obj->object); - *pobject = &obj->object; - - return nvkm_gsp_rm_alloc(&chan->chan->rm.object, oclass->handle, oclass->base.oclass, 0, - &obj->rm); -} - static void * r535_gr_chan_dtor(struct nvkm_object *object) { @@ -203,7 +138,7 @@ r535_gr_promote_ctx(struct r535_gr *gr, bool golden, struct nvkm_vmm *vmm, return nvkm_gsp_rm_ctrl_wr(&vmm->rm.device.subdevice, ctrl); } -static int +int r535_gr_chan_new(struct nvkm_gr *base, struct nvkm_chan *chan, const struct nvkm_oclass *oclass, struct nvkm_object **pobject) { @@ -227,7 +162,7 @@ r535_gr_chan_new(struct nvkm_gr *base, struct nvkm_chan *chan, const struct nvkm return 0; } -static u64 +u64 r535_gr_units(struct nvkm_gr *gr) { struct nvkm_gsp *gsp = gr->engine.subdev.device->gsp; @@ -235,7 +170,7 @@ r535_gr_units(struct nvkm_gr *gr) return (gsp->gr.tpcs << 8) | gsp->gr.gpcs; } -static int +int r535_gr_oneinit(struct nvkm_gr *base) { NV2080_CTRL_INTERNAL_STATIC_GR_GET_CONTEXT_BUFFERS_INFO_PARAMS *info; @@ -243,6 +178,7 @@ r535_gr_oneinit(struct nvkm_gr *base) struct nvkm_subdev *subdev = &gr->base.engine.subdev; struct nvkm_device *device = subdev->device; struct nvkm_gsp *gsp = device->gsp; + struct nvkm_rm *rm = gsp->rm; struct nvkm_mmu *mmu = device->mmu; struct { struct nvkm_memory *inst; @@ -250,6 +186,7 @@ r535_gr_oneinit(struct nvkm_gr *base) struct nvkm_gsp_object chan; struct nvkm_vma *vma[R515_GR_MAX_CTXBUFS]; } golden = {}; + struct nvkm_gsp_object threed; int ret; /* Allocate a channel to use for golden context init. */ @@ -421,30 +358,12 @@ r535_gr_oneinit(struct nvkm_gr *base) goto done; /* Allocate 3D class on channel to trigger golden context init in RM. */ - { - int i; - - for (i = 0; gr->base.func->sclass[i].ctor; i++) { - if ((gr->base.func->sclass[i].oclass & 0xff) == 0x97) { - struct nvkm_gsp_object threed; - - ret = nvkm_gsp_rm_alloc(&golden.chan, 0x97000000, - gr->base.func->sclass[i].oclass, 0, - &threed); - if (ret) - goto done; - - nvkm_gsp_rm_free(&threed); - break; - } - } - - if (WARN_ON(!gr->base.func->sclass[i].ctor)) { - ret = -EINVAL; - goto done; - } - } + ret = nvkm_gsp_rm_alloc(&golden.chan, 0x97000000, rm->gpu->gr.class.threed, 0, &threed); + if (ret) + goto done; + /* There's no need to keep the golden channel around, as RM caches the context. */ + nvkm_gsp_rm_free(&threed); done: nvkm_gsp_rm_free(&golden.chan); for (int i = gr->ctxbuf_nr - 1; i >= 0; i--) @@ -455,7 +374,7 @@ r535_gr_oneinit(struct nvkm_gr *base) } -static void * +void * r535_gr_dtor(struct nvkm_gr *base) { struct r535_gr *gr = r535_gr(base); @@ -466,38 +385,3 @@ r535_gr_dtor(struct nvkm_gr *base) kfree(gr->base.func); return gr; } - -int -r535_gr_new(const struct gf100_gr_func *hw, - struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct nvkm_gr **pgr) -{ - struct nvkm_gr_func *rm; - struct r535_gr *gr; - int nclass; - - for (nclass = 0; hw->sclass[nclass].oclass; nclass++); - - if (!(rm = kzalloc(sizeof(*rm) + (nclass + 1) * sizeof(rm->sclass[0]), GFP_KERNEL))) - return -ENOMEM; - - rm->dtor = r535_gr_dtor; - rm->oneinit = r535_gr_oneinit; - rm->units = r535_gr_units; - rm->chan_new = r535_gr_chan_new; - - for (int i = 0; i < nclass; i++) { - rm->sclass[i].minver = hw->sclass[i].minver; - rm->sclass[i].maxver = hw->sclass[i].maxver; - rm->sclass[i].oclass = hw->sclass[i].oclass; - rm->sclass[i].ctor = r535_gr_obj_ctor; - } - - if (!(gr = kzalloc(sizeof(*gr), GFP_KERNEL))) { - kfree(rm); - return -ENOMEM; - } - - *pgr = &gr->base; - - return nvkm_gr_ctor(rm, device, type, inst, true, &gr->base); -} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvdec.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvdec.c index 05d0916d199e..a8c42ec0367b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvdec.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvdec.c @@ -19,91 +19,27 @@ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ -#include <engine/nvdec/priv.h> - -#include <core/object.h> -#include <subdev/gsp.h> -#include <engine/fifo.h> +#include <rm/engine.h> #include "nvrm/nvdec.h" -struct r535_nvdec_obj { - struct nvkm_object object; - struct nvkm_gsp_object rm; -}; - -static void * -r535_nvdec_obj_dtor(struct nvkm_object *object) -{ - struct r535_nvdec_obj *obj = container_of(object, typeof(*obj), object); - - nvkm_gsp_rm_free(&obj->rm); - return obj; -} - -static const struct nvkm_object_func -r535_nvdec_obj = { - .dtor = r535_nvdec_obj_dtor, -}; - static int -r535_nvdec_obj_ctor(const struct nvkm_oclass *oclass, void *argv, u32 argc, - struct nvkm_object **pobject) +r535_nvdec_alloc(struct nvkm_gsp_object *chan, u32 handle, u32 class, int inst, + struct nvkm_gsp_object *nvdec) { - struct nvkm_chan *chan = nvkm_uchan_chan(oclass->parent); - struct r535_nvdec_obj *obj; NV_BSP_ALLOCATION_PARAMETERS *args; - if (!(obj = kzalloc(sizeof(*obj), GFP_KERNEL))) - return -ENOMEM; - - nvkm_object_ctor(&r535_nvdec_obj, oclass, &obj->object); - *pobject = &obj->object; - - args = nvkm_gsp_rm_alloc_get(&chan->rm.object, oclass->handle, oclass->base.oclass, - sizeof(*args), &obj->rm); + args = nvkm_gsp_rm_alloc_get(chan, handle, class, sizeof(*args), nvdec); if (WARN_ON(IS_ERR(args))) return PTR_ERR(args); args->size = sizeof(*args); - args->engineInstance = oclass->engine->subdev.inst; + args->engineInstance = inst; - return nvkm_gsp_rm_alloc_wr(&obj->rm, args); + return nvkm_gsp_rm_alloc_wr(nvdec, args); } -static void * -r535_nvdec_dtor(struct nvkm_engine *engine) -{ - struct nvkm_nvdec *nvdec = nvkm_nvdec(engine); - - kfree(nvdec->engine.func); - return nvdec; -} - -int -r535_nvdec_new(const struct nvkm_engine_func *hw, struct nvkm_device *device, - enum nvkm_subdev_type type, int inst, struct nvkm_nvdec **pnvdec) -{ - struct nvkm_engine_func *rm; - int nclass; - - for (nclass = 0; hw->sclass[nclass].oclass; nclass++); - - if (!(rm = kzalloc(sizeof(*rm) + (nclass + 1) * sizeof(rm->sclass[0]), GFP_KERNEL))) - return -ENOMEM; - - rm->dtor = r535_nvdec_dtor; - for (int i = 0; i < nclass; i++) { - rm->sclass[i].minver = hw->sclass[i].minver; - rm->sclass[i].maxver = hw->sclass[i].maxver; - rm->sclass[i].oclass = hw->sclass[i].oclass; - rm->sclass[i].ctor = r535_nvdec_obj_ctor; - } - - if (!(*pnvdec = kzalloc(sizeof(**pnvdec), GFP_KERNEL))) { - kfree(rm); - return -ENOMEM; - } - - return nvkm_engine_ctor(rm, device, type, inst, true, &(*pnvdec)->engine); -} +const struct nvkm_rm_api_engine +r535_nvdec = { + .alloc = r535_nvdec_alloc, +}; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvenc.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvenc.c index dcf80d1f1e9e..acb3ce8bb9de 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvenc.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvenc.c @@ -19,91 +19,27 @@ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ -#include <engine/nvenc/priv.h> - -#include <core/object.h> -#include <subdev/gsp.h> -#include <engine/fifo.h> +#include <rm/engine.h> #include "nvrm/nvenc.h" -struct r535_nvenc_obj { - struct nvkm_object object; - struct nvkm_gsp_object rm; -}; - -static void * -r535_nvenc_obj_dtor(struct nvkm_object *object) -{ - struct r535_nvenc_obj *obj = container_of(object, typeof(*obj), object); - - nvkm_gsp_rm_free(&obj->rm); - return obj; -} - -static const struct nvkm_object_func -r535_nvenc_obj = { - .dtor = r535_nvenc_obj_dtor, -}; - static int -r535_nvenc_obj_ctor(const struct nvkm_oclass *oclass, void *argv, u32 argc, - struct nvkm_object **pobject) +r535_nvenc_alloc(struct nvkm_gsp_object *chan, u32 handle, u32 class, int inst, + struct nvkm_gsp_object *nvenc) { - struct nvkm_chan *chan = nvkm_uchan_chan(oclass->parent); - struct r535_nvenc_obj *obj; NV_MSENC_ALLOCATION_PARAMETERS *args; - if (!(obj = kzalloc(sizeof(*obj), GFP_KERNEL))) - return -ENOMEM; - - nvkm_object_ctor(&r535_nvenc_obj, oclass, &obj->object); - *pobject = &obj->object; - - args = nvkm_gsp_rm_alloc_get(&chan->rm.object, oclass->handle, oclass->base.oclass, - sizeof(*args), &obj->rm); + args = nvkm_gsp_rm_alloc_get(chan, handle, class, sizeof(*args), nvenc); if (WARN_ON(IS_ERR(args))) return PTR_ERR(args); args->size = sizeof(*args); - args->engineInstance = oclass->engine->subdev.inst; + args->engineInstance = inst; - return nvkm_gsp_rm_alloc_wr(&obj->rm, args); + return nvkm_gsp_rm_alloc_wr(nvenc, args); } -static void * -r535_nvenc_dtor(struct nvkm_engine *engine) -{ - struct nvkm_nvenc *nvenc = nvkm_nvenc(engine); - - kfree(nvenc->engine.func); - return nvenc; -} - -int -r535_nvenc_new(const struct nvkm_engine_func *hw, struct nvkm_device *device, - enum nvkm_subdev_type type, int inst, struct nvkm_nvenc **pnvenc) -{ - struct nvkm_engine_func *rm; - int nclass; - - for (nclass = 0; hw->sclass[nclass].oclass; nclass++); - - if (!(rm = kzalloc(sizeof(*rm) + (nclass + 1) * sizeof(rm->sclass[0]), GFP_KERNEL))) - return -ENOMEM; - - rm->dtor = r535_nvenc_dtor; - for (int i = 0; i < nclass; i++) { - rm->sclass[i].minver = hw->sclass[i].minver; - rm->sclass[i].maxver = hw->sclass[i].maxver; - rm->sclass[i].oclass = hw->sclass[i].oclass; - rm->sclass[i].ctor = r535_nvenc_obj_ctor; - } - - if (!(*pnvenc = kzalloc(sizeof(**pnvenc), GFP_KERNEL))) { - kfree(rm); - return -ENOMEM; - } - - return nvkm_engine_ctor(rm, device, type, inst, true, &(*pnvenc)->engine); -} +const struct nvkm_rm_api_engine +r535_nvenc = { + .alloc = r535_nvenc_alloc, +}; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvjpg.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvjpg.c index 8a8d7becba93..fbc4080ad8d8 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvjpg.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvjpg.c @@ -19,88 +19,27 @@ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ -#include <engine/nvjpg/priv.h> - -#include <core/object.h> -#include <subdev/gsp.h> -#include <engine/fifo.h> +#include <rm/engine.h> #include "nvrm/nvjpg.h" -struct r535_nvjpg_obj { - struct nvkm_object object; - struct nvkm_gsp_object rm; -}; - -static void * -r535_nvjpg_obj_dtor(struct nvkm_object *object) -{ - struct r535_nvjpg_obj *obj = container_of(object, typeof(*obj), object); - - nvkm_gsp_rm_free(&obj->rm); - return obj; -} - -static const struct nvkm_object_func -r535_nvjpg_obj = { - .dtor = r535_nvjpg_obj_dtor, -}; - static int -r535_nvjpg_obj_ctor(const struct nvkm_oclass *oclass, void *argv, u32 argc, - struct nvkm_object **pobject) +r535_nvjpg_alloc(struct nvkm_gsp_object *chan, u32 handle, u32 class, int inst, + struct nvkm_gsp_object *nvjpg) { - struct nvkm_chan *chan = nvkm_uchan_chan(oclass->parent); - struct r535_nvjpg_obj *obj; NV_NVJPG_ALLOCATION_PARAMETERS *args; - if (!(obj = kzalloc(sizeof(*obj), GFP_KERNEL))) - return -ENOMEM; - - nvkm_object_ctor(&r535_nvjpg_obj, oclass, &obj->object); - *pobject = &obj->object; - - args = nvkm_gsp_rm_alloc_get(&chan->rm.object, oclass->handle, oclass->base.oclass, - sizeof(*args), &obj->rm); + args = nvkm_gsp_rm_alloc_get(chan, handle, class, sizeof(*args), nvjpg); if (WARN_ON(IS_ERR(args))) return PTR_ERR(args); args->size = sizeof(*args); - args->engineInstance = oclass->engine->subdev.inst; + args->engineInstance = inst; - return nvkm_gsp_rm_alloc_wr(&obj->rm, args); + return nvkm_gsp_rm_alloc_wr(nvjpg, args); } -static void * -r535_nvjpg_dtor(struct nvkm_engine *engine) -{ - kfree(engine->func); - return engine; -} - -int -r535_nvjpg_new(const struct nvkm_engine_func *hw, struct nvkm_device *device, - enum nvkm_subdev_type type, int inst, struct nvkm_engine **pengine) -{ - struct nvkm_engine_func *rm; - int nclass, ret; - - for (nclass = 0; hw->sclass[nclass].oclass; nclass++); - - if (!(rm = kzalloc(sizeof(*rm) + (nclass + 1) * sizeof(rm->sclass[0]), GFP_KERNEL))) - return -ENOMEM; - - rm->dtor = r535_nvjpg_dtor; - for (int i = 0; i < nclass; i++) { - rm->sclass[i].minver = hw->sclass[i].minver; - rm->sclass[i].maxver = hw->sclass[i].maxver; - rm->sclass[i].oclass = hw->sclass[i].oclass; - rm->sclass[i].ctor = r535_nvjpg_obj_ctor; - } - - ret = nvkm_engine_new_(rm, device, type, inst, true, pengine); - if (ret) - kfree(rm); - - return ret; -} +const struct nvkm_rm_api_engine +r535_nvjpg = { + .alloc = r535_nvjpg_alloc, +}; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/ofa.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/ofa.c index 4bd84ff04702..2156808cba4f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/ofa.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/ofa.c @@ -19,88 +19,26 @@ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ -#include <engine/ofa/priv.h> - -#include <core/object.h> -#include <subdev/gsp.h> -#include <subdev/mmu.h> -#include <engine/fifo.h> +#include <rm/engine.h> #include "nvrm/ofa.h" -struct r535_ofa_obj { - struct nvkm_object object; - struct nvkm_gsp_object rm; -}; - -static void * -r535_ofa_obj_dtor(struct nvkm_object *object) -{ - struct r535_ofa_obj *obj = container_of(object, typeof(*obj), object); - - nvkm_gsp_rm_free(&obj->rm); - return obj; -} - -static const struct nvkm_object_func -r535_ofa_obj = { - .dtor = r535_ofa_obj_dtor, -}; - static int -r535_ofa_obj_ctor(const struct nvkm_oclass *oclass, void *argv, u32 argc, - struct nvkm_object **pobject) +r535_ofa_alloc(struct nvkm_gsp_object *chan, u32 handle, u32 class, int inst, + struct nvkm_gsp_object *ofa) { - struct nvkm_chan *chan = nvkm_uchan_chan(oclass->parent); - struct r535_ofa_obj *obj; NV_OFA_ALLOCATION_PARAMETERS *args; - if (!(obj = kzalloc(sizeof(*obj), GFP_KERNEL))) - return -ENOMEM; - - nvkm_object_ctor(&r535_ofa_obj, oclass, &obj->object); - *pobject = &obj->object; - - args = nvkm_gsp_rm_alloc_get(&chan->rm.object, oclass->handle, oclass->base.oclass, - sizeof(*args), &obj->rm); + args = nvkm_gsp_rm_alloc_get(chan, handle, class, sizeof(*args), ofa); if (WARN_ON(IS_ERR(args))) return PTR_ERR(args); args->size = sizeof(*args); - return nvkm_gsp_rm_alloc_wr(&obj->rm, args); + return nvkm_gsp_rm_alloc_wr(ofa, args); } -static void * -r535_ofa_dtor(struct nvkm_engine *engine) -{ - kfree(engine->func); - return engine; -} - -int -r535_ofa_new(const struct nvkm_engine_func *hw, struct nvkm_device *device, - enum nvkm_subdev_type type, int inst, struct nvkm_engine **pengine) -{ - struct nvkm_engine_func *rm; - int nclass, ret; - - for (nclass = 0; hw->sclass[nclass].oclass; nclass++); - - if (!(rm = kzalloc(sizeof(*rm) + (nclass + 1) * sizeof(rm->sclass[0]), GFP_KERNEL))) - return -ENOMEM; - - rm->dtor = r535_ofa_dtor; - for (int i = 0; i < nclass; i++) { - rm->sclass[i].minver = hw->sclass[i].minver; - rm->sclass[i].maxver = hw->sclass[i].maxver; - rm->sclass[i].oclass = hw->sclass[i].oclass; - rm->sclass[i].ctor = r535_ofa_obj_ctor; - } - - ret = nvkm_engine_new_(rm, device, type, inst, true, pengine); - if (ret) - kfree(rm); - - return ret; -} +const struct nvkm_rm_api_engine +r535_ofa = { + .alloc = r535_ofa_alloc, +}; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rm.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rm.c index 3c17b75b5e37..6de7d1a91119 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rm.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rm.c @@ -11,6 +11,11 @@ r535_api = { .alloc = &r535_alloc, .client = &r535_client, .device = &r535_device, + .ce = &r535_ce, + .nvdec = &r535_nvdec, + .nvenc = &r535_nvenc, + .nvjpg = &r535_nvjpg, + .ofa = &r535_ofa, }; const struct nvkm_rm_impl diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h index 41d4ed70fc10..bda22703690a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h @@ -53,6 +53,11 @@ struct nvkm_rm_api { void (*dtor)(struct nvkm_gsp_event *); } event; } *device; + + const struct nvkm_rm_api_engine { + int (*alloc)(struct nvkm_gsp_object *chan, u32 handle, u32 class, int inst, + struct nvkm_gsp_object *); + } *ce, *nvdec, *nvenc, *nvjpg, *ofa; }; extern const struct nvkm_rm_impl r535_rm_tu102; @@ -62,4 +67,14 @@ extern const struct nvkm_rm_api_ctrl r535_ctrl; extern const struct nvkm_rm_api_alloc r535_alloc; extern const struct nvkm_rm_api_client r535_client; extern const struct nvkm_rm_api_device r535_device; +extern const struct nvkm_rm_api_engine r535_ce; +void *r535_gr_dtor(struct nvkm_gr *); +int r535_gr_oneinit(struct nvkm_gr *); +u64 r535_gr_units(struct nvkm_gr *); +int r535_gr_chan_new(struct nvkm_gr *, struct nvkm_chan *, const struct nvkm_oclass *, + struct nvkm_object **); +extern const struct nvkm_rm_api_engine r535_nvdec; +extern const struct nvkm_rm_api_engine r535_nvenc; +extern const struct nvkm_rm_api_engine r535_nvjpg; +extern const struct nvkm_rm_api_engine r535_ofa; #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/tu1xx.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/tu1xx.c index bb674b9cef69..883b9eddbfe6 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/tu1xx.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/tu1xx.c @@ -22,4 +22,14 @@ tu1xx_gpu = { .fifo.chan = { .class = TURING_CHANNEL_GPFIFO_A, }, + + .ce.class = TURING_DMA_COPY_A, + .gr.class = { + .i2m = KEPLER_INLINE_TO_MEMORY_B, + .twod = FERMI_TWOD_A, + .threed = TURING_A, + .compute = TURING_COMPUTE_A, + }, + .nvdec.class = NVC4B0_VIDEO_DECODER, + .nvenc.class = NVC4B7_VIDEO_ENCODER, }; -- 2.49.0
Ben Skeggs
2025-May-17 00:09 UTC
[PATCH v3 20/62] drm/nouveau/gsp: add defines for rmapi object handles
Add header containing defines for RMAPI handles used by NVKM, and use them in place of magic values when calling RM_ALLOC. Signed-off-by: Ben Skeggs <bskeggs at nvidia.com> Reviewed-by: Dave Airlie <airlied at redhat.com> Reviewed-by: Timur Tabi <ttabi at nvidia.com> Tested-by: Timur Tabi <ttabi at nvidia.com> --- .../drm/nouveau/nvkm/subdev/gsp/rm/handles.h | 17 +++++++++++++++++ .../nouveau/nvkm/subdev/gsp/rm/r535/client.c | 2 +- .../nouveau/nvkm/subdev/gsp/rm/r535/device.c | 6 +++--- .../drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c | 2 +- .../drm/nouveau/nvkm/subdev/gsp/rm/r535/fifo.c | 2 +- .../drm/nouveau/nvkm/subdev/gsp/rm/r535/gr.c | 4 ++-- .../drm/nouveau/nvkm/subdev/gsp/rm/r535/vmm.c | 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h | 1 + 8 files changed, 27 insertions(+), 9 deletions(-) create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/handles.h diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/handles.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/handles.h new file mode 100644 index 000000000000..50f2f2a86b5a --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/handles.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#ifndef __NVKM_RM_HANDLES_H__ +#define __NVKM_RM_HANDLES_H__ + +/* RMAPI handles for various objects allocated from GSP-RM with RM_ALLOC. */ + +#define NVKM_RM_CLIENT(id) (0xc1d00000 | (id)) +#define NVKM_RM_DEVICE 0xde1d0000 +#define NVKM_RM_SUBDEVICE 0x5d1d0000 +#define NVKM_RM_DISP 0x00730000 +#define NVKM_RM_VASPACE 0x90f10000 +#define NVKM_RM_CHAN(chid) (0xf1f00000 | (chid)) +#define NVKM_RM_THREED 0x97000000 +#endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/client.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/client.c index c0146c00584d..449338da1795 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/client.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/client.c @@ -53,7 +53,7 @@ r535_gsp_client_ctor(struct nvkm_gsp *gsp, struct nvkm_gsp_client *client) client->object.client = client; INIT_LIST_HEAD(&client->events); - args = nvkm_gsp_rm_alloc_get(&client->object, 0xc1d00000 | ret, NV01_ROOT, sizeof(*args), + args = nvkm_gsp_rm_alloc_get(&client->object, NVKM_RM_CLIENT(ret), NV01_ROOT, sizeof(*args), &client->object); if (IS_ERR(args)) { r535_gsp_client_dtor(client); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/device.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/device.c index 094abf7b5f97..f830e12a8f6e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/device.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/device.c @@ -111,8 +111,8 @@ r535_gsp_subdevice_ctor(struct nvkm_gsp_device *device) { NV2080_ALLOC_PARAMETERS *args; - return nvkm_gsp_rm_alloc(&device->object, 0x5d1d0000, NV20_SUBDEVICE_0, sizeof(*args), - &device->subdevice); + return nvkm_gsp_rm_alloc(&device->object, NVKM_RM_SUBDEVICE, NV20_SUBDEVICE_0, + sizeof(*args), &device->subdevice); } static int @@ -121,7 +121,7 @@ r535_gsp_device_ctor(struct nvkm_gsp_client *client, struct nvkm_gsp_device *dev NV0080_ALLOC_PARAMETERS *args; int ret; - args = nvkm_gsp_rm_alloc_get(&client->object, 0xde1d0000, NV01_DEVICE_0, sizeof(*args), + args = nvkm_gsp_rm_alloc_get(&client->object, NVKM_RM_DEVICE, NV01_DEVICE_0, sizeof(*args), &device->object); if (IS_ERR(args)) return PTR_ERR(args); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c index e65f9074e94f..1ba86e223978 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c @@ -1468,7 +1468,7 @@ r535_disp_oneinit(struct nvkm_disp *disp) if (ret) return ret; - ret = nvkm_gsp_rm_alloc(&disp->rm.device.object, 0x00730000, NV04_DISPLAY_COMMON, 0, + ret = nvkm_gsp_rm_alloc(&disp->rm.device.object, NVKM_RM_DISP, NV04_DISPLAY_COMMON, 0, &disp->rm.objcom); if (ret) return ret; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/fifo.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/fifo.c index 98aa272be642..ad9d93f9820d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/fifo.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/fifo.c @@ -101,7 +101,7 @@ r535_chan_ramfc_write(struct nvkm_chan *chan, u64 offset, u64 length, u32 devm, if (!chan->rm.mthdbuf.ptr) return -ENOMEM; - args = nvkm_gsp_rm_alloc_get(&chan->vmm->rm.device.object, 0xf1f00000 | chan->id, + args = nvkm_gsp_rm_alloc_get(&chan->vmm->rm.device.object, NVKM_RM_CHAN(chan->id), fifo->func->chan.user.oclass, sizeof(*args), &chan->rm.object); if (WARN_ON(IS_ERR(args))) diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gr.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gr.c index 3618fa36040c..4c0df52e8683 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gr.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gr.c @@ -205,7 +205,7 @@ r535_gr_oneinit(struct nvkm_gr *base) { NV_CHANNELGPFIFO_ALLOCATION_PARAMETERS *args; - args = nvkm_gsp_rm_alloc_get(&golden.vmm->rm.device.object, 0xf1f00000, + args = nvkm_gsp_rm_alloc_get(&golden.vmm->rm.device.object, NVKM_RM_CHAN(0), device->fifo->func->chan.user.oclass, sizeof(*args), &golden.chan); if (IS_ERR(args)) { @@ -358,7 +358,7 @@ r535_gr_oneinit(struct nvkm_gr *base) goto done; /* Allocate 3D class on channel to trigger golden context init in RM. */ - ret = nvkm_gsp_rm_alloc(&golden.chan, 0x97000000, rm->gpu->gr.class.threed, 0, &threed); + ret = nvkm_gsp_rm_alloc(&golden.chan, NVKM_RM_THREED, rm->gpu->gr.class.threed, 0, &threed); if (ret) goto done; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/vmm.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/vmm.c index c697885c65d3..99af6c19a9a9 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/vmm.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/vmm.c @@ -34,7 +34,7 @@ r535_mmu_promote_vmm(struct nvkm_vmm *vmm) if (ret) return ret; - args = nvkm_gsp_rm_alloc_get(&vmm->rm.device.object, 0x90f10000, FERMI_VASPACE_A, + args = nvkm_gsp_rm_alloc_get(&vmm->rm.device.object, NVKM_RM_VASPACE, FERMI_VASPACE_A, sizeof(*args), &vmm->rm.object); if (IS_ERR(args)) return PTR_ERR(args); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h index bda22703690a..4d9e5ea3b2fa 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h @@ -5,6 +5,7 @@ #include <subdev/gsp.h> #ifndef __NVKM_RM_H__ #define __NVKM_RM_H__ +#include "handles.h" struct nvkm_rm_impl { const struct nvkm_rm_api *api; -- 2.49.0
Ben Skeggs
2025-May-17 00:09 UTC
[PATCH v3 21/62] drm/nouveau/gsp: add hal for wpr config info + meta init
545.23.06 increases the libos3 heap size requirements, and GH100/GBxxx will need their own implementation entirely. Signed-off-by: Ben Skeggs <bskeggs at nvidia.com> Reviewed-by: Dave Airlie <airlied at redhat.com> Reviewed-by: Timur Tabi <ttabi at nvidia.com> Tested-by: Timur Tabi <ttabi at nvidia.com> --- .../gpu/drm/nouveau/include/nvkm/subdev/gsp.h | 3 + .../gpu/drm/nouveau/nvkm/subdev/gsp/ad102.c | 4 - .../gpu/drm/nouveau/nvkm/subdev/gsp/base.c | 1 + .../gpu/drm/nouveau/nvkm/subdev/gsp/ga100.c | 3 - .../gpu/drm/nouveau/nvkm/subdev/gsp/ga102.c | 4 - .../gpu/drm/nouveau/nvkm/subdev/gsp/priv.h | 6 -- .../drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c | 92 +----------------- .../nvkm/subdev/gsp/rm/r535/nvrm/gsp.h | 8 ++ .../drm/nouveau/nvkm/subdev/gsp/rm/r535/rm.c | 18 ++++ .../gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h | 8 ++ .../gpu/drm/nouveau/nvkm/subdev/gsp/tu102.c | 97 ++++++++++++++++++- .../gpu/drm/nouveau/nvkm/subdev/gsp/tu116.c | 3 - 12 files changed, 134 insertions(+), 113 deletions(-) diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h index eeaf72f6add3..ef781c4ca11f 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h @@ -17,6 +17,9 @@ struct nvkm_gsp_mem { dma_addr_t addr; }; +int nvkm_gsp_mem_ctor(struct nvkm_gsp *, size_t size, struct nvkm_gsp_mem *); +void nvkm_gsp_mem_dtor(struct nvkm_gsp_mem *); + struct nvkm_gsp_radix3 { struct nvkm_gsp_mem lvl0; struct nvkm_gsp_mem lvl1; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ad102.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ad102.c index d7933bfc59fd..8ab02d683c90 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ad102.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ad102.c @@ -28,10 +28,6 @@ ad102_gsp = { .sig_section = ".fwsignature_ad10x", - .wpr_heap.os_carveout_size = 20 << 20, - .wpr_heap.base_size = 8 << 20, - .wpr_heap.min_size = 84 << 20, - .booter.ctor = ga102_gsp_booter_ctor, .dtor = r535_gsp_dtor, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/base.c index 0f8526aa969f..be6bbf06d58b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/base.c @@ -148,6 +148,7 @@ nvkm_gsp_new_(const struct nvkm_gsp_fwif *fwif, struct nvkm_device *device, gsp->rm->device = device; gsp->rm->gpu = fwif->func->rm.gpu; + gsp->rm->wpr = fwif->rm->wpr; gsp->rm->api = fwif->rm->api; } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ga100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ga100.c index 77e3501296c9..a6836a85b2ac 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ga100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ga100.c @@ -45,9 +45,6 @@ ga100_gsp = { .sig_section = ".fwsignature_ga100", - .wpr_heap.base_size = 8 << 20, - .wpr_heap.min_size = 64 << 20, - .booter.ctor = tu102_gsp_booter_ctor, .dtor = r535_gsp_dtor, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ga102.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ga102.c index 709a046d86bf..202b5bdc3980 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ga102.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ga102.c @@ -156,10 +156,6 @@ ga102_gsp_r535 = { .sig_section = ".fwsignature_ga10x", - .wpr_heap.os_carveout_size = 20 << 20, - .wpr_heap.base_size = 8 << 20, - .wpr_heap.min_size = 84 << 20, - .booter.ctor = ga102_gsp_booter_ctor, .dtor = r535_gsp_dtor, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/priv.h index de274f6426c1..d42ae235d2f4 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/priv.h @@ -36,12 +36,6 @@ struct nvkm_gsp_func { char *sig_section; - struct { - u32 os_carveout_size; - u32 base_size; - u64 min_size; - } wpr_heap; - struct { int (*ctor)(struct nvkm_gsp *, const char *name, const struct firmware *, struct nvkm_falcon *, struct nvkm_falcon_fw *); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c index 8ca0f99ccbac..ec69fdb9492a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c @@ -231,7 +231,7 @@ r535_gsp_rpc_get_gsp_static_info(struct nvkm_gsp *gsp) return 0; } -static void +void nvkm_gsp_mem_dtor(struct nvkm_gsp_mem *mem) { if (mem->data) { @@ -260,7 +260,7 @@ nvkm_gsp_mem_dtor(struct nvkm_gsp_mem *mem) * so we take a device reference to ensure its lifetime. The reference is * dropped in the destructor. */ -static int +int nvkm_gsp_mem_ctor(struct nvkm_gsp *gsp, size_t size, struct nvkm_gsp_mem *mem) { mem->data = dma_alloc_coherent(gsp->subdev.device->dev, size, &mem->addr, GFP_KERNEL); @@ -1129,55 +1129,6 @@ r535_gsp_msg_run_cpu_sequencer(void *priv, u32 fn, void *repv, u32 repc) return 0; } -static int -r535_gsp_wpr_meta_init(struct nvkm_gsp *gsp) -{ - GspFwWprMeta *meta; - int ret; - - ret = nvkm_gsp_mem_ctor(gsp, 0x1000, &gsp->wpr_meta); - if (ret) - return ret; - - meta = gsp->wpr_meta.data; - - meta->magic = GSP_FW_WPR_META_MAGIC; - meta->revision = GSP_FW_WPR_META_REVISION; - - meta->sysmemAddrOfRadix3Elf = gsp->radix3.lvl0.addr; - meta->sizeOfRadix3Elf = gsp->fb.wpr2.elf.size; - - meta->sysmemAddrOfBootloader = gsp->boot.fw.addr; - meta->sizeOfBootloader = gsp->boot.fw.size; - meta->bootloaderCodeOffset = gsp->boot.code_offset; - meta->bootloaderDataOffset = gsp->boot.data_offset; - meta->bootloaderManifestOffset = gsp->boot.manifest_offset; - - meta->sysmemAddrOfSignature = gsp->sig.addr; - meta->sizeOfSignature = gsp->sig.size; - - meta->gspFwRsvdStart = gsp->fb.heap.addr; - meta->nonWprHeapOffset = gsp->fb.heap.addr; - meta->nonWprHeapSize = gsp->fb.heap.size; - meta->gspFwWprStart = gsp->fb.wpr2.addr; - meta->gspFwHeapOffset = gsp->fb.wpr2.heap.addr; - meta->gspFwHeapSize = gsp->fb.wpr2.heap.size; - meta->gspFwOffset = gsp->fb.wpr2.elf.addr; - meta->bootBinOffset = gsp->fb.wpr2.boot.addr; - meta->frtsOffset = gsp->fb.wpr2.frts.addr; - meta->frtsSize = gsp->fb.wpr2.frts.size; - meta->gspFwWprEnd = ALIGN_DOWN(gsp->fb.bios.vga_workspace.addr, 0x20000); - meta->fbSize = gsp->fb.size; - meta->vgaWorkspaceOffset = gsp->fb.bios.vga_workspace.addr; - meta->vgaWorkspaceSize = gsp->fb.bios.vga_workspace.size; - meta->bootCount = 0; - meta->partitionRpcAddr = 0; - meta->partitionRpcRequestOffset = 0; - meta->partitionRpcReplyOffset = 0; - meta->verified = 0; - return 0; -} - static int r535_gsp_shared_init(struct nvkm_gsp *gsp) { @@ -2179,49 +2130,10 @@ r535_gsp_oneinit(struct nvkm_gsp *gsp) /* Release FW images - we've copied them to DMA buffers now. */ nvkm_gsp_dtor_fws(gsp); - /* Calculate FB layout. */ - gsp->fb.wpr2.frts.size = 0x100000; - gsp->fb.wpr2.frts.addr = ALIGN_DOWN(gsp->fb.bios.addr, 0x20000) - gsp->fb.wpr2.frts.size; - - gsp->fb.wpr2.boot.size = gsp->boot.fw.size; - gsp->fb.wpr2.boot.addr = ALIGN_DOWN(gsp->fb.wpr2.frts.addr - gsp->fb.wpr2.boot.size, 0x1000); - - gsp->fb.wpr2.elf.size = gsp->fw.len; - gsp->fb.wpr2.elf.addr = ALIGN_DOWN(gsp->fb.wpr2.boot.addr - gsp->fb.wpr2.elf.size, 0x10000); - - { - u32 fb_size_gb = DIV_ROUND_UP_ULL(gsp->fb.size, 1 << 30); - - gsp->fb.wpr2.heap.size - gsp->func->wpr_heap.os_carveout_size + - gsp->func->wpr_heap.base_size + - ALIGN(GSP_FW_HEAP_PARAM_SIZE_PER_GB_FB * fb_size_gb, 1 << 20) + - ALIGN(GSP_FW_HEAP_PARAM_CLIENT_ALLOC_SIZE, 1 << 20); - - gsp->fb.wpr2.heap.size = max(gsp->fb.wpr2.heap.size, gsp->func->wpr_heap.min_size); - } - - gsp->fb.wpr2.heap.addr = ALIGN_DOWN(gsp->fb.wpr2.elf.addr - gsp->fb.wpr2.heap.size, 0x100000); - gsp->fb.wpr2.heap.size = ALIGN_DOWN(gsp->fb.wpr2.elf.addr - gsp->fb.wpr2.heap.addr, 0x100000); - - gsp->fb.wpr2.addr = ALIGN_DOWN(gsp->fb.wpr2.heap.addr - sizeof(GspFwWprMeta), 0x100000); - gsp->fb.wpr2.size = gsp->fb.wpr2.frts.addr + gsp->fb.wpr2.frts.size - gsp->fb.wpr2.addr; - - gsp->fb.heap.size = 0x100000; - gsp->fb.heap.addr = gsp->fb.wpr2.addr - gsp->fb.heap.size; - - ret = nvkm_gsp_fwsec_frts(gsp); - if (WARN_ON(ret)) - return ret; - ret = r535_gsp_libos_init(gsp); if (WARN_ON(ret)) return ret; - ret = r535_gsp_wpr_meta_init(gsp); - if (WARN_ON(ret)) - return ret; - ret = r535_gsp_rpc_set_system_info(gsp); if (WARN_ON(ret)) return ret; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvrm/gsp.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvrm/gsp.h index 085a7dac0405..b6683a5bf870 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvrm/gsp.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvrm/gsp.h @@ -814,4 +814,12 @@ typedef struct GSP_MSG_QUEUE_ELEMENT NvU32 elemCount; // Number of message queue elements this message has. NV_DECLARE_ALIGNED(rpc_message_header_v rpc, 8); } GSP_MSG_QUEUE_ELEMENT; + +#define GSP_FW_HEAP_PARAM_OS_SIZE_LIBOS2 (0 << 20) // No FB heap usage +#define GSP_FW_HEAP_PARAM_OS_SIZE_LIBOS3 (20 << 20) + +#define GSP_FW_HEAP_PARAM_BASE_RM_SIZE_TU10X (8 << 20) // Turing thru Ada + +#define GSP_FW_HEAP_SIZE_OVERRIDE_LIBOS2_MIN_MB (64u) +#define GSP_FW_HEAP_SIZE_OVERRIDE_LIBOS3_BAREMETAL_MIN_MB (84u) #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rm.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rm.c index 6de7d1a91119..60e8678b7913 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rm.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rm.c @@ -4,6 +4,22 @@ */ #include <rm/rm.h> +#include "nvrm/gsp.h" + +static const struct nvkm_rm_wpr +r535_wpr_libos2 = { + .os_carveout_size = GSP_FW_HEAP_PARAM_OS_SIZE_LIBOS2, + .base_size = GSP_FW_HEAP_PARAM_BASE_RM_SIZE_TU10X, + .heap_size_min = GSP_FW_HEAP_SIZE_OVERRIDE_LIBOS2_MIN_MB, +}; + +static const struct nvkm_rm_wpr +r535_wpr_libos3 = { + .os_carveout_size = GSP_FW_HEAP_PARAM_OS_SIZE_LIBOS3, + .base_size = GSP_FW_HEAP_PARAM_BASE_RM_SIZE_TU10X, + .heap_size_min = GSP_FW_HEAP_SIZE_OVERRIDE_LIBOS3_BAREMETAL_MIN_MB, +}; + static const struct nvkm_rm_api r535_api = { .rpc = &r535_rpc, @@ -20,10 +36,12 @@ r535_api = { const struct nvkm_rm_impl r535_rm_tu102 = { + .wpr = &r535_wpr_libos2, .api = &r535_api, }; const struct nvkm_rm_impl r535_rm_ga102 = { + .wpr = &r535_wpr_libos3, .api = &r535_api, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h index 4d9e5ea3b2fa..1a2fec3935a4 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h @@ -8,15 +8,23 @@ #include "handles.h" struct nvkm_rm_impl { + const struct nvkm_rm_wpr *wpr; const struct nvkm_rm_api *api; }; struct nvkm_rm { struct nvkm_device *device; const struct nvkm_rm_gpu *gpu; + const struct nvkm_rm_wpr *wpr; const struct nvkm_rm_api *api; }; +struct nvkm_rm_wpr { + u32 os_carveout_size; + u32 base_size; + u64 heap_size_min; +}; + struct nvkm_rm_api { const struct nvkm_rm_api_rpc { void *(*get)(struct nvkm_gsp *, u32 fn, u32 argc); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/tu102.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/tu102.c index fef9c4444017..a07f59e5ef7a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/tu102.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/tu102.c @@ -24,6 +24,8 @@ #include <subdev/fb.h> #include <engine/sec2.h> +#include <rm/r535/nvrm/gsp.h> + #include <nvfw/flcn.h> #include <nvfw/fw.h> #include <nvfw/hs.h> @@ -195,6 +197,69 @@ tu102_gsp_init(struct nvkm_gsp *gsp) return r535_gsp_init(gsp); } +static int +tu102_gsp_wpr_meta_init(struct nvkm_gsp *gsp) +{ + GspFwWprMeta *meta; + int ret; + + ret = nvkm_gsp_mem_ctor(gsp, sizeof(*meta), &gsp->wpr_meta); + if (ret) + return ret; + + meta = gsp->wpr_meta.data; + + meta->magic = GSP_FW_WPR_META_MAGIC; + meta->revision = GSP_FW_WPR_META_REVISION; + + meta->sysmemAddrOfRadix3Elf = gsp->radix3.lvl0.addr; + meta->sizeOfRadix3Elf = gsp->fb.wpr2.elf.size; + + meta->sysmemAddrOfBootloader = gsp->boot.fw.addr; + meta->sizeOfBootloader = gsp->boot.fw.size; + meta->bootloaderCodeOffset = gsp->boot.code_offset; + meta->bootloaderDataOffset = gsp->boot.data_offset; + meta->bootloaderManifestOffset = gsp->boot.manifest_offset; + + meta->sysmemAddrOfSignature = gsp->sig.addr; + meta->sizeOfSignature = gsp->sig.size; + + meta->gspFwRsvdStart = gsp->fb.heap.addr; + meta->nonWprHeapOffset = gsp->fb.heap.addr; + meta->nonWprHeapSize = gsp->fb.heap.size; + meta->gspFwWprStart = gsp->fb.wpr2.addr; + meta->gspFwHeapOffset = gsp->fb.wpr2.heap.addr; + meta->gspFwHeapSize = gsp->fb.wpr2.heap.size; + meta->gspFwOffset = gsp->fb.wpr2.elf.addr; + meta->bootBinOffset = gsp->fb.wpr2.boot.addr; + meta->frtsOffset = gsp->fb.wpr2.frts.addr; + meta->frtsSize = gsp->fb.wpr2.frts.size; + meta->gspFwWprEnd = ALIGN_DOWN(gsp->fb.bios.vga_workspace.addr, 0x20000); + meta->fbSize = gsp->fb.size; + meta->vgaWorkspaceOffset = gsp->fb.bios.vga_workspace.addr; + meta->vgaWorkspaceSize = gsp->fb.bios.vga_workspace.size; + meta->bootCount = 0; + meta->partitionRpcAddr = 0; + meta->partitionRpcRequestOffset = 0; + meta->partitionRpcReplyOffset = 0; + meta->verified = 0; + return 0; +} + +static u64 +tu102_gsp_wpr_heap_size(struct nvkm_gsp *gsp) +{ + u32 fb_size_gb = DIV_ROUND_UP_ULL(gsp->fb.size, 1 << 30); + u64 heap_size; + + heap_size = gsp->rm->wpr->os_carveout_size + + gsp->rm->wpr->base_size + + ALIGN(GSP_FW_HEAP_PARAM_SIZE_PER_GB_FB * fb_size_gb, 1 << 20) + + ALIGN(GSP_FW_HEAP_PARAM_CLIENT_ALLOC_SIZE, 1 << 20); + + return max(heap_size, gsp->rm->wpr->heap_size_min); +} + static u64 tu102_gsp_vga_workspace_addr(struct nvkm_gsp *gsp, u64 fb_size) { @@ -241,6 +306,35 @@ tu102_gsp_oneinit(struct nvkm_gsp *gsp) if (ret) return ret; + /* Calculate FB layout. */ + gsp->fb.wpr2.frts.size = 0x100000; + gsp->fb.wpr2.frts.addr = ALIGN_DOWN(gsp->fb.bios.addr, 0x20000) - gsp->fb.wpr2.frts.size; + + gsp->fb.wpr2.boot.size = gsp->boot.fw.size; + gsp->fb.wpr2.boot.addr = ALIGN_DOWN(gsp->fb.wpr2.frts.addr - gsp->fb.wpr2.boot.size, 0x1000); + + gsp->fb.wpr2.elf.size = gsp->fw.len; + gsp->fb.wpr2.elf.addr = ALIGN_DOWN(gsp->fb.wpr2.boot.addr - gsp->fb.wpr2.elf.size, 0x10000); + + gsp->fb.wpr2.heap.size = tu102_gsp_wpr_heap_size(gsp); + + gsp->fb.wpr2.heap.addr = ALIGN_DOWN(gsp->fb.wpr2.elf.addr - gsp->fb.wpr2.heap.size, 0x100000); + gsp->fb.wpr2.heap.size = ALIGN_DOWN(gsp->fb.wpr2.elf.addr - gsp->fb.wpr2.heap.addr, 0x100000); + + gsp->fb.wpr2.addr = ALIGN_DOWN(gsp->fb.wpr2.heap.addr - sizeof(GspFwWprMeta), 0x100000); + gsp->fb.wpr2.size = gsp->fb.wpr2.frts.addr + gsp->fb.wpr2.frts.size - gsp->fb.wpr2.addr; + + gsp->fb.heap.size = 0x100000; + gsp->fb.heap.addr = gsp->fb.wpr2.addr - gsp->fb.heap.size; + + ret = tu102_gsp_wpr_meta_init(gsp); + if (ret) + return ret; + + ret = nvkm_gsp_fwsec_frts(gsp); + if (WARN_ON(ret)) + return ret; + /* Reset GSP into RISC-V mode. */ ret = gsp->func->reset(gsp); if (ret) @@ -274,9 +368,6 @@ tu102_gsp = { .sig_section = ".fwsignature_tu10x", - .wpr_heap.base_size = 8 << 20, - .wpr_heap.min_size = 64 << 20, - .booter.ctor = tu102_gsp_booter_ctor, .dtor = r535_gsp_dtor, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/tu116.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/tu116.c index 5f279813626f..9e897bdcb647 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/tu116.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/tu116.c @@ -28,9 +28,6 @@ tu116_gsp = { .sig_section = ".fwsignature_tu11x", - .wpr_heap.base_size = 8 << 20, - .wpr_heap.min_size = 64 << 20, - .booter.ctor = tu102_gsp_booter_ctor, .dtor = r535_gsp_dtor, -- 2.49.0
Ben Skeggs
2025-May-17 00:09 UTC
[PATCH v3 22/62] drm/nouveau/gsp: add hal for gsp.set_system_info()
545.23.06 has incompatible changes to GspSystemInfo. Signed-off-by: Ben Skeggs <bskeggs at nvidia.com> Reviewed-by: Dave Airlie <airlied at redhat.com> Reviewed-by: Timur Tabi <ttabi at nvidia.com> Tested-by: Timur Tabi <ttabi at nvidia.com> --- drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c | 10 ++++++++-- drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rm.c | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h | 5 +++++ 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c index ec69fdb9492a..f574a3ad2082 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c @@ -871,7 +871,7 @@ r535_gsp_acpi_info(struct nvkm_gsp *gsp, ACPI_METHOD_DATA *acpi) } static int -r535_gsp_rpc_set_system_info(struct nvkm_gsp *gsp) +r535_gsp_set_system_info(struct nvkm_gsp *gsp) { struct nvkm_device *device = gsp->subdev.device; struct nvkm_device_pci *pdev = container_of(device, typeof(*pdev), device); @@ -2080,6 +2080,7 @@ int r535_gsp_oneinit(struct nvkm_gsp *gsp) { struct nvkm_device *device = gsp->subdev.device; + const struct nvkm_rm_api *rmapi = gsp->rm->api; const u8 *data; u64 size; int ret; @@ -2134,7 +2135,7 @@ r535_gsp_oneinit(struct nvkm_gsp *gsp) if (WARN_ON(ret)) return ret; - ret = r535_gsp_rpc_set_system_info(gsp); + ret = rmapi->gsp->set_system_info(gsp); if (WARN_ON(ret)) return ret; @@ -2146,3 +2147,8 @@ r535_gsp_oneinit(struct nvkm_gsp *gsp) idr_init(&gsp->client_id.idr); return 0; } + +const struct nvkm_rm_api_gsp +r535_gsp = { + .set_system_info = r535_gsp_set_system_info, +}; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rm.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rm.c index 60e8678b7913..efedd387fcc5 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rm.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rm.c @@ -22,6 +22,7 @@ r535_wpr_libos3 = { static const struct nvkm_rm_api r535_api = { + .gsp = &r535_gsp, .rpc = &r535_rpc, .ctrl = &r535_ctrl, .alloc = &r535_alloc, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h index 1a2fec3935a4..4a37904f7f9c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h @@ -26,6 +26,10 @@ struct nvkm_rm_wpr { }; struct nvkm_rm_api { + const struct nvkm_rm_api_gsp { + int (*set_system_info)(struct nvkm_gsp *); + } *gsp; + const struct nvkm_rm_api_rpc { void *(*get)(struct nvkm_gsp *, u32 fn, u32 argc); void *(*push)(struct nvkm_gsp *gsp, void *argv, @@ -71,6 +75,7 @@ struct nvkm_rm_api { extern const struct nvkm_rm_impl r535_rm_tu102; extern const struct nvkm_rm_impl r535_rm_ga102; +extern const struct nvkm_rm_api_gsp r535_gsp; extern const struct nvkm_rm_api_rpc r535_rpc; extern const struct nvkm_rm_api_ctrl r535_ctrl; extern const struct nvkm_rm_api_alloc r535_alloc; -- 2.49.0
Ben Skeggs
2025-May-17 00:09 UTC
[PATCH v3 23/62] drm/nouveau/gsp: add hal for gsp.get_static_info()
545.23.06 has incompatible changes to a number of definitions that impact the layout of GspStaticConfigInfo. Signed-off-by: Ben Skeggs <bskeggs at nvidia.com> Reviewed-by: Dave Airlie <airlied at redhat.com> Reviewed-by: Timur Tabi <ttabi at nvidia.com> Tested-by: Timur Tabi <ttabi at nvidia.com> --- .../drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c | 65 +++++++++++-------- .../gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h | 1 + 2 files changed, 38 insertions(+), 28 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c index f574a3ad2082..ed0fbfbd5168 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c @@ -165,35 +165,14 @@ r535_gsp_intr_get_table(struct nvkm_gsp *gsp) return ret; } -static int -r535_gsp_rpc_get_gsp_static_info(struct nvkm_gsp *gsp) +static void +r535_gsp_get_static_info_fb(struct nvkm_gsp *gsp, + const struct NV2080_CTRL_CMD_FB_GET_FB_REGION_INFO_PARAMS *info) { - GspStaticConfigInfo *rpc; int last_usable = -1; - rpc = nvkm_gsp_rpc_rd(gsp, NV_VGPU_MSG_FUNCTION_GET_GSP_STATIC_INFO, sizeof(*rpc)); - if (IS_ERR(rpc)) - return PTR_ERR(rpc); - - gsp->internal.client.object.client = &gsp->internal.client; - gsp->internal.client.object.parent = NULL; - gsp->internal.client.object.handle = rpc->hInternalClient; - gsp->internal.client.gsp = gsp; - - gsp->internal.device.object.client = &gsp->internal.client; - gsp->internal.device.object.parent = &gsp->internal.client.object; - gsp->internal.device.object.handle = rpc->hInternalDevice; - - gsp->internal.device.subdevice.client = &gsp->internal.client; - gsp->internal.device.subdevice.parent = &gsp->internal.device.object; - gsp->internal.device.subdevice.handle = rpc->hInternalSubdevice; - - gsp->bar.rm_bar1_pdb = rpc->bar1PdeBase; - gsp->bar.rm_bar2_pdb = rpc->bar2PdeBase; - - for (int i = 0; i < rpc->fbRegionInfoParams.numFBRegions; i++) { - NV2080_CTRL_CMD_FB_GET_FB_REGION_FB_REGION_INFO *reg - &rpc->fbRegionInfoParams.fbRegion[i]; + for (int i = 0; i < info->numFBRegions; i++) { + const NV2080_CTRL_CMD_FB_GET_FB_REGION_FB_REGION_INFO *reg = &info->fbRegion[i]; nvkm_debug(&gsp->subdev, "fb region %d: " "%016llx-%016llx rsvd:%016llx perf:%08x comp:%d iso:%d prot:%d\n", i, @@ -215,10 +194,38 @@ r535_gsp_rpc_get_gsp_static_info(struct nvkm_gsp *gsp) } if (last_usable >= 0) { - u32 rsvd_base = rpc->fbRegionInfoParams.fbRegion[last_usable].limit + 1; + u32 rsvd_base = info->fbRegion[last_usable].limit + 1; gsp->fb.rsvd_size = gsp->fb.heap.addr - rsvd_base; } +} + +static int +r535_gsp_get_static_info(struct nvkm_gsp *gsp) +{ + GspStaticConfigInfo *rpc; + + rpc = nvkm_gsp_rpc_rd(gsp, NV_VGPU_MSG_FUNCTION_GET_GSP_STATIC_INFO, sizeof(*rpc)); + if (IS_ERR(rpc)) + return PTR_ERR(rpc); + + gsp->internal.client.object.client = &gsp->internal.client; + gsp->internal.client.object.parent = NULL; + gsp->internal.client.object.handle = rpc->hInternalClient; + gsp->internal.client.gsp = gsp; + + gsp->internal.device.object.client = &gsp->internal.client; + gsp->internal.device.object.parent = &gsp->internal.client.object; + gsp->internal.device.object.handle = rpc->hInternalDevice; + + gsp->internal.device.subdevice.client = &gsp->internal.client; + gsp->internal.device.subdevice.parent = &gsp->internal.device.object; + gsp->internal.device.subdevice.handle = rpc->hInternalSubdevice; + + gsp->bar.rm_bar1_pdb = rpc->bar1PdeBase; + gsp->bar.rm_bar2_pdb = rpc->bar2PdeBase; + + r535_gsp_get_static_info_fb(gsp, &rpc->fbRegionInfoParams); for (int gpc = 0; gpc < ARRAY_SIZE(rpc->tpcInfo); gpc++) { if (rpc->gpcInfo.gpcMask & BIT(gpc)) { @@ -277,9 +284,10 @@ static int r535_gsp_postinit(struct nvkm_gsp *gsp) { struct nvkm_device *device = gsp->subdev.device; + const struct nvkm_rm_api *rmapi = gsp->rm->api; int ret; - ret = r535_gsp_rpc_get_gsp_static_info(gsp); + ret = rmapi->gsp->get_static_info(gsp); if (WARN_ON(ret)) return ret; @@ -2151,4 +2159,5 @@ r535_gsp_oneinit(struct nvkm_gsp *gsp) const struct nvkm_rm_api_gsp r535_gsp = { .set_system_info = r535_gsp_set_system_info, + .get_static_info = r535_gsp_get_static_info, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h index 4a37904f7f9c..445793d8147b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h @@ -28,6 +28,7 @@ struct nvkm_rm_wpr { struct nvkm_rm_api { const struct nvkm_rm_api_gsp { int (*set_system_info)(struct nvkm_gsp *); + int (*get_static_info)(struct nvkm_gsp *); } *gsp; const struct nvkm_rm_api_rpc { -- 2.49.0
Ben Skeggs
2025-May-17 00:09 UTC
[PATCH v3 24/62] drm/nouveau/gsp: add hal for gsp.xlat_mc_engine_idx()
545.23.06 has incompatible changes to MC_ENGINE_IDX definitions. Signed-off-by: Ben Skeggs <bskeggs at nvidia.com> Reviewed-by: Dave Airlie <airlied at redhat.com> Reviewed-by: Timur Tabi <ttabi at nvidia.com> Tested-by: Timur Tabi <ttabi at nvidia.com> --- .../drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c | 79 +++++++++++-------- .../gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h | 1 + 2 files changed, 45 insertions(+), 35 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c index ed0fbfbd5168..65640b43f477 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c @@ -86,10 +86,52 @@ r535_gsp_intr(struct nvkm_inth *inth) return IRQ_HANDLED; } +static bool +r535_gsp_xlat_mc_engine_idx(u32 mc_engine_idx, enum nvkm_subdev_type *ptype, int *pinst) +{ + switch (mc_engine_idx) { + case MC_ENGINE_IDX_GSP: + *ptype = NVKM_SUBDEV_GSP; + *pinst = 0; + return true; + case MC_ENGINE_IDX_DISP: + *ptype = NVKM_ENGINE_DISP; + *pinst = 0; + return true; + case MC_ENGINE_IDX_CE0 ... MC_ENGINE_IDX_CE9: + *ptype = NVKM_ENGINE_CE; + *pinst = mc_engine_idx - MC_ENGINE_IDX_CE0; + return true; + case MC_ENGINE_IDX_GR0: + *ptype = NVKM_ENGINE_GR; + *pinst = 0; + return true; + case MC_ENGINE_IDX_NVDEC0 ... MC_ENGINE_IDX_NVDEC7: + *ptype = NVKM_ENGINE_NVDEC; + *pinst = mc_engine_idx - MC_ENGINE_IDX_NVDEC0; + return true; + case MC_ENGINE_IDX_MSENC ... MC_ENGINE_IDX_MSENC2: + *ptype = NVKM_ENGINE_NVENC; + *pinst = mc_engine_idx - MC_ENGINE_IDX_MSENC; + return true; + case MC_ENGINE_IDX_NVJPEG0 ... MC_ENGINE_IDX_NVJPEG7: + *ptype = NVKM_ENGINE_NVJPG; + *pinst = mc_engine_idx - MC_ENGINE_IDX_NVJPEG0; + return true; + case MC_ENGINE_IDX_OFA0: + *ptype = NVKM_ENGINE_OFA; + *pinst = 0; + return true; + default: + return false; + } +} + static int r535_gsp_intr_get_table(struct nvkm_gsp *gsp) { NV2080_CTRL_INTERNAL_INTR_GET_KERNEL_TABLE_PARAMS *ctrl; + const struct nvkm_rm_api *rmapi = gsp->rm->api; int ret = 0; ctrl = nvkm_gsp_rm_ctrl_get(&gsp->internal.device.subdevice, @@ -112,42 +154,8 @@ r535_gsp_intr_get_table(struct nvkm_gsp *gsp) ctrl->table[i].engineIdx, ctrl->table[i].pmcIntrMask, ctrl->table[i].vectorStall, ctrl->table[i].vectorNonStall); - switch (ctrl->table[i].engineIdx) { - case MC_ENGINE_IDX_GSP: - type = NVKM_SUBDEV_GSP; - inst = 0; - break; - case MC_ENGINE_IDX_DISP: - type = NVKM_ENGINE_DISP; - inst = 0; - break; - case MC_ENGINE_IDX_CE0 ... MC_ENGINE_IDX_CE9: - type = NVKM_ENGINE_CE; - inst = ctrl->table[i].engineIdx - MC_ENGINE_IDX_CE0; - break; - case MC_ENGINE_IDX_GR0: - type = NVKM_ENGINE_GR; - inst = 0; - break; - case MC_ENGINE_IDX_NVDEC0 ... MC_ENGINE_IDX_NVDEC7: - type = NVKM_ENGINE_NVDEC; - inst = ctrl->table[i].engineIdx - MC_ENGINE_IDX_NVDEC0; - break; - case MC_ENGINE_IDX_MSENC ... MC_ENGINE_IDX_MSENC2: - type = NVKM_ENGINE_NVENC; - inst = ctrl->table[i].engineIdx - MC_ENGINE_IDX_MSENC; - break; - case MC_ENGINE_IDX_NVJPEG0 ... MC_ENGINE_IDX_NVJPEG7: - type = NVKM_ENGINE_NVJPG; - inst = ctrl->table[i].engineIdx - MC_ENGINE_IDX_NVJPEG0; - break; - case MC_ENGINE_IDX_OFA0: - type = NVKM_ENGINE_OFA; - inst = 0; - break; - default: + if (!rmapi->gsp->xlat_mc_engine_idx(ctrl->table[i].engineIdx, &type, &inst)) continue; - } if (WARN_ON(gsp->intr_nr == ARRAY_SIZE(gsp->intr))) { ret = -ENOSPC; @@ -2160,4 +2168,5 @@ const struct nvkm_rm_api_gsp r535_gsp = { .set_system_info = r535_gsp_set_system_info, .get_static_info = r535_gsp_get_static_info, + .xlat_mc_engine_idx = r535_gsp_xlat_mc_engine_idx, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h index 445793d8147b..aecb066982d8 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h @@ -29,6 +29,7 @@ struct nvkm_rm_api { const struct nvkm_rm_api_gsp { int (*set_system_info)(struct nvkm_gsp *); int (*get_static_info)(struct nvkm_gsp *); + bool (*xlat_mc_engine_idx)(u32 mc_engine_idx, enum nvkm_subdev_type *, int *inst); } *gsp; const struct nvkm_rm_api_rpc { -- 2.49.0
Ben Skeggs
2025-May-17 00:09 UTC
[PATCH v3 25/62] drm/nouveau/gsp: add hal for gsp.drop_send_user_shared_data()
545.23.06 removes NV_VGPU_MSG_EVENT_GSP_SEND_USER_SHARED_DATA, but has another event (NVLINK_FAULT_UP) in its place. Signed-off-by: Ben Skeggs <bskeggs at nvidia.com> Reviewed-by: Dave Airlie <airlied at redhat.com> Reviewed-by: Timur Tabi <ttabi at nvidia.com> Tested-by: Timur Tabi <ttabi at nvidia.com> --- drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c | 11 ++++++++++- drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h | 1 + 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c index 65640b43f477..f7cc8e03d999 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c @@ -2092,6 +2092,12 @@ r535_gsp_dtor(struct nvkm_gsp *gsp) nvkm_gsp_mem_dtor(&gsp->logrm); } +static void +r535_gsp_drop_send_user_shared_data(struct nvkm_gsp *gsp) +{ + r535_gsp_msg_ntfy_add(gsp, NV_VGPU_MSG_EVENT_GSP_SEND_USER_SHARED_DATA, NULL, NULL); +} + int r535_gsp_oneinit(struct nvkm_gsp *gsp) { @@ -2139,7 +2145,9 @@ r535_gsp_oneinit(struct nvkm_gsp *gsp) r535_gsp_msg_ntfy_add(gsp, NV_VGPU_MSG_EVENT_OS_ERROR_LOG, r535_gsp_msg_os_error_log, gsp); r535_gsp_msg_ntfy_add(gsp, NV_VGPU_MSG_EVENT_PERF_BRIDGELESS_INFO_UPDATE, NULL, NULL); r535_gsp_msg_ntfy_add(gsp, NV_VGPU_MSG_EVENT_UCODE_LIBOS_PRINT, NULL, NULL); - r535_gsp_msg_ntfy_add(gsp, NV_VGPU_MSG_EVENT_GSP_SEND_USER_SHARED_DATA, NULL, NULL); + if (rmapi->gsp->drop_send_user_shared_data) + rmapi->gsp->drop_send_user_shared_data(gsp); + ret = r535_gsp_rm_boot_ctor(gsp); if (ret) return ret; @@ -2169,4 +2177,5 @@ r535_gsp = { .set_system_info = r535_gsp_set_system_info, .get_static_info = r535_gsp_get_static_info, .xlat_mc_engine_idx = r535_gsp_xlat_mc_engine_idx, + .drop_send_user_shared_data = r535_gsp_drop_send_user_shared_data, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h index aecb066982d8..4a27e8bfafcc 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h @@ -30,6 +30,7 @@ struct nvkm_rm_api { int (*set_system_info)(struct nvkm_gsp *); int (*get_static_info)(struct nvkm_gsp *); bool (*xlat_mc_engine_idx)(u32 mc_engine_idx, enum nvkm_subdev_type *, int *inst); + void (*drop_send_user_shared_data)(struct nvkm_gsp *); } *gsp; const struct nvkm_rm_api_rpc { -- 2.49.0
Ben Skeggs
2025-May-17 00:09 UTC
[PATCH v3 26/62] drm/nouveau/gsp: add hal for disp.bl_ctrl()
545.23.06 has incompatible changes to NV0073_CTRL_SPECIFIC_BACKLIGHT_BRIGHTNESS_PARAMS. Signed-off-by: Ben Skeggs <bskeggs at nvidia.com> Reviewed-by: Dave Airlie <airlied at redhat.com> Reviewed-by: Timur Tabi <ttabi at nvidia.com> Tested-by: Timur Tabi <ttabi at nvidia.com> --- .../nouveau/nvkm/subdev/gsp/rm/r535/disp.c | 57 ++++++++++--------- .../drm/nouveau/nvkm/subdev/gsp/rm/r535/rm.c | 1 + .../gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h | 5 ++ 3 files changed, 37 insertions(+), 26 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c index 1ba86e223978..1e9bbfd402d3 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c @@ -252,47 +252,47 @@ r535_core = { }; static int -r535_sor_bl_set(struct nvkm_ior *sor, int lvl) +r535_bl_ctrl(struct nvkm_disp *disp, unsigned display_id, bool set, int *pval) { - struct nvkm_disp *disp = sor->disp; + u32 cmd = set ? NV0073_CTRL_CMD_SPECIFIC_SET_BACKLIGHT_BRIGHTNESS : + NV0073_CTRL_CMD_SPECIFIC_GET_BACKLIGHT_BRIGHTNESS; NV0073_CTRL_SPECIFIC_BACKLIGHT_BRIGHTNESS_PARAMS *ctrl; + int ret; - ctrl = nvkm_gsp_rm_ctrl_get(&disp->rm.objcom, - NV0073_CTRL_CMD_SPECIFIC_SET_BACKLIGHT_BRIGHTNESS, - sizeof(*ctrl)); + ctrl = nvkm_gsp_rm_ctrl_get(&disp->rm.objcom, cmd, sizeof(*ctrl)); if (IS_ERR(ctrl)) return PTR_ERR(ctrl); - ctrl->displayId = BIT(sor->asy.outp->index); - ctrl->brightness = lvl; + ctrl->displayId = BIT(display_id); + ctrl->brightness = *pval; - return nvkm_gsp_rm_ctrl_wr(&disp->rm.objcom, ctrl); + ret = nvkm_gsp_rm_ctrl_push(&disp->rm.objcom, &ctrl, sizeof(*ctrl)); + if (ret) + return ret; + + *pval = ctrl->brightness; + + nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl); + return 0; } static int -r535_sor_bl_get(struct nvkm_ior *sor) +r535_sor_bl_set(struct nvkm_ior *sor, int lvl) { struct nvkm_disp *disp = sor->disp; - NV0073_CTRL_SPECIFIC_BACKLIGHT_BRIGHTNESS_PARAMS *ctrl; - int ret, lvl; - - ctrl = nvkm_gsp_rm_ctrl_get(&disp->rm.objcom, - NV0073_CTRL_CMD_SPECIFIC_GET_BACKLIGHT_BRIGHTNESS, - sizeof(*ctrl)); - if (IS_ERR(ctrl)) - return PTR_ERR(ctrl); + const struct nvkm_rm_api *rmapi = disp->engine.subdev.device->gsp->rm->api; - ctrl->displayId = BIT(sor->asy.outp->index); + return rmapi->disp->bl_ctrl(disp, sor->asy.outp->index, true, &lvl); +} - ret = nvkm_gsp_rm_ctrl_push(&disp->rm.objcom, &ctrl, sizeof(*ctrl)); - if (ret) { - nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl); - return ret; - } +static int +r535_sor_bl_get(struct nvkm_ior *sor) +{ + struct nvkm_disp *disp = sor->disp; + const struct nvkm_rm_api *rmapi = disp->engine.subdev.device->gsp->rm->api; + int lvl, ret = rmapi->disp->bl_ctrl(disp, sor->asy.outp->index, false, &lvl); - lvl = ctrl->brightness; - nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl); - return lvl; + return (ret == 0) ? lvl : ret; } static const struct nvkm_ior_func_bl @@ -1722,3 +1722,8 @@ r535_disp_new(const struct nvkm_disp_func *hw, struct nvkm_device *device, mutex_init(&(*pdisp)->super.mutex); //XXX return ret; } + +const struct nvkm_rm_api_disp +r535_disp = { + .bl_ctrl = r535_bl_ctrl, +}; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rm.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rm.c index efedd387fcc5..9eff944f6c39 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rm.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rm.c @@ -28,6 +28,7 @@ r535_api = { .alloc = &r535_alloc, .client = &r535_client, .device = &r535_device, + .disp = &r535_disp, .ce = &r535_ce, .nvdec = &r535_nvdec, .nvenc = &r535_nvenc, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h index 4a27e8bfafcc..2386e419be62 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h @@ -70,6 +70,10 @@ struct nvkm_rm_api { } event; } *device; + const struct nvkm_rm_api_disp { + int (*bl_ctrl)(struct nvkm_disp *, unsigned display_id, bool set, int *val); + } *disp; + const struct nvkm_rm_api_engine { int (*alloc)(struct nvkm_gsp_object *chan, u32 handle, u32 class, int inst, struct nvkm_gsp_object *); @@ -84,6 +88,7 @@ extern const struct nvkm_rm_api_ctrl r535_ctrl; extern const struct nvkm_rm_api_alloc r535_alloc; extern const struct nvkm_rm_api_client r535_client; extern const struct nvkm_rm_api_device r535_device; +extern const struct nvkm_rm_api_disp r535_disp; extern const struct nvkm_rm_api_engine r535_ce; void *r535_gr_dtor(struct nvkm_gr *); int r535_gr_oneinit(struct nvkm_gr *); -- 2.49.0
Ben Skeggs
2025-May-17 00:09 UTC
[PATCH v3 27/62] drm/nouveau/gsp: add hal for disp.dp.set_indexed_link_rates()
545.23.06 has incompatible changes to NV0073_CTRL_CMD_DP_CONFIG_INDEXED_LINK_RATES. Signed-off-by: Ben Skeggs <bskeggs at nvidia.com> Reviewed-by: Dave Airlie <airlied at redhat.com> Reviewed-by: Timur Tabi <ttabi at nvidia.com> Tested-by: Timur Tabi <ttabi at nvidia.com> --- .../nouveau/nvkm/subdev/gsp/rm/r535/disp.c | 21 ++++++++++++++----- .../gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h | 5 +++++ 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c index 1e9bbfd402d3..9eff06e12fca 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c @@ -1021,15 +1021,11 @@ r535_dp_train(struct nvkm_outp *outp, bool retrain) } static int -r535_dp_rates(struct nvkm_outp *outp) +r535_dp_set_indexed_link_rates(struct nvkm_outp *outp) { NV0073_CTRL_CMD_DP_CONFIG_INDEXED_LINK_RATES_PARAMS *ctrl; struct nvkm_disp *disp = outp->disp; - if (outp->conn->info.type != DCB_CONNECTOR_eDP || - !outp->dp.rates || outp->dp.rate[0].dpcd < 0) - return 0; - if (WARN_ON(outp->dp.rates > ARRAY_SIZE(ctrl->linkRateTbl))) return -EINVAL; @@ -1045,6 +1041,18 @@ r535_dp_rates(struct nvkm_outp *outp) return nvkm_gsp_rm_ctrl_wr(&disp->rm.objcom, ctrl); } +static int +r535_dp_rates(struct nvkm_outp *outp) +{ + struct nvkm_rm *rm = outp->disp->rm.objcom.client->gsp->rm; + + if (outp->conn->info.type != DCB_CONNECTOR_eDP || + !outp->dp.rates || outp->dp.rate[0].dpcd < 0) + return 0; + + return rm->api->disp->dp.set_indexed_link_rates(outp); +} + static int r535_dp_aux_xfer(struct nvkm_outp *outp, u8 type, u32 addr, u8 *data, u8 *psize) { @@ -1726,4 +1734,7 @@ r535_disp_new(const struct nvkm_disp_func *hw, struct nvkm_device *device, const struct nvkm_rm_api_disp r535_disp = { .bl_ctrl = r535_bl_ctrl, + .dp = { + .set_indexed_link_rates = r535_dp_set_indexed_link_rates, + } }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h index 2386e419be62..9df95c5b9961 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h @@ -6,6 +6,7 @@ #ifndef __NVKM_RM_H__ #define __NVKM_RM_H__ #include "handles.h" +struct nvkm_outp; struct nvkm_rm_impl { const struct nvkm_rm_wpr *wpr; @@ -72,6 +73,10 @@ struct nvkm_rm_api { const struct nvkm_rm_api_disp { int (*bl_ctrl)(struct nvkm_disp *, unsigned display_id, bool set, int *val); + + struct { + int (*set_indexed_link_rates)(struct nvkm_outp *); + } dp; } *disp; const struct nvkm_rm_api_engine { -- 2.49.0
Ben Skeggs
2025-May-17 00:09 UTC
[PATCH v3 28/62] drm/nouveau/gsp: add hal for disp.get_static_info()
550.40.07 has incompatible changes to NV2080_CTRL_CMD_INTERNAL_DISPLAY_GET_STATIC_INFO. Signed-off-by: Ben Skeggs <bskeggs at nvidia.com> Reviewed-by: Dave Airlie <airlied at redhat.com> Reviewed-by: Timur Tabi <ttabi at nvidia.com> Tested-by: Timur Tabi <ttabi at nvidia.com> --- .../nouveau/nvkm/subdev/gsp/rm/r535/disp.c | 37 ++++++++++++------- .../gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h | 2 + 2 files changed, 26 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c index 9eff06e12fca..82fc159ec070 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c @@ -1440,11 +1440,31 @@ r535_disp_init(struct nvkm_disp *disp) return 0; } +static int +r535_disp_get_static_info(struct nvkm_disp *disp) +{ + NV2080_CTRL_INTERNAL_DISPLAY_GET_STATIC_INFO_PARAMS *ctrl; + struct nvkm_gsp *gsp = disp->rm.objcom.client->gsp; + + ctrl = nvkm_gsp_rm_ctrl_rd(&gsp->internal.device.subdevice, + NV2080_CTRL_CMD_INTERNAL_DISPLAY_GET_STATIC_INFO, + sizeof(*ctrl)); + if (IS_ERR(ctrl)) + return PTR_ERR(ctrl); + + disp->wndw.mask = ctrl->windowPresentMask; + disp->wndw.nr = fls(disp->wndw.mask); + + nvkm_gsp_rm_ctrl_done(&gsp->internal.device.subdevice, ctrl); + return 0; +} + static int r535_disp_oneinit(struct nvkm_disp *disp) { struct nvkm_device *device = disp->engine.subdev.device; struct nvkm_gsp *gsp = device->gsp; + const struct nvkm_rm_api *rmapi = gsp->rm->api; NV2080_CTRL_INTERNAL_DISPLAY_WRITE_INST_MEM_PARAMS *ctrl; int ret, i; @@ -1481,19 +1501,9 @@ r535_disp_oneinit(struct nvkm_disp *disp) if (ret) return ret; - { - NV2080_CTRL_INTERNAL_DISPLAY_GET_STATIC_INFO_PARAMS *ctrl; - - ctrl = nvkm_gsp_rm_ctrl_rd(&gsp->internal.device.subdevice, - NV2080_CTRL_CMD_INTERNAL_DISPLAY_GET_STATIC_INFO, - sizeof(*ctrl)); - if (IS_ERR(ctrl)) - return PTR_ERR(ctrl); - - disp->wndw.mask = ctrl->windowPresentMask; - disp->wndw.nr = fls(disp->wndw.mask); - nvkm_gsp_rm_ctrl_done(&gsp->internal.device.subdevice, ctrl); - } + ret = rmapi->disp->get_static_info(disp); + if (ret) + return ret; /* */ { @@ -1733,6 +1743,7 @@ r535_disp_new(const struct nvkm_disp_func *hw, struct nvkm_device *device, const struct nvkm_rm_api_disp r535_disp = { + .get_static_info = r535_disp_get_static_info, .bl_ctrl = r535_bl_ctrl, .dp = { .set_indexed_link_rates = r535_dp_set_indexed_link_rates, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h index 9df95c5b9961..b9c775aec58e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h @@ -72,6 +72,8 @@ struct nvkm_rm_api { } *device; const struct nvkm_rm_api_disp { + int (*get_static_info)(struct nvkm_disp *); + int (*bl_ctrl)(struct nvkm_disp *, unsigned display_id, bool set, int *val); struct { -- 2.49.0
Ben Skeggs
2025-May-17 00:09 UTC
[PATCH v3 29/62] drm/nouveau/gsp: add hal for disp.chan.set_pushbuf()
550.40.07 has incompatible changes to NV2080_CTRL_CMD_INTERNAL_DISPLAY_CHANNEL_PUSHBUFFER. Signed-off-by: Ben Skeggs <bskeggs at nvidia.com> Reviewed-by: Dave Airlie <airlied at redhat.com> Reviewed-by: Timur Tabi <ttabi at nvidia.com> Tested-by: Timur Tabi <ttabi at nvidia.com> --- .../nouveau/nvkm/subdev/gsp/rm/r535/disp.c | 27 +++++++++++-------- .../gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h | 5 ++++ 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c index 82fc159ec070..389b2738f711 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c @@ -70,9 +70,9 @@ r535_chan_fini(struct nvkm_disp_chan *chan) } static int -r535_chan_push(struct nvkm_disp_chan *chan) +r535_disp_chan_set_pushbuf(struct nvkm_disp *disp, s32 oclass, int inst, struct nvkm_memory *memory) { - struct nvkm_gsp *gsp = chan->disp->engine.subdev.device->gsp; + struct nvkm_gsp *gsp = disp->rm.objcom.client->gsp; NV2080_CTRL_INTERNAL_DISPLAY_CHANNEL_PUSHBUFFER_PARAMS *ctrl; ctrl = nvkm_gsp_rm_ctrl_get(&gsp->internal.device.subdevice, @@ -81,8 +81,8 @@ r535_chan_push(struct nvkm_disp_chan *chan) if (IS_ERR(ctrl)) return PTR_ERR(ctrl); - if (chan->memory) { - switch (nvkm_memory_target(chan->memory)) { + if (memory) { + switch (nvkm_memory_target(memory)) { case NVKM_MEM_TARGET_NCOH: ctrl->addressSpace = ADDR_SYSMEM; ctrl->cacheSnoop = 0; @@ -99,13 +99,13 @@ r535_chan_push(struct nvkm_disp_chan *chan) return -EINVAL; } - ctrl->physicalAddr = nvkm_memory_addr(chan->memory); - ctrl->limit = nvkm_memory_size(chan->memory) - 1; + ctrl->physicalAddr = nvkm_memory_addr(memory); + ctrl->limit = nvkm_memory_size(memory) - 1; } - ctrl->hclass = chan->object.oclass; - ctrl->channelInstance = chan->head; - ctrl->valid = ((chan->object.oclass & 0xff) != 0x7a) ? 1 : 0; + ctrl->hclass = oclass; + ctrl->channelInstance = inst; + ctrl->valid = ((oclass & 0xff) != 0x7a) ? 1 : 0; return nvkm_gsp_rm_ctrl_wr(&gsp->internal.device.subdevice, ctrl); } @@ -113,10 +113,11 @@ r535_chan_push(struct nvkm_disp_chan *chan) static int r535_curs_init(struct nvkm_disp_chan *chan) { + const struct nvkm_rm_api *rmapi = chan->disp->rm.objcom.client->gsp->rm->api; NV50VAIO_CHANNELPIO_ALLOCATION_PARAMETERS *args; int ret; - ret = r535_chan_push(chan); + ret = rmapi->disp->chan.set_pushbuf(chan->disp, chan->object.oclass, chan->head, NULL); if (ret) return ret; @@ -166,10 +167,11 @@ r535_dmac_fini(struct nvkm_disp_chan *chan) static int r535_dmac_init(struct nvkm_disp_chan *chan) { + const struct nvkm_rm_api *rmapi = chan->disp->rm.objcom.client->gsp->rm->api; NV50VAIO_CHANNELDMA_ALLOCATION_PARAMETERS *args; int ret; - ret = r535_chan_push(chan); + ret = rmapi->disp->chan.set_pushbuf(chan->disp, chan->object.oclass, chan->head, chan->memory); if (ret) return ret; @@ -1747,5 +1749,8 @@ r535_disp = { .bl_ctrl = r535_bl_ctrl, .dp = { .set_indexed_link_rates = r535_dp_set_indexed_link_rates, + }, + .chan = { + .set_pushbuf = r535_disp_chan_set_pushbuf, } }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h index b9c775aec58e..a8f070871d80 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h @@ -79,6 +79,11 @@ struct nvkm_rm_api { struct { int (*set_indexed_link_rates)(struct nvkm_outp *); } dp; + + struct { + int (*set_pushbuf)(struct nvkm_disp *, s32 oclass, int inst, + struct nvkm_memory *); + } chan; } *disp; const struct nvkm_rm_api_engine { -- 2.49.0
Ben Skeggs
2025-May-17 00:09 UTC
[PATCH v3 30/62] drm/nouveau/gsp: add hal for fifo.xlat_rm_engine_type()
550.40.07 has incompatible changes to RM_ENGINE_TYPE defines. Signed-off-by: Ben Skeggs <bskeggs at nvidia.com> Reviewed-by: Dave Airlie <airlied at redhat.com> Reviewed-by: Timur Tabi <ttabi at nvidia.com> Tested-by: Timur Tabi <ttabi at nvidia.com> --- .../nouveau/nvkm/subdev/gsp/rm/r535/fifo.c | 101 +++++++++--------- .../drm/nouveau/nvkm/subdev/gsp/rm/r535/rm.c | 1 + .../gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h | 6 ++ 3 files changed, 56 insertions(+), 52 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/fifo.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/fifo.c index ad9d93f9820d..136a64d82973 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/fifo.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/fifo.c @@ -324,56 +324,52 @@ r535_runl = { }; static int -r535_fifo_2080_type(enum nvkm_subdev_type type, int inst) +r535_fifo_xlat_rm_engine_type(u32 rm, enum nvkm_subdev_type *ptype, int *p2080) { - switch (type) { - case NVKM_ENGINE_GR: return NV2080_ENGINE_TYPE_GR0; - case NVKM_ENGINE_CE: return NV2080_ENGINE_TYPE_COPY0 + inst; - case NVKM_ENGINE_SEC2: return NV2080_ENGINE_TYPE_SEC2; - case NVKM_ENGINE_NVDEC: return NV2080_ENGINE_TYPE_NVDEC0 + inst; - case NVKM_ENGINE_NVENC: return NV2080_ENGINE_TYPE_NVENC0 + inst; - case NVKM_ENGINE_NVJPG: return NV2080_ENGINE_TYPE_NVJPEG0 + inst; - case NVKM_ENGINE_OFA: return NV2080_ENGINE_TYPE_OFA; - case NVKM_ENGINE_SW: return NV2080_ENGINE_TYPE_SW; - default: - break; - } +#define RM_ENGINE_TYPE(RM,NVKM,INST) \ + RM_ENGINE_TYPE_##RM: \ + *ptype = NVKM_ENGINE_##NVKM; \ + *p2080 = NV2080_ENGINE_TYPE_##RM; \ + return INST - WARN_ON(1); - return -EINVAL; -} - -static int -r535_fifo_engn_type(RM_ENGINE_TYPE rm, enum nvkm_subdev_type *ptype) -{ switch (rm) { - case RM_ENGINE_TYPE_GR0: - *ptype = NVKM_ENGINE_GR; - return 0; - case RM_ENGINE_TYPE_COPY0...RM_ENGINE_TYPE_COPY9: - *ptype = NVKM_ENGINE_CE; - return rm - RM_ENGINE_TYPE_COPY0; - case RM_ENGINE_TYPE_NVDEC0...RM_ENGINE_TYPE_NVDEC7: - *ptype = NVKM_ENGINE_NVDEC; - return rm - RM_ENGINE_TYPE_NVDEC0; - case RM_ENGINE_TYPE_NVENC0...RM_ENGINE_TYPE_NVENC2: - *ptype = NVKM_ENGINE_NVENC; - return rm - RM_ENGINE_TYPE_NVENC0; - case RM_ENGINE_TYPE_SW: - *ptype = NVKM_ENGINE_SW; - return 0; - case RM_ENGINE_TYPE_SEC2: - *ptype = NVKM_ENGINE_SEC2; - return 0; - case RM_ENGINE_TYPE_NVJPEG0...RM_ENGINE_TYPE_NVJPEG7: - *ptype = NVKM_ENGINE_NVJPG; - return rm - RM_ENGINE_TYPE_NVJPEG0; - case RM_ENGINE_TYPE_OFA: - *ptype = NVKM_ENGINE_OFA; - return 0; + case RM_ENGINE_TYPE( GR0, GR, 0); + case RM_ENGINE_TYPE( COPY0, CE, 0); + case RM_ENGINE_TYPE( COPY1, CE, 1); + case RM_ENGINE_TYPE( COPY2, CE, 2); + case RM_ENGINE_TYPE( COPY3, CE, 3); + case RM_ENGINE_TYPE( COPY4, CE, 4); + case RM_ENGINE_TYPE( COPY5, CE, 5); + case RM_ENGINE_TYPE( COPY6, CE, 6); + case RM_ENGINE_TYPE( COPY7, CE, 7); + case RM_ENGINE_TYPE( COPY8, CE, 8); + case RM_ENGINE_TYPE( COPY9, CE, 9); + case RM_ENGINE_TYPE( NVDEC0, NVDEC, 0); + case RM_ENGINE_TYPE( NVDEC1, NVDEC, 1); + case RM_ENGINE_TYPE( NVDEC2, NVDEC, 2); + case RM_ENGINE_TYPE( NVDEC3, NVDEC, 3); + case RM_ENGINE_TYPE( NVDEC4, NVDEC, 4); + case RM_ENGINE_TYPE( NVDEC5, NVDEC, 5); + case RM_ENGINE_TYPE( NVDEC6, NVDEC, 6); + case RM_ENGINE_TYPE( NVDEC7, NVDEC, 7); + case RM_ENGINE_TYPE( NVENC0, NVENC, 0); + case RM_ENGINE_TYPE( NVENC1, NVENC, 1); + case RM_ENGINE_TYPE( NVENC2, NVENC, 2); + case RM_ENGINE_TYPE(NVJPEG0, NVJPG, 0); + case RM_ENGINE_TYPE(NVJPEG1, NVJPG, 1); + case RM_ENGINE_TYPE(NVJPEG2, NVJPG, 2); + case RM_ENGINE_TYPE(NVJPEG3, NVJPG, 3); + case RM_ENGINE_TYPE(NVJPEG4, NVJPG, 4); + case RM_ENGINE_TYPE(NVJPEG5, NVJPG, 5); + case RM_ENGINE_TYPE(NVJPEG6, NVJPG, 6); + case RM_ENGINE_TYPE(NVJPEG7, NVJPG, 7); + case RM_ENGINE_TYPE( SW, SW, 0); + case RM_ENGINE_TYPE( SEC2, SEC2, 0); + case RM_ENGINE_TYPE( OFA, OFA, 0); default: return -EINVAL; } +#undef RM_ENGINE_TYPE } static int @@ -410,7 +406,9 @@ static int r535_fifo_runl_ctor(struct nvkm_fifo *fifo) { struct nvkm_subdev *subdev = &fifo->engine.subdev; - struct nvkm_gsp *gsp = subdev->device->gsp; + struct nvkm_device *device = subdev->device; + struct nvkm_gsp *gsp = device->gsp; + struct nvkm_rm *rm = gsp->rm; struct nvkm_runl *runl; struct nvkm_engn *engn; u32 cgids = 2048; @@ -450,19 +448,13 @@ r535_fifo_runl_ctor(struct nvkm_fifo *fifo) if (!runl) continue; - inst = r535_fifo_engn_type(rmid, &type); + inst = rm->api->fifo->xlat_rm_engine_type(rmid, &type, &nv2080); if (inst < 0) { nvkm_warn(subdev, "RM_ENGINE_TYPE 0x%x\n", rmid); nvkm_runl_del(runl); continue; } - nv2080 = r535_fifo_2080_type(type, inst); - if (nv2080 < 0) { - nvkm_runl_del(runl); - continue; - } - ret = nvkm_rm_engine_new(gsp->rm, type, inst); if (ret) { nvkm_runl_del(runl); @@ -544,3 +536,8 @@ r535_fifo_new(const struct nvkm_fifo_func *hw, struct nvkm_device *device, return nvkm_fifo_new_(rm, device, type, inst, pfifo); } + +const struct nvkm_rm_api_fifo +r535_fifo = { + .xlat_rm_engine_type = r535_fifo_xlat_rm_engine_type, +}; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rm.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rm.c index 9eff944f6c39..8d41df85fb19 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rm.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rm.c @@ -29,6 +29,7 @@ r535_api = { .client = &r535_client, .device = &r535_device, .disp = &r535_disp, + .fifo = &r535_fifo, .ce = &r535_ce, .nvdec = &r535_nvdec, .nvenc = &r535_nvenc, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h index a8f070871d80..23a9a2043d9c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h @@ -86,6 +86,11 @@ struct nvkm_rm_api { } chan; } *disp; + const struct nvkm_rm_api_fifo { + int (*xlat_rm_engine_type)(u32 rm_engine_type, + enum nvkm_subdev_type *, int *nv2080_type); + } *fifo; + const struct nvkm_rm_api_engine { int (*alloc)(struct nvkm_gsp_object *chan, u32 handle, u32 class, int inst, struct nvkm_gsp_object *); @@ -101,6 +106,7 @@ extern const struct nvkm_rm_api_alloc r535_alloc; extern const struct nvkm_rm_api_client r535_client; extern const struct nvkm_rm_api_device r535_device; extern const struct nvkm_rm_api_disp r535_disp; +extern const struct nvkm_rm_api_fifo r535_fifo; extern const struct nvkm_rm_api_engine r535_ce; void *r535_gr_dtor(struct nvkm_gr *); int r535_gr_oneinit(struct nvkm_gr *); -- 2.49.0
Ben Skeggs
2025-May-17 00:09 UTC
[PATCH v3 31/62] drm/nouveau/gsp: add hal for fifo.ectx_size()
NV2080_CTRL_CMD_INTERNAL_GET_CONSTRUCTED_FALCON_INFO is moved to NV2080_CTRL_CMD_GPU_GET_CONSTRUCTED_FALCON_INFO in 550.40.07. Signed-off-by: Ben Skeggs <bskeggs at nvidia.com> Reviewed-by: Dave Airlie <airlied at redhat.com> Reviewed-by: Timur Tabi <ttabi at nvidia.com> Tested-by: Timur Tabi <ttabi at nvidia.com> --- drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/fifo.c | 3 ++- drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/fifo.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/fifo.c index 136a64d82973..55022ad67208 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/fifo.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/fifo.c @@ -507,7 +507,7 @@ r535_fifo_runl_ctor(struct nvkm_fifo *fifo) nvkm_gsp_rm_ctrl_done(&gsp->internal.device.subdevice, ctrl); } - return r535_fifo_ectx_size(fifo); + return rm->api->fifo->ectx_size(fifo); } static void @@ -540,4 +540,5 @@ r535_fifo_new(const struct nvkm_fifo_func *hw, struct nvkm_device *device, const struct nvkm_rm_api_fifo r535_fifo = { .xlat_rm_engine_type = r535_fifo_xlat_rm_engine_type, + .ectx_size = r535_fifo_ectx_size, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h index 23a9a2043d9c..8783c21af0e7 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h @@ -89,6 +89,7 @@ struct nvkm_rm_api { const struct nvkm_rm_api_fifo { int (*xlat_rm_engine_type)(u32 rm_engine_type, enum nvkm_subdev_type *, int *nv2080_type); + int (*ectx_size)(struct nvkm_fifo *); } *fifo; const struct nvkm_rm_api_engine { -- 2.49.0
Ben Skeggs
2025-May-17 00:09 UTC
[PATCH v3 32/62] drm/nouveau/gsp: add hal for gr.get_ctxbufs_info()
NV2080_CTRL_CMD_INTERNAL_STATIC_KGR_GET_CONTEXT_BUFFERS_INFO has incompatible changes in 550.40.07. Signed-off-by: Ben Skeggs <bskeggs at nvidia.com> Reviewed-by: Dave Airlie <airlied at redhat.com> Reviewed-by: Timur Tabi <ttabi at nvidia.com> Tested-by: Timur Tabi <ttabi at nvidia.com> --- .../nouveau/nvkm/subdev/gsp/rm/r535/fifo.c | 4 +- .../drm/nouveau/nvkm/subdev/gsp/rm/r535/gr.c | 186 ++++++++++-------- .../drm/nouveau/nvkm/subdev/gsp/rm/r535/rm.c | 1 + .../gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h | 7 + 4 files changed, 114 insertions(+), 84 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/fifo.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/fifo.c index 55022ad67208..58a47c62690a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/fifo.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/fifo.c @@ -250,7 +250,7 @@ r535_gr_ctor(struct nvkm_engn *engn, struct nvkm_vctx *vctx, struct nvkm_chan *c } static const struct nvkm_engn_func -r535_gr = { +r535_engn_gr = { .nonstall = r535_engn_nonstall, .ctor2 = r535_gr_ctor, }; @@ -468,7 +468,7 @@ r535_fifo_runl_ctor(struct nvkm_fifo *fifo) engn = nvkm_runl_add(runl, nv2080, &r535_engn_ce, type, inst); break; case NVKM_ENGINE_GR: - engn = nvkm_runl_add(runl, nv2080, &r535_gr, type, inst); + engn = nvkm_runl_add(runl, nv2080, &r535_engn_gr, type, inst); break; case NVKM_ENGINE_NVDEC: case NVKM_ENGINE_NVENC: diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gr.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gr.c index 4c0df52e8683..e0fa88aa608f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gr.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gr.c @@ -170,10 +170,106 @@ r535_gr_units(struct nvkm_gr *gr) return (gsp->gr.tpcs << 8) | gsp->gr.gpcs; } +static void +r535_gr_get_ctxbuf_info(struct r535_gr *gr, int i, + struct NV2080_CTRL_INTERNAL_ENGINE_CONTEXT_BUFFER_INFO *info) +{ + struct nvkm_subdev *subdev = &gr->base.engine.subdev; + static const struct { + u32 id0; /* NV0080_CTRL_FIFO_GET_ENGINE_CONTEXT_PROPERTIES_ENGINE_ID */ + u32 id1; /* NV2080_CTRL_GPU_PROMOTE_CTX_BUFFER_ID */ + bool global; + bool init; + bool ro; + } map[] = { +#define _A(n,N,G,I,R) { .id0 = NV0080_CTRL_FIFO_GET_ENGINE_CONTEXT_PROPERTIES_ENGINE_ID_##n, \ + .id1 = NV2080_CTRL_GPU_PROMOTE_CTX_BUFFER_ID_##N, \ + .global = (G), .init = (I), .ro = (R) } +#define _B(N,G,I,R) _A(GRAPHICS_##N, N, (G), (I), (R)) + /* global init ro */ + _A( GRAPHICS, MAIN, false, true, false), + _B( PATCH, false, true, false), + _A( GRAPHICS_BUNDLE_CB, BUFFER_BUNDLE_CB, true, false, false), + _B( PAGEPOOL, true, false, false), + _B( ATTRIBUTE_CB, true, false, false), + _B( RTV_CB_GLOBAL, true, false, false), + _B( FECS_EVENT, true, true, false), + _B( PRIV_ACCESS_MAP, true, true, true), +#undef _B +#undef _A + }; + u32 size = info->size; + u8 align, page; + int id; + + for (id = 0; id < ARRAY_SIZE(map); id++) { + if (map[id].id0 == i) + break; + } + + nvkm_debug(subdev, "%02x: size:0x%08x %s\n", i, + size, (id < ARRAY_SIZE(map)) ? "*" : ""); + if (id >= ARRAY_SIZE(map)) + return; + + if (map[id].id1 == NV2080_CTRL_GPU_PROMOTE_CTX_BUFFER_ID_MAIN) + size = ALIGN(size, 0x1000) + 64 * 0x1000; /* per-subctx headers */ + + if (size >= 1 << 21) page = 21; + else if (size >= 1 << 16) page = 16; + else page = 12; + + if (map[id].id1 == NV2080_CTRL_GPU_PROMOTE_CTX_BUFFER_ID_ATTRIBUTE_CB) + align = order_base_2(size); + else + align = page; + + if (WARN_ON(gr->ctxbuf_nr == ARRAY_SIZE(gr->ctxbuf))) + return; + + gr->ctxbuf[gr->ctxbuf_nr].bufferId = map[id].id1; + gr->ctxbuf[gr->ctxbuf_nr].size = size; + gr->ctxbuf[gr->ctxbuf_nr].page = page; + gr->ctxbuf[gr->ctxbuf_nr].align = align; + gr->ctxbuf[gr->ctxbuf_nr].global = map[id].global; + gr->ctxbuf[gr->ctxbuf_nr].init = map[id].init; + gr->ctxbuf[gr->ctxbuf_nr].ro = map[id].ro; + gr->ctxbuf_nr++; + + if (map[id].id1 == NV2080_CTRL_GPU_PROMOTE_CTX_BUFFER_ID_PRIV_ACCESS_MAP) { + if (WARN_ON(gr->ctxbuf_nr == ARRAY_SIZE(gr->ctxbuf))) + return; + + gr->ctxbuf[gr->ctxbuf_nr] = gr->ctxbuf[gr->ctxbuf_nr - 1]; + gr->ctxbuf[gr->ctxbuf_nr].bufferId + NV2080_CTRL_GPU_PROMOTE_CTX_BUFFER_ID_UNRESTRICTED_PRIV_ACCESS_MAP; + gr->ctxbuf_nr++; + } +} + +static int +r535_gr_get_ctxbufs_info(struct r535_gr *gr) +{ + NV2080_CTRL_INTERNAL_STATIC_GR_GET_CONTEXT_BUFFERS_INFO_PARAMS *info; + struct nvkm_subdev *subdev = &gr->base.engine.subdev; + struct nvkm_gsp *gsp = subdev->device->gsp; + + info = nvkm_gsp_rm_ctrl_rd(&gsp->internal.device.subdevice, + NV2080_CTRL_CMD_INTERNAL_STATIC_KGR_GET_CONTEXT_BUFFERS_INFO, + sizeof(*info)); + if (WARN_ON(IS_ERR(info))) + return PTR_ERR(info); + + for (int i = 0; i < ARRAY_SIZE(info->engineContextBuffersInfo[0].engine); i++) + r535_gr_get_ctxbuf_info(gr, i, &info->engineContextBuffersInfo[0].engine[i]); + + nvkm_gsp_rm_ctrl_done(&gsp->internal.device.subdevice, info); + return 0; +} + int r535_gr_oneinit(struct nvkm_gr *base) { - NV2080_CTRL_INTERNAL_STATIC_GR_GET_CONTEXT_BUFFERS_INFO_PARAMS *info; struct r535_gr *gr = container_of(base, typeof(*gr), base); struct nvkm_subdev *subdev = &gr->base.engine.subdev; struct nvkm_device *device = subdev->device; @@ -269,88 +365,9 @@ r535_gr_oneinit(struct nvkm_gr *base) * * Also build the information that'll be used to create channel contexts. */ - info = nvkm_gsp_rm_ctrl_rd(&gsp->internal.device.subdevice, - NV2080_CTRL_CMD_INTERNAL_STATIC_KGR_GET_CONTEXT_BUFFERS_INFO, - sizeof(*info)); - if (WARN_ON(IS_ERR(info))) { - ret = PTR_ERR(info); + ret = gsp->rm->api->gr->get_ctxbufs_info(gr); + if (ret) goto done; - } - - for (int i = 0; i < ARRAY_SIZE(info->engineContextBuffersInfo[0].engine); i++) { - static const struct { - u32 id0; /* NV0080_CTRL_FIFO_GET_ENGINE_CONTEXT_PROPERTIES_ENGINE_ID */ - u32 id1; /* NV2080_CTRL_GPU_PROMOTE_CTX_BUFFER_ID */ - bool global; - bool init; - bool ro; - } map[] = { -#define _A(n,N,G,I,R) { .id0 = NV0080_CTRL_FIFO_GET_ENGINE_CONTEXT_PROPERTIES_ENGINE_ID_##n, \ - .id1 = NV2080_CTRL_GPU_PROMOTE_CTX_BUFFER_ID_##N, \ - .global = (G), .init = (I), .ro = (R) } -#define _B(N,G,I,R) _A(GRAPHICS_##N, N, (G), (I), (R)) - /* global init ro */ - _A( GRAPHICS, MAIN, false, true, false), - _B( PATCH, false, true, false), - _A( GRAPHICS_BUNDLE_CB, BUFFER_BUNDLE_CB, true, false, false), - _B( PAGEPOOL, true, false, false), - _B( ATTRIBUTE_CB, true, false, false), - _B( RTV_CB_GLOBAL, true, false, false), - _B( FECS_EVENT, true, true, false), - _B( PRIV_ACCESS_MAP, true, true, true), -#undef _B -#undef _A - }; - u32 size = info->engineContextBuffersInfo[0].engine[i].size; - u8 align, page; - int id; - - for (id = 0; id < ARRAY_SIZE(map); id++) { - if (map[id].id0 == i) - break; - } - - nvkm_debug(subdev, "%02x: size:0x%08x %s\n", i, - size, (id < ARRAY_SIZE(map)) ? "*" : ""); - if (id >= ARRAY_SIZE(map)) - continue; - - if (map[id].id1 == NV2080_CTRL_GPU_PROMOTE_CTX_BUFFER_ID_MAIN) - size = ALIGN(size, 0x1000) + 64 * 0x1000; /* per-subctx headers */ - - if (size >= 1 << 21) page = 21; - else if (size >= 1 << 16) page = 16; - else page = 12; - - if (map[id].id1 == NV2080_CTRL_GPU_PROMOTE_CTX_BUFFER_ID_ATTRIBUTE_CB) - align = order_base_2(size); - else - align = page; - - if (WARN_ON(gr->ctxbuf_nr == ARRAY_SIZE(gr->ctxbuf))) - continue; - - gr->ctxbuf[gr->ctxbuf_nr].bufferId = map[id].id1; - gr->ctxbuf[gr->ctxbuf_nr].size = size; - gr->ctxbuf[gr->ctxbuf_nr].page = page; - gr->ctxbuf[gr->ctxbuf_nr].align = align; - gr->ctxbuf[gr->ctxbuf_nr].global = map[id].global; - gr->ctxbuf[gr->ctxbuf_nr].init = map[id].init; - gr->ctxbuf[gr->ctxbuf_nr].ro = map[id].ro; - gr->ctxbuf_nr++; - - if (map[id].id1 == NV2080_CTRL_GPU_PROMOTE_CTX_BUFFER_ID_PRIV_ACCESS_MAP) { - if (WARN_ON(gr->ctxbuf_nr == ARRAY_SIZE(gr->ctxbuf))) - continue; - - gr->ctxbuf[gr->ctxbuf_nr] = gr->ctxbuf[gr->ctxbuf_nr - 1]; - gr->ctxbuf[gr->ctxbuf_nr].bufferId - NV2080_CTRL_GPU_PROMOTE_CTX_BUFFER_ID_UNRESTRICTED_PRIV_ACCESS_MAP; - gr->ctxbuf_nr++; - } - } - - nvkm_gsp_rm_ctrl_done(&gsp->internal.device.subdevice, info); /* Promote golden context to RM. */ ret = r535_gr_promote_ctx(gr, true, golden.vmm, gr->ctxbuf_mem, golden.vma, &golden.chan); @@ -385,3 +402,8 @@ r535_gr_dtor(struct nvkm_gr *base) kfree(gr->base.func); return gr; } + +const struct nvkm_rm_api_gr +r535_gr = { + .get_ctxbufs_info = r535_gr_get_ctxbufs_info, +}; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rm.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rm.c index 8d41df85fb19..43cf44bf3abb 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rm.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rm.c @@ -31,6 +31,7 @@ r535_api = { .disp = &r535_disp, .fifo = &r535_fifo, .ce = &r535_ce, + .gr = &r535_gr, .nvdec = &r535_nvdec, .nvenc = &r535_nvenc, .nvjpg = &r535_nvjpg, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h index 8783c21af0e7..f085e25e4e08 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h @@ -7,6 +7,7 @@ #define __NVKM_RM_H__ #include "handles.h" struct nvkm_outp; +struct r535_gr; struct nvkm_rm_impl { const struct nvkm_rm_wpr *wpr; @@ -96,6 +97,11 @@ struct nvkm_rm_api { int (*alloc)(struct nvkm_gsp_object *chan, u32 handle, u32 class, int inst, struct nvkm_gsp_object *); } *ce, *nvdec, *nvenc, *nvjpg, *ofa; + + const struct nvkm_rm_api_gr { + int (*get_ctxbufs_info)(struct r535_gr *); + } *gr; + }; extern const struct nvkm_rm_impl r535_rm_tu102; @@ -109,6 +115,7 @@ extern const struct nvkm_rm_api_device r535_device; extern const struct nvkm_rm_api_disp r535_disp; extern const struct nvkm_rm_api_fifo r535_fifo; extern const struct nvkm_rm_api_engine r535_ce; +extern const struct nvkm_rm_api_gr r535_gr; void *r535_gr_dtor(struct nvkm_gr *); int r535_gr_oneinit(struct nvkm_gr *); u64 r535_gr_units(struct nvkm_gr *); -- 2.49.0
Ben Skeggs
2025-May-17 00:09 UTC
[PATCH v3 33/62] drm/nouveau/gsp: add hal for gsp.set_rmargs()
555.42.02 has incompatible changes to GSP_ARGUMENTS_CACHED. Signed-off-by: Ben Skeggs <bskeggs at nvidia.com> Reviewed-by: Dave Airlie <airlied at redhat.com> Reviewed-by: Timur Tabi <ttabi at nvidia.com> Tested-by: Timur Tabi <ttabi at nvidia.com> --- .../gpu/drm/nouveau/nvkm/subdev/gsp/priv.h | 1 - .../drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c | 36 +++++++++++-------- .../gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h | 1 + .../gpu/drm/nouveau/nvkm/subdev/gsp/tu102.c | 2 +- 4 files changed, 23 insertions(+), 17 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/priv.h index d42ae235d2f4..c8429863b642 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/priv.h @@ -71,7 +71,6 @@ void r535_gsp_dtor(struct nvkm_gsp *); int r535_gsp_oneinit(struct nvkm_gsp *); int r535_gsp_init(struct nvkm_gsp *); int r535_gsp_fini(struct nvkm_gsp *, bool suspend); -int r535_gsp_rmargs_init(struct nvkm_gsp *gsp, bool resume); int nvkm_gsp_new_(const struct nvkm_gsp_fwif *, struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_gsp **); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c index f7cc8e03d999..0c05a0448766 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c @@ -1196,23 +1196,11 @@ r535_gsp_shared_init(struct nvkm_gsp *gsp) return 0; } -int -r535_gsp_rmargs_init(struct nvkm_gsp *gsp, bool resume) +static void +r535_gsp_set_rmargs(struct nvkm_gsp *gsp, bool resume) { - GSP_ARGUMENTS_CACHED *args; - int ret; + GSP_ARGUMENTS_CACHED *args = gsp->rmargs.data; - if (!resume) { - ret = r535_gsp_shared_init(gsp); - if (ret) - return ret; - - ret = nvkm_gsp_mem_ctor(gsp, 0x1000, &gsp->rmargs); - if (ret) - return ret; - } - - args = gsp->rmargs.data; args->messageQueueInitArguments.sharedMemPhysAddr = gsp->shm.mem.addr; args->messageQueueInitArguments.pageTableEntryCount = gsp->shm.ptes.nr; args->messageQueueInitArguments.cmdQueueOffset @@ -1229,7 +1217,24 @@ r535_gsp_rmargs_init(struct nvkm_gsp *gsp, bool resume) args->srInitArguments.flags = 0; args->srInitArguments.bInPMTransition = 1; } +} + +static int +r535_gsp_rmargs_init(struct nvkm_gsp *gsp, bool resume) +{ + int ret; + + if (!resume) { + ret = r535_gsp_shared_init(gsp); + if (ret) + return ret; + + ret = nvkm_gsp_mem_ctor(gsp, 0x1000, &gsp->rmargs); + if (ret) + return ret; + } + gsp->rm->api->gsp->set_rmargs(gsp, resume); return 0; } @@ -2174,6 +2179,7 @@ r535_gsp_oneinit(struct nvkm_gsp *gsp) const struct nvkm_rm_api_gsp r535_gsp = { + .set_rmargs = r535_gsp_set_rmargs, .set_system_info = r535_gsp_set_system_info, .get_static_info = r535_gsp_get_static_info, .xlat_mc_engine_idx = r535_gsp_xlat_mc_engine_idx, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h index f085e25e4e08..3d677e5bdd2c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h @@ -29,6 +29,7 @@ struct nvkm_rm_wpr { struct nvkm_rm_api { const struct nvkm_rm_api_gsp { + void (*set_rmargs)(struct nvkm_gsp *, bool resume); int (*set_system_info)(struct nvkm_gsp *); int (*get_static_info)(struct nvkm_gsp *); bool (*xlat_mc_engine_idx)(u32 mc_engine_idx, enum nvkm_subdev_type *, int *inst); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/tu102.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/tu102.c index a07f59e5ef7a..b080a8da1caf 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/tu102.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/tu102.c @@ -183,7 +183,7 @@ tu102_gsp_init(struct nvkm_gsp *gsp) mbox0 = lower_32_bits(gsp->wpr_meta.addr); mbox1 = upper_32_bits(gsp->wpr_meta.addr); } else { - r535_gsp_rmargs_init(gsp, true); + gsp->rm->api->gsp->set_rmargs(gsp, true); mbox0 = lower_32_bits(gsp->sr.meta.addr); mbox1 = upper_32_bits(gsp->sr.meta.addr); -- 2.49.0
Ben Skeggs
2025-May-17 00:09 UTC
[PATCH v3 34/62] drm/nouveau/gsp: add hals for fbsr.suspend/resume()
555.42.02 has incompatible changes to FBSR. At the same time, move the calling of FBSR functions from the instmem subdev's suspend/resume paths, to GSP's. This is needed to fix ordering issues that arise from changes to FBSR in newer RM versions. Signed-off-by: Ben Skeggs <bskeggs at nvidia.com> Reviewed-by: Dave Airlie <airlied at redhat.com> Reviewed-by: Timur Tabi <ttabi at nvidia.com> Tested-by: Timur Tabi <ttabi at nvidia.com> --- .../gpu/drm/nouveau/include/nvkm/subdev/gsp.h | 1 + .../drm/nouveau/include/nvkm/subdev/instmem.h | 5 ---- .../nouveau/nvkm/subdev/gsp/rm/r535/fbsr.c | 29 +++++++++---------- .../drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c | 11 +++++++ .../drm/nouveau/nvkm/subdev/gsp/rm/r535/rm.c | 1 + .../gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h | 6 ++++ .../drm/nouveau/nvkm/subdev/instmem/base.c | 8 +++-- 7 files changed, 38 insertions(+), 23 deletions(-) diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h index ef781c4ca11f..40e1b5300dff 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h @@ -133,6 +133,7 @@ struct nvkm_gsp { struct sg_table sgt; struct nvkm_gsp_radix3 radix3; struct nvkm_gsp_mem meta; + struct sg_table fbsr; } sr; struct { diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/instmem.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/instmem.h index e10cbd9203ec..7d93c742ee59 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/instmem.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/instmem.h @@ -24,11 +24,6 @@ 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); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/fbsr.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/fbsr.c index b2f22bd93f4e..0e436c4fb4e0 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/fbsr.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/fbsr.c @@ -201,21 +201,18 @@ fbsr_inst(struct fbsr *fbsr, const char *type, struct nvkm_memory *memory) } static void -r535_instmem_resume(struct nvkm_instmem *imem) +r535_fbsr_resume(struct nvkm_gsp *gsp) { /* RM has restored VRAM contents already, so just need to free the sysmem buffer. */ - if (imem->rm.fbsr_valid) { - nvkm_gsp_sg_free(imem->subdev.device, &imem->rm.fbsr); - imem->rm.fbsr_valid = false; - } + nvkm_gsp_sg_free(gsp->subdev.device, &gsp->sr.fbsr); } static int -r535_instmem_suspend(struct nvkm_instmem *imem) +r535_fbsr_suspend(struct nvkm_gsp *gsp) { - struct nvkm_subdev *subdev = &imem->subdev; + struct nvkm_subdev *subdev = &gsp->subdev; struct nvkm_device *device = subdev->device; - struct nvkm_gsp *gsp = device->gsp; + struct nvkm_instmem *imem = device->imem; struct nvkm_instobj *iobj; struct fbsr fbsr = {}; struct fbsr_item *item, *temp; @@ -256,7 +253,7 @@ r535_instmem_suspend(struct nvkm_instmem *imem) fbsr.size += gsp->fb.bios.vga_workspace.size; nvkm_debug(subdev, "fbsr: size: 0x%llx bytes\n", fbsr.size); - ret = nvkm_gsp_sg(gsp->subdev.device, fbsr.size, &imem->rm.fbsr); + ret = nvkm_gsp_sg(gsp->subdev.device, fbsr.size, &gsp->sr.fbsr); if (ret) goto done; @@ -265,7 +262,7 @@ r535_instmem_suspend(struct nvkm_instmem *imem) if (ret) goto done_sgt; - ret = fbsr_init(&fbsr, &imem->rm.fbsr, items_size); + ret = fbsr_init(&fbsr, &gsp->sr.fbsr, items_size); if (WARN_ON(ret)) goto done_sgt; @@ -276,12 +273,10 @@ r535_instmem_suspend(struct nvkm_instmem *imem) goto done_sgt; } - imem->rm.fbsr_valid = true; - /* Cleanup everything except the sysmem backup, which will be removed after resume. */ done_sgt: if (ret) /* ... unless we failed already. */ - nvkm_gsp_sg_free(device, &imem->rm.fbsr); + nvkm_gsp_sg_free(device, &gsp->sr.fbsr); done: list_for_each_entry_safe(item, temp, &fbsr.items, head) { list_del(&item->head); @@ -293,6 +288,12 @@ r535_instmem_suspend(struct nvkm_instmem *imem) return ret; } +const struct nvkm_rm_api_fbsr +r535_fbsr = { + .suspend = r535_fbsr_suspend, + .resume = r535_fbsr_resume, +}; + static void * r535_instmem_dtor(struct nvkm_instmem *imem) { @@ -313,8 +314,6 @@ r535_instmem_new(const struct nvkm_instmem_func *hw, rm->dtor = r535_instmem_dtor; rm->fini = hw->fini; - rm->suspend = r535_instmem_suspend; - rm->resume = r535_instmem_resume; rm->memory_new = hw->memory_new; rm->memory_wrap = hw->memory_wrap; rm->zero = false; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c index 0c05a0448766..64e9ecf93441 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c @@ -1730,6 +1730,7 @@ nvkm_gsp_radix3_sg(struct nvkm_gsp *gsp, struct sg_table *sgt, u64 size, int r535_gsp_fini(struct nvkm_gsp *gsp, bool suspend) { + struct nvkm_rm *rm = gsp->rm; int ret; if (suspend) { @@ -1754,6 +1755,14 @@ r535_gsp_fini(struct nvkm_gsp *gsp, bool suspend) sr->revision = GSP_FW_SR_META_REVISION; sr->sysmemAddrOfSuspendResumeData = gsp->sr.radix3.lvl0.addr; sr->sizeOfSuspendResumeData = len; + + ret = rm->api->fbsr->suspend(gsp); + if (ret) { + nvkm_gsp_mem_dtor(&gsp->sr.meta); + nvkm_gsp_radix3_dtor(gsp, &gsp->sr.radix3); + nvkm_gsp_sg_free(gsp->subdev.device, &gsp->sr.sgt); + return ret; + } } ret = r535_gsp_rpc_unloading_guest_driver(gsp, suspend); @@ -1787,6 +1796,8 @@ r535_gsp_init(struct nvkm_gsp *gsp) done: if (gsp->sr.meta.data) { + gsp->rm->api->fbsr->resume(gsp); + nvkm_gsp_mem_dtor(&gsp->sr.meta); nvkm_gsp_radix3_dtor(gsp, &gsp->sr.radix3); nvkm_gsp_sg_free(gsp->subdev.device, &gsp->sr.sgt); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rm.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rm.c index 43cf44bf3abb..a4190676e1ad 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rm.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rm.c @@ -28,6 +28,7 @@ r535_api = { .alloc = &r535_alloc, .client = &r535_client, .device = &r535_device, + .fbsr = &r535_fbsr, .disp = &r535_disp, .fifo = &r535_fifo, .ce = &r535_ce, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h index 3d677e5bdd2c..ce04ed9e3c27 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h @@ -73,6 +73,11 @@ struct nvkm_rm_api { } event; } *device; + const struct nvkm_rm_api_fbsr { + int (*suspend)(struct nvkm_gsp *); + void (*resume)(struct nvkm_gsp *); + } *fbsr; + const struct nvkm_rm_api_disp { int (*get_static_info)(struct nvkm_disp *); @@ -113,6 +118,7 @@ extern const struct nvkm_rm_api_ctrl r535_ctrl; extern const struct nvkm_rm_api_alloc r535_alloc; extern const struct nvkm_rm_api_client r535_client; extern const struct nvkm_rm_api_device r535_device; +extern const struct nvkm_rm_api_fbsr r535_fbsr; extern const struct nvkm_rm_api_disp r535_disp; extern const struct nvkm_rm_api_fifo r535_fifo; extern const struct nvkm_rm_api_engine r535_ce; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c index a2cd3330efc6..2f55bab8e132 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c @@ -182,9 +182,11 @@ nvkm_instmem_fini(struct nvkm_subdev *subdev, bool suspend) int ret; if (suspend) { - ret = imem->func->suspend(imem); - if (ret) - return ret; + if (imem->func->suspend) { + ret = imem->func->suspend(imem); + if (ret) + return ret; + } imem->suspend = true; } -- 2.49.0
Ben Skeggs
2025-May-17 00:09 UTC
[PATCH v3 35/62] drm/nouveau/gsp: add hal for disp.get_supported()
555.42.02 has incompatible changes to NV0073_CTRL_CMD_SYSTEM_GET_SUPPORTED. Signed-off-by: Ben Skeggs <bskeggs at nvidia.com> Reviewed-by: Dave Airlie <airlied at redhat.com> Reviewed-by: Timur Tabi <ttabi at nvidia.com> Tested-by: Timur Tabi <ttabi at nvidia.com> --- .../nouveau/nvkm/subdev/gsp/rm/r535/disp.c | 42 +++++++++++-------- .../gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h | 1 + 2 files changed, 25 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c index 389b2738f711..40c50d9fca0b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c @@ -1442,6 +1442,21 @@ r535_disp_init(struct nvkm_disp *disp) return 0; } +static int +r535_disp_get_supported(struct nvkm_disp *disp, unsigned long *pmask) +{ + NV0073_CTRL_SYSTEM_GET_SUPPORTED_PARAMS *ctrl; + + ctrl = nvkm_gsp_rm_ctrl_rd(&disp->rm.objcom, + NV0073_CTRL_CMD_SYSTEM_GET_SUPPORTED, sizeof(*ctrl)); + if (IS_ERR(ctrl)) + return PTR_ERR(ctrl); + + *pmask = ctrl->displayMask; + nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl); + return 0; +} + static int r535_disp_get_static_info(struct nvkm_disp *disp) { @@ -1468,6 +1483,7 @@ r535_disp_oneinit(struct nvkm_disp *disp) struct nvkm_gsp *gsp = device->gsp; const struct nvkm_rm_api *rmapi = gsp->rm->api; NV2080_CTRL_INTERNAL_DISPLAY_WRITE_INST_MEM_PARAMS *ctrl; + unsigned long mask; int ret, i; /* RAMIN. */ @@ -1634,25 +1650,14 @@ r535_disp_oneinit(struct nvkm_disp *disp) return ret; } - /* */ - { - NV0073_CTRL_SYSTEM_GET_SUPPORTED_PARAMS *ctrl; - unsigned long mask; - int i; - - ctrl = nvkm_gsp_rm_ctrl_rd(&disp->rm.objcom, - NV0073_CTRL_CMD_SYSTEM_GET_SUPPORTED, sizeof(*ctrl)); - if (IS_ERR(ctrl)) - return PTR_ERR(ctrl); - - mask = ctrl->displayMask; - nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl); + ret = rmapi->disp->get_supported(disp, &mask); + if (ret) + return ret; - for_each_set_bit(i, &mask, 32) { - ret = r535_outp_new(disp, i); - if (ret) - return ret; - } + for_each_set_bit(i, &mask, 32) { + ret = r535_outp_new(disp, i); + if (ret) + return ret; } ret = nvkm_event_init(&r535_disp_event, &gsp->subdev, 3, 32, &disp->rm.event); @@ -1746,6 +1751,7 @@ r535_disp_new(const struct nvkm_disp_func *hw, struct nvkm_device *device, const struct nvkm_rm_api_disp r535_disp = { .get_static_info = r535_disp_get_static_info, + .get_supported = r535_disp_get_supported, .bl_ctrl = r535_bl_ctrl, .dp = { .set_indexed_link_rates = r535_dp_set_indexed_link_rates, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h index ce04ed9e3c27..3f0cb6790f00 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h @@ -80,6 +80,7 @@ struct nvkm_rm_api { const struct nvkm_rm_api_disp { int (*get_static_info)(struct nvkm_disp *); + int (*get_supported)(struct nvkm_disp *, unsigned long *display_mask); int (*bl_ctrl)(struct nvkm_disp *, unsigned display_id, bool set, int *val); -- 2.49.0
Ben Skeggs
2025-May-17 00:09 UTC
[PATCH v3 36/62] drm/nouveau/gsp: add hal for disp.get_connect_state()
555.42.02 has incompatible changes to NV0073_CTRL_CMD_SYSTEM_GET_CONNECT_STATE. Signed-off-by: Ben Skeggs <bskeggs at nvidia.com> Reviewed-by: Dave Airlie <airlied at redhat.com> Reviewed-by: Timur Tabi <ttabi at nvidia.com> Tested-by: Timur Tabi <ttabi at nvidia.com> --- .../nouveau/nvkm/subdev/gsp/rm/r535/disp.c | 28 +++++++++++-------- .../gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h | 1 + 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c index 40c50d9fca0b..4df5b2b72d29 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c @@ -852,10 +852,9 @@ r535_outp_dfp_get_info(struct nvkm_outp *outp) } static int -r535_outp_detect(struct nvkm_outp *outp) +r535_disp_get_connect_state(struct nvkm_disp *disp, unsigned display_id) { NV0073_CTRL_SYSTEM_GET_CONNECT_STATE_PARAMS *ctrl; - struct nvkm_disp *disp = outp->disp; int ret; ctrl = nvkm_gsp_rm_ctrl_get(&disp->rm.objcom, @@ -864,23 +863,29 @@ r535_outp_detect(struct nvkm_outp *outp) return PTR_ERR(ctrl); ctrl->subDeviceInstance = 0; - ctrl->displayMask = BIT(outp->index); + ctrl->displayMask = BIT(display_id); ret = nvkm_gsp_rm_ctrl_push(&disp->rm.objcom, &ctrl, sizeof(*ctrl)); - if (ret) { - nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl); - return ret; - } + if (ret == 0 && (ctrl->displayMask & BIT(display_id))) + ret = 1; + + nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl); + return ret; +} - if (ctrl->displayMask & BIT(outp->index)) { +static int +r535_outp_detect(struct nvkm_outp *outp) +{ + const struct nvkm_rm_api *rmapi = outp->disp->rm.objcom.client->gsp->rm->api; + int ret; + + ret = rmapi->disp->get_connect_state(outp->disp, outp->index); + if (ret == 1) { ret = r535_outp_dfp_get_info(outp); if (ret == 0) ret = 1; - } else { - ret = 0; } - nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl); return ret; } @@ -1752,6 +1757,7 @@ const struct nvkm_rm_api_disp r535_disp = { .get_static_info = r535_disp_get_static_info, .get_supported = r535_disp_get_supported, + .get_connect_state = r535_disp_get_connect_state, .bl_ctrl = r535_bl_ctrl, .dp = { .set_indexed_link_rates = r535_dp_set_indexed_link_rates, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h index 3f0cb6790f00..58c745554544 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h @@ -81,6 +81,7 @@ struct nvkm_rm_api { const struct nvkm_rm_api_disp { int (*get_static_info)(struct nvkm_disp *); int (*get_supported)(struct nvkm_disp *, unsigned long *display_mask); + int (*get_connect_state)(struct nvkm_disp *, unsigned display_id); int (*bl_ctrl)(struct nvkm_disp *, unsigned display_id, bool set, int *val); -- 2.49.0
Ben Skeggs
2025-May-17 00:09 UTC
[PATCH v3 37/62] drm/nouveau/gsp: add hal for disp.get_active()
555.42.02 has incompatible changes to NV0073_CTRL_CMD_SYSTEM_GET_ACTIVE. Signed-off-by: Ben Skeggs <bskeggs at nvidia.com> Reviewed-by: Dave Airlie <airlied at redhat.com> Reviewed-by: Timur Tabi <ttabi at nvidia.com> Tested-by: Timur Tabi <ttabi at nvidia.com> --- drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c | 7 +++++-- drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h | 1 + 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c index 4df5b2b72d29..97b7e54df61f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c @@ -724,7 +724,7 @@ r535_outp_acquire(struct nvkm_outp *outp, bool hda) } static int -r535_disp_head_displayid(struct nvkm_disp *disp, int head, u32 *displayid) +r535_disp_get_active(struct nvkm_disp *disp, unsigned head, u32 *displayid) { NV0073_CTRL_SYSTEM_GET_ACTIVE_PARAMS *ctrl; int ret; @@ -757,7 +757,9 @@ r535_outp_inherit(struct nvkm_outp *outp) int ret; list_for_each_entry(head, &disp->heads, head) { - ret = r535_disp_head_displayid(disp, head->id, &displayid); + const struct nvkm_rm_api *rmapi = disp->rm.objcom.client->gsp->rm->api; + + ret = rmapi->disp->get_active(disp, head->id, &displayid); if (WARN_ON(ret)) return NULL; @@ -1758,6 +1760,7 @@ r535_disp = { .get_static_info = r535_disp_get_static_info, .get_supported = r535_disp_get_supported, .get_connect_state = r535_disp_get_connect_state, + .get_active = r535_disp_get_active, .bl_ctrl = r535_bl_ctrl, .dp = { .set_indexed_link_rates = r535_dp_set_indexed_link_rates, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h index 58c745554544..f25539401b20 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h @@ -82,6 +82,7 @@ struct nvkm_rm_api { int (*get_static_info)(struct nvkm_disp *); int (*get_supported)(struct nvkm_disp *, unsigned long *display_mask); int (*get_connect_state)(struct nvkm_disp *, unsigned display_id); + int (*get_active)(struct nvkm_disp *, unsigned head, u32 *display_id); int (*bl_ctrl)(struct nvkm_disp *, unsigned display_id, bool set, int *val); -- 2.49.0
Ben Skeggs
2025-May-17 00:09 UTC
[PATCH v3 38/62] drm/nouveau/gsp: add hal for disp.dp.get_caps()
555.42.02 has incompatible changes to NV0073_CTRL_CMD_DP_GET_CAPS. Signed-off-by: Ben Skeggs <bskeggs at nvidia.com> Reviewed-by: Dave Airlie <airlied at redhat.com> Reviewed-by: Timur Tabi <ttabi at nvidia.com> Tested-by: Timur Tabi <ttabi at nvidia.com> --- .../nouveau/nvkm/subdev/gsp/rm/r535/disp.c | 81 +++++++++++-------- .../gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h | 1 + 2 files changed, 48 insertions(+), 34 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c index 97b7e54df61f..14187e1618b8 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c @@ -1159,6 +1159,49 @@ r535_dp = { .dp.drive = r535_dp_drive, }; +static int +r535_dp_get_caps(struct nvkm_disp *disp, int *plink_bw, bool *pmst, bool *pwm) +{ + NV0073_CTRL_CMD_DP_GET_CAPS_PARAMS *ctrl; + int ret; + + ctrl = nvkm_gsp_rm_ctrl_get(&disp->rm.objcom, + NV0073_CTRL_CMD_DP_GET_CAPS, sizeof(*ctrl)); + if (IS_ERR(ctrl)) + return PTR_ERR(ctrl); + + ctrl->sorIndex = ~0; + + ret = nvkm_gsp_rm_ctrl_push(&disp->rm.objcom, &ctrl, sizeof(*ctrl)); + if (ret) { + nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl); + return ret; + } + + switch (NVVAL_GET(ctrl->maxLinkRate, NV0073_CTRL_CMD, DP_GET_CAPS, MAX_LINK_RATE)) { + case NV0073_CTRL_CMD_DP_GET_CAPS_MAX_LINK_RATE_1_62: + *plink_bw = 0x06; + break; + case NV0073_CTRL_CMD_DP_GET_CAPS_MAX_LINK_RATE_2_70: + *plink_bw = 0x0a; + break; + case NV0073_CTRL_CMD_DP_GET_CAPS_MAX_LINK_RATE_5_40: + *plink_bw = 0x14; + break; + case NV0073_CTRL_CMD_DP_GET_CAPS_MAX_LINK_RATE_8_10: + *plink_bw = 0x1e; + break; + default: + *plink_bw = 0x00; + break; + } + + *pmst = ctrl->bIsMultistreamSupported; + *pwm = ctrl->bHasIncreasedWatermarkLimits; + nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl); + return 0; +} + static int r535_tmds_edid_get(struct nvkm_outp *outp, u8 *data, u16 *psize) { @@ -1203,6 +1246,7 @@ r535_tmds = { static int r535_outp_new(struct nvkm_disp *disp, u32 id) { + const struct nvkm_rm_api *rmapi = disp->rm.objcom.client->gsp->rm->api; NV0073_CTRL_SPECIFIC_OR_GET_INFO_PARAMS *ctrl; enum nvkm_ior_proto proto; struct dcb_output dcbE = {}; @@ -1287,43 +1331,11 @@ r535_outp_new(struct nvkm_disp *disp, u32 id) if (ret) return ret; } else { - NV0073_CTRL_CMD_DP_GET_CAPS_PARAMS *ctrl; bool mst, wm; - ctrl = nvkm_gsp_rm_ctrl_get(&disp->rm.objcom, - NV0073_CTRL_CMD_DP_GET_CAPS, sizeof(*ctrl)); - if (IS_ERR(ctrl)) - return PTR_ERR(ctrl); - - ctrl->sorIndex = ~0; - - ret = nvkm_gsp_rm_ctrl_push(&disp->rm.objcom, &ctrl, sizeof(*ctrl)); - if (ret) { - nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl); + ret = rmapi->disp->dp.get_caps(disp, &dcbE.dpconf.link_bw, &mst, &wm); + if (ret) return ret; - } - - switch (NVVAL_GET(ctrl->maxLinkRate, NV0073_CTRL_CMD, DP_GET_CAPS, MAX_LINK_RATE)) { - case NV0073_CTRL_CMD_DP_GET_CAPS_MAX_LINK_RATE_1_62: - dcbE.dpconf.link_bw = 0x06; - break; - case NV0073_CTRL_CMD_DP_GET_CAPS_MAX_LINK_RATE_2_70: - dcbE.dpconf.link_bw = 0x0a; - break; - case NV0073_CTRL_CMD_DP_GET_CAPS_MAX_LINK_RATE_5_40: - dcbE.dpconf.link_bw = 0x14; - break; - case NV0073_CTRL_CMD_DP_GET_CAPS_MAX_LINK_RATE_8_10: - dcbE.dpconf.link_bw = 0x1e; - break; - default: - dcbE.dpconf.link_bw = 0x00; - break; - } - - mst = ctrl->bIsMultistreamSupported; - wm = ctrl->bHasIncreasedWatermarkLimits; - nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl); if (WARN_ON(!dcbE.dpconf.link_bw)) return -EINVAL; @@ -1763,6 +1775,7 @@ r535_disp = { .get_active = r535_disp_get_active, .bl_ctrl = r535_bl_ctrl, .dp = { + .get_caps = r535_dp_get_caps, .set_indexed_link_rates = r535_dp_set_indexed_link_rates, }, .chan = { diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h index f25539401b20..01cb97f1e494 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h @@ -87,6 +87,7 @@ struct nvkm_rm_api { int (*bl_ctrl)(struct nvkm_disp *, unsigned display_id, bool set, int *val); struct { + int (*get_caps)(struct nvkm_disp *, int *link_bw, bool *mst, bool *wm); int (*set_indexed_link_rates)(struct nvkm_outp *); } dp; -- 2.49.0
Ben Skeggs
2025-May-17 00:09 UTC
[PATCH v3 39/62] drm/nouveau/gsp: add hal for fifo.chan.alloc
570.86.16 has incompatible changes to NV_CHANNEL_ALLOC_PARAMS. At the same time, remove the duplicated channel allocation code from golden context init. Signed-off-by: Ben Skeggs <bskeggs at nvidia.com> Reviewed-by: Dave Airlie <airlied at redhat.com> Reviewed-by: Timur Tabi <ttabi at nvidia.com> Tested-by: Timur Tabi <ttabi at nvidia.com> --- .../nouveau/nvkm/subdev/gsp/rm/r535/fifo.c | 103 +++++++++++------- .../drm/nouveau/nvkm/subdev/gsp/rm/r535/gr.c | 70 ++---------- .../gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h | 7 ++ 3 files changed, 76 insertions(+), 104 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/fifo.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/fifo.c index 58a47c62690a..645706179913 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/fifo.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/fifo.c @@ -70,50 +70,29 @@ r535_chan_ramfc_clear(struct nvkm_chan *chan) #define CHID_PER_USERD 8 static int -r535_chan_ramfc_write(struct nvkm_chan *chan, u64 offset, u64 length, u32 devm, bool priv) +r535_chan_alloc(struct nvkm_gsp_device *device, u32 handle, u32 nv2080_engine_type, u8 runq, + bool priv, int chid, u64 inst_addr, u64 userd_addr, u64 mthdbuf_addr, + struct nvkm_vmm *vmm, u64 gpfifo_offset, u32 gpfifo_length, + struct nvkm_gsp_object *chan) { - struct nvkm_fifo *fifo = chan->cgrp->runl->fifo; - struct nvkm_engn *engn; - struct nvkm_device *device = fifo->engine.subdev.device; + struct nvkm_gsp *gsp = device->object.client->gsp; + struct nvkm_fifo *fifo = gsp->subdev.device->fifo; + const int userd_p = chid / CHID_PER_USERD; + const int userd_i = chid % CHID_PER_USERD; NV_CHANNELGPFIFO_ALLOCATION_PARAMETERS *args; - const int userd_p = chan->id / CHID_PER_USERD; - const int userd_i = chan->id % CHID_PER_USERD; - u32 eT = ~0; - int ret; - if (unlikely(device->gr && !device->gr->engine.subdev.oneinit)) { - ret = nvkm_subdev_oneinit(&device->gr->engine.subdev); - if (ret) - return ret; - } - - nvkm_runl_foreach_engn(engn, chan->cgrp->runl) { - eT = engn->id; - break; - } - - if (WARN_ON(eT == ~0)) - return -EINVAL; - - chan->rm.mthdbuf.ptr = dma_alloc_coherent(fifo->engine.subdev.device->dev, - fifo->rm.mthdbuf_size, - &chan->rm.mthdbuf.addr, GFP_KERNEL); - if (!chan->rm.mthdbuf.ptr) - return -ENOMEM; - - args = nvkm_gsp_rm_alloc_get(&chan->vmm->rm.device.object, NVKM_RM_CHAN(chan->id), - fifo->func->chan.user.oclass, sizeof(*args), - &chan->rm.object); + args = nvkm_gsp_rm_alloc_get(&device->object, handle, + fifo->func->chan.user.oclass, sizeof(*args), chan); if (WARN_ON(IS_ERR(args))) return PTR_ERR(args); - args->gpFifoOffset = offset; - args->gpFifoEntries = length / 8; + args->gpFifoOffset = gpfifo_offset; + args->gpFifoEntries = gpfifo_length / 8; args->flags = NVDEF(NVOS04, FLAGS, CHANNEL_TYPE, PHYSICAL); args->flags |= NVDEF(NVOS04, FLAGS, VPR, FALSE); args->flags |= NVDEF(NVOS04, FLAGS, CHANNEL_SKIP_MAP_REFCOUNTING, FALSE); - args->flags |= NVVAL(NVOS04, FLAGS, GROUP_CHANNEL_RUNQUEUE, chan->runq); + args->flags |= NVVAL(NVOS04, FLAGS, GROUP_CHANNEL_RUNQUEUE, runq); if (!priv) args->flags |= NVDEF(NVOS04, FLAGS, PRIVILEGED_CHANNEL, FALSE); else @@ -136,25 +115,25 @@ r535_chan_ramfc_write(struct nvkm_chan *chan, u64 offset, u64 length, u32 devm, args->flags |= NVDEF(NVOS04, FLAGS, MAP_CHANNEL, FALSE); args->flags |= NVDEF(NVOS04, FLAGS, SKIP_CTXBUFFER_ALLOC, FALSE); - args->hVASpace = chan->vmm->rm.object.handle; - args->engineType = eT; + args->hVASpace = vmm->rm.object.handle; + args->engineType = nv2080_engine_type; - args->instanceMem.base = chan->inst->addr; - args->instanceMem.size = chan->inst->size; + args->instanceMem.base = inst_addr; + args->instanceMem.size = fifo->func->chan.func->inst->size; args->instanceMem.addressSpace = 2; args->instanceMem.cacheAttrib = 1; - args->userdMem.base = nvkm_memory_addr(chan->userd.mem) + chan->userd.base; + args->userdMem.base = userd_addr; args->userdMem.size = fifo->func->chan.func->userd->size; args->userdMem.addressSpace = 2; args->userdMem.cacheAttrib = 1; - args->ramfcMem.base = chan->inst->addr + 0; + args->ramfcMem.base = inst_addr; args->ramfcMem.size = 0x200; args->ramfcMem.addressSpace = 2; args->ramfcMem.cacheAttrib = 1; - args->mthdbufMem.base = chan->rm.mthdbuf.addr; + args->mthdbufMem.base = mthdbuf_addr; args->mthdbufMem.size = fifo->rm.mthdbuf_size; args->mthdbufMem.addressSpace = 1; args->mthdbufMem.cacheAttrib = 0; @@ -166,7 +145,44 @@ r535_chan_ramfc_write(struct nvkm_chan *chan, u64 offset, u64 length, u32 devm, args->internalFlags |= NVDEF(NV_KERNELCHANNEL, ALLOC_INTERNALFLAGS, ERROR_NOTIFIER_TYPE, NONE); args->internalFlags |= NVDEF(NV_KERNELCHANNEL, ALLOC_INTERNALFLAGS, ECC_ERROR_NOTIFIER_TYPE, NONE); - ret = nvkm_gsp_rm_alloc_wr(&chan->rm.object, args); + return nvkm_gsp_rm_alloc_wr(chan, args); +} + +static int +r535_chan_ramfc_write(struct nvkm_chan *chan, u64 offset, u64 length, u32 devm, bool priv) +{ + struct nvkm_fifo *fifo = chan->cgrp->runl->fifo; + struct nvkm_engn *engn; + struct nvkm_device *device = fifo->engine.subdev.device; + const struct nvkm_rm_api *rmapi = device->gsp->rm->api; + u32 eT = ~0; + int ret; + + if (unlikely(device->gr && !device->gr->engine.subdev.oneinit)) { + ret = nvkm_subdev_oneinit(&device->gr->engine.subdev); + if (ret) + return ret; + } + + nvkm_runl_foreach_engn(engn, chan->cgrp->runl) { + eT = engn->id; + break; + } + + if (WARN_ON(eT == ~0)) + return -EINVAL; + + chan->rm.mthdbuf.ptr = dma_alloc_coherent(fifo->engine.subdev.device->dev, + fifo->rm.mthdbuf_size, + &chan->rm.mthdbuf.addr, GFP_KERNEL); + if (!chan->rm.mthdbuf.ptr) + return -ENOMEM; + + ret = rmapi->fifo->chan.alloc(&chan->vmm->rm.device, NVKM_RM_CHAN(chan->id), + eT, chan->runq, priv, chan->id, chan->inst->addr, + nvkm_memory_addr(chan->userd.mem) + chan->userd.base, + chan->rm.mthdbuf.addr, chan->vmm, offset, length, + &chan->rm.object); if (ret) return ret; @@ -541,4 +557,7 @@ const struct nvkm_rm_api_fifo r535_fifo = { .xlat_rm_engine_type = r535_fifo_xlat_rm_engine_type, .ectx_size = r535_fifo_ectx_size, + .chan = { + .alloc = r535_chan_alloc, + }, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gr.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gr.c index e0fa88aa608f..cc28de66cfa3 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gr.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gr.c @@ -298,74 +298,20 @@ r535_gr_oneinit(struct nvkm_gr *base) if (ret) goto done; - { - NV_CHANNELGPFIFO_ALLOCATION_PARAMETERS *args; - - args = nvkm_gsp_rm_alloc_get(&golden.vmm->rm.device.object, NVKM_RM_CHAN(0), - device->fifo->func->chan.user.oclass, - sizeof(*args), &golden.chan); - if (IS_ERR(args)) { - ret = PTR_ERR(args); - goto done; - } - - args->gpFifoOffset = 0; - args->gpFifoEntries = 0x1000 / 8; - args->flags - NVDEF(NVOS04, FLAGS, CHANNEL_TYPE, PHYSICAL) | - NVDEF(NVOS04, FLAGS, VPR, FALSE) | - NVDEF(NVOS04, FLAGS, CHANNEL_SKIP_MAP_REFCOUNTING, FALSE) | - NVVAL(NVOS04, FLAGS, GROUP_CHANNEL_RUNQUEUE, 0) | - NVDEF(NVOS04, FLAGS, PRIVILEGED_CHANNEL, TRUE) | - NVDEF(NVOS04, FLAGS, DELAY_CHANNEL_SCHEDULING, FALSE) | - NVDEF(NVOS04, FLAGS, CHANNEL_DENY_PHYSICAL_MODE_CE, FALSE) | - NVVAL(NVOS04, FLAGS, CHANNEL_USERD_INDEX_VALUE, 0) | - NVDEF(NVOS04, FLAGS, CHANNEL_USERD_INDEX_FIXED, FALSE) | - NVVAL(NVOS04, FLAGS, CHANNEL_USERD_INDEX_PAGE_VALUE, 0) | - NVDEF(NVOS04, FLAGS, CHANNEL_USERD_INDEX_PAGE_FIXED, TRUE) | - NVDEF(NVOS04, FLAGS, CHANNEL_DENY_AUTH_LEVEL_PRIV, FALSE) | - NVDEF(NVOS04, FLAGS, CHANNEL_SKIP_SCRUBBER, FALSE) | - NVDEF(NVOS04, FLAGS, CHANNEL_CLIENT_MAP_FIFO, FALSE) | - NVDEF(NVOS04, FLAGS, SET_EVICT_LAST_CE_PREFETCH_CHANNEL, FALSE) | - NVDEF(NVOS04, FLAGS, CHANNEL_VGPU_PLUGIN_CONTEXT, FALSE) | - NVDEF(NVOS04, FLAGS, CHANNEL_PBDMA_ACQUIRE_TIMEOUT, FALSE) | - NVDEF(NVOS04, FLAGS, GROUP_CHANNEL_THREAD, DEFAULT) | - NVDEF(NVOS04, FLAGS, MAP_CHANNEL, FALSE) | - NVDEF(NVOS04, FLAGS, SKIP_CTXBUFFER_ALLOC, FALSE); - args->hVASpace = golden.vmm->rm.object.handle; - args->engineType = 1; - args->instanceMem.base = nvkm_memory_addr(golden.inst); - args->instanceMem.size = 0x1000; - args->instanceMem.addressSpace = 2; - args->instanceMem.cacheAttrib = 1; - args->ramfcMem.base = nvkm_memory_addr(golden.inst); - args->ramfcMem.size = 0x200; - args->ramfcMem.addressSpace = 2; - args->ramfcMem.cacheAttrib = 1; - args->userdMem.base = nvkm_memory_addr(golden.inst) + 0x1000; - args->userdMem.size = 0x200; - args->userdMem.addressSpace = 2; - args->userdMem.cacheAttrib = 1; - args->mthdbufMem.base = nvkm_memory_addr(golden.inst) + 0x2000; - args->mthdbufMem.size = 0x5000; - args->mthdbufMem.addressSpace = 2; - args->mthdbufMem.cacheAttrib = 1; - args->internalFlags - NVDEF(NV_KERNELCHANNEL, ALLOC_INTERNALFLAGS, PRIVILEGE, ADMIN) | - NVDEF(NV_KERNELCHANNEL, ALLOC_INTERNALFLAGS, ERROR_NOTIFIER_TYPE, NONE) | - NVDEF(NV_KERNELCHANNEL, ALLOC_INTERNALFLAGS, ECC_ERROR_NOTIFIER_TYPE, NONE); - - ret = nvkm_gsp_rm_alloc_wr(&golden.chan, args); - if (ret) - goto done; - } + ret = rm->api->fifo->chan.alloc(&golden.vmm->rm.device, NVKM_RM_CHAN(0), 1, 0, true, 0, + nvkm_memory_addr(golden.inst), + nvkm_memory_addr(golden.inst) + 0x1000, + nvkm_memory_addr(golden.inst) + 0x2000, + golden.vmm, 0, 0x1000, &golden.chan); + if (ret) + goto done; /* Fetch context buffer info from RM and allocate each of them here to use * during golden context init (or later as a global context buffer). * * Also build the information that'll be used to create channel contexts. */ - ret = gsp->rm->api->gr->get_ctxbufs_info(gr); + ret = rm->api->gr->get_ctxbufs_info(gr); if (ret) goto done; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h index 01cb97f1e494..29663dbe99e1 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h @@ -101,6 +101,13 @@ struct nvkm_rm_api { int (*xlat_rm_engine_type)(u32 rm_engine_type, enum nvkm_subdev_type *, int *nv2080_type); int (*ectx_size)(struct nvkm_fifo *); + struct { + int (*alloc)(struct nvkm_gsp_device *, u32 handle, + u32 nv2080_engine_type, u8 runq, bool priv, int chid, + u64 inst_addr, u64 userd_addr, u64 mthdbuf_addr, + struct nvkm_vmm *, u64 gpfifo_offset, u32 gpfifo_length, + struct nvkm_gsp_object *); + } chan; } *fifo; const struct nvkm_rm_api_engine { -- 2.49.0
Ben Skeggs
2025-May-17 00:09 UTC
[PATCH v3 40/62] drm/nouveau/gsp: add hal for fifo.rsvd_chids
555.42.02 reserves some CHIDs for internal use. Signed-off-by: Ben Skeggs <bskeggs at nvidia.com> Reviewed-by: Dave Airlie <airlied at redhat.com> Reviewed-by: Timur Tabi <ttabi at nvidia.com> Tested-by: Timur Tabi <ttabi at nvidia.com> --- drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/fifo.c | 7 ++++--- drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gr.c | 3 ++- drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h | 1 + 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/fifo.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/fifo.c index 645706179913..a480c1a5686d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/fifo.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/fifo.c @@ -427,13 +427,14 @@ r535_fifo_runl_ctor(struct nvkm_fifo *fifo) struct nvkm_rm *rm = gsp->rm; struct nvkm_runl *runl; struct nvkm_engn *engn; - u32 cgids = 2048; u32 chids = 2048; + u32 first = rm->api->fifo->rsvd_chids; + u32 count = chids - first; int ret; NV2080_CTRL_FIFO_GET_DEVICE_INFO_TABLE_PARAMS *ctrl; - if ((ret = nvkm_chid_new(&nvkm_chan_event, subdev, cgids, 0, cgids, &fifo->cgid)) || - (ret = nvkm_chid_new(&nvkm_chan_event, subdev, chids, 0, chids, &fifo->chid))) + if ((ret = nvkm_chid_new(&nvkm_chan_event, subdev, chids, first, count, &fifo->cgid)) || + (ret = nvkm_chid_new(&nvkm_chan_event, subdev, chids, first, count, &fifo->chid))) return ret; ctrl = nvkm_gsp_rm_ctrl_rd(&gsp->internal.device.subdevice, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gr.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gr.c index cc28de66cfa3..9e97b7b1a0fb 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gr.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gr.c @@ -298,7 +298,8 @@ r535_gr_oneinit(struct nvkm_gr *base) if (ret) goto done; - ret = rm->api->fifo->chan.alloc(&golden.vmm->rm.device, NVKM_RM_CHAN(0), 1, 0, true, 0, + ret = rm->api->fifo->chan.alloc(&golden.vmm->rm.device, NVKM_RM_CHAN(0), + 1, 0, true, rm->api->fifo->rsvd_chids, nvkm_memory_addr(golden.inst), nvkm_memory_addr(golden.inst) + 0x1000, nvkm_memory_addr(golden.inst) + 0x2000, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h index 29663dbe99e1..a370beda3c71 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h @@ -101,6 +101,7 @@ struct nvkm_rm_api { int (*xlat_rm_engine_type)(u32 rm_engine_type, enum nvkm_subdev_type *, int *nv2080_type); int (*ectx_size)(struct nvkm_fifo *); + unsigned rsvd_chids; struct { int (*alloc)(struct nvkm_gsp_device *, u32 handle, u32 nv2080_engine_type, u8 runq, bool priv, int chid, -- 2.49.0
Ben Skeggs
2025-May-17 00:09 UTC
[PATCH v3 41/62] drm/nouveau/gsp: add hal for fifo.rc_triggered()
565.57.01 has incompatible changes to rpc_rc_triggered_v17_02. Signed-off-by: Ben Skeggs <bskeggs at nvidia.com> Reviewed-by: Dave Airlie <airlied at redhat.com> Reviewed-by: Timur Tabi <ttabi at nvidia.com> Tested-by: Timur Tabi <ttabi at nvidia.com> --- .../nouveau/nvkm/subdev/gsp/rm/r535/fifo.c | 34 +++++++++++++++++++ .../drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c | 30 +--------------- .../gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h | 1 + 3 files changed, 36 insertions(+), 29 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/fifo.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/fifo.c index a480c1a5686d..1561b5a9b6fc 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/fifo.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/fifo.c @@ -339,6 +339,39 @@ r535_runl = { .allow = r535_runl_allow, }; +static void +r535_fifo_rc_chid(struct nvkm_fifo *fifo, int chid) +{ + struct nvkm_chan *chan; + unsigned long flags; + + chan = nvkm_chan_get_chid(&fifo->engine, chid, &flags); + if (!chan) { + nvkm_error(&fifo->engine.subdev, "rc: chid %d not found!\n", chid); + return; + } + + nvkm_chan_error(chan, false); + nvkm_chan_put(&chan, flags); +} + +static int +r535_fifo_rc_triggered(void *priv, u32 fn, void *repv, u32 repc) +{ + rpc_rc_triggered_v17_02 *msg = repv; + struct nvkm_gsp *gsp = priv; + + if (WARN_ON(repc < sizeof(*msg))) + return -EINVAL; + + nvkm_error(&gsp->subdev, "rc: engn:%08x chid:%d type:%d scope:%d part:%d\n", + msg->nv2080EngineType, msg->chid, msg->exceptType, msg->scope, + msg->partitionAttributionId); + + r535_fifo_rc_chid(gsp->subdev.device->fifo, msg->chid); + return 0; +} + static int r535_fifo_xlat_rm_engine_type(u32 rm, enum nvkm_subdev_type *ptype, int *p2080) { @@ -558,6 +591,7 @@ const struct nvkm_rm_api_fifo r535_fifo = { .xlat_rm_engine_type = r535_fifo_xlat_rm_engine_type, .ectx_size = r535_fifo_ectx_size, + .rc_triggered = r535_fifo_rc_triggered, .chan = { .alloc = r535_chan_alloc, }, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c index 64e9ecf93441..b7c2a785bc58 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c @@ -926,33 +926,6 @@ r535_gsp_msg_os_error_log(void *priv, u32 fn, void *repv, u32 repc) return 0; } -static int -r535_gsp_msg_rc_triggered(void *priv, u32 fn, void *repv, u32 repc) -{ - rpc_rc_triggered_v17_02 *msg = repv; - struct nvkm_gsp *gsp = priv; - struct nvkm_subdev *subdev = &gsp->subdev; - struct nvkm_chan *chan; - unsigned long flags; - - if (WARN_ON(repc < sizeof(*msg))) - return -EINVAL; - - nvkm_error(subdev, "rc engn:%08x chid:%d type:%d scope:%d part:%d\n", - msg->nv2080EngineType, msg->chid, msg->exceptType, msg->scope, - msg->partitionAttributionId); - - chan = nvkm_chan_get_chid(&subdev->device->fifo->engine, msg->chid, &flags); - if (!chan) { - nvkm_error(subdev, "rc chid:%d not found!\n", msg->chid); - return 0; - } - - nvkm_chan_error(chan, false); - nvkm_chan_put(&chan, flags); - return 0; -} - static int r535_gsp_msg_mmu_fault_queued(void *priv, u32 fn, void *repv, u32 repc) { @@ -2154,8 +2127,7 @@ r535_gsp_oneinit(struct nvkm_gsp *gsp) r535_gsp_msg_ntfy_add(gsp, NV_VGPU_MSG_EVENT_GSP_RUN_CPU_SEQUENCER, r535_gsp_msg_run_cpu_sequencer, gsp); r535_gsp_msg_ntfy_add(gsp, NV_VGPU_MSG_EVENT_POST_EVENT, r535_gsp_msg_post_event, gsp); - r535_gsp_msg_ntfy_add(gsp, NV_VGPU_MSG_EVENT_RC_TRIGGERED, - r535_gsp_msg_rc_triggered, gsp); + r535_gsp_msg_ntfy_add(gsp, NV_VGPU_MSG_EVENT_RC_TRIGGERED, rmapi->fifo->rc_triggered, gsp); r535_gsp_msg_ntfy_add(gsp, NV_VGPU_MSG_EVENT_MMU_FAULT_QUEUED, r535_gsp_msg_mmu_fault_queued, gsp); r535_gsp_msg_ntfy_add(gsp, NV_VGPU_MSG_EVENT_OS_ERROR_LOG, r535_gsp_msg_os_error_log, gsp); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h index a370beda3c71..1ca5b025eeb4 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h @@ -102,6 +102,7 @@ struct nvkm_rm_api { enum nvkm_subdev_type *, int *nv2080_type); int (*ectx_size)(struct nvkm_fifo *); unsigned rsvd_chids; + int (*rc_triggered)(void *priv, u32 fn, void *repv, u32 repc); struct { int (*alloc)(struct nvkm_gsp_device *, u32 handle, u32 nv2080_engine_type, u8 runq, bool priv, int chid, -- 2.49.0
Ben Skeggs
2025-May-17 00:09 UTC
[PATCH v3 42/62] drm/nouveau/gsp: add hal for disp.chan.dmac_alloc()
565.57.01 has incompatible changes to NV50VAIO_CHANNELDMA_ALLOCATION_PARAMETERS. Signed-off-by: Ben Skeggs <bskeggs at nvidia.com> Reviewed-by: Dave Airlie <airlied at redhat.com> Reviewed-by: Timur Tabi <ttabi at nvidia.com> Tested-by: Timur Tabi <ttabi at nvidia.com> --- .../nouveau/nvkm/subdev/gsp/rm/r535/disp.c | 31 ++++++++++++------- .../gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h | 2 ++ 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c index 14187e1618b8..7e9e2d3564da 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c @@ -164,27 +164,35 @@ r535_dmac_fini(struct nvkm_disp_chan *chan) r535_chan_fini(chan); } +static int +r535_dmac_alloc(struct nvkm_disp *disp, u32 oclass, int inst, u32 put_offset, + struct nvkm_gsp_object *dmac) +{ + NV50VAIO_CHANNELDMA_ALLOCATION_PARAMETERS *args; + + args = nvkm_gsp_rm_alloc_get(&disp->rm.object, (oclass << 16) | inst, oclass, + sizeof(*args), dmac); + if (IS_ERR(args)) + return PTR_ERR(args); + + args->channelInstance = inst; + args->offset = put_offset; + + return nvkm_gsp_rm_alloc_wr(dmac, args); +} + static int r535_dmac_init(struct nvkm_disp_chan *chan) { const struct nvkm_rm_api *rmapi = chan->disp->rm.objcom.client->gsp->rm->api; - NV50VAIO_CHANNELDMA_ALLOCATION_PARAMETERS *args; int ret; ret = rmapi->disp->chan.set_pushbuf(chan->disp, chan->object.oclass, chan->head, chan->memory); if (ret) return ret; - args = nvkm_gsp_rm_alloc_get(&chan->disp->rm.object, - (chan->object.oclass << 16) | chan->head, - chan->object.oclass, sizeof(*args), &chan->rm.object); - if (IS_ERR(args)) - return PTR_ERR(args); - - args->channelInstance = chan->head; - args->offset = chan->suspend_put; - - return nvkm_gsp_rm_alloc_wr(&chan->rm.object, args); + return rmapi->disp->chan.dmac_alloc(chan->disp, chan->object.oclass, chan->head, + chan->suspend_put, &chan->rm.object); } static int @@ -1780,5 +1788,6 @@ r535_disp = { }, .chan = { .set_pushbuf = r535_disp_chan_set_pushbuf, + .dmac_alloc = r535_dmac_alloc, } }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h index 1ca5b025eeb4..7aed7cd72e85 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h @@ -94,6 +94,8 @@ struct nvkm_rm_api { struct { int (*set_pushbuf)(struct nvkm_disp *, s32 oclass, int inst, struct nvkm_memory *); + int (*dmac_alloc)(struct nvkm_disp *, u32 oclass, int inst, u32 put_offset, + struct nvkm_gsp_object *); } chan; } *disp; -- 2.49.0
Ben Skeggs
2025-May-17 00:09 UTC
[PATCH v3 43/62] drm/nouveau/gsp: add hal for gsp.sr_data_size()
570.86.15 uses a slightly different calculation for the size of the sysmem buffer needed to store GSP-RM's vidmem data across suspend. Signed-off-by: Ben Skeggs <bskeggs at nvidia.com> Reviewed-by: Dave Airlie <airlied at redhat.com> Reviewed-by: Timur Tabi <ttabi at nvidia.com> Tested-by: Timur Tabi <ttabi at nvidia.com> --- .../gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c | 12 ++++++++++-- drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h | 1 + 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c index b7c2a785bc58..85eb838d2a09 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c @@ -1700,6 +1700,14 @@ nvkm_gsp_radix3_sg(struct nvkm_gsp *gsp, struct sg_table *sgt, u64 size, return ret; } +static u32 +r535_gsp_sr_data_size(struct nvkm_gsp *gsp) +{ + GspFwWprMeta *meta = gsp->wpr_meta.data; + + return meta->gspFwWprEnd - meta->gspFwWprStart; +} + int r535_gsp_fini(struct nvkm_gsp *gsp, bool suspend) { @@ -1707,8 +1715,7 @@ r535_gsp_fini(struct nvkm_gsp *gsp, bool suspend) int ret; if (suspend) { - GspFwWprMeta *meta = gsp->wpr_meta.data; - u64 len = meta->gspFwWprEnd - meta->gspFwWprStart; + u32 len = rm->api->gsp->sr_data_size(gsp); GspFwSRMeta *sr; ret = nvkm_gsp_sg(gsp->subdev.device, len, &gsp->sr.sgt); @@ -2167,4 +2174,5 @@ r535_gsp = { .get_static_info = r535_gsp_get_static_info, .xlat_mc_engine_idx = r535_gsp_xlat_mc_engine_idx, .drop_send_user_shared_data = r535_gsp_drop_send_user_shared_data, + .sr_data_size = r535_gsp_sr_data_size, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h index 7aed7cd72e85..eb018b73d26f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h @@ -34,6 +34,7 @@ struct nvkm_rm_api { int (*get_static_info)(struct nvkm_gsp *); bool (*xlat_mc_engine_idx)(u32 mc_engine_idx, enum nvkm_subdev_type *, int *inst); void (*drop_send_user_shared_data)(struct nvkm_gsp *); + u32 (*sr_data_size)(struct nvkm_gsp *); } *gsp; const struct nvkm_rm_api_rpc { -- 2.49.0
Ben Skeggs
2025-May-17 00:09 UTC
[PATCH v3 44/62] drm/nouveau/gsp: add common client alloc code
570.144 has incompatible changes to NV0000_ALLOC_PARAMETERS. Factor out the common code so it can be shared. Signed-off-by: Ben Skeggs <bskeggs at nvidia.com> --- .../gpu/drm/nouveau/include/nvkm/subdev/gsp.h | 17 +------ .../gpu/drm/nouveau/nvkm/subdev/gsp/rm/Kbuild | 1 + .../drm/nouveau/nvkm/subdev/gsp/rm/client.c | 49 +++++++++++++++++++ .../drm/nouveau/nvkm/subdev/gsp/rm/handles.h | 1 + .../nouveau/nvkm/subdev/gsp/rm/r535/client.c | 44 ++--------------- .../gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h | 3 +- 6 files changed, 59 insertions(+), 56 deletions(-) create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/client.c diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h index 40e1b5300dff..4ad07f3ced69 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h @@ -411,21 +411,8 @@ nvkm_gsp_rm_free(struct nvkm_gsp_object *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->api->client->ctor(gsp, client); -} - -static inline void -nvkm_gsp_client_dtor(struct nvkm_gsp_client *client) -{ - if (client->gsp) - client->gsp->rm->api->client->dtor(client); -} +int nvkm_gsp_client_ctor(struct nvkm_gsp *, struct nvkm_gsp_client *); +void nvkm_gsp_client_dtor(struct nvkm_gsp_client *); static inline int nvkm_gsp_device_ctor(struct nvkm_gsp_client *client, struct nvkm_gsp_device *device) diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/Kbuild index e5d5f8880d31..0eac850d1f33 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/Kbuild @@ -1,6 +1,7 @@ # SPDX-License-Identifier: MIT # # Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. +nvkm-y += nvkm/subdev/gsp/rm/client.o nvkm-y += nvkm/subdev/gsp/rm/engine.o nvkm-y += nvkm/subdev/gsp/rm/gr.o nvkm-y += nvkm/subdev/gsp/rm/nvdec.o diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/client.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/client.c new file mode 100644 index 000000000000..72d3e3ca84c2 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/client.c @@ -0,0 +1,49 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#include "rm.h" + +void +nvkm_gsp_client_dtor(struct nvkm_gsp_client *client) +{ + const unsigned int id = client->object.handle - NVKM_RM_CLIENT(0); + struct nvkm_gsp *gsp = client->gsp; + + if (!gsp) + return; + + if (client->object.client) + nvkm_gsp_rm_free(&client->object); + + mutex_lock(&gsp->client_id.mutex); + idr_remove(&gsp->client_id.idr, id); + mutex_unlock(&gsp->client_id.mutex); + + client->gsp = NULL; +} + +int +nvkm_gsp_client_ctor(struct nvkm_gsp *gsp, struct nvkm_gsp_client *client) +{ + int id, ret; + + if (WARN_ON(!gsp->rm)) + return -ENOSYS; + + mutex_lock(&gsp->client_id.mutex); + id = idr_alloc(&gsp->client_id.idr, client, 0, NVKM_RM_CLIENT_MASK + 1, GFP_KERNEL); + mutex_unlock(&gsp->client_id.mutex); + if (id < 0) + return id; + + client->gsp = gsp; + client->object.client = client; + INIT_LIST_HEAD(&client->events); + + ret = gsp->rm->api->client->ctor(client, NVKM_RM_CLIENT(id)); + if (ret) + nvkm_gsp_client_dtor(client); + + return ret; +} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/handles.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/handles.h index 50f2f2a86b5a..3bdb5ad320d7 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/handles.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/handles.h @@ -8,6 +8,7 @@ /* RMAPI handles for various objects allocated from GSP-RM with RM_ALLOC. */ #define NVKM_RM_CLIENT(id) (0xc1d00000 | (id)) +#define NVKM_RM_CLIENT_MASK 0x0000ffff #define NVKM_RM_DEVICE 0xde1d0000 #define NVKM_RM_SUBDEVICE 0x5d1d0000 #define NVKM_RM_DISP 0x00730000 diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/client.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/client.c index 449338da1795..ec71f683e609 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/client.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/client.c @@ -23,57 +23,23 @@ #include "nvrm/client.h" -static void -r535_gsp_client_dtor(struct nvkm_gsp_client *client) -{ - struct nvkm_gsp *gsp = client->gsp; - - nvkm_gsp_rm_free(&client->object); - - mutex_lock(&gsp->client_id.mutex); - idr_remove(&gsp->client_id.idr, client->object.handle & 0xffff); - mutex_unlock(&gsp->client_id.mutex); - - client->gsp = NULL; -} - static int -r535_gsp_client_ctor(struct nvkm_gsp *gsp, struct nvkm_gsp_client *client) +r535_gsp_client_ctor(struct nvkm_gsp_client *client, u32 handle) { NV0000_ALLOC_PARAMETERS *args; - int ret; - - mutex_lock(&gsp->client_id.mutex); - ret = idr_alloc(&gsp->client_id.idr, client, 0, 0xffff + 1, GFP_KERNEL); - mutex_unlock(&gsp->client_id.mutex); - if (ret < 0) - return ret; - client->gsp = gsp; - client->object.client = client; - INIT_LIST_HEAD(&client->events); - - args = nvkm_gsp_rm_alloc_get(&client->object, NVKM_RM_CLIENT(ret), NV01_ROOT, sizeof(*args), + args = nvkm_gsp_rm_alloc_get(&client->object, handle, NV01_ROOT, sizeof(*args), &client->object); - if (IS_ERR(args)) { - r535_gsp_client_dtor(client); - return ret; - } + if (IS_ERR(args)) + return PTR_ERR(args); args->hClient = client->object.handle; args->processID = ~0; - ret = nvkm_gsp_rm_alloc_wr(&client->object, args); - if (ret) { - r535_gsp_client_dtor(client); - return ret; - } - - return 0; + return nvkm_gsp_rm_alloc_wr(&client->object, args); } const struct nvkm_rm_api_client r535_client = { .ctor = r535_gsp_client_ctor, - .dtor = r535_gsp_client_dtor, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h index eb018b73d26f..5e9d7351ecc4 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h @@ -59,8 +59,7 @@ struct nvkm_rm_api { } *alloc; const struct nvkm_rm_api_client { - int (*ctor)(struct nvkm_gsp *, struct nvkm_gsp_client *); - void (*dtor)(struct nvkm_gsp_client *); + int (*ctor)(struct nvkm_gsp_client *, u32 handle); } *client; const struct nvkm_rm_api_device { -- 2.49.0
Ben Skeggs
2025-May-17 00:09 UTC
[PATCH v3 46/62] drm/nouveau/pci: add PRI address of config space mirror to nvkm_pci_func
These registers have moved on GH100/GBxxx, and the GSP-RM init code uses hardcoded values from earlier GPUs to fill GspSystemInfo. Replace the per-GPU accessors in nvkm_pci_func with region info, and use it when initialising GspSystemInfo. Signed-off-by: Ben Skeggs <bskeggs at nvidia.com> Reviewed-by: Dave Airlie <airlied at redhat.com> Reviewed-by: Timur Tabi <ttabi at nvidia.com> Tested-by: Timur Tabi <ttabi at nvidia.com> --- .../drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c | 5 ++-- .../drm/nouveau/nvkm/subdev/gsp/rm/r570/gsp.c | 5 ++-- .../gpu/drm/nouveau/nvkm/subdev/pci/base.c | 10 ++++---- drivers/gpu/drm/nouveau/nvkm/subdev/pci/g84.c | 5 ++-- drivers/gpu/drm/nouveau/nvkm/subdev/pci/g92.c | 5 ++-- drivers/gpu/drm/nouveau/nvkm/subdev/pci/g94.c | 5 ++-- .../gpu/drm/nouveau/nvkm/subdev/pci/gf100.c | 5 ++-- .../gpu/drm/nouveau/nvkm/subdev/pci/gf106.c | 5 ++-- .../gpu/drm/nouveau/nvkm/subdev/pci/gk104.c | 5 ++-- .../gpu/drm/nouveau/nvkm/subdev/pci/gp100.c | 4 +-- .../gpu/drm/nouveau/nvkm/subdev/pci/nv04.c | 25 +------------------ .../gpu/drm/nouveau/nvkm/subdev/pci/nv40.c | 25 +------------------ .../gpu/drm/nouveau/nvkm/subdev/pci/nv46.c | 4 +-- .../gpu/drm/nouveau/nvkm/subdev/pci/nv4c.c | 4 +-- .../gpu/drm/nouveau/nvkm/subdev/pci/priv.h | 11 ++++---- 15 files changed, 33 insertions(+), 90 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c index ce3d4dd49ac8..e2171d0d25be 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c @@ -24,6 +24,7 @@ #include "priv.h" #include <core/pci.h> +#include <subdev/pci/priv.h> #include <subdev/timer.h> #include <subdev/vfn.h> #include <engine/fifo/chan.h> @@ -905,8 +906,8 @@ r535_gsp_set_system_info(struct nvkm_gsp *gsp) info->gpuPhysInstAddr = device->func->resource_addr(device, 3); info->nvDomainBusDeviceFunc = pci_dev_id(pdev->pdev); info->maxUserVa = TASK_SIZE; - info->pciConfigMirrorBase = 0x088000; - info->pciConfigMirrorSize = 0x001000; + info->pciConfigMirrorBase = device->pci->func->cfg.addr; + info->pciConfigMirrorSize = device->pci->func->cfg.size; r535_gsp_acpi_info(gsp, &info->acpiMethodData); return nvkm_gsp_rpc_wr(gsp, info, NVKM_GSP_RPC_REPLY_NOWAIT); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/gsp.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/gsp.c index 55795c49371f..a3c070d41923 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/gsp.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/gsp.c @@ -12,6 +12,7 @@ #include "nvrm/msgfn.h" #include <core/pci.h> +#include <subdev/pci/priv.h> static u32 r570_gsp_sr_data_size(struct nvkm_gsp *gsp) @@ -157,8 +158,8 @@ r570_gsp_set_system_info(struct nvkm_gsp *gsp) info->gpuPhysInstAddr = device->func->resource_addr(device, 3); info->nvDomainBusDeviceFunc = pci_dev_id(pdev); info->maxUserVa = TASK_SIZE; - info->pciConfigMirrorBase = 0x088000; - info->pciConfigMirrorSize = 0x001000; + info->pciConfigMirrorBase = device->pci->func->cfg.addr; + info->pciConfigMirrorSize = device->pci->func->cfg.size; info->PCIDeviceID = (pdev->device << 16) | pdev->vendor; info->PCISubDeviceID = (pdev->subsystem_device << 16) | pdev->subsystem_vendor; info->PCIRevisionID = pdev->revision; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c index 5a0de45d36ce..6867934256a7 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c @@ -39,26 +39,26 @@ nvkm_pci_msi_rearm(struct nvkm_device *device) u32 nvkm_pci_rd32(struct nvkm_pci *pci, u16 addr) { - return pci->func->rd32(pci, addr); + return nvkm_rd32(pci->subdev.device, pci->func->cfg.addr + addr); } void nvkm_pci_wr08(struct nvkm_pci *pci, u16 addr, u8 data) { - pci->func->wr08(pci, addr, data); + nvkm_wr08(pci->subdev.device, pci->func->cfg.addr + addr, data); } void nvkm_pci_wr32(struct nvkm_pci *pci, u16 addr, u32 data) { - pci->func->wr32(pci, addr, data); + nvkm_wr32(pci->subdev.device, pci->func->cfg.addr + addr, data); } u32 nvkm_pci_mask(struct nvkm_pci *pci, u16 addr, u32 mask, u32 value) { - u32 data = pci->func->rd32(pci, addr); - pci->func->wr32(pci, addr, (data & ~mask) | value); + u32 data = nvkm_pci_rd32(pci, addr); + nvkm_pci_wr32(pci, addr, (data & ~mask) | value); return data; } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/g84.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/g84.c index 5b29aacedef3..5308f6539a3f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/g84.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/g84.c @@ -132,10 +132,9 @@ g84_pcie_init(struct nvkm_pci *pci) static const struct nvkm_pci_func g84_pci_func = { + .cfg = { .addr = 0x088000, .size = 0x1000 }, + .init = g84_pci_init, - .rd32 = nv40_pci_rd32, - .wr08 = nv40_pci_wr08, - .wr32 = nv40_pci_wr32, .msi_rearm = nv46_pci_msi_rearm, .pcie.init = g84_pcie_init, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/g92.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/g92.c index a9e0674009c6..8ae7aa02e675 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/g92.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/g92.c @@ -33,10 +33,9 @@ g92_pcie_version_supported(struct nvkm_pci *pci) static const struct nvkm_pci_func g92_pci_func = { + .cfg = { .addr = 0x088000, .size = 0x1000 }, + .init = g84_pci_init, - .rd32 = nv40_pci_rd32, - .wr08 = nv40_pci_wr08, - .wr32 = nv40_pci_wr32, .msi_rearm = nv46_pci_msi_rearm, .pcie.init = g84_pcie_init, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/g94.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/g94.c index 7bacd0693283..df745d0690ca 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/g94.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/g94.c @@ -25,10 +25,9 @@ static const struct nvkm_pci_func g94_pci_func = { + .cfg = { .addr = 0x088000, .size = 0x1000 }, + .init = g84_pci_init, - .rd32 = nv40_pci_rd32, - .wr08 = nv40_pci_wr08, - .wr32 = nv40_pci_wr32, .msi_rearm = nv40_pci_msi_rearm, .pcie.init = g84_pcie_init, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/gf100.c index 099906092fe1..6ce941df87b7 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/gf100.c @@ -78,10 +78,9 @@ gf100_pcie_set_link(struct nvkm_pci *pci, enum nvkm_pcie_speed speed, u8 width) static const struct nvkm_pci_func gf100_pci_func = { + .cfg = { .addr = 0x088000, .size = 0x1000 }, + .init = g84_pci_init, - .rd32 = nv40_pci_rd32, - .wr08 = nv40_pci_wr08, - .wr32 = nv40_pci_wr32, .msi_rearm = gf100_pci_msi_rearm, .pcie.init = gf100_pcie_init, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/gf106.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/gf106.c index bcde609ba866..712ca7e0959a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/gf106.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/gf106.c @@ -25,10 +25,9 @@ static const struct nvkm_pci_func gf106_pci_func = { + .cfg = { .addr = 0x088000, .size = 0x1000 }, + .init = g84_pci_init, - .rd32 = nv40_pci_rd32, - .wr08 = nv40_pci_wr08, - .wr32 = nv40_pci_wr32, .msi_rearm = nv40_pci_msi_rearm, .pcie.init = gf100_pcie_init, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/gk104.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/gk104.c index 6be87ecffc89..ec6d0a7de995 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/gk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/gk104.c @@ -204,10 +204,9 @@ gk104_pcie_set_link(struct nvkm_pci *pci, enum nvkm_pcie_speed speed, u8 width) static const struct nvkm_pci_func gk104_pci_func = { + .cfg = { .addr = 0x088000, .size = 0x1000 }, + .init = g84_pci_init, - .rd32 = nv40_pci_rd32, - .wr08 = nv40_pci_wr08, - .wr32 = nv40_pci_wr32, .msi_rearm = nv40_pci_msi_rearm, .pcie.init = gk104_pcie_init, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/gp100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/gp100.c index a5fafda0014d..4204316a544f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/gp100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/gp100.c @@ -31,9 +31,7 @@ gp100_pci_msi_rearm(struct nvkm_pci *pci) static const struct nvkm_pci_func gp100_pci_func = { - .rd32 = nv40_pci_rd32, - .wr08 = nv40_pci_wr08, - .wr32 = nv40_pci_wr32, + .cfg = { .addr = 0x088000, .size = 0x1000 }, .msi_rearm = gp100_pci_msi_rearm, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/nv04.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/nv04.c index 9ab64194b185..b8a3f6850fa7 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/nv04.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/nv04.c @@ -23,32 +23,9 @@ */ #include "priv.h" -static u32 -nv04_pci_rd32(struct nvkm_pci *pci, u16 addr) -{ - struct nvkm_device *device = pci->subdev.device; - return nvkm_rd32(device, 0x001800 + addr); -} - -static void -nv04_pci_wr08(struct nvkm_pci *pci, u16 addr, u8 data) -{ - struct nvkm_device *device = pci->subdev.device; - nvkm_wr08(device, 0x001800 + addr, data); -} - -static void -nv04_pci_wr32(struct nvkm_pci *pci, u16 addr, u32 data) -{ - struct nvkm_device *device = pci->subdev.device; - nvkm_wr32(device, 0x001800 + addr, data); -} - static const struct nvkm_pci_func nv04_pci_func = { - .rd32 = nv04_pci_rd32, - .wr08 = nv04_pci_wr08, - .wr32 = nv04_pci_wr32, + .cfg = { .addr = 0x001800, .size = 0x1000 }, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/nv40.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/nv40.c index 6a3c31cf0200..1971dbbdeb2b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/nv40.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/nv40.c @@ -23,27 +23,6 @@ */ #include "priv.h" -u32 -nv40_pci_rd32(struct nvkm_pci *pci, u16 addr) -{ - struct nvkm_device *device = pci->subdev.device; - return nvkm_rd32(device, 0x088000 + addr); -} - -void -nv40_pci_wr08(struct nvkm_pci *pci, u16 addr, u8 data) -{ - struct nvkm_device *device = pci->subdev.device; - nvkm_wr08(device, 0x088000 + addr, data); -} - -void -nv40_pci_wr32(struct nvkm_pci *pci, u16 addr, u32 data) -{ - struct nvkm_device *device = pci->subdev.device; - nvkm_wr32(device, 0x088000 + addr, data); -} - void nv40_pci_msi_rearm(struct nvkm_pci *pci) { @@ -52,9 +31,7 @@ nv40_pci_msi_rearm(struct nvkm_pci *pci) static const struct nvkm_pci_func nv40_pci_func = { - .rd32 = nv40_pci_rd32, - .wr08 = nv40_pci_wr08, - .wr32 = nv40_pci_wr32, + .cfg = { .addr = 0x088000, .size = 0x1000 }, .msi_rearm = nv40_pci_msi_rearm, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/nv46.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/nv46.c index 9cad17f178ec..0093eabac9ae 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/nv46.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/nv46.c @@ -38,9 +38,7 @@ nv46_pci_msi_rearm(struct nvkm_pci *pci) static const struct nvkm_pci_func nv46_pci_func = { - .rd32 = nv40_pci_rd32, - .wr08 = nv40_pci_wr08, - .wr32 = nv40_pci_wr32, + .cfg = { .addr = 0x088000, .size = 0x1000 }, .msi_rearm = nv46_pci_msi_rearm, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/nv4c.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/nv4c.c index 741e34bf307c..b445081bb80e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/nv4c.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/nv4c.c @@ -25,9 +25,7 @@ static const struct nvkm_pci_func nv4c_pci_func = { - .rd32 = nv40_pci_rd32, - .wr08 = nv40_pci_wr08, - .wr32 = nv40_pci_wr32, + .cfg = { .addr = 0x088000, .size = 0x1000 }, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/priv.h index 9b7583532962..988eeee1471c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/priv.h @@ -8,10 +8,12 @@ int nvkm_pci_new_(const struct nvkm_pci_func *, struct nvkm_device *, enum nvkm_ struct nvkm_pci **); struct nvkm_pci_func { + struct { + u32 addr; + u16 size; + } cfg; + void (*init)(struct nvkm_pci *); - u32 (*rd32)(struct nvkm_pci *, u16 addr); - void (*wr08)(struct nvkm_pci *, u16 addr, u8 data); - void (*wr32)(struct nvkm_pci *, u16 addr, u32 data); void (*msi_rearm)(struct nvkm_pci *); struct { @@ -27,9 +29,6 @@ struct nvkm_pci_func { } pcie; }; -u32 nv40_pci_rd32(struct nvkm_pci *, u16); -void nv40_pci_wr08(struct nvkm_pci *, u16, u8); -void nv40_pci_wr32(struct nvkm_pci *, u16, u32); void nv40_pci_msi_rearm(struct nvkm_pci *); void nv46_pci_msi_rearm(struct nvkm_pci *); -- 2.49.0
Ben Skeggs
2025-May-17 00:09 UTC
[PATCH v3 47/62] drm/nouveau/instmem: add hal for set_bar0_window_addr()
GH100/GBxxx have moved the register that controls where in VRAM the the BAR0 NV_PRAMIN window points. Add a HAL for this, as the BAR0 window is needed for BAR2 bootstrap. Signed-off-by: Ben Skeggs <bskeggs at nvidia.com> Reviewed-by: Dave Airlie <airlied at redhat.com> Reviewed-by: Timur Tabi <ttabi at nvidia.com> Tested-by: Timur Tabi <ttabi at nvidia.com> --- .../gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/fbsr.c | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c | 11 +++++++++-- drivers/gpu/drm/nouveau/nvkm/subdev/instmem/priv.h | 1 + 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/fbsr.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/fbsr.c index 1976d0030d17..150e22fde2ac 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/fbsr.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/fbsr.c @@ -317,6 +317,7 @@ r535_instmem_new(const struct nvkm_instmem_func *hw, rm->memory_new = hw->memory_new; rm->memory_wrap = hw->memory_wrap; rm->zero = false; + rm->set_bar0_window_addr = hw->set_bar0_window_addr; ret = nv50_instmem_new_(rm, device, type, inst, pinstmem); if (ret) diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c index dd5b5a17ece0..0ef66d7d5e51 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c @@ -65,7 +65,7 @@ nv50_instobj_wr32_slow(struct nvkm_memory *memory, u64 offset, u32 data) spin_lock_irqsave(&imem->base.lock, flags); if (unlikely(imem->addr != base)) { - nvkm_wr32(device, 0x001700, base >> 16); + imem->base.func->set_bar0_window_addr(device, base); imem->addr = base; } nvkm_wr32(device, 0x700000 + addr, data); @@ -85,7 +85,7 @@ nv50_instobj_rd32_slow(struct nvkm_memory *memory, u64 offset) spin_lock_irqsave(&imem->base.lock, flags); if (unlikely(imem->addr != base)) { - nvkm_wr32(device, 0x001700, base >> 16); + imem->base.func->set_bar0_window_addr(device, base); imem->addr = base; } data = nvkm_rd32(device, 0x700000 + addr); @@ -394,6 +394,12 @@ nv50_instobj_new(struct nvkm_instmem *imem, u32 size, u32 align, bool zero, * instmem subdev implementation *****************************************************************************/ +static void +nv50_instmem_set_bar0_window_addr(struct nvkm_device *device, u64 addr) +{ + nvkm_wr32(device, 0x001700, addr >> 16); +} + static void nv50_instmem_fini(struct nvkm_instmem *base) { @@ -415,6 +421,7 @@ nv50_instmem = { .memory_new = nv50_instobj_new, .memory_wrap = nv50_instobj_wrap, .zero = false, + .set_bar0_window_addr = nv50_instmem_set_bar0_window_addr, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/priv.h index 4c14c96fb60a..d5b5fcd9262b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/priv.h @@ -16,6 +16,7 @@ struct nvkm_instmem_func { bool zero, struct nvkm_memory **); int (*memory_wrap)(struct nvkm_instmem *, struct nvkm_memory *, struct nvkm_memory **); bool zero; + void (*set_bar0_window_addr)(struct nvkm_device *, u64 addr); }; int nv50_instmem_new_(const struct nvkm_instmem_func *, struct nvkm_device *, -- 2.49.0
Ben Skeggs
2025-May-17 00:09 UTC
[PATCH v3 48/62] drm/nouveau/mmu: bump up the maximum page table depth
GH100/GBxxx have 6-level page tables. Signed-off-by: Ben Skeggs <bskeggs at nvidia.com> Reviewed-by: Dave Airlie <airlied at redhat.com> Reviewed-by: Timur Tabi <ttabi at nvidia.com> Tested-by: Timur Tabi <ttabi at nvidia.com> --- drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h | 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h index 935b1cacd528..7188e3eb2d07 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h @@ -8,7 +8,7 @@ struct nvkm_vma { struct list_head head; struct rb_node tree; u64 addr; - u64 size:50; + u64 size; bool mapref:1; /* PTs (de)referenced on (un)map (vs pre-allocated). */ bool sparse:1; /* Unmapped PDEs/PTEs will not trigger MMU faults. */ #define NVKM_VMA_PAGE_NONE 7 diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c index 9c97800fe037..b54397e5364c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c @@ -19,7 +19,7 @@ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ -#define NVKM_VMM_LEVELS_MAX 5 +#define NVKM_VMM_LEVELS_MAX 6 #include "vmm.h" #include <subdev/fb.h> -- 2.49.0
Ben Skeggs
2025-May-17 00:09 UTC
[PATCH v3 49/62] drm/nouveau/gsp: fetch level shift and PDE from BAR2 VMM
When mirroring BAR2 page tables to RM, we need to know the level shift for the root page table (which is currently hardcoded), as well as the raw PDE value (which is currently hardcoded in GP1xx-AD1xx format). In order to support GH100/GBxxx, modify the code to determine the page shift from per-GPU info in nvkm_vmm_page, as well as read the relevant PDE back from the root page table rather than recalculating it. Signed-off-by: Ben Skeggs <bskeggs at nvidia.com> Reviewed-by: Dave Airlie <airlied at redhat.com> Reviewed-by: Timur Tabi <ttabi at nvidia.com> Tested-by: Timur Tabi <ttabi at nvidia.com> --- .../drm/nouveau/nvkm/subdev/gsp/rm/r535/bar.c | 23 ++++++++++++++----- 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/bar.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/bar.c index b8fb8150ae48..91242f09648e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/bar.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/bar.c @@ -50,7 +50,7 @@ r535_bar_bar2_wait(struct nvkm_bar *base) } static int -r535_bar_bar2_update_pde(struct nvkm_gsp *gsp, u64 addr) +r535_bar_bar2_update_pde(struct nvkm_gsp *gsp, u8 page_shift, u64 pdbe) { rpc_update_bar_pde_v15_00 *rpc; @@ -59,8 +59,8 @@ r535_bar_bar2_update_pde(struct nvkm_gsp *gsp, u64 addr) return -EIO; rpc->info.barType = NV_RPC_UPDATE_PDE_BAR_2; - rpc->info.entryValue = addr ? ((addr >> 4) | 2) : 0; /* PD3 entry format! */ - rpc->info.entryLevelShift = 47; //XXX: probably fetch this from mmu! + rpc->info.entryValue = pdbe; + rpc->info.entryLevelShift = page_shift; return nvkm_gsp_rpc_wr(gsp, rpc, NVKM_GSP_RPC_REPLY_RECV); } @@ -68,12 +68,13 @@ r535_bar_bar2_update_pde(struct nvkm_gsp *gsp, u64 addr) static void r535_bar_bar2_fini(struct nvkm_bar *bar) { + struct nvkm_vmm *vmm = gf100_bar(bar)->bar[0].vmm; struct nvkm_gsp *gsp = bar->subdev.device->gsp; bar->flushBAR2 = bar->flushBAR2PhysMode; nvkm_done(bar->flushFBZero); - WARN_ON(r535_bar_bar2_update_pde(gsp, 0)); + WARN_ON(r535_bar_bar2_update_pde(gsp, vmm->func->page[0].shift, 0)); } static void @@ -82,8 +83,18 @@ r535_bar_bar2_init(struct nvkm_bar *bar) struct nvkm_device *device = bar->subdev.device; struct nvkm_vmm *vmm = gf100_bar(bar)->bar[0].vmm; struct nvkm_gsp *gsp = device->gsp; - - WARN_ON(r535_bar_bar2_update_pde(gsp, vmm->pd->pde[0]->pt[0]->addr)); + struct nvkm_memory *pdb = vmm->pd->pt[0]->memory; + u32 pdb_offset = vmm->pd->pt[0]->base; + u32 pdbe_lo, pdbe_hi; + u64 pdbe; + + nvkm_kmap(pdb); + pdbe_lo = nvkm_ro32(pdb, pdb_offset + 0); + pdbe_hi = nvkm_ro32(pdb, pdb_offset + 4); + pdbe = ((u64)pdbe_hi << 32) | pdbe_lo; + nvkm_done(pdb); + + WARN_ON(r535_bar_bar2_update_pde(gsp, vmm->func->page[0].shift, pdbe)); vmm->rm.bar2_pdb = gsp->bar.rm_bar2_pdb; if (!bar->flushFBZero) { -- 2.49.0
Ben Skeggs
2025-May-17 00:09 UTC
[PATCH v3 50/62] drm/nouveau/gsp: init client VMMs with NV0080_CTRL_DMA_SET_PAGE_DIRECTORY
The current code using NV90F1_CTRL_CMD_VASPACE_COPY_SERVER_RESERVED_PDES not only requires changes to support the new page table layout used on Hopper/Blackwell GPUs, but is also broken in that it always mirrors the PDEs used for virtual address 0, rather than the area reserved for RM. This works fine for the non-NVK case where the kernel has full control of the VMM layout and things end up in the right place, but NVK puts its kernel reserved area much higher in the address space. Fixing the code to work at any VA is not enough as some parts of RM want the reserved area in a specific location, and NVK would then hit other assertions in RM instead. Fortunately, it appears that RM never needs to allocate anything within its reserved area for DRM clients, and the COPY_SERVER_RESERVED_PDES control call primarily serves to allow RM to locate the root page table when initialising a channel's instance block. Flag VMMs allocated by the DRM driver as externally owned, and use NV0080_CTRL_CMD_DMA_SET_PAGE_DIRECTORY to inform RM of the root page table in a similar way to NVIDIA's UVM driver. The COPY_SERVER_RESERVED_PDES paths are kept for the golden context image and gr scrubber channel, where RM needs the reserved area. Signed-off-by: Ben Skeggs <bskeggs at nvidia.com> Reviewed-by: Dave Airlie <airlied at redhat.com> Reviewed-by: Timur Tabi <ttabi at nvidia.com> Tested-by: Timur Tabi <ttabi at nvidia.com> --- .../gpu/drm/nouveau/include/nvkm/subdev/mmu.h | 1 + .../drm/nouveau/nvkm/subdev/gsp/rm/r535/gr.c | 3 +- .../nvkm/subdev/gsp/rm/r535/nvrm/vmm.h | 42 ++++++++++++ .../drm/nouveau/nvkm/subdev/gsp/rm/r535/vmm.c | 66 ++++++++++++++++--- .../drm/nouveau/nvkm/subdev/gsp/rm/r570/gr.c | 2 +- .../gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h | 3 +- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c | 8 +-- 7 files changed, 106 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h index 7188e3eb2d07..4cab139f3236 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h @@ -73,6 +73,7 @@ struct nvkm_vmm { struct nvkm_gsp_object object; struct nvkm_vma *rsvd; + bool external; } rm; }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gr.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gr.c index 1f5cf21f3f61..ddb57d5e73d6 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gr.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gr.c @@ -276,7 +276,6 @@ r535_gr_oneinit(struct nvkm_gr *base) struct nvkm_device *device = subdev->device; struct nvkm_gsp *gsp = device->gsp; struct nvkm_rm *rm = gsp->rm; - struct nvkm_mmu *mmu = device->mmu; struct { struct nvkm_memory *inst; struct nvkm_vmm *vmm; @@ -295,7 +294,7 @@ r535_gr_oneinit(struct nvkm_gr *base) if (ret) goto done; - ret = mmu->func->promote_vmm(golden.vmm); + ret = r535_mmu_vaspace_new(golden.vmm, NVKM_RM_VASPACE, false); if (ret) goto done; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvrm/vmm.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvrm/vmm.h index f58edf62e4ae..f6ec04efd119 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvrm/vmm.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvrm/vmm.h @@ -23,6 +23,11 @@ typedef struct #define NV_VASPACE_ALLOCATION_INDEX_GPU_NEW 0x00 //<! Create new VASpace, by default +#define NV_VASPACE_ALLOCATION_FLAGS_IS_EXTERNALLY_OWNED BIT(3) + +#define SPLIT_VAS_SERVER_RM_MANAGED_VA_START 0x100000000ULL // 4GB +#define SPLIT_VAS_SERVER_RM_MANAGED_VA_SIZE 0x20000000ULL // 512MB + #define GMMU_FMT_MAX_LEVELS 6U #define NV90F1_CTRL_CMD_VASPACE_COPY_SERVER_RESERVED_PDES (0x90f10106U) /* finn: Evaluated from "(FINN_FERMI_VASPACE_A_VASPACE_INTERFACE_ID << 8) | NV90F1_CTRL_VASPACE_COPY_SERVER_RESERVED_PDES_PARAMS_MESSAGE_ID" */ @@ -87,4 +92,41 @@ typedef struct NV90F1_CTRL_VASPACE_COPY_SERVER_RESERVED_PDES_PARAMS { NvU8 pageShift; } levels[GMMU_FMT_MAX_LEVELS]; } NV90F1_CTRL_VASPACE_COPY_SERVER_RESERVED_PDES_PARAMS; + +#define NV0080_CTRL_CMD_DMA_SET_PAGE_DIRECTORY (0x801813U) /* finn: Evaluated from "(FINN_NV01_DEVICE_0_DMA_INTERFACE_ +ID << 8) | NV0080_CTRL_DMA_SET_PAGE_DIRECTORY_PARAMS_MESSAGE_ID" */ + +typedef struct NV0080_CTRL_DMA_SET_PAGE_DIRECTORY_PARAMS { + NV_DECLARE_ALIGNED(NvU64 physAddress, 8); + NvU32 numEntries; + NvU32 flags; + NvHandle hVASpace; + NvU32 chId; + NvU32 subDeviceId; // ID+1, 0 for BC + NvU32 pasid; +} NV0080_CTRL_DMA_SET_PAGE_DIRECTORY_PARAMS; + +#define NV0080_CTRL_DMA_SET_PAGE_DIRECTORY_FLAGS_APERTURE 1:0 +#define NV0080_CTRL_DMA_SET_PAGE_DIRECTORY_FLAGS_APERTURE_VIDMEM (0x00000000U) +#define NV0080_CTRL_DMA_SET_PAGE_DIRECTORY_FLAGS_APERTURE_SYSMEM_COH (0x00000001U) +#define NV0080_CTRL_DMA_SET_PAGE_DIRECTORY_FLAGS_APERTURE_SYSMEM_NONCOH (0x00000002U) +#define NV0080_CTRL_DMA_SET_PAGE_DIRECTORY_FLAGS_PRESERVE_PDES 2:2 +#define NV0080_CTRL_DMA_SET_PAGE_DIRECTORY_FLAGS_PRESERVE_PDES_FALSE (0x00000000U) +#define NV0080_CTRL_DMA_SET_PAGE_DIRECTORY_FLAGS_PRESERVE_PDES_TRUE (0x00000001U) +#define NV0080_CTRL_DMA_SET_PAGE_DIRECTORY_FLAGS_ALL_CHANNELS 3:3 +#define NV0080_CTRL_DMA_SET_PAGE_DIRECTORY_FLAGS_ALL_CHANNELS_FALSE (0x00000000U) +#define NV0080_CTRL_DMA_SET_PAGE_DIRECTORY_FLAGS_ALL_CHANNELS_TRUE (0x00000001U) +#define NV0080_CTRL_DMA_SET_PAGE_DIRECTORY_FLAGS_IGNORE_CHANNEL_BUSY 4:4 +#define NV0080_CTRL_DMA_SET_PAGE_DIRECTORY_FLAGS_IGNORE_CHANNEL_BUSY_FALSE (0x00000000U) +#define NV0080_CTRL_DMA_SET_PAGE_DIRECTORY_FLAGS_IGNORE_CHANNEL_BUSY_TRUE (0x00000001U) +#define NV0080_CTRL_DMA_SET_PAGE_DIRECTORY_FLAGS_EXTEND_VASPACE 5:5 +#define NV0080_CTRL_DMA_SET_PAGE_DIRECTORY_FLAGS_EXTEND_VASPACE_FALSE (0x00000000U) +#define NV0080_CTRL_DMA_SET_PAGE_DIRECTORY_FLAGS_EXTEND_VASPACE_TRUE (0x00000001U) + +#define NV0080_CTRL_CMD_DMA_UNSET_PAGE_DIRECTORY (0x801814U) /* finn: Evaluated from "(FINN_NV01_DEVICE_0_DMA_INTERFACE_ID << 8) | NV0080_CTRL_DMA_UNSET_PAGE_DIRECTORY_PARAMS_MESSAGE_ID" */ + +typedef struct NV0080_CTRL_DMA_UNSET_PAGE_DIRECTORY_PARAMS { + NvHandle hVASpace; + NvU32 subDeviceId; // ID+1, 0 for BC +} NV0080_CTRL_DMA_UNSET_PAGE_DIRECTORY_PARAMS; #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/vmm.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/vmm.c index 05690f745bb4..dbddc5cc333d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/vmm.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/vmm.c @@ -21,10 +21,36 @@ */ #include <subdev/mmu/vmm.h> +#include <nvhw/drf.h> #include "nvrm/vmm.h" +void +r535_mmu_vaspace_del(struct nvkm_vmm *vmm) +{ + if (vmm->rm.external) { + NV0080_CTRL_DMA_UNSET_PAGE_DIRECTORY_PARAMS *ctrl; + + ctrl = nvkm_gsp_rm_ctrl_get(&vmm->rm.device.object, + NV0080_CTRL_CMD_DMA_UNSET_PAGE_DIRECTORY, + sizeof(*ctrl)); + if (!IS_ERR(ctrl)) { + ctrl->hVASpace = vmm->rm.object.handle; + + WARN_ON(nvkm_gsp_rm_ctrl_wr(&vmm->rm.device.object, ctrl)); + } + + vmm->rm.external = false; + } + + nvkm_gsp_rm_free(&vmm->rm.object); + nvkm_gsp_device_dtor(&vmm->rm.device); + nvkm_gsp_client_dtor(&vmm->rm.client); + + nvkm_vmm_put(vmm, &vmm->rm.rsvd); +} + int -r535_mmu_vaspace_new(struct nvkm_vmm *vmm, u32 handle) +r535_mmu_vaspace_new(struct nvkm_vmm *vmm, u32 handle, bool external) { NV_VASPACE_ALLOCATION_PARAMETERS *args; int ret; @@ -40,12 +66,14 @@ r535_mmu_vaspace_new(struct nvkm_vmm *vmm, u32 handle) return PTR_ERR(args); args->index = NV_VASPACE_ALLOCATION_INDEX_GPU_NEW; + if (external) + args->flags = NV_VASPACE_ALLOCATION_FLAGS_IS_EXTERNALLY_OWNED; ret = nvkm_gsp_rm_alloc_wr(&vmm->rm.object, args); if (ret) return ret; - { + if (!external) { NV90F1_CTRL_VASPACE_COPY_SERVER_RESERVED_PDES_PARAMS *ctrl; mutex_lock(&vmm->mutex.vmm); @@ -55,6 +83,11 @@ r535_mmu_vaspace_new(struct nvkm_vmm *vmm, u32 handle) if (ret) return ret; + /* Some parts of RM expect the server-reserved area to be in a specific location. */ + if (WARN_ON(vmm->rm.rsvd->addr != SPLIT_VAS_SERVER_RM_MANAGED_VA_START || + vmm->rm.rsvd->size != SPLIT_VAS_SERVER_RM_MANAGED_VA_SIZE)) + return -EINVAL; + ctrl = nvkm_gsp_rm_ctrl_get(&vmm->rm.object, NV90F1_CTRL_CMD_VASPACE_COPY_SERVER_RESERVED_PDES, sizeof(*ctrl)); @@ -73,14 +106,29 @@ r535_mmu_vaspace_new(struct nvkm_vmm *vmm, u32 handle) ctrl->levels[1].size = 0x1000; ctrl->levels[1].aperture = 1; ctrl->levels[1].pageShift = 0x26; - if (vmm->pd->pde[0]->pde[0]) { - ctrl->levels[2].physAddress = vmm->pd->pde[0]->pde[0]->pt[0]->addr; - ctrl->levels[2].size = 0x1000; - ctrl->levels[2].aperture = 1; - ctrl->levels[2].pageShift = 0x1d; - } + ctrl->levels[2].physAddress = vmm->pd->pde[0]->pde[0]->pt[0]->addr; + ctrl->levels[2].size = 0x1000; + ctrl->levels[2].aperture = 1; + ctrl->levels[2].pageShift = 0x1d; ret = nvkm_gsp_rm_ctrl_wr(&vmm->rm.object, ctrl); + } else { + NV0080_CTRL_DMA_SET_PAGE_DIRECTORY_PARAMS *ctrl; + + ctrl = nvkm_gsp_rm_ctrl_get(&vmm->rm.device.object, + NV0080_CTRL_CMD_DMA_SET_PAGE_DIRECTORY, + sizeof(*ctrl)); + if (IS_ERR(ctrl)) + return PTR_ERR(ctrl); + + ctrl->physAddress = vmm->pd->pt[0]->addr; + ctrl->numEntries = 1 << vmm->func->page[0].desc->bits; + ctrl->flags = NVDEF(NV0080_CTRL_DMA_SET_PAGE_DIRECTORY, FLAGS, APERTURE, VIDMEM); + ctrl->hVASpace = vmm->rm.object.handle; + + ret = nvkm_gsp_rm_ctrl_wr(&vmm->rm.device.object, ctrl); + if (ret == 0) + vmm->rm.external = true; } return ret; @@ -89,7 +137,7 @@ r535_mmu_vaspace_new(struct nvkm_vmm *vmm, u32 handle) static int r535_mmu_promote_vmm(struct nvkm_vmm *vmm) { - return r535_mmu_vaspace_new(vmm, NVKM_RM_VASPACE); + return r535_mmu_vaspace_new(vmm, NVKM_RM_VASPACE, true); } static void diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/gr.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/gr.c index c92ec231f09a..b6cced9b8aa1 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/gr.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/gr.c @@ -126,7 +126,7 @@ r570_gr_scrubber_init(struct r535_gr *gr) if (ret) goto done; - ret = r535_mmu_vaspace_new(gr->scrubber.vmm, KGRAPHICS_SCRUBBER_HANDLE_VAS); + ret = r535_mmu_vaspace_new(gr->scrubber.vmm, KGRAPHICS_SCRUBBER_HANDLE_VAS, false); if (ret) goto done; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h index fc63ac61a9d1..ead48c106bb6 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h @@ -147,7 +147,8 @@ extern const struct nvkm_rm_api_alloc r535_alloc; extern const struct nvkm_rm_api_client r535_client; void r535_gsp_client_dtor(struct nvkm_gsp_client *); extern const struct nvkm_rm_api_device r535_device; -int r535_mmu_vaspace_new(struct nvkm_vmm *, u32 handle); +int r535_mmu_vaspace_new(struct nvkm_vmm *, u32 handle, bool external); +void r535_mmu_vaspace_del(struct nvkm_vmm *); extern const struct nvkm_rm_api_fbsr r535_fbsr; void r535_fbsr_resume(struct nvkm_gsp *); int r535_fbsr_memlist(struct nvkm_gsp_device *, u32 handle, enum nvkm_memory_target, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c index b54397e5364c..f95c58b67633 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c @@ -1030,12 +1030,8 @@ nvkm_vmm_dtor(struct nvkm_vmm *vmm) struct nvkm_vma *vma; struct rb_node *node; - if (vmm->rm.client.gsp) { - nvkm_gsp_rm_free(&vmm->rm.object); - nvkm_gsp_device_dtor(&vmm->rm.device); - nvkm_gsp_client_dtor(&vmm->rm.client); - nvkm_vmm_put(vmm, &vmm->rm.rsvd); - } + if (vmm->rm.client.gsp) + r535_mmu_vaspace_del(vmm); if (0) nvkm_vmm_dump(vmm); -- 2.49.0
Ben Skeggs
2025-May-17 00:09 UTC
[PATCH v3 51/62] drm/nouveau/gsp: support deeper page tables in COPY_SERVER_RESERVED_PDES
Use data from 'struct nvkm_vmm_page/desc' to determine which PDEs need to be mirrored to RM instead of hardcoded values for pre-Hopper page tables. Needed to support Hopper/Blackwell. Signed-off-by: Ben Skeggs <bskeggs at nvidia.com> Reviewed-by: Dave Airlie <airlied at redhat.com> Reviewed-by: Timur Tabi <ttabi at nvidia.com> Tested-by: Timur Tabi <ttabi at nvidia.com> --- .../drm/nouveau/nvkm/subdev/gsp/rm/r535/vmm.c | 47 +++++++++++++------ 1 file changed, 32 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/vmm.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/vmm.c index dbddc5cc333d..52f2e5f14517 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/vmm.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/vmm.c @@ -75,9 +75,22 @@ r535_mmu_vaspace_new(struct nvkm_vmm *vmm, u32 handle, bool external) if (!external) { NV90F1_CTRL_VASPACE_COPY_SERVER_RESERVED_PDES_PARAMS *ctrl; + u8 page_shift = 29; /* 512MiB */ + const u64 page_size = BIT_ULL(page_shift); + const struct nvkm_vmm_page *page; + const struct nvkm_vmm_desc *desc; + struct nvkm_vmm_pt *pd = vmm->pd; + + for (page = vmm->func->page; page->shift; page++) { + if (page->shift == page_shift) + break; + } + + if (WARN_ON(!page->shift)) + return -EINVAL; mutex_lock(&vmm->mutex.vmm); - ret = nvkm_vmm_get_locked(vmm, true, false, false, 0x1d, 32, 0x20000000, + ret = nvkm_vmm_get_locked(vmm, true, false, false, page_shift, 32, page_size, &vmm->rm.rsvd); mutex_unlock(&vmm->mutex.vmm); if (ret) @@ -94,22 +107,26 @@ r535_mmu_vaspace_new(struct nvkm_vmm *vmm, u32 handle, bool external) if (IS_ERR(ctrl)) return PTR_ERR(ctrl); - ctrl->pageSize = 0x20000000; + ctrl->pageSize = page_size; ctrl->virtAddrLo = vmm->rm.rsvd->addr; ctrl->virtAddrHi = vmm->rm.rsvd->addr + vmm->rm.rsvd->size - 1; - ctrl->numLevelsToCopy = vmm->pd->pde[0]->pde[0] ? 3 : 2; - ctrl->levels[0].physAddress = vmm->pd->pt[0]->addr; - ctrl->levels[0].size = 0x20; - ctrl->levels[0].aperture = 1; - ctrl->levels[0].pageShift = 0x2f; - ctrl->levels[1].physAddress = vmm->pd->pde[0]->pt[0]->addr; - ctrl->levels[1].size = 0x1000; - ctrl->levels[1].aperture = 1; - ctrl->levels[1].pageShift = 0x26; - ctrl->levels[2].physAddress = vmm->pd->pde[0]->pde[0]->pt[0]->addr; - ctrl->levels[2].size = 0x1000; - ctrl->levels[2].aperture = 1; - ctrl->levels[2].pageShift = 0x1d; + + for (desc = page->desc; desc->bits; desc++) { + ctrl->numLevelsToCopy++; + page_shift += desc->bits; + } + desc--; + + for (int i = 0; i < ctrl->numLevelsToCopy; i++, desc--) { + page_shift -= desc->bits; + + ctrl->levels[i].physAddress = pd->pt[0]->addr; + ctrl->levels[i].size = (1 << desc->bits) * desc->size; + ctrl->levels[i].aperture = 1; + ctrl->levels[i].pageShift = page_shift; + + pd = pd->pde[0]; + } ret = nvkm_gsp_rm_ctrl_wr(&vmm->rm.object, ctrl); } else { -- 2.49.0
Ben Skeggs
2025-May-17 00:09 UTC
[PATCH v3 52/62] drm/nouveau/gv100-: switch to volta semaphore methods
HOPPER_CHANNEL_GPFIFO_A removes the SEMAPHORE[A-D] methods that are currently used by nouveau to implement fences on GF100 and newer. Switch to the newer SEM methods available from VOLTA_CHANNEL_GPFIFO, which are also available on the Hopper/Blackwell host classes. Signed-off-by: Ben Skeggs <bskeggs at nvidia.com> Reviewed-by: Dave Airlie <airlied at redhat.com> Reviewed-by: Timur Tabi <ttabi at nvidia.com> Tested-by: Timur Tabi <ttabi at nvidia.com> --- drivers/gpu/drm/nouveau/Kbuild | 1 + drivers/gpu/drm/nouveau/gv100_fence.c | 93 +++++++++++++++++++ .../drm/nouveau/include/nvhw/class/clc36f.h | 52 +++++++++++ .../gpu/drm/nouveau/include/nvif/push906f.h | 1 + drivers/gpu/drm/nouveau/nouveau_drm.c | 4 +- drivers/gpu/drm/nouveau/nouveau_fence.h | 1 + 6 files changed, 151 insertions(+), 1 deletion(-) create mode 100644 drivers/gpu/drm/nouveau/gv100_fence.c create mode 100644 drivers/gpu/drm/nouveau/include/nvhw/class/clc36f.h diff --git a/drivers/gpu/drm/nouveau/Kbuild b/drivers/gpu/drm/nouveau/Kbuild index 0759ba15954b..385d24530d1e 100644 --- a/drivers/gpu/drm/nouveau/Kbuild +++ b/drivers/gpu/drm/nouveau/Kbuild @@ -69,5 +69,6 @@ nouveau-y += nv17_fence.o nouveau-y += nv50_fence.o nouveau-y += nv84_fence.o nouveau-y += nvc0_fence.o +nouveau-y += gv100_fence.o obj-$(CONFIG_DRM_NOUVEAU) += nouveau.o diff --git a/drivers/gpu/drm/nouveau/gv100_fence.c b/drivers/gpu/drm/nouveau/gv100_fence.c new file mode 100644 index 000000000000..cccdeca72002 --- /dev/null +++ b/drivers/gpu/drm/nouveau/gv100_fence.c @@ -0,0 +1,93 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#include "nouveau_drv.h" +#include "nouveau_dma.h" +#include "nouveau_fence.h" + +#include "nv50_display.h" + +#include <nvif/push906f.h> + +#include <nvhw/class/clc36f.h> + +static int +gv100_fence_emit32(struct nouveau_channel *chan, u64 virtual, u32 sequence) +{ + struct nvif_push *push = &chan->chan.push; + int ret; + + ret = PUSH_WAIT(push, 8); + if (ret) + return ret; + + PUSH_MTHD(push, NVC36F, SEM_ADDR_LO, lower_32_bits(virtual), + SEM_ADDR_HI, upper_32_bits(virtual), + SEM_PAYLOAD_LO, sequence); + + PUSH_MTHD(push, NVC36F, SEM_EXECUTE, + NVDEF(NVC36F, SEM_EXECUTE, OPERATION, RELEASE) | + NVDEF(NVC36F, SEM_EXECUTE, RELEASE_WFI, EN) | + NVDEF(NVC36F, SEM_EXECUTE, PAYLOAD_SIZE, 32BIT) | + NVDEF(NVC36F, SEM_EXECUTE, RELEASE_TIMESTAMP, DIS)); + + PUSH_MTHD(push, NVC36F, NON_STALL_INTERRUPT, 0); + + PUSH_KICK(push); + return 0; +} + +static int +gv100_fence_sync32(struct nouveau_channel *chan, u64 virtual, u32 sequence) +{ + struct nvif_push *push = &chan->chan.push; + int ret; + + ret = PUSH_WAIT(push, 6); + if (ret) + return ret; + + PUSH_MTHD(push, NVC36F, SEM_ADDR_LO, lower_32_bits(virtual), + SEM_ADDR_HI, upper_32_bits(virtual), + SEM_PAYLOAD_LO, sequence); + + PUSH_MTHD(push, NVC36F, SEM_EXECUTE, + NVDEF(NVC36F, SEM_EXECUTE, OPERATION, ACQ_CIRC_GEQ) | + NVDEF(NVC36F, SEM_EXECUTE, ACQUIRE_SWITCH_TSG, EN) | + NVDEF(NVC36F, SEM_EXECUTE, PAYLOAD_SIZE, 32BIT)); + + PUSH_KICK(push); + return 0; +} + +static int +gv100_fence_context_new(struct nouveau_channel *chan) +{ + struct nv84_fence_chan *fctx; + int ret; + + ret = nv84_fence_context_new(chan); + if (ret) + return ret; + + fctx = chan->fence; + fctx->base.emit32 = gv100_fence_emit32; + fctx->base.sync32 = gv100_fence_sync32; + return 0; +} + +int +gv100_fence_create(struct nouveau_drm *drm) +{ + struct nv84_fence_priv *priv; + int ret; + + ret = nv84_fence_create(drm); + if (ret) + return ret; + + priv = drm->fence; + priv->base.context_new = gv100_fence_context_new; + return 0; +} diff --git a/drivers/gpu/drm/nouveau/include/nvhw/class/clc36f.h b/drivers/gpu/drm/nouveau/include/nvhw/class/clc36f.h new file mode 100644 index 000000000000..8735dda4c8a7 --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvhw/class/clc36f.h @@ -0,0 +1,52 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#ifndef _clc36f_h_ +#define _clc36f_h_ + +#define NVC36F_NON_STALL_INTERRUPT (0x00000020) +#define NVC36F_NON_STALL_INTERRUPT_HANDLE 31:0 +#define NVC36F_SEM_ADDR_LO (0x0000005c) +#define NVC36F_SEM_ADDR_LO_OFFSET 31:2 +#define NVC36F_SEM_ADDR_HI (0x00000060) +#define NVC36F_SEM_ADDR_HI_OFFSET 7:0 +#define NVC36F_SEM_PAYLOAD_LO (0x00000064) +#define NVC36F_SEM_PAYLOAD_LO_PAYLOAD 31:0 +#define NVC36F_SEM_PAYLOAD_HI (0x00000068) +#define NVC36F_SEM_PAYLOAD_HI_PAYLOAD 31:0 +#define NVC36F_SEM_EXECUTE (0x0000006c) +#define NVC36F_SEM_EXECUTE_OPERATION 2:0 +#define NVC36F_SEM_EXECUTE_OPERATION_ACQUIRE 0x00000000 +#define NVC36F_SEM_EXECUTE_OPERATION_RELEASE 0x00000001 +#define NVC36F_SEM_EXECUTE_OPERATION_ACQ_STRICT_GEQ 0x00000002 +#define NVC36F_SEM_EXECUTE_OPERATION_ACQ_CIRC_GEQ 0x00000003 +#define NVC36F_SEM_EXECUTE_OPERATION_ACQ_AND 0x00000004 +#define NVC36F_SEM_EXECUTE_OPERATION_ACQ_NOR 0x00000005 +#define NVC36F_SEM_EXECUTE_OPERATION_REDUCTION 0x00000006 +#define NVC36F_SEM_EXECUTE_ACQUIRE_SWITCH_TSG 12:12 +#define NVC36F_SEM_EXECUTE_ACQUIRE_SWITCH_TSG_DIS 0x00000000 +#define NVC36F_SEM_EXECUTE_ACQUIRE_SWITCH_TSG_EN 0x00000001 +#define NVC36F_SEM_EXECUTE_RELEASE_WFI 20:20 +#define NVC36F_SEM_EXECUTE_RELEASE_WFI_DIS 0x00000000 +#define NVC36F_SEM_EXECUTE_RELEASE_WFI_EN 0x00000001 +#define NVC36F_SEM_EXECUTE_PAYLOAD_SIZE 24:24 +#define NVC36F_SEM_EXECUTE_PAYLOAD_SIZE_32BIT 0x00000000 +#define NVC36F_SEM_EXECUTE_PAYLOAD_SIZE_64BIT 0x00000001 +#define NVC36F_SEM_EXECUTE_RELEASE_TIMESTAMP 25:25 +#define NVC36F_SEM_EXECUTE_RELEASE_TIMESTAMP_DIS 0x00000000 +#define NVC36F_SEM_EXECUTE_RELEASE_TIMESTAMP_EN 0x00000001 +#define NVC36F_SEM_EXECUTE_REDUCTION 30:27 +#define NVC36F_SEM_EXECUTE_REDUCTION_IMIN 0x00000000 +#define NVC36F_SEM_EXECUTE_REDUCTION_IMAX 0x00000001 +#define NVC36F_SEM_EXECUTE_REDUCTION_IXOR 0x00000002 +#define NVC36F_SEM_EXECUTE_REDUCTION_IAND 0x00000003 +#define NVC36F_SEM_EXECUTE_REDUCTION_IOR 0x00000004 +#define NVC36F_SEM_EXECUTE_REDUCTION_IADD 0x00000005 +#define NVC36F_SEM_EXECUTE_REDUCTION_INC 0x00000006 +#define NVC36F_SEM_EXECUTE_REDUCTION_DEC 0x00000007 +#define NVC36F_SEM_EXECUTE_REDUCTION_FORMAT 31:31 +#define NVC36F_SEM_EXECUTE_REDUCTION_FORMAT_SIGNED 0x00000000 +#define NVC36F_SEM_EXECUTE_REDUCTION_FORMAT_UNSIGNED 0x00000001 + +#endif diff --git a/drivers/gpu/drm/nouveau/include/nvif/push906f.h b/drivers/gpu/drm/nouveau/include/nvif/push906f.h index cc2866bc8b0a..79df71de98d2 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/push906f.h +++ b/drivers/gpu/drm/nouveau/include/nvif/push906f.h @@ -7,6 +7,7 @@ #ifndef PUSH906F_SUBC // Host methods #define PUSH906F_SUBC_NV906F 0 +#define PUSH906F_SUBC_NVC36F 0 // Twod #define PUSH906F_SUBC_NV902D 3 diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index c69139701056..e7544942791d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -503,11 +503,13 @@ nouveau_accel_init(struct nouveau_drm *drm) case KEPLER_CHANNEL_GPFIFO_B: case MAXWELL_CHANNEL_GPFIFO_A: case PASCAL_CHANNEL_GPFIFO_A: + ret = nvc0_fence_create(drm); + break; case VOLTA_CHANNEL_GPFIFO_A: case TURING_CHANNEL_GPFIFO_A: case AMPERE_CHANNEL_GPFIFO_A: case AMPERE_CHANNEL_GPFIFO_B: - ret = nvc0_fence_create(drm); + ret = gv100_fence_create(drm); break; default: break; diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.h b/drivers/gpu/drm/nouveau/nouveau_fence.h index 8bc065acfe35..6a983dd9f7b9 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fence.h +++ b/drivers/gpu/drm/nouveau/nouveau_fence.h @@ -83,6 +83,7 @@ void nv17_fence_resume(struct nouveau_drm *drm); int nv50_fence_create(struct nouveau_drm *); int nv84_fence_create(struct nouveau_drm *); int nvc0_fence_create(struct nouveau_drm *); +int gv100_fence_create(struct nouveau_drm *); struct nv84_fence_chan { struct nouveau_fence_chan base; -- 2.49.0
Ben Skeggs
2025-May-17 00:09 UTC
[PATCH v3 53/62] drm/nouveau: improve handling of 64-bit BARs
GPUs exist now with a 64-bit BAR0, which mean that BAR1 and BAR2's indices (as passed to pci_resource_len() etc) are bumped up by one. Modify nvkm_device.resource_addr/size() to take an enum instead of an integer bar index, and take IORESOURCE_MEM_64 into account when translating to the "raw" bar id. Signed-off-by: Ben Skeggs <bskeggs at nvidia.com> Reviewed-by: Dave Airlie <airlied at redhat.com> Reviewed-by: Timur Tabi <ttabi at nvidia.com> Tested-by: Timur Tabi <ttabi at nvidia.com> --- .../drm/nouveau/include/nvkm/core/device.h | 11 +++++-- drivers/gpu/drm/nouveau/nouveau_abi16.c | 2 +- drivers/gpu/drm/nouveau/nouveau_bo.c | 4 +-- drivers/gpu/drm/nouveau/nouveau_chan.c | 4 ++- drivers/gpu/drm/nouveau/nouveau_ttm.c | 12 +++---- .../gpu/drm/nouveau/nvkm/engine/device/base.c | 4 +-- .../gpu/drm/nouveau/nvkm/engine/device/pci.c | 32 ++++++++++++++++--- .../drm/nouveau/nvkm/engine/device/tegra.c | 18 ++++++++--- .../gpu/drm/nouveau/nvkm/engine/device/user.c | 4 +-- .../gpu/drm/nouveau/nvkm/engine/disp/chan.c | 2 +- .../gpu/drm/nouveau/nvkm/engine/disp/gv100.c | 2 +- .../gpu/drm/nouveau/nvkm/engine/fifo/base.c | 2 +- .../gpu/drm/nouveau/nvkm/engine/fifo/chan.c | 6 ++-- .../gpu/drm/nouveau/nvkm/engine/fifo/chan.h | 2 +- .../gpu/drm/nouveau/nvkm/engine/fifo/gf100.c | 2 +- .../gpu/drm/nouveau/nvkm/engine/fifo/gk104.c | 4 +-- .../gpu/drm/nouveau/nvkm/engine/fifo/gv100.c | 1 - .../gpu/drm/nouveau/nvkm/engine/fifo/nv04.c | 2 +- .../gpu/drm/nouveau/nvkm/engine/fifo/nv40.c | 2 +- .../gpu/drm/nouveau/nvkm/engine/fifo/nv50.c | 2 +- .../gpu/drm/nouveau/nvkm/engine/fifo/uchan.c | 2 +- drivers/gpu/drm/nouveau/nvkm/engine/gr/nv20.c | 2 +- drivers/gpu/drm/nouveau/nvkm/engine/gr/nv40.c | 2 +- .../gpu/drm/nouveau/nvkm/subdev/bar/gf100.c | 14 ++++---- .../gpu/drm/nouveau/nvkm/subdev/bar/nv50.c | 4 +-- .../drm/nouveau/nvkm/subdev/devinit/fbmem.h | 4 +-- .../gpu/drm/nouveau/nvkm/subdev/fault/user.c | 2 +- .../drm/nouveau/nvkm/subdev/gsp/rm/r535/bar.c | 2 +- .../drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c | 6 ++-- .../drm/nouveau/nvkm/subdev/gsp/rm/r570/gsp.c | 6 ++-- .../drm/nouveau/nvkm/subdev/instmem/nv40.c | 10 ++---- .../drm/nouveau/nvkm/subdev/instmem/nv50.c | 2 +- .../drm/nouveau/nvkm/subdev/mmu/memgf100.c | 2 +- .../gpu/drm/nouveau/nvkm/subdev/mmu/memnv04.c | 2 +- .../gpu/drm/nouveau/nvkm/subdev/mmu/memnv50.c | 2 +- .../gpu/drm/nouveau/nvkm/subdev/vfn/uvfn.c | 2 +- 36 files changed, 109 insertions(+), 73 deletions(-) diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/device.h b/drivers/gpu/drm/nouveau/include/nvkm/core/device.h index 46afb877a296..f50f52d4dc3f 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/core/device.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/device.h @@ -77,6 +77,13 @@ struct nvkm_device { struct nvkm_subdev *nvkm_device_subdev(struct nvkm_device *, int type, int inst); struct nvkm_engine *nvkm_device_engine(struct nvkm_device *, int type, int inst); +enum nvkm_bar_id { + NVKM_BAR_INVALID = 0, + NVKM_BAR0_PRI, + NVKM_BAR1_FB, + NVKM_BAR2_INST, +}; + struct nvkm_device_func { struct nvkm_device_pci *(*pci)(struct nvkm_device *); struct nvkm_device_tegra *(*tegra)(struct nvkm_device *); @@ -85,8 +92,8 @@ struct nvkm_device_func { int (*init)(struct nvkm_device *); void (*fini)(struct nvkm_device *, bool suspend); int (*irq)(struct nvkm_device *); - resource_size_t (*resource_addr)(struct nvkm_device *, unsigned bar); - resource_size_t (*resource_size)(struct nvkm_device *, unsigned bar); + resource_size_t (*resource_addr)(struct nvkm_device *, enum nvkm_bar_id); + resource_size_t (*resource_size)(struct nvkm_device *, enum nvkm_bar_id); bool cpu_coherent; }; diff --git a/drivers/gpu/drm/nouveau/nouveau_abi16.c b/drivers/gpu/drm/nouveau/nouveau_abi16.c index 2a0617e5fe2a..4c100005ef81 100644 --- a/drivers/gpu/drm/nouveau/nouveau_abi16.c +++ b/drivers/gpu/drm/nouveau/nouveau_abi16.c @@ -315,7 +315,7 @@ nouveau_abi16_ioctl_getparam(ABI16_IOCTL_ARGS) break; } case NOUVEAU_GETPARAM_VRAM_BAR_SIZE: - getparam->value = nvkm_device->func->resource_size(nvkm_device, 1); + getparam->value = nvkm_device->func->resource_size(nvkm_device, NVKM_BAR1_FB); break; case NOUVEAU_GETPARAM_VRAM_USED: { struct ttm_resource_manager *vram_mgr = ttm_manager_type(&drm->ttm.bdev, TTM_PL_VRAM); diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 2016c1e7242f..9ab8380feb39 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -1204,7 +1204,7 @@ nouveau_ttm_io_mem_reserve(struct ttm_device *bdev, struct ttm_resource *reg) fallthrough; /* tiled memory */ case TTM_PL_VRAM: reg->bus.offset = (reg->start << PAGE_SHIFT) + - device->func->resource_addr(device, 1); + device->func->resource_addr(device, NVKM_BAR1_FB); reg->bus.is_iomem = true; /* Some BARs do not support being ioremapped WC */ @@ -1295,7 +1295,7 @@ vm_fault_t nouveau_ttm_fault_reserve_notify(struct ttm_buffer_object *bo) struct nouveau_drm *drm = nouveau_bdev(bo->bdev); struct nouveau_bo *nvbo = nouveau_bo(bo); struct nvkm_device *device = nvxx_device(drm); - u32 mappable = device->func->resource_size(device, 1) >> PAGE_SHIFT; + u32 mappable = device->func->resource_size(device, NVKM_BAR1_FB) >> PAGE_SHIFT; int i, ret; /* as long as the bo isn't in vram, and isn't tiled, we've got diff --git a/drivers/gpu/drm/nouveau/nouveau_chan.c b/drivers/gpu/drm/nouveau/nouveau_chan.c index 1286a664f688..5bcd29809c1e 100644 --- a/drivers/gpu/drm/nouveau/nouveau_chan.c +++ b/drivers/gpu/drm/nouveau/nouveau_chan.c @@ -209,13 +209,15 @@ nouveau_channel_prep(struct nouveau_cli *cli, } else if (chan->push.buffer->bo.resource->mem_type == TTM_PL_VRAM) { if (device->info.family == NV_DEVICE_INFO_V0_TNT) { + struct nvkm_device *nvkm_device = nvxx_device(drm); + /* nv04 vram pushbuf hack, retarget to its location in * the framebuffer bar rather than direct vram access.. * nfi why this exists, it came from the -nv ddx. */ args.target = NV_DMA_V0_TARGET_PCI; args.access = NV_DMA_V0_ACCESS_RDWR; - args.start = nvxx_device(drm)->func->resource_addr(nvxx_device(drm), 1); + args.start = nvkm_device->func->resource_addr(nvkm_device, NVKM_BAR1_FB); args.limit = args.start + device->info.ram_user - 1; } else { args.target = NV_DMA_V0_TARGET_VRAM; diff --git a/drivers/gpu/drm/nouveau/nouveau_ttm.c b/drivers/gpu/drm/nouveau/nouveau_ttm.c index e244927eb5d4..7d2436e5d50d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_ttm.c +++ b/drivers/gpu/drm/nouveau/nouveau_ttm.c @@ -312,8 +312,8 @@ nouveau_ttm_init(struct nouveau_drm *drm) /* VRAM init */ drm->gem.vram_available = drm->client.device.info.ram_user; - arch_io_reserve_memtype_wc(device->func->resource_addr(device, 1), - device->func->resource_size(device, 1)); + arch_io_reserve_memtype_wc(device->func->resource_addr(device, NVKM_BAR1_FB), + device->func->resource_size(device, NVKM_BAR1_FB)); ret = nouveau_ttm_init_vram(drm); if (ret) { @@ -321,8 +321,8 @@ nouveau_ttm_init(struct nouveau_drm *drm) return ret; } - drm->ttm.mtrr = arch_phys_wc_add(device->func->resource_addr(device, 1), - device->func->resource_size(device, 1)); + drm->ttm.mtrr = arch_phys_wc_add(device->func->resource_addr(device, NVKM_BAR1_FB), + device->func->resource_size(device, NVKM_BAR1_FB)); /* GART init */ if (!drm->agp.bridge) { @@ -357,7 +357,7 @@ nouveau_ttm_fini(struct nouveau_drm *drm) arch_phys_wc_del(drm->ttm.mtrr); drm->ttm.mtrr = 0; - arch_io_free_memtype_wc(device->func->resource_addr(device, 1), - device->func->resource_size(device, 1)); + arch_io_free_memtype_wc(device->func->resource_addr(device, NVKM_BAR1_FB), + device->func->resource_size(device, NVKM_BAR1_FB)); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c index 0cd20d0f8782..ebcaf2ecff48 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c @@ -3027,8 +3027,8 @@ nvkm_device_ctor(const struct nvkm_device_func *func, device->debug = nvkm_dbgopt(device->dbgopt, "device"); INIT_LIST_HEAD(&device->subdev); - mmio_base = device->func->resource_addr(device, 0); - mmio_size = device->func->resource_size(device, 0); + mmio_base = device->func->resource_addr(device, NVKM_BAR0_PRI); + mmio_size = device->func->resource_size(device, NVKM_BAR0_PRI); device->pri = ioremap(mmio_base, mmio_size); if (device->pri == NULL) { diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/pci.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/pci.c index 3ff6436007fa..8f0261a0d618 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/pci.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/pci.c @@ -1560,18 +1560,42 @@ nvkm_device_pci(struct nvkm_device *device) return container_of(device, struct nvkm_device_pci, device); } +static int +nvkm_device_pci_resource_idx(struct nvkm_device_pci *pdev, enum nvkm_bar_id bar) +{ + int idx = 0; + + if (bar == NVKM_BAR0_PRI) + return idx; + + idx += (pci_resource_flags(pdev->pdev, idx) & IORESOURCE_MEM_64) ? 2 : 1; + if (bar == NVKM_BAR1_FB) + return idx; + + idx += (pci_resource_flags(pdev->pdev, idx) & IORESOURCE_MEM_64) ? 2 : 1; + if (bar == NVKM_BAR2_INST) + return idx; + + WARN_ON(1); + return -1; +} + static resource_size_t -nvkm_device_pci_resource_addr(struct nvkm_device *device, unsigned bar) +nvkm_device_pci_resource_addr(struct nvkm_device *device, enum nvkm_bar_id bar) { struct nvkm_device_pci *pdev = nvkm_device_pci(device); - return pci_resource_start(pdev->pdev, bar); + int idx = nvkm_device_pci_resource_idx(pdev, bar); + + return idx >= 0 ? pci_resource_start(pdev->pdev, idx) : 0; } static resource_size_t -nvkm_device_pci_resource_size(struct nvkm_device *device, unsigned bar) +nvkm_device_pci_resource_size(struct nvkm_device *device, enum nvkm_bar_id bar) { struct nvkm_device_pci *pdev = nvkm_device_pci(device); - return pci_resource_len(pdev->pdev, bar); + int idx = nvkm_device_pci_resource_idx(pdev, bar); + + return idx >= 0 ? pci_resource_len(pdev->pdev, idx) : 0; } static int diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c index 78a83f904bbd..f7f21d9ed6ef 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c @@ -186,21 +186,31 @@ nvkm_device_tegra(struct nvkm_device *device) } static struct resource * -nvkm_device_tegra_resource(struct nvkm_device *device, unsigned bar) +nvkm_device_tegra_resource(struct nvkm_device *device, enum nvkm_bar_id bar) { struct nvkm_device_tegra *tdev = nvkm_device_tegra(device); - return platform_get_resource(tdev->pdev, IORESOURCE_MEM, bar); + int idx; + + switch (bar) { + case NVKM_BAR0_PRI: idx = 0; break; + case NVKM_BAR1_FB : idx = 1; break; + default: + WARN_ON(1); + return -EINVAL; + } + + return platform_get_resource(tdev->pdev, IORESOURCE_MEM, idx); } static resource_size_t -nvkm_device_tegra_resource_addr(struct nvkm_device *device, unsigned bar) +nvkm_device_tegra_resource_addr(struct nvkm_device *device, enum nvkm_bar_id bar) { struct resource *res = nvkm_device_tegra_resource(device, bar); return res ? res->start : 0; } static resource_size_t -nvkm_device_tegra_resource_size(struct nvkm_device *device, unsigned bar) +nvkm_device_tegra_resource_size(struct nvkm_device *device, enum nvkm_bar_id bar) { struct resource *res = nvkm_device_tegra_resource(device, bar); return res ? resource_size(res) : 0; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/user.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/user.c index d7f75b3a43c8..1f331ec8d747 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/user.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/user.c @@ -209,8 +209,8 @@ nvkm_udevice_map(struct nvkm_object *object, void *argv, u32 argc, struct nvkm_udevice *udev = nvkm_udevice(object); struct nvkm_device *device = udev->device; *type = NVKM_OBJECT_MAP_IO; - *addr = device->func->resource_addr(device, 0); - *size = device->func->resource_size(device, 0); + *addr = device->func->resource_addr(device, NVKM_BAR0_PRI); + *size = device->func->resource_size(device, NVKM_BAR0_PRI); return 0; } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/chan.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/chan.c index 4e43ee383c34..9b84e357d354 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/chan.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/chan.c @@ -49,7 +49,7 @@ nvkm_disp_chan_map(struct nvkm_object *object, void *argv, u32 argc, { struct nvkm_disp_chan *chan = nvkm_disp_chan(object); struct nvkm_device *device = chan->disp->engine.subdev.device; - const u64 base = device->func->resource_addr(device, 0); + const u64 base = device->func->resource_addr(device, NVKM_BAR0_PRI); *type = NVKM_OBJECT_MAP_IO; *addr = base + chan->func->user(chan, size); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gv100.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gv100.c index cfa3698d3a2f..614921166fba 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gv100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gv100.c @@ -805,7 +805,7 @@ gv100_disp_caps_map(struct nvkm_object *object, void *argv, u32 argc, struct gv100_disp_caps *caps = gv100_disp_caps(object); struct nvkm_device *device = caps->disp->engine.subdev.device; *type = NVKM_OBJECT_MAP_IO; - *addr = 0x640000 + device->func->resource_addr(device, 0); + *addr = 0x640000 + device->func->resource_addr(device, NVKM_BAR0_PRI); *size = 0x1000; return 0; } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/base.c index 3c2ca711dc5c..fdffa0391b31 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/base.c @@ -303,7 +303,7 @@ nvkm_fifo_oneinit(struct nvkm_engine *engine) } /* Allocate USERD + BAR1 polling area. */ - if (fifo->func->chan.func->userd->bar == 1) { + if (fifo->func->chan.func->userd->bar == NVKM_BAR1_FB) { struct nvkm_vmm *bar1 = nvkm_bar_bar1_vmm(device); ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, fifo->chid->nr * diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.c index 78be7abc90d1..4e09985424b6 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.c @@ -355,14 +355,14 @@ nvkm_chan_new_(const struct nvkm_chan_func *func, struct nvkm_runl *runl, int ru /* Validate arguments against class requirements. */ if ((runq && runq >= runl->func->runqs) || (!func->inst->vmm != !vmm) || - ((func->userd->bar < 0) == !userd) || + (!func->userd->bar == !userd) || (!func->ramfc->ctxdma != !dmaobj) || ((func->ramfc->devm < devm) && devm != BIT(0)) || (!func->ramfc->priv && priv)) { RUNL_DEBUG(runl, "args runq:%d:%d vmm:%d:%p userd:%d:%p " "push:%d:%p devm:%08x:%08x priv:%d:%d", runl->func->runqs, runq, func->inst->vmm, vmm, - func->userd->bar < 0, userd, func->ramfc->ctxdma, dmaobj, + func->userd->bar, userd, func->ramfc->ctxdma, dmaobj, func->ramfc->devm, devm, func->ramfc->priv, priv); return -EINVAL; } @@ -439,7 +439,7 @@ nvkm_chan_new_(const struct nvkm_chan_func *func, struct nvkm_runl *runl, int ru /* Allocate channel ID. */ chan->id = nvkm_chid_get(runl->chid, chan); if (chan->id >= 0) { - if (func->userd->bar < 0) { + if (!func->userd->bar) { if (ouserd + chan->func->userd->size > nvkm_memory_size(userd)) { RUNL_DEBUG(runl, "ouserd %llx", ouserd); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.h b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.h index 85b94f699128..445db5dfd1e4 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.h @@ -24,7 +24,7 @@ struct nvkm_chan_func { } *inst; const struct nvkm_chan_func_userd { - int bar; + enum nvkm_bar_id bar; u32 base; u32 size; void (*clear)(struct nvkm_chan *); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c index 6c94451d0faa..e4a4fad2eafc 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c @@ -133,7 +133,7 @@ gf100_chan_userd_clear(struct nvkm_chan *chan) static const struct nvkm_chan_func_userd gf100_chan_userd = { - .bar = 1, + .bar = NVKM_BAR1_FB, .size = 0x1000, .clear = gf100_chan_userd_clear, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c index d8a4d773a58c..5655eda52a7b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c @@ -113,7 +113,7 @@ gk104_chan_ramfc = { const struct nvkm_chan_func_userd gk104_chan_userd = { - .bar = 1, + .bar = NVKM_BAR1_FB, .size = 0x200, .clear = gf100_chan_userd_clear, }; @@ -745,7 +745,7 @@ gk104_fifo_init(struct nvkm_fifo *fifo) { struct nvkm_device *device = fifo->engine.subdev.device; - if (fifo->func->chan.func->userd->bar == 1) + if (fifo->func->chan.func->userd->bar == NVKM_BAR1_FB) nvkm_wr32(device, 0x002254, 0x10000000 | fifo->userd.bar1->addr >> 12); nvkm_wr32(device, 0x002100, 0xffffffff); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gv100.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gv100.c index 33066c8cdc64..d7f046c03cfd 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gv100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gv100.c @@ -70,7 +70,6 @@ gv100_chan_ramfc = { const struct nvkm_chan_func_userd gv100_chan_userd = { - .bar = -1, .size = 0x200, .clear = gf100_chan_userd_clear, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv04.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv04.c index 674faf002b20..c4b8e567d86f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv04.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv04.c @@ -154,7 +154,7 @@ nv04_chan_ramfc = { const struct nvkm_chan_func_userd nv04_chan_userd = { - .bar = 0, + .bar = NVKM_BAR0_PRI, .base = 0x800000, .size = 0x010000, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv40.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv40.c index e50a94b6d7f8..084ca5561ee1 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv40.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv40.c @@ -93,7 +93,7 @@ nv40_chan_ramfc = { static const struct nvkm_chan_func_userd nv40_chan_userd = { - .bar = 0, + .bar = NVKM_BAR0_PRI, .base = 0xc00000, .size = 0x001000, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv50.c index 954b5f3a7d57..7bf77661157d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv50.c @@ -124,7 +124,7 @@ nv50_chan_ramfc = { const struct nvkm_chan_func_userd nv50_chan_userd = { - .bar = 0, + .bar = NVKM_BAR0_PRI, .base = 0xc00000, .size = 0x002000, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/uchan.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/uchan.c index 9e56bcc166ed..52420a1edca5 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/uchan.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/uchan.c @@ -258,7 +258,7 @@ nvkm_uchan_map(struct nvkm_object *object, void *argv, u32 argc, struct nvkm_chan *chan = nvkm_uchan(object)->chan; struct nvkm_device *device = chan->cgrp->runl->fifo->engine.subdev.device; - if (chan->func->userd->bar < 0) + if (!chan->func->userd->bar) return -ENOSYS; *type = NVKM_OBJECT_MAP_IO; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv20.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv20.c index 02a8c62a0a32..13407fafe947 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv20.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv20.c @@ -297,7 +297,7 @@ nv20_gr_init(struct nvkm_gr *base) nvkm_wr32(device, NV10_PGRAPH_SURFACE, tmp); /* begin RAM config */ - vramsz = device->func->resource_size(device, 1) - 1; + vramsz = device->func->resource_size(device, NVKM_BAR1_FB) - 1; nvkm_wr32(device, 0x4009A4, nvkm_rd32(device, 0x100200)); nvkm_wr32(device, 0x4009A8, nvkm_rd32(device, 0x100204)); nvkm_wr32(device, NV10_PGRAPH_RDI_INDEX, 0x00EA0000); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv40.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv40.c index a5e1f02791b4..b609b0150ba1 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv40.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv40.c @@ -386,7 +386,7 @@ nv40_gr_init(struct nvkm_gr *base) } /* begin RAM config */ - vramsz = device->func->resource_size(device, 1) - 1; + vramsz = device->func->resource_size(device, NVKM_BAR1_FB) - 1; switch (device->chipset) { case 0x40: nvkm_wr32(device, 0x4009A4, nvkm_rd32(device, 0x100200)); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c index 51070b7dda85..e5e60915029c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c @@ -82,7 +82,7 @@ gf100_bar_bar2_init(struct nvkm_bar *base) static int gf100_bar_oneinit_bar(struct gf100_bar *bar, struct gf100_barN *bar_vm, - struct lock_class_key *key, int bar_nr) + struct lock_class_key *key, enum nvkm_bar_id bar_id) { struct nvkm_device *device = bar->base.subdev.device; resource_size_t bar_len; @@ -93,14 +93,14 @@ gf100_bar_oneinit_bar(struct gf100_bar *bar, struct gf100_barN *bar_vm, if (ret) return ret; - bar_len = device->func->resource_size(device, bar_nr); + bar_len = device->func->resource_size(device, bar_id); if (!bar_len) return -ENOMEM; - if (bar_nr == 3 && bar->bar2_halve) + if (bar_id == NVKM_BAR2_INST && bar->bar2_halve) bar_len >>= 1; ret = nvkm_vmm_new(device, 0, bar_len, NULL, 0, key, - (bar_nr == 3) ? "bar2" : "bar1", &bar_vm->vmm); + (bar_id == NVKM_BAR2_INST) ? "bar2" : "bar1", &bar_vm->vmm); if (ret) return ret; @@ -110,7 +110,7 @@ gf100_bar_oneinit_bar(struct gf100_bar *bar, struct gf100_barN *bar_vm, /* * Bootstrap page table lookup. */ - if (bar_nr == 3) { + if (bar_id == NVKM_BAR2_INST) { ret = nvkm_vmm_boot(bar_vm->vmm); if (ret) return ret; @@ -129,7 +129,7 @@ gf100_bar_oneinit(struct nvkm_bar *base) /* BAR2 */ if (bar->base.func->bar2.init) { - ret = gf100_bar_oneinit_bar(bar, &bar->bar[0], &bar2_lock, 3); + ret = gf100_bar_oneinit_bar(bar, &bar->bar[0], &bar2_lock, NVKM_BAR2_INST); if (ret) return ret; @@ -138,7 +138,7 @@ gf100_bar_oneinit(struct nvkm_bar *base) } /* BAR1 */ - ret = gf100_bar_oneinit_bar(bar, &bar->bar[1], &bar1_lock, 1); + ret = gf100_bar_oneinit_bar(bar, &bar->bar[1], &bar1_lock, NVKM_BAR1_FB); if (ret) return ret; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c index 27d8a1be43e4..6a881becb02c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c @@ -127,7 +127,7 @@ nv50_bar_oneinit(struct nvkm_bar *base) /* BAR2 */ start = 0x0100000000ULL; - size = device->func->resource_size(device, 3); + size = device->func->resource_size(device, NVKM_BAR2_INST); if (!size) return -ENOMEM; limit = start + size; @@ -167,7 +167,7 @@ nv50_bar_oneinit(struct nvkm_bar *base) /* BAR1 */ start = 0x0000000000ULL; - size = device->func->resource_size(device, 1); + size = device->func->resource_size(device, NVKM_BAR1_FB); if (!size) return -ENOMEM; limit = start + size; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/fbmem.h b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/fbmem.h index 6c5bbff12eb4..b918e22df5a8 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/fbmem.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/fbmem.h @@ -47,8 +47,8 @@ static inline struct io_mapping * fbmem_init(struct nvkm_device *dev) { - return io_mapping_create_wc(dev->func->resource_addr(dev, 1), - dev->func->resource_size(dev, 1)); + return io_mapping_create_wc(dev->func->resource_addr(dev, NVKM_BAR1_FB), + dev->func->resource_size(dev, NVKM_BAR1_FB)); } static inline void diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fault/user.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fault/user.c index c123e5893d76..cd2fbc0472d8 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fault/user.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fault/user.c @@ -50,7 +50,7 @@ nvkm_ufault_map(struct nvkm_object *object, void *argv, u32 argc, struct nvkm_fault_buffer *buffer = nvkm_fault_buffer(object); struct nvkm_device *device = buffer->fault->subdev.device; *type = NVKM_OBJECT_MAP_IO; - *addr = device->func->resource_addr(device, 3) + buffer->addr; + *addr = device->func->resource_addr(device, NVKM_BAR2_INST) + buffer->addr; *size = nvkm_memory_size(buffer->mem); return 0; } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/bar.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/bar.c index 91242f09648e..d06bf95b9a4a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/bar.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/bar.c @@ -191,7 +191,7 @@ r535_bar_new_(const struct nvkm_bar_func *hw, struct nvkm_device *device, } *pbar = bar; - bar->flushBAR2PhysMode = ioremap(device->func->resource_addr(device, 3), PAGE_SIZE); + bar->flushBAR2PhysMode = ioremap(device->func->resource_addr(device, NVKM_BAR2_INST), PAGE_SIZE); if (!bar->flushBAR2PhysMode) return -ENOMEM; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c index e2171d0d25be..fe00425c5479 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c @@ -901,9 +901,9 @@ r535_gsp_set_system_info(struct nvkm_gsp *gsp) if (IS_ERR(info)) return PTR_ERR(info); - info->gpuPhysAddr = device->func->resource_addr(device, 0); - info->gpuPhysFbAddr = device->func->resource_addr(device, 1); - info->gpuPhysInstAddr = device->func->resource_addr(device, 3); + info->gpuPhysAddr = device->func->resource_addr(device, NVKM_BAR0_PRI); + info->gpuPhysFbAddr = device->func->resource_addr(device, NVKM_BAR1_FB); + info->gpuPhysInstAddr = device->func->resource_addr(device, NVKM_BAR2_INST); info->nvDomainBusDeviceFunc = pci_dev_id(pdev->pdev); info->maxUserVa = TASK_SIZE; info->pciConfigMirrorBase = device->pci->func->cfg.addr; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/gsp.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/gsp.c index a3c070d41923..730dcb645cca 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/gsp.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/gsp.c @@ -153,9 +153,9 @@ r570_gsp_set_system_info(struct nvkm_gsp *gsp) if (IS_ERR(info)) return PTR_ERR(info); - info->gpuPhysAddr = device->func->resource_addr(device, 0); - info->gpuPhysFbAddr = device->func->resource_addr(device, 1); - info->gpuPhysInstAddr = device->func->resource_addr(device, 3); + info->gpuPhysAddr = device->func->resource_addr(device, NVKM_BAR0_PRI); + info->gpuPhysFbAddr = device->func->resource_addr(device, NVKM_BAR1_FB); + info->gpuPhysInstAddr = device->func->resource_addr(device, NVKM_BAR2_INST); info->nvDomainBusDeviceFunc = pci_dev_id(pdev); info->maxUserVa = TASK_SIZE; info->pciConfigMirrorBase = device->pci->func->cfg.addr; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv40.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv40.c index 6b462f960922..2544b9f0ec85 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv40.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv40.c @@ -239,7 +239,6 @@ nv40_instmem_new(struct nvkm_device *device, enum nvkm_subdev_type type, int ins struct nvkm_instmem **pimem) { struct nv40_instmem *imem; - int bar; if (!(imem = kzalloc(sizeof(*imem), GFP_KERNEL))) return -ENOMEM; @@ -247,13 +246,8 @@ nv40_instmem_new(struct nvkm_device *device, enum nvkm_subdev_type type, int ins *pimem = &imem->base; /* map bar */ - if (device->func->resource_size(device, 2)) - bar = 2; - else - bar = 3; - - imem->iomem = ioremap_wc(device->func->resource_addr(device, bar), - device->func->resource_size(device, bar)); + imem->iomem = ioremap_wc(device->func->resource_addr(device, NVKM_BAR2_INST), + device->func->resource_size(device, NVKM_BAR2_INST)); if (!imem->iomem) { nvkm_error(&imem->base.subdev, "unable to map PRAMIN BAR\n"); return -EFAULT; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c index 0ef66d7d5e51..9d29e5234734 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c @@ -172,7 +172,7 @@ nv50_instobj_kmap(struct nv50_instobj *iobj, struct nvkm_vmm *vmm) /* Make the mapping visible to the host. */ iobj->bar = bar; - iobj->map = ioremap_wc(device->func->resource_addr(device, 3) + + iobj->map = ioremap_wc(device->func->resource_addr(device, NVKM_BAR2_INST) + (u32)iobj->bar->addr, size); if (!iobj->map) { nvkm_warn(subdev, "PRAMIN ioremap failed\n"); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/memgf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/memgf100.c index d9c9bee45222..160a5749a29f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/memgf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/memgf100.c @@ -60,7 +60,7 @@ gf100_mem_map(struct nvkm_mmu *mmu, struct nvkm_memory *memory, void *argv, if (ret) return ret; - *paddr = device->func->resource_addr(device, 1) + (*pvma)->addr; + *paddr = device->func->resource_addr(device, NVKM_BAR1_FB) + (*pvma)->addr; *psize = (*pvma)->size; return 0; } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/memnv04.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/memnv04.c index 79a3b0cc9f5b..1e3db52de6cb 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/memnv04.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/memnv04.c @@ -41,7 +41,7 @@ nv04_mem_map(struct nvkm_mmu *mmu, struct nvkm_memory *memory, void *argv, if ((ret = nvif_unvers(ret, &argv, &argc, args->vn))) return ret; - *paddr = device->func->resource_addr(device, 1) + addr; + *paddr = device->func->resource_addr(device, NVKM_BAR1_FB) + addr; *psize = nvkm_memory_size(memory); *pvma = ERR_PTR(-ENODEV); return 0; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/memnv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/memnv50.c index 46759b89fc1f..33b2321e9d87 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/memnv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/memnv50.c @@ -57,7 +57,7 @@ nv50_mem_map(struct nvkm_mmu *mmu, struct nvkm_memory *memory, void *argv, if (ret) return ret; - *paddr = device->func->resource_addr(device, 1) + (*pvma)->addr; + *paddr = device->func->resource_addr(device, NVKM_BAR1_FB) + (*pvma)->addr; *psize = (*pvma)->size; return nvkm_memory_map(memory, 0, bar, *pvma, &uvmm, sizeof(uvmm)); } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/vfn/uvfn.c b/drivers/gpu/drm/nouveau/nvkm/subdev/vfn/uvfn.c index c5460a14c541..4e64d8843373 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/vfn/uvfn.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/vfn/uvfn.c @@ -36,7 +36,7 @@ nvkm_uvfn_map(struct nvkm_object *object, void *argv, u32 argc, struct nvkm_vfn *vfn = nvkm_uvfn(object)->vfn; struct nvkm_device *device = vfn->subdev.device; - *addr = device->func->resource_addr(device, 0) + vfn->addr.user; + *addr = device->func->resource_addr(device, NVKM_BAR0_PRI) + vfn->addr.user; *size = vfn->func->user.size; *type = NVKM_OBJECT_MAP_IO; return 0; -- 2.49.0
This commit enables basic support for Hopper GPUs, and is intended primarily as a base supporting Blackwell GPUs, which reuse most of the code added here. Advanced features such as Confidential Compute are not supported. Beyond a few miscellaneous register moves and HW class ID plumbing, the bulk of the changes implemented here are to support the GSP-RM boot sequence used on Hopper/Blackwell GPUs, as well as a new page table layout. There should be no changes here that impact prior GPUs. Signed-off-by: Ben Skeggs <bskeggs at nvidia.com> Co-developed-by: Timur Tabi <ttabi at nvidia.com> Signed-off-by: Timur Tabi <ttabi at nvidia.com> Reviewed-by: Dave Airlie <airlied at redhat.com> Reviewed-by: Timur Tabi <ttabi at nvidia.com> Tested-by: Timur Tabi <ttabi at nvidia.com> --- .../include/nvhw/ref/gh100/dev_falcon_v4.h | 20 + .../nouveau/include/nvhw/ref/gh100/dev_fb.h | 15 + .../include/nvhw/ref/gh100/dev_fsp_pri.h | 28 ++ .../nouveau/include/nvhw/ref/gh100/dev_mmu.h | 173 +++++++++ .../include/nvhw/ref/gh100/dev_riscv_pri.h | 14 + .../include/nvhw/ref/gh100/dev_therm.h | 17 + .../include/nvhw/ref/gh100/dev_xtl_ep_pri.h | 10 + .../include/nvhw/ref/gh100/pri_nv_xal_ep.h | 13 + drivers/gpu/drm/nouveau/include/nvif/cl0080.h | 1 + drivers/gpu/drm/nouveau/include/nvif/class.h | 9 + .../drm/nouveau/include/nvkm/core/device.h | 4 + .../drm/nouveau/include/nvkm/core/layout.h | 1 + .../gpu/drm/nouveau/include/nvkm/subdev/fb.h | 1 + .../gpu/drm/nouveau/include/nvkm/subdev/fsp.h | 22 ++ .../gpu/drm/nouveau/include/nvkm/subdev/gsp.h | 13 + .../drm/nouveau/include/nvkm/subdev/instmem.h | 1 + .../gpu/drm/nouveau/include/nvkm/subdev/mmu.h | 1 + .../gpu/drm/nouveau/include/nvkm/subdev/pci.h | 1 + drivers/gpu/drm/nouveau/nouveau_bo.c | 1 + drivers/gpu/drm/nouveau/nouveau_chan.c | 1 + drivers/gpu/drm/nouveau/nouveau_drm.c | 1 + drivers/gpu/drm/nouveau/nvif/user.c | 1 + .../gpu/drm/nouveau/nvkm/engine/device/base.c | 18 + .../gpu/drm/nouveau/nvkm/engine/device/priv.h | 1 + .../gpu/drm/nouveau/nvkm/engine/device/user.c | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/Kbuild | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/fb/Kbuild | 1 + .../gpu/drm/nouveau/nvkm/subdev/fb/ga102.c | 2 +- .../gpu/drm/nouveau/nvkm/subdev/fb/gh100.c | 30 ++ drivers/gpu/drm/nouveau/nvkm/subdev/fb/priv.h | 2 + .../gpu/drm/nouveau/nvkm/subdev/fsp/Kbuild | 6 + .../gpu/drm/nouveau/nvkm/subdev/fsp/base.c | 66 ++++ .../gpu/drm/nouveau/nvkm/subdev/fsp/gh100.c | 275 ++++++++++++++ .../gpu/drm/nouveau/nvkm/subdev/fsp/priv.h | 28 ++ .../gpu/drm/nouveau/nvkm/subdev/gsp/Kbuild | 1 + .../gpu/drm/nouveau/nvkm/subdev/gsp/base.c | 2 + .../gpu/drm/nouveau/nvkm/subdev/gsp/gh100.c | 353 ++++++++++++++++++ .../gpu/drm/nouveau/nvkm/subdev/gsp/priv.h | 8 + .../gpu/drm/nouveau/nvkm/subdev/gsp/rm/Kbuild | 1 + .../drm/nouveau/nvkm/subdev/gsp/rm/gh100.c | 27 ++ .../gpu/drm/nouveau/nvkm/subdev/gsp/rm/gpu.h | 1 + .../drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c | 6 + .../drm/nouveau/nvkm/subdev/gsp/rm/r570/gsp.c | 11 +- .../nvkm/subdev/gsp/rm/r570/nvrm/gsp.h | 58 +++ .../drm/nouveau/nvkm/subdev/gsp/rm/r570/rm.c | 15 + .../gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h | 3 + .../gpu/drm/nouveau/nvkm/subdev/gsp/tu102.c | 4 +- .../drm/nouveau/nvkm/subdev/instmem/Kbuild | 1 + .../drm/nouveau/nvkm/subdev/instmem/gh100.c | 28 ++ .../drm/nouveau/nvkm/subdev/instmem/nv50.c | 6 +- .../drm/nouveau/nvkm/subdev/instmem/priv.h | 5 + .../gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild | 2 + .../gpu/drm/nouveau/nvkm/subdev/mmu/gh100.c | 25 ++ .../gpu/drm/nouveau/nvkm/subdev/mmu/priv.h | 2 + .../gpu/drm/nouveau/nvkm/subdev/mmu/tu102.c | 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h | 7 + .../drm/nouveau/nvkm/subdev/mmu/vmmgh100.c | 306 +++++++++++++++ .../drm/nouveau/nvkm/subdev/mmu/vmmgp100.c | 3 + .../drm/nouveau/nvkm/subdev/mmu/vmmtu102.c | 2 +- .../gpu/drm/nouveau/nvkm/subdev/pci/Kbuild | 1 + .../gpu/drm/nouveau/nvkm/subdev/pci/gh100.c | 30 ++ 61 files changed, 1680 insertions(+), 9 deletions(-) create mode 100644 drivers/gpu/drm/nouveau/include/nvhw/ref/gh100/dev_falcon_v4.h create mode 100644 drivers/gpu/drm/nouveau/include/nvhw/ref/gh100/dev_fb.h create mode 100644 drivers/gpu/drm/nouveau/include/nvhw/ref/gh100/dev_fsp_pri.h create mode 100644 drivers/gpu/drm/nouveau/include/nvhw/ref/gh100/dev_mmu.h create mode 100644 drivers/gpu/drm/nouveau/include/nvhw/ref/gh100/dev_riscv_pri.h create mode 100644 drivers/gpu/drm/nouveau/include/nvhw/ref/gh100/dev_therm.h create mode 100644 drivers/gpu/drm/nouveau/include/nvhw/ref/gh100/dev_xtl_ep_pri.h create mode 100644 drivers/gpu/drm/nouveau/include/nvhw/ref/gh100/pri_nv_xal_ep.h create mode 100644 drivers/gpu/drm/nouveau/include/nvkm/subdev/fsp.h create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/fb/gh100.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/fsp/Kbuild create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/fsp/base.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/fsp/gh100.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/fsp/priv.h create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/gh100.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gh100.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gh100.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gh100.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgh100.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/pci/gh100.c diff --git a/drivers/gpu/drm/nouveau/include/nvhw/ref/gh100/dev_falcon_v4.h b/drivers/gpu/drm/nouveau/include/nvhw/ref/gh100/dev_falcon_v4.h new file mode 100644 index 000000000000..52171b412aa1 --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvhw/ref/gh100/dev_falcon_v4.h @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#ifndef __gh100_dev_falcon_v4_h__ +#define __gh100_dev_falcon_v4_h__ + +#define NV_PFALCON_FALCON_MAILBOX0 0x00000040 /* RW-4R */ +#define NV_PFALCON_FALCON_MAILBOX0_DATA 31:0 /* RWIVF */ +#define NV_PFALCON_FALCON_MAILBOX0_DATA_INIT 0x00000000 /* RWI-V */ +#define NV_PFALCON_FALCON_MAILBOX1 0x00000044 /* RW-4R */ +#define NV_PFALCON_FALCON_MAILBOX1_DATA 31:0 /* RWIVF */ +#define NV_PFALCON_FALCON_MAILBOX1_DATA_INIT 0x00000000 /* RWI-V */ + +#define NV_PFALCON_FALCON_HWCFG2 0x000000f4 /* R--4R */ +#define NV_PFALCON_FALCON_HWCFG2_RISCV_BR_PRIV_LOCKDOWN 13:13 /* R--VF */ +#define NV_PFALCON_FALCON_HWCFG2_RISCV_BR_PRIV_LOCKDOWN_LOCK 0x00000001 /* R---V */ +#define NV_PFALCON_FALCON_HWCFG2_RISCV_BR_PRIV_LOCKDOWN_UNLOCK 0x00000000 /* R---V */ + +#endif // __gh100_dev_falcon_v4_h__ diff --git a/drivers/gpu/drm/nouveau/include/nvhw/ref/gh100/dev_fb.h b/drivers/gpu/drm/nouveau/include/nvhw/ref/gh100/dev_fb.h new file mode 100644 index 000000000000..819f09465952 --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvhw/ref/gh100/dev_fb.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#ifndef __gh100_dev_fb_h_ +#define __gh100_dev_fb_h_ + +#define NV_PFB_NISO_FLUSH_SYSMEM_ADDR_SHIFT 8 /* */ +#define NV_PFB_FBHUB_PCIE_FLUSH_SYSMEM_ADDR_LO 0x00100A34 /* RW-4R */ +#define NV_PFB_FBHUB_PCIE_FLUSH_SYSMEM_ADDR_LO_ADR 31:0 /* RWIVF */ +#define NV_PFB_FBHUB_PCIE_FLUSH_SYSMEM_ADDR_HI 0x00100A38 /* RW-4R */ +#define NV_PFB_FBHUB_PCIE_FLUSH_SYSMEM_ADDR_HI_ADR 31:0 /* RWIVF */ +#define NV_PFB_FBHUB_PCIE_FLUSH_SYSMEM_ADDR_HI_ADR_MASK 0x000FFFFF /* ----V */ + +#endif // __gh100_dev_fb_h_ diff --git a/drivers/gpu/drm/nouveau/include/nvhw/ref/gh100/dev_fsp_pri.h b/drivers/gpu/drm/nouveau/include/nvhw/ref/gh100/dev_fsp_pri.h new file mode 100644 index 000000000000..e9507242cae5 --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvhw/ref/gh100/dev_fsp_pri.h @@ -0,0 +1,28 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#ifndef __gh100_dev_fsp_pri_h__ +#define __gh100_dev_fsp_pri_h__ + +#define NV_PFSP 0x8F3FFF:0x8F0000 /* RW--D */ + +#define NV_PFSP_MSGQ_HEAD(i) (0x008F2c80+(i)*8) /* RW-4A */ +#define NV_PFSP_MSGQ_HEAD__SIZE_1 8 /* */ +#define NV_PFSP_MSGQ_HEAD_VAL 31:0 /* RWIUF */ +#define NV_PFSP_MSGQ_HEAD_VAL_INIT 0x00000000 /* RWI-V */ +#define NV_PFSP_MSGQ_TAIL(i) (0x008F2c84+(i)*8) /* RW-4A */ +#define NV_PFSP_MSGQ_TAIL__SIZE_1 8 /* */ +#define NV_PFSP_MSGQ_TAIL_VAL 31:0 /* RWIUF */ +#define NV_PFSP_MSGQ_TAIL_VAL_INIT 0x00000000 /* RWI-V */ + +#define NV_PFSP_QUEUE_HEAD(i) (0x008F2c00+(i)*8) /* RW-4A */ +#define NV_PFSP_QUEUE_HEAD__SIZE_1 8 /* */ +#define NV_PFSP_QUEUE_HEAD_ADDRESS 31:0 /* RWIVF */ +#define NV_PFSP_QUEUE_HEAD_ADDRESS_INIT 0x00000000 /* RWI-V */ +#define NV_PFSP_QUEUE_TAIL(i) (0x008F2c04+(i)*8) /* RW-4A */ +#define NV_PFSP_QUEUE_TAIL__SIZE_1 8 /* */ +#define NV_PFSP_QUEUE_TAIL_ADDRESS 31:0 /* RWIVF */ +#define NV_PFSP_QUEUE_TAIL_ADDRESS_INIT 0x00000000 /* RWI-V */ + +#endif // __gh100_dev_fsp_pri_h__ diff --git a/drivers/gpu/drm/nouveau/include/nvhw/ref/gh100/dev_mmu.h b/drivers/gpu/drm/nouveau/include/nvhw/ref/gh100/dev_mmu.h new file mode 100644 index 000000000000..6707e0e3b96b --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvhw/ref/gh100/dev_mmu.h @@ -0,0 +1,173 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#ifndef __gh100_dev_mmu_h__ +#define __gh100_dev_mmu_h__ + +#define NV_MMU_PTE /* ----G */ +#define NV_MMU_PTE_APERTURE (1*32+2):(1*32+1) /* RWXVF */ +#define NV_MMU_PTE_APERTURE_VIDEO_MEMORY 0x00000000 /* RW--V */ +#define NV_MMU_PTE_APERTURE_PEER_MEMORY 0x00000001 /* RW--V */ +#define NV_MMU_PTE_APERTURE_SYSTEM_COHERENT_MEMORY 0x00000002 /* RW--V */ +#define NV_MMU_PTE_APERTURE_SYSTEM_NON_COHERENT_MEMORY 0x00000003 /* RW--V */ +#define NV_MMU_PTE_KIND (1*32+7):(1*32+4) /* RWXVF */ +#define NV_MMU_PTE_KIND_INVALID 0x07 /* R---V */ +#define NV_MMU_PTE_KIND_PITCH 0x00 /* R---V */ +#define NV_MMU_PTE_KIND_GENERIC_MEMORY 0x6 /* R---V */ +#define NV_MMU_PTE_KIND_Z16 0x1 /* R---V */ +#define NV_MMU_PTE_KIND_S8 0x2 /* R---V */ +#define NV_MMU_PTE_KIND_S8Z24 0x3 /* R---V */ +#define NV_MMU_PTE_KIND_ZF32_X24S8 0x4 /* R---V */ +#define NV_MMU_PTE_KIND_Z24S8 0x5 /* R---V */ +#define NV_MMU_PTE_KIND_GENERIC_MEMORY_COMPRESSIBLE 0x8 /* R---V */ +#define NV_MMU_PTE_KIND_GENERIC_MEMORY_COMPRESSIBLE_DISABLE_PLC 0x9 /* R---V */ +#define NV_MMU_PTE_KIND_S8_COMPRESSIBLE_DISABLE_PLC 0xA /* R---V */ +#define NV_MMU_PTE_KIND_Z16_COMPRESSIBLE_DISABLE_PLC 0xB /* R---V */ +#define NV_MMU_PTE_KIND_S8Z24_COMPRESSIBLE_DISABLE_PLC 0xC /* R---V */ +#define NV_MMU_PTE_KIND_ZF32_X24S8_COMPRESSIBLE_DISABLE_PLC 0xD /* R---V */ +#define NV_MMU_PTE_KIND_Z24S8_COMPRESSIBLE_DISABLE_PLC 0xE /* R---V */ +#define NV_MMU_PTE_KIND_SMSKED_MESSAGE 0xF /* R---V */ + +#define NV_MMU_VER3_PDE /* ----G */ +#define NV_MMU_VER3_PDE_IS_PTE 0:0 /* RWXVF */ +#define NV_MMU_VER3_PDE_IS_PTE_TRUE 0x1 /* RW--V */ +#define NV_MMU_VER3_PDE_IS_PTE_FALSE 0x0 /* RW--V */ +#define NV_MMU_VER3_PDE_VALID 0:0 /* RWXVF */ +#define NV_MMU_VER3_PDE_VALID_TRUE 0x1 /* RW--V */ +#define NV_MMU_VER3_PDE_VALID_FALSE 0x0 /* RW--V */ +#define NV_MMU_VER3_PDE_APERTURE 2:1 /* RWXVF */ +#define NV_MMU_VER3_PDE_APERTURE_INVALID 0x00000000 /* RW--V */ +#define NV_MMU_VER3_PDE_APERTURE_VIDEO_MEMORY 0x00000001 /* RW--V */ +#define NV_MMU_VER3_PDE_APERTURE_SYSTEM_COHERENT_MEMORY 0x00000002 /* RW--V */ +#define NV_MMU_VER3_PDE_APERTURE_SYSTEM_NON_COHERENT_MEMORY 0x00000003 /* RW--V */ +#define NV_MMU_VER3_PDE_PCF 5:3 /* RWXVF */ +#define NV_MMU_VER3_PDE_PCF_VALID_CACHED_ATS_ALLOWED__OR__INVALID_ATS_ALLOWED 0x00000000 /* RW--V */ +#define NV_MMU_VER3_PDE_PCF_VALID_CACHED_ATS_ALLOWED 0x00000000 /* RW--V */ +#define NV_MMU_VER3_PDE_PCF_INVALID_ATS_ALLOWED 0x00000000 /* RW--V */ +#define NV_MMU_VER3_PDE_PCF_VALID_UNCACHED_ATS_ALLOWED__OR__SPARSE_ATS_ALLOWED 0x00000001 /* RW--V */ +#define NV_MMU_VER3_PDE_PCF_VALID_UNCACHED_ATS_ALLOWED 0x00000001 /* RW--V */ +#define NV_MMU_VER3_PDE_PCF_SPARSE_ATS_ALLOWED 0x00000001 /* RW--V */ +#define NV_MMU_VER3_PDE_PCF_VALID_CACHED_ATS_NOT_ALLOWED__OR__INVALID_ATS_NOT_ALLOWED 0x00000002 /* RW--V */ +#define NV_MMU_VER3_PDE_PCF_VALID_CACHED_ATS_NOT_ALLOWED 0x00000002 /* RW--V */ +#define NV_MMU_VER3_PDE_PCF_INVALID_ATS_NOT_ALLOWED 0x00000002 /* RW--V */ +#define NV_MMU_VER3_PDE_PCF_VALID_UNCACHED_ATS_NOT_ALLOWED__OR__SPARSE_ATS_NOT_ALLOWED 0x00000003 /* RW--V */ +#define NV_MMU_VER3_PDE_PCF_VALID_UNCACHED_ATS_NOT_ALLOWED 0x00000003 /* RW--V */ +#define NV_MMU_VER3_PDE_PCF_SPARSE_ATS_NOT_ALLOWED 0x00000003 /* RW--V */ +#define NV_MMU_VER3_PDE_ADDRESS 51:12 /* RWXVF */ +#define NV_MMU_VER3_PDE_ADDRESS_SHIFT 0x0000000c /* */ +#define NV_MMU_VER3_PDE__SIZE 8 + +#define NV_MMU_VER3_DUAL_PDE /* ----G */ +#define NV_MMU_VER3_DUAL_PDE_IS_PTE 0:0 /* RWXVF */ +#define NV_MMU_VER3_DUAL_PDE_IS_PTE_TRUE 0x1 /* RW--V */ +#define NV_MMU_VER3_DUAL_PDE_IS_PTE_FALSE 0x0 /* RW--V */ +#define NV_MMU_VER3_DUAL_PDE_VALID 0:0 /* RWXVF */ +#define NV_MMU_VER3_DUAL_PDE_VALID_TRUE 0x1 /* RW--V */ +#define NV_MMU_VER3_DUAL_PDE_VALID_FALSE 0x0 /* RW--V */ +#define NV_MMU_VER3_DUAL_PDE_APERTURE_BIG 2:1 /* RWXVF */ +#define NV_MMU_VER3_DUAL_PDE_APERTURE_BIG_INVALID 0x00000000 /* RW--V */ +#define NV_MMU_VER3_DUAL_PDE_APERTURE_BIG_VIDEO_MEMORY 0x00000001 /* RW--V */ +#define NV_MMU_VER3_DUAL_PDE_APERTURE_BIG_SYSTEM_COHERENT_MEMORY 0x00000002 /* RW--V */ +#define NV_MMU_VER3_DUAL_PDE_APERTURE_BIG_SYSTEM_NON_COHERENT_MEMORY 0x00000003 /* RW--V */ +#define NV_MMU_VER3_DUAL_PDE_PCF_BIG 5:3 /* RWXVF */ +#define NV_MMU_VER3_DUAL_PDE_PCF_BIG_VALID_CACHED_ATS_ALLOWED__OR__INVALID_ATS_ALLOWED 0x00000000 /* RW--V */ +#define NV_MMU_VER3_DUAL_PDE_PCF_BIG_VALID_CACHED_ATS_ALLOWED 0x00000000 /* RW--V */ +#define NV_MMU_VER3_DUAL_PDE_PCF_BIG_INVALID_ATS_ALLOWED 0x00000000 /* RW--V */ +#define NV_MMU_VER3_DUAL_PDE_PCF_BIG_VALID_UNCACHED_ATS_ALLOWED__OR__SPARSE_ATS_ALLOWED 0x00000001 /* RW--V */ +#define NV_MMU_VER3_DUAL_PDE_PCF_BIG_VALID_UNCACHED_ATS_ALLOWED 0x00000001 /* RW--V */ +#define NV_MMU_VER3_DUAL_PDE_PCF_BIG_SPARSE_ATS_ALLOWED 0x00000001 /* RW--V */ +#define NV_MMU_VER3_DUAL_PDE_PCF_BIG_VALID_CACHED_ATS_NOT_ALLOWED__OR__INVALID_ATS_NOT_ALLOWED 0x00000002 /* RW--V */ +#define NV_MMU_VER3_DUAL_PDE_PCF_BIG_VALID_CACHED_ATS_NOT_ALLOWED 0x00000002 /* RW--V */ +#define NV_MMU_VER3_DUAL_PDE_PCF_BIG_INVALID_ATS_NOT_ALLOWED 0x00000002 /* RW--V */ +#define NV_MMU_VER3_DUAL_PDE_PCF_BIG_VALID_UNCACHED_ATS_NOT_ALLOWED__OR__SPARSE_ATS_NOT_ALLOWED 0x00000003 /* RW--V */ +#define NV_MMU_VER3_DUAL_PDE_PCF_BIG_VALID_UNCACHED_ATS_NOT_ALLOWED 0x00000003 /* RW--V */ +#define NV_MMU_VER3_DUAL_PDE_PCF_BIG_SPARSE_ATS_NOT_ALLOWED 0x00000003 /* RW--V */ +#define NV_MMU_VER3_DUAL_PDE_ADDRESS_BIG 51:8 /* RWXVF */ +#define NV_MMU_VER3_DUAL_PDE_APERTURE_SMALL 66:65 /* RWXVF */ +#define NV_MMU_VER3_DUAL_PDE_APERTURE_SMALL_INVALID 0x00000000 /* RW--V */ +#define NV_MMU_VER3_DUAL_PDE_APERTURE_SMALL_VIDEO_MEMORY 0x00000001 /* RW--V */ +#define NV_MMU_VER3_DUAL_PDE_APERTURE_SMALL_SYSTEM_COHERENT_MEMORY 0x00000002 /* RW--V */ +#define NV_MMU_VER3_DUAL_PDE_APERTURE_SMALL_SYSTEM_NON_COHERENT_MEMORY 0x00000003 /* RW--V */ +#define NV_MMU_VER3_DUAL_PDE_PCF_SMALL 69:67 /* RWXVF */ +#define NV_MMU_VER3_DUAL_PDE_PCF_SMALL_VALID_CACHED_ATS_ALLOWED__OR__INVALID_ATS_ALLOWED 0x00000000 /* RW--V */ +#define NV_MMU_VER3_DUAL_PDE_PCF_SMALL_VALID_CACHED_ATS_ALLOWED 0x00000000 /* RW--V */ +#define NV_MMU_VER3_DUAL_PDE_PCF_SMALL_INVALID_ATS_ALLOWED 0x00000000 /* RW--V */ +#define NV_MMU_VER3_DUAL_PDE_PCF_SMALL_VALID_UNCACHED_ATS_ALLOWED__OR__SPARSE_ATS_ALLOWED 0x00000001 /* RW--V */ +#define NV_MMU_VER3_DUAL_PDE_PCF_SMALL_VALID_UNCACHED_ATS_ALLOWED 0x00000001 /* RW--V */ +#define NV_MMU_VER3_DUAL_PDE_PCF_SMALL_SPARSE_ATS_ALLOWED 0x00000001 /* RW--V */ +#define NV_MMU_VER3_DUAL_PDE_PCF_SMALL_VALID_CACHED_ATS_NOT_ALLOWED__OR__INVALID_ATS_NOT_ALLOWED 0x00000002 /* RW--V */ +#define NV_MMU_VER3_DUAL_PDE_PCF_SMALL_VALID_CACHED_ATS_NOT_ALLOWED 0x00000002 /* RW--V */ +#define NV_MMU_VER3_DUAL_PDE_PCF_SMALL_INVALID_ATS_NOT_ALLOWED 0x00000002 /* RW--V */ +#define NV_MMU_VER3_DUAL_PDE_PCF_SMALL_VALID_UNCACHED_ATS_NOT_ALLOWED__OR__SPARSE_ATS_NOT_ALLOWED 0x00000003 /* RW--V */ +#define NV_MMU_VER3_DUAL_PDE_PCF_SMALL_VALID_UNCACHED_ATS_NOT_ALLOWED 0x00000003 /* RW--V */ +#define NV_MMU_VER3_DUAL_PDE_PCF_SMALL_SPARSE_ATS_NOT_ALLOWED 0x00000003 /* RW--V */ +#define NV_MMU_VER3_DUAL_PDE_ADDRESS_SMALL 115:76 /* RWXVF */ +#define NV_MMU_VER3_DUAL_PDE_ADDRESS_SHIFT 0x0000000c /* */ +#define NV_MMU_VER3_DUAL_PDE_ADDRESS_BIG_SHIFT 8 /* */ +#define NV_MMU_VER3_DUAL_PDE__SIZE 16 + +#define NV_MMU_VER3_PTE /* ----G */ +#define NV_MMU_VER3_PTE_VALID 0:0 /* RWXVF */ +#define NV_MMU_VER3_PTE_VALID_TRUE 0x1 /* RW--V */ +#define NV_MMU_VER3_PTE_VALID_FALSE 0x0 /* RW--V */ +#define NV_MMU_VER3_PTE_APERTURE 2:1 /* RWXVF */ +#define NV_MMU_VER3_PTE_APERTURE_VIDEO_MEMORY 0x00000000 /* RW--V */ +#define NV_MMU_VER3_PTE_APERTURE_PEER_MEMORY 0x00000001 /* RW--V */ +#define NV_MMU_VER3_PTE_APERTURE_SYSTEM_COHERENT_MEMORY 0x00000002 /* RW--V */ +#define NV_MMU_VER3_PTE_APERTURE_SYSTEM_NON_COHERENT_MEMORY 0x00000003 /* RW--V */ +#define NV_MMU_VER3_PTE_PCF 7:3 /* RWXVF */ +#define NV_MMU_VER3_PTE_PCF_INVALID 0x00000000 /* RW--V */ +#define NV_MMU_VER3_PTE_PCF_SPARSE 0x00000001 /* RW--V */ +#define NV_MMU_VER3_PTE_PCF_MAPPING_NOWHERE 0x00000002 /* RW--V */ +#define NV_MMU_VER3_PTE_PCF_NO_VALID_4KB_PAGE 0x00000003 /* RW--V */ +#define NV_MMU_VER3_PTE_PCF_REGULAR_RW_ATOMIC_CACHED_ACE 0x00000000 /* RW--V */ +#define NV_MMU_VER3_PTE_PCF_REGULAR_RW_ATOMIC_UNCACHED_ACE 0x00000001 /* RW--V */ +#define NV_MMU_VER3_PTE_PCF_PRIVILEGE_RW_ATOMIC_CACHED_ACE 0x00000002 /* RW--V */ +#define NV_MMU_VER3_PTE_PCF_PRIVILEGE_RW_ATOMIC_UNCACHED_ACE 0x00000003 /* RW--V */ +#define NV_MMU_VER3_PTE_PCF_REGULAR_RO_ATOMIC_CACHED_ACE 0x00000004 /* RW--V */ +#define NV_MMU_VER3_PTE_PCF_REGULAR_RO_ATOMIC_UNCACHED_ACE 0x00000005 /* RW--V */ +#define NV_MMU_VER3_PTE_PCF_PRIVILEGE_RO_ATOMIC_CACHED_ACE 0x00000006 /* RW--V */ +#define NV_MMU_VER3_PTE_PCF_PRIVILEGE_RO_ATOMIC_UNCACHED_ACE 0x00000007 /* RW--V */ +#define NV_MMU_VER3_PTE_PCF_REGULAR_RW_NO_ATOMIC_CACHED_ACE 0x00000008 /* RW--V */ +#define NV_MMU_VER3_PTE_PCF_REGULAR_RW_NO_ATOMIC_UNCACHED_ACE 0x00000009 /* RW--V */ +#define NV_MMU_VER3_PTE_PCF_PRIVILEGE_RW_NO_ATOMIC_CACHED_ACE 0x0000000A /* RW--V */ +#define NV_MMU_VER3_PTE_PCF_PRIVILEGE_RW_NO_ATOMIC_UNCACHED_ACE 0x0000000B /* RW--V */ +#define NV_MMU_VER3_PTE_PCF_REGULAR_RO_NO_ATOMIC_CACHED_ACE 0x0000000C /* RW--V */ +#define NV_MMU_VER3_PTE_PCF_REGULAR_RO_NO_ATOMIC_UNCACHED_ACE 0x0000000D /* RW--V */ +#define NV_MMU_VER3_PTE_PCF_PRIVILEGE_RO_NO_ATOMIC_CACHED_ACE 0x0000000E /* RW--V */ +#define NV_MMU_VER3_PTE_PCF_PRIVILEGE_RO_NO_ATOMIC_UNCACHED_ACE 0x0000000F /* RW--V */ +#define NV_MMU_VER3_PTE_PCF_REGULAR_RW_ATOMIC_CACHED_ACD 0x00000010 /* RW--V */ +#define NV_MMU_VER3_PTE_PCF_REGULAR_RW_ATOMIC_UNCACHED_ACD 0x00000011 /* RW--V */ +#define NV_MMU_VER3_PTE_PCF_PRIVILEGE_RW_ATOMIC_CACHED_ACD 0x00000012 /* RW--V */ +#define NV_MMU_VER3_PTE_PCF_PRIVILEGE_RW_ATOMIC_UNCACHED_ACD 0x00000013 /* RW--V */ +#define NV_MMU_VER3_PTE_PCF_REGULAR_RO_ATOMIC_CACHED_ACD 0x00000014 /* RW--V */ +#define NV_MMU_VER3_PTE_PCF_REGULAR_RO_ATOMIC_UNCACHED_ACD 0x00000015 /* RW--V */ +#define NV_MMU_VER3_PTE_PCF_PRIVILEGE_RO_ATOMIC_CACHED_ACD 0x00000016 /* RW--V */ +#define NV_MMU_VER3_PTE_PCF_PRIVILEGE_RO_ATOMIC_UNCACHED_ACD 0x00000017 /* RW--V */ +#define NV_MMU_VER3_PTE_PCF_REGULAR_RW_NO_ATOMIC_CACHED_ACD 0x00000018 /* RW--V */ +#define NV_MMU_VER3_PTE_PCF_REGULAR_RW_NO_ATOMIC_UNCACHED_ACD 0x00000019 /* RW--V */ +#define NV_MMU_VER3_PTE_PCF_PRIVILEGE_RW_NO_ATOMIC_CACHED_ACD 0x0000001A /* RW--V */ +#define NV_MMU_VER3_PTE_PCF_PRIVILEGE_RW_NO_ATOMIC_UNCACHED_ACD 0x0000001B /* RW--V */ +#define NV_MMU_VER3_PTE_PCF_REGULAR_RO_NO_ATOMIC_CACHED_ACD 0x0000001C /* RW--V */ +#define NV_MMU_VER3_PTE_PCF_REGULAR_RO_NO_ATOMIC_UNCACHED_ACD 0x0000001D /* RW--V */ +#define NV_MMU_VER3_PTE_PCF_PRIVILEGE_RO_NO_ATOMIC_CACHED_ACD 0x0000001E /* RW--V */ +#define NV_MMU_VER3_PTE_PCF_PRIVILEGE_RO_NO_ATOMIC_UNCACHED_ACD 0x0000001F /* RW--V */ +#define NV_MMU_VER3_PTE_KIND 11:8 /* RWXVF */ +#define NV_MMU_VER3_PTE_ADDRESS 51:12 /* RWXVF */ +#define NV_MMU_VER3_PTE_ADDRESS_SYS 51:12 /* RWXVF */ +#define NV_MMU_VER3_PTE_ADDRESS_PEER 51:12 /* RWXVF */ +#define NV_MMU_VER3_PTE_ADDRESS_VID 39:12 /* RWXVF */ +#define NV_MMU_VER3_PTE_PEER_ID 63:(64-3) /* RWXVF */ +#define NV_MMU_VER3_PTE_PEER_ID_0 0x00000000 /* RW--V */ +#define NV_MMU_VER3_PTE_PEER_ID_1 0x00000001 /* RW--V */ +#define NV_MMU_VER3_PTE_PEER_ID_2 0x00000002 /* RW--V */ +#define NV_MMU_VER3_PTE_PEER_ID_3 0x00000003 /* RW--V */ +#define NV_MMU_VER3_PTE_PEER_ID_4 0x00000004 /* RW--V */ +#define NV_MMU_VER3_PTE_PEER_ID_5 0x00000005 /* RW--V */ +#define NV_MMU_VER3_PTE_PEER_ID_6 0x00000006 /* RW--V */ +#define NV_MMU_VER3_PTE_PEER_ID_7 0x00000007 /* RW--V */ +#define NV_MMU_VER3_PTE_ADDRESS_SHIFT 0x0000000c /* */ +#define NV_MMU_VER3_PTE__SIZE 8 + +#endif // __gh100_dev_mmu_h__ diff --git a/drivers/gpu/drm/nouveau/include/nvhw/ref/gh100/dev_riscv_pri.h b/drivers/gpu/drm/nouveau/include/nvhw/ref/gh100/dev_riscv_pri.h new file mode 100644 index 000000000000..8ff4663168d2 --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvhw/ref/gh100/dev_riscv_pri.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#ifndef __gh100_dev_riscv_pri_h__ +#define __gh100_dev_riscv_pri_h__ + +#define NV_PRISCV_RISCV_CPUCTL 0x00000388 /* RW-4R */ +#define NV_PRISCV_RISCV_CPUCTL_HALTED 4:4 /* R-IVF */ +#define NV_PRISCV_RISCV_CPUCTL_HALTED_INIT 0x00000001 /* R-I-V */ +#define NV_PRISCV_RISCV_CPUCTL_HALTED_TRUE 0x00000001 /* R---V */ +#define NV_PRISCV_RISCV_CPUCTL_HALTED_FALSE 0x00000000 /* R---V */ + +#endif // __gh100_dev_riscv_pri_h__ diff --git a/drivers/gpu/drm/nouveau/include/nvhw/ref/gh100/dev_therm.h b/drivers/gpu/drm/nouveau/include/nvhw/ref/gh100/dev_therm.h new file mode 100644 index 000000000000..49b4816cb00b --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvhw/ref/gh100/dev_therm.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#ifndef __gh100_dev_therm_h__ +#define __gh100_dev_therm_h__ + +#define NV_THERM_I2CS_SCRATCH 0x000200bc /* RW-4R */ +#define NV_THERM_I2CS_SCRATCH_DATA 31:0 /* RWIVF */ +#define NV_THERM_I2CS_SCRATCH_DATA_INIT 0x00000000 /* RWI-V */ + +#define NV_THERM_I2CS_SCRATCH_FSP_BOOT_COMPLETE NV_THERM_I2CS_SCRATCH +#define NV_THERM_I2CS_SCRATCH_FSP_BOOT_COMPLETE_STATUS 31:0 +#define NV_THERM_I2CS_SCRATCH_FSP_BOOT_COMPLETE_STATUS_SUCCESS 0x000000FF +#define NV_THERM_I2CS_SCRATCH_FSP_BOOT_COMPLETE_STATUS_FAILED 0x00000000 + +#endif // __gh100_dev_therm_h__ diff --git a/drivers/gpu/drm/nouveau/include/nvhw/ref/gh100/dev_xtl_ep_pri.h b/drivers/gpu/drm/nouveau/include/nvhw/ref/gh100/dev_xtl_ep_pri.h new file mode 100644 index 000000000000..12b49e9894a2 --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvhw/ref/gh100/dev_xtl_ep_pri.h @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#ifndef __gh100_dev_xtl_ep_pri_h__ +#define __gh100_dev_xtl_ep_pri_h__ + +#define NV_EP_PCFGM 0x92FFF:0x92000 /* RW--D */ + +#endif // __gh100_dev_xtl_ep_pri_h__ diff --git a/drivers/gpu/drm/nouveau/include/nvhw/ref/gh100/pri_nv_xal_ep.h b/drivers/gpu/drm/nouveau/include/nvhw/ref/gh100/pri_nv_xal_ep.h new file mode 100644 index 000000000000..1a891bd33fa3 --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvhw/ref/gh100/pri_nv_xal_ep.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#ifndef __gh100_pri_nv_xal_ep_h__ +#define __gh100_pri_nv_xal_ep_h__ + +#define NV_XAL_EP_BAR0_WINDOW_BASE_SHIFT 0x000010 +#define NV_XAL_EP_BAR0_WINDOW_BASE 21:0 +#define NV_XAL_EP_BAR0_WINDOW 0x0010fd40 + +#endif // __gh100_pri_nv_xal_ep_h__ + diff --git a/drivers/gpu/drm/nouveau/include/nvif/cl0080.h b/drivers/gpu/drm/nouveau/include/nvif/cl0080.h index ea937fa7bc55..60a52ef52071 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/cl0080.h +++ b/drivers/gpu/drm/nouveau/include/nvif/cl0080.h @@ -29,6 +29,7 @@ struct nv_device_info_v0 { #define NV_DEVICE_INFO_V0_TURING 0x0c #define NV_DEVICE_INFO_V0_AMPERE 0x0d #define NV_DEVICE_INFO_V0_ADA 0x0e +#define NV_DEVICE_INFO_V0_HOPPER 0x0f __u8 family; __u8 pad06[2]; __u64 ram_size; diff --git a/drivers/gpu/drm/nouveau/include/nvif/class.h b/drivers/gpu/drm/nouveau/include/nvif/class.h index 71a2a53bff7f..83acf367a65c 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/class.h +++ b/drivers/gpu/drm/nouveau/include/nvif/class.h @@ -63,6 +63,7 @@ #define VOLTA_USERMODE_A 0x0000c361 #define TURING_USERMODE_A 0x0000c461 #define AMPERE_USERMODE_A 0x0000c561 +#define HOPPER_USERMODE_A 0x0000c661 #define MAXWELL_FAULT_BUFFER_A /* clb069.h */ 0x0000b069 #define VOLTA_FAULT_BUFFER_A /* clb069.h */ 0x0000c369 @@ -85,6 +86,7 @@ #define TURING_CHANNEL_GPFIFO_A /* if0020.h */ 0x0000c46f #define AMPERE_CHANNEL_GPFIFO_A /* if0020.h */ 0x0000c56f #define AMPERE_CHANNEL_GPFIFO_B /* if0020.h */ 0x0000c76f +#define HOPPER_CHANNEL_GPFIFO_A 0x0000c86f #define NV50_DISP /* if0010.h */ 0x00005070 #define G82_DISP /* if0010.h */ 0x00008270 @@ -194,8 +196,11 @@ #define ADA_A /* cl9097.h */ 0x0000c997 +#define HOPPER_A 0x0000cb97 + #define NV74_BSP 0x000074b0 +#define NVB8B0_VIDEO_DECODER 0x0000b8b0 #define NVC4B0_VIDEO_DECODER 0x0000c4b0 #define NVC6B0_VIDEO_DECODER 0x0000c6b0 #define NVC7B0_VIDEO_DECODER 0x0000c7b0 @@ -228,6 +233,7 @@ #define TURING_DMA_COPY_A 0x0000c5b5 #define AMPERE_DMA_COPY_A 0x0000c6b5 #define AMPERE_DMA_COPY_B 0x0000c7b5 +#define HOPPER_DMA_COPY_A 0x0000c8b5 #define NVC4B7_VIDEO_ENCODER 0x0000c4b7 #define NVC7B7_VIDEO_ENCODER 0x0000c7b7 @@ -250,12 +256,15 @@ #define AMPERE_COMPUTE_A 0x0000c6c0 #define AMPERE_COMPUTE_B 0x0000c7c0 #define ADA_COMPUTE_A 0x0000c9c0 +#define HOPPER_COMPUTE_A 0x0000cbc0 #define NV74_CIPHER 0x000074c1 +#define NVB8D1_VIDEO_NVJPG 0x0000b8d1 #define NVC4D1_VIDEO_NVJPG 0x0000c4d1 #define NVC9D1_VIDEO_NVJPG 0x0000c9d1 +#define NVB8FA_VIDEO_OFA 0x0000b8fa #define NVC6FA_VIDEO_OFA 0x0000c6fa #define NVC7FA_VIDEO_OFA 0x0000c7fa #define NVC9FA_VIDEO_OFA 0x0000c9fa diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/device.h b/drivers/gpu/drm/nouveau/include/nvkm/core/device.h index f50f52d4dc3f..926542350abc 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, + GH100 = 0x180, AD100 = 0x190, } card_type; u32 chipset; @@ -131,6 +132,9 @@ struct nvkm_device *nvkm_device_find(u64 name); _temp; \ }) +#define NVKM_RD32_(p,o,dr) nvkm_rd32((p), (o) + (dr)) +#define NVKM_RD32(p,A...) DRF_RV(NVKM_RD32_, (p), 0, ##A) + void nvkm_device_del(struct nvkm_device **); struct nvkm_device_oclass { diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/layout.h b/drivers/gpu/drm/nouveau/include/nvkm/core/layout.h index 2debef27bd95..d92ffd17b729 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/core/layout.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/layout.h @@ -1,4 +1,5 @@ /* SPDX-License-Identifier: MIT */ +NVKM_LAYOUT_ONCE(NVKM_SUBDEV_FSP , struct nvkm_fsp , fsp) 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) diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h index 5b798a1a313d..c114903ce388 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h @@ -102,6 +102,7 @@ int gv100_fb_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct n int tu102_fb_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fb **); int ga100_fb_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fb **); int ga102_fb_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fb **); +int gh100_fb_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fb **); #include <subdev/bios.h> #include <subdev/bios/ramcfg.h> diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/fsp.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/fsp.h new file mode 100644 index 000000000000..2a8c1d5a65f9 --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/fsp.h @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#ifndef __NVKM_FSP_H__ +#define __NVKM_FSP_H__ +#include <core/subdev.h> +#include <core/falcon.h> + +struct nvkm_fsp { + const struct nvkm_fsp_func *func; + struct nvkm_subdev subdev; + + struct nvkm_falcon falcon; +}; + +bool nvkm_fsp_verify_gsp_fmc(struct nvkm_fsp *, u32 hash_size, u32 pkey_size, u32 sig_size); +int nvkm_fsp_boot_gsp_fmc(struct nvkm_fsp *, u64 args_addr, u32 rsvd_size, bool resume, + u64 img_addr, const u8 *hash, const u8 *pkey, const u8 *sig); + +int gh100_fsp_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fsp **); +#endif diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h index 4ad07f3ced69..8f611b2503b7 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h @@ -68,6 +68,9 @@ struct nvkm_gsp { const struct firmware *load; const struct firmware *unload; } booter; + + const struct firmware *fmc; + const struct firmware *bl; const struct firmware *rm; } fws; @@ -113,6 +116,15 @@ struct nvkm_gsp { struct nvkm_falcon_fw unload; } booter; + struct { + struct nvkm_gsp_mem fw; + u8 *hash; + u8 *pkey; + u8 *sig; + + struct nvkm_gsp_mem args; + } fmc; + struct { struct nvkm_gsp_mem fw; u32 code_offset; @@ -478,5 +490,6 @@ int tu102_gsp_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_ 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 gh100_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 7d93c742ee59..db835cf7b8ac 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/instmem.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/instmem.h @@ -36,4 +36,5 @@ int nv04_instmem_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nv int nv40_instmem_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_instmem **); int nv50_instmem_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_instmem **); int gk20a_instmem_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_instmem **); +int gh100_instmem_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_instmem **); #endif diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h index 4cab139f3236..abcb0dbcde70 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h @@ -166,4 +166,5 @@ int gp100_mmu_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct int gp10b_mmu_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_mmu **); int gv100_mmu_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_mmu **); int tu102_mmu_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_mmu **); +int gh100_mmu_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_mmu **); #endif diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/pci.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/pci.h index 3c103101d5fc..112b674ed9c8 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/pci.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/pci.h @@ -50,6 +50,7 @@ int gf100_pci_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct int gf106_pci_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_pci **); int gk104_pci_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_pci **); int gp100_pci_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_pci **); +int gh100_pci_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_pci **); /* pcie functions */ int nvkm_pcie_set_link(struct nvkm_pci *, enum nvkm_pcie_speed, u8 width); diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 9ab8380feb39..fbe0144927e8 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -923,6 +923,7 @@ nouveau_bo_move_init(struct nouveau_drm *drm) struct ttm_resource *, struct ttm_resource *); int (*init)(struct nouveau_channel *, u32 handle); } _methods[] = { + { "COPY", 4, 0xc8b5, nve0_bo_move_copy, nve0_bo_move_init }, { "COPY", 4, 0xc7b5, nve0_bo_move_copy, nve0_bo_move_init }, { "GRCE", 0, 0xc7b5, nve0_bo_move_copy, nvc0_bo_move_init }, { "COPY", 4, 0xc6b5, nve0_bo_move_copy, nve0_bo_move_init }, diff --git a/drivers/gpu/drm/nouveau/nouveau_chan.c b/drivers/gpu/drm/nouveau/nouveau_chan.c index 5bcd29809c1e..a14aa6715bb9 100644 --- a/drivers/gpu/drm/nouveau/nouveau_chan.c +++ b/drivers/gpu/drm/nouveau/nouveau_chan.c @@ -255,6 +255,7 @@ nouveau_channel_ctor(struct nouveau_cli *cli, bool priv, u64 runm, struct nouveau_channel **pchan) { const struct nvif_mclass hosts[] = { + { HOPPER_CHANNEL_GPFIFO_A, 0 }, { AMPERE_CHANNEL_GPFIFO_B, 0 }, { AMPERE_CHANNEL_GPFIFO_A, 0 }, { TURING_CHANNEL_GPFIFO_A, 0 }, diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index e7544942791d..5b6bb4c2f78b 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -509,6 +509,7 @@ nouveau_accel_init(struct nouveau_drm *drm) case TURING_CHANNEL_GPFIFO_A: case AMPERE_CHANNEL_GPFIFO_A: case AMPERE_CHANNEL_GPFIFO_B: + case HOPPER_CHANNEL_GPFIFO_A: ret = gv100_fence_create(drm); break; default: diff --git a/drivers/gpu/drm/nouveau/nvif/user.c b/drivers/gpu/drm/nouveau/nvif/user.c index b648a5e036af..ae470a1fdfb8 100644 --- a/drivers/gpu/drm/nouveau/nvif/user.c +++ b/drivers/gpu/drm/nouveau/nvif/user.c @@ -41,6 +41,7 @@ nvif_user_ctor(struct nvif_device *device, const char *name) int version; const struct nvif_user_func *func; } users[] = { + { HOPPER_USERMODE_A, -1, &nvif_userc361 }, { AMPERE_USERMODE_A, -1, &nvif_userc361 }, { TURING_USERMODE_A, -1, &nvif_userc361 }, { VOLTA_USERMODE_A, -1, &nvif_userc361 }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c index ebcaf2ecff48..5082fe5f1966 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c @@ -2681,6 +2681,22 @@ nv177_chipset = { .sec2 = { 0x00000001, ga102_sec2_new }, }; +static const struct nvkm_device_chip +nv180_chipset = { + .name = "GH100", + .bar = { 0x00000001, tu102_bar_new }, + .fault = { 0x00000001, tu102_fault_new }, + .fb = { 0x00000001, gh100_fb_new }, + .fsp = { 0x00000001, gh100_fsp_new }, + .gsp = { 0x00000001, gh100_gsp_new }, + .imem = { 0x00000001, gh100_instmem_new }, + .mmu = { 0x00000001, gh100_mmu_new }, + .pci = { 0x00000001, gh100_pci_new }, + .timer = { 0x00000001, gk20a_timer_new }, + .vfn = { 0x00000001, ga100_vfn_new }, + .fifo = { 0x00000001, ga102_fifo_new }, +}; + static const struct nvkm_device_chip nv192_chipset = { .name = "AD102", @@ -3101,6 +3117,7 @@ nvkm_device_ctor(const struct nvkm_device_func *func, case 0x140: device->card_type = GV100; break; case 0x160: device->card_type = TU100; break; case 0x170: device->card_type = GA100; break; + case 0x180: device->card_type = GH100; break; case 0x190: device->card_type = AD100; break; default: break; @@ -3204,6 +3221,7 @@ nvkm_device_ctor(const struct nvkm_device_func *func, case 0x174: device->chip = &nv174_chipset; break; case 0x176: device->chip = &nv176_chipset; break; case 0x177: device->chip = &nv177_chipset; break; + case 0x180: device->chip = &nv180_chipset; break; case 0x192: device->chip = &nv192_chipset; break; case 0x193: device->chip = &nv193_chipset; break; case 0x194: device->chip = &nv194_chipset; break; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/priv.h b/drivers/gpu/drm/nouveau/nvkm/engine/device/priv.h index 8da5e896dd74..75ee7506d443 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/priv.h @@ -11,6 +11,7 @@ #include <subdev/devinit.h> #include <subdev/fault.h> #include <subdev/fb.h> +#include <subdev/fsp.h> #include <subdev/fuse.h> #include <subdev/gpio.h> #include <subdev/gsp.h> diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/user.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/user.c index 1f331ec8d747..57c2678022b5 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/user.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/user.c @@ -148,6 +148,7 @@ nvkm_udevice_info(struct nvkm_udevice *udev, void *data, u32 size) case TU100: args->v0.family = NV_DEVICE_INFO_V0_TURING; break; case GA100: args->v0.family = NV_DEVICE_INFO_V0_AMPERE; break; case AD100: args->v0.family = NV_DEVICE_INFO_V0_ADA; break; + case GH100: args->v0.family = NV_DEVICE_INFO_V0_HOPPER; break; default: args->v0.family = 0; break; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/Kbuild index 4c2f6fc4ef58..c19ea4ea9bd3 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/Kbuild @@ -9,6 +9,7 @@ include $(src)/nvkm/subdev/fault/Kbuild include $(src)/nvkm/subdev/fb/Kbuild include $(src)/nvkm/subdev/fuse/Kbuild include $(src)/nvkm/subdev/gpio/Kbuild +include $(src)/nvkm/subdev/fsp/Kbuild include $(src)/nvkm/subdev/gsp/Kbuild include $(src)/nvkm/subdev/i2c/Kbuild include $(src)/nvkm/subdev/iccsense/Kbuild diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/Kbuild index d1611ad3bf81..f13312934131 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/Kbuild @@ -35,6 +35,7 @@ nvkm-y += nvkm/subdev/fb/gv100.o 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/gh100.o nvkm-y += nvkm/subdev/fb/r535.o diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ga102.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ga102.c index 25f82b372bca..2819780050d8 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ga102.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ga102.c @@ -25,7 +25,7 @@ #include <subdev/gsp.h> #include <engine/nvdec.h> -static u64 +u64 ga102_fb_vidmem_size(struct nvkm_fb *fb) { return (u64)nvkm_rd32(fb->subdev.device, 0x1183a4) << 20; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gh100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gh100.c new file mode 100644 index 000000000000..2d8c51f882d5 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gh100.c @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#include "priv.h" + +#include <nvhw/drf.h> +#include <nvhw/ref/gh100/dev_fb.h> + +static void +gh100_fb_sysmem_flush_page_init(struct nvkm_fb *fb) +{ + const u64 addr = fb->sysmem.flush_page_addr >> NV_PFB_NISO_FLUSH_SYSMEM_ADDR_SHIFT; + struct nvkm_device *device = fb->subdev.device; + + nvkm_wr32(device, NV_PFB_FBHUB_PCIE_FLUSH_SYSMEM_ADDR_HI, upper_32_bits(addr)); + nvkm_wr32(device, NV_PFB_FBHUB_PCIE_FLUSH_SYSMEM_ADDR_LO, lower_32_bits(addr)); +} + +static const struct nvkm_fb_func +gh100_fb = { + .sysmem.flush_page_init = gh100_fb_sysmem_flush_page_init, + .vidmem.size = ga102_fb_vidmem_size, +}; + +int +gh100_fb_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct nvkm_fb **pfb) +{ + return r535_fb_new(&gh100_fb, device, type, inst, pfb); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/priv.h index 35c55dfba23d..ebe996503ab2 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/priv.h @@ -98,4 +98,6 @@ int gp102_fb_vpr_scrub(struct nvkm_fb *); int gv100_fb_init_page(struct nvkm_fb *); bool tu102_fb_vpr_scrub_required(struct nvkm_fb *); + +u64 ga102_fb_vidmem_size(struct nvkm_fb *); #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fsp/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/fsp/Kbuild new file mode 100644 index 000000000000..ff04992b181d --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fsp/Kbuild @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: MIT +# +# Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + +nvkm-y += nvkm/subdev/fsp/base.o +nvkm-y += nvkm/subdev/fsp/gh100.o diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fsp/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fsp/base.c new file mode 100644 index 000000000000..e366a980baa9 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fsp/base.c @@ -0,0 +1,66 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#include "priv.h" + +int +nvkm_fsp_boot_gsp_fmc(struct nvkm_fsp *fsp, u64 args_addr, u32 rsvd_size, bool resume, + u64 img_addr, const u8 *hash, const u8 *pkey, const u8 *sig) +{ + return fsp->func->cot.boot_gsp_fmc(fsp, args_addr, rsvd_size, resume, + img_addr, hash, pkey, sig); +} + +bool +nvkm_fsp_verify_gsp_fmc(struct nvkm_fsp *fsp, u32 hash_size, u32 pkey_size, u32 sig_size) +{ + return hash_size == fsp->func->cot.size_hash && + pkey_size == fsp->func->cot.size_pkey && + sig_size == fsp->func->cot.size_sig; +} + +static int +nvkm_fsp_preinit(struct nvkm_subdev *subdev) +{ + struct nvkm_fsp *fsp = nvkm_fsp(subdev); + + return fsp->func->wait_secure_boot(fsp); +} + +static void * +nvkm_fsp_dtor(struct nvkm_subdev *subdev) +{ + struct nvkm_fsp *fsp = nvkm_fsp(subdev); + + nvkm_falcon_dtor(&fsp->falcon); + return fsp; +} + +static const struct nvkm_falcon_func +nvkm_fsp_flcn = { + .emem_pio = &gp102_flcn_emem_pio, +}; + +static const struct nvkm_subdev_func +nvkm_fsp = { + .dtor = nvkm_fsp_dtor, + .preinit = nvkm_fsp_preinit, +}; + +int +nvkm_fsp_new_(const struct nvkm_fsp_func *func, + struct nvkm_device *device, enum nvkm_subdev_type type, int inst, + struct nvkm_fsp **pfsp) +{ + struct nvkm_fsp *fsp; + + fsp = *pfsp = kzalloc(sizeof(*fsp), GFP_KERNEL); + if (!fsp) + return -ENOMEM; + + fsp->func = func; + nvkm_subdev_ctor(&nvkm_fsp, device, type, inst, &fsp->subdev); + + return nvkm_falcon_ctor(&nvkm_fsp_flcn, &fsp->subdev, "fsp", 0x8f2000, &fsp->falcon); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fsp/gh100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fsp/gh100.c new file mode 100644 index 000000000000..9f4285af3fed --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fsp/gh100.c @@ -0,0 +1,275 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#include "priv.h" + +#include <nvhw/drf.h> +#include <nvhw/ref/gh100/dev_fsp_pri.h> +#include <nvhw/ref/gh100/dev_therm.h> + +#include <nvrm/nvtypes.h> + +#define MCTP_HEADER_VERSION 3:0 +#define MCTP_HEADER_RSVD 7:4 + +#define MCTP_HEADER_DEID 15:8 +#define MCTP_HEADER_SEID 23:16 + +#define MCTP_HEADER_TAG 26:24 +#define MCTP_HEADER_TO 27:27 +#define MCTP_HEADER_SEQ 29:28 +#define MCTP_HEADER_EOM 30:30 +#define MCTP_HEADER_SOM 31:31 + +#define MCTP_MSG_HEADER_TYPE 6:0 +#define MCTP_MSG_HEADER_IC 7:7 + +#define MCTP_MSG_HEADER_VENDOR_ID 23:8 +#define MCTP_MSG_HEADER_NVDM_TYPE 31:24 + +#define MCTP_MSG_HEADER_TYPE_VENDOR_PCI 0x7e +#define MCTP_MSG_HEADER_VENDOR_ID_NV 0x10de + +#define NVDM_TYPE_COT 0x14 +#define NVDM_TYPE_FSP_RESPONSE 0x15 + +#pragma pack(1) +typedef struct nvdm_payload_cot +{ + NvU16 version; + NvU16 size; + NvU64 gspFmcSysmemOffset; + NvU64 frtsSysmemOffset; + NvU32 frtsSysmemSize; + + // Note this is an offset from the end of FB + NvU64 frtsVidmemOffset; + NvU32 frtsVidmemSize; + + // Authentication related fields + NvU32 hash384[12]; + NvU32 publicKey[96]; + NvU32 signature[96]; + + NvU64 gspBootArgsSysmemOffset; +} NVDM_PAYLOAD_COT; +#pragma pack() + +#pragma pack(1) +typedef struct +{ + NvU32 taskId; + NvU32 commandNvdmType; + NvU32 errorCode; +} NVDM_PAYLOAD_COMMAND_RESPONSE; +#pragma pack() + +static u32 +gh100_fsp_poll(struct nvkm_fsp *fsp) +{ + struct nvkm_device *device = fsp->subdev.device; + u32 head, tail; + + head = nvkm_rd32(device, NV_PFSP_MSGQ_HEAD(0)); + tail = nvkm_rd32(device, NV_PFSP_MSGQ_TAIL(0)); + + if (head == tail) + return 0; + + return (tail - head) + sizeof(u32); /* TAIL points at last DWORD written. */ +} + +static int +gh100_fsp_recv(struct nvkm_fsp *fsp, u8 *packet, u32 max_packet_size) +{ + struct nvkm_device *device = fsp->subdev.device; + u32 packet_size; + int ret; + + packet_size = gh100_fsp_poll(fsp); + if (!packet_size || WARN_ON(packet_size % 4 || packet_size > max_packet_size)) + return -EINVAL; + + ret = nvkm_falcon_pio_rd(&fsp->falcon, 0, EMEM, 0, packet, 0, packet_size); + if (ret) + return ret; + + nvkm_wr32(device, NV_PFSP_MSGQ_TAIL(0), 0); + nvkm_wr32(device, NV_PFSP_MSGQ_HEAD(0), 0); + + return packet_size; +} + +static int +gh100_fsp_wait(struct nvkm_fsp *fsp) +{ + int time = 1000; + + do { + if (gh100_fsp_poll(fsp)) + return 0; + + usleep_range(1000, 2000); + } while(time--); + + return -ETIMEDOUT; +} + +static int +gh100_fsp_send(struct nvkm_fsp *fsp, const u8 *packet, u32 packet_size) +{ + struct nvkm_device *device = fsp->subdev.device; + int time = 1000, ret; + + if (WARN_ON(packet_size % sizeof(u32))) + return -EINVAL; + + /* Ensure any previously sent message has been consumed. */ + do { + u32 head = nvkm_rd32(device, NV_PFSP_QUEUE_HEAD(0)); + u32 tail = nvkm_rd32(device, NV_PFSP_QUEUE_TAIL(0)); + + if (tail == head) + break; + + usleep_range(1000, 2000); + } while(time--); + + if (time < 0) + return -ETIMEDOUT; + + /* Write message to EMEM. */ + ret = nvkm_falcon_pio_wr(&fsp->falcon, packet, 0, 0, EMEM, 0, packet_size, 0, false); + if (ret) + return ret; + + /* Update queue pointers - TAIL points at last DWORD written. */ + nvkm_wr32(device, NV_PFSP_QUEUE_TAIL(0), packet_size - sizeof(u32)); + nvkm_wr32(device, NV_PFSP_QUEUE_HEAD(0), 0); + return 0; +} + +static int +gh100_fsp_send_sync(struct nvkm_fsp *fsp, u8 nvdm_type, const u8 *packet, u32 packet_size) +{ + struct nvkm_subdev *subdev = &fsp->subdev; + struct { + u32 mctp_header; + u32 nvdm_header; + NVDM_PAYLOAD_COMMAND_RESPONSE response; + } reply; + int ret; + + ret = gh100_fsp_send(fsp, packet, packet_size); + if (ret) + return ret; + + ret = gh100_fsp_wait(fsp); + if (ret) + return ret; + + ret = gh100_fsp_recv(fsp, (u8 *)&reply, sizeof(reply)); + if (ret < 0) + return ret; + + if (NVVAL_TEST(reply.mctp_header, MCTP, HEADER, SOM, !=, 1) || + NVVAL_TEST(reply.mctp_header, MCTP, HEADER, EOM, !=, 1)) { + nvkm_error(subdev, "unexpected MCTP header in reply: 0x%08x\n", reply.mctp_header); + return -EIO; + } + + if (NVDEF_TEST(reply.nvdm_header, MCTP, MSG_HEADER, TYPE, !=, VENDOR_PCI) || + NVDEF_TEST(reply.nvdm_header, MCTP, MSG_HEADER, VENDOR_ID, !=, NV) || + NVVAL_TEST(reply.nvdm_header, MCTP, MSG_HEADER, NVDM_TYPE, !=, NVDM_TYPE_FSP_RESPONSE)) { + nvkm_error(subdev, "unexpected NVDM header in reply: 0x%08x\n", reply.nvdm_header); + return -EIO; + } + + if (reply.response.commandNvdmType != nvdm_type) { + nvkm_error(subdev, "expected NVDM type 0x%02x in reply, got 0x%02x\n", + nvdm_type, reply.response.commandNvdmType); + return -EIO; + } + + if (reply.response.errorCode) { + nvkm_error(subdev, "NVDM command 0x%02x failed with error 0x%08x\n", + nvdm_type, reply.response.errorCode); + return -EIO; + } + + return 0; +} + +int +gh100_fsp_boot_gsp_fmc(struct nvkm_fsp *fsp, u64 args_addr, u32 rsvd_size, bool resume, + u64 img_addr, const u8 *hash, const u8 *pkey, const u8 *sig) +{ + struct { + u32 mctp_header; + u32 nvdm_header; + NVDM_PAYLOAD_COT cot; + } msg = {}; + + msg.mctp_header = NVVAL(MCTP, HEADER, SOM, 1) | + NVVAL(MCTP, HEADER, EOM, 1) | + NVVAL(MCTP, HEADER, SEID, 0) | + NVVAL(MCTP, HEADER, SEQ, 0); + + msg.nvdm_header = NVDEF(MCTP, MSG_HEADER, TYPE, VENDOR_PCI) | + NVDEF(MCTP, MSG_HEADER, VENDOR_ID, NV) | + NVVAL(MCTP, MSG_HEADER, NVDM_TYPE, NVDM_TYPE_COT); + + msg.cot.version = fsp->func->cot.version; + msg.cot.size = sizeof(msg.cot); + msg.cot.gspFmcSysmemOffset = img_addr; + if (!resume) { + msg.cot.frtsVidmemOffset = ALIGN(rsvd_size, 0x200000); + msg.cot.frtsVidmemSize = 0x100000; + } + + memcpy(msg.cot.hash384, hash, fsp->func->cot.size_hash); + memcpy(msg.cot.publicKey, pkey, fsp->func->cot.size_pkey); + memcpy(msg.cot.signature, sig, fsp->func->cot.size_sig); + + msg.cot.gspBootArgsSysmemOffset = args_addr; + + return gh100_fsp_send_sync(fsp, NVDM_TYPE_COT, (const u8 *)&msg, sizeof(msg)); +} + +static int +gh100_fsp_wait_secure_boot(struct nvkm_fsp *fsp) +{ + struct nvkm_device *device = fsp->subdev.device; + unsigned timeout_ms = 4000; + + do { + u32 status = NVKM_RD32(device, NV_THERM, I2CS_SCRATCH, FSP_BOOT_COMPLETE_STATUS); + + if (status == NV_THERM_I2CS_SCRATCH_FSP_BOOT_COMPLETE_STATUS_SUCCESS) + return 0; + + usleep_range(1000, 2000); + } while (timeout_ms--); + + return -ETIMEDOUT; +} + +static const struct nvkm_fsp_func +gh100_fsp = { + .wait_secure_boot = gh100_fsp_wait_secure_boot, + .cot = { + .version = 1, + .size_hash = 48, + .size_pkey = 384, + .size_sig = 384, + .boot_gsp_fmc = gh100_fsp_boot_gsp_fmc, + }, +}; + +int +gh100_fsp_new(struct nvkm_device *device, + enum nvkm_subdev_type type, int inst, struct nvkm_fsp **pfsp) +{ + return nvkm_fsp_new_(&gh100_fsp, device, type, inst, pfsp); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fsp/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/fsp/priv.h new file mode 100644 index 000000000000..91517f3dedfb --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fsp/priv.h @@ -0,0 +1,28 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#ifndef __NVKM_FSP_PRIV_H__ +#define __NVKM_FSP_PRIV_H__ +#define nvkm_fsp(p) container_of((p), struct nvkm_fsp, subdev) +#include <subdev/fsp.h> + +struct nvkm_fsp_func { + int (*wait_secure_boot)(struct nvkm_fsp *); + + struct { + u32 version; + u32 size_hash; + u32 size_pkey; + u32 size_sig; + int (*boot_gsp_fmc)(struct nvkm_fsp *, u64 args_addr, u32 rsvd_size, bool resume, + u64 img_addr, const u8 *hash, const u8 *pkey, const u8 *sig); + } cot; +}; + +int nvkm_fsp_new_(const struct nvkm_fsp_func *, + struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fsp **); + +int gh100_fsp_boot_gsp_fmc(struct nvkm_fsp *, u64 args_addr, u32 rsvd_size, bool resume, + u64 img_addr, const u8 *hash, const u8 *pkey, const u8 *sig); +#endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/Kbuild index ba892c111c26..3c6c1309c4b4 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/Kbuild @@ -7,6 +7,7 @@ nvkm-y += nvkm/subdev/gsp/tu102.o nvkm-y += nvkm/subdev/gsp/tu116.o nvkm-y += nvkm/subdev/gsp/ga100.o nvkm-y += nvkm/subdev/gsp/ga102.o +nvkm-y += nvkm/subdev/gsp/gh100.o nvkm-y += nvkm/subdev/gsp/ad102.o include $(src)/nvkm/subdev/gsp/rm/Kbuild diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/base.c index 3a452349afde..d23243a83a4c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/base.c @@ -83,6 +83,8 @@ nvkm_gsp_oneinit(struct nvkm_subdev *subdev) void nvkm_gsp_dtor_fws(struct nvkm_gsp *gsp) { + nvkm_firmware_put(gsp->fws.fmc); + gsp->fws.fmc = NULL; nvkm_firmware_put(gsp->fws.bl); gsp->fws.bl = NULL; nvkm_firmware_put(gsp->fws.booter.unload); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/gh100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/gh100.c new file mode 100644 index 000000000000..3ad71696c111 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/gh100.c @@ -0,0 +1,353 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#include "priv.h" + +#include <linux/elf.h> +#include <linux/crc32.h> + +#include <subdev/fb.h> +#include <subdev/fsp.h> + +#include <rm/r570/nvrm/gsp.h> + +#include <nvhw/drf.h> +#include <nvhw/ref/gh100/dev_falcon_v4.h> +#include <nvhw/ref/gh100/dev_riscv_pri.h> + +static int +gh100_gsp_fini(struct nvkm_gsp *gsp, bool suspend) +{ + struct nvkm_falcon *falcon = &gsp->falcon; + int ret, time = 4000; + + /* Shutdown RM. */ + ret = r535_gsp_fini(gsp, suspend); + if (ret && suspend) + return ret; + + /* Wait for RISC-V to halt. */ + do { + u32 data = nvkm_falcon_rd32(falcon, falcon->addr2 + NV_PRISCV_RISCV_CPUCTL); + + if (NVVAL_GET(data, NV_PRISCV, RISCV_CPUCTL, HALTED)) + return 0; + + usleep_range(1000, 2000); + } while(time--); + + return -ETIMEDOUT; +} + +static bool +gh100_gsp_lockdown_released(struct nvkm_gsp *gsp, u32 *mbox0) +{ + u32 data; + + /* Wait for GSP access via BAR0 to be allowed. */ + *mbox0 = nvkm_falcon_rd32(&gsp->falcon, NV_PFALCON_FALCON_MAILBOX0); + + if (*mbox0 && (*mbox0 & 0xffffff00) == 0xbadf4100) + return false; + + /* Check if an error code has been reported. */ + if (*mbox0) { + u32 mbox1 = nvkm_falcon_rd32(&gsp->falcon, NV_PFALCON_FALCON_MAILBOX1); + + /* Any value that's not GSP_FMC_BOOT_PARAMS addr is an error. */ + if ((((u64)mbox1 << 32) | *mbox0) != gsp->fmc.args.addr) + return true; + } + + /* Check if lockdown has been released. */ + data = nvkm_falcon_rd32(&gsp->falcon, NV_PFALCON_FALCON_HWCFG2); + return !NVVAL_GET(data, NV_PFALCON, FALCON_HWCFG2, RISCV_BR_PRIV_LOCKDOWN); +} + +static int +gh100_gsp_init(struct nvkm_gsp *gsp) +{ + struct nvkm_subdev *subdev = &gsp->subdev; + struct nvkm_device *device = subdev->device; + const bool resume = gsp->sr.meta.data != NULL; + struct nvkm_gsp_mem *meta; + GSP_FMC_BOOT_PARAMS *args; + int ret, time = 4000; + u32 mbox0; + + if (!resume) { + ret = nvkm_gsp_mem_ctor(gsp, sizeof(*args), &gsp->fmc.args); + if (ret) + return ret; + + meta = &gsp->wpr_meta; + } else { + gsp->rm->api->gsp->set_rmargs(gsp, true); + meta = &gsp->sr.meta; + } + + args = gsp->fmc.args.data; + + args->bootGspRmParams.gspRmDescOffset = meta->addr; + args->bootGspRmParams.gspRmDescSize = meta->size; + args->bootGspRmParams.target = GSP_DMA_TARGET_COHERENT_SYSTEM; + args->bootGspRmParams.bIsGspRmBoot = 1; + + args->gspRmParams.target = GSP_DMA_TARGET_NONCOHERENT_SYSTEM; + args->gspRmParams.bootArgsOffset = gsp->libos.addr; + + ret = nvkm_fsp_boot_gsp_fmc(device->fsp, gsp->fmc.args.addr, gsp->fb.heap.size, resume, + gsp->fmc.fw.addr, gsp->fmc.hash, gsp->fmc.pkey, gsp->fmc.sig); + if (ret) + return ret; + + do { + if (gh100_gsp_lockdown_released(gsp, &mbox0)) + break; + + usleep_range(1000, 2000); + } while(time--); + + if (time < 0) { + nvkm_error(subdev, "GSP-FMC boot timed out\n"); + return -ETIMEDOUT; + } + + if (mbox0) { + nvkm_error(subdev, "GSP-FMC boot failed (mbox: 0x%08x)\n", mbox0); + return -EIO; + } + + return r535_gsp_init(gsp); +} + +static int +gh100_gsp_wpr_meta_init(struct nvkm_gsp *gsp) +{ + GspFwWprMeta *meta; + int ret; + + ret = nvkm_gsp_mem_ctor(gsp, sizeof(*meta), &gsp->wpr_meta); + if (ret) + return ret; + + gsp->fb.size = nvkm_fb_vidmem_size(gsp->subdev.device); + gsp->fb.bios.vga_workspace.size = 128 * 1024; + gsp->fb.heap.size = gsp->rm->wpr->heap_size_non_wpr; + + meta = gsp->wpr_meta.data; + + meta->magic = GSP_FW_WPR_META_MAGIC; + meta->revision = GSP_FW_WPR_META_REVISION; + + meta->sizeOfRadix3Elf = gsp->fw.len; + meta->sysmemAddrOfRadix3Elf = gsp->radix3.lvl0.addr; + + meta->sizeOfBootloader = gsp->boot.fw.size; + meta->sysmemAddrOfBootloader = gsp->boot.fw.addr; + meta->bootloaderCodeOffset = gsp->boot.code_offset; + meta->bootloaderDataOffset = gsp->boot.data_offset; + meta->bootloaderManifestOffset = gsp->boot.manifest_offset; + + meta->sysmemAddrOfSignature = gsp->sig.addr; + meta->sizeOfSignature = gsp->sig.size; + + meta->nonWprHeapSize = gsp->fb.heap.size; + meta->gspFwHeapSize = tu102_gsp_wpr_heap_size(gsp); + meta->frtsSize = 0x100000; + meta->vgaWorkspaceSize = gsp->fb.bios.vga_workspace.size; + meta->pmuReservedSize = 0; + return 0; +} + +/* The sh_flags value for the binary blobs in the ELF image */ +#define FMC_SHF_FLAGS (SHF_MASKPROC | SHF_MASKOS | SHF_OS_NONCONFORMING | SHF_ALLOC) + +#define ELF_HDR_SIZE ((u8)sizeof(struct elf32_hdr)) +#define ELF_SHDR_SIZE ((u8)sizeof(struct elf32_shdr)) + +/* The FMC ELF header must be exactly this */ +static const u8 elf_header[] = { + 0x7f, 'E', 'L', 'F', 1, 1, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 1, 0, 0, 0, /* e_type, e_machine, e_version */ + 0, 0, 0, 0, 0, 0, 0, 0, /* e_entry, e_phoff */ + + ELF_HDR_SIZE, 0, 0, 0, 0, 0, 0, 0, /* e_shoff, e_flags */ + ELF_HDR_SIZE, 0, 0, 0, /* e_ehsize, e_phentsize */ + 0, 0, ELF_SHDR_SIZE, 0, /* e_phnum, e_shentsize */ + + 6, 0, 1, 0, /* e_shnum, e_shstrndx */ +}; + +/** + * elf_validate_sections - validate each section in the FMC ELF image + * @elf: ELF image + * @length: size of the entire ELF image + */ +static bool +elf_validate_sections(const void *elf, size_t length) +{ + const struct elf32_hdr *ehdr = elf; + const struct elf32_shdr *shdr = elf + ehdr->e_shoff; + + /* The offset of the first section */ + Elf32_Off section_begin = ehdr->e_shoff + ehdr->e_shnum * ehdr->e_shentsize; + + if (section_begin > length) + return false; + + /* The first section header is the null section, so skip it */ + for (unsigned int i = 1; i < ehdr->e_shnum; i++) { + if (i == ehdr->e_shstrndx) { + if (shdr[i].sh_type != SHT_STRTAB) + return false; + if (shdr[i].sh_flags != SHF_STRINGS) + return false; + } else { + if (shdr[i].sh_type != SHT_PROGBITS) + return false; + if (shdr[i].sh_flags != FMC_SHF_FLAGS) + return false; + } + + /* Ensure that each section is inside the image */ + if (shdr[i].sh_offset < section_begin || + (u64)shdr[i].sh_offset + shdr[i].sh_size > length) + return false; + + /* Non-zero sh_info is a CRC */ + if (shdr[i].sh_info) { + /* The kernel's CRC32 needs a pre- and post-xor to match standard CRCs */ + u32 crc32 = crc32_le(~0, elf + shdr[i].sh_offset, shdr[i].sh_size) ^ ~0; + + if (shdr[i].sh_info != crc32) + return false; + } + } + + return true; +} + +/** + * elf_section - return a pointer to the data for a given section + * @elf: ELF image + * @name: section name to search for + * @len: pointer to returned length of found section + */ +static const void * +elf_section(const void *elf, const char *name, unsigned int *len) +{ + const struct elf32_hdr *ehdr = elf; + const struct elf32_shdr *shdr = elf + ehdr->e_shoff; + const char *names = elf + shdr[ehdr->e_shstrndx].sh_offset; + + for (unsigned int i = 1; i < ehdr->e_shnum; i++) { + if (!strcmp(&names[shdr[i].sh_name], name)) { + *len = shdr[i].sh_size; + return elf + shdr[i].sh_offset; + } + } + + return NULL; +} + +static int +gh100_gsp_oneinit(struct nvkm_gsp *gsp) +{ + struct nvkm_subdev *subdev = &gsp->subdev; + struct nvkm_device *device = subdev->device; + struct nvkm_fsp *fsp = device->fsp; + const void *fw = gsp->fws.fmc->data; + const void *hash, *sig, *pkey, *img; + unsigned int img_len = 0, hash_len = 0, pkey_len = 0, sig_len = 0; + int ret; + + if (gsp->fws.fmc->size < ELF_HDR_SIZE || + memcmp(fw, elf_header, sizeof(elf_header)) || + !elf_validate_sections(fw, gsp->fws.fmc->size)) { + nvkm_error(subdev, "fmc firmware image is invalid\n"); + return -ENODATA; + } + + hash = elf_section(fw, "hash", &hash_len); + sig = elf_section(fw, "signature", &sig_len); + pkey = elf_section(fw, "publickey", &pkey_len); + img = elf_section(fw, "image", &img_len); + + if (!hash || !sig || !pkey || !img) { + nvkm_error(subdev, "fmc firmware image is invalid\n"); + return -ENODATA; + } + + if (!nvkm_fsp_verify_gsp_fmc(fsp, hash_len, pkey_len, sig_len)) + return -EINVAL; + + /* Load GSP-FMC FW into memory. */ + ret = nvkm_gsp_mem_ctor(gsp, img_len, &gsp->fmc.fw); + if (ret) + return ret; + + memcpy(gsp->fmc.fw.data, img, img_len); + + gsp->fmc.hash = kmemdup(hash, hash_len, GFP_KERNEL); + gsp->fmc.pkey = kmemdup(pkey, pkey_len, GFP_KERNEL); + gsp->fmc.sig = kmemdup(sig, sig_len, GFP_KERNEL); + if (!gsp->fmc.hash || !gsp->fmc.pkey || !gsp->fmc.sig) + return -ENOMEM; + + ret = r535_gsp_oneinit(gsp); + if (ret) + return ret; + + return gh100_gsp_wpr_meta_init(gsp); +} + +static const struct nvkm_gsp_func +gh100_gsp = { + .flcn = &ga102_gsp_flcn, + + .sig_section = ".fwsignature_gh100", + + .dtor = r535_gsp_dtor, + .oneinit = gh100_gsp_oneinit, + .init = gh100_gsp_init, + .fini = gh100_gsp_fini, + + .rm.gpu = &gh100_gpu, +}; + +static int +gh100_gsp_load(struct nvkm_gsp *gsp, int ver, const struct nvkm_gsp_fwif *fwif) +{ + int ret; + + ret = tu102_gsp_load_rm(gsp, fwif); + if (ret) + goto done; + + ret = nvkm_gsp_load_fw(gsp, "fmc", fwif->ver, &gsp->fws.fmc); + +done: + if (ret) + nvkm_gsp_dtor_fws(gsp); + + return ret; +} + +static struct nvkm_gsp_fwif +gh100_gsps[] = { + { 0, gh100_gsp_load, &gh100_gsp, &r570_rm_gh100, "570.144", true }, + {} +}; + +int +gh100_gsp_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, + struct nvkm_gsp **pgsp) +{ + return nvkm_gsp_new_(gh100_gsps, device, type, inst, pgsp); +} + +NVKM_GSP_FIRMWARE_FMC(gh100, 570.144); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/priv.h index c8429863b642..86ec580ba936 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/priv.h @@ -22,7 +22,9 @@ int nvkm_gsp_load_fw(struct nvkm_gsp *, const char *name, const char *ver, void nvkm_gsp_dtor_fws(struct nvkm_gsp *); int gv100_gsp_nofw(struct nvkm_gsp *, int, const struct nvkm_gsp_fwif *); + int tu102_gsp_load(struct nvkm_gsp *, int, const struct nvkm_gsp_fwif *); +int tu102_gsp_load_rm(struct nvkm_gsp *, const struct nvkm_gsp_fwif *); #define NVKM_GSP_FIRMWARE_BOOTER(chip,vers) \ MODULE_FIRMWARE("nvidia/"#chip"/gsp/booter_load-"#vers".bin"); \ @@ -30,6 +32,11 @@ MODULE_FIRMWARE("nvidia/"#chip"/gsp/booter_unload-"#vers".bin"); \ MODULE_FIRMWARE("nvidia/"#chip"/gsp/bootloader-"#vers".bin"); \ MODULE_FIRMWARE("nvidia/"#chip"/gsp/gsp-"#vers".bin") +#define NVKM_GSP_FIRMWARE_FMC(chip,vers) \ +MODULE_FIRMWARE("nvidia/"#chip"/gsp/fmc-"#vers".bin"); \ +MODULE_FIRMWARE("nvidia/"#chip"/gsp/bootloader-"#vers".bin"); \ +MODULE_FIRMWARE("nvidia/"#chip"/gsp/gsp-"#vers".bin") + struct nvkm_gsp_func { const struct nvkm_falcon_func *flcn; const struct nvkm_falcon_fw_func *fwsec; @@ -60,6 +67,7 @@ int tu102_gsp_oneinit(struct nvkm_gsp *); int tu102_gsp_init(struct nvkm_gsp *); int tu102_gsp_fini(struct nvkm_gsp *, bool suspend); int tu102_gsp_reset(struct nvkm_gsp *); +u64 tu102_gsp_wpr_heap_size(struct nvkm_gsp *); extern const struct nvkm_falcon_func ga102_gsp_flcn; extern const struct nvkm_falcon_fw_func ga102_gsp_fwsec; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/Kbuild index d3f4e60bb131..2a71868d6710 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/Kbuild @@ -11,6 +11,7 @@ nvkm-y += nvkm/subdev/gsp/rm/tu1xx.o nvkm-y += nvkm/subdev/gsp/rm/ga100.o nvkm-y += nvkm/subdev/gsp/rm/ga1xx.o nvkm-y += nvkm/subdev/gsp/rm/ad10x.o +nvkm-y += nvkm/subdev/gsp/rm/gh100.o include $(src)/nvkm/subdev/gsp/rm/r535/Kbuild include $(src)/nvkm/subdev/gsp/rm/r570/Kbuild diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gh100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gh100.c new file mode 100644 index 000000000000..088250559e12 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gh100.c @@ -0,0 +1,27 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#include "gpu.h" + +#include <nvif/class.h> + +const struct nvkm_rm_gpu +gh100_gpu = { + .usermode.class = HOPPER_USERMODE_A, + + .fifo.chan = { + .class = HOPPER_CHANNEL_GPFIFO_A, + }, + + .ce.class = HOPPER_DMA_COPY_A, + .gr.class = { + .i2m = KEPLER_INLINE_TO_MEMORY_B, + .twod = FERMI_TWOD_A, + .threed = HOPPER_A, + .compute = HOPPER_COMPUTE_A, + }, + .nvdec.class = NVB8B0_VIDEO_DECODER, + .nvjpg.class = NVB8D1_VIDEO_NVJPG, + .ofa.class = NVB8FA_VIDEO_OFA, +}; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gpu.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gpu.h index a256be42ab6e..443753f3369a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gpu.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gpu.h @@ -62,4 +62,5 @@ extern const struct nvkm_rm_gpu tu1xx_gpu; extern const struct nvkm_rm_gpu ga100_gpu; extern const struct nvkm_rm_gpu ga1xx_gpu; extern const struct nvkm_rm_gpu ad10x_gpu; +extern const struct nvkm_rm_gpu gh100_gpu; #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c index fe00425c5479..baf42339f93e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c @@ -2073,6 +2073,12 @@ r535_gsp_dtor(struct nvkm_gsp *gsp) nvkm_falcon_fw_dtor(&gsp->booter.unload); nvkm_falcon_fw_dtor(&gsp->booter.load); + nvkm_gsp_mem_dtor(&gsp->fmc.args); + kfree(gsp->fmc.sig); + kfree(gsp->fmc.pkey); + kfree(gsp->fmc.hash); + nvkm_gsp_mem_dtor(&gsp->fmc.fw); + mutex_destroy(&gsp->msgq.mutex); mutex_destroy(&gsp->cmdq.mutex); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/gsp.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/gsp.c index 730dcb645cca..9d2fa4e66d59 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/gsp.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/gsp.c @@ -26,8 +26,10 @@ r570_gsp_sr_data_size(struct nvkm_gsp *gsp) static void r570_gsp_drop_post_nocat_record(struct nvkm_gsp *gsp) { - if (gsp->subdev.debug < NV_DBG_DEBUG) + if (gsp->subdev.debug < NV_DBG_DEBUG) { r535_gsp_msg_ntfy_add(gsp, NV_VGPU_MSG_EVENT_GSP_POST_NOCAT_RECORD, NULL, NULL); + r535_gsp_msg_ntfy_add(gsp, NV_VGPU_MSG_EVENT_GSP_LOCKDOWN_NOTICE, NULL, NULL); + } } static bool @@ -102,6 +104,13 @@ r570_gsp_get_static_info(struct nvkm_gsp *gsp) r535_gsp_get_static_info_fb(gsp, &rpc->fbRegionInfoParams); + if (gsp->rm->wpr->offset_set_by_acr) { + GspFwWprMeta *meta = gsp->wpr_meta.data; + + meta->nonWprHeapOffset = rpc->fwWprLayoutOffset.nonWprHeapOffset; + meta->frtsOffset = rpc->fwWprLayoutOffset.frtsOffset; + } + nvkm_gsp_rpc_done(gsp, rpc); ret = r570_gr_gpc_mask(gsp, &gpc_mask); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/nvrm/gsp.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/nvrm/gsp.h index 4685a898fac6..b6075021e74f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/nvrm/gsp.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/nvrm/gsp.h @@ -573,4 +573,62 @@ typedef struct (88u + (BULLSEYE_ROOT_HEAP_ALLOC_RM_DATA_SECTION_SIZE_DELTA) + \ (BULLSEYE_ROOT_HEAP_ALLOC_BAREMETAL_LIBOS_HEAP_SIZE_DELTA)) +typedef struct GSP_FMC_INIT_PARAMS +{ + // CC initialization "registry keys" + NvU32 regkeys; +} GSP_FMC_INIT_PARAMS; + +typedef enum { + GSP_DMA_TARGET_LOCAL_FB, + GSP_DMA_TARGET_COHERENT_SYSTEM, + GSP_DMA_TARGET_NONCOHERENT_SYSTEM, + GSP_DMA_TARGET_COUNT +} GSP_DMA_TARGET; + +typedef struct GSP_ACR_BOOT_GSP_RM_PARAMS +{ + // Physical memory aperture through which gspRmDescPa is accessed + GSP_DMA_TARGET target; + // Size in bytes of the GSP-RM descriptor structure + NvU32 gspRmDescSize; + // Physical offset in the target aperture of the GSP-RM descriptor structure + NvU64 gspRmDescOffset; + // Physical offset in FB to set the start of the WPR containing GSP-RM + NvU64 wprCarveoutOffset; + // Size in bytes of the WPR containing GSP-RM + NvU32 wprCarveoutSize; + // Whether to boot GSP-RM or GSP-Proxy through ACR + NvBool bIsGspRmBoot; +} GSP_ACR_BOOT_GSP_RM_PARAMS; + +typedef struct GSP_RM_PARAMS +{ + // Physical memory aperture through which bootArgsOffset is accessed + GSP_DMA_TARGET target; + // Physical offset in the memory aperture that will be passed to GSP-RM + NvU64 bootArgsOffset; +} GSP_RM_PARAMS; + +typedef struct GSP_SPDM_PARAMS +{ + // Physical Memory Aperture through which all addresses are accessed + GSP_DMA_TARGET target; + + // Physical offset in the memory aperture where SPDM payload is stored + NvU64 payloadBufferOffset; + + // Size of the above payload buffer + NvU32 payloadBufferSize; +} GSP_SPDM_PARAMS; + +typedef struct GSP_FMC_BOOT_PARAMS +{ + GSP_FMC_INIT_PARAMS initParams; + GSP_ACR_BOOT_GSP_RM_PARAMS bootGspRmParams; + GSP_RM_PARAMS gspRmParams; + GSP_SPDM_PARAMS gspSpdmParams; +} GSP_FMC_BOOT_PARAMS; + +#define GSP_FW_HEAP_PARAM_BASE_RM_SIZE_GH100 (14 << 20) // Hopper+ #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/rm.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/rm.c index ad80d8a3d6d3..8a641e5a5b92 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/rm.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/rm.c @@ -20,6 +20,15 @@ r570_wpr_libos3 = { .heap_size_min = GSP_FW_HEAP_SIZE_OVERRIDE_LIBOS3_BAREMETAL_MIN_MB, }; +static const struct nvkm_rm_wpr +r570_wpr_libos3_gh100 = { + .os_carveout_size = GSP_FW_HEAP_PARAM_OS_SIZE_LIBOS3_BAREMETAL, + .base_size = GSP_FW_HEAP_PARAM_BASE_RM_SIZE_GH100, + .heap_size_min = GSP_FW_HEAP_SIZE_OVERRIDE_LIBOS3_BAREMETAL_MIN_MB, + .heap_size_non_wpr = 0x200000, + .offset_set_by_acr = true, +}; + static const struct nvkm_rm_api r570_api = { .gsp = &r570_gsp, @@ -50,3 +59,9 @@ r570_rm_ga102 = { .wpr = &r570_wpr_libos3, .api = &r570_api, }; + +const struct nvkm_rm_impl +r570_rm_gh100 = { + .wpr = &r570_wpr_libos3_gh100, + .api = &r570_api, +}; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h index ead48c106bb6..626ebce39be5 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h @@ -25,6 +25,8 @@ struct nvkm_rm_wpr { u32 os_carveout_size; u32 base_size; u64 heap_size_min; + u32 heap_size_non_wpr; + bool offset_set_by_acr; }; struct nvkm_rm_api { @@ -173,6 +175,7 @@ extern const struct nvkm_rm_api_engine r535_ofa; extern const struct nvkm_rm_impl r570_rm_tu102; extern const struct nvkm_rm_impl r570_rm_ga102; +extern const struct nvkm_rm_impl r570_rm_gh100; extern const struct nvkm_rm_api_gsp r570_gsp; extern const struct nvkm_rm_api_client r570_client; extern const struct nvkm_rm_api_fbsr r570_fbsr; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/tu102.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/tu102.c index 97c02aa93d55..58e233bc53b1 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/tu102.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/tu102.c @@ -246,7 +246,7 @@ tu102_gsp_wpr_meta_init(struct nvkm_gsp *gsp) return 0; } -static u64 +u64 tu102_gsp_wpr_heap_size(struct nvkm_gsp *gsp) { u32 fb_size_gb = DIV_ROUND_UP_ULL(gsp->fb.size, 1 << 30); @@ -379,7 +379,7 @@ tu102_gsp = { .rm.gpu = &tu1xx_gpu, }; -static int +int tu102_gsp_load_rm(struct nvkm_gsp *gsp, const struct nvkm_gsp_fwif *fwif) { struct nvkm_subdev *subdev = &gsp->subdev; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/Kbuild index 06cbe19ce376..fa7a2862dd1f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/Kbuild @@ -4,3 +4,4 @@ nvkm-y += nvkm/subdev/instmem/nv04.o nvkm-y += nvkm/subdev/instmem/nv40.o nvkm-y += nvkm/subdev/instmem/nv50.o nvkm-y += nvkm/subdev/instmem/gk20a.o +nvkm-y += nvkm/subdev/instmem/gh100.o diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gh100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gh100.c new file mode 100644 index 000000000000..8d8dd5f8a6c7 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gh100.c @@ -0,0 +1,28 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#include "priv.h" + +#include <nvhw/ref/gh100/pri_nv_xal_ep.h> + +static void +gh100_instmem_set_bar0_window_addr(struct nvkm_device *device, u64 addr) +{ + nvkm_wr32(device, NV_XAL_EP_BAR0_WINDOW, addr >> NV_XAL_EP_BAR0_WINDOW_BASE_SHIFT); +} + +static const struct nvkm_instmem_func +gh100_instmem = { + .fini = nv50_instmem_fini, + .memory_new = nv50_instobj_new, + .memory_wrap = nv50_instobj_wrap, + .set_bar0_window_addr = gh100_instmem_set_bar0_window_addr, +}; + +int +gh100_instmem_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, + struct nvkm_instmem **pimem) +{ + return r535_instmem_new(&gh100_instmem, device, type, inst, pimem); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c index 9d29e5234734..4ca6fb30743d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c @@ -353,7 +353,7 @@ nv50_instobj_func = { .map = nv50_instobj_map, }; -static int +int nv50_instobj_wrap(struct nvkm_instmem *base, struct nvkm_memory *memory, struct nvkm_memory **pmemory) { @@ -373,7 +373,7 @@ nv50_instobj_wrap(struct nvkm_instmem *base, return 0; } -static int +int nv50_instobj_new(struct nvkm_instmem *imem, u32 size, u32 align, bool zero, struct nvkm_memory **pmemory) { @@ -400,7 +400,7 @@ nv50_instmem_set_bar0_window_addr(struct nvkm_device *device, u64 addr) nvkm_wr32(device, 0x001700, addr >> 16); } -static void +void nv50_instmem_fini(struct nvkm_instmem *base) { nv50_instmem(base)->addr = ~0ULL; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/priv.h index d5b5fcd9262b..87bbdd786eaa 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/priv.h @@ -21,6 +21,11 @@ struct nvkm_instmem_func { int nv50_instmem_new_(const struct nvkm_instmem_func *, struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_instmem **); +void nv50_instmem_fini(struct nvkm_instmem *); +int nv50_instobj_new(struct nvkm_instmem *, u32 size, u32 align, bool zero, + struct nvkm_memory **); +int nv50_instobj_wrap(struct nvkm_instmem *, struct nvkm_memory *vram, + struct nvkm_memory **bar2); void nvkm_instmem_ctor(const struct nvkm_instmem_func *, struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_instmem *); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild index a602b0cb5b31..ea4848931540 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild @@ -15,6 +15,7 @@ nvkm-y += nvkm/subdev/mmu/gp100.o nvkm-y += nvkm/subdev/mmu/gp10b.o nvkm-y += nvkm/subdev/mmu/gv100.o nvkm-y += nvkm/subdev/mmu/tu102.o +nvkm-y += nvkm/subdev/mmu/gh100.o nvkm-y += nvkm/subdev/mmu/mem.o nvkm-y += nvkm/subdev/mmu/memnv04.o @@ -36,6 +37,7 @@ nvkm-y += nvkm/subdev/mmu/vmmgp100.o nvkm-y += nvkm/subdev/mmu/vmmgp10b.o nvkm-y += nvkm/subdev/mmu/vmmgv100.o nvkm-y += nvkm/subdev/mmu/vmmtu102.o +nvkm-y += nvkm/subdev/mmu/vmmgh100.o nvkm-y += nvkm/subdev/mmu/umem.o nvkm-y += nvkm/subdev/mmu/ummu.o diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gh100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gh100.c new file mode 100644 index 000000000000..2918fb32cc91 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gh100.c @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#include "mem.h" +#include "vmm.h" + +#include <nvif/class.h> + +static const struct nvkm_mmu_func +gh100_mmu = { + .dma_bits = 52, + .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}, gh100_vmm_new }, + .kind = tu102_mmu_kind, + .kind_sys = true, +}; + +int +gh100_mmu_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, + struct nvkm_mmu **pmmu) +{ + return r535_mmu_new(&gh100_mmu, device, type, inst, pmmu); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h index e9ca6537778c..90efef8f0b54 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h @@ -53,6 +53,8 @@ const u8 *gf100_mmu_kind(struct nvkm_mmu *, int *count, u8 *invalid); const u8 *gm200_mmu_kind(struct nvkm_mmu *, int *, u8 *); +const u8 *tu102_mmu_kind(struct nvkm_mmu *, int *, u8 *); + struct nvkm_mmu_pt { union { struct nvkm_mmu_ptc *ptc; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/tu102.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/tu102.c index df662ce4a4b0..7acff3642e20 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/tu102.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/tu102.c @@ -28,7 +28,7 @@ #include <nvif/class.h> -static const u8 * +const u8 * tu102_mmu_kind(struct nvkm_mmu *mmu, int *count, u8 *invalid) { static const u8 diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h index f9bc30cdb2b3..4586a425dbe4 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h @@ -143,6 +143,8 @@ struct nvkm_vmm_func { int (*aper)(enum nvkm_memory_target); int (*valid)(struct nvkm_vmm *, void *argv, u32 argc, struct nvkm_vmm_map *); + int (*valid2)(struct nvkm_vmm *, bool ro, bool priv, u8 kind, u8 comp, + struct nvkm_vmm_map *); void (*flush)(struct nvkm_vmm *, int depth); int (*mthd)(struct nvkm_vmm *, struct nvkm_client *, @@ -254,6 +256,8 @@ void gp100_vmm_invalidate_pdb(struct nvkm_vmm *, u64 addr); int gv100_vmm_join(struct nvkm_vmm *, struct nvkm_memory *); +void tu102_vmm_flush(struct nvkm_vmm *, int depth); + int nv04_vmm_new(struct nvkm_mmu *, bool, u64, u64, void *, u32, struct lock_class_key *, const char *, struct nvkm_vmm **); int nv41_vmm_new(struct nvkm_mmu *, bool, u64, u64, void *, u32, @@ -296,6 +300,9 @@ int gv100_vmm_new(struct nvkm_mmu *, bool, u64, u64, void *, u32, int tu102_vmm_new(struct nvkm_mmu *, bool, u64, u64, void *, u32, struct lock_class_key *, const char *, struct nvkm_vmm **); +int gh100_vmm_new(struct nvkm_mmu *, bool, u64, u64, void *, u32, + struct lock_class_key *, const char *, + struct nvkm_vmm **); #define VMM_PRINT(l,v,p,f,a...) do { \ struct nvkm_vmm *_vmm = (v); \ diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgh100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgh100.c new file mode 100644 index 000000000000..5614df3432da --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgh100.c @@ -0,0 +1,306 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#include "vmm.h" + +#include <subdev/fb.h> + +#include <nvhw/drf.h> +#include <nvhw/ref/gh100/dev_mmu.h> + +static inline void +gh100_vmm_pgt_pte(struct nvkm_vmm *vmm, struct nvkm_mmu_pt *pt, u32 ptei, u32 ptes, + struct nvkm_vmm_map *map, u64 addr) +{ + u64 data = addr | map->type; + + while (ptes--) { + VMM_WO064(pt, vmm, ptei++ * NV_MMU_VER3_PTE__SIZE, data); + data += map->next; + } +} + +static void +gh100_vmm_pgt_sgl(struct nvkm_vmm *vmm, struct nvkm_mmu_pt *pt, u32 ptei, u32 ptes, + struct nvkm_vmm_map *map) +{ + VMM_MAP_ITER_SGL(vmm, pt, ptei, ptes, map, gh100_vmm_pgt_pte); +} + +static void +gh100_vmm_pgt_dma(struct nvkm_vmm *vmm, struct nvkm_mmu_pt *pt, u32 ptei, u32 ptes, + struct nvkm_vmm_map *map) +{ + if (map->page->shift == PAGE_SHIFT) { + VMM_SPAM(vmm, "DMAA %08x %08x PTE(s)", ptei, ptes); + + nvkm_kmap(pt->memory); + while (ptes--) { + const u64 data = *map->dma++ | map->type; + + VMM_WO064(pt, vmm, ptei++ * NV_MMU_VER3_PTE__SIZE, data); + } + nvkm_done(pt->memory); + return; + } + + VMM_MAP_ITER_DMA(vmm, pt, ptei, ptes, map, gh100_vmm_pgt_pte); +} + +static void +gh100_vmm_pgt_mem(struct nvkm_vmm *vmm, struct nvkm_mmu_pt *pt, u32 ptei, u32 ptes, + struct nvkm_vmm_map *map) +{ + VMM_MAP_ITER_MEM(vmm, pt, ptei, ptes, map, gh100_vmm_pgt_pte); +} + +static void +gh100_vmm_pgt_sparse(struct nvkm_vmm *vmm, + struct nvkm_mmu_pt *pt, u32 ptei, u32 ptes) +{ + const u64 data = NVDEF(NV_MMU, VER3_PTE, PCF, SPARSE); + + VMM_FO064(pt, vmm, ptei * NV_MMU_VER3_PTE__SIZE, data, ptes); +} + +static const struct nvkm_vmm_desc_func +gh100_vmm_desc_spt = { + .unmap = gf100_vmm_pgt_unmap, + .sparse = gh100_vmm_pgt_sparse, + .mem = gh100_vmm_pgt_mem, + .dma = gh100_vmm_pgt_dma, + .sgl = gh100_vmm_pgt_sgl, +}; + +static void +gh100_vmm_lpt_invalid(struct nvkm_vmm *vmm, + struct nvkm_mmu_pt *pt, u32 ptei, u32 ptes) +{ + const u64 data = NVDEF(NV_MMU, VER3_PTE, PCF, NO_VALID_4KB_PAGE); + + VMM_FO064(pt, vmm, ptei * NV_MMU_VER3_PTE__SIZE, data, ptes); +} + +static const struct nvkm_vmm_desc_func +gh100_vmm_desc_lpt = { + .invalid = gh100_vmm_lpt_invalid, + .unmap = gf100_vmm_pgt_unmap, + .sparse = gh100_vmm_pgt_sparse, + .mem = gh100_vmm_pgt_mem, +}; + +static inline void +gh100_vmm_pd0_pte(struct nvkm_vmm *vmm, struct nvkm_mmu_pt *pt, + u32 ptei, u32 ptes, struct nvkm_vmm_map *map, u64 addr) +{ + u64 data = addr | map->type; + + while (ptes--) { + VMM_WO128(pt, vmm, ptei++ * NV_MMU_VER3_DUAL_PDE__SIZE, data, 0ULL); + data += map->next; + } +} + +static void +gh100_vmm_pd0_mem(struct nvkm_vmm *vmm, struct nvkm_mmu_pt *pt, + u32 ptei, u32 ptes, struct nvkm_vmm_map *map) +{ + VMM_MAP_ITER_MEM(vmm, pt, ptei, ptes, map, gh100_vmm_pd0_pte); +} + +static inline bool +gh100_vmm_pde(struct nvkm_mmu_pt *pt, u64 *data) +{ + switch (nvkm_memory_target(pt->memory)) { + case NVKM_MEM_TARGET_VRAM: + *data |= NVDEF(NV_MMU, VER3_PDE, APERTURE, VIDEO_MEMORY); + *data |= NVDEF(NV_MMU, VER3_PDE, PCF, VALID_CACHED_ATS_NOT_ALLOWED); + break; + case NVKM_MEM_TARGET_HOST: + *data |= NVDEF(NV_MMU, VER3_PDE, APERTURE, SYSTEM_COHERENT_MEMORY); + *data |= NVDEF(NV_MMU, VER3_PDE, PCF, VALID_UNCACHED_ATS_ALLOWED); + break; + case NVKM_MEM_TARGET_NCOH: + *data |= NVDEF(NV_MMU, VER3_PDE, APERTURE, SYSTEM_NON_COHERENT_MEMORY); + *data |= NVDEF(NV_MMU, VER3_PDE, PCF, VALID_CACHED_ATS_ALLOWED); + break; + default: + WARN_ON(1); + return false; + } + + *data |= pt->addr; + return true; +} + +static void +gh100_vmm_pd0_pde(struct nvkm_vmm *vmm, struct nvkm_vmm_pt *pgd, u32 pdei) +{ + struct nvkm_vmm_pt *pgt = pgd->pde[pdei]; + struct nvkm_mmu_pt *pd = pgd->pt[0]; + u64 data[2] = {}; + + if (pgt->pt[0] && !gh100_vmm_pde(pgt->pt[0], &data[0])) + return; + if (pgt->pt[1] && !gh100_vmm_pde(pgt->pt[1], &data[1])) + return; + + nvkm_kmap(pd->memory); + VMM_WO128(pd, vmm, pdei * NV_MMU_VER3_DUAL_PDE__SIZE, data[0], data[1]); + nvkm_done(pd->memory); +} + +static void +gh100_vmm_pd0_sparse(struct nvkm_vmm *vmm, + struct nvkm_mmu_pt *pt, u32 pdei, u32 pdes) +{ + const u64 data = NVDEF(NV_MMU, VER3_DUAL_PDE, PCF_BIG, SPARSE_ATS_ALLOWED); + + VMM_FO128(pt, vmm, pdei * NV_MMU_VER3_DUAL_PDE__SIZE, data, 0ULL, pdes); +} + +static void +gh100_vmm_pd0_unmap(struct nvkm_vmm *vmm, + struct nvkm_mmu_pt *pt, u32 pdei, u32 pdes) +{ + VMM_FO128(pt, vmm, pdei * NV_MMU_VER3_DUAL_PDE__SIZE, 0ULL, 0ULL, pdes); +} + +static const struct nvkm_vmm_desc_func +gh100_vmm_desc_pd0 = { + .unmap = gh100_vmm_pd0_unmap, + .sparse = gh100_vmm_pd0_sparse, + .pde = gh100_vmm_pd0_pde, + .mem = gh100_vmm_pd0_mem, +}; + +static void +gh100_vmm_pd1_pde(struct nvkm_vmm *vmm, struct nvkm_vmm_pt *pgd, u32 pdei) +{ + struct nvkm_vmm_pt *pgt = pgd->pde[pdei]; + struct nvkm_mmu_pt *pd = pgd->pt[0]; + u64 data = 0; + + if (!gh100_vmm_pde(pgt->pt[0], &data)) + return; + + nvkm_kmap(pd->memory); + VMM_WO064(pd, vmm, pdei * NV_MMU_VER3_PDE__SIZE, data); + nvkm_done(pd->memory); +} + +static const struct nvkm_vmm_desc_func +gh100_vmm_desc_pd1 = { + .unmap = gf100_vmm_pgt_unmap, + .sparse = gh100_vmm_pgt_sparse, + .pde = gh100_vmm_pd1_pde, +}; + +static const struct nvkm_vmm_desc +gh100_vmm_desc_16[] = { + { LPT, 5, 8, 0x0100, &gh100_vmm_desc_lpt }, + { PGD, 8, 16, 0x1000, &gh100_vmm_desc_pd0 }, + { PGD, 9, 8, 0x1000, &gh100_vmm_desc_pd1 }, + { PGD, 9, 8, 0x1000, &gh100_vmm_desc_pd1 }, + { PGD, 9, 8, 0x1000, &gh100_vmm_desc_pd1 }, + { PGD, 1, 8, 0x1000, &gh100_vmm_desc_pd1 }, + {} +}; + +static const struct nvkm_vmm_desc +gh100_vmm_desc_12[] = { + { SPT, 9, 8, 0x1000, &gh100_vmm_desc_spt }, + { PGD, 8, 16, 0x1000, &gh100_vmm_desc_pd0 }, + { PGD, 9, 8, 0x1000, &gh100_vmm_desc_pd1 }, + { PGD, 9, 8, 0x1000, &gh100_vmm_desc_pd1 }, + { PGD, 9, 8, 0x1000, &gh100_vmm_desc_pd1 }, + { PGD, 1, 8, 0x1000, &gh100_vmm_desc_pd1 }, + {} +}; + +static int +gh100_vmm_valid(struct nvkm_vmm *vmm, bool ro, bool priv, u8 kind, u8 comp, + struct nvkm_vmm_map *map) +{ + const enum nvkm_memory_target target = nvkm_memory_target(map->memory); + const bool vol = target == NVKM_MEM_TARGET_HOST; + const struct nvkm_vmm_page *page = map->page; + u8 kind_inv, pcf; + int kindn, aper; + const u8 *kindm; + + map->next = 1ULL << page->shift; + map->type = 0; + + aper = vmm->func->aper(target); + if (WARN_ON(aper < 0)) + return aper; + + 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; + } + + if (priv) { + if (ro) { + if (vol) + pcf = NV_MMU_VER3_PTE_PCF_PRIVILEGE_RO_ATOMIC_UNCACHED_ACD; + else + pcf = NV_MMU_VER3_PTE_PCF_PRIVILEGE_RO_ATOMIC_CACHED_ACD; + } else { + if (vol) + pcf = NV_MMU_VER3_PTE_PCF_PRIVILEGE_RW_ATOMIC_UNCACHED_ACD; + else + pcf = NV_MMU_VER3_PTE_PCF_PRIVILEGE_RW_ATOMIC_CACHED_ACD; + } + } else { + if (ro) { + if (vol) + pcf = NV_MMU_VER3_PTE_PCF_REGULAR_RO_ATOMIC_UNCACHED_ACD; + else + pcf = NV_MMU_VER3_PTE_PCF_REGULAR_RO_ATOMIC_CACHED_ACD; + } else { + if (vol) + pcf = NV_MMU_VER3_PTE_PCF_REGULAR_RW_ATOMIC_UNCACHED_ACD; + else + pcf = NV_MMU_VER3_PTE_PCF_REGULAR_RW_ATOMIC_CACHED_ACD; + } + } + + map->type |= NVDEF(NV_MMU, VER3_PTE, VALID, TRUE); + map->type |= NVVAL(NV_MMU, VER3_PTE, APERTURE, aper); + map->type |= NVVAL(NV_MMU, VER3_PTE, PCF, pcf); + map->type |= NVVAL(NV_MMU, VER3_PTE, KIND, kind); + return 0; +} + +static const struct nvkm_vmm_func +gh100_vmm = { + .join = gv100_vmm_join, + .part = gf100_vmm_part, + .aper = gf100_vmm_aper, + .valid = gp100_vmm_valid, + .valid2 = gh100_vmm_valid, + .flush = tu102_vmm_flush, + .page = { + { 56, &gh100_vmm_desc_16[5], NVKM_VMM_PAGE_Sxxx }, + { 47, &gh100_vmm_desc_16[4], NVKM_VMM_PAGE_Sxxx }, + { 38, &gh100_vmm_desc_16[3], NVKM_VMM_PAGE_Sxxx }, + { 29, &gh100_vmm_desc_16[2], NVKM_VMM_PAGE_SVxC }, + { 21, &gh100_vmm_desc_16[1], NVKM_VMM_PAGE_SVxC }, + { 16, &gh100_vmm_desc_16[0], NVKM_VMM_PAGE_SVxC }, + { 12, &gh100_vmm_desc_12[0], NVKM_VMM_PAGE_SVHx }, + {} + } +}; + +int +gh100_vmm_new(struct nvkm_mmu *mmu, bool managed, u64 addr, u64 size, + void *argv, u32 argc, struct lock_class_key *key, + const char *name, struct nvkm_vmm **pvmm) +{ + return gp100_vmm_new_(&gh100_vmm, mmu, managed, addr, size, + argv, argc, key, name, pvmm); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgp100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgp100.c index bddac77f48f0..851fd847a2a9 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgp100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgp100.c @@ -436,6 +436,9 @@ gp100_vmm_valid(struct nvkm_vmm *vmm, void *argv, u32 argc, return ret; } + if (vmm->func->valid2) + return vmm->func->valid2(vmm, ro, priv, kind, 0, map); + aper = vmm->func->aper(target); if (WARN_ON(aper < 0)) return aper; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmtu102.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmtu102.c index 8379e72d77ab..4b30eab40bba 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmtu102.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmtu102.c @@ -23,7 +23,7 @@ #include <subdev/timer.h> -static void +void tu102_vmm_flush(struct nvkm_vmm *vmm, int depth) { struct nvkm_device *device = vmm->mmu->subdev.device; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/Kbuild index 174bdf995271..a14ea0f7b1c8 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/Kbuild @@ -13,3 +13,4 @@ nvkm-y += nvkm/subdev/pci/gf100.o nvkm-y += nvkm/subdev/pci/gf106.o nvkm-y += nvkm/subdev/pci/gk104.o nvkm-y += nvkm/subdev/pci/gp100.o +nvkm-y += nvkm/subdev/pci/gh100.o diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/gh100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/gh100.c new file mode 100644 index 000000000000..42da92d7a5fe --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/gh100.c @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#include "priv.h" + +#include <nvhw/drf.h> +#include <nvhw/ref/gh100/dev_xtl_ep_pri.h> + +static void +gh100_pci_msi_rearm(struct nvkm_pci *pci) +{ + /* Handled by top-level intr ACK. */ +} + +static const struct nvkm_pci_func +gh100_pci = { + .cfg = { + .addr = DRF_LO(NV_EP_PCFGM), + .size = DRF_HI(NV_EP_PCFGM) - DRF_LO(NV_EP_PCFGM) + 1, + }, + .msi_rearm = gh100_pci_msi_rearm, +}; + +int +gh100_pci_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, + struct nvkm_pci **ppci) +{ + return nvkm_pci_new_(&gh100_pci, device, type, inst, ppci); +} -- 2.49.0
Ben Skeggs
2025-May-17 00:09 UTC
[PATCH v3 55/62] drm/nouveau: add helper functions for allocating pinned/cpu-mapped bos
Replace some awkward sequences that are repeated in a number of places with helper functions. Signed-off-by: Ben Skeggs <bskeggs at nvidia.com> Reviewed-by: Dave Airlie <airlied at redhat.com> Reviewed-by: Timur Tabi <ttabi at nvidia.com> Tested-by: Timur Tabi <ttabi at nvidia.com> --- drivers/gpu/drm/nouveau/dispnv04/crtc.c | 22 +++------- drivers/gpu/drm/nouveau/dispnv50/disp.c | 20 +-------- drivers/gpu/drm/nouveau/nouveau_bo.c | 55 +++++++++++++++++++++++++ drivers/gpu/drm/nouveau/nouveau_bo.h | 5 +++ drivers/gpu/drm/nouveau/nouveau_chan.c | 14 +------ drivers/gpu/drm/nouveau/nouveau_dmem.c | 18 +++----- drivers/gpu/drm/nouveau/nv10_fence.c | 6 +-- drivers/gpu/drm/nouveau/nv17_fence.c | 15 +------ drivers/gpu/drm/nouveau/nv50_fence.c | 15 +------ drivers/gpu/drm/nouveau/nv84_fence.c | 19 ++------- 10 files changed, 81 insertions(+), 108 deletions(-) diff --git a/drivers/gpu/drm/nouveau/dispnv04/crtc.c b/drivers/gpu/drm/nouveau/dispnv04/crtc.c index 67146f1e8482..c063756eaea3 100644 --- a/drivers/gpu/drm/nouveau/dispnv04/crtc.c +++ b/drivers/gpu/drm/nouveau/dispnv04/crtc.c @@ -768,9 +768,7 @@ static void nv_crtc_destroy(struct drm_crtc *crtc) disp->image[nv_crtc->index] = NULL; } - nouveau_bo_unmap(nv_crtc->cursor.nvbo); - nouveau_bo_unpin(nv_crtc->cursor.nvbo); - nouveau_bo_fini(nv_crtc->cursor.nvbo); + nouveau_bo_unpin_del(&nv_crtc->cursor.nvbo); nvif_event_dtor(&nv_crtc->vblank); nvif_head_dtor(&nv_crtc->head); kfree(nv_crtc); @@ -1303,6 +1301,7 @@ nv04_crtc_vblank_handler(struct nvif_event *event, void *repv, u32 repc) int nv04_crtc_create(struct drm_device *dev, int crtc_num) { + struct nouveau_cli *cli = &nouveau_drm(dev)->client; struct nouveau_display *disp = nouveau_display(dev); struct nouveau_crtc *nv_crtc; struct drm_plane *primary; @@ -1336,20 +1335,9 @@ nv04_crtc_create(struct drm_device *dev, int crtc_num) drm_crtc_helper_add(&nv_crtc->base, &nv04_crtc_helper_funcs); drm_mode_crtc_set_gamma_size(&nv_crtc->base, 256); - ret = nouveau_bo_new(&nouveau_drm(dev)->client, 64*64*4, 0x100, - NOUVEAU_GEM_DOMAIN_VRAM, 0, 0x0000, NULL, NULL, - &nv_crtc->cursor.nvbo); - if (!ret) { - ret = nouveau_bo_pin(nv_crtc->cursor.nvbo, - NOUVEAU_GEM_DOMAIN_VRAM, false); - if (!ret) { - ret = nouveau_bo_map(nv_crtc->cursor.nvbo); - if (ret) - nouveau_bo_unpin(nv_crtc->cursor.nvbo); - } - if (ret) - nouveau_bo_fini(nv_crtc->cursor.nvbo); - } + ret = nouveau_bo_new_map(cli, NOUVEAU_GEM_DOMAIN_VRAM, 64 * 64 * 4, &nv_crtc->cursor.nvbo); + if (ret) + return ret; nv04_cursor_init(nv_crtc); diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c index 9bed728cb00e..10485510b539 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/disp.c +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c @@ -2808,10 +2808,7 @@ nv50_display_destroy(struct drm_device *dev) nvif_object_dtor(&disp->caps); nv50_core_del(&disp->core); - nouveau_bo_unmap(disp->sync); - if (disp->sync) - nouveau_bo_unpin(disp->sync); - nouveau_bo_fini(disp->sync); + nouveau_bo_unpin_del(&disp->sync); nouveau_display(dev)->priv = NULL; kfree(disp); @@ -2843,20 +2840,7 @@ nv50_display_create(struct drm_device *dev) dev->mode_config.normalize_zpos = true; /* small shared memory area we use for notifiers and semaphores */ - ret = nouveau_bo_new(&drm->client, 4096, 0x1000, - NOUVEAU_GEM_DOMAIN_VRAM, - 0, 0x0000, NULL, NULL, &disp->sync); - if (!ret) { - ret = nouveau_bo_pin(disp->sync, NOUVEAU_GEM_DOMAIN_VRAM, true); - if (!ret) { - ret = nouveau_bo_map(disp->sync); - if (ret) - nouveau_bo_unpin(disp->sync); - } - if (ret) - nouveau_bo_fini(disp->sync); - } - + ret = nouveau_bo_new_map(&drm->client, NOUVEAU_GEM_DOMAIN_VRAM, PAGE_SIZE, &disp->sync); if (ret) goto out; diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index fbe0144927e8..3a5ddf60380e 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -401,6 +401,61 @@ nouveau_bo_new(struct nouveau_cli *cli, u64 size, int align, return 0; } +void +nouveau_bo_unpin_del(struct nouveau_bo **pnvbo) +{ + struct nouveau_bo *nvbo = *pnvbo; + + if (!nvbo) + return; + + nouveau_bo_unmap(nvbo); + nouveau_bo_unpin(nvbo); + nouveau_bo_fini(nvbo); + + *pnvbo = NULL; +} + +int +nouveau_bo_new_pin(struct nouveau_cli *cli, u32 domain, u32 size, struct nouveau_bo **pnvbo) +{ + struct nouveau_bo *nvbo; + int ret; + + ret = nouveau_bo_new(cli, size, 0, domain, 0, 0, NULL, NULL, &nvbo); + if (ret) + return ret; + + ret = nouveau_bo_pin(nvbo, domain, false); + if (ret) { + nouveau_bo_fini(nvbo); + return ret; + } + + *pnvbo = nvbo; + return 0; +} + +int +nouveau_bo_new_map(struct nouveau_cli *cli, u32 domain, u32 size, struct nouveau_bo **pnvbo) +{ + struct nouveau_bo *nvbo; + int ret; + + ret = nouveau_bo_new_pin(cli, domain, size, &nvbo); + if (ret) + return ret; + + ret = nouveau_bo_map(nvbo); + if (ret) { + nouveau_bo_unpin_del(&nvbo); + return ret; + } + + *pnvbo = nvbo; + return 0; +} + static void set_placement_range(struct nouveau_bo *nvbo, uint32_t domain) { diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.h b/drivers/gpu/drm/nouveau/nouveau_bo.h index 596a63a50a20..f402f14bebb0 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.h +++ b/drivers/gpu/drm/nouveau/nouveau_bo.h @@ -9,6 +9,7 @@ struct nouveau_channel; struct nouveau_cli; struct nouveau_drm; struct nouveau_fence; +struct nouveau_vma; struct nouveau_bo { struct ttm_buffer_object bo; @@ -89,6 +90,10 @@ void nouveau_bo_sync_for_cpu(struct nouveau_bo *nvbo); void nouveau_bo_add_io_reserve_lru(struct ttm_buffer_object *bo); void nouveau_bo_del_io_reserve_lru(struct ttm_buffer_object *bo); +int nouveau_bo_new_pin(struct nouveau_cli *, u32 domain, u32 size, struct nouveau_bo **); +int nouveau_bo_new_map(struct nouveau_cli *, u32 domain, u32 size, struct nouveau_bo **); +void nouveau_bo_unpin_del(struct nouveau_bo **); + /* TODO: submit equivalent to TTM generic API upstream? */ static inline void __iomem * nvbo_kmap_obj_iovirtual(struct nouveau_bo *nvbo) diff --git a/drivers/gpu/drm/nouveau/nouveau_chan.c b/drivers/gpu/drm/nouveau/nouveau_chan.c index a14aa6715bb9..4b4bbbd8d7b7 100644 --- a/drivers/gpu/drm/nouveau/nouveau_chan.c +++ b/drivers/gpu/drm/nouveau/nouveau_chan.c @@ -105,10 +105,7 @@ nouveau_channel_del(struct nouveau_channel **pchan) nvif_mem_dtor(&chan->mem_userd); nvif_object_dtor(&chan->push.ctxdma); nouveau_vma_del(&chan->push.vma); - nouveau_bo_unmap(chan->push.buffer); - if (chan->push.buffer && chan->push.buffer->bo.pin_count) - nouveau_bo_unpin(chan->push.buffer); - nouveau_bo_fini(chan->push.buffer); + nouveau_bo_unpin_del(&chan->push.buffer); kfree(chan); } *pchan = NULL; @@ -163,14 +160,7 @@ nouveau_channel_prep(struct nouveau_cli *cli, if (nouveau_vram_pushbuf) target = NOUVEAU_GEM_DOMAIN_VRAM; - ret = nouveau_bo_new(cli, size, 0, target, 0, 0, NULL, NULL, - &chan->push.buffer); - if (ret == 0) { - ret = nouveau_bo_pin(chan->push.buffer, target, false); - if (ret == 0) - ret = nouveau_bo_map(chan->push.buffer); - } - + ret = nouveau_bo_new_map(cli, target, size, &chan->push.buffer); if (ret) { nouveau_channel_del(pchan); return ret; diff --git a/drivers/gpu/drm/nouveau/nouveau_dmem.c b/drivers/gpu/drm/nouveau/nouveau_dmem.c index 61d0f411ef84..ca4932a150e3 100644 --- a/drivers/gpu/drm/nouveau/nouveau_dmem.c +++ b/drivers/gpu/drm/nouveau/nouveau_dmem.c @@ -256,20 +256,15 @@ nouveau_dmem_chunk_alloc(struct nouveau_drm *drm, struct page **ppage) chunk->pagemap.ops = &nouveau_dmem_pagemap_ops; chunk->pagemap.owner = drm->dev; - ret = nouveau_bo_new(&drm->client, DMEM_CHUNK_SIZE, 0, - NOUVEAU_GEM_DOMAIN_VRAM, 0, 0, NULL, NULL, - &chunk->bo); + ret = nouveau_bo_new_pin(&drm->client, NOUVEAU_GEM_DOMAIN_VRAM, DMEM_CHUNK_SIZE, + &chunk->bo); if (ret) goto out_release; - ret = nouveau_bo_pin(chunk->bo, NOUVEAU_GEM_DOMAIN_VRAM, false); - if (ret) - goto out_bo_free; - ptr = memremap_pages(&chunk->pagemap, numa_node_id()); if (IS_ERR(ptr)) { ret = PTR_ERR(ptr); - goto out_bo_unpin; + goto out_bo_free; } mutex_lock(&drm->dmem->mutex); @@ -292,10 +287,8 @@ nouveau_dmem_chunk_alloc(struct nouveau_drm *drm, struct page **ppage) return 0; -out_bo_unpin: - nouveau_bo_unpin(chunk->bo); out_bo_free: - nouveau_bo_fini(chunk->bo); + nouveau_bo_unpin_del(&chunk->bo); out_release: release_mem_region(chunk->pagemap.range.start, range_len(&chunk->pagemap.range)); out_free: @@ -426,8 +419,7 @@ nouveau_dmem_fini(struct nouveau_drm *drm) list_for_each_entry_safe(chunk, tmp, &drm->dmem->chunks, list) { nouveau_dmem_evict_chunk(chunk); - nouveau_bo_unpin(chunk->bo); - nouveau_bo_fini(chunk->bo); + nouveau_bo_unpin_del(&chunk->bo); WARN_ON(chunk->callocated); list_del(&chunk->list); memunmap_pages(&chunk->pagemap); diff --git a/drivers/gpu/drm/nouveau/nv10_fence.c b/drivers/gpu/drm/nouveau/nv10_fence.c index 8c73f40e3bda..40ee95340814 100644 --- a/drivers/gpu/drm/nouveau/nv10_fence.c +++ b/drivers/gpu/drm/nouveau/nv10_fence.c @@ -85,10 +85,8 @@ void nv10_fence_destroy(struct nouveau_drm *drm) { struct nv10_fence_priv *priv = drm->fence; - nouveau_bo_unmap(priv->bo); - if (priv->bo) - nouveau_bo_unpin(priv->bo); - nouveau_bo_fini(priv->bo); + + nouveau_bo_unpin_del(&priv->bo); drm->fence = NULL; kfree(priv); } diff --git a/drivers/gpu/drm/nouveau/nv17_fence.c b/drivers/gpu/drm/nouveau/nv17_fence.c index d09bfd11369f..1b0c0aa3c305 100644 --- a/drivers/gpu/drm/nouveau/nv17_fence.c +++ b/drivers/gpu/drm/nouveau/nv17_fence.c @@ -130,20 +130,7 @@ nv17_fence_create(struct nouveau_drm *drm) priv->base.context_del = nv10_fence_context_del; spin_lock_init(&priv->lock); - ret = nouveau_bo_new(&drm->client, 4096, 0x1000, - NOUVEAU_GEM_DOMAIN_VRAM, - 0, 0x0000, NULL, NULL, &priv->bo); - if (!ret) { - ret = nouveau_bo_pin(priv->bo, NOUVEAU_GEM_DOMAIN_VRAM, false); - if (!ret) { - ret = nouveau_bo_map(priv->bo); - if (ret) - nouveau_bo_unpin(priv->bo); - } - if (ret) - nouveau_bo_fini(priv->bo); - } - + ret = nouveau_bo_new_map(&drm->client, NOUVEAU_GEM_DOMAIN_VRAM, PAGE_SIZE, &priv->bo); if (ret) { nv10_fence_destroy(drm); return ret; diff --git a/drivers/gpu/drm/nouveau/nv50_fence.c b/drivers/gpu/drm/nouveau/nv50_fence.c index 62e28dddf87c..e1f0e8adf313 100644 --- a/drivers/gpu/drm/nouveau/nv50_fence.c +++ b/drivers/gpu/drm/nouveau/nv50_fence.c @@ -81,20 +81,7 @@ nv50_fence_create(struct nouveau_drm *drm) priv->base.context_del = nv10_fence_context_del; spin_lock_init(&priv->lock); - ret = nouveau_bo_new(&drm->client, 4096, 0x1000, - NOUVEAU_GEM_DOMAIN_VRAM, - 0, 0x0000, NULL, NULL, &priv->bo); - if (!ret) { - ret = nouveau_bo_pin(priv->bo, NOUVEAU_GEM_DOMAIN_VRAM, false); - if (!ret) { - ret = nouveau_bo_map(priv->bo); - if (ret) - nouveau_bo_unpin(priv->bo); - } - if (ret) - nouveau_bo_fini(priv->bo); - } - + ret = nouveau_bo_new_map(&drm->client, NOUVEAU_GEM_DOMAIN_VRAM, PAGE_SIZE, &priv->bo); if (ret) { nv10_fence_destroy(drm); return ret; diff --git a/drivers/gpu/drm/nouveau/nv84_fence.c b/drivers/gpu/drm/nouveau/nv84_fence.c index aa7dd0c5d917..1765b2cedaf9 100644 --- a/drivers/gpu/drm/nouveau/nv84_fence.c +++ b/drivers/gpu/drm/nouveau/nv84_fence.c @@ -185,10 +185,8 @@ static void nv84_fence_destroy(struct nouveau_drm *drm) { struct nv84_fence_priv *priv = drm->fence; - nouveau_bo_unmap(priv->bo); - if (priv->bo) - nouveau_bo_unpin(priv->bo); - nouveau_bo_fini(priv->bo); + + nouveau_bo_unpin_del(&priv->bo); drm->fence = NULL; kfree(priv); } @@ -222,19 +220,8 @@ nv84_fence_create(struct nouveau_drm *drm) * will lose CPU/GPU coherency! */ NOUVEAU_GEM_DOMAIN_GART | NOUVEAU_GEM_DOMAIN_COHERENT; - ret = nouveau_bo_new(&drm->client, 16 * drm->chan_total, 0, - domain, 0, 0, NULL, NULL, &priv->bo); - if (ret == 0) { - ret = nouveau_bo_pin(priv->bo, domain, false); - if (ret == 0) { - ret = nouveau_bo_map(priv->bo); - if (ret) - nouveau_bo_unpin(priv->bo); - } - if (ret) - nouveau_bo_fini(priv->bo); - } + ret = nouveau_bo_new_map(&drm->client, domain, 16 * drm->chan_total, &priv->bo); if (ret) nv84_fence_destroy(drm); return ret; -- 2.49.0
Ben Skeggs
2025-May-17 00:09 UTC
[PATCH v3 56/62] drm/nouveau/nv50-: separate CHANNEL_GPFIFO handling out from CHANNEL_DMA
Primarily a cleanup to allow for changes in newer CHANNEL_GPFIFO classes to be more easily implemented. Compared to the prior implementation, this submits userspace push buffer segments as subroutines and uses the NV_RAMUSERD_TOP_LEVEL_GET registers to track the main (kernel) push buffer progress. Fixes a number of sporadic failures seen during piglit runs. Signed-off-by: Ben Skeggs <bskeggs at nvidia.com> Reviewed-by: Dave Airlie <airlied at redhat.com> Reviewed-by: Timur Tabi <ttabi at nvidia.com> Tested-by: Timur Tabi <ttabi at nvidia.com> --- drivers/gpu/drm/nouveau/include/nvif/chan.h | 56 ++++++++ drivers/gpu/drm/nouveau/include/nvif/object.h | 2 +- drivers/gpu/drm/nouveau/include/nvif/push.h | 14 +- drivers/gpu/drm/nouveau/nouveau_abi16.c | 2 +- drivers/gpu/drm/nouveau/nouveau_chan.c | 31 +++-- drivers/gpu/drm/nouveau/nouveau_chan.h | 11 +- drivers/gpu/drm/nouveau/nouveau_dma.c | 103 +------------- drivers/gpu/drm/nouveau/nouveau_dma.h | 13 +- drivers/gpu/drm/nouveau/nouveau_exec.c | 10 +- drivers/gpu/drm/nouveau/nouveau_gem.c | 8 +- drivers/gpu/drm/nouveau/nvif/Kbuild | 5 + drivers/gpu/drm/nouveau/nvif/chan.c | 127 ++++++++++++++++++ drivers/gpu/drm/nouveau/nvif/chan506f.c | 72 ++++++++++ drivers/gpu/drm/nouveau/nvif/chanc36f.c | 39 ++++++ 14 files changed, 344 insertions(+), 149 deletions(-) create mode 100644 drivers/gpu/drm/nouveau/include/nvif/chan.h create mode 100644 drivers/gpu/drm/nouveau/nvif/chan.c create mode 100644 drivers/gpu/drm/nouveau/nvif/chan506f.c create mode 100644 drivers/gpu/drm/nouveau/nvif/chanc36f.c diff --git a/drivers/gpu/drm/nouveau/include/nvif/chan.h b/drivers/gpu/drm/nouveau/include/nvif/chan.h new file mode 100644 index 000000000000..c1f7a8fce05b --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvif/chan.h @@ -0,0 +1,56 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#ifndef __NVIF_CHAN_H__ +#define __NVIF_CHAN_H__ +#include "push.h" + +struct nvif_chan { + const struct nvif_chan_func { + struct { + u32 (*read_get)(struct nvif_chan *); + } push; + + struct { + u32 (*read_get)(struct nvif_chan *); + void (*push)(struct nvif_chan *, bool main, u64 addr, u32 size, + bool no_prefetch); + void (*kick)(struct nvif_chan *); + } gpfifo; + } *func; + + struct { + struct nvif_map map; + } userd; + + struct { + struct nvif_map map; + u32 cur; + u32 max; + int free; + } gpfifo; + + struct nvif_push push; + + struct nvif_user *usermode; + u32 doorbell_token; +}; + +int nvif_chan_dma_wait(struct nvif_chan *, u32 push_nr); + +void nvif_chan_gpfifo_ctor(const struct nvif_chan_func *, void *userd, void *gpfifo, u32 gpfifo_size, + void *push, u64 push_addr, u32 push_size, struct nvif_chan *); +int nvif_chan_gpfifo_wait(struct nvif_chan *, u32 gpfifo_nr, u32 push_nr); +void nvif_chan_gpfifo_push(struct nvif_chan *, u64 addr, u32 size, bool no_prefetch); + +int nvif_chan506f_ctor(struct nvif_chan *, void *userd, void *gpfifo, u32 gpfifo_size, + void *push, u64 push_addr, u32 push_size); +u32 nvif_chan506f_read_get(struct nvif_chan *); +u32 nvif_chan506f_gpfifo_read_get(struct nvif_chan *); +void nvif_chan506f_gpfifo_push(struct nvif_chan *, bool main, u64 addr, u32 size, bool no_prefetch); + +int nvif_chanc36f_ctor(struct nvif_chan *, void *userd, void *gpfifo, u32 gpfifo_size, + void *push, u64 push_addr, u32 push_size, + struct nvif_user *usermode, u32 doorbell_token); +#endif diff --git a/drivers/gpu/drm/nouveau/include/nvif/object.h b/drivers/gpu/drm/nouveau/include/nvif/object.h index 8d205b6af46a..1b32dc701f61 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/object.h +++ b/drivers/gpu/drm/nouveau/include/nvif/object.h @@ -16,7 +16,7 @@ struct nvif_object { u32 handle; s32 oclass; void *priv; /*XXX: hack */ - struct { + struct nvif_map { void __iomem *ptr; u64 size; } map; diff --git a/drivers/gpu/drm/nouveau/include/nvif/push.h b/drivers/gpu/drm/nouveau/include/nvif/push.h index 6d3a8a3d2087..a493fababe3c 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/push.h +++ b/drivers/gpu/drm/nouveau/include/nvif/push.h @@ -31,6 +31,12 @@ struct nvif_push { void (*kick)(struct nvif_push *push); struct nvif_mem mem; + u64 addr; + + struct { + u32 get; + u32 max; + } hw; u32 *bgn; u32 *cur; @@ -41,7 +47,7 @@ struct nvif_push { static inline __must_check int PUSH_WAIT(struct nvif_push *push, u32 size) { - if (push->cur + size >= push->end) { + if (push->cur + size > push->end) { int ret = push->wait(push, size); if (ret) return ret; @@ -55,7 +61,11 @@ PUSH_WAIT(struct nvif_push *push, u32 size) static inline int PUSH_KICK(struct nvif_push *push) { - push->kick(push); + if (push->cur != push->bgn) { + push->kick(push); + push->bgn = push->cur; + } + return 0; } diff --git a/drivers/gpu/drm/nouveau/nouveau_abi16.c b/drivers/gpu/drm/nouveau/nouveau_abi16.c index 4c100005ef81..a3ba07fc48a0 100644 --- a/drivers/gpu/drm/nouveau/nouveau_abi16.c +++ b/drivers/gpu/drm/nouveau/nouveau_abi16.c @@ -416,7 +416,7 @@ nouveau_abi16_ioctl_channel_alloc(ABI16_IOCTL_ARGS) */ if (nouveau_cli_uvmm(cli)) { ret = nouveau_sched_create(&chan->sched, drm, drm->sched_wq, - chan->chan->dma.ib_max); + chan->chan->chan.gpfifo.max); if (ret) goto done; } diff --git a/drivers/gpu/drm/nouveau/nouveau_chan.c b/drivers/gpu/drm/nouveau/nouveau_chan.c index 4b4bbbd8d7b7..ad1e99184f7a 100644 --- a/drivers/gpu/drm/nouveau/nouveau_chan.c +++ b/drivers/gpu/drm/nouveau/nouveau_chan.c @@ -424,25 +424,24 @@ nouveau_channel_init(struct nouveau_channel *chan, u32 vram, u32 gart) } /* initialise dma tracking parameters */ - switch (chan->user.oclass) { - case NV03_CHANNEL_DMA: - case NV10_CHANNEL_DMA: - case NV17_CHANNEL_DMA: - case NV40_CHANNEL_DMA: + if (chan->user.oclass < NV50_CHANNEL_GPFIFO) { chan->user_put = 0x40; chan->user_get = 0x44; chan->dma.max = (0x10000 / 4) - 2; - break; - default: - chan->user_put = 0x40; - chan->user_get = 0x44; - chan->user_get_hi = 0x60; - chan->dma.ib_base = 0x10000 / 4; - chan->dma.ib_max = NV50_DMA_IB_MAX; - chan->dma.ib_put = 0; - chan->dma.ib_free = chan->dma.ib_max - chan->dma.ib_put; - chan->dma.max = chan->dma.ib_base; - break; + } else + if (chan->user.oclass < VOLTA_CHANNEL_GPFIFO_A) { + ret = nvif_chan506f_ctor(&chan->chan, chan->userd->map.ptr, + (u8*)chan->push.buffer->kmap.virtual + 0x10000, 0x2000, + chan->push.buffer->kmap.virtual, chan->push.addr, 0x10000); + if (ret) + return ret; + } else { + ret = nvif_chanc36f_ctor(&chan->chan, chan->userd->map.ptr, + (u8*)chan->push.buffer->kmap.virtual + 0x10000, 0x2000, + chan->push.buffer->kmap.virtual, chan->push.addr, 0x10000, + &drm->client.device.user, chan->token); + if (ret) + return ret; } chan->dma.put = 0; diff --git a/drivers/gpu/drm/nouveau/nouveau_chan.h b/drivers/gpu/drm/nouveau/nouveau_chan.h index 016f668c0bc1..ea8c3cdab46f 100644 --- a/drivers/gpu/drm/nouveau/nouveau_chan.h +++ b/drivers/gpu/drm/nouveau/nouveau_chan.h @@ -3,13 +3,11 @@ #define __NOUVEAU_CHAN_H__ #include <nvif/object.h> #include <nvif/event.h> -#include <nvif/push.h> +#include <nvif/chan.h> struct nvif_device; struct nouveau_channel { - struct { - struct nvif_push push; - } chan; + struct nvif_chan chan; struct nouveau_cli *cli; struct nouveau_vmm *vmm; @@ -41,12 +39,7 @@ struct nouveau_channel { int free; int cur; int put; - int ib_base; - int ib_max; - int ib_free; - int ib_put; } dma; - u32 user_get_hi; u32 user_get; u32 user_put; diff --git a/drivers/gpu/drm/nouveau/nouveau_dma.c b/drivers/gpu/drm/nouveau/nouveau_dma.c index a1f329ef0641..017a803121d4 100644 --- a/drivers/gpu/drm/nouveau/nouveau_dma.c +++ b/drivers/gpu/drm/nouveau/nouveau_dma.c @@ -43,8 +43,6 @@ READ_GET(struct nouveau_channel *chan, uint64_t *prev_get, int *timeout) uint64_t val; val = nvif_rd32(chan->userd, chan->user_get); - if (chan->user_get_hi) - val |= (uint64_t)nvif_rd32(chan->userd, chan->user_get_hi) << 32; /* reset counter as long as GET is still advancing, this is * to avoid misdetecting a GPU lockup if the GPU happens to @@ -68,111 +66,12 @@ READ_GET(struct nouveau_channel *chan, uint64_t *prev_get, int *timeout) return (val - chan->push.addr) >> 2; } -void -nv50_dma_push(struct nouveau_channel *chan, u64 offset, u32 length, - bool no_prefetch) -{ - struct nvif_user *user = &chan->cli->drm->client.device.user; - struct nouveau_bo *pb = chan->push.buffer; - int ip = (chan->dma.ib_put * 2) + chan->dma.ib_base; - - BUG_ON(chan->dma.ib_free < 1); - WARN_ON(length > NV50_DMA_PUSH_MAX_LENGTH); - - nouveau_bo_wr32(pb, ip++, lower_32_bits(offset)); - nouveau_bo_wr32(pb, ip++, upper_32_bits(offset) | length << 8 | - (no_prefetch ? (1 << 31) : 0)); - - chan->dma.ib_put = (chan->dma.ib_put + 1) & chan->dma.ib_max; - - mb(); - /* Flush writes. */ - nouveau_bo_rd32(pb, 0); - - nvif_wr32(chan->userd, 0x8c, chan->dma.ib_put); - if (user->func && user->func->doorbell) - user->func->doorbell(user, chan->token); - chan->dma.ib_free--; -} - -static int -nv50_dma_push_wait(struct nouveau_channel *chan, int count) -{ - uint32_t cnt = 0, prev_get = 0; - - while (chan->dma.ib_free < count) { - uint32_t get = nvif_rd32(chan->userd, 0x88); - if (get != prev_get) { - prev_get = get; - cnt = 0; - } - - if ((++cnt & 0xff) == 0) { - udelay(1); - if (cnt > 100000) - return -EBUSY; - } - - chan->dma.ib_free = get - chan->dma.ib_put; - if (chan->dma.ib_free <= 0) - chan->dma.ib_free += chan->dma.ib_max; - } - - return 0; -} - -static int -nv50_dma_wait(struct nouveau_channel *chan, int slots, int count) -{ - uint64_t prev_get = 0; - int ret, cnt = 0; - - ret = nv50_dma_push_wait(chan, slots + 1); - if (unlikely(ret)) - return ret; - - while (chan->dma.free < count) { - int get = READ_GET(chan, &prev_get, &cnt); - if (unlikely(get < 0)) { - if (get == -EINVAL) - continue; - - return get; - } - - if (get <= chan->dma.cur) { - chan->dma.free = chan->dma.max - chan->dma.cur; - if (chan->dma.free >= count) - break; - - FIRE_RING(chan); - do { - get = READ_GET(chan, &prev_get, &cnt); - if (unlikely(get < 0)) { - if (get == -EINVAL) - continue; - return get; - } - } while (get == 0); - chan->dma.cur = 0; - chan->dma.put = 0; - } - - chan->dma.free = get - chan->dma.cur - 1; - } - - return 0; -} - int -nouveau_dma_wait(struct nouveau_channel *chan, int slots, int size) +nouveau_dma_wait(struct nouveau_channel *chan, int size) { uint64_t prev_get = 0; int cnt = 0, get; - if (chan->dma.ib_max) - return nv50_dma_wait(chan, slots, size); - while (chan->dma.free < size) { get = READ_GET(chan, &prev_get, &cnt); if (unlikely(get == -EBUSY)) diff --git a/drivers/gpu/drm/nouveau/nouveau_dma.h b/drivers/gpu/drm/nouveau/nouveau_dma.h index c52cda82353e..0e27b76d1e1c 100644 --- a/drivers/gpu/drm/nouveau/nouveau_dma.h +++ b/drivers/gpu/drm/nouveau/nouveau_dma.h @@ -30,9 +30,7 @@ #include "nouveau_bo.h" #include "nouveau_chan.h" -int nouveau_dma_wait(struct nouveau_channel *, int slots, int size); -void nv50_dma_push(struct nouveau_channel *, u64 addr, u32 length, - bool no_prefetch); +int nouveau_dma_wait(struct nouveau_channel *, int size); /* * There's a hw race condition where you can't jump to your PUT offset, @@ -67,7 +65,7 @@ RING_SPACE(struct nouveau_channel *chan, int size) { int ret; - ret = nouveau_dma_wait(chan, 1, size); + ret = nouveau_dma_wait(chan, size); if (ret) return ret; @@ -94,12 +92,7 @@ FIRE_RING(struct nouveau_channel *chan) return; chan->accel_done = true; - if (chan->dma.ib_max) { - nv50_dma_push(chan, chan->push.addr + (chan->dma.put << 2), - (chan->dma.cur - chan->dma.put) << 2, false); - } else { - WRITE_PUT(chan->dma.cur); - } + WRITE_PUT(chan->dma.cur); chan->dma.put = chan->dma.cur; } diff --git a/drivers/gpu/drm/nouveau/nouveau_exec.c b/drivers/gpu/drm/nouveau/nouveau_exec.c index a0b5f1b16e8b..eac7cf8940a3 100644 --- a/drivers/gpu/drm/nouveau/nouveau_exec.c +++ b/drivers/gpu/drm/nouveau/nouveau_exec.c @@ -10,6 +10,8 @@ #include "nouveau_sched.h" #include "nouveau_uvmm.h" +#include <nvif/class.h> + /** * DOC: Overview * @@ -131,7 +133,7 @@ nouveau_exec_job_run(struct nouveau_job *job) struct nouveau_fence *fence = exec_job->fence; int i, ret; - ret = nouveau_dma_wait(chan, exec_job->push.count + 1, 16); + ret = nvif_chan_gpfifo_wait(&chan->chan, exec_job->push.count + 1, 16); if (ret) { NV_PRINTK(err, job->cli, "nv50cal_space: %d\n", ret); return ERR_PTR(ret); @@ -141,7 +143,7 @@ nouveau_exec_job_run(struct nouveau_job *job) struct drm_nouveau_exec_push *p = &exec_job->push.s[i]; bool no_prefetch = p->flags & DRM_NOUVEAU_EXEC_PUSH_NO_PREFETCH; - nv50_dma_push(chan, p->va, p->va_len, no_prefetch); + nvif_chan_gpfifo_push(&chan->chan, p->va, p->va_len, no_prefetch); } ret = nouveau_fence_emit(fence); @@ -375,10 +377,10 @@ nouveau_exec_ioctl_exec(struct drm_device *dev, if (unlikely(atomic_read(&chan->killed))) return nouveau_abi16_put(abi16, -ENODEV); - if (!chan->dma.ib_max) + if (chan->user.oclass < NV50_CHANNEL_GPFIFO) return nouveau_abi16_put(abi16, -ENOSYS); - push_max = nouveau_exec_push_max_from_ib_max(chan->dma.ib_max); + push_max = nouveau_exec_push_max_from_ib_max(chan->chan.gpfifo.max); if (unlikely(req->push_count > push_max)) { NV_PRINTK(err, cli, "pushbuf push count exceeds limit: %d max %d\n", req->push_count, push_max); diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c index 67e3c99de73a..5877545c2c50 100644 --- a/drivers/gpu/drm/nouveau/nouveau_gem.c +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c @@ -850,8 +850,8 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data, } } - if (chan->dma.ib_max) { - ret = nouveau_dma_wait(chan, req->nr_push + 1, 16); + if (chan->user.oclass >= NV50_CHANNEL_GPFIFO) { + ret = nvif_chan_gpfifo_wait(&chan->chan, req->nr_push + 1, 16); if (ret) { NV_PRINTK(err, cli, "nv50cal_space: %d\n", ret); goto out; @@ -864,7 +864,7 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data, u32 length = push[i].length & ~NOUVEAU_GEM_PUSHBUF_NO_PREFETCH; bool no_prefetch = push[i].length & NOUVEAU_GEM_PUSHBUF_NO_PREFETCH; - nv50_dma_push(chan, addr, length, no_prefetch); + nvif_chan_gpfifo_push(&chan->chan, addr, length, no_prefetch); } } else if (drm->client.device.info.chipset >= 0x25) { @@ -958,7 +958,7 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data, u_free(push); out_next: - if (chan->dma.ib_max) { + if (chan->user.oclass >= NV50_CHANNEL_GPFIFO) { req->suffix0 = 0x00000000; req->suffix1 = 0x00000000; } else diff --git a/drivers/gpu/drm/nouveau/nvif/Kbuild b/drivers/gpu/drm/nouveau/nvif/Kbuild index b7963a39dd91..991722951fbb 100644 --- a/drivers/gpu/drm/nouveau/nvif/Kbuild +++ b/drivers/gpu/drm/nouveau/nvif/Kbuild @@ -14,6 +14,11 @@ nvif-y += nvif/outp.o nvif-y += nvif/timer.o nvif-y += nvif/vmm.o +# Channel classes +nvif-y += nvif/chan.o +nvif-y += nvif/chan506f.o +nvif-y += nvif/chanc36f.o + # Usermode classes nvif-y += nvif/user.o nvif-y += nvif/userc361.o diff --git a/drivers/gpu/drm/nouveau/nvif/chan.c b/drivers/gpu/drm/nouveau/nvif/chan.c new file mode 100644 index 000000000000..7f58a1c17979 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvif/chan.c @@ -0,0 +1,127 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#include <nvif/chan.h> + +static void +nvif_chan_gpfifo_push_kick(struct nvif_push *push) +{ + struct nvif_chan *chan = container_of(push, typeof(*chan), push); + u32 put = push->bgn - (u32 *)chan->push.mem.object.map.ptr; + u32 cnt = push->cur - push->bgn; + + chan->func->gpfifo.push(chan, true, chan->push.addr + (put << 2), cnt << 2, false); + chan->func->gpfifo.kick(chan); +} + +static int +nvif_chan_gpfifo_push_wait(struct nvif_push *push, u32 push_nr) +{ + struct nvif_chan *chan = container_of(push, typeof(*chan), push); + + return nvif_chan_gpfifo_wait(chan, 1, push_nr); +} + +void +nvif_chan_gpfifo_push(struct nvif_chan *chan, u64 addr, u32 size, bool no_prefetch) +{ + chan->func->gpfifo.push(chan, false, addr, size, no_prefetch); +} + +int +nvif_chan_gpfifo_wait(struct nvif_chan *chan, u32 gpfifo_nr, u32 push_nr) +{ + struct nvif_push *push = &chan->push; + int ret = 0, time = 1000000; + + /* Account for the GPFIFO entry needed to submit pushbuf. */ + if (push_nr) + gpfifo_nr++; + + /* Wait for space in main push buffer. */ + if (push->cur + push_nr > push->end) { + ret = nvif_chan_dma_wait(chan, push_nr); + if (ret) + return ret; + } + + /* Wait for GPFIFO space. */ + while (chan->gpfifo.free < gpfifo_nr) { + chan->gpfifo.free = chan->func->gpfifo.read_get(chan) - chan->gpfifo.cur - 1; + if (chan->gpfifo.free < 0) + chan->gpfifo.free += chan->gpfifo.max + 1; + + if (chan->gpfifo.free < gpfifo_nr) { + if (!time--) + return -ETIMEDOUT; + udelay(1); + } + } + + return 0; +} + +void +nvif_chan_gpfifo_ctor(const struct nvif_chan_func *func, void *userd, void *gpfifo, u32 gpfifo_size, + void *push, u64 push_addr, u32 push_size, struct nvif_chan *chan) +{ + chan->func = func; + + chan->userd.map.ptr = userd; + + chan->gpfifo.map.ptr = gpfifo; + chan->gpfifo.max = (gpfifo_size >> 3) - 1; + chan->gpfifo.free = chan->gpfifo.max; + + chan->push.mem.object.map.ptr = push; + chan->push.wait = nvif_chan_gpfifo_push_wait; + chan->push.kick = nvif_chan_gpfifo_push_kick; + chan->push.addr = push_addr; + chan->push.hw.max = push_size >> 2; + chan->push.bgn = chan->push.cur = chan->push.end = push; +} + +int +nvif_chan_dma_wait(struct nvif_chan *chan, u32 nr) +{ + struct nvif_push *push = &chan->push; + u32 cur = push->cur - (u32 *)push->mem.object.map.ptr; + u32 free, time = 1000000; + + do { + u32 get = chan->func->push.read_get(chan); + + if (get <= cur) { + free = push->hw.max - cur; + if (free >= nr) + break; + + PUSH_KICK(push); + + while (get == 0) { + get = chan->func->push.read_get(chan); + if (get == 0) { + if (!time--) + return -ETIMEDOUT; + udelay(1); + } + } + + cur = 0; + } + + free = get - cur - 1; + + if (free < nr) { + if (!time--) + return -ETIMEDOUT; + udelay(1); + } + } while (free < nr); + + push->bgn = (u32 *)push->mem.object.map.ptr + cur; + push->cur = push->bgn; + push->end = push->bgn + free; + return 0; +} diff --git a/drivers/gpu/drm/nouveau/nvif/chan506f.c b/drivers/gpu/drm/nouveau/nvif/chan506f.c new file mode 100644 index 000000000000..5a5f8ddc058f --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvif/chan506f.c @@ -0,0 +1,72 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#include <nvif/chan.h> + +static void +nvif_chan506f_gpfifo_kick(struct nvif_chan *chan) +{ + wmb(); + nvif_wr32(&chan->userd, 0x8c, chan->gpfifo.cur); +} + +void +nvif_chan506f_gpfifo_push(struct nvif_chan *chan, bool main, u64 addr, u32 size, bool no_prefetch) +{ + u32 gpptr = chan->gpfifo.cur << 3; + + if (WARN_ON(!chan->gpfifo.free)) + return; + + nvif_wr32(&chan->gpfifo, gpptr + 0, lower_32_bits(addr)); + nvif_wr32(&chan->gpfifo, gpptr + 4, upper_32_bits(addr) | + (main ? 0 : BIT(9)) | + (size >> 2) << 10 | + (no_prefetch ? BIT(31) : 0)); + + chan->gpfifo.cur = (chan->gpfifo.cur + 1) & chan->gpfifo.max; + chan->gpfifo.free--; + if (!chan->gpfifo.free) + chan->push.end = chan->push.cur; +} + +u32 +nvif_chan506f_gpfifo_read_get(struct nvif_chan *chan) +{ + return nvif_rd32(&chan->userd, 0x88); +} + +u32 +nvif_chan506f_read_get(struct nvif_chan *chan) +{ + u32 tlgetlo = nvif_rd32(&chan->userd, 0x58); + u32 tlgethi = nvif_rd32(&chan->userd, 0x5c); + struct nvif_push *push = &chan->push; + + /* Update cached GET pointer if TOP_LEVEL_GET is valid. */ + if (tlgethi & BIT(31)) { + u64 tlget = ((u64)(tlgethi & 0xff) << 32) | tlgetlo; + + push->hw.get = (tlget - push->addr) >> 2; + } + + return push->hw.get; +} + +static const struct nvif_chan_func +nvif_chan506f = { + .push.read_get = nvif_chan506f_read_get, + .gpfifo.read_get = nvif_chan506f_gpfifo_read_get, + .gpfifo.push = nvif_chan506f_gpfifo_push, + .gpfifo.kick = nvif_chan506f_gpfifo_kick, +}; + +int +nvif_chan506f_ctor(struct nvif_chan *chan, void *userd, void *gpfifo, u32 gpfifo_size, + void *push, u64 push_addr, u32 push_size) +{ + nvif_chan_gpfifo_ctor(&nvif_chan506f, userd, gpfifo, gpfifo_size, + push, push_addr, push_size, chan); + return 0; +} diff --git a/drivers/gpu/drm/nouveau/nvif/chanc36f.c b/drivers/gpu/drm/nouveau/nvif/chanc36f.c new file mode 100644 index 000000000000..28a4207a4390 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvif/chanc36f.c @@ -0,0 +1,39 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#include <nvif/chan.h> +#include <nvif/user.h> + +static void +nvif_chanc36f_gpfifo_kick(struct nvif_chan *chan) +{ + struct nvif_user *usermode = chan->usermode; + + nvif_wr32(&chan->userd, 0x8c, chan->gpfifo.cur); + + wmb(); /* ensure CPU writes are flushed to BAR1 */ + nvif_rd32(&chan->userd, 0); /* ensure BAR1 writes are flushed to vidmem */ + + usermode->func->doorbell(usermode, chan->doorbell_token); +} + +static const struct nvif_chan_func +nvif_chanc36f = { + .push.read_get = nvif_chan506f_read_get, + .gpfifo.read_get = nvif_chan506f_gpfifo_read_get, + .gpfifo.push = nvif_chan506f_gpfifo_push, + .gpfifo.kick = nvif_chanc36f_gpfifo_kick, +}; + +int +nvif_chanc36f_ctor(struct nvif_chan *chan, void *userd, void *gpfifo, u32 gpfifo_size, + void *push, u64 push_addr, u32 push_size, + struct nvif_user *usermode, u32 doorbell_token) +{ + nvif_chan_gpfifo_ctor(&nvif_chanc36f, userd, gpfifo, gpfifo_size, + push, push_addr, push_size, chan); + chan->usermode = usermode; + chan->doorbell_token = doorbell_token; + return 0; +} -- 2.49.0
Ben Skeggs
2025-May-17 00:09 UTC
[PATCH v3 57/62] drm/nouveau/gf100-: track chan progress with non-WFI semaphore release
>From VOLTA_CHANNEL_GPFIFO_A onwards, HW no longer updates the GET/GP_GETpointers in USERD following channel progress, but instead updates on a timer for compatibility, and SW is expected to implement its own method of tracking channel progress (typically via non-WFI semaphore release). Nouveau has been making use of the compatibility mode up until now, however, from BLACKWELL_CHANNEL_GPFIFO_A HW no longer supports USERD writeback at all. Allocate a per-channel buffer in system memory, and append a non-WFI semaphore release to the end of each push buffer segment to simulate the pointers previously read from USERD. This change is implemented for Fermi (which is the first to support non- WFI semaphore release) onwards, as readback from system memory is likely faster than BAR1 reads. Signed-off-by: Ben Skeggs <bskeggs at nvidia.com> Reviewed-by: Dave Airlie <airlied at redhat.com> Reviewed-by: Timur Tabi <ttabi at nvidia.com> Tested-by: Timur Tabi <ttabi at nvidia.com> --- drivers/gpu/drm/nouveau/include/nvif/chan.h | 30 +++++-- drivers/gpu/drm/nouveau/nouveau_bo.c | 22 +++++ drivers/gpu/drm/nouveau/nouveau_bo.h | 2 + drivers/gpu/drm/nouveau/nouveau_chan.c | 19 ++++- drivers/gpu/drm/nouveau/nouveau_chan.h | 5 ++ drivers/gpu/drm/nouveau/nouveau_exec.c | 2 + drivers/gpu/drm/nouveau/nouveau_gem.c | 2 + drivers/gpu/drm/nouveau/nvif/Kbuild | 1 + drivers/gpu/drm/nouveau/nvif/chan.c | 33 +++++++- drivers/gpu/drm/nouveau/nvif/chan506f.c | 6 +- drivers/gpu/drm/nouveau/nvif/chan906f.c | 93 +++++++++++++++++++++ drivers/gpu/drm/nouveau/nvif/chanc36f.c | 48 +++++++++-- 12 files changed, 245 insertions(+), 18 deletions(-) create mode 100644 drivers/gpu/drm/nouveau/nvif/chan906f.c diff --git a/drivers/gpu/drm/nouveau/include/nvif/chan.h b/drivers/gpu/drm/nouveau/include/nvif/chan.h index c1f7a8fce05b..c329a29068d5 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/chan.h +++ b/drivers/gpu/drm/nouveau/include/nvif/chan.h @@ -17,7 +17,13 @@ struct nvif_chan { void (*push)(struct nvif_chan *, bool main, u64 addr, u32 size, bool no_prefetch); void (*kick)(struct nvif_chan *); + int (*post)(struct nvif_chan *, u32 gpptr, u32 pbptr); + u32 post_size; } gpfifo; + + struct { + int (*release)(struct nvif_chan *, u64 addr, u32 data); + } sem; } *func; struct { @@ -31,6 +37,11 @@ struct nvif_chan { int free; } gpfifo; + struct { + struct nvif_map map; + u64 addr; + } sema; + struct nvif_push push; struct nvif_user *usermode; @@ -43,14 +54,23 @@ void nvif_chan_gpfifo_ctor(const struct nvif_chan_func *, void *userd, void *gpf void *push, u64 push_addr, u32 push_size, struct nvif_chan *); int nvif_chan_gpfifo_wait(struct nvif_chan *, u32 gpfifo_nr, u32 push_nr); void nvif_chan_gpfifo_push(struct nvif_chan *, u64 addr, u32 size, bool no_prefetch); +int nvif_chan_gpfifo_post(struct nvif_chan *); -int nvif_chan506f_ctor(struct nvif_chan *, void *userd, void *gpfifo, u32 gpfifo_size, - void *push, u64 push_addr, u32 push_size); -u32 nvif_chan506f_read_get(struct nvif_chan *); -u32 nvif_chan506f_gpfifo_read_get(struct nvif_chan *); void nvif_chan506f_gpfifo_push(struct nvif_chan *, bool main, u64 addr, u32 size, bool no_prefetch); +void nvif_chan506f_gpfifo_kick(struct nvif_chan *); + +int nvif_chan906f_ctor_(const struct nvif_chan_func *, void *userd, void *gpfifo, u32 gpfifo_size, + void *push, u64 push_addr, u32 push_size, void *sema, u64 sema_addr, + struct nvif_chan *); +u32 nvif_chan906f_read_get(struct nvif_chan *); +u32 nvif_chan906f_gpfifo_read_get(struct nvif_chan *); +int nvif_chan906f_gpfifo_post(struct nvif_chan *, u32 gpptr, u32 pbptr); +int nvif_chan506f_ctor(struct nvif_chan *, void *userd, void *gpfifo, u32 gpfifo_size, + void *push, u64 push_addr, u32 push_size); +int nvif_chan906f_ctor(struct nvif_chan *, void *userd, void *gpfifo, u32 gpfifo_size, + void *push, u64 push_addr, u32 push_size, void *sema, u64 sema_addr); int nvif_chanc36f_ctor(struct nvif_chan *, void *userd, void *gpfifo, u32 gpfifo_size, - void *push, u64 push_addr, u32 push_size, + void *push, u64 push_addr, u32 push_size, void *sema, u64 sema_addr, struct nvif_user *usermode, u32 doorbell_token); #endif diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 3a5ddf60380e..a32a50f41a43 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -456,6 +456,28 @@ nouveau_bo_new_map(struct nouveau_cli *cli, u32 domain, u32 size, struct nouveau return 0; } +int +nouveau_bo_new_map_gpu(struct nouveau_cli *cli, u32 domain, u32 size, + struct nouveau_bo **pnvbo, struct nouveau_vma **pvma) +{ + struct nouveau_vmm *vmm = nouveau_cli_vmm(cli); + struct nouveau_bo *nvbo; + int ret; + + ret = nouveau_bo_new_map(cli, domain, size, &nvbo); + if (ret) + return ret; + + ret = nouveau_vma_new(nvbo, vmm, pvma); + if (ret) { + nouveau_bo_unpin_del(&nvbo); + return ret; + } + + *pnvbo = nvbo; + return 0; +} + static void set_placement_range(struct nouveau_bo *nvbo, uint32_t domain) { diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.h b/drivers/gpu/drm/nouveau/nouveau_bo.h index f402f14bebb0..d59fd12268b9 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.h +++ b/drivers/gpu/drm/nouveau/nouveau_bo.h @@ -92,6 +92,8 @@ void nouveau_bo_del_io_reserve_lru(struct ttm_buffer_object *bo); int nouveau_bo_new_pin(struct nouveau_cli *, u32 domain, u32 size, struct nouveau_bo **); int nouveau_bo_new_map(struct nouveau_cli *, u32 domain, u32 size, struct nouveau_bo **); +int nouveau_bo_new_map_gpu(struct nouveau_cli *, u32 domain, u32 size, + struct nouveau_bo **, struct nouveau_vma **); void nouveau_bo_unpin_del(struct nouveau_bo **); /* TODO: submit equivalent to TTM generic API upstream? */ diff --git a/drivers/gpu/drm/nouveau/nouveau_chan.c b/drivers/gpu/drm/nouveau/nouveau_chan.c index ad1e99184f7a..2a775d908e24 100644 --- a/drivers/gpu/drm/nouveau/nouveau_chan.c +++ b/drivers/gpu/drm/nouveau/nouveau_chan.c @@ -103,6 +103,8 @@ nouveau_channel_del(struct nouveau_channel **pchan) nvif_event_dtor(&chan->kill); nvif_object_dtor(&chan->user); nvif_mem_dtor(&chan->mem_userd); + nouveau_vma_del(&chan->sema.vma); + nouveau_bo_unpin_del(&chan->sema.bo); nvif_object_dtor(&chan->push.ctxdma); nouveau_vma_del(&chan->push.vma); nouveau_bo_unpin_del(&chan->push.buffer); @@ -189,8 +191,10 @@ nouveau_channel_prep(struct nouveau_cli *cli, chan->push.addr = chan->push.vma->addr; - if (device->info.family >= NV_DEVICE_INFO_V0_FERMI) - return 0; + if (device->info.family >= NV_DEVICE_INFO_V0_FERMI) { + return nouveau_bo_new_map_gpu(cli, NOUVEAU_GEM_DOMAIN_GART, PAGE_SIZE, + &chan->sema.bo, &chan->sema.vma); + } args.target = NV_DMA_V0_TARGET_VM; args.access = NV_DMA_V0_ACCESS_VM; @@ -429,16 +433,25 @@ nouveau_channel_init(struct nouveau_channel *chan, u32 vram, u32 gart) chan->user_get = 0x44; chan->dma.max = (0x10000 / 4) - 2; } else - if (chan->user.oclass < VOLTA_CHANNEL_GPFIFO_A) { + if (chan->user.oclass < FERMI_CHANNEL_GPFIFO) { ret = nvif_chan506f_ctor(&chan->chan, chan->userd->map.ptr, (u8*)chan->push.buffer->kmap.virtual + 0x10000, 0x2000, chan->push.buffer->kmap.virtual, chan->push.addr, 0x10000); if (ret) return ret; + } else + if (chan->user.oclass < VOLTA_CHANNEL_GPFIFO_A) { + ret = nvif_chan906f_ctor(&chan->chan, chan->userd->map.ptr, + (u8*)chan->push.buffer->kmap.virtual + 0x10000, 0x2000, + chan->push.buffer->kmap.virtual, chan->push.addr, 0x10000, + chan->sema.bo->kmap.virtual, chan->sema.vma->addr); + if (ret) + return ret; } else { ret = nvif_chanc36f_ctor(&chan->chan, chan->userd->map.ptr, (u8*)chan->push.buffer->kmap.virtual + 0x10000, 0x2000, chan->push.buffer->kmap.virtual, chan->push.addr, 0x10000, + chan->sema.bo->kmap.virtual, chan->sema.vma->addr, &drm->client.device.user, chan->token); if (ret) return ret; diff --git a/drivers/gpu/drm/nouveau/nouveau_chan.h b/drivers/gpu/drm/nouveau/nouveau_chan.h index ea8c3cdab46f..561877725aac 100644 --- a/drivers/gpu/drm/nouveau/nouveau_chan.h +++ b/drivers/gpu/drm/nouveau/nouveau_chan.h @@ -43,6 +43,11 @@ struct nouveau_channel { u32 user_get; u32 user_put; + struct { + struct nouveau_bo *bo; + struct nouveau_vma *vma; + } sema; + struct nvif_object user; struct nvif_object blit; diff --git a/drivers/gpu/drm/nouveau/nouveau_exec.c b/drivers/gpu/drm/nouveau/nouveau_exec.c index eac7cf8940a3..41b7c608c905 100644 --- a/drivers/gpu/drm/nouveau/nouveau_exec.c +++ b/drivers/gpu/drm/nouveau/nouveau_exec.c @@ -146,6 +146,8 @@ nouveau_exec_job_run(struct nouveau_job *job) nvif_chan_gpfifo_push(&chan->chan, p->va, p->va_len, no_prefetch); } + nvif_chan_gpfifo_post(&chan->chan); + ret = nouveau_fence_emit(fence); if (ret) { nouveau_fence_unref(&exec_job->fence); diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c index 5877545c2c50..690e10fbf0bd 100644 --- a/drivers/gpu/drm/nouveau/nouveau_gem.c +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c @@ -866,6 +866,8 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data, nvif_chan_gpfifo_push(&chan->chan, addr, length, no_prefetch); } + + nvif_chan_gpfifo_post(&chan->chan); } else if (drm->client.device.info.chipset >= 0x25) { ret = PUSH_WAIT(&chan->chan.push, req->nr_push * 2); diff --git a/drivers/gpu/drm/nouveau/nvif/Kbuild b/drivers/gpu/drm/nouveau/nvif/Kbuild index 991722951fbb..198889c20ce1 100644 --- a/drivers/gpu/drm/nouveau/nvif/Kbuild +++ b/drivers/gpu/drm/nouveau/nvif/Kbuild @@ -17,6 +17,7 @@ nvif-y += nvif/vmm.o # Channel classes nvif-y += nvif/chan.o nvif-y += nvif/chan506f.o +nvif-y += nvif/chan906f.o nvif-y += nvif/chanc36f.o # Usermode classes diff --git a/drivers/gpu/drm/nouveau/nvif/chan.c b/drivers/gpu/drm/nouveau/nvif/chan.c index 7f58a1c17979..baa10227d51a 100644 --- a/drivers/gpu/drm/nouveau/nvif/chan.c +++ b/drivers/gpu/drm/nouveau/nvif/chan.c @@ -9,7 +9,16 @@ nvif_chan_gpfifo_push_kick(struct nvif_push *push) { struct nvif_chan *chan = container_of(push, typeof(*chan), push); u32 put = push->bgn - (u32 *)chan->push.mem.object.map.ptr; - u32 cnt = push->cur - push->bgn; + u32 cnt; + + if (chan->func->gpfifo.post) { + if (push->end - push->cur < chan->func->gpfifo.post_size) + push->end = push->cur + chan->func->gpfifo.post_size; + + WARN_ON(nvif_chan_gpfifo_post(chan)); + } + + cnt = push->cur - push->bgn; chan->func->gpfifo.push(chan, true, chan->push.addr + (put << 2), cnt << 2, false); chan->func->gpfifo.kick(chan); @@ -23,6 +32,16 @@ nvif_chan_gpfifo_push_wait(struct nvif_push *push, u32 push_nr) return nvif_chan_gpfifo_wait(chan, 1, push_nr); } +int +nvif_chan_gpfifo_post(struct nvif_chan *chan) +{ + const u32 *map = chan->push.mem.object.map.ptr; + const u32 pbptr = (chan->push.cur - map) + chan->func->gpfifo.post_size; + const u32 gpptr = (chan->gpfifo.cur + 1) & chan->gpfifo.max; + + return chan->func->gpfifo.post(chan, gpptr, pbptr); +} + void nvif_chan_gpfifo_push(struct nvif_chan *chan, u64 addr, u32 size, bool no_prefetch) { @@ -35,6 +54,14 @@ nvif_chan_gpfifo_wait(struct nvif_chan *chan, u32 gpfifo_nr, u32 push_nr) struct nvif_push *push = &chan->push; int ret = 0, time = 1000000; + if (gpfifo_nr) { + /* Account for pushbuf space needed by nvif_chan_gpfifo_post(), + * if used after pushing userspace GPFIFO entries. + */ + if (chan->func->gpfifo.post) + push_nr += chan->func->gpfifo.post_size; + } + /* Account for the GPFIFO entry needed to submit pushbuf. */ if (push_nr) gpfifo_nr++; @@ -89,6 +116,8 @@ nvif_chan_dma_wait(struct nvif_chan *chan, u32 nr) u32 cur = push->cur - (u32 *)push->mem.object.map.ptr; u32 free, time = 1000000; + nr += chan->func->gpfifo.post_size; + do { u32 get = chan->func->push.read_get(chan); @@ -122,6 +151,6 @@ nvif_chan_dma_wait(struct nvif_chan *chan, u32 nr) push->bgn = (u32 *)push->mem.object.map.ptr + cur; push->cur = push->bgn; - push->end = push->bgn + free; + push->end = push->bgn + free - chan->func->gpfifo.post_size; return 0; } diff --git a/drivers/gpu/drm/nouveau/nvif/chan506f.c b/drivers/gpu/drm/nouveau/nvif/chan506f.c index 5a5f8ddc058f..d3900887c4a7 100644 --- a/drivers/gpu/drm/nouveau/nvif/chan506f.c +++ b/drivers/gpu/drm/nouveau/nvif/chan506f.c @@ -4,7 +4,7 @@ */ #include <nvif/chan.h> -static void +void nvif_chan506f_gpfifo_kick(struct nvif_chan *chan) { wmb(); @@ -31,13 +31,13 @@ nvif_chan506f_gpfifo_push(struct nvif_chan *chan, bool main, u64 addr, u32 size, chan->push.end = chan->push.cur; } -u32 +static u32 nvif_chan506f_gpfifo_read_get(struct nvif_chan *chan) { return nvif_rd32(&chan->userd, 0x88); } -u32 +static u32 nvif_chan506f_read_get(struct nvif_chan *chan) { u32 tlgetlo = nvif_rd32(&chan->userd, 0x58); diff --git a/drivers/gpu/drm/nouveau/nvif/chan906f.c b/drivers/gpu/drm/nouveau/nvif/chan906f.c new file mode 100644 index 000000000000..c9cfb85179b0 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvif/chan906f.c @@ -0,0 +1,93 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#include <nvif/chan.h> +#include <nvif/user.h> +#include <nvif/push906f.h> + +#include <nvhw/class/cl906f.h> + +/* Limits GPFIFO size to 1MiB, and "main" push buffer size to 64KiB. */ +#define NVIF_CHAN906F_PBPTR_BITS 15 +#define NVIF_CHAN906F_PBPTR_MASK ((1 << NVIF_CHAN906F_PBPTR_BITS) - 1) + +#define NVIF_CHAN906F_GPPTR_SHIFT NVIF_CHAN906F_PBPTR_BITS +#define NVIF_CHAN906F_GPPTR_BITS (32 - NVIF_CHAN906F_PBPTR_BITS) +#define NVIF_CHAN906F_GPPTR_MASK ((1 << NVIF_CHAN906F_GPPTR_BITS) - 1) + +#define NVIF_CHAN906F_SEM_RELEASE_SIZE 5 + +static int +nvif_chan906f_sem_release(struct nvif_chan *chan, u64 addr, u32 data) +{ + struct nvif_push *push = &chan->push; + int ret; + + ret = PUSH_WAIT(push, NVIF_CHAN906F_SEM_RELEASE_SIZE); + if (ret) + return ret; + + PUSH_MTHD(push, NV906F, SEMAPHOREA, + NVVAL(NV906F, SEMAPHOREA, OFFSET_UPPER, upper_32_bits(addr)), + + SEMAPHOREB, lower_32_bits(addr), + + SEMAPHOREC, data, + + SEMAPHORED, + NVDEF(NV906F, SEMAPHORED, OPERATION, RELEASE) | + NVDEF(NV906F, SEMAPHORED, RELEASE_WFI, DIS) | + NVDEF(NV906F, SEMAPHORED, RELEASE_SIZE, 16BYTE)); + + return 0; +} + +int +nvif_chan906f_gpfifo_post(struct nvif_chan *chan, u32 gpptr, u32 pbptr) +{ + return chan->func->sem.release(chan, chan->sema.addr, + (gpptr << NVIF_CHAN906F_GPPTR_SHIFT) | pbptr); +} + +u32 +nvif_chan906f_gpfifo_read_get(struct nvif_chan *chan) +{ + return nvif_rd32(&chan->sema, 0) >> NVIF_CHAN906F_GPPTR_SHIFT; +} + +u32 +nvif_chan906f_read_get(struct nvif_chan *chan) +{ + return nvif_rd32(&chan->sema, 0) & NVIF_CHAN906F_PBPTR_MASK; +} + +static const struct nvif_chan_func +nvif_chan906f = { + .push.read_get = nvif_chan906f_read_get, + .gpfifo.read_get = nvif_chan906f_gpfifo_read_get, + .gpfifo.push = nvif_chan506f_gpfifo_push, + .gpfifo.kick = nvif_chan506f_gpfifo_kick, + .gpfifo.post = nvif_chan906f_gpfifo_post, + .gpfifo.post_size = NVIF_CHAN906F_SEM_RELEASE_SIZE, + .sem.release = nvif_chan906f_sem_release, +}; + +int +nvif_chan906f_ctor_(const struct nvif_chan_func *func, void *userd, void *gpfifo, u32 gpfifo_size, + void *push, u64 push_addr, u32 push_size, void *sema, u64 sema_addr, + struct nvif_chan *chan) +{ + nvif_chan_gpfifo_ctor(func, userd, gpfifo, gpfifo_size, push, push_addr, push_size, chan); + chan->sema.map.ptr = sema; + chan->sema.addr = sema_addr; + return 0; +} + +int +nvif_chan906f_ctor(struct nvif_chan *chan, void *userd, void *gpfifo, u32 gpfifo_size, + void *push, u64 push_addr, u32 push_size, void *sema, u64 sema_addr) +{ + return nvif_chan906f_ctor_(&nvif_chan906f, userd, gpfifo, gpfifo_size, + push, push_addr, push_size, sema, sema_addr, chan); +} diff --git a/drivers/gpu/drm/nouveau/nvif/chanc36f.c b/drivers/gpu/drm/nouveau/nvif/chanc36f.c index 28a4207a4390..ca02b939c3fd 100644 --- a/drivers/gpu/drm/nouveau/nvif/chanc36f.c +++ b/drivers/gpu/drm/nouveau/nvif/chanc36f.c @@ -5,6 +5,9 @@ #include <nvif/chan.h> #include <nvif/user.h> +#include <nvif/push906f.h> +#include <nvhw/class/clc36f.h> + static void nvif_chanc36f_gpfifo_kick(struct nvif_chan *chan) { @@ -18,21 +21,56 @@ nvif_chanc36f_gpfifo_kick(struct nvif_chan *chan) usermode->func->doorbell(usermode, chan->doorbell_token); } +#define NVIF_CHANC36F_SEM_RELEASE_SIZE 6 + +static int +nvif_chanc36f_sem_release(struct nvif_chan *chan, u64 addr, u32 data) +{ + struct nvif_push *push = &chan->push; + int ret; + + ret = PUSH_WAIT(push, NVIF_CHANC36F_SEM_RELEASE_SIZE); + if (ret) + return ret; + + PUSH_MTHD(push, NVC36F, SEM_ADDR_LO, lower_32_bits(addr), + + SEM_ADDR_HI, upper_32_bits(addr), + + SEM_PAYLOAD_LO, data); + + PUSH_MTHD(push, NVC36F, SEM_EXECUTE, + NVDEF(NVC36F, SEM_EXECUTE, OPERATION, RELEASE) | + NVDEF(NVC36F, SEM_EXECUTE, RELEASE_WFI, DIS) | + NVDEF(NVC36F, SEM_EXECUTE, PAYLOAD_SIZE, 32BIT) | + NVDEF(NVC36F, SEM_EXECUTE, RELEASE_TIMESTAMP, DIS)); + + return 0; +} + static const struct nvif_chan_func nvif_chanc36f = { - .push.read_get = nvif_chan506f_read_get, - .gpfifo.read_get = nvif_chan506f_gpfifo_read_get, + .push.read_get = nvif_chan906f_read_get, + .gpfifo.read_get = nvif_chan906f_gpfifo_read_get, .gpfifo.push = nvif_chan506f_gpfifo_push, .gpfifo.kick = nvif_chanc36f_gpfifo_kick, + .gpfifo.post = nvif_chan906f_gpfifo_post, + .gpfifo.post_size = NVIF_CHANC36F_SEM_RELEASE_SIZE, + .sem.release = nvif_chanc36f_sem_release, }; int nvif_chanc36f_ctor(struct nvif_chan *chan, void *userd, void *gpfifo, u32 gpfifo_size, - void *push, u64 push_addr, u32 push_size, + void *push, u64 push_addr, u32 push_size, void *sema, u64 sema_addr, struct nvif_user *usermode, u32 doorbell_token) { - nvif_chan_gpfifo_ctor(&nvif_chanc36f, userd, gpfifo, gpfifo_size, - push, push_addr, push_size, chan); + int ret; + + ret = nvif_chan906f_ctor_(&nvif_chanc36f, userd, gpfifo, gpfifo_size, + push, push_addr, push_size, sema, sema_addr, chan); + if (ret) + return ret; + chan->usermode = usermode; chan->doorbell_token = doorbell_token; return 0; -- 2.49.0
This commit enables basic support for the GB100/GB102 Blackwell GPUs. Beyond HW class ID plumbing there's very little change here vs GH100. Signed-off-by: Ben Skeggs <bskeggs at nvidia.com> Reviewed-by: Dave Airlie <airlied at redhat.com> Reviewed-by: Timur Tabi <ttabi at nvidia.com> Tested-by: Timur Tabi <ttabi at nvidia.com> --- .../include/nvhw/ref/gb100/dev_hshub_base.h | 28 +++++++++++++++ drivers/gpu/drm/nouveau/include/nvif/cl0080.h | 1 + drivers/gpu/drm/nouveau/include/nvif/class.h | 9 +++++ .../drm/nouveau/include/nvkm/core/device.h | 1 + .../gpu/drm/nouveau/include/nvkm/subdev/fb.h | 1 + .../gpu/drm/nouveau/include/nvkm/subdev/fsp.h | 1 + .../gpu/drm/nouveau/include/nvkm/subdev/gsp.h | 1 + drivers/gpu/drm/nouveau/nouveau_bo.c | 1 + drivers/gpu/drm/nouveau/nouveau_chan.c | 33 ++++++++--------- drivers/gpu/drm/nouveau/nouveau_drm.c | 1 + .../gpu/drm/nouveau/nvkm/engine/device/base.c | 33 +++++++++++++++++ .../gpu/drm/nouveau/nvkm/engine/device/user.c | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/fb/Kbuild | 1 + .../gpu/drm/nouveau/nvkm/subdev/fb/gb100.c | 34 ++++++++++++++++++ .../gpu/drm/nouveau/nvkm/subdev/fsp/Kbuild | 1 + .../gpu/drm/nouveau/nvkm/subdev/fsp/gb100.c | 24 +++++++++++++ .../gpu/drm/nouveau/nvkm/subdev/fsp/gh100.c | 2 +- .../gpu/drm/nouveau/nvkm/subdev/fsp/priv.h | 1 + .../gpu/drm/nouveau/nvkm/subdev/gsp/Kbuild | 1 + .../gpu/drm/nouveau/nvkm/subdev/gsp/gb100.c | 35 +++++++++++++++++++ .../gpu/drm/nouveau/nvkm/subdev/gsp/gh100.c | 17 +++++---- .../gpu/drm/nouveau/nvkm/subdev/gsp/priv.h | 6 ++++ .../gpu/drm/nouveau/nvkm/subdev/gsp/rm/Kbuild | 1 + .../drm/nouveau/nvkm/subdev/gsp/rm/gb10x.c | 27 ++++++++++++++ .../gpu/drm/nouveau/nvkm/subdev/gsp/rm/gpu.h | 1 + .../drm/nouveau/nvkm/subdev/gsp/rm/r570/rm.c | 16 +++++++++ .../gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h | 2 ++ 27 files changed, 257 insertions(+), 23 deletions(-) create mode 100644 drivers/gpu/drm/nouveau/include/nvhw/ref/gb100/dev_hshub_base.h create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/fb/gb100.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/fsp/gb100.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/gb100.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gb10x.c diff --git a/drivers/gpu/drm/nouveau/include/nvhw/ref/gb100/dev_hshub_base.h b/drivers/gpu/drm/nouveau/include/nvhw/ref/gb100/dev_hshub_base.h new file mode 100644 index 000000000000..c9d74bd95e0b --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvhw/ref/gb100/dev_hshub_base.h @@ -0,0 +1,28 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#ifndef __gb100_dev_hshub_base_h__ +#define __gb100_dev_hshub_base_h__ + +#define NV_PFB_HSHUB0 0x00870fff:0x00870000 + +#define NV_PFB_HSHUB 0x00000FFF:0x00000000 /* RW--D */ +#define NV_PFB_HSHUB_PCIE_FLUSH_SYSMEM_ADDR_LO 0x00000E50 /* RW-4R */ +#define NV_PFB_HSHUB_PCIE_FLUSH_SYSMEM_ADDR_LO_ADR 31:0 /* RWIVF */ +#define NV_PFB_HSHUB_PCIE_FLUSH_SYSMEM_ADDR_LO_ADR_INIT 0x00000000 /* RWI-V */ +#define NV_PFB_HSHUB_PCIE_FLUSH_SYSMEM_ADDR_LO_ADR_MASK 0xFFFFFF00 /* ----V */ +#define NV_PFB_HSHUB_PCIE_FLUSH_SYSMEM_ADDR_HI 0x00000E54 /* RW-4R */ +#define NV_PFB_HSHUB_PCIE_FLUSH_SYSMEM_ADDR_HI_ADR 31:0 /* RWIVF */ +#define NV_PFB_HSHUB_PCIE_FLUSH_SYSMEM_ADDR_HI_ADR_INIT 0x00000000 /* RWI-V */ +#define NV_PFB_HSHUB_PCIE_FLUSH_SYSMEM_ADDR_HI_ADR_MASK 0x000FFFFF /* ----V */ +#define NV_PFB_HSHUB_EG_PCIE_FLUSH_SYSMEM_ADDR_LO 0x000006C0 /* RW-4R */ +#define NV_PFB_HSHUB_EG_PCIE_FLUSH_SYSMEM_ADDR_LO_ADR 31:0 /* RWIVF */ +#define NV_PFB_HSHUB_EG_PCIE_FLUSH_SYSMEM_ADDR_LO_ADR_INIT 0x00000000 /* RWI-V */ +#define NV_PFB_HSHUB_EG_PCIE_FLUSH_SYSMEM_ADDR_LO_ADR_MASK 0xFFFFFF00 /* ----V */ +#define NV_PFB_HSHUB_EG_PCIE_FLUSH_SYSMEM_ADDR_HI 0x000006C4 /* RW-4R */ +#define NV_PFB_HSHUB_EG_PCIE_FLUSH_SYSMEM_ADDR_HI_ADR 31:0 /* RWIVF */ +#define NV_PFB_HSHUB_EG_PCIE_FLUSH_SYSMEM_ADDR_HI_ADR_INIT 0x00000000 /* RWI-V */ +#define NV_PFB_HSHUB_EG_PCIE_FLUSH_SYSMEM_ADDR_HI_ADR_MASK 0x000FFFFF /* ----V */ + +#endif // __gb100_dev_hshub_base_h__ diff --git a/drivers/gpu/drm/nouveau/include/nvif/cl0080.h b/drivers/gpu/drm/nouveau/include/nvif/cl0080.h index 60a52ef52071..ea8267e0d8da 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/cl0080.h +++ b/drivers/gpu/drm/nouveau/include/nvif/cl0080.h @@ -30,6 +30,7 @@ struct nv_device_info_v0 { #define NV_DEVICE_INFO_V0_AMPERE 0x0d #define NV_DEVICE_INFO_V0_ADA 0x0e #define NV_DEVICE_INFO_V0_HOPPER 0x0f +#define NV_DEVICE_INFO_V0_BLACKWELL 0x10 __u8 family; __u8 pad06[2]; __u64 ram_size; diff --git a/drivers/gpu/drm/nouveau/include/nvif/class.h b/drivers/gpu/drm/nouveau/include/nvif/class.h index 83acf367a65c..606483fc850b 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/class.h +++ b/drivers/gpu/drm/nouveau/include/nvif/class.h @@ -57,6 +57,7 @@ #define KEPLER_INLINE_TO_MEMORY_A 0x0000a040 #define KEPLER_INLINE_TO_MEMORY_B 0x0000a140 +#define BLACKWELL_INLINE_TO_MEMORY_A 0x0000cd40 #define NV04_DISP /* cl0046.h */ 0x00000046 @@ -87,6 +88,7 @@ #define AMPERE_CHANNEL_GPFIFO_A /* if0020.h */ 0x0000c56f #define AMPERE_CHANNEL_GPFIFO_B /* if0020.h */ 0x0000c76f #define HOPPER_CHANNEL_GPFIFO_A 0x0000c86f +#define BLACKWELL_CHANNEL_GPFIFO_A 0x0000c96f #define NV50_DISP /* if0010.h */ 0x00005070 #define G82_DISP /* if0010.h */ 0x00008270 @@ -198,6 +200,8 @@ #define HOPPER_A 0x0000cb97 +#define BLACKWELL_A 0x0000cd97 + #define NV74_BSP 0x000074b0 #define NVB8B0_VIDEO_DECODER 0x0000b8b0 @@ -205,6 +209,7 @@ #define NVC6B0_VIDEO_DECODER 0x0000c6b0 #define NVC7B0_VIDEO_DECODER 0x0000c7b0 #define NVC9B0_VIDEO_DECODER 0x0000c9b0 +#define NVCDB0_VIDEO_DECODER 0x0000cdb0 #define GT212_MSVLD 0x000085b1 #define IGT21A_MSVLD 0x000086b1 @@ -234,6 +239,7 @@ #define AMPERE_DMA_COPY_A 0x0000c6b5 #define AMPERE_DMA_COPY_B 0x0000c7b5 #define HOPPER_DMA_COPY_A 0x0000c8b5 +#define BLACKWELL_DMA_COPY_A 0x0000c9b5 #define NVC4B7_VIDEO_ENCODER 0x0000c4b7 #define NVC7B7_VIDEO_ENCODER 0x0000c7b7 @@ -257,15 +263,18 @@ #define AMPERE_COMPUTE_B 0x0000c7c0 #define ADA_COMPUTE_A 0x0000c9c0 #define HOPPER_COMPUTE_A 0x0000cbc0 +#define BLACKWELL_COMPUTE_A 0x0000cdc0 #define NV74_CIPHER 0x000074c1 #define NVB8D1_VIDEO_NVJPG 0x0000b8d1 #define NVC4D1_VIDEO_NVJPG 0x0000c4d1 #define NVC9D1_VIDEO_NVJPG 0x0000c9d1 +#define NVCDD1_VIDEO_NVJPG 0x0000cdd1 #define NVB8FA_VIDEO_OFA 0x0000b8fa #define NVC6FA_VIDEO_OFA 0x0000c6fa #define NVC7FA_VIDEO_OFA 0x0000c7fa #define NVC9FA_VIDEO_OFA 0x0000c9fa +#define NVCDFA_VIDEO_OFA 0x0000cdfa #endif diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/device.h b/drivers/gpu/drm/nouveau/include/nvkm/core/device.h index 926542350abc..0664195e5684 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/core/device.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/device.h @@ -48,6 +48,7 @@ struct nvkm_device { GA100 = 0x170, GH100 = 0x180, AD100 = 0x190, + GB10x = 0x1a0, } card_type; u32 chipset; u8 chiprev; diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h index c114903ce388..7bd73f9f749b 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h @@ -103,6 +103,7 @@ int tu102_fb_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct n int ga100_fb_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fb **); int ga102_fb_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fb **); int gh100_fb_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fb **); +int gb100_fb_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fb **); #include <subdev/bios.h> #include <subdev/bios/ramcfg.h> diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/fsp.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/fsp.h index 2a8c1d5a65f9..7122f814e4d0 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/fsp.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/fsp.h @@ -19,4 +19,5 @@ int nvkm_fsp_boot_gsp_fmc(struct nvkm_fsp *, u64 args_addr, u32 rsvd_size, bool u64 img_addr, const u8 *hash, const u8 *pkey, const u8 *sig); int gh100_fsp_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fsp **); +int gb100_fsp_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fsp **); #endif diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h index 8f611b2503b7..c5982fd74725 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h @@ -492,4 +492,5 @@ int ga100_gsp_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_ int ga102_gsp_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_gsp **); int gh100_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 **); +int gb100_gsp_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_gsp **); #endif diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index a32a50f41a43..1a9a74c26e8e 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -1000,6 +1000,7 @@ nouveau_bo_move_init(struct nouveau_drm *drm) struct ttm_resource *, struct ttm_resource *); int (*init)(struct nouveau_channel *, u32 handle); } _methods[] = { + { "COPY", 4, 0xc9b5, nve0_bo_move_copy, nve0_bo_move_init }, { "COPY", 4, 0xc8b5, nve0_bo_move_copy, nve0_bo_move_init }, { "COPY", 4, 0xc7b5, nve0_bo_move_copy, nve0_bo_move_init }, { "GRCE", 0, 0xc7b5, nve0_bo_move_copy, nvc0_bo_move_init }, diff --git a/drivers/gpu/drm/nouveau/nouveau_chan.c b/drivers/gpu/drm/nouveau/nouveau_chan.c index 2a775d908e24..726de0aa0fcf 100644 --- a/drivers/gpu/drm/nouveau/nouveau_chan.c +++ b/drivers/gpu/drm/nouveau/nouveau_chan.c @@ -249,22 +249,23 @@ nouveau_channel_ctor(struct nouveau_cli *cli, bool priv, u64 runm, struct nouveau_channel **pchan) { const struct nvif_mclass hosts[] = { - { HOPPER_CHANNEL_GPFIFO_A, 0 }, - { AMPERE_CHANNEL_GPFIFO_B, 0 }, - { AMPERE_CHANNEL_GPFIFO_A, 0 }, - { TURING_CHANNEL_GPFIFO_A, 0 }, - { VOLTA_CHANNEL_GPFIFO_A, 0 }, - { PASCAL_CHANNEL_GPFIFO_A, 0 }, - { MAXWELL_CHANNEL_GPFIFO_A, 0 }, - { KEPLER_CHANNEL_GPFIFO_B, 0 }, - { KEPLER_CHANNEL_GPFIFO_A, 0 }, - { FERMI_CHANNEL_GPFIFO , 0 }, - { G82_CHANNEL_GPFIFO , 0 }, - { NV50_CHANNEL_GPFIFO , 0 }, - { NV40_CHANNEL_DMA , 0 }, - { NV17_CHANNEL_DMA , 0 }, - { NV10_CHANNEL_DMA , 0 }, - { NV03_CHANNEL_DMA , 0 }, + { BLACKWELL_CHANNEL_GPFIFO_A, 0 }, + { HOPPER_CHANNEL_GPFIFO_A, 0 }, + { AMPERE_CHANNEL_GPFIFO_B, 0 }, + { AMPERE_CHANNEL_GPFIFO_A, 0 }, + { TURING_CHANNEL_GPFIFO_A, 0 }, + { VOLTA_CHANNEL_GPFIFO_A, 0 }, + { PASCAL_CHANNEL_GPFIFO_A, 0 }, + { MAXWELL_CHANNEL_GPFIFO_A, 0 }, + { KEPLER_CHANNEL_GPFIFO_B, 0 }, + { KEPLER_CHANNEL_GPFIFO_A, 0 }, + { FERMI_CHANNEL_GPFIFO , 0 }, + { G82_CHANNEL_GPFIFO , 0 }, + { NV50_CHANNEL_GPFIFO , 0 }, + { NV40_CHANNEL_DMA , 0 }, + { NV17_CHANNEL_DMA , 0 }, + { NV10_CHANNEL_DMA , 0 }, + { NV03_CHANNEL_DMA , 0 }, {} }; DEFINE_RAW_FLEX(struct nvif_chan_v0, args, name, TASK_COMM_LEN + 16); diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index 5b6bb4c2f78b..0be604af5b29 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -510,6 +510,7 @@ nouveau_accel_init(struct nouveau_drm *drm) case AMPERE_CHANNEL_GPFIFO_A: case AMPERE_CHANNEL_GPFIFO_B: case HOPPER_CHANNEL_GPFIFO_A: + case BLACKWELL_CHANNEL_GPFIFO_A: ret = gv100_fence_create(drm); break; default: diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c index 5082fe5f1966..f6f23cbc7a73 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c @@ -2802,6 +2802,36 @@ nv197_chipset = { .sec2 = { 0x00000001, ga102_sec2_new }, }; +static const struct nvkm_device_chip +nv1a0_chipset = { + .name = "GB100", + .bar = { 0x00000001, tu102_bar_new }, + .fb = { 0x00000001, gb100_fb_new }, + .fsp = { 0x00000001, gb100_fsp_new }, + .gsp = { 0x00000001, gb100_gsp_new }, + .imem = { 0x00000001, gh100_instmem_new }, + .mmu = { 0x00000001, gh100_mmu_new }, + .pci = { 0x00000001, gh100_pci_new }, + .timer = { 0x00000001, gk20a_timer_new }, + .vfn = { 0x00000001, ga100_vfn_new }, + .fifo = { 0x00000001, ga102_fifo_new }, +}; + +static const struct nvkm_device_chip +nv1a2_chipset = { + .name = "GB102", + .bar = { 0x00000001, tu102_bar_new }, + .fb = { 0x00000001, gb100_fb_new }, + .fsp = { 0x00000001, gb100_fsp_new }, + .gsp = { 0x00000001, gb100_gsp_new }, + .imem = { 0x00000001, gh100_instmem_new }, + .mmu = { 0x00000001, gh100_mmu_new }, + .pci = { 0x00000001, gh100_pci_new }, + .timer = { 0x00000001, gk20a_timer_new }, + .vfn = { 0x00000001, ga100_vfn_new }, + .fifo = { 0x00000001, ga102_fifo_new }, +}; + struct nvkm_subdev * nvkm_device_subdev(struct nvkm_device *device, int type, int inst) { @@ -3119,6 +3149,7 @@ nvkm_device_ctor(const struct nvkm_device_func *func, case 0x170: device->card_type = GA100; break; case 0x180: device->card_type = GH100; break; case 0x190: device->card_type = AD100; break; + case 0x1a0: device->card_type = GB10x; break; default: break; } @@ -3227,6 +3258,8 @@ nvkm_device_ctor(const struct nvkm_device_func *func, case 0x194: device->chip = &nv194_chipset; break; case 0x196: device->chip = &nv196_chipset; break; case 0x197: device->chip = &nv197_chipset; break; + case 0x1a0: device->chip = &nv1a0_chipset; break; + case 0x1a2: device->chip = &nv1a2_chipset; break; default: if (nvkm_boolopt(device->cfgopt, "NvEnableUnsupportedChipsets", false)) { switch (device->chipset) { diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/user.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/user.c index 57c2678022b5..07f45cc16210 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/user.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/user.c @@ -149,6 +149,7 @@ nvkm_udevice_info(struct nvkm_udevice *udev, void *data, u32 size) case GA100: args->v0.family = NV_DEVICE_INFO_V0_AMPERE; break; case AD100: args->v0.family = NV_DEVICE_INFO_V0_ADA; break; case GH100: args->v0.family = NV_DEVICE_INFO_V0_HOPPER; break; + case GB10x: args->v0.family = NV_DEVICE_INFO_V0_BLACKWELL; break; default: args->v0.family = 0; break; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/Kbuild index f13312934131..b438a57f2efc 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/Kbuild @@ -36,6 +36,7 @@ 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/gh100.o +nvkm-y += nvkm/subdev/fb/gb100.o nvkm-y += nvkm/subdev/fb/r535.o diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gb100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gb100.c new file mode 100644 index 000000000000..1c78c8853617 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gb100.c @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#include "priv.h" + +#include <nvhw/drf.h> +#include <nvhw/ref/gb100/dev_hshub_base.h> + +static void +gb100_fb_sysmem_flush_page_init(struct nvkm_fb *fb) +{ + const u32 addr_hi = upper_32_bits(fb->sysmem.flush_page_addr); + const u32 addr_lo = lower_32_bits(fb->sysmem.flush_page_addr); + const u32 hshub = DRF_LO(NV_PFB_HSHUB0); + struct nvkm_device *device = fb->subdev.device; + + nvkm_wr32(device, hshub + NV_PFB_HSHUB_PCIE_FLUSH_SYSMEM_ADDR_HI, addr_hi); + nvkm_wr32(device, hshub + NV_PFB_HSHUB_PCIE_FLUSH_SYSMEM_ADDR_LO, addr_lo); + nvkm_wr32(device, hshub + NV_PFB_HSHUB_EG_PCIE_FLUSH_SYSMEM_ADDR_HI, addr_hi); + nvkm_wr32(device, hshub + NV_PFB_HSHUB_EG_PCIE_FLUSH_SYSMEM_ADDR_LO, addr_lo); +} + +static const struct nvkm_fb_func +gb100_fb = { + .sysmem.flush_page_init = gb100_fb_sysmem_flush_page_init, + .vidmem.size = ga102_fb_vidmem_size, +}; + +int +gb100_fb_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct nvkm_fb **pfb) +{ + return r535_fb_new(&gb100_fb, device, type, inst, pfb); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fsp/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/fsp/Kbuild index ff04992b181d..337772acdddc 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fsp/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fsp/Kbuild @@ -4,3 +4,4 @@ nvkm-y += nvkm/subdev/fsp/base.o nvkm-y += nvkm/subdev/fsp/gh100.o +nvkm-y += nvkm/subdev/fsp/gb100.o diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fsp/gb100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fsp/gb100.c new file mode 100644 index 000000000000..e06636bf54b6 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fsp/gb100.c @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#include "priv.h" + +static const struct nvkm_fsp_func +gb100_fsp = { + .wait_secure_boot = gh100_fsp_wait_secure_boot, + .cot = { + .version = 2, + .size_hash = 48, + .size_pkey = 97, + .size_sig = 96, + .boot_gsp_fmc = gh100_fsp_boot_gsp_fmc, + }, +}; + +int +gb100_fsp_new(struct nvkm_device *device, + enum nvkm_subdev_type type, int inst, struct nvkm_fsp **pfsp) +{ + return nvkm_fsp_new_(&gb100_fsp, device, type, inst, pfsp); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fsp/gh100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fsp/gh100.c index 9f4285af3fed..2815be4bf5de 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fsp/gh100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fsp/gh100.c @@ -237,7 +237,7 @@ gh100_fsp_boot_gsp_fmc(struct nvkm_fsp *fsp, u64 args_addr, u32 rsvd_size, bool return gh100_fsp_send_sync(fsp, NVDM_TYPE_COT, (const u8 *)&msg, sizeof(msg)); } -static int +int gh100_fsp_wait_secure_boot(struct nvkm_fsp *fsp) { struct nvkm_device *device = fsp->subdev.device; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fsp/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/fsp/priv.h index 91517f3dedfb..f0b2c605c33d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fsp/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fsp/priv.h @@ -23,6 +23,7 @@ struct nvkm_fsp_func { int nvkm_fsp_new_(const struct nvkm_fsp_func *, struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fsp **); +int gh100_fsp_wait_secure_boot(struct nvkm_fsp *); int gh100_fsp_boot_gsp_fmc(struct nvkm_fsp *, u64 args_addr, u32 rsvd_size, bool resume, u64 img_addr, const u8 *hash, const u8 *pkey, const u8 *sig); #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/Kbuild index 3c6c1309c4b4..4aebea4f6a64 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/Kbuild @@ -9,5 +9,6 @@ nvkm-y += nvkm/subdev/gsp/ga100.o nvkm-y += nvkm/subdev/gsp/ga102.o nvkm-y += nvkm/subdev/gsp/gh100.o nvkm-y += nvkm/subdev/gsp/ad102.o +nvkm-y += nvkm/subdev/gsp/gb100.o include $(src)/nvkm/subdev/gsp/rm/Kbuild diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/gb100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/gb100.c new file mode 100644 index 000000000000..12a3f2c1ed82 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/gb100.c @@ -0,0 +1,35 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#include "priv.h" + +static const struct nvkm_gsp_func +gb100_gsp = { + .flcn = &ga102_gsp_flcn, + + .sig_section = ".fwsignature_gb10x", + + .dtor = r535_gsp_dtor, + .oneinit = gh100_gsp_oneinit, + .init = gh100_gsp_init, + .fini = gh100_gsp_fini, + + .rm.gpu = &gb10x_gpu, +}; + +static struct nvkm_gsp_fwif +gb100_gsps[] = { + { 0, gh100_gsp_load, &gb100_gsp, &r570_rm_gb10x, "570.144", true }, + {} +}; + +int +gb100_gsp_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, + struct nvkm_gsp **pgsp) +{ + return nvkm_gsp_new_(gb100_gsps, device, type, inst, pgsp); +} + +NVKM_GSP_FIRMWARE_FMC(gb100, 570.144); +NVKM_GSP_FIRMWARE_FMC(gb102, 570.144); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/gh100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/gh100.c index 3ad71696c111..ce31e8248807 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/gh100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/gh100.c @@ -16,7 +16,7 @@ #include <nvhw/ref/gh100/dev_falcon_v4.h> #include <nvhw/ref/gh100/dev_riscv_pri.h> -static int +int gh100_gsp_fini(struct nvkm_gsp *gsp, bool suspend) { struct nvkm_falcon *falcon = &gsp->falcon; @@ -65,7 +65,7 @@ gh100_gsp_lockdown_released(struct nvkm_gsp *gsp, u32 *mbox0) return !NVVAL_GET(data, NV_PFALCON, FALCON_HWCFG2, RISCV_BR_PRIV_LOCKDOWN); } -static int +int gh100_gsp_init(struct nvkm_gsp *gsp) { struct nvkm_subdev *subdev = &gsp->subdev; @@ -74,6 +74,7 @@ gh100_gsp_init(struct nvkm_gsp *gsp) struct nvkm_gsp_mem *meta; GSP_FMC_BOOT_PARAMS *args; int ret, time = 4000; + u32 rsvd_size; u32 mbox0; if (!resume) { @@ -97,7 +98,11 @@ gh100_gsp_init(struct nvkm_gsp *gsp) args->gspRmParams.target = GSP_DMA_TARGET_NONCOHERENT_SYSTEM; args->gspRmParams.bootArgsOffset = gsp->libos.addr; - ret = nvkm_fsp_boot_gsp_fmc(device->fsp, gsp->fmc.args.addr, gsp->fb.heap.size, resume, + rsvd_size = gsp->fb.heap.size; + if (gsp->rm->wpr->rsvd_size_pmu) + rsvd_size = ALIGN(rsvd_size + gsp->rm->wpr->rsvd_size_pmu, 0x200000); + + ret = nvkm_fsp_boot_gsp_fmc(device->fsp, gsp->fmc.args.addr, rsvd_size, resume, gsp->fmc.fw.addr, gsp->fmc.hash, gsp->fmc.pkey, gsp->fmc.sig); if (ret) return ret; @@ -157,7 +162,7 @@ gh100_gsp_wpr_meta_init(struct nvkm_gsp *gsp) meta->gspFwHeapSize = tu102_gsp_wpr_heap_size(gsp); meta->frtsSize = 0x100000; meta->vgaWorkspaceSize = gsp->fb.bios.vga_workspace.size; - meta->pmuReservedSize = 0; + meta->pmuReservedSize = gsp->rm->wpr->rsvd_size_pmu; return 0; } @@ -254,7 +259,7 @@ elf_section(const void *elf, const char *name, unsigned int *len) return NULL; } -static int +int gh100_gsp_oneinit(struct nvkm_gsp *gsp) { struct nvkm_subdev *subdev = &gsp->subdev; @@ -319,7 +324,7 @@ gh100_gsp = { .rm.gpu = &gh100_gpu, }; -static int +int gh100_gsp_load(struct nvkm_gsp *gsp, int ver, const struct nvkm_gsp_fwif *fwif) { int ret; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/priv.h index 86ec580ba936..4f14e85fc69e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/priv.h @@ -26,6 +26,8 @@ int gv100_gsp_nofw(struct nvkm_gsp *, int, const struct nvkm_gsp_fwif *); int tu102_gsp_load(struct nvkm_gsp *, int, const struct nvkm_gsp_fwif *); int tu102_gsp_load_rm(struct nvkm_gsp *, const struct nvkm_gsp_fwif *); +int gh100_gsp_load(struct nvkm_gsp *, int, const struct nvkm_gsp_fwif *); + #define NVKM_GSP_FIRMWARE_BOOTER(chip,vers) \ MODULE_FIRMWARE("nvidia/"#chip"/gsp/booter_load-"#vers".bin"); \ MODULE_FIRMWARE("nvidia/"#chip"/gsp/booter_unload-"#vers".bin"); \ @@ -75,6 +77,10 @@ int ga102_gsp_booter_ctor(struct nvkm_gsp *, const char *, const struct firmware struct nvkm_falcon *, struct nvkm_falcon_fw *); int ga102_gsp_reset(struct nvkm_gsp *); +int gh100_gsp_oneinit(struct nvkm_gsp *); +int gh100_gsp_init(struct nvkm_gsp *); +int gh100_gsp_fini(struct nvkm_gsp *, bool suspend); + void r535_gsp_dtor(struct nvkm_gsp *); int r535_gsp_oneinit(struct nvkm_gsp *); int r535_gsp_init(struct nvkm_gsp *); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/Kbuild index 2a71868d6710..2efef4b694d6 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/Kbuild @@ -12,6 +12,7 @@ nvkm-y += nvkm/subdev/gsp/rm/ga100.o nvkm-y += nvkm/subdev/gsp/rm/ga1xx.o nvkm-y += nvkm/subdev/gsp/rm/ad10x.o nvkm-y += nvkm/subdev/gsp/rm/gh100.o +nvkm-y += nvkm/subdev/gsp/rm/gb10x.o include $(src)/nvkm/subdev/gsp/rm/r535/Kbuild include $(src)/nvkm/subdev/gsp/rm/r570/Kbuild diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gb10x.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gb10x.c new file mode 100644 index 000000000000..3a296d8fd2e0 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gb10x.c @@ -0,0 +1,27 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#include "gpu.h" + +#include <nvif/class.h> + +const struct nvkm_rm_gpu +gb10x_gpu = { + .usermode.class = HOPPER_USERMODE_A, + + .fifo.chan = { + .class = BLACKWELL_CHANNEL_GPFIFO_A, + }, + + .ce.class = BLACKWELL_DMA_COPY_A, + .gr.class = { + .i2m = BLACKWELL_INLINE_TO_MEMORY_A, + .twod = FERMI_TWOD_A, + .threed = BLACKWELL_A, + .compute = BLACKWELL_COMPUTE_A, + }, + .nvdec.class = NVCDB0_VIDEO_DECODER, + .nvjpg.class = NVCDD1_VIDEO_NVJPG, + .ofa.class = NVCDFA_VIDEO_OFA, +}; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gpu.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gpu.h index 443753f3369a..e84376c85e99 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gpu.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gpu.h @@ -63,4 +63,5 @@ extern const struct nvkm_rm_gpu ga100_gpu; extern const struct nvkm_rm_gpu ga1xx_gpu; extern const struct nvkm_rm_gpu ad10x_gpu; extern const struct nvkm_rm_gpu gh100_gpu; +extern const struct nvkm_rm_gpu gb10x_gpu; #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/rm.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/rm.c index 8a641e5a5b92..7e5b411fa543 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/rm.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/rm.c @@ -29,6 +29,16 @@ r570_wpr_libos3_gh100 = { .offset_set_by_acr = true, }; +static const struct nvkm_rm_wpr +r570_wpr_libos3_gb10x = { + .os_carveout_size = GSP_FW_HEAP_PARAM_OS_SIZE_LIBOS3_BAREMETAL, + .base_size = GSP_FW_HEAP_PARAM_BASE_RM_SIZE_GH100, + .heap_size_min = GSP_FW_HEAP_SIZE_OVERRIDE_LIBOS3_BAREMETAL_MIN_MB, + .heap_size_non_wpr = 0x200000, + .rsvd_size_pmu = ALIGN(0x0800000 + 0x1000000 + 0x0001000, 0x20000), + .offset_set_by_acr = true, +}; + static const struct nvkm_rm_api r570_api = { .gsp = &r570_gsp, @@ -65,3 +75,9 @@ r570_rm_gh100 = { .wpr = &r570_wpr_libos3_gh100, .api = &r570_api, }; + +const struct nvkm_rm_impl +r570_rm_gb10x = { + .wpr = &r570_wpr_libos3_gb10x, + .api = &r570_api, +}; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h index 626ebce39be5..2e9bd74d39be 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h @@ -26,6 +26,7 @@ struct nvkm_rm_wpr { u32 base_size; u64 heap_size_min; u32 heap_size_non_wpr; + u32 rsvd_size_pmu; bool offset_set_by_acr; }; @@ -176,6 +177,7 @@ extern const struct nvkm_rm_api_engine r535_ofa; extern const struct nvkm_rm_impl r570_rm_tu102; extern const struct nvkm_rm_impl r570_rm_ga102; extern const struct nvkm_rm_impl r570_rm_gh100; +extern const struct nvkm_rm_impl r570_rm_gb10x; extern const struct nvkm_rm_api_gsp r570_gsp; extern const struct nvkm_rm_api_client r570_client; extern const struct nvkm_rm_api_fbsr r570_fbsr; -- 2.49.0
Ben Skeggs
2025-May-17 00:09 UTC
[PATCH v3 59/62] drm/nouveau/gsp: add hal for fifo.chan.doorbell_handle
The doorbell register on GB20x GPUs has additional fields. Signed-off-by: Ben Skeggs <bskeggs at nvidia.com> Reviewed-by: Dave Airlie <airlied at redhat.com> Reviewed-by: Timur Tabi <ttabi at nvidia.com> Tested-by: Timur Tabi <ttabi at nvidia.com> --- drivers/gpu/drm/nouveau/nvkm/engine/fifo/priv.h | 2 ++ drivers/gpu/drm/nouveau/nvkm/engine/fifo/tu102.c | 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ad10x.c | 3 +++ drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ga100.c | 3 +++ drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ga1xx.c | 3 +++ drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gb10x.c | 3 +++ drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gh100.c | 3 +++ drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gpu.h | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/fifo.c | 4 +++- drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/tu1xx.c | 3 +++ 10 files changed, 25 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/priv.h b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/priv.h index a0f3277605a5..9ebb35c31db0 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/priv.h @@ -6,6 +6,7 @@ #include <core/enum.h> struct nvkm_cctx; struct nvkm_cgrp; +struct nvkm_chan; struct nvkm_engn; struct nvkm_memory; struct nvkm_runl; @@ -195,6 +196,7 @@ extern const struct nvkm_chan_func_ramfc gv100_chan_ramfc; void tu102_fifo_intr_ctxsw_timeout_info(struct nvkm_engn *, u32 info); extern const struct nvkm_fifo_func_mmu_fault tu102_fifo_mmu_fault; +u32 tu102_chan_doorbell_handle(struct nvkm_chan *); int ga100_fifo_runl_ctor(struct nvkm_fifo *); int ga100_fifo_nonstall_ctor(struct nvkm_fifo *); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/tu102.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/tu102.c index 1d39a6840a40..c5a03298e88c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/tu102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/tu102.c @@ -31,7 +31,7 @@ #include <nvif/class.h> -static u32 +u32 tu102_chan_doorbell_handle(struct nvkm_chan *chan) { return (chan->cgrp->runl->id << 16) | chan->id; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ad10x.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ad10x.c index d699c386adec..e1ce6355c35f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ad10x.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ad10x.c @@ -4,6 +4,8 @@ */ #include "gpu.h" +#include <engine/fifo/priv.h> + #include <nvif/class.h> const struct nvkm_rm_gpu @@ -21,6 +23,7 @@ ad10x_gpu = { .fifo.chan = { .class = AMPERE_CHANNEL_GPFIFO_A, + .doorbell_handle = tu102_chan_doorbell_handle, }, .ce.class = AMPERE_DMA_COPY_B, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ga100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ga100.c index 5e7f18dbf18b..a48c6134075d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ga100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ga100.c @@ -4,6 +4,8 @@ */ #include "gpu.h" +#include <engine/fifo/priv.h> + #include <nvif/class.h> const struct nvkm_rm_gpu @@ -12,6 +14,7 @@ ga100_gpu = { .fifo.chan = { .class = AMPERE_CHANNEL_GPFIFO_A, + .doorbell_handle = tu102_chan_doorbell_handle, }, .ce.class = AMPERE_DMA_COPY_A, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ga1xx.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ga1xx.c index 61525d23aaa0..50536ad7f85d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ga1xx.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ga1xx.c @@ -4,6 +4,8 @@ */ #include "gpu.h" +#include <engine/fifo/priv.h> + #include <nvif/class.h> const struct nvkm_rm_gpu @@ -21,6 +23,7 @@ ga1xx_gpu = { .fifo.chan = { .class = AMPERE_CHANNEL_GPFIFO_A, + .doorbell_handle = tu102_chan_doorbell_handle, }, .ce.class = AMPERE_DMA_COPY_B, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gb10x.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gb10x.c index 3a296d8fd2e0..2f517dcd721a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gb10x.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gb10x.c @@ -4,6 +4,8 @@ */ #include "gpu.h" +#include <engine/fifo/priv.h> + #include <nvif/class.h> const struct nvkm_rm_gpu @@ -12,6 +14,7 @@ gb10x_gpu = { .fifo.chan = { .class = BLACKWELL_CHANNEL_GPFIFO_A, + .doorbell_handle = tu102_chan_doorbell_handle, }, .ce.class = BLACKWELL_DMA_COPY_A, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gh100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gh100.c index 088250559e12..49e2c54e1aa8 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gh100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gh100.c @@ -4,6 +4,8 @@ */ #include "gpu.h" +#include <engine/fifo/priv.h> + #include <nvif/class.h> const struct nvkm_rm_gpu @@ -12,6 +14,7 @@ gh100_gpu = { .fifo.chan = { .class = HOPPER_CHANNEL_GPFIFO_A, + .doorbell_handle = tu102_chan_doorbell_handle, }, .ce.class = HOPPER_DMA_COPY_A, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gpu.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gpu.h index e84376c85e99..77aa7b13a3af 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gpu.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gpu.h @@ -25,6 +25,7 @@ struct nvkm_rm_gpu { struct { struct { u32 class; + u32 (*doorbell_handle)(struct nvkm_chan *); } chan; } fifo; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/fifo.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/fifo.c index 4238362ec073..eaba4d50860d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/fifo.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/fifo.c @@ -41,7 +41,9 @@ static u32 r535_chan_doorbell_handle(struct nvkm_chan *chan) { - return (chan->cgrp->runl->id << 16) | chan->id; + struct nvkm_gsp *gsp = chan->rm.object.client->gsp; + + return gsp->rm->gpu->fifo.chan.doorbell_handle(chan); } static void diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/tu1xx.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/tu1xx.c index 883b9eddbfe6..423502f870db 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/tu1xx.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/tu1xx.c @@ -4,6 +4,8 @@ */ #include "gpu.h" +#include <engine/fifo/priv.h> + #include <nvif/class.h> const struct nvkm_rm_gpu @@ -21,6 +23,7 @@ tu1xx_gpu = { .fifo.chan = { .class = TURING_CHANNEL_GPFIFO_A, + .doorbell_handle = tu102_chan_doorbell_handle, }, .ce.class = TURING_DMA_COPY_A, -- 2.49.0
This commit adds support for the GB20x GPUs found on GeForce RTX 50xx series boards. Beyond a few miscellaneous register moves and HW class ID plumbing, this reuses most of the code added to support GH100/GB10x. Signed-off-by: Ben Skeggs <bskeggs at nvidia.com> Reviewed-by: Dave Airlie <airlied at redhat.com> Reviewed-by: Timur Tabi <ttabi at nvidia.com> Tested-by: Timur Tabi <ttabi at nvidia.com> --- .../include/nvhw/ref/gb10b/dev_fbhub.h | 18 ++++ .../nouveau/include/nvhw/ref/gb202/dev_ce.h | 12 +++ .../include/nvhw/ref/gb202/dev_therm.h | 17 ++++ drivers/gpu/drm/nouveau/include/nvif/class.h | 15 ++++ .../drm/nouveau/include/nvkm/core/device.h | 1 + .../gpu/drm/nouveau/include/nvkm/subdev/fb.h | 1 + .../gpu/drm/nouveau/include/nvkm/subdev/fsp.h | 1 + .../gpu/drm/nouveau/include/nvkm/subdev/gsp.h | 1 + drivers/gpu/drm/nouveau/nouveau_bo.c | 1 + drivers/gpu/drm/nouveau/nouveau_chan.c | 1 + drivers/gpu/drm/nouveau/nouveau_drm.c | 1 + drivers/gpu/drm/nouveau/nvif/user.c | 9 +- drivers/gpu/drm/nouveau/nvkm/engine/ce/Kbuild | 1 + .../gpu/drm/nouveau/nvkm/engine/ce/gb202.c | 16 ++++ drivers/gpu/drm/nouveau/nvkm/engine/ce/priv.h | 2 + .../gpu/drm/nouveau/nvkm/engine/device/base.c | 86 +++++++++++++++++++ .../gpu/drm/nouveau/nvkm/engine/device/user.c | 1 + .../gpu/drm/nouveau/nvkm/engine/fifo/Kbuild | 1 + .../gpu/drm/nouveau/nvkm/engine/fifo/gb202.c | 14 +++ .../gpu/drm/nouveau/nvkm/engine/fifo/priv.h | 2 + drivers/gpu/drm/nouveau/nvkm/subdev/fb/Kbuild | 1 + .../gpu/drm/nouveau/nvkm/subdev/fb/gb202.c | 30 +++++++ .../gpu/drm/nouveau/nvkm/subdev/fsp/Kbuild | 1 + .../gpu/drm/nouveau/nvkm/subdev/fsp/gb202.c | 45 ++++++++++ .../gpu/drm/nouveau/nvkm/subdev/gsp/Kbuild | 1 + .../gpu/drm/nouveau/nvkm/subdev/gsp/gb202.c | 38 ++++++++ .../gpu/drm/nouveau/nvkm/subdev/gsp/rm/Kbuild | 1 + .../drm/nouveau/nvkm/subdev/gsp/rm/gb20x.c | 44 ++++++++++ .../gpu/drm/nouveau/nvkm/subdev/gsp/rm/gpu.h | 2 + .../nouveau/nvkm/subdev/gsp/rm/r535/fifo.c | 16 ++++ .../drm/nouveau/nvkm/subdev/gsp/rm/r570/rm.c | 16 ++++ .../gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h | 1 + 32 files changed, 393 insertions(+), 4 deletions(-) create mode 100644 drivers/gpu/drm/nouveau/include/nvhw/ref/gb10b/dev_fbhub.h create mode 100644 drivers/gpu/drm/nouveau/include/nvhw/ref/gb202/dev_ce.h create mode 100644 drivers/gpu/drm/nouveau/include/nvhw/ref/gb202/dev_therm.h create mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/ce/gb202.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/fifo/gb202.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/fb/gb202.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/fsp/gb202.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/gb202.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gb20x.c diff --git a/drivers/gpu/drm/nouveau/include/nvhw/ref/gb10b/dev_fbhub.h b/drivers/gpu/drm/nouveau/include/nvhw/ref/gb10b/dev_fbhub.h new file mode 100644 index 000000000000..4d0bb8e14298 --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvhw/ref/gb10b/dev_fbhub.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#ifndef __gb10b_dev_fb_h__ +#define __gb10b_dev_fb_h__ + +#define NV_PFB_FBHUB0_PCIE_FLUSH_SYSMEM_ADDR_LO 0x008a1d58 /* RW-4R */ +#define NV_PFB_FBHUB0_PCIE_FLUSH_SYSMEM_ADDR_LO_ADR 31:0 /* RWIVF */ +#define NV_PFB_FBHUB0_PCIE_FLUSH_SYSMEM_ADDR_LO_ADR_INIT 0x00000000 /* RWI-V */ +#define NV_PFB_FBHUB0_PCIE_FLUSH_SYSMEM_ADDR_LO_ADR_MASK 0xffffff00 /* RW--V */ +#define NV_PFB_FBHUB0_PCIE_FLUSH_SYSMEM_ADDR_HI 0x008a1d5c /* RW-4R */ +#define NV_PFB_FBHUB0_PCIE_FLUSH_SYSMEM_ADDR_HI_ADR 31:0 /* RWIVF */ +#define NV_PFB_FBHUB0_PCIE_FLUSH_SYSMEM_ADDR_HI_ADR_INIT 0x00000000 /* RWI-V */ +#define NV_PFB_FBHUB0_PCIE_FLUSH_SYSMEM_ADDR_HI_ADR_MASK 0x000fffff /* RW--V */ + +#endif // __gb10b_dev_fb_h__ + diff --git a/drivers/gpu/drm/nouveau/include/nvhw/ref/gb202/dev_ce.h b/drivers/gpu/drm/nouveau/include/nvhw/ref/gb202/dev_ce.h new file mode 100644 index 000000000000..b09f04b31738 --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvhw/ref/gb202/dev_ce.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#ifndef __gb202_dev_ce_h__ +#define __gb202_dev_ce_h__ + +#define NV_CE_GRCE_MASK 0x001040d8 /* C--4R */ +#define NV_CE_GRCE_MASK_VALUE 9:0 /* C--VF */ +#define NV_CE_GRCE_MASK_VALUE_INIT 0x00f /* C---V */ + +#endif // __gb202_dev_ce_h__ diff --git a/drivers/gpu/drm/nouveau/include/nvhw/ref/gb202/dev_therm.h b/drivers/gpu/drm/nouveau/include/nvhw/ref/gb202/dev_therm.h new file mode 100644 index 000000000000..ed359cb528fb --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvhw/ref/gb202/dev_therm.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#ifndef __gb202_dev_therm_h__ +#define __gb202_dev_therm_h__ + +#define NV_THERM_I2CS_SCRATCH 0x00ad00bc /* RW-4R */ +#define NV_THERM_I2CS_SCRATCH_DATA 31:0 /* RWIVF */ +#define NV_THERM_I2CS_SCRATCH_DATA_INIT 0x00000000 /* RWI-V */ +#define NV_THERM_I2CS_SCRATCH_FSP_BOOT_COMPLETE NV_THERM_I2CS_SCRATCH +#define NV_THERM_I2CS_SCRATCH_FSP_BOOT_COMPLETE_STATUS 31:0 +#define NV_THERM_I2CS_SCRATCH_FSP_BOOT_COMPLETE_STATUS_SUCCESS 0x000000FF +#define NV_THERM_I2CS_SCRATCH_FSP_BOOT_COMPLETE_STATUS_FAILED 0x00000000 + +#endif // __gb202_dev_therm_h__ + diff --git a/drivers/gpu/drm/nouveau/include/nvif/class.h b/drivers/gpu/drm/nouveau/include/nvif/class.h index 606483fc850b..ff6823cb2cd8 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/class.h +++ b/drivers/gpu/drm/nouveau/include/nvif/class.h @@ -65,6 +65,7 @@ #define TURING_USERMODE_A 0x0000c461 #define AMPERE_USERMODE_A 0x0000c561 #define HOPPER_USERMODE_A 0x0000c661 +#define BLACKWELL_USERMODE_A 0x0000c761 #define MAXWELL_FAULT_BUFFER_A /* clb069.h */ 0x0000b069 #define VOLTA_FAULT_BUFFER_A /* clb069.h */ 0x0000c369 @@ -89,6 +90,7 @@ #define AMPERE_CHANNEL_GPFIFO_B /* if0020.h */ 0x0000c76f #define HOPPER_CHANNEL_GPFIFO_A 0x0000c86f #define BLACKWELL_CHANNEL_GPFIFO_A 0x0000c96f +#define BLACKWELL_CHANNEL_GPFIFO_B 0x0000ca6f #define NV50_DISP /* if0010.h */ 0x00005070 #define G82_DISP /* if0010.h */ 0x00008270 @@ -106,8 +108,10 @@ #define TU102_DISP /* if0010.h */ 0x0000c570 #define GA102_DISP /* if0010.h */ 0x0000c670 #define AD102_DISP /* if0010.h */ 0x0000c770 +#define GB202_DISP 0x0000ca70 #define GV100_DISP_CAPS 0x0000c373 +#define GB202_DISP_CAPS 0x0000ca73 #define NV31_MPEG 0x00003174 #define G82_MPEG 0x00008274 @@ -122,6 +126,7 @@ #define GV100_DISP_CURSOR /* if0014.h */ 0x0000c37a #define TU102_DISP_CURSOR /* if0014.h */ 0x0000c57a #define GA102_DISP_CURSOR /* if0014.h */ 0x0000c67a +#define GB202_DISP_CURSOR 0x0000ca7a #define NV50_DISP_OVERLAY /* if0014.h */ 0x0000507b #define G82_DISP_OVERLAY /* if0014.h */ 0x0000827b @@ -132,6 +137,7 @@ #define GV100_DISP_WINDOW_IMM_CHANNEL_DMA /* if0014.h */ 0x0000c37b #define TU102_DISP_WINDOW_IMM_CHANNEL_DMA /* if0014.h */ 0x0000c57b #define GA102_DISP_WINDOW_IMM_CHANNEL_DMA /* if0014.h */ 0x0000c67b +#define GB202_DISP_WINDOW_IMM_CHANNEL_DMA 0x0000ca7b #define NV50_DISP_BASE_CHANNEL_DMA /* if0014.h */ 0x0000507c #define G82_DISP_BASE_CHANNEL_DMA /* if0014.h */ 0x0000827c @@ -157,6 +163,7 @@ #define TU102_DISP_CORE_CHANNEL_DMA /* if0014.h */ 0x0000c57d #define GA102_DISP_CORE_CHANNEL_DMA /* if0014.h */ 0x0000c67d #define AD102_DISP_CORE_CHANNEL_DMA /* if0014.h */ 0x0000c77d +#define GB202_DISP_CORE_CHANNEL_DMA 0x0000ca7d #define NV50_DISP_OVERLAY_CHANNEL_DMA /* if0014.h */ 0x0000507e #define G82_DISP_OVERLAY_CHANNEL_DMA /* if0014.h */ 0x0000827e @@ -168,6 +175,7 @@ #define GV100_DISP_WINDOW_CHANNEL_DMA /* if0014.h */ 0x0000c37e #define TU102_DISP_WINDOW_CHANNEL_DMA /* if0014.h */ 0x0000c57e #define GA102_DISP_WINDOW_CHANNEL_DMA /* if0014.h */ 0x0000c67e +#define GB202_DISP_WINDOW_CHANNEL_DMA 0x0000ca7e #define NV50_TESLA 0x00005097 #define G82_TESLA 0x00008297 @@ -201,6 +209,7 @@ #define HOPPER_A 0x0000cb97 #define BLACKWELL_A 0x0000cd97 +#define BLACKWELL_B 0x0000ce97 #define NV74_BSP 0x000074b0 @@ -210,6 +219,7 @@ #define NVC7B0_VIDEO_DECODER 0x0000c7b0 #define NVC9B0_VIDEO_DECODER 0x0000c9b0 #define NVCDB0_VIDEO_DECODER 0x0000cdb0 +#define NVCFB0_VIDEO_DECODER 0x0000cfb0 #define GT212_MSVLD 0x000085b1 #define IGT21A_MSVLD 0x000086b1 @@ -240,10 +250,12 @@ #define AMPERE_DMA_COPY_B 0x0000c7b5 #define HOPPER_DMA_COPY_A 0x0000c8b5 #define BLACKWELL_DMA_COPY_A 0x0000c9b5 +#define BLACKWELL_DMA_COPY_B 0x0000cab5 #define NVC4B7_VIDEO_ENCODER 0x0000c4b7 #define NVC7B7_VIDEO_ENCODER 0x0000c7b7 #define NVC9B7_VIDEO_ENCODER 0x0000c9b7 +#define NVCFB7_VIDEO_ENCODER 0x0000cfb7 #define FERMI_DECOMPRESS 0x000090b8 @@ -264,6 +276,7 @@ #define ADA_COMPUTE_A 0x0000c9c0 #define HOPPER_COMPUTE_A 0x0000cbc0 #define BLACKWELL_COMPUTE_A 0x0000cdc0 +#define BLACKWELL_COMPUTE_B 0x0000cec0 #define NV74_CIPHER 0x000074c1 @@ -271,10 +284,12 @@ #define NVC4D1_VIDEO_NVJPG 0x0000c4d1 #define NVC9D1_VIDEO_NVJPG 0x0000c9d1 #define NVCDD1_VIDEO_NVJPG 0x0000cdd1 +#define NVCFD1_VIDEO_NVJPG 0x0000cfd1 #define NVB8FA_VIDEO_OFA 0x0000b8fa #define NVC6FA_VIDEO_OFA 0x0000c6fa #define NVC7FA_VIDEO_OFA 0x0000c7fa #define NVC9FA_VIDEO_OFA 0x0000c9fa #define NVCDFA_VIDEO_OFA 0x0000cdfa +#define NVCFFA_VIDEO_OFA 0x0000cffa #endif diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/device.h b/drivers/gpu/drm/nouveau/include/nvkm/core/device.h index 0664195e5684..99579e7b9376 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/core/device.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/device.h @@ -49,6 +49,7 @@ struct nvkm_device { GH100 = 0x180, AD100 = 0x190, GB10x = 0x1a0, + GB20x = 0x1b0, } card_type; u32 chipset; u8 chiprev; diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h index 7bd73f9f749b..e0d777a933e1 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h @@ -104,6 +104,7 @@ int ga100_fb_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct n int ga102_fb_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fb **); int gh100_fb_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fb **); int gb100_fb_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fb **); +int gb202_fb_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fb **); #include <subdev/bios.h> #include <subdev/bios/ramcfg.h> diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/fsp.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/fsp.h index 7122f814e4d0..8a3dbb1cbb46 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/fsp.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/fsp.h @@ -20,4 +20,5 @@ int nvkm_fsp_boot_gsp_fmc(struct nvkm_fsp *, u64 args_addr, u32 rsvd_size, bool int gh100_fsp_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fsp **); int gb100_fsp_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fsp **); +int gb202_fsp_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fsp **); #endif diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h index c5982fd74725..226c7ec56b8e 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h @@ -493,4 +493,5 @@ int ga102_gsp_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_ int gh100_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 **); int gb100_gsp_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_gsp **); +int gb202_gsp_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_gsp **); #endif diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 1a9a74c26e8e..b96f0555ca14 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -1000,6 +1000,7 @@ nouveau_bo_move_init(struct nouveau_drm *drm) struct ttm_resource *, struct ttm_resource *); int (*init)(struct nouveau_channel *, u32 handle); } _methods[] = { + { "COPY", 4, 0xcab5, nve0_bo_move_copy, nve0_bo_move_init }, { "COPY", 4, 0xc9b5, nve0_bo_move_copy, nve0_bo_move_init }, { "COPY", 4, 0xc8b5, nve0_bo_move_copy, nve0_bo_move_init }, { "COPY", 4, 0xc7b5, nve0_bo_move_copy, nve0_bo_move_init }, diff --git a/drivers/gpu/drm/nouveau/nouveau_chan.c b/drivers/gpu/drm/nouveau/nouveau_chan.c index 726de0aa0fcf..b1e92b1f7a26 100644 --- a/drivers/gpu/drm/nouveau/nouveau_chan.c +++ b/drivers/gpu/drm/nouveau/nouveau_chan.c @@ -249,6 +249,7 @@ nouveau_channel_ctor(struct nouveau_cli *cli, bool priv, u64 runm, struct nouveau_channel **pchan) { const struct nvif_mclass hosts[] = { + { BLACKWELL_CHANNEL_GPFIFO_B, 0 }, { BLACKWELL_CHANNEL_GPFIFO_A, 0 }, { HOPPER_CHANNEL_GPFIFO_A, 0 }, { AMPERE_CHANNEL_GPFIFO_B, 0 }, diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index 0be604af5b29..0c82a63cd49d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -511,6 +511,7 @@ nouveau_accel_init(struct nouveau_drm *drm) case AMPERE_CHANNEL_GPFIFO_B: case HOPPER_CHANNEL_GPFIFO_A: case BLACKWELL_CHANNEL_GPFIFO_A: + case BLACKWELL_CHANNEL_GPFIFO_B: ret = gv100_fence_create(drm); break; default: diff --git a/drivers/gpu/drm/nouveau/nvif/user.c b/drivers/gpu/drm/nouveau/nvif/user.c index ae470a1fdfb8..53f03fa1c9c2 100644 --- a/drivers/gpu/drm/nouveau/nvif/user.c +++ b/drivers/gpu/drm/nouveau/nvif/user.c @@ -41,10 +41,11 @@ nvif_user_ctor(struct nvif_device *device, const char *name) int version; const struct nvif_user_func *func; } users[] = { - { HOPPER_USERMODE_A, -1, &nvif_userc361 }, - { AMPERE_USERMODE_A, -1, &nvif_userc361 }, - { TURING_USERMODE_A, -1, &nvif_userc361 }, - { VOLTA_USERMODE_A, -1, &nvif_userc361 }, + { BLACKWELL_USERMODE_A, -1, &nvif_userc361 }, + { HOPPER_USERMODE_A, -1, &nvif_userc361 }, + { AMPERE_USERMODE_A, -1, &nvif_userc361 }, + { TURING_USERMODE_A, -1, &nvif_userc361 }, + { VOLTA_USERMODE_A, -1, &nvif_userc361 }, {} }; int cid, ret; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/ce/Kbuild b/drivers/gpu/drm/nouveau/nvkm/engine/ce/Kbuild index 8bf1635ffabc..9754bac65df7 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/ce/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/engine/ce/Kbuild @@ -10,3 +10,4 @@ nvkm-y += nvkm/engine/ce/gv100.o nvkm-y += nvkm/engine/ce/tu102.o nvkm-y += nvkm/engine/ce/ga100.o nvkm-y += nvkm/engine/ce/ga102.o +nvkm-y += nvkm/engine/ce/gb202.o diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/ce/gb202.c b/drivers/gpu/drm/nouveau/nvkm/engine/ce/gb202.c new file mode 100644 index 000000000000..37c3c619c71b --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/engine/ce/gb202.c @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#include "priv.h" + +#include <nvhw/drf.h> +#include <nvhw/ref/gb202/dev_ce.h> + +u32 +gb202_ce_grce_mask(struct nvkm_device *device) +{ + u32 data = nvkm_rd32(device, NV_CE_GRCE_MASK); + + return NVVAL_GET(data, NV_CE, GRCE_MASK, VALUE); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/ce/priv.h b/drivers/gpu/drm/nouveau/nvkm/engine/ce/priv.h index 806a76a72249..34fd2657134b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/ce/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/ce/priv.h @@ -16,4 +16,6 @@ int ga100_ce_oneinit(struct nvkm_engine *); int ga100_ce_init(struct nvkm_engine *); int ga100_ce_fini(struct nvkm_engine *, bool); int ga100_ce_nonstall(struct nvkm_engine *); + +u32 gb202_ce_grce_mask(struct nvkm_device *); #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c index f6f23cbc7a73..3375a59ebf1a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c @@ -2832,6 +2832,86 @@ nv1a2_chipset = { .fifo = { 0x00000001, ga102_fifo_new }, }; +static const struct nvkm_device_chip +nv1b2_chipset = { + .name = "GB202", + .bar = { 0x00000001, tu102_bar_new }, + .fb = { 0x00000001, gb202_fb_new }, + .fsp = { 0x00000001, gb202_fsp_new }, + .gsp = { 0x00000001, gb202_gsp_new }, + .imem = { 0x00000001, gh100_instmem_new }, + .mmu = { 0x00000001, gh100_mmu_new }, + .pci = { 0x00000001, gh100_pci_new }, + .timer = { 0x00000001, gk20a_timer_new }, + .vfn = { 0x00000001, ga100_vfn_new }, + .disp = { 0x00000001, ga102_disp_new }, + .fifo = { 0x00000001, ga102_fifo_new }, +}; + +static const struct nvkm_device_chip +nv1b3_chipset = { + .name = "GB203", + .bar = { 0x00000001, tu102_bar_new }, + .fb = { 0x00000001, gb202_fb_new }, + .fsp = { 0x00000001, gb202_fsp_new }, + .gsp = { 0x00000001, gb202_gsp_new }, + .imem = { 0x00000001, gh100_instmem_new }, + .mmu = { 0x00000001, gh100_mmu_new }, + .pci = { 0x00000001, gh100_pci_new }, + .timer = { 0x00000001, gk20a_timer_new }, + .vfn = { 0x00000001, ga100_vfn_new }, + .disp = { 0x00000001, ga102_disp_new }, + .fifo = { 0x00000001, ga102_fifo_new }, +}; + +static const struct nvkm_device_chip +nv1b5_chipset = { + .name = "GB205", + .bar = { 0x00000001, tu102_bar_new }, + .fb = { 0x00000001, gb202_fb_new }, + .fsp = { 0x00000001, gb202_fsp_new }, + .gsp = { 0x00000001, gb202_gsp_new }, + .imem = { 0x00000001, gh100_instmem_new }, + .mmu = { 0x00000001, gh100_mmu_new }, + .pci = { 0x00000001, gh100_pci_new }, + .timer = { 0x00000001, gk20a_timer_new }, + .vfn = { 0x00000001, ga100_vfn_new }, + .disp = { 0x00000001, ga102_disp_new }, + .fifo = { 0x00000001, ga102_fifo_new }, +}; + +static const struct nvkm_device_chip +nv1b6_chipset = { + .name = "GB206", + .bar = { 0x00000001, tu102_bar_new }, + .fb = { 0x00000001, gb202_fb_new }, + .fsp = { 0x00000001, gb202_fsp_new }, + .gsp = { 0x00000001, gb202_gsp_new }, + .imem = { 0x00000001, gh100_instmem_new }, + .mmu = { 0x00000001, gh100_mmu_new }, + .pci = { 0x00000001, gh100_pci_new }, + .timer = { 0x00000001, gk20a_timer_new }, + .vfn = { 0x00000001, ga100_vfn_new }, + .disp = { 0x00000001, ga102_disp_new }, + .fifo = { 0x00000001, ga102_fifo_new }, +}; + +static const struct nvkm_device_chip +nv1b7_chipset = { + .name = "GB207", + .bar = { 0x00000001, tu102_bar_new }, + .fb = { 0x00000001, gb202_fb_new }, + .fsp = { 0x00000001, gb202_fsp_new }, + .gsp = { 0x00000001, gb202_gsp_new }, + .imem = { 0x00000001, gh100_instmem_new }, + .mmu = { 0x00000001, gh100_mmu_new }, + .pci = { 0x00000001, gh100_pci_new }, + .timer = { 0x00000001, gk20a_timer_new }, + .vfn = { 0x00000001, ga100_vfn_new }, + .disp = { 0x00000001, ga102_disp_new }, + .fifo = { 0x00000001, ga102_fifo_new }, +}; + struct nvkm_subdev * nvkm_device_subdev(struct nvkm_device *device, int type, int inst) { @@ -3150,6 +3230,7 @@ nvkm_device_ctor(const struct nvkm_device_func *func, case 0x180: device->card_type = GH100; break; case 0x190: device->card_type = AD100; break; case 0x1a0: device->card_type = GB10x; break; + case 0x1b0: device->card_type = GB20x; break; default: break; } @@ -3260,6 +3341,11 @@ nvkm_device_ctor(const struct nvkm_device_func *func, case 0x197: device->chip = &nv197_chipset; break; case 0x1a0: device->chip = &nv1a0_chipset; break; case 0x1a2: device->chip = &nv1a2_chipset; break; + case 0x1b2: device->chip = &nv1b2_chipset; break; + case 0x1b3: device->chip = &nv1b3_chipset; break; + case 0x1b5: device->chip = &nv1b5_chipset; break; + case 0x1b6: device->chip = &nv1b6_chipset; break; + case 0x1b7: device->chip = &nv1b7_chipset; break; default: if (nvkm_boolopt(device->cfgopt, "NvEnableUnsupportedChipsets", false)) { switch (device->chipset) { diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/user.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/user.c index 07f45cc16210..58191b7a0494 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/user.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/user.c @@ -150,6 +150,7 @@ nvkm_udevice_info(struct nvkm_udevice *udev, void *data, u32 size) case AD100: args->v0.family = NV_DEVICE_INFO_V0_ADA; break; case GH100: args->v0.family = NV_DEVICE_INFO_V0_HOPPER; break; case GB10x: args->v0.family = NV_DEVICE_INFO_V0_BLACKWELL; break; + case GB20x: args->v0.family = NV_DEVICE_INFO_V0_BLACKWELL; break; default: args->v0.family = 0; break; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/Kbuild b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/Kbuild index 5a074b9970ab..376e9c3bcb1a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/Kbuild @@ -25,6 +25,7 @@ nvkm-y += nvkm/engine/fifo/gv100.o nvkm-y += nvkm/engine/fifo/tu102.o nvkm-y += nvkm/engine/fifo/ga100.o nvkm-y += nvkm/engine/fifo/ga102.o +nvkm-y += nvkm/engine/fifo/gb202.o nvkm-y += nvkm/engine/fifo/ucgrp.o nvkm-y += nvkm/engine/fifo/uchan.o diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gb202.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gb202.c new file mode 100644 index 000000000000..b469e8afeb0b --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gb202.c @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#include "priv.h" +#include "cgrp.h" +#include "chan.h" +#include "runl.h" + +u32 +gb202_chan_doorbell_handle(struct nvkm_chan *chan) +{ + return BIT(30) | (chan->cgrp->runl->id << 16) | chan->id; +} diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/priv.h b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/priv.h index 9ebb35c31db0..5e81ae195329 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/priv.h @@ -208,6 +208,8 @@ extern const struct nvkm_engn_func ga100_engn_ce; extern const struct nvkm_cgrp_func ga100_cgrp; extern const struct nvkm_chan_func ga100_chan; +u32 gb202_chan_doorbell_handle(struct nvkm_chan *); + int nvkm_uchan_new(struct nvkm_fifo *, struct nvkm_cgrp *, const struct nvkm_oclass *, void *argv, u32 argc, struct nvkm_object **); int nvkm_ucgrp_new(struct nvkm_fifo *, const struct nvkm_oclass *, void *argv, u32 argc, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/Kbuild index b438a57f2efc..8d8a5382d1b1 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/Kbuild @@ -37,6 +37,7 @@ nvkm-y += nvkm/subdev/fb/ga100.o nvkm-y += nvkm/subdev/fb/ga102.o nvkm-y += nvkm/subdev/fb/gh100.o nvkm-y += nvkm/subdev/fb/gb100.o +nvkm-y += nvkm/subdev/fb/gb202.o nvkm-y += nvkm/subdev/fb/r535.o diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gb202.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gb202.c new file mode 100644 index 000000000000..848505026d02 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gb202.c @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#include "priv.h" + +#include <nvhw/drf.h> +#include <nvhw/ref/gb10b/dev_fbhub.h> + +static void +gb202_fb_sysmem_flush_page_init(struct nvkm_fb *fb) +{ + struct nvkm_device *device = fb->subdev.device; + const u64 addr = fb->sysmem.flush_page_addr; + + nvkm_wr32(device, NV_PFB_FBHUB0_PCIE_FLUSH_SYSMEM_ADDR_HI, upper_32_bits(addr)); + nvkm_wr32(device, NV_PFB_FBHUB0_PCIE_FLUSH_SYSMEM_ADDR_LO, lower_32_bits(addr)); +} + +static const struct nvkm_fb_func +gb202_fb = { + .sysmem.flush_page_init = gb202_fb_sysmem_flush_page_init, + .vidmem.size = ga102_fb_vidmem_size, +}; + +int +gb202_fb_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct nvkm_fb **pfb) +{ + return r535_fb_new(&gb202_fb, device, type, inst, pfb); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fsp/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/fsp/Kbuild index 337772acdddc..1a9ded3a86f8 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fsp/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fsp/Kbuild @@ -5,3 +5,4 @@ nvkm-y += nvkm/subdev/fsp/base.o nvkm-y += nvkm/subdev/fsp/gh100.o nvkm-y += nvkm/subdev/fsp/gb100.o +nvkm-y += nvkm/subdev/fsp/gb202.o diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fsp/gb202.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fsp/gb202.c new file mode 100644 index 000000000000..3438aac6383e --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fsp/gb202.c @@ -0,0 +1,45 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#include "priv.h" + +#include <nvhw/drf.h> +#include <nvhw/ref/gb202/dev_therm.h> + +static int +gb202_fsp_wait_secure_boot(struct nvkm_fsp *fsp) +{ + struct nvkm_device *device = fsp->subdev.device; + unsigned timeout_ms = 4000; + + do { + u32 status = NVKM_RD32(device, NV_THERM, I2CS_SCRATCH, FSP_BOOT_COMPLETE_STATUS); + + if (status == NV_THERM_I2CS_SCRATCH_FSP_BOOT_COMPLETE_STATUS_SUCCESS) + return 0; + + usleep_range(1000, 2000); + } while (timeout_ms--); + + return -ETIMEDOUT; +} + +static const struct nvkm_fsp_func +gb202_fsp = { + .wait_secure_boot = gb202_fsp_wait_secure_boot, + .cot = { + .version = 2, + .size_hash = 48, + .size_pkey = 97, + .size_sig = 96, + .boot_gsp_fmc = gh100_fsp_boot_gsp_fmc, + }, +}; + +int +gb202_fsp_new(struct nvkm_device *device, + enum nvkm_subdev_type type, int inst, struct nvkm_fsp **pfsp) +{ + return nvkm_fsp_new_(&gb202_fsp, device, type, inst, pfsp); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/Kbuild index 4aebea4f6a64..e9c948b67bbd 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/Kbuild @@ -10,5 +10,6 @@ nvkm-y += nvkm/subdev/gsp/ga102.o nvkm-y += nvkm/subdev/gsp/gh100.o nvkm-y += nvkm/subdev/gsp/ad102.o nvkm-y += nvkm/subdev/gsp/gb100.o +nvkm-y += nvkm/subdev/gsp/gb202.o include $(src)/nvkm/subdev/gsp/rm/Kbuild diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/gb202.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/gb202.c new file mode 100644 index 000000000000..c1d718172ddf --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/gb202.c @@ -0,0 +1,38 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#include "priv.h" + +static const struct nvkm_gsp_func +gb202_gsp = { + .flcn = &ga102_gsp_flcn, + + .sig_section = ".fwsignature_gb20x", + + .dtor = r535_gsp_dtor, + .oneinit = gh100_gsp_oneinit, + .init = gh100_gsp_init, + .fini = gh100_gsp_fini, + + .rm.gpu = &gb20x_gpu, +}; + +static struct nvkm_gsp_fwif +gb202_gsps[] = { + { 0, gh100_gsp_load, &gb202_gsp, &r570_rm_gb20x, "570.144", true }, + {} +}; + +int +gb202_gsp_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, + struct nvkm_gsp **pgsp) +{ + return nvkm_gsp_new_(gb202_gsps, device, type, inst, pgsp); +} + +NVKM_GSP_FIRMWARE_FMC(gb202, 570.144); +NVKM_GSP_FIRMWARE_FMC(gb203, 570.144); +NVKM_GSP_FIRMWARE_FMC(gb205, 570.144); +NVKM_GSP_FIRMWARE_FMC(gb206, 570.144); +NVKM_GSP_FIRMWARE_FMC(gb207, 570.144); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/Kbuild index 2efef4b694d6..04037394a2da 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/Kbuild @@ -13,6 +13,7 @@ nvkm-y += nvkm/subdev/gsp/rm/ga1xx.o nvkm-y += nvkm/subdev/gsp/rm/ad10x.o nvkm-y += nvkm/subdev/gsp/rm/gh100.o nvkm-y += nvkm/subdev/gsp/rm/gb10x.o +nvkm-y += nvkm/subdev/gsp/rm/gb20x.o include $(src)/nvkm/subdev/gsp/rm/r535/Kbuild include $(src)/nvkm/subdev/gsp/rm/r570/Kbuild diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gb20x.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gb20x.c new file mode 100644 index 000000000000..950471d9996e --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gb20x.c @@ -0,0 +1,44 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#include "gpu.h" + +#include <engine/ce/priv.h> +#include <engine/fifo/priv.h> + +#include <nvif/class.h> + +const struct nvkm_rm_gpu +gb20x_gpu = { + .disp.class = { + .root = GB202_DISP, + .caps = GB202_DISP_CAPS, + .core = GB202_DISP_CORE_CHANNEL_DMA, + .wndw = GB202_DISP_WINDOW_CHANNEL_DMA, + .wimm = GB202_DISP_WINDOW_IMM_CHANNEL_DMA, + .curs = GB202_DISP_CURSOR, + }, + + .usermode.class = BLACKWELL_USERMODE_A, + + .fifo.chan = { + .class = BLACKWELL_CHANNEL_GPFIFO_B, + .doorbell_handle = gb202_chan_doorbell_handle, + }, + + .ce = { + .class = BLACKWELL_DMA_COPY_B, + .grce_mask = gb202_ce_grce_mask, + }, + .gr.class = { + .i2m = BLACKWELL_INLINE_TO_MEMORY_A, + .twod = FERMI_TWOD_A, + .threed = BLACKWELL_B, + .compute = BLACKWELL_COMPUTE_B, + }, + .nvdec.class = NVCFB0_VIDEO_DECODER, + .nvenc.class = NVCFB7_VIDEO_ENCODER, + .nvjpg.class = NVCFD1_VIDEO_NVJPG, + .ofa.class = NVCFFA_VIDEO_OFA, +}; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gpu.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gpu.h index 77aa7b13a3af..46a6325641b7 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gpu.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gpu.h @@ -31,6 +31,7 @@ struct nvkm_rm_gpu { struct { u32 class; + u32 (*grce_mask)(struct nvkm_device *); } ce; struct { @@ -65,4 +66,5 @@ extern const struct nvkm_rm_gpu ga1xx_gpu; extern const struct nvkm_rm_gpu ad10x_gpu; extern const struct nvkm_rm_gpu gh100_gpu; extern const struct nvkm_rm_gpu gb10x_gpu; +extern const struct nvkm_rm_gpu gb20x_gpu; #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/fifo.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/fifo.c index eaba4d50860d..1ac5628c5140 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/fifo.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/fifo.c @@ -507,6 +507,22 @@ r535_fifo_runl_ctor(struct nvkm_fifo *fifo) continue; } + /* Skip SW engine - there's currently no support for NV SW classes. */ + if (type == NVKM_ENGINE_SW) + continue; + + /* Skip lone GRCEs (ones not paired with GR on a runlist), as they + * don't appear to function as async copy engines. + */ + if (type == NVKM_ENGINE_CE && + rm->gpu->ce.grce_mask && + (rm->gpu->ce.grce_mask(device) & BIT(inst)) && + !nvkm_runl_find_engn(engn, runl, engn->engine->subdev.type == NVKM_ENGINE_GR)) { + RUNL_DEBUG(runl, "skip LCE %d - GRCE without GR", inst); + nvkm_runl_del(runl); + continue; + } + ret = nvkm_rm_engine_new(gsp->rm, type, inst); if (ret) { nvkm_runl_del(runl); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/rm.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/rm.c index 7e5b411fa543..498658d0c60c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/rm.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/rm.c @@ -39,6 +39,16 @@ r570_wpr_libos3_gb10x = { .offset_set_by_acr = true, }; +static const struct nvkm_rm_wpr +r570_wpr_libos3_gb20x = { + .os_carveout_size = GSP_FW_HEAP_PARAM_OS_SIZE_LIBOS3_BAREMETAL, + .base_size = GSP_FW_HEAP_PARAM_BASE_RM_SIZE_GH100, + .heap_size_min = GSP_FW_HEAP_SIZE_OVERRIDE_LIBOS3_BAREMETAL_MIN_MB, + .heap_size_non_wpr = 0x220000, + .rsvd_size_pmu = ALIGN(0x0800000 + 0x1000000 + 0x0001000, 0x20000), + .offset_set_by_acr = true, +}; + static const struct nvkm_rm_api r570_api = { .gsp = &r570_gsp, @@ -81,3 +91,9 @@ r570_rm_gb10x = { .wpr = &r570_wpr_libos3_gb10x, .api = &r570_api, }; + +const struct nvkm_rm_impl +r570_rm_gb20x = { + .wpr = &r570_wpr_libos3_gb20x, + .api = &r570_api, +}; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h index 2e9bd74d39be..393ea775941f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h @@ -178,6 +178,7 @@ extern const struct nvkm_rm_impl r570_rm_tu102; extern const struct nvkm_rm_impl r570_rm_ga102; extern const struct nvkm_rm_impl r570_rm_gh100; extern const struct nvkm_rm_impl r570_rm_gb10x; +extern const struct nvkm_rm_impl r570_rm_gb20x; extern const struct nvkm_rm_api_gsp r570_gsp; extern const struct nvkm_rm_api_client r570_client; extern const struct nvkm_rm_api_fbsr r570_fbsr; -- 2.49.0
Ben Skeggs
2025-May-17 00:09 UTC
[PATCH v3 61/62] drm/dp: add option to disable zero sized address only transactions.
From: Dave Airlie <airlied at redhat.com> Some older NVIDIA and some newer NVIDIA hardware/firmware seems to have issues with address only transactions (firmware rejects them). Add an option to the core drm dp to avoid address only transactions, This just puts the MOT flag removal on the last message of the transfer and avoids the start of transfer transaction. This with the flag set in nouveau, allows eDP probing on GB203 device. Signed-off-by: Dave Airlie <airlied at redhat.com> Reviewed-by: Ben Skeggs <bskeggs at nvidia.com> Reviewed-by: Timur Tabi <ttabi at nvidia.com> Tested-by: Timur Tabi <ttabi at nvidia.com> --- drivers/gpu/drm/display/drm_dp_helper.c | 39 +++++++++++++++---------- include/drm/display/drm_dp_helper.h | 5 ++++ 2 files changed, 28 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/display/drm_dp_helper.c b/drivers/gpu/drm/display/drm_dp_helper.c index 57828f2b7b5a..55b8fd6aa9bf 100644 --- a/drivers/gpu/drm/display/drm_dp_helper.c +++ b/drivers/gpu/drm/display/drm_dp_helper.c @@ -2137,14 +2137,17 @@ static int drm_dp_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, for (i = 0; i < num; i++) { msg.address = msgs[i].addr; - drm_dp_i2c_msg_set_request(&msg, &msgs[i]); - /* Send a bare address packet to start the transaction. - * Zero sized messages specify an address only (bare - * address) transaction. - */ - msg.buffer = NULL; - msg.size = 0; - err = drm_dp_i2c_do_msg(aux, &msg); + + if (!aux->no_zero_sized) { + drm_dp_i2c_msg_set_request(&msg, &msgs[i]); + /* Send a bare address packet to start the transaction. + * Zero sized messages specify an address only (bare + * address) transaction. + */ + msg.buffer = NULL; + msg.size = 0; + err = drm_dp_i2c_do_msg(aux, &msg); + } /* * Reset msg.request in case in case it got @@ -2163,6 +2166,8 @@ static int drm_dp_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, msg.buffer = msgs[i].buf + j; msg.size = min(transfer_size, msgs[i].len - j); + if (j + msg.size == msgs[i].len && aux->no_zero_sized) + msg.request &= ~DP_AUX_I2C_MOT; err = drm_dp_i2c_drain_msg(aux, &msg); /* @@ -2180,15 +2185,17 @@ static int drm_dp_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, } if (err >= 0) err = num; - /* Send a bare address packet to close out the transaction. - * Zero sized messages specify an address only (bare - * address) transaction. - */ - msg.request &= ~DP_AUX_I2C_MOT; - msg.buffer = NULL; - msg.size = 0; - (void)drm_dp_i2c_do_msg(aux, &msg); + if (!aux->no_zero_sized) { + /* Send a bare address packet to close out the transaction. + * Zero sized messages specify an address only (bare + * address) transaction. + */ + msg.request &= ~DP_AUX_I2C_MOT; + msg.buffer = NULL; + msg.size = 0; + (void)drm_dp_i2c_do_msg(aux, &msg); + } return err; } diff --git a/include/drm/display/drm_dp_helper.h b/include/drm/display/drm_dp_helper.h index d9614e2c8939..4d03b591a755 100644 --- a/include/drm/display/drm_dp_helper.h +++ b/include/drm/display/drm_dp_helper.h @@ -518,6 +518,11 @@ struct drm_dp_aux { * @powered_down: If true then the remote endpoint is powered down. */ bool powered_down; + + /** + * @no_zero_sized: If the hw can't use zero sized transfers (NVIDIA) + */ + bool no_zero_sized; }; int drm_dp_dpcd_probe(struct drm_dp_aux *aux, unsigned int offset); -- 2.49.0
Timur Tabi
2025-May-18 20:55 UTC
[PATCH v3 00/62] add support for Hopper and Blackwell GPUs
On Sat, 2025-05-17 at 10:08 +1000, Ben Skeggs wrote:> A tree containing this series is available here[1], and a temporary > linux-firmware tree here[2].? Timur will send an official patch to > the linux-firmware tree once this series is closer to being merged.Good news: the firmware images are in the linux-firmware official repo already. https://gitlab.com/kernel-firmware/linux-firmware and https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git