diff --git a/drivers/gpu/drm/nova/file.rs b/drivers/gpu/drm/nova/file.rs index 1c026f6c2f87..988f639af116 100644 --- a/drivers/gpu/drm/nova/file.rs +++ b/drivers/gpu/drm/nova/file.rs @@ -42,10 +42,12 @@ impl GpuInfo { /// another documented default instead. fn new(reg_data: &DrmRegData<'_>) -> Result { 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)) } 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) -> Result> { 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 190a14ea8189..fb6f8a86a503 100644 --- a/drivers/gpu/nova-core/gpu.rs +++ b/drivers/gpu/nova-core/gpu.rs @@ -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 ); } diff --git a/drivers/gpu/nova-core/gsp/commands.rs b/drivers/gpu/nova-core/gsp/commands.rs index e087c9e8c35c..c193149bc20e 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 { } /// 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; diff --git a/include/uapi/drm/nova_drm.h b/include/uapi/drm/nova_drm.h index 079da428164d..97be2b54ce9b 100644 --- a/include/uapi/drm/nova_drm.h +++ b/include/uapi/drm/nova_drm.h @@ -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