[RFC 08/29] nvkm/vgpu: get the size VMMU segment from GSP firmware

Zhi Wang
2024-09-22T12:50:38Z

The allocation of FBMEM for vGPUs requires to be aligned with the size of
VMMU segment. Before reserving the FBMEM for vGPUs, the size of VMMU
segment must be known.

Send a GSP RM control to get VMMU segment size from GSP firmware in vGPU
support initalization.

Signed-off-by: Zhi Wang <zhiw@nvidia.com>
---
.../nouveau/include/nvkm/vgpu_mgr/vgpu_mgr.h | 2 ++
.../nvidia/inc/ctrl/ctrl2080/ctrl2080gpu.h | 12 ++++++++
.../gpu/drm/nouveau/nvkm/vgpu_mgr/vgpu_mgr.c | 30 +++++++++++++++++++
3 files changed, 44 insertions(+)

diff --git a/drivers/gpu/drm/nouveau/include/nvkm/vgpu_mgr/vgpu_mgr.h b/drivers/gpu/drm/nouveau/include/nvkm/vgpu_mgr/vgpu_mgr.h
index 6bc10fa40cde..aaba6d9a88b4 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/vgpu_mgr/vgpu_mgr.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/vgpu_mgr/vgpu_mgr.h
@@ -15,6 +15,8 @@ struct nvkm_vgpu_mgr {

const struct nvif_device_impl *dev_impl;
struct nvif_device_priv *dev_priv;
+
+ u64 vmmu_segment_size;
};

bool nvkm_vgpu_mgr_is_supported(struct nvkm_device *device);
diff --git a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl2080/ctrl2080gpu.h b/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl2080/ctrl2080gpu.h
index 29d7a1052142..4d57d8664ee5 100644
--- a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl2080/ctrl2080gpu.h
+++ b/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl2080/ctrl2080gpu.h
@@ -97,4 +97,16 @@ typedef struct NV2080_CTRL_GPU_GET_GID_INFO_PARAMS {
NvU8 data[NV2080_GPU_MAX_GID_LENGTH];
} NV2080_CTRL_GPU_GET_GID_INFO_PARAMS;

+#define NV2080_CTRL_CMD_GPU_GET_VMMU_SEGMENT_SIZE (0x2080017e)
+
+typedef struct NV2080_CTRL_GPU_GET_VMMU_SEGMENT_SIZE_PARAMS {
+ NV_DECLARE_ALIGNED(NvU64 vmmuSegmentSize, 8);
+} NV2080_CTRL_GPU_GET_VMMU_SEGMENT_SIZE_PARAMS;
+
+#define NV2080_CTRL_GPU_VMMU_SEGMENT_SIZE_32MB 0x02000000U
+#define NV2080_CTRL_GPU_VMMU_SEGMENT_SIZE_64MB 0x04000000U
+#define NV2080_CTRL_GPU_VMMU_SEGMENT_SIZE_128MB 0x08000000U
+#define NV2080_CTRL_GPU_VMMU_SEGMENT_SIZE_256MB 0x10000000U
+#define NV2080_CTRL_GPU_VMMU_SEGMENT_SIZE_512MB 0x20000000U
+
#endif
diff --git a/drivers/gpu/drm/nouveau/nvkm/vgpu_mgr/vgpu_mgr.c b/drivers/gpu/drm/nouveau/nvkm/vgpu_mgr/vgpu_mgr.c
index d6ddb1f02275..d2ea5a07cbfc 100644
--- a/drivers/gpu/drm/nouveau/nvkm/vgpu_mgr/vgpu_mgr.c
+++ b/drivers/gpu/drm/nouveau/nvkm/vgpu_mgr/vgpu_mgr.c
@@ -4,6 +4,8 @@
#include <nvif/driverif.h>
#include <core/pci.h>

+#include <subdev/gsp.h>
+
#include <nvrm/nvtypes.h>
#include <nvrm/535.113.01/nvidia/inc/kernel/gpu/gsp/gsp_static_config.h>

@@ -86,6 +88,26 @@ static int attach_nvkm(struct nvkm_vgpu_mgr *vgpu_mgr)
return ret;
}

+static int get_vmmu_segment_size(struct nvkm_vgpu_mgr *mgr)
+{
+ struct nvkm_device *device = mgr->nvkm_dev;
+ struct nvkm_gsp *gsp = device->gsp;
+ NV2080_CTRL_GPU_GET_VMMU_SEGMENT_SIZE_PARAMS *ctrl;
+
+ ctrl = nvkm_gsp_rm_ctrl_rd(&gsp->internal.device.subdevice,
+ NV2080_CTRL_CMD_GPU_GET_VMMU_SEGMENT_SIZE,
+ sizeof(*ctrl));
+ if (IS_ERR(ctrl))
+ return PTR_ERR(ctrl);
+
+ nvdev_debug(device, "VMMU segment size: %llx\n", ctrl->vmmuSegmentSize);
+
+ mgr->vmmu_segment_size = ctrl->vmmuSegmentSize;
+
+ nvkm_gsp_rm_ctrl_done(&gsp->internal.device.subdevice, ctrl);
+ return 0;
+}
+
/**
* nvkm_vgpu_mgr_init - Initialize the vGPU manager support
* @device: the nvkm_device pointer
@@ -106,11 +128,19 @@ int nvkm_vgpu_mgr_init(struct nvkm_device *device)
if (ret)
return ret;

+ ret = get_vmmu_segment_size(vgpu_mgr);
+ if (ret)
+ goto err_get_vmmu_seg_size;
+
vgpu_mgr->enabled = true;
pci_info(nvkm_to_pdev(device),
"NVIDIA vGPU mananger support is enabled.\n");

return 0;
+
+err_get_vmmu_seg_size:
+ detach_nvkm(vgpu_mgr);
+ return ret;
}

/**
--
2.34.1