hal.rs 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. // SPDX-License-Identifier: GPL-2.0
  2. use kernel::prelude::*;
  3. use crate::{
  4. driver::Bar0,
  5. falcon::{
  6. Falcon,
  7. FalconBromParams,
  8. FalconEngine, //
  9. },
  10. gpu::Chipset,
  11. };
  12. mod ga102;
  13. mod tu102;
  14. /// Method used to load data into falcon memory. Some GPU architectures need
  15. /// PIO and others can use DMA.
  16. pub(crate) enum LoadMethod {
  17. /// Programmed I/O
  18. Pio,
  19. /// Direct Memory Access
  20. Dma,
  21. }
  22. /// Hardware Abstraction Layer for Falcon cores.
  23. ///
  24. /// Implements chipset-specific low-level operations. The trait is generic against [`FalconEngine`]
  25. /// so its `BASE` parameter can be used in order to avoid runtime bound checks when accessing
  26. /// registers.
  27. pub(crate) trait FalconHal<E: FalconEngine>: Send + Sync {
  28. /// Activates the Falcon core if the engine is a risvc/falcon dual engine.
  29. fn select_core(&self, _falcon: &Falcon<E>, _bar: &Bar0) -> Result {
  30. Ok(())
  31. }
  32. /// Returns the fused version of the signature to use in order to run a HS firmware on this
  33. /// falcon instance. `engine_id_mask` and `ucode_id` are obtained from the firmware header.
  34. fn signature_reg_fuse_version(
  35. &self,
  36. falcon: &Falcon<E>,
  37. bar: &Bar0,
  38. engine_id_mask: u16,
  39. ucode_id: u8,
  40. ) -> Result<u32>;
  41. /// Program the boot ROM registers prior to starting a secure firmware.
  42. fn program_brom(&self, falcon: &Falcon<E>, bar: &Bar0, params: &FalconBromParams) -> Result;
  43. /// Check if the RISC-V core is active.
  44. /// Returns `true` if the RISC-V core is active, `false` otherwise.
  45. fn is_riscv_active(&self, bar: &Bar0) -> bool;
  46. /// Wait for memory scrubbing to complete.
  47. fn reset_wait_mem_scrubbing(&self, bar: &Bar0) -> Result;
  48. /// Reset the falcon engine.
  49. fn reset_eng(&self, bar: &Bar0) -> Result;
  50. /// returns the method needed to load data into Falcon memory
  51. fn load_method(&self) -> LoadMethod;
  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. let hal = match chipset {
  63. TU102 | TU104 | TU106 | TU116 | TU117 => {
  64. KBox::new(tu102::Tu102::<E>::new(), GFP_KERNEL)? as KBox<dyn FalconHal<E>>
  65. }
  66. GA102 | GA103 | GA104 | GA106 | GA107 | AD102 | AD103 | AD104 | AD106 | AD107 => {
  67. KBox::new(ga102::Ga102::<E>::new(), GFP_KERNEL)? as KBox<dyn FalconHal<E>>
  68. }
  69. _ => return Err(ENOTSUPP),
  70. };
  71. Ok(hal)
  72. }