Skip to content

Commit 6f17ab9

Browse files
committed
Merge tag 'drm-rust-next-2025-09-16' of https://gitlab.freedesktop.org/drm/rust/kernel into drm-next
DRM Rust changes for v6.18 Alloc - Add BorrowedPage type and AsPageIter trait - Implement Vmalloc::to_page() and VmallocPageIter - Implement AsPageIter for VBox and VVec DMA & Scatterlist - Add dma::DataDirection and type alias for dma_addr_t - Abstraction for struct scatterlist and struct sg_table DRM - In the DRM GEM module, simplify overall use of generics, add DriverFile type alias and drop Object::SIZE. Nova (Core) - Various register!() macro improvements (paving the way for lifting it to common driver infrastructure) - Minor VBios fixes and refactoring - Minor firmware request refactoring - Advance firmware boot stages; process Booter and patch its signature, process GSP and GSP bootloader - Switch development fimrware version to r570.144 - Add basic firmware bindings for r570.144 - Move GSP boot code to its own module - Clean up and take advantage of pin-init features to store most of the driver's private data within a single allocation - Update ARef import from sync::aref - Add website to MAINTAINERS entry Nova (DRM) - Update ARef import from sync::aref - Add website to MAINTAINERS entry Pin-Init - Merge pin-init PR from Benno - `#[pin_data]` now generates a `*Projection` struct similar to the `pin-project` crate. - Add initializer code blocks to `[try_][pin_]init!` macros: make initializer macros accept any number of `_: {/* arbitrary code */},` & make them run the code at that point. - Make the `[try_][pin_]init!` macros expose initialized fields via a `let` binding as `&mut T` or `Pin<&mut T>` for later fields. Rust - Various methods for AsBytes and FromBytes traits Tyr - Initial Rust driver skeleton for ARM Mali GPUs. - It can power up the GPU, query for GPU metatdata through MMIO and provide the metadata to userspace via DRM device IOCTL (struct drm_panthor_dev_query). Signed-off-by: Dave Airlie <[email protected]> From: "Danilo Krummrich" <[email protected]> Link: https://lore.kernel.org/r/[email protected]
2 parents 5770495 + 299eb32 commit 6f17ab9

Some content is hidden

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

62 files changed

+4001
-666
lines changed

Documentation/gpu/nova/core/todo.rst

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -131,8 +131,6 @@ crate so it can be used by other components as well.
131131

132132
Features desired before this happens:
133133

134-
* Relative register with build-time base address validation,
135-
* Arrays of registers with build-time index validation,
136134
* Make I/O optional I/O (for field values that are not registers),
137135
* Support other sizes than `u32`,
138136
* Allow visibility control for registers and individual fields,
@@ -232,23 +230,6 @@ Rust abstraction for debugfs APIs.
232230
GPU (general)
233231
=============
234232

235-
Parse firmware headers
236-
----------------------
237-
238-
Parse ELF headers from the firmware files loaded from the filesystem.
239-
240-
| Reference: ELF utils
241-
| Complexity: Beginner
242-
| Contact: Abdiel Janulgue
243-
244-
Build radix3 page table
245-
-----------------------
246-
247-
Build the radix3 page table to map the firmware.
248-
249-
| Complexity: Intermediate
250-
| Contact: Abdiel Janulgue
251-
252233
Initial Devinit support
253234
-----------------------
254235

MAINTAINERS

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2086,6 +2086,19 @@ F: Documentation/devicetree/bindings/gpu/arm,mali-valhall-csf.yaml
20862086
F: drivers/gpu/drm/panthor/
20872087
F: include/uapi/drm/panthor_drm.h
20882088

2089+
ARM MALI TYR DRM DRIVER
2090+
M: Daniel Almeida <[email protected]>
2091+
M: Alice Ryhl <[email protected]>
2092+
2093+
S: Supported
2094+
W: https://rust-for-linux.com/tyr-gpu-driver
2095+
W https://drm.pages.freedesktop.org/maintainer-tools/drm-rust.html
2096+
B: https://gitlab.freedesktop.org/panfrost/linux/-/issues
2097+
T: git https://gitlab.freedesktop.org/drm/rust/kernel.git
2098+
F: Documentation/devicetree/bindings/gpu/arm,mali-valhall-csf.yaml
2099+
F: drivers/gpu/drm/tyr/
2100+
F: include/uapi/drm/panthor_drm.h
2101+
20892102
ARM MALI-DP DRM DRIVER
20902103
M: Liviu Dudau <[email protected]>
20912104
S: Supported
@@ -7237,7 +7250,7 @@ F: include/linux/dma-mapping.h
72377250
F: include/linux/swiotlb.h
72387251
F: kernel/dma/
72397252

7240-
DMA MAPPING HELPERS DEVICE DRIVER API [RUST]
7253+
DMA MAPPING & SCATTERLIST API [RUST]
72417254
M: Danilo Krummrich <[email protected]>
72427255
R: Abdiel Janulgue <[email protected]>
72437256
R: Daniel Almeida <[email protected]>
@@ -7248,7 +7261,9 @@ S: Supported
72487261
W: https://rust-for-linux.com
72497262
T: git git://git.kernel.org/pub/scm/linux/kernel/git/driver-core/driver-core.git
72507263
F: rust/helpers/dma.c
7264+
F: rust/helpers/scatterlist.c
72517265
F: rust/kernel/dma.rs
7266+
F: rust/kernel/scatterlist.rs
72527267
F: samples/rust/rust_dma.rs
72537268

72547269
DMA-BUF HEAPS FRAMEWORK
@@ -7838,6 +7853,7 @@ M: Danilo Krummrich <[email protected]>
78387853
M: Alexandre Courbot <[email protected]>
78397854
78407855
S: Supported
7856+
W: https://rust-for-linux.com/nova-gpu-driver
78417857
Q: https://patchwork.freedesktop.org/project/nouveau/
78427858
B: https://gitlab.freedesktop.org/drm/nova/-/issues
78437859
C: irc://irc.oftc.net/nouveau
@@ -7849,6 +7865,7 @@ DRM DRIVER FOR NVIDIA GPUS [RUST]
78497865
M: Danilo Krummrich <[email protected]>
78507866
78517867
S: Supported
7868+
W: https://rust-for-linux.com/nova-gpu-driver
78527869
Q: https://patchwork.freedesktop.org/project/nouveau/
78537870
B: https://gitlab.freedesktop.org/drm/nova/-/issues
78547871
C: irc://irc.oftc.net/nouveau

drivers/gpu/drm/Kconfig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -396,6 +396,8 @@ source "drivers/gpu/drm/sprd/Kconfig"
396396

397397
source "drivers/gpu/drm/imagination/Kconfig"
398398

399+
source "drivers/gpu/drm/tyr/Kconfig"
400+
399401
config DRM_HYPERV
400402
tristate "DRM Support for Hyper-V synthetic video device"
401403
depends on DRM && PCI && HYPERV

drivers/gpu/drm/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,7 @@ obj-$(CONFIG_DRM_VBOXVIDEO) += vboxvideo/
220220
obj-$(CONFIG_DRM_LIMA) += lima/
221221
obj-$(CONFIG_DRM_PANFROST) += panfrost/
222222
obj-$(CONFIG_DRM_PANTHOR) += panthor/
223+
obj-$(CONFIG_DRM_TYR) += tyr/
223224
obj-$(CONFIG_DRM_ASPEED_GFX) += aspeed/
224225
obj-$(CONFIG_DRM_MCDE) += mcde/
225226
obj-$(CONFIG_DRM_TIDSS) += tidss/

drivers/gpu/drm/nova/driver.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
// SPDX-License-Identifier: GPL-2.0
22

3-
use kernel::{auxiliary, c_str, device::Core, drm, drm::gem, drm::ioctl, prelude::*, types::ARef};
3+
use kernel::{
4+
auxiliary, c_str, device::Core, drm, drm::gem, drm::ioctl, prelude::*, sync::aref::ARef,
5+
};
46

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

drivers/gpu/drm/nova/gem.rs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use kernel::{
44
drm,
55
drm::{gem, gem::BaseObject},
66
prelude::*,
7-
types::ARef,
7+
sync::aref::ARef,
88
};
99

1010
use crate::{
@@ -16,16 +16,14 @@ use crate::{
1616
#[pin_data]
1717
pub(crate) struct NovaObject {}
1818

19-
impl gem::BaseDriverObject<gem::Object<NovaObject>> for NovaObject {
19+
impl gem::DriverObject for NovaObject {
20+
type Driver = NovaDriver;
21+
2022
fn new(_dev: &NovaDevice, _size: usize) -> impl PinInit<Self, Error> {
2123
try_pin_init!(NovaObject {})
2224
}
2325
}
2426

25-
impl gem::DriverObject for NovaObject {
26-
type Driver = NovaDriver;
27-
}
28-
2927
impl NovaObject {
3028
/// Create a new DRM GEM object.
3129
pub(crate) fn new(dev: &NovaDevice, size: usize) -> Result<ARef<gem::Object<Self>>> {

drivers/gpu/drm/tyr/Kconfig

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# SPDX-License-Identifier: GPL-2.0 or MIT
2+
3+
config DRM_TYR
4+
tristate "Tyr (Rust DRM support for ARM Mali CSF-based GPUs)"
5+
depends on DRM=y
6+
depends on RUST
7+
depends on ARM || ARM64 || COMPILE_TEST
8+
depends on !GENERIC_ATOMIC64 # for IOMMU_IO_PGTABLE_LPAE
9+
default n
10+
help
11+
Rust DRM driver for ARM Mali CSF-based GPUs.
12+
13+
This driver is for Mali (or Immortalis) Valhall Gxxx GPUs.
14+
15+
Note that the Mali-G68 and Mali-G78, while Valhall architecture, will
16+
be supported with the panfrost driver as they are not CSF GPUs.
17+
18+
if M is selected, the module will be called tyr. This driver is work
19+
in progress and may not be functional.

drivers/gpu/drm/tyr/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 or MIT
2+
3+
obj-$(CONFIG_DRM_TYR) += tyr.o

drivers/gpu/drm/tyr/driver.rs

Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
// SPDX-License-Identifier: GPL-2.0 or MIT
2+
3+
use kernel::c_str;
4+
use kernel::clk::Clk;
5+
use kernel::clk::OptionalClk;
6+
use kernel::device::Bound;
7+
use kernel::device::Core;
8+
use kernel::device::Device;
9+
use kernel::devres::Devres;
10+
use kernel::drm;
11+
use kernel::drm::ioctl;
12+
use kernel::new_mutex;
13+
use kernel::of;
14+
use kernel::platform;
15+
use kernel::prelude::*;
16+
use kernel::regulator;
17+
use kernel::regulator::Regulator;
18+
use kernel::sizes::SZ_2M;
19+
use kernel::sync::Arc;
20+
use kernel::sync::Mutex;
21+
use kernel::time;
22+
use kernel::types::ARef;
23+
24+
use crate::file::File;
25+
use crate::gem::TyrObject;
26+
use crate::gpu;
27+
use crate::gpu::GpuInfo;
28+
use crate::regs;
29+
30+
pub(crate) type IoMem = kernel::io::mem::IoMem<SZ_2M>;
31+
32+
/// Convenience type alias for the DRM device type for this driver.
33+
pub(crate) type TyrDevice = drm::Device<TyrDriver>;
34+
35+
#[pin_data(PinnedDrop)]
36+
pub(crate) struct TyrDriver {
37+
device: ARef<TyrDevice>,
38+
}
39+
40+
#[pin_data(PinnedDrop)]
41+
pub(crate) struct TyrData {
42+
pub(crate) pdev: ARef<platform::Device>,
43+
44+
#[pin]
45+
clks: Mutex<Clocks>,
46+
47+
#[pin]
48+
regulators: Mutex<Regulators>,
49+
50+
/// Some information on the GPU.
51+
///
52+
/// This is mainly queried by userspace, i.e.: Mesa.
53+
pub(crate) gpu_info: GpuInfo,
54+
}
55+
56+
// Both `Clk` and `Regulator` do not implement `Send` or `Sync`, but they
57+
// should. There are patches on the mailing list to address this, but they have
58+
// not landed yet.
59+
//
60+
// For now, add this workaround so that this patch compiles with the promise
61+
// that it will be removed in a future patch.
62+
//
63+
// SAFETY: This will be removed in a future patch.
64+
unsafe impl Send for TyrData {}
65+
// SAFETY: This will be removed in a future patch.
66+
unsafe impl Sync for TyrData {}
67+
68+
fn issue_soft_reset(dev: &Device<Bound>, iomem: &Devres<IoMem>) -> Result {
69+
regs::GPU_CMD.write(dev, iomem, regs::GPU_CMD_SOFT_RESET)?;
70+
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+
}
85+
86+
Ok(())
87+
}
88+
89+
kernel::of_device_table!(
90+
OF_TABLE,
91+
MODULE_OF_TABLE,
92+
<TyrDriver as platform::Driver>::IdInfo,
93+
[
94+
(of::DeviceId::new(c_str!("rockchip,rk3588-mali")), ()),
95+
(of::DeviceId::new(c_str!("arm,mali-valhall-csf")), ())
96+
]
97+
);
98+
99+
impl platform::Driver for TyrDriver {
100+
type IdInfo = ();
101+
const OF_ID_TABLE: Option<of::IdTable<Self::IdInfo>> = Some(&OF_TABLE);
102+
103+
fn probe(
104+
pdev: &platform::Device<Core>,
105+
_info: Option<&Self::IdInfo>,
106+
) -> Result<Pin<KBox<Self>>> {
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")))?;
110+
111+
core_clk.prepare_enable()?;
112+
stacks_clk.prepare_enable()?;
113+
coregroup_clk.prepare_enable()?;
114+
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"))?;
117+
118+
let request = pdev.io_request_by_index(0).ok_or(ENODEV)?;
119+
let iomem = Arc::pin_init(request.iomap_sized::<SZ_2M>(), GFP_KERNEL)?;
120+
121+
issue_soft_reset(pdev.as_ref(), &iomem)?;
122+
gpu::l2_power_on(pdev.as_ref(), &iomem)?;
123+
124+
let gpu_info = GpuInfo::new(pdev.as_ref(), &iomem)?;
125+
gpu_info.log(pdev);
126+
127+
let platform: ARef<platform::Device> = pdev.into();
128+
129+
let data = try_pin_init!(TyrData {
130+
pdev: platform.clone(),
131+
clks <- new_mutex!(Clocks {
132+
core: core_clk,
133+
stacks: stacks_clk,
134+
coregroup: coregroup_clk,
135+
}),
136+
regulators <- new_mutex!(Regulators {
137+
mali: mali_regulator,
138+
sram: sram_regulator,
139+
}),
140+
gpu_info,
141+
});
142+
143+
let tdev: ARef<TyrDevice> = drm::Device::new(pdev.as_ref(), data)?;
144+
drm::driver::Registration::new_foreign_owned(&tdev, pdev.as_ref(), 0)?;
145+
146+
let driver = KBox::pin_init(try_pin_init!(TyrDriver { device: tdev }), GFP_KERNEL)?;
147+
148+
// We need this to be dev_info!() because dev_dbg!() does not work at
149+
// all in Rust for now, and we need to see whether probe succeeded.
150+
dev_info!(pdev.as_ref(), "Tyr initialized correctly.\n");
151+
Ok(driver)
152+
}
153+
}
154+
155+
#[pinned_drop]
156+
impl PinnedDrop for TyrDriver {
157+
fn drop(self: Pin<&mut Self>) {}
158+
}
159+
160+
#[pinned_drop]
161+
impl PinnedDrop for TyrData {
162+
fn drop(self: Pin<&mut Self>) {
163+
// TODO: the type-state pattern for Clks will fix this.
164+
let clks = self.clks.lock();
165+
clks.core.disable_unprepare();
166+
clks.stacks.disable_unprepare();
167+
clks.coregroup.disable_unprepare();
168+
}
169+
}
170+
171+
// We need to retain the name "panthor" to achieve drop-in compatibility with
172+
// the C driver in the userspace stack.
173+
const INFO: drm::DriverInfo = drm::DriverInfo {
174+
major: 1,
175+
minor: 5,
176+
patchlevel: 0,
177+
name: c_str!("panthor"),
178+
desc: c_str!("ARM Mali Tyr DRM driver"),
179+
};
180+
181+
#[vtable]
182+
impl drm::Driver for TyrDriver {
183+
type Data = TyrData;
184+
type File = File;
185+
type Object = drm::gem::Object<TyrObject>;
186+
187+
const INFO: drm::DriverInfo = INFO;
188+
189+
kernel::declare_drm_ioctls! {
190+
(PANTHOR_DEV_QUERY, drm_panthor_dev_query, ioctl::RENDER_ALLOW, File::dev_query),
191+
}
192+
}
193+
194+
#[pin_data]
195+
struct Clocks {
196+
core: Clk,
197+
stacks: OptionalClk,
198+
coregroup: OptionalClk,
199+
}
200+
201+
#[pin_data]
202+
struct Regulators {
203+
mali: Regulator<regulator::Enabled>,
204+
sram: Regulator<regulator::Enabled>,
205+
}

0 commit comments

Comments
 (0)