Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

gpu: nova-core: gsp: Boot GSP

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.

Reviewed-by: Lyude Paul <lyude@redhat.com>
Signed-off-by: Alistair Popple <apopple@nvidia.com>
Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
Message-ID: <20251110-gsp_boot-v9-15-8ae4058e3c0e@nvidia.com>

authored by

Alistair Popple and committed by
Alexandre Courbot
5949d419 945c1eee

+64 -6
-2
drivers/gpu/nova-core/falcon.rs
··· 616 616 /// Check if the RISC-V core is active. 617 617 /// 618 618 /// Returns `true` if the RISC-V core is active, `false` otherwise. 619 - #[expect(unused)] 620 619 pub(crate) fn is_riscv_active(&self, bar: &Bar0) -> bool { 621 620 let cpuctl = regs::NV_PRISCV_RISCV_CPUCTL::read(bar, &E::ID); 622 621 cpuctl.active_stat() 623 622 } 624 623 625 624 /// Write the application version to the OS register. 626 - #[expect(dead_code)] 627 625 pub(crate) fn write_os_version(&self, bar: &Bar0, app_version: u32) { 628 626 regs::NV_PFALCON_FALCON_OS::default() 629 627 .set_value(app_version)
+1 -2
drivers/gpu/nova-core/firmware/riscv.rs
··· 57 57 } 58 58 59 59 /// A parsed firmware for a RISC-V core, ready to be loaded and run. 60 - #[expect(unused)] 61 60 pub(crate) struct RiscvFirmware { 62 61 /// Offset at which the code starts in the firmware image. 63 62 pub(crate) code_offset: u32, ··· 65 66 /// Offset at which the manifest starts in the firmware image. 66 67 pub(crate) manifest_offset: u32, 67 68 /// Application version. 68 - app_version: u32, 69 + pub(crate) app_version: u32, 69 70 /// Device-mapped firmware image. 70 71 pub(crate) ucode: DmaObject, 71 72 }
+63 -2
drivers/gpu/nova-core/gsp/boot.rs
··· 4 4 device, 5 5 dma::CoherentAllocation, 6 6 dma_write, 7 + io::poll::read_poll_timeout, 7 8 pci, 8 - prelude::*, // 9 + prelude::*, 10 + time::Delta, // 9 11 }; 10 12 11 13 use crate::{ ··· 145 143 146 144 Self::run_fwsec_frts(dev, gsp_falcon, bar, &bios, &fb_layout)?; 147 145 148 - let _booter_loader = BooterFirmware::new( 146 + let booter_loader = BooterFirmware::new( 149 147 dev, 150 148 BooterKind::Loader, 151 149 chipset, ··· 161 159 self.cmdq 162 160 .send_command(bar, commands::SetSystemInfo::new(pdev))?; 163 161 self.cmdq.send_command(bar, commands::SetRegistry::new())?; 162 + 163 + gsp_falcon.reset(bar)?; 164 + let libos_handle = self.libos.dma_handle(); 165 + let (mbox0, mbox1) = gsp_falcon.boot( 166 + bar, 167 + Some(libos_handle as u32), 168 + Some((libos_handle >> 32) as u32), 169 + )?; 170 + dev_dbg!( 171 + pdev.as_ref(), 172 + "GSP MBOX0: {:#x}, MBOX1: {:#x}\n", 173 + mbox0, 174 + mbox1 175 + ); 176 + 177 + dev_dbg!( 178 + pdev.as_ref(), 179 + "Using SEC2 to load and run the booter_load firmware...\n" 180 + ); 181 + 182 + sec2_falcon.reset(bar)?; 183 + sec2_falcon.dma_load(bar, &booter_loader)?; 184 + let wpr_handle = wpr_meta.dma_handle(); 185 + let (mbox0, mbox1) = sec2_falcon.boot( 186 + bar, 187 + Some(wpr_handle as u32), 188 + Some((wpr_handle >> 32) as u32), 189 + )?; 190 + dev_dbg!( 191 + pdev.as_ref(), 192 + "SEC2 MBOX0: {:#x}, MBOX1{:#x}\n", 193 + mbox0, 194 + mbox1 195 + ); 196 + 197 + if mbox0 != 0 { 198 + dev_err!( 199 + pdev.as_ref(), 200 + "Booter-load failed with error {:#x}\n", 201 + mbox0 202 + ); 203 + return Err(ENODEV); 204 + } 205 + 206 + gsp_falcon.write_os_version(bar, gsp_fw.bootloader.app_version); 207 + 208 + // Poll for RISC-V to become active before running sequencer 209 + read_poll_timeout( 210 + || Ok(gsp_falcon.is_riscv_active(bar)), 211 + |val: &bool| *val, 212 + Delta::from_millis(10), 213 + Delta::from_secs(5), 214 + )?; 215 + 216 + dev_dbg!( 217 + pdev.as_ref(), 218 + "RISC-V active? {}\n", 219 + gsp_falcon.is_riscv_active(bar), 220 + ); 164 221 165 222 Ok(()) 166 223 }