// SPDX-License-Identifier: GPL-2.0 use kernel::{ io::{ poll::read_poll_timeout, register::{ RegisterBase, WithBase, // }, Io, }, prelude::*, time::Delta, // }; use crate::{ driver::Bar0, falcon::{ Falcon, FalconEngine, PFalcon2Base, PFalconBase, // }, regs, }; /// Pattern returned by GSP register reads while the PRIV target mask still blocks CPU access. const GSP_TARGET_MASK_LOCKED_PATTERN: u32 = 0xbadf_4100; const GSP_TARGET_MASK_LOCKED_MASK: u32 = 0xffff_ff00; /// Type specifying the `Gsp` falcon engine. Cannot be instantiated. pub(crate) struct Gsp(()); impl RegisterBase for Gsp { const BASE: usize = 0x00110000; } impl RegisterBase for Gsp { const BASE: usize = 0x00111000; } impl FalconEngine for Gsp {} impl Falcon { /// Clears the SWGEN0 bit in the Falcon's IRQ status clear register to /// allow GSP to signal CPU for processing new messages in message queue. pub(crate) fn clear_swgen0_intr(&self, bar: Bar0<'_>) { bar.write( WithBase::of::(), regs::NV_PFALCON_FALCON_IRQSCLR::zeroed().with_swgen0(true), ); } /// Checks if GSP reload/resume has completed during the boot process. pub(crate) fn check_reload_completed(&self, bar: Bar0<'_>, timeout: Delta) -> Result { read_poll_timeout( || Ok(bar.read(regs::NV_PGC6_BSI_SECURE_SCRATCH_14)), |val| val.boot_stage_3_handoff(), Delta::ZERO, timeout, ) .map(|_| true) } /// Returns whether the RISC-V branch privilege lockdown bit is set. pub(crate) fn riscv_branch_privilege_lockdown(&self, bar: Bar0<'_>) -> bool { bar.read(regs::NV_PFALCON_FALCON_HWCFG2::of::()) .riscv_br_priv_lockdown() } /// Returns whether GSP registers can be read by the CPU. pub(crate) fn priv_target_mask_released(&self, bar: Bar0<'_>) -> bool { let hwcfg2 = bar .read(regs::NV_PFALCON_FALCON_HWCFG2::of::()) .into_raw(); hwcfg2 != 0 && (hwcfg2 & GSP_TARGET_MASK_LOCKED_MASK) != GSP_TARGET_MASK_LOCKED_PATTERN } }