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 /// Hardware Abstraction Layer for Falcon cores. 19 /// 20 /// Implements chipset-specific low-level operations. The trait is generic against [`FalconEngine`] 21 /// so its `BASE` parameter can be used in order to avoid runtime bound checks when accessing 22 /// registers. 23 pub(crate) trait FalconHal<E: FalconEngine>: Send + Sync { 24 /// Activates the Falcon core if the engine is a risvc/falcon dual engine. 25 fn select_core(&self, _falcon: &Falcon<E>, _bar: &Bar0) -> Result { 26 Ok(()) 27 } 28 29 /// Returns the fused version of the signature to use in order to run a HS firmware on this 30 /// falcon instance. `engine_id_mask` and `ucode_id` are obtained from the firmware header. 31 fn signature_reg_fuse_version( 32 &self, 33 falcon: &Falcon<E>, 34 bar: &Bar0, 35 engine_id_mask: u16, 36 ucode_id: u8, 37 ) -> Result<u32>; 38 39 /// Program the boot ROM registers prior to starting a secure firmware. 40 fn program_brom(&self, falcon: &Falcon<E>, bar: &Bar0, params: &FalconBromParams) -> Result; 41 42 /// Check if the RISC-V core is active. 43 /// Returns `true` if the RISC-V core is active, `false` otherwise. 44 fn is_riscv_active(&self, bar: &Bar0) -> bool; 45 46 /// Wait for memory scrubbing to complete. 47 fn reset_wait_mem_scrubbing(&self, bar: &Bar0) -> Result; 48 49 /// Reset the falcon engine. 50 fn reset_eng(&self, bar: &Bar0) -> Result; 51 } 52 53 /// Returns a boxed falcon HAL adequate for `chipset`. 54 /// 55 /// We use a heap-allocated trait object instead of a statically defined one because the 56 /// generic `FalconEngine` argument makes it difficult to define all the combinations 57 /// statically. 58 pub(super) fn falcon_hal<E: FalconEngine + 'static>( 59 chipset: Chipset, 60 ) -> Result<KBox<dyn FalconHal<E>>> { 61 use Chipset::*; 62 63 let hal = match chipset { 64 TU102 | TU104 | TU106 | TU116 | TU117 => { 65 KBox::new(tu102::Tu102::<E>::new(), GFP_KERNEL)? as KBox<dyn FalconHal<E>> 66 } 67 GA102 | GA103 | GA104 | GA106 | GA107 | AD102 | AD103 | AD104 | AD106 | AD107 => { 68 KBox::new(ga102::Ga102::<E>::new(), GFP_KERNEL)? as KBox<dyn FalconHal<E>> 69 } 70 _ => return Err(ENOTSUPP), 71 }; 72 73 Ok(hal) 74 } 75