// SPDX-License-Identifier: GPL-2.0 use kernel::prelude::*; use crate::{ driver::Bar0, falcon::{ Falcon, FalconBromParams, FalconEngine, // }, gpu::{ Architecture, Chipset, // }, }; 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`] /// so its `BASE` parameter can be used in order to avoid runtime bound checks when accessing /// registers. pub(crate) trait FalconHal: Send + Sync { /// Activates the Falcon core if the engine is a risvc/falcon dual engine. fn select_core(&self, _falcon: &Falcon, _bar: Bar0<'_>) -> Result { Ok(()) } /// Returns the fused version of the signature to use in order to run a HS firmware on this /// falcon instance. `engine_id_mask` and `ucode_id` are obtained from the firmware header. fn signature_reg_fuse_version( &self, falcon: &Falcon, bar: Bar0<'_>, engine_id_mask: u16, ucode_id: u8, ) -> Result; /// Program the boot ROM registers prior to starting a secure firmware. fn program_brom(&self, falcon: &Falcon, bar: Bar0<'_>, params: &FalconBromParams); /// 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 the method used to load data into the falcon's memory. /// /// The only chipsets supporting PIO are those < GA102, and PIO is the preferred method for /// these. For anything above, the PIO registers appear to be masked to the CPU, so DMA is the /// only usable method. fn load_method(&self) -> LoadMethod; } /// Returns a boxed falcon HAL adequate for `chipset`. /// /// We use a heap-allocated trait object instead of a statically defined one because the /// generic `FalconEngine` argument makes it difficult to define all the combinations /// statically. pub(super) fn falcon_hal( chipset: Chipset, ) -> Result>> { let hal = match chipset.arch() { Architecture::Turing => { KBox::new(tu102::Tu102::::new(), GFP_KERNEL)? as KBox> } // GA100 boots like Turing so use Turing HAL Architecture::Ampere if chipset == Chipset::GA100 => { KBox::new(tu102::Tu102::::new(), GFP_KERNEL)? as KBox> } Architecture::Ampere | Architecture::Ada | Architecture::Hopper | Architecture::BlackwellGB10x | Architecture::BlackwellGB20x => { KBox::new(ga102::Ga102::::new(), GFP_KERNEL)? as KBox> } }; Ok(hal) }