xref: /linux/drivers/gpu/nova-core/falcon/hal.rs (revision e54ad0cd3673c93cdafda58505eaa81610fe3aef)
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 
42 /// Returns a boxed falcon HAL adequate for `chipset`.
43 ///
44 /// We use a heap-allocated trait object instead of a statically defined one because the
45 /// generic `FalconEngine` argument makes it difficult to define all the combinations
46 /// statically.
47 pub(super) fn falcon_hal<E: FalconEngine + 'static>(
48     chipset: Chipset,
49 ) -> Result<KBox<dyn FalconHal<E>>> {
50     use Chipset::*;
51 
52     let hal = match chipset {
53         GA102 | GA103 | GA104 | GA106 | GA107 | AD102 | AD103 | AD104 | AD106 | AD107 => {
54             KBox::new(ga102::Ga102::<E>::new(), GFP_KERNEL)? as KBox<dyn FalconHal<E>>
55         }
56         _ => return Err(ENOTSUPP),
57     };
58 
59     Ok(hal)
60 }
61