1 // SPDX-License-Identifier: GPL-2.0 2 3 use core::marker::PhantomData; 4 5 use kernel::{ 6 io::{ 7 poll::read_poll_timeout, 8 Io, // 9 }, 10 prelude::*, 11 time::Delta, // 12 }; 13 14 use crate::{ 15 falcon::{ 16 hal::LoadMethod, 17 Falcon, 18 FalconBromParams, 19 FalconEngine, // 20 }, 21 regs, // 22 }; 23 24 use super::FalconHal; 25 26 pub(super) struct Tu102<E: FalconEngine>(PhantomData<E>); 27 28 impl<E: FalconEngine> Tu102<E> { 29 pub(super) fn new() -> Self { 30 Self(PhantomData) 31 } 32 } 33 34 impl<E: FalconEngine> FalconHal<E> for Tu102<E> { 35 fn select_core(&self, _falcon: &Falcon<'_, E>) -> Result { 36 Ok(()) 37 } 38 39 fn signature_reg_fuse_version( 40 &self, 41 _falcon: &Falcon<'_, E>, 42 _engine_id_mask: u16, 43 _ucode_id: u8, 44 ) -> Result<u32> { 45 Ok(0) 46 } 47 48 fn program_brom(&self, _falcon: &Falcon<'_, E>, _params: &FalconBromParams) {} 49 50 fn is_riscv_active(&self, falcon: &Falcon<'_, E>) -> bool { 51 falcon 52 .pfalcon2 53 .read(regs::NV_PRISCV_RISCV_CORE_SWITCH_RISCV_STATUS) 54 .active_stat() 55 } 56 57 fn is_riscv_halted(&self, _falcon: &Falcon<'_, E>) -> Result<bool> { 58 Err(ENOTSUPP) 59 } 60 61 fn reset_wait_mem_scrubbing(&self, falcon: &Falcon<'_, E>) -> Result { 62 // TIMEOUT: memory scrubbing should complete in less than 10ms. 63 read_poll_timeout( 64 || Ok(falcon.pfalcon.read(regs::NV_PFALCON_FALCON_DMACTL)), 65 |r| r.mem_scrubbing_done(), 66 Delta::ZERO, 67 Delta::from_millis(10), 68 ) 69 .map(|_| ()) 70 } 71 72 fn reset_eng(&self, falcon: &Falcon<'_, E>) -> Result { 73 regs::NV_PFALCON_FALCON_ENGINE::reset_engine(falcon.pfalcon); 74 self.reset_wait_mem_scrubbing(falcon)?; 75 76 Ok(()) 77 } 78 79 fn load_method(&self) -> LoadMethod { 80 LoadMethod::Pio 81 } 82 } 83