Boot the GSP to the RISC-V active state. Completing the boot requires running the CPU sequencer which will be added in a future commit.
Signed-off-by: Alistair Popple <apop...@nvidia.com> --- drivers/gpu/nova-core/falcon.rs | 1 - drivers/gpu/nova-core/firmware.rs | 4 +- drivers/gpu/nova-core/firmware/riscv.rs | 3 +- drivers/gpu/nova-core/gpu.rs | 56 +++++++++++++++++++++++-- 4 files changed, 56 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/nova-core/falcon.rs b/drivers/gpu/nova-core/falcon.rs index 875804499b077..0c8ee7761f705 100644 --- a/drivers/gpu/nova-core/falcon.rs +++ b/drivers/gpu/nova-core/falcon.rs @@ -620,7 +620,6 @@ pub(crate) fn is_riscv_active(&self, bar: &Bar0) -> Result<bool> { } /// Write the application version to the OS register. - #[expect(dead_code)] pub(crate) fn write_os_version(&self, bar: &Bar0, app_version: u32) -> Result<()> { regs::NV_PFALCON_FALCON_OS::default() .set_value(app_version) diff --git a/drivers/gpu/nova-core/firmware.rs b/drivers/gpu/nova-core/firmware.rs index 6c210e668d541..d35f1affaa28d 100644 --- a/drivers/gpu/nova-core/firmware.rs +++ b/drivers/gpu/nova-core/firmware.rs @@ -115,11 +115,11 @@ pub(super) fn elf64_section<'a, 'b>(elf: &'a [u8], name: &'b str) -> Option<&'a } /// Structure encapsulating the firmware blobs required for the GPU to operate. -#[expect(dead_code)] pub(crate) struct Firmware { /// Runs on the sec2 falcon engine to load and start the GSP bootloader. - booter_loader: BooterFirmware, + pub booter_loader: BooterFirmware, /// Runs on the sec2 falcon engine to stop and unload a running GSP firmware. + #[expect(unused)] booter_unloader: BooterFirmware, /// GSP bootloader, verifies the GSP firmware before loading and running it. pub gsp_bootloader: RiscvFirmware, diff --git a/drivers/gpu/nova-core/firmware/riscv.rs b/drivers/gpu/nova-core/firmware/riscv.rs index 81bb348055031..b67e130e06cd6 100644 --- a/drivers/gpu/nova-core/firmware/riscv.rs +++ b/drivers/gpu/nova-core/firmware/riscv.rs @@ -50,7 +50,6 @@ fn new(bin_fw: &BinFirmware<'_>) -> Result<Self> { } /// A parsed firmware for a RISC-V core, ready to be loaded and run. -#[expect(unused)] pub(crate) struct RiscvFirmware { /// Offset at which the code starts in the firmware image. pub code_offset: u32, @@ -59,7 +58,7 @@ pub(crate) struct RiscvFirmware { /// Offset at which the manifest starts in the firmware image. pub manifest_offset: u32, /// Application version. - app_version: u32, + pub app_version: u32, /// Device-mapped firmware image. pub ucode: DmaObject, } diff --git a/drivers/gpu/nova-core/gpu.rs b/drivers/gpu/nova-core/gpu.rs index c070bd581e2c9..f86221a681e27 100644 --- a/drivers/gpu/nova-core/gpu.rs +++ b/drivers/gpu/nova-core/gpu.rs @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 -use kernel::{device, devres::Devres, error::code::*, pci, prelude::*, sync::Arc}; +use kernel::{device, devres::Devres, error::code::*, pci, prelude::*, sync::Arc, time::Delta}; use crate::driver::Bar0; use crate::falcon::{gsp::Gsp, sec2::Sec2, Falcon}; @@ -313,8 +313,58 @@ pub(crate) fn new( Self::run_fwsec_frts(pdev.as_ref(), &gsp_falcon, bar, &bios, &fb_layout)?; let libos = gsp::GspMemObjects::new(pdev, bar, &fw, &fb_layout)?; - let _libos_handle = libos.libos_dma_handle(); - let _wpr_handle = libos.wpr_meta.dma_handle(); + let libos_handle = libos.libos_dma_handle(); + let wpr_handle = libos.wpr_meta.dma_handle(); + + gsp_falcon.reset(bar)?; + let (mbox0, mbox1) = gsp_falcon.boot( + bar, + Some(libos_handle as u32), + Some((libos_handle >> 32) as u32), + )?; + dev_dbg!( + pdev.as_ref(), + "GSP MBOX0: {:#x}, MBOX1: {:#x}\n", + mbox0, + mbox1 + ); + + dev_dbg!( + pdev.as_ref(), + "Using SEC2 to load and run the booter_load firmware...\n" + ); + + sec2_falcon.reset(bar)?; + sec2_falcon.dma_load(bar, &fw.booter_loader)?; + let (mbox0, mbox1) = sec2_falcon.boot( + bar, + Some(wpr_handle as u32), + Some((wpr_handle >> 32) as u32), + )?; + dev_dbg!( + pdev.as_ref(), + "SEC2 MBOX0: {:#x}, MBOX1{:#x}\n", + mbox0, + mbox1 + ); + + // Match what Nouveau does here: + gsp_falcon.write_os_version(bar, fw.gsp_bootloader.app_version)?; + + // Poll for RISC-V to become active before running sequencer + util::wait_on(Delta::from_secs(5), || { + if gsp_falcon.is_riscv_active(bar).unwrap_or(false) { + Some(()) + } else { + None + } + })?; + + dev_dbg!( + pdev.as_ref(), + "RISC-V active? {}\n", + gsp_falcon.is_riscv_active(bar)?, + ); Ok(pin_init!(Self { spec, -- 2.47.2