summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexandre Courbot <acourbot@nvidia.com>2025-06-19 22:23:57 +0900
committerDanilo Krummrich <dakr@kernel.org>2025-06-23 19:16:02 +0200
commit9bcc046a929f73358bf23678306b31d927a7e088 (patch)
tree981bc77d24974b2fe48048e70514ebd2e1b73dc7
parentbbe5db761086e870678697f8920db518a6297a18 (diff)
gpu: nova-core: add DMA object struct
Since we will need to allocate lots of distinct memory chunks to be shared between GPU and CPU, introduce a type dedicated to that. It is a light wrapper around CoherentAllocation. Reviewed-by: Lyude Paul <lyude@redhat.com> Signed-off-by: Alexandre Courbot <acourbot@nvidia.com> Link: https://lore.kernel.org/r/20250619-nova-frts-v6-13-ecf41ef99252@nvidia.com Signed-off-by: Danilo Krummrich <dakr@kernel.org>
-rw-r--r--drivers/gpu/nova-core/dma.rs61
-rw-r--r--drivers/gpu/nova-core/nova_core.rs1
2 files changed, 62 insertions, 0 deletions
diff --git a/drivers/gpu/nova-core/dma.rs b/drivers/gpu/nova-core/dma.rs
new file mode 100644
index 000000000000..4b063aaef65e
--- /dev/null
+++ b/drivers/gpu/nova-core/dma.rs
@@ -0,0 +1,61 @@
+// SPDX-License-Identifier: GPL-2.0
+
+//! Simple DMA object wrapper.
+
+// To be removed when all code is used.
+#![expect(dead_code)]
+
+use core::ops::{Deref, DerefMut};
+
+use kernel::device;
+use kernel::dma::CoherentAllocation;
+use kernel::page::PAGE_SIZE;
+use kernel::prelude::*;
+
+pub(crate) struct DmaObject {
+ dma: CoherentAllocation<u8>,
+}
+
+impl DmaObject {
+ pub(crate) fn new(dev: &device::Device<device::Bound>, len: usize) -> Result<Self> {
+ let len = core::alloc::Layout::from_size_align(len, PAGE_SIZE)
+ .map_err(|_| EINVAL)?
+ .pad_to_align()
+ .size();
+ let dma = CoherentAllocation::alloc_coherent(dev, len, GFP_KERNEL | __GFP_ZERO)?;
+
+ Ok(Self { dma })
+ }
+
+ pub(crate) fn from_data(dev: &device::Device<device::Bound>, data: &[u8]) -> Result<Self> {
+ Self::new(dev, data.len()).map(|mut dma_obj| {
+ // TODO: replace with `CoherentAllocation::write()` once available.
+ // SAFETY:
+ // - `dma_obj`'s size is at least `data.len()`.
+ // - We have just created this object and there is no other user at this stage.
+ unsafe {
+ core::ptr::copy_nonoverlapping(
+ data.as_ptr(),
+ dma_obj.dma.start_ptr_mut(),
+ data.len(),
+ );
+ }
+
+ dma_obj
+ })
+ }
+}
+
+impl Deref for DmaObject {
+ type Target = CoherentAllocation<u8>;
+
+ fn deref(&self) -> &Self::Target {
+ &self.dma
+ }
+}
+
+impl DerefMut for DmaObject {
+ fn deref_mut(&mut self) -> &mut Self::Target {
+ &mut self.dma
+ }
+}
diff --git a/drivers/gpu/nova-core/nova_core.rs b/drivers/gpu/nova-core/nova_core.rs
index c3fde3e132ea..121fe5c11044 100644
--- a/drivers/gpu/nova-core/nova_core.rs
+++ b/drivers/gpu/nova-core/nova_core.rs
@@ -2,6 +2,7 @@
//! Nova Core GPU Driver
+mod dma;
mod driver;
mod firmware;
mod gfw;