diff options
| author | Timur Tabi <ttabi@nvidia.com> | 2026-01-22 16:28:44 -0600 |
|---|---|---|
| committer | Alexandre Courbot <acourbot@nvidia.com> | 2026-01-24 10:48:59 +0900 |
| commit | ab2aad252fe21347674cf969a5e9d44d69e403bb (patch) | |
| tree | 55a3cd89d0de14140262ce2e62e9dbe12d205cc3 /drivers/gpu/nova-core | |
| parent | a75718afc9a5c61d9266d5d0010228a6a3bb7233 (diff) | |
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: Timur Tabi <ttabi@nvidia.com>
Reviewed-by: Gary Guo <gary@garyguo.net>
Acked-by: Danilo 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: Alexandre Courbot <acourbot@nvidia.com>
Diffstat (limited to 'drivers/gpu/nova-core')
| -rw-r--r-- | drivers/gpu/nova-core/falcon.rs | 11 | ||||
| -rw-r--r-- | drivers/gpu/nova-core/falcon/hal.rs | 12 | ||||
| -rw-r--r-- | drivers/gpu/nova-core/falcon/hal/ga102.rs | 5 | ||||
| -rw-r--r-- | drivers/gpu/nova-core/falcon/hal/tu102.rs | 5 | ||||
| -rw-r--r-- | drivers/gpu/nova-core/firmware/fwsec.rs | 2 | ||||
| -rw-r--r-- | drivers/gpu/nova-core/gsp/boot.rs | 2 |
6 files changed, 34 insertions, 3 deletions
diff --git a/drivers/gpu/nova-core/falcon.rs b/drivers/gpu/nova-core/falcon.rs index e43563068e75..37bfee1d0949 100644 --- a/drivers/gpu/nova-core/falcon.rs +++ b/drivers/gpu/nova-core/falcon.rs @@ -23,6 +23,7 @@ use kernel::{ use crate::{ dma::DmaObject, driver::Bar0, + falcon::hal::LoadMethod, gpu::Chipset, num::{ FromSafeCast, @@ -514,7 +515,7 @@ impl<E: FalconEngine + 'static> Falcon<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 @@ impl<E: FalconEngine + 'static> Falcon<E> { 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() diff --git a/drivers/gpu/nova-core/falcon/hal.rs b/drivers/gpu/nova-core/falcon/hal.rs index c886ba03d1f6..89babd5f9325 100644 --- a/drivers/gpu/nova-core/falcon/hal.rs +++ b/drivers/gpu/nova-core/falcon/hal.rs @@ -15,6 +15,15 @@ use crate::{ 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 @@ pub(crate) trait FalconHal<E: FalconEngine>: Send + Sync { /// 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`. diff --git a/drivers/gpu/nova-core/falcon/hal/ga102.rs b/drivers/gpu/nova-core/falcon/hal/ga102.rs index 39863813a2bf..8f62df10da0a 100644 --- a/drivers/gpu/nova-core/falcon/hal/ga102.rs +++ b/drivers/gpu/nova-core/falcon/hal/ga102.rs @@ -12,6 +12,7 @@ use kernel::{ use crate::{ driver::Bar0, falcon::{ + hal::LoadMethod, Falcon, FalconBromParams, FalconEngine, @@ -151,4 +152,8 @@ impl<E: FalconEngine> FalconHal<E> for Ga102<E> { Ok(()) } + + fn load_method(&self) -> LoadMethod { + LoadMethod::Dma + } } diff --git a/drivers/gpu/nova-core/falcon/hal/tu102.rs b/drivers/gpu/nova-core/falcon/hal/tu102.rs index 23fbf6110572..7de6f24cc0a0 100644 --- a/drivers/gpu/nova-core/falcon/hal/tu102.rs +++ b/drivers/gpu/nova-core/falcon/hal/tu102.rs @@ -11,6 +11,7 @@ use kernel::{ use crate::{ driver::Bar0, falcon::{ + hal::LoadMethod, Falcon, FalconBromParams, FalconEngine, // @@ -69,4 +70,8 @@ impl<E: FalconEngine> FalconHal<E> for Tu102<E> { Ok(()) } + + fn load_method(&self) -> LoadMethod { + LoadMethod::Pio + } } diff --git a/drivers/gpu/nova-core/firmware/fwsec.rs b/drivers/gpu/nova-core/firmware/fwsec.rs index e4009faba6c5..6fc5a008bb47 100644 --- a/drivers/gpu/nova-core/firmware/fwsec.rs +++ b/drivers/gpu/nova-core/firmware/fwsec.rs @@ -428,7 +428,7 @@ impl FwsecFirmware { .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) diff --git a/drivers/gpu/nova-core/gsp/boot.rs b/drivers/gpu/nova-core/gsp/boot.rs index 581b412554dc..be427fe26a58 100644 --- a/drivers/gpu/nova-core/gsp/boot.rs +++ b/drivers/gpu/nova-core/gsp/boot.rs @@ -183,7 +183,7 @@ impl super::Gsp { ); sec2_falcon.reset(bar)?; - sec2_falcon.dma_load(bar, &booter_loader)?; + sec2_falcon.load(bar, &booter_loader)?; let wpr_handle = wpr_meta.dma_handle(); let (mbox0, mbox1) = sec2_falcon.boot( bar, |
