Re: [PATCH v4 09/33] gpu: nova-core: Hopper/Blackwell: skip GFW boot waiting

John Hubbard
2026-02-12T01:49:48Z

On 2/11/26 2:09 AM, Danilo Krummrich wrote:
> On Tue Feb 10, 2026 at 3:45 AM CET, John Hubbard wrote:
...
>> diff --git a/drivers/gpu/nova-core/gpu.rs b/drivers/gpu/nova-core/gpu.rs
>> index 24feb0e8723e..f04e2a795e90 100644
>> --- a/drivers/gpu/nova-core/gpu.rs
>> +++ b/drivers/gpu/nova-core/gpu.rs
>> @@ -304,10 +304,19 @@ pub(crate) fn new<'a>(
>> let chipset = spec.chipset();
>>
>> try_pin_init!(Self {
>> - // We must wait for GFW_BOOT completion before doing any significant setup on the GPU.
>> + // Turing, Ampere, Ada: we must wait for GFW_BOOT completion before doing any
>> + // significant setup on the GPU.
>> + //
>> + // Hopper/Blackwell: skip GFW_BOOT completion waiting entirely, and use the simpler FSP
>> + // Chain of Trust boot path (elsewhere) instead.
>> _: {
>> - gfw::wait_gfw_boot_completion(bar)
>> - .inspect_err(|_| dev_err!(pdev, "GFW boot did not complete\n"))?;
>> + if matches!(
>> + chipset.arch(),
>> + Architecture::Turing | Architecture::Ampere | Architecture::Ada
>
> I assume Blackwell is not an exception and we expect this to be the case for
> future architectures as well? I.e. checking for "!Architecture::Blackwell" makes
> no sense?

You are correct. I've applied this locally, so that future GPUs
continue to skip GFW_BOOT (which I'm thinking of renaming now, but
in a future patchset):

diff --git a/drivers/gpu/nova-core/gpu.rs b/drivers/gpu/nova-core/gpu.rs
index f04e2a795e90..2034c05c04de 100644
--- a/drivers/gpu/nova-core/gpu.rs
+++ b/drivers/gpu/nova-core/gpu.rs
@@ -167,6 +167,18 @@ pub(crate) const fn dma_mask(&self) -> DmaMask {
Self::Hopper | Self::Blackwell => DmaMask::new::<52>(),
}
}
+
+ /// Returns whether the GPU uses GFW_BOOT for firmware loading.
+ ///
+ /// Pre-Hopper architectures (Turing, Ampere, Ada) require waiting for GFW_BOOT completion
+ /// before any significant GPU setup. Hopper and later use the FSP Chain of Trust boot path
+ /// instead.
+ pub(crate) const fn needs_gfw_boot(&self) -> bool {
+ match self {
+ Self::Turing | Self::Ampere | Self::Ada => true,
+ _ => false,
+ }
+ }
}

impl TryFrom<u8> for Architecture {
@@ -304,16 +316,8 @@ pub(crate) fn new<'a>(
let chipset = spec.chipset();

try_pin_init!(Self {
- // Turing, Ampere, Ada: we must wait for GFW_BOOT completion before doing any
- // significant setup on the GPU.
- //
- // Hopper/Blackwell: skip GFW_BOOT completion waiting entirely, and use the simpler FSP
- // Chain of Trust boot path (elsewhere) instead.
_: {
- if matches!(
- chipset.arch(),
- Architecture::Turing | Architecture::Ampere | Architecture::Ada
- ) {
+ if chipset.arch().needs_gfw_boot() {
gfw::wait_gfw_boot_completion(bar)
.inspect_err(|_| dev_err!(pdev, "GFW boot did not complete\n"))?;
}

>
>> + ) {
>> + gfw::wait_gfw_boot_completion(bar)
>> + .inspect_err(|_| dev_err!(pdev, "GFW boot did not complete\n"))?;
>> + }
>> },

thanks,
--
John Hubbard