diff options
author | Alexandre Courbot <acourbot@nvidia.com> | 2025-06-19 22:23:58 +0900 |
---|---|---|
committer | Danilo Krummrich <dakr@kernel.org> | 2025-06-23 19:55:53 +0200 |
commit | 6554ad65b5891e52689061606e277a69e44462c4 (patch) | |
tree | 19aec225982b4a045250e5d637736b98f0e60d52 /drivers/gpu/nova-core/gpu.rs | |
parent | 9bcc046a929f73358bf23678306b31d927a7e088 (diff) |
gpu: nova-core: register sysmem flush page
Reserve a page of system memory so sysmembar can perform a read on it if
a system write occurred since the last flush. Do this early as it can be
required to e.g. reset the GPU falcons.
Chipsets capabilities differ in that respect, so this commit also
introduces the FB HAL.
Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
Link: https://lore.kernel.org/r/20250619-nova-frts-v6-14-ecf41ef99252@nvidia.com
[ * Use kernel::page::PAGE_SIZE instead of kernel::bindings::PAGE_SIZE.
* Get rid of the Option for SysmemFlush.
* Slightly reword SysmemFlush doc-comments.
- Danilo ]
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
Diffstat (limited to 'drivers/gpu/nova-core/gpu.rs')
-rw-r--r-- | drivers/gpu/nova-core/gpu.rs | 21 |
1 files changed, 19 insertions, 2 deletions
diff --git a/drivers/gpu/nova-core/gpu.rs b/drivers/gpu/nova-core/gpu.rs index e44ff6fa0714..992840f6b108 100644 --- a/drivers/gpu/nova-core/gpu.rs +++ b/drivers/gpu/nova-core/gpu.rs @@ -3,6 +3,7 @@ use kernel::{device, devres::Devres, error::code::*, pci, prelude::*}; use crate::driver::Bar0; +use crate::fb::SysmemFlush; use crate::firmware::{Firmware, FIRMWARE_VERSION}; use crate::gfw; use crate::regs; @@ -158,12 +159,24 @@ impl Spec { } /// Structure holding the resources required to operate the GPU. -#[pin_data] +#[pin_data(PinnedDrop)] pub(crate) struct Gpu { spec: Spec, /// MMIO mapping of PCI BAR 0 bar: Devres<Bar0>, fw: Firmware, + /// System memory page required for flushing all pending GPU-side memory writes done through + /// PCIE into system memory. + sysmem_flush: SysmemFlush, +} + +#[pinned_drop] +impl PinnedDrop for Gpu { + fn drop(self: Pin<&mut Self>) { + // Unregister the sysmem flush page before we release it. + self.bar + .try_access_with(|b| self.sysmem_flush.unregister(b)); + } } impl Gpu { @@ -187,10 +200,14 @@ impl Gpu { gfw::wait_gfw_boot_completion(bar) .inspect_err(|_| dev_err!(pdev.as_ref(), "GFW boot did not complete"))?; + // System memory page required for sysmembar to properly flush into system memory. + let sysmem_flush = SysmemFlush::register(pdev.as_ref(), bar, spec.chipset)?; + Ok(pin_init!(Self { spec, bar: devres_bar, - fw + fw, + sysmem_flush, })) } } |