From: John Hubbard Date: Tue, 2 Jun 2026 03:20:50 +0000 (-0700) Subject: gpu: nova-core: Hopper/Blackwell: new location for PCI config mirror X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ee9414e6055bf3249f535bfe0f7d4e3c5a3e4b13;p=thirdparty%2Flinux.git gpu: nova-core: Hopper/Blackwell: new location for PCI config mirror Hopper and Blackwell GPUs moved the PCI config space mirror from 0x088000 to 0x092000. Select the correct address per architecture when building the GSP system info command. Signed-off-by: John Hubbard Reviewed-by: Eliot Courtney Link: https://patch.msgid.link/20260602032111.224790-3-jhubbard@nvidia.com Co-developed-by: Alexandre Courbot Signed-off-by: Alexandre Courbot --- diff --git a/drivers/gpu/nova-core/gpu.rs b/drivers/gpu/nova-core/gpu.rs index 38c75df77e16e..7dd736e5b1909 100644 --- a/drivers/gpu/nova-core/gpu.rs +++ b/drivers/gpu/nova-core/gpu.rs @@ -1,5 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 +use core::ops::Range; + use kernel::{ device, dma::Device, @@ -134,6 +136,11 @@ impl Chipset { pub(crate) const fn needs_fwsec_bootloader(self) -> bool { matches!(self.arch(), Architecture::Turing) || matches!(self, Self::GA100) } + + /// Returns the address range of the PCI config mirror space. + pub(crate) fn pci_config_mirror_range(self) -> Range { + hal::gpu_hal(self).pci_config_mirror_range() + } } // TODO diff --git a/drivers/gpu/nova-core/gpu/hal.rs b/drivers/gpu/nova-core/gpu/hal.rs index 0b636b713593b..cd833bd49b9b0 100644 --- a/drivers/gpu/nova-core/gpu/hal.rs +++ b/drivers/gpu/nova-core/gpu/hal.rs @@ -1,5 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 +use core::ops::Range; + use kernel::{ dma::DmaMask, prelude::*, // @@ -22,6 +24,9 @@ pub(crate) trait GpuHal { /// Returns the DMA mask for the current architecture. fn dma_mask(&self) -> DmaMask; + + /// Returns the address range of the PCI config mirror space. + fn pci_config_mirror_range(&self) -> Range; } pub(super) fn gpu_hal(chipset: Chipset) -> &'static dyn GpuHal { diff --git a/drivers/gpu/nova-core/gpu/hal/gh100.rs b/drivers/gpu/nova-core/gpu/hal/gh100.rs index 41fbabb04ff8c..17778a6189009 100644 --- a/drivers/gpu/nova-core/gpu/hal/gh100.rs +++ b/drivers/gpu/nova-core/gpu/hal/gh100.rs @@ -1,5 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 +use core::ops::Range; + use kernel::{ dma::DmaMask, prelude::*, // @@ -19,6 +21,13 @@ impl GpuHal for Gh100 { fn dma_mask(&self) -> DmaMask { DmaMask::new::<52>() } + + fn pci_config_mirror_range(&self) -> Range { + const PCI_CONFIG_MIRROR_START: u32 = 0x092000; + const PCI_CONFIG_MIRROR_SIZE: u32 = 0x001000; + + PCI_CONFIG_MIRROR_START..PCI_CONFIG_MIRROR_START + PCI_CONFIG_MIRROR_SIZE + } } const GH100: Gh100 = Gh100; diff --git a/drivers/gpu/nova-core/gpu/hal/tu102.rs b/drivers/gpu/nova-core/gpu/hal/tu102.rs index 2881ab03dbcda..125478bfe07a0 100644 --- a/drivers/gpu/nova-core/gpu/hal/tu102.rs +++ b/drivers/gpu/nova-core/gpu/hal/tu102.rs @@ -18,6 +18,8 @@ //! //! Note that the devinit sequence also needs to run during suspend/resume. +use core::ops::Range; + use kernel::{ dma::DmaMask, io::{ @@ -85,6 +87,13 @@ impl GpuHal for Tu102 { fn dma_mask(&self) -> DmaMask { DmaMask::new::<47>() } + + fn pci_config_mirror_range(&self) -> Range { + const PCI_CONFIG_MIRROR_START: u32 = 0x088000; + const PCI_CONFIG_MIRROR_SIZE: u32 = 0x001000; + + PCI_CONFIG_MIRROR_START..PCI_CONFIG_MIRROR_START + PCI_CONFIG_MIRROR_SIZE + } } const TU102: Tu102 = Tu102; diff --git a/drivers/gpu/nova-core/gsp/boot.rs b/drivers/gpu/nova-core/gsp/boot.rs index 087ee59da6d9a..8c316fa2e585a 100644 --- a/drivers/gpu/nova-core/gsp/boot.rs +++ b/drivers/gpu/nova-core/gsp/boot.rs @@ -144,7 +144,7 @@ impl super::Gsp { dev_dbg!(pdev, "RISC-V active? {}\n", gsp_falcon.is_riscv_active(bar),); self.cmdq - .send_command_no_wait(bar, commands::SetSystemInfo::new(pdev))?; + .send_command_no_wait(bar, commands::SetSystemInfo::new(pdev, chipset))?; self.cmdq .send_command_no_wait(bar, commands::SetRegistry::new())?; diff --git a/drivers/gpu/nova-core/gsp/commands.rs b/drivers/gpu/nova-core/gsp/commands.rs index 3a365455d10c1..f84de9f4f0450 100644 --- a/drivers/gpu/nova-core/gsp/commands.rs +++ b/drivers/gpu/nova-core/gsp/commands.rs @@ -19,6 +19,7 @@ use kernel::{ }; use crate::{ + gpu::Chipset, gsp::{ cmdq::{ Cmdq, @@ -37,12 +38,13 @@ use crate::{ /// The `GspSetSystemInfo` command. pub(crate) struct SetSystemInfo<'a> { pdev: &'a pci::Device, + chipset: Chipset, } impl<'a> SetSystemInfo<'a> { /// Creates a new `GspSetSystemInfo` command using the parameters of `pdev`. - pub(crate) fn new(pdev: &'a pci::Device) -> Self { - Self { pdev } + pub(crate) fn new(pdev: &'a pci::Device, chipset: Chipset) -> Self { + Self { pdev, chipset } } } @@ -53,7 +55,7 @@ impl<'a> CommandToGsp for SetSystemInfo<'a> { type InitError = Error; fn init(&self) -> impl Init { - Self::Command::init(self.pdev) + Self::Command::init(self.pdev, self.chipset) } } diff --git a/drivers/gpu/nova-core/gsp/fw/commands.rs b/drivers/gpu/nova-core/gsp/fw/commands.rs index 42985d446baec..7bcc41fc7fa07 100644 --- a/drivers/gpu/nova-core/gsp/fw/commands.rs +++ b/drivers/gpu/nova-core/gsp/fw/commands.rs @@ -11,7 +11,10 @@ use kernel::{ }, // }; -use crate::gsp::GSP_PAGE_SIZE; +use crate::{ + gpu::Chipset, + gsp::GSP_PAGE_SIZE, // +}; use super::bindings; @@ -25,8 +28,12 @@ static_assert!(size_of::() < GSP_PAGE_SIZE); impl GspSetSystemInfo { /// Returns an in-place initializer for the `GspSetSystemInfo` command. #[allow(non_snake_case)] - pub(crate) fn init<'a>(dev: &'a pci::Device) -> impl Init + 'a { + pub(crate) fn init<'a>( + dev: &'a pci::Device, + chipset: Chipset, + ) -> impl Init + 'a { type InnerGspSystemInfo = bindings::GspSystemInfo; + let pci_config_mirror_range = chipset.pci_config_mirror_range(); let init_inner = try_init!(InnerGspSystemInfo { gpuPhysAddr: dev.resource_start(0)?, gpuPhysFbAddr: dev.resource_start(1)?, @@ -36,8 +43,8 @@ impl GspSetSystemInfo { // Using TASK_SIZE in r535_gsp_rpc_set_system_info() seems wrong because // TASK_SIZE is per-task. That's probably a design issue in GSP-RM though. maxUserVa: (1 << 47) - 4096, - pciConfigMirrorBase: 0x088000, - pciConfigMirrorSize: 0x001000, + pciConfigMirrorBase: pci_config_mirror_range.start, + pciConfigMirrorSize: pci_config_mirror_range.end - pci_config_mirror_range.start, PCIDeviceID: (u32::from(dev.device_id()) << 16) | u32::from(dev.vendor_id().as_raw()), PCISubDeviceID: (u32::from(dev.subsystem_device_id()) << 16)