To support the maximum vGPUs on devices that support vGPU, a larger
WPR2 heap size is required. On Ada with vGPU supported, the size should
be set to at least 581MB.
When vGPU support is enabled:
- Reserve a larger WPR2 heap size of 581MB.
- Set vf_partition_count to MAX_PARTITIONS_WITH_GFID_32VM (32) to
support the maximum number of virtual functions in the WPR2 meta,
or MAX_PARTITIONS_WITH_GFID (48) when total VFs exceeds 32.
When vGPU support is not enabled, the original heap size calculation and
partition count of 0 are preserved.
Cc: Alexandre Courbot <[email protected]>
Signed-off-by: Zhi Wang <[email protected]>
---
drivers/gpu/nova-core/fb.rs | 21 +++++++++++++++----
drivers/gpu/nova-core/gpu.rs | 13 +++++++++++-
drivers/gpu/nova-core/gsp.rs | 7 ++++++-
drivers/gpu/nova-core/gsp/boot.rs | 2 +-
drivers/gpu/nova-core/gsp/fw.rs | 6 ++++++
.../gpu/nova-core/gsp/fw/r570_144/bindings.rs | 4 ++++
drivers/gpu/nova-core/vgpu.rs | 2 +-
7 files changed, 47 insertions(+), 8 deletions(-)
diff --git a/drivers/gpu/nova-core/fb.rs b/drivers/gpu/nova-core/fb.rs
index 1a84a15581a4..2228b6b08699 100644
--- a/drivers/gpu/nova-core/fb.rs
+++ b/drivers/gpu/nova-core/fb.rs
@@ -181,7 +181,15 @@ pub(crate) struct FbLayout {
impl FbLayout {
/// Computes the FB layout for `chipset` required to run the `gsp_fw` GSP
firmware.
- pub(crate) fn new(chipset: Chipset, bar: &Bar0, gsp_fw: &GspFirmware) ->
Result<Self> {
+ ///
+ /// When `vf_partition_count` is non-zero, a larger WPR2 heap is reserved
to support
+ /// vGPU virtual functions: 1370 MiB for 48 partitions, 581 MiB for 32 or
fewer.
+ pub(crate) fn new(
+ chipset: Chipset,
+ bar: &Bar0,
+ gsp_fw: &GspFirmware,
+ vf_partition_count: u8,
+ ) -> Result<Self> {
let hal = hal::fb_hal(chipset);
let fb = {
@@ -243,8 +251,13 @@ pub(crate) fn new(chipset: Chipset, bar: &Bar0, gsp_fw:
&GspFirmware) -> Result<
let wpr2_heap = {
const WPR2_HEAP_DOWN_ALIGN: Alignment = Alignment::new::<SZ_1M>();
- let wpr2_heap_size =
- gsp::LibosParams::from_chipset(chipset).wpr_heap_size(chipset,
fb.end)?;
+ let wpr2_heap_size = if vf_partition_count == 0 {
+ gsp::LibosParams::from_chipset(chipset).wpr_heap_size(chipset,
fb.end)?
+ } else if vf_partition_count > gsp::MAX_PARTITIONS_WITH_GFID_32VM {
+ gsp::GSP_FW_HEAP_SIZE_VGPU_48VMS
+ } else {
+ gsp::GSP_FW_HEAP_SIZE_VGPU_DEFAULT
+ };
let wpr2_heap_addr = (elf.start -
wpr2_heap_size).align_down(WPR2_HEAP_DOWN_ALIGN);
FbRange(wpr2_heap_addr..(elf.start).align_down(WPR2_HEAP_DOWN_ALIGN))
@@ -272,7 +285,7 @@ pub(crate) fn new(chipset: Chipset, bar: &Bar0, gsp_fw:
&GspFirmware) -> Result<
wpr2_heap,
wpr2,
heap,
- vf_partition_count: 0,
+ vf_partition_count,
})
}
}
diff --git a/drivers/gpu/nova-core/gpu.rs b/drivers/gpu/nova-core/gpu.rs
index e1c16e1b9ec4..e254ddca0fa4 100644
--- a/drivers/gpu/nova-core/gpu.rs
+++ b/drivers/gpu/nova-core/gpu.rs
@@ -25,7 +25,9 @@
gfw,
gsp::{
Gsp,
- GspBootContext, //
+ GspBootContext,
+ MAX_PARTITIONS_WITH_GFID,
+ MAX_PARTITIONS_WITH_GFID_32VM, //
},
regs,
vgpu::Vgpu, //
@@ -389,6 +391,15 @@ pub(crate) fn new<'a>(
sec2_falcon,
fsp_falcon: None,
vgpu_requested: vgpu.vgpu_requested,
+ vf_partition_count: if vgpu.vgpu_requested {
+ if vgpu.total_vfs >
u16::from(MAX_PARTITIONS_WITH_GFID_32VM) {
+ MAX_PARTITIONS_WITH_GFID
+ } else {
+ MAX_PARTITIONS_WITH_GFID_32VM
+ }
+ } else {
+ 0
+ },
};
gsp.boot(&mut ctx)?;
vgpu.vgpu_enabled = ctx.vgpu_requested;
diff --git a/drivers/gpu/nova-core/gsp.rs b/drivers/gpu/nova-core/gsp.rs
index 9435c7430dfe..528f37e581c7 100644
--- a/drivers/gpu/nova-core/gsp.rs
+++ b/drivers/gpu/nova-core/gsp.rs
@@ -26,8 +26,12 @@
mod sequencer;
pub(crate) use fw::{
+ GSP_FW_HEAP_SIZE_VGPU_48VMS,
+ GSP_FW_HEAP_SIZE_VGPU_DEFAULT,
GspFwWprMeta,
- LibosParams, //
+ LibosParams,
+ MAX_PARTITIONS_WITH_GFID,
+ MAX_PARTITIONS_WITH_GFID_32VM, //
};
use crate::{
@@ -62,6 +66,7 @@ pub(crate) struct GspBootContext<'a> {
pub(crate) sec2_falcon: &'a Falcon<Sec2Falcon>,
pub(crate) fsp_falcon: Option<Falcon<FspFalcon>>,
pub(crate) vgpu_requested: bool,
+ pub(crate) vf_partition_count: u8,
}
impl GspBootContext<'_> {
diff --git a/drivers/gpu/nova-core/gsp/boot.rs
b/drivers/gpu/nova-core/gsp/boot.rs
index ed8729041d46..86b7a7aa8f5a 100644
--- a/drivers/gpu/nova-core/gsp/boot.rs
+++ b/drivers/gpu/nova-core/gsp/boot.rs
@@ -346,7 +346,7 @@ pub(crate) fn boot(
let dev = ctx.dev();
let gsp_fw = KBox::pin_init(GspFirmware::new(dev, chipset,
FIRMWARE_VERSION), GFP_KERNEL)?;
- let fb_layout = FbLayout::new(chipset, bar, &gsp_fw)?;
+ let fb_layout = FbLayout::new(chipset, bar, &gsp_fw,
ctx.vf_partition_count)?;
dev_dbg!(dev, "{:#x?}\n", fb_layout);
let wpr_meta = Coherent::<GspFwWprMeta>::zeroed(dev, GFP_KERNEL)?;
diff --git a/drivers/gpu/nova-core/gsp/fw.rs b/drivers/gpu/nova-core/gsp/fw.rs
index ca01ac3af9c6..b46ab6b921e3 100644
--- a/drivers/gpu/nova-core/gsp/fw.rs
+++ b/drivers/gpu/nova-core/gsp/fw.rs
@@ -454,6 +454,12 @@ enum GspFwHeapParams {}
/// Minimum required alignment for the GSP heap.
const GSP_HEAP_ALIGNMENT: Alignment = Alignment::new::<{ 1 << 20 }>();
+// vGPU constants from the bindings, re-exported for use by fb.rs and gpu.rs.
+pub(crate) const GSP_FW_HEAP_SIZE_VGPU_DEFAULT: u64 =
bindings::GSP_FW_HEAP_SIZE_VGPU_DEFAULT as u64;
+pub(crate) const GSP_FW_HEAP_SIZE_VGPU_48VMS: u64 =
bindings::GSP_FW_HEAP_SIZE_VGPU_48VMS as u64;
+pub(crate) const MAX_PARTITIONS_WITH_GFID: u8 =
bindings::MAX_PARTITIONS_WITH_GFID;
+pub(crate) const MAX_PARTITIONS_WITH_GFID_32VM: u8 =
bindings::MAX_PARTITIONS_WITH_GFID_32VM;
+
// These constants override the generated bindings for architecture-specific
heap sizing.
// See Open RM: kgspCalculateGspFwHeapSize and related functions.
//
diff --git a/drivers/gpu/nova-core/gsp/fw/r570_144/bindings.rs
b/drivers/gpu/nova-core/gsp/fw/r570_144/bindings.rs
index 354ee2cfa295..1273152266ad 100644
--- a/drivers/gpu/nova-core/gsp/fw/r570_144/bindings.rs
+++ b/drivers/gpu/nova-core/gsp/fw/r570_144/bindings.rs
@@ -40,6 +40,10 @@ fn fmt(&self, fmt: &mut ::core::fmt::Formatter<'_>) ->
::core::fmt::Result {
pub const GSP_FW_HEAP_SIZE_OVERRIDE_LIBOS2_MAX_MB: u32 = 256;
pub const GSP_FW_HEAP_SIZE_OVERRIDE_LIBOS3_BAREMETAL_MIN_MB: u32 = 88;
pub const GSP_FW_HEAP_SIZE_OVERRIDE_LIBOS3_BAREMETAL_MAX_MB: u32 = 280;
+pub const GSP_FW_HEAP_SIZE_VGPU_DEFAULT: u32 = 581 << 20;
+pub const GSP_FW_HEAP_SIZE_VGPU_48VMS: u32 = 1370 << 20;
+pub const MAX_PARTITIONS_WITH_GFID: u8 = 48;
+pub const MAX_PARTITIONS_WITH_GFID_32VM: u8 = 32;
pub const GSP_FW_WPR_META_REVISION: u32 = 1;
pub const GSP_FW_WPR_META_MAGIC: i64 = -2577556379034558285;
pub const REGISTRY_TABLE_ENTRY_TYPE_DWORD: u32 = 1;
diff --git a/drivers/gpu/nova-core/vgpu.rs b/drivers/gpu/nova-core/vgpu.rs
index d35081a088cf..5736eaa79654 100644
--- a/drivers/gpu/nova-core/vgpu.rs
+++ b/drivers/gpu/nova-core/vgpu.rs
@@ -14,7 +14,7 @@
pub(crate) struct Vgpu {
pub(crate) vgpu_requested: bool,
pub(crate) vgpu_enabled: bool,
- pub total_vfs: u16,
+ pub(crate) total_vfs: u16,
}
impl Vgpu {
--
2.51.0