1 // SPDX-License-Identifier: GPL-2.0
2
3 use kernel::prelude::*;
4
5 use crate::driver::Bar0;
6 use crate::falcon::{Falcon, FalconBromParams, FalconEngine};
7 use crate::gpu::Chipset;
8
9 mod ga102;
10
11 /// Hardware Abstraction Layer for Falcon cores.
12 ///
13 /// Implements chipset-specific low-level operations. The trait is generic against [`FalconEngine`]
14 /// so its `BASE` parameter can be used in order to avoid runtime bound checks when accessing
15 /// registers.
16 pub(crate) trait FalconHal<E: FalconEngine>: Sync {
17 /// Activates the Falcon core if the engine is a risvc/falcon dual engine.
select_core(&self, _falcon: &Falcon<E>, _bar: &Bar0) -> Result18 fn select_core(&self, _falcon: &Falcon<E>, _bar: &Bar0) -> Result {
19 Ok(())
20 }
21
22 /// Returns the fused version of the signature to use in order to run a HS firmware on this
23 /// falcon instance. `engine_id_mask` and `ucode_id` are obtained from the firmware header.
signature_reg_fuse_version( &self, falcon: &Falcon<E>, bar: &Bar0, engine_id_mask: u16, ucode_id: u8, ) -> Result<u32>24 fn signature_reg_fuse_version(
25 &self,
26 falcon: &Falcon<E>,
27 bar: &Bar0,
28 engine_id_mask: u16,
29 ucode_id: u8,
30 ) -> Result<u32>;
31
32 /// Program the boot ROM registers prior to starting a secure firmware.
program_brom(&self, falcon: &Falcon<E>, bar: &Bar0, params: &FalconBromParams) -> Result33 fn program_brom(&self, falcon: &Falcon<E>, bar: &Bar0, params: &FalconBromParams) -> Result;
34 }
35
36 /// Returns a boxed falcon HAL adequate for `chipset`.
37 ///
38 /// We use a heap-allocated trait object instead of a statically defined one because the
39 /// generic `FalconEngine` argument makes it difficult to define all the combinations
40 /// statically.
falcon_hal<E: FalconEngine + 'static>( chipset: Chipset, ) -> Result<KBox<dyn FalconHal<E>>>41 pub(super) fn falcon_hal<E: FalconEngine + 'static>(
42 chipset: Chipset,
43 ) -> Result<KBox<dyn FalconHal<E>>> {
44 use Chipset::*;
45
46 let hal = match chipset {
47 GA102 | GA103 | GA104 | GA106 | GA107 => {
48 KBox::new(ga102::Ga102::<E>::new(), GFP_KERNEL)? as KBox<dyn FalconHal<E>>
49 }
50 _ => return Err(ENOTSUPP),
51 };
52
53 Ok(hal)
54 }
55