Skip to content

Commit c4f8ac0

Browse files
committed
Merge tag 'nova-next-v6.16-2025-05-20' of https://gitlab.freedesktop.org/drm/nova into drm-next
Nova changes for v6.16 auxiliary: - bus abstractions - implementation for driver registration - add sample driver drm: - implement __drm_dev_alloc() - DRM core infrastructure Rust abstractions - device, driver and registration - DRM IOCTL - DRM File - GEM object - IntoGEMObject rework - generically implement AlwaysRefCounted through IntoGEMObject - refactor unsound from_gem_obj() into as_ref() - refactor into_gem_obj() into as_raw() driver-core: - merge topic/device-context-2025-04-17 from driver-core tree - implement Devres::access() - fix: doctest build under `!CONFIG_PCI` - accessor for Device::parent() - fix: conditionally expect `dead_code` for `parent()` - impl TryFrom<&Device> bus devices (PCI, platform) nova-core: - remove completed Vec extentions from task list - register auxiliary device for nova-drm - derive useful traits for Chipset - add missing GA100 chipset - take &Device<Bound> in Gpu::new() - infrastructure to generate register definitions - fix register layout of NV_PMC_BOOT_0 - move Firmware into own (Rust) module - fix: select AUXILIARY_BUS nova-drm: - initial driver skeleton (depends on drm and auxiliary bus abstractions) - fix: select AUXILIARY_BUS Rust (dependencies): - implement Opaque::zeroed() - implement Revocable::try_access_with() - implement Revocable::access() From: Danilo Krummrich <[email protected]> Link: https://lore.kernel.org/r/aCxAf3RqQAXLDhAj@cassiopeiae
2 parents 7c1a940 + 276c53c commit c4f8ac0

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+2762
-197
lines changed

Documentation/gpu/nova/core/todo.rst

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,13 @@ Usage:
102102
let boot0 = Boot0::read(&bar);
103103
pr_info!("Revision: {}\n", boot0.revision());
104104
105+
Note: a work-in-progress implementation currently resides in
106+
`drivers/gpu/nova-core/regs/macros.rs` and is used in nova-core. It would be
107+
nice to improve it (possibly using proc macros) and move it to the `kernel`
108+
crate so it can be used by other components as well.
109+
105110
| Complexity: Advanced
111+
| Contact: Alexandre Courbot
106112
107113
Delay / Sleep abstractions
108114
--------------------------
@@ -190,16 +196,6 @@ Rust abstraction for debugfs APIs.
190196
| Reference: Export GSP log buffers
191197
| Complexity: Intermediate
192198
193-
Vec extensions
194-
--------------
195-
196-
Implement ``Vec::truncate`` and ``Vec::resize``.
197-
198-
Currently this is used for some experimental code to parse the vBIOS.
199-
200-
| Reference vBIOS support
201-
| Complexity: Beginner
202-
203199
GPU (general)
204200
=============
205201

MAINTAINERS

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3880,6 +3880,9 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/driver-core/driver-core.git
38803880
F: Documentation/driver-api/auxiliary_bus.rst
38813881
F: drivers/base/auxiliary.c
38823882
F: include/linux/auxiliary_bus.h
3883+
F: rust/helpers/auxiliary.c
3884+
F: rust/kernel/auxiliary.rs
3885+
F: samples/rust/rust_driver_auxiliary.rs
38833886

38843887
AUXILIARY DISPLAY DRIVERS
38853888
M: Andy Shevchenko <[email protected]>
@@ -7607,6 +7610,18 @@ T: git https://gitlab.freedesktop.org/drm/nova.git nova-next
76077610
F: Documentation/gpu/nova/
76087611
F: drivers/gpu/nova-core/
76097612

7613+
DRM DRIVER FOR NVIDIA GPUS [RUST]
7614+
M: Danilo Krummrich <[email protected]>
7615+
7616+
S: Supported
7617+
Q: https://patchwork.freedesktop.org/project/nouveau/
7618+
B: https://gitlab.freedesktop.org/drm/nova/-/issues
7619+
C: irc://irc.oftc.net/nouveau
7620+
T: git https://gitlab.freedesktop.org/drm/nova.git nova-next
7621+
F: Documentation/gpu/nova/
7622+
F: drivers/gpu/drm/nova/
7623+
F: include/uapi/drm/nova_drm.h
7624+
76107625
DRM DRIVER FOR OLIMEX LCD-OLINUXINO PANELS
76117626
M: Stefan Mavrodiev <[email protected]>
76127627
S: Maintained
@@ -7820,6 +7835,7 @@ F: Documentation/devicetree/bindings/display/
78207835
F: Documentation/devicetree/bindings/gpu/
78217836
F: Documentation/gpu/
78227837
F: drivers/gpu/
7838+
F: rust/kernel/drm/
78237839
F: include/drm/
78247840
F: include/linux/vga*
78257841
F: include/uapi/drm/
@@ -7836,6 +7852,7 @@ F: Documentation/devicetree/bindings/gpu/
78367852
F: Documentation/gpu/
78377853
F: drivers/gpu/drm/
78387854
F: drivers/gpu/vga/
7855+
F: rust/kernel/drm/
78397856
F: include/drm/drm
78407857
F: include/linux/vga*
78417858
F: include/uapi/drm/

drivers/gpu/drm/Kconfig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,8 @@ source "drivers/gpu/drm/amd/amdgpu/Kconfig"
274274

275275
source "drivers/gpu/drm/nouveau/Kconfig"
276276

277+
source "drivers/gpu/drm/nova/Kconfig"
278+
277279
source "drivers/gpu/drm/i915/Kconfig"
278280

279281
source "drivers/gpu/drm/xe/Kconfig"

drivers/gpu/drm/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,7 @@ obj-$(CONFIG_DRM_VMWGFX)+= vmwgfx/
177177
obj-$(CONFIG_DRM_VGEM) += vgem/
178178
obj-$(CONFIG_DRM_VKMS) += vkms/
179179
obj-$(CONFIG_DRM_NOUVEAU) +=nouveau/
180+
obj-$(CONFIG_DRM_NOVA) += nova/
180181
obj-$(CONFIG_DRM_EXYNOS) +=exynos/
181182
obj-$(CONFIG_DRM_ROCKCHIP) +=rockchip/
182183
obj-$(CONFIG_DRM_GMA500) += gma500/

drivers/gpu/drm/drm_drv.c

Lines changed: 42 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -830,36 +830,62 @@ void *__devm_drm_dev_alloc(struct device *parent,
830830
EXPORT_SYMBOL(__devm_drm_dev_alloc);
831831

832832
/**
833-
* drm_dev_alloc - Allocate new DRM device
834-
* @driver: DRM driver to allocate device for
833+
* __drm_dev_alloc - Allocation of a &drm_device instance
835834
* @parent: Parent device object
835+
* @driver: DRM driver
836+
* @size: the size of the struct which contains struct drm_device
837+
* @offset: the offset of the &drm_device within the container.
836838
*
837-
* This is the deprecated version of devm_drm_dev_alloc(), which does not support
838-
* subclassing through embedding the struct &drm_device in a driver private
839-
* structure, and which does not support automatic cleanup through devres.
839+
* This should *NOT* be by any drivers, but is a dedicated interface for the
840+
* corresponding Rust abstraction.
840841
*
841-
* RETURNS:
842-
* Pointer to new DRM device, or ERR_PTR on failure.
842+
* This is the same as devm_drm_dev_alloc(), but without the corresponding
843+
* resource management through the parent device, but not the same as
844+
* drm_dev_alloc(), since the latter is the deprecated version, which does not
845+
* support subclassing.
846+
*
847+
* Returns: A pointer to new DRM device, or an ERR_PTR on failure.
843848
*/
844-
struct drm_device *drm_dev_alloc(const struct drm_driver *driver,
845-
struct device *parent)
849+
void *__drm_dev_alloc(struct device *parent,
850+
const struct drm_driver *driver,
851+
size_t size, size_t offset)
846852
{
847-
struct drm_device *dev;
853+
void *container;
854+
struct drm_device *drm;
848855
int ret;
849856

850-
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
851-
if (!dev)
857+
container = kzalloc(size, GFP_KERNEL);
858+
if (!container)
852859
return ERR_PTR(-ENOMEM);
853860

854-
ret = drm_dev_init(dev, driver, parent);
861+
drm = container + offset;
862+
ret = drm_dev_init(drm, driver, parent);
855863
if (ret) {
856-
kfree(dev);
864+
kfree(container);
857865
return ERR_PTR(ret);
858866
}
867+
drmm_add_final_kfree(drm, container);
859868

860-
drmm_add_final_kfree(dev, dev);
869+
return container;
870+
}
871+
EXPORT_SYMBOL(__drm_dev_alloc);
861872

862-
return dev;
873+
/**
874+
* drm_dev_alloc - Allocate new DRM device
875+
* @driver: DRM driver to allocate device for
876+
* @parent: Parent device object
877+
*
878+
* This is the deprecated version of devm_drm_dev_alloc(), which does not support
879+
* subclassing through embedding the struct &drm_device in a driver private
880+
* structure, and which does not support automatic cleanup through devres.
881+
*
882+
* RETURNS:
883+
* Pointer to new DRM device, or ERR_PTR on failure.
884+
*/
885+
struct drm_device *drm_dev_alloc(const struct drm_driver *driver,
886+
struct device *parent)
887+
{
888+
return __drm_dev_alloc(parent, driver, sizeof(struct drm_device), 0);
863889
}
864890
EXPORT_SYMBOL(drm_dev_alloc);
865891

drivers/gpu/drm/nova/Kconfig

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
config DRM_NOVA
2+
tristate "Nova DRM driver"
3+
depends on DRM=y
4+
depends on PCI
5+
depends on RUST
6+
select AUXILIARY_BUS
7+
default n
8+
help
9+
Choose this if you want to build the Nova DRM driver for Nvidia
10+
GSP-based GPUs.
11+
12+
This driver is work in progress and may not be functional.
13+
14+
If M is selected, the module will be called nova.

drivers/gpu/drm/nova/Makefile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# SPDX-License-Identifier: GPL-2.0
2+
3+
obj-$(CONFIG_DRM_NOVA) += nova.o

drivers/gpu/drm/nova/driver.rs

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
3+
use kernel::{auxiliary, c_str, device::Core, drm, drm::gem, drm::ioctl, prelude::*, types::ARef};
4+
5+
use crate::file::File;
6+
use crate::gem::NovaObject;
7+
8+
pub(crate) struct NovaDriver {
9+
#[expect(unused)]
10+
drm: ARef<drm::Device<Self>>,
11+
}
12+
13+
/// Convienence type alias for the DRM device type for this driver
14+
pub(crate) type NovaDevice = drm::Device<NovaDriver>;
15+
16+
#[pin_data]
17+
pub(crate) struct NovaData {
18+
pub(crate) adev: ARef<auxiliary::Device>,
19+
}
20+
21+
const INFO: drm::DriverInfo = drm::DriverInfo {
22+
major: 0,
23+
minor: 0,
24+
patchlevel: 0,
25+
name: c_str!("nova"),
26+
desc: c_str!("Nvidia Graphics"),
27+
};
28+
29+
const NOVA_CORE_MODULE_NAME: &CStr = c_str!("NovaCore");
30+
const AUXILIARY_NAME: &CStr = c_str!("nova-drm");
31+
32+
kernel::auxiliary_device_table!(
33+
AUX_TABLE,
34+
MODULE_AUX_TABLE,
35+
<NovaDriver as auxiliary::Driver>::IdInfo,
36+
[(
37+
auxiliary::DeviceId::new(NOVA_CORE_MODULE_NAME, AUXILIARY_NAME),
38+
()
39+
)]
40+
);
41+
42+
impl auxiliary::Driver for NovaDriver {
43+
type IdInfo = ();
44+
const ID_TABLE: auxiliary::IdTable<Self::IdInfo> = &AUX_TABLE;
45+
46+
fn probe(adev: &auxiliary::Device<Core>, _info: &Self::IdInfo) -> Result<Pin<KBox<Self>>> {
47+
let data = try_pin_init!(NovaData { adev: adev.into() });
48+
49+
let drm = drm::Device::<Self>::new(adev.as_ref(), data)?;
50+
drm::Registration::new_foreign_owned(&drm, adev.as_ref(), 0)?;
51+
52+
Ok(KBox::new(Self { drm }, GFP_KERNEL)?.into())
53+
}
54+
}
55+
56+
#[vtable]
57+
impl drm::Driver for NovaDriver {
58+
type Data = NovaData;
59+
type File = File;
60+
type Object = gem::Object<NovaObject>;
61+
62+
const INFO: drm::DriverInfo = INFO;
63+
64+
kernel::declare_drm_ioctls! {
65+
(NOVA_GETPARAM, drm_nova_getparam, ioctl::RENDER_ALLOW, File::get_param),
66+
(NOVA_GEM_CREATE, drm_nova_gem_create, ioctl::AUTH | ioctl::RENDER_ALLOW, File::gem_create),
67+
(NOVA_GEM_INFO, drm_nova_gem_info, ioctl::AUTH | ioctl::RENDER_ALLOW, File::gem_info),
68+
}
69+
}

drivers/gpu/drm/nova/file.rs

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
3+
use crate::driver::{NovaDevice, NovaDriver};
4+
use crate::gem::NovaObject;
5+
use crate::uapi::{GemCreate, GemInfo, Getparam};
6+
use kernel::{
7+
alloc::flags::*,
8+
drm::{self, gem::BaseObject},
9+
pci,
10+
prelude::*,
11+
types::Opaque,
12+
uapi,
13+
};
14+
15+
pub(crate) struct File;
16+
17+
impl drm::file::DriverFile for File {
18+
type Driver = NovaDriver;
19+
20+
fn open(_dev: &NovaDevice) -> Result<Pin<KBox<Self>>> {
21+
Ok(KBox::new(Self, GFP_KERNEL)?.into())
22+
}
23+
}
24+
25+
impl File {
26+
/// IOCTL: get_param: Query GPU / driver metadata.
27+
pub(crate) fn get_param(
28+
dev: &NovaDevice,
29+
getparam: &Opaque<uapi::drm_nova_getparam>,
30+
_file: &drm::File<File>,
31+
) -> Result<u32> {
32+
let adev = &dev.adev;
33+
let parent = adev.parent().ok_or(ENOENT)?;
34+
let pdev: &pci::Device = parent.try_into()?;
35+
let getparam: &Getparam = getparam.into();
36+
37+
let value = match getparam.param() as u32 {
38+
uapi::NOVA_GETPARAM_VRAM_BAR_SIZE => pdev.resource_len(1)?,
39+
_ => return Err(EINVAL),
40+
};
41+
42+
getparam.set_value(value);
43+
44+
Ok(0)
45+
}
46+
47+
/// IOCTL: gem_create: Create a new DRM GEM object.
48+
pub(crate) fn gem_create(
49+
dev: &NovaDevice,
50+
req: &Opaque<uapi::drm_nova_gem_create>,
51+
file: &drm::File<File>,
52+
) -> Result<u32> {
53+
let req: &GemCreate = req.into();
54+
let obj = NovaObject::new(dev, req.size().try_into()?)?;
55+
56+
req.set_handle(obj.create_handle(file)?);
57+
58+
Ok(0)
59+
}
60+
61+
/// IOCTL: gem_info: Query GEM metadata.
62+
pub(crate) fn gem_info(
63+
_dev: &NovaDevice,
64+
req: &Opaque<uapi::drm_nova_gem_info>,
65+
file: &drm::File<File>,
66+
) -> Result<u32> {
67+
let req: &GemInfo = req.into();
68+
let bo = NovaObject::lookup_handle(file, req.handle())?;
69+
70+
req.set_size(bo.size().try_into()?);
71+
72+
Ok(0)
73+
}
74+
}

drivers/gpu/drm/nova/gem.rs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
3+
use kernel::{
4+
drm,
5+
drm::{gem, gem::BaseObject},
6+
prelude::*,
7+
types::ARef,
8+
};
9+
10+
use crate::{
11+
driver::{NovaDevice, NovaDriver},
12+
file::File,
13+
};
14+
15+
/// GEM Object inner driver data
16+
#[pin_data]
17+
pub(crate) struct NovaObject {}
18+
19+
impl gem::BaseDriverObject<gem::Object<NovaObject>> for NovaObject {
20+
fn new(_dev: &NovaDevice, _size: usize) -> impl PinInit<Self, Error> {
21+
try_pin_init!(NovaObject {})
22+
}
23+
}
24+
25+
impl gem::DriverObject for NovaObject {
26+
type Driver = NovaDriver;
27+
}
28+
29+
impl NovaObject {
30+
/// Create a new DRM GEM object.
31+
pub(crate) fn new(dev: &NovaDevice, size: usize) -> Result<ARef<gem::Object<Self>>> {
32+
let aligned_size = size.next_multiple_of(1 << 12);
33+
34+
if size == 0 || size > aligned_size {
35+
return Err(EINVAL);
36+
}
37+
38+
gem::Object::new(dev, aligned_size)
39+
}
40+
41+
/// Look up a GEM object handle for a `File` and return an `ObjectRef` for it.
42+
#[inline]
43+
pub(crate) fn lookup_handle(
44+
file: &drm::File<File>,
45+
handle: u32,
46+
) -> Result<ARef<gem::Object<Self>>> {
47+
gem::Object::lookup_handle(file, handle)
48+
}
49+
}

0 commit comments

Comments
 (0)