drm: nova: Add usable VRAM size to GPU info

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@nvidia.com>
Link: https://patch.msgid.link/20260909064506.910162-9-apopple@nvidia.com
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
This commit is contained in:
Alistair Popple 2026-09-09 16:45:01 +10:00 committed by Danilo Krummrich
parent ce6e59897b
commit d9886a1a06
5 changed files with 25 additions and 5 deletions

View File

@ -42,10 +42,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().into(),
chipid: spec.chipset.into(),
vram_size: gsp_static_info.vram_size(),
};
Ok(Self(info))
}

View File

@ -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

View File

@ -336,7 +336,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,
/// GPU memory manager owning memory management resources.
///
/// Must be kept declared *before* `gsp_resources`, so that its components are dropped while
@ -473,9 +473,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
);
}

View File

@ -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],
/// BAR1 Page Directory Entry base address.
pub(crate) bar1_pde_base: u64,
@ -268,6 +268,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;

View File

@ -182,6 +182,12 @@ struct drm_nova_info_gpu {
* See &enum drm_nova_chipid for currently known chips.
*/
__u32 chipid;
/**
* @vram_size: Amount of usable FB, excluding GSP carveouts and protected
* regions.
*/
__u64 vram_size;
};
#define DRM_NOVA_GETPARAM 0x00