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