1 // SPDX-License-Identifier: GPL-2.0 2 3 use kernel::prelude::*; 4 5 use crate::{ 6 driver::Bar0, 7 falcon::{ 8 Falcon, 9 FalconBromParams, 10 FalconEngine, // 11 }, 12 gpu::Chipset, 13 }; 14 15 mod ga102; 16 mod tu102; 17 18 /// Method used to load data into falcon memory. Some GPU architectures need 19 /// PIO and others can use DMA. 20 pub(crate) enum LoadMethod { 21 /// Programmed I/O 22 Pio, 23 /// Direct Memory Access 24 Dma, 25 } 26 27 /// Hardware Abstraction Layer for Falcon cores. 28 /// 29 /// Implements chipset-specific low-level operations. The trait is generic against [`FalconEngine`] 30 /// so its `BASE` parameter can be used in order to avoid runtime bound checks when accessing 31 /// registers. 32 pub(crate) trait FalconHal<E: FalconEngine>: Send + Sync { 33 /// Activates the Falcon core if the engine is a risvc/falcon dual engine. 34 fn select_core(&self, _falcon: &Falcon<E>, _bar: &Bar0) -> Result { 35 Ok(()) 36 } 37 38 /// Returns the fused version of the signature to use in order to run a HS firmware on this 39 /// falcon instance. `engine_id_mask` and `ucode_id` are obtained from the firmware header. 40 fn signature_reg_fuse_version( 41 &self, 42 falcon: &Falcon<E>, 43 bar: &Bar0, 44 engine_id_mask: u16, 45 ucode_id: u8, 46 ) -> Result<u32>; 47 48 /// Program the boot ROM registers prior to starting a secure firmware. 49 fn program_brom(&self, falcon: &Falcon<E>, bar: &Bar0, params: &FalconBromParams) -> Result; 50 51 /// Check if the RISC-V core is active. 52 /// Returns `true` if the RISC-V core is active, `false` otherwise. 53 fn is_riscv_active(&self, bar: &Bar0) -> bool; 54 55 /// Wait for memory scrubbing to complete. 56 fn reset_wait_mem_scrubbing(&self, bar: &Bar0) -> Result; 57 58 /// Reset the falcon engine. 59 fn reset_eng(&self, bar: &Bar0) -> Result; 60 61 /// returns the method needed to load data into Falcon memory 62 fn load_method(&self) -> LoadMethod; 63 } 64 65 /// Returns a boxed falcon HAL adequate for `chipset`. 66 /// 67 /// We use a heap-allocated trait object instead of a statically defined one because the 68 /// generic `FalconEngine` argument makes it difficult to define all the combinations 69 /// statically. 70 pub(super) fn falcon_hal<E: FalconEngine + 'static>( 71 chipset: Chipset, 72 ) -> Result<KBox<dyn FalconHal<E>>> { 73 use Chipset::*; 74 75 let hal = match chipset { 76 TU102 | TU104 | TU106 | TU116 | TU117 => { 77 KBox::new(tu102::Tu102::<E>::new(), GFP_KERNEL)? as KBox<dyn FalconHal<E>> 78 } 79 GA102 | GA103 | GA104 | GA106 | GA107 | AD102 | AD103 | AD104 | AD106 | AD107 => { 80 KBox::new(ga102::Ga102::<E>::new(), GFP_KERNEL)? as KBox<dyn FalconHal<E>> 81 } 82 _ => return Err(ENOTSUPP), 83 }; 84 85 Ok(hal) 86 } 87