* [PATCH 1/3] gpu: nova-core: Add function to query WPR2 range
2026-07-21 15:41 [PATCH 0/3] gpu: nova-core: Move PFB and PBUS register Antonin Malzieu Ridolfi via B4 Relay
@ 2026-07-21 15:41 ` Antonin Malzieu Ridolfi via B4 Relay
2026-07-25 13:24 ` Alexandre Courbot
2026-07-21 15:41 ` [PATCH 2/3] gpu: nova-core: Move PFB registers definitions Antonin Malzieu Ridolfi via B4 Relay
` (2 subsequent siblings)
3 siblings, 1 reply; 10+ messages in thread
From: Antonin Malzieu Ridolfi via B4 Relay @ 2026-07-21 15:41 UTC (permalink / raw)
To: Danilo Krummrich, Alexandre Courbot, Alice Ryhl, David Airlie,
Simona Vetter
Cc: nova-gpu, dri-devel, linux-kernel, daniel.almeida,
Antonin Malzieu Ridolfi
From: Antonin Malzieu Ridolfi <dev@nanonej.com>
Create new function abstracting WPR2 region range query.
Refactor gsp hal tu102 to query the WPR2 region range using this new
function.
Suggested-by: Alexandre Courbot <acourbot@nvidia.com>
Signed-off-by: Antonin Malzieu Ridolfi <dev@nanonej.com>
---
drivers/gpu/nova-core/fb.rs | 15 +++++++++
drivers/gpu/nova-core/gsp/hal/tu102.rs | 58 +++++++++++++++-------------------
2 files changed, 41 insertions(+), 32 deletions(-)
diff --git a/drivers/gpu/nova-core/fb.rs b/drivers/gpu/nova-core/fb.rs
index 273cff752fae..864a34ca20b8 100644
--- a/drivers/gpu/nova-core/fb.rs
+++ b/drivers/gpu/nova-core/fb.rs
@@ -270,3 +270,18 @@ pub(crate) fn new(chipset: Chipset, bar: Bar0<'_>, gsp_fw: &GspFirmware) -> Resu
})
}
}
+
+/// 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_lo, wpr2_hi) = (
+ bar.read(crate::regs::NV_PFB_PRI_MMU_WPR2_ADDR_LO),
+ bar.read(crate::regs::NV_PFB_PRI_MMU_WPR2_ADDR_HI),
+ );
+
+ if !wpr2_hi.is_wpr2_set() {
+ return None;
+ }
+
+ Some(wpr2_lo.lower_bound()..wpr2_hi.higher_bound())
+}
diff --git a/drivers/gpu/nova-core/gsp/hal/tu102.rs b/drivers/gpu/nova-core/gsp/hal/tu102.rs
index 29bb17171f56..b3242aaeea45 100644
--- a/drivers/gpu/nova-core/gsp/hal/tu102.rs
+++ b/drivers/gpu/nova-core/gsp/hal/tu102.rs
@@ -17,7 +17,10 @@
sec2::Sec2,
Falcon, //
},
- fb::FbLayout,
+ fb::{
+ wpr2_range,
+ FbLayout, //
+ },
firmware::{
booter::{
BooterFirmware,
@@ -90,9 +93,8 @@ fn run(&self, ctx: &mut GspBootContext<'_, '_>) -> Result {
.inspect_err(|e| dev_err!(dev, "FWSEC-SB failed to run: {:?}\n", e));
// Remove WPR2 region if set.
- let wpr2_hi = bar.read(regs::NV_PFB_PRI_MMU_WPR2_ADDR_HI);
let booter_unloader_res = (|| {
- if !wpr2_hi.is_wpr2_set() {
+ if wpr2_range(bar).is_none() {
return Ok(());
}
@@ -110,8 +112,7 @@ fn run(&self, ctx: &mut GspBootContext<'_, '_>) -> Result {
}
// Confirm that the WPR2 region has been removed.
- let wpr2_hi = bar.read(regs::NV_PFB_PRI_MMU_WPR2_ADDR_HI);
- if wpr2_hi.is_wpr2_set() {
+ if wpr2_range(bar).is_some() {
dev_err!(
dev,
"WPR2 region still set after Booter Unloader returned\n"
@@ -144,9 +145,9 @@ fn run_fwsec_frts(
bios: &Vbios,
fb_layout: &FbLayout,
) -> Result {
- // Check that the WPR2 region does not already exist - if it does, we cannot run
- // FWSEC-FRTS until the GPU is reset.
- if bar.read(regs::NV_PFB_PRI_MMU_WPR2_ADDR_HI).higher_bound() != 0 {
+ // Check that the WPR2 region does not already exist -
+ // if it does, we cannot run FWSEC-FRTS until the GPU is reset.
+ if wpr2_range(bar).is_some() {
dev_err!(
dev,
"WPR2 region already exists - GPU needs to be reset to proceed\n"
@@ -189,34 +190,27 @@ fn run_fwsec_frts(
}
// Check that the WPR2 region has been created as we requested.
- let (wpr2_lo, wpr2_hi) = (
- bar.read(regs::NV_PFB_PRI_MMU_WPR2_ADDR_LO).lower_bound(),
- bar.read(regs::NV_PFB_PRI_MMU_WPR2_ADDR_HI).higher_bound(),
- );
-
- match (wpr2_lo, wpr2_hi) {
- (_, 0) => {
- dev_err!(dev, "WPR2 region not created after running FWSEC-FRTS\n");
+ let Some(wpr2_range) = wpr2_range(bar) else {
+ dev_err!(dev, "WPR2 region not created after running FWSEC-FRTS\n");
- Err(EIO)
- }
- (wpr2_lo, _) if wpr2_lo != fb_layout.frts.start => {
- dev_err!(
- dev,
- "WPR2 region created at unexpected address {:#x}; expected {:#x}\n",
- wpr2_lo,
- fb_layout.frts.start,
- );
+ return Err(EIO);
+ };
- Err(EIO)
- }
- (wpr2_lo, wpr2_hi) => {
- dev_dbg!(dev, "WPR2: {:#x}-{:#x}\n", wpr2_lo, wpr2_hi);
- dev_dbg!(dev, "GPU instance built\n");
+ if wpr2_range.start != fb_layout.frts.start {
+ dev_err!(
+ dev,
+ "WPR2 region created at unexpected address {:#x}; expected {:#x}\n",
+ wpr2_range.start,
+ fb_layout.frts.start,
+ );
- Ok(())
- }
+ return Err(EIO);
}
+
+ dev_dbg!(dev, "WPR2: {:#x}-{:#x}\n", wpr2_range.start, wpr2_range.end);
+ dev_dbg!(dev, "GPU instance built\n");
+
+ Ok(())
}
/// Load and prepare the resources required to properly reset the GSP after it has been stopped.
--
2.55.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* Re: [PATCH 1/3] gpu: nova-core: Add function to query WPR2 range
2026-07-21 15:41 ` [PATCH 1/3] gpu: nova-core: Add function to query WPR2 range Antonin Malzieu Ridolfi via B4 Relay
@ 2026-07-25 13:24 ` Alexandre Courbot
0 siblings, 0 replies; 10+ messages in thread
From: Alexandre Courbot @ 2026-07-25 13:24 UTC (permalink / raw)
To: Antonin Malzieu Ridolfi via B4 Relay
Cc: dev, Danilo Krummrich, Alice Ryhl, David Airlie, Simona Vetter,
nova-gpu, dri-devel, linux-kernel, daniel.almeida
On Wed Jul 22, 2026 at 12:41 AM JST, Antonin Malzieu Ridolfi via B4 Relay wrote:
> From: Antonin Malzieu Ridolfi <dev@nanonej.com>
>
> Create new function abstracting WPR2 region range query.
> Refactor gsp hal tu102 to query the WPR2 region range using this new
> function.
>
> Suggested-by: Alexandre Courbot <acourbot@nvidia.com>
> Signed-off-by: Antonin Malzieu Ridolfi <dev@nanonej.com>
> ---
> drivers/gpu/nova-core/fb.rs | 15 +++++++++
> drivers/gpu/nova-core/gsp/hal/tu102.rs | 58 +++++++++++++++-------------------
> 2 files changed, 41 insertions(+), 32 deletions(-)
>
> diff --git a/drivers/gpu/nova-core/fb.rs b/drivers/gpu/nova-core/fb.rs
> index 273cff752fae..864a34ca20b8 100644
> --- a/drivers/gpu/nova-core/fb.rs
> +++ b/drivers/gpu/nova-core/fb.rs
> @@ -270,3 +270,18 @@ pub(crate) fn new(chipset: Chipset, bar: Bar0<'_>, gsp_fw: &GspFirmware) -> Resu
> })
> }
> }
> +
> +/// 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_lo, wpr2_hi) = (
> + bar.read(crate::regs::NV_PFB_PRI_MMU_WPR2_ADDR_LO),
> + bar.read(crate::regs::NV_PFB_PRI_MMU_WPR2_ADDR_HI),
> + );
> +
> + if !wpr2_hi.is_wpr2_set() {
> + return None;
> + }
To preserve the current semantics, let's read WPR_ADDR_HI first, check
`is_wpr2_set` (and early-return `None` if not set), and then read
`WPR_ADDR_LO` to build the range.
> +
> + Some(wpr2_lo.lower_bound()..wpr2_hi.higher_bound())
> +}
> diff --git a/drivers/gpu/nova-core/gsp/hal/tu102.rs b/drivers/gpu/nova-core/gsp/hal/tu102.rs
> index 29bb17171f56..b3242aaeea45 100644
> --- a/drivers/gpu/nova-core/gsp/hal/tu102.rs
> +++ b/drivers/gpu/nova-core/gsp/hal/tu102.rs
> @@ -17,7 +17,10 @@
> sec2::Sec2,
> Falcon, //
> },
> - fb::FbLayout,
> + fb::{
> + wpr2_range,
> + FbLayout, //
> + },
> firmware::{
> booter::{
> BooterFirmware,
> @@ -90,9 +93,8 @@ fn run(&self, ctx: &mut GspBootContext<'_, '_>) -> Result {
> .inspect_err(|e| dev_err!(dev, "FWSEC-SB failed to run: {:?}\n", e));
>
> // Remove WPR2 region if set.
> - let wpr2_hi = bar.read(regs::NV_PFB_PRI_MMU_WPR2_ADDR_HI);
> let booter_unloader_res = (|| {
> - if !wpr2_hi.is_wpr2_set() {
> + if wpr2_range(bar).is_none() {
> return Ok(());
> }
>
> @@ -110,8 +112,7 @@ fn run(&self, ctx: &mut GspBootContext<'_, '_>) -> Result {
> }
>
> // Confirm that the WPR2 region has been removed.
> - let wpr2_hi = bar.read(regs::NV_PFB_PRI_MMU_WPR2_ADDR_HI);
> - if wpr2_hi.is_wpr2_set() {
> + if wpr2_range(bar).is_some() {
> dev_err!(
> dev,
> "WPR2 region still set after Booter Unloader returned\n"
> @@ -144,9 +145,9 @@ fn run_fwsec_frts(
> bios: &Vbios,
> fb_layout: &FbLayout,
> ) -> Result {
> - // Check that the WPR2 region does not already exist - if it does, we cannot run
> - // FWSEC-FRTS until the GPU is reset.
> - if bar.read(regs::NV_PFB_PRI_MMU_WPR2_ADDR_HI).higher_bound() != 0 {
> + // Check that the WPR2 region does not already exist -
> + // if it does, we cannot run FWSEC-FRTS until the GPU is reset.
This comment is reformatted for now good reason iiuc.
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 2/3] gpu: nova-core: Move PFB registers definitions
2026-07-21 15:41 [PATCH 0/3] gpu: nova-core: Move PFB and PBUS register Antonin Malzieu Ridolfi via B4 Relay
2026-07-21 15:41 ` [PATCH 1/3] gpu: nova-core: Add function to query WPR2 range Antonin Malzieu Ridolfi via B4 Relay
@ 2026-07-21 15:41 ` Antonin Malzieu Ridolfi via B4 Relay
2026-07-25 13:27 ` Alexandre Courbot
2026-07-21 15:41 ` [PATCH 3/3] gpu: nova-core: Move one PBUS register definition Antonin Malzieu Ridolfi via B4 Relay
2026-07-21 15:46 ` [PATCH 0/3] gpu: nova-core: Move PFB and PBUS register Nanonej Dev
3 siblings, 1 reply; 10+ messages in thread
From: Antonin Malzieu Ridolfi via B4 Relay @ 2026-07-21 15:41 UTC (permalink / raw)
To: Danilo Krummrich, Alexandre Courbot, Alice Ryhl, David Airlie,
Simona Vetter
Cc: nova-gpu, dri-devel, linux-kernel, daniel.almeida,
Antonin Malzieu Ridolfi
From: Antonin Malzieu Ridolfi <dev@nanonej.com>
Suggested-by: Alexandre Courbot <acourbot@nvidia.com>
Suggested-by: Danilo Krummrich <dakr@kernel.org>
Signed-off-by: Antonin Malzieu Ridolfi <dev@nanonej.com>
---
drivers/gpu/nova-core/fb.rs | 4 +-
drivers/gpu/nova-core/fb/hal/ga100.rs | 8 ++-
drivers/gpu/nova-core/fb/hal/gb100.rs | 6 +-
drivers/gpu/nova-core/fb/hal/gb202.rs | 6 +-
drivers/gpu/nova-core/fb/hal/gh100.rs | 6 +-
drivers/gpu/nova-core/fb/hal/tu102.rs | 8 ++-
drivers/gpu/nova-core/fb/regs.rs | 132 +++++++++++++++++++++++++++++++++-
drivers/gpu/nova-core/regs.rs | 127 --------------------------------
8 files changed, 155 insertions(+), 142 deletions(-)
diff --git a/drivers/gpu/nova-core/fb.rs b/drivers/gpu/nova-core/fb.rs
index 864a34ca20b8..59e715b73479 100644
--- a/drivers/gpu/nova-core/fb.rs
+++ b/drivers/gpu/nova-core/fb.rs
@@ -275,8 +275,8 @@ pub(crate) fn new(chipset: Chipset, bar: Bar0<'_>, gsp_fw: &GspFirmware) -> Resu
/// Returns `None` if the WPR2 region is not set.
pub(crate) fn wpr2_range(bar: Bar0<'_>) -> Option<Range<u64>> {
let (wpr2_lo, wpr2_hi) = (
- bar.read(crate::regs::NV_PFB_PRI_MMU_WPR2_ADDR_LO),
- bar.read(crate::regs::NV_PFB_PRI_MMU_WPR2_ADDR_HI),
+ bar.read(regs::NV_PFB_PRI_MMU_WPR2_ADDR_LO),
+ bar.read(regs::NV_PFB_PRI_MMU_WPR2_ADDR_HI),
);
if !wpr2_hi.is_wpr2_set() {
diff --git a/drivers/gpu/nova-core/fb/hal/ga100.rs b/drivers/gpu/nova-core/fb/hal/ga100.rs
index 3cc1caf361c7..d13c9a826eef 100644
--- a/drivers/gpu/nova-core/fb/hal/ga100.rs
+++ b/drivers/gpu/nova-core/fb/hal/ga100.rs
@@ -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()
}
diff --git a/drivers/gpu/nova-core/fb/hal/gb100.rs b/drivers/gpu/nova-core/fb/hal/gb100.rs
index 6e0eba101ca1..ec55ec3fc7e1 100644
--- a/drivers/gpu/nova-core/fb/hal/gb100.rs
+++ b/drivers/gpu/nova-core/fb/hal/gb100.rs
@@ -22,9 +22,11 @@
use crate::{
driver::Bar0,
- fb::hal::FbHal,
+ fb::{
+ hal::FbHal,
+ regs, //
+ },
num::usize_into_u32,
- regs, //
};
struct Gb100;
diff --git a/drivers/gpu/nova-core/fb/hal/gb202.rs b/drivers/gpu/nova-core/fb/hal/gb202.rs
index b78e0970f66d..69ba35d2ea08 100644
--- a/drivers/gpu/nova-core/fb/hal/gb202.rs
+++ b/drivers/gpu/nova-core/fb/hal/gb202.rs
@@ -12,8 +12,10 @@
use crate::{
driver::Bar0,
- fb::hal::FbHal,
- regs, //
+ fb::{
+ hal::FbHal,
+ regs, //
+ },
};
struct Gb202;
diff --git a/drivers/gpu/nova-core/fb/hal/gh100.rs b/drivers/gpu/nova-core/fb/hal/gh100.rs
index d39fe99537ed..2867ae058d0a 100644
--- a/drivers/gpu/nova-core/fb/hal/gh100.rs
+++ b/drivers/gpu/nova-core/fb/hal/gh100.rs
@@ -10,8 +10,10 @@
use crate::{
driver::Bar0,
- fb::hal::FbHal,
- regs, //
+ fb::{
+ hal::FbHal,
+ regs, //
+ },
};
struct Gh100;
diff --git a/drivers/gpu/nova-core/fb/hal/tu102.rs b/drivers/gpu/nova-core/fb/hal/tu102.rs
index f629e8e9d5d5..2ef04ccb550c 100644
--- a/drivers/gpu/nova-core/fb/hal/tu102.rs
+++ b/drivers/gpu/nova-core/fb/hal/tu102.rs
@@ -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()
}
diff --git a/drivers/gpu/nova-core/fb/regs.rs b/drivers/gpu/nova-core/fb/regs.rs
index b2ec02f584be..b2baa4a2a85f 100644
--- a/drivers/gpu/nova-core/fb/regs.rs
+++ b/drivers/gpu/nova-core/fb/regs.rs
@@ -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 [`super::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
+ }
+}
diff --git a/drivers/gpu/nova-core/regs.rs b/drivers/gpu/nova-core/regs.rs
index 397124f245ee..f7304b27ae0c 100644
--- a/drivers/gpu/nova-core/regs.rs
+++ b/drivers/gpu/nova-core/regs.rs
@@ -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
--
2.55.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* Re: [PATCH 2/3] gpu: nova-core: Move PFB registers definitions
2026-07-21 15:41 ` [PATCH 2/3] gpu: nova-core: Move PFB registers definitions Antonin Malzieu Ridolfi via B4 Relay
@ 2026-07-25 13:27 ` Alexandre Courbot
0 siblings, 0 replies; 10+ messages in thread
From: Alexandre Courbot @ 2026-07-25 13:27 UTC (permalink / raw)
To: Antonin Malzieu Ridolfi via B4 Relay
Cc: dev, Danilo Krummrich, Alice Ryhl, David Airlie, Simona Vetter,
nova-gpu, dri-devel, linux-kernel, daniel.almeida
On Wed Jul 22, 2026 at 12:41 AM JST, Antonin Malzieu Ridolfi via B4 Relay wrote:
> From: Antonin Malzieu Ridolfi <dev@nanonej.com>
>
Every patch needs a commit message, even if short.
(also please check whether the issue raised by Sashiko [1] has merit)
[1] https://sashiko.dev/#/patchset/20260721-nova-core-regs-split-v1-0-384fa2a42244@nanonej.com?part=2
One more comment inline, but this is pretty much what I had in mind; so
looking pretty good imho!
> Suggested-by: Alexandre Courbot <acourbot@nvidia.com>
> Suggested-by: Danilo Krummrich <dakr@kernel.org>
> Signed-off-by: Antonin Malzieu Ridolfi <dev@nanonej.com>
> ---
> drivers/gpu/nova-core/fb.rs | 4 +-
> drivers/gpu/nova-core/fb/hal/ga100.rs | 8 ++-
> drivers/gpu/nova-core/fb/hal/gb100.rs | 6 +-
> drivers/gpu/nova-core/fb/hal/gb202.rs | 6 +-
> drivers/gpu/nova-core/fb/hal/gh100.rs | 6 +-
> drivers/gpu/nova-core/fb/hal/tu102.rs | 8 ++-
> drivers/gpu/nova-core/fb/regs.rs | 132 +++++++++++++++++++++++++++++++++-
> drivers/gpu/nova-core/regs.rs | 127 --------------------------------
> 8 files changed, 155 insertions(+), 142 deletions(-)
>
> diff --git a/drivers/gpu/nova-core/fb.rs b/drivers/gpu/nova-core/fb.rs
> index 864a34ca20b8..59e715b73479 100644
> --- a/drivers/gpu/nova-core/fb.rs
> +++ b/drivers/gpu/nova-core/fb.rs
> @@ -275,8 +275,8 @@ pub(crate) fn new(chipset: Chipset, bar: Bar0<'_>, gsp_fw: &GspFirmware) -> Resu
> /// Returns `None` if the WPR2 region is not set.
> pub(crate) fn wpr2_range(bar: Bar0<'_>) -> Option<Range<u64>> {
> let (wpr2_lo, wpr2_hi) = (
> - bar.read(crate::regs::NV_PFB_PRI_MMU_WPR2_ADDR_LO),
> - bar.read(crate::regs::NV_PFB_PRI_MMU_WPR2_ADDR_HI),
> + bar.read(regs::NV_PFB_PRI_MMU_WPR2_ADDR_LO),
> + bar.read(regs::NV_PFB_PRI_MMU_WPR2_ADDR_HI),
> );
>
> if !wpr2_hi.is_wpr2_set() {
> diff --git a/drivers/gpu/nova-core/fb/hal/ga100.rs b/drivers/gpu/nova-core/fb/hal/ga100.rs
> index 3cc1caf361c7..d13c9a826eef 100644
> --- a/drivers/gpu/nova-core/fb/hal/ga100.rs
> +++ b/drivers/gpu/nova-core/fb/hal/ga100.rs
> @@ -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()
> }
>
> diff --git a/drivers/gpu/nova-core/fb/hal/gb100.rs b/drivers/gpu/nova-core/fb/hal/gb100.rs
> index 6e0eba101ca1..ec55ec3fc7e1 100644
> --- a/drivers/gpu/nova-core/fb/hal/gb100.rs
> +++ b/drivers/gpu/nova-core/fb/hal/gb100.rs
> @@ -22,9 +22,11 @@
>
> use crate::{
> driver::Bar0,
> - fb::hal::FbHal,
> + fb::{
> + hal::FbHal,
> + regs, //
> + },
> num::usize_into_u32,
> - regs, //
> };
>
> struct Gb100;
> diff --git a/drivers/gpu/nova-core/fb/hal/gb202.rs b/drivers/gpu/nova-core/fb/hal/gb202.rs
> index b78e0970f66d..69ba35d2ea08 100644
> --- a/drivers/gpu/nova-core/fb/hal/gb202.rs
> +++ b/drivers/gpu/nova-core/fb/hal/gb202.rs
> @@ -12,8 +12,10 @@
>
> use crate::{
> driver::Bar0,
> - fb::hal::FbHal,
> - regs, //
> + fb::{
> + hal::FbHal,
> + regs, //
> + },
> };
>
> struct Gb202;
> diff --git a/drivers/gpu/nova-core/fb/hal/gh100.rs b/drivers/gpu/nova-core/fb/hal/gh100.rs
> index d39fe99537ed..2867ae058d0a 100644
> --- a/drivers/gpu/nova-core/fb/hal/gh100.rs
> +++ b/drivers/gpu/nova-core/fb/hal/gh100.rs
> @@ -10,8 +10,10 @@
>
> use crate::{
> driver::Bar0,
> - fb::hal::FbHal,
> - regs, //
> + fb::{
> + hal::FbHal,
> + regs, //
> + },
> };
>
> struct Gh100;
> diff --git a/drivers/gpu/nova-core/fb/hal/tu102.rs b/drivers/gpu/nova-core/fb/hal/tu102.rs
> index f629e8e9d5d5..2ef04ccb550c 100644
> --- a/drivers/gpu/nova-core/fb/hal/tu102.rs
> +++ b/drivers/gpu/nova-core/fb/hal/tu102.rs
> @@ -9,8 +9,10 @@
>
> use crate::{
> driver::Bar0,
> - fb::hal::FbHal,
> - regs, //
> + fb::{
> + hal::FbHal, //
> + regs,
nit: `//` not on last line.
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 3/3] gpu: nova-core: Move one PBUS register definition
2026-07-21 15:41 [PATCH 0/3] gpu: nova-core: Move PFB and PBUS register Antonin Malzieu Ridolfi via B4 Relay
2026-07-21 15:41 ` [PATCH 1/3] gpu: nova-core: Add function to query WPR2 range Antonin Malzieu Ridolfi via B4 Relay
2026-07-21 15:41 ` [PATCH 2/3] gpu: nova-core: Move PFB registers definitions Antonin Malzieu Ridolfi via B4 Relay
@ 2026-07-21 15:41 ` Antonin Malzieu Ridolfi via B4 Relay
2026-07-21 15:51 ` Nanonej Dev
2026-07-25 13:30 ` Alexandre Courbot
2026-07-21 15:46 ` [PATCH 0/3] gpu: nova-core: Move PFB and PBUS register Nanonej Dev
3 siblings, 2 replies; 10+ messages in thread
From: Antonin Malzieu Ridolfi via B4 Relay @ 2026-07-21 15:41 UTC (permalink / raw)
To: Danilo Krummrich, Alexandre Courbot, Alice Ryhl, David Airlie,
Simona Vetter
Cc: nova-gpu, dri-devel, linux-kernel, daniel.almeida,
Antonin Malzieu Ridolfi
From: Antonin Malzieu Ridolfi <dev@nanonej.com>
Suggested-by: Alexandre Courbot <acourbot@nvidia.com>
Suggested-by: Danilo Krummrich <dakr@kernel.org>
Signed-off-by: Antonin Malzieu Ridolfi <dev@nanonej.com>
---
drivers/gpu/nova-core/gsp/hal/tu102.rs | 2 +-
drivers/gpu/nova-core/gsp/regs.rs | 11 +++++++++++
drivers/gpu/nova-core/regs.rs | 5 -----
3 files changed, 12 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/nova-core/gsp/hal/tu102.rs b/drivers/gpu/nova-core/gsp/hal/tu102.rs
index b3242aaeea45..91b995c2ee57 100644
--- a/drivers/gpu/nova-core/gsp/hal/tu102.rs
+++ b/drivers/gpu/nova-core/gsp/hal/tu102.rs
@@ -40,12 +40,12 @@
GspHal,
UnloadBundle, //
},
+ regs,
sequencer::GspSequencer,
Gsp,
GspBootContext,
GspFwWprMeta, //
},
- regs,
vbios::Vbios, //
};
diff --git a/drivers/gpu/nova-core/gsp/regs.rs b/drivers/gpu/nova-core/gsp/regs.rs
index a76dea3c3ab0..9a48aa87e7fb 100644
--- a/drivers/gpu/nova-core/gsp/regs.rs
+++ b/drivers/gpu/nova-core/gsp/regs.rs
@@ -2,6 +2,8 @@
use kernel::io::register;
+use crate::regs::NV_PBUS_SW_SCRATCH;
+
// PGSP
register! {
@@ -9,3 +11,12 @@
31:0 address;
}
}
+
+// PBUS
+
+register! {
+ /// Scratch register 0xe used as FRTS firmware error code.
+ pub(super) NV_PBUS_SW_SCRATCH_0E_FRTS_ERR(u32) => NV_PBUS_SW_SCRATCH[0xe] {
+ 31:16 frts_err_code;
+ }
+}
diff --git a/drivers/gpu/nova-core/regs.rs b/drivers/gpu/nova-core/regs.rs
index f7304b27ae0c..dda3be837f62 100644
--- a/drivers/gpu/nova-core/regs.rs
+++ b/drivers/gpu/nova-core/regs.rs
@@ -109,11 +109,6 @@ fn fmt(&self, f: &mut kernel::fmt::Formatter<'_>) -> kernel::fmt::Result {
register! {
pub(crate) NV_PBUS_SW_SCRATCH(u32)[64] @ 0x00001400 {}
-
- /// Scratch register 0xe used as FRTS firmware error code.
- pub(crate) NV_PBUS_SW_SCRATCH_0E_FRTS_ERR(u32) => NV_PBUS_SW_SCRATCH[0xe] {
- 31:16 frts_err_code;
- }
}
// PGC6 register space.
--
2.55.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* Re: [PATCH 3/3] gpu: nova-core: Move one PBUS register definition
2026-07-21 15:41 ` [PATCH 3/3] gpu: nova-core: Move one PBUS register definition Antonin Malzieu Ridolfi via B4 Relay
@ 2026-07-21 15:51 ` Nanonej Dev
2026-07-25 13:28 ` Alexandre Courbot
2026-07-25 13:30 ` Alexandre Courbot
1 sibling, 1 reply; 10+ messages in thread
From: Nanonej Dev @ 2026-07-21 15:51 UTC (permalink / raw)
To: Alexandre Courbot
Cc: Danilo Krummrich, Alice Ryhl, David Airlie, Simona Vetter,
nova-gpu, dri-devel, linux-kernel, daniel.almeida
[-- Attachment #1.1: Type: text/plain, Size: 537 bytes --]
> - Move the `NV_PBUS_SW_SCRATCH_0E_FRTS_ERR` register under the `gsp`
> module, since it is clearly themed after `FRTS`, which is part of the
> GSP boot. But, without moving `NV_PBUS_SW_SCRATCH` (the actual
> register being aliased). I expect you will hit a bug of the `register`
> macro when doing this one - I'll try to address it, but the first two
> steps should be safe to do and correct.
You told me that I would hit a bug on `NV_PBUS_SW_SCRATCH`, but as far as I compile, I didn't. Anything I could have missed?
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 343 bytes --]
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 3/3] gpu: nova-core: Move one PBUS register definition
2026-07-21 15:51 ` Nanonej Dev
@ 2026-07-25 13:28 ` Alexandre Courbot
0 siblings, 0 replies; 10+ messages in thread
From: Alexandre Courbot @ 2026-07-25 13:28 UTC (permalink / raw)
To: Nanonej Dev
Cc: Danilo Krummrich, Alice Ryhl, David Airlie, Simona Vetter,
nova-gpu, dri-devel, linux-kernel, daniel.almeida
On Wed Jul 22, 2026 at 12:51 AM JST, Nanonej Dev wrote:
>> - Move the `NV_PBUS_SW_SCRATCH_0E_FRTS_ERR` register under the `gsp`
>> module, since it is clearly themed after `FRTS`, which is part of the
>> GSP boot. But, without moving `NV_PBUS_SW_SCRATCH` (the actual
>> register being aliased). I expect you will hit a bug of the `register`
>> macro when doing this one - I'll try to address it, but the first two
>> steps should be safe to do and correct.
>
> You told me that I would hit a bug on `NV_PBUS_SW_SCRATCH`, but as far as I compile, I didn't. Anything I could have missed?
I was expecting issues with relative registers that need to refer to a
base type defined in another module; but as relative registers should be
going away soon [1], so will this problem. IOW, I suggest waiting a bit
before attempting to move the PFALCON/PFALCON2 registers.
[1] https://lore.kernel.org/all/20260721-typed_register-v1-0-452d72b60262@garyguo.net/
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 3/3] gpu: nova-core: Move one PBUS register definition
2026-07-21 15:41 ` [PATCH 3/3] gpu: nova-core: Move one PBUS register definition Antonin Malzieu Ridolfi via B4 Relay
2026-07-21 15:51 ` Nanonej Dev
@ 2026-07-25 13:30 ` Alexandre Courbot
1 sibling, 0 replies; 10+ messages in thread
From: Alexandre Courbot @ 2026-07-25 13:30 UTC (permalink / raw)
To: Antonin Malzieu Ridolfi via B4 Relay
Cc: dev, Danilo Krummrich, Alice Ryhl, David Airlie, Simona Vetter,
nova-gpu, dri-devel, linux-kernel, daniel.almeida
On Wed Jul 22, 2026 at 12:41 AM JST, Antonin Malzieu Ridolfi via B4 Relay wrote:
> From: Antonin Malzieu Ridolfi <dev@nanonej.com>
>
Same as patch 2, we need a commit message here.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 0/3] gpu: nova-core: Move PFB and PBUS register
2026-07-21 15:41 [PATCH 0/3] gpu: nova-core: Move PFB and PBUS register Antonin Malzieu Ridolfi via B4 Relay
` (2 preceding siblings ...)
2026-07-21 15:41 ` [PATCH 3/3] gpu: nova-core: Move one PBUS register definition Antonin Malzieu Ridolfi via B4 Relay
@ 2026-07-21 15:46 ` Nanonej Dev
3 siblings, 0 replies; 10+ messages in thread
From: Nanonej Dev @ 2026-07-21 15:46 UTC (permalink / raw)
To: Alexandre Courbot
Cc: Danilo Krummrich, Alice Ryhl, David Airlie, Simona Vetter,
nova-gpu, dri-devel, linux-kernel, daniel.almeida
[-- Attachment #1.1: Type: text/plain, Size: 1132 bytes --]
> There could be a function in the `fb` module that reads the registers
> and returns an `Option<Range<u64>>` - `None` if `is_wpr2_set` is
> `false`, or the WPR2 range otherwise. Then the GSP TU102 HAL would just
> use this function instead of poking the register as it currently does.
>
> Doing so would move the WPR2 registers to the right place, and provide the
> right abstraction for the WPR2 region.
>
> A patch series doing this could look like this:
>
> - Add the `fb` module function abstracting the WPR2 region registers and
> use it in the GSP's TU102 HAL.
> - Move the `NV_PFB_PRI_MMU_WPR2_ADDR*` registers under the `fb` module.
> - Move the `NV_PBUS_SW_SCRATCH_0E_FRTS_ERR` register under the `gsp`
> module, since it is clearly themed after `FRTS`, which is part of the
> GSP boot. But, without moving `NV_PBUS_SW_SCRATCH` (the actual
> register being aliased). I expect you will hit a bug of the `register`
> macro when doing this one - I'll try to address it, but the first two
> steps should be safe to do and correct.
Thanks for the plan Alexandre, worked like a charm.
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 343 bytes --]
^ permalink raw reply [flat|nested] 10+ messages in thread