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