The GSP boot path threads pdev, bar, chipset, gsp_falcon and sec2_falcon individually through boot() -> run_fwsec_frts() -> sequencer.
Bundle them into a GspBootContext struct to cut down on parameter passing and the associated import boilerplate. It is for easily introducing other boot params like vGPU enable, WRP size in future. No functional change is intended. Signed-off-by: Zhi Wang <[email protected]> --- drivers/gpu/nova-core/gpu.rs | 16 ++++- drivers/gpu/nova-core/gsp.rs | 22 ++++++ drivers/gpu/nova-core/gsp/boot.rs | 97 ++++++++++---------------- drivers/gpu/nova-core/gsp/sequencer.rs | 71 ++++++++----------- 4 files changed, 99 insertions(+), 107 deletions(-) diff --git a/drivers/gpu/nova-core/gpu.rs b/drivers/gpu/nova-core/gpu.rs index 9b042ef1a308..61a90ebad7f8 100644 --- a/drivers/gpu/nova-core/gpu.rs +++ b/drivers/gpu/nova-core/gpu.rs @@ -18,7 +18,10 @@ }, fb::SysmemFlush, gfw, - gsp::Gsp, + gsp::{ + Gsp, + GspBootContext, // + }, regs, }; @@ -283,7 +286,16 @@ pub(crate) fn new<'a>( gsp <- Gsp::new(pdev), - _: { gsp.boot(pdev, bar, spec.chipset, gsp_falcon, sec2_falcon)? }, + _: { + let ctx = GspBootContext { + pdev, + bar, + chipset: spec.chipset, + gsp_falcon, + sec2_falcon, + }; + gsp.boot(&ctx)? + }, bar: devres_bar, }) diff --git a/drivers/gpu/nova-core/gsp.rs b/drivers/gpu/nova-core/gsp.rs index 174feaca0a6b..afb8304286d3 100644 --- a/drivers/gpu/nova-core/gsp.rs +++ b/drivers/gpu/nova-core/gsp.rs @@ -25,6 +25,13 @@ }; use crate::{ + driver::Bar0, + falcon::{ + gsp::Gsp as GspFalcon, + sec2::Sec2 as Sec2Falcon, + Falcon, // + }, + gpu::Chipset, gsp::cmdq::Cmdq, gsp::fw::{ GspArgumentsPadded, @@ -39,6 +46,21 @@ /// Number of GSP pages to use in a RM log buffer. const RM_LOG_BUFFER_NUM_PAGES: usize = 0x10; +/// Common context for the GSP boot process. +pub(crate) struct GspBootContext<'a> { + pub(crate) pdev: &'a pci::Device<device::Bound>, + pub(crate) bar: &'a Bar0, + pub(crate) chipset: Chipset, + pub(crate) gsp_falcon: &'a Falcon<GspFalcon>, + pub(crate) sec2_falcon: &'a Falcon<Sec2Falcon>, +} + +impl GspBootContext<'_> { + pub(crate) fn dev(&self) -> &device::Device<device::Bound> { + self.pdev.as_ref() + } +} + /// Array of page table entries, as understood by the GSP bootloader. #[repr(C)] struct PteArray<const NUM_ENTRIES: usize>([u64; NUM_ENTRIES]); diff --git a/drivers/gpu/nova-core/gsp/boot.rs b/drivers/gpu/nova-core/gsp/boot.rs index be427fe26a58..a294d89fab0e 100644 --- a/drivers/gpu/nova-core/gsp/boot.rs +++ b/drivers/gpu/nova-core/gsp/boot.rs @@ -1,22 +1,14 @@ // SPDX-License-Identifier: GPL-2.0 use kernel::{ - device, dma::CoherentAllocation, dma_write, io::poll::read_poll_timeout, - pci, prelude::*, time::Delta, // }; use crate::{ - driver::Bar0, - falcon::{ - gsp::Gsp, - sec2::Sec2, - Falcon, // - }, fb::FbLayout, firmware::{ booter::{ @@ -30,7 +22,6 @@ gsp::GspFirmware, FIRMWARE_VERSION, // }, - gpu::Chipset, gsp::{ commands, sequencer::{ @@ -47,12 +38,13 @@ impl super::Gsp { /// Helper function to load and run the FWSEC-FRTS firmware and confirm that it has properly /// created the WPR2 region. fn run_fwsec_frts( - dev: &device::Device<device::Bound>, - falcon: &Falcon<Gsp>, - bar: &Bar0, + ctx: &super::GspBootContext<'_>, bios: &Vbios, fb_layout: &FbLayout, ) -> Result<()> { + let dev = ctx.dev(); + let bar = ctx.bar; + // Check that the WPR2 region does not already exists - if it does, we cannot run // FWSEC-FRTS until the GPU is reset. if regs::NV_PFB_PRI_MMU_WPR2_ADDR_HI::read(bar).higher_bound() != 0 { @@ -65,7 +57,7 @@ fn run_fwsec_frts( let fwsec_frts = FwsecFirmware::new( dev, - falcon, + ctx.gsp_falcon, bar, bios, FwsecCommand::Frts { @@ -75,7 +67,7 @@ fn run_fwsec_frts( )?; // Run FWSEC-FRTS to create the WPR2 region. - fwsec_frts.run(dev, falcon, bar)?; + fwsec_frts.run(dev, ctx.gsp_falcon, bar)?; // SCRATCH_E contains the error code for FWSEC-FRTS. let frts_status = regs::NV_PBUS_SW_SCRATCH_0E_FRTS_ERR::read(bar).frts_err_code(); @@ -127,31 +119,28 @@ fn run_fwsec_frts( /// structures that the GSP will use at runtime. /// /// Upon return, the GSP is up and running, and its runtime object given as return value. - pub(crate) fn boot( - mut self: Pin<&mut Self>, - pdev: &pci::Device<device::Bound>, - bar: &Bar0, - chipset: Chipset, - gsp_falcon: &Falcon<Gsp>, - sec2_falcon: &Falcon<Sec2>, - ) -> Result { - let dev = pdev.as_ref(); + pub(crate) fn boot(mut self: Pin<&mut Self>, ctx: &super::GspBootContext<'_>) -> Result { + let dev = ctx.dev(); + let bar = ctx.bar; let bios = Vbios::new(dev, bar)?; - let gsp_fw = KBox::pin_init(GspFirmware::new(dev, chipset, FIRMWARE_VERSION), GFP_KERNEL)?; + let gsp_fw = KBox::pin_init( + GspFirmware::new(dev, ctx.chipset, FIRMWARE_VERSION), + GFP_KERNEL, + )?; - let fb_layout = FbLayout::new(chipset, bar, &gsp_fw)?; + let fb_layout = FbLayout::new(ctx.chipset, bar, &gsp_fw)?; dev_dbg!(dev, "{:#x?}\n", fb_layout); - Self::run_fwsec_frts(dev, gsp_falcon, bar, &bios, &fb_layout)?; + Self::run_fwsec_frts(ctx, &bios, &fb_layout)?; let booter_loader = BooterFirmware::new( dev, BooterKind::Loader, - chipset, + ctx.chipset, FIRMWARE_VERSION, - sec2_falcon, + ctx.sec2_falcon, bar, )?; @@ -160,76 +149,60 @@ pub(crate) fn boot( dma_write!(wpr_meta[0] = GspFwWprMeta::new(&gsp_fw, &fb_layout))?; self.cmdq - .send_command(bar, commands::SetSystemInfo::new(pdev))?; + .send_command(bar, commands::SetSystemInfo::new(ctx.pdev))?; self.cmdq.send_command(bar, commands::SetRegistry::new())?; - gsp_falcon.reset(bar)?; + ctx.gsp_falcon.reset(bar)?; let libos_handle = self.libos.dma_handle(); - let (mbox0, mbox1) = gsp_falcon.boot( + let (mbox0, mbox1) = ctx.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!(dev, "GSP MBOX0: {:#x}, MBOX1: {:#x}\n", mbox0, mbox1); dev_dbg!( - pdev.as_ref(), + dev, "Using SEC2 to load and run the booter_load firmware...\n" ); - sec2_falcon.reset(bar)?; - sec2_falcon.load(bar, &booter_loader)?; + ctx.sec2_falcon.reset(bar)?; + ctx.sec2_falcon.load(bar, &booter_loader)?; let wpr_handle = wpr_meta.dma_handle(); - let (mbox0, mbox1) = sec2_falcon.boot( + let (mbox0, mbox1) = ctx.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 - ); + dev_dbg!(dev, "SEC2 MBOX0: {:#x}, MBOX1{:#x}\n", mbox0, mbox1); if mbox0 != 0 { - dev_err!( - pdev.as_ref(), - "Booter-load failed with error {:#x}\n", - mbox0 - ); + dev_err!(dev, "Booter-load failed with error {:#x}\n", mbox0); return Err(ENODEV); } - gsp_falcon.write_os_version(bar, gsp_fw.bootloader.app_version); + ctx.gsp_falcon + .write_os_version(bar, gsp_fw.bootloader.app_version); // Poll for RISC-V to become active before running sequencer read_poll_timeout( - || Ok(gsp_falcon.is_riscv_active(bar)), + || Ok(ctx.gsp_falcon.is_riscv_active(bar)), |val: &bool| *val, Delta::from_millis(10), Delta::from_secs(5), )?; dev_dbg!( - pdev.as_ref(), + dev, "RISC-V active? {}\n", - gsp_falcon.is_riscv_active(bar), + ctx.gsp_falcon.is_riscv_active(bar), ); // Create and run the GSP sequencer. let seq_params = GspSequencerParams { + ctx, bootloader_app_version: gsp_fw.bootloader.app_version, libos_dma_handle: libos_handle, - gsp_falcon, - sec2_falcon, - dev: pdev.as_ref().into(), - bar, }; GspSequencer::run(&mut self.cmdq, seq_params)?; @@ -239,8 +212,8 @@ pub(crate) fn boot( // Obtain and display basic GPU information. let info = commands::get_gsp_info(&mut self.cmdq, bar)?; match info.gpu_name() { - Ok(name) => dev_info!(pdev.as_ref(), "GPU name: {}\n", name), - Err(e) => dev_warn!(pdev.as_ref(), "GPU name unavailable: {:?}\n", e), + Ok(name) => dev_info!(dev, "GPU name: {}\n", name), + Err(e) => dev_warn!(dev, "GPU name unavailable: {:?}\n", e), } Ok(()) diff --git a/drivers/gpu/nova-core/gsp/sequencer.rs b/drivers/gpu/nova-core/gsp/sequencer.rs index d6c489c39092..b274ac7b2e05 100644 --- a/drivers/gpu/nova-core/gsp/sequencer.rs +++ b/drivers/gpu/nova-core/gsp/sequencer.rs @@ -23,12 +23,6 @@ }; use crate::{ - driver::Bar0, - falcon::{ - gsp::Gsp, - sec2::Sec2, - Falcon, // - }, gsp::{ cmdq::{ Cmdq, @@ -133,12 +127,8 @@ pub(crate) fn new(data: &[u8], dev: &device::Device) -> Result<(Self, usize)> { pub(crate) struct GspSequencer<'a> { /// Sequencer information with command data. seq_info: GspSequence, - /// `Bar0` for register access. - bar: &'a Bar0, - /// SEC2 falcon for core operations. - sec2_falcon: &'a Falcon<Sec2>, - /// GSP falcon for core operations. - gsp_falcon: &'a Falcon<Gsp>, + /// GSP boot context. + ctx: &'a super::GspBootContext<'a>, /// LibOS DMA handle address. libos_dma_handle: u64, /// Bootloader application version. @@ -156,7 +146,7 @@ impl GspSeqCmdRunner for fw::RegWritePayload { fn run(&self, sequencer: &GspSequencer<'_>) -> Result { let addr = usize::from_safe_cast(self.addr()); - sequencer.bar.try_write32(self.val(), addr) + sequencer.ctx.bar.try_write32(self.val(), addr) } } @@ -164,8 +154,9 @@ impl GspSeqCmdRunner for fw::RegModifyPayload { fn run(&self, sequencer: &GspSequencer<'_>) -> Result { let addr = usize::from_safe_cast(self.addr()); - sequencer.bar.try_read32(addr).and_then(|val| { + sequencer.ctx.bar.try_read32(addr).and_then(|val| { sequencer + .ctx .bar .try_write32((val & !self.mask()) | self.val(), addr) }) @@ -184,11 +175,11 @@ fn run(&self, sequencer: &GspSequencer<'_>) -> Result { }; // First read. - sequencer.bar.try_read32(addr)?; + sequencer.ctx.bar.try_read32(addr)?; // Poll the requested register with requested timeout. read_poll_timeout( - || sequencer.bar.try_read32(addr), + || sequencer.ctx.bar.try_read32(addr), |current| (current & self.mask()) == self.val(), Delta::ZERO, Delta::from_micros(timeout_us), @@ -208,7 +199,7 @@ impl GspSeqCmdRunner for fw::RegStorePayload { fn run(&self, sequencer: &GspSequencer<'_>) -> Result { let addr = usize::from_safe_cast(self.addr()); - sequencer.bar.try_read32(addr).map(|_| ()) + sequencer.ctx.bar.try_read32(addr).map(|_| ()) } } @@ -221,16 +212,16 @@ fn run(&self, seq: &GspSequencer<'_>) -> Result { GspSeqCmd::DelayUs(cmd) => cmd.run(seq), GspSeqCmd::RegStore(cmd) => cmd.run(seq), GspSeqCmd::CoreReset => { - seq.gsp_falcon.reset(seq.bar)?; - seq.gsp_falcon.dma_reset(seq.bar); + seq.ctx.gsp_falcon.reset(seq.ctx.bar)?; + seq.ctx.gsp_falcon.dma_reset(seq.ctx.bar); Ok(()) } GspSeqCmd::CoreStart => { - seq.gsp_falcon.start(seq.bar)?; + seq.ctx.gsp_falcon.start(seq.ctx.bar)?; Ok(()) } GspSeqCmd::CoreWaitForHalt => { - seq.gsp_falcon.wait_till_halted(seq.bar)?; + seq.ctx.gsp_falcon.wait_till_halted(seq.ctx.bar)?; Ok(()) } GspSeqCmd::CoreResume => { @@ -239,35 +230,37 @@ fn run(&self, seq: &GspSequencer<'_>) -> Result { // sequencer will start both. // Reset the GSP to prepare it for resuming. - seq.gsp_falcon.reset(seq.bar)?; + seq.ctx.gsp_falcon.reset(seq.ctx.bar)?; // Write the libOS DMA handle to GSP mailboxes. - seq.gsp_falcon.write_mailboxes( - seq.bar, + seq.ctx.gsp_falcon.write_mailboxes( + seq.ctx.bar, Some(seq.libos_dma_handle as u32), Some((seq.libos_dma_handle >> 32) as u32), ); // Start the SEC2 falcon which will trigger GSP-RM to resume on the GSP. - seq.sec2_falcon.start(seq.bar)?; + seq.ctx.sec2_falcon.start(seq.ctx.bar)?; // Poll until GSP-RM reload/resume has completed (up to 2 seconds). - seq.gsp_falcon - .check_reload_completed(seq.bar, Delta::from_secs(2))?; + seq.ctx + .gsp_falcon + .check_reload_completed(seq.ctx.bar, Delta::from_secs(2))?; // Verify SEC2 completed successfully by checking its mailbox for errors. - let mbox0 = seq.sec2_falcon.read_mailbox0(seq.bar); + let mbox0 = seq.ctx.sec2_falcon.read_mailbox0(seq.ctx.bar); if mbox0 != 0 { dev_err!(seq.dev, "Sequencer: sec2 errors: {:?}\n", mbox0); return Err(EIO); } // Configure GSP with the bootloader version. - seq.gsp_falcon - .write_os_version(seq.bar, seq.bootloader_app_version); + seq.ctx + .gsp_falcon + .write_os_version(seq.ctx.bar, seq.bootloader_app_version); // Verify the GSP's RISC-V core is active indicating successful GSP boot. - if !seq.gsp_falcon.is_riscv_active(seq.bar) { + if !seq.ctx.gsp_falcon.is_riscv_active(seq.ctx.bar) { dev_err!(seq.dev, "Sequencer: RISC-V core is not active\n"); return Err(EIO); } @@ -348,18 +341,12 @@ fn iter(&self) -> GspSeqIter<'_> { /// Parameters for running the GSP sequencer. pub(crate) struct GspSequencerParams<'a> { + /// Shared boot context. + pub(crate) ctx: &'a super::GspBootContext<'a>, /// Bootloader application version. pub(crate) bootloader_app_version: u32, /// LibOS DMA handle address. pub(crate) libos_dma_handle: u64, - /// GSP falcon for core operations. - pub(crate) gsp_falcon: &'a Falcon<Gsp>, - /// SEC2 falcon for core operations. - pub(crate) sec2_falcon: &'a Falcon<Sec2>, - /// Device for logging. - pub(crate) dev: ARef<device::Device>, - /// BAR0 for register access. - pub(crate) bar: &'a Bar0, } impl<'a> GspSequencer<'a> { @@ -374,12 +361,10 @@ pub(crate) fn run(cmdq: &mut Cmdq, params: GspSequencerParams<'a>) -> Result { let sequencer = GspSequencer { seq_info, - bar: params.bar, - sec2_falcon: params.sec2_falcon, - gsp_falcon: params.gsp_falcon, + ctx: params.ctx, libos_dma_handle: params.libos_dma_handle, bootloader_app_version: params.bootloader_app_version, - dev: params.dev, + dev: params.ctx.pdev.as_ref().into(), }; dev_dbg!(sequencer.dev, "Running CPU Sequencer commands\n"); -- 2.51.0
