pub(crate) wpr2: FbRange,
pub(crate) heap: FbRange,
pub(crate) vf_partition_count: u8,
+ /// PMU reserved memory size, in bytes.
+ pub(crate) pmu_reserved_size: u32,
}
impl FbLayout {
wpr2,
heap,
vf_partition_count: 0,
+ pmu_reserved_size: hal.pmu_reserved_size(),
})
}
}
// SPDX-License-Identifier: GPL-2.0
+// SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
use kernel::prelude::*;
mod ga100;
mod ga102;
+mod gb100;
mod tu102;
pub(crate) trait FbHal {
/// Returns the VRAM size, in bytes.
fn vidmem_size(&self, bar: &Bar0) -> u64;
+ /// Returns the amount of VRAM to reserve for the PMU.
+ fn pmu_reserved_size(&self) -> u32;
+
/// Returns the FRTS size, in bytes.
fn frts_size(&self) -> u64;
}
match chipset.arch() {
Architecture::Turing => tu102::TU102_HAL,
Architecture::Ampere if chipset == Chipset::GA100 => ga100::GA100_HAL,
- Architecture::Ampere => ga102::GA102_HAL,
- Architecture::Ada
- | Architecture::Hopper
- | Architecture::BlackwellGB10x
- | Architecture::BlackwellGB20x => ga102::GA102_HAL,
+ Architecture::Ampere | Architecture::Ada | Architecture::Hopper => ga102::GA102_HAL,
+ Architecture::BlackwellGB10x | Architecture::BlackwellGB20x => gb100::GB100_HAL,
}
}
// SPDX-License-Identifier: GPL-2.0
+// SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
use kernel::{
io::Io,
super::tu102::vidmem_size_gp102(bar)
}
+ fn pmu_reserved_size(&self) -> u32 {
+ super::tu102::pmu_reserved_size_tu102()
+ }
+
// GA100 is a special case where its FRTS region exists, but is empty. We
// return a size of 0 because we still need to record where the region starts.
fn frts_size(&self) -> u64 {
// SPDX-License-Identifier: GPL-2.0
+// SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
use kernel::{
io::Io,
regs, //
};
-fn vidmem_size_ga102(bar: &Bar0) -> u64 {
+pub(super) fn vidmem_size_ga102(bar: &Bar0) -> u64 {
bar.read(regs::NV_USABLE_FB_SIZE_IN_MB).usable_fb_size()
}
vidmem_size_ga102(bar)
}
+ fn pmu_reserved_size(&self) -> u32 {
+ super::tu102::pmu_reserved_size_tu102()
+ }
+
fn frts_size(&self) -> u64 {
super::tu102::frts_size_tu102()
}
--- /dev/null
+// SPDX-License-Identifier: GPL-2.0
+// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+
+//! Blackwell framebuffer HAL.
+
+use kernel::{
+ prelude::*,
+ ptr::{
+ const_align_up,
+ Alignment, //
+ },
+ sizes::*, //
+};
+
+use crate::{
+ driver::Bar0,
+ fb::hal::FbHal,
+ num::usize_into_u32, //
+};
+
+struct Gb100;
+
+const fn pmu_reserved_size_gb100() -> u32 {
+ usize_into_u32::<{ const_align_up(SZ_8M + SZ_16M + SZ_4K, Alignment::new::<SZ_128K>()).unwrap() }>(
+ )
+}
+
+impl FbHal for Gb100 {
+ fn read_sysmem_flush_page(&self, bar: &Bar0) -> u64 {
+ super::ga100::read_sysmem_flush_page_ga100(bar)
+ }
+
+ fn write_sysmem_flush_page(&self, bar: &Bar0, addr: u64) -> Result {
+ super::ga100::write_sysmem_flush_page_ga100(bar, addr);
+
+ Ok(())
+ }
+
+ fn supports_display(&self, bar: &Bar0) -> bool {
+ super::ga100::display_enabled_ga100(bar)
+ }
+
+ fn vidmem_size(&self, bar: &Bar0) -> u64 {
+ super::ga102::vidmem_size_ga102(bar)
+ }
+
+ fn pmu_reserved_size(&self) -> u32 {
+ pmu_reserved_size_gb100()
+ }
+
+ fn frts_size(&self) -> u64 {
+ super::tu102::frts_size_tu102()
+ }
+}
+
+const GB100: Gb100 = Gb100;
+pub(super) const GB100_HAL: &dyn FbHal = &GB100;
// SPDX-License-Identifier: GPL-2.0
+// SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
use kernel::{
io::Io,
.usable_fb_size()
}
+pub(super) const fn pmu_reserved_size_tu102() -> u32 {
+ 0
+}
+
pub(super) const fn frts_size_tu102() -> u64 {
u64::SZ_1M
}
vidmem_size_gp102(bar)
}
+ fn pmu_reserved_size(&self) -> u32 {
+ pmu_reserved_size_tu102()
+ }
+
fn frts_size(&self) -> u64 {
frts_size_tu102()
}
fbSize: fb_layout.fb.end - fb_layout.fb.start,
vgaWorkspaceOffset: fb_layout.vga_workspace.start,
vgaWorkspaceSize: fb_layout.vga_workspace.end - fb_layout.vga_workspace.start,
+ pmuReservedSize: fb_layout.pmu_reserved_size,
..Zeroable::init_zeroed()
});