Skip to content

Commit 15392f7

Browse files
committed
Merge tag 'drm-rust-next-2026-01-26' of https://gitlab.freedesktop.org/drm/rust/kernel into drm-next
DRM Rust changes for v7.0-rc1 DRM: - Fix documentation for Registration constructors. - Use pin_init::zeroed() for fops initialization. - Annotate DRM helpers with __rust_helper. - Improve safety documentation for gem::Object::new(). - Update AlwaysRefCounted imports. MM: - Prevent integer overflow in page_align(). Nova (Core): - Prepare for Turing support. This includes parsing and handling Turing-specific firmware headers and sections as well as a Turing Falcon HAL implementation. - Get rid of the Result<impl PinInit<T, E>> anti-pattern. - Relocate initializer-specific code into the appropriate initializer. - Use CStr::from_bytes_until_nul() to remove custom helpers. - Improve handling of unexpected firmware values. - Clean up redundant debug prints. - Replace c_str!() with native Rust C-string literals. - Update nova-core task list. Nova (DRM): - Align GEM object size to system page size. Tyr: - Use generated uAPI bindings for GpuInfo. - Replace manual sleeps with read_poll_timeout(). - Replace c_str!() with native Rust C-string literals. - Suppress warnings for unread fields. - Fix incorrect register name in print statement. Signed-off-by: Dave Airlie <airlied@redhat.com> From: "Danilo Krummrich" <dakr@kernel.org> Link: https://patch.msgid.link/DFYW1WV6DUCG.3K8V2DAVD1Q4A@kernel.org
2 parents 205bd15 + cea7b66 commit 15392f7

30 files changed

Lines changed: 822 additions & 431 deletions

File tree

Documentation/gpu/nova/core/todo.rst

Lines changed: 15 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,15 @@ trait [1] from the num crate.
4141
Having this generalization also helps with implementing a generic macro that
4242
automatically generates the corresponding mappings between a value and a number.
4343

44+
FromPrimitive support has been worked on in the past, but hasn't been followed
45+
since then [1].
46+
47+
There also have been considerations of ToPrimitive [2].
48+
4449
| Complexity: Beginner
4550
| Link: https://docs.rs/num/latest/num/trait.FromPrimitive.html
51+
| Link: https://lore.kernel.org/all/cover.1750689857.git.y.j3ms.n@gmail.com/ [1]
52+
| Link: https://rust-for-linux.zulipchat.com/#narrow/channel/288089-General/topic/Implement.20.60FromPrimitive.60.20trait.20.2B.20derive.20macro.20for.20nova-core/with/541971854 [2]
4653
4754
Generic register abstraction [REGA]
4855
-----------------------------------
@@ -134,21 +141,6 @@ A `num` core kernel module is being designed to provide these operations.
134141
| Complexity: Intermediate
135142
| Contact: Alexandre Courbot
136143
137-
IRQ abstractions
138-
----------------
139-
140-
Rust abstractions for IRQ handling.
141-
142-
There is active ongoing work from Daniel Almeida [1] for the "core" abstractions
143-
to request IRQs.
144-
145-
Besides optional review and testing work, the required ``pci::Device`` code
146-
around those core abstractions needs to be worked out.
147-
148-
| Complexity: Intermediate
149-
| Link: https://lore.kernel.org/lkml/20250122163932.46697-1-daniel.almeida@collabora.com/ [1]
150-
| Contact: Daniel Almeida
151-
152144
Page abstraction for foreign pages
153145
----------------------------------
154146

@@ -161,40 +153,16 @@ There is active onging work from Abdiel Janulgue [1] and Lina [2].
161153
| Link: https://lore.kernel.org/linux-mm/20241119112408.779243-1-abdiel.janulgue@gmail.com/ [1]
162154
| Link: https://lore.kernel.org/rust-for-linux/20250202-rust-page-v1-0-e3170d7fe55e@asahilina.net/ [2]
163155
164-
Scatterlist / sg_table abstractions
165-
-----------------------------------
166-
167-
Rust abstractions for scatterlist / sg_table.
168-
169-
There is preceding work from Abdiel Janulgue, which hasn't made it to the
170-
mailing list yet.
171-
172-
| Complexity: Intermediate
173-
| Contact: Abdiel Janulgue
174-
175156
PCI MISC APIs
176157
-------------
177158

178-
Extend the existing PCI device / driver abstractions by SR-IOV, config space,
179-
capability, MSI API abstractions.
180-
181-
| Complexity: Beginner
159+
Extend the existing PCI device / driver abstractions by SR-IOV, capability, MSI
160+
API abstractions.
182161

183-
XArray bindings [XARR]
184-
----------------------
185-
186-
We need bindings for `xa_alloc`/`xa_alloc_cyclic` in order to generate the
187-
auxiliary device IDs.
188-
189-
| Complexity: Intermediate
162+
SR-IOV [1] is work in progress.
190163

191-
Debugfs abstractions
192-
--------------------
193-
194-
Rust abstraction for debugfs APIs.
195-
196-
| Reference: Export GSP log buffers
197-
| Complexity: Intermediate
164+
| Complexity: Beginner
165+
| Link: https://lore.kernel.org/all/20251119-rust-pci-sriov-v1-0-883a94599a97@redhat.com/ [1]
198166
199167
GPU (general)
200168
=============
@@ -233,7 +201,10 @@ Some possible options:
233201
- maple_tree
234202
- native Rust collections
235203

204+
There is work in progress for using drm_buddy [1].
205+
236206
| Complexity: Advanced
207+
| Link: https://lore.kernel.org/all/20251219203805.1246586-4-joelagnelf@nvidia.com/ [1]
237208
238209
Instance Memory
239210
---------------

drivers/gpu/drm/nova/driver.rs

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,15 @@
11
// SPDX-License-Identifier: GPL-2.0
22

33
use kernel::{
4-
auxiliary, c_str, device::Core, drm, drm::gem, drm::ioctl, prelude::*, sync::aref::ARef,
4+
auxiliary,
5+
device::Core,
6+
drm::{
7+
self,
8+
gem,
9+
ioctl, //
10+
},
11+
prelude::*,
12+
sync::aref::ARef, //
513
};
614

715
use crate::file::File;
@@ -24,12 +32,12 @@ const INFO: drm::DriverInfo = drm::DriverInfo {
2432
major: 0,
2533
minor: 0,
2634
patchlevel: 0,
27-
name: c_str!("nova"),
28-
desc: c_str!("Nvidia Graphics"),
35+
name: c"nova",
36+
desc: c"Nvidia Graphics",
2937
};
3038

31-
const NOVA_CORE_MODULE_NAME: &CStr = c_str!("NovaCore");
32-
const AUXILIARY_NAME: &CStr = c_str!("nova-drm");
39+
const NOVA_CORE_MODULE_NAME: &CStr = c"NovaCore";
40+
const AUXILIARY_NAME: &CStr = c"nova-drm";
3341

3442
kernel::auxiliary_device_table!(
3543
AUX_TABLE,

drivers/gpu/drm/nova/gem.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
use kernel::{
44
drm,
55
drm::{gem, gem::BaseObject},
6+
page,
67
prelude::*,
78
sync::aref::ARef,
89
};
@@ -27,11 +28,10 @@ impl gem::DriverObject for NovaObject {
2728
impl NovaObject {
2829
/// Create a new DRM GEM object.
2930
pub(crate) fn new(dev: &NovaDevice, size: usize) -> Result<ARef<gem::Object<Self>>> {
30-
let aligned_size = size.next_multiple_of(1 << 12);
31-
32-
if size == 0 || size > aligned_size {
31+
if size == 0 {
3332
return Err(EINVAL);
3433
}
34+
let aligned_size = page::page_align(size).ok_or(EINVAL)?;
3535

3636
gem::Object::new(dev, aligned_size)
3737
}

drivers/gpu/drm/tyr/driver.rs

Lines changed: 24 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
// SPDX-License-Identifier: GPL-2.0 or MIT
22

3-
use kernel::c_str;
43
use kernel::clk::Clk;
54
use kernel::clk::OptionalClk;
65
use kernel::device::Bound;
@@ -9,17 +8,18 @@ use kernel::device::Device;
98
use kernel::devres::Devres;
109
use kernel::drm;
1110
use kernel::drm::ioctl;
11+
use kernel::io::poll;
1212
use kernel::new_mutex;
1313
use kernel::of;
1414
use kernel::platform;
1515
use kernel::prelude::*;
1616
use kernel::regulator;
1717
use kernel::regulator::Regulator;
1818
use kernel::sizes::SZ_2M;
19+
use kernel::sync::aref::ARef;
1920
use kernel::sync::Arc;
2021
use kernel::sync::Mutex;
2122
use kernel::time;
22-
use kernel::types::ARef;
2323

2424
use crate::file::File;
2525
use crate::gem::TyrObject;
@@ -34,7 +34,7 @@ pub(crate) type TyrDevice = drm::Device<TyrDriver>;
3434

3535
#[pin_data(PinnedDrop)]
3636
pub(crate) struct TyrDriver {
37-
device: ARef<TyrDevice>,
37+
_device: ARef<TyrDevice>,
3838
}
3939

4040
#[pin_data(PinnedDrop)]
@@ -68,20 +68,13 @@ unsafe impl Sync for TyrData {}
6868
fn issue_soft_reset(dev: &Device<Bound>, iomem: &Devres<IoMem>) -> Result {
6969
regs::GPU_CMD.write(dev, iomem, regs::GPU_CMD_SOFT_RESET)?;
7070

71-
// TODO: We cannot poll, as there is no support in Rust currently, so we
72-
// sleep. Change this when read_poll_timeout() is implemented in Rust.
73-
kernel::time::delay::fsleep(time::Delta::from_millis(100));
74-
75-
if regs::GPU_IRQ_RAWSTAT.read(dev, iomem)? & regs::GPU_IRQ_RAWSTAT_RESET_COMPLETED == 0 {
76-
dev_err!(dev, "GPU reset failed with errno\n");
77-
dev_err!(
78-
dev,
79-
"GPU_INT_RAWSTAT is {}\n",
80-
regs::GPU_IRQ_RAWSTAT.read(dev, iomem)?
81-
);
82-
83-
return Err(EIO);
84-
}
71+
poll::read_poll_timeout(
72+
|| regs::GPU_IRQ_RAWSTAT.read(dev, iomem),
73+
|status| *status & regs::GPU_IRQ_RAWSTAT_RESET_COMPLETED != 0,
74+
time::Delta::from_millis(1),
75+
time::Delta::from_millis(100),
76+
)
77+
.inspect_err(|_| dev_err!(dev, "GPU reset failed."))?;
8578

8679
Ok(())
8780
}
@@ -91,8 +84,8 @@ kernel::of_device_table!(
9184
MODULE_OF_TABLE,
9285
<TyrDriver as platform::Driver>::IdInfo,
9386
[
94-
(of::DeviceId::new(c_str!("rockchip,rk3588-mali")), ()),
95-
(of::DeviceId::new(c_str!("arm,mali-valhall-csf")), ())
87+
(of::DeviceId::new(c"rockchip,rk3588-mali"), ()),
88+
(of::DeviceId::new(c"arm,mali-valhall-csf"), ())
9689
]
9790
);
9891

@@ -104,16 +97,16 @@ impl platform::Driver for TyrDriver {
10497
pdev: &platform::Device<Core>,
10598
_info: Option<&Self::IdInfo>,
10699
) -> impl PinInit<Self, Error> {
107-
let core_clk = Clk::get(pdev.as_ref(), Some(c_str!("core")))?;
108-
let stacks_clk = OptionalClk::get(pdev.as_ref(), Some(c_str!("stacks")))?;
109-
let coregroup_clk = OptionalClk::get(pdev.as_ref(), Some(c_str!("coregroup")))?;
100+
let core_clk = Clk::get(pdev.as_ref(), Some(c"core"))?;
101+
let stacks_clk = OptionalClk::get(pdev.as_ref(), Some(c"stacks"))?;
102+
let coregroup_clk = OptionalClk::get(pdev.as_ref(), Some(c"coregroup"))?;
110103

111104
core_clk.prepare_enable()?;
112105
stacks_clk.prepare_enable()?;
113106
coregroup_clk.prepare_enable()?;
114107

115-
let mali_regulator = Regulator::<regulator::Enabled>::get(pdev.as_ref(), c_str!("mali"))?;
116-
let sram_regulator = Regulator::<regulator::Enabled>::get(pdev.as_ref(), c_str!("sram"))?;
108+
let mali_regulator = Regulator::<regulator::Enabled>::get(pdev.as_ref(), c"mali")?;
109+
let sram_regulator = Regulator::<regulator::Enabled>::get(pdev.as_ref(), c"sram")?;
117110

118111
let request = pdev.io_request_by_index(0).ok_or(ENODEV)?;
119112
let iomem = Arc::pin_init(request.iomap_sized::<SZ_2M>(), GFP_KERNEL)?;
@@ -134,16 +127,16 @@ impl platform::Driver for TyrDriver {
134127
coregroup: coregroup_clk,
135128
}),
136129
regulators <- new_mutex!(Regulators {
137-
mali: mali_regulator,
138-
sram: sram_regulator,
130+
_mali: mali_regulator,
131+
_sram: sram_regulator,
139132
}),
140133
gpu_info,
141134
});
142135

143136
let tdev: ARef<TyrDevice> = drm::Device::new(pdev.as_ref(), data)?;
144137
drm::driver::Registration::new_foreign_owned(&tdev, pdev.as_ref(), 0)?;
145138

146-
let driver = TyrDriver { device: tdev };
139+
let driver = TyrDriver { _device: tdev };
147140

148141
// We need this to be dev_info!() because dev_dbg!() does not work at
149142
// all in Rust for now, and we need to see whether probe succeeded.
@@ -174,8 +167,8 @@ const INFO: drm::DriverInfo = drm::DriverInfo {
174167
major: 1,
175168
minor: 5,
176169
patchlevel: 0,
177-
name: c_str!("panthor"),
178-
desc: c_str!("ARM Mali Tyr DRM driver"),
170+
name: c"panthor",
171+
desc: c"ARM Mali Tyr DRM driver",
179172
};
180173

181174
#[vtable]
@@ -200,6 +193,6 @@ struct Clocks {
200193

201194
#[pin_data]
202195
struct Regulators {
203-
mali: Regulator<regulator::Enabled>,
204-
sram: Regulator<regulator::Enabled>,
196+
_mali: Regulator<regulator::Enabled>,
197+
_sram: Regulator<regulator::Enabled>,
205198
}

drivers/gpu/drm/tyr/gpu.rs

Lines changed: 31 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
// SPDX-License-Identifier: GPL-2.0 or MIT
22

3+
use core::ops::Deref;
4+
use core::ops::DerefMut;
35
use kernel::bits::genmask_u32;
46
use kernel::device::Bound;
57
use kernel::device::Device;
68
use kernel::devres::Devres;
9+
use kernel::io::poll;
710
use kernel::platform;
811
use kernel::prelude::*;
9-
use kernel::time;
12+
use kernel::time::Delta;
1013
use kernel::transmute::AsBytes;
1114
use kernel::uapi;
1215

@@ -19,29 +22,9 @@ use crate::regs;
1922
/// # Invariants
2023
///
2124
/// - The layout of this struct identical to the C `struct drm_panthor_gpu_info`.
22-
#[repr(C)]
23-
pub(crate) struct GpuInfo {
24-
pub(crate) gpu_id: u32,
25-
pub(crate) gpu_rev: u32,
26-
pub(crate) csf_id: u32,
27-
pub(crate) l2_features: u32,
28-
pub(crate) tiler_features: u32,
29-
pub(crate) mem_features: u32,
30-
pub(crate) mmu_features: u32,
31-
pub(crate) thread_features: u32,
32-
pub(crate) max_threads: u32,
33-
pub(crate) thread_max_workgroup_size: u32,
34-
pub(crate) thread_max_barrier_size: u32,
35-
pub(crate) coherency_features: u32,
36-
pub(crate) texture_features: [u32; 4],
37-
pub(crate) as_present: u32,
38-
pub(crate) selected_coherency: u32,
39-
pub(crate) shader_present: u64,
40-
pub(crate) l2_present: u64,
41-
pub(crate) tiler_present: u64,
42-
pub(crate) core_features: u32,
43-
pub(crate) pad: u32,
44-
}
25+
#[repr(transparent)]
26+
#[derive(Clone, Copy)]
27+
pub(crate) struct GpuInfo(pub(crate) uapi::drm_panthor_gpu_info);
4528

4629
impl GpuInfo {
4730
pub(crate) fn new(dev: &Device<Bound>, iomem: &Devres<IoMem>) -> Result<Self> {
@@ -74,7 +57,7 @@ impl GpuInfo {
7457
let l2_present = u64::from(regs::GPU_L2_PRESENT_LO.read(dev, iomem)?);
7558
let l2_present = l2_present | u64::from(regs::GPU_L2_PRESENT_HI.read(dev, iomem)?) << 32;
7659

77-
Ok(Self {
60+
Ok(Self(uapi::drm_panthor_gpu_info {
7861
gpu_id,
7962
gpu_rev,
8063
csf_id,
@@ -96,7 +79,8 @@ impl GpuInfo {
9679
tiler_present,
9780
core_features,
9881
pad: 0,
99-
})
82+
gpu_features: 0,
83+
}))
10084
}
10185

10286
pub(crate) fn log(&self, pdev: &platform::Device) {
@@ -155,6 +139,20 @@ impl GpuInfo {
155139
}
156140
}
157141

142+
impl Deref for GpuInfo {
143+
type Target = uapi::drm_panthor_gpu_info;
144+
145+
fn deref(&self) -> &Self::Target {
146+
&self.0
147+
}
148+
}
149+
150+
impl DerefMut for GpuInfo {
151+
fn deref_mut(&mut self) -> &mut Self::Target {
152+
&mut self.0
153+
}
154+
}
155+
158156
// SAFETY: `GpuInfo`'s invariant guarantees that it is the same type that is
159157
// already exposed to userspace by the C driver. This implies that it fulfills
160158
// the requirements for `AsBytes`.
@@ -207,14 +205,13 @@ impl From<u32> for GpuId {
207205
pub(crate) fn l2_power_on(dev: &Device<Bound>, iomem: &Devres<IoMem>) -> Result {
208206
regs::L2_PWRON_LO.write(dev, iomem, 1)?;
209207

210-
// TODO: We cannot poll, as there is no support in Rust currently, so we
211-
// sleep. Change this when read_poll_timeout() is implemented in Rust.
212-
kernel::time::delay::fsleep(time::Delta::from_millis(100));
213-
214-
if regs::L2_READY_LO.read(dev, iomem)? != 1 {
215-
dev_err!(dev, "Failed to power on the GPU\n");
216-
return Err(EIO);
217-
}
208+
poll::read_poll_timeout(
209+
|| regs::L2_READY_LO.read(dev, iomem),
210+
|status| *status == 1,
211+
Delta::from_millis(1),
212+
Delta::from_millis(100),
213+
)
214+
.inspect_err(|_| dev_err!(dev, "Failed to power on the GPU."))?;
218215

219216
Ok(())
220217
}

0 commit comments

Comments
 (0)