gpu: nova-core: Move PFB registers definitions

Move PFB registers definitions into fb module and update registers
visibility.

Suggested-by: Alexandre Courbot <acourbot@nvidia.com>
Suggested-by: Danilo Krummrich <dakr@kernel.org>
Signed-off-by: Antonin Malzieu Ridolfi <dev@nanonej.com>
Link: https://patch.msgid.link/20260727-nova-core-regs-split-v2-2-21b5e6e32ea5@nanonej.com
Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
This commit is contained in:
Antonin Malzieu Ridolfi
2026-07-27 17:51:52 +02:00
committed by Alexandre Courbot
parent 7c9953b868
commit 81aa6f190a
8 changed files with 155 additions and 142 deletions

View File

@@ -293,13 +293,13 @@ pub(crate) fn new(
/// Reads the WPR2 memory region registers and returns the range if set.
/// Returns `None` if the WPR2 region is not set.
pub(crate) fn wpr2_range(bar: Bar0<'_>) -> Option<Range<u64>> {
let wpr2_hi = bar.read(crate::regs::NV_PFB_PRI_MMU_WPR2_ADDR_HI);
let wpr2_hi = bar.read(regs::NV_PFB_PRI_MMU_WPR2_ADDR_HI);
if !wpr2_hi.is_wpr2_set() {
return None;
}
let wpr2_lo = bar.read(crate::regs::NV_PFB_PRI_MMU_WPR2_ADDR_LO);
let wpr2_lo = bar.read(regs::NV_PFB_PRI_MMU_WPR2_ADDR_LO);
Some(wpr2_lo.lower_bound()..wpr2_hi.higher_bound())
}

View File

@@ -9,8 +9,10 @@
use crate::{
driver::Bar0,
fb::hal::FbHal,
regs, //
fb::{
hal::FbHal,
regs, //
},
};
use super::tu102::FLUSH_SYSMEM_ADDR_SHIFT;
@@ -41,7 +43,7 @@ pub(super) fn write_sysmem_flush_page_ga100(bar: Bar0<'_>, addr: u64) {
}
pub(super) fn display_enabled_ga100(bar: Bar0<'_>) -> bool {
!bar.read(regs::ga100::NV_FUSE_STATUS_OPT_DISPLAY)
!bar.read(crate::regs::ga100::NV_FUSE_STATUS_OPT_DISPLAY)
.display_disabled()
}

View File

@@ -22,9 +22,11 @@
use crate::{
driver::Bar0,
fb::hal::FbHal,
fb::{
hal::FbHal,
regs, //
},
num::usize_into_u32,
regs, //
};
struct Gb100;

View File

@@ -12,8 +12,10 @@
use crate::{
driver::Bar0,
fb::hal::FbHal,
regs, //
fb::{
hal::FbHal,
regs, //
},
};
struct Gb202;

View File

@@ -10,8 +10,10 @@
use crate::{
driver::Bar0,
fb::hal::FbHal,
regs, //
fb::{
hal::FbHal,
regs, //
},
};
struct Gh100;

View File

@@ -9,8 +9,10 @@
use crate::{
driver::Bar0,
fb::hal::FbHal,
regs, //
fb::{
hal::FbHal,
regs, //
},
};
/// Shift applied to the sysmem address before it is written into `NV_PFB_NISO_FLUSH_SYSMEM_ADDR`,
@@ -31,7 +33,7 @@ pub(super) fn write_sysmem_flush_page_gm107(bar: Bar0<'_>, addr: u64) -> Result
}
pub(super) fn display_enabled_gm107(bar: Bar0<'_>) -> bool {
!bar.read(regs::gm107::NV_FUSE_STATUS_OPT_DISPLAY)
!bar.read(crate::regs::gm107::NV_FUSE_STATUS_OPT_DISPLAY)
.display_disabled()
}

View File

@@ -1,6 +1,9 @@
// SPDX-License-Identifier: GPL-2.0
use kernel::io::register;
use kernel::{
io::register,
sizes::SizeConstants, //
};
// PDISP
@@ -23,3 +26,130 @@ pub(super) fn vga_workspace_addr(self) -> Option<u64> {
}
}
}
// PFB
register! {
/// Low bits of the physical system memory address used by the GPU to perform sysmembar
/// operations (see [`crate::fb::SysmemFlush`]).
pub(super) NV_PFB_NISO_FLUSH_SYSMEM_ADDR(u32) @ 0x00100c10 {
31:0 adr_39_08;
}
/// High bits of the physical system memory address used by the GPU to perform sysmembar
/// operations.
pub(super) NV_PFB_NISO_FLUSH_SYSMEM_ADDR_HI(u32) @ 0x00100c40 {
23:0 adr_63_40;
}
pub(super) NV_PFB_PRI_MMU_LOCAL_MEMORY_RANGE(u32) @ 0x00100ce0 {
30:30 ecc_mode_enabled => bool;
9:4 lower_mag;
3:0 lower_scale;
}
pub(super) NV_PFB_PRI_MMU_WPR2_ADDR_LO(u32) @ 0x001fa824 {
/// Bits 12..40 of the lower (inclusive) bound of the WPR2 region.
31:4 lo_val;
}
pub(super) NV_PFB_PRI_MMU_WPR2_ADDR_HI(u32) @ 0x001fa828 {
/// Bits 12..40 of the higher (exclusive) bound of the WPR2 region.
31:4 hi_val;
}
}
/// Base of the GB10x HSHUB0 register window (`NV_HSHUB0_PRIV_BASE` in Open RM).
///
/// The base is provided by the GB10x framebuffer HAL.
pub(super) struct Hshub0Base(());
register! {
// GB10x sysmem flush registers, relative to the HSHUB0 base. GB10x routes sysmembar
// through a primary and an EG (egress) pair that must both be programmed to the same
// address. Hardware ignores bits 7:0 of each LO register. The boot path uses a fixed
// HSHUB0 base, so the multiple runtime-discovered HSHUB bases are not needed here.
pub(super) NV_PFB_HSHUB_PCIE_FLUSH_SYSMEM_ADDR_LO(u32) @ Hshub0Base + 0x00000e50 {
31:0 adr => u32;
}
pub(super) NV_PFB_HSHUB_PCIE_FLUSH_SYSMEM_ADDR_HI(u32) @ Hshub0Base + 0x00000e54 {
19:0 adr;
}
pub(super) NV_PFB_HSHUB_EG_PCIE_FLUSH_SYSMEM_ADDR_LO(u32) @ Hshub0Base + 0x000006c0 {
31:0 adr => u32;
}
pub(super) NV_PFB_HSHUB_EG_PCIE_FLUSH_SYSMEM_ADDR_HI(u32) @ Hshub0Base + 0x000006c4 {
19:0 adr;
}
}
register! {
// GB20x FBHUB0 sysmem flush registers. Unlike the older
// NV_PFB_NISO_FLUSH_SYSMEM_ADDR registers, which encode the address with an
// 8-bit right-shift, these take the raw address split into lower and upper
// halves. Hardware ignores bits 7:0 of the LO register.
pub(super) NV_PFB_FBHUB0_PCIE_FLUSH_SYSMEM_ADDR_LO(u32) @ 0x008a1d58 {
31:0 adr => u32;
}
pub(super) NV_PFB_FBHUB0_PCIE_FLUSH_SYSMEM_ADDR_HI(u32) @ 0x008a1d5c {
19:0 adr;
}
}
register! {
/// Low bits of the physical system memory address used by the GPU to perform
/// sysmembar operations on Hopper.
///
/// Like the GB20x FBHUB0 registers, and unlike the Ampere
/// `NV_PFB_NISO_FLUSH_SYSMEM_ADDR` registers (which encode the address with an
/// 8-bit right-shift), these take the raw address split into lower and upper
/// halves. Hardware ignores bits 7:0 of the LO register.
pub(super) NV_PFB_FBHUB_PCIE_FLUSH_SYSMEM_ADDR_LO(u32) @ 0x00100a34 {
31:0 adr => u32;
}
/// High bits of the physical system memory address used by the GPU to perform
/// sysmembar operations on Hopper.
pub(super) NV_PFB_FBHUB_PCIE_FLUSH_SYSMEM_ADDR_HI(u32) @ 0x00100a38 {
19:0 adr;
}
}
impl NV_PFB_PRI_MMU_LOCAL_MEMORY_RANGE {
/// Returns the usable framebuffer size, in bytes.
pub(super) fn usable_fb_size(self) -> u64 {
let size = (u64::from(self.lower_mag()) << u64::from(self.lower_scale())) * u64::SZ_1M;
if self.ecc_mode_enabled() {
// Remove the amount of memory reserved for ECC (one per 16 units).
size / 16 * 15
} else {
size
}
}
}
impl NV_PFB_PRI_MMU_WPR2_ADDR_LO {
/// Returns the lower (inclusive) bound of the WPR2 region.
pub(super) fn lower_bound(self) -> u64 {
u64::from(self.lo_val()) << 12
}
}
impl NV_PFB_PRI_MMU_WPR2_ADDR_HI {
/// Returns the higher (exclusive) bound of the WPR2 region.
///
/// A value of zero means the WPR2 region is not set.
pub(super) fn higher_bound(self) -> u64 {
u64::from(self.hi_val()) << 12
}
/// Returns whether the WPR2 region is currently set.
pub(super) fn is_wpr2_set(self) -> bool {
self.hi_val() != 0
}
}

View File

@@ -116,133 +116,6 @@ fn fmt(&self, f: &mut kernel::fmt::Formatter<'_>) -> kernel::fmt::Result {
}
}
// PFB
register! {
/// Low bits of the physical system memory address used by the GPU to perform sysmembar
/// operations (see [`crate::fb::SysmemFlush`]).
pub(crate) NV_PFB_NISO_FLUSH_SYSMEM_ADDR(u32) @ 0x00100c10 {
31:0 adr_39_08;
}
/// High bits of the physical system memory address used by the GPU to perform sysmembar
/// operations.
pub(crate) NV_PFB_NISO_FLUSH_SYSMEM_ADDR_HI(u32) @ 0x00100c40 {
23:0 adr_63_40;
}
pub(crate) NV_PFB_PRI_MMU_LOCAL_MEMORY_RANGE(u32) @ 0x00100ce0 {
30:30 ecc_mode_enabled => bool;
9:4 lower_mag;
3:0 lower_scale;
}
pub(crate) NV_PFB_PRI_MMU_WPR2_ADDR_LO(u32) @ 0x001fa824 {
/// Bits 12..40 of the lower (inclusive) bound of the WPR2 region.
31:4 lo_val;
}
pub(crate) NV_PFB_PRI_MMU_WPR2_ADDR_HI(u32) @ 0x001fa828 {
/// Bits 12..40 of the higher (exclusive) bound of the WPR2 region.
31:4 hi_val;
}
}
/// Base of the GB10x HSHUB0 register window (`NV_HSHUB0_PRIV_BASE` in Open RM).
///
/// The base is provided by the GB10x framebuffer HAL.
pub(crate) struct Hshub0Base(());
register! {
// GB10x sysmem flush registers, relative to the HSHUB0 base. GB10x routes sysmembar
// through a primary and an EG (egress) pair that must both be programmed to the same
// address. Hardware ignores bits 7:0 of each LO register. The boot path uses a fixed
// HSHUB0 base, so the multiple runtime-discovered HSHUB bases are not needed here.
pub(crate) NV_PFB_HSHUB_PCIE_FLUSH_SYSMEM_ADDR_LO(u32) @ Hshub0Base + 0x00000e50 {
31:0 adr => u32;
}
pub(crate) NV_PFB_HSHUB_PCIE_FLUSH_SYSMEM_ADDR_HI(u32) @ Hshub0Base + 0x00000e54 {
19:0 adr;
}
pub(crate) NV_PFB_HSHUB_EG_PCIE_FLUSH_SYSMEM_ADDR_LO(u32) @ Hshub0Base + 0x000006c0 {
31:0 adr => u32;
}
pub(crate) NV_PFB_HSHUB_EG_PCIE_FLUSH_SYSMEM_ADDR_HI(u32) @ Hshub0Base + 0x000006c4 {
19:0 adr;
}
}
register! {
// GB20x FBHUB0 sysmem flush registers. Unlike the older
// NV_PFB_NISO_FLUSH_SYSMEM_ADDR registers, which encode the address with an
// 8-bit right-shift, these take the raw address split into lower and upper
// halves. Hardware ignores bits 7:0 of the LO register.
pub(crate) NV_PFB_FBHUB0_PCIE_FLUSH_SYSMEM_ADDR_LO(u32) @ 0x008a1d58 {
31:0 adr => u32;
}
pub(crate) NV_PFB_FBHUB0_PCIE_FLUSH_SYSMEM_ADDR_HI(u32) @ 0x008a1d5c {
19:0 adr;
}
}
register! {
/// Low bits of the physical system memory address used by the GPU to perform
/// sysmembar operations on Hopper.
///
/// Like the GB20x FBHUB0 registers, and unlike the Ampere
/// `NV_PFB_NISO_FLUSH_SYSMEM_ADDR` registers (which encode the address with an
/// 8-bit right-shift), these take the raw address split into lower and upper
/// halves. Hardware ignores bits 7:0 of the LO register.
pub(crate) NV_PFB_FBHUB_PCIE_FLUSH_SYSMEM_ADDR_LO(u32) @ 0x00100a34 {
31:0 adr => u32;
}
/// High bits of the physical system memory address used by the GPU to perform
/// sysmembar operations on Hopper.
pub(crate) NV_PFB_FBHUB_PCIE_FLUSH_SYSMEM_ADDR_HI(u32) @ 0x00100a38 {
19:0 adr;
}
}
impl NV_PFB_PRI_MMU_LOCAL_MEMORY_RANGE {
/// Returns the usable framebuffer size, in bytes.
pub(crate) fn usable_fb_size(self) -> u64 {
let size = (u64::from(self.lower_mag()) << u64::from(self.lower_scale())) * u64::SZ_1M;
if self.ecc_mode_enabled() {
// Remove the amount of memory reserved for ECC (one per 16 units).
size / 16 * 15
} else {
size
}
}
}
impl NV_PFB_PRI_MMU_WPR2_ADDR_LO {
/// Returns the lower (inclusive) bound of the WPR2 region.
pub(crate) fn lower_bound(self) -> u64 {
u64::from(self.lo_val()) << 12
}
}
impl NV_PFB_PRI_MMU_WPR2_ADDR_HI {
/// Returns the higher (exclusive) bound of the WPR2 region.
///
/// A value of zero means the WPR2 region is not set.
pub(crate) fn higher_bound(self) -> u64 {
u64::from(self.hi_val()) << 12
}
/// Returns whether the WPR2 region is currently set.
pub(crate) fn is_wpr2_set(self) -> bool {
self.hi_val() != 0
}
}
// PGC6 register space.
//
// `GC6` is a GPU low-power state where VRAM is in self-refresh and the GPU is powered down (except