On 12/17/25 7:29 PM, Timur Tabi wrote: > A few Falcon methods are actually GPU-specific, so move them > into the HAL. > > Signed-off-by: Timur Tabi <[email protected]> > --- > drivers/gpu/nova-core/falcon.rs | 45 ++--------------------- > drivers/gpu/nova-core/falcon/hal.rs | 10 +++++ > drivers/gpu/nova-core/falcon/hal/ga102.rs | 43 ++++++++++++++++++++++ > 3 files changed, 56 insertions(+), 42 deletions(-)
Reviewed-by: John Hubbard <[email protected]> thanks, -- John Hubbard > > diff --git a/drivers/gpu/nova-core/falcon.rs b/drivers/gpu/nova-core/falcon.rs > index 44a1a531a361..6b54c0ca458a 100644 > --- a/drivers/gpu/nova-core/falcon.rs > +++ b/drivers/gpu/nova-core/falcon.rs > @@ -13,7 +13,6 @@ > prelude::*, > sync::aref::ARef, > time::{ > - delay::fsleep, > Delta, // > }, > }; > @@ -394,48 +393,11 @@ pub(crate) fn dma_reset(&self, bar: &Bar0) { > regs::NV_PFALCON_FALCON_DMACTL::default().write(bar, &E::ID); > } > > - /// Wait for memory scrubbing to complete. > - fn reset_wait_mem_scrubbing(&self, bar: &Bar0) -> Result { > - // TIMEOUT: memory scrubbing should complete in less than 20ms. > - read_poll_timeout( > - || Ok(regs::NV_PFALCON_FALCON_HWCFG2::read(bar, &E::ID)), > - |r| r.mem_scrubbing_done(), > - Delta::ZERO, > - Delta::from_millis(20), > - ) > - .map(|_| ()) > - } > - > - /// Reset the falcon engine. > - fn reset_eng(&self, bar: &Bar0) -> Result { > - let _ = regs::NV_PFALCON_FALCON_HWCFG2::read(bar, &E::ID); > - > - // According to OpenRM's `kflcnPreResetWait_GA102` documentation, HW > sometimes does not set > - // RESET_READY so a non-failing timeout is used. > - let _ = read_poll_timeout( > - || Ok(regs::NV_PFALCON_FALCON_HWCFG2::read(bar, &E::ID)), > - |r| r.reset_ready(), > - Delta::ZERO, > - Delta::from_micros(150), > - ); > - > - regs::NV_PFALCON_FALCON_ENGINE::update(bar, &E::ID, |v| > v.set_reset(true)); > - > - // TIMEOUT: falcon engine should not take more than 10us to reset. > - fsleep(Delta::from_micros(10)); > - > - regs::NV_PFALCON_FALCON_ENGINE::update(bar, &E::ID, |v| > v.set_reset(false)); > - > - self.reset_wait_mem_scrubbing(bar)?; > - > - Ok(()) > - } > - > /// Reset the controller, select the falcon core, and wait for memory > scrubbing to complete. > pub(crate) fn reset(&self, bar: &Bar0) -> Result { > - self.reset_eng(bar)?; > + self.hal.reset_eng(bar)?; > self.hal.select_core(self, bar)?; > - self.reset_wait_mem_scrubbing(bar)?; > + self.hal.reset_wait_mem_scrubbing(bar)?; > > regs::NV_PFALCON_FALCON_RM::default() > .set_value(regs::NV_PMC_BOOT_0::read(bar).into()) > @@ -665,8 +627,7 @@ pub(crate) fn signature_reg_fuse_version( > /// > /// Returns `true` if the RISC-V core is active, `false` otherwise. > pub(crate) fn is_riscv_active(&self, bar: &Bar0) -> bool { > - let cpuctl = regs::NV_PRISCV_RISCV_CPUCTL::read(bar, &E::ID); > - cpuctl.active_stat() > + self.hal.is_riscv_active(bar) > } > > /// Write the application version to the OS register. > diff --git a/drivers/gpu/nova-core/falcon/hal.rs > b/drivers/gpu/nova-core/falcon/hal.rs > index 8dc56a28ad65..c77a1568ea96 100644 > --- a/drivers/gpu/nova-core/falcon/hal.rs > +++ b/drivers/gpu/nova-core/falcon/hal.rs > @@ -37,6 +37,16 @@ fn signature_reg_fuse_version( > > /// Program the boot ROM registers prior to starting a secure firmware. > fn program_brom(&self, falcon: &Falcon<E>, bar: &Bar0, params: > &FalconBromParams) -> Result; > + > + /// Check if the RISC-V core is active. > + /// Returns `true` if the RISC-V core is active, `false` otherwise. > + fn is_riscv_active(&self, bar: &Bar0) -> bool; > + > + /// Wait for memory scrubbing to complete. > + fn reset_wait_mem_scrubbing(&self, bar: &Bar0) -> Result; > + > + /// Reset the falcon engine. > + fn reset_eng(&self, bar: &Bar0) -> Result; > } > > /// Returns a boxed falcon HAL adequate for `chipset`. > diff --git a/drivers/gpu/nova-core/falcon/hal/ga102.rs > b/drivers/gpu/nova-core/falcon/hal/ga102.rs > index 69a7a95cac16..232d51a4921f 100644 > --- a/drivers/gpu/nova-core/falcon/hal/ga102.rs > +++ b/drivers/gpu/nova-core/falcon/hal/ga102.rs > @@ -6,6 +6,7 @@ > device, > io::poll::read_poll_timeout, > prelude::*, > + time::delay::fsleep, > time::Delta, // > }; > > @@ -117,4 +118,46 @@ fn signature_reg_fuse_version( > fn program_brom(&self, _falcon: &Falcon<E>, bar: &Bar0, params: > &FalconBromParams) -> Result { > program_brom_ga102::<E>(bar, params) > } > + > + fn is_riscv_active(&self, bar: &Bar0) -> bool { > + let cpuctl = regs::NV_PRISCV_RISCV_CPUCTL::read(bar, &E::ID); > + cpuctl.active_stat() > + } > + > + /// Wait for memory scrubbing to complete. > + fn reset_wait_mem_scrubbing(&self, bar: &Bar0) -> Result { > + // TIMEOUT: memory scrubbing should complete in less than 20ms. > + read_poll_timeout( > + || Ok(regs::NV_PFALCON_FALCON_HWCFG2::read(bar, &E::ID)), > + |r| r.mem_scrubbing_done(), > + Delta::ZERO, > + Delta::from_millis(20), > + ) > + .map(|_| ()) > + } > + > + /// Reset the falcon engine. > + fn reset_eng(&self, bar: &Bar0) -> Result { > + let _ = regs::NV_PFALCON_FALCON_HWCFG2::read(bar, &E::ID); > + > + // According to OpenRM's `kflcnPreResetWait_GA102` documentation, HW > sometimes does not set > + // RESET_READY so a non-failing timeout is used. > + let _ = read_poll_timeout( > + || Ok(regs::NV_PFALCON_FALCON_HWCFG2::read(bar, &E::ID)), > + |r| r.reset_ready(), > + Delta::ZERO, > + Delta::from_micros(150), > + ); > + > + regs::NV_PFALCON_FALCON_ENGINE::update(bar, &E::ID, |v| > v.set_reset(true)); > + > + // TIMEOUT: falcon engine should not take more than 10us to reset. > + fsleep(Delta::from_micros(10)); > + > + regs::NV_PFALCON_FALCON_ENGINE::update(bar, &E::ID, |v| > v.set_reset(false)); > + > + self.reset_wait_mem_scrubbing(bar)?; > + > + Ok(()) > + } > }
