[PATCH POC v3 5/5] drm: nova: demonstrate interaction with nova-core

From: Alexandre Courbot

Date: Fri May 29 2026 - 11:49:50 EST


Export a few items from nova-core and use them from nova-drm in order to
print the chipset of the GPU being probed.

Some documentation items are added to make Clippy happy.

This is only meant for demonstration purposes, and won't be merged.

Signed-off-by: Alexandre Courbot <acourbot@xxxxxxxxxx>
---
drivers/gpu/drm/nova/driver.rs | 9 +++++-
drivers/gpu/nova-core/driver.rs | 59 +++++++++++++++++++++++++++++---------
drivers/gpu/nova-core/gpu.rs | 9 ++++--
drivers/gpu/nova-core/nova_core.rs | 4 +--
4 files changed, 61 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/nova/driver.rs b/drivers/gpu/drm/nova/driver.rs
index 4289df7de01c..2a3f47974079 100644
--- a/drivers/gpu/drm/nova/driver.rs
+++ b/drivers/gpu/drm/nova/driver.rs
@@ -9,12 +9,15 @@
ioctl, //
},
prelude::*,
- sync::aref::ARef, //
+ sync::aref::ARef,
+ types::ForLt, //
};

use crate::file::File;
use crate::gem::NovaObject;

+use nova_core::driver::AuxData;
+
pub(crate) struct NovaDriver;

pub(crate) struct Nova {
@@ -60,6 +63,10 @@ fn probe<'bound>(
adev: &'bound auxiliary::Device<Core<'_>>,
_info: &'bound Self::IdInfo,
) -> impl PinInit<Self::Data<'bound>, Error> + 'bound {
+ let aux_data = adev.registration_data::<ForLt!(AuxData<'_>)>()?;
+
+ pr_info!("Chipset from nova-core: {}\n", aux_data.chipset());
+
let data = try_pin_init!(NovaData { adev: adev.into() });

let drm = drm::Device::<Self>::new(adev.as_ref(), data)?;
diff --git a/drivers/gpu/nova-core/driver.rs b/drivers/gpu/nova-core/driver.rs
index cff5034c2dcd..95fb4d13e676 100644
--- a/drivers/gpu/nova-core/driver.rs
+++ b/drivers/gpu/nova-core/driver.rs
@@ -1,5 +1,7 @@
// SPDX-License-Identifier: GPL-2.0

+//! Main driver module.
+
use kernel::{
auxiliary,
device::Core,
@@ -20,18 +22,36 @@
types::ForLt,
};

-use crate::gpu::Gpu;
+use crate::gpu::{
+ Chipset,
+ Gpu, //
+};

/// Counter for generating unique auxiliary device IDs.
static AUXILIARY_ID_COUNTER: Atomic<u32> = Atomic::new(0);

+/// Data passed to the auxiliary device registration, for the sibling driver to use.
+pub struct AuxData<'bound> {
+ gpu: &'bound Gpu<'bound>,
+}
+
+impl AuxData<'_> {
+ /// Returns the chipset of this GPU.
+ pub fn chipset(&self) -> Chipset {
+ self.gpu.spec.chipset
+ }
+}
+
+/// Driver-associated data.
#[pin_data]
-pub(crate) struct NovaCore<'bound> {
+pub struct NovaCore<'bound> {
+ // Fields are dropped in declaration order: unregister the auxiliary device before dropping
+ // `gpu`, and drop `gpu` before `bar` because `AuxData` borrows `gpu` and `Gpu` borrows `bar`.
+ #[allow(clippy::type_complexity)]
+ _reg: auxiliary::Registration<'bound, ForLt!(AuxData<'_>)>,
#[pin]
pub(crate) gpu: Gpu<'bound>,
bar: pci::Bar<'bound, BAR0_SIZE>,
- #[allow(clippy::type_complexity)]
- _reg: auxiliary::Registration<'bound, ForLt!(())>,
}

pub(crate) struct NovaCoreDriver;
@@ -93,7 +113,7 @@ fn probe<'bound>(
// other threads of execution.
unsafe { pdev.dma_set_mask_and_coherent(DmaMask::new::<GPU_DMA_BITS>())? };

- Ok(try_pin_init!(NovaCore {
+ Ok(try_pin_init!(&this in NovaCore {
bar: pdev.iomap_region_sized::<BAR0_SIZE>(0, c"nova-core/bar0")?,
// TODO: Use `&bar` self-referential pin-init syntax once available.
//
@@ -101,15 +121,26 @@ fn probe<'bound>(
// (`try_pin_init!()` initializes fields in declaration order), lives at a pinned
// stable address, and is dropped after `gpu` (struct field drop order).
gpu <- Gpu::new(pdev, unsafe { &*core::ptr::from_ref(bar) }),
- _reg: auxiliary::Registration::new(
- pdev.as_ref(),
- c"nova-drm",
- // TODO[XARR]: Use XArray or perhaps IDA for proper ID allocation/recycling. For
- // now, use a simple atomic counter that never recycles IDs.
- AUXILIARY_ID_COUNTER.fetch_add(1, Relaxed),
- crate::MODULE_NAME,
- (),
- )?,
+ // SAFETY: `NovaCore` is dropped when the device is unbound; i.e. `mem::forget()` is
+ // never called on it.
+ _reg: unsafe {
+ auxiliary::Registration::new_with_lt(
+ pdev.as_ref(),
+ c"nova-drm",
+ // TODO[XARR]: Use XArray or perhaps IDA for proper ID allocation/recycling.
+ // For now, use a simple atomic counter that never recycles IDs.
+ AUXILIARY_ID_COUNTER.fetch_add(1, Relaxed),
+ crate::MODULE_NAME,
+ AuxData {
+ // TODO: Use `&gpu` self-referential pin-init syntax once available.
+ //
+ // SAFETY: `this.gpu` is initialized before this expression is
+ // evaluated, lives at a pinned stable address, and is dropped after
+ // `_reg` (struct field drop order).
+ gpu: &*core::ptr::from_ref(&this.as_ref().gpu),
+ },
+ )?
+ },
}))
})
}
diff --git a/drivers/gpu/nova-core/gpu.rs b/drivers/gpu/nova-core/gpu.rs
index cf134cab49cd..5636659f24a8 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

+//! Core types for the driver.
+
use kernel::{
device,
fmt,
@@ -29,7 +31,8 @@ macro_rules! define_chipset {
{
/// Enum representation of the GPU chipset.
#[derive(fmt::Debug, Copy, Clone, PartialOrd, Ord, PartialEq, Eq)]
- pub(crate) enum Chipset {
+ #[allow(missing_docs)]
+ pub enum Chipset {
$($variant = $value),*,
}

@@ -183,7 +186,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
/// Structure holding a basic description of the GPU: `Chipset` and `Revision`.
#[derive(Clone, Copy)]
pub(crate) struct Spec {
- chipset: Chipset,
+ pub(crate) chipset: Chipset,
revision: Revision,
}

@@ -245,7 +248,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
/// Structure holding the resources required to operate the GPU.
#[pin_data]
pub(crate) struct Gpu<'gpu> {
- spec: Spec,
+ pub(crate) spec: Spec,
/// MMIO mapping of PCI BAR 0.
bar: &'gpu Bar0,
/// System memory page required for flushing all pending GPU-side memory writes done through
diff --git a/drivers/gpu/nova-core/nova_core.rs b/drivers/gpu/nova-core/nova_core.rs
index 5a260062295f..5166e10ce8a0 100644
--- a/drivers/gpu/nova-core/nova_core.rs
+++ b/drivers/gpu/nova-core/nova_core.rs
@@ -13,11 +13,11 @@
#[macro_use]
mod bitfield;

-mod driver;
+pub mod driver;
mod falcon;
mod fb;
mod firmware;
-mod gpu;
+pub mod gpu;
mod gsp;
#[macro_use]
mod num;

--
2.54.0