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