[PATCH v10 08/28] gpu: nova-core: Blackwell: calculate reserved FB heap size

John Hubbard
2026-04-11T02:50:21Z

Various "reserved" areas of FB (frame buffer: vidmem) have to be
calculated, because the GSP booting process needs this information.

PMU_RESERVED_SIZE is computed at compile time using const_align_up() and
applied only for Blackwell dGPU architectures. All other architectures
leave it at zero, matching Open RM behavior.

Signed-off-by: John Hubbard <jhubbard@nvidia.com>
---
drivers/gpu/nova-core/fb.rs | 38 ++++++++++++++++++++++++++++++---
drivers/gpu/nova-core/gsp/fw.rs | 1 +
2 files changed, 36 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/nova-core/fb.rs b/drivers/gpu/nova-core/fb.rs
index 35899e9b2560..c2005e4b4177 100644
--- a/drivers/gpu/nova-core/fb.rs
+++ b/drivers/gpu/nova-core/fb.rs
@@ -12,6 +12,7 @@
io::Io,
prelude::*,
ptr::{
+ const_align_up,
Alignable,
Alignment, //
},
@@ -22,10 +23,16 @@
use crate::{
driver::Bar0,
firmware::gsp::GspFirmware,
- gpu::Chipset,
+ gpu::{
+ Architecture,
+ Chipset, //
+ },
gsp,
- num::FromSafeCast,
- regs, //
+ num::{
+ usize_into_u32,
+ FromSafeCast, //
+ },
+ regs,
};

mod hal;
@@ -168,6 +175,8 @@ pub(crate) struct FbLayout {
pub(crate) wpr2: FbRange,
pub(crate) heap: FbRange,
pub(crate) vf_partition_count: u8,
+ /// PMU reserved memory size, in bytes.
+ pub(crate) pmu_reserved_size: u32,
}

impl FbLayout {
@@ -268,6 +277,29 @@ pub(crate) fn new(chipset: Chipset, bar: &Bar0, gsp_fw: &GspFirmware) -> Result<
wpr2,
heap,
vf_partition_count: 0,
+ pmu_reserved_size: match chipset.arch() {
+ Architecture::BlackwellGB10x | Architecture::BlackwellGB20x => PMU_RESERVED_SIZE,
+ _ => 0,
+ },
})
}
}
+
+/// Returns the PMU reserved memory size for `chipset`.
+#[expect(dead_code)]
+pub(crate) fn calc_pmu_reserved_size(chipset: Chipset) -> u32 {
+ match chipset.arch() {
+ Architecture::BlackwellGB10x | Architecture::BlackwellGB20x => PMU_RESERVED_SIZE,
+ _ => 0,
+ }
+}
+
+/// PMU reserved size, aligned to 128KB.
+pub(crate) const PMU_RESERVED_SIZE: u32 = usize_into_u32::<
+ {
+ match const_align_up(SZ_8M + SZ_16M + SZ_4K, Alignment::new::<SZ_128K>()) {
+ Some(v) => v,
+ None => panic!("PMU_RESERVED_SIZE: alignment overflow"),
+ }
+ },
+>();
diff --git a/drivers/gpu/nova-core/gsp/fw.rs b/drivers/gpu/nova-core/gsp/fw.rs
index 3245793bbe42..5d36604ea1a3 100644
--- a/drivers/gpu/nova-core/gsp/fw.rs
+++ b/drivers/gpu/nova-core/gsp/fw.rs
@@ -247,6 +247,7 @@ pub(crate) fn new<'a>(
fbSize: fb_layout.fb.end - fb_layout.fb.start,
vgaWorkspaceOffset: fb_layout.vga_workspace.start,
vgaWorkspaceSize: fb_layout.vga_workspace.end - fb_layout.vga_workspace.start,
+ pmuReservedSize: fb_layout.pmu_reserved_size,
..Zeroable::init_zeroed()
});

--
2.53.0