[PATCH 1/3] gpu: nova-core: Add function to query WPR2 range
Antonin Malzieu Ridolfi via B4 Relay <[email protected]> Tue, 21 Jul 2026 17:41:07 +0200
| Newsgroups | dev.linux.lists.nova-gpu,org.freedesktop.lists.dri-devel,org.kernel.feeds.b4-sent,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
From: Antonin Malzieu Ridolfi <[email protected]> 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 <[email protected]> Signed-off-by: Antonin Malzieu Ridolfi <[email protected]> --- 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