diff --git a/drivers/gpu/nova-core/gpu.rs b/drivers/gpu/nova-core/gpu.rs index 38c75df77e16..7dd736e5b190 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 @@ pub(crate) const fn arch(self) -> Architecture { 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 0b636b713593..cd833bd49b9b 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 41fbabb04ff8..17778a618900 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 @@ fn wait_gfw_boot_completion(&self, _bar: &Bar0) -> Result { 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 2881ab03dbcd..125478bfe07a 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 @@ fn wait_gfw_boot_completion(&self, bar: &Bar0) -> Result { 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 087ee59da6d9..8c316fa2e585 100644 --- a/drivers/gpu/nova-core/gsp/boot.rs +++ b/drivers/gpu/nova-core/gsp/boot.rs @@ -144,7 +144,7 @@ pub(crate) fn boot( 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 3a365455d10c..f84de9f4f045 100644 --- a/drivers/gpu/nova-core/gsp/commands.rs +++ b/drivers/gpu/nova-core/gsp/commands.rs @@ -19,6 +19,7 @@ }; use crate::{ + gpu::Chipset, gsp::{ cmdq::{ Cmdq, @@ -37,12 +38,13 @@ /// 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 42985d446bae..7bcc41fc7fa0 100644 --- a/drivers/gpu/nova-core/gsp/fw/commands.rs +++ b/drivers/gpu/nova-core/gsp/fw/commands.rs @@ -11,7 +11,10 @@ }, // }; -use crate::gsp::GSP_PAGE_SIZE; +use crate::{ + gpu::Chipset, + gsp::GSP_PAGE_SIZE, // +}; use super::bindings; @@ -25,8 +28,12 @@ pub(crate) struct GspSetSystemInfo { 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 @@ pub(crate) fn init<'a>(dev: &'a pci::Device) -> impl Init