1bbe5db76SAlexandre Courbot // SPDX-License-Identifier: GPL-2.0 2bbe5db76SAlexandre Courbot 3bbe5db76SAlexandre Courbot //! GPU Firmware (GFW) support. 4bbe5db76SAlexandre Courbot //! 5bbe5db76SAlexandre Courbot //! Upon reset, the GPU runs some firmware code from the BIOS to setup its core parameters. Most of 6bbe5db76SAlexandre Courbot //! the GPU is considered unusable until this step is completed, so we must wait on it before 7bbe5db76SAlexandre Courbot //! performing driver initialization. 8bbe5db76SAlexandre Courbot 9bbe5db76SAlexandre Courbot use core::time::Duration; 10bbe5db76SAlexandre Courbot 11bbe5db76SAlexandre Courbot use kernel::bindings; 12bbe5db76SAlexandre Courbot use kernel::prelude::*; 13bbe5db76SAlexandre Courbot 14bbe5db76SAlexandre Courbot use crate::driver::Bar0; 15bbe5db76SAlexandre Courbot use crate::regs; 16bbe5db76SAlexandre Courbot use crate::util; 17bbe5db76SAlexandre Courbot 18bbe5db76SAlexandre Courbot /// Wait until `GFW` (GPU Firmware) completes, or a 4 seconds timeout elapses. 19bbe5db76SAlexandre Courbot pub(crate) fn wait_gfw_boot_completion(bar: &Bar0) -> Result { 20bbe5db76SAlexandre Courbot // TIMEOUT: arbitrarily large value. GFW starts running immediately after the GPU is put out of 21bbe5db76SAlexandre Courbot // reset, and should complete in less time than that. 22bbe5db76SAlexandre Courbot util::wait_on(Duration::from_secs(4), || { 23bbe5db76SAlexandre Courbot // Check that FWSEC has lowered its protection level before reading the GFW_BOOT 24bbe5db76SAlexandre Courbot // status. 25bbe5db76SAlexandre Courbot let gfw_booted = regs::NV_PGC6_AON_SECURE_SCRATCH_GROUP_05_PRIV_LEVEL_MASK::read(bar) 26bbe5db76SAlexandre Courbot .read_protection_level0() 27bbe5db76SAlexandre Courbot && regs::NV_PGC6_AON_SECURE_SCRATCH_GROUP_05_0_GFW_BOOT::read(bar).completed(); 28bbe5db76SAlexandre Courbot 29bbe5db76SAlexandre Courbot if gfw_booted { 30bbe5db76SAlexandre Courbot Some(()) 31bbe5db76SAlexandre Courbot } else { 32*3606620bSAlexandre Courbot // TODO[DLAY]: replace with [1] once it merges. 33bbe5db76SAlexandre Courbot // [1] https://lore.kernel.org/rust-for-linux/20250423192857.199712-6-fujita.tomonori@gmail.com/ 34bbe5db76SAlexandre Courbot // 35bbe5db76SAlexandre Courbot // SAFETY: `msleep()` is safe to call with any parameter. 36bbe5db76SAlexandre Courbot unsafe { bindings::msleep(1) }; 37bbe5db76SAlexandre Courbot 38bbe5db76SAlexandre Courbot None 39bbe5db76SAlexandre Courbot } 40bbe5db76SAlexandre Courbot }) 41bbe5db76SAlexandre Courbot } 42