]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
gpu: nova-core: Hopper/Blackwell: new location for PCI config mirror
authorJohn Hubbard <jhubbard@nvidia.com>
Tue, 2 Jun 2026 03:20:50 +0000 (20:20 -0700)
committerAlexandre Courbot <acourbot@nvidia.com>
Tue, 2 Jun 2026 13:33:15 +0000 (22:33 +0900)
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 <jhubbard@nvidia.com>
Reviewed-by: Eliot Courtney <ecourtney@nvidia.com>
Link: https://patch.msgid.link/20260602032111.224790-3-jhubbard@nvidia.com
Co-developed-by: Alexandre Courbot <acourbot@nvidia.com>
Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
drivers/gpu/nova-core/gpu.rs
drivers/gpu/nova-core/gpu/hal.rs
drivers/gpu/nova-core/gpu/hal/gh100.rs
drivers/gpu/nova-core/gpu/hal/tu102.rs
drivers/gpu/nova-core/gsp/boot.rs
drivers/gpu/nova-core/gsp/commands.rs
drivers/gpu/nova-core/gsp/fw/commands.rs

index 38c75df77e16e55bdfc1ee374e36c70dfed30b57..7dd736e5b1909c7b3604ce4d39e95a714f7492b0 100644 (file)
@@ -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<u32> {
+        hal::gpu_hal(self).pci_config_mirror_range()
+    }
 }
 
 // TODO
index 0b636b713593bd1400eebe9e6b0ad32a5e6c1e88..cd833bd49b9b0fa004e86c33b730cb87575660cc 100644 (file)
@@ -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<u32>;
 }
 
 pub(super) fn gpu_hal(chipset: Chipset) -> &'static dyn GpuHal {
index 41fbabb04ff8c5b3099bbaf0167f267f7108067c..17778a61890095d1d87ff9d988d62e68c7f83f56 100644 (file)
@@ -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<u32> {
+        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;
index 2881ab03dbcdaeaf5db53187e76e562069e0df70..125478bfe07a06b62f0cf1c9562268d4b105e1b9 100644 (file)
@@ -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<u32> {
+        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;
index 087ee59da6d9a8153e05a69793592da6e8cbb26a..8c316fa2e585a41715c151654708cfad9e712a9b 100644 (file)
@@ -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())?;
 
index 3a365455d10c16435720a21af63a0adc8c85b446..f84de9f4f045036b813d8d565660aa76ac6f395b 100644 (file)
@@ -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<device::Bound>,
+    chipset: Chipset,
 }
 
 impl<'a> SetSystemInfo<'a> {
     /// Creates a new `GspSetSystemInfo` command using the parameters of `pdev`.
-    pub(crate) fn new(pdev: &'a pci::Device<device::Bound>) -> Self {
-        Self { pdev }
+    pub(crate) fn new(pdev: &'a pci::Device<device::Bound>, 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, Self::InitError> {
-        Self::Command::init(self.pdev)
+        Self::Command::init(self.pdev, self.chipset)
     }
 }
 
index 42985d446baec9dc8f392bdf760b7329cbae3430..7bcc41fc7fa07b3aef539a2f943acaf0c722475e 100644 (file)
@@ -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::<GspSetSystemInfo>() < 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<device::Bound>) -> impl Init<Self, Error> + 'a {
+    pub(crate) fn init<'a>(
+        dev: &'a pci::Device<device::Bound>,
+        chipset: Chipset,
+    ) -> impl Init<Self, Error> + '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)