On Wed, Sep 9, 2026 at 2:46 AM Alistair Popple <[email protected]> wrote:
>
> Add a field to the GPU info structure containing the total usable
> framebuffer size. The usable framebuffer excludes GSP carveouts and
> other protected regions, so it may differ from the BAR size and total
> physical VRAM.
>
> Signed-off-by: Alistair Popple <[email protected]>
>
> ---
>
> Changes since v5:
>
>  - Expose the GSP static info through a NovaCoreApi::gsp_static_info()
>    accessor and read the VRAM size from it rather than adding a
>    forwarding method, as suggested by Danilo
>
> Changes since v3:
>
>  - Partially new for v4 - previously a separate scalar GETPARAM
>    parameter
> ---
>  drivers/gpu/drm/nova/file.rs          |  2 ++
>  drivers/gpu/nova-core/api.rs          |  6 ++++++
>  drivers/gpu/nova-core/gpu.rs          |  6 ++----
>  drivers/gpu/nova-core/gsp/commands.rs | 10 +++++++++-
>  include/uapi/drm/nova_drm.h           |  6 ++++++
>  5 files changed, 25 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/gpu/drm/nova/file.rs b/drivers/gpu/drm/nova/file.rs
> index 4a65bec0fbce..d0ab3df6bcd2 100644
> --- a/drivers/gpu/drm/nova/file.rs
> +++ b/drivers/gpu/drm/nova/file.rs
> @@ -38,10 +38,12 @@ impl GpuInfo {
>      /// another documented default instead.
>      fn new(reg_data: &DrmRegData<'_>) -> Result<Self> {
>          let spec = reg_data.api.with(|api| api.get_ref().spec());
> +        let gsp_static_info = reg_data.api.with(|api| 
> api.get_ref().gsp_static_info());
>
>          let info = uapi::drm_nova_info_gpu {
>              architecture: spec.chipset.arch() as u32,
>              chipid: spec.chipset as u32,
> +            vram_size: gsp_static_info.vram_size(),
>          };
>          Ok(Self(info))
>      }
> diff --git a/drivers/gpu/nova-core/api.rs b/drivers/gpu/nova-core/api.rs
> index 876451dcc051..64f9ea442278 100644
> --- a/drivers/gpu/nova-core/api.rs
> +++ b/drivers/gpu/nova-core/api.rs
> @@ -15,6 +15,7 @@
>  pub use crate::gpu::Spec;
>
>  use crate::gpu::Gpu;
> +use crate::gsp::commands::GetGspStaticInfoReply;
>
>  /// API handle for the auxiliary bus child drivers to interact with 
> nova-core.
>  pub struct NovaCoreApi<'bound> {
> @@ -28,6 +29,11 @@ pub fn of(adev: &auxiliary::Device<Bound>) -> 
> Result<NovaCoreApiHandle<'_>> {
>          NovaCoreApiHandle::of(adev)
>      }
>
> +    /// Returns the GPU [`GetGspStaticInfoReply`].
> +    pub fn gsp_static_info(&self) -> &GetGspStaticInfoReply {
> +        &self.gpu.gsp_static_info
> +    }
> +
>      /// Returns the GPU [`Spec`].
>      pub fn spec(&self) -> &Spec {
>          &self.gpu.spec
> diff --git a/drivers/gpu/nova-core/gpu.rs b/drivers/gpu/nova-core/gpu.rs
> index 91db64dcaea7..b9fba3a79b1e 100644
> --- a/drivers/gpu/nova-core/gpu.rs
> +++ b/drivers/gpu/nova-core/gpu.rs
> @@ -301,7 +301,7 @@ struct GspResources<'gpu> {
>  pub(crate) struct Gpu<'gpu> {
>      pub(crate) spec: Spec,
>      /// Static GPU information as provided by the GSP.
> -    gsp_static_info: GetGspStaticInfoReply,
> +    pub(crate) gsp_static_info: GetGspStaticInfoReply,
>      /// GSP and its resources.
>      #[pin]
>      gsp_resources: GspResources<'gpu>,
> @@ -422,9 +422,7 @@ pub(crate) fn new<'a>(
>                      dev_dbg!(
>                          dev,
>                          "Total usable VRAM: {} MiB\n",
> -                        info.usable_fb_regions.iter().fold(0u64, |res, 
> region| res
> -                            .saturating_add(region.end - region.start))
> -                            / u64::SZ_1M
> +                        info.vram_size() / u64::SZ_1M
>                      );
>                  }
>
> diff --git a/drivers/gpu/nova-core/gsp/commands.rs 
> b/drivers/gpu/nova-core/gsp/commands.rs
> index ffc25fd8c47b..5c1f9d296198 100644
> --- a/drivers/gpu/nova-core/gsp/commands.rs
> +++ b/drivers/gpu/nova-core/gsp/commands.rs
> @@ -212,7 +212,7 @@ fn init(&self) -> impl Init<Self::Command, 
> Self::InitError> {
>  }
>
>  /// The reply from the GSP to the [`GetGspStaticInfo`] command.
> -pub(crate) struct GetGspStaticInfoReply {
> +pub struct GetGspStaticInfoReply {
>      gpu_name: [u8; 64],
>      /// Usable FB (VRAM) regions for driver memory allocation.
>      pub(crate) usable_fb_regions: KVec<Range<u64>>,
> @@ -261,6 +261,14 @@ pub(crate) fn gpu_name(&self) -> 
> core::result::Result<&str, GpuNameError> {
>              .to_str()
>              .map_err(GpuNameError::InvalidUtf8)
>      }
> +
> +    /// Returns the total usable VRAM size in bytes, i.e. the summed lengths 
> of all usable FB
> +    /// regions.
> +    pub fn vram_size(&self) -> u64 {
> +        self.usable_fb_regions.iter().fold(0, |size, region| {
> +            size.saturating_add(region.end - region.start)
> +        })
> +    }
>  }
>
>  pub(crate) use fw::commands::PowerStateLevel;
> diff --git a/include/uapi/drm/nova_drm.h b/include/uapi/drm/nova_drm.h
> index 26a5e7ca5425..946bd4bf8fbd 100644
> --- a/include/uapi/drm/nova_drm.h
> +++ b/include/uapi/drm/nova_drm.h
> @@ -180,6 +180,12 @@ struct drm_nova_info_gpu {
>          * currently known chips.
>          */
>         __u32 chipid;
> +
> +       /**
> +        * @vram_size: Amount of usable FB, excluding GSP carveouts and 
> protected
> +        * regions.

Does this also exclude the compression tag carve-out?

> +        */
> +       __u64 vram_size;
>  };
>
>  #define DRM_NOVA_GETPARAM              0x00
> --
> 2.54.0
>

Reply via email to