From 82ed3243219d160601fdb98742633bee7dc6f360 Mon Sep 17 00:00:00 2001 From: Timur Tabi Date: Thu, 22 Jan 2026 16:28:41 -0600 Subject: [PATCH] gpu: nova-core: move some functions into the HAL A few Falcon methods are actually GPU-specific, so move them into the HAL. Signed-off-by: Timur Tabi Reviewed-by: John Hubbard Reviewed-by: Gary Guo Acked-by: Danilo Krummrich Link: https://patch.msgid.link/20260122222848.2555890-7-ttabi@nvidia.com Signed-off-by: Alexandre Courbot --- drivers/gpu/nova-core/falcon.rs | 45 ++--------------------- drivers/gpu/nova-core/falcon/hal.rs | 10 +++++ drivers/gpu/nova-core/falcon/hal/ga102.rs | 41 +++++++++++++++++++++ 3 files changed, 54 insertions(+), 42 deletions(-) diff --git a/drivers/gpu/nova-core/falcon.rs b/drivers/gpu/nova-core/falcon.rs index 34b36f7b3bfdc..e43563068e75b 100644 --- a/drivers/gpu/nova-core/falcon.rs +++ b/drivers/gpu/nova-core/falcon.rs @@ -16,7 +16,6 @@ use kernel::{ prelude::*, sync::aref::ARef, time::{ - delay::fsleep, Delta, // }, }; @@ -398,48 +397,11 @@ impl Falcon { 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()) @@ -674,8 +636,7 @@ impl Falcon { /// /// 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 8dc56a28ad650..c77a1568ea96e 100644 --- a/drivers/gpu/nova-core/falcon/hal.rs +++ b/drivers/gpu/nova-core/falcon/hal.rs @@ -37,6 +37,16 @@ pub(crate) trait FalconHal: Send + Sync { /// Program the boot ROM registers prior to starting a secure firmware. fn program_brom(&self, falcon: &Falcon, 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 0bdfe45a2d03b..61cc3d2611965 100644 --- a/drivers/gpu/nova-core/falcon/hal/ga102.rs +++ b/drivers/gpu/nova-core/falcon/hal/ga102.rs @@ -6,6 +6,7 @@ use kernel::{ device, io::poll::read_poll_timeout, prelude::*, + time::delay::fsleep, time::Delta, // }; @@ -117,4 +118,44 @@ impl FalconHal for Ga102 { fn program_brom(&self, _falcon: &Falcon, bar: &Bar0, params: &FalconBromParams) -> Result { program_brom_ga102::(bar, params) } + + fn is_riscv_active(&self, bar: &Bar0) -> bool { + let cpuctl = regs::NV_PRISCV_RISCV_CPUCTL::read(bar, &E::ID); + cpuctl.active_stat() + } + + 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(|_| ()) + } + + 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(()) + } } -- 2.47.3