On Thu Dec 18, 2025 at 12:29 PM JST, 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(-)
>
> 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.
This doccomment is already in the HAL trait, so no need to repeat it
here.
> + 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.
Ditto.