Commit ab2aad25 authored by Timur Tabi's avatar Timur Tabi Committed by Alexandre Courbot
Browse files

gpu: nova-core: add Falcon HAL method load_method()



Some GPUs do not support using DMA to transfer code/data from system
memory to Falcon memory, and instead must use programmed I/O (PIO).
Add a function to the Falcon HAL to indicate whether a given GPU's
Falcons support DMA for this purpose.

Signed-off-by: default avatarTimur Tabi <ttabi@nvidia.com>
Reviewed-by: default avatarGary Guo <gary@garyguo.net>
Acked-by: default avatarDanilo Krummrich <dakr@kernel.org>
Link: https://patch.msgid.link/20260122222848.2555890-10-ttabi@nvidia.com


[acourbot@nvidia.com: add short code to call into the HAL.]
[acourbot@nvidia.com: make `dma_load` private as per feedback.]
Signed-off-by: default avatarAlexandre Courbot <acourbot@nvidia.com>
parent a75718af
Loading
Loading
Loading
Loading
+10 −1
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@
use crate::{
    dma::DmaObject,
    driver::Bar0,
    falcon::hal::LoadMethod,
    gpu::Chipset,
    num::{
        FromSafeCast,
@@ -514,7 +515,7 @@ fn dma_wr<F: FalconFirmware<Target = E>>(
    }

    /// Perform a DMA load into `IMEM` and `DMEM` of `fw`, and prepare the falcon to run it.
    pub(crate) fn dma_load<F: FalconFirmware<Target = E>>(&self, bar: &Bar0, fw: &F) -> Result {
    fn dma_load<F: FalconFirmware<Target = E>>(&self, bar: &Bar0, fw: &F) -> Result {
        // The Non-Secure section only exists on firmware used by Turing and GA100, and
        // those platforms do not use DMA.
        if fw.imem_ns_load_params().is_some() {
@@ -639,6 +640,14 @@ pub(crate) fn is_riscv_active(&self, bar: &Bar0) -> bool {
        self.hal.is_riscv_active(bar)
    }

    // Load a firmware image into Falcon memory
    pub(crate) fn load<F: FalconFirmware<Target = E>>(&self, bar: &Bar0, fw: &F) -> Result {
        match self.hal.load_method() {
            LoadMethod::Dma => self.dma_load(bar, fw),
            LoadMethod::Pio => Err(ENOTSUPP),
        }
    }

    /// Write the application version to the OS register.
    pub(crate) fn write_os_version(&self, bar: &Bar0, app_version: u32) {
        regs::NV_PFALCON_FALCON_OS::default()
+12 −0
Original line number Diff line number Diff line
@@ -15,6 +15,15 @@
mod ga102;
mod tu102;

/// Method used to load data into falcon memory. Some GPU architectures need
/// PIO and others can use DMA.
pub(crate) enum LoadMethod {
    /// Programmed I/O
    Pio,
    /// Direct Memory Access
    Dma,
}

/// Hardware Abstraction Layer for Falcon cores.
///
/// Implements chipset-specific low-level operations. The trait is generic against [`FalconEngine`]
@@ -48,6 +57,9 @@ fn signature_reg_fuse_version(

    /// Reset the falcon engine.
    fn reset_eng(&self, bar: &Bar0) -> Result;

    /// returns the method needed to load data into Falcon memory
    fn load_method(&self) -> LoadMethod;
}

/// Returns a boxed falcon HAL adequate for `chipset`.
+5 −0
Original line number Diff line number Diff line
@@ -12,6 +12,7 @@
use crate::{
    driver::Bar0,
    falcon::{
        hal::LoadMethod,
        Falcon,
        FalconBromParams,
        FalconEngine,
@@ -151,4 +152,8 @@ fn reset_eng(&self, bar: &Bar0) -> Result {

        Ok(())
    }

    fn load_method(&self) -> LoadMethod {
        LoadMethod::Dma
    }
}
+5 −0
Original line number Diff line number Diff line
@@ -11,6 +11,7 @@
use crate::{
    driver::Bar0,
    falcon::{
        hal::LoadMethod,
        Falcon,
        FalconBromParams,
        FalconEngine, //
@@ -69,4 +70,8 @@ fn reset_eng(&self, bar: &Bar0) -> Result {

        Ok(())
    }

    fn load_method(&self) -> LoadMethod {
        LoadMethod::Pio
    }
}
+1 −1
Original line number Diff line number Diff line
@@ -428,7 +428,7 @@ pub(crate) fn run(
            .reset(bar)
            .inspect_err(|e| dev_err!(dev, "Failed to reset GSP falcon: {:?}\n", e))?;
        falcon
            .dma_load(bar, self)
            .load(bar, self)
            .inspect_err(|e| dev_err!(dev, "Failed to load FWSEC firmware: {:?}\n", e))?;
        let (mbox0, _) = falcon
            .boot(bar, Some(0), None)
Loading