NVIDIA GPU driver infrastructure
 help / color / mirror / Atom feed
From: Timur Tabi <ttabi@nvidia.com>
To: Danilo Krummrich <dakr@kernel.org>,
	Alexandre Courbot <acourbot@nvidia.com>,
	John Hubbard <jhubbard@nvidia.com>,
	Eliot Courtney <ecourtney@nvidia.com>, <nova-gpu@lists.linux.dev>
Subject: [PATCH 2/5] gpu: nova-core: merge LibosParams into GspFwHeapParams
Date: Tue, 10 Nov 2026 17:10:50 -0600	[thread overview]
Message-ID: <20261110231053.1352163-3-ttabi@nvidia.com> (raw)
In-Reply-To: <20261110231053.1352163-1-ttabi@nvidia.com>

LibosParams and GspFwHeapParams are two types used to hold data and/or
methods for calculating the heap sides that GSP-RM needs for booting.
Although they technically represent distinct parts of the equations,
they are always used together.

A future change to this code will introduce runtime calculations based
on values extracted from the GSP-RM, replacing the compile-time
constants currently used.  Merging the two types in this commit keeps
the current functionality while providing a foundation that simplifies
future changes.

For the same reason, the LIBOSx constants are replaced with variables.

Signed-off-by: Timur Tabi <ttabi@nvidia.com>
---
 drivers/gpu/nova-core/fb.rs     |   9 ++-
 drivers/gpu/nova-core/gsp.rs    |   4 +-
 drivers/gpu/nova-core/gsp/fw.rs | 119 +++++++++++++++++---------------
 3 files changed, 69 insertions(+), 63 deletions(-)

diff --git a/drivers/gpu/nova-core/fb.rs b/drivers/gpu/nova-core/fb.rs
index b0c0b8fe6008..9a3314768385 100644
--- a/drivers/gpu/nova-core/fb.rs
+++ b/drivers/gpu/nova-core/fb.rs
@@ -299,14 +299,13 @@ pub(crate) fn wpr2_range(bar: Bar0<'_>) -> Option<Range<u64>> {
 
 /// Computes the number of VF partitions and the WPR2 heap size from the vGPU state.
 fn wpr2_heap_params(chipset: Chipset, vgpu_state: VgpuState, fb_size: u64) -> Result<(u8, u64)> {
+    let heap_params = gsp::GspFwHeapParams::from_chipset(chipset);
+
     Ok(match vgpu_state {
-        VgpuState::Disabled => (
-            0,
-            gsp::LibosParams::from_chipset(chipset).wpr_heap_size(chipset, fb_size)?,
-        ),
+        VgpuState::Disabled => (0, heap_params.wpr_heap_size(fb_size)?),
         VgpuState::Enabled { total_vfs } => (
             u8::try_from(total_vfs.get()).map_err(|_| EINVAL)?,
-            gsp::LibosParams::vgpu_wpr_heap_size(),
+            heap_params.vgpu_wpr_heap_size(),
         ),
     })
 }
diff --git a/drivers/gpu/nova-core/gsp.rs b/drivers/gpu/nova-core/gsp.rs
index 908d4ea72ad1..85ef94a8b5c7 100644
--- a/drivers/gpu/nova-core/gsp.rs
+++ b/drivers/gpu/nova-core/gsp.rs
@@ -29,9 +29,9 @@
 
 pub(crate) use fw::{
     GspFmcBootParams,
+    GspFwHeapParams,
     GspFwWprMeta,
-    LibosMemoryRegionInitArgument,
-    LibosParams, //
+    LibosMemoryRegionInitArgument, //
 };
 pub(crate) use hal::boot_firmware_files;
 
diff --git a/drivers/gpu/nova-core/gsp/fw.rs b/drivers/gpu/nova-core/gsp/fw.rs
index c396daf06f1e..f30819fd89c2 100644
--- a/drivers/gpu/nova-core/gsp/fw.rs
+++ b/drivers/gpu/nova-core/gsp/fw.rs
@@ -65,26 +65,73 @@
 /// build-time constant, so the driver chooses it, and this constant is the one copy.
 pub(crate) const GSP_MSG_QUEUE_ELEMENT_SIZE_MAX: usize = GSP_PAGE_SIZE * 16;
 
-/// Empty type to group methods related to heap parameters for running the GSP firmware.
-enum GspFwHeapParams {}
+/// Heap memory requirements and constraints for booting GSP-RM.
+pub(crate) struct GspFwHeapParams {
+    /// The amount of heap memory used during GSP-RM boot and initialization (up to and including
+    /// the first client subdevice allocation), in bytes.
+    base_rm_size: u64,
+    /// The base amount of heap required by the GSP operating system, in bytes.
+    carveout_size: u64,
+    /// The minimum and maximum sizes allowed for the GSP FW heap, in bytes.
+    allowed_heap_size: Range<u64>,
+}
 
 /// Minimum required alignment for the GSP heap.
 const GSP_HEAP_ALIGNMENT: Alignment = Alignment::new::<{ 1 << 20 }>();
 
 impl GspFwHeapParams {
-    /// Returns the amount of GSP-RM heap memory used during GSP-RM boot and initialization (up to
-    /// and including the first client subdevice allocation).
-    fn base_rm_size(chipset: Chipset) -> u64 {
+    /// Version 2 of the GSP LIBOS (Turing and GA100)
+    fn libos2() -> Self {
+        Self {
+            base_rm_size: cv!(bindings::GSP_FW_HEAP_PARAM_BASE_RM_SIZE_TU10X),
+            carveout_size: cv!(bindings::GSP_FW_HEAP_PARAM_OS_SIZE_LIBOS2),
+            allowed_heap_size: cv!(bindings::GSP_FW_HEAP_SIZE_OVERRIDE_LIBOS2_MIN_MB => u64)
+                * u64::SZ_1M
+                ..cv!(bindings::GSP_FW_HEAP_SIZE_OVERRIDE_LIBOS2_MAX_MB => u64) * u64::SZ_1M,
+        }
+    }
+
+    /// Version 3 of the GSP LIBOS (GA102 - AD10x)
+    fn libos3() -> Self {
+        Self {
+            base_rm_size: cv!(bindings::GSP_FW_HEAP_PARAM_BASE_RM_SIZE_TU10X),
+            carveout_size: cv!(bindings::GSP_FW_HEAP_PARAM_OS_SIZE_LIBOS3_BAREMETAL),
+            allowed_heap_size: cv!(
+                bindings::GSP_FW_HEAP_SIZE_OVERRIDE_LIBOS3_BAREMETAL_MIN_MB => u64)
+                * u64::SZ_1M
+                ..cv!(bindings::GSP_FW_HEAP_SIZE_OVERRIDE_LIBOS3_BAREMETAL_MAX_MB => u64)
+                    * u64::SZ_1M,
+        }
+    }
+
+    /// Version 3 of the GSP LIBOS, (GH100+)
+    fn libos3_gh100() -> Self {
+        let base = Self::libos3();
+
+        Self {
+            base_rm_size: cv!(bindings::GSP_FW_HEAP_PARAM_BASE_RM_SIZE_GH100),
+            carveout_size: base.carveout_size,
+            allowed_heap_size: base.allowed_heap_size,
+        }
+    }
+
+    /// Returns the heap parameters corresponding to `chipset`.
+    ///
+    /// The parameters reported by GSP-RM are initialized to zero.
+    pub(crate) fn from_chipset(chipset: Chipset) -> Self {
         match chipset.arch() {
-            Architecture::Turing | Architecture::Ampere | Architecture::Ada => {
-                u64::from(bindings::GSP_FW_HEAP_PARAM_BASE_RM_SIZE_TU10X)
-            }
-            Architecture::Hopper | Architecture::BlackwellGB10x | Architecture::BlackwellGB20x => {
-                u64::from(bindings::GSP_FW_HEAP_PARAM_BASE_RM_SIZE_GH100)
-            }
+            Architecture::Turing => Self::libos2(),
+            Architecture::Ampere if chipset < Chipset::GA102 => Self::libos2(),
+            Architecture::Ampere | Architecture::Ada => Self::libos3(),
+            _ => Self::libos3_gh100(),
         }
     }
 
+    /// Returns the WPR heap size to reserve when vGPU is enabled.
+    pub(crate) fn vgpu_wpr_heap_size(&self) -> u64 {
+        u64::from(bindings::GSP_FW_HEAP_SIZE_VGPU_DEFAULT)
+    }
+
     /// Returns the amount of heap memory required to support a single channel allocation.
     fn client_alloc_size() -> u64 {
         u64::from(bindings::GSP_FW_HEAP_PARAM_CLIENT_ALLOC_SIZE)
@@ -103,60 +150,20 @@ fn management_overhead(fb_size: u64) -> Result<u64> {
             .align_up(GSP_HEAP_ALIGNMENT)
             .ok_or(EINVAL)
     }
-}
-
-/// Heap memory requirements and constraints for a given version of the GSP LIBOS.
-pub(crate) struct LibosParams {
-    /// The base amount of heap required by the GSP operating system, in bytes.
-    carveout_size: u64,
-    /// The minimum and maximum sizes allowed for the GSP FW heap, in bytes.
-    allowed_heap_size: Range<u64>,
-}
-
-impl LibosParams {
-    /// Version 2 of the GSP LIBOS (Turing and GA100)
-    const LIBOS2: LibosParams = LibosParams {
-        carveout_size: cv!(bindings::GSP_FW_HEAP_PARAM_OS_SIZE_LIBOS2),
-        allowed_heap_size: cv!(bindings::GSP_FW_HEAP_SIZE_OVERRIDE_LIBOS2_MIN_MB => u64)
-            * u64::SZ_1M
-            ..cv!(bindings::GSP_FW_HEAP_SIZE_OVERRIDE_LIBOS2_MAX_MB => u64) * u64::SZ_1M,
-    };
-
-    /// Version 3 of the GSP LIBOS (GA102+)
-    const LIBOS3: LibosParams = LibosParams {
-        carveout_size: cv!(bindings::GSP_FW_HEAP_PARAM_OS_SIZE_LIBOS3_BAREMETAL),
-        allowed_heap_size: cv!(bindings::GSP_FW_HEAP_SIZE_OVERRIDE_LIBOS3_BAREMETAL_MIN_MB => u64)
-            * u64::SZ_1M
-            ..cv!(bindings::GSP_FW_HEAP_SIZE_OVERRIDE_LIBOS3_BAREMETAL_MAX_MB => u64) * u64::SZ_1M,
-    };
-
-    /// Returns the libos parameters corresponding to `chipset`.
-    pub(crate) fn from_chipset(chipset: Chipset) -> &'static LibosParams {
-        if chipset < Chipset::GA102 {
-            &Self::LIBOS2
-        } else {
-            &Self::LIBOS3
-        }
-    }
-
-    /// Returns the WPR heap size to reserve when vGPU is enabled.
-    pub(crate) fn vgpu_wpr_heap_size() -> u64 {
-        u64::from(bindings::GSP_FW_HEAP_SIZE_VGPU_DEFAULT)
-    }
 
     /// Returns the amount of memory (in bytes) to allocate for the WPR heap for a framebuffer size
-    /// of `fb_size` (in bytes) for `chipset`.
-    pub(crate) fn wpr_heap_size(&self, chipset: Chipset, fb_size: u64) -> Result<u64> {
+    /// of `fb_size` (in bytes).
+    pub(crate) fn wpr_heap_size(&self, fb_size: u64) -> Result<u64> {
         // The WPR heap will contain the following:
         // LIBOS carveout,
         Ok(self
             .carveout_size
             // RM boot working memory,
-            .saturating_add(GspFwHeapParams::base_rm_size(chipset))
+            .saturating_add(self.base_rm_size)
             // One RM client,
-            .saturating_add(GspFwHeapParams::client_alloc_size())
+            .saturating_add(Self::client_alloc_size())
             // Overhead for memory management.
-            .saturating_add(GspFwHeapParams::management_overhead(fb_size)?)
+            .saturating_add(Self::management_overhead(fb_size)?)
             // Clamp to the supported heap sizes.
             .clamp(self.allowed_heap_size.start, self.allowed_heap_size.end - 1))
     }
-- 
2.54.0


  parent reply	other threads:[~2026-11-10 23:11 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-10 23:10 [PATCH 0/5] Transition nova-core to use TLV variables for heap sizes Timur Tabi
2026-11-10 23:10 ` [PATCH 1/5] gpu: nova-core: add Tlv.get_u64 Timur Tabi
2026-11-11  0:20   ` John Hubbard
2026-11-11  2:59     ` Timur Tabi
2026-11-11  3:45       ` John Hubbard
2026-11-11  5:21         ` Eliot Courtney
2026-11-11  5:27   ` Eliot Courtney
2026-11-10 23:10 ` Timur Tabi [this message]
2026-11-11  6:30   ` [PATCH 2/5] gpu: nova-core: merge LibosParams into GspFwHeapParams Eliot Courtney
2026-11-10 23:10 ` [PATCH 3/5] gpu: nova-core: read GSP heap variables from TLV Timur Tabi
2026-11-10 23:10 ` [PATCH 4/5] gpu: nova-core: use the TLV heap sizes Timur Tabi
2026-11-10 23:10 ` [PATCH 5/5] gpu: nova-core: remove heap size related HAL functions Timur Tabi
2026-11-10 23:21 ` [PATCH 0/5] Transition nova-core to use TLV variables for heap sizes Timur Tabi

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261110231053.1352163-3-ttabi@nvidia.com \
    --to=ttabi@nvidia.com \
    --cc=acourbot@nvidia.com \
    --cc=dakr@kernel.org \
    --cc=ecourtney@nvidia.com \
    --cc=jhubbard@nvidia.com \
    --cc=nova-gpu@lists.linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox