[PATCH v7 04/31] gpu: nova-core: move GPU init into Gpu::new()

From: John Hubbard

Date: Tue Mar 17 2026 - 18:55:43 EST


Move Spec creation and the dev_info log from the driver's probe() into
Gpu::new(), so that GPU-specific identification lives in the Gpu
constructor.

Restructure Gpu::new() to use pin_init_scope wrapping try_pin_init!,
which allows running fallible setup code (Spec::new) before the
pin-initializer. Add Spec::chipset() accessor for use by later patches.

The DMA mask setup stays in probe() where the safety argument for
dma_set_mask_and_coherent is straightforward.

Cc: Danilo Krummrich <dakr@xxxxxxxxxx>
Cc: Gary Guo <gary@xxxxxxxxxxx>
Signed-off-by: John Hubbard <jhubbard@xxxxxxxxxx>
---
drivers/gpu/nova-core/gpu.rs | 49 +++++++++++++++++++++---------------
1 file changed, 29 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/nova-core/gpu.rs b/drivers/gpu/nova-core/gpu.rs
index 3b4ccc3d18b9..8f317d213908 100644
--- a/drivers/gpu/nova-core/gpu.rs
+++ b/drivers/gpu/nova-core/gpu.rs
@@ -102,7 +102,7 @@ fn try_from(value: u32) -> Result<Self, Self::Error> {
});

impl Chipset {
- pub(crate) const fn arch(self) -> Architecture {
+ pub(crate) const fn arch(&self) -> Architecture {
match self {
Self::TU102 | Self::TU104 | Self::TU106 | Self::TU117 | Self::TU116 => {
Architecture::Turing
@@ -241,6 +241,10 @@ fn new(dev: &device::Device, bar: &Bar0) -> Result<Spec> {
dev_err!(dev, "Unsupported chipset: {}\n", boot42);
})
}
+
+ pub(crate) fn chipset(&self) -> Chipset {
+ self.chipset
+ }
}

impl TryFrom<regs::NV_PMC_BOOT_42> for Spec {
@@ -289,32 +293,37 @@ pub(crate) fn new<'a>(
devres_bar: Arc<Devres<Bar0>>,
bar: &'a Bar0,
) -> impl PinInit<Self, Error> + 'a {
- try_pin_init!(Self {
- spec: Spec::new(pdev.as_ref(), bar).inspect(|spec| {
- dev_info!(pdev,"NVIDIA ({})\n", spec);
- })?,
+ pin_init::pin_init_scope(move || {
+ let spec = Spec::new(pdev.as_ref(), bar)?;
+ dev_info!(pdev, "NVIDIA ({})\n", spec);
+
+ let chipset = spec.chipset();

- // We must wait for GFW_BOOT completion before doing any significant setup on the GPU.
- _: {
- gfw::wait_gfw_boot_completion(bar)
- .inspect_err(|_| dev_err!(pdev, "GFW boot did not complete\n"))?;
- },
+ Ok(try_pin_init!(Self {
+ // We must wait for GFW_BOOT completion before doing any significant setup
+ // on the GPU.
+ _: {
+ gfw::wait_gfw_boot_completion(bar)
+ .inspect_err(|_| dev_err!(pdev, "GFW boot did not complete\n"))?;
+ },

- sysmem_flush: SysmemFlush::register(pdev.as_ref(), bar, spec.chipset)?,
+ sysmem_flush: SysmemFlush::register(pdev.as_ref(), bar, chipset)?,

- gsp_falcon: Falcon::new(
- pdev.as_ref(),
- spec.chipset,
- )
- .inspect(|falcon| falcon.clear_swgen0_intr(bar))?,
+ gsp_falcon: Falcon::new(
+ pdev.as_ref(),
+ chipset,
+ )
+ .inspect(|falcon| falcon.clear_swgen0_intr(bar))?,

- sec2_falcon: Falcon::new(pdev.as_ref(), spec.chipset)?,
+ sec2_falcon: Falcon::new(pdev.as_ref(), chipset)?,

- gsp <- Gsp::new(pdev),
+ gsp <- Gsp::new(pdev),

- _: { gsp.boot(pdev, bar, spec.chipset, gsp_falcon, sec2_falcon)? },
+ _: { gsp.boot(pdev, bar, chipset, gsp_falcon, sec2_falcon)? },

- bar: devres_bar,
+ bar: devres_bar,
+ spec,
+ }))
})
}

--
2.53.0