`GspBootContext` contains the resources required to boot the GSP. As it turns out, this is also the context required for unloading it.
Reflect that fact by replacing the arguments of `Gsp::unload` with the `GspBootContext`. This symmetry between `Gsp::boot` and `Gsp::unload` will also be convenient when we want to make these methods generic over the boot context corresponding to the boot method used. Signed-off-by: Alexandre Courbot <[email protected]> --- drivers/gpu/nova-core/gpu.rs | 19 ++++++++++++++++--- drivers/gpu/nova-core/gsp/boot.rs | 17 +++++++---------- drivers/gpu/nova-core/gsp/hal.rs | 15 +-------------- drivers/gpu/nova-core/gsp/hal/gh100.rs | 13 +++---------- drivers/gpu/nova-core/gsp/hal/tu102.rs | 20 +++++++++----------- 5 files changed, 36 insertions(+), 48 deletions(-) diff --git a/drivers/gpu/nova-core/gpu.rs b/drivers/gpu/nova-core/gpu.rs index a34114d3afcb..7918ebb508f9 100644 --- a/drivers/gpu/nova-core/gpu.rs +++ b/drivers/gpu/nova-core/gpu.rs @@ -268,7 +268,9 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { #[pin_data(PinnedDrop)] struct GspResources<'gpu> { /// Device owning the GPU. - device: &'gpu device::Device<device::Bound>, + device: &'gpu pci::Device<device::Bound>, + /// Details about the chipset. + spec: Spec, /// MMIO mapping of PCI BAR 0. bar: Bar0<'gpu>, /// GSP falcon instance, used for GSP boot up and cleanup. @@ -311,7 +313,16 @@ fn drop(self: Pin<&mut Self>) { .gsp .as_ref() .get_ref() - .unload(device, bar, &*this.gsp_falcon, &*this.sec2_falcon, bundle) + .unload( + GspBootContext { + pdev: device, + bar, + chipset: this.spec.chipset, + gsp_falcon: &*this.gsp_falcon, + sec2_falcon: &*this.sec2_falcon, + }, + bundle, + ) .inspect_err(|e| dev_err!(device, "failed to unload GSP: {:?}\n", e)); } } @@ -343,7 +354,9 @@ pub(crate) fn new( sysmem_flush: SysmemFlush::register(pdev.as_ref(), bar, spec.chipset)?, gsp_resources <- try_pin_init!(GspResources { - device: pdev.as_ref(), + device: pdev, + + spec: *spec, bar, diff --git a/drivers/gpu/nova-core/gsp/boot.rs b/drivers/gpu/nova-core/gsp/boot.rs index 3f11eaec26c7..336ad23c96f9 100644 --- a/drivers/gpu/nova-core/gsp/boot.rs +++ b/drivers/gpu/nova-core/gsp/boot.rs @@ -3,7 +3,6 @@ use kernel::{ bits, - device, dma::Coherent, io::poll::read_poll_timeout, prelude::*, @@ -14,7 +13,6 @@ driver::Bar0, falcon::{ gsp::Gsp, - sec2::Sec2, Falcon, // }, fb::FbLayout, @@ -102,7 +100,7 @@ pub(crate) fn boot( dev_err!(dev, "GSP boot failed with error {:?}\n", e); // Ignore errors during unload; we will return the error that happened during boot. - let _ = self.unload(dev, bar, gsp_falcon, ctx.sec2_falcon, unload_bundle); + let _ = self.unload(ctx, unload_bundle); Err(e) } @@ -136,17 +134,16 @@ fn shutdown_gsp( /// This stops all activity on the GSP. pub(crate) fn unload( &self, - dev: &device::Device<device::Bound>, - bar: Bar0<'_>, - gsp_falcon: &Falcon<Gsp>, - sec2_falcon: &Falcon<Sec2>, + ctx: super::GspBootContext<'_>, unload_bundle: Option<super::UnloadBundle>, ) -> Result { + let dev = ctx.dev(); + // Shut down the GSP. Keep going even in case of error. let mut res = Self::shutdown_gsp( &self.cmdq, - bar, - gsp_falcon, + ctx.bar, + ctx.gsp_falcon, commands::PowerStateLevel::Level0, ) .inspect_err(|e| dev_err!(dev, "GSP shutdown failed: {:?}\n", e)); @@ -156,7 +153,7 @@ pub(crate) fn unload( res = res.and( unload_bundle .0 - .run(dev, bar, gsp_falcon, sec2_falcon) + .run(&ctx) .inspect_err(|e| dev_err!(dev, "Unload bundle failed: {:?}\n", e)), ); } else { diff --git a/drivers/gpu/nova-core/gsp/hal.rs b/drivers/gpu/nova-core/gsp/hal.rs index 00e39cc1fbde..113d445239b9 100644 --- a/drivers/gpu/nova-core/gsp/hal.rs +++ b/drivers/gpu/nova-core/gsp/hal.rs @@ -5,18 +5,11 @@ mod tu102; use kernel::{ - device, dma::Coherent, prelude::*, // }; use crate::{ - driver::Bar0, - falcon::{ - gsp::Gsp as GspEngine, - sec2::Sec2, - Falcon, // - }, fb::FbLayout, firmware::gsp::GspFirmware, gpu::{ @@ -37,13 +30,7 @@ /// required for unloading is prepared at load time, and stored here until it needs to be run. pub(super) trait UnloadBundle: Send { /// Performs the steps required to properly reset the GSP after it has been stopped. - fn run( - &self, - dev: &device::Device<device::Bound>, - bar: Bar0<'_>, - gsp_falcon: &Falcon<GspEngine>, - sec2_falcon: &Falcon<Sec2>, - ) -> Result; + fn run(&self, ctx: &GspBootContext<'_>) -> Result; } /// Trait implemented by GSP HALs. diff --git a/drivers/gpu/nova-core/gsp/hal/gh100.rs b/drivers/gpu/nova-core/gsp/hal/gh100.rs index 02203dfd3584..a87d526d2310 100644 --- a/drivers/gpu/nova-core/gsp/hal/gh100.rs +++ b/drivers/gpu/nova-core/gsp/hal/gh100.rs @@ -14,7 +14,6 @@ driver::Bar0, falcon::{ gsp::Gsp as GspEngine, - sec2::Sec2, Falcon, // }, fb::FbLayout, @@ -118,22 +117,16 @@ fn wait_for_gsp_lockdown_release( struct FspUnloadBundle; impl UnloadBundle for FspUnloadBundle { - fn run( - &self, - dev: &device::Device<device::Bound>, - bar: Bar0<'_>, - gsp_falcon: &Falcon<GspEngine>, - _sec2_falcon: &Falcon<Sec2>, - ) -> Result { + fn run(&self, ctx: &GspBootContext<'_>) -> Result { // GSP falcon does most of the work of resetting, so just wait for it to finish. read_poll_timeout( - || Ok(gsp_falcon.is_riscv_active(bar)), + || Ok(ctx.gsp_falcon.is_riscv_active(ctx.bar)), |&active| !active, Delta::from_millis(10), Delta::from_secs(5), ) .map(|_| ()) - .inspect_err(|_| dev_err!(dev, "GSP falcon failed to halt\n")) + .inspect_err(|_| dev_err!(ctx.dev(), "GSP falcon failed to halt\n")) } } diff --git a/drivers/gpu/nova-core/gsp/hal/tu102.rs b/drivers/gpu/nova-core/gsp/hal/tu102.rs index 984716fc0bf9..7cb322b0e31d 100644 --- a/drivers/gpu/nova-core/gsp/hal/tu102.rs +++ b/drivers/gpu/nova-core/gsp/hal/tu102.rs @@ -123,18 +123,15 @@ fn build( } impl UnloadBundle for Sec2UnloadBundle { - fn run( - &self, - dev: &device::Device<device::Bound>, - bar: Bar0<'_>, - gsp_falcon: &Falcon<GspEngine>, - sec2_falcon: &Falcon<Sec2>, - ) -> Result { + fn run(&self, ctx: &GspBootContext<'_>) -> Result { + let dev = ctx.dev(); + let bar = ctx.bar; + // Run FWSEC-SB to reset the GSP falcon to its pre-libos state. // Log errors but keep going if it fails. let fwsec_sb_res = self .fwsec_sb - .run(dev, bar, gsp_falcon) + .run(dev, bar, ctx.gsp_falcon) .inspect_err(|e| dev_err!(dev, "FWSEC-SB failed to run: {:?}\n", e)); // Remove WPR2 region if set. @@ -144,13 +141,14 @@ fn run( return Ok(()); } - sec2_falcon.reset(bar)?; - sec2_falcon.load(dev, bar, &self.booter_unloader)?; + ctx.sec2_falcon.reset(bar)?; + ctx.sec2_falcon.load(dev, bar, &self.booter_unloader)?; // Sentinel value to confirm that Booter Unloader has run. const MAILBOX_SENTINEL: u32 = 0xff; let (mbox0, _) = - sec2_falcon.boot(bar, Some(MAILBOX_SENTINEL), Some(MAILBOX_SENTINEL))?; + ctx.sec2_falcon + .boot(bar, Some(MAILBOX_SENTINEL), Some(MAILBOX_SENTINEL))?; if mbox0 != 0 { dev_err!(dev, "Booter Unloader returned error 0x{:x}\n", mbox0); return Err(EINVAL); -- 2.54.0
