Re: [PATCH v6 08/13] drm: nova: Add usable VRAM size to GPU info
From: Faith Ekstrand
Date: Mon Oct 19 2026 - 12:35:45 EST
On Wed, Sep 9, 2026 at 2:46 AM Alistair Popple <apopple@xxxxxxxxxx> 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 <apopple@xxxxxxxxxx>
>
> ---
>
> 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
>