gpu: nova-core: firmware: gsp: use dma::Coherent for level0 table

Replace the nova-core local `DmaObject` with a `CoherentBox` that can
fulfill the same role.

Since `CoherentBox` is more flexible than `DmaObject`, we can use the
native `u64` type for page table entries instead of messing with bytes.

The `dma` module becomes unused with that change, so remove it as well.

Reviewed-by: Gary Guo <gary@garyguo.net>
Reviewed-by: Danilo Krummrich <dakr@kernel.org>
Link: https://patch.msgid.link/20260327-b4-nova-dma-removal-v2-7-616e1d0b5cb3@nvidia.com
Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
This commit is contained in:
Alexandre Courbot 2026-03-27 00:22:13 +09:00
parent 371db8bcb9
commit e10dcb9d65
3 changed files with 12 additions and 64 deletions

View File

@ -1,53 +0,0 @@
// SPDX-License-Identifier: GPL-2.0
//! Simple DMA object wrapper.
use core::ops::{
Deref,
DerefMut, //
};
use kernel::{
device,
dma::Coherent,
page::PAGE_SIZE,
prelude::*, //
};
pub(crate) struct DmaObject {
dma: Coherent<[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 = Coherent::zeroed_slice(dev, len, GFP_KERNEL)?;
Ok(Self { dma })
}
pub(crate) fn from_data(dev: &device::Device<device::Bound>, data: &[u8]) -> Result<Self> {
let dma_obj = Self::new(dev, data.len())?;
// SAFETY: We have just allocated the DMA memory, we are the only users and
// we haven't made the device aware of the handle yet.
unsafe { dma_obj.as_mut()[..data.len()].copy_from_slice(data) };
Ok(dma_obj)
}
}
impl Deref for DmaObject {
type Target = Coherent<[u8]>;
fn deref(&self) -> &Self::Target {
&self.dma
}
}
impl DerefMut for DmaObject {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.dma
}
}

View File

@ -4,10 +4,10 @@
device,
dma::{
Coherent,
CoherentBox,
DataDirection,
DmaAddress, //
},
kvec,
prelude::*,
scatterlist::{
Owned,
@ -16,7 +16,6 @@
};
use crate::{
dma::DmaObject,
firmware::riscv::RiscvFirmware,
gpu::{
Architecture,
@ -137,7 +136,7 @@ pub(crate) struct GspFirmware {
#[pin]
level1: SGTable<Owned<VVec<u8>>>,
/// Level 0 page table (single 4KB page) with one entry: DMA address of first level 1 page.
level0: DmaObject,
level0: Coherent<[u64]>,
/// Size in bytes of the firmware contained in [`Self::fw`].
pub(crate) size: usize,
/// Device-mapped GSP signatures matching the GPU's [`Chipset`].
@ -198,17 +197,20 @@ pub(crate) fn new<'a>(
// Allocate the level 0 page table as a device-visible DMA object, and map the
// level 1 page table onto it.
// Level 0 page table data.
let mut level0_data = kvec![0u8; GSP_PAGE_SIZE]?;
// Fill level 1 page entry.
let level1_entry = level1.iter().next().ok_or(EINVAL)?;
let level1_entry_addr = level1_entry.dma_address();
let dst = &mut level0_data[..size_of_val(&level1_entry_addr)];
dst.copy_from_slice(&level1_entry_addr.to_le_bytes());
// Turn the level0 page table into a [`DmaObject`].
DmaObject::from_data(dev, &level0_data)?
// Create level 0 page table data and fill its first entry with the level 1
// table.
let mut level0 = CoherentBox::<[u64]>::zeroed_slice(
dev,
GSP_PAGE_SIZE / size_of::<u64>(),
GFP_KERNEL
)?;
level0[0] = level1_entry_addr.to_le();
level0.into()
},
size,
signatures: {

View File

@ -13,7 +13,6 @@
#[macro_use]
mod bitfield;
mod dma;
mod driver;
mod falcon;
mod fb;