aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nova/uapi.rs
diff options
context:
space:
mode:
authorDanilo Krummrich <[email protected]>2025-04-24 16:02:50 +0000
committerDanilo Krummrich <[email protected]>2025-05-12 18:48:15 +0000
commitcdeaeb9dd762d7711241a62459dfb730b2cd0281 (patch)
treeeb1f96b9c4aa55c1abe9893b0653f2a1949b6e4b /drivers/gpu/drm/nova/uapi.rs
parentgpu: nova-core: register auxiliary device for nova-drm (diff)
downloadkernel-cdeaeb9dd762d7711241a62459dfb730b2cd0281.tar.gz
kernel-cdeaeb9dd762d7711241a62459dfb730b2cd0281.zip
drm: nova-drm: add initial driver skeleton
Add the initial nova-drm driver skeleton. nova-drm is connected to nova-core through the auxiliary bus and implements the DRM parts of the nova driver stack. For now, it implements the fundamental DRM abstractions, i.e. creates a DRM device and registers it, exposing a three sample IOCTLs. DRM_IOCTL_NOVA_GETPARAM - provides the PCI bar size from the bar that maps the GPUs VRAM from nova-core DRM_IOCTL_NOVA_GEM_CREATE - creates a new dummy DRM GEM object and returns a handle DRM_IOCTL_NOVA_GEM_INFO - provides metadata for the DRM GEM object behind a given handle I implemented a small userspace test suite [1] that utilizes this interface. Link: https://gitlab.freedesktop.org/dakr/drm-test [1] Reviewed-by: Maxime Ripard <[email protected]> Acked-by: Dave Airlie <[email protected]> Link: https://lore.kernel.org/r/[email protected] [ Kconfig: depend on DRM=y rather than just DRM. - Danilo ] Signed-off-by: Danilo Krummrich <[email protected]>
Diffstat (limited to 'drivers/gpu/drm/nova/uapi.rs')
-rw-r--r--drivers/gpu/drm/nova/uapi.rs61
1 files changed, 61 insertions, 0 deletions
diff --git a/drivers/gpu/drm/nova/uapi.rs b/drivers/gpu/drm/nova/uapi.rs
new file mode 100644
index 000000000000..eb228a58d423
--- /dev/null
+++ b/drivers/gpu/drm/nova/uapi.rs
@@ -0,0 +1,61 @@
+// SPDX-License-Identifier: GPL-2.0
+
+use kernel::uapi;
+
+// TODO Work out some common infrastructure to avoid boilerplate code for uAPI abstractions.
+
+macro_rules! define_uapi_abstraction {
+ ($name:ident <= $inner:ty) => {
+ #[repr(transparent)]
+ pub struct $name(::kernel::types::Opaque<$inner>);
+
+ impl ::core::convert::From<&::kernel::types::Opaque<$inner>> for &$name {
+ fn from(value: &::kernel::types::Opaque<$inner>) -> Self {
+ // SAFETY: `Self` is a transparent wrapper of `$inner`.
+ unsafe { ::core::mem::transmute(value) }
+ }
+ }
+ };
+}
+
+define_uapi_abstraction!(Getparam <= uapi::drm_nova_getparam);
+
+impl Getparam {
+ pub fn param(&self) -> u64 {
+ // SAFETY: `self.get()` is a valid pointer to a `struct drm_nova_getparam`.
+ unsafe { (*self.0.get()).param }
+ }
+
+ pub fn set_value(&self, v: u64) {
+ // SAFETY: `self.get()` is a valid pointer to a `struct drm_nova_getparam`.
+ unsafe { (*self.0.get()).value = v };
+ }
+}
+
+define_uapi_abstraction!(GemCreate <= uapi::drm_nova_gem_create);
+
+impl GemCreate {
+ pub fn size(&self) -> u64 {
+ // SAFETY: `self.get()` is a valid pointer to a `struct drm_nova_gem_create`.
+ unsafe { (*self.0.get()).size }
+ }
+
+ pub fn set_handle(&self, handle: u32) {
+ // SAFETY: `self.get()` is a valid pointer to a `struct drm_nova_gem_create`.
+ unsafe { (*self.0.get()).handle = handle };
+ }
+}
+
+define_uapi_abstraction!(GemInfo <= uapi::drm_nova_gem_info);
+
+impl GemInfo {
+ pub fn handle(&self) -> u32 {
+ // SAFETY: `self.get()` is a valid pointer to a `struct drm_nova_gem_info`.
+ unsafe { (*self.0.get()).handle }
+ }
+
+ pub fn set_size(&self, size: u64) {
+ // SAFETY: `self.get()` is a valid pointer to a `struct drm_nova_gem_info`.
+ unsafe { (*self.0.get()).size = size };
+ }
+}